From 981963a2118bc74c3ed9e4499048d2fe3353fbaf Mon Sep 17 00:00:00 2001 From: Douglas Anderson Date: Mon, 9 Nov 2020 17:00:59 -0800 Subject: dt-bindings: dt-bindings: display: simple: Add BOE NV110WTM-N61 Add yet another eDP panel. Signed-off-by: Douglas Anderson Acked-by: Rob Herring Signed-off-by: Sam Ravnborg Link: https://patchwork.freedesktop.org/patch/msgid/20201109170018.v4.5.I28d9e32b3cc0aae980ecc39d364263a3f9871298@changeid --- Documentation/devicetree/bindings/display/panel/panel-simple.yaml | 2 ++ 1 file changed, 2 insertions(+) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/display/panel/panel-simple.yaml b/Documentation/devicetree/bindings/display/panel/panel-simple.yaml index 27fffafe5b5c..35b42ee4ed1d 100644 --- a/Documentation/devicetree/bindings/display/panel/panel-simple.yaml +++ b/Documentation/devicetree/bindings/display/panel/panel-simple.yaml @@ -76,6 +76,8 @@ properties: # BOE OPTOELECTRONICS TECHNOLOGY 10.1" WXGA TFT LCD panel - boe,nv101wxmn51 # BOE NV133FHM-N61 13.3" FHD (1920x1080) TFT LCD Panel + - boe,nv110wtm-n61 + # BOE NV110WTM-N61 11.0" 2160x1440 TFT LCD Panel - boe,nv133fhm-n61 # BOE NV133FHM-N62 13.3" FHD (1920x1080) TFT LCD Panel - boe,nv133fhm-n62 -- cgit v1.2.3 From 2abb0b994db569422c79e77208d1c0d560faa57f Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Sun, 15 Nov 2020 19:51:45 +0100 Subject: dt-bindings: display: mcde: Convert to YAML schema This moves the MCDE bindings over to using the YAML schema to describe the ST-Ericsson MCDE display controller, making use of the generic DSI controller schema. In the process we correct an error in the old text bindings: the clocks for the SDI host controllers were specified as part of the main MCDE component while they should be specified in the DSI host controller subnodes. This was a leftover from an earlier iteration of the first patch series adding the MCDE. We also add the "port" node, we will use this when adding LCD panels using the direct parallel interface DPI instead of DSI. Signed-off-by: Linus Walleij Reviewed-by: Sam Ravnborg Reviewed-by: Rob Herring Cc: devicetree@vger.kernel.org Link: https://patchwork.freedesktop.org/patch/msgid/20201115185145.566772-1-linus.walleij@linaro.org --- .../devicetree/bindings/display/ste,mcde.txt | 104 ------------- .../devicetree/bindings/display/ste,mcde.yaml | 169 +++++++++++++++++++++ 2 files changed, 169 insertions(+), 104 deletions(-) delete mode 100644 Documentation/devicetree/bindings/display/ste,mcde.txt create mode 100644 Documentation/devicetree/bindings/display/ste,mcde.yaml (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/display/ste,mcde.txt b/Documentation/devicetree/bindings/display/ste,mcde.txt deleted file mode 100644 index 4c33c692bd5f..000000000000 --- a/Documentation/devicetree/bindings/display/ste,mcde.txt +++ /dev/null @@ -1,104 +0,0 @@ -ST-Ericsson Multi Channel Display Engine MCDE - -The ST-Ericsson MCDE is a display controller with support for compositing -and displaying several channels memory resident graphics data on DSI or -LCD displays or bridges. It is used in the ST-Ericsson U8500 platform. - -Required properties: - -- compatible: must be: - "ste,mcde" -- reg: register base for the main MCDE control registers, should be - 0x1000 in size -- interrupts: the interrupt line for the MCDE -- epod-supply: a phandle to the EPOD regulator -- vana-supply: a phandle to the analog voltage regulator -- clocks: an array of the MCDE clocks in this strict order: - MCDECLK (main MCDE clock), LCDCLK (LCD clock), PLLDSI - (HDMI clock), DSI0ESCLK (DSI0 energy save clock), - DSI1ESCLK (DSI1 energy save clock), DSI2ESCLK (DSI2 energy - save clock) -- clock-names: must be the following array: - "mcde", "lcd", "hdmi" - to match the required clock inputs above. -- #address-cells: should be <1> (for the DSI hosts that will be children) -- #size-cells: should be <1> (for the DSI hosts that will be children) -- ranges: this should always be stated - -Required subnodes: - -The devicetree must specify subnodes for the DSI host adapters. -These must have the following characteristics: - -- compatible: must be: - "ste,mcde-dsi" -- reg: must specify the register range for the DSI host -- vana-supply: phandle to the VANA voltage regulator -- clocks: phandles to the high speed and low power (energy save) clocks - the high speed clock is not present on the third (dsi2) block, so it - should only have the "lp" clock -- clock-names: "hs" for the high speed clock and "lp" for the low power - (energy save) clock -- #address-cells: should be <1> -- #size-cells: should be <0> - -Display panels and bridges will appear as children on the DSI hosts, and -the displays are connected to the DSI hosts using the common binding -for video transmitter interfaces; see -Documentation/devicetree/bindings/media/video-interfaces.txt - -If a DSI host is unused (not connected) it will have no children defined. - -Example: - -mcde@a0350000 { - compatible = "ste,mcde"; - reg = <0xa0350000 0x1000>; - interrupts = ; - epod-supply = <&db8500_b2r2_mcde_reg>; - vana-supply = <&ab8500_ldo_ana_reg>; - clocks = <&prcmu_clk PRCMU_MCDECLK>, /* Main MCDE clock */ - <&prcmu_clk PRCMU_LCDCLK>, /* LCD clock */ - <&prcmu_clk PRCMU_PLLDSI>; /* HDMI clock */ - clock-names = "mcde", "lcd", "hdmi"; - #address-cells = <1>; - #size-cells = <1>; - ranges; - - dsi0: dsi@a0351000 { - compatible = "ste,mcde-dsi"; - reg = <0xa0351000 0x1000>; - vana-supply = <&ab8500_ldo_ana_reg>; - clocks = <&prcmu_clk PRCMU_DSI0CLK>, <&prcmu_clk PRCMU_DSI0ESCCLK>; - clock-names = "hs", "lp"; - #address-cells = <1>; - #size-cells = <0>; - - panel { - compatible = "samsung,s6d16d0"; - reg = <0>; - vdd1-supply = <&ab8500_ldo_aux1_reg>; - reset-gpios = <&gpio2 1 GPIO_ACTIVE_LOW>; - }; - - }; - dsi1: dsi@a0352000 { - compatible = "ste,mcde-dsi"; - reg = <0xa0352000 0x1000>; - vana-supply = <&ab8500_ldo_ana_reg>; - clocks = <&prcmu_clk PRCMU_DSI1CLK>, <&prcmu_clk PRCMU_DSI1ESCCLK>; - clock-names = "hs", "lp"; - #address-cells = <1>; - #size-cells = <0>; - }; - dsi2: dsi@a0353000 { - compatible = "ste,mcde-dsi"; - reg = <0xa0353000 0x1000>; - vana-supply = <&ab8500_ldo_ana_reg>; - /* This DSI port only has the Low Power / Energy Save clock */ - clocks = <&prcmu_clk PRCMU_DSI2ESCCLK>; - clock-names = "lp"; - #address-cells = <1>; - #size-cells = <0>; - }; -}; diff --git a/Documentation/devicetree/bindings/display/ste,mcde.yaml b/Documentation/devicetree/bindings/display/ste,mcde.yaml new file mode 100644 index 000000000000..830c9b4091cc --- /dev/null +++ b/Documentation/devicetree/bindings/display/ste,mcde.yaml @@ -0,0 +1,169 @@ +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/display/ste,mcde.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: ST-Ericsson Multi Channel Display Engine MCDE + +maintainers: + - Linus Walleij + +properties: + compatible: + const: ste,mcde + + reg: + maxItems: 1 + + interrupts: + maxItems: 1 + + clocks: + description: an array of the MCDE clocks + items: + - description: MCDECLK (main MCDE clock) + - description: LCDCLK (LCD clock) + - description: PLLDSI (HDMI clock) + + clock-names: + items: + - const: mcde + - const: lcd + - const: hdmi + + resets: + maxItems: 1 + + epod-supply: + description: a phandle to the EPOD regulator + + vana-supply: + description: a phandle to the analog voltage regulator + + port: + type: object + description: + A DPI port node with endpoint definitions as defined in + Documentation/devicetree/bindings/media/video-interfaces.txt + + "#address-cells": + const: 1 + + "#size-cells": + const: 1 + + ranges: true + +patternProperties: + "^dsi@[0-9a-f]+$": + description: subnodes for the three DSI host adapters + type: object + allOf: + - $ref: dsi-controller.yaml# + properties: + compatible: + const: ste,mcde-dsi + + reg: + maxItems: 1 + + vana-supply: + description: a phandle to the analog voltage regulator + + clocks: + description: phandles to the high speed and low power (energy save) clocks + the high speed clock is not present on the third (dsi2) block, so it + should only have the "lp" clock + minItems: 1 + maxItems: 2 + + clock-names: + oneOf: + - items: + - const: hs + - const: lp + - items: + - const: lp + + required: + - compatible + - reg + - vana-supply + - clocks + - clock-names + + unevaluatedProperties: false + +required: + - compatible + - reg + - interrupts + - clocks + - clock-names + - epod-supply + - vana-supply + +additionalProperties: false + +examples: + - | + #include + #include + #include + #include + + mcde@a0350000 { + compatible = "ste,mcde"; + reg = <0xa0350000 0x1000>; + interrupts = ; + epod-supply = <&db8500_b2r2_mcde_reg>; + vana-supply = <&ab8500_ldo_ana_reg>; + clocks = <&prcmu_clk PRCMU_MCDECLK>, + <&prcmu_clk PRCMU_LCDCLK>, + <&prcmu_clk PRCMU_PLLDSI>; + clock-names = "mcde", "lcd", "hdmi"; + #address-cells = <1>; + #size-cells = <1>; + ranges; + + dsi0: dsi@a0351000 { + compatible = "ste,mcde-dsi"; + reg = <0xa0351000 0x1000>; + vana-supply = <&ab8500_ldo_ana_reg>; + clocks = <&prcmu_clk PRCMU_DSI0CLK>, <&prcmu_clk PRCMU_DSI0ESCCLK>; + clock-names = "hs", "lp"; + #address-cells = <1>; + #size-cells = <0>; + + panel@0 { + compatible = "samsung,s6d16d0"; + reg = <0>; + vdd1-supply = <&ab8500_ldo_aux1_reg>; + reset-gpios = <&gpio2 1 GPIO_ACTIVE_LOW>; + }; + }; + + dsi1: dsi@a0352000 { + compatible = "ste,mcde-dsi"; + reg = <0xa0352000 0x1000>; + vana-supply = <&ab8500_ldo_ana_reg>; + clocks = <&prcmu_clk PRCMU_DSI1CLK>, <&prcmu_clk PRCMU_DSI1ESCCLK>; + clock-names = "hs", "lp"; + #address-cells = <1>; + #size-cells = <0>; + }; + + dsi2: dsi@a0353000 { + compatible = "ste,mcde-dsi"; + reg = <0xa0353000 0x1000>; + vana-supply = <&ab8500_ldo_ana_reg>; + /* This DSI port only has the Low Power / Energy Save clock */ + clocks = <&prcmu_clk PRCMU_DSI2ESCCLK>; + clock-names = "lp"; + #address-cells = <1>; + #size-cells = <0>; + }; + }; + +... -- cgit v1.2.3 From 00aedfa4592d93ed7a6d54ffa7f5e22efb9d9147 Mon Sep 17 00:00:00 2001 From: Dave Stevenson Date: Thu, 3 Dec 2020 14:25:41 +0100 Subject: dt-bindings: Add compatible for BCM2711 DSI1 DSI1 on BCM2711 doesn't require the DMA workaround that is used on BCM2835/6/7, therefore it needs a new compatible string. Signed-off-by: Dave Stevenson Signed-off-by: Maxime Ripard Link: https://patchwork.freedesktop.org/patch/msgid/20201203132543.861591-7-maxime@cerno.tech --- Documentation/devicetree/bindings/display/brcm,bcm2835-dsi0.yaml | 1 + 1 file changed, 1 insertion(+) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/display/brcm,bcm2835-dsi0.yaml b/Documentation/devicetree/bindings/display/brcm,bcm2835-dsi0.yaml index eb44e072b6e5..55c60919991f 100644 --- a/Documentation/devicetree/bindings/display/brcm,bcm2835-dsi0.yaml +++ b/Documentation/devicetree/bindings/display/brcm,bcm2835-dsi0.yaml @@ -18,6 +18,7 @@ properties: compatible: enum: + - brcm,bcm2711-dsi1 - brcm,bcm2835-dsi0 - brcm,bcm2835-dsi1 -- cgit v1.2.3 From 98cda4b5f246c86ddbd7c4c084a15829da6c8f81 Mon Sep 17 00:00:00 2001 From: Neil Armstrong Date: Fri, 4 Dec 2020 09:19:48 +0100 Subject: dt-bindings: panel-simple-dsi: add Khadas TS050 panel bindings This add the bindings for the Khadas TS050 1080x1920 5" LCD DSI panel designed to work with the Khadas Edge-V, Captain, VIM3 and VIM3L Single Board Computers. Signed-off-by: Neil Armstrong Reviewed-by: Sam Ravnborg Link: https://patchwork.freedesktop.org/patch/msgid/20201204081949.38418-2-narmstrong@baylibre.com --- Documentation/devicetree/bindings/display/panel/panel-simple-dsi.yaml | 2 ++ 1 file changed, 2 insertions(+) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/display/panel/panel-simple-dsi.yaml b/Documentation/devicetree/bindings/display/panel/panel-simple-dsi.yaml index 72e4b6d4d5e1..fbd71669248f 100644 --- a/Documentation/devicetree/bindings/display/panel/panel-simple-dsi.yaml +++ b/Documentation/devicetree/bindings/display/panel/panel-simple-dsi.yaml @@ -35,6 +35,8 @@ properties: - boe,tv080wum-nl0 # Innolux P079ZCA 7.85" 768x1024 TFT LCD panel - innolux,p079zca + # Khadas TS050 5" 1080x1920 LCD panel + - khadas,ts050 # Kingdisplay KD097D04 9.7" 1536x2048 TFT LCD panel - kingdisplay,kd097d04 # LG ACX467AKM-7 4.95" 1080×1920 LCD Panel -- cgit v1.2.3 From 2ff3eaa551551426013ab651d54455901a534245 Mon Sep 17 00:00:00 2001 From: Guido Günther Date: Wed, 18 Nov 2020 09:29:52 +0100 Subject: dt-bindings: vendor-prefixes: Add ys vendor prefix MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add prefix for Shenzhen Yashi Changhua Intelligent Technology Co., Ltd. Signed-off-by: Guido Günther Reviewed-by: Linus Walleij Reviewed-by: Sam Ravnborg Acked-by: Rob Herring Link: https://patchwork.freedesktop.org/patch/msgid/efa9b6da947e0cd87ec47c1a211690045304989b.1605688147.git.agx@sigxcpu.org --- Documentation/devicetree/bindings/vendor-prefixes.yaml | 2 ++ 1 file changed, 2 insertions(+) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/vendor-prefixes.yaml b/Documentation/devicetree/bindings/vendor-prefixes.yaml index e40ee369f808..fbcba08450c5 100644 --- a/Documentation/devicetree/bindings/vendor-prefixes.yaml +++ b/Documentation/devicetree/bindings/vendor-prefixes.yaml @@ -1222,6 +1222,8 @@ patternProperties: description: YSH & ATIL "^yones-toptech,.*": description: Yones Toptech Co., Ltd. + "^ys,.*": + description: Shenzhen Yashi Changhua Intelligent Technology Co., Ltd. "^ysoft,.*": description: Y Soft Corporation a.s. "^zealz,.*": -- cgit v1.2.3 From 75c66a03dfce9db61cbc4764e14fc6bb7c7d40d9 Mon Sep 17 00:00:00 2001 From: Guido Günther Date: Wed, 18 Nov 2020 09:29:53 +0100 Subject: dt-bindings: display: mantix: Add compatible for panel from YS MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This panel from Shenzhen Yashi Changhua Intelligent Technology Co uses the same driver IC but a different LCD. Signed-off-by: Guido Günther Reviewed-by: Linus Walleij Reviewed-by: Sam Ravnborg Acked-by: Rob Herring Link: https://patchwork.freedesktop.org/patch/msgid/eb2a0e50cbb8cfebc27d259607e543fedb8c6b27.1605688147.git.agx@sigxcpu.org --- .../devicetree/bindings/display/panel/mantix,mlaf057we51-x.yaml | 1 + 1 file changed, 1 insertion(+) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/display/panel/mantix,mlaf057we51-x.yaml b/Documentation/devicetree/bindings/display/panel/mantix,mlaf057we51-x.yaml index 51f423297ec8..9e78f2e60f99 100644 --- a/Documentation/devicetree/bindings/display/panel/mantix,mlaf057we51-x.yaml +++ b/Documentation/devicetree/bindings/display/panel/mantix,mlaf057we51-x.yaml @@ -20,6 +20,7 @@ properties: compatible: enum: - mantix,mlaf057we51-x + - ys,ys57pss36bh5gq port: true reg: -- cgit v1.2.3 From a46c112512dec510f78c7613fd0895f09bf3e728 Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Mon, 30 Nov 2020 13:29:18 +0200 Subject: dt-bindings: dp-connector: add binding for DisplayPort connector Add binding for DisplayPort connector. A few notes: * Similar to hdmi-connector, it has hpd-gpios as an optional property, as the HPD could also be handled by, e.g., the DP bridge. * dp-pwr-supply, which provides 3.3V on DP_PWR pin, is optional, as it is not strictly required: standard DP cables do not even have the pin connected. * Connector type. Full size and mini connectors are identical except for the connector size and form, so I believe there is no functional need for this property. But similar to 'label' property, it might be used to present information about the connector to the userspace. * No eDP. There's really no "eDP connector", as it's always a custom made connection between the DP and the DP panel, although the eDP spec does offer a few suggested pin setups. So possibly there is no need for edp-connector binding, but even if there is, I don't want to guess what it could look like, and could it be part of the dp-connector binding. * No DP++. I'm not familiar with DP++. DP++ might need an i2c bus added to the bindings. Signed-off-by: Tomi Valkeinen Reviewed-by: Laurent Pinchart Reviewed-by: Rob Herring Link: https://patchwork.freedesktop.org/patch/msgid/20201130112919.241054-2-tomi.valkeinen@ti.com --- .../bindings/display/connector/dp-connector.yaml | 56 ++++++++++++++++++++++ 1 file changed, 56 insertions(+) create mode 100644 Documentation/devicetree/bindings/display/connector/dp-connector.yaml (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/display/connector/dp-connector.yaml b/Documentation/devicetree/bindings/display/connector/dp-connector.yaml new file mode 100644 index 000000000000..1c17d60e7760 --- /dev/null +++ b/Documentation/devicetree/bindings/display/connector/dp-connector.yaml @@ -0,0 +1,56 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/display/connector/dp-connector.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: DisplayPort Connector + +maintainers: + - Tomi Valkeinen + +properties: + compatible: + const: dp-connector + + label: true + + type: + enum: + - full-size + - mini + + hpd-gpios: + description: A GPIO line connected to HPD + maxItems: 1 + + dp-pwr-supply: + description: Power supply for the DP_PWR pin + maxItems: 1 + + port: + $ref: /schemas/graph.yaml#/properties/port + description: Connection to controller providing DP signals + +required: + - compatible + - type + - port + +additionalProperties: false + +examples: + - | + connector { + compatible = "dp-connector"; + label = "dp0"; + type = "full-size"; + + port { + dp_connector_in: endpoint { + remote-endpoint = <&dp_out>; + }; + }; + }; + +... -- cgit v1.2.3 From 63ade1043457bf800b68045dfee2cfc75625398d Mon Sep 17 00:00:00 2001 From: Sumera Priyadarsini Date: Thu, 10 Dec 2020 00:34:53 +0530 Subject: drm/vkms: Add setup and testing information Update the vkms documentation to contain steps to: - setup the vkms driver - run tests using igt Signed-off-by: Sumera Priyadarsini Reviewed-by: Daniel Vetter Signed-off-by: Melissa Wen Link: https://patchwork.freedesktop.org/patch/msgid/20201209190453.c6kp5winikr55n3i@adolin --- Documentation/gpu/vkms.rst | 70 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 70 insertions(+) (limited to 'Documentation') diff --git a/Documentation/gpu/vkms.rst b/Documentation/gpu/vkms.rst index 13bab1d93bb3..9e030c74a82e 100644 --- a/Documentation/gpu/vkms.rst +++ b/Documentation/gpu/vkms.rst @@ -7,6 +7,76 @@ .. kernel-doc:: drivers/gpu/drm/vkms/vkms_drv.c :doc: vkms (Virtual Kernel Modesetting) +Setup +===== + +The VKMS driver can be setup with the following steps: + +To check if VKMS is loaded, run:: + + lsmod | grep vkms + +This should list the VKMS driver. If no output is obtained, then +you need to enable and/or load the VKMS driver. +Ensure that the VKMS driver has been set as a loadable module in your +kernel config file. Do:: + + make nconfig + + Go to `Device Drivers> Graphics support` + + Enable `Virtual KMS (EXPERIMENTAL)` + +Compile and build the kernel for the changes to get reflected. +Now, to load the driver, use:: + + sudo modprobe vkms + +On running the lsmod command now, the VKMS driver will appear listed. +You can also observe the driver being loaded in the dmesg logs. + +To disable the driver, use :: + + sudo modprobe -r vkms + +Testing With IGT +================ + +The IGT GPU Tools is a test suite used specifically for debugging and +development of the DRM drivers. +The IGT Tools can be installed from +`here `_ . + +The tests need to be run without a compositor, so you need to switch to text +only mode. You can do this by:: + + sudo systemctl isolate multi-user.target + +To return to graphical mode, do:: + + sudo systemctl isolate graphical.target + +Once you are in text only mode, you can run tests using the --device switch +or IGT_DEVICE variable to specify the device filter for the driver we want +to test. IGT_DEVICE can also be used with the run-test.sh script to run the +tests for a specific driver:: + + sudo ./build/tests/ --device "sys:/sys/devices/platform/vkms" + sudo IGT_DEVICE="sys:/sys/devices/platform/vkms" ./build/tests/ + sudo IGT_DEVICE="sys:/sys/devices/platform/vkms" ./scripts/run-tests.sh -t + +For example, to test the functionality of the writeback library, +we can run the kms_writeback test:: + + sudo ./build/tests/kms_writeback --device "sys:/sys/devices/platform/vkms" + sudo IGT_DEVICE="sys:/sys/devices/platform/vkms" ./build/tests/kms_writeback + sudo IGT_DEVICE="sys:/sys/devices/platform/vkms" ./scripts/run-tests.sh -t kms_writeback + +You can also run subtests if you do not want to run the entire test:: + + sudo ./build/tests/kms_flip --run-subtest basic-plain-flip --device "sys:/sys/devices/platform/vkms" + sudo IGT_DEVICE="sys:/sys/devices/platform/vkms" ./build/tests/kms_flip --run-subtest basic-plain-flip + TODO ==== -- cgit v1.2.3 From 26e08a6da54c575c69a113ab0c41c2890c0d613d Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Fri, 4 Dec 2020 21:02:42 +0100 Subject: dma-buf: Fix kerneldoc formatting I wanted to look up something and noticed the hyperlink doesn't work. While fixing that also noticed a trivial kerneldoc comment typo in the same section, fix that too. Reviewed-by: Michael J. Ruhl Reviewed-by: Simon Ser Signed-off-by: Daniel Vetter Link: https://patchwork.freedesktop.org/patch/msgid/20201204200242.2671481-1-daniel.vetter@ffwll.ch --- Documentation/driver-api/dma-buf.rst | 2 +- include/linux/dma-buf-map.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'Documentation') diff --git a/Documentation/driver-api/dma-buf.rst b/Documentation/driver-api/dma-buf.rst index d6b2a195dbed..a2133d69872c 100644 --- a/Documentation/driver-api/dma-buf.rst +++ b/Documentation/driver-api/dma-buf.rst @@ -190,7 +190,7 @@ DMA Fence uABI/Sync File Indefinite DMA Fences ~~~~~~~~~~~~~~~~~~~~~ -At various times &dma_fence with an indefinite time until dma_fence_wait() +At various times struct dma_fence with an indefinite time until dma_fence_wait() finishes have been proposed. Examples include: * Future fences, used in HWC1 to signal when a buffer isn't used by the display diff --git a/include/linux/dma-buf-map.h b/include/linux/dma-buf-map.h index 583a3a1f9447..278d489e4bdd 100644 --- a/include/linux/dma-buf-map.h +++ b/include/linux/dma-buf-map.h @@ -122,7 +122,7 @@ struct dma_buf_map { /** * DMA_BUF_MAP_INIT_VADDR - Initializes struct dma_buf_map to an address in system memory - * @vaddr: A system-memory address + * @vaddr_: A system-memory address */ #define DMA_BUF_MAP_INIT_VADDR(vaddr_) \ { \ -- cgit v1.2.3 From 3b7bc18b4e5140a1407075f45df55e7a76100472 Mon Sep 17 00:00:00 2001 From: José Roberto de Souza Date: Mon, 14 Dec 2020 10:54:40 -0800 Subject: doc: Fix build of documentation after i915 file rename MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Commit 70a2b431c364 ("drm/i915/gt: Rename lrc.c to execlists_submission.c") renamed intel_lrc.c to intel_execlists_submission.c but forgot to update i915.rst. Fixes: 70a2b431c364 ("drm/i915/gt: Rename lrc.c to execlists_submission.c") Cc: Chris Wilson Signed-off-by: José Roberto de Souza Reviewed-by: Chris Wilson Link: https://patchwork.freedesktop.org/patch/msgid/20201214185440.243537-1-jose.souza@intel.com --- Documentation/gpu/i915.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Documentation') diff --git a/Documentation/gpu/i915.rst b/Documentation/gpu/i915.rst index 20868f3d0123..486c720f3890 100644 --- a/Documentation/gpu/i915.rst +++ b/Documentation/gpu/i915.rst @@ -428,7 +428,7 @@ User Batchbuffer Execution Logical Rings, Logical Ring Contexts and Execlists -------------------------------------------------- -.. kernel-doc:: drivers/gpu/drm/i915/gt/intel_lrc.c +.. kernel-doc:: drivers/gpu/drm/i915/gt/intel_execlists_submission.c :doc: Logical Rings, Logical Ring Contexts and Execlists Global GTT views -- cgit v1.2.3 From e07f001ccc758e98c6f9c001dc9efbd9d30d415d Mon Sep 17 00:00:00 2001 From: Simon Ser Date: Wed, 16 Dec 2020 21:22:15 +0100 Subject: drm/doc: rename FB_DAMAGE_CLIPS section Make it more human-readable. Signed-off-by: Simon Ser Reviewed-by: Daniel Vetter Cc: Pekka Paalanen Link: https://patchwork.freedesktop.org/patch/msgid/20201216202222.48146-2-contact@emersion.fr --- Documentation/gpu/drm-kms.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'Documentation') diff --git a/Documentation/gpu/drm-kms.rst b/Documentation/gpu/drm-kms.rst index 3c5ae4f6dfd2..76cf6acc23a5 100644 --- a/Documentation/gpu/drm-kms.rst +++ b/Documentation/gpu/drm-kms.rst @@ -475,8 +475,8 @@ Plane Composition Properties .. kernel-doc:: drivers/gpu/drm/drm_blend.c :export: -FB_DAMAGE_CLIPS -~~~~~~~~~~~~~~~ +Damage Tracking Properties +-------------------------- .. kernel-doc:: drivers/gpu/drm/drm_damage_helper.c :doc: overview -- cgit v1.2.3 From 9d8f78f6ae7d1337e7ccc1be809579d1815d3344 Mon Sep 17 00:00:00 2001 From: Simon Ser Date: Wed, 16 Dec 2020 21:22:16 +0100 Subject: drm/doc: move composition function docs to new section Move drm_blend.c function reference from the KMS properties section to the plane abstraction section. This makes the KMS properties section more readable for user-space developers. Signed-off-by: Simon Ser Reviewed-by: Daniel Vetter Cc: Pekka Paalanen Link: https://patchwork.freedesktop.org/patch/msgid/20201216202222.48146-3-contact@emersion.fr --- Documentation/gpu/drm-kms.rst | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'Documentation') diff --git a/Documentation/gpu/drm-kms.rst b/Documentation/gpu/drm-kms.rst index 76cf6acc23a5..3f92d4eb224b 100644 --- a/Documentation/gpu/drm-kms.rst +++ b/Documentation/gpu/drm-kms.rst @@ -370,6 +370,12 @@ Plane Functions Reference .. kernel-doc:: drivers/gpu/drm/drm_plane.c :export: +Plane Composition Functions Reference +------------------------------------- + +.. kernel-doc:: drivers/gpu/drm/drm_blend.c + :export: + Display Modes Function Reference ================================ @@ -472,9 +478,6 @@ Plane Composition Properties .. kernel-doc:: drivers/gpu/drm/drm_blend.c :doc: overview -.. kernel-doc:: drivers/gpu/drm/drm_blend.c - :export: - Damage Tracking Properties -------------------------- -- cgit v1.2.3 From 31c558f47497e9bc04aee337ebdfdaea491344a6 Mon Sep 17 00:00:00 2001 From: Simon Ser Date: Wed, 16 Dec 2020 21:22:17 +0100 Subject: drm/doc: move damage tracking functions to new section Move drm_damage_helper function reference from the KMS properties section to the plane abstraction section. This makes the KMS properties section more readable for user-space developers. Signed-off-by: Simon Ser Reviewed-by: Daniel Vetter Cc: Pekka Paalanen Link: https://patchwork.freedesktop.org/patch/msgid/20201216202222.48146-4-contact@emersion.fr --- Documentation/gpu/drm-kms.rst | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) (limited to 'Documentation') diff --git a/Documentation/gpu/drm-kms.rst b/Documentation/gpu/drm-kms.rst index 3f92d4eb224b..e6329e7e638e 100644 --- a/Documentation/gpu/drm-kms.rst +++ b/Documentation/gpu/drm-kms.rst @@ -376,6 +376,15 @@ Plane Composition Functions Reference .. kernel-doc:: drivers/gpu/drm/drm_blend.c :export: +Plane Damage Tracking Functions Reference +----------------------------------------- + +.. kernel-doc:: drivers/gpu/drm/drm_damage_helper.c + :export: + +.. kernel-doc:: include/drm/drm_damage_helper.h + :internal: + Display Modes Function Reference ================================ @@ -484,12 +493,6 @@ Damage Tracking Properties .. kernel-doc:: drivers/gpu/drm/drm_damage_helper.c :doc: overview -.. kernel-doc:: drivers/gpu/drm/drm_damage_helper.c - :export: - -.. kernel-doc:: include/drm/drm_damage_helper.h - :internal: - Color Management Properties --------------------------- -- cgit v1.2.3 From 2189100c94a7647be01de36b5bb2edaeb7befc9c Mon Sep 17 00:00:00 2001 From: Simon Ser Date: Wed, 16 Dec 2020 21:22:18 +0100 Subject: drm/doc: move color management functions under CRTC section Move drm_color_mgmt function reference from the KMS properties section to the CRTC abstraction section. This makes the KMS properties section more readable for user-space developers. Signed-off-by: Simon Ser Reviewed-by: Daniel Vetter Cc: Pekka Paalanen Link: https://patchwork.freedesktop.org/patch/msgid/20201216202222.48146-5-contact@emersion.fr --- Documentation/gpu/drm-kms.rst | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) (limited to 'Documentation') diff --git a/Documentation/gpu/drm-kms.rst b/Documentation/gpu/drm-kms.rst index e6329e7e638e..2f3efb63e5ba 100644 --- a/Documentation/gpu/drm-kms.rst +++ b/Documentation/gpu/drm-kms.rst @@ -319,6 +319,15 @@ CRTC Functions Reference .. kernel-doc:: drivers/gpu/drm/drm_crtc.c :export: +Color Management Functions Reference +------------------------------------ + +.. kernel-doc:: drivers/gpu/drm/drm_color_mgmt.c + :export: + +.. kernel-doc:: include/drm/drm_color_mgmt.h + :internal: + Frame Buffer Abstraction ======================== @@ -499,12 +508,6 @@ Color Management Properties .. kernel-doc:: drivers/gpu/drm/drm_color_mgmt.c :doc: overview -.. kernel-doc:: drivers/gpu/drm/drm_color_mgmt.c - :export: - -.. kernel-doc:: include/drm/drm_color_mgmt.h - :internal: - Tile Group Property ------------------- -- cgit v1.2.3 From 46f9be4c8a7bde68e6f63a61fae4778cf3b61750 Mon Sep 17 00:00:00 2001 From: Simon Ser Date: Thu, 17 Dec 2020 12:32:12 +0100 Subject: drm/doc: the KMS properties section is for user-space devs State that the "KMS Properties" section is mainly for user-space developers. Signed-off-by: Simon Ser Cc: Pekka Paalanen Reviewed-by: Daniel Vetter Link: https://patchwork.freedesktop.org/patch/msgid/20201217113220.102271-2-contact@emersion.fr --- Documentation/gpu/drm-kms.rst | 3 +++ 1 file changed, 3 insertions(+) (limited to 'Documentation') diff --git a/Documentation/gpu/drm-kms.rst b/Documentation/gpu/drm-kms.rst index 2f3efb63e5ba..7a05601f1067 100644 --- a/Documentation/gpu/drm-kms.rst +++ b/Documentation/gpu/drm-kms.rst @@ -460,6 +460,9 @@ KMS Locking KMS Properties ============== +This section of the documentation is primarily aimed at user-space developers. +For the driver APIs, see the other sections. + Property Types and Blob Property Support ---------------------------------------- -- cgit v1.2.3 From 77a71abbdd77a32245f47bb1418ef8f05f905154 Mon Sep 17 00:00:00 2001 From: Simon Ser Date: Thu, 17 Dec 2020 12:32:13 +0100 Subject: drm/doc: introduce new section for standard plane properties Introduce a new "Standard Plane Properties" section for properties defined in drm_plane.c. Move the mis-placed IN_FORMATS docs there. Signed-off-by: Simon Ser Reviewed-by: Daniel Vetter Cc: Pekka Paalanen Link: https://patchwork.freedesktop.org/patch/msgid/20201217113220.102271-3-contact@emersion.fr --- Documentation/gpu/drm-kms.rst | 6 ++++++ drivers/gpu/drm/drm_blend.c | 6 ------ drivers/gpu/drm/drm_plane.c | 12 ++++++++++++ 3 files changed, 18 insertions(+), 6 deletions(-) (limited to 'Documentation') diff --git a/Documentation/gpu/drm-kms.rst b/Documentation/gpu/drm-kms.rst index 7a05601f1067..87e5023e3f55 100644 --- a/Documentation/gpu/drm-kms.rst +++ b/Documentation/gpu/drm-kms.rst @@ -493,6 +493,12 @@ Standard CRTC Properties .. kernel-doc:: drivers/gpu/drm/drm_crtc.c :doc: standard CRTC properties +Standard Plane Properties +------------------------- + +.. kernel-doc:: drivers/gpu/drm/drm_plane.c + :doc: standard plane properties + Plane Composition Properties ---------------------------- diff --git a/drivers/gpu/drm/drm_blend.c b/drivers/gpu/drm/drm_blend.c index 5c2141e9a9f4..26e2f2ffd255 100644 --- a/drivers/gpu/drm/drm_blend.c +++ b/drivers/gpu/drm/drm_blend.c @@ -185,12 +185,6 @@ * plane does not expose the "alpha" property, then this is * assumed to be 1.0 * - * IN_FORMATS: - * Blob property which contains the set of buffer format and modifier - * pairs supported by this plane. The blob is a drm_format_modifier_blob - * struct. Without this property the plane doesn't support buffers with - * modifiers. Userspace cannot change this property. - * * Note that all the property extensions described here apply either to the * plane or the CRTC (e.g. for the background color, which currently is not * exposed and assumed to be black). diff --git a/drivers/gpu/drm/drm_plane.c b/drivers/gpu/drm/drm_plane.c index 49b0a8b9ac02..4c1a45ac18e6 100644 --- a/drivers/gpu/drm/drm_plane.c +++ b/drivers/gpu/drm/drm_plane.c @@ -61,6 +61,18 @@ * userspace too much. */ +/** + * DOC: standard plane properties + * + * DRM planes have a few standardized properties: + * + * IN_FORMATS: + * Blob property which contains the set of buffer format and modifier + * pairs supported by this plane. The blob is a drm_format_modifier_blob + * struct. Without this property the plane doesn't support buffers with + * modifiers. Userspace cannot change this property. + */ + static unsigned int drm_num_planes(struct drm_device *dev) { unsigned int num = 0; -- cgit v1.2.3 From f5ad1c747956d501516610ee7900f4a6d57ee2f5 Mon Sep 17 00:00:00 2001 From: Daniel Lezcano Date: Tue, 8 Dec 2020 17:41:43 +0100 Subject: Documentation/powercap/dtpm: Add documentation for dtpm The dynamic thermal and power management is a technique to dynamically adjust the power consumption of different devices in order to ensure a global thermal constraint. An userspace daemon is usually monitoring the temperature and the power to take immediate action on the device. The DTPM framework provides an unified API to userspace to act on the power. Document this framework. Signed-off-by: Daniel Lezcano Reviewed-by: Lukasz Luba Signed-off-by: Rafael J. Wysocki --- Documentation/power/index.rst | 1 + Documentation/power/powercap/dtpm.rst | 212 ++++++++++++++++++++++++++++++++++ 2 files changed, 213 insertions(+) create mode 100644 Documentation/power/powercap/dtpm.rst (limited to 'Documentation') diff --git a/Documentation/power/index.rst b/Documentation/power/index.rst index ced8a8007434..a0f5244fb427 100644 --- a/Documentation/power/index.rst +++ b/Documentation/power/index.rst @@ -30,6 +30,7 @@ Power Management userland-swsusp powercap/powercap + powercap/dtpm regulator/consumer regulator/design diff --git a/Documentation/power/powercap/dtpm.rst b/Documentation/power/powercap/dtpm.rst new file mode 100644 index 000000000000..a38dee3d815b --- /dev/null +++ b/Documentation/power/powercap/dtpm.rst @@ -0,0 +1,212 @@ +.. SPDX-License-Identifier: GPL-2.0 + +========================================== +Dynamic Thermal Power Management framework +========================================== + +On the embedded world, the complexity of the SoC leads to an +increasing number of hotspots which need to be monitored and mitigated +as a whole in order to prevent the temperature to go above the +normative and legally stated 'skin temperature'. + +Another aspect is to sustain the performance for a given power budget, +for example virtual reality where the user can feel dizziness if the +performance is capped while a big CPU is processing something else. Or +reduce the battery charging because the dissipated power is too high +compared with the power consumed by other devices. + +The user space is the most adequate place to dynamically act on the +different devices by limiting their power given an application +profile: it has the knowledge of the platform. + +The Dynamic Thermal Power Management (DTPM) is a technique acting on +the device power by limiting and/or balancing a power budget among +different devices. + +The DTPM framework provides an unified interface to act on the +device power. + +Overview +======== + +The DTPM framework relies on the powercap framework to create the +powercap entries in the sysfs directory and implement the backend +driver to do the connection with the power manageable device. + +The DTPM is a tree representation describing the power constraints +shared between devices, not their physical positions. + +The nodes of the tree are a virtual description aggregating the power +characteristics of the children nodes and their power limitations. + +The leaves of the tree are the real power manageable devices. + +For instance:: + + SoC + | + `-- pkg + | + |-- pd0 (cpu0-3) + | + `-- pd1 (cpu4-5) + +The pkg power will be the sum of pd0 and pd1 power numbers:: + + SoC (400mW - 3100mW) + | + `-- pkg (400mW - 3100mW) + | + |-- pd0 (100mW - 700mW) + | + `-- pd1 (300mW - 2400mW) + +When the nodes are inserted in the tree, their power characteristics are propagated to the parents:: + + SoC (600mW - 5900mW) + | + |-- pkg (400mW - 3100mW) + | | + | |-- pd0 (100mW - 700mW) + | | + | `-- pd1 (300mW - 2400mW) + | + `-- pd2 (200mW - 2800mW) + +Each node have a weight on a 2^10 basis reflecting the percentage of power consumption along the siblings:: + + SoC (w=1024) + | + |-- pkg (w=538) + | | + | |-- pd0 (w=231) + | | + | `-- pd1 (w=794) + | + `-- pd2 (w=486) + + Note the sum of weights at the same level are equal to 1024. + +When a power limitation is applied to a node, then it is distributed along the children given their weights. For example, if we set a power limitation of 3200mW at the 'SoC' root node, the resulting tree will be:: + + SoC (w=1024) <--- power_limit = 3200mW + | + |-- pkg (w=538) --> power_limit = 1681mW + | | + | |-- pd0 (w=231) --> power_limit = 378mW + | | + | `-- pd1 (w=794) --> power_limit = 1303mW + | + `-- pd2 (w=486) --> power_limit = 1519mW + + +Flat description +---------------- + +A root node is created and it is the parent of all the nodes. This +description is the simplest one and it is supposed to give to user +space a flat representation of all the devices supporting the power +limitation without any power limitation distribution. + +Hierarchical description +------------------------ + +The different devices supporting the power limitation are represented +hierarchically. There is one root node, all intermediate nodes are +grouping the child nodes which can be intermediate nodes also or real +devices. + +The intermediate nodes aggregate the power information and allows to +set the power limit given the weight of the nodes. + +User space API +============== + +As stated in the overview, the DTPM framework is built on top of the +powercap framework. Thus the sysfs interface is the same, please refer +to the powercap documentation for further details. + + * power_uw: Instantaneous power consumption. If the node is an + intermediate node, then the power consumption will be the sum of all + children power consumption. + + * max_power_range_uw: The power range resulting of the maximum power + minus the minimum power. + + * name: The name of the node. This is implementation dependent. Even + if it is not recommended for the user space, several nodes can have + the same name. + + * constraint_X_name: The name of the constraint. + + * constraint_X_max_power_uw: The maximum power limit to be applicable + to the node. + + * constraint_X_power_limit_uw: The power limit to be applied to the + node. If the value contained in constraint_X_max_power_uw is set, + the constraint will be removed. + + * constraint_X_time_window_us: The meaning of this file will depend + on the constraint number. + +Constraints +----------- + + * Constraint 0: The power limitation is immediately applied, without + limitation in time. + +Kernel API +========== + +Overview +-------- + +The DTPM framework has no power limiting backend support. It is +generic and provides a set of API to let the different drivers to +implement the backend part for the power limitation and create the +power constraints tree. + +It is up to the platform to provide the initialization function to +allocate and link the different nodes of the tree. + +A special macro has the role of declaring a node and the corresponding +initialization function via a description structure. This one contains +an optional parent field allowing to hook different devices to an +already existing tree at boot time. + +For instance:: + + struct dtpm_descr my_descr = { + .name = "my_name", + .init = my_init_func, + }; + + DTPM_DECLARE(my_descr); + +The nodes of the DTPM tree are described with dtpm structure. The +steps to add a new power limitable device is done in three steps: + + * Allocate the dtpm node + * Set the power number of the dtpm node + * Register the dtpm node + +The registration of the dtpm node is done with the powercap +ops. Basically, it must implements the callbacks to get and set the +power and the limit. + +Alternatively, if the node to be inserted is an intermediate one, then +a simple function to insert it as a future parent is available. + +If a device has its power characteristics changing, then the tree must +be updated with the new power numbers and weights. + +Nomenclature +------------ + + * dtpm_alloc() : Allocate and initialize a dtpm structure + + * dtpm_register() : Add the dtpm node to the tree + + * dtpm_unregister() : Remove the dtpm node from the tree + + * dtpm_update_power() : Update the power characteristics of the dtpm node -- cgit v1.2.3 From 0d2a7e15d7912aa27dd3366f75d181b5141ca9a2 Mon Sep 17 00:00:00 2001 From: Adam Ford Date: Sun, 13 Dec 2020 12:37:56 -0600 Subject: dt-bindings: arm: renesas: Add Beacon RZ/G2N and RZ/G2H boards Add beacon,beacon-rzg2n and beacon,beacon-rzg2h to the bindings list. Signed-off-by: Adam Ford Acked-by: Rob Herring Link: https://lore.kernel.org/r/20201213183759.223246-17-aford173@gmail.com Signed-off-by: Geert Uytterhoeven --- Documentation/devicetree/bindings/arm/renesas.yaml | 2 ++ 1 file changed, 2 insertions(+) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/arm/renesas.yaml b/Documentation/devicetree/bindings/arm/renesas.yaml index fe11be65039a..5fd0696a9f91 100644 --- a/Documentation/devicetree/bindings/arm/renesas.yaml +++ b/Documentation/devicetree/bindings/arm/renesas.yaml @@ -130,6 +130,7 @@ properties: - description: RZ/G2N (R8A774B1) items: - enum: + - beacon,beacon-rzg2n # Beacon EmbeddedWorks RZ/G2N Kit - hoperun,hihope-rzg2n # HopeRun HiHope RZ/G2N platform - const: renesas,r8a774b1 @@ -154,6 +155,7 @@ properties: - description: RZ/G2H (R8A774E1) items: - enum: + - beacon,beacon-rzg2h # Beacon EmbeddedWorks RZ/G2H Kit - hoperun,hihope-rzg2h # HopeRun HiHope RZ/G2H platform - const: renesas,r8a774e1 -- cgit v1.2.3 From 934b05e818620e922151734b2d0e070e388e3c53 Mon Sep 17 00:00:00 2001 From: ChiYuan Huang Date: Thu, 17 Dec 2020 23:00:41 +0800 Subject: regulator: rt4831: Adds DT binding document for Richtek RT4831 DSV regulator Adds DT binding document for Richtek RT4831 DSV regulator. Signed-off-by: ChiYuan Huang Link: https://lore.kernel.org/r/1608217244-314-3-git-send-email-u0084500@gmail.com Signed-off-by: Mark Brown --- .../regulator/richtek,rt4831-regulator.yaml | 35 ++++++++++++++++++++++ 1 file changed, 35 insertions(+) create mode 100644 Documentation/devicetree/bindings/regulator/richtek,rt4831-regulator.yaml (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/regulator/richtek,rt4831-regulator.yaml b/Documentation/devicetree/bindings/regulator/richtek,rt4831-regulator.yaml new file mode 100644 index 000000000000..d9c23333e157 --- /dev/null +++ b/Documentation/devicetree/bindings/regulator/richtek,rt4831-regulator.yaml @@ -0,0 +1,35 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/regulator/richtek,rt4831-regulator.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Richtek RT4831 Display Bias Voltage Regulator + +maintainers: + - ChiYuan Huang + +description: | + RT4831 is a multifunctional device that can provide power to the LCD display + and LCD backlight. + + For Display Bias Voltage DSVP and DSVN, the output range is about 4V to 6.5V. + It is sufficient to meet the current LCD power requirement. + + DSVLCM is a boost regulator in IC internal as DSVP and DSVN input power. + Its voltage should be configured above 0.15V to 0.2V gap larger than the + voltage needed for DSVP and DSVN. Too much voltage gap could improve the + voltage drop from the heavy loading scenario. But it also make the power + efficiency worse. It's a trade-off. + + Datasheet is available at + https://www.richtek.com/assets/product_file/RT4831A/DS4831A-05.pdf + +patternProperties: + "^DSV(LCM|P|N)$": + type: object + $ref: regulator.yaml# + description: + Properties for single Display Bias Voltage regulator. + +additionalProperties: false -- cgit v1.2.3 From ffe9819b6766b9a623822f3427df4953ab448127 Mon Sep 17 00:00:00 2001 From: Alexandru Ardelean Date: Mon, 21 Dec 2020 17:29:36 +0200 Subject: spi: dt-bindings: document zero value for spi-{rx,tx}-bus-width properties Following a change to the SPI framework, providing a value of zero for 'spi-rx-bus-width' and 'spi-tx-bus-width' is now possible and will essentially mean that no RX or TX is allowed. Reviewed-by: Rob Herring Signed-off-by: Alexandru Ardelean Link: https://lore.kernel.org/r/20201221152936.53873-3-alexandru.ardelean@analog.com Signed-off-by: Mark Brown --- Documentation/devicetree/bindings/spi/spi-controller.yaml | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/spi/spi-controller.yaml b/Documentation/devicetree/bindings/spi/spi-controller.yaml index 5f505810104d..06786f1b43d2 100644 --- a/Documentation/devicetree/bindings/spi/spi-controller.yaml +++ b/Documentation/devicetree/bindings/spi/spi-controller.yaml @@ -152,8 +152,9 @@ patternProperties: spi-rx-bus-width: description: Bus width to the SPI bus used for read transfers. + If 0 is provided, then no RX will be possible on this device. $ref: /schemas/types.yaml#/definitions/uint32 - enum: [1, 2, 4, 8] + enum: [0, 1, 2, 4, 8] default: 1 spi-rx-delay-us: @@ -163,8 +164,9 @@ patternProperties: spi-tx-bus-width: description: Bus width to the SPI bus used for write transfers. + If 0 is provided, then no TX will be possible on this device. $ref: /schemas/types.yaml#/definitions/uint32 - enum: [1, 2, 4, 8] + enum: [0, 1, 2, 4, 8] default: 1 spi-tx-delay-us: -- cgit v1.2.3 From f426c3b1d66fb76ad11ef097e840c0eb32b7f9be Mon Sep 17 00:00:00 2001 From: Manivannan Sadhasivam Date: Mon, 30 Nov 2020 15:09:21 +0530 Subject: dt-bindings: msm: Add LLCC for SM8250 Add LLCC compatible for SM8250 SoC. Signed-off-by: Manivannan Sadhasivam Link: https://lore.kernel.org/r/20201130093924.45057-2-manivannan.sadhasivam@linaro.org Signed-off-by: Bjorn Andersson --- Documentation/devicetree/bindings/arm/msm/qcom,llcc.yaml | 1 + 1 file changed, 1 insertion(+) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/arm/msm/qcom,llcc.yaml b/Documentation/devicetree/bindings/arm/msm/qcom,llcc.yaml index 0a9889debc7c..c299dc907f6c 100644 --- a/Documentation/devicetree/bindings/arm/msm/qcom,llcc.yaml +++ b/Documentation/devicetree/bindings/arm/msm/qcom,llcc.yaml @@ -24,6 +24,7 @@ properties: - qcom,sc7180-llcc - qcom,sdm845-llcc - qcom,sm8150-llcc + - qcom,sm8250-llcc reg: items: -- cgit v1.2.3 From e2b0330c5a20baa4ab55553c60412c367d179e7b Mon Sep 17 00:00:00 2001 From: Dmitry Baryshkov Date: Tue, 15 Dec 2020 13:45:37 +0300 Subject: dt-bindings: soc: qcom: convert qcom,smem bindings to yaml Convert soc/qcom/qcom,smem.txt bindings to YAML format. Reviewed-by: Bjorn Andersson Reviewed-by: Rob Herring Signed-off-by: Dmitry Baryshkov Link: https://lore.kernel.org/r/20201215104537.768914-1-dmitry.baryshkov@linaro.org Signed-off-by: Bjorn Andersson --- .../devicetree/bindings/soc/qcom/qcom,smem.txt | 57 ----------------- .../devicetree/bindings/soc/qcom/qcom,smem.yaml | 72 ++++++++++++++++++++++ 2 files changed, 72 insertions(+), 57 deletions(-) delete mode 100644 Documentation/devicetree/bindings/soc/qcom/qcom,smem.txt create mode 100644 Documentation/devicetree/bindings/soc/qcom/qcom,smem.yaml (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/soc/qcom/qcom,smem.txt b/Documentation/devicetree/bindings/soc/qcom/qcom,smem.txt deleted file mode 100644 index 9326cdf6e1b1..000000000000 --- a/Documentation/devicetree/bindings/soc/qcom/qcom,smem.txt +++ /dev/null @@ -1,57 +0,0 @@ -Qualcomm Shared Memory Manager binding - -This binding describes the Qualcomm Shared Memory Manager, used to share data -between various subsystems and OSes in Qualcomm platforms. - -- compatible: - Usage: required - Value type: - Definition: must be: - "qcom,smem" - -- memory-region: - Usage: required - Value type: - Definition: handle to memory reservation for main SMEM memory region. - -- qcom,rpm-msg-ram: - Usage: required - Value type: - Definition: handle to RPM message memory resource - -- hwlocks: - Usage: required - Value type: - Definition: reference to a hwspinlock used to protect allocations from - the shared memory - -= EXAMPLE -The following example shows the SMEM setup for MSM8974, with a main SMEM region -at 0xfa00000 and the RPM message ram at 0xfc428000: - - reserved-memory { - #address-cells = <1>; - #size-cells = <1>; - ranges; - - smem_region: smem@fa00000 { - reg = <0xfa00000 0x200000>; - no-map; - }; - }; - - smem@fa00000 { - compatible = "qcom,smem"; - - memory-region = <&smem_region>; - qcom,rpm-msg-ram = <&rpm_msg_ram>; - - hwlocks = <&tcsr_mutex 3>; - }; - - soc { - rpm_msg_ram: memory@fc428000 { - compatible = "qcom,rpm-msg-ram"; - reg = <0xfc428000 0x4000>; - }; - }; diff --git a/Documentation/devicetree/bindings/soc/qcom/qcom,smem.yaml b/Documentation/devicetree/bindings/soc/qcom/qcom,smem.yaml new file mode 100644 index 000000000000..f7e17713b3d8 --- /dev/null +++ b/Documentation/devicetree/bindings/soc/qcom/qcom,smem.yaml @@ -0,0 +1,72 @@ +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) +%YAML 1.2 +--- +$id: "http://devicetree.org/schemas/soc/qcom/qcom,smem.yaml#" +$schema: "http://devicetree.org/meta-schemas/core.yaml#" + +title: Qualcomm Shared Memory Manager binding + +maintainers: + - Andy Gross + - Bjorn Andersson + +description: | + This binding describes the Qualcomm Shared Memory Manager, used to share data + between various subsystems and OSes in Qualcomm platforms. + +properties: + compatible: + const: qcom,smem + + memory-region: + maxItems: 1 + description: handle to memory reservation for main SMEM memory region. + + hwlocks: + maxItems: 1 + + qcom,rpm-msg-ram: + $ref: /schemas/types.yaml#/definitions/phandle + description: handle to RPM message memory resource + +required: + - compatible + - memory-region + - hwlocks + +additionalProperties: false + +examples: + - | + reserved-memory { + #address-cells = <1>; + #size-cells = <1>; + ranges; + + smem_region: smem@fa00000 { + reg = <0xfa00000 0x200000>; + no-map; + }; + }; + + smem { + compatible = "qcom,smem"; + + memory-region = <&smem_region>; + qcom,rpm-msg-ram = <&rpm_msg_ram>; + + hwlocks = <&tcsr_mutex 3>; + }; + + soc { + #address-cells = <1>; + #size-cells = <1>; + ranges; + + rpm_msg_ram: sram@fc428000 { + compatible = "qcom,rpm-msg-ram"; + reg = <0xfc428000 0x4000>; + }; + }; + +... -- cgit v1.2.3 From abe533d9d422b101f4a08a8741ac01a7dc1e83bf Mon Sep 17 00:00:00 2001 From: Rafał Miłecki Date: Tue, 8 Dec 2020 08:03:03 +0100 Subject: dt-bindings: arm: bcm: document Netgear R8000P binding MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit It's a BCM4906 based device. Signed-off-by: Rafał Miłecki Acked-by: Rob Herring Signed-off-by: Florian Fainelli --- Documentation/devicetree/bindings/arm/bcm/brcm,bcm4908.yaml | 2 ++ 1 file changed, 2 insertions(+) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/arm/bcm/brcm,bcm4908.yaml b/Documentation/devicetree/bindings/arm/bcm/brcm,bcm4908.yaml index 5fec063d9a13..e55731f43c84 100644 --- a/Documentation/devicetree/bindings/arm/bcm/brcm,bcm4908.yaml +++ b/Documentation/devicetree/bindings/arm/bcm/brcm,bcm4908.yaml @@ -19,6 +19,8 @@ properties: oneOf: - description: BCM4906 based boards items: + - enum: + - netgear,r8000p - const: brcm,bcm4906 - const: brcm,bcm4908 -- cgit v1.2.3 From 8e0cbf356377fabac47a027dd176cd1cacc5fc01 Mon Sep 17 00:00:00 2001 From: Mark Pearson Date: Tue, 29 Dec 2020 19:18:25 -0500 Subject: Documentation: Add documentation for new platform_profile sysfs attribute On modern systems the platform performance, temperature, fan and other hardware related characteristics are often dynamically configurable. The profile is often automatically adjusted to the load by some automatic-mechanism (which may very well live outside the kernel). These auto platform-adjustment mechanisms often can be configured with one of several 'platform-profiles', with either a bias towards low-power consumption or towards performance (and higher power consumption and thermals). Introduce a new platform_profile sysfs API which offers a generic API for selecting the performance-profile of these automatic-mechanisms. Co-developed-by: Hans de Goede Signed-off-by: Mark Pearson Signed-off-by: Hans de Goede Signed-off-by: Rafael J. Wysocki --- Documentation/ABI/testing/sysfs-platform_profile | 24 +++++++++++++ Documentation/userspace-api/index.rst | 1 + .../userspace-api/sysfs-platform_profile.rst | 42 ++++++++++++++++++++++ 3 files changed, 67 insertions(+) create mode 100644 Documentation/ABI/testing/sysfs-platform_profile create mode 100644 Documentation/userspace-api/sysfs-platform_profile.rst (limited to 'Documentation') diff --git a/Documentation/ABI/testing/sysfs-platform_profile b/Documentation/ABI/testing/sysfs-platform_profile new file mode 100644 index 000000000000..9d6b89b66cca --- /dev/null +++ b/Documentation/ABI/testing/sysfs-platform_profile @@ -0,0 +1,24 @@ +What: /sys/firmware/acpi/platform_profile_choices +Date: October 2020 +Contact: Hans de Goede +Description: This file contains a space-separated list of profiles supported for this device. + + Drivers must use the following standard profile-names: + + ============ ============================================ + low-power Low power consumption + cool Cooler operation + quiet Quieter operation + balanced Balance between low power consumption and performance + performance High performance operation + ============ ============================================ + + Userspace may expect drivers to offer more than one of these + standard profile names. + +What: /sys/firmware/acpi/platform_profile +Date: October 2020 +Contact: Hans de Goede +Description: Reading this file gives the current selected profile for this + device. Writing this file with one of the strings from + platform_profile_choices changes the profile to the new value. diff --git a/Documentation/userspace-api/index.rst b/Documentation/userspace-api/index.rst index acd2cc2a538d..d29b020e5622 100644 --- a/Documentation/userspace-api/index.rst +++ b/Documentation/userspace-api/index.rst @@ -24,6 +24,7 @@ place where this information is gathered. ioctl/index iommu media/index + sysfs-platform_profile .. only:: subproject and html diff --git a/Documentation/userspace-api/sysfs-platform_profile.rst b/Documentation/userspace-api/sysfs-platform_profile.rst new file mode 100644 index 000000000000..c33a71263d9e --- /dev/null +++ b/Documentation/userspace-api/sysfs-platform_profile.rst @@ -0,0 +1,42 @@ +===================================================================== +Platform Profile Selection (e.g. /sys/firmware/acpi/platform_profile) +===================================================================== + +On modern systems the platform performance, temperature, fan and other +hardware related characteristics are often dynamically configurable. The +platform configuration is often automatically adjusted to the current +conditions by some automatic mechanism (which may very well live outside +the kernel). + +These auto platform adjustment mechanisms often can be configured with +one of several platform profiles, with either a bias towards low power +operation or towards performance. + +The purpose of the platform_profile attribute is to offer a generic sysfs +API for selecting the platform profile of these automatic mechanisms. + +Note that this API is only for selecting the platform profile, it is +NOT a goal of this API to allow monitoring the resulting performance +characteristics. Monitoring performance is best done with device/vendor +specific tools such as e.g. turbostat. + +Specifically when selecting a high performance profile the actual achieved +performance may be limited by various factors such as: the heat generated +by other components, room temperature, free air flow at the bottom of a +laptop, etc. It is explicitly NOT a goal of this API to let userspace know +about any sub-optimal conditions which are impeding reaching the requested +performance level. + +Since numbers on their own cannot represent the multiple variables that a +profile will adjust (power consumption, heat generation, etc) this API +uses strings to describe the various profiles. To make sure that userspace +gets a consistent experience the sysfs-platform_profile ABI document defines +a fixed set of profile names. Drivers *must* map their internal profile +representation onto this fixed set. + +If there is no good match when mapping then a new profile name may be +added. Drivers which wish to introduce new profile names must: + + 1. Explain why the existing profile names canot be used. + 2. Add the new profile name, along with a clear description of the + expected behaviour, to the sysfs-platform_profile ABI documentation. -- cgit v1.2.3 From 7193542331435f63010d9d1bbe05405c5398aed3 Mon Sep 17 00:00:00 2001 From: Vinod Koul Date: Thu, 26 Nov 2020 14:01:37 +0530 Subject: dt-bindings: arm: qcom: Document SDX55 platform and boards Document the SDX55 platform binding and also the boards using it. Reviewed-by: Rob Herring Signed-off-by: Vinod Koul Signed-off-by: Manivannan Sadhasivam Link: https://lore.kernel.org/r/20201126083138.47047-2-manivannan.sadhasivam@linaro.org Signed-off-by: Bjorn Andersson --- Documentation/devicetree/bindings/arm/qcom.yaml | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/arm/qcom.yaml b/Documentation/devicetree/bindings/arm/qcom.yaml index c97d4a580f47..f4af99b5b9af 100644 --- a/Documentation/devicetree/bindings/arm/qcom.yaml +++ b/Documentation/devicetree/bindings/arm/qcom.yaml @@ -40,6 +40,7 @@ description: | sdm630 sdm660 sdm845 + sdx55 sm8250 The 'board' element must be one of the following strings: @@ -167,6 +168,11 @@ properties: - xiaomi,lavender - const: qcom,sdm660 + - items: + - enum: + - qcom,sdx55-mtp + - const: qcom,sdx55 + - items: - enum: - qcom,ipq6018-cp01-c1 -- cgit v1.2.3 From a417178abc4ae2517231ee67a1291d58929fade1 Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Mon, 7 Dec 2020 17:55:20 +0100 Subject: MAINTAINERS: crypto: s5p-sss: drop Kamil Konieczny E-mails to Kamil Konieczny to his Samsung address bounce with 550 (User unknown). Kamil no longer takes care about Samsung S5P SSS driver so remove the invalid email address from: - mailmap, - bindings maintainer entries, - maintainers entry for S5P Security Subsystem crypto accelerator. Signed-off-by: Krzysztof Kozlowski Acked-by: Vladimir Zapolskiy Signed-off-by: Herbert Xu --- .mailmap | 1 - Documentation/devicetree/bindings/crypto/samsung-slimsss.yaml | 1 - Documentation/devicetree/bindings/crypto/samsung-sss.yaml | 1 - MAINTAINERS | 1 - 4 files changed, 4 deletions(-) (limited to 'Documentation') diff --git a/.mailmap b/.mailmap index 632700cee55c..17d50c1f249f 100644 --- a/.mailmap +++ b/.mailmap @@ -174,7 +174,6 @@ Juha Yrjola Juha Yrjola Juha Yrjola Julien Thierry -Kamil Konieczny Kay Sievers Kees Cook Kees Cook diff --git a/Documentation/devicetree/bindings/crypto/samsung-slimsss.yaml b/Documentation/devicetree/bindings/crypto/samsung-slimsss.yaml index 7743eae049ab..676950bb7b37 100644 --- a/Documentation/devicetree/bindings/crypto/samsung-slimsss.yaml +++ b/Documentation/devicetree/bindings/crypto/samsung-slimsss.yaml @@ -8,7 +8,6 @@ title: Samsung Exynos SoC SlimSSS (Slim Security SubSystem) module maintainers: - Krzysztof Kozlowski - - Kamil Konieczny description: |+ The SlimSSS module in Exynos5433 SoC supports the following: diff --git a/Documentation/devicetree/bindings/crypto/samsung-sss.yaml b/Documentation/devicetree/bindings/crypto/samsung-sss.yaml index cf1c47a81d7f..6d62b0e42fc9 100644 --- a/Documentation/devicetree/bindings/crypto/samsung-sss.yaml +++ b/Documentation/devicetree/bindings/crypto/samsung-sss.yaml @@ -8,7 +8,6 @@ title: Samsung Exynos SoC SSS (Security SubSystem) module maintainers: - Krzysztof Kozlowski - - Kamil Konieczny description: |+ The SSS module in S5PV210 SoC supports the following: diff --git a/MAINTAINERS b/MAINTAINERS index 546aa66428c9..aeb3a118842e 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -15689,7 +15689,6 @@ F: drivers/media/i2c/s5k5baf.c SAMSUNG S5P Security SubSystem (SSS) DRIVER M: Krzysztof Kozlowski M: Vladimir Zapolskiy -M: Kamil Konieczny L: linux-crypto@vger.kernel.org L: linux-samsung-soc@vger.kernel.org S: Maintained -- cgit v1.2.3 From 0eb76ba29d16df2951d37c54ca279c4e5630b071 Mon Sep 17 00:00:00 2001 From: Ard Biesheuvel Date: Fri, 11 Dec 2020 13:27:15 +0100 Subject: crypto: remove cipher routines from public crypto API The cipher routines in the crypto API are mostly intended for templates implementing skcipher modes generically in software, and shouldn't be used outside of the crypto subsystem. So move the prototypes and all related definitions to a new header file under include/crypto/internal. Also, let's use the new module namespace feature to move the symbol exports into a new namespace CRYPTO_INTERNAL. Signed-off-by: Ard Biesheuvel Acked-by: Eric Biggers Signed-off-by: Herbert Xu --- Documentation/crypto/api-skcipher.rst | 4 +- arch/arm/crypto/aes-neonbs-glue.c | 3 + arch/s390/crypto/aes_s390.c | 2 + crypto/adiantum.c | 2 + crypto/ansi_cprng.c | 2 + crypto/cbc.c | 1 + crypto/ccm.c | 2 + crypto/cfb.c | 2 + crypto/cipher.c | 7 +- crypto/cmac.c | 2 + crypto/ctr.c | 2 + crypto/drbg.c | 2 + crypto/ecb.c | 1 + crypto/essiv.c | 2 + crypto/keywrap.c | 2 + crypto/ofb.c | 2 + crypto/pcbc.c | 2 + crypto/skcipher.c | 2 + crypto/testmgr.c | 3 + crypto/vmac.c | 2 + crypto/xcbc.c | 2 + crypto/xts.c | 2 + drivers/crypto/geode-aes.c | 2 + drivers/crypto/inside-secure/safexcel.c | 1 + drivers/crypto/inside-secure/safexcel_hash.c | 1 + drivers/crypto/qat/qat_common/adf_ctl_drv.c | 1 + drivers/crypto/qat/qat_common/qat_algs.c | 1 + drivers/crypto/vmx/aes.c | 1 + drivers/crypto/vmx/vmx.c | 1 + include/crypto/algapi.h | 39 ----- include/crypto/internal/cipher.h | 218 +++++++++++++++++++++++++++ include/crypto/internal/skcipher.h | 1 + include/linux/crypto.h | 163 -------------------- 33 files changed, 273 insertions(+), 207 deletions(-) create mode 100644 include/crypto/internal/cipher.h (limited to 'Documentation') diff --git a/Documentation/crypto/api-skcipher.rst b/Documentation/crypto/api-skcipher.rst index 1aaf8985894b..04d6cc5357c8 100644 --- a/Documentation/crypto/api-skcipher.rst +++ b/Documentation/crypto/api-skcipher.rst @@ -28,8 +28,8 @@ Symmetric Key Cipher Request Handle Single Block Cipher API ----------------------- -.. kernel-doc:: include/linux/crypto.h +.. kernel-doc:: include/crypto/internal/cipher.h :doc: Single Block Cipher API -.. kernel-doc:: include/linux/crypto.h +.. kernel-doc:: include/crypto/internal/cipher.h :functions: crypto_alloc_cipher crypto_free_cipher crypto_has_cipher crypto_cipher_blocksize crypto_cipher_setkey crypto_cipher_encrypt_one crypto_cipher_decrypt_one diff --git a/arch/arm/crypto/aes-neonbs-glue.c b/arch/arm/crypto/aes-neonbs-glue.c index f70af1d0514b..5c6cd3c63cbc 100644 --- a/arch/arm/crypto/aes-neonbs-glue.c +++ b/arch/arm/crypto/aes-neonbs-glue.c @@ -9,6 +9,7 @@ #include #include #include +#include #include #include #include @@ -23,6 +24,8 @@ MODULE_ALIAS_CRYPTO("cbc(aes)-all"); MODULE_ALIAS_CRYPTO("ctr(aes)"); MODULE_ALIAS_CRYPTO("xts(aes)"); +MODULE_IMPORT_NS(CRYPTO_INTERNAL); + asmlinkage void aesbs_convert_key(u8 out[], u32 const rk[], int rounds); asmlinkage void aesbs_ecb_encrypt(u8 out[], u8 const in[], u8 const rk[], diff --git a/arch/s390/crypto/aes_s390.c b/arch/s390/crypto/aes_s390.c index 73044634d342..54c7536f2482 100644 --- a/arch/s390/crypto/aes_s390.c +++ b/arch/s390/crypto/aes_s390.c @@ -21,6 +21,7 @@ #include #include #include +#include #include #include #include @@ -1055,3 +1056,4 @@ MODULE_ALIAS_CRYPTO("aes-all"); MODULE_DESCRIPTION("Rijndael (AES) Cipher Algorithm"); MODULE_LICENSE("GPL"); +MODULE_IMPORT_NS(CRYPTO_INTERNAL); diff --git a/crypto/adiantum.c b/crypto/adiantum.c index ce4d5725342c..84450130cb6b 100644 --- a/crypto/adiantum.c +++ b/crypto/adiantum.c @@ -32,6 +32,7 @@ #include #include +#include #include #include #include @@ -616,3 +617,4 @@ MODULE_DESCRIPTION("Adiantum length-preserving encryption mode"); MODULE_LICENSE("GPL v2"); MODULE_AUTHOR("Eric Biggers "); MODULE_ALIAS_CRYPTO("adiantum"); +MODULE_IMPORT_NS(CRYPTO_INTERNAL); diff --git a/crypto/ansi_cprng.c b/crypto/ansi_cprng.c index c475c1129ff2..3f512efaba3a 100644 --- a/crypto/ansi_cprng.c +++ b/crypto/ansi_cprng.c @@ -7,6 +7,7 @@ * (C) Neil Horman */ +#include #include #include #include @@ -470,3 +471,4 @@ subsys_initcall(prng_mod_init); module_exit(prng_mod_fini); MODULE_ALIAS_CRYPTO("stdrng"); MODULE_ALIAS_CRYPTO("ansi_cprng"); +MODULE_IMPORT_NS(CRYPTO_INTERNAL); diff --git a/crypto/cbc.c b/crypto/cbc.c index 0d9509dff891..6c03e96b945f 100644 --- a/crypto/cbc.c +++ b/crypto/cbc.c @@ -6,6 +6,7 @@ */ #include +#include #include #include #include diff --git a/crypto/ccm.c b/crypto/ccm.c index 494d70901186..6b815ece51c6 100644 --- a/crypto/ccm.c +++ b/crypto/ccm.c @@ -6,6 +6,7 @@ */ #include +#include #include #include #include @@ -954,3 +955,4 @@ MODULE_ALIAS_CRYPTO("ccm_base"); MODULE_ALIAS_CRYPTO("rfc4309"); MODULE_ALIAS_CRYPTO("ccm"); MODULE_ALIAS_CRYPTO("cbcmac"); +MODULE_IMPORT_NS(CRYPTO_INTERNAL); diff --git a/crypto/cfb.c b/crypto/cfb.c index 4e5219bbcd19..0d664dfb47bc 100644 --- a/crypto/cfb.c +++ b/crypto/cfb.c @@ -20,6 +20,7 @@ */ #include +#include #include #include #include @@ -250,3 +251,4 @@ module_exit(crypto_cfb_module_exit); MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("CFB block cipher mode of operation"); MODULE_ALIAS_CRYPTO("cfb"); +MODULE_IMPORT_NS(CRYPTO_INTERNAL); diff --git a/crypto/cipher.c b/crypto/cipher.c index fd78150deb1c..b47141ed4a9f 100644 --- a/crypto/cipher.c +++ b/crypto/cipher.c @@ -9,6 +9,7 @@ */ #include +#include #include #include #include @@ -53,7 +54,7 @@ int crypto_cipher_setkey(struct crypto_cipher *tfm, return cia->cia_setkey(crypto_cipher_tfm(tfm), key, keylen); } -EXPORT_SYMBOL_GPL(crypto_cipher_setkey); +EXPORT_SYMBOL_NS_GPL(crypto_cipher_setkey, CRYPTO_INTERNAL); static inline void cipher_crypt_one(struct crypto_cipher *tfm, u8 *dst, const u8 *src, bool enc) @@ -81,11 +82,11 @@ void crypto_cipher_encrypt_one(struct crypto_cipher *tfm, { cipher_crypt_one(tfm, dst, src, true); } -EXPORT_SYMBOL_GPL(crypto_cipher_encrypt_one); +EXPORT_SYMBOL_NS_GPL(crypto_cipher_encrypt_one, CRYPTO_INTERNAL); void crypto_cipher_decrypt_one(struct crypto_cipher *tfm, u8 *dst, const u8 *src) { cipher_crypt_one(tfm, dst, src, false); } -EXPORT_SYMBOL_GPL(crypto_cipher_decrypt_one); +EXPORT_SYMBOL_NS_GPL(crypto_cipher_decrypt_one, CRYPTO_INTERNAL); diff --git a/crypto/cmac.c b/crypto/cmac.c index df36be1efb81..f4a5d3bfb376 100644 --- a/crypto/cmac.c +++ b/crypto/cmac.c @@ -11,6 +11,7 @@ * Author: Kazunori Miyazawa */ +#include #include #include #include @@ -313,3 +314,4 @@ module_exit(crypto_cmac_module_exit); MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("CMAC keyed hash algorithm"); MODULE_ALIAS_CRYPTO("cmac"); +MODULE_IMPORT_NS(CRYPTO_INTERNAL); diff --git a/crypto/ctr.c b/crypto/ctr.c index c39fcffba27f..23c698b22013 100644 --- a/crypto/ctr.c +++ b/crypto/ctr.c @@ -7,6 +7,7 @@ #include #include +#include #include #include #include @@ -358,3 +359,4 @@ MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("CTR block cipher mode of operation"); MODULE_ALIAS_CRYPTO("rfc3686"); MODULE_ALIAS_CRYPTO("ctr"); +MODULE_IMPORT_NS(CRYPTO_INTERNAL); diff --git a/crypto/drbg.c b/crypto/drbg.c index 3132967a1749..1b4587e0ddad 100644 --- a/crypto/drbg.c +++ b/crypto/drbg.c @@ -98,6 +98,7 @@ */ #include +#include #include /*************************************************************** @@ -2161,3 +2162,4 @@ MODULE_DESCRIPTION("NIST SP800-90A Deterministic Random Bit Generator (DRBG) " CRYPTO_DRBG_HMAC_STRING CRYPTO_DRBG_CTR_STRING); MODULE_ALIAS_CRYPTO("stdrng"); +MODULE_IMPORT_NS(CRYPTO_INTERNAL); diff --git a/crypto/ecb.c b/crypto/ecb.c index 69a687cbdf21..71fbb0543d64 100644 --- a/crypto/ecb.c +++ b/crypto/ecb.c @@ -6,6 +6,7 @@ */ #include +#include #include #include #include diff --git a/crypto/essiv.c b/crypto/essiv.c index d012be23d496..8bcc5bdcb2a9 100644 --- a/crypto/essiv.c +++ b/crypto/essiv.c @@ -30,6 +30,7 @@ #include #include +#include #include #include #include @@ -643,3 +644,4 @@ module_exit(essiv_module_exit); MODULE_DESCRIPTION("ESSIV skcipher/aead wrapper for block encryption"); MODULE_LICENSE("GPL v2"); MODULE_ALIAS_CRYPTO("essiv"); +MODULE_IMPORT_NS(CRYPTO_INTERNAL); diff --git a/crypto/keywrap.c b/crypto/keywrap.c index 0355cce21b1e..3517773bc7f7 100644 --- a/crypto/keywrap.c +++ b/crypto/keywrap.c @@ -85,6 +85,7 @@ #include #include #include +#include #include struct crypto_kw_block { @@ -316,3 +317,4 @@ MODULE_LICENSE("Dual BSD/GPL"); MODULE_AUTHOR("Stephan Mueller "); MODULE_DESCRIPTION("Key Wrapping (RFC3394 / NIST SP800-38F)"); MODULE_ALIAS_CRYPTO("kw"); +MODULE_IMPORT_NS(CRYPTO_INTERNAL); diff --git a/crypto/ofb.c b/crypto/ofb.c index 2ec68e3f2c55..b630fdecceee 100644 --- a/crypto/ofb.c +++ b/crypto/ofb.c @@ -8,6 +8,7 @@ */ #include +#include #include #include #include @@ -102,3 +103,4 @@ module_exit(crypto_ofb_module_exit); MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("OFB block cipher mode of operation"); MODULE_ALIAS_CRYPTO("ofb"); +MODULE_IMPORT_NS(CRYPTO_INTERNAL); diff --git a/crypto/pcbc.c b/crypto/pcbc.c index ae921fb74dc9..7030f59e46b6 100644 --- a/crypto/pcbc.c +++ b/crypto/pcbc.c @@ -10,6 +10,7 @@ */ #include +#include #include #include #include @@ -191,3 +192,4 @@ module_exit(crypto_pcbc_module_exit); MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("PCBC block cipher mode of operation"); MODULE_ALIAS_CRYPTO("pcbc"); +MODULE_IMPORT_NS(CRYPTO_INTERNAL); diff --git a/crypto/skcipher.c b/crypto/skcipher.c index b4dae640de9f..ff16d05644c7 100644 --- a/crypto/skcipher.c +++ b/crypto/skcipher.c @@ -10,6 +10,7 @@ */ #include +#include #include #include #include @@ -986,3 +987,4 @@ EXPORT_SYMBOL_GPL(skcipher_alloc_instance_simple); MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("Symmetric key cipher type"); +MODULE_IMPORT_NS(CRYPTO_INTERNAL); diff --git a/crypto/testmgr.c b/crypto/testmgr.c index 321e38eef51b..a896d77e9611 100644 --- a/crypto/testmgr.c +++ b/crypto/testmgr.c @@ -33,10 +33,13 @@ #include #include #include +#include #include #include "internal.h" +MODULE_IMPORT_NS(CRYPTO_INTERNAL); + static bool notests; module_param(notests, bool, 0644); MODULE_PARM_DESC(notests, "disable crypto self-tests"); diff --git a/crypto/vmac.c b/crypto/vmac.c index 9b565d1040d6..4633b2dda1e0 100644 --- a/crypto/vmac.c +++ b/crypto/vmac.c @@ -36,6 +36,7 @@ #include #include #include +#include #include /* @@ -693,3 +694,4 @@ module_exit(vmac_module_exit); MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("VMAC hash algorithm"); MODULE_ALIAS_CRYPTO("vmac64"); +MODULE_IMPORT_NS(CRYPTO_INTERNAL); diff --git a/crypto/xcbc.c b/crypto/xcbc.c index af3b7eb5d7c7..6074c5c1da49 100644 --- a/crypto/xcbc.c +++ b/crypto/xcbc.c @@ -6,6 +6,7 @@ * Kazunori Miyazawa */ +#include #include #include #include @@ -272,3 +273,4 @@ module_exit(crypto_xcbc_module_exit); MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("XCBC keyed hash algorithm"); MODULE_ALIAS_CRYPTO("xcbc"); +MODULE_IMPORT_NS(CRYPTO_INTERNAL); diff --git a/crypto/xts.c b/crypto/xts.c index ad45b009774b..6c12f30dbdd6 100644 --- a/crypto/xts.c +++ b/crypto/xts.c @@ -7,6 +7,7 @@ * Based on ecb.c * Copyright (c) 2006 Herbert Xu */ +#include #include #include #include @@ -464,3 +465,4 @@ module_exit(xts_module_exit); MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("XTS block cipher mode"); MODULE_ALIAS_CRYPTO("xts"); +MODULE_IMPORT_NS(CRYPTO_INTERNAL); diff --git a/drivers/crypto/geode-aes.c b/drivers/crypto/geode-aes.c index f4f18bfc2247..4ee010f39912 100644 --- a/drivers/crypto/geode-aes.c +++ b/drivers/crypto/geode-aes.c @@ -10,6 +10,7 @@ #include #include #include +#include #include #include @@ -434,3 +435,4 @@ module_pci_driver(geode_aes_driver); MODULE_AUTHOR("Advanced Micro Devices, Inc."); MODULE_DESCRIPTION("Geode LX Hardware AES driver"); MODULE_LICENSE("GPL"); +MODULE_IMPORT_NS(CRYPTO_INTERNAL); diff --git a/drivers/crypto/inside-secure/safexcel.c b/drivers/crypto/inside-secure/safexcel.c index 2e1562108a85..30aedfcfee7c 100644 --- a/drivers/crypto/inside-secure/safexcel.c +++ b/drivers/crypto/inside-secure/safexcel.c @@ -1999,3 +1999,4 @@ MODULE_AUTHOR("Ofer Heifetz "); MODULE_AUTHOR("Igal Liberman "); MODULE_DESCRIPTION("Support for SafeXcel cryptographic engines: EIP97 & EIP197"); MODULE_LICENSE("GPL v2"); +MODULE_IMPORT_NS(CRYPTO_INTERNAL); diff --git a/drivers/crypto/inside-secure/safexcel_hash.c b/drivers/crypto/inside-secure/safexcel_hash.c index 50fb6d90a2e0..bc60b5802256 100644 --- a/drivers/crypto/inside-secure/safexcel_hash.c +++ b/drivers/crypto/inside-secure/safexcel_hash.c @@ -13,6 +13,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/crypto/qat/qat_common/adf_ctl_drv.c b/drivers/crypto/qat/qat_common/adf_ctl_drv.c index eb9b3be9d8eb..96b437bfe3de 100644 --- a/drivers/crypto/qat/qat_common/adf_ctl_drv.c +++ b/drivers/crypto/qat/qat_common/adf_ctl_drv.c @@ -464,3 +464,4 @@ MODULE_AUTHOR("Intel"); MODULE_DESCRIPTION("Intel(R) QuickAssist Technology"); MODULE_ALIAS_CRYPTO("intel_qat"); MODULE_VERSION(ADF_DRV_VERSION); +MODULE_IMPORT_NS(CRYPTO_INTERNAL); diff --git a/drivers/crypto/qat/qat_common/qat_algs.c b/drivers/crypto/qat/qat_common/qat_algs.c index 31c7a206a629..ff78c73c47e3 100644 --- a/drivers/crypto/qat/qat_common/qat_algs.c +++ b/drivers/crypto/qat/qat_common/qat_algs.c @@ -4,6 +4,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/crypto/vmx/aes.c b/drivers/crypto/vmx/aes.c index 2bc5d4e1adf4..d05c02baebcf 100644 --- a/drivers/crypto/vmx/aes.c +++ b/drivers/crypto/vmx/aes.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include "aesp8-ppc.h" diff --git a/drivers/crypto/vmx/vmx.c b/drivers/crypto/vmx/vmx.c index 3e0335fb406c..87a194455d6a 100644 --- a/drivers/crypto/vmx/vmx.c +++ b/drivers/crypto/vmx/vmx.c @@ -78,3 +78,4 @@ MODULE_DESCRIPTION("IBM VMX cryptographic acceleration instructions " "support on Power 8"); MODULE_LICENSE("GPL"); MODULE_VERSION("1.0.0"); +MODULE_IMPORT_NS(CRYPTO_INTERNAL); diff --git a/include/crypto/algapi.h b/include/crypto/algapi.h index 18dd7a4aaf7d..86f0748009af 100644 --- a/include/crypto/algapi.h +++ b/include/crypto/algapi.h @@ -189,45 +189,6 @@ static inline void *crypto_instance_ctx(struct crypto_instance *inst) return inst->__ctx; } -struct crypto_cipher_spawn { - struct crypto_spawn base; -}; - -static inline int crypto_grab_cipher(struct crypto_cipher_spawn *spawn, - struct crypto_instance *inst, - const char *name, u32 type, u32 mask) -{ - type &= ~CRYPTO_ALG_TYPE_MASK; - type |= CRYPTO_ALG_TYPE_CIPHER; - mask |= CRYPTO_ALG_TYPE_MASK; - return crypto_grab_spawn(&spawn->base, inst, name, type, mask); -} - -static inline void crypto_drop_cipher(struct crypto_cipher_spawn *spawn) -{ - crypto_drop_spawn(&spawn->base); -} - -static inline struct crypto_alg *crypto_spawn_cipher_alg( - struct crypto_cipher_spawn *spawn) -{ - return spawn->base.alg; -} - -static inline struct crypto_cipher *crypto_spawn_cipher( - struct crypto_cipher_spawn *spawn) -{ - u32 type = CRYPTO_ALG_TYPE_CIPHER; - u32 mask = CRYPTO_ALG_TYPE_MASK; - - return __crypto_cipher_cast(crypto_spawn_tfm(&spawn->base, type, mask)); -} - -static inline struct cipher_alg *crypto_cipher_alg(struct crypto_cipher *tfm) -{ - return &crypto_cipher_tfm(tfm)->__crt_alg->cra_cipher; -} - static inline struct crypto_async_request *crypto_get_backlog( struct crypto_queue *queue) { diff --git a/include/crypto/internal/cipher.h b/include/crypto/internal/cipher.h new file mode 100644 index 000000000000..a9174ba90250 --- /dev/null +++ b/include/crypto/internal/cipher.h @@ -0,0 +1,218 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * Copyright (c) 2002 James Morris + * Copyright (c) 2002 David S. Miller (davem@redhat.com) + * Copyright (c) 2005 Herbert Xu + * + * Portions derived from Cryptoapi, by Alexander Kjeldaas + * and Nettle, by Niels Möller. + */ + +#ifndef _CRYPTO_INTERNAL_CIPHER_H +#define _CRYPTO_INTERNAL_CIPHER_H + +#include + +struct crypto_cipher { + struct crypto_tfm base; +}; + +/** + * DOC: Single Block Cipher API + * + * The single block cipher API is used with the ciphers of type + * CRYPTO_ALG_TYPE_CIPHER (listed as type "cipher" in /proc/crypto). + * + * Using the single block cipher API calls, operations with the basic cipher + * primitive can be implemented. These cipher primitives exclude any block + * chaining operations including IV handling. + * + * The purpose of this single block cipher API is to support the implementation + * of templates or other concepts that only need to perform the cipher operation + * on one block at a time. Templates invoke the underlying cipher primitive + * block-wise and process either the input or the output data of these cipher + * operations. + */ + +static inline struct crypto_cipher *__crypto_cipher_cast(struct crypto_tfm *tfm) +{ + return (struct crypto_cipher *)tfm; +} + +/** + * crypto_alloc_cipher() - allocate single block cipher handle + * @alg_name: is the cra_name / name or cra_driver_name / driver name of the + * single block cipher + * @type: specifies the type of the cipher + * @mask: specifies the mask for the cipher + * + * Allocate a cipher handle for a single block cipher. The returned struct + * crypto_cipher is the cipher handle that is required for any subsequent API + * invocation for that single block cipher. + * + * Return: allocated cipher handle in case of success; IS_ERR() is true in case + * of an error, PTR_ERR() returns the error code. + */ +static inline struct crypto_cipher *crypto_alloc_cipher(const char *alg_name, + u32 type, u32 mask) +{ + type &= ~CRYPTO_ALG_TYPE_MASK; + type |= CRYPTO_ALG_TYPE_CIPHER; + mask |= CRYPTO_ALG_TYPE_MASK; + + return __crypto_cipher_cast(crypto_alloc_base(alg_name, type, mask)); +} + +static inline struct crypto_tfm *crypto_cipher_tfm(struct crypto_cipher *tfm) +{ + return &tfm->base; +} + +/** + * crypto_free_cipher() - zeroize and free the single block cipher handle + * @tfm: cipher handle to be freed + */ +static inline void crypto_free_cipher(struct crypto_cipher *tfm) +{ + crypto_free_tfm(crypto_cipher_tfm(tfm)); +} + +/** + * crypto_has_cipher() - Search for the availability of a single block cipher + * @alg_name: is the cra_name / name or cra_driver_name / driver name of the + * single block cipher + * @type: specifies the type of the cipher + * @mask: specifies the mask for the cipher + * + * Return: true when the single block cipher is known to the kernel crypto API; + * false otherwise + */ +static inline int crypto_has_cipher(const char *alg_name, u32 type, u32 mask) +{ + type &= ~CRYPTO_ALG_TYPE_MASK; + type |= CRYPTO_ALG_TYPE_CIPHER; + mask |= CRYPTO_ALG_TYPE_MASK; + + return crypto_has_alg(alg_name, type, mask); +} + +/** + * crypto_cipher_blocksize() - obtain block size for cipher + * @tfm: cipher handle + * + * The block size for the single block cipher referenced with the cipher handle + * tfm is returned. The caller may use that information to allocate appropriate + * memory for the data returned by the encryption or decryption operation + * + * Return: block size of cipher + */ +static inline unsigned int crypto_cipher_blocksize(struct crypto_cipher *tfm) +{ + return crypto_tfm_alg_blocksize(crypto_cipher_tfm(tfm)); +} + +static inline unsigned int crypto_cipher_alignmask(struct crypto_cipher *tfm) +{ + return crypto_tfm_alg_alignmask(crypto_cipher_tfm(tfm)); +} + +static inline u32 crypto_cipher_get_flags(struct crypto_cipher *tfm) +{ + return crypto_tfm_get_flags(crypto_cipher_tfm(tfm)); +} + +static inline void crypto_cipher_set_flags(struct crypto_cipher *tfm, + u32 flags) +{ + crypto_tfm_set_flags(crypto_cipher_tfm(tfm), flags); +} + +static inline void crypto_cipher_clear_flags(struct crypto_cipher *tfm, + u32 flags) +{ + crypto_tfm_clear_flags(crypto_cipher_tfm(tfm), flags); +} + +/** + * crypto_cipher_setkey() - set key for cipher + * @tfm: cipher handle + * @key: buffer holding the key + * @keylen: length of the key in bytes + * + * The caller provided key is set for the single block cipher referenced by the + * cipher handle. + * + * Note, the key length determines the cipher type. Many block ciphers implement + * different cipher modes depending on the key size, such as AES-128 vs AES-192 + * vs. AES-256. When providing a 16 byte key for an AES cipher handle, AES-128 + * is performed. + * + * Return: 0 if the setting of the key was successful; < 0 if an error occurred + */ +int crypto_cipher_setkey(struct crypto_cipher *tfm, + const u8 *key, unsigned int keylen); + +/** + * crypto_cipher_encrypt_one() - encrypt one block of plaintext + * @tfm: cipher handle + * @dst: points to the buffer that will be filled with the ciphertext + * @src: buffer holding the plaintext to be encrypted + * + * Invoke the encryption operation of one block. The caller must ensure that + * the plaintext and ciphertext buffers are at least one block in size. + */ +void crypto_cipher_encrypt_one(struct crypto_cipher *tfm, + u8 *dst, const u8 *src); + +/** + * crypto_cipher_decrypt_one() - decrypt one block of ciphertext + * @tfm: cipher handle + * @dst: points to the buffer that will be filled with the plaintext + * @src: buffer holding the ciphertext to be decrypted + * + * Invoke the decryption operation of one block. The caller must ensure that + * the plaintext and ciphertext buffers are at least one block in size. + */ +void crypto_cipher_decrypt_one(struct crypto_cipher *tfm, + u8 *dst, const u8 *src); + +struct crypto_cipher_spawn { + struct crypto_spawn base; +}; + +static inline int crypto_grab_cipher(struct crypto_cipher_spawn *spawn, + struct crypto_instance *inst, + const char *name, u32 type, u32 mask) +{ + type &= ~CRYPTO_ALG_TYPE_MASK; + type |= CRYPTO_ALG_TYPE_CIPHER; + mask |= CRYPTO_ALG_TYPE_MASK; + return crypto_grab_spawn(&spawn->base, inst, name, type, mask); +} + +static inline void crypto_drop_cipher(struct crypto_cipher_spawn *spawn) +{ + crypto_drop_spawn(&spawn->base); +} + +static inline struct crypto_alg *crypto_spawn_cipher_alg( + struct crypto_cipher_spawn *spawn) +{ + return spawn->base.alg; +} + +static inline struct crypto_cipher *crypto_spawn_cipher( + struct crypto_cipher_spawn *spawn) +{ + u32 type = CRYPTO_ALG_TYPE_CIPHER; + u32 mask = CRYPTO_ALG_TYPE_MASK; + + return __crypto_cipher_cast(crypto_spawn_tfm(&spawn->base, type, mask)); +} + +static inline struct cipher_alg *crypto_cipher_alg(struct crypto_cipher *tfm) +{ + return &crypto_cipher_tfm(tfm)->__crt_alg->cra_cipher; +} + +#endif diff --git a/include/crypto/internal/skcipher.h b/include/crypto/internal/skcipher.h index 10226c12c5df..9dd6c0c17eb8 100644 --- a/include/crypto/internal/skcipher.h +++ b/include/crypto/internal/skcipher.h @@ -9,6 +9,7 @@ #define _CRYPTO_INTERNAL_SKCIPHER_H #include +#include #include #include #include diff --git a/include/linux/crypto.h b/include/linux/crypto.h index ef90e07c9635..9b55cd6b1f1b 100644 --- a/include/linux/crypto.h +++ b/include/linux/crypto.h @@ -636,10 +636,6 @@ struct crypto_tfm { void *__crt_ctx[] CRYPTO_MINALIGN_ATTR; }; -struct crypto_cipher { - struct crypto_tfm base; -}; - struct crypto_comp { struct crypto_tfm base; }; @@ -743,165 +739,6 @@ static inline unsigned int crypto_tfm_ctx_alignment(void) return __alignof__(tfm->__crt_ctx); } -/** - * DOC: Single Block Cipher API - * - * The single block cipher API is used with the ciphers of type - * CRYPTO_ALG_TYPE_CIPHER (listed as type "cipher" in /proc/crypto). - * - * Using the single block cipher API calls, operations with the basic cipher - * primitive can be implemented. These cipher primitives exclude any block - * chaining operations including IV handling. - * - * The purpose of this single block cipher API is to support the implementation - * of templates or other concepts that only need to perform the cipher operation - * on one block at a time. Templates invoke the underlying cipher primitive - * block-wise and process either the input or the output data of these cipher - * operations. - */ - -static inline struct crypto_cipher *__crypto_cipher_cast(struct crypto_tfm *tfm) -{ - return (struct crypto_cipher *)tfm; -} - -/** - * crypto_alloc_cipher() - allocate single block cipher handle - * @alg_name: is the cra_name / name or cra_driver_name / driver name of the - * single block cipher - * @type: specifies the type of the cipher - * @mask: specifies the mask for the cipher - * - * Allocate a cipher handle for a single block cipher. The returned struct - * crypto_cipher is the cipher handle that is required for any subsequent API - * invocation for that single block cipher. - * - * Return: allocated cipher handle in case of success; IS_ERR() is true in case - * of an error, PTR_ERR() returns the error code. - */ -static inline struct crypto_cipher *crypto_alloc_cipher(const char *alg_name, - u32 type, u32 mask) -{ - type &= ~CRYPTO_ALG_TYPE_MASK; - type |= CRYPTO_ALG_TYPE_CIPHER; - mask |= CRYPTO_ALG_TYPE_MASK; - - return __crypto_cipher_cast(crypto_alloc_base(alg_name, type, mask)); -} - -static inline struct crypto_tfm *crypto_cipher_tfm(struct crypto_cipher *tfm) -{ - return &tfm->base; -} - -/** - * crypto_free_cipher() - zeroize and free the single block cipher handle - * @tfm: cipher handle to be freed - */ -static inline void crypto_free_cipher(struct crypto_cipher *tfm) -{ - crypto_free_tfm(crypto_cipher_tfm(tfm)); -} - -/** - * crypto_has_cipher() - Search for the availability of a single block cipher - * @alg_name: is the cra_name / name or cra_driver_name / driver name of the - * single block cipher - * @type: specifies the type of the cipher - * @mask: specifies the mask for the cipher - * - * Return: true when the single block cipher is known to the kernel crypto API; - * false otherwise - */ -static inline int crypto_has_cipher(const char *alg_name, u32 type, u32 mask) -{ - type &= ~CRYPTO_ALG_TYPE_MASK; - type |= CRYPTO_ALG_TYPE_CIPHER; - mask |= CRYPTO_ALG_TYPE_MASK; - - return crypto_has_alg(alg_name, type, mask); -} - -/** - * crypto_cipher_blocksize() - obtain block size for cipher - * @tfm: cipher handle - * - * The block size for the single block cipher referenced with the cipher handle - * tfm is returned. The caller may use that information to allocate appropriate - * memory for the data returned by the encryption or decryption operation - * - * Return: block size of cipher - */ -static inline unsigned int crypto_cipher_blocksize(struct crypto_cipher *tfm) -{ - return crypto_tfm_alg_blocksize(crypto_cipher_tfm(tfm)); -} - -static inline unsigned int crypto_cipher_alignmask(struct crypto_cipher *tfm) -{ - return crypto_tfm_alg_alignmask(crypto_cipher_tfm(tfm)); -} - -static inline u32 crypto_cipher_get_flags(struct crypto_cipher *tfm) -{ - return crypto_tfm_get_flags(crypto_cipher_tfm(tfm)); -} - -static inline void crypto_cipher_set_flags(struct crypto_cipher *tfm, - u32 flags) -{ - crypto_tfm_set_flags(crypto_cipher_tfm(tfm), flags); -} - -static inline void crypto_cipher_clear_flags(struct crypto_cipher *tfm, - u32 flags) -{ - crypto_tfm_clear_flags(crypto_cipher_tfm(tfm), flags); -} - -/** - * crypto_cipher_setkey() - set key for cipher - * @tfm: cipher handle - * @key: buffer holding the key - * @keylen: length of the key in bytes - * - * The caller provided key is set for the single block cipher referenced by the - * cipher handle. - * - * Note, the key length determines the cipher type. Many block ciphers implement - * different cipher modes depending on the key size, such as AES-128 vs AES-192 - * vs. AES-256. When providing a 16 byte key for an AES cipher handle, AES-128 - * is performed. - * - * Return: 0 if the setting of the key was successful; < 0 if an error occurred - */ -int crypto_cipher_setkey(struct crypto_cipher *tfm, - const u8 *key, unsigned int keylen); - -/** - * crypto_cipher_encrypt_one() - encrypt one block of plaintext - * @tfm: cipher handle - * @dst: points to the buffer that will be filled with the ciphertext - * @src: buffer holding the plaintext to be encrypted - * - * Invoke the encryption operation of one block. The caller must ensure that - * the plaintext and ciphertext buffers are at least one block in size. - */ -void crypto_cipher_encrypt_one(struct crypto_cipher *tfm, - u8 *dst, const u8 *src); - -/** - * crypto_cipher_decrypt_one() - decrypt one block of ciphertext - * @tfm: cipher handle - * @dst: points to the buffer that will be filled with the plaintext - * @src: buffer holding the ciphertext to be decrypted - * - * Invoke the decryption operation of one block. The caller must ensure that - * the plaintext and ciphertext buffers are at least one block in size. - */ -void crypto_cipher_decrypt_one(struct crypto_cipher *tfm, - u8 *dst, const u8 *src); - static inline struct crypto_comp *__crypto_comp_cast(struct crypto_tfm *tfm) { return (struct crypto_comp *)tfm; -- cgit v1.2.3 From 33ff64884c4e5ffcac1c4aa767e38bf4b3f443a0 Mon Sep 17 00:00:00 2001 From: Declan Murphy Date: Wed, 16 Dec 2020 11:46:35 +0000 Subject: dt-bindings: crypto: Add Keem Bay OCS HCU bindings Add device-tree bindings for the Intel Keem Bay Offload Crypto Subsystem (OCS) Hashing Control Unit (HCU) crypto driver. Signed-off-by: Declan Murphy Signed-off-by: Daniele Alessandrelli Acked-by: Mark Gross Reviewed-by: Rob Herring Signed-off-by: Herbert Xu --- .../bindings/crypto/intel,keembay-ocs-hcu.yaml | 46 ++++++++++++++++++++++ 1 file changed, 46 insertions(+) create mode 100644 Documentation/devicetree/bindings/crypto/intel,keembay-ocs-hcu.yaml (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/crypto/intel,keembay-ocs-hcu.yaml b/Documentation/devicetree/bindings/crypto/intel,keembay-ocs-hcu.yaml new file mode 100644 index 000000000000..acb92706d280 --- /dev/null +++ b/Documentation/devicetree/bindings/crypto/intel,keembay-ocs-hcu.yaml @@ -0,0 +1,46 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/crypto/intel,keembay-ocs-hcu.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Intel Keem Bay OCS HCU Device Tree Bindings + +maintainers: + - Declan Murphy + - Daniele Alessandrelli + +description: + The Intel Keem Bay Offload and Crypto Subsystem (OCS) Hash Control Unit (HCU) + provides hardware-accelerated hashing and HMAC. + +properties: + compatible: + const: intel,keembay-ocs-hcu + + reg: + maxItems: 1 + + interrupts: + maxItems: 1 + + clocks: + maxItems: 1 + +required: + - compatible + - reg + - interrupts + - clocks + +additionalProperties: false + +examples: + - | + #include + crypto@3000b000 { + compatible = "intel,keembay-ocs-hcu"; + reg = <0x3000b000 0x1000>; + interrupts = ; + clocks = <&scmi_clk 94>; + }; -- cgit v1.2.3 From fd159539f7b0dbfe0aa196c3182e44b9ba49edb8 Mon Sep 17 00:00:00 2001 From: Adam Ford Date: Sat, 7 Nov 2020 08:48:08 -0600 Subject: dt-bindings: arm: fsl: Add beacon,imx8mn-beacon-kit Add beacon,imx8mn-beacon-kit to list of compatible options. Signed-off-by: Adam Ford Reviewed-by: Krzysztof Kozlowski Acked-by: Rob Herring Signed-off-by: Shawn Guo --- Documentation/devicetree/bindings/arm/fsl.yaml | 1 + 1 file changed, 1 insertion(+) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/arm/fsl.yaml b/Documentation/devicetree/bindings/arm/fsl.yaml index 34000f7fbe02..cee74fc0c115 100644 --- a/Documentation/devicetree/bindings/arm/fsl.yaml +++ b/Documentation/devicetree/bindings/arm/fsl.yaml @@ -691,6 +691,7 @@ properties: - description: i.MX8MN based Boards items: - enum: + - beacon,imx8mn-beacon-kit # i.MX8MN Beacon Development Kit - fsl,imx8mn-ddr4-evk # i.MX8MN DDR4 EVK Board - fsl,imx8mn-evk # i.MX8MN LPDDR4 EVK Board - const: fsl,imx8mn -- cgit v1.2.3 From e90d5df7f08f25a5a7a7b1acbee2f1062cd566d1 Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Mon, 28 Dec 2020 12:53:20 -0800 Subject: Documentation: HID: hid-alps editing & corrections Do basic editing & correction to hid-alps.rst: - fix grammar - fix punctuation spacing Signed-off-by: Randy Dunlap Cc: Jiri Kosina Cc: Benjamin Tissoires Cc: linux-input@vger.kernel.org Cc: Jonathan Corbet Cc: Jonathan Cameron Cc: linux-doc@vger.kernel.org Reviewed-by: Jonathan Cameron Signed-off-by: Jiri Kosina --- Documentation/hid/hid-alps.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'Documentation') diff --git a/Documentation/hid/hid-alps.rst b/Documentation/hid/hid-alps.rst index e2f4c4c11e3f..767c96bcbb7c 100644 --- a/Documentation/hid/hid-alps.rst +++ b/Documentation/hid/hid-alps.rst @@ -64,7 +64,7 @@ Case2 ReportID_3 TP Absolute Command Read/Write ------------------ -To read/write to RAM, need to send a commands to the device. +To read/write to RAM, need to send a command to the device. The command format is as below. @@ -80,7 +80,7 @@ Byte6 Value Byte Byte7 Checksum ===== ====================== -Command Byte is read=0xD1/write=0xD2 . +Command Byte is read=0xD1/write=0xD2. Address is read/write RAM address. -- cgit v1.2.3 From 4acdc5e5ca80bf1541b25104b58c3f780b5d7f27 Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Mon, 28 Dec 2020 12:53:21 -0800 Subject: Documentation: HID: amd-sfh-hid editing & corrections Do basic editing & correction to amd-sfh-hid.rst: - fix punctuation - use HID instead of hid consistently - fix grammar, verb tense - fix Block Diagram heading Signed-off-by: Randy Dunlap Cc: Jiri Kosina Cc: Jonathan Cameron Cc: Srinivas Pandruvada Cc: linux-input@vger.kernel.org Cc: linux-iio@vger.kernel.org Cc: Jonathan Corbet Cc: linux-doc@vger.kernel.org Reviewed-by: Jonathan Cameron Signed-off-by: Jiri Kosina --- Documentation/hid/amd-sfh-hid.rst | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) (limited to 'Documentation') diff --git a/Documentation/hid/amd-sfh-hid.rst b/Documentation/hid/amd-sfh-hid.rst index 1f2fe29ccd4f..19ae94cde3b4 100644 --- a/Documentation/hid/amd-sfh-hid.rst +++ b/Documentation/hid/amd-sfh-hid.rst @@ -3,13 +3,13 @@ AMD Sensor Fusion Hub ===================== -AMD Sensor Fusion Hub (SFH) is part of an SOC starting from Ryzen based platforms. +AMD Sensor Fusion Hub (SFH) is part of an SOC starting from Ryzen-based platforms. The solution is working well on several OEM products. AMD SFH uses HID over PCIe bus. In terms of architecture it resembles ISH, however the major difference is all the HID reports are generated as part of the kernel driver. -1. Block Diagram -================ +Block Diagram +------------- :: @@ -45,20 +45,20 @@ the HID reports are generated as part of the kernel driver. AMD HID Transport Layer ----------------------- AMD SFH transport is also implemented as a bus. Each client application executing in the AMD MP2 is -registered as a device on this bus. Here: MP2 which is an ARM core connected to x86 for processing +registered as a device on this bus. Here, MP2 is an ARM core connected to x86 for processing sensor data. The layer, which binds each device (AMD SFH HID driver) identifies the device type and -registers with the hid core. Transport layer attach a constant "struct hid_ll_driver" object with +registers with the HID core. Transport layer attaches a constant "struct hid_ll_driver" object with each device. Once a device is registered with HID core, the callbacks provided via this struct are used by HID core to communicate with the device. AMD HID Transport layer implements the synchronous calls. AMD HID Client Layer -------------------- -This layer is responsible to implement HID request and descriptors. As firmware is OS agnostic, HID +This layer is responsible to implement HID requests and descriptors. As firmware is OS agnostic, HID client layer fills the HID request structure and descriptors. HID client layer is complex as it is -interface between MP2 PCIe layer and HID. HID client layer initialized the MP2 PCIe layer and holds -the instance of MP2 layer. It identifies the number of sensors connected using MP2-PCIe layer. Base -on that allocates the DRAM address for each and every sensor and pass it to MP2-PCIe driver.On -enumeration of each the sensor, client layer fills the HID Descriptor structure and HID input repor +interface between MP2 PCIe layer and HID. HID client layer initializes the MP2 PCIe layer and holds +the instance of MP2 layer. It identifies the number of sensors connected using MP2-PCIe layer. Based +on that allocates the DRAM address for each and every sensor and passes it to MP2-PCIe driver. On +enumeration of each sensor, client layer fills the HID Descriptor structure and HID input report structure. HID Feature report structure is optional. The report descriptor structure varies from sensor to sensor. @@ -72,7 +72,7 @@ The communication between X86 and MP2 is split into three parts. 2. Data transfer via DRAM. 3. Supported sensor info via P2C registers. -Commands are sent to MP2 using C2P Mailbox registers. Writing into C2P Message registers generate +Commands are sent to MP2 using C2P Mailbox registers. Writing into C2P Message registers generates interrupt to MP2. The client layer allocates the physical memory and the same is sent to MP2 via the PCI layer. MP2 firmware writes the command output to the access DRAM memory which the client layer has allocated. Firmware always writes minimum of 32 bytes into DRAM. So as a protocol driver -- cgit v1.2.3 From 750376f5e13628c5853f42e24921603f8d86b2ae Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Mon, 28 Dec 2020 12:53:22 -0800 Subject: Documentation: HID: hiddev editing & corrections Do basic editing & correction to hiddev.rst: - use HID instead of hid consistently - add hyphenation of multi-word adjectives - drop a duplicate word - unhyphenate "a priori" Signed-off-by: Randy Dunlap Cc: Jiri Kosina Cc: Benjamin Tissoires Cc: linux-input@vger.kernel.org Cc: Jonathan Corbet Cc: linux-doc@vger.kernel.org Cc: Jonathan Cameron Reviewed-by: Jonathan Cameron Signed-off-by: Jiri Kosina --- Documentation/hid/hiddev.rst | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'Documentation') diff --git a/Documentation/hid/hiddev.rst b/Documentation/hid/hiddev.rst index 9b28a97c03e6..caebc6266603 100644 --- a/Documentation/hid/hiddev.rst +++ b/Documentation/hid/hiddev.rst @@ -27,7 +27,7 @@ the following:: --> hiddev.c ----> POWER / MONITOR CONTROL In addition, other subsystems (apart from USB) can potentially feed -events into the input subsystem, but these have no effect on the hid +events into the input subsystem, but these have no effect on the HID device interface. Using the HID Device Interface @@ -73,7 +73,7 @@ The hiddev API uses a read() interface, and a set of ioctl() calls. HID devices exchange data with the host computer using data bundles called "reports". Each report is divided into "fields", each of which can have one or more "usages". In the hid-core, -each one of these usages has a single signed 32 bit value. +each one of these usages has a single signed 32-bit value. read(): ------- @@ -113,7 +113,7 @@ HIDIOCAPPLICATION - (none) This ioctl call returns the HID application usage associated with the -hid device. The third argument to ioctl() specifies which application +HID device. The third argument to ioctl() specifies which application index to get. This is useful when the device has more than one application collection. If the index is invalid (greater or equal to the number of application collections this device has) the ioctl @@ -181,7 +181,7 @@ looked up by type (input, output or feature) and id, so these fields must be filled in by the user. The ID can be absolute -- the actual report id as reported by the device -- or relative -- HID_REPORT_ID_FIRST for the first report, and (HID_REPORT_ID_NEXT | -report_id) for the next report after report_id. Without a-priori +report_id) for the next report after report_id. Without a priori information about report ids, the right way to use this ioctl is to use the relative IDs above to enumerate the valid IDs. The ioctl returns non-zero when there is no more next ID. The real report ID is @@ -200,7 +200,7 @@ HIDIOCGUCODE - struct hiddev_usage_ref (read/write) Returns the usage_code in a hiddev_usage_ref structure, given that -given its report type, report id, field index, and index within the +its report type, report id, field index, and index within the field have already been filled into the structure. HIDIOCGUSAGE -- cgit v1.2.3 From 997930996e04f49578a956cd555519caa912dedd Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Mon, 28 Dec 2020 12:53:23 -0800 Subject: Documentation: HID: intel-ish-hid editing & corrections Do basic editing & correction to intel-ish-hid.rst: - fix grammar, verb tense, punctutation, and word phrasing - fix spellos - hyphenate multi-word adjectives - collapse 2 spaces to one space in the middle of sentences - use "I2C" instead of lower-case letters (as Linux I2C does) - change space indentation to tab - use HID instead of hid consistently - use a list so that some line items do not run together - use "a UUID" instead of "an UUID" Signed-off-by: Randy Dunlap Cc: Jiri Kosina Cc: Jonathan Cameron Cc: Srinivas Pandruvada Cc: linux-input@vger.kernel.org Cc: linux-iio@vger.kernel.org Cc: Jonathan Corbet Cc: linux-doc@vger.kernel.org Reviewed-by: Jonathan Cameron Signed-off-by: Jiri Kosina --- Documentation/hid/intel-ish-hid.rst | 78 +++++++++++++++++++------------------ 1 file changed, 40 insertions(+), 38 deletions(-) (limited to 'Documentation') diff --git a/Documentation/hid/intel-ish-hid.rst b/Documentation/hid/intel-ish-hid.rst index d4785cf6eefd..f6ce44ff611d 100644 --- a/Documentation/hid/intel-ish-hid.rst +++ b/Documentation/hid/intel-ish-hid.rst @@ -4,19 +4,19 @@ Intel Integrated Sensor Hub (ISH) A sensor hub enables the ability to offload sensor polling and algorithm processing to a dedicated low power co-processor. This allows the core -processor to go into low power modes more often, resulting in the increased +processor to go into low power modes more often, resulting in increased battery life. -There are many vendors providing external sensor hubs confirming to HID -Sensor usage tables, and used in several tablets, 2 in 1 convertible laptops -and embedded products. Linux had this support since Linux 3.9. +There are many vendors providing external sensor hubs conforming to HID +Sensor usage tables. These may be found in tablets, 2-in-1 convertible laptops +and embedded products. Linux has had this support since Linux 3.9. Intel® introduced integrated sensor hubs as a part of the SoC starting from Cherry Trail and now supported on multiple generations of CPU packages. There are many commercial devices already shipped with Integrated Sensor Hubs (ISH). -These ISH also comply to HID sensor specification, but the difference is the +These ISH also comply to HID sensor specification, but the difference is the transport protocol used for communication. The current external sensor hubs -mainly use HID over i2C or USB. But ISH doesn't use either i2c or USB. +mainly use HID over I2C or USB. But ISH doesn't use either I2C or USB. 1. Overview =========== @@ -35,7 +35,7 @@ for a very high speed communication:: ----------------- ---------------------- PCI PCI ----------------- ---------------------- - |Host controller| --> | ISH processor | + |Host controller| --> | ISH processor | ----------------- ---------------------- USB Link ----------------- ---------------------- @@ -50,13 +50,13 @@ applications implemented in the firmware. The ISH allows multiple sensor management applications executing in the firmware. Like USB endpoints the messaging can be to/from a client. As part of enumeration process, these clients are identified. These clients can be simple -HID sensor applications, sensor calibration application or senor firmware -update application. +HID sensor applications, sensor calibration applications or sensor firmware +update applications. The implementation model is similar, like USB bus, ISH transport is also implemented as a bus. Each client application executing in the ISH processor is registered as a device on this bus. The driver, which binds each device -(ISH HID driver) identifies the device type and registers with the hid core. +(ISH HID driver) identifies the device type and registers with the HID core. 2. ISH Implementation: Block Diagram ==================================== @@ -104,7 +104,7 @@ is registered as a device on this bus. The driver, which binds each device The ISH is exposed as "Non-VGA unclassified PCI device" to the host. The PCI product and vendor IDs are changed from different generations of processors. So -the source code which enumerate drivers needs to update from generation to +the source code which enumerates drivers needs to update from generation to generation. 3.2 Inter Processor Communication (IPC) driver @@ -112,41 +112,42 @@ generation. Location: drivers/hid/intel-ish-hid/ipc -The IPC message used memory mapped I/O. The registers are defined in +The IPC message uses memory mapped I/O. The registers are defined in hw-ish-regs.h. 3.2.1 IPC/FW message types ^^^^^^^^^^^^^^^^^^^^^^^^^^ -There are two types of messages, one for management of link and other messages -are to and from transport layers. +There are two types of messages, one for management of link and another for +messages to and from transport layers. TX and RX of Transport messages ............................... -A set of memory mapped register offers support of multi byte messages TX and -RX (E.g.IPC_REG_ISH2HOST_MSG, IPC_REG_HOST2ISH_MSG). The IPC layer maintains -internal queues to sequence messages and send them in order to the FW. +A set of memory mapped register offers support of multi-byte messages TX and +RX (e.g. IPC_REG_ISH2HOST_MSG, IPC_REG_HOST2ISH_MSG). The IPC layer maintains +internal queues to sequence messages and send them in order to the firmware. Optionally the caller can register handler to get notification of completion. -A door bell mechanism is used in messaging to trigger processing in host and +A doorbell mechanism is used in messaging to trigger processing in host and client firmware side. When ISH interrupt handler is called, the ISH2HOST doorbell register is used by host drivers to determine that the interrupt is for ISH. Each side has 32 32-bit message registers and a 32-bit doorbell. Doorbell -register has the following format: -Bits 0..6: fragment length (7 bits are used) -Bits 10..13: encapsulated protocol -Bits 16..19: management command (for IPC management protocol) -Bit 31: doorbell trigger (signal H/W interrupt to the other side) -Other bits are reserved, should be 0. +register has the following format:: + + Bits 0..6: fragment length (7 bits are used) + Bits 10..13: encapsulated protocol + Bits 16..19: management command (for IPC management protocol) + Bit 31: doorbell trigger (signal H/W interrupt to the other side) + Other bits are reserved, should be 0. 3.2.2 Transport layer interface ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -To abstract HW level IPC communication, a set of callbacks are registered. +To abstract HW level IPC communication, a set of callbacks is registered. The transport layer uses them to send and receive messages. -Refer to struct ishtp_hw_ops for callbacks. +Refer to struct ishtp_hw_ops for callbacks. 3.3 ISH Transport layer ----------------------- @@ -158,7 +159,7 @@ Location: drivers/hid/intel-ish-hid/ishtp/ The transport layer is a bi-directional protocol, which defines: - Set of commands to start, stop, connect, disconnect and flow control -(ishtp/hbm.h) for details +(see ishtp/hbm.h for details) - A flow control mechanism to avoid buffer overflows This protocol resembles bus messages described in the following document: @@ -168,14 +169,14 @@ specifications/dcmi-hi-1-0-spec.pdf "Chapter 7: Bus Message Layer" 3.3.2 Connection and Flow Control Mechanism ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Each FW client and a protocol is identified by an UUID. In order to communicate +Each FW client and a protocol is identified by a UUID. In order to communicate to a FW client, a connection must be established using connect request and response bus messages. If successful, a pair (host_client_id and fw_client_id) will identify the connection. Once connection is established, peers send each other flow control bus messages independently. Every peer may send a message only if it has received a -flow-control credit before. Once it sent a message, it may not send another one +flow-control credit before. Once it has sent a message, it may not send another one before receiving the next flow control credit. Either side can send disconnect request bus message to end communication. Also the link will be dropped if major FW reset occurs. @@ -209,7 +210,7 @@ and DMA_XFER_ACK act as ownership indicators. At initial state all outgoing memory belongs to the sender (TX to host, RX to FW), DMA_XFER transfers ownership on the region that contains ISHTP message to the receiving side, DMA_XFER_ACK returns ownership to the sender. A sender -needs not wait for previous DMA_XFER to be ack'ed, and may send another message +need not wait for previous DMA_XFER to be ack'ed, and may send another message as long as remaining continuous memory in its ownership is enough. In principle, multiple DMA_XFER and DMA_XFER_ACK messages may be sent at once (up to IPC MTU), thus allowing for interrupt throttling. @@ -219,8 +220,8 @@ fragments and via IPC otherwise. 3.3.4 Ring Buffers ^^^^^^^^^^^^^^^^^^ -When a client initiate a connection, a ring or RX and TX buffers are allocated. -The size of ring can be specified by the client. HID client set 16 and 32 for +When a client initiates a connection, a ring of RX and TX buffers is allocated. +The size of ring can be specified by the client. HID client sets 16 and 32 for TX and RX buffers respectively. On send request from client, the data to be sent is copied to one of the send ring buffer and scheduled to be sent using bus message protocol. These buffers are required because the FW may have not @@ -230,10 +231,10 @@ to send. Same thing holds true on receive side and flow control is required. 3.3.5 Host Enumeration ^^^^^^^^^^^^^^^^^^^^^^ -The host enumeration bus command allow discovery of clients present in the FW. +The host enumeration bus command allows discovery of clients present in the FW. There can be multiple sensor clients and clients for calibration function. -To ease in implantation and allow independent driver handle each client +To ease implementation and allow independent drivers to handle each client, this transport layer takes advantage of Linux Bus driver model. Each client is registered as device on the transport bus (ishtp bus). @@ -270,7 +271,7 @@ The ISHTP client driver is responsible for: The functionality in these drivers is the same as an external sensor hub. Refer to Documentation/hid/hid-sensor.rst for HID sensor -Documentation/ABI/testing/sysfs-bus-iio for IIO ABIs to user space +Documentation/ABI/testing/sysfs-bus-iio for IIO ABIs to user space. 3.6 End to End HID transport Sequence Diagram --------------------------------------------- @@ -341,9 +342,10 @@ Documentation/ABI/testing/sysfs-bus-iio for IIO ABIs to user space 3.7 ISH Debugging ----------------- -To debug ISH, event tracing mechanism is used. To enable debug logs -echo 1 > /sys/kernel/debug/tracing/events/intel_ish/enable -cat sys/kernel/debug/tracing/trace +To debug ISH, event tracing mechanism is used. To enable debug logs:: + + echo 1 > /sys/kernel/debug/tracing/events/intel_ish/enable + cat sys/kernel/debug/tracing/trace 3.8 ISH IIO sysfs Example on Lenovo thinkpad Yoga 260 ----------------------------------------------------- -- cgit v1.2.3 From 1c9003637f1ed4a62f9df6bbf7e179c4dff32116 Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Mon, 28 Dec 2020 12:53:24 -0800 Subject: Documentation: HID: hidraw editing & corrections Do basic editing & correction to hidraw.rst: - use "hidraw" consistently except at the beginning of a sentence - add archive.org URL for signal11.us since the latter seems to be MIA - use a list for 2 URLs so that they don't run together Signed-off-by: Randy Dunlap Cc: Jiri Kosina Cc: Benjamin Tissoires Cc: linux-input@vger.kernel.org Cc: Alan Ott Cc: Jonathan Corbet Cc: linux-doc@vger.kernel.org Cc: Jonathan Cameron Reviewed-by: Jonathan Cameron Signed-off-by: Jiri Kosina --- Documentation/hid/hidraw.rst | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'Documentation') diff --git a/Documentation/hid/hidraw.rst b/Documentation/hid/hidraw.rst index f41c1f0f6252..b717ee5cdaef 100644 --- a/Documentation/hid/hidraw.rst +++ b/Documentation/hid/hidraw.rst @@ -21,7 +21,7 @@ Hidraw is the only alternative, short of writing a custom kernel driver, for these non-conformant devices. A benefit of hidraw is that its use by userspace applications is independent -of the underlying hardware type. Currently, Hidraw is implemented for USB +of the underlying hardware type. Currently, hidraw is implemented for USB and Bluetooth. In the future, as new hardware bus types are developed which use the HID specification, hidraw will be expanded to add support for these new bus types. @@ -31,9 +31,10 @@ create hidraw device nodes. Udev will typically create the device nodes directly under /dev (eg: /dev/hidraw0). As this location is distribution- and udev rule-dependent, applications should use libudev to locate hidraw devices attached to the system. There is a tutorial on libudev with a -working example at: +working example at:: http://www.signal11.us/oss/udev/ + https://web.archive.org/web/2019*/www.signal11.us The HIDRAW API --------------- -- cgit v1.2.3 From ce6bf2d9ee1af23e39cc87f45674a3cfd935e1bb Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Mon, 28 Dec 2020 12:53:25 -0800 Subject: Documentation: HID: hid-sensor editing & corrections Do basic editing & correction to hid-sensor.rst: - use HID consistently instead of hid - drop a duplicate word - change article adjective an -> a - fix grammar & punctuation - spell out RW -> read-write - hyphenate multi-word adjectives Signed-off-by: Randy Dunlap Cc: Jiri Kosina Cc: Jonathan Cameron Cc: Srinivas Pandruvada Cc: linux-input@vger.kernel.org Cc: linux-iio@vger.kernel.org Cc: Jonathan Corbet Cc: linux-doc@vger.kernel.org Reviewed-by: Jonathan Cameron Signed-off-by: Jiri Kosina --- Documentation/hid/hid-sensor.rst | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) (limited to 'Documentation') diff --git a/Documentation/hid/hid-sensor.rst b/Documentation/hid/hid-sensor.rst index 758972e34971..c1c9b8d8dca6 100644 --- a/Documentation/hid/hid-sensor.rst +++ b/Documentation/hid/hid-sensor.rst @@ -48,12 +48,12 @@ for different sensors. For example an accelerometer can send X,Y and Z data, whe an ambient light sensor can send illumination data. So the implementation has two parts: -- Core hid driver +- Core HID driver - Individual sensor processing part (sensor drivers) Core driver ----------- -The core driver registers (hid-sensor-hub) registers as a HID driver. It parses +The core driver (hid-sensor-hub) registers as a HID driver. It parses report descriptors and identifies all the sensors present. It adds an MFD device with name HID-SENSOR-xxxx (where xxxx is usage id from the specification). @@ -95,14 +95,14 @@ Registration functions:: u32 usage_id, struct hid_sensor_hub_callbacks *usage_callback): -Registers callbacks for an usage id. The callback functions are not allowed +Registers callbacks for a usage id. The callback functions are not allowed to sleep:: int sensor_hub_remove_callback(struct hid_sensor_hub_device *hsdev, u32 usage_id): -Removes callbacks for an usage id. +Removes callbacks for a usage id. Parsing function:: @@ -166,7 +166,7 @@ This allows some differentiating use cases, where vendor can provide application Some common use cases are debug other sensors or to provide some events like keyboard attached/detached or lid open/close. -To allow application to utilize these sensors, here they are exported uses sysfs +To allow application to utilize these sensors, here they are exported using sysfs attribute groups, attributes and misc device interface. An example of this representation on sysfs:: @@ -207,9 +207,9 @@ An example of this representation on sysfs:: │   │   │   ├── input-1-200202-units │   │   │   ├── input-1-200202-value -Here there is a custom sensors with four fields, two feature and two inputs. +Here there is a custom sensor with four fields: two feature and two inputs. Each field is represented by a set of attributes. All fields except the "value" -are read only. The value field is a RW field. +are read only. The value field is a read-write field. Example:: @@ -237,6 +237,6 @@ These reports are pushed using misc device interface in a FIFO order:: │   │   │   ├── 10:53 -> ../HID-SENSOR-2000e1.6.auto │   ├── HID-SENSOR-2000e1.6.auto -Each reports can be of variable length preceded by a header. This header -consist of a 32 bit usage id, 64 bit time stamp and 32 bit length field of raw +Each report can be of variable length preceded by a header. This header +consists of a 32-bit usage id, 64-bit time stamp and 32-bit length field of raw data. -- cgit v1.2.3 From a14e9d72858f66f227c011106aeb102428a415e5 Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Mon, 28 Dec 2020 12:53:26 -0800 Subject: Documentation: HID: hid-transport editing & corrections Do basic editing & correction to hid-transport.rst: - s/responsible of/responsible for/ - fix grammar & punctuation Signed-off-by: Randy Dunlap Cc: Jiri Kosina Cc: Benjamin Tissoires Cc: linux-input@vger.kernel.org Cc: David Herrmann Cc: Jonathan Corbet Cc: linux-doc@vger.kernel.org Cc: Jonathan Cameron Reviewed-by: Jonathan Cameron Signed-off-by: Jiri Kosina --- Documentation/hid/hid-transport.rst | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'Documentation') diff --git a/Documentation/hid/hid-transport.rst b/Documentation/hid/hid-transport.rst index 0fe526f36db6..6f1692da296c 100644 --- a/Documentation/hid/hid-transport.rst +++ b/Documentation/hid/hid-transport.rst @@ -12,8 +12,8 @@ Bluetooth, I2C and user-space I/O drivers. The HID subsystem is designed as a bus. Any I/O subsystem may provide HID devices and register them with the HID bus. HID core then loads generic device -drivers on top of it. The transport drivers are responsible of raw data -transport and device setup/management. HID core is responsible of +drivers on top of it. The transport drivers are responsible for raw data +transport and device setup/management. HID core is responsible for report-parsing, report interpretation and the user-space API. Device specifics and quirks are handled by all layers depending on the quirk. @@ -67,7 +67,7 @@ Transport drivers attach a constant "struct hid_ll_driver" object with each device. Once a device is registered with HID core, the callbacks provided via this struct are used by HID core to communicate with the device. -Transport drivers are responsible of detecting device failures and unplugging. +Transport drivers are responsible for detecting device failures and unplugging. HID core will operate a device as long as it is registered regardless of any device failures. Once transport drivers detect unplug or failure events, they must unregister the device from HID core and HID core will stop using the @@ -101,7 +101,7 @@ properties in common. channel. Any unrequested incoming or outgoing data report must be sent on this channel and is never acknowledged by the remote side. Devices usually send their input events on this channel. Outgoing events are normally - not send via intr, except if high throughput is required. + not sent via intr, except if high throughput is required. - Control Channel (ctrl): The ctrl channel is used for synchronous requests and device management. Unrequested data input events must not be sent on this channel and are normally ignored. Instead, devices only send management @@ -161,7 +161,7 @@ allowed on the intr channel and are the only means of data there. payload may be blocked by the underlying transport driver if the specification does not allow them. - SET_REPORT: A SET_REPORT request has a report ID plus data as payload. It is - sent from host to device and a device must update it's current report state + sent from host to device and a device must update its current report state according to the given data. Any of the 3 report types can be used. However, INPUT reports as payload might be blocked by the underlying transport driver if the specification does not allow them. @@ -294,7 +294,7 @@ The available HID callbacks are: void (*request) (struct hid_device *hdev, struct hid_report *report, int reqtype) - Send an HID request on the ctrl channel. "report" contains the report that + Send a HID request on the ctrl channel. "report" contains the report that should be sent and "reqtype" the request type. Request-type can be HID_REQ_SET_REPORT or HID_REQ_GET_REPORT. -- cgit v1.2.3 From 356006a6cfb750f094b773ad8276c428887e5142 Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Mon, 28 Dec 2020 12:53:27 -0800 Subject: Documentation: HID: uhid editing & corrections Do basic editing & correction to hid-alps.rst: - correct a file name (.txt -> .rst) - use less hyphenation when not needed - fix grammar & punctuation - fix article adjectives - fix typos/spellos - use HID instead of hid consistently Signed-off-by: Randy Dunlap Cc: Jiri Kosina Cc: Benjamin Tissoires Cc: linux-input@vger.kernel.org Cc: David Herrmann Cc: Jonathan Corbet Cc: linux-doc@vger.kernel.org Cc: Jonathan Cameron Reviewed-by: Jonathan Cameron Signed-off-by: Jiri Kosina --- Documentation/hid/uhid.rst | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) (limited to 'Documentation') diff --git a/Documentation/hid/uhid.rst b/Documentation/hid/uhid.rst index b18cb96c885f..2243a6b75914 100644 --- a/Documentation/hid/uhid.rst +++ b/Documentation/hid/uhid.rst @@ -3,7 +3,7 @@ UHID - User-space I/O driver support for HID subsystem ====================================================== UHID allows user-space to implement HID transport drivers. Please see -hid-transport.txt for an introduction into HID transport drivers. This document +hid-transport.rst for an introduction into HID transport drivers. This document relies heavily on the definitions declared there. With UHID, a user-space transport driver can create kernel hid-devices for each @@ -15,7 +15,7 @@ There is an example user-space application in ./samples/uhid/uhid-example.c The UHID API ------------ -UHID is accessed through a character misc-device. The minor-number is allocated +UHID is accessed through a character misc-device. The minor number is allocated dynamically so you need to rely on udev (or similar) to create the device node. This is /dev/uhid by default. @@ -45,23 +45,23 @@ The "type" field defines the payload. For each type, there is a payload-structure available in the union "u" (except for empty payloads). This payload contains management and/or device data. -The first thing you should do is sending an UHID_CREATE2 event. This will -register the device. UHID will respond with an UHID_START event. You can now +The first thing you should do is send a UHID_CREATE2 event. This will +register the device. UHID will respond with a UHID_START event. You can now start sending data to and reading data from UHID. However, unless UHID sends the UHID_OPEN event, the internally attached HID Device Driver has no user attached. That is, you might put your device asleep unless you receive the UHID_OPEN event. If you receive the UHID_OPEN event, you should start I/O. If the last -user closes the HID device, you will receive an UHID_CLOSE event. This may be -followed by an UHID_OPEN event again and so on. There is no need to perform +user closes the HID device, you will receive a UHID_CLOSE event. This may be +followed by a UHID_OPEN event again and so on. There is no need to perform reference-counting in user-space. That is, you will never receive multiple -UHID_OPEN events without an UHID_CLOSE event. The HID subsystem performs +UHID_OPEN events without a UHID_CLOSE event. The HID subsystem performs ref-counting for you. You may decide to ignore UHID_OPEN/UHID_CLOSE, though. I/O is allowed even though the device may have no users. If you want to send data on the interrupt channel to the HID subsystem, you send -an HID_INPUT2 event with your raw data payload. If the kernel wants to send data -on the interrupt channel to the device, you will read an UHID_OUTPUT event. +a HID_INPUT2 event with your raw data payload. If the kernel wants to send data +on the interrupt channel to the device, you will read a UHID_OUTPUT event. Data requests on the control channel are currently limited to GET_REPORT and SET_REPORT (no other data reports on the control channel are defined so far). Those requests are always synchronous. That means, the kernel sends @@ -71,7 +71,7 @@ the response via UHID_GET_REPORT_REPLY and UHID_SET_REPORT_REPLY to the kernel. The kernel blocks internal driver-execution during such round-trips (times out after a hard-coded period). -If your device disconnects, you should send an UHID_DESTROY event. This will +If your device disconnects, you should send a UHID_DESTROY event. This will unregister the device. You can now send UHID_CREATE2 again to register a new device. If you close() the fd, the device is automatically unregistered and destroyed @@ -125,7 +125,7 @@ UHID_START: This is sent when the HID device is started. Consider this as an answer to UHID_CREATE2. This is always the first event that is sent. Note that this event might not be available immediately after write(UHID_CREATE2) returns. - Device drivers might required delayed setups. + Device drivers might require delayed setups. This event contains a payload of type uhid_start_req. The "dev_flags" field describes special behaviors of a device. The following flags are defined: @@ -149,7 +149,7 @@ UHID_STOP: reloaded/changed the device driver loaded on your HID device (or some other maintenance actions happened). - You can usually ignored any UHID_STOP events safely. + You can usually ignore any UHID_STOP events safely. UHID_OPEN: This is sent when the HID device is opened. That is, the data that the HID @@ -166,17 +166,17 @@ UHID_OUTPUT: This is sent if the HID device driver wants to send raw data to the I/O device on the interrupt channel. You should read the payload and forward it to the device. The payload is of type "struct uhid_output_req". - This may be received even though you haven't received UHID_OPEN, yet. + This may be received even though you haven't received UHID_OPEN yet. UHID_GET_REPORT: This event is sent if the kernel driver wants to perform a GET_REPORT request - on the control channeld as described in the HID specs. The report-type and + on the control channel as described in the HID specs. The report-type and report-number are available in the payload. The kernel serializes GET_REPORT requests so there will never be two in parallel. However, if you fail to respond with a UHID_GET_REPORT_REPLY, the request might silently time out. - Once you read a GET_REPORT request, you shall forward it to the hid device and - remember the "id" field in the payload. Once your hid device responds to the + Once you read a GET_REPORT request, you shall forward it to the HID device and + remember the "id" field in the payload. Once your HID device responds to the GET_REPORT (or if it fails), you must send a UHID_GET_REPORT_REPLY to the kernel with the exact same "id" as in the request. If the request already timed out, the kernel will ignore the response silently. The "id" field is @@ -184,7 +184,7 @@ UHID_GET_REPORT: UHID_SET_REPORT: This is the SET_REPORT equivalent of UHID_GET_REPORT. On receipt, you shall - send a SET_REPORT request to your hid device. Once it replies, you must tell + send a SET_REPORT request to your HID device. Once it replies, you must tell the kernel about it via UHID_SET_REPORT_REPLY. The same restrictions as for UHID_GET_REPORT apply. -- cgit v1.2.3 From 5f327f08192e2ff957ea43a2b4a2659663320483 Mon Sep 17 00:00:00 2001 From: Manivannan Sadhasivam Date: Mon, 4 Jan 2021 09:41:34 +0530 Subject: dt-bindings: mtd: partitions: Add binding for Qcom SMEM parser Add YAML binding for Qualcomm Shared Memory (SMEM) Flash partition parser. Signed-off-by: Manivannan Sadhasivam Reviewed-by: Rob Herring Signed-off-by: Miquel Raynal Link: https://lore.kernel.org/linux-mtd/20210104041137.113075-2-manivannan.sadhasivam@linaro.org --- .../bindings/mtd/partitions/qcom,smem-part.yaml | 33 ++++++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 Documentation/devicetree/bindings/mtd/partitions/qcom,smem-part.yaml (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/mtd/partitions/qcom,smem-part.yaml b/Documentation/devicetree/bindings/mtd/partitions/qcom,smem-part.yaml new file mode 100644 index 000000000000..cf3f8c1e035d --- /dev/null +++ b/Documentation/devicetree/bindings/mtd/partitions/qcom,smem-part.yaml @@ -0,0 +1,33 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/mtd/partitions/qcom,smem-part.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Qualcomm SMEM NAND flash partition parser binding + +maintainers: + - Manivannan Sadhasivam + +description: | + The Qualcomm SoCs supporting the NAND controller interface features a Shared + Memory (SMEM) based partition table scheme. The maximum partitions supported + varies between partition table revisions. V3 supports maximum 16 partitions + and V4 supports 48 partitions. + +properties: + compatible: + const: qcom,smem-part + +required: + - compatible + +additionalProperties: false + +examples: + - | + flash { + partitions { + compatible = "qcom,smem-part"; + }; + }; -- cgit v1.2.3 From f8c9dd2b826d8f1c23b8e86d5e4135a668a7bdd4 Mon Sep 17 00:00:00 2001 From: Sowjanya Komatineni Date: Fri, 11 Dec 2020 18:02:40 +0100 Subject: media: dt-bindings: tegra: Update csi data-lanes to maximum 8 lanes Tegra VI/CSI hardware don't have native 8 lane CSI RX port. But x8 capture can be supported by using consecutive x4 ports simultaneously with HDMI-to-CSI bridges where source image is split on to two x4 ports. This patch updates dt-bindings for csi endpoint data-lane property with maximum of 8 lanes. Acked-by: Rob Herring Acked-by: Sakari Ailus Signed-off-by: Sowjanya Komatineni Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- .../devicetree/bindings/display/tegra/nvidia,tegra20-host1x.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/display/tegra/nvidia,tegra20-host1x.txt b/Documentation/devicetree/bindings/display/tegra/nvidia,tegra20-host1x.txt index 34d993338453..8a6d3e1ee306 100644 --- a/Documentation/devicetree/bindings/display/tegra/nvidia,tegra20-host1x.txt +++ b/Documentation/devicetree/bindings/display/tegra/nvidia,tegra20-host1x.txt @@ -111,8 +111,8 @@ of the following host1x client modules: endpoint (required node) Required properties: - - data-lanes: an array of data lane from 1 to 4. Valid array - lengths are 1/2/4. + - data-lanes: an array of data lane from 1 to 8. Valid array + lengths are 1/2/4/8. - remote-endpoint: phandle to sensor 'endpoint' node. port@1 (required node) -- cgit v1.2.3 From 0f3cc7cac0e8b58a9ec1d1d76abaa9d489112c03 Mon Sep 17 00:00:00 2001 From: Michael Tretter Date: Wed, 2 Dec 2020 14:30:38 +0100 Subject: media: dt-bindings: media: allegro,al5e: Convert to YAML Convert the Allegro DVT video IP codec text binding to Yaml. Add the converted binding to the MAINTAINERS file. Signed-off-by: Michael Tretter Reviewed-by: Rob Herring Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- .../devicetree/bindings/media/allegro,al5e.yaml | 105 +++++++++++++++++++++ .../devicetree/bindings/media/allegro.txt | 43 --------- MAINTAINERS | 1 + 3 files changed, 106 insertions(+), 43 deletions(-) create mode 100644 Documentation/devicetree/bindings/media/allegro,al5e.yaml delete mode 100644 Documentation/devicetree/bindings/media/allegro.txt (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/media/allegro,al5e.yaml b/Documentation/devicetree/bindings/media/allegro,al5e.yaml new file mode 100644 index 000000000000..135bea94b587 --- /dev/null +++ b/Documentation/devicetree/bindings/media/allegro,al5e.yaml @@ -0,0 +1,105 @@ +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/media/allegro,al5e.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Allegro DVT Video IP Codecs Device Tree Bindings + +maintainers: + - Michael Tretter + +description: |- + Allegro DVT video IP codecs present in the Xilinx ZynqMP SoC. The IP core may + either be a H.264/H.265 encoder or H.264/H.265 decoder ip core. + + Each actual codec engine is controlled by a microcontroller (MCU). Host + software uses a provided mailbox interface to communicate with the MCU. The + MCUs share an interrupt. + +properties: + compatible: + oneOf: + - items: + - const: allegro,al5e-1.1 + - const: allegro,al5e + - items: + - const: allegro,al5d-1.1 + - const: allegro,al5d + + reg: + items: + - description: The registers + - description: The SRAM + + reg-names: + items: + - const: regs + - const: sram + + interrupts: + maxItems: 1 + + clocks: + items: + - description: Core clock + - description: MCU clock + - description: Core AXI master port clock + - description: MCU AXI master port clock + - description: AXI4-Lite slave port clock + + clock-names: + items: + - const: core_clk + - const: mcu_clk + - const: m_axi_core_aclk + - const: m_axi_mcu_aclk + - const: s_axi_lite_aclk + +required: + - compatible + - reg + - reg-names + - interrupts + - clocks + - clock-names + +additionalProperties: False + +examples: + - | + fpga { + #address-cells = <2>; + #size-cells = <2>; + + al5e: video-codec@a0009000 { + compatible = "allegro,al5e-1.1", "allegro,al5e"; + reg = <0 0xa0009000 0 0x1000>, + <0 0xa0000000 0 0x8000>; + reg-names = "regs", "sram"; + interrupts = <0 96 4>; + clocks = <&xlnx_vcu 0>, <&xlnx_vcu 1>, + <&clkc 71>, <&clkc 71>, <&clkc 71>; + clock-names = "core_clk", "mcu_clk", "m_axi_core_aclk", + "m_axi_mcu_aclk", "s_axi_lite_aclk"; + }; + }; + - | + fpga { + #address-cells = <2>; + #size-cells = <2>; + + al5d: video-codec@a0029000 { + compatible = "allegro,al5d-1.1", "allegro,al5d"; + reg = <0 0xa0029000 0 0x1000>, + <0 0xa0020000 0 0x8000>; + reg-names = "regs", "sram"; + interrupts = <0 96 4>; + clocks = <&xlnx_vcu 2>, <&xlnx_vcu 3>, + <&clkc 71>, <&clkc 71>, <&clkc 71>; + clock-names = "core_clk", "mcu_clk", "m_axi_core_aclk", + "m_axi_mcu_aclk", "s_axi_lite_aclk"; + }; + }; + +... diff --git a/Documentation/devicetree/bindings/media/allegro.txt b/Documentation/devicetree/bindings/media/allegro.txt deleted file mode 100644 index a92e2fbf26c9..000000000000 --- a/Documentation/devicetree/bindings/media/allegro.txt +++ /dev/null @@ -1,43 +0,0 @@ -Device-tree bindings for the Allegro DVT video IP codecs present in the Xilinx -ZynqMP SoC. The IP core may either be a H.264/H.265 encoder or H.264/H.265 -decoder ip core. - -Each actual codec engines is controlled by a microcontroller (MCU). Host -software uses a provided mailbox interface to communicate with the MCU. The -MCU share an interrupt. - -Required properties: - - compatible: value should be one of the following - "allegro,al5e-1.1", "allegro,al5e": encoder IP core - "allegro,al5d-1.1", "allegro,al5d": decoder IP core - - reg: base and length of the memory mapped register region and base and - length of the memory mapped sram - - reg-names: must include "regs" and "sram" - - interrupts: shared interrupt from the MCUs to the processing system - - clocks: must contain an entry for each entry in clock-names - - clock-names: must include "core_clk", "mcu_clk", "m_axi_core_aclk", - "m_axi_mcu_aclk", "s_axi_lite_aclk" - -Example: - al5e: video-codec@a0009000 { - compatible = "allegro,al5e-1.1", "allegro,al5e"; - reg = <0 0xa0009000 0 0x1000>, - <0 0xa0000000 0 0x8000>; - reg-names = "regs", "sram"; - interrupts = <0 96 4>; - clocks = <&xlnx_vcu 0>, <&xlnx_vcu 1>, - <&clkc 71>, <&clkc 71>, <&clkc 71>; - clock-names = "core_clk", "mcu_clk", "m_axi_core_aclk", - "m_axi_mcu_aclk", "s_axi_lite_aclk" - }; - al5d: video-codec@a0029000 { - compatible = "allegro,al5d-1.1", "allegro,al5d"; - reg = <0 0xa0029000 0 0x1000>, - <0 0xa0020000 0 0x8000>; - reg-names = "regs", "sram"; - interrupts = <0 96 4>; - clocks = <&xlnx_vcu 2>, <&xlnx_vcu 3>, - <&clkc 71>, <&clkc 71>, <&clkc 71>; - clock-names = "core_clk", "mcu_clk", "m_axi_core_aclk", - "m_axi_mcu_aclk", "s_axi_lite_aclk" - }; diff --git a/MAINTAINERS b/MAINTAINERS index a40345e0477c..471561d9d55f 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -699,6 +699,7 @@ M: Michael Tretter R: Pengutronix Kernel Team L: linux-media@vger.kernel.org S: Maintained +F: Documentation/devicetree/bindings/media/allegro,al5e.yaml F: drivers/media/platform/allegro-dvt/ ALLWINNER A10 CSI DRIVER -- cgit v1.2.3 From e33c93b2206fedee35df756940e07af7b1f29768 Mon Sep 17 00:00:00 2001 From: Adam Ford Date: Thu, 17 Dec 2020 10:27:40 -0600 Subject: ASoC: wm8962: Add optional mclk device tree binding The driver can request an optional clock for mclk. Update the txt file to reflect this. Suggested-by: Geert Uytterhoeven Signed-off-by: Adam Ford Acked-by: Charles Keepax Reviewed-by: Geert Uytterhoeven Acked-by: Rob Herring Link: https://lore.kernel.org/r/20201217162740.1452000-1-aford173@gmail.com Signed-off-by: Mark Brown --- Documentation/devicetree/bindings/sound/wm8962.txt | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/sound/wm8962.txt b/Documentation/devicetree/bindings/sound/wm8962.txt index dcfa9a3369fd..c36c649ddfd0 100644 --- a/Documentation/devicetree/bindings/sound/wm8962.txt +++ b/Documentation/devicetree/bindings/sound/wm8962.txt @@ -9,6 +9,9 @@ Required properties: - reg : the I2C address of the device. Optional properties: + + - clocks : The clock source of the mclk + - spk-mono: This is a boolean property. If present, the SPK_MONO bit of R51 (Class D Control 2) gets set, indicating that the speaker is in mono mode. @@ -27,6 +30,7 @@ Example: wm8962: codec@1a { compatible = "wlf,wm8962"; reg = <0x1a>; + clocks = <&clks IMX6QDL_CLK_CKO>; gpio-cfg = < 0x0000 /* 0:Default */ -- cgit v1.2.3 From 86e666df40c995add80a2acfb394dbce7c68dee2 Mon Sep 17 00:00:00 2001 From: Sergio Paracuellos Date: Sun, 13 Dec 2020 17:17:14 +0100 Subject: dt-bindings: pinctrl: rt2880: properly redo bindings When this bindings where applied there weren't already reviewed and some old hacks was being used to properly pass the schemas checks. This commits fix them up: - Instead of using 'if-then' clause use '-pins$'. - 'groups' and 'function' are included inside a new '^(.*-)?pinmux$' node. - compatible string is not an 'enum' but a 'const'. - 'pinctrl-0' and 'pinctrl-names' removed since they are used in consumer nodes. Signed-off-by: Sergio Paracuellos Reviewed-by: Rob Herring Reviewed-by: Linus Walleij Link: https://lore.kernel.org/r/20201213161721.6514-2-sergio.paracuellos@gmail.com Signed-off-by: Linus Walleij --- .../bindings/pinctrl/ralink,rt2880-pinmux.yaml | 62 ++++++++++------------ 1 file changed, 28 insertions(+), 34 deletions(-) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/pinctrl/ralink,rt2880-pinmux.yaml b/Documentation/devicetree/bindings/pinctrl/ralink,rt2880-pinmux.yaml index 7dea3e26d99e..b32f2676cab5 100644 --- a/Documentation/devicetree/bindings/pinctrl/ralink,rt2880-pinmux.yaml +++ b/Documentation/devicetree/bindings/pinctrl/ralink,rt2880-pinmux.yaml @@ -15,39 +15,38 @@ description: properties: compatible: - enum: - - ralink,rt2880-pinmux + const: ralink,rt2880-pinmux - pinctrl-0: - description: - A phandle to the node containing the subnodes containing default - configurations. This is for pinctrl hogs. +patternProperties: + '-pins$': + type: object + patternProperties: + '^(.*-)?pinmux$': + type: object + description: node for pinctrl. + $ref: pinmux-node.yaml# + + properties: + groups: + description: Name of the pin group to use for the functions. + enum: [i2c, spi, uart1, uart2, uart3, rgmii1, rgmii2, mdio, + pcie, sdhci] + function: + description: The mux function to select + enum: [gpio, i2c, spi, uart1, uart2, uart3, rgmii1, rgmii2, + mdio, nand1, nand2, sdhci] + + required: + - groups + - function + + additionalProperties: false - pinctrl-names: - description: - A pinctrl state named "default" can be defined. - const: default + additionalProperties: false required: - compatible -patternProperties: - '[a-z0-9_-]+': - if: - type: object - description: node for pinctrl. - $ref: "pinmux-node.yaml" - then: - properties: - groups: - description: Name of the pin group to use for the functions. - enum: [i2c, spi, uart1, uart2, uart3, rgmii1, rgmii2, mdio, - pcie, sdhci] - function: - description: The mux function to select - enum: [gpio, i2c, spi, uart1, uart2, uart3, rgmii1, rgmii2, - mdio, nand1, nand2, sdhci] - additionalProperties: false examples: @@ -55,14 +54,9 @@ examples: - | pinctrl { compatible = "ralink,rt2880-pinmux"; - pinctrl-names = "default"; - pinctrl-0 = <&state_default>; - - state_default: pinctrl0 { - }; - i2c_pins: i2c0 { - i2c0 { + i2c_pins: i2c0-pins { + pinmux { groups = "i2c"; function = "i2c"; }; -- cgit v1.2.3 From d2a704e297117cce7863b24a4fabe65930209cd3 Mon Sep 17 00:00:00 2001 From: Li Jun Date: Tue, 29 Dec 2020 19:37:43 +0800 Subject: dt-bindings: usb: dwc3-imx8mp: add imx8mp dwc3 glue bindings NXP imx8mp integrates 2 dwc3 3.30b IP and add some wakeup logic to support low power mode, the glue layer is for this wakeup functionality, which has a separated interrupt, can support wakeup from U3 and connect events for host, and vbus wakeup for device. Reviewed-by: Krzysztof Kozlowski Reviewed-by: Rob Herring Signed-off-by: Li Jun Link: https://lore.kernel.org/r/1609241866-9508-2-git-send-email-jun.li@nxp.com Signed-off-by: Greg Kroah-Hartman --- .../devicetree/bindings/usb/fsl,imx8mp-dwc3.yaml | 105 +++++++++++++++++++++ 1 file changed, 105 insertions(+) create mode 100644 Documentation/devicetree/bindings/usb/fsl,imx8mp-dwc3.yaml (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/usb/fsl,imx8mp-dwc3.yaml b/Documentation/devicetree/bindings/usb/fsl,imx8mp-dwc3.yaml new file mode 100644 index 000000000000..cb4c6f6d3a33 --- /dev/null +++ b/Documentation/devicetree/bindings/usb/fsl,imx8mp-dwc3.yaml @@ -0,0 +1,105 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +# Copyright (c) 2020 NXP +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/usb/fsl,imx8mp-dwc3.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: NXP iMX8MP Soc USB Controller + +maintainers: + - Li Jun + +properties: + compatible: + const: fsl,imx8mp-dwc3 + + reg: + maxItems: 1 + description: Address and length of the register set for the wrapper of + dwc3 core on the SOC. + + "#address-cells": + enum: [ 1, 2 ] + + "#size-cells": + enum: [ 1, 2 ] + + dma-ranges: + description: + See section 2.3.9 of the DeviceTree Specification. + + ranges: true + + interrupts: + maxItems: 1 + description: The interrupt that is asserted when a wakeup event is + received. + + clocks: + description: + A list of phandle and clock-specifier pairs for the clocks + listed in clock-names. + items: + - description: system hsio root clock. + - description: suspend clock, used for usb wakeup logic. + + clock-names: + items: + - const: hsio + - const: suspend + +# Required child node: + +patternProperties: + "^dwc3@[0-9a-f]+$": + type: object + description: + A child node must exist to represent the core DWC3 IP block + The content of the node is defined in dwc3.txt. + +required: + - compatible + - reg + - "#address-cells" + - "#size-cells" + - dma-ranges + - ranges + - clocks + - clock-names + - interrupts + +additionalProperties: false + +examples: + - | + #include + #include + usb3_0: usb@32f10100 { + compatible = "fsl,imx8mp-dwc3"; + reg = <0x32f10100 0x8>; + clocks = <&clk IMX8MP_CLK_HSIO_ROOT>, + <&clk IMX8MP_CLK_USB_ROOT>; + clock-names = "hsio", "suspend"; + interrupts = ; + #address-cells = <1>; + #size-cells = <1>; + dma-ranges = <0x40000000 0x40000000 0xc0000000>; + ranges; + + dwc3@38100000 { + compatible = "snps,dwc3"; + reg = <0x38100000 0x10000>; + clocks = <&clk IMX8MP_CLK_HSIO_AXI>, + <&clk IMX8MP_CLK_USB_CORE_REF>, + <&clk IMX8MP_CLK_USB_ROOT>; + clock-names = "bus_early", "ref", "suspend"; + assigned-clocks = <&clk IMX8MP_CLK_HSIO_AXI>; + assigned-clock-parents = <&clk IMX8MP_SYS_PLL2_500M>; + assigned-clock-rates = <500000000>; + interrupts = ; + phys = <&usb3_phy0>, <&usb3_phy0>; + phy-names = "usb2-phy", "usb3-phy"; + snps,dis-u2-freeclk-exists-quirk; + }; + }; -- cgit v1.2.3 From 14e43bf435612639cab01541fce7cc41bf7e370b Mon Sep 17 00:00:00 2001 From: Eric Biggers Date: Tue, 22 Sep 2020 09:44:18 -0700 Subject: vfs: don't unnecessarily clone write access for writable fds There's no need for mnt_want_write_file() to increment mnt_writers when the file is already open for writing, provided that mnt_drop_write_file() is changed to conditionally decrement it. We seem to have ended up in the current situation because mnt_want_write_file() used to be paired with mnt_drop_write(), due to mnt_drop_write_file() not having been added yet. So originally mnt_want_write_file() had to always increment mnt_writers. But later mnt_drop_write_file() was added, and all callers of mnt_want_write_file() were paired with it. This makes the compatibility between mnt_want_write_file() and mnt_drop_write() no longer necessary. Therefore, make __mnt_want_write_file() and __mnt_drop_write_file() skip incrementing mnt_writers on files already open for writing. This removes the only caller of mnt_clone_write(), so remove that too. Signed-off-by: Eric Biggers Signed-off-by: Al Viro --- Documentation/filesystems/porting.rst | 7 +++++ fs/namespace.c | 53 +++++++++++++---------------------- include/linux/mount.h | 1 - 3 files changed, 27 insertions(+), 34 deletions(-) (limited to 'Documentation') diff --git a/Documentation/filesystems/porting.rst b/Documentation/filesystems/porting.rst index 867036aa90b8..6a6d3e673b48 100644 --- a/Documentation/filesystems/porting.rst +++ b/Documentation/filesystems/porting.rst @@ -865,3 +865,10 @@ no matter what. Everything is handled by the caller. clone_private_mount() returns a longterm mount now, so the proper destructor of its result is kern_unmount() or kern_unmount_array(). + +--- + +**mandatory** + +mnt_want_write_file() can now only be paired with mnt_drop_write_file(), +whereas previously it could be paired with mnt_drop_write() as well. diff --git a/fs/namespace.c b/fs/namespace.c index d2db7dfe232b..9f2d94e0f3e0 100644 --- a/fs/namespace.c +++ b/fs/namespace.c @@ -359,51 +359,37 @@ int mnt_want_write(struct vfsmount *m) } EXPORT_SYMBOL_GPL(mnt_want_write); -/** - * mnt_clone_write - get write access to a mount - * @mnt: the mount on which to take a write - * - * This is effectively like mnt_want_write, except - * it must only be used to take an extra write reference - * on a mountpoint that we already know has a write reference - * on it. This allows some optimisation. - * - * After finished, mnt_drop_write must be called as usual to - * drop the reference. - */ -int mnt_clone_write(struct vfsmount *mnt) -{ - /* superblock may be r/o */ - if (__mnt_is_readonly(mnt)) - return -EROFS; - preempt_disable(); - mnt_inc_writers(real_mount(mnt)); - preempt_enable(); - return 0; -} -EXPORT_SYMBOL_GPL(mnt_clone_write); - /** * __mnt_want_write_file - get write access to a file's mount * @file: the file who's mount on which to take a write * - * This is like __mnt_want_write, but it takes a file and can - * do some optimisations if the file is open for write already + * This is like __mnt_want_write, but if the file is already open for writing it + * skips incrementing mnt_writers (since the open file already has a reference) + * and instead only does the check for emergency r/o remounts. This must be + * paired with __mnt_drop_write_file. */ int __mnt_want_write_file(struct file *file) { - if (!(file->f_mode & FMODE_WRITER)) - return __mnt_want_write(file->f_path.mnt); - else - return mnt_clone_write(file->f_path.mnt); + if (file->f_mode & FMODE_WRITER) { + /* + * Superblock may have become readonly while there are still + * writable fd's, e.g. due to a fs error with errors=remount-ro + */ + if (__mnt_is_readonly(file->f_path.mnt)) + return -EROFS; + return 0; + } + return __mnt_want_write(file->f_path.mnt); } /** * mnt_want_write_file - get write access to a file's mount * @file: the file who's mount on which to take a write * - * This is like mnt_want_write, but it takes a file and can - * do some optimisations if the file is open for write already + * This is like mnt_want_write, but if the file is already open for writing it + * skips incrementing mnt_writers (since the open file already has a reference) + * and instead only does the freeze protection and the check for emergency r/o + * remounts. This must be paired with mnt_drop_write_file. */ int mnt_want_write_file(struct file *file) { @@ -449,7 +435,8 @@ EXPORT_SYMBOL_GPL(mnt_drop_write); void __mnt_drop_write_file(struct file *file) { - __mnt_drop_write(file->f_path.mnt); + if (!(file->f_mode & FMODE_WRITER)) + __mnt_drop_write(file->f_path.mnt); } void mnt_drop_write_file(struct file *file) diff --git a/include/linux/mount.h b/include/linux/mount.h index aaf343b38671..b43191fe6af7 100644 --- a/include/linux/mount.h +++ b/include/linux/mount.h @@ -79,7 +79,6 @@ struct path; extern int mnt_want_write(struct vfsmount *mnt); extern int mnt_want_write_file(struct file *file); -extern int mnt_clone_write(struct vfsmount *mnt); extern void mnt_drop_write(struct vfsmount *mnt); extern void mnt_drop_write_file(struct file *file); extern void mntput(struct vfsmount *mnt); -- cgit v1.2.3 From be06c2577eca6d9dbf61985d4078eb904024380f Mon Sep 17 00:00:00 2001 From: "Paul E. McKenney" Date: Mon, 9 Nov 2020 08:22:16 -0800 Subject: docs: Remove redundant "``" from Requirements.rst The docbook system has learned that "()" designates a function, so this commit removes the no-longer-needed "``" to improve readability of the raw .rst file. Reported-by: Peter Zijlstra Cc: Mauro Carvalho Chehab Cc: Jonathan Corbet [ paulmck: Apply Stephen Rothwell feedback. ] Signed-off-by: Paul E. McKenney --- .../RCU/Design/Requirements/Requirements.rst | 664 ++++++++++----------- 1 file changed, 332 insertions(+), 332 deletions(-) (limited to 'Documentation') diff --git a/Documentation/RCU/Design/Requirements/Requirements.rst b/Documentation/RCU/Design/Requirements/Requirements.rst index e8c84fcc0507..9b23be637e17 100644 --- a/Documentation/RCU/Design/Requirements/Requirements.rst +++ b/Documentation/RCU/Design/Requirements/Requirements.rst @@ -72,11 +72,11 @@ understanding of this guarantee. RCU's grace-period guarantee allows updaters to wait for the completion of all pre-existing RCU read-side critical sections. An RCU read-side -critical section begins with the marker ``rcu_read_lock()`` and ends -with the marker ``rcu_read_unlock()``. These markers may be nested, and +critical section begins with the marker rcu_read_lock() and ends +with the marker rcu_read_unlock(). These markers may be nested, and RCU treats a nested set as one big RCU read-side critical section. -Production-quality implementations of ``rcu_read_lock()`` and -``rcu_read_unlock()`` are extremely lightweight, and in fact have +Production-quality implementations of rcu_read_lock() and +rcu_read_unlock() are extremely lightweight, and in fact have exactly zero overhead in Linux kernels built for production use with ``CONFIG_PREEMPT=n``. @@ -102,12 +102,12 @@ overhead to readers, for example: 15 WRITE_ONCE(y, 1); 16 } -Because the ``synchronize_rcu()`` on line 14 waits for all pre-existing -readers, any instance of ``thread0()`` that loads a value of zero from -``x`` must complete before ``thread1()`` stores to ``y``, so that +Because the synchronize_rcu() on line 14 waits for all pre-existing +readers, any instance of thread0() that loads a value of zero from +``x`` must complete before thread1() stores to ``y``, so that instance must also load a value of zero from ``y``. Similarly, any -instance of ``thread0()`` that loads a value of one from ``y`` must have -started after the ``synchronize_rcu()`` started, and must therefore also +instance of thread0() that loads a value of one from ``y`` must have +started after the synchronize_rcu() started, and must therefore also load a value of one from ``x``. Therefore, the outcome: :: @@ -121,14 +121,14 @@ cannot happen. +-----------------------------------------------------------------------+ | Wait a minute! You said that updaters can make useful forward | | progress concurrently with readers, but pre-existing readers will | -| block ``synchronize_rcu()``!!! | +| block synchronize_rcu()!!! | | Just who are you trying to fool??? | +-----------------------------------------------------------------------+ | **Answer**: | +-----------------------------------------------------------------------+ | First, if updaters do not wish to be blocked by readers, they can use | -| ``call_rcu()`` or ``kfree_rcu()``, which will be discussed later. | -| Second, even when using ``synchronize_rcu()``, the other update-side | +| call_rcu() or kfree_rcu(), which will be discussed later. | +| Second, even when using synchronize_rcu(), the other update-side | | code does run concurrently with readers, whether pre-existing or not. | +-----------------------------------------------------------------------+ @@ -170,34 +170,34 @@ recovery from node failure, more or less as follows: 29 WRITE_ONCE(state, STATE_NORMAL); 30 } -The RCU read-side critical section in ``do_something_dlm()`` works with -the ``synchronize_rcu()`` in ``start_recovery()`` to guarantee that -``do_something()`` never runs concurrently with ``recovery()``, but with -little or no synchronization overhead in ``do_something_dlm()``. +The RCU read-side critical section in do_something_dlm() works with +the synchronize_rcu() in start_recovery() to guarantee that +do_something() never runs concurrently with recovery(), but with +little or no synchronization overhead in do_something_dlm(). +-----------------------------------------------------------------------+ | **Quick Quiz**: | +-----------------------------------------------------------------------+ -| Why is the ``synchronize_rcu()`` on line 28 needed? | +| Why is the synchronize_rcu() on line 28 needed? | +-----------------------------------------------------------------------+ | **Answer**: | +-----------------------------------------------------------------------+ | Without that extra grace period, memory reordering could result in | -| ``do_something_dlm()`` executing ``do_something()`` concurrently with | -| the last bits of ``recovery()``. | +| do_something_dlm() executing do_something() concurrently with | +| the last bits of recovery(). | +-----------------------------------------------------------------------+ In order to avoid fatal problems such as deadlocks, an RCU read-side -critical section must not contain calls to ``synchronize_rcu()``. +critical section must not contain calls to synchronize_rcu(). Similarly, an RCU read-side critical section must not contain anything that waits, directly or indirectly, on completion of an invocation of -``synchronize_rcu()``. +synchronize_rcu(). Although RCU's grace-period guarantee is useful in and of itself, with `quite a few use cases `__, it would be good to be able to use RCU to coordinate read-side access to linked data structures. For this, the grace-period guarantee is not sufficient, -as can be seen in function ``add_gp_buggy()`` below. We will look at the +as can be seen in function add_gp_buggy() below. We will look at the reader's code later, but in the meantime, just think of the reader as locklessly picking up the ``gp`` pointer, and, if the value loaded is non-\ ``NULL``, locklessly accessing the ``->a`` and ``->b`` fields. @@ -256,8 +256,8 @@ Publish/Subscribe Guarantee RCU's publish-subscribe guarantee allows data to be inserted into a linked data structure without disrupting RCU readers. The updater uses -``rcu_assign_pointer()`` to insert the new data, and readers use -``rcu_dereference()`` to access data, whether new or old. The following +rcu_assign_pointer() to insert the new data, and readers use +rcu_dereference() to access data, whether new or old. The following shows an example of insertion: :: @@ -279,7 +279,7 @@ shows an example of insertion: 15 return true; 16 } -The ``rcu_assign_pointer()`` on line 13 is conceptually equivalent to a +The rcu_assign_pointer() on line 13 is conceptually equivalent to a simple assignment statement, but also guarantees that its assignment will happen after the two assignments in lines 11 and 12, similar to the C11 ``memory_order_release`` store operation. It also prevents any @@ -289,7 +289,7 @@ number of “interesting” compiler optimizations, for example, the use of +-----------------------------------------------------------------------+ | **Quick Quiz**: | +-----------------------------------------------------------------------+ -| But ``rcu_assign_pointer()`` does nothing to prevent the two | +| But rcu_assign_pointer() does nothing to prevent the two | | assignments to ``p->a`` and ``p->b`` from being reordered. Can't that | | also cause problems? | +-----------------------------------------------------------------------+ @@ -303,7 +303,7 @@ number of “interesting” compiler optimizations, for example, the use of It is tempting to assume that the reader need not do anything special to control its accesses to the RCU-protected data, as shown in -``do_something_gp_buggy()`` below: +do_something_gp_buggy() below: :: @@ -345,7 +345,7 @@ If this function ran concurrently with a series of updates that replaced the current structure with a new one, the fetches of ``gp->a`` and ``gp->b`` might well come from two different structures, which could cause serious confusion. To prevent this (and much else besides), -``do_something_gp()`` uses ``rcu_dereference()`` to fetch from ``gp``: +do_something_gp() uses rcu_dereference() to fetch from ``gp``: :: @@ -362,21 +362,21 @@ cause serious confusion. To prevent this (and much else besides), 11 return false; 12 } -The ``rcu_dereference()`` uses volatile casts and (for DEC Alpha) memory +The rcu_dereference() uses volatile casts and (for DEC Alpha) memory barriers in the Linux kernel. Should a `high-quality implementation of C11 ``memory_order_consume`` [PDF] `__ -ever appear, then ``rcu_dereference()`` could be implemented as a +ever appear, then rcu_dereference() could be implemented as a ``memory_order_consume`` load. Regardless of the exact implementation, a -pointer fetched by ``rcu_dereference()`` may not be used outside of the +pointer fetched by rcu_dereference() may not be used outside of the outermost RCU read-side critical section containing that -``rcu_dereference()``, unless protection of the corresponding data +rcu_dereference(), unless protection of the corresponding data element has been passed from RCU to some other synchronization mechanism, most commonly locking or `reference counting `__. -In short, updaters use ``rcu_assign_pointer()`` and readers use -``rcu_dereference()``, and these two RCU API elements work together to +In short, updaters use rcu_assign_pointer() and readers use +rcu_dereference(), and these two RCU API elements work together to ensure that readers have a consistent view of newly added data elements. Of course, it is also necessary to remove elements from RCU-protected @@ -388,9 +388,9 @@ data structures, for example, using the following process: the newly removed data element). #. At this point, only the updater has a reference to the newly removed data element, so it can safely reclaim the data element, for example, - by passing it to ``kfree()``. + by passing it to kfree(). -This process is implemented by ``remove_gp_synchronous()``: +This process is implemented by remove_gp_synchronous(): :: @@ -413,16 +413,16 @@ This process is implemented by ``remove_gp_synchronous()``: This function is straightforward, with line 13 waiting for a grace period before line 14 frees the old data element. This waiting ensures -that readers will reach line 7 of ``do_something_gp()`` before the data -element referenced by ``p`` is freed. The ``rcu_access_pointer()`` on -line 6 is similar to ``rcu_dereference()``, except that: +that readers will reach line 7 of do_something_gp() before the data +element referenced by ``p`` is freed. The rcu_access_pointer() on +line 6 is similar to rcu_dereference(), except that: -#. The value returned by ``rcu_access_pointer()`` cannot be +#. The value returned by rcu_access_pointer() cannot be dereferenced. If you want to access the value pointed to as well as - the pointer itself, use ``rcu_dereference()`` instead of - ``rcu_access_pointer()``. -#. The call to ``rcu_access_pointer()`` need not be protected. In - contrast, ``rcu_dereference()`` must either be within an RCU + the pointer itself, use rcu_dereference() instead of + rcu_access_pointer(). +#. The call to rcu_access_pointer() need not be protected. In + contrast, rcu_dereference() must either be within an RCU read-side critical section or in a code segment where the pointer cannot change, for example, in code protected by the corresponding update-side lock. @@ -430,13 +430,13 @@ line 6 is similar to ``rcu_dereference()``, except that: +-----------------------------------------------------------------------+ | **Quick Quiz**: | +-----------------------------------------------------------------------+ -| Without the ``rcu_dereference()`` or the ``rcu_access_pointer()``, | +| Without the rcu_dereference() or the rcu_access_pointer(), | | what destructive optimizations might the compiler make use of? | +-----------------------------------------------------------------------+ | **Answer**: | +-----------------------------------------------------------------------+ -| Let's start with what happens to ``do_something_gp()`` if it fails to | -| use ``rcu_dereference()``. It could reuse a value formerly fetched | +| Let's start with what happens to do_something_gp() if it fails to | +| use rcu_dereference(). It could reuse a value formerly fetched | | from this same pointer. It could also fetch the pointer from ``gp`` | | in a byte-at-a-time manner, resulting in *load tearing*, in turn | | resulting a bytewise mash-up of two distinct pointer values. It might | @@ -445,15 +445,15 @@ line 6 is similar to ``rcu_dereference()``, except that: | update has changed the pointer to match the wrong guess. Too bad | | about any dereferences that returned pre-initialization garbage in | | the meantime! | -| For ``remove_gp_synchronous()``, as long as all modifications to | +| For remove_gp_synchronous(), as long as all modifications to | | ``gp`` are carried out while holding ``gp_lock``, the above | | optimizations are harmless. However, ``sparse`` will complain if you | | define ``gp`` with ``__rcu`` and then access it without using either | -| ``rcu_access_pointer()`` or ``rcu_dereference()``. | +| rcu_access_pointer() or rcu_dereference(). | +-----------------------------------------------------------------------+ In short, RCU's publish-subscribe guarantee is provided by the -combination of ``rcu_assign_pointer()`` and ``rcu_dereference()``. This +combination of rcu_assign_pointer() and rcu_dereference(). This guarantee allows data elements to be safely added to RCU-protected linked data structures without disrupting RCU readers. This guarantee can be used in combination with the grace-period guarantee to also allow @@ -462,9 +462,9 @@ again without disrupting RCU readers. This guarantee was only partially premeditated. DYNIX/ptx used an explicit memory barrier for publication, but had nothing resembling -``rcu_dereference()`` for subscription, nor did it have anything +rcu_dereference() for subscription, nor did it have anything resembling the dependency-ordering barrier that was later subsumed -into ``rcu_dereference()`` and later still into ``READ_ONCE()``. The +into rcu_dereference() and later still into READ_ONCE(). The need for these operations made itself known quite suddenly at a late-1990s meeting with the DEC Alpha architects, back in the days when DEC was still a free-standing company. It took the Alpha architects a @@ -474,7 +474,7 @@ documentation did not make this point clear. More recent work with the C and C++ standards committees have provided much education on tricks and traps from the compiler. In short, compilers were much less tricky in the early 1990s, but in 2015, don't even think about omitting -``rcu_dereference()``! +rcu_dereference()! Memory-Barrier Guarantees ~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -484,31 +484,31 @@ demonstrates the need for RCU's stringent memory-ordering guarantees on systems with more than one CPU: #. Each CPU that has an RCU read-side critical section that begins - before ``synchronize_rcu()`` starts is guaranteed to execute a full + before synchronize_rcu() starts is guaranteed to execute a full memory barrier between the time that the RCU read-side critical - section ends and the time that ``synchronize_rcu()`` returns. Without + section ends and the time that synchronize_rcu() returns. Without this guarantee, a pre-existing RCU read-side critical section might hold a reference to the newly removed ``struct foo`` after the - ``kfree()`` on line 14 of ``remove_gp_synchronous()``. + kfree() on line 14 of remove_gp_synchronous(). #. Each CPU that has an RCU read-side critical section that ends after - ``synchronize_rcu()`` returns is guaranteed to execute a full memory - barrier between the time that ``synchronize_rcu()`` begins and the + synchronize_rcu() returns is guaranteed to execute a full memory + barrier between the time that synchronize_rcu() begins and the time that the RCU read-side critical section begins. Without this guarantee, a later RCU read-side critical section running after the - ``kfree()`` on line 14 of ``remove_gp_synchronous()`` might later run - ``do_something_gp()`` and find the newly deleted ``struct foo``. -#. If the task invoking ``synchronize_rcu()`` remains on a given CPU, + kfree() on line 14 of remove_gp_synchronous() might later run + do_something_gp() and find the newly deleted ``struct foo``. +#. If the task invoking synchronize_rcu() remains on a given CPU, then that CPU is guaranteed to execute a full memory barrier sometime - during the execution of ``synchronize_rcu()``. This guarantee ensures - that the ``kfree()`` on line 14 of ``remove_gp_synchronous()`` really + during the execution of synchronize_rcu(). This guarantee ensures + that the kfree() on line 14 of remove_gp_synchronous() really does execute after the removal on line 11. -#. If the task invoking ``synchronize_rcu()`` migrates among a group of +#. If the task invoking synchronize_rcu() migrates among a group of CPUs during that invocation, then each of the CPUs in that group is guaranteed to execute a full memory barrier sometime during the - execution of ``synchronize_rcu()``. This guarantee also ensures that - the ``kfree()`` on line 14 of ``remove_gp_synchronous()`` really does + execution of synchronize_rcu(). This guarantee also ensures that + the kfree() on line 14 of remove_gp_synchronous() really does execute after the removal on line 11, but also in the case where the - thread executing the ``synchronize_rcu()`` migrates in the meantime. + thread executing the synchronize_rcu() migrates in the meantime. +-----------------------------------------------------------------------+ | **Quick Quiz**: | @@ -516,19 +516,19 @@ systems with more than one CPU: | Given that multiple CPUs can start RCU read-side critical sections at | | any time without any ordering whatsoever, how can RCU possibly tell | | whether or not a given RCU read-side critical section starts before a | -| given instance of ``synchronize_rcu()``? | +| given instance of synchronize_rcu()? | +-----------------------------------------------------------------------+ | **Answer**: | +-----------------------------------------------------------------------+ | If RCU cannot tell whether or not a given RCU read-side critical | -| section starts before a given instance of ``synchronize_rcu()``, then | +| section starts before a given instance of synchronize_rcu(), then | | it must assume that the RCU read-side critical section started first. | -| In other words, a given instance of ``synchronize_rcu()`` can avoid | +| In other words, a given instance of synchronize_rcu() can avoid | | waiting on a given RCU read-side critical section only if it can | -| prove that ``synchronize_rcu()`` started first. | -| A related question is “When ``rcu_read_lock()`` doesn't generate any | +| prove that synchronize_rcu() started first. | +| A related question is “When rcu_read_lock() doesn't generate any | | code, why does it matter how it relates to a grace period?” The | -| answer is that it is not the relationship of ``rcu_read_lock()`` | +| answer is that it is not the relationship of rcu_read_lock() | | itself that is important, but rather the relationship of the code | | within the enclosed RCU read-side critical section to the code | | preceding and following the grace period. If we take this viewpoint, | @@ -556,14 +556,14 @@ systems with more than one CPU: | Yes, they really are required. To see why the first guarantee is | | required, consider the following sequence of events: | | | -| #. CPU 1: ``rcu_read_lock()`` | +| #. CPU 1: rcu_read_lock() | | #. CPU 1: ``q = rcu_dereference(gp); /* Very likely to return p. */`` | | #. CPU 0: ``list_del_rcu(p);`` | -| #. CPU 0: ``synchronize_rcu()`` starts. | +| #. CPU 0: synchronize_rcu() starts. | | #. CPU 1: ``do_something_with(q->a);`` | | ``/* No smp_mb(), so might happen after kfree(). */`` | -| #. CPU 1: ``rcu_read_unlock()`` | -| #. CPU 0: ``synchronize_rcu()`` returns. | +| #. CPU 1: rcu_read_unlock() | +| #. CPU 0: synchronize_rcu() returns. | | #. CPU 0: ``kfree(p);`` | | | | Therefore, there absolutely must be a full memory barrier between the | @@ -574,14 +574,14 @@ systems with more than one CPU: | is roughly similar: | | | | #. CPU 0: ``list_del_rcu(p);`` | -| #. CPU 0: ``synchronize_rcu()`` starts. | -| #. CPU 1: ``rcu_read_lock()`` | +| #. CPU 0: synchronize_rcu() starts. | +| #. CPU 1: rcu_read_lock() | | #. CPU 1: ``q = rcu_dereference(gp);`` | | ``/* Might return p if no memory barrier. */`` | -| #. CPU 0: ``synchronize_rcu()`` returns. | +| #. CPU 0: synchronize_rcu() returns. | | #. CPU 0: ``kfree(p);`` | | #. CPU 1: ``do_something_with(q->a); /* Boom!!! */`` | -| #. CPU 1: ``rcu_read_unlock()`` | +| #. CPU 1: rcu_read_unlock() | | | | And similarly, without a memory barrier between the beginning of the | | grace period and the beginning of the RCU read-side critical section, | @@ -597,7 +597,7 @@ systems with more than one CPU: +-----------------------------------------------------------------------+ | **Quick Quiz**: | +-----------------------------------------------------------------------+ -| You claim that ``rcu_read_lock()`` and ``rcu_read_unlock()`` generate | +| You claim that rcu_read_lock() and rcu_read_unlock() generate | | absolutely no code in some kernel builds. This means that the | | compiler might arbitrarily rearrange consecutive RCU read-side | | critical sections. Given such rearrangement, if a given RCU read-side | @@ -607,11 +607,11 @@ systems with more than one CPU: +-----------------------------------------------------------------------+ | **Answer**: | +-----------------------------------------------------------------------+ -| In cases where ``rcu_read_lock()`` and ``rcu_read_unlock()`` generate | +| In cases where rcu_read_lock() and rcu_read_unlock() generate | | absolutely no code, RCU infers quiescent states only at special | | locations, for example, within the scheduler. Because calls to | -| ``schedule()`` had better prevent calling-code accesses to shared | -| variables from being rearranged across the call to ``schedule()``, if | +| schedule() had better prevent calling-code accesses to shared | +| variables from being rearranged across the call to schedule(), if | | RCU detects the end of a given RCU read-side critical section, it | | will necessarily detect the end of all prior RCU read-side critical | | sections, no matter how aggressively the compiler scrambles the code. | @@ -655,8 +655,8 @@ read-side critical section might search for a given data element, and then might acquire the update-side spinlock in order to update that element, all while remaining in that RCU read-side critical section. Of course, it is necessary to exit the RCU read-side critical section -before invoking ``synchronize_rcu()``, however, this inconvenience can -be avoided through use of the ``call_rcu()`` and ``kfree_rcu()`` API +before invoking synchronize_rcu(), however, this inconvenience can +be avoided through use of the call_rcu() and kfree_rcu() API members described later in this document. +-----------------------------------------------------------------------+ @@ -694,10 +694,10 @@ these non-guarantees were premeditated. Readers Impose Minimal Ordering ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -Reader-side markers such as ``rcu_read_lock()`` and -``rcu_read_unlock()`` provide absolutely no ordering guarantees except +Reader-side markers such as rcu_read_lock() and +rcu_read_unlock() provide absolutely no ordering guarantees except through their interaction with the grace-period APIs such as -``synchronize_rcu()``. To see this, consider the following pair of +synchronize_rcu(). To see this, consider the following pair of threads: :: @@ -722,7 +722,7 @@ threads: 18 rcu_read_unlock(); 19 } -After ``thread0()`` and ``thread1()`` execute concurrently, it is quite +After thread0() and thread1() execute concurrently, it is quite possible to have :: @@ -730,7 +730,7 @@ possible to have (r1 == 1 && r2 == 0) (that is, ``y`` appears to have been assigned before ``x``), which would -not be possible if ``rcu_read_lock()`` and ``rcu_read_unlock()`` had +not be possible if rcu_read_lock() and rcu_read_unlock() had much in the way of ordering properties. But they do not, so the CPU is within its rights to do significant reordering. This is by design: Any significant ordering constraints would slow down these fast-path APIs. @@ -742,14 +742,14 @@ significant ordering constraints would slow down these fast-path APIs. +-----------------------------------------------------------------------+ | **Answer**: | +-----------------------------------------------------------------------+ -| No, the volatile casts in ``READ_ONCE()`` and ``WRITE_ONCE()`` | +| No, the volatile casts in READ_ONCE() and WRITE_ONCE() | | prevent the compiler from reordering in this particular case. | +-----------------------------------------------------------------------+ Readers Do Not Exclude Updaters ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -Neither ``rcu_read_lock()`` nor ``rcu_read_unlock()`` exclude updates. +Neither rcu_read_lock() nor rcu_read_unlock() exclude updates. All they do is to prevent grace periods from ending. The following example illustrates this: @@ -775,19 +775,19 @@ example illustrates this: 18 spin_unlock(&my_lock); 19 } -If the ``thread0()`` function's ``rcu_read_lock()`` excluded the -``thread1()`` function's update, the ``WARN_ON()`` could never fire. But -the fact is that ``rcu_read_lock()`` does not exclude much of anything -aside from subsequent grace periods, of which ``thread1()`` has none, so -the ``WARN_ON()`` can and does fire. +If the thread0() function's rcu_read_lock() excluded the +thread1() function's update, the WARN_ON() could never fire. But +the fact is that rcu_read_lock() does not exclude much of anything +aside from subsequent grace periods, of which thread1() has none, so +the WARN_ON() can and does fire. Updaters Only Wait For Old Readers ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -It might be tempting to assume that after ``synchronize_rcu()`` +It might be tempting to assume that after synchronize_rcu() completes, there are no readers executing. This temptation must be avoided because new readers can start immediately after -``synchronize_rcu()`` starts, and ``synchronize_rcu()`` is under no +synchronize_rcu() starts, and synchronize_rcu() is under no obligation to wait for these new readers. +-----------------------------------------------------------------------+ @@ -799,10 +799,10 @@ obligation to wait for these new readers. +-----------------------------------------------------------------------+ | **Answer**: | +-----------------------------------------------------------------------+ -| For no time at all. Even if ``synchronize_rcu()`` were to wait until | +| For no time at all. Even if synchronize_rcu() were to wait until | | all readers had completed, a new reader might start immediately after | -| ``synchronize_rcu()`` completed. Therefore, the code following | -| ``synchronize_rcu()`` can *never* rely on there being no readers. | +| synchronize_rcu() completed. Therefore, the code following | +| synchronize_rcu() can *never* rely on there being no readers. | +-----------------------------------------------------------------------+ Grace Periods Don't Partition Read-Side Critical Sections @@ -892,12 +892,12 @@ period is known to end before the second grace period starts: 28 rcu_read_unlock(); 29 } -Here, if ``(r1 == 1)``, then ``thread0()``'s write to ``b`` must happen -before the end of ``thread1()``'s grace period. If in addition -``(r4 == 1)``, then ``thread3()``'s read from ``b`` must happen after -the beginning of ``thread2()``'s grace period. If it is also the case -that ``(r2 == 1)``, then the end of ``thread1()``'s grace period must -precede the beginning of ``thread2()``'s grace period. This mean that +Here, if ``(r1 == 1)``, then thread0()'s write to ``b`` must happen +before the end of thread1()'s grace period. If in addition +``(r4 == 1)``, then thread3()'s read from ``b`` must happen after +the beginning of thread2()'s grace period. If it is also the case +that ``(r2 == 1)``, then the end of thread1()'s grace period must +precede the beginning of thread2()'s grace period. This mean that the two RCU read-side critical sections cannot overlap, guaranteeing that ``(r3 == 1)``. As a result, the outcome: @@ -1076,8 +1076,8 @@ is captured by the following list of situations: b. Wait-free read-side primitives for real-time use. This focus on read-mostly situations means that RCU must interoperate -with other synchronization primitives. For example, the ``add_gp()`` and -``remove_gp_synchronous()`` examples discussed earlier use RCU to +with other synchronization primitives. For example, the add_gp() and +remove_gp_synchronous() examples discussed earlier use RCU to protect readers and locking to coordinate updaters. However, the need extends much farther, requiring that a variety of synchronization primitives be legal within RCU read-side critical sections, including @@ -1104,11 +1104,11 @@ memory barriers. | sections. | | Note that it *is* legal for a normal RCU read-side critical section | | to conditionally acquire a sleeping locks (as in | -| ``mutex_trylock()``), but only as long as it does not loop | +| mutex_trylock()), but only as long as it does not loop | | indefinitely attempting to conditionally acquire that sleeping locks. | -| The key point is that things like ``mutex_trylock()`` either return | +| The key point is that things like mutex_trylock() either return | | with the mutex held, or return an error indication if the mutex was | -| not immediately available. Either way, ``mutex_trylock()`` returns | +| not immediately available. Either way, mutex_trylock() returns | | immediately without sleeping. | +-----------------------------------------------------------------------+ @@ -1191,57 +1191,57 @@ for those kernels not needing it. The remaining performance requirements are, for the most part, unsurprising. For example, in keeping with RCU's read-side -specialization, ``rcu_dereference()`` should have negligible overhead +specialization, rcu_dereference() should have negligible overhead (for example, suppression of a few minor compiler optimizations). -Similarly, in non-preemptible environments, ``rcu_read_lock()`` and -``rcu_read_unlock()`` should have exactly zero overhead. +Similarly, in non-preemptible environments, rcu_read_lock() and +rcu_read_unlock() should have exactly zero overhead. In preemptible environments, in the case where the RCU read-side critical section was not preempted (as will be the case for the -highest-priority real-time process), ``rcu_read_lock()`` and -``rcu_read_unlock()`` should have minimal overhead. In particular, they +highest-priority real-time process), rcu_read_lock() and +rcu_read_unlock() should have minimal overhead. In particular, they should not contain atomic read-modify-write operations, memory-barrier instructions, preemption disabling, interrupt disabling, or backwards branches. However, in the case where the RCU read-side critical section -was preempted, ``rcu_read_unlock()`` may acquire spinlocks and disable +was preempted, rcu_read_unlock() may acquire spinlocks and disable interrupts. This is why it is better to nest an RCU read-side critical section within a preempt-disable region than vice versa, at least in cases where that critical section is short enough to avoid unduly degrading real-time latencies. -The ``synchronize_rcu()`` grace-period-wait primitive is optimized for +The synchronize_rcu() grace-period-wait primitive is optimized for throughput. It may therefore incur several milliseconds of latency in addition to the duration of the longest RCU read-side critical section. On the other hand, multiple concurrent invocations of -``synchronize_rcu()`` are required to use batching optimizations so that +synchronize_rcu() are required to use batching optimizations so that they can be satisfied by a single underlying grace-period-wait operation. For example, in the Linux kernel, it is not unusual for a single grace-period-wait operation to serve more than `1,000 separate invocations `__ -of ``synchronize_rcu()``, thus amortizing the per-invocation overhead +of synchronize_rcu(), thus amortizing the per-invocation overhead down to nearly zero. However, the grace-period optimization is also required to avoid measurable degradation of real-time scheduling and interrupt latencies. -In some cases, the multi-millisecond ``synchronize_rcu()`` latencies are -unacceptable. In these cases, ``synchronize_rcu_expedited()`` may be +In some cases, the multi-millisecond synchronize_rcu() latencies are +unacceptable. In these cases, synchronize_rcu_expedited() may be used instead, reducing the grace-period latency down to a few tens of microseconds on small systems, at least in cases where the RCU read-side critical sections are short. There are currently no special latency -requirements for ``synchronize_rcu_expedited()`` on large systems, but, +requirements for synchronize_rcu_expedited() on large systems, but, consistent with the empirical nature of the RCU specification, that is subject to change. However, there most definitely are scalability -requirements: A storm of ``synchronize_rcu_expedited()`` invocations on +requirements: A storm of synchronize_rcu_expedited() invocations on 4096 CPUs should at least make reasonable forward progress. In return -for its shorter latencies, ``synchronize_rcu_expedited()`` is permitted +for its shorter latencies, synchronize_rcu_expedited() is permitted to impose modest degradation of real-time latency on non-idle online CPUs. Here, “modest” means roughly the same latency degradation as a scheduling-clock interrupt. There are a number of situations where even -``synchronize_rcu_expedited()``'s reduced grace-period latency is -unacceptable. In these situations, the asynchronous ``call_rcu()`` can -be used in place of ``synchronize_rcu()`` as follows: +synchronize_rcu_expedited()'s reduced grace-period latency is +unacceptable. In these situations, the asynchronous call_rcu() can +be used in place of synchronize_rcu() as follows: :: @@ -1275,19 +1275,19 @@ be used in place of ``synchronize_rcu()`` as follows: 28 } A definition of ``struct foo`` is finally needed, and appears on -lines 1-5. The function ``remove_gp_cb()`` is passed to ``call_rcu()`` +lines 1-5. The function remove_gp_cb() is passed to call_rcu() on line 25, and will be invoked after the end of a subsequent grace -period. This gets the same effect as ``remove_gp_synchronous()``, but +period. This gets the same effect as remove_gp_synchronous(), but without forcing the updater to wait for a grace period to elapse. The -``call_rcu()`` function may be used in a number of situations where -neither ``synchronize_rcu()`` nor ``synchronize_rcu_expedited()`` would -be legal, including within preempt-disable code, ``local_bh_disable()`` +call_rcu() function may be used in a number of situations where +neither synchronize_rcu() nor synchronize_rcu_expedited() would +be legal, including within preempt-disable code, local_bh_disable() code, interrupt-disable code, and interrupt handlers. However, even -``call_rcu()`` is illegal within NMI handlers and from idle and offline -CPUs. The callback function (``remove_gp_cb()`` in this case) will be +call_rcu() is illegal within NMI handlers and from idle and offline +CPUs. The callback function (remove_gp_cb() in this case) will be executed within softirq (software interrupt) environment within the Linux kernel, either within a real softirq handler or under the -protection of ``local_bh_disable()``. In both the Linux kernel and in +protection of local_bh_disable(). In both the Linux kernel and in userspace, it is bad practice to write an RCU callback function that takes too long. Long-running operations should be relegated to separate threads or (in the Linux kernel) workqueues. @@ -1295,23 +1295,23 @@ threads or (in the Linux kernel) workqueues. +-----------------------------------------------------------------------+ | **Quick Quiz**: | +-----------------------------------------------------------------------+ -| Why does line 19 use ``rcu_access_pointer()``? After all, | -| ``call_rcu()`` on line 25 stores into the structure, which would | +| Why does line 19 use rcu_access_pointer()? After all, | +| call_rcu() on line 25 stores into the structure, which would | | interact badly with concurrent insertions. Doesn't this mean that | -| ``rcu_dereference()`` is required? | +| rcu_dereference() is required? | +-----------------------------------------------------------------------+ | **Answer**: | +-----------------------------------------------------------------------+ | Presumably the ``->gp_lock`` acquired on line 18 excludes any | -| changes, including any insertions that ``rcu_dereference()`` would | +| changes, including any insertions that rcu_dereference() would | | protect against. Therefore, any insertions will be delayed until | | after ``->gp_lock`` is released on line 25, which in turn means that | -| ``rcu_access_pointer()`` suffices. | +| rcu_access_pointer() suffices. | +-----------------------------------------------------------------------+ -However, all that ``remove_gp_cb()`` is doing is invoking ``kfree()`` on +However, all that remove_gp_cb() is doing is invoking kfree() on the data element. This is a common idiom, and is supported by -``kfree_rcu()``, which allows “fire and forget” operation as shown +kfree_rcu(), which allows “fire and forget” operation as shown below: :: @@ -1338,20 +1338,20 @@ below: 20 return true; 21 } -Note that ``remove_gp_faf()`` simply invokes ``kfree_rcu()`` and +Note that remove_gp_faf() simply invokes kfree_rcu() and proceeds, without any need to pay any further attention to the -subsequent grace period and ``kfree()``. It is permissible to invoke -``kfree_rcu()`` from the same environments as for ``call_rcu()``. -Interestingly enough, DYNIX/ptx had the equivalents of ``call_rcu()`` -and ``kfree_rcu()``, but not ``synchronize_rcu()``. This was due to the +subsequent grace period and kfree(). It is permissible to invoke +kfree_rcu() from the same environments as for call_rcu(). +Interestingly enough, DYNIX/ptx had the equivalents of call_rcu() +and kfree_rcu(), but not synchronize_rcu(). This was due to the fact that RCU was not heavily used within DYNIX/ptx, so the very few -places that needed something like ``synchronize_rcu()`` simply +places that needed something like synchronize_rcu() simply open-coded it. +-----------------------------------------------------------------------+ | **Quick Quiz**: | +-----------------------------------------------------------------------+ -| Earlier it was claimed that ``call_rcu()`` and ``kfree_rcu()`` | +| Earlier it was claimed that call_rcu() and kfree_rcu() | | allowed updaters to avoid being blocked by readers. But how can that | | be correct, given that the invocation of the callback and the freeing | | of the memory (respectively) must still wait for a grace period to | @@ -1363,16 +1363,16 @@ open-coded it. | definition would say that updates in garbage-collected languages | | cannot complete until the next time the garbage collector runs, which | | does not seem at all reasonable. The key point is that in most cases, | -| an updater using either ``call_rcu()`` or ``kfree_rcu()`` can proceed | -| to the next update as soon as it has invoked ``call_rcu()`` or | -| ``kfree_rcu()``, without having to wait for a subsequent grace | +| an updater using either call_rcu() or kfree_rcu() can proceed | +| to the next update as soon as it has invoked call_rcu() or | +| kfree_rcu(), without having to wait for a subsequent grace | | period. | +-----------------------------------------------------------------------+ But what if the updater must wait for the completion of code to be executed after the end of the grace period, but has other tasks that can be carried out in the meantime? The polling-style -``get_state_synchronize_rcu()`` and ``cond_synchronize_rcu()`` functions +get_state_synchronize_rcu() and cond_synchronize_rcu() functions may be used for this purpose, as shown below: :: @@ -1397,11 +1397,11 @@ may be used for this purpose, as shown below: 18 return true; 19 } -On line 14, ``get_state_synchronize_rcu()`` obtains a “cookie” from RCU, +On line 14, get_state_synchronize_rcu() obtains a “cookie” from RCU, then line 15 carries out other tasks, and finally, line 16 returns immediately if a grace period has elapsed in the meantime, but otherwise waits as required. The need for ``get_state_synchronize_rcu`` and -``cond_synchronize_rcu()`` has appeared quite recently, so it is too +cond_synchronize_rcu() has appeared quite recently, so it is too early to tell whether they will stand the test of time. RCU thus provides a range of tools to allow updaters to strike the @@ -1421,8 +1421,8 @@ example, an infinite loop in an RCU read-side critical section must by definition prevent later grace periods from ever completing. For a more involved example, consider a 64-CPU system built with ``CONFIG_RCU_NOCB_CPU=y`` and booted with ``rcu_nocbs=1-63``, where -CPUs 1 through 63 spin in tight loops that invoke ``call_rcu()``. Even -if these tight loops also contain calls to ``cond_resched()`` (thus +CPUs 1 through 63 spin in tight loops that invoke call_rcu(). Even +if these tight loops also contain calls to cond_resched() (thus allowing grace periods to complete), CPU 0 simply will not be able to invoke callbacks as fast as the other 63 CPUs can register them, at least not until the system runs out of memory. In both of these @@ -1435,21 +1435,21 @@ RCU takes the following steps to encourage timely completion of grace periods: #. If a grace period fails to complete within 100 milliseconds, RCU - causes future invocations of ``cond_resched()`` on the holdout CPUs + causes future invocations of cond_resched() on the holdout CPUs to provide an RCU quiescent state. RCU also causes those CPUs' - ``need_resched()`` invocations to return ``true``, but only after the + need_resched() invocations to return ``true``, but only after the corresponding CPU's next scheduling-clock. #. CPUs mentioned in the ``nohz_full`` kernel boot parameter can run indefinitely in the kernel without scheduling-clock interrupts, which - defeats the above ``need_resched()`` strategem. RCU will therefore - invoke ``resched_cpu()`` on any ``nohz_full`` CPUs still holding out + defeats the above need_resched() strategem. RCU will therefore + invoke resched_cpu() on any ``nohz_full`` CPUs still holding out after 109 milliseconds. #. In kernels built with ``CONFIG_RCU_BOOST=y``, if a given task that has been preempted within an RCU read-side critical section is holding out for more than 500 milliseconds, RCU will resort to priority boosting. #. If a CPU is still holding out 10 seconds into the grace period, RCU - will invoke ``resched_cpu()`` on it regardless of its ``nohz_full`` + will invoke resched_cpu() on it regardless of its ``nohz_full`` state. The above values are defaults for systems running with ``HZ=1000``. They @@ -1460,7 +1460,7 @@ caution when changing them. Note that these forward-progress measures are provided only for RCU, not for `SRCU <#Sleepable%20RCU>`__ or `Tasks RCU <#Tasks%20RCU>`__. -RCU takes the following steps in ``call_rcu()`` to encourage timely +RCU takes the following steps in call_rcu() to encourage timely invocation of callbacks when any given non-\ ``rcu_nocbs`` CPU has 10,000 callbacks, or has 10,000 more callbacks than it had the last time encouragement was provided: @@ -1481,8 +1481,8 @@ RCU, not for `SRCU <#Sleepable%20RCU>`__ or `Tasks RCU <#Tasks%20RCU>`__. Even for RCU, callback-invocation forward progress for ``rcu_nocbs`` CPUs is much less well-developed, in part because workloads benefiting from ``rcu_nocbs`` CPUs tend to invoke -``call_rcu()`` relatively infrequently. If workloads emerge that need -both ``rcu_nocbs`` CPUs and high ``call_rcu()`` invocation rates, then +call_rcu() relatively infrequently. If workloads emerge that need +both ``rcu_nocbs`` CPUs and high call_rcu() invocation rates, then additional forward-progress work will be required. Composability @@ -1496,11 +1496,11 @@ in fact may be nested arbitrarily deeply. In practice, as with all real-world implementations of composable constructs, there are limitations. -Implementations of RCU for which ``rcu_read_lock()`` and -``rcu_read_unlock()`` generate no code, such as Linux-kernel RCU when +Implementations of RCU for which rcu_read_lock() and +rcu_read_unlock() generate no code, such as Linux-kernel RCU when ``CONFIG_PREEMPT=n``, can be nested arbitrarily deeply. After all, there is no overhead. Except that if all these instances of -``rcu_read_lock()`` and ``rcu_read_unlock()`` are visible to the +rcu_read_lock() and rcu_read_unlock() are visible to the compiler, compilation will eventually fail due to exhausting memory, mass storage, or user patience, whichever comes first. If the nesting is not visible to the compiler, as is the case with mutually recursive @@ -1558,11 +1558,11 @@ argue that such workloads should instead use something other than RCU, the fact remains that RCU must handle such workloads gracefully. This requirement is another factor driving batching of grace periods, but it is also the driving force behind the checks for large numbers of queued -RCU callbacks in the ``call_rcu()`` code path. Finally, high update +RCU callbacks in the call_rcu() code path. Finally, high update rates should not delay RCU read-side critical sections, although some small read-side delays can occur when using -``synchronize_rcu_expedited()``, courtesy of this function's use of -``smp_call_function_single()``. +synchronize_rcu_expedited(), courtesy of this function's use of +smp_call_function_single(). Although all three of these corner cases were understood in the early 1990s, a simple user-level test consisting of ``close(open(path))`` in a @@ -1583,45 +1583,45 @@ Software-Engineering Requirements Between Murphy's Law and “To err is human”, it is necessary to guard against mishaps and misuse: -#. It is all too easy to forget to use ``rcu_read_lock()`` everywhere +#. It is all too easy to forget to use rcu_read_lock() everywhere that it is needed, so kernels built with ``CONFIG_PROVE_RCU=y`` will - splat if ``rcu_dereference()`` is used outside of an RCU read-side + splat if rcu_dereference() is used outside of an RCU read-side critical section. Update-side code can use - ``rcu_dereference_protected()``, which takes a `lockdep + rcu_dereference_protected(), which takes a `lockdep expression `__ to indicate what is providing the protection. If the indicated protection is not provided, a lockdep splat is emitted. Code shared between readers and updaters can use - ``rcu_dereference_check()``, which also takes a lockdep expression, - and emits a lockdep splat if neither ``rcu_read_lock()`` nor the + rcu_dereference_check(), which also takes a lockdep expression, + and emits a lockdep splat if neither rcu_read_lock() nor the indicated protection is in place. In addition, - ``rcu_dereference_raw()`` is used in those (hopefully rare) cases + rcu_dereference_raw() is used in those (hopefully rare) cases where the required protection cannot be easily described. Finally, - ``rcu_read_lock_held()`` is provided to allow a function to verify + rcu_read_lock_held() is provided to allow a function to verify that it has been invoked within an RCU read-side critical section. I was made aware of this set of requirements shortly after Thomas Gleixner audited a number of RCU uses. #. A given function might wish to check for RCU-related preconditions upon entry, before using any other RCU API. The - ``rcu_lockdep_assert()`` does this job, asserting the expression in + rcu_lockdep_assert() does this job, asserting the expression in kernels having lockdep enabled and doing nothing otherwise. -#. It is also easy to forget to use ``rcu_assign_pointer()`` and - ``rcu_dereference()``, perhaps (incorrectly) substituting a simple +#. It is also easy to forget to use rcu_assign_pointer() and + rcu_dereference(), perhaps (incorrectly) substituting a simple assignment. To catch this sort of error, a given RCU-protected pointer may be tagged with ``__rcu``, after which sparse will complain about simple-assignment accesses to that pointer. Arnd Bergmann made me aware of this requirement, and also supplied the needed `patch series `__. #. Kernels built with ``CONFIG_DEBUG_OBJECTS_RCU_HEAD=y`` will splat if - a data element is passed to ``call_rcu()`` twice in a row, without a + a data element is passed to call_rcu() twice in a row, without a grace period in between. (This error is similar to a double free.) The corresponding ``rcu_head`` structures that are dynamically allocated are automatically tracked, but ``rcu_head`` structures allocated on the stack must be initialized with - ``init_rcu_head_on_stack()`` and cleaned up with - ``destroy_rcu_head_on_stack()``. Similarly, statically allocated + init_rcu_head_on_stack() and cleaned up with + destroy_rcu_head_on_stack(). Similarly, statically allocated non-stack ``rcu_head`` structures must be initialized with - ``init_rcu_head()`` and cleaned up with ``destroy_rcu_head()``. + init_rcu_head() and cleaned up with destroy_rcu_head(). Mathieu Desnoyers made me aware of this requirement, and also supplied the needed `patch `__. @@ -1638,9 +1638,9 @@ against mishaps and misuse: ``rcupdate.rcu_cpu_stall_suppress`` to suppress the splats. This kernel parameter may also be set via ``sysfs``. Furthermore, RCU CPU stall warnings are counter-productive during sysrq dumps and during - panics. RCU therefore supplies the ``rcu_sysrq_start()`` and - ``rcu_sysrq_end()`` API members to be called before and after long - sysrq dumps. RCU also supplies the ``rcu_panic()`` notifier that is + panics. RCU therefore supplies the rcu_sysrq_start() and + rcu_sysrq_end() API members to be called before and after long + sysrq dumps. RCU also supplies the rcu_panic() notifier that is automatically invoked at the beginning of a panic to suppress further RCU CPU stall warnings. @@ -1656,7 +1656,7 @@ against mishaps and misuse: synchronization mechanism, for example, reference counting. #. In kernels built with ``CONFIG_RCU_TRACE=y``, RCU-related information is provided via event tracing. -#. Open-coded use of ``rcu_assign_pointer()`` and ``rcu_dereference()`` +#. Open-coded use of rcu_assign_pointer() and rcu_dereference() to create typical linked data structures can be surprisingly error-prone. Therefore, RCU-protected `linked lists `__ and, @@ -1665,11 +1665,11 @@ against mishaps and misuse: other special-purpose RCU-protected data structures are available in the Linux kernel and the userspace RCU library. #. Some linked structures are created at compile time, but still require - ``__rcu`` checking. The ``RCU_POINTER_INITIALIZER()`` macro serves + ``__rcu`` checking. The RCU_POINTER_INITIALIZER() macro serves this purpose. -#. It is not necessary to use ``rcu_assign_pointer()`` when creating +#. It is not necessary to use rcu_assign_pointer() when creating linked structures that are to be published via a single external - pointer. The ``RCU_INIT_POINTER()`` macro is provided for this task + pointer. The RCU_INIT_POINTER() macro is provided for this task and also for assigning ``NULL`` pointers at runtime. This not a hard-and-fast list: RCU's diagnostic capabilities will @@ -1743,17 +1743,17 @@ Early Boot ~~~~~~~~~~ The Linux kernel's boot sequence is an interesting process, and RCU is -used early, even before ``rcu_init()`` is invoked. In fact, a number of +used early, even before rcu_init() is invoked. In fact, a number of RCU's primitives can be used as soon as the initial task's ``task_struct`` is available and the boot CPU's per-CPU variables are -set up. The read-side primitives (``rcu_read_lock()``, -``rcu_read_unlock()``, ``rcu_dereference()``, and -``rcu_access_pointer()``) will operate normally very early on, as will -``rcu_assign_pointer()``. +set up. The read-side primitives (rcu_read_lock(), +rcu_read_unlock(), rcu_dereference(), and +rcu_access_pointer()) will operate normally very early on, as will +rcu_assign_pointer(). -Although ``call_rcu()`` may be invoked at any time during boot, +Although call_rcu() may be invoked at any time during boot, callbacks are not guaranteed to be invoked until after all of RCU's -kthreads have been spawned, which occurs at ``early_initcall()`` time. +kthreads have been spawned, which occurs at early_initcall() time. This delay in callback invocation is due to the fact that RCU does not invoke callbacks until it is fully initialized, and this full initialization cannot occur until after the scheduler has initialized @@ -1762,22 +1762,22 @@ it would be possible to invoke callbacks earlier, however, this is not a panacea because there would be severe restrictions on what operations those callbacks could invoke. -Perhaps surprisingly, ``synchronize_rcu()`` and -``synchronize_rcu_expedited()``, will operate normally during very early +Perhaps surprisingly, synchronize_rcu() and +synchronize_rcu_expedited(), will operate normally during very early boot, the reason being that there is only one CPU and preemption is -disabled. This means that the call ``synchronize_rcu()`` (or friends) +disabled. This means that the call synchronize_rcu() (or friends) itself is a quiescent state and thus a grace period, so the early-boot implementation can be a no-op. However, once the scheduler has spawned its first kthread, this early -boot trick fails for ``synchronize_rcu()`` (as well as for -``synchronize_rcu_expedited()``) in ``CONFIG_PREEMPT=y`` kernels. The +boot trick fails for synchronize_rcu() (as well as for +synchronize_rcu_expedited()) in ``CONFIG_PREEMPT=y`` kernels. The reason is that an RCU read-side critical section might be preempted, -which means that a subsequent ``synchronize_rcu()`` really does have to +which means that a subsequent synchronize_rcu() really does have to wait for something, as opposed to simply returning immediately. -Unfortunately, ``synchronize_rcu()`` can't do this until all of its +Unfortunately, synchronize_rcu() can't do this until all of its kthreads are spawned, which doesn't happen until some time during -``early_initcalls()`` time. But this is no excuse: RCU is nevertheless +early_initcalls() time. But this is no excuse: RCU is nevertheless required to correctly handle synchronous grace periods during this time period. Once all of its kthreads are up and running, RCU starts running normally. @@ -1820,7 +1820,7 @@ Interrupts and NMIs The Linux kernel has interrupts, and RCU read-side critical sections are legal within interrupt handlers and within interrupt-disabled regions of -code, as are invocations of ``call_rcu()``. +code, as are invocations of call_rcu(). Some Linux-kernel architectures can enter an interrupt handler from non-idle process context, and then just never leave it, instead @@ -1832,7 +1832,7 @@ way during a rewrite of RCU's dyntick-idle code. The Linux kernel has non-maskable interrupts (NMIs), and RCU read-side critical sections are legal within NMI handlers. Thankfully, RCU -update-side primitives, including ``call_rcu()``, are prohibited within +update-side primitives, including call_rcu(), are prohibited within NMI handlers. The name notwithstanding, some Linux-kernel architectures can have @@ -1844,10 +1844,10 @@ that meets this requirement. Furthermore, NMI handlers can be interrupted by what appear to RCU to be normal interrupts. One way that this can happen is for code that -directly invokes ``rcu_irq_enter()`` and ``rcu_irq_exit()`` to be called +directly invokes rcu_irq_enter() and rcu_irq_exit() to be called from an NMI handler. This astonishing fact of life prompted the current -code structure, which has ``rcu_irq_enter()`` invoking -``rcu_nmi_enter()`` and ``rcu_irq_exit()`` invoking ``rcu_nmi_exit()``. +code structure, which has rcu_irq_enter() invoking +rcu_nmi_enter() and rcu_irq_exit() invoking rcu_nmi_exit(). And yes, I also learned of this requirement the hard way. Loadable Modules @@ -1857,45 +1857,45 @@ The Linux kernel has loadable modules, and these modules can also be unloaded. After a given module has been unloaded, any attempt to call one of its functions results in a segmentation fault. The module-unload functions must therefore cancel any delayed calls to loadable-module -functions, for example, any outstanding ``mod_timer()`` must be dealt -with via ``del_timer_sync()`` or similar. +functions, for example, any outstanding mod_timer() must be dealt +with via del_timer_sync() or similar. Unfortunately, there is no way to cancel an RCU callback; once you -invoke ``call_rcu()``, the callback function is eventually going to be +invoke call_rcu(), the callback function is eventually going to be invoked, unless the system goes down first. Because it is normally considered socially irresponsible to crash the system in response to a module unload request, we need some other way to deal with in-flight RCU callbacks. -RCU therefore provides ``rcu_barrier()``, which waits until all +RCU therefore provides rcu_barrier(), which waits until all in-flight RCU callbacks have been invoked. If a module uses -``call_rcu()``, its exit function should therefore prevent any future -invocation of ``call_rcu()``, then invoke ``rcu_barrier()``. In theory, -the underlying module-unload code could invoke ``rcu_barrier()`` +call_rcu(), its exit function should therefore prevent any future +invocation of call_rcu(), then invoke rcu_barrier(). In theory, +the underlying module-unload code could invoke rcu_barrier() unconditionally, but in practice this would incur unacceptable latencies. Nikita Danilov noted this requirement for an analogous filesystem-unmount situation, and Dipankar Sarma incorporated -``rcu_barrier()`` into RCU. The need for ``rcu_barrier()`` for module +rcu_barrier() into RCU. The need for rcu_barrier() for module unloading became apparent later. .. important:: - The ``rcu_barrier()`` function is not, repeat, + The rcu_barrier() function is not, repeat, *not*, obligated to wait for a grace period. It is instead only required to wait for RCU callbacks that have already been posted. Therefore, if there are no RCU callbacks posted anywhere in the system, - ``rcu_barrier()`` is within its rights to return immediately. Even if - there are callbacks posted, ``rcu_barrier()`` does not necessarily need + rcu_barrier() is within its rights to return immediately. Even if + there are callbacks posted, rcu_barrier() does not necessarily need to wait for a grace period. +-----------------------------------------------------------------------+ | **Quick Quiz**: | +-----------------------------------------------------------------------+ | Wait a minute! Each RCU callbacks must wait for a grace period to | -| complete, and ``rcu_barrier()`` must wait for each pre-existing | -| callback to be invoked. Doesn't ``rcu_barrier()`` therefore need to | +| complete, and rcu_barrier() must wait for each pre-existing | +| callback to be invoked. Doesn't rcu_barrier() therefore need to | | wait for a full grace period if there is even one callback posted | | anywhere in the system? | +-----------------------------------------------------------------------+ @@ -1904,14 +1904,14 @@ unloading became apparent later. | Absolutely not!!! | | Yes, each RCU callbacks must wait for a grace period to complete, but | | it might well be partly (or even completely) finished waiting by the | -| time ``rcu_barrier()`` is invoked. In that case, ``rcu_barrier()`` | +| time rcu_barrier() is invoked. In that case, rcu_barrier() | | need only wait for the remaining portion of the grace period to | | elapse. So even if there are quite a few callbacks posted, | -| ``rcu_barrier()`` might well return quite quickly. | +| rcu_barrier() might well return quite quickly. | | | | So if you need to wait for a grace period as well as for all | | pre-existing callbacks, you will need to invoke both | -| ``synchronize_rcu()`` and ``rcu_barrier()``. If latency is a concern, | +| synchronize_rcu() and rcu_barrier(). If latency is a concern, | | you can always use workqueues to invoke them concurrently. | +-----------------------------------------------------------------------+ @@ -1929,18 +1929,18 @@ The Linux-kernel CPU-hotplug implementation has notifiers that are used to allow the various kernel subsystems (including RCU) to respond appropriately to a given CPU-hotplug operation. Most RCU operations may be invoked from CPU-hotplug notifiers, including even synchronous -grace-period operations such as (``synchronize_rcu()`` and -``synchronize_rcu_expedited()``). However, these synchronous operations +grace-period operations such as (synchronize_rcu() and +synchronize_rcu_expedited()). However, these synchronous operations do block and therefore cannot be invoked from notifiers that execute via -``stop_machine()``, specifically those between the ``CPUHP_AP_OFFLINE`` +stop_machine(), specifically those between the ``CPUHP_AP_OFFLINE`` and ``CPUHP_AP_ONLINE`` states. -In addition, all-callback-wait operations such as ``rcu_barrier()`` may +In addition, all-callback-wait operations such as rcu_barrier() may not be invoked from any CPU-hotplug notifier. This restriction is due to the fact that there are phases of CPU-hotplug operations where the outgoing CPU's callbacks will not be invoked until after the CPU-hotplug operation ends, which could also result in deadlock. Furthermore, -``rcu_barrier()`` blocks CPU-hotplug operations during its execution, +rcu_barrier() blocks CPU-hotplug operations during its execution, which results in another type of deadlock when invoked from a CPU-hotplug notifier. @@ -1955,12 +1955,12 @@ if offline CPUs block an RCU grace period for too long. An offline CPU's quiescent state will be reported either: -1. As the CPU goes offline using RCU's hotplug notifier (``rcu_report_dead()``). -2. When grace period initialization (``rcu_gp_init()``) detects a +1. As the CPU goes offline using RCU's hotplug notifier (rcu_report_dead()). +2. When grace period initialization (rcu_gp_init()) detects a race either with CPU offlining or with a task unblocking on a leaf ``rcu_node`` structure whose CPUs are all offline. -The CPU-online path (``rcu_cpu_starting()``) should never need to report +The CPU-online path (rcu_cpu_starting()) should never need to report a quiescent state for an offline CPU. However, as a debugging measure, it does emit a warning if a quiescent state was not already reported for that CPU. @@ -1984,11 +1984,11 @@ room for further improvement. There is no longer any prohibition against holding any of scheduler's runqueue or priority-inheritance spinlocks across an -``rcu_read_unlock()``, even if interrupts and preemption were enabled +rcu_read_unlock(), even if interrupts and preemption were enabled somewhere within the corresponding RCU read-side critical section. -Therefore, it is now perfectly legal to execute ``rcu_read_lock()`` +Therefore, it is now perfectly legal to execute rcu_read_lock() with preemption enabled, acquire one of the scheduler locks, and hold -that lock across the matching ``rcu_read_unlock()``. +that lock across the matching rcu_read_unlock(). Similarly, the RCU flavor consolidation has removed the need for negative nesting. The fact that interrupt-disabled regions of code act as RCU @@ -1999,7 +1999,7 @@ Tracing and RCU ~~~~~~~~~~~~~~~ It is possible to use tracing on RCU code, but tracing itself uses RCU. -For this reason, ``rcu_dereference_raw_check()`` is provided for use +For this reason, rcu_dereference_raw_check() is provided for use by tracing, which avoids the destructive recursion that could otherwise ensue. This API is also used by virtualization in some architectures, where RCU readers execute in environments in which tracing cannot be @@ -2010,12 +2010,12 @@ Accesses to User Memory and RCU ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ The kernel needs to access user-space memory, for example, to access data -referenced by system-call parameters. The ``get_user()`` macro does this job. +referenced by system-call parameters. The get_user() macro does this job. However, user-space memory might well be paged out, which means that -``get_user()`` might well page-fault and thus block while waiting for the +get_user() might well page-fault and thus block while waiting for the resulting I/O to complete. It would be a very bad thing for the compiler to -reorder a ``get_user()`` invocation into an RCU read-side critical section. +reorder a get_user() invocation into an RCU read-side critical section. For example, suppose that the source code looked like this: @@ -2041,22 +2041,22 @@ the following: 6 do_something_with(v, user_v); If the compiler did make this transformation in a ``CONFIG_PREEMPT=n`` kernel -build, and if ``get_user()`` did page fault, the result would be a quiescent +build, and if get_user() did page fault, the result would be a quiescent state in the middle of an RCU read-side critical section. This misplaced quiescent state could result in line 4 being a use-after-free access, which could be bad for your kernel's actuarial statistics. Similar examples -can be constructed with the call to ``get_user()`` preceding the -``rcu_read_lock()``. +can be constructed with the call to get_user() preceding the +rcu_read_lock(). -Unfortunately, ``get_user()`` doesn't have any particular ordering properties, +Unfortunately, get_user() doesn't have any particular ordering properties, and in some architectures the underlying ``asm`` isn't even marked ``volatile``. And even if it was marked ``volatile``, the above access to ``p->value`` is not volatile, so the compiler would not have any reason to keep those two accesses in order. -Therefore, the Linux-kernel definitions of ``rcu_read_lock()`` and -``rcu_read_unlock()`` must act as compiler barriers, at least for outermost -instances of ``rcu_read_lock()`` and ``rcu_read_unlock()`` within a nested set +Therefore, the Linux-kernel definitions of rcu_read_lock() and +rcu_read_unlock() must act as compiler barriers, at least for outermost +instances of rcu_read_lock() and rcu_read_unlock() within a nested set of RCU read-side critical sections. Energy Efficiency @@ -2071,26 +2071,26 @@ call. Because RCU avoids interrupting idle CPUs, it is illegal to execute an RCU read-side critical section on an idle CPU. (Kernels built with -``CONFIG_PROVE_RCU=y`` will splat if you try it.) The ``RCU_NONIDLE()`` +``CONFIG_PROVE_RCU=y`` will splat if you try it.) The RCU_NONIDLE() macro and ``_rcuidle`` event tracing is provided to work around this -restriction. In addition, ``rcu_is_watching()`` may be used to test +restriction. In addition, rcu_is_watching() may be used to test whether or not it is currently legal to run RCU read-side critical sections on this CPU. I learned of the need for diagnostics on the one -hand and ``RCU_NONIDLE()`` on the other while inspecting idle-loop code. +hand and RCU_NONIDLE() on the other while inspecting idle-loop code. Steven Rostedt supplied ``_rcuidle`` event tracing, which is used quite heavily in the idle loop. However, there are some restrictions on the -code placed within ``RCU_NONIDLE()``: +code placed within RCU_NONIDLE(): #. Blocking is prohibited. In practice, this is not a serious restriction given that idle tasks are prohibited from blocking to begin with. -#. Although nesting ``RCU_NONIDLE()`` is permitted, they cannot nest +#. Although nesting RCU_NONIDLE() is permitted, they cannot nest indefinitely deeply. However, given that they can be nested on the order of a million deep, even on 32-bit systems, this should not be a serious restriction. This nesting limit would probably be reached long after the compiler OOMed or the stack overflowed. -#. Any code path that enters ``RCU_NONIDLE()`` must sequence out of that - same ``RCU_NONIDLE()``. For example, the following is grossly +#. Any code path that enters RCU_NONIDLE() must sequence out of that + same RCU_NONIDLE(). For example, the following is grossly illegal: :: @@ -2103,7 +2103,7 @@ code placed within ``RCU_NONIDLE()``: It is just as illegal to transfer control into the middle of - ``RCU_NONIDLE()``'s argument. Yes, in theory, you could transfer in + RCU_NONIDLE()'s argument. Yes, in theory, you could transfer in as long as you also transferred out, but in practice you could also expect to get sharply worded review comments. @@ -2195,9 +2195,9 @@ scheduling-clock interrupt be enabled when RCU needs it to be: sections, and RCU believes this CPU to be idle, no problem. This sort of thing is used by some architectures for light-weight exception handlers, which can then avoid the overhead of - ``rcu_irq_enter()`` and ``rcu_irq_exit()`` at exception entry and + rcu_irq_enter() and rcu_irq_exit() at exception entry and exit, respectively. Some go further and avoid the entireties of - ``irq_enter()`` and ``irq_exit()``. + irq_enter() and irq_exit(). Just make very sure you are running some of your tests with ``CONFIG_PROVE_RCU=y``, just in case one of your code paths was in fact joking about not doing RCU read-side critical sections. @@ -2221,7 +2221,7 @@ scheduling-clock interrupt be enabled when RCU needs it to be: | **Quick Quiz**: | +-----------------------------------------------------------------------+ | But what if my driver has a hardware interrupt handler that can run | -| for many seconds? I cannot invoke ``schedule()`` from an hardware | +| for many seconds? I cannot invoke schedule() from an hardware | | interrupt handler, after all! | +-----------------------------------------------------------------------+ | **Answer**: | @@ -2243,8 +2243,8 @@ Memory Efficiency Although small-memory non-realtime systems can simply use Tiny RCU, code size is only one aspect of memory efficiency. Another aspect is the size -of the ``rcu_head`` structure used by ``call_rcu()`` and -``kfree_rcu()``. Although this structure contains nothing more than a +of the ``rcu_head`` structure used by call_rcu() and +kfree_rcu(). Although this structure contains nothing more than a pair of pointers, it does appear in many RCU-protected data structures, including some that are size critical. The ``page`` structure is a case in point, as evidenced by the many occurrences of the ``union`` keyword @@ -2254,7 +2254,7 @@ This need for memory efficiency is one reason that RCU uses hand-crafted singly linked lists to track the ``rcu_head`` structures that are waiting for a grace period to elapse. It is also the reason why ``rcu_head`` structures do not contain debug information, such as fields -tracking the file and line of the ``call_rcu()`` or ``kfree_rcu()`` that +tracking the file and line of the call_rcu() or kfree_rcu() that posted them. Although this information might appear in debug-only kernel builds at some point, in the meantime, the ``->func`` field will often provide the needed debug information. @@ -2268,14 +2268,14 @@ conditions next`` field. RCU makes this guarantee as long as ``call_rcu()`` is -used to post the callback, as opposed to ``kfree_rcu()`` or some future -“lazy” variant of ``call_rcu()`` that might one day be created for +``->next`` field. RCU makes this guarantee as long as call_rcu() is +used to post the callback, as opposed to kfree_rcu() or some future +“lazy” variant of call_rcu() that might one day be created for energy-efficiency purposes. That said, there are limits. RCU requires that the ``rcu_head`` structure be aligned to a two-byte boundary, and passing a misaligned -``rcu_head`` structure to one of the ``call_rcu()`` family of functions +``rcu_head`` structure to one of the call_rcu() family of functions will result in a splat. It is therefore necessary to exercise caution when packing structures containing fields of type ``rcu_head``. Why not a four-byte or even eight-byte alignment requirement? Because the m68k @@ -2299,7 +2299,7 @@ hot code paths in performance-critical portions of the Linux kernel's networking, security, virtualization, and scheduling code paths. RCU must therefore use efficient implementations, especially in its read-side primitives. To that end, it would be good if preemptible RCU's -implementation of ``rcu_read_lock()`` could be inlined, however, doing +implementation of rcu_read_lock() could be inlined, however, doing this requires resolving ``#include`` issues with the ``task_struct`` structure. @@ -2312,8 +2312,8 @@ on the ``rcu_node`` structure. RCU is required to tolerate all CPUs continuously invoking any combination of RCU's runtime primitives with minimal per-operation overhead. In fact, in many cases, increasing load must *decrease* the per-operation overhead, witness the batching -optimizations for ``synchronize_rcu()``, ``call_rcu()``, -``synchronize_rcu_expedited()``, and ``rcu_barrier()``. As a general +optimizations for synchronize_rcu(), call_rcu(), +synchronize_rcu_expedited(), and rcu_barrier(). As a general rule, RCU must cheerfully accept whatever the rest of the Linux kernel decides to throw at it. @@ -2346,7 +2346,7 @@ number of race conditions. RCU must avoid degrading real-time response for CPU-bound threads, whether executing in usermode (which is one use case for ``CONFIG_NO_HZ_FULL=y``) or in the kernel. That said, CPU-bound loops in -the kernel must execute ``cond_resched()`` at least once per few tens of +the kernel must execute cond_resched() at least once per few tens of milliseconds in order to avoid receiving an IPI from RCU. Finally, RCU's status as a synchronization primitive means that any RCU @@ -2412,7 +2412,7 @@ grace periods from ever ending. The result was an out-of-memory condition and a system hang. The solution was the creation of RCU-bh, which does -``local_bh_disable()`` across its read-side critical sections, and which +local_bh_disable() across its read-side critical sections, and which uses the transition from one type of softirq processing to another as a quiescent state in addition to context switch, idle, user mode, and offline. This means that RCU-bh grace periods can complete even when @@ -2420,29 +2420,29 @@ some of the CPUs execute in softirq indefinitely, thus allowing algorithms based on RCU-bh to withstand network-based denial-of-service attacks. -Because ``rcu_read_lock_bh()`` and ``rcu_read_unlock_bh()`` disable and +Because rcu_read_lock_bh() and rcu_read_unlock_bh() disable and re-enable softirq handlers, any attempt to start a softirq handlers during the RCU-bh read-side critical section will be deferred. In this -case, ``rcu_read_unlock_bh()`` will invoke softirq processing, which can +case, rcu_read_unlock_bh() will invoke softirq processing, which can take considerable time. One can of course argue that this softirq overhead should be associated with the code following the RCU-bh -read-side critical section rather than ``rcu_read_unlock_bh()``, but the +read-side critical section rather than rcu_read_unlock_bh(), but the fact is that most profiling tools cannot be expected to make this sort of fine distinction. For example, suppose that a three-millisecond-long RCU-bh read-side critical section executes during a time of heavy networking load. There will very likely be an attempt to invoke at least one softirq handler during that three milliseconds, but any such invocation will be delayed until the time of the -``rcu_read_unlock_bh()``. This can of course make it appear at first -glance as if ``rcu_read_unlock_bh()`` was executing very slowly. +rcu_read_unlock_bh(). This can of course make it appear at first +glance as if rcu_read_unlock_bh() was executing very slowly. The `RCU-bh API `__ -includes ``rcu_read_lock_bh()``, ``rcu_read_unlock_bh()``, -``rcu_dereference_bh()``, ``rcu_dereference_bh_check()``, -``synchronize_rcu_bh()``, ``synchronize_rcu_bh_expedited()``, -``call_rcu_bh()``, ``rcu_barrier_bh()``, and -``rcu_read_lock_bh_held()``. However, the update-side APIs are now +includes rcu_read_lock_bh(), rcu_read_unlock_bh(), +rcu_dereference_bh(), rcu_dereference_bh_check(), +synchronize_rcu_bh(), synchronize_rcu_bh_expedited(), +call_rcu_bh(), rcu_barrier_bh(), and +rcu_read_lock_bh_held(). However, the update-side APIs are now simple wrappers for other RCU flavors, namely RCU-sched in CONFIG_PREEMPT=n kernels and RCU-preempt otherwise. @@ -2467,27 +2467,27 @@ RCU-sched APIs have identical implementations, while kernels built with ``CONFIG_PREEMPT=y`` provide a separate implementation for each. Note well that in ``CONFIG_PREEMPT=y`` kernels, -``rcu_read_lock_sched()`` and ``rcu_read_unlock_sched()`` disable and +rcu_read_lock_sched() and rcu_read_unlock_sched() disable and re-enable preemption, respectively. This means that if there was a preemption attempt during the RCU-sched read-side critical section, -``rcu_read_unlock_sched()`` will enter the scheduler, with all the -latency and overhead entailed. Just as with ``rcu_read_unlock_bh()``, -this can make it look as if ``rcu_read_unlock_sched()`` was executing +rcu_read_unlock_sched() will enter the scheduler, with all the +latency and overhead entailed. Just as with rcu_read_unlock_bh(), +this can make it look as if rcu_read_unlock_sched() was executing very slowly. However, the highest-priority task won't be preempted, so -that task will enjoy low-overhead ``rcu_read_unlock_sched()`` +that task will enjoy low-overhead rcu_read_unlock_sched() invocations. The `RCU-sched API `__ -includes ``rcu_read_lock_sched()``, ``rcu_read_unlock_sched()``, -``rcu_read_lock_sched_notrace()``, ``rcu_read_unlock_sched_notrace()``, -``rcu_dereference_sched()``, ``rcu_dereference_sched_check()``, -``synchronize_sched()``, ``synchronize_rcu_sched_expedited()``, -``call_rcu_sched()``, ``rcu_barrier_sched()``, and -``rcu_read_lock_sched_held()``. However, anything that disables +includes rcu_read_lock_sched(), rcu_read_unlock_sched(), +rcu_read_lock_sched_notrace(), rcu_read_unlock_sched_notrace(), +rcu_dereference_sched(), rcu_dereference_sched_check(), +synchronize_sched(), synchronize_rcu_sched_expedited(), +call_rcu_sched(), rcu_barrier_sched(), and +rcu_read_lock_sched_held(). However, anything that disables preemption also marks an RCU-sched read-side critical section, including -``preempt_disable()`` and ``preempt_enable()``, ``local_irq_save()`` and -``local_irq_restore()``, and so on. +preempt_disable() and preempt_enable(), local_irq_save() and +local_irq_restore(), and so on. Sleepable RCU ~~~~~~~~~~~~~ @@ -2509,7 +2509,7 @@ this structure must be passed in to each SRCU function, for example, structure. The key benefit of these domains is that a slow SRCU reader in one domain does not delay an SRCU grace period in some other domain. That said, one consequence of these domains is that read-side code must -pass a “cookie” from ``srcu_read_lock()`` to ``srcu_read_unlock()``, for +pass a “cookie” from srcu_read_lock() to srcu_read_unlock(), for example, as follows: :: @@ -2539,24 +2539,24 @@ period to elapse. For example, this results in a self-deadlock: 6 srcu_read_unlock(&ss, idx); However, if line 5 acquired a mutex that was held across a -``synchronize_srcu()`` for domain ``ss``, deadlock would still be +synchronize_srcu() for domain ``ss``, deadlock would still be possible. Furthermore, if line 5 acquired a mutex that was held across a -``synchronize_srcu()`` for some other domain ``ss1``, and if an +synchronize_srcu() for some other domain ``ss1``, and if an ``ss1``-domain SRCU read-side critical section acquired another mutex -that was held across as ``ss``-domain ``synchronize_srcu()``, deadlock +that was held across as ``ss``-domain synchronize_srcu(), deadlock would again be possible. Such a deadlock cycle could extend across an arbitrarily large number of different SRCU domains. Again, with great power comes great responsibility. Unlike the other RCU flavors, SRCU read-side critical sections can run on idle and even offline CPUs. This ability requires that -``srcu_read_lock()`` and ``srcu_read_unlock()`` contain memory barriers, +srcu_read_lock() and srcu_read_unlock() contain memory barriers, which means that SRCU readers will run a bit slower than would RCU -readers. It also motivates the ``smp_mb__after_srcu_read_unlock()`` API, -which, in combination with ``srcu_read_unlock()``, guarantees a full +readers. It also motivates the smp_mb__after_srcu_read_unlock() API, +which, in combination with srcu_read_unlock(), guarantees a full memory barrier. -Also unlike other RCU flavors, ``synchronize_srcu()`` may **not** be +Also unlike other RCU flavors, synchronize_srcu() may **not** be invoked from CPU-hotplug notifiers, due to the fact that SRCU grace periods make use of timers and the possibility of timers being temporarily “stranded” on the outgoing CPU. This stranding of timers @@ -2565,7 +2565,7 @@ the CPU-hotplug process. The problem is that if a notifier is waiting on an SRCU grace period, that grace period is waiting on a timer, and that timer is stranded on the outgoing CPU, then the notifier will never be awakened, in other words, deadlock has occurred. This same situation of -course also prohibits ``srcu_barrier()`` from being invoked from +course also prohibits srcu_barrier() from being invoked from CPU-hotplug notifiers. SRCU also differs from other RCU flavors in that SRCU's expedited and @@ -2576,12 +2576,12 @@ have not yet completed. (But please note that this is a property of the current implementation, not necessarily of future implementations.) In addition, if SRCU has been idle for longer than the interval specified by the ``srcutree.exp_holdoff`` kernel boot parameter (25 microseconds -by default), and if a ``synchronize_srcu()`` invocation ends this idle +by default), and if a synchronize_srcu() invocation ends this idle period, that invocation will be automatically expedited. As of v4.12, SRCU's callbacks are maintained per-CPU, eliminating a locking bottleneck present in prior kernel versions. Although this will -allow users to put much heavier stress on ``call_srcu()``, it is +allow users to put much heavier stress on call_srcu(), it is important to note that SRCU does not yet take any special steps to deal with callback flooding. So if you are posting (say) 10,000 SRCU callbacks per second per CPU, you are probably totally OK, but if you @@ -2592,12 +2592,12 @@ of your CPUs and the size of your memory. The `SRCU API `__ -includes ``srcu_read_lock()``, ``srcu_read_unlock()``, -``srcu_dereference()``, ``srcu_dereference_check()``, -``synchronize_srcu()``, ``synchronize_srcu_expedited()``, -``call_srcu()``, ``srcu_barrier()``, and ``srcu_read_lock_held()``. It -also includes ``DEFINE_SRCU()``, ``DEFINE_STATIC_SRCU()``, and -``init_srcu_struct()`` APIs for defining and initializing +includes srcu_read_lock(), srcu_read_unlock(), +srcu_dereference(), srcu_dereference_check(), +synchronize_srcu(), synchronize_srcu_expedited(), +call_srcu(), srcu_barrier(), and srcu_read_lock_held(). It +also includes DEFINE_SRCU(), DEFINE_STATIC_SRCU(), and +init_srcu_struct() APIs for defining and initializing ``srcu_struct`` structures. Tasks RCU @@ -2608,11 +2608,11 @@ required to install different types of probes. It would be good to be able to free old trampolines, which sounds like a job for some form of RCU. However, because it is necessary to be able to install a trace anywhere in the code, it is not possible to use read-side markers such -as ``rcu_read_lock()`` and ``rcu_read_unlock()``. In addition, it does +as rcu_read_lock() and rcu_read_unlock(). In addition, it does not work to have these markers in the trampoline itself, because there -would need to be instructions following ``rcu_read_unlock()``. Although -``synchronize_rcu()`` would guarantee that execution reached the -``rcu_read_unlock()``, it would not be able to guarantee that execution +would need to be instructions following rcu_read_unlock(). Although +synchronize_rcu() would guarantee that execution reached the +rcu_read_unlock(), it would not be able to guarantee that execution had completely left the trampoline. Worse yet, in some situations the trampoline's protection must extend a few instructions *prior* to execution reaching the trampoline. For example, these few instructions @@ -2623,15 +2623,15 @@ actually reached the trampoline itself. The solution, in the form of `Tasks RCU `__, is to have implicit read-side critical sections that are delimited by voluntary context switches, that -is, calls to ``schedule()``, ``cond_resched()``, and -``synchronize_rcu_tasks()``. In addition, transitions to and from +is, calls to schedule(), cond_resched(), and +synchronize_rcu_tasks(). In addition, transitions to and from userspace execution also delimit tasks-RCU read-side critical sections. The tasks-RCU API is quite compact, consisting only of -``call_rcu_tasks()``, ``synchronize_rcu_tasks()``, and -``rcu_barrier_tasks()``. In ``CONFIG_PREEMPT=n`` kernels, trampolines -cannot be preempted, so these APIs map to ``call_rcu()``, -``synchronize_rcu()``, and ``rcu_barrier()``, respectively. In +call_rcu_tasks(), synchronize_rcu_tasks(), and +rcu_barrier_tasks(). In ``CONFIG_PREEMPT=n`` kernels, trampolines +cannot be preempted, so these APIs map to call_rcu(), +synchronize_rcu(), and rcu_barrier(), respectively. In ``CONFIG_PREEMPT=y`` kernels, trampolines can be preempted, and these three APIs are therefore implemented by separate functions that check for voluntary context switches. @@ -2646,8 +2646,8 @@ grace-period state machine so as to avoid the need for the additional latency. RCU disables CPU hotplug in a few places, perhaps most notably in the -``rcu_barrier()`` operations. If there is a strong reason to use -``rcu_barrier()`` in CPU-hotplug notifiers, it will be necessary to +rcu_barrier() operations. If there is a strong reason to use +rcu_barrier() in CPU-hotplug notifiers, it will be necessary to avoid disabling CPU hotplug. This would introduce some complexity, so there had better be a *very* good reason. @@ -2664,7 +2664,7 @@ However, this combining tree does not spread its memory across NUMA nodes nor does it align the CPU groups with hardware features such as sockets or cores. Such spreading and alignment is currently believed to be unnecessary because the hotpath read-side primitives do not access -the combining tree, nor does ``call_rcu()`` in the common case. If you +the combining tree, nor does call_rcu() in the common case. If you believe that your architecture needs such spreading and alignment, then your architecture should also benefit from the ``rcutree.rcu_fanout_leaf`` boot parameter, which can be set to the @@ -2685,7 +2685,7 @@ likely that adjustments will be required to more gracefully handle extreme loads. It might also be necessary to be able to relate CPU utilization by RCU's kthreads and softirq handlers to the code that instigated this CPU utilization. For example, RCU callback overhead -might be charged back to the originating ``call_rcu()`` instance, though +might be charged back to the originating call_rcu() instance, though probably not in production kernels. Additional work may be required to provide reasonable forward-progress -- cgit v1.2.3 From 2c8bce609f095a8879d3948e0c18d629881518dd Mon Sep 17 00:00:00 2001 From: "Paul E. McKenney" Date: Tue, 10 Nov 2020 16:17:42 -0800 Subject: doc: Remove obsolete RCU-bh and RCU-sched update-side API members synchronize_rcu_bh(), synchronize_rcu_bh_expedited(), call_rcu_bh(), rcu_barrier_bh(), synchronize_sched(), synchronize_rcu_sched_expedited(), call_rcu_sched(), and rcu_barrier_sched() no longer exist, so this commit removes mention of them. Reported-by: Joel Fernandes Signed-off-by: Paul E. McKenney --- .../RCU/Design/Requirements/Requirements.rst | 28 +++++++++++----------- 1 file changed, 14 insertions(+), 14 deletions(-) (limited to 'Documentation') diff --git a/Documentation/RCU/Design/Requirements/Requirements.rst b/Documentation/RCU/Design/Requirements/Requirements.rst index 9b23be637e17..1e3df779c9c1 100644 --- a/Documentation/RCU/Design/Requirements/Requirements.rst +++ b/Documentation/RCU/Design/Requirements/Requirements.rst @@ -2438,13 +2438,13 @@ glance as if rcu_read_unlock_bh() was executing very slowly. The `RCU-bh API `__ -includes rcu_read_lock_bh(), rcu_read_unlock_bh(), -rcu_dereference_bh(), rcu_dereference_bh_check(), -synchronize_rcu_bh(), synchronize_rcu_bh_expedited(), -call_rcu_bh(), rcu_barrier_bh(), and -rcu_read_lock_bh_held(). However, the update-side APIs are now -simple wrappers for other RCU flavors, namely RCU-sched in -CONFIG_PREEMPT=n kernels and RCU-preempt otherwise. +includes rcu_read_lock_bh(), rcu_read_unlock_bh(), rcu_dereference_bh(), +rcu_dereference_bh_check(), and rcu_read_lock_bh_held(). However, the +old RCU-bh update-side APIs are now gone, replaced by synchronize_rcu(), +synchronize_rcu_expedited(), call_rcu(), and rcu_barrier(). In addition, +anything that disables bottom halves also marks an RCU-bh read-side +critical section, including local_bh_disable() and local_bh_enable(), +local_irq_save() and local_irq_restore(), and so on. Sched Flavor (Historical) ~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -2481,13 +2481,13 @@ The `RCU-sched API `__ includes rcu_read_lock_sched(), rcu_read_unlock_sched(), rcu_read_lock_sched_notrace(), rcu_read_unlock_sched_notrace(), -rcu_dereference_sched(), rcu_dereference_sched_check(), -synchronize_sched(), synchronize_rcu_sched_expedited(), -call_rcu_sched(), rcu_barrier_sched(), and -rcu_read_lock_sched_held(). However, anything that disables -preemption also marks an RCU-sched read-side critical section, including -preempt_disable() and preempt_enable(), local_irq_save() and -local_irq_restore(), and so on. +rcu_dereference_sched(), rcu_dereference_sched_check(), and +rcu_read_lock_sched_held(). However, the old RCU-sched update-side APIs +are now gone, replaced by synchronize_rcu(), synchronize_rcu_expedited(), +call_rcu(), and rcu_barrier(). In addition, anything that disables +preemption also marks an RCU-sched read-side critical section, +including preempt_disable() and preempt_enable(), local_irq_save() +and local_irq_restore(), and so on. Sleepable RCU ~~~~~~~~~~~~~ -- cgit v1.2.3 From 9d3a04853fe640e0eba2c0799c880b7dcf190219 Mon Sep 17 00:00:00 2001 From: Paul Gortmaker Date: Sat, 28 Nov 2020 15:32:59 -0500 Subject: docs: Fix typos and drop/fix dead links in RCU documentation It appears the Compaq link moved to a machine at HP for a while after the merger of the two, but that doesn't work either. A search of HP for "wiz_2637" (w and w/o html suffix) comes up empty. Since the references aren't critical to the documents we remove them. Also, the lkml.kernel.org/g links have been broken for ages, so replace them with lore.kernel.org/r links - standardize on lore for all links too. Note that we put off fixing these 4y ago - presumably thinking that a treewide fixup was pending. Probably safe to go fix the RCU ones now. https://lore.kernel.org/r/20160915144926.GD10850@linux.vnet.ibm.com/ Cc: Michael Opdenacker Cc: Steven Rostedt Cc: "Paul E. McKenney" Signed-off-by: Paul Gortmaker Signed-off-by: Paul E. McKenney --- .../RCU/Design/Requirements/Requirements.rst | 23 +++++++++++----------- Documentation/RCU/checklist.rst | 8 +++----- 2 files changed, 14 insertions(+), 17 deletions(-) (limited to 'Documentation') diff --git a/Documentation/RCU/Design/Requirements/Requirements.rst b/Documentation/RCU/Design/Requirements/Requirements.rst index 1e3df779c9c1..f32f8faddc7d 100644 --- a/Documentation/RCU/Design/Requirements/Requirements.rst +++ b/Documentation/RCU/Design/Requirements/Requirements.rst @@ -321,11 +321,10 @@ do_something_gp_buggy() below: 12 } However, this temptation must be resisted because there are a -surprisingly large number of ways that the compiler (to say nothing of -`DEC Alpha CPUs `__) -can trip this code up. For but one example, if the compiler were short -of registers, it might choose to refetch from ``gp`` rather than keeping -a separate copy in ``p`` as follows: +surprisingly large number of ways that the compiler (or weak ordering +CPUs like the DEC Alpha) can trip this code up. For but one example, if +the compiler were short of registers, it might choose to refetch from +``gp`` rather than keeping a separate copy in ``p`` as follows: :: @@ -1183,7 +1182,7 @@ costs have plummeted. However, as I learned from Matt Mackall's `bloatwatch `__ efforts, memory footprint is critically important on single-CPU systems with non-preemptible (``CONFIG_PREEMPT=n``) kernels, and thus `tiny -RCU `__ +RCU `__ was born. Josh Triplett has since taken over the small-memory banner with his `Linux kernel tinification `__ project, which resulted in `SRCU <#Sleepable%20RCU>`__ becoming optional @@ -1624,7 +1623,7 @@ against mishaps and misuse: init_rcu_head() and cleaned up with destroy_rcu_head(). Mathieu Desnoyers made me aware of this requirement, and also supplied the needed - `patch `__. + `patch `__. #. An infinite loop in an RCU read-side critical section will eventually trigger an RCU CPU stall warning splat, with the duration of “eventually” being controlled by the ``RCU_CPU_STALL_TIMEOUT`` @@ -1716,7 +1715,7 @@ requires almost all of them be hidden behind a ``CONFIG_RCU_EXPERT`` This all should be quite obvious, but the fact remains that Linus Torvalds recently had to -`remind `__ +`remind `__ me of this requirement. Firmware Interface @@ -1837,9 +1836,9 @@ NMI handlers. The name notwithstanding, some Linux-kernel architectures can have nested NMIs, which RCU must handle correctly. Andy Lutomirski `surprised -me `__ +me `__ with this requirement; he also kindly surprised me with `an -algorithm `__ +algorithm `__ that meets this requirement. Furthermore, NMI handlers can be interrupted by what appear to RCU to be @@ -2264,7 +2263,7 @@ more extreme measures. Returning to the ``page`` structure, the ``rcu_head`` field shares storage with a great many other structures that are used at various points in the corresponding page's lifetime. In order to correctly resolve certain `race -conditions `__, +conditions `__, the Linux kernel's memory-management subsystem needs a particular bit to remain zero during all phases of grace-period processing, and that bit happens to map to the bottom bit of the ``rcu_head`` structure's @@ -2328,7 +2327,7 @@ preempted. This requirement made its presence known after users made it clear that an earlier `real-time patch `__ did not meet their needs, in conjunction with some `RCU -issues `__ +issues `__ encountered by a very early version of the -rt patchset. In addition, RCU must make do with a sub-100-microsecond real-time diff --git a/Documentation/RCU/checklist.rst b/Documentation/RCU/checklist.rst index bb7128eb322e..2d1dc1deffc9 100644 --- a/Documentation/RCU/checklist.rst +++ b/Documentation/RCU/checklist.rst @@ -70,7 +70,7 @@ over a rather long period of time, but improvements are always welcome! is less readable and prevents lockdep from detecting locking issues. Letting RCU-protected pointers "leak" out of an RCU read-side - critical section is every bid as bad as letting them leak out + critical section is every bit as bad as letting them leak out from under a lock. Unless, of course, you have arranged some other means of protection, such as a lock or a reference count -before- letting them out of the RCU read-side critical section. @@ -129,9 +129,7 @@ over a rather long period of time, but improvements are always welcome! accesses. The rcu_dereference() primitive ensures that the CPU picks up the pointer before it picks up the data that the pointer points to. This really is necessary - on Alpha CPUs. If you don't believe me, see: - - http://www.openvms.compaq.com/wizard/wiz_2637.html + on Alpha CPUs. The rcu_dereference() primitive is also an excellent documentation aid, letting the person reading the @@ -216,7 +214,7 @@ over a rather long period of time, but improvements are always welcome! 7. As of v4.20, a given kernel implements only one RCU flavor, which is RCU-sched for PREEMPT=n and RCU-preempt for PREEMPT=y. If the updater uses call_rcu() or synchronize_rcu(), - then the corresponding readers my use rcu_read_lock() and + then the corresponding readers may use rcu_read_lock() and rcu_read_unlock(), rcu_read_lock_bh() and rcu_read_unlock_bh(), or any pair of primitives that disables and re-enables preemption, for example, rcu_read_lock_sched() and rcu_read_unlock_sched(). -- cgit v1.2.3 From d756c74e6f6e76e99f8bffcea57833816dd335b6 Mon Sep 17 00:00:00 2001 From: "Paul E. McKenney" Date: Wed, 9 Dec 2020 16:54:41 -0800 Subject: doc: Update RCU requirements RCU_INIT_POINTER() description Back in the day, RCU_INIT_POINTER() was the only way to avoid memory-barrier instructions while storing NULL to an RCU-protected pointer. Fortunately, in 2016, rcu_assign_pointer() started checking for compile-time NULL pointers and omitting the memory-barrier instructions in that case. Unfortunately, RCU's Requirements.rst document was not updated accordingly. This commit therefore at long last carries out that update. Fixes: 3a37f7275cda ("rcu: No ordering for rcu_assign_pointer() of NULL") Link: https://lore.kernel.org/lkml/20201209230755.GV7338@casper.infradead.org/ Reported-by: Matthew Wilcox Acked-by: Linus Torvalds Signed-off-by: Paul E. McKenney --- Documentation/RCU/Design/Requirements/Requirements.rst | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'Documentation') diff --git a/Documentation/RCU/Design/Requirements/Requirements.rst b/Documentation/RCU/Design/Requirements/Requirements.rst index f32f8faddc7d..65c7839114a5 100644 --- a/Documentation/RCU/Design/Requirements/Requirements.rst +++ b/Documentation/RCU/Design/Requirements/Requirements.rst @@ -1668,8 +1668,7 @@ against mishaps and misuse: this purpose. #. It is not necessary to use rcu_assign_pointer() when creating linked structures that are to be published via a single external - pointer. The RCU_INIT_POINTER() macro is provided for this task - and also for assigning ``NULL`` pointers at runtime. + pointer. The RCU_INIT_POINTER() macro is provided for this task. This not a hard-and-fast list: RCU's diagnostic capabilities will continue to be guided by the number and type of usage bugs found in -- cgit v1.2.3 From 2252ec1464730ce718dc8087c13a419b9aa58758 Mon Sep 17 00:00:00 2001 From: "Paul E. McKenney" Date: Thu, 10 Dec 2020 09:53:50 -0800 Subject: doc: Remove obsolete rcutree.rcu_idle_lazy_gp_delay boot parameter This commit removes documentation for the rcutree.rcu_idle_lazy_gp_delay kernel boot parameter given that this parameter no longer exists. Fixes: 77a40f97030b ("rcu: Remove kfree_rcu() special casing and lazy-callback handling") Signed-off-by: Paul E. McKenney --- Documentation/admin-guide/kernel-parameters.txt | 6 ------ 1 file changed, 6 deletions(-) (limited to 'Documentation') diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt index c722ec19cd00..b5baa8a54df0 100644 --- a/Documentation/admin-guide/kernel-parameters.txt +++ b/Documentation/admin-guide/kernel-parameters.txt @@ -4179,12 +4179,6 @@ Set wakeup interval for idle CPUs that have RCU callbacks (RCU_FAST_NO_HZ=y). - rcutree.rcu_idle_lazy_gp_delay= [KNL] - Set wakeup interval for idle CPUs that have - only "lazy" RCU callbacks (RCU_FAST_NO_HZ=y). - Lazy RCU callbacks are those which RCU can - prove do nothing more than free memory. - rcutree.rcu_kick_kthreads= [KNL] Cause the grace-period kthread to get an extra wake_up() if it sleeps three times longer than -- cgit v1.2.3 From 8b9a0ecc7ef5e1ed3afbc926de17399a37128c82 Mon Sep 17 00:00:00 2001 From: Scott Wood Date: Tue, 15 Dec 2020 15:16:46 +0100 Subject: rcu: Unconditionally use rcuc threads on PREEMPT_RT PREEMPT_RT systems have long used the rcutree.use_softirq kernel boot parameter to avoid use of RCU_SOFTIRQ handlers, which can disrupt real-time applications by invoking callbacks during return from interrupts that arrived while executing time-critical code. This kernel boot parameter instead runs RCU core processing in an 'rcuc' kthread, thus allowing the scheduler to do its job of avoiding disrupting time-critical code. This commit therefore disables the rcutree.use_softirq kernel boot parameter on PREEMPT_RT systems, thus forcing such systems to do RCU core processing in 'rcuc' kthreads. This approach has long been in use by users of the -rt patchset, and there have been no complaints. There is therefore no way for the system administrator to override this choice, at least without modifying and rebuilding the kernel. Signed-off-by: Scott Wood [bigeasy: Reword commit message] Signed-off-by: Sebastian Andrzej Siewior [ paulmck: Update kernel-parameters.txt accordingly. ] Signed-off-by: Paul E. McKenney --- Documentation/admin-guide/kernel-parameters.txt | 4 ++++ kernel/rcu/tree.c | 4 +++- 2 files changed, 7 insertions(+), 1 deletion(-) (limited to 'Documentation') diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt index c722ec19cd00..521255f4ef13 100644 --- a/Documentation/admin-guide/kernel-parameters.txt +++ b/Documentation/admin-guide/kernel-parameters.txt @@ -4092,6 +4092,10 @@ value, meaning that RCU_SOFTIRQ is used by default. Specify rcutree.use_softirq=0 to use rcuc kthreads. + But note that CONFIG_PREEMPT_RT=y kernels disable + this kernel boot parameter, forcibly setting it + to zero. + rcutree.rcu_fanout_exact= [KNL] Disable autobalancing of the rcu_node combining tree. This is used by rcutorture, and might diff --git a/kernel/rcu/tree.c b/kernel/rcu/tree.c index 40e5e3dd253e..d60903581300 100644 --- a/kernel/rcu/tree.c +++ b/kernel/rcu/tree.c @@ -100,8 +100,10 @@ static struct rcu_state rcu_state = { static bool dump_tree; module_param(dump_tree, bool, 0444); /* By default, use RCU_SOFTIRQ instead of rcuc kthreads. */ -static bool use_softirq = true; +static bool use_softirq = !IS_ENABLED(CONFIG_PREEMPT_RT); +#ifndef CONFIG_PREEMPT_RT module_param(use_softirq, bool, 0444); +#endif /* Control rcu_node-tree auto-balancing at boot time. */ static bool rcu_fanout_exact; module_param(rcu_fanout_exact, bool, 0444); -- cgit v1.2.3 From 36221e109eb20ac111bc3bf3e8d5639aa457c7e0 Mon Sep 17 00:00:00 2001 From: Julia Cartwright Date: Tue, 15 Dec 2020 15:16:47 +0100 Subject: rcu: Enable rcu_normal_after_boot unconditionally for RT Expedited RCU grace periods send IPIs to all non-idle CPUs, and thus can disrupt time-critical code in real-time applications. However, there is a portion of boot-time processing (presumably before any real-time applications have started) where expedited RCU grace periods are the only option. And so it is that experience with the -rt patchset indicates that PREEMPT_RT systems should always set the rcupdate.rcu_normal_after_boot kernel boot parameter. This commit therefore makes the post-boot application environment safe for real-time applications by making PREEMPT_RT systems disable the rcupdate.rcu_normal_after_boot kernel boot parameter and acting as if this parameter had been set. This means that post-boot calls to synchronize_rcu_expedited() will be treated as if they were instead calls to synchronize_rcu(), thus preventing the IPIs, and thus avoiding disrupting real-time applications. Suggested-by: Luiz Capitulino Acked-by: Paul E. McKenney Signed-off-by: Julia Cartwright Signed-off-by: Sebastian Andrzej Siewior [ paulmck: Update kernel-parameters.txt accordingly. ] Signed-off-by: Paul E. McKenney --- Documentation/admin-guide/kernel-parameters.txt | 7 +++++++ kernel/rcu/update.c | 4 +++- 2 files changed, 10 insertions(+), 1 deletion(-) (limited to 'Documentation') diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt index 521255f4ef13..e0008d9caccb 100644 --- a/Documentation/admin-guide/kernel-parameters.txt +++ b/Documentation/admin-guide/kernel-parameters.txt @@ -4474,6 +4474,13 @@ only normal grace-period primitives. No effect on CONFIG_TINY_RCU kernels. + But note that CONFIG_PREEMPT_RT=y kernels enables + this kernel boot parameter, forcibly setting + it to the value one, that is, converting any + post-boot attempt at an expedited RCU grace + period to instead use normal non-expedited + grace-period processing. + rcupdate.rcu_task_ipi_delay= [KNL] Set time in jiffies during which RCU tasks will avoid sending IPIs, starting with the beginning diff --git a/kernel/rcu/update.c b/kernel/rcu/update.c index 39334d2d2b37..b95ae86c40a7 100644 --- a/kernel/rcu/update.c +++ b/kernel/rcu/update.c @@ -56,8 +56,10 @@ #ifndef CONFIG_TINY_RCU module_param(rcu_expedited, int, 0); module_param(rcu_normal, int, 0); -static int rcu_normal_after_boot; +static int rcu_normal_after_boot = IS_ENABLED(CONFIG_PREEMPT_RT); +#ifndef CONFIG_PREEMPT_RT module_param(rcu_normal_after_boot, int, 0); +#endif #endif /* #ifndef CONFIG_TINY_RCU */ #ifdef CONFIG_DEBUG_LOCK_ALLOC -- cgit v1.2.3 From ee7f4a87a18cd3bb141b38e2ef0c3e53253cdf63 Mon Sep 17 00:00:00 2001 From: "Paul E. McKenney" Date: Wed, 18 Nov 2020 16:01:32 -0800 Subject: srcu: Document polling interfaces for Tree SRCU grace periods This commit adds requirements documentation for the get_state_synchronize_srcu(), start_poll_synchronize_srcu(), and poll_state_synchronize_srcu() functions. Link: https://lore.kernel.org/rcu/20201112201547.GF3365678@moria.home.lan/ Reported-by: Kent Overstreet Reviewed-by: Neeraj Upadhyay Signed-off-by: Paul E. McKenney --- Documentation/RCU/Design/Requirements/Requirements.rst | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) (limited to 'Documentation') diff --git a/Documentation/RCU/Design/Requirements/Requirements.rst b/Documentation/RCU/Design/Requirements/Requirements.rst index e8c84fcc0507..93a189ae8592 100644 --- a/Documentation/RCU/Design/Requirements/Requirements.rst +++ b/Documentation/RCU/Design/Requirements/Requirements.rst @@ -2600,6 +2600,24 @@ also includes ``DEFINE_SRCU()``, ``DEFINE_STATIC_SRCU()``, and ``init_srcu_struct()`` APIs for defining and initializing ``srcu_struct`` structures. +More recently, the SRCU API has added polling interfaces: + +#. start_poll_synchronize_srcu() returns a cookie identifying + the completion of a future SRCU grace period and ensures + that this grace period will be started. +#. poll_state_synchronize_srcu() returns ``true`` iff the + specified cookie corresponds to an already-completed + SRCU grace period. +#. get_state_synchronize_srcu() returns a cookie just like + start_poll_synchronize_srcu() does, but differs in that + it does nothing to ensure that any future SRCU grace period + will be started. + +These functions are used to avoid unnecessary SRCU grace periods in +certain types of buffer-cache algorithms having multi-stage age-out +mechanisms. The idea is that by the time the block has aged completely +from the cache, an SRCU grace period will be very likely to have elapsed. + Tasks RCU ~~~~~~~~~ -- cgit v1.2.3 From a4767912aa63bb66a7c35ddacd1946f3691af803 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Sat, 4 Apr 2020 21:50:39 +0300 Subject: dt-bindings: display: bridge: thc63lvd1024: Document dual-output mode The DT binding support both dual-input and dual-output mode, but only dual-input is documented. Document dual-output mode. Suggested-by: Jacopo Mondi Signed-off-by: Laurent Pinchart Acked-by: Jacopo Mondi Reviewed-by: Rob Herring Reviewed-by: Kieran Bingham --- .../bindings/display/bridge/thine,thc63lvd1024.yaml | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/display/bridge/thine,thc63lvd1024.yaml b/Documentation/devicetree/bindings/display/bridge/thine,thc63lvd1024.yaml index 469ac4a34273..fedd3460d6f6 100644 --- a/Documentation/devicetree/bindings/display/bridge/thine,thc63lvd1024.yaml +++ b/Documentation/devicetree/bindings/display/bridge/thine,thc63lvd1024.yaml @@ -30,11 +30,17 @@ properties: This device has four video ports. Their connections are modeled using the OF graph bindings specified in Documentation/devicetree/bindings/graph.txt. - The device can operate in single-link mode or dual-link mode. In - single-link mode, all pixels are received on port@0, and port@1 shall not - contain any endpoint. In dual-link mode, even-numbered pixels are - received on port@0 and odd-numbered pixels on port@1, and both port@0 and - port@1 shall contain endpoints. + The device can operate in single or dual input and output modes. + + When operating in single input mode, all pixels are received on port@0, + and port@1 shall not contain any endpoint. In dual input mode, + even-numbered pixels are received on port@0 and odd-numbered pixels on + port@1, and both port@0 and port@1 shall contain endpoints. + + When operating in single output mode all pixels are output from the first + CMOS/TTL port and port@3 shall not contain any endpoint. In dual output + mode pixels are output from both CMOS/TTL ports and both port@2 and + port@3 shall contain endpoints. properties: '#address-cells': -- cgit v1.2.3 From a9a472aab9cd9a7636e2af031e48ab663130648f Mon Sep 17 00:00:00 2001 From: Fabrizio Castro Date: Fri, 2 Aug 2019 08:33:58 +0100 Subject: dt-bindings: display: bridge: renesas,lvds: RZ/G2E needs renesas,companion too Document RZ/G2E support for property renesas,companion. Signed-off-by: Fabrizio Castro Reviewed-by: Laurent Pinchart Reviewed-by: Jacopo Mondi Reviewed-by: Rob Herring Signed-off-by: Laurent Pinchart --- Documentation/devicetree/bindings/display/bridge/renesas,lvds.yaml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/display/bridge/renesas,lvds.yaml b/Documentation/devicetree/bindings/display/bridge/renesas,lvds.yaml index e5b163951b91..7eddcdb666dc 100644 --- a/Documentation/devicetree/bindings/display/bridge/renesas,lvds.yaml +++ b/Documentation/devicetree/bindings/display/bridge/renesas,lvds.yaml @@ -83,9 +83,9 @@ properties: $ref: /schemas/types.yaml#/definitions/phandle description: phandle to the companion LVDS encoder. This property is mandatory - for the first LVDS encoder on D3 and E3 SoCs, and shall point to - the second encoder to be used as a companion in dual-link mode. It - shall not be set for any other LVDS encoder. + for the first LVDS encoder on R-Car D3 and E3, and RZ/G2E SoCs, and shall + point to the second encoder to be used as a companion in dual-link mode. + It shall not be set for any other LVDS encoder. required: - compatible -- cgit v1.2.3 From 4187f9c16b7daf375dc2ad1e51c0782f8a9e4f7c Mon Sep 17 00:00:00 2001 From: Jun Nie Date: Fri, 4 Dec 2020 15:53:43 +0800 Subject: dt-bindings: interconnect: single yaml file for RPM interconnect drivers MSM8916 and QCS404 bindings are almost identical, so combine them into one. This will make it easier to add interconnect bindings for more SoC with RPM. Signed-off-by: Jun Nie Reviewed-by: Rob Herring Link: https://lore.kernel.org/r/20201204075345.5161-4-jun.nie@linaro.org Signed-off-by: Georgi Djakov --- .../bindings/interconnect/qcom,msm8916.yaml | 77 -------------------- .../bindings/interconnect/qcom,qcs404.yaml | 77 -------------------- .../devicetree/bindings/interconnect/qcom,rpm.yaml | 81 ++++++++++++++++++++++ 3 files changed, 81 insertions(+), 154 deletions(-) delete mode 100644 Documentation/devicetree/bindings/interconnect/qcom,msm8916.yaml delete mode 100644 Documentation/devicetree/bindings/interconnect/qcom,qcs404.yaml create mode 100644 Documentation/devicetree/bindings/interconnect/qcom,rpm.yaml (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/interconnect/qcom,msm8916.yaml b/Documentation/devicetree/bindings/interconnect/qcom,msm8916.yaml deleted file mode 100644 index e1009ae4e8f7..000000000000 --- a/Documentation/devicetree/bindings/interconnect/qcom,msm8916.yaml +++ /dev/null @@ -1,77 +0,0 @@ -# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) -%YAML 1.2 ---- -$id: http://devicetree.org/schemas/interconnect/qcom,msm8916.yaml# -$schema: http://devicetree.org/meta-schemas/core.yaml# - -title: Qualcomm MSM8916 Network-On-Chip interconnect - -maintainers: - - Georgi Djakov - -description: | - The Qualcomm MSM8916 interconnect providers support adjusting the - bandwidth requirements between the various NoC fabrics. - -properties: - compatible: - enum: - - qcom,msm8916-bimc - - qcom,msm8916-pcnoc - - qcom,msm8916-snoc - - reg: - maxItems: 1 - - '#interconnect-cells': - const: 1 - - clock-names: - items: - - const: bus - - const: bus_a - - clocks: - items: - - description: Bus Clock - - description: Bus A Clock - -required: - - compatible - - reg - - '#interconnect-cells' - - clock-names - - clocks - -additionalProperties: false - -examples: - - | - #include - - bimc: interconnect@400000 { - compatible = "qcom,msm8916-bimc"; - reg = <0x00400000 0x62000>; - #interconnect-cells = <1>; - clock-names = "bus", "bus_a"; - clocks = <&rpmcc RPM_SMD_BIMC_CLK>, - <&rpmcc RPM_SMD_BIMC_A_CLK>; - }; - - pcnoc: interconnect@500000 { - compatible = "qcom,msm8916-pcnoc"; - reg = <0x00500000 0x11000>; - #interconnect-cells = <1>; - clock-names = "bus", "bus_a"; - clocks = <&rpmcc RPM_SMD_PCNOC_CLK>, - <&rpmcc RPM_SMD_PCNOC_A_CLK>; - }; - - snoc: interconnect@580000 { - compatible = "qcom,msm8916-snoc"; - reg = <0x00580000 0x14000>; - #interconnect-cells = <1>; - clock-names = "bus", "bus_a"; - clocks = <&rpmcc RPM_SMD_SNOC_CLK>, - <&rpmcc RPM_SMD_SNOC_A_CLK>; - }; diff --git a/Documentation/devicetree/bindings/interconnect/qcom,qcs404.yaml b/Documentation/devicetree/bindings/interconnect/qcom,qcs404.yaml deleted file mode 100644 index 3fbb8785fbc9..000000000000 --- a/Documentation/devicetree/bindings/interconnect/qcom,qcs404.yaml +++ /dev/null @@ -1,77 +0,0 @@ -# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) -%YAML 1.2 ---- -$id: http://devicetree.org/schemas/interconnect/qcom,qcs404.yaml# -$schema: http://devicetree.org/meta-schemas/core.yaml# - -title: Qualcomm QCS404 Network-On-Chip interconnect - -maintainers: - - Georgi Djakov - -description: | - The Qualcomm QCS404 interconnect providers support adjusting the - bandwidth requirements between the various NoC fabrics. - -properties: - reg: - maxItems: 1 - - compatible: - enum: - - qcom,qcs404-bimc - - qcom,qcs404-pcnoc - - qcom,qcs404-snoc - - '#interconnect-cells': - const: 1 - - clock-names: - items: - - const: bus - - const: bus_a - - clocks: - items: - - description: Bus Clock - - description: Bus A Clock - -required: - - compatible - - reg - - '#interconnect-cells' - - clock-names - - clocks - -additionalProperties: false - -examples: - - | - #include - - bimc: interconnect@400000 { - reg = <0x00400000 0x80000>; - compatible = "qcom,qcs404-bimc"; - #interconnect-cells = <1>; - clock-names = "bus", "bus_a"; - clocks = <&rpmcc RPM_SMD_BIMC_CLK>, - <&rpmcc RPM_SMD_BIMC_A_CLK>; - }; - - pnoc: interconnect@500000 { - reg = <0x00500000 0x15080>; - compatible = "qcom,qcs404-pcnoc"; - #interconnect-cells = <1>; - clock-names = "bus", "bus_a"; - clocks = <&rpmcc RPM_SMD_PNOC_CLK>, - <&rpmcc RPM_SMD_PNOC_A_CLK>; - }; - - snoc: interconnect@580000 { - reg = <0x00580000 0x23080>; - compatible = "qcom,qcs404-snoc"; - #interconnect-cells = <1>; - clock-names = "bus", "bus_a"; - clocks = <&rpmcc RPM_SMD_SNOC_CLK>, - <&rpmcc RPM_SMD_SNOC_A_CLK>; - }; diff --git a/Documentation/devicetree/bindings/interconnect/qcom,rpm.yaml b/Documentation/devicetree/bindings/interconnect/qcom,rpm.yaml new file mode 100644 index 000000000000..d720b68b3ead --- /dev/null +++ b/Documentation/devicetree/bindings/interconnect/qcom,rpm.yaml @@ -0,0 +1,81 @@ +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/interconnect/qcom,rpm.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Qualcomm RPM Network-On-Chip Interconnect + +maintainers: + - Georgi Djakov + +description: | + RPM interconnect providers support system bandwidth requirements through + RPM processor. The provider is able to communicate with the RPM through + the RPM shared memory device. + +properties: + reg: + maxItems: 1 + + compatible: + enum: + - qcom,msm8916-bimc + - qcom,msm8916-pcnoc + - qcom,msm8916-snoc + - qcom,qcs404-bimc + - qcom,qcs404-pcnoc + - qcom,qcs404-snoc + + '#interconnect-cells': + const: 1 + + clock-names: + items: + - const: bus + - const: bus_a + + clocks: + items: + - description: Bus Clock + - description: Bus A Clock + +required: + - compatible + - reg + - '#interconnect-cells' + - clock-names + - clocks + +additionalProperties: false + +examples: + - | + #include + + bimc: interconnect@400000 { + compatible = "qcom,msm8916-bimc"; + reg = <0x00400000 0x62000>; + #interconnect-cells = <1>; + clock-names = "bus", "bus_a"; + clocks = <&rpmcc RPM_SMD_BIMC_CLK>, + <&rpmcc RPM_SMD_BIMC_A_CLK>; + }; + + pcnoc: interconnect@500000 { + compatible = "qcom,msm8916-pcnoc"; + reg = <0x00500000 0x11000>; + #interconnect-cells = <1>; + clock-names = "bus", "bus_a"; + clocks = <&rpmcc RPM_SMD_PCNOC_CLK>, + <&rpmcc RPM_SMD_PCNOC_A_CLK>; + }; + + snoc: interconnect@580000 { + compatible = "qcom,msm8916-snoc"; + reg = <0x00580000 0x14000>; + #interconnect-cells = <1>; + clock-names = "bus", "bus_a"; + clocks = <&rpmcc RPM_SMD_SNOC_CLK>, + <&rpmcc RPM_SMD_SNOC_A_CLK>; + }; -- cgit v1.2.3 From 4ec908d2104026c67e4eb0fee722ed6893622763 Mon Sep 17 00:00:00 2001 From: Jun Nie Date: Fri, 4 Dec 2020 15:53:44 +0800 Subject: dt-bindings: interconnect: Add Qualcomm MSM8939 DT bindings The Qualcomm MSM8939 platform has several bus fabrics that could be controlled and tuned dynamically according to the bandwidth demand. Signed-off-by: Jun Nie Reviewed-by: Rob Herring Link: https://lore.kernel.org/r/20201204075345.5161-5-jun.nie@linaro.org Signed-off-by: Georgi Djakov --- .../devicetree/bindings/interconnect/qcom,rpm.yaml | 4 + include/dt-bindings/interconnect/qcom,msm8939.h | 105 +++++++++++++++++++++ 2 files changed, 109 insertions(+) create mode 100644 include/dt-bindings/interconnect/qcom,msm8939.h (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/interconnect/qcom,rpm.yaml b/Documentation/devicetree/bindings/interconnect/qcom,rpm.yaml index d720b68b3ead..983d71fb5399 100644 --- a/Documentation/devicetree/bindings/interconnect/qcom,rpm.yaml +++ b/Documentation/devicetree/bindings/interconnect/qcom,rpm.yaml @@ -23,6 +23,10 @@ properties: - qcom,msm8916-bimc - qcom,msm8916-pcnoc - qcom,msm8916-snoc + - qcom,msm8939-bimc + - qcom,msm8939-pcnoc + - qcom,msm8939-snoc + - qcom,msm8939-snoc-mm - qcom,qcs404-bimc - qcom,qcs404-pcnoc - qcom,qcs404-snoc diff --git a/include/dt-bindings/interconnect/qcom,msm8939.h b/include/dt-bindings/interconnect/qcom,msm8939.h new file mode 100644 index 000000000000..c22369a4b9f5 --- /dev/null +++ b/include/dt-bindings/interconnect/qcom,msm8939.h @@ -0,0 +1,105 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Qualcomm interconnect IDs + * + * Copyright (c) 2020, Linaro Ltd. + * Author: Jun Nie + */ + +#ifndef __DT_BINDINGS_INTERCONNECT_QCOM_MSM8939_H +#define __DT_BINDINGS_INTERCONNECT_QCOM_MSM8939_H + +#define BIMC_SNOC_SLV 0 +#define MASTER_QDSS_BAM 1 +#define MASTER_QDSS_ETR 2 +#define MASTER_SNOC_CFG 3 +#define PCNOC_SNOC_SLV 4 +#define SLAVE_APSS 5 +#define SLAVE_CATS_128 6 +#define SLAVE_OCMEM_64 7 +#define SLAVE_IMEM 8 +#define SLAVE_QDSS_STM 9 +#define SLAVE_SRVC_SNOC 10 +#define SNOC_BIMC_0_MAS 11 +#define SNOC_BIMC_1_MAS 12 +#define SNOC_BIMC_2_MAS 13 +#define SNOC_INT_0 14 +#define SNOC_INT_1 15 +#define SNOC_INT_BIMC 16 +#define SNOC_PCNOC_MAS 17 +#define SNOC_QDSS_INT 18 + +#define MASTER_VIDEO_P0 0 +#define MASTER_JPEG 1 +#define MASTER_VFE 2 +#define MASTER_MDP_PORT0 3 +#define MASTER_MDP_PORT1 4 +#define MASTER_CPP 5 +#define SNOC_MM_INT_0 6 +#define SNOC_MM_INT_1 7 +#define SNOC_MM_INT_2 8 + +#define BIMC_SNOC_MAS 0 +#define MASTER_AMPSS_M0 1 +#define MASTER_GRAPHICS_3D 2 +#define MASTER_TCU0 3 +#define SLAVE_AMPSS_L2 4 +#define SLAVE_EBI_CH0 5 +#define SNOC_BIMC_0_SLV 6 +#define SNOC_BIMC_1_SLV 7 +#define SNOC_BIMC_2_SLV 8 + +#define MASTER_BLSP_1 0 +#define MASTER_DEHR 1 +#define MASTER_LPASS 2 +#define MASTER_CRYPTO_CORE0 3 +#define MASTER_SDCC_1 4 +#define MASTER_SDCC_2 5 +#define MASTER_SPDM 6 +#define MASTER_USB_HS1 7 +#define MASTER_USB_HS2 8 +#define PCNOC_INT_0 9 +#define PCNOC_INT_1 10 +#define PCNOC_MAS_0 11 +#define PCNOC_MAS_1 12 +#define PCNOC_SLV_0 13 +#define PCNOC_SLV_1 14 +#define PCNOC_SLV_2 15 +#define PCNOC_SLV_3 16 +#define PCNOC_SLV_4 17 +#define PCNOC_SLV_8 18 +#define PCNOC_SLV_9 19 +#define PCNOC_SNOC_MAS 20 +#define SLAVE_BIMC_CFG 21 +#define SLAVE_BLSP_1 22 +#define SLAVE_BOOT_ROM 23 +#define SLAVE_CAMERA_CFG 24 +#define SLAVE_CLK_CTL 25 +#define SLAVE_CRYPTO_0_CFG 26 +#define SLAVE_DEHR_CFG 27 +#define SLAVE_DISPLAY_CFG 28 +#define SLAVE_GRAPHICS_3D_CFG 29 +#define SLAVE_IMEM_CFG 30 +#define SLAVE_LPASS 31 +#define SLAVE_MPM 32 +#define SLAVE_MSG_RAM 33 +#define SLAVE_MSS 34 +#define SLAVE_PDM 35 +#define SLAVE_PMIC_ARB 36 +#define SLAVE_PCNOC_CFG 37 +#define SLAVE_PRNG 38 +#define SLAVE_QDSS_CFG 39 +#define SLAVE_RBCPR_CFG 40 +#define SLAVE_SDCC_1 41 +#define SLAVE_SDCC_2 42 +#define SLAVE_SECURITY 43 +#define SLAVE_SNOC_CFG 44 +#define SLAVE_SPDM 45 +#define SLAVE_TCSR 46 +#define SLAVE_TLMM 47 +#define SLAVE_USB_HS1 48 +#define SLAVE_USB_HS2 49 +#define SLAVE_VENUS_CFG 50 +#define SNOC_PCNOC_SLV 51 + +#endif -- cgit v1.2.3 From cf9a4be47fd14473b4d0dd6f494ed7279c2bc8a0 Mon Sep 17 00:00:00 2001 From: Simon Ser Date: Tue, 22 Dec 2020 14:35:24 +0100 Subject: drm/doc: render drm.h uapi docs It doesn't seem like drm.h docs are included anywhere. Render them next to drm_mode.h, under the "Userspace API Structures" section. This also allows references to e.g. DRM_CAP_* to be properly linkified elsewhere in our docs. Signed-off-by: Simon Ser Acked-by: Daniel Vetter Cc: Pekka Paalanen Link: https://patchwork.freedesktop.org/patch/msgid/20201222133524.160842-6-contact@emersion.fr --- Documentation/gpu/drm-uapi.rst | 3 +++ 1 file changed, 3 insertions(+) (limited to 'Documentation') diff --git a/Documentation/gpu/drm-uapi.rst b/Documentation/gpu/drm-uapi.rst index 7dce175f6d75..04bdc7a91d53 100644 --- a/Documentation/gpu/drm-uapi.rst +++ b/Documentation/gpu/drm-uapi.rst @@ -457,5 +457,8 @@ Userspace API Structures .. kernel-doc:: include/uapi/drm/drm_mode.h :doc: overview +.. kernel-doc:: include/uapi/drm/drm.h + :internal: + .. kernel-doc:: include/uapi/drm/drm_mode.h :internal: -- cgit v1.2.3 From 99a064fb3a73920262119efead4d5048b7da2f55 Mon Sep 17 00:00:00 2001 From: Jim Quinlan Date: Tue, 22 Dec 2020 09:56:02 -0500 Subject: dt-bindings: arm: Add optional interrupt to smc/hvc SCMI transport In the normal use of smc/hvc as SCMI transport, the message completion is indicated by the return of the SMC call. This binding provides for an optional interrupt named "a2p" which can be used instead to indicate the completion of a message. Link: https://lore.kernel.org/r/20201222145603.40192-2-jim2101024@gmail.com Reviewed-by: Rob Herring Acked-by: Florian Fainelli Signed-off-by: Jim Quinlan [sudeep.holla: minor wording changes to the commit log] Signed-off-by: Sudeep Holla --- Documentation/devicetree/bindings/arm/arm,scmi.txt | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/arm/arm,scmi.txt b/Documentation/devicetree/bindings/arm/arm,scmi.txt index b5ce5b39bb9c..667d58e0a659 100644 --- a/Documentation/devicetree/bindings/arm/arm,scmi.txt +++ b/Documentation/devicetree/bindings/arm/arm,scmi.txt @@ -31,6 +31,14 @@ Optional properties: - mbox-names: shall be "tx" or "rx" depending on mboxes entries. +- interrupts : when using smc or hvc transports, this optional + property indicates that msg completion by the platform is indicated + by an interrupt rather than by the return of the smc call. This + should not be used except when the platform requires such behavior. + +- interrupt-names : if "interrupts" is present, interrupt-names must also + be present and have the value "a2p". + See Documentation/devicetree/bindings/mailbox/mailbox.txt for more details about the generic mailbox controller and client driver bindings. -- cgit v1.2.3 From 8e9199189443b39a0c3db629150610b832af9ac8 Mon Sep 17 00:00:00 2001 From: Adam Ford Date: Sat, 2 Jan 2021 05:54:09 -0600 Subject: dt-bindings: memory: renesas,rpc-if: Add support for RZ/G2 Series The RZ/G2 Series has the RPC-IF interface. Update bindings to support: r8a774a1, r8a774b1, r8a774c0, and r8a774e1 Signed-off-by: Adam Ford Link: https://lore.kernel.org/r/20210102115412.3402059-1-aford173@gmail.com Signed-off-by: Krzysztof Kozlowski --- .../devicetree/bindings/memory-controllers/renesas,rpc-if.yaml | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/memory-controllers/renesas,rpc-if.yaml b/Documentation/devicetree/bindings/memory-controllers/renesas,rpc-if.yaml index 6d6ba608fd22..990489fdd2ac 100644 --- a/Documentation/devicetree/bindings/memory-controllers/renesas,rpc-if.yaml +++ b/Documentation/devicetree/bindings/memory-controllers/renesas,rpc-if.yaml @@ -26,10 +26,14 @@ properties: compatible: items: - enum: + - renesas,r8a774a1-rpc-if # RZ/G2M + - renesas,r8a774b1-rpc-if # RZ/G2N + - renesas,r8a774c0-rpc-if # RZ/G2E + - renesas,r8a774e1-rpc-if # RZ/G2H - renesas,r8a77970-rpc-if # R-Car V3M - renesas,r8a77980-rpc-if # R-Car V3H - renesas,r8a77995-rpc-if # R-Car D3 - - const: renesas,rcar-gen3-rpc-if # a generic R-Car gen3 device + - const: renesas,rcar-gen3-rpc-if # a generic R-Car gen3 or RZ/G2 device reg: items: -- cgit v1.2.3 From 698dc0cf944772a79a9aa417e647c0f7587e51df Mon Sep 17 00:00:00 2001 From: Heinrich Schuchardt Date: Tue, 5 Jan 2021 14:20:07 -0800 Subject: dt-bindings: input: adc-keys: clarify description The current description of ADC keys is not precise enough. "when this key is pressed" leaves it open if a key is considered pressed below or above the threshold. This has led to confusion: drivers/input/keyboard/adc-keys.c ignores the meaning of thresholds and sets the key that is closest to press-threshold-microvolt. This patch nails down the definitions and provides an interpretation of the supplied example. Signed-off-by: Heinrich Schuchardt Acked-by: Rob Herring Link: https://lore.kernel.org/r/20201222110815.24121-1-xypron.glpk@gmx.de Signed-off-by: Dmitry Torokhov --- .../devicetree/bindings/input/adc-keys.txt | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/input/adc-keys.txt b/Documentation/devicetree/bindings/input/adc-keys.txt index e551814629b4..6c8be6a9ace2 100644 --- a/Documentation/devicetree/bindings/input/adc-keys.txt +++ b/Documentation/devicetree/bindings/input/adc-keys.txt @@ -5,7 +5,8 @@ Required properties: - compatible: "adc-keys" - io-channels: Phandle to an ADC channel - io-channel-names = "buttons"; - - keyup-threshold-microvolt: Voltage at which all the keys are considered up. + - keyup-threshold-microvolt: Voltage above or equal to which all the keys are + considered up. Optional properties: - poll-interval: Poll interval time in milliseconds @@ -17,7 +18,12 @@ Each button (key) is represented as a sub-node of "adc-keys": Required subnode-properties: - label: Descriptive name of the key. - linux,code: Keycode to emit. - - press-threshold-microvolt: Voltage ADC input when this key is pressed. + - press-threshold-microvolt: voltage above or equal to which this key is + considered pressed. + +No two values of press-threshold-microvolt may be the same. +All values of press-threshold-microvolt must be less than +keyup-threshold-microvolt. Example: @@ -47,3 +53,15 @@ Example: press-threshold-microvolt = <500000>; }; }; + ++--------------------------------+------------------------+ +| 2.000.000 <= value | no key pressed | ++--------------------------------+------------------------+ +| 1.500.000 <= value < 2.000.000 | KEY_VOLUMEUP pressed | ++--------------------------------+------------------------+ +| 1.000.000 <= value < 1.500.000 | KEY_VOLUMEDOWN pressed | ++--------------------------------+------------------------+ +| 500.000 <= value < 1.000.000 | KEY_ENTER pressed | ++--------------------------------+------------------------+ +| value < 500.000 | no key pressed | ++--------------------------------+------------------------+ -- cgit v1.2.3 From ede71cae72855f8d6f6268510895210adc317666 Mon Sep 17 00:00:00 2001 From: Masanari Iida Date: Tue, 5 Jan 2021 23:40:29 +0900 Subject: net-next: docs: Fix typos in snmp_counter.rst This patch fixes some spelling typos in snmp_counter.rst Signed-off-by: Masanari Iida Reviewed-by: Randy Dunlap Signed-off-by: David S. Miller --- Documentation/networking/snmp_counter.rst | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) (limited to 'Documentation') diff --git a/Documentation/networking/snmp_counter.rst b/Documentation/networking/snmp_counter.rst index 4edd0d38779e..423d138b5ff3 100644 --- a/Documentation/networking/snmp_counter.rst +++ b/Documentation/networking/snmp_counter.rst @@ -314,7 +314,7 @@ https://lwn.net/Articles/576263/ * TcpExtTCPOrigDataSent This counter is explained by `kernel commit f19c29e3e391`_, I pasted the -explaination below:: +explanation below:: TCPOrigDataSent: number of outgoing packets with original data (excluding retransmission but including data-in-SYN). This counter is different from @@ -324,7 +324,7 @@ explaination below:: * TCPSynRetrans This counter is explained by `kernel commit f19c29e3e391`_, I pasted the -explaination below:: +explanation below:: TCPSynRetrans: number of SYN and SYN/ACK retransmits to break down retransmissions into SYN, fast-retransmits, timeout retransmits, etc. @@ -332,7 +332,7 @@ explaination below:: * TCPFastOpenActiveFail This counter is explained by `kernel commit f19c29e3e391`_, I pasted the -explaination below:: +explanation below:: TCPFastOpenActiveFail: Fast Open attempts (SYN/data) failed because the remote does not accept it or the attempts timed out. @@ -382,7 +382,7 @@ Defined in `RFC1213 tcpAttemptFails`_. Defined in `RFC1213 tcpOutRsts`_. The RFC says this counter indicates the 'segments sent containing the RST flag', but in linux kernel, this -couner indicates the segments kerenl tried to send. The sending +counter indicates the segments kernel tried to send. The sending process might be failed due to some errors (e.g. memory alloc failed). .. _RFC1213 tcpOutRsts: https://tools.ietf.org/html/rfc1213#page-52 @@ -700,7 +700,7 @@ SACK option could have up to 4 blocks, they are checked individually. E.g., if 3 blocks of a SACk is invalid, the corresponding counter would be updated 3 times. The comment of the `Add counters for discarded SACK blocks`_ patch has additional -explaination: +explanation: .. _Add counters for discarded SACK blocks: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=18f02545a9a16c9a89778b91a162ad16d510bb32 @@ -829,7 +829,7 @@ PAWS check fails or the received sequence number is out of window. * TcpExtTCPACKSkippedTimeWait -Tha ACK is skipped in Time-Wait status, the reason would be either +The ACK is skipped in Time-Wait status, the reason would be either PAWS check failed or the received sequence number is out of window. * TcpExtTCPACKSkippedChallenge @@ -984,7 +984,7 @@ TcpExtSyncookiesRecv counter wont be updated. Challenge ACK ============= -For details of challenge ACK, please refer the explaination of +For details of challenge ACK, please refer the explanation of TcpExtTCPACKSkippedChallenge. * TcpExtTCPChallengeACK @@ -1002,7 +1002,7 @@ prune ===== When a socket is under memory pressure, the TCP stack will try to reclaim memory from the receiving queue and out of order queue. One of -the reclaiming method is 'collapse', which means allocate a big sbk, +the reclaiming method is 'collapse', which means allocate a big skb, copy the contiguous skbs to the single big skb, and free these contiguous skbs. @@ -1163,7 +1163,7 @@ The server side nstat output:: IpExtOutOctets 52 0.0 IpExtInNoECTPkts 1 0.0 -Input a string in nc client side again ('world' in our exmaple):: +Input a string in nc client side again ('world' in our example):: nstatuser@nstat-a:~$ nc -v nstat-b 9000 Connection to nstat-b 9000 port [tcp/*] succeeded! @@ -1211,7 +1211,7 @@ replied an ACK. But kernel handled them in different ways. When the TCP window scale option is not used, kernel will try to enable fast path immediately when the connection comes into the established state, but if the TCP window scale option is used, kernel will disable the -fast path at first, and try to enable it after kerenl receives +fast path at first, and try to enable it after kernel receives packets. We could use the 'ss' command to verify whether the window scale option is used. e.g. run below command on either server or client:: @@ -1343,7 +1343,7 @@ Check TcpExtTCPAbortOnMemory on client:: nstatuser@nstat-a:~$ nstat | grep -i abort TcpExtTCPAbortOnMemory 54 0.0 -Check orphane socket count on client:: +Check orphaned socket count on client:: nstatuser@nstat-a:~$ ss -s Total: 131 (kernel 0) @@ -1685,7 +1685,7 @@ Send 3 SYN repeatly to nstat-b:: nstatuser@nstat-a:~$ for i in {1..3}; do sudo tcpreplay -i ens3 /tmp/syn_fixcsum.pcap; done -Check snmp cunter on nstat-b:: +Check snmp counter on nstat-b:: nstatuser@nstat-b:~$ nstat | grep -i skip TcpExtTCPACKSkippedSynRecv 1 0.0 @@ -1770,7 +1770,7 @@ string 'foo' in our example:: Connection from nstat-a 42132 received! foo -On nstat-a, the tcpdump should have caputred the ACK. We should check +On nstat-a, the tcpdump should have captured the ACK. We should check the source port numbers of the two nc clients:: nstatuser@nstat-a:~$ ss -ta '( dport = :9000 || dport = :9001 )' | tee @@ -1778,7 +1778,7 @@ the source port numbers of the two nc clients:: ESTAB 0 0 192.168.122.250:50208 192.168.122.251:9000 ESTAB 0 0 192.168.122.250:42132 192.168.122.251:9001 -Run tcprewrite, change port 9001 to port 9000, chagne port 42132 to +Run tcprewrite, change port 9001 to port 9000, change port 42132 to port 50208:: nstatuser@nstat-a:~$ tcprewrite --infile /tmp/seq_pre.pcap --outfile /tmp/seq.pcap -r 9001:9000 -r 42132:50208 --fixcsum -- cgit v1.2.3 From 9684752e5fe3989b45f686a4e0202a683038be4a Mon Sep 17 00:00:00 2001 From: Sowjanya Komatineni Date: Mon, 21 Dec 2020 13:17:32 -0800 Subject: dt-bindings: spi: Add Tegra Quad SPI device tree binding This patch adds YAML based device tree binding document for Tegra Quad SPI driver. Signed-off-by: Sowjanya Komatineni Link: https://lore.kernel.org/r/1608585459-17250-3-git-send-email-skomatineni@nvidia.com Signed-off-by: Mark Brown --- .../bindings/spi/nvidia,tegra210-quad.yaml | 117 +++++++++++++++++++++ 1 file changed, 117 insertions(+) create mode 100644 Documentation/devicetree/bindings/spi/nvidia,tegra210-quad.yaml (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/spi/nvidia,tegra210-quad.yaml b/Documentation/devicetree/bindings/spi/nvidia,tegra210-quad.yaml new file mode 100644 index 000000000000..35a8045b2c70 --- /dev/null +++ b/Documentation/devicetree/bindings/spi/nvidia,tegra210-quad.yaml @@ -0,0 +1,117 @@ +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/spi/nvidia,tegra210-quad.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Tegra Quad SPI Controller + +maintainers: + - Thierry Reding + - Jonathan Hunter + +allOf: + - $ref: "spi-controller.yaml#" + +properties: + compatible: + enum: + - nvidia,tegra210-qspi + - nvidia,tegra186-qspi + - nvidia,tegra194-qspi + + reg: + maxItems: 1 + + interrupts: + maxItems: 1 + + clock-names: + items: + - const: qspi + - const: qspi_out + + clocks: + maxItems: 2 + + resets: + maxItems: 1 + + dmas: + maxItems: 2 + + dma-names: + items: + - const: rx + - const: tx + +patternProperties: + "@[0-9a-f]+": + type: object + + properties: + spi-rx-bus-width: + enum: [1, 2, 4] + + spi-tx-bus-width: + enum: [1, 2, 4] + + nvidia,tx-clk-tap-delay: + description: + Delays the clock going out to device with this tap value. + Tap value varies based on platform design trace lengths from Tegra + QSPI to corresponding slave device. + $ref: /schemas/types.yaml#/definitions/uint32 + minimum: 0 + maximum: 31 + + nvidia,rx-clk-tap-delay: + description: + Delays the clock coming in from the device with this tap value. + Tap value varies based on platform design trace lengths from Tegra + QSPI to corresponding slave device. + $ref: /schemas/types.yaml#/definitions/uint32 + minimum: 0 + maximum: 255 + + required: + - reg + +required: + - compatible + - reg + - interrupts + - clock-names + - clocks + - resets + +unevaluatedProperties: false + +examples: + - | + #include + #include + #include + spi@70410000 { + compatible = "nvidia,tegra210-qspi"; + reg = <0x70410000 0x1000>; + interrupts = ; + #address-cells = <1>; + #size-cells = <0>; + clocks = <&tegra_car TEGRA210_CLK_QSPI>, + <&tegra_car TEGRA210_CLK_QSPI_PM>; + clock-names = "qspi", "qspi_out"; + resets = <&tegra_car 211>; + dmas = <&apbdma 5>, <&apbdma 5>; + dma-names = "rx", "tx"; + + flash@0 { + compatible = "spi-nor"; + reg = <0>; + spi-max-frequency = <104000000>; + spi-tx-bus-width = <2>; + spi-rx-bus-width = <2>; + nvidia,tx-clk-tap-delay = <0>; + nvidia,rx-clk-tap-delay = <0>; + }; + }; -- cgit v1.2.3 From 8b76621b8917a87a8da5fd19f615ff573abf27a3 Mon Sep 17 00:00:00 2001 From: Joakim Zhang Date: Fri, 6 Nov 2020 18:56:24 +0800 Subject: dt-bindings: can: fsl,flexcan: add fsl,scu-index property to indicate a resource For SoCs with SCU support, need setup stop mode via SCU firmware, so this property can help indicate a resource in SCU firmware. Signed-off-by: Joakim Zhang Link: https://lore.kernel.org/r/20201106105627.31061-3-qiangqing.zhang@nxp.com Signed-off-by: Marc Kleine-Budde --- Documentation/devicetree/bindings/net/can/fsl,flexcan.yaml | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/net/can/fsl,flexcan.yaml b/Documentation/devicetree/bindings/net/can/fsl,flexcan.yaml index 0d2df30f19db..fe6a949a2eab 100644 --- a/Documentation/devicetree/bindings/net/can/fsl,flexcan.yaml +++ b/Documentation/devicetree/bindings/net/can/fsl,flexcan.yaml @@ -110,6 +110,16 @@ properties: description: Enable CAN remote wakeup. + fsl,scu-index: + description: | + The scu index of CAN instance. + For SoCs with SCU support, need setup stop mode via SCU firmware, so this + property can help indicate a resource. It supports up to 3 CAN instances + now. + $ref: /schemas/types.yaml#/definitions/uint8 + minimum: 0 + maximum: 2 + required: - compatible - reg @@ -137,4 +147,5 @@ examples: clocks = <&clks 1>, <&clks 2>; clock-names = "ipg", "per"; fsl,stop-mode = <&gpr 0x34 28>; + fsl,scu-index = /bits/ 8 <1>; }; -- cgit v1.2.3 From 752b0aac99c7e0b179875cdfa102d378ccb794a2 Mon Sep 17 00:00:00 2001 From: Paul Kocialkowski Date: Sun, 6 Dec 2020 17:51:27 +0100 Subject: dt-bindings: irq: sun7i-nmi: Add binding documentation for the V3s NMI The V3s NMI controller seems register-compatible with the A80 (sun9i). Add new items for the compatible string, with an entry specific to the V3s and the A80 entry. Acked-by: Rob Herring Signed-off-by: Paul Kocialkowski Signed-off-by: Maxime Ripard Link: https://lore.kernel.org/r/20201206165131.1041983-2-contact@paulk.fr --- .../bindings/interrupt-controller/allwinner,sun7i-a20-sc-nmi.yaml | 3 +++ 1 file changed, 3 insertions(+) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/interrupt-controller/allwinner,sun7i-a20-sc-nmi.yaml b/Documentation/devicetree/bindings/interrupt-controller/allwinner,sun7i-a20-sc-nmi.yaml index 8acca0ae3129..4fd1e2780026 100644 --- a/Documentation/devicetree/bindings/interrupt-controller/allwinner,sun7i-a20-sc-nmi.yaml +++ b/Documentation/devicetree/bindings/interrupt-controller/allwinner,sun7i-a20-sc-nmi.yaml @@ -29,6 +29,9 @@ properties: - items: - const: allwinner,sun8i-a83t-r-intc - const: allwinner,sun6i-a31-r-intc + - items: + - const: allwinner,sun8i-v3s-nmi + - const: allwinner,sun9i-a80-nmi - const: allwinner,sun9i-a80-nmi - items: - const: allwinner,sun50i-a64-r-intc -- cgit v1.2.3 From 46ad18e7d0e294bc2a225e40ad98fa27eb20b86d Mon Sep 17 00:00:00 2001 From: Paul Kocialkowski Date: Sun, 6 Dec 2020 17:51:30 +0100 Subject: dt-bindings: arm: sunxi: Add SL631 with IMX179 bindings This adds documentation for the compatible strings of the SL631 Action Camera with IMX179. Note that the device is sold under various different names, such as the SJCAM SJ4000 Air or F60 Action Camera. This is a similar situation to the Q8 tablets and just like them, the allwinner vendor is used as fallback. Signed-off-by: Paul Kocialkowski Signed-off-by: Maxime Ripard Reviewed-by: Rob Herring Link: https://lore.kernel.org/r/20201206165131.1041983-5-contact@paulk.fr --- Documentation/devicetree/bindings/arm/sunxi.yaml | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/arm/sunxi.yaml b/Documentation/devicetree/bindings/arm/sunxi.yaml index 6db32fbf813f..85324cebb75d 100644 --- a/Documentation/devicetree/bindings/arm/sunxi.yaml +++ b/Documentation/devicetree/bindings/arm/sunxi.yaml @@ -777,6 +777,12 @@ properties: - const: sinlinx,sina33 - const: allwinner,sun8i-a33 + - description: SL631 Action Camera with IMX179 + items: + - const: allwinner,sl631-imx179 + - const: allwinner,sl631 + - const: allwinner,sun8i-v3 + - description: Tanix TX6 items: - const: oranth,tanix-tx6 -- cgit v1.2.3 From 3c3f87d71181f7bde8c2998dd48cb3d861f391c0 Mon Sep 17 00:00:00 2001 From: Icenowy Zheng Date: Thu, 24 Dec 2020 10:39:59 +0800 Subject: dt-bindings: arm: sunxi: add PineTab Early Adopter edition Early adopter's PineTabs (and further releases) will have a new LCD panel different with the one that is used when in development (because the old panel's supply discontinued). Add a new DT compatible for it. Signed-off-by: Icenowy Zheng Signed-off-by: Maxime Ripard Link: https://lore.kernel.org/r/20201224024001.19248-1-icenowy@aosc.io --- Documentation/devicetree/bindings/arm/sunxi.yaml | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/arm/sunxi.yaml b/Documentation/devicetree/bindings/arm/sunxi.yaml index 85324cebb75d..8ab0d79dd44e 100644 --- a/Documentation/devicetree/bindings/arm/sunxi.yaml +++ b/Documentation/devicetree/bindings/arm/sunxi.yaml @@ -700,6 +700,11 @@ properties: - const: pine64,pinetab - const: allwinner,sun50i-a64 + - description: Pine64 PineTab, Early Adopter's batch (and maybe later ones) + items: + - const: pine64,pinetab-early-adopter + - const: allwinner,sun50i-a64 + - description: Pine64 SoPine Baseboard items: - const: pine64,sopine-baseboard -- cgit v1.2.3 From bdb574e592bcf5f7fe17d0173464327fc08ded5b Mon Sep 17 00:00:00 2001 From: Icenowy Zheng Date: Thu, 24 Dec 2020 10:41:38 +0800 Subject: dt-bindings: arm: sunxi: document orig PineTab DT as sample As the original PineTab DT (which uses sun50i-a64-pinetab name) is only for development samples, document this. Signed-off-by: Icenowy Zheng Signed-off-by: Maxime Ripard Link: https://lore.kernel.org/r/20201224024138.19422-1-icenowy@aosc.io --- Documentation/devicetree/bindings/arm/sunxi.yaml | 2 +- arch/arm64/boot/dts/allwinner/sun50i-a64-pinetab.dts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/arm/sunxi.yaml b/Documentation/devicetree/bindings/arm/sunxi.yaml index 8ab0d79dd44e..42a4d01077f0 100644 --- a/Documentation/devicetree/bindings/arm/sunxi.yaml +++ b/Documentation/devicetree/bindings/arm/sunxi.yaml @@ -695,7 +695,7 @@ properties: - const: pine64,pinephone-1.2 - const: allwinner,sun50i-a64 - - description: Pine64 PineTab + - description: Pine64 PineTab, Development Sample items: - const: pine64,pinetab - const: allwinner,sun50i-a64 diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64-pinetab.dts b/arch/arm64/boot/dts/allwinner/sun50i-a64-pinetab.dts index 0494bfaf2ffa..422a8507f674 100644 --- a/arch/arm64/boot/dts/allwinner/sun50i-a64-pinetab.dts +++ b/arch/arm64/boot/dts/allwinner/sun50i-a64-pinetab.dts @@ -14,7 +14,7 @@ #include / { - model = "PineTab"; + model = "PineTab, Development Sample"; compatible = "pine64,pinetab", "allwinner,sun50i-a64"; aliases { -- cgit v1.2.3 From 536f74a892e6a034e09a0d204dd2a3b3b02c5b30 Mon Sep 17 00:00:00 2001 From: Dylan Van Assche Date: Wed, 30 Dec 2020 11:42:05 +0100 Subject: arm64: allwinner: dts: pinephone: add 'pine64, pinephone' to the compatible list All revisions of the PinePhone share most of the hardware. This patch makes it easier to detect PinePhone hardware without having to check for each possible revision. Signed-off-by: Dylan Van Assche Signed-off-by: Maxime Ripard Link: https://lore.kernel.org/r/20201230104205.5592-1-me@dylanvanassche.be --- Documentation/devicetree/bindings/arm/sunxi.yaml | 3 +++ arch/arm64/boot/dts/allwinner/sun50i-a64-pinephone-1.0.dts | 2 +- arch/arm64/boot/dts/allwinner/sun50i-a64-pinephone-1.1.dts | 2 +- arch/arm64/boot/dts/allwinner/sun50i-a64-pinephone-1.2.dts | 2 +- 4 files changed, 6 insertions(+), 3 deletions(-) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/arm/sunxi.yaml b/Documentation/devicetree/bindings/arm/sunxi.yaml index 42a4d01077f0..7ea4d9645e93 100644 --- a/Documentation/devicetree/bindings/arm/sunxi.yaml +++ b/Documentation/devicetree/bindings/arm/sunxi.yaml @@ -683,16 +683,19 @@ properties: - description: Pine64 PinePhone Developer Batch (1.0) items: - const: pine64,pinephone-1.0 + - const: pine64,pinephone - const: allwinner,sun50i-a64 - description: Pine64 PinePhone Braveheart (1.1) items: - const: pine64,pinephone-1.1 + - const: pine64,pinephone - const: allwinner,sun50i-a64 - description: Pine64 PinePhone (1.2) items: - const: pine64,pinephone-1.2 + - const: pine64,pinephone - const: allwinner,sun50i-a64 - description: Pine64 PineTab, Development Sample diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64-pinephone-1.0.dts b/arch/arm64/boot/dts/allwinner/sun50i-a64-pinephone-1.0.dts index 3d5a2ae9aa39..fb65319a3bd3 100644 --- a/arch/arm64/boot/dts/allwinner/sun50i-a64-pinephone-1.0.dts +++ b/arch/arm64/boot/dts/allwinner/sun50i-a64-pinephone-1.0.dts @@ -7,7 +7,7 @@ / { model = "Pine64 PinePhone Developer Batch (1.0)"; - compatible = "pine64,pinephone-1.0", "allwinner,sun50i-a64"; + compatible = "pine64,pinephone-1.0", "pine64,pinephone", "allwinner,sun50i-a64"; }; &sgm3140 { diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64-pinephone-1.1.dts b/arch/arm64/boot/dts/allwinner/sun50i-a64-pinephone-1.1.dts index c9b9f6e9ee8c..5e59d3752178 100644 --- a/arch/arm64/boot/dts/allwinner/sun50i-a64-pinephone-1.1.dts +++ b/arch/arm64/boot/dts/allwinner/sun50i-a64-pinephone-1.1.dts @@ -7,7 +7,7 @@ / { model = "Pine64 PinePhone Braveheart (1.1)"; - compatible = "pine64,pinephone-1.1", "allwinner,sun50i-a64"; + compatible = "pine64,pinephone-1.1", "pine64,pinephone", "allwinner,sun50i-a64"; }; &backlight { diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64-pinephone-1.2.dts b/arch/arm64/boot/dts/allwinner/sun50i-a64-pinephone-1.2.dts index acc0ab53b9c1..4e7e237cb46a 100644 --- a/arch/arm64/boot/dts/allwinner/sun50i-a64-pinephone-1.2.dts +++ b/arch/arm64/boot/dts/allwinner/sun50i-a64-pinephone-1.2.dts @@ -7,7 +7,7 @@ / { model = "Pine64 PinePhone (1.2)"; - compatible = "pine64,pinephone-1.2", "allwinner,sun50i-a64"; + compatible = "pine64,pinephone-1.2", "pine64,pinephone", "allwinner,sun50i-a64"; wifi_pwrseq: wifi-pwrseq { compatible = "mmc-pwrseq-simple"; -- cgit v1.2.3 From d649303243707121dfcad8f47db19239fef4f3da Mon Sep 17 00:00:00 2001 From: Ricardo Rivera-Matos Date: Wed, 6 Jan 2021 13:58:48 -0600 Subject: dt-bindings: power: Add the bq256xx dt bindings Add the bindings for the bq256xx series of battery charging ICs. Datasheets: - https://www.ti.com/lit/ds/symlink/bq25600.pdf - https://www.ti.com/lit/ds/symlink/bq25601.pdf - https://www.ti.com/lit/ds/symlink/bq25600d.pdf - https://www.ti.com/lit/ds/symlink/bq25601d.pdf - https://www.ti.com/lit/ds/symlink/bq25611d.pdf - https://www.ti.com/lit/ds/symlink/bq25618.pdf - https://www.ti.com/lit/ds/symlink/bq25619.pdf Reviewed-by: Rob Herring Signed-off-by: Ricardo Rivera-Matos Signed-off-by: Sebastian Reichel --- .../devicetree/bindings/power/supply/bq256xx.yaml | 110 +++++++++++++++++++++ 1 file changed, 110 insertions(+) create mode 100644 Documentation/devicetree/bindings/power/supply/bq256xx.yaml (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/power/supply/bq256xx.yaml b/Documentation/devicetree/bindings/power/supply/bq256xx.yaml new file mode 100644 index 000000000000..18b54783e11a --- /dev/null +++ b/Documentation/devicetree/bindings/power/supply/bq256xx.yaml @@ -0,0 +1,110 @@ +# SPDX-License-Identifier: (GPL-2.0-only or BSD-2-Clause) +# Copyright (C) 2020 Texas Instruments Incorporated +%YAML 1.2 +--- +$id: "http://devicetree.org/schemas/power/supply/bq256xx.yaml#" +$schema: "http://devicetree.org/meta-schemas/core.yaml#" + +title: TI bq256xx Switch Mode Buck Charger + +maintainers: + - Ricardo Rivera-Matos + +description: | + The bq256xx devices are a family of highly-integrated battery charge + management and system power management ICs for single cell Li-ion and Li- + polymer batteries. + + Datasheets: + - https://www.ti.com/lit/ds/symlink/bq25600.pdf + - https://www.ti.com/lit/ds/symlink/bq25601.pdf + - https://www.ti.com/lit/ds/symlink/bq25600d.pdf + - https://www.ti.com/lit/ds/symlink/bq25601d.pdf + - https://www.ti.com/lit/ds/symlink/bq25611d.pdf + - https://www.ti.com/lit/ds/symlink/bq25618.pdf + - https://www.ti.com/lit/ds/symlink/bq25619.pdf + +properties: + compatible: + enum: + - ti,bq25600 + - ti,bq25601 + - ti,bq25600d + - ti,bq25601d + - ti,bq25611d + - ti,bq25618 + - ti,bq25619 + + reg: + maxItems: 1 + + ti,watchdog-timeout-ms: + $ref: /schemas/types.yaml#/definitions/uint32 + default: 0 + description: | + Watchdog timer in ms. 0 (default) disables the watchdog + minimum: 0 + maximum: 160000 + enum: [ 0, 40000, 80000, 160000] + + input-voltage-limit-microvolt: + description: | + Minimum input voltage limit in µV with a 100000 µV step + minimum: 3900000 + maximum: 5400000 + + input-current-limit-microamp: + description: | + Maximum input current limit in µA with a 100000 µA step + minimum: 100000 + maximum: 3200000 + + monitored-battery: + $ref: /schemas/types.yaml#/definitions/phandle + description: phandle to the battery node being monitored + + interrupts: + maxItems: 1 + description: | + Interrupt sends an active low, 256 μs pulse to host to report the charger + device status and faults. + +required: + - compatible + - reg + - monitored-battery + +additionalProperties: false + +examples: + - | + bat: battery { + compatible = "simple-battery"; + constant-charge-current-max-microamp = <2040000>; + constant-charge-voltage-max-microvolt = <4352000>; + precharge-current-microamp = <180000>; + charge-term-current-microamp = <180000>; + }; + #include + #include + i2c { + + clock-frequency = <400000>; + + #address-cells = <1>; + #size-cells = <0>; + + charger@6b { + compatible = "ti,bq25601"; + reg = <0x6b>; + monitored-battery = <&bat>; + + interrupt-parent = <&gpio1>; + interrupts = <16 IRQ_TYPE_EDGE_FALLING>; + ti,watchdog-timeout-ms = <40000>; + + input-voltage-limit-microvolt = <4500000>; + input-current-limit-microamp = <2400000>; + }; + }; +... -- cgit v1.2.3 From 8d7792823da4abd799d63aaceb23805203a5419e Mon Sep 17 00:00:00 2001 From: Maximilian Luz Date: Mon, 21 Dec 2020 19:39:57 +0100 Subject: docs: driver-api: Add Surface Aggregator subsystem documentation Add documentation for the Surface Aggregator subsystem and its client drivers, giving an overview of the subsystem, its use-cases, its internal structure and internal API, as well as its external API for writing client drivers. Signed-off-by: Maximilian Luz Reviewed-by: Hans de Goede Link: https://lore.kernel.org/r/20201221183959.1186143-8-luzmaximilian@gmail.com Signed-off-by: Hans de Goede --- Documentation/driver-api/index.rst | 1 + .../driver-api/surface_aggregator/client-api.rst | 38 ++ .../driver-api/surface_aggregator/client.rst | 393 ++++++++++++++ .../surface_aggregator/clients/index.rst | 10 + .../driver-api/surface_aggregator/index.rst | 21 + .../driver-api/surface_aggregator/internal-api.rst | 67 +++ .../driver-api/surface_aggregator/internal.rst | 577 +++++++++++++++++++++ .../driver-api/surface_aggregator/overview.rst | 77 +++ .../driver-api/surface_aggregator/ssh.rst | 344 ++++++++++++ MAINTAINERS | 1 + 10 files changed, 1529 insertions(+) create mode 100644 Documentation/driver-api/surface_aggregator/client-api.rst create mode 100644 Documentation/driver-api/surface_aggregator/client.rst create mode 100644 Documentation/driver-api/surface_aggregator/clients/index.rst create mode 100644 Documentation/driver-api/surface_aggregator/index.rst create mode 100644 Documentation/driver-api/surface_aggregator/internal-api.rst create mode 100644 Documentation/driver-api/surface_aggregator/internal.rst create mode 100644 Documentation/driver-api/surface_aggregator/overview.rst create mode 100644 Documentation/driver-api/surface_aggregator/ssh.rst (limited to 'Documentation') diff --git a/Documentation/driver-api/index.rst b/Documentation/driver-api/index.rst index 2456d0a97ed8..9d9af54d68c5 100644 --- a/Documentation/driver-api/index.rst +++ b/Documentation/driver-api/index.rst @@ -99,6 +99,7 @@ available subsections can be seen below. rfkill serial/index sm501 + surface_aggregator/index switchtec sync_file vfio-mediated-device diff --git a/Documentation/driver-api/surface_aggregator/client-api.rst b/Documentation/driver-api/surface_aggregator/client-api.rst new file mode 100644 index 000000000000..8e0b000d0e64 --- /dev/null +++ b/Documentation/driver-api/surface_aggregator/client-api.rst @@ -0,0 +1,38 @@ +.. SPDX-License-Identifier: GPL-2.0+ + +=============================== +Client Driver API Documentation +=============================== + +.. contents:: + :depth: 2 + + +Serial Hub Communication +======================== + +.. kernel-doc:: include/linux/surface_aggregator/serial_hub.h + +.. kernel-doc:: drivers/platform/surface/aggregator/ssh_packet_layer.c + :export: + + +Controller and Core Interface +============================= + +.. kernel-doc:: include/linux/surface_aggregator/controller.h + +.. kernel-doc:: drivers/platform/surface/aggregator/controller.c + :export: + +.. kernel-doc:: drivers/platform/surface/aggregator/core.c + :export: + + +Client Bus and Client Device API +================================ + +.. kernel-doc:: include/linux/surface_aggregator/device.h + +.. kernel-doc:: drivers/platform/surface/aggregator/bus.c + :export: diff --git a/Documentation/driver-api/surface_aggregator/client.rst b/Documentation/driver-api/surface_aggregator/client.rst new file mode 100644 index 000000000000..26d13085a117 --- /dev/null +++ b/Documentation/driver-api/surface_aggregator/client.rst @@ -0,0 +1,393 @@ +.. SPDX-License-Identifier: GPL-2.0+ + +.. |ssam_controller| replace:: :c:type:`struct ssam_controller ` +.. |ssam_device| replace:: :c:type:`struct ssam_device ` +.. |ssam_device_driver| replace:: :c:type:`struct ssam_device_driver ` +.. |ssam_client_bind| replace:: :c:func:`ssam_client_bind` +.. |ssam_client_link| replace:: :c:func:`ssam_client_link` +.. |ssam_get_controller| replace:: :c:func:`ssam_get_controller` +.. |ssam_controller_get| replace:: :c:func:`ssam_controller_get` +.. |ssam_controller_put| replace:: :c:func:`ssam_controller_put` +.. |ssam_device_alloc| replace:: :c:func:`ssam_device_alloc` +.. |ssam_device_add| replace:: :c:func:`ssam_device_add` +.. |ssam_device_remove| replace:: :c:func:`ssam_device_remove` +.. |ssam_device_driver_register| replace:: :c:func:`ssam_device_driver_register` +.. |ssam_device_driver_unregister| replace:: :c:func:`ssam_device_driver_unregister` +.. |module_ssam_device_driver| replace:: :c:func:`module_ssam_device_driver` +.. |SSAM_DEVICE| replace:: :c:func:`SSAM_DEVICE` +.. |ssam_notifier_register| replace:: :c:func:`ssam_notifier_register` +.. |ssam_notifier_unregister| replace:: :c:func:`ssam_notifier_unregister` +.. |ssam_request_sync| replace:: :c:func:`ssam_request_sync` +.. |ssam_event_mask| replace:: :c:type:`enum ssam_event_mask ` + + +====================== +Writing Client Drivers +====================== + +For the API documentation, refer to: + +.. toctree:: + :maxdepth: 2 + + client-api + + +Overview +======== + +Client drivers can be set up in two main ways, depending on how the +corresponding device is made available to the system. We specifically +differentiate between devices that are presented to the system via one of +the conventional ways, e.g. as platform devices via ACPI, and devices that +are non-discoverable and instead need to be explicitly provided by some +other mechanism, as discussed further below. + + +Non-SSAM Client Drivers +======================= + +All communication with the SAM EC is handled via the |ssam_controller| +representing that EC to the kernel. Drivers targeting a non-SSAM device (and +thus not being a |ssam_device_driver|) need to explicitly establish a +connection/relation to that controller. This can be done via the +|ssam_client_bind| function. Said function returns a reference to the SSAM +controller, but, more importantly, also establishes a device link between +client device and controller (this can also be done separate via +|ssam_client_link|). It is important to do this, as it, first, guarantees +that the returned controller is valid for use in the client driver for as +long as this driver is bound to its device, i.e. that the driver gets +unbound before the controller ever becomes invalid, and, second, as it +ensures correct suspend/resume ordering. This setup should be done in the +driver's probe function, and may be used to defer probing in case the SSAM +subsystem is not ready yet, for example: + +.. code-block:: c + + static int client_driver_probe(struct platform_device *pdev) + { + struct ssam_controller *ctrl; + + ctrl = ssam_client_bind(&pdev->dev); + if (IS_ERR(ctrl)) + return PTR_ERR(ctrl) == -ENODEV ? -EPROBE_DEFER : PTR_ERR(ctrl); + + // ... + + return 0; + } + +The controller may be separately obtained via |ssam_get_controller| and its +lifetime be guaranteed via |ssam_controller_get| and |ssam_controller_put|. +Note that none of these functions, however, guarantee that the controller +will not be shut down or suspended. These functions essentially only operate +on the reference, i.e. only guarantee a bare minimum of accessibility +without any guarantees at all on practical operability. + + +Adding SSAM Devices +=================== + +If a device does not already exist/is not already provided via conventional +means, it should be provided as |ssam_device| via the SSAM client device +hub. New devices can be added to this hub by entering their UID into the +corresponding registry. SSAM devices can also be manually allocated via +|ssam_device_alloc|, subsequently to which they have to be added via +|ssam_device_add| and eventually removed via |ssam_device_remove|. By +default, the parent of the device is set to the controller device provided +for allocation, however this may be changed before the device is added. Note +that, when changing the parent device, care must be taken to ensure that the +controller lifetime and suspend/resume ordering guarantees, in the default +setup provided through the parent-child relation, are preserved. If +necessary, by use of |ssam_client_link| as is done for non-SSAM client +drivers and described in more detail above. + +A client device must always be removed by the party which added the +respective device before the controller shuts down. Such removal can be +guaranteed by linking the driver providing the SSAM device to the controller +via |ssam_client_link|, causing it to unbind before the controller driver +unbinds. Client devices registered with the controller as parent are +automatically removed when the controller shuts down, but this should not be +relied upon, especially as this does not extend to client devices with a +different parent. + + +SSAM Client Drivers +=================== + +SSAM client device drivers are, in essence, no different than other device +driver types. They are represented via |ssam_device_driver| and bind to a +|ssam_device| via its UID (:c:type:`struct ssam_device.uid `) +member and the match table +(:c:type:`struct ssam_device_driver.match_table `), +which should be set when declaring the driver struct instance. Refer to the +|SSAM_DEVICE| macro documentation for more details on how to define members +of the driver's match table. + +The UID for SSAM client devices consists of a ``domain``, a ``category``, +a ``target``, an ``instance``, and a ``function``. The ``domain`` is used +differentiate between physical SAM devices +(:c:type:`SSAM_DOMAIN_SERIALHUB `), i.e. devices that can +be accessed via the Surface Serial Hub, and virtual ones +(:c:type:`SSAM_DOMAIN_VIRTUAL `), such as client-device +hubs, that have no real representation on the SAM EC and are solely used on +the kernel/driver-side. For physical devices, ``category`` represents the +target category, ``target`` the target ID, and ``instance`` the instance ID +used to access the physical SAM device. In addition, ``function`` references +a specific device functionality, but has no meaning to the SAM EC. The +(default) name of a client device is generated based on its UID. + +A driver instance can be registered via |ssam_device_driver_register| and +unregistered via |ssam_device_driver_unregister|. For convenience, the +|module_ssam_device_driver| macro may be used to define module init- and +exit-functions registering the driver. + +The controller associated with a SSAM client device can be found in its +:c:type:`struct ssam_device.ctrl ` member. This reference is +guaranteed to be valid for at least as long as the client driver is bound, +but should also be valid for as long as the client device exists. Note, +however, that access outside of the bound client driver must ensure that the +controller device is not suspended while making any requests or +(un-)registering event notifiers (and thus should generally be avoided). This +is guaranteed when the controller is accessed from inside the bound client +driver. + + +Making Synchronous Requests +=========================== + +Synchronous requests are (currently) the main form of host-initiated +communication with the EC. There are a couple of ways to define and execute +such requests, however, most of them boil down to something similar as shown +in the example below. This example defines a write-read request, meaning +that the caller provides an argument to the SAM EC and receives a response. +The caller needs to know the (maximum) length of the response payload and +provide a buffer for it. + +Care must be taken to ensure that any command payload data passed to the SAM +EC is provided in little-endian format and, similarly, any response payload +data received from it is converted from little-endian to host endianness. + +.. code-block:: c + + int perform_request(struct ssam_controller *ctrl, u32 arg, u32 *ret) + { + struct ssam_request rqst; + struct ssam_response resp; + int status; + + /* Convert request argument to little-endian. */ + __le32 arg_le = cpu_to_le32(arg); + __le32 ret_le = cpu_to_le32(0); + + /* + * Initialize request specification. Replace this with your values. + * The rqst.payload field may be NULL if rqst.length is zero, + * indicating that the request does not have any argument. + * + * Note: The request parameters used here are not valid, i.e. + * they do not correspond to an actual SAM/EC request. + */ + rqst.target_category = SSAM_SSH_TC_SAM; + rqst.target_id = 0x01; + rqst.command_id = 0x02; + rqst.instance_id = 0x03; + rqst.flags = SSAM_REQUEST_HAS_RESPONSE; + rqst.length = sizeof(arg_le); + rqst.payload = (u8 *)&arg_le; + + /* Initialize request response. */ + resp.capacity = sizeof(ret_le); + resp.length = 0; + resp.pointer = (u8 *)&ret_le; + + /* + * Perform actual request. The response pointer may be null in case + * the request does not have any response. This must be consistent + * with the SSAM_REQUEST_HAS_RESPONSE flag set in the specification + * above. + */ + status = ssam_request_sync(ctrl, &rqst, &resp); + + /* + * Alternatively use + * + * ssam_request_sync_onstack(ctrl, &rqst, &resp, sizeof(arg_le)); + * + * to perform the request, allocating the message buffer directly + * on the stack as opposed to allocation via kzalloc(). + */ + + /* + * Convert request response back to native format. Note that in the + * error case, this value is not touched by the SSAM core, i.e. + * 'ret_le' will be zero as specified in its initialization. + */ + *ret = le32_to_cpu(ret_le); + + return status; + } + +Note that |ssam_request_sync| in its essence is a wrapper over lower-level +request primitives, which may also be used to perform requests. Refer to its +implementation and documentation for more details. + +An arguably more user-friendly way of defining such functions is by using +one of the generator macros, for example via: + +.. code-block:: c + + SSAM_DEFINE_SYNC_REQUEST_W(__ssam_tmp_perf_mode_set, __le32, { + .target_category = SSAM_SSH_TC_TMP, + .target_id = 0x01, + .command_id = 0x03, + .instance_id = 0x00, + }); + +This example defines a function + +.. code-block:: c + + int __ssam_tmp_perf_mode_set(struct ssam_controller *ctrl, const __le32 *arg); + +executing the specified request, with the controller passed in when calling +said function. In this example, the argument is provided via the ``arg`` +pointer. Note that the generated function allocates the message buffer on +the stack. Thus, if the argument provided via the request is large, these +kinds of macros should be avoided. Also note that, in contrast to the +previous non-macro example, this function does not do any endianness +conversion, which has to be handled by the caller. Apart from those +differences the function generated by the macro is similar to the one +provided in the non-macro example above. + +The full list of such function-generating macros is + +- :c:func:`SSAM_DEFINE_SYNC_REQUEST_N` for requests without return value and + without argument. +- :c:func:`SSAM_DEFINE_SYNC_REQUEST_R` for requests with return value but no + argument. +- :c:func:`SSAM_DEFINE_SYNC_REQUEST_W` for requests without return value but + with argument. + +Refer to their respective documentation for more details. For each one of +these macros, a special variant is provided, which targets request types +applicable to multiple instances of the same device type: + +- :c:func:`SSAM_DEFINE_SYNC_REQUEST_MD_N` +- :c:func:`SSAM_DEFINE_SYNC_REQUEST_MD_R` +- :c:func:`SSAM_DEFINE_SYNC_REQUEST_MD_W` + +The difference of those macros to the previously mentioned versions is, that +the device target and instance IDs are not fixed for the generated function, +but instead have to be provided by the caller of said function. + +Additionally, variants for direct use with client devices, i.e. +|ssam_device|, are also provided. These can, for example, be used as +follows: + +.. code-block:: c + + SSAM_DEFINE_SYNC_REQUEST_CL_R(ssam_bat_get_sta, __le32, { + .target_category = SSAM_SSH_TC_BAT, + .command_id = 0x01, + }); + +This invocation of the macro defines a function + +.. code-block:: c + + int ssam_bat_get_sta(struct ssam_device *sdev, __le32 *ret); + +executing the specified request, using the device IDs and controller given +in the client device. The full list of such macros for client devices is: + +- :c:func:`SSAM_DEFINE_SYNC_REQUEST_CL_N` +- :c:func:`SSAM_DEFINE_SYNC_REQUEST_CL_R` +- :c:func:`SSAM_DEFINE_SYNC_REQUEST_CL_W` + + +Handling Events +=============== + +To receive events from the SAM EC, an event notifier must be registered for +the desired event via |ssam_notifier_register|. The notifier must be +unregistered via |ssam_notifier_unregister| once it is not required any +more. + +Event notifiers are registered by providing (at minimum) a callback to call +in case an event has been received, the registry specifying how the event +should be enabled, an event ID specifying for which target category and, +optionally and depending on the registry used, for which instance ID events +should be enabled, and finally, flags describing how the EC will send these +events. If the specific registry does not enable events by instance ID, the +instance ID must be set to zero. Additionally, a priority for the respective +notifier may be specified, which determines its order in relation to any +other notifier registered for the same target category. + +By default, event notifiers will receive all events for the specific target +category, regardless of the instance ID specified when registering the +notifier. The core may be instructed to only call a notifier if the target +ID or instance ID (or both) of the event match the ones implied by the +notifier IDs (in case of target ID, the target ID of the registry), by +providing an event mask (see |ssam_event_mask|). + +In general, the target ID of the registry is also the target ID of the +enabled event (with the notable exception being keyboard input events on the +Surface Laptop 1 and 2, which are enabled via a registry with target ID 1, +but provide events with target ID 2). + +A full example for registering an event notifier and handling received +events is provided below: + +.. code-block:: c + + u32 notifier_callback(struct ssam_event_notifier *nf, + const struct ssam_event *event) + { + int status = ... + + /* Handle the event here ... */ + + /* Convert return value and indicate that we handled the event. */ + return ssam_notifier_from_errno(status) | SSAM_NOTIF_HANDLED; + } + + int setup_notifier(struct ssam_device *sdev, + struct ssam_event_notifier *nf) + { + /* Set priority wrt. other handlers of same target category. */ + nf->base.priority = 1; + + /* Set event/notifier callback. */ + nf->base.fn = notifier_callback; + + /* Specify event registry, i.e. how events get enabled/disabled. */ + nf->event.reg = SSAM_EVENT_REGISTRY_KIP; + + /* Specify which event to enable/disable */ + nf->event.id.target_category = sdev->uid.category; + nf->event.id.instance = sdev->uid.instance; + + /* + * Specify for which events the notifier callback gets executed. + * This essentially tells the core if it can skip notifiers that + * don't have target or instance IDs matching those of the event. + */ + nf->event.mask = SSAM_EVENT_MASK_STRICT; + + /* Specify event flags. */ + nf->event.flags = SSAM_EVENT_SEQUENCED; + + return ssam_notifier_register(sdev->ctrl, nf); + } + +Multiple event notifiers can be registered for the same event. The event +handler core takes care of enabling and disabling events when notifiers are +registered and unregistered, by keeping track of how many notifiers for a +specific event (combination of registry, event target category, and event +instance ID) are currently registered. This means that a specific event will +be enabled when the first notifier for it is being registered and disabled +when the last notifier for it is being unregistered. Note that the event +flags are therefore only used on the first registered notifier, however, one +should take care that notifiers for a specific event are always registered +with the same flag and it is considered a bug to do otherwise. diff --git a/Documentation/driver-api/surface_aggregator/clients/index.rst b/Documentation/driver-api/surface_aggregator/clients/index.rst new file mode 100644 index 000000000000..31e026d96102 --- /dev/null +++ b/Documentation/driver-api/surface_aggregator/clients/index.rst @@ -0,0 +1,10 @@ +.. SPDX-License-Identifier: GPL-2.0+ + +=========================== +Client Driver Documentation +=========================== + +This is the documentation for client drivers themselves. Refer to +:doc:`../client` for documentation on how to write client drivers. + +.. Place documentation for individual client drivers here. diff --git a/Documentation/driver-api/surface_aggregator/index.rst b/Documentation/driver-api/surface_aggregator/index.rst new file mode 100644 index 000000000000..6f3e1094904d --- /dev/null +++ b/Documentation/driver-api/surface_aggregator/index.rst @@ -0,0 +1,21 @@ +.. SPDX-License-Identifier: GPL-2.0+ + +======================================= +Surface System Aggregator Module (SSAM) +======================================= + +.. toctree:: + :maxdepth: 2 + + overview + client + clients/index + ssh + internal + +.. only:: subproject and html + + Indices + ======= + + * :ref:`genindex` diff --git a/Documentation/driver-api/surface_aggregator/internal-api.rst b/Documentation/driver-api/surface_aggregator/internal-api.rst new file mode 100644 index 000000000000..639a67b5a392 --- /dev/null +++ b/Documentation/driver-api/surface_aggregator/internal-api.rst @@ -0,0 +1,67 @@ +.. SPDX-License-Identifier: GPL-2.0+ + +========================== +Internal API Documentation +========================== + +.. contents:: + :depth: 2 + + +Packet Transport Layer +====================== + +.. kernel-doc:: drivers/platform/surface/aggregator/ssh_parser.h + :internal: + +.. kernel-doc:: drivers/platform/surface/aggregator/ssh_parser.c + :internal: + +.. kernel-doc:: drivers/platform/surface/aggregator/ssh_msgb.h + :internal: + +.. kernel-doc:: drivers/platform/surface/aggregator/ssh_packet_layer.h + :internal: + +.. kernel-doc:: drivers/platform/surface/aggregator/ssh_packet_layer.c + :internal: + + +Request Transport Layer +======================= + +.. kernel-doc:: drivers/platform/surface/aggregator/ssh_request_layer.h + :internal: + +.. kernel-doc:: drivers/platform/surface/aggregator/ssh_request_layer.c + :internal: + + +Controller +========== + +.. kernel-doc:: drivers/platform/surface/aggregator/controller.h + :internal: + +.. kernel-doc:: drivers/platform/surface/aggregator/controller.c + :internal: + + +Client Device Bus +================= + +.. kernel-doc:: drivers/platform/surface/aggregator/bus.c + :internal: + + +Core +==== + +.. kernel-doc:: drivers/platform/surface/aggregator/core.c + :internal: + + +Trace Helpers +============= + +.. kernel-doc:: drivers/platform/surface/aggregator/trace.h diff --git a/Documentation/driver-api/surface_aggregator/internal.rst b/Documentation/driver-api/surface_aggregator/internal.rst new file mode 100644 index 000000000000..72704734982a --- /dev/null +++ b/Documentation/driver-api/surface_aggregator/internal.rst @@ -0,0 +1,577 @@ +.. SPDX-License-Identifier: GPL-2.0+ + +.. |ssh_ptl| replace:: :c:type:`struct ssh_ptl ` +.. |ssh_ptl_submit| replace:: :c:func:`ssh_ptl_submit` +.. |ssh_ptl_cancel| replace:: :c:func:`ssh_ptl_cancel` +.. |ssh_ptl_shutdown| replace:: :c:func:`ssh_ptl_shutdown` +.. |ssh_ptl_rx_rcvbuf| replace:: :c:func:`ssh_ptl_rx_rcvbuf` +.. |ssh_rtl| replace:: :c:type:`struct ssh_rtl ` +.. |ssh_rtl_submit| replace:: :c:func:`ssh_rtl_submit` +.. |ssh_rtl_cancel| replace:: :c:func:`ssh_rtl_cancel` +.. |ssh_rtl_shutdown| replace:: :c:func:`ssh_rtl_shutdown` +.. |ssh_packet| replace:: :c:type:`struct ssh_packet ` +.. |ssh_packet_get| replace:: :c:func:`ssh_packet_get` +.. |ssh_packet_put| replace:: :c:func:`ssh_packet_put` +.. |ssh_packet_ops| replace:: :c:type:`struct ssh_packet_ops ` +.. |ssh_packet_base_priority| replace:: :c:type:`enum ssh_packet_base_priority ` +.. |ssh_packet_flags| replace:: :c:type:`enum ssh_packet_flags ` +.. |SSH_PACKET_PRIORITY| replace:: :c:func:`SSH_PACKET_PRIORITY` +.. |ssh_frame| replace:: :c:type:`struct ssh_frame ` +.. |ssh_command| replace:: :c:type:`struct ssh_command ` +.. |ssh_request| replace:: :c:type:`struct ssh_request ` +.. |ssh_request_get| replace:: :c:func:`ssh_request_get` +.. |ssh_request_put| replace:: :c:func:`ssh_request_put` +.. |ssh_request_ops| replace:: :c:type:`struct ssh_request_ops ` +.. |ssh_request_init| replace:: :c:func:`ssh_request_init` +.. |ssh_request_flags| replace:: :c:type:`enum ssh_request_flags ` +.. |ssam_controller| replace:: :c:type:`struct ssam_controller ` +.. |ssam_device| replace:: :c:type:`struct ssam_device ` +.. |ssam_device_driver| replace:: :c:type:`struct ssam_device_driver ` +.. |ssam_client_bind| replace:: :c:func:`ssam_client_bind` +.. |ssam_client_link| replace:: :c:func:`ssam_client_link` +.. |ssam_request_sync| replace:: :c:type:`struct ssam_request_sync ` +.. |ssam_event_registry| replace:: :c:type:`struct ssam_event_registry ` +.. |ssam_event_id| replace:: :c:type:`struct ssam_event_id ` +.. |ssam_nf| replace:: :c:type:`struct ssam_nf ` +.. |ssam_nf_refcount_inc| replace:: :c:func:`ssam_nf_refcount_inc` +.. |ssam_nf_refcount_dec| replace:: :c:func:`ssam_nf_refcount_dec` +.. |ssam_notifier_register| replace:: :c:func:`ssam_notifier_register` +.. |ssam_notifier_unregister| replace:: :c:func:`ssam_notifier_unregister` +.. |ssam_cplt| replace:: :c:type:`struct ssam_cplt ` +.. |ssam_event_queue| replace:: :c:type:`struct ssam_event_queue ` +.. |ssam_request_sync_submit| replace:: :c:func:`ssam_request_sync_submit` + +===================== +Core Driver Internals +===================== + +Architectural overview of the Surface System Aggregator Module (SSAM) core +and Surface Serial Hub (SSH) driver. For the API documentation, refer to: + +.. toctree:: + :maxdepth: 2 + + internal-api + + +Overview +======== + +The SSAM core implementation is structured in layers, somewhat following the +SSH protocol structure: + +Lower-level packet transport is implemented in the *packet transport layer +(PTL)*, directly building on top of the serial device (serdev) +infrastructure of the kernel. As the name indicates, this layer deals with +the packet transport logic and handles things like packet validation, packet +acknowledgment (ACKing), packet (retransmission) timeouts, and relaying +packet payloads to higher-level layers. + +Above this sits the *request transport layer (RTL)*. This layer is centered +around command-type packet payloads, i.e. requests (sent from host to EC), +responses of the EC to those requests, and events (sent from EC to host). +It, specifically, distinguishes events from request responses, matches +responses to their corresponding requests, and implements request timeouts. + +The *controller* layer is building on top of this and essentially decides +how request responses and, especially, events are dealt with. It provides an +event notifier system, handles event activation/deactivation, provides a +workqueue for event and asynchronous request completion, and also manages +the message counters required for building command messages (``SEQ``, +``RQID``). This layer basically provides a fundamental interface to the SAM +EC for use in other kernel drivers. + +While the controller layer already provides an interface for other kernel +drivers, the client *bus* extends this interface to provide support for +native SSAM devices, i.e. devices that are not defined in ACPI and not +implemented as platform devices, via |ssam_device| and |ssam_device_driver| +simplify management of client devices and client drivers. + +Refer to :doc:`client` for documentation regarding the client device/driver +API and interface options for other kernel drivers. It is recommended to +familiarize oneself with that chapter and the :doc:`ssh` before continuing +with the architectural overview below. + + +Packet Transport Layer +====================== + +The packet transport layer is represented via |ssh_ptl| and is structured +around the following key concepts: + +Packets +------- + +Packets are the fundamental transmission unit of the SSH protocol. They are +managed by the packet transport layer, which is essentially the lowest layer +of the driver and is built upon by other components of the SSAM core. +Packets to be transmitted by the SSAM core are represented via |ssh_packet| +(in contrast, packets received by the core do not have any specific +structure and are managed entirely via the raw |ssh_frame|). + +This structure contains the required fields to manage the packet inside the +transport layer, as well as a reference to the buffer containing the data to +be transmitted (i.e. the message wrapped in |ssh_frame|). Most notably, it +contains an internal reference count, which is used for managing its +lifetime (accessible via |ssh_packet_get| and |ssh_packet_put|). When this +counter reaches zero, the ``release()`` callback provided to the packet via +its |ssh_packet_ops| reference is executed, which may then deallocate the +packet or its enclosing structure (e.g. |ssh_request|). + +In addition to the ``release`` callback, the |ssh_packet_ops| reference also +provides a ``complete()`` callback, which is run once the packet has been +completed and provides the status of this completion, i.e. zero on success +or a negative errno value in case of an error. Once the packet has been +submitted to the packet transport layer, the ``complete()`` callback is +always guaranteed to be executed before the ``release()`` callback, i.e. the +packet will always be completed, either successfully, with an error, or due +to cancellation, before it will be released. + +The state of a packet is managed via its ``state`` flags +(|ssh_packet_flags|), which also contains the packet type. In particular, +the following bits are noteworthy: + +* ``SSH_PACKET_SF_LOCKED_BIT``: This bit is set when completion, either + through error or success, is imminent. It indicates that no further + references of the packet should be taken and any existing references + should be dropped as soon as possible. The process setting this bit is + responsible for removing any references to this packet from the packet + queue and pending set. + +* ``SSH_PACKET_SF_COMPLETED_BIT``: This bit is set by the process running the + ``complete()`` callback and is used to ensure that this callback only runs + once. + +* ``SSH_PACKET_SF_QUEUED_BIT``: This bit is set when the packet is queued on + the packet queue and cleared when it is dequeued. + +* ``SSH_PACKET_SF_PENDING_BIT``: This bit is set when the packet is added to + the pending set and cleared when it is removed from it. + +Packet Queue +------------ + +The packet queue is the first of the two fundamental collections in the +packet transport layer. It is a priority queue, with priority of the +respective packets based on the packet type (major) and number of tries +(minor). See |SSH_PACKET_PRIORITY| for more details on the priority value. + +All packets to be transmitted by the transport layer must be submitted to +this queue via |ssh_ptl_submit|. Note that this includes control packets +sent by the transport layer itself. Internally, data packets can be +re-submitted to this queue due to timeouts or NAK packets sent by the EC. + +Pending Set +----------- + +The pending set is the second of the two fundamental collections in the +packet transport layer. It stores references to packets that have already +been transmitted, but wait for acknowledgment (e.g. the corresponding ACK +packet) by the EC. + +Note that a packet may both be pending and queued if it has been +re-submitted due to a packet acknowledgment timeout or NAK. On such a +re-submission, packets are not removed from the pending set. + +Transmitter Thread +------------------ + +The transmitter thread is responsible for most of the actual work regarding +packet transmission. In each iteration, it (waits for and) checks if the +next packet on the queue (if any) can be transmitted and, if so, removes it +from the queue and increments its counter for the number of transmission +attempts, i.e. tries. If the packet is sequenced, i.e. requires an ACK by +the EC, the packet is added to the pending set. Next, the packet's data is +submitted to the serdev subsystem. In case of an error or timeout during +this submission, the packet is completed by the transmitter thread with the +status value of the callback set accordingly. In case the packet is +unsequenced, i.e. does not require an ACK by the EC, the packet is completed +with success on the transmitter thread. + +Transmission of sequenced packets is limited by the number of concurrently +pending packets, i.e. a limit on how many packets may be waiting for an ACK +from the EC in parallel. This limit is currently set to one (see :doc:`ssh` +for the reasoning behind this). Control packets (i.e. ACK and NAK) can +always be transmitted. + +Receiver Thread +--------------- + +Any data received from the EC is put into a FIFO buffer for further +processing. This processing happens on the receiver thread. The receiver +thread parses and validates the received message into its |ssh_frame| and +corresponding payload. It prepares and submits the necessary ACK (and on +validation error or invalid data NAK) packets for the received messages. + +This thread also handles further processing, such as matching ACK messages +to the corresponding pending packet (via sequence ID) and completing it, as +well as initiating re-submission of all currently pending packets on +receival of a NAK message (re-submission in case of a NAK is similar to +re-submission due to timeout, see below for more details on that). Note that +the successful completion of a sequenced packet will always run on the +receiver thread (whereas any failure-indicating completion will run on the +process where the failure occurred). + +Any payload data is forwarded via a callback to the next upper layer, i.e. +the request transport layer. + +Timeout Reaper +-------------- + +The packet acknowledgment timeout is a per-packet timeout for sequenced +packets, started when the respective packet begins (re-)transmission (i.e. +this timeout is armed once per transmission attempt on the transmitter +thread). It is used to trigger re-submission or, when the number of tries +has been exceeded, cancellation of the packet in question. + +This timeout is handled via a dedicated reaper task, which is essentially a +work item (re-)scheduled to run when the next packet is set to time out. The +work item then checks the set of pending packets for any packets that have +exceeded the timeout and, if there are any remaining packets, re-schedules +itself to the next appropriate point in time. + +If a timeout has been detected by the reaper, the packet will either be +re-submitted if it still has some remaining tries left, or completed with +``-ETIMEDOUT`` as status if not. Note that re-submission, in this case and +triggered by receival of a NAK, means that the packet is added to the queue +with a now incremented number of tries, yielding a higher priority. The +timeout for the packet will be disabled until the next transmission attempt +and the packet remains on the pending set. + +Note that due to transmission and packet acknowledgment timeouts, the packet +transport layer is always guaranteed to make progress, if only through +timing out packets, and will never fully block. + +Concurrency and Locking +----------------------- + +There are two main locks in the packet transport layer: One guarding access +to the packet queue and one guarding access to the pending set. These +collections may only be accessed and modified under the respective lock. If +access to both collections is needed, the pending lock must be acquired +before the queue lock to avoid deadlocks. + +In addition to guarding the collections, after initial packet submission +certain packet fields may only be accessed under one of the locks. +Specifically, the packet priority must only be accessed while holding the +queue lock and the packet timestamp must only be accessed while holding the +pending lock. + +Other parts of the packet transport layer are guarded independently. State +flags are managed by atomic bit operations and, if necessary, memory +barriers. Modifications to the timeout reaper work item and expiration date +are guarded by their own lock. + +The reference of the packet to the packet transport layer (``ptl``) is +somewhat special. It is either set when the upper layer request is submitted +or, if there is none, when the packet is first submitted. After it is set, +it will not change its value. Functions that may run concurrently with +submission, i.e. cancellation, can not rely on the ``ptl`` reference to be +set. Access to it in these functions is guarded by ``READ_ONCE()``, whereas +setting ``ptl`` is equally guarded with ``WRITE_ONCE()`` for symmetry. + +Some packet fields may be read outside of the respective locks guarding +them, specifically priority and state for tracing. In those cases, proper +access is ensured by employing ``WRITE_ONCE()`` and ``READ_ONCE()``. Such +read-only access is only allowed when stale values are not critical. + +With respect to the interface for higher layers, packet submission +(|ssh_ptl_submit|), packet cancellation (|ssh_ptl_cancel|), data receival +(|ssh_ptl_rx_rcvbuf|), and layer shutdown (|ssh_ptl_shutdown|) may always be +executed concurrently with respect to each other. Note that packet +submission may not run concurrently with itself for the same packet. +Equally, shutdown and data receival may also not run concurrently with +themselves (but may run concurrently with each other). + + +Request Transport Layer +======================= + +The request transport layer is represented via |ssh_rtl| and builds on top +of the packet transport layer. It deals with requests, i.e. SSH packets sent +by the host containing a |ssh_command| as frame payload. This layer +separates responses to requests from events, which are also sent by the EC +via a |ssh_command| payload. While responses are handled in this layer, +events are relayed to the next upper layer, i.e. the controller layer, via +the corresponding callback. The request transport layer is structured around +the following key concepts: + +Request +------- + +Requests are packets with a command-type payload, sent from host to EC to +query data from or trigger an action on it (or both simultaneously). They +are represented by |ssh_request|, wrapping the underlying |ssh_packet| +storing its message data (i.e. SSH frame with command payload). Note that +all top-level representations, e.g. |ssam_request_sync| are built upon this +struct. + +As |ssh_request| extends |ssh_packet|, its lifetime is also managed by the +reference counter inside the packet struct (which can be accessed via +|ssh_request_get| and |ssh_request_put|). Once the counter reaches zero, the +``release()`` callback of the |ssh_request_ops| reference of the request is +called. + +Requests can have an optional response that is equally sent via a SSH +message with command-type payload (from EC to host). The party constructing +the request must know if a response is expected and mark this in the request +flags provided to |ssh_request_init|, so that the request transport layer +can wait for this response. + +Similar to |ssh_packet|, |ssh_request| also has a ``complete()`` callback +provided via its request ops reference and is guaranteed to be completed +before it is released once it has been submitted to the request transport +layer via |ssh_rtl_submit|. For a request without a response, successful +completion will occur once the underlying packet has been successfully +transmitted by the packet transport layer (i.e. from within the packet +completion callback). For a request with response, successful completion +will occur once the response has been received and matched to the request +via its request ID (which happens on the packet layer's data-received +callback running on the receiver thread). If the request is completed with +an error, the status value will be set to the corresponding (negative) errno +value. + +The state of a request is again managed via its ``state`` flags +(|ssh_request_flags|), which also encode the request type. In particular, +the following bits are noteworthy: + +* ``SSH_REQUEST_SF_LOCKED_BIT``: This bit is set when completion, either + through error or success, is imminent. It indicates that no further + references of the request should be taken and any existing references + should be dropped as soon as possible. The process setting this bit is + responsible for removing any references to this request from the request + queue and pending set. + +* ``SSH_REQUEST_SF_COMPLETED_BIT``: This bit is set by the process running the + ``complete()`` callback and is used to ensure that this callback only runs + once. + +* ``SSH_REQUEST_SF_QUEUED_BIT``: This bit is set when the request is queued on + the request queue and cleared when it is dequeued. + +* ``SSH_REQUEST_SF_PENDING_BIT``: This bit is set when the request is added to + the pending set and cleared when it is removed from it. + +Request Queue +------------- + +The request queue is the first of the two fundamental collections in the +request transport layer. In contrast to the packet queue of the packet +transport layer, it is not a priority queue and the simple first come first +serve principle applies. + +All requests to be transmitted by the request transport layer must be +submitted to this queue via |ssh_rtl_submit|. Once submitted, requests may +not be re-submitted, and will not be re-submitted automatically on timeout. +Instead, the request is completed with a timeout error. If desired, the +caller can create and submit a new request for another try, but it must not +submit the same request again. + +Pending Set +----------- + +The pending set is the second of the two fundamental collections in the +request transport layer. This collection stores references to all pending +requests, i.e. requests awaiting a response from the EC (similar to what the +pending set of the packet transport layer does for packets). + +Transmitter Task +---------------- + +The transmitter task is scheduled when a new request is available for +transmission. It checks if the next request on the request queue can be +transmitted and, if so, submits its underlying packet to the packet +transport layer. This check ensures that only a limited number of +requests can be pending, i.e. waiting for a response, at the same time. If +the request requires a response, the request is added to the pending set +before its packet is submitted. + +Packet Completion Callback +-------------------------- + +The packet completion callback is executed once the underlying packet of a +request has been completed. In case of an error completion, the +corresponding request is completed with the error value provided in this +callback. + +On successful packet completion, further processing depends on the request. +If the request expects a response, it is marked as transmitted and the +request timeout is started. If the request does not expect a response, it is +completed with success. + +Data-Received Callback +---------------------- + +The data received callback notifies the request transport layer of data +being received by the underlying packet transport layer via a data-type +frame. In general, this is expected to be a command-type payload. + +If the request ID of the command is one of the request IDs reserved for +events (one to ``SSH_NUM_EVENTS``, inclusively), it is forwarded to the +event callback registered in the request transport layer. If the request ID +indicates a response to a request, the respective request is looked up in +the pending set and, if found and marked as transmitted, completed with +success. + +Timeout Reaper +-------------- + +The request-response-timeout is a per-request timeout for requests expecting +a response. It is used to ensure that a request does not wait indefinitely +on a response from the EC and is started after the underlying packet has +been successfully completed. + +This timeout is, similar to the packet acknowledgment timeout on the packet +transport layer, handled via a dedicated reaper task. This task is +essentially a work-item (re-)scheduled to run when the next request is set +to time out. The work item then scans the set of pending requests for any +requests that have timed out and completes them with ``-ETIMEDOUT`` as +status. Requests will not be re-submitted automatically. Instead, the issuer +of the request must construct and submit a new request, if so desired. + +Note that this timeout, in combination with packet transmission and +acknowledgment timeouts, guarantees that the request layer will always make +progress, even if only through timing out packets, and never fully block. + +Concurrency and Locking +----------------------- + +Similar to the packet transport layer, there are two main locks in the +request transport layer: One guarding access to the request queue and one +guarding access to the pending set. These collections may only be accessed +and modified under the respective lock. + +Other parts of the request transport layer are guarded independently. State +flags are (again) managed by atomic bit operations and, if necessary, memory +barriers. Modifications to the timeout reaper work item and expiration date +are guarded by their own lock. + +Some request fields may be read outside of the respective locks guarding +them, specifically the state for tracing. In those cases, proper access is +ensured by employing ``WRITE_ONCE()`` and ``READ_ONCE()``. Such read-only +access is only allowed when stale values are not critical. + +With respect to the interface for higher layers, request submission +(|ssh_rtl_submit|), request cancellation (|ssh_rtl_cancel|), and layer +shutdown (|ssh_rtl_shutdown|) may always be executed concurrently with +respect to each other. Note that request submission may not run concurrently +with itself for the same request (and also may only be called once per +request). Equally, shutdown may also not run concurrently with itself. + + +Controller Layer +================ + +The controller layer extends on the request transport layer to provide an +easy-to-use interface for client drivers. It is represented by +|ssam_controller| and the SSH driver. While the lower level transport layers +take care of transmitting and handling packets and requests, the controller +layer takes on more of a management role. Specifically, it handles device +initialization, power management, and event handling, including event +delivery and registration via the (event) completion system (|ssam_cplt|). + +Event Registration +------------------ + +In general, an event (or rather a class of events) has to be explicitly +requested by the host before the EC will send it (HID input events seem to +be the exception). This is done via an event-enable request (similarly, +events should be disabled via an event-disable request once no longer +desired). + +The specific request used to enable (or disable) an event is given via an +event registry, i.e. the governing authority of this event (so to speak), +represented by |ssam_event_registry|. As parameters to this request, the +target category and, depending on the event registry, instance ID of the +event to be enabled must be provided. This (optional) instance ID must be +zero if the registry does not use it. Together, target category and instance +ID form the event ID, represented by |ssam_event_id|. In short, both, event +registry and event ID, are required to uniquely identify a respective class +of events. + +Note that a further *request ID* parameter must be provided for the +enable-event request. This parameter does not influence the class of events +being enabled, but instead is set as the request ID (RQID) on each event of +this class sent by the EC. It is used to identify events (as a limited +number of request IDs is reserved for use in events only, specifically one +to ``SSH_NUM_EVENTS`` inclusively) and also map events to their specific +class. Currently, the controller always sets this parameter to the target +category specified in |ssam_event_id|. + +As multiple client drivers may rely on the same (or overlapping) classes of +events and enable/disable calls are strictly binary (i.e. on/off), the +controller has to manage access to these events. It does so via reference +counting, storing the counter inside an RB-tree based mapping with event +registry and ID as key (there is no known list of valid event registry and +event ID combinations). See |ssam_nf|, |ssam_nf_refcount_inc|, and +|ssam_nf_refcount_dec| for details. + +This management is done together with notifier registration (described in +the next section) via the top-level |ssam_notifier_register| and +|ssam_notifier_unregister| functions. + +Event Delivery +-------------- + +To receive events, a client driver has to register an event notifier via +|ssam_notifier_register|. This increments the reference counter for that +specific class of events (as detailed in the previous section), enables the +class on the EC (if it has not been enabled already), and installs the +provided notifier callback. + +Notifier callbacks are stored in lists, with one (RCU) list per target +category (provided via the event ID; NB: there is a fixed known number of +target categories). There is no known association from the combination of +event registry and event ID to the command data (target ID, target category, +command ID, and instance ID) that can be provided by an event class, apart +from target category and instance ID given via the event ID. + +Note that due to the way notifiers are (or rather have to be) stored, client +drivers may receive events that they have not requested and need to account +for them. Specifically, they will, by default, receive all events from the +same target category. To simplify dealing with this, filtering of events by +target ID (provided via the event registry) and instance ID (provided via +the event ID) can be requested when registering a notifier. This filtering +is applied when iterating over the notifiers at the time they are executed. + +All notifier callbacks are executed on a dedicated workqueue, the so-called +completion workqueue. After an event has been received via the callback +installed in the request layer (running on the receiver thread of the packet +transport layer), it will be put on its respective event queue +(|ssam_event_queue|). From this event queue the completion work item of that +queue (running on the completion workqueue) will pick up the event and +execute the notifier callback. This is done to avoid blocking on the +receiver thread. + +There is one event queue per combination of target ID and target category. +This is done to ensure that notifier callbacks are executed in sequence for +events of the same target ID and target category. Callbacks can be executed +in parallel for events with a different combination of target ID and target +category. + +Concurrency and Locking +----------------------- + +Most of the concurrency related safety guarantees of the controller are +provided by the lower-level request transport layer. In addition to this, +event (un-)registration is guarded by its own lock. + +Access to the controller state is guarded by the state lock. This lock is a +read/write semaphore. The reader part can be used to ensure that the state +does not change while functions depending on the state to stay the same +(e.g. |ssam_notifier_register|, |ssam_notifier_unregister|, +|ssam_request_sync_submit|, and derivatives) are executed and this guarantee +is not already provided otherwise (e.g. through |ssam_client_bind| or +|ssam_client_link|). The writer part guards any transitions that will change +the state, i.e. initialization, destruction, suspension, and resumption. + +The controller state may be accessed (read-only) outside the state lock for +smoke-testing against invalid API usage (e.g. in |ssam_request_sync_submit|). +Note that such checks are not supposed to (and will not) protect against all +invalid usages, but rather aim to help catch them. In those cases, proper +variable access is ensured by employing ``WRITE_ONCE()`` and ``READ_ONCE()``. + +Assuming any preconditions on the state not changing have been satisfied, +all non-initialization and non-shutdown functions may run concurrently with +each other. This includes |ssam_notifier_register|, |ssam_notifier_unregister|, +|ssam_request_sync_submit|, as well as all functions building on top of those. diff --git a/Documentation/driver-api/surface_aggregator/overview.rst b/Documentation/driver-api/surface_aggregator/overview.rst new file mode 100644 index 000000000000..1e9d57e50063 --- /dev/null +++ b/Documentation/driver-api/surface_aggregator/overview.rst @@ -0,0 +1,77 @@ +.. SPDX-License-Identifier: GPL-2.0+ + +======== +Overview +======== + +The Surface/System Aggregator Module (SAM, SSAM) is an (arguably *the*) +embedded controller (EC) on Microsoft Surface devices. It has been originally +introduced on 4th generation devices (Surface Pro 4, Surface Book 1), but +its responsibilities and feature-set have since been expanded significantly +with the following generations. + + +Features and Integration +======================== + +Not much is currently known about SAM on 4th generation devices (Surface Pro +4, Surface Book 1), due to the use of a different communication interface +between host and EC (as detailed below). On 5th (Surface Pro 2017, Surface +Book 2, Surface Laptop 1) and later generation devices, SAM is responsible +for providing battery information (both current status and static values, +such as maximum capacity etc.), as well as an assortment of temperature +sensors (e.g. skin temperature) and cooling/performance-mode setting to the +host. On the Surface Book 2, specifically, it additionally provides an +interface for properly handling clipboard detachment (i.e. separating the +display part from the keyboard part of the device), on the Surface Laptop 1 +and 2 it is required for keyboard HID input. This HID subsystem has been +restructured for 7th generation devices and on those, specifically Surface +Laptop 3 and Surface Book 3, is responsible for all major HID input (i.e. +keyboard and touchpad). + +While features have not changed much on a coarse level since the 5th +generation, internal interfaces have undergone some rather large changes. On +5th and 6th generation devices, both battery and temperature information is +exposed to ACPI via a shim driver (referred to as Surface ACPI Notify, or +SAN), translating ACPI generic serial bus write-/read-accesses to SAM +requests. On 7th generation devices, this additional layer is gone and these +devices require a driver hooking directly into the SAM interface. Equally, +on newer generations, less devices are declared in ACPI, making them a bit +harder to discover and requiring us to hard-code a sort of device registry. +Due to this, a SSAM bus and subsystem with client devices +(:c:type:`struct ssam_device `) has been implemented. + + +Communication +============= + +The type of communication interface between host and EC depends on the +generation of the Surface device. On 4th generation devices, host and EC +communicate via HID, specifically using a HID-over-I2C device, whereas on +5th and later generations, communication takes place via a USART serial +device. In accordance to the drivers found on other operating systems, we +refer to the serial device and its driver as Surface Serial Hub (SSH). When +needed, we differentiate between both types of SAM by referring to them as +SAM-over-SSH and SAM-over-HID. + +Currently, this subsystem only supports SAM-over-SSH. The SSH communication +interface is described in more detail below. The HID interface has not been +reverse engineered yet and it is, at the moment, unclear how many (and +which) concepts of the SSH interface detailed below can be transferred to +it. + +Surface Serial Hub +------------------ + +As already elaborated above, the Surface Serial Hub (SSH) is the +communication interface for SAM on 5th- and all later-generation Surface +devices. On the highest level, communication can be separated into two main +types: Requests, messages sent from host to EC that may trigger a direct +response from the EC (explicitly associated with the request), and events +(sometimes also referred to as notifications), sent from EC to host without +being a direct response to a previous request. We may also refer to requests +without response as commands. In general, events need to be enabled via one +of multiple dedicated requests before they are sent by the EC. + +See :doc:`ssh` for a more technical protocol documentation and +:doc:`internal` for an overview of the internal driver architecture. diff --git a/Documentation/driver-api/surface_aggregator/ssh.rst b/Documentation/driver-api/surface_aggregator/ssh.rst new file mode 100644 index 000000000000..bf007d6c9873 --- /dev/null +++ b/Documentation/driver-api/surface_aggregator/ssh.rst @@ -0,0 +1,344 @@ +.. SPDX-License-Identifier: GPL-2.0+ + +.. |u8| replace:: :c:type:`u8 ` +.. |u16| replace:: :c:type:`u16 ` +.. |TYPE| replace:: ``TYPE`` +.. |LEN| replace:: ``LEN`` +.. |SEQ| replace:: ``SEQ`` +.. |SYN| replace:: ``SYN`` +.. |NAK| replace:: ``NAK`` +.. |ACK| replace:: ``ACK`` +.. |DATA| replace:: ``DATA`` +.. |DATA_SEQ| replace:: ``DATA_SEQ`` +.. |DATA_NSQ| replace:: ``DATA_NSQ`` +.. |TC| replace:: ``TC`` +.. |TID| replace:: ``TID`` +.. |IID| replace:: ``IID`` +.. |RQID| replace:: ``RQID`` +.. |CID| replace:: ``CID`` + +=========================== +Surface Serial Hub Protocol +=========================== + +The Surface Serial Hub (SSH) is the central communication interface for the +embedded Surface Aggregator Module controller (SAM or EC), found on newer +Surface generations. We will refer to this protocol and interface as +SAM-over-SSH, as opposed to SAM-over-HID for the older generations. + +On Surface devices with SAM-over-SSH, SAM is connected to the host via UART +and defined in ACPI as device with ID ``MSHW0084``. On these devices, +significant functionality is provided via SAM, including access to battery +and power information and events, thermal read-outs and events, and many +more. For Surface Laptops, keyboard input is handled via HID directed +through SAM, on the Surface Laptop 3 and Surface Book 3 this also includes +touchpad input. + +Note that the standard disclaimer for this subsystem also applies to this +document: All of this has been reverse-engineered and may thus be erroneous +and/or incomplete. + +All CRCs used in the following are two-byte ``crc_ccitt_false(0xffff, ...)``. +All multi-byte values are little-endian, there is no implicit padding between +values. + + +SSH Packet Protocol: Definitions +================================ + +The fundamental communication unit of the SSH protocol is a frame +(:c:type:`struct ssh_frame `). A frame consists of the following +fields, packed together and in order: + +.. flat-table:: SSH Frame + :widths: 1 1 4 + :header-rows: 1 + + * - Field + - Type + - Description + + * - |TYPE| + - |u8| + - Type identifier of the frame. + + * - |LEN| + - |u16| + - Length of the payload associated with the frame. + + * - |SEQ| + - |u8| + - Sequence ID (see explanation below). + +Each frame structure is followed by a CRC over this structure. The CRC over +the frame structure (|TYPE|, |LEN|, and |SEQ| fields) is placed directly +after the frame structure and before the payload. The payload is followed by +its own CRC (over all payload bytes). If the payload is not present (i.e. +the frame has ``LEN=0``), the CRC of the payload is still present and will +evaluate to ``0xffff``. The |LEN| field does not include any of the CRCs, it +equals the number of bytes inbetween the CRC of the frame and the CRC of the +payload. + +Additionally, the following fixed two-byte sequences are used: + +.. flat-table:: SSH Byte Sequences + :widths: 1 1 4 + :header-rows: 1 + + * - Name + - Value + - Description + + * - |SYN| + - ``[0xAA, 0x55]`` + - Synchronization bytes. + +A message consists of |SYN|, followed by the frame (|TYPE|, |LEN|, |SEQ| and +CRC) and, if specified in the frame (i.e. ``LEN > 0``), payload bytes, +followed finally, regardless if the payload is present, the payload CRC. The +messages corresponding to an exchange are, in part, identified by having the +same sequence ID (|SEQ|), stored inside the frame (more on this in the next +section). The sequence ID is a wrapping counter. + +A frame can have the following types +(:c:type:`enum ssh_frame_type `): + +.. flat-table:: SSH Frame Types + :widths: 1 1 4 + :header-rows: 1 + + * - Name + - Value + - Short Description + + * - |NAK| + - ``0x04`` + - Sent on error in previously received message. + + * - |ACK| + - ``0x40`` + - Sent to acknowledge receival of |DATA| frame. + + * - |DATA_SEQ| + - ``0x80`` + - Sent to transfer data. Sequenced. + + * - |DATA_NSQ| + - ``0x00`` + - Same as |DATA_SEQ|, but does not need to be ACKed. + +Both |NAK|- and |ACK|-type frames are used to control flow of messages and +thus do not carry a payload. |DATA_SEQ|- and |DATA_NSQ|-type frames on the +other hand must carry a payload. The flow sequence and interaction of +different frame types will be described in more depth in the next section. + + +SSH Packet Protocol: Flow Sequence +================================== + +Each exchange begins with |SYN|, followed by a |DATA_SEQ|- or +|DATA_NSQ|-type frame, followed by its CRC, payload, and payload CRC. In +case of a |DATA_NSQ|-type frame, the exchange is then finished. In case of a +|DATA_SEQ|-type frame, the receiving party has to acknowledge receival of +the frame by responding with a message containing an |ACK|-type frame with +the same sequence ID of the |DATA| frame. In other words, the sequence ID of +the |ACK| frame specifies the |DATA| frame to be acknowledged. In case of an +error, e.g. an invalid CRC, the receiving party responds with a message +containing an |NAK|-type frame. As the sequence ID of the previous data +frame, for which an error is indicated via the |NAK| frame, cannot be relied +upon, the sequence ID of the |NAK| frame should not be used and is set to +zero. After receival of an |NAK| frame, the sending party should re-send all +outstanding (non-ACKed) messages. + +Sequence IDs are not synchronized between the two parties, meaning that they +are managed independently for each party. Identifying the messages +corresponding to a single exchange thus relies on the sequence ID as well as +the type of the message, and the context. Specifically, the sequence ID is +used to associate an ``ACK`` with its ``DATA_SEQ``-type frame, but not +``DATA_SEQ``- or ``DATA_NSQ``-type frames with other ``DATA``- type frames. + +An example exchange might look like this: + +:: + + tx: -- SYN FRAME(D) CRC(F) PAYLOAD CRC(P) ----------------------------- + rx: ------------------------------------- SYN FRAME(A) CRC(F) CRC(P) -- + +where both frames have the same sequence ID (``SEQ``). Here, ``FRAME(D)`` +indicates a |DATA_SEQ|-type frame, ``FRAME(A)`` an ``ACK``-type frame, +``CRC(F)`` the CRC over the previous frame, ``CRC(P)`` the CRC over the +previous payload. In case of an error, the exchange would look like this: + +:: + + tx: -- SYN FRAME(D) CRC(F) PAYLOAD CRC(P) ----------------------------- + rx: ------------------------------------- SYN FRAME(N) CRC(F) CRC(P) -- + +upon which the sender should re-send the message. ``FRAME(N)`` indicates an +|NAK|-type frame. Note that the sequence ID of the |NAK|-type frame is fixed +to zero. For |DATA_NSQ|-type frames, both exchanges are the same: + +:: + + tx: -- SYN FRAME(DATA_NSQ) CRC(F) PAYLOAD CRC(P) ---------------------- + rx: ------------------------------------------------------------------- + +Here, an error can be detected, but not corrected or indicated to the +sending party. These exchanges are symmetric, i.e. switching ``rx`` and +``tx`` results again in a valid exchange. Currently, no longer exchanges are +known. + + +Commands: Requests, Responses, and Events +========================================= + +Commands are sent as payload inside a data frame. Currently, this is the +only known payload type of |DATA| frames, with a payload-type value of +``0x80`` (:c:type:`SSH_PLD_TYPE_CMD `). + +The command-type payload (:c:type:`struct ssh_command `) +consists of an eight-byte command structure, followed by optional and +variable length command data. The length of this optional data is derived +from the frame payload length given in the corresponding frame, i.e. it is +``frame.len - sizeof(struct ssh_command)``. The command struct contains the +following fields, packed together and in order: + +.. flat-table:: SSH Command + :widths: 1 1 4 + :header-rows: 1 + + * - Field + - Type + - Description + + * - |TYPE| + - |u8| + - Type of the payload. For commands always ``0x80``. + + * - |TC| + - |u8| + - Target category. + + * - |TID| (out) + - |u8| + - Target ID for outgoing (host to EC) commands. + + * - |TID| (in) + - |u8| + - Target ID for incoming (EC to host) commands. + + * - |IID| + - |u8| + - Instance ID. + + * - |RQID| + - |u16| + - Request ID. + + * - |CID| + - |u8| + - Command ID. + +The command struct and data, in general, does not contain any failure +detection mechanism (e.g. CRCs), this is solely done on the frame level. + +Command-type payloads are used by the host to send commands and requests to +the EC as well as by the EC to send responses and events back to the host. +We differentiate between requests (sent by the host), responses (sent by the +EC in response to a request), and events (sent by the EC without a preceding +request). + +Commands and events are uniquely identified by their target category +(``TC``) and command ID (``CID``). The target category specifies a general +category for the command (e.g. system in general, vs. battery and AC, vs. +temperature, and so on), while the command ID specifies the command inside +that category. Only the combination of |TC| + |CID| is unique. Additionally, +commands have an instance ID (``IID``), which is used to differentiate +between different sub-devices. For example ``TC=3`` ``CID=1`` is a +request to get the temperature on a thermal sensor, where |IID| specifies +the respective sensor. If the instance ID is not used, it should be set to +zero. If instance IDs are used, they, in general, start with a value of one, +whereas zero may be used for instance independent queries, if applicable. A +response to a request should have the same target category, command ID, and +instance ID as the corresponding request. + +Responses are matched to their corresponding request via the request ID +(``RQID``) field. This is a 16 bit wrapping counter similar to the sequence +ID on the frames. Note that the sequence ID of the frames for a +request-response pair does not match. Only the request ID has to match. +Frame-protocol wise these are two separate exchanges, and may even be +separated, e.g. by an event being sent after the request but before the +response. Not all commands produce a response, and this is not detectable by +|TC| + |CID|. It is the responsibility of the issuing party to wait for a +response (or signal this to the communication framework, as is done in +SAN/ACPI via the ``SNC`` flag). + +Events are identified by unique and reserved request IDs. These IDs should +not be used by the host when sending a new request. They are used on the +host to, first, detect events and, second, match them with a registered +event handler. Request IDs for events are chosen by the host and directed to +the EC when setting up and enabling an event source (via the +enable-event-source request). The EC then uses the specified request ID for +events sent from the respective source. Note that an event should still be +identified by its target category, command ID, and, if applicable, instance +ID, as a single event source can send multiple different event types. In +general, however, a single target category should map to a single reserved +event request ID. + +Furthermore, requests, responses, and events have an associated target ID +(``TID``). This target ID is split into output (host to EC) and input (EC to +host) fields, with the respecting other field (e.g. output field on incoming +messages) set to zero. Two ``TID`` values are known: Primary (``0x01``) and +secondary (``0x02``). In general, the response to a request should have the +same ``TID`` value, however, the field (output vs. input) should be used in +accordance to the direction in which the response is sent (i.e. on the input +field, as responses are generally sent from the EC to the host). + +Note that, even though requests and events should be uniquely identifiable +by target category and command ID alone, the EC may require specific +target ID and instance ID values to accept a command. A command that is +accepted for ``TID=1``, for example, may not be accepted for ``TID=2`` +and vice versa. + + +Limitations and Observations +============================ + +The protocol can, in theory, handle up to ``U8_MAX`` frames in parallel, +with up to ``U16_MAX`` pending requests (neglecting request IDs reserved for +events). In practice, however, this is more limited. From our testing +(although via a python and thus a user-space program), it seems that the EC +can handle up to four requests (mostly) reliably in parallel at a certain +time. With five or more requests in parallel, consistent discarding of +commands (ACKed frame but no command response) has been observed. For five +simultaneous commands, this reproducibly resulted in one command being +dropped and four commands being handled. + +However, it has also been noted that, even with three requests in parallel, +occasional frame drops happen. Apart from this, with a limit of three +pending requests, no dropped commands (i.e. command being dropped but frame +carrying command being ACKed) have been observed. In any case, frames (and +possibly also commands) should be re-sent by the host if a certain timeout +is exceeded. This is done by the EC for frames with a timeout of one second, +up to two re-tries (i.e. three transmissions in total). The limit of +re-tries also applies to received NAKs, and, in a worst case scenario, can +lead to entire messages being dropped. + +While this also seems to work fine for pending data frames as long as no +transmission failures occur, implementation and handling of these seems to +depend on the assumption that there is only one non-acknowledged data frame. +In particular, the detection of repeated frames relies on the last sequence +number. This means that, if a frame that has been successfully received by +the EC is sent again, e.g. due to the host not receiving an |ACK|, the EC +will only detect this if it has the sequence ID of the last frame received +by the EC. As an example: Sending two frames with ``SEQ=0`` and ``SEQ=1`` +followed by a repetition of ``SEQ=0`` will not detect the second ``SEQ=0`` +frame as such, and thus execute the command in this frame each time it has +been received, i.e. twice in this example. Sending ``SEQ=0``, ``SEQ=1`` and +then repeating ``SEQ=1`` will detect the second ``SEQ=1`` as repetition of +the first one and ignore it, thus executing the contained command only once. + +In conclusion, this suggests a limit of at most one pending un-ACKed frame +(per party, effectively leading to synchronous communication regarding +frames) and at most three pending commands. The limit to synchronous frame +transfers seems to be consistent with behavior observed on Windows. diff --git a/MAINTAINERS b/MAINTAINERS index 845a245f562c..41f082551942 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -11818,6 +11818,7 @@ M: Maximilian Luz S: Maintained W: https://github.com/linux-surface/surface-aggregator-module C: irc://chat.freenode.net/##linux-surface +F: Documentation/driver-api/surface_aggregator/ F: drivers/platform/surface/aggregator/ F: include/linux/surface_aggregator/ -- cgit v1.2.3 From 178f6ab77e617c984d6520b92e747075a12676ff Mon Sep 17 00:00:00 2001 From: Maximilian Luz Date: Mon, 21 Dec 2020 19:39:58 +0100 Subject: platform/surface: Add Surface Aggregator user-space interface Add a misc-device providing user-space access to the Surface Aggregator EC, mainly intended for debugging, testing, and reverse-engineering. This interface gives user-space applications the ability to send requests to the EC and receive the corresponding responses. The device-file is managed by a pseudo platform-device and corresponding driver to avoid dependence on the dedicated bus, allowing it to be loaded in a minimal configuration. A python library and scripts to access this device can be found at [1]. [1]: https://github.com/linux-surface/surface-aggregator-module/tree/master/scripts/ssam Signed-off-by: Maximilian Luz Link: https://lore.kernel.org/r/20201221183959.1186143-9-luzmaximilian@gmail.com Signed-off-by: Hans de Goede --- .../driver-api/surface_aggregator/clients/cdev.rst | 87 ++++++ .../surface_aggregator/clients/index.rst | 12 +- Documentation/userspace-api/ioctl/ioctl-number.rst | 2 + MAINTAINERS | 2 + drivers/platform/surface/Kconfig | 17 ++ drivers/platform/surface/Makefile | 1 + drivers/platform/surface/surface_aggregator_cdev.c | 303 +++++++++++++++++++++ include/uapi/linux/surface_aggregator/cdev.h | 78 ++++++ 8 files changed, 501 insertions(+), 1 deletion(-) create mode 100644 Documentation/driver-api/surface_aggregator/clients/cdev.rst create mode 100644 drivers/platform/surface/surface_aggregator_cdev.c create mode 100644 include/uapi/linux/surface_aggregator/cdev.h (limited to 'Documentation') diff --git a/Documentation/driver-api/surface_aggregator/clients/cdev.rst b/Documentation/driver-api/surface_aggregator/clients/cdev.rst new file mode 100644 index 000000000000..248c1372d879 --- /dev/null +++ b/Documentation/driver-api/surface_aggregator/clients/cdev.rst @@ -0,0 +1,87 @@ +.. SPDX-License-Identifier: GPL-2.0+ + +.. |u8| replace:: :c:type:`u8 ` +.. |u16| replace:: :c:type:`u16 ` +.. |ssam_cdev_request| replace:: :c:type:`struct ssam_cdev_request ` +.. |ssam_cdev_request_flags| replace:: :c:type:`enum ssam_cdev_request_flags ` + +============================== +User-Space EC Interface (cdev) +============================== + +The ``surface_aggregator_cdev`` module provides a misc-device for the SSAM +controller to allow for a (more or less) direct connection from user-space to +the SAM EC. It is intended to be used for development and debugging, and +therefore should not be used or relied upon in any other way. Note that this +module is not loaded automatically, but instead must be loaded manually. + +The provided interface is accessible through the ``/dev/surface/aggregator`` +device-file. All functionality of this interface is provided via IOCTLs. +These IOCTLs and their respective input/output parameter structs are defined in +``include/uapi/linux/surface_aggregator/cdev.h``. + +A small python library and scripts for accessing this interface can be found +at https://github.com/linux-surface/surface-aggregator-module/tree/master/scripts/ssam. + + +Controller IOCTLs +================= + +The following IOCTLs are provided: + +.. flat-table:: Controller IOCTLs + :widths: 1 1 1 1 4 + :header-rows: 1 + + * - Type + - Number + - Direction + - Name + - Description + + * - ``0xA5`` + - ``1`` + - ``WR`` + - ``REQUEST`` + - Perform synchronous SAM request. + + +``REQUEST`` +----------- + +Defined as ``_IOWR(0xA5, 1, struct ssam_cdev_request)``. + +Executes a synchronous SAM request. The request specification is passed in +as argument of type |ssam_cdev_request|, which is then written to/modified +by the IOCTL to return status and result of the request. + +Request payload data must be allocated separately and is passed in via the +``payload.data`` and ``payload.length`` members. If a response is required, +the response buffer must be allocated by the caller and passed in via the +``response.data`` member. The ``response.length`` member must be set to the +capacity of this buffer, or if no response is required, zero. Upon +completion of the request, the call will write the response to the response +buffer (if its capacity allows it) and overwrite the length field with the +actual size of the response, in bytes. + +Additionally, if the request has a response, this must be indicated via the +request flags, as is done with in-kernel requests. Request flags can be set +via the ``flags`` member and the values correspond to the values found in +|ssam_cdev_request_flags|. + +Finally, the status of the request itself is returned in the ``status`` +member (a negative errno value indicating failure). Note that failure +indication of the IOCTL is separated from failure indication of the request: +The IOCTL returns a negative status code if anything failed during setup of +the request (``-EFAULT``) or if the provided argument or any of its fields +are invalid (``-EINVAL``). In this case, the status value of the request +argument may be set, providing more detail on what went wrong (e.g. +``-ENOMEM`` for out-of-memory), but this value may also be zero. The IOCTL +will return with a zero status code in case the request has been set up, +submitted, and completed (i.e. handed back to user-space) successfully from +inside the IOCTL, but the request ``status`` member may still be negative in +case the actual execution of the request failed after it has been submitted. + +A full definition of the argument struct is provided below: + +.. kernel-doc:: include/uapi/linux/surface_aggregator/cdev.h diff --git a/Documentation/driver-api/surface_aggregator/clients/index.rst b/Documentation/driver-api/surface_aggregator/clients/index.rst index 31e026d96102..ab260ec82cfb 100644 --- a/Documentation/driver-api/surface_aggregator/clients/index.rst +++ b/Documentation/driver-api/surface_aggregator/clients/index.rst @@ -7,4 +7,14 @@ Client Driver Documentation This is the documentation for client drivers themselves. Refer to :doc:`../client` for documentation on how to write client drivers. -.. Place documentation for individual client drivers here. +.. toctree:: + :maxdepth: 1 + + cdev + +.. only:: subproject and html + + Indices + ======= + + * :ref:`genindex` diff --git a/Documentation/userspace-api/ioctl/ioctl-number.rst b/Documentation/userspace-api/ioctl/ioctl-number.rst index a4c75a28c839..b5231d7f9200 100644 --- a/Documentation/userspace-api/ioctl/ioctl-number.rst +++ b/Documentation/userspace-api/ioctl/ioctl-number.rst @@ -324,6 +324,8 @@ Code Seq# Include File Comments 0xA3 90-9F linux/dtlk.h 0xA4 00-1F uapi/linux/tee.h Generic TEE subsystem 0xA4 00-1F uapi/asm/sgx.h +0xA5 01 linux/surface_aggregator/cdev.h Microsoft Surface Platform System Aggregator + 0xAA 00-3F linux/uapi/linux/userfaultfd.h 0xAB 00-1F linux/nbd.h 0xAC 00-1F linux/raw.h diff --git a/MAINTAINERS b/MAINTAINERS index 41f082551942..9bd55c842898 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -11820,7 +11820,9 @@ W: https://github.com/linux-surface/surface-aggregator-module C: irc://chat.freenode.net/##linux-surface F: Documentation/driver-api/surface_aggregator/ F: drivers/platform/surface/aggregator/ +F: drivers/platform/surface/surface_aggregator_cdev.c F: include/linux/surface_aggregator/ +F: include/uapi/linux/surface_aggregator/ MICROTEK X6 SCANNER M: Oliver Neukum diff --git a/drivers/platform/surface/Kconfig b/drivers/platform/surface/Kconfig index 2916a47b130e..988b2de6b500 100644 --- a/drivers/platform/surface/Kconfig +++ b/drivers/platform/surface/Kconfig @@ -41,6 +41,23 @@ config SURFACE_3_POWER_OPREGION This driver provides support for ACPI operation region of the Surface 3 battery platform driver. +config SURFACE_AGGREGATOR_CDEV + tristate "Surface System Aggregator Module User-Space Interface" + depends on SURFACE_AGGREGATOR + help + Provides a misc-device interface to the Surface System Aggregator + Module (SSAM) controller. + + This option provides a module (called surface_aggregator_cdev), that, + when loaded, will add a client device (and its respective driver) to + the SSAM controller. Said client device manages a misc-device + interface (/dev/surface/aggregator), which can be used by user-space + tools to directly communicate with the SSAM EC by sending requests and + receiving the corresponding responses. + + The provided interface is intended for debugging and development only, + and should not be used otherwise. + config SURFACE_GPE tristate "Surface GPE/Lid Support Driver" depends on DMI diff --git a/drivers/platform/surface/Makefile b/drivers/platform/surface/Makefile index 034134fe0264..161f0ad05795 100644 --- a/drivers/platform/surface/Makefile +++ b/drivers/platform/surface/Makefile @@ -8,5 +8,6 @@ obj-$(CONFIG_SURFACE3_WMI) += surface3-wmi.o obj-$(CONFIG_SURFACE_3_BUTTON) += surface3_button.o obj-$(CONFIG_SURFACE_3_POWER_OPREGION) += surface3_power.o obj-$(CONFIG_SURFACE_AGGREGATOR) += aggregator/ +obj-$(CONFIG_SURFACE_AGGREGATOR_CDEV) += surface_aggregator_cdev.o obj-$(CONFIG_SURFACE_GPE) += surface_gpe.o obj-$(CONFIG_SURFACE_PRO3_BUTTON) += surfacepro3_button.o diff --git a/drivers/platform/surface/surface_aggregator_cdev.c b/drivers/platform/surface/surface_aggregator_cdev.c new file mode 100644 index 000000000000..340d15b148b9 --- /dev/null +++ b/drivers/platform/surface/surface_aggregator_cdev.c @@ -0,0 +1,303 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Provides user-space access to the SSAM EC via the /dev/surface/aggregator + * misc device. Intended for debugging and development. + * + * Copyright (C) 2020 Maximilian Luz + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#define SSAM_CDEV_DEVICE_NAME "surface_aggregator_cdev" + +struct ssam_cdev { + struct kref kref; + struct rw_semaphore lock; + struct ssam_controller *ctrl; + struct miscdevice mdev; +}; + +static void __ssam_cdev_release(struct kref *kref) +{ + kfree(container_of(kref, struct ssam_cdev, kref)); +} + +static struct ssam_cdev *ssam_cdev_get(struct ssam_cdev *cdev) +{ + if (cdev) + kref_get(&cdev->kref); + + return cdev; +} + +static void ssam_cdev_put(struct ssam_cdev *cdev) +{ + if (cdev) + kref_put(&cdev->kref, __ssam_cdev_release); +} + +static int ssam_cdev_device_open(struct inode *inode, struct file *filp) +{ + struct miscdevice *mdev = filp->private_data; + struct ssam_cdev *cdev = container_of(mdev, struct ssam_cdev, mdev); + + filp->private_data = ssam_cdev_get(cdev); + return stream_open(inode, filp); +} + +static int ssam_cdev_device_release(struct inode *inode, struct file *filp) +{ + ssam_cdev_put(filp->private_data); + return 0; +} + +static long ssam_cdev_request(struct ssam_cdev *cdev, unsigned long arg) +{ + struct ssam_cdev_request __user *r; + struct ssam_cdev_request rqst; + struct ssam_request spec; + struct ssam_response rsp; + const void __user *plddata; + void __user *rspdata; + int status = 0, ret = 0, tmp; + + r = (struct ssam_cdev_request __user *)arg; + ret = copy_struct_from_user(&rqst, sizeof(rqst), r, sizeof(*r)); + if (ret) + goto out; + + plddata = u64_to_user_ptr(rqst.payload.data); + rspdata = u64_to_user_ptr(rqst.response.data); + + /* Setup basic request fields. */ + spec.target_category = rqst.target_category; + spec.target_id = rqst.target_id; + spec.command_id = rqst.command_id; + spec.instance_id = rqst.instance_id; + spec.flags = 0; + spec.length = rqst.payload.length; + spec.payload = NULL; + + if (rqst.flags & SSAM_CDEV_REQUEST_HAS_RESPONSE) + spec.flags |= SSAM_REQUEST_HAS_RESPONSE; + + if (rqst.flags & SSAM_CDEV_REQUEST_UNSEQUENCED) + spec.flags |= SSAM_REQUEST_UNSEQUENCED; + + rsp.capacity = rqst.response.length; + rsp.length = 0; + rsp.pointer = NULL; + + /* Get request payload from user-space. */ + if (spec.length) { + if (!plddata) { + ret = -EINVAL; + goto out; + } + + spec.payload = kzalloc(spec.length, GFP_KERNEL); + if (!spec.payload) { + ret = -ENOMEM; + goto out; + } + + if (copy_from_user((void *)spec.payload, plddata, spec.length)) { + ret = -EFAULT; + goto out; + } + } + + /* Allocate response buffer. */ + if (rsp.capacity) { + if (!rspdata) { + ret = -EINVAL; + goto out; + } + + rsp.pointer = kzalloc(rsp.capacity, GFP_KERNEL); + if (!rsp.pointer) { + ret = -ENOMEM; + goto out; + } + } + + /* Perform request. */ + status = ssam_request_sync(cdev->ctrl, &spec, &rsp); + if (status) + goto out; + + /* Copy response to user-space. */ + if (rsp.length && copy_to_user(rspdata, rsp.pointer, rsp.length)) + ret = -EFAULT; + +out: + /* Always try to set response-length and status. */ + tmp = put_user(rsp.length, &r->response.length); + if (tmp) + ret = tmp; + + tmp = put_user(status, &r->status); + if (tmp) + ret = tmp; + + /* Cleanup. */ + kfree(spec.payload); + kfree(rsp.pointer); + + return ret; +} + +static long __ssam_cdev_device_ioctl(struct ssam_cdev *cdev, unsigned int cmd, + unsigned long arg) +{ + switch (cmd) { + case SSAM_CDEV_REQUEST: + return ssam_cdev_request(cdev, arg); + + default: + return -ENOTTY; + } +} + +static long ssam_cdev_device_ioctl(struct file *file, unsigned int cmd, + unsigned long arg) +{ + struct ssam_cdev *cdev = file->private_data; + long status; + + /* Ensure that controller is valid for as long as we need it. */ + if (down_read_killable(&cdev->lock)) + return -ERESTARTSYS; + + if (!cdev->ctrl) { + up_read(&cdev->lock); + return -ENODEV; + } + + status = __ssam_cdev_device_ioctl(cdev, cmd, arg); + + up_read(&cdev->lock); + return status; +} + +static const struct file_operations ssam_controller_fops = { + .owner = THIS_MODULE, + .open = ssam_cdev_device_open, + .release = ssam_cdev_device_release, + .unlocked_ioctl = ssam_cdev_device_ioctl, + .compat_ioctl = ssam_cdev_device_ioctl, + .llseek = noop_llseek, +}; + +static int ssam_dbg_device_probe(struct platform_device *pdev) +{ + struct ssam_controller *ctrl; + struct ssam_cdev *cdev; + int status; + + ctrl = ssam_client_bind(&pdev->dev); + if (IS_ERR(ctrl)) + return PTR_ERR(ctrl) == -ENODEV ? -EPROBE_DEFER : PTR_ERR(ctrl); + + cdev = kzalloc(sizeof(*cdev), GFP_KERNEL); + if (!cdev) + return -ENOMEM; + + kref_init(&cdev->kref); + init_rwsem(&cdev->lock); + cdev->ctrl = ctrl; + + cdev->mdev.parent = &pdev->dev; + cdev->mdev.minor = MISC_DYNAMIC_MINOR; + cdev->mdev.name = "surface_aggregator"; + cdev->mdev.nodename = "surface/aggregator"; + cdev->mdev.fops = &ssam_controller_fops; + + status = misc_register(&cdev->mdev); + if (status) { + kfree(cdev); + return status; + } + + platform_set_drvdata(pdev, cdev); + return 0; +} + +static int ssam_dbg_device_remove(struct platform_device *pdev) +{ + struct ssam_cdev *cdev = platform_get_drvdata(pdev); + + misc_deregister(&cdev->mdev); + + /* + * The controller is only guaranteed to be valid for as long as the + * driver is bound. Remove controller so that any lingering open files + * cannot access it any more after we're gone. + */ + down_write(&cdev->lock); + cdev->ctrl = NULL; + up_write(&cdev->lock); + + ssam_cdev_put(cdev); + return 0; +} + +static struct platform_device *ssam_cdev_device; + +static struct platform_driver ssam_cdev_driver = { + .probe = ssam_dbg_device_probe, + .remove = ssam_dbg_device_remove, + .driver = { + .name = SSAM_CDEV_DEVICE_NAME, + .probe_type = PROBE_PREFER_ASYNCHRONOUS, + }, +}; + +static int __init ssam_debug_init(void) +{ + int status; + + ssam_cdev_device = platform_device_alloc(SSAM_CDEV_DEVICE_NAME, + PLATFORM_DEVID_NONE); + if (!ssam_cdev_device) + return -ENOMEM; + + status = platform_device_add(ssam_cdev_device); + if (status) + goto err_device; + + status = platform_driver_register(&ssam_cdev_driver); + if (status) + goto err_driver; + + return 0; + +err_driver: + platform_device_del(ssam_cdev_device); +err_device: + platform_device_put(ssam_cdev_device); + return status; +} +module_init(ssam_debug_init); + +static void __exit ssam_debug_exit(void) +{ + platform_driver_unregister(&ssam_cdev_driver); + platform_device_unregister(ssam_cdev_device); +} +module_exit(ssam_debug_exit); + +MODULE_AUTHOR("Maximilian Luz "); +MODULE_DESCRIPTION("User-space interface for Surface System Aggregator Module"); +MODULE_LICENSE("GPL"); diff --git a/include/uapi/linux/surface_aggregator/cdev.h b/include/uapi/linux/surface_aggregator/cdev.h new file mode 100644 index 000000000000..fbcce04abfe9 --- /dev/null +++ b/include/uapi/linux/surface_aggregator/cdev.h @@ -0,0 +1,78 @@ +/* SPDX-License-Identifier: GPL-2.0+ WITH Linux-syscall-note */ +/* + * Surface System Aggregator Module (SSAM) user-space EC interface. + * + * Definitions, structs, and IOCTLs for the /dev/surface/aggregator misc + * device. This device provides direct user-space access to the SSAM EC. + * Intended for debugging and development. + * + * Copyright (C) 2020 Maximilian Luz + */ + +#ifndef _UAPI_LINUX_SURFACE_AGGREGATOR_CDEV_H +#define _UAPI_LINUX_SURFACE_AGGREGATOR_CDEV_H + +#include +#include + +/** + * enum ssam_cdev_request_flags - Request flags for SSAM cdev request IOCTL. + * + * @SSAM_CDEV_REQUEST_HAS_RESPONSE: + * Specifies that the request expects a response. If not set, the request + * will be directly completed after its underlying packet has been + * transmitted. If set, the request transport system waits for a response + * of the request. + * + * @SSAM_CDEV_REQUEST_UNSEQUENCED: + * Specifies that the request should be transmitted via an unsequenced + * packet. If set, the request must not have a response, meaning that this + * flag and the %SSAM_CDEV_REQUEST_HAS_RESPONSE flag are mutually + * exclusive. + */ +enum ssam_cdev_request_flags { + SSAM_CDEV_REQUEST_HAS_RESPONSE = 0x01, + SSAM_CDEV_REQUEST_UNSEQUENCED = 0x02, +}; + +/** + * struct ssam_cdev_request - Controller request IOCTL argument. + * @target_category: Target category of the SAM request. + * @target_id: Target ID of the SAM request. + * @command_id: Command ID of the SAM request. + * @instance_id: Instance ID of the SAM request. + * @flags: Request flags (see &enum ssam_cdev_request_flags). + * @status: Request status (output). + * @payload: Request payload (input data). + * @payload.data: Pointer to request payload data. + * @payload.length: Length of request payload data (in bytes). + * @response: Request response (output data). + * @response.data: Pointer to response buffer. + * @response.length: On input: Capacity of response buffer (in bytes). + * On output: Length of request response (number of bytes + * in the buffer that are actually used). + */ +struct ssam_cdev_request { + __u8 target_category; + __u8 target_id; + __u8 command_id; + __u8 instance_id; + __u16 flags; + __s16 status; + + struct { + __u64 data; + __u16 length; + __u8 __pad[6]; + } payload; + + struct { + __u64 data; + __u16 length; + __u8 __pad[6]; + } response; +} __attribute__((__packed__)); + +#define SSAM_CDEV_REQUEST _IOWR(0xA5, 1, struct ssam_cdev_request) + +#endif /* _UAPI_LINUX_SURFACE_AGGREGATOR_CDEV_H */ -- cgit v1.2.3 From fc00bc8ac1dada4085f9308f85f2d6359da0faa8 Mon Sep 17 00:00:00 2001 From: Maximilian Luz Date: Mon, 21 Dec 2020 19:39:59 +0100 Subject: platform/surface: Add Surface ACPI Notify driver The Surface ACPI Notify (SAN) device provides an ACPI interface to the Surface Aggregator EC, specifically the Surface Serial Hub interface. This interface allows EC requests to be made from ACPI code and can convert a subset of EC events back to ACPI notifications. Specifically, this interface provides a GenericSerialBus operation region ACPI code can execute a request by writing the request command data and payload to this operation region and reading back the corresponding response via a write-then-read operation. Furthermore, this interface provides a _DSM method to be called when certain events from the EC have been received, essentially turning them into ACPI notifications. The driver provided in this commit essentially takes care of translating the request data written to the operation region, executing the request, waiting for it to finish, and finally writing and translating back the response (if the request has one). Furthermore, this driver takes care of enabling the events handled via ACPI _DSM calls. Lastly, this driver also exposes an interface providing discrete GPU (dGPU) power-on notifications on the Surface Book 2, which are also received via the operation region interface (but not handled by the SAN driver directly), making them accessible to other drivers (such as a dGPU hot-plug driver that may be added later on). On 5th and 6th generation Surface devices (Surface Pro 5/2017, Pro 6, Book 2, Laptop 1 and 2), the SAN interface provides full battery and thermal subsystem access, as well as other EC based functionality. On those models, battery and thermal sensor devices are implemented as standard ACPI devices of that type, however, forward ACPI calls to the corresponding Surface Aggregator EC request via the SAN interface and receive corresponding notifications (e.g. battery information change) from it. This interface is therefore required to provide said functionality on those devices. Signed-off-by: Maximilian Luz Reviewed-by: Hans de Goede Link: https://lore.kernel.org/r/20201221183959.1186143-10-luzmaximilian@gmail.com Signed-off-by: Hans de Goede --- .../surface_aggregator/clients/index.rst | 1 + .../driver-api/surface_aggregator/clients/san.rst | 44 + MAINTAINERS | 2 + drivers/platform/surface/Kconfig | 19 + drivers/platform/surface/Makefile | 1 + drivers/platform/surface/surface_acpi_notify.c | 886 +++++++++++++++++++++ include/linux/surface_acpi_notify.h | 39 + 7 files changed, 992 insertions(+) create mode 100644 Documentation/driver-api/surface_aggregator/clients/san.rst create mode 100644 drivers/platform/surface/surface_acpi_notify.c create mode 100644 include/linux/surface_acpi_notify.h (limited to 'Documentation') diff --git a/Documentation/driver-api/surface_aggregator/clients/index.rst b/Documentation/driver-api/surface_aggregator/clients/index.rst index ab260ec82cfb..3ccabce23271 100644 --- a/Documentation/driver-api/surface_aggregator/clients/index.rst +++ b/Documentation/driver-api/surface_aggregator/clients/index.rst @@ -11,6 +11,7 @@ This is the documentation for client drivers themselves. Refer to :maxdepth: 1 cdev + san .. only:: subproject and html diff --git a/Documentation/driver-api/surface_aggregator/clients/san.rst b/Documentation/driver-api/surface_aggregator/clients/san.rst new file mode 100644 index 000000000000..38c2580e7758 --- /dev/null +++ b/Documentation/driver-api/surface_aggregator/clients/san.rst @@ -0,0 +1,44 @@ +.. SPDX-License-Identifier: GPL-2.0+ + +.. |san_client_link| replace:: :c:func:`san_client_link` +.. |san_dgpu_notifier_register| replace:: :c:func:`san_dgpu_notifier_register` +.. |san_dgpu_notifier_unregister| replace:: :c:func:`san_dgpu_notifier_unregister` + +=================== +Surface ACPI Notify +=================== + +The Surface ACPI Notify (SAN) device provides the bridge between ACPI and +SAM controller. Specifically, ACPI code can execute requests and handle +battery and thermal events via this interface. In addition to this, events +relating to the discrete GPU (dGPU) of the Surface Book 2 can be sent from +ACPI code (note: the Surface Book 3 uses a different method for this). The +only currently known event sent via this interface is a dGPU power-on +notification. While this driver handles the former part internally, it only +relays the dGPU events to any other driver interested via its public API and +does not handle them. + +The public interface of this driver is split into two parts: Client +registration and notifier-block registration. + +A client to the SAN interface can be linked as consumer to the SAN device +via |san_client_link|. This can be used to ensure that the a client +receiving dGPU events does not miss any events due to the SAN interface not +being set up as this forces the client driver to unbind once the SAN driver +is unbound. + +Notifier-blocks can be registered by any device for as long as the module is +loaded, regardless of being linked as client or not. Registration is done +with |san_dgpu_notifier_register|. If the notifier is not needed any more, it +should be unregistered via |san_dgpu_notifier_unregister|. + +Consult the API documentation below for more details. + + +API Documentation +================= + +.. kernel-doc:: include/linux/surface_acpi_notify.h + +.. kernel-doc:: drivers/platform/surface/surface_acpi_notify.c + :export: diff --git a/MAINTAINERS b/MAINTAINERS index 9bd55c842898..cf250c1365b0 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -11820,7 +11820,9 @@ W: https://github.com/linux-surface/surface-aggregator-module C: irc://chat.freenode.net/##linux-surface F: Documentation/driver-api/surface_aggregator/ F: drivers/platform/surface/aggregator/ +F: drivers/platform/surface/surface_acpi_notify.c F: drivers/platform/surface/surface_aggregator_cdev.c +F: include/linux/surface_acpi_notify.h F: include/linux/surface_aggregator/ F: include/uapi/linux/surface_aggregator/ diff --git a/drivers/platform/surface/Kconfig b/drivers/platform/surface/Kconfig index 988b2de6b500..83b0a4c7b352 100644 --- a/drivers/platform/surface/Kconfig +++ b/drivers/platform/surface/Kconfig @@ -41,6 +41,25 @@ config SURFACE_3_POWER_OPREGION This driver provides support for ACPI operation region of the Surface 3 battery platform driver. +config SURFACE_ACPI_NOTIFY + tristate "Surface ACPI Notify Driver" + depends on SURFACE_AGGREGATOR + help + Surface ACPI Notify (SAN) driver for Microsoft Surface devices. + + This driver provides support for the ACPI interface (called SAN) of + the Surface System Aggregator Module (SSAM) EC. This interface is used + on 5th- and 6th-generation Microsoft Surface devices (including + Surface Pro 5 and 6, Surface Book 2, Surface Laptops 1 and 2, and in + reduced functionality on the Surface Laptop 3) to execute SSAM + requests directly from ACPI code, as well as receive SSAM events and + turn them into ACPI notifications. It essentially acts as a + translation layer between the SSAM controller and ACPI. + + Specifically, this driver may be needed for battery status reporting, + thermal sensor access, and real-time clock information, depending on + the Surface device in question. + config SURFACE_AGGREGATOR_CDEV tristate "Surface System Aggregator Module User-Space Interface" depends on SURFACE_AGGREGATOR diff --git a/drivers/platform/surface/Makefile b/drivers/platform/surface/Makefile index 161f0ad05795..3eb971006877 100644 --- a/drivers/platform/surface/Makefile +++ b/drivers/platform/surface/Makefile @@ -7,6 +7,7 @@ obj-$(CONFIG_SURFACE3_WMI) += surface3-wmi.o obj-$(CONFIG_SURFACE_3_BUTTON) += surface3_button.o obj-$(CONFIG_SURFACE_3_POWER_OPREGION) += surface3_power.o +obj-$(CONFIG_SURFACE_ACPI_NOTIFY) += surface_acpi_notify.o obj-$(CONFIG_SURFACE_AGGREGATOR) += aggregator/ obj-$(CONFIG_SURFACE_AGGREGATOR_CDEV) += surface_aggregator_cdev.o obj-$(CONFIG_SURFACE_GPE) += surface_gpe.o diff --git a/drivers/platform/surface/surface_acpi_notify.c b/drivers/platform/surface/surface_acpi_notify.c new file mode 100644 index 000000000000..8cd67a669c86 --- /dev/null +++ b/drivers/platform/surface/surface_acpi_notify.c @@ -0,0 +1,886 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Driver for the Surface ACPI Notify (SAN) interface/shim. + * + * Translates communication from ACPI to Surface System Aggregator Module + * (SSAM/SAM) requests and back, specifically SAM-over-SSH. Translates SSAM + * events back to ACPI notifications. Allows handling of discrete GPU + * notifications sent from ACPI via the SAN interface by providing them to any + * registered external driver. + * + * Copyright (C) 2019-2020 Maximilian Luz + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +struct san_data { + struct device *dev; + struct ssam_controller *ctrl; + + struct acpi_connection_info info; + + struct ssam_event_notifier nf_bat; + struct ssam_event_notifier nf_tmp; +}; + +#define to_san_data(ptr, member) \ + container_of(ptr, struct san_data, member) + + +/* -- dGPU notifier interface. ---------------------------------------------- */ + +struct san_rqsg_if { + struct rw_semaphore lock; + struct device *dev; + struct blocking_notifier_head nh; +}; + +static struct san_rqsg_if san_rqsg_if = { + .lock = __RWSEM_INITIALIZER(san_rqsg_if.lock), + .dev = NULL, + .nh = BLOCKING_NOTIFIER_INIT(san_rqsg_if.nh), +}; + +static int san_set_rqsg_interface_device(struct device *dev) +{ + int status = 0; + + down_write(&san_rqsg_if.lock); + if (!san_rqsg_if.dev && dev) + san_rqsg_if.dev = dev; + else + status = -EBUSY; + up_write(&san_rqsg_if.lock); + + return status; +} + +/** + * san_client_link() - Link client as consumer to SAN device. + * @client: The client to link. + * + * Sets up a device link between the provided client device as consumer and + * the SAN device as provider. This function can be used to ensure that the + * SAN interface has been set up and will be set up for as long as the driver + * of the client device is bound. This guarantees that, during that time, all + * dGPU events will be received by any registered notifier. + * + * The link will be automatically removed once the client device's driver is + * unbound. + * + * Return: Returns zero on success, %-ENXIO if the SAN interface has not been + * set up yet, and %-ENOMEM if device link creation failed. + */ +int san_client_link(struct device *client) +{ + const u32 flags = DL_FLAG_PM_RUNTIME | DL_FLAG_AUTOREMOVE_CONSUMER; + struct device_link *link; + + down_read(&san_rqsg_if.lock); + + if (!san_rqsg_if.dev) { + up_read(&san_rqsg_if.lock); + return -ENXIO; + } + + link = device_link_add(client, san_rqsg_if.dev, flags); + if (!link) { + up_read(&san_rqsg_if.lock); + return -ENOMEM; + } + + if (READ_ONCE(link->status) == DL_STATE_SUPPLIER_UNBIND) { + up_read(&san_rqsg_if.lock); + return -ENXIO; + } + + up_read(&san_rqsg_if.lock); + return 0; +} +EXPORT_SYMBOL_GPL(san_client_link); + +/** + * san_dgpu_notifier_register() - Register a SAN dGPU notifier. + * @nb: The notifier-block to register. + * + * Registers a SAN dGPU notifier, receiving any new SAN dGPU events sent from + * ACPI. The registered notifier will be called with &struct san_dgpu_event + * as notifier data and the command ID of that event as notifier action. + */ +int san_dgpu_notifier_register(struct notifier_block *nb) +{ + return blocking_notifier_chain_register(&san_rqsg_if.nh, nb); +} +EXPORT_SYMBOL_GPL(san_dgpu_notifier_register); + +/** + * san_dgpu_notifier_unregister() - Unregister a SAN dGPU notifier. + * @nb: The notifier-block to unregister. + */ +int san_dgpu_notifier_unregister(struct notifier_block *nb) +{ + return blocking_notifier_chain_unregister(&san_rqsg_if.nh, nb); +} +EXPORT_SYMBOL_GPL(san_dgpu_notifier_unregister); + +static int san_dgpu_notifier_call(struct san_dgpu_event *evt) +{ + int ret; + + ret = blocking_notifier_call_chain(&san_rqsg_if.nh, evt->command, evt); + return notifier_to_errno(ret); +} + + +/* -- ACPI _DSM event relay. ------------------------------------------------ */ + +#define SAN_DSM_REVISION 0 + +/* 93b666c5-70c6-469f-a215-3d487c91ab3c */ +static const guid_t SAN_DSM_UUID = + GUID_INIT(0x93b666c5, 0x70c6, 0x469f, 0xa2, 0x15, 0x3d, + 0x48, 0x7c, 0x91, 0xab, 0x3c); + +enum san_dsm_event_fn { + SAN_DSM_EVENT_FN_BAT1_STAT = 0x03, + SAN_DSM_EVENT_FN_BAT1_INFO = 0x04, + SAN_DSM_EVENT_FN_ADP1_STAT = 0x05, + SAN_DSM_EVENT_FN_ADP1_INFO = 0x06, + SAN_DSM_EVENT_FN_BAT2_STAT = 0x07, + SAN_DSM_EVENT_FN_BAT2_INFO = 0x08, + SAN_DSM_EVENT_FN_THERMAL = 0x09, + SAN_DSM_EVENT_FN_DPTF = 0x0a, +}; + +enum sam_event_cid_bat { + SAM_EVENT_CID_BAT_BIX = 0x15, + SAM_EVENT_CID_BAT_BST = 0x16, + SAM_EVENT_CID_BAT_ADP = 0x17, + SAM_EVENT_CID_BAT_PROT = 0x18, + SAM_EVENT_CID_BAT_DPTF = 0x4f, +}; + +enum sam_event_cid_tmp { + SAM_EVENT_CID_TMP_TRIP = 0x0b, +}; + +struct san_event_work { + struct delayed_work work; + struct device *dev; + struct ssam_event event; /* must be last */ +}; + +static int san_acpi_notify_event(struct device *dev, u64 func, + union acpi_object *param) +{ + acpi_handle san = ACPI_HANDLE(dev); + union acpi_object *obj; + int status = 0; + + if (!acpi_check_dsm(san, &SAN_DSM_UUID, SAN_DSM_REVISION, 1 << func)) + return 0; + + dev_dbg(dev, "notify event %#04llx\n", func); + + obj = acpi_evaluate_dsm_typed(san, &SAN_DSM_UUID, SAN_DSM_REVISION, + func, param, ACPI_TYPE_BUFFER); + if (!obj) + return -EFAULT; + + if (obj->buffer.length != 1 || obj->buffer.pointer[0] != 0) { + dev_err(dev, "got unexpected result from _DSM\n"); + status = -EPROTO; + } + + ACPI_FREE(obj); + return status; +} + +static int san_evt_bat_adp(struct device *dev, const struct ssam_event *event) +{ + int status; + + status = san_acpi_notify_event(dev, SAN_DSM_EVENT_FN_ADP1_STAT, NULL); + if (status) + return status; + + /* + * Ensure that the battery states get updated correctly. When the + * battery is fully charged and an adapter is plugged in, it sometimes + * is not updated correctly, instead showing it as charging. + * Explicitly trigger battery updates to fix this. + */ + + status = san_acpi_notify_event(dev, SAN_DSM_EVENT_FN_BAT1_STAT, NULL); + if (status) + return status; + + return san_acpi_notify_event(dev, SAN_DSM_EVENT_FN_BAT2_STAT, NULL); +} + +static int san_evt_bat_bix(struct device *dev, const struct ssam_event *event) +{ + enum san_dsm_event_fn fn; + + if (event->instance_id == 0x02) + fn = SAN_DSM_EVENT_FN_BAT2_INFO; + else + fn = SAN_DSM_EVENT_FN_BAT1_INFO; + + return san_acpi_notify_event(dev, fn, NULL); +} + +static int san_evt_bat_bst(struct device *dev, const struct ssam_event *event) +{ + enum san_dsm_event_fn fn; + + if (event->instance_id == 0x02) + fn = SAN_DSM_EVENT_FN_BAT2_STAT; + else + fn = SAN_DSM_EVENT_FN_BAT1_STAT; + + return san_acpi_notify_event(dev, fn, NULL); +} + +static int san_evt_bat_dptf(struct device *dev, const struct ssam_event *event) +{ + union acpi_object payload; + + /* + * The Surface ACPI expects a buffer and not a package. It specifically + * checks for ObjectType (Arg3) == 0x03. This will cause a warning in + * acpica/nsarguments.c, but that warning can be safely ignored. + */ + payload.type = ACPI_TYPE_BUFFER; + payload.buffer.length = event->length; + payload.buffer.pointer = (u8 *)&event->data[0]; + + return san_acpi_notify_event(dev, SAN_DSM_EVENT_FN_DPTF, &payload); +} + +static unsigned long san_evt_bat_delay(u8 cid) +{ + switch (cid) { + case SAM_EVENT_CID_BAT_ADP: + /* + * Wait for battery state to update before signaling adapter + * change. + */ + return msecs_to_jiffies(5000); + + case SAM_EVENT_CID_BAT_BST: + /* Ensure we do not miss anything important due to caching. */ + return msecs_to_jiffies(2000); + + default: + return 0; + } +} + +static bool san_evt_bat(const struct ssam_event *event, struct device *dev) +{ + int status; + + switch (event->command_id) { + case SAM_EVENT_CID_BAT_BIX: + status = san_evt_bat_bix(dev, event); + break; + + case SAM_EVENT_CID_BAT_BST: + status = san_evt_bat_bst(dev, event); + break; + + case SAM_EVENT_CID_BAT_ADP: + status = san_evt_bat_adp(dev, event); + break; + + case SAM_EVENT_CID_BAT_PROT: + /* + * TODO: Implement support for battery protection status change + * event. + */ + return true; + + case SAM_EVENT_CID_BAT_DPTF: + status = san_evt_bat_dptf(dev, event); + break; + + default: + return false; + } + + if (status) { + dev_err(dev, "error handling power event (cid = %#04x)\n", + event->command_id); + } + + return true; +} + +static void san_evt_bat_workfn(struct work_struct *work) +{ + struct san_event_work *ev; + + ev = container_of(work, struct san_event_work, work.work); + san_evt_bat(&ev->event, ev->dev); + kfree(ev); +} + +static u32 san_evt_bat_nf(struct ssam_event_notifier *nf, + const struct ssam_event *event) +{ + struct san_data *d = to_san_data(nf, nf_bat); + struct san_event_work *work; + unsigned long delay = san_evt_bat_delay(event->command_id); + + if (delay == 0) + return san_evt_bat(event, d->dev) ? SSAM_NOTIF_HANDLED : 0; + + work = kzalloc(sizeof(*work) + event->length, GFP_KERNEL); + if (!work) + return ssam_notifier_from_errno(-ENOMEM); + + INIT_DELAYED_WORK(&work->work, san_evt_bat_workfn); + work->dev = d->dev; + + memcpy(&work->event, event, sizeof(struct ssam_event) + event->length); + + schedule_delayed_work(&work->work, delay); + return SSAM_NOTIF_HANDLED; +} + +static int san_evt_tmp_trip(struct device *dev, const struct ssam_event *event) +{ + union acpi_object param; + + /* + * The Surface ACPI expects an integer and not a package. This will + * cause a warning in acpica/nsarguments.c, but that warning can be + * safely ignored. + */ + param.type = ACPI_TYPE_INTEGER; + param.integer.value = event->instance_id; + + return san_acpi_notify_event(dev, SAN_DSM_EVENT_FN_THERMAL, ¶m); +} + +static bool san_evt_tmp(const struct ssam_event *event, struct device *dev) +{ + int status; + + switch (event->command_id) { + case SAM_EVENT_CID_TMP_TRIP: + status = san_evt_tmp_trip(dev, event); + break; + + default: + return false; + } + + if (status) { + dev_err(dev, "error handling thermal event (cid = %#04x)\n", + event->command_id); + } + + return true; +} + +static u32 san_evt_tmp_nf(struct ssam_event_notifier *nf, + const struct ssam_event *event) +{ + struct san_data *d = to_san_data(nf, nf_tmp); + + return san_evt_tmp(event, d->dev) ? SSAM_NOTIF_HANDLED : 0; +} + + +/* -- ACPI GSB OperationRegion handler -------------------------------------- */ + +struct gsb_data_in { + u8 cv; +} __packed; + +struct gsb_data_rqsx { + u8 cv; /* Command value (san_gsb_request_cv). */ + u8 tc; /* Target category. */ + u8 tid; /* Target ID. */ + u8 iid; /* Instance ID. */ + u8 snc; /* Expect-response-flag. */ + u8 cid; /* Command ID. */ + u16 cdl; /* Payload length. */ + u8 pld[]; /* Payload. */ +} __packed; + +struct gsb_data_etwl { + u8 cv; /* Command value (should be 0x02). */ + u8 etw3; /* Unknown. */ + u8 etw4; /* Unknown. */ + u8 msg[]; /* Error message (ASCIIZ). */ +} __packed; + +struct gsb_data_out { + u8 status; /* _SSH communication status. */ + u8 len; /* _SSH payload length. */ + u8 pld[]; /* _SSH payload. */ +} __packed; + +union gsb_buffer_data { + struct gsb_data_in in; /* Common input. */ + struct gsb_data_rqsx rqsx; /* RQSX input. */ + struct gsb_data_etwl etwl; /* ETWL input. */ + struct gsb_data_out out; /* Output. */ +}; + +struct gsb_buffer { + u8 status; /* GSB AttribRawProcess status. */ + u8 len; /* GSB AttribRawProcess length. */ + union gsb_buffer_data data; +} __packed; + +#define SAN_GSB_MAX_RQSX_PAYLOAD (U8_MAX - 2 - sizeof(struct gsb_data_rqsx)) +#define SAN_GSB_MAX_RESPONSE (U8_MAX - 2 - sizeof(struct gsb_data_out)) + +#define SAN_GSB_COMMAND 0 + +enum san_gsb_request_cv { + SAN_GSB_REQUEST_CV_RQST = 0x01, + SAN_GSB_REQUEST_CV_ETWL = 0x02, + SAN_GSB_REQUEST_CV_RQSG = 0x03, +}; + +#define SAN_REQUEST_NUM_TRIES 5 + +static acpi_status san_etwl(struct san_data *d, struct gsb_buffer *b) +{ + struct gsb_data_etwl *etwl = &b->data.etwl; + + if (b->len < sizeof(struct gsb_data_etwl)) { + dev_err(d->dev, "invalid ETWL package (len = %d)\n", b->len); + return AE_OK; + } + + dev_err(d->dev, "ETWL(%#04x, %#04x): %.*s\n", etwl->etw3, etwl->etw4, + (unsigned int)(b->len - sizeof(struct gsb_data_etwl)), + (char *)etwl->msg); + + /* Indicate success. */ + b->status = 0x00; + b->len = 0x00; + + return AE_OK; +} + +static +struct gsb_data_rqsx *san_validate_rqsx(struct device *dev, const char *type, + struct gsb_buffer *b) +{ + struct gsb_data_rqsx *rqsx = &b->data.rqsx; + + if (b->len < sizeof(struct gsb_data_rqsx)) { + dev_err(dev, "invalid %s package (len = %d)\n", type, b->len); + return NULL; + } + + if (get_unaligned(&rqsx->cdl) != b->len - sizeof(struct gsb_data_rqsx)) { + dev_err(dev, "bogus %s package (len = %d, cdl = %d)\n", + type, b->len, get_unaligned(&rqsx->cdl)); + return NULL; + } + + if (get_unaligned(&rqsx->cdl) > SAN_GSB_MAX_RQSX_PAYLOAD) { + dev_err(dev, "payload for %s package too large (cdl = %d)\n", + type, get_unaligned(&rqsx->cdl)); + return NULL; + } + + return rqsx; +} + +static void gsb_rqsx_response_error(struct gsb_buffer *gsb, int status) +{ + gsb->status = 0x00; + gsb->len = 0x02; + gsb->data.out.status = (u8)(-status); + gsb->data.out.len = 0x00; +} + +static void gsb_rqsx_response_success(struct gsb_buffer *gsb, u8 *ptr, size_t len) +{ + gsb->status = 0x00; + gsb->len = len + 2; + gsb->data.out.status = 0x00; + gsb->data.out.len = len; + + if (len) + memcpy(&gsb->data.out.pld[0], ptr, len); +} + +static acpi_status san_rqst_fixup_suspended(struct san_data *d, + struct ssam_request *rqst, + struct gsb_buffer *gsb) +{ + if (rqst->target_category == SSAM_SSH_TC_BAS && rqst->command_id == 0x0D) { + u8 base_state = 1; + + /* Base state quirk: + * The base state may be queried from ACPI when the EC is still + * suspended. In this case it will return '-EPERM'. This query + * will only be triggered from the ACPI lid GPE interrupt, thus + * we are either in laptop or studio mode (base status 0x01 or + * 0x02). Furthermore, we will only get here if the device (and + * EC) have been suspended. + * + * We now assume that the device is in laptop mode (0x01). This + * has the drawback that it will wake the device when unfolding + * it in studio mode, but it also allows us to avoid actively + * waiting for the EC to wake up, which may incur a notable + * delay. + */ + + dev_dbg(d->dev, "rqst: fixup: base-state quirk\n"); + + gsb_rqsx_response_success(gsb, &base_state, sizeof(base_state)); + return AE_OK; + } + + gsb_rqsx_response_error(gsb, -ENXIO); + return AE_OK; +} + +static acpi_status san_rqst(struct san_data *d, struct gsb_buffer *buffer) +{ + u8 rspbuf[SAN_GSB_MAX_RESPONSE]; + struct gsb_data_rqsx *gsb_rqst; + struct ssam_request rqst; + struct ssam_response rsp; + int status = 0; + + gsb_rqst = san_validate_rqsx(d->dev, "RQST", buffer); + if (!gsb_rqst) + return AE_OK; + + rqst.target_category = gsb_rqst->tc; + rqst.target_id = gsb_rqst->tid; + rqst.command_id = gsb_rqst->cid; + rqst.instance_id = gsb_rqst->iid; + rqst.flags = gsb_rqst->snc ? SSAM_REQUEST_HAS_RESPONSE : 0; + rqst.length = get_unaligned(&gsb_rqst->cdl); + rqst.payload = &gsb_rqst->pld[0]; + + rsp.capacity = ARRAY_SIZE(rspbuf); + rsp.length = 0; + rsp.pointer = &rspbuf[0]; + + /* Handle suspended device. */ + if (d->dev->power.is_suspended) { + dev_warn(d->dev, "rqst: device is suspended, not executing\n"); + return san_rqst_fixup_suspended(d, &rqst, buffer); + } + + status = __ssam_retry(ssam_request_sync_onstack, SAN_REQUEST_NUM_TRIES, + d->ctrl, &rqst, &rsp, SAN_GSB_MAX_RQSX_PAYLOAD); + + if (!status) { + gsb_rqsx_response_success(buffer, rsp.pointer, rsp.length); + } else { + dev_err(d->dev, "rqst: failed with error %d\n", status); + gsb_rqsx_response_error(buffer, status); + } + + return AE_OK; +} + +static acpi_status san_rqsg(struct san_data *d, struct gsb_buffer *buffer) +{ + struct gsb_data_rqsx *gsb_rqsg; + struct san_dgpu_event evt; + int status; + + gsb_rqsg = san_validate_rqsx(d->dev, "RQSG", buffer); + if (!gsb_rqsg) + return AE_OK; + + evt.category = gsb_rqsg->tc; + evt.target = gsb_rqsg->tid; + evt.command = gsb_rqsg->cid; + evt.instance = gsb_rqsg->iid; + evt.length = get_unaligned(&gsb_rqsg->cdl); + evt.payload = &gsb_rqsg->pld[0]; + + status = san_dgpu_notifier_call(&evt); + if (!status) { + gsb_rqsx_response_success(buffer, NULL, 0); + } else { + dev_err(d->dev, "rqsg: failed with error %d\n", status); + gsb_rqsx_response_error(buffer, status); + } + + return AE_OK; +} + +static acpi_status san_opreg_handler(u32 function, acpi_physical_address command, + u32 bits, u64 *value64, void *opreg_context, + void *region_context) +{ + struct san_data *d = to_san_data(opreg_context, info); + struct gsb_buffer *buffer = (struct gsb_buffer *)value64; + int accessor_type = (function & 0xFFFF0000) >> 16; + + if (command != SAN_GSB_COMMAND) { + dev_warn(d->dev, "unsupported command: %#04llx\n", command); + return AE_OK; + } + + if (accessor_type != ACPI_GSB_ACCESS_ATTRIB_RAW_PROCESS) { + dev_err(d->dev, "invalid access type: %#04x\n", accessor_type); + return AE_OK; + } + + /* Buffer must have at least contain the command-value. */ + if (buffer->len == 0) { + dev_err(d->dev, "request-package too small\n"); + return AE_OK; + } + + switch (buffer->data.in.cv) { + case SAN_GSB_REQUEST_CV_RQST: + return san_rqst(d, buffer); + + case SAN_GSB_REQUEST_CV_ETWL: + return san_etwl(d, buffer); + + case SAN_GSB_REQUEST_CV_RQSG: + return san_rqsg(d, buffer); + + default: + dev_warn(d->dev, "unsupported SAN0 request (cv: %#04x)\n", + buffer->data.in.cv); + return AE_OK; + } +} + + +/* -- Driver setup. --------------------------------------------------------- */ + +static int san_events_register(struct platform_device *pdev) +{ + struct san_data *d = platform_get_drvdata(pdev); + int status; + + d->nf_bat.base.priority = 1; + d->nf_bat.base.fn = san_evt_bat_nf; + d->nf_bat.event.reg = SSAM_EVENT_REGISTRY_SAM; + d->nf_bat.event.id.target_category = SSAM_SSH_TC_BAT; + d->nf_bat.event.id.instance = 0; + d->nf_bat.event.mask = SSAM_EVENT_MASK_TARGET; + d->nf_bat.event.flags = SSAM_EVENT_SEQUENCED; + + d->nf_tmp.base.priority = 1; + d->nf_tmp.base.fn = san_evt_tmp_nf; + d->nf_tmp.event.reg = SSAM_EVENT_REGISTRY_SAM; + d->nf_tmp.event.id.target_category = SSAM_SSH_TC_TMP; + d->nf_tmp.event.id.instance = 0; + d->nf_tmp.event.mask = SSAM_EVENT_MASK_TARGET; + d->nf_tmp.event.flags = SSAM_EVENT_SEQUENCED; + + status = ssam_notifier_register(d->ctrl, &d->nf_bat); + if (status) + return status; + + status = ssam_notifier_register(d->ctrl, &d->nf_tmp); + if (status) + ssam_notifier_unregister(d->ctrl, &d->nf_bat); + + return status; +} + +static void san_events_unregister(struct platform_device *pdev) +{ + struct san_data *d = platform_get_drvdata(pdev); + + ssam_notifier_unregister(d->ctrl, &d->nf_bat); + ssam_notifier_unregister(d->ctrl, &d->nf_tmp); +} + +#define san_consumer_printk(level, dev, handle, fmt, ...) \ +do { \ + char *path = ""; \ + struct acpi_buffer buffer = { \ + .length = ACPI_ALLOCATE_BUFFER, \ + .pointer = NULL, \ + }; \ + \ + if (ACPI_SUCCESS(acpi_get_name(handle, ACPI_FULL_PATHNAME, &buffer))) \ + path = buffer.pointer; \ + \ + dev_##level(dev, "[%s]: " fmt, path, ##__VA_ARGS__); \ + kfree(buffer.pointer); \ +} while (0) + +#define san_consumer_dbg(dev, handle, fmt, ...) \ + san_consumer_printk(dbg, dev, handle, fmt, ##__VA_ARGS__) + +#define san_consumer_warn(dev, handle, fmt, ...) \ + san_consumer_printk(warn, dev, handle, fmt, ##__VA_ARGS__) + +static bool is_san_consumer(struct platform_device *pdev, acpi_handle handle) +{ + struct acpi_handle_list dep_devices; + acpi_handle supplier = ACPI_HANDLE(&pdev->dev); + acpi_status status; + int i; + + if (!acpi_has_method(handle, "_DEP")) + return false; + + status = acpi_evaluate_reference(handle, "_DEP", NULL, &dep_devices); + if (ACPI_FAILURE(status)) { + san_consumer_dbg(&pdev->dev, handle, "failed to evaluate _DEP\n"); + return false; + } + + for (i = 0; i < dep_devices.count; i++) { + if (dep_devices.handles[i] == supplier) + return true; + } + + return false; +} + +static acpi_status san_consumer_setup(acpi_handle handle, u32 lvl, + void *context, void **rv) +{ + const u32 flags = DL_FLAG_PM_RUNTIME | DL_FLAG_AUTOREMOVE_SUPPLIER; + struct platform_device *pdev = context; + struct acpi_device *adev; + struct device_link *link; + + if (!is_san_consumer(pdev, handle)) + return AE_OK; + + /* Ignore ACPI devices that are not present. */ + if (acpi_bus_get_device(handle, &adev) != 0) + return AE_OK; + + san_consumer_dbg(&pdev->dev, handle, "creating device link\n"); + + /* Try to set up device links, ignore but log errors. */ + link = device_link_add(&adev->dev, &pdev->dev, flags); + if (!link) { + san_consumer_warn(&pdev->dev, handle, "failed to create device link\n"); + return AE_OK; + } + + return AE_OK; +} + +static int san_consumer_links_setup(struct platform_device *pdev) +{ + acpi_status status; + + status = acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT, + ACPI_UINT32_MAX, san_consumer_setup, NULL, + pdev, NULL); + + return status ? -EFAULT : 0; +} + +static int san_probe(struct platform_device *pdev) +{ + acpi_handle san = ACPI_HANDLE(&pdev->dev); + struct ssam_controller *ctrl; + struct san_data *data; + acpi_status astatus; + int status; + + ctrl = ssam_client_bind(&pdev->dev); + if (IS_ERR(ctrl)) + return PTR_ERR(ctrl) == -ENODEV ? -EPROBE_DEFER : PTR_ERR(ctrl); + + status = san_consumer_links_setup(pdev); + if (status) + return status; + + data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL); + if (!data) + return -ENOMEM; + + data->dev = &pdev->dev; + data->ctrl = ctrl; + + platform_set_drvdata(pdev, data); + + astatus = acpi_install_address_space_handler(san, ACPI_ADR_SPACE_GSBUS, + &san_opreg_handler, NULL, + &data->info); + if (ACPI_FAILURE(astatus)) + return -ENXIO; + + status = san_events_register(pdev); + if (status) + goto err_enable_events; + + status = san_set_rqsg_interface_device(&pdev->dev); + if (status) + goto err_install_dev; + + acpi_walk_dep_device_list(san); + return 0; + +err_install_dev: + san_events_unregister(pdev); +err_enable_events: + acpi_remove_address_space_handler(san, ACPI_ADR_SPACE_GSBUS, + &san_opreg_handler); + return status; +} + +static int san_remove(struct platform_device *pdev) +{ + acpi_handle san = ACPI_HANDLE(&pdev->dev); + + san_set_rqsg_interface_device(NULL); + acpi_remove_address_space_handler(san, ACPI_ADR_SPACE_GSBUS, + &san_opreg_handler); + san_events_unregister(pdev); + + /* + * We have unregistered our event sources. Now we need to ensure that + * all delayed works they may have spawned are run to completion. + */ + flush_scheduled_work(); + + return 0; +} + +static const struct acpi_device_id san_match[] = { + { "MSHW0091" }, + { }, +}; +MODULE_DEVICE_TABLE(acpi, san_match); + +static struct platform_driver surface_acpi_notify = { + .probe = san_probe, + .remove = san_remove, + .driver = { + .name = "surface_acpi_notify", + .acpi_match_table = san_match, + .probe_type = PROBE_PREFER_ASYNCHRONOUS, + }, +}; +module_platform_driver(surface_acpi_notify); + +MODULE_AUTHOR("Maximilian Luz "); +MODULE_DESCRIPTION("Surface ACPI Notify driver for Surface System Aggregator Module"); +MODULE_LICENSE("GPL"); diff --git a/include/linux/surface_acpi_notify.h b/include/linux/surface_acpi_notify.h new file mode 100644 index 000000000000..8e3e86c7d78c --- /dev/null +++ b/include/linux/surface_acpi_notify.h @@ -0,0 +1,39 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Interface for Surface ACPI Notify (SAN) driver. + * + * Provides access to discrete GPU notifications sent from ACPI via the SAN + * driver, which are not handled by this driver directly. + * + * Copyright (C) 2019-2020 Maximilian Luz + */ + +#ifndef _LINUX_SURFACE_ACPI_NOTIFY_H +#define _LINUX_SURFACE_ACPI_NOTIFY_H + +#include +#include + +/** + * struct san_dgpu_event - Discrete GPU ACPI event. + * @category: Category of the event. + * @target: Target ID of the event source. + * @command: Command ID of the event. + * @instance: Instance ID of the event source. + * @length: Length of the event's payload data (in bytes). + * @payload: Pointer to the event's payload data. + */ +struct san_dgpu_event { + u8 category; + u8 target; + u8 command; + u8 instance; + u16 length; + u8 *payload; +}; + +int san_client_link(struct device *client); +int san_dgpu_notifier_register(struct notifier_block *nb); +int san_dgpu_notifier_unregister(struct notifier_block *nb); + +#endif /* _LINUX_SURFACE_ACPI_NOTIFY_H */ -- cgit v1.2.3 From 361c0f3d80dc3b54c20a19e8ffa2ad728fc1d23d Mon Sep 17 00:00:00 2001 From: Sebastian Andrzej Siewior Date: Tue, 15 Dec 2020 15:16:48 +0100 Subject: doc: Update RCU's requirements page about the PREEMPT_RT wiki The PREEMPT_RT wiki moved from kernel.org to the Linux Foundation wiki. The kernel.org wiki is read only. This commit therefore updates the URL of the active PREEMPT_RT wiki. Signed-off-by: Sebastian Andrzej Siewior Signed-off-by: Paul E. McKenney --- Documentation/RCU/Design/Requirements/Requirements.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Documentation') diff --git a/Documentation/RCU/Design/Requirements/Requirements.rst b/Documentation/RCU/Design/Requirements/Requirements.rst index 65c7839114a5..bac1cdde57d1 100644 --- a/Documentation/RCU/Design/Requirements/Requirements.rst +++ b/Documentation/RCU/Design/Requirements/Requirements.rst @@ -2317,7 +2317,7 @@ decides to throw at it. The Linux kernel is used for real-time workloads, especially in conjunction with the `-rt -patchset `__. The +patchset `__. The real-time-latency response requirements are such that the traditional approach of disabling preemption across RCU read-side critical sections is inappropriate. Kernels built with ``CONFIG_PREEMPT=y`` therefore use -- cgit v1.2.3 From 81ad58be2f83f9bd675f67ca5b8f420358ddf13c Mon Sep 17 00:00:00 2001 From: Sebastian Andrzej Siewior Date: Tue, 15 Dec 2020 15:16:49 +0100 Subject: doc: Use CONFIG_PREEMPTION CONFIG_PREEMPTION is selected by CONFIG_PREEMPT and by CONFIG_PREEMPT_RT. Both PREEMPT and PREEMPT_RT require the same functionality which today depends on CONFIG_PREEMPT. Update the documents and mention CONFIG_PREEMPTION. Spell out CONFIG_PREEMPT_RT (instead PREEMPT_RT) since it is an option now. Signed-off-by: Sebastian Andrzej Siewior Signed-off-by: Paul E. McKenney --- .../Expedited-Grace-Periods.rst | 4 ++-- .../RCU/Design/Requirements/Requirements.rst | 22 +++++++++++----------- Documentation/RCU/checklist.rst | 2 +- Documentation/RCU/rcubarrier.rst | 6 +++--- Documentation/RCU/stallwarn.rst | 4 ++-- Documentation/RCU/whatisRCU.rst | 10 +++++----- 6 files changed, 24 insertions(+), 24 deletions(-) (limited to 'Documentation') diff --git a/Documentation/RCU/Design/Expedited-Grace-Periods/Expedited-Grace-Periods.rst b/Documentation/RCU/Design/Expedited-Grace-Periods/Expedited-Grace-Periods.rst index 72f0f6fbd53c..6f89cf1e567d 100644 --- a/Documentation/RCU/Design/Expedited-Grace-Periods/Expedited-Grace-Periods.rst +++ b/Documentation/RCU/Design/Expedited-Grace-Periods/Expedited-Grace-Periods.rst @@ -38,7 +38,7 @@ sections. RCU-preempt Expedited Grace Periods =================================== -``CONFIG_PREEMPT=y`` kernels implement RCU-preempt. +``CONFIG_PREEMPTION=y`` kernels implement RCU-preempt. The overall flow of the handling of a given CPU by an RCU-preempt expedited grace period is shown in the following diagram: @@ -112,7 +112,7 @@ things. RCU-sched Expedited Grace Periods --------------------------------- -``CONFIG_PREEMPT=n`` kernels implement RCU-sched. The overall flow of +``CONFIG_PREEMPTION=n`` kernels implement RCU-sched. The overall flow of the handling of a given CPU by an RCU-sched expedited grace period is shown in the following diagram: diff --git a/Documentation/RCU/Design/Requirements/Requirements.rst b/Documentation/RCU/Design/Requirements/Requirements.rst index bac1cdde57d1..42a81e30619e 100644 --- a/Documentation/RCU/Design/Requirements/Requirements.rst +++ b/Documentation/RCU/Design/Requirements/Requirements.rst @@ -78,7 +78,7 @@ RCU treats a nested set as one big RCU read-side critical section. Production-quality implementations of rcu_read_lock() and rcu_read_unlock() are extremely lightweight, and in fact have exactly zero overhead in Linux kernels built for production use with -``CONFIG_PREEMPT=n``. +``CONFIG_PREEMPTION=n``. This guarantee allows ordering to be enforced with extremely low overhead to readers, for example: @@ -1181,7 +1181,7 @@ and has become decreasingly so as memory sizes have expanded and memory costs have plummeted. However, as I learned from Matt Mackall's `bloatwatch `__ efforts, memory footprint is critically important on single-CPU systems with -non-preemptible (``CONFIG_PREEMPT=n``) kernels, and thus `tiny +non-preemptible (``CONFIG_PREEMPTION=n``) kernels, and thus `tiny RCU `__ was born. Josh Triplett has since taken over the small-memory banner with his `Linux kernel tinification `__ @@ -1497,7 +1497,7 @@ limitations. Implementations of RCU for which rcu_read_lock() and rcu_read_unlock() generate no code, such as Linux-kernel RCU when -``CONFIG_PREEMPT=n``, can be nested arbitrarily deeply. After all, there +``CONFIG_PREEMPTION=n``, can be nested arbitrarily deeply. After all, there is no overhead. Except that if all these instances of rcu_read_lock() and rcu_read_unlock() are visible to the compiler, compilation will eventually fail due to exhausting memory, @@ -1769,7 +1769,7 @@ implementation can be a no-op. However, once the scheduler has spawned its first kthread, this early boot trick fails for synchronize_rcu() (as well as for -synchronize_rcu_expedited()) in ``CONFIG_PREEMPT=y`` kernels. The +synchronize_rcu_expedited()) in ``CONFIG_PREEMPTION=y`` kernels. The reason is that an RCU read-side critical section might be preempted, which means that a subsequent synchronize_rcu() really does have to wait for something, as opposed to simply returning immediately. @@ -2038,7 +2038,7 @@ the following: 5 rcu_read_unlock(); 6 do_something_with(v, user_v); -If the compiler did make this transformation in a ``CONFIG_PREEMPT=n`` kernel +If the compiler did make this transformation in a ``CONFIG_PREEMPTION=n`` kernel build, and if get_user() did page fault, the result would be a quiescent state in the middle of an RCU read-side critical section. This misplaced quiescent state could result in line 4 being a use-after-free access, @@ -2320,7 +2320,7 @@ conjunction with the `-rt patchset `__. The real-time-latency response requirements are such that the traditional approach of disabling preemption across RCU read-side critical sections -is inappropriate. Kernels built with ``CONFIG_PREEMPT=y`` therefore use +is inappropriate. Kernels built with ``CONFIG_PREEMPTION=y`` therefore use an RCU implementation that allows RCU read-side critical sections to be preempted. This requirement made its presence known after users made it clear that an earlier `real-time @@ -2460,11 +2460,11 @@ not have this property, given that any point in the code outside of an RCU read-side critical section can be a quiescent state. Therefore, *RCU-sched* was created, which follows “classic” RCU in that an RCU-sched grace period waits for pre-existing interrupt and NMI -handlers. In kernels built with ``CONFIG_PREEMPT=n``, the RCU and +handlers. In kernels built with ``CONFIG_PREEMPTION=n``, the RCU and RCU-sched APIs have identical implementations, while kernels built with -``CONFIG_PREEMPT=y`` provide a separate implementation for each. +``CONFIG_PREEMPTION=y`` provide a separate implementation for each. -Note well that in ``CONFIG_PREEMPT=y`` kernels, +Note well that in ``CONFIG_PREEMPTION=y`` kernels, rcu_read_lock_sched() and rcu_read_unlock_sched() disable and re-enable preemption, respectively. This means that if there was a preemption attempt during the RCU-sched read-side critical section, @@ -2627,10 +2627,10 @@ userspace execution also delimit tasks-RCU read-side critical sections. The tasks-RCU API is quite compact, consisting only of call_rcu_tasks(), synchronize_rcu_tasks(), and -rcu_barrier_tasks(). In ``CONFIG_PREEMPT=n`` kernels, trampolines +rcu_barrier_tasks(). In ``CONFIG_PREEMPTION=n`` kernels, trampolines cannot be preempted, so these APIs map to call_rcu(), synchronize_rcu(), and rcu_barrier(), respectively. In -``CONFIG_PREEMPT=y`` kernels, trampolines can be preempted, and these +``CONFIG_PREEMPTION=y`` kernels, trampolines can be preempted, and these three APIs are therefore implemented by separate functions that check for voluntary context switches. diff --git a/Documentation/RCU/checklist.rst b/Documentation/RCU/checklist.rst index 2d1dc1deffc9..1030119294d0 100644 --- a/Documentation/RCU/checklist.rst +++ b/Documentation/RCU/checklist.rst @@ -212,7 +212,7 @@ over a rather long period of time, but improvements are always welcome! the rest of the system. 7. As of v4.20, a given kernel implements only one RCU flavor, - which is RCU-sched for PREEMPT=n and RCU-preempt for PREEMPT=y. + which is RCU-sched for PREEMPTION=n and RCU-preempt for PREEMPTION=y. If the updater uses call_rcu() or synchronize_rcu(), then the corresponding readers may use rcu_read_lock() and rcu_read_unlock(), rcu_read_lock_bh() and rcu_read_unlock_bh(), diff --git a/Documentation/RCU/rcubarrier.rst b/Documentation/RCU/rcubarrier.rst index f64f4413a47c..3b4a24877496 100644 --- a/Documentation/RCU/rcubarrier.rst +++ b/Documentation/RCU/rcubarrier.rst @@ -9,7 +9,7 @@ RCU (read-copy update) is a synchronization mechanism that can be thought of as a replacement for read-writer locking (among other things), but with very low-overhead readers that are immune to deadlock, priority inversion, and unbounded latency. RCU read-side critical sections are delimited -by rcu_read_lock() and rcu_read_unlock(), which, in non-CONFIG_PREEMPT +by rcu_read_lock() and rcu_read_unlock(), which, in non-CONFIG_PREEMPTION kernels, generate no code whatsoever. This means that RCU writers are unaware of the presence of concurrent @@ -329,10 +329,10 @@ Answer: This cannot happen. The reason is that on_each_cpu() has its last to smp_call_function() and further to smp_call_function_on_cpu(), causing this latter to spin until the cross-CPU invocation of rcu_barrier_func() has completed. This by itself would prevent - a grace period from completing on non-CONFIG_PREEMPT kernels, + a grace period from completing on non-CONFIG_PREEMPTION kernels, since each CPU must undergo a context switch (or other quiescent state) before the grace period can complete. However, this is - of no use in CONFIG_PREEMPT kernels. + of no use in CONFIG_PREEMPTION kernels. Therefore, on_each_cpu() disables preemption across its call to smp_call_function() and also across the local call to diff --git a/Documentation/RCU/stallwarn.rst b/Documentation/RCU/stallwarn.rst index c9ab6af4d3be..e97d1b4876ef 100644 --- a/Documentation/RCU/stallwarn.rst +++ b/Documentation/RCU/stallwarn.rst @@ -25,7 +25,7 @@ warnings: - A CPU looping with bottom halves disabled. -- For !CONFIG_PREEMPT kernels, a CPU looping anywhere in the kernel +- For !CONFIG_PREEMPTION kernels, a CPU looping anywhere in the kernel without invoking schedule(). If the looping in the kernel is really expected and desirable behavior, you might need to add some calls to cond_resched(). @@ -44,7 +44,7 @@ warnings: result in the ``rcu_.*kthread starved for`` console-log message, which will include additional debugging information. -- A CPU-bound real-time task in a CONFIG_PREEMPT kernel, which might +- A CPU-bound real-time task in a CONFIG_PREEMPTION kernel, which might happen to preempt a low-priority task in the middle of an RCU read-side critical section. This is especially damaging if that low-priority task is not permitted to run on any other CPU, diff --git a/Documentation/RCU/whatisRCU.rst b/Documentation/RCU/whatisRCU.rst index 1a4723f48bd9..17e95ab2a201 100644 --- a/Documentation/RCU/whatisRCU.rst +++ b/Documentation/RCU/whatisRCU.rst @@ -683,7 +683,7 @@ Quick Quiz #1: ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ This section presents a "toy" RCU implementation that is based on "classic RCU". It is also short on performance (but only for updates) and -on features such as hotplug CPU and the ability to run in CONFIG_PREEMPT +on features such as hotplug CPU and the ability to run in CONFIG_PREEMPTION kernels. The definitions of rcu_dereference() and rcu_assign_pointer() are the same as those shown in the preceding section, so they are omitted. :: @@ -739,7 +739,7 @@ Quick Quiz #2: Quick Quiz #3: If it is illegal to block in an RCU read-side critical section, what the heck do you do in - PREEMPT_RT, where normal spinlocks can block??? + CONFIG_PREEMPT_RT, where normal spinlocks can block??? :ref:`Answers to Quick Quiz <8_whatisRCU>` @@ -1093,7 +1093,7 @@ Quick Quiz #2: overhead is **negative**. Answer: - Imagine a single-CPU system with a non-CONFIG_PREEMPT + Imagine a single-CPU system with a non-CONFIG_PREEMPTION kernel where a routing table is used by process-context code, but can be updated by irq-context code (for example, by an "ICMP REDIRECT" packet). The usual way of handling @@ -1120,10 +1120,10 @@ Answer: Quick Quiz #3: If it is illegal to block in an RCU read-side critical section, what the heck do you do in - PREEMPT_RT, where normal spinlocks can block??? + CONFIG_PREEMPT_RT, where normal spinlocks can block??? Answer: - Just as PREEMPT_RT permits preemption of spinlock + Just as CONFIG_PREEMPT_RT permits preemption of spinlock critical sections, it permits preemption of RCU read-side critical sections. It also permits spinlocks blocking while in RCU read-side critical -- cgit v1.2.3 From 2c4319bd1d14d01f5b6654a90c2b6362f3a407d8 Mon Sep 17 00:00:00 2001 From: "Paul E. McKenney" Date: Wed, 23 Sep 2020 17:39:46 -0700 Subject: rcutorture: Test runtime toggling of CPUs' callback offloading Frederic Weisbecker is adding the ability to change the rcu_nocbs state of CPUs at runtime, that is, to offload and deoffload their RCU callback processing without the need to reboot. As the old saying goes, "if it ain't tested, it don't work", so this commit therefore adds prototype rcutorture testing for this capability. Signed-off-by: Paul E. McKenney Cc: Frederic Weisbecker --- Documentation/admin-guide/kernel-parameters.txt | 8 +++ kernel/rcu/rcutorture.c | 90 ++++++++++++++++++++++++- 2 files changed, 95 insertions(+), 3 deletions(-) (limited to 'Documentation') diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt index c722ec19cd00..9f8ac776ae41 100644 --- a/Documentation/admin-guide/kernel-parameters.txt +++ b/Documentation/admin-guide/kernel-parameters.txt @@ -4338,6 +4338,14 @@ stress RCU, they don't participate in the actual test, hence the "fake". + rcutorture.nocbs_nthreads= [KNL] + Set number of RCU callback-offload togglers. + Zero (the default) disables toggling. + + rcutorture.nocbs_toggle= [KNL] + Set the delay in milliseconds between successive + callback-offload toggling attempts. + rcutorture.nreaders= [KNL] Set number of RCU readers. The value -1 selects N-1, where N is the number of CPUs. A value diff --git a/kernel/rcu/rcutorture.c b/kernel/rcu/rcutorture.c index 528ed10b78fd..22735bc3eacc 100644 --- a/kernel/rcu/rcutorture.c +++ b/kernel/rcu/rcutorture.c @@ -97,6 +97,8 @@ torture_param(int, object_debug, 0, torture_param(int, onoff_holdoff, 0, "Time after boot before CPU hotplugs (s)"); torture_param(int, onoff_interval, 0, "Time between CPU hotplugs (jiffies), 0=disable"); +torture_param(int, nocbs_nthreads, 0, "Number of NOCB toggle threads, 0 to disable"); +torture_param(int, nocbs_toggle, 1000, "Time between toggling nocb state (ms)"); torture_param(int, read_exit_delay, 13, "Delay between read-then-exit episodes (s)"); torture_param(int, read_exit_burst, 16, @@ -127,10 +129,12 @@ static char *torture_type = "rcu"; module_param(torture_type, charp, 0444); MODULE_PARM_DESC(torture_type, "Type of RCU to torture (rcu, srcu, ...)"); +static int nrealnocbers; static int nrealreaders; static struct task_struct *writer_task; static struct task_struct **fakewriter_tasks; static struct task_struct **reader_tasks; +static struct task_struct **nocb_tasks; static struct task_struct *stats_task; static struct task_struct *fqs_task; static struct task_struct *boost_tasks[NR_CPUS]; @@ -174,6 +178,8 @@ static unsigned long n_read_exits; static struct list_head rcu_torture_removed; static unsigned long shutdown_jiffies; static unsigned long start_gp_seq; +static atomic_long_t n_nocb_offload; +static atomic_long_t n_nocb_deoffload; static int rcu_torture_writer_state; #define RTWS_FIXED_DELAY 0 @@ -1498,6 +1504,53 @@ rcu_torture_reader(void *arg) return 0; } +/* + * Randomly Toggle CPUs' callback-offload state. This uses hrtimers to + * increase race probabilities and fuzzes the interval between toggling. + */ +static int rcu_nocb_toggle(void *arg) +{ + int cpu; + int maxcpu = -1; + int oldnice = task_nice(current); + long r; + DEFINE_TORTURE_RANDOM(rand); + ktime_t toggle_delay; + unsigned long toggle_fuzz; + ktime_t toggle_interval = ms_to_ktime(nocbs_toggle); + + VERBOSE_TOROUT_STRING("rcu_nocb_toggle task started"); + while (!rcu_inkernel_boot_has_ended()) + schedule_timeout_interruptible(HZ / 10); + for_each_online_cpu(cpu) + maxcpu = cpu; + WARN_ON(maxcpu < 0); + if (toggle_interval > ULONG_MAX) + toggle_fuzz = ULONG_MAX >> 3; + else + toggle_fuzz = toggle_interval >> 3; + if (toggle_fuzz <= 0) + toggle_fuzz = NSEC_PER_USEC; + do { + r = torture_random(&rand); + cpu = (r >> 4) % (maxcpu + 1); + if (r & 0x1) { + rcu_nocb_cpu_offload(cpu); + atomic_long_inc(&n_nocb_offload); + } else { + rcu_nocb_cpu_deoffload(cpu); + atomic_long_inc(&n_nocb_deoffload); + } + toggle_delay = torture_random(&rand) % toggle_fuzz + toggle_interval; + set_current_state(TASK_INTERRUPTIBLE); + schedule_hrtimeout(&toggle_delay, HRTIMER_MODE_REL); + if (stutter_wait("rcu_nocb_toggle")) + sched_set_normal(current, oldnice); + } while (!torture_must_stop()); + torture_kthread_stopping("rcu_nocb_toggle"); + return 0; +} + /* * Print torture statistics. Caller must ensure that there is only * one call to this function at a given time!!! This is normally @@ -1553,7 +1606,9 @@ rcu_torture_stats_print(void) data_race(n_barrier_successes), data_race(n_barrier_attempts), data_race(n_rcu_torture_barrier_error)); - pr_cont("read-exits: %ld\n", data_race(n_read_exits)); + pr_cont("read-exits: %ld ", data_race(n_read_exits)); + pr_cont("nocb-toggles: %ld:%ld\n", + atomic_long_read(&n_nocb_offload), atomic_long_read(&n_nocb_deoffload)); pr_alert("%s%s ", torture_type, TORTURE_FLAG); if (atomic_read(&n_rcu_torture_mberror) || @@ -1647,7 +1702,8 @@ rcu_torture_print_module_parms(struct rcu_torture_ops *cur_ops, const char *tag) "stall_cpu_block=%d " "n_barrier_cbs=%d " "onoff_interval=%d onoff_holdoff=%d " - "read_exit_delay=%d read_exit_burst=%d\n", + "read_exit_delay=%d read_exit_burst=%d " + "nocbs_nthreads=%d nocbs_toggle=%d\n", torture_type, tag, nrealreaders, nfakewriters, stat_interval, verbose, test_no_idle_hz, shuffle_interval, stutter, irqreader, fqs_duration, fqs_holdoff, fqs_stutter, @@ -1657,7 +1713,8 @@ rcu_torture_print_module_parms(struct rcu_torture_ops *cur_ops, const char *tag) stall_cpu_block, n_barrier_cbs, onoff_interval, onoff_holdoff, - read_exit_delay, read_exit_burst); + read_exit_delay, read_exit_burst, + nocbs_nthreads, nocbs_toggle); } static int rcutorture_booster_cleanup(unsigned int cpu) @@ -2500,6 +2557,13 @@ rcu_torture_cleanup(void) torture_stop_kthread(rcu_torture_stall, stall_task); torture_stop_kthread(rcu_torture_writer, writer_task); + if (nocb_tasks) { + for (i = 0; i < nrealnocbers; i++) + torture_stop_kthread(rcu_nocb_toggle, nocb_tasks[i]); + kfree(nocb_tasks); + nocb_tasks = NULL; + } + if (reader_tasks) { for (i = 0; i < nrealreaders; i++) torture_stop_kthread(rcu_torture_reader, @@ -2762,6 +2826,26 @@ rcu_torture_init(void) if (firsterr) goto unwind; } + nrealnocbers = nocbs_nthreads; + if (WARN_ON(nrealnocbers < 0)) + nrealnocbers = 1; + if (WARN_ON(nocbs_toggle < 0)) + nocbs_toggle = HZ; + if (nrealnocbers > 0) { + nocb_tasks = kcalloc(nrealnocbers, sizeof(nocb_tasks[0]), GFP_KERNEL); + if (nocb_tasks == NULL) { + VERBOSE_TOROUT_ERRSTRING("out of memory"); + firsterr = -ENOMEM; + goto unwind; + } + } else { + nocb_tasks = NULL; + } + for (i = 0; i < nrealnocbers; i++) { + firsterr = torture_create_kthread(rcu_nocb_toggle, NULL, nocb_tasks[i]); + if (firsterr) + goto unwind; + } if (stat_interval > 0) { firsterr = torture_create_kthread(rcu_torture_stats, NULL, stats_task); -- cgit v1.2.3 From 683954e55c981467bfd4688417e914bafc40959f Mon Sep 17 00:00:00 2001 From: Neeraj Upadhyay Date: Mon, 16 Nov 2020 21:36:00 +0530 Subject: rcu: Check and report missed fqs timer wakeup on RCU stall For a new grace period request, the RCU GP kthread transitions through following states: a. [RCU_GP_WAIT_GPS] -> [RCU_GP_DONE_GPS] The RCU_GP_WAIT_GPS state is where the GP kthread waits for a request for a new GP. Once it receives a request (for example, when a new RCU callback is queued), the GP kthread transitions to RCU_GP_DONE_GPS. b. [RCU_GP_DONE_GPS] -> [RCU_GP_ONOFF] Grace period initialization starts in rcu_gp_init(), which records the start of new GP in rcu_state.gp_seq and transitions to RCU_GP_ONOFF. c. [RCU_GP_ONOFF] -> [RCU_GP_INIT] The purpose of the RCU_GP_ONOFF state is to apply the online/offline information that was buffered for any CPUs that recently came online or went offline. This state is maintained in per-leaf rcu_node bitmasks, with the buffered state in ->qsmaskinitnext and the state for the upcoming GP in ->qsmaskinit. At the end of this RCU_GP_ONOFF state, each bit in ->qsmaskinit will correspond to a CPU that must pass through a quiescent state before the upcoming grace period is allowed to complete. However, a leaf rcu_node structure with an all-zeroes ->qsmaskinit cannot necessarily be ignored. In preemptible RCU, there might well be tasks still in RCU read-side critical sections that were first preempted while running on one of the CPUs managed by this structure. Such tasks will be queued on this structure's ->blkd_tasks list. Only after this list fully drains can this leaf rcu_node structure be ignored, and even then only if none of its CPUs have come back online in the meantime. Once that happens, the ->qsmaskinit masks further up the tree will be updated to exclude this leaf rcu_node structure. Once the ->qsmaskinitnext and ->qsmaskinit fields have been updated as needed, the GP kthread transitions to RCU_GP_INIT. d. [RCU_GP_INIT] -> [RCU_GP_WAIT_FQS] The purpose of the RCU_GP_INIT state is to copy each ->qsmaskinit to the ->qsmask field within each rcu_node structure. This copying is done breadth-first from the root to the leaves. Why not just copy directly from ->qsmaskinitnext to ->qsmask? Because the ->qsmaskinitnext masks can change in the meantime as additional CPUs come online or go offline. Such changes would result in inconsistencies in the ->qsmask fields up and down the tree, which could in turn result in too-short grace periods or grace-period hangs. These issues are avoided by snapshotting the leaf rcu_node structures' ->qsmaskinitnext fields into their ->qsmaskinit counterparts, generating a consistent set of ->qsmaskinit fields throughout the tree, and only then copying these consistent ->qsmaskinit fields to their ->qsmask counterparts. Once this initialization step is complete, the GP kthread transitions to RCU_GP_WAIT_FQS, where it waits to do a force-quiescent-state scan on the one hand or for the end of the grace period on the other. e. [RCU_GP_WAIT_FQS] -> [RCU_GP_DOING_FQS] The RCU_GP_WAIT_FQS state waits for one of three things: (1) An explicit request to do a force-quiescent-state scan, (2) The end of the grace period, or (3) A short interval of time, after which it will do a force-quiescent-state (FQS) scan. The explicit request can come from rcutorture or from any CPU that has too many RCU callbacks queued (see the qhimark kernel parameter and the RCU_GP_FLAG_OVLD flag). The aforementioned "short period of time" is specified by the jiffies_till_first_fqs boot parameter for a given grace period's first FQS scan and by the jiffies_till_next_fqs for later FQS scans. Either way, once the wait is over, the GP kthread transitions to RCU_GP_DOING_FQS. f. [RCU_GP_DOING_FQS] -> [RCU_GP_CLEANUP] The RCU_GP_DOING_FQS state performs an FQS scan. Each such scan carries out two functions for any CPU whose bit is still set in its leaf rcu_node structure's ->qsmask field, that is, for any CPU that has not yet reported a quiescent state for the current grace period: i. Report quiescent states on behalf of CPUs that have been observed to be idle (from an RCU perspective) since the beginning of the grace period. ii. If the current grace period is too old, take various actions to encourage holdout CPUs to pass through quiescent states, including enlisting the aid of any calls to cond_resched() and might_sleep(), and even including IPIing the holdout CPUs. These checks are skipped for any leaf rcu_node structure with a all-zero ->qsmask field, however such structures are subject to RCU priority boosting if there are tasks on a given structure blocking the current grace period. The end of the grace period is detected when the root rcu_node structure's ->qsmask is zero and when there are no longer any preempted tasks blocking the current grace period. (No, this last check is not redundant. To see this, consider an rcu_node tree having exactly one structure that serves as both root and leaf.) Once the end of the grace period is detected, the GP kthread transitions to RCU_GP_CLEANUP. g. [RCU_GP_CLEANUP] -> [RCU_GP_CLEANED] The RCU_GP_CLEANUP state marks the end of grace period by updating the rcu_state structure's ->gp_seq field and also all rcu_node structures' ->gp_seq field. As before, the rcu_node tree is traversed in breadth first order. Once this update is complete, the GP kthread transitions to the RCU_GP_CLEANED state. i. [RCU_GP_CLEANED] -> [RCU_GP_INIT] Once in the RCU_GP_CLEANED state, the GP kthread immediately transitions into the RCU_GP_INIT state. j. The role of timers. If there is at least one idle CPU, and if timers are not firing, the transition from RCU_GP_DOING_FQS to RCU_GP_CLEANUP will never happen. Timers can fail to fire for a number of reasons, including issues in timer configuration, issues in the timer framework, and failure to handle softirqs (for example, when there is a storm of interrupts). Whatever the reason, if the timers fail to fire, the GP kthread will never be awakened, resulting in RCU CPU stall warnings and eventually in OOM. However, an RCU CPU stall warning has a large number of potential causes, as documented in Documentation/RCU/stallwarn.rst. This commit therefore adds analysis to the RCU CPU stall-warning code to emit an additional message if the cause of the stall is likely to be timer failure. Signed-off-by: Neeraj Upadhyay Signed-off-by: Paul E. McKenney --- Documentation/RCU/stallwarn.rst | 23 ++++++++++++++++++++++- kernel/rcu/tree.c | 25 +++++++++++++++---------- kernel/rcu/tree_stall.h | 32 ++++++++++++++++++++++++++++++++ 3 files changed, 69 insertions(+), 11 deletions(-) (limited to 'Documentation') diff --git a/Documentation/RCU/stallwarn.rst b/Documentation/RCU/stallwarn.rst index c9ab6af4d3be..d53856cc6390 100644 --- a/Documentation/RCU/stallwarn.rst +++ b/Documentation/RCU/stallwarn.rst @@ -92,7 +92,9 @@ warnings: buggy timer hardware through bugs in the interrupt or exception path (whether hardware, firmware, or software) through bugs in Linux's timer subsystem through bugs in the scheduler, and, - yes, even including bugs in RCU itself. + yes, even including bugs in RCU itself. It can also result in + the ``rcu_.*timer wakeup didn't happen for`` console-log message, + which will include additional debugging information. - A bug in the RCU implementation. @@ -292,6 +294,25 @@ kthread is waiting for a short timeout, the "state" precedes value of the task_struct ->state field, and the "cpu" indicates that the grace-period kthread last ran on CPU 5. +If the relevant grace-period kthread does not wake from FQS wait in a +reasonable time, then the following additional line is printed:: + + kthread timer wakeup didn't happen for 23804 jiffies! g7076 f0x0 RCU_GP_WAIT_FQS(5) ->state=0x402 + +The "23804" indicates that kthread's timer expired more than 23 thousand +jiffies ago. The rest of the line has meaning similar to the kthread +starvation case. + +Additionally, the following line is printed:: + + Possible timer handling issue on cpu=4 timer-softirq=11142 + +Here "cpu" indicates that the grace-period kthread last ran on CPU 4, +where it queued the fqs timer. The number following the "timer-softirq" +is the current ``TIMER_SOFTIRQ`` count on cpu 4. If this value does not +change on successive RCU CPU stall warnings, there is further reason to +suspect a timer problem. + Multiple Warnings From One Stall ================================ diff --git a/kernel/rcu/tree.c b/kernel/rcu/tree.c index 40e5e3dd253e..e918f100cc34 100644 --- a/kernel/rcu/tree.c +++ b/kernel/rcu/tree.c @@ -1765,7 +1765,7 @@ static bool rcu_gp_init(void) * go offline later. Please also refer to "Hotplug CPU" section * of RCU's Requirements documentation. */ - rcu_state.gp_state = RCU_GP_ONOFF; + WRITE_ONCE(rcu_state.gp_state, RCU_GP_ONOFF); rcu_for_each_leaf_node(rnp) { smp_mb(); // Pair with barriers used when updating ->ofl_seq to odd values. firstseq = READ_ONCE(rnp->ofl_seq); @@ -1831,7 +1831,7 @@ static bool rcu_gp_init(void) * The grace period cannot complete until the initialization * process finishes, because this kthread handles both. */ - rcu_state.gp_state = RCU_GP_INIT; + WRITE_ONCE(rcu_state.gp_state, RCU_GP_INIT); rcu_for_each_node_breadth_first(rnp) { rcu_gp_slow(gp_init_delay); raw_spin_lock_irqsave_rcu_node(rnp, flags); @@ -1930,17 +1930,22 @@ static void rcu_gp_fqs_loop(void) ret = 0; for (;;) { if (!ret) { - rcu_state.jiffies_force_qs = jiffies + j; + WRITE_ONCE(rcu_state.jiffies_force_qs, jiffies + j); + /* + * jiffies_force_qs before RCU_GP_WAIT_FQS state + * update; required for stall checks. + */ + smp_wmb(); WRITE_ONCE(rcu_state.jiffies_kick_kthreads, jiffies + (j ? 3 * j : 2)); } trace_rcu_grace_period(rcu_state.name, rcu_state.gp_seq, TPS("fqswait")); - rcu_state.gp_state = RCU_GP_WAIT_FQS; + WRITE_ONCE(rcu_state.gp_state, RCU_GP_WAIT_FQS); ret = swait_event_idle_timeout_exclusive( rcu_state.gp_wq, rcu_gp_fqs_check_wake(&gf), j); rcu_gp_torture_wait(); - rcu_state.gp_state = RCU_GP_DOING_FQS; + WRITE_ONCE(rcu_state.gp_state, RCU_GP_DOING_FQS); /* Locking provides needed memory barriers. */ /* If grace period done, leave loop. */ if (!READ_ONCE(rnp->qsmask) && @@ -2054,7 +2059,7 @@ static void rcu_gp_cleanup(void) trace_rcu_grace_period(rcu_state.name, rcu_state.gp_seq, TPS("end")); rcu_seq_end(&rcu_state.gp_seq); ASSERT_EXCLUSIVE_WRITER(rcu_state.gp_seq); - rcu_state.gp_state = RCU_GP_IDLE; + WRITE_ONCE(rcu_state.gp_state, RCU_GP_IDLE); /* Check for GP requests since above loop. */ rdp = this_cpu_ptr(&rcu_data); if (!needgp && ULONG_CMP_LT(rnp->gp_seq, rnp->gp_seq_needed)) { @@ -2093,12 +2098,12 @@ static int __noreturn rcu_gp_kthread(void *unused) for (;;) { trace_rcu_grace_period(rcu_state.name, rcu_state.gp_seq, TPS("reqwait")); - rcu_state.gp_state = RCU_GP_WAIT_GPS; + WRITE_ONCE(rcu_state.gp_state, RCU_GP_WAIT_GPS); swait_event_idle_exclusive(rcu_state.gp_wq, READ_ONCE(rcu_state.gp_flags) & RCU_GP_FLAG_INIT); rcu_gp_torture_wait(); - rcu_state.gp_state = RCU_GP_DONE_GPS; + WRITE_ONCE(rcu_state.gp_state, RCU_GP_DONE_GPS); /* Locking provides needed memory barrier. */ if (rcu_gp_init()) break; @@ -2113,9 +2118,9 @@ static int __noreturn rcu_gp_kthread(void *unused) rcu_gp_fqs_loop(); /* Handle grace-period end. */ - rcu_state.gp_state = RCU_GP_CLEANUP; + WRITE_ONCE(rcu_state.gp_state, RCU_GP_CLEANUP); rcu_gp_cleanup(); - rcu_state.gp_state = RCU_GP_CLEANED; + WRITE_ONCE(rcu_state.gp_state, RCU_GP_CLEANED); } } diff --git a/kernel/rcu/tree_stall.h b/kernel/rcu/tree_stall.h index 29cf096b5d20..353da30bd558 100644 --- a/kernel/rcu/tree_stall.h +++ b/kernel/rcu/tree_stall.h @@ -482,6 +482,36 @@ static void rcu_check_gp_kthread_starvation(void) } } +/* Complain about missing wakeups from expired fqs wait timer */ +static void rcu_check_gp_kthread_expired_fqs_timer(void) +{ + struct task_struct *gpk = rcu_state.gp_kthread; + short gp_state; + unsigned long jiffies_fqs; + int cpu; + + /* + * Order reads of .gp_state and .jiffies_force_qs. + * Matching smp_wmb() is present in rcu_gp_fqs_loop(). + */ + gp_state = smp_load_acquire(&rcu_state.gp_state); + jiffies_fqs = READ_ONCE(rcu_state.jiffies_force_qs); + + if (gp_state == RCU_GP_WAIT_FQS && + time_after(jiffies, jiffies_fqs + RCU_STALL_MIGHT_MIN) && + gpk && !READ_ONCE(gpk->on_rq)) { + cpu = task_cpu(gpk); + pr_err("%s kthread timer wakeup didn't happen for %ld jiffies! g%ld f%#x %s(%d) ->state=%#lx\n", + rcu_state.name, (jiffies - jiffies_fqs), + (long)rcu_seq_current(&rcu_state.gp_seq), + data_race(rcu_state.gp_flags), + gp_state_getname(RCU_GP_WAIT_FQS), RCU_GP_WAIT_FQS, + gpk->state); + pr_err("\tPossible timer handling issue on cpu=%d timer-softirq=%u\n", + cpu, kstat_softirqs_cpu(TIMER_SOFTIRQ, cpu)); + } +} + static void print_other_cpu_stall(unsigned long gp_seq, unsigned long gps) { int cpu; @@ -543,6 +573,7 @@ static void print_other_cpu_stall(unsigned long gp_seq, unsigned long gps) WRITE_ONCE(rcu_state.jiffies_stall, jiffies + 3 * rcu_jiffies_till_stall_check() + 3); + rcu_check_gp_kthread_expired_fqs_timer(); rcu_check_gp_kthread_starvation(); panic_on_rcu_stall(); @@ -578,6 +609,7 @@ static void print_cpu_stall(unsigned long gps) jiffies - gps, (long)rcu_seq_current(&rcu_state.gp_seq), totqlen); + rcu_check_gp_kthread_expired_fqs_timer(); rcu_check_gp_kthread_starvation(); rcu_dump_cpu_stacks(); -- cgit v1.2.3 From e76506f0e85129d726c487c873a2245c92446515 Mon Sep 17 00:00:00 2001 From: "Paul E. McKenney" Date: Sun, 15 Nov 2020 10:24:52 -0800 Subject: refscale: Allow summarization of verbose output The refscale test prints enough per-kthread console output to provoke RCU CPU stall warnings on large systems. This commit therefore allows this output to be summarized. For example, the refscale.verbose_batched=32 boot parameter would causes only every 32nd line of output to be logged. Signed-off-by: Paul E. McKenney --- Documentation/admin-guide/kernel-parameters.txt | 6 ++++++ kernel/rcu/refscale.c | 21 ++++++++++++++++----- 2 files changed, 22 insertions(+), 5 deletions(-) (limited to 'Documentation') diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt index c722ec19cd00..3244f9e04a64 100644 --- a/Documentation/admin-guide/kernel-parameters.txt +++ b/Documentation/admin-guide/kernel-parameters.txt @@ -4557,6 +4557,12 @@ refscale.verbose= [KNL] Enable additional printk() statements. + refscale.verbose_batched= [KNL] + Batch the additional printk() statements. If zero + (the default) or negative, print everything. Otherwise, + print every Nth verbose statement, where N is the value + specified. + relax_domain_level= [KNL, SMP] Set scheduler's default relax_domain_level. See Documentation/admin-guide/cgroup-v1/cpusets.rst. diff --git a/kernel/rcu/refscale.c b/kernel/rcu/refscale.c index 23ff36a66f97..3da246f2ccf5 100644 --- a/kernel/rcu/refscale.c +++ b/kernel/rcu/refscale.c @@ -46,6 +46,16 @@ #define VERBOSE_SCALEOUT(s, x...) \ do { if (verbose) pr_alert("%s" SCALE_FLAG s, scale_type, ## x); } while (0) +static atomic_t verbose_batch_ctr; + +#define VERBOSE_SCALEOUT_BATCH(s, x...) \ +do { \ + if (verbose && \ + (verbose_batched <= 0 || \ + !(atomic_inc_return(&verbose_batch_ctr) % verbose_batched))) \ + pr_alert("%s" SCALE_FLAG s, scale_type, ## x); \ +} while (0) + #define VERBOSE_SCALEOUT_ERRSTRING(s, x...) \ do { if (verbose) pr_alert("%s" SCALE_FLAG "!!! " s, scale_type, ## x); } while (0) @@ -57,6 +67,7 @@ module_param(scale_type, charp, 0444); MODULE_PARM_DESC(scale_type, "Type of test (rcu, srcu, refcnt, rwsem, rwlock."); torture_param(int, verbose, 0, "Enable verbose debugging printk()s"); +torture_param(int, verbose_batched, 0, "Batch verbose debugging printk()s"); // Wait until there are multiple CPUs before starting test. torture_param(int, holdoff, IS_BUILTIN(CONFIG_RCU_REF_SCALE_TEST) ? 10 : 0, @@ -368,14 +379,14 @@ ref_scale_reader(void *arg) u64 start; s64 duration; - VERBOSE_SCALEOUT("ref_scale_reader %ld: task started", me); + VERBOSE_SCALEOUT_BATCH("ref_scale_reader %ld: task started", me); set_cpus_allowed_ptr(current, cpumask_of(me % nr_cpu_ids)); set_user_nice(current, MAX_NICE); atomic_inc(&n_init); if (holdoff) schedule_timeout_interruptible(holdoff * HZ); repeat: - VERBOSE_SCALEOUT("ref_scale_reader %ld: waiting to start next experiment on cpu %d", me, smp_processor_id()); + VERBOSE_SCALEOUT_BATCH("ref_scale_reader %ld: waiting to start next experiment on cpu %d", me, smp_processor_id()); // Wait for signal that this reader can start. wait_event(rt->wq, (atomic_read(&nreaders_exp) && smp_load_acquire(&rt->start_reader)) || @@ -392,7 +403,7 @@ repeat: while (atomic_read_acquire(&n_started)) cpu_relax(); - VERBOSE_SCALEOUT("ref_scale_reader %ld: experiment %d started", me, exp_idx); + VERBOSE_SCALEOUT_BATCH("ref_scale_reader %ld: experiment %d started", me, exp_idx); // To reduce noise, do an initial cache-warming invocation, check @@ -421,8 +432,8 @@ repeat: if (atomic_dec_and_test(&nreaders_exp)) wake_up(&main_wq); - VERBOSE_SCALEOUT("ref_scale_reader %ld: experiment %d ended, (readers remaining=%d)", - me, exp_idx, atomic_read(&nreaders_exp)); + VERBOSE_SCALEOUT_BATCH("ref_scale_reader %ld: experiment %d ended, (readers remaining=%d)", + me, exp_idx, atomic_read(&nreaders_exp)); if (!torture_must_stop()) goto repeat; -- cgit v1.2.3 From 8a67a20bf257ca378d6e5588fbe4382966395ac8 Mon Sep 17 00:00:00 2001 From: "Paul E. McKenney" Date: Wed, 25 Nov 2020 13:00:04 -0800 Subject: torture: Throttle VERBOSE_TOROUT_*() output This commit adds kernel boot parameters torture.verbose_sleep_frequency and torture.verbose_sleep_duration, which allow VERBOSE_TOROUT_*() output to be throttled with periodic sleeps on large systems. Signed-off-by: Paul E. McKenney --- Documentation/admin-guide/kernel-parameters.txt | 8 ++++++++ include/linux/torture.h | 15 +++++++++++++-- kernel/torture.c | 20 ++++++++++++++++++++ 3 files changed, 41 insertions(+), 2 deletions(-) (limited to 'Documentation') diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt index 3244f9e04a64..18f3aa759e54 100644 --- a/Documentation/admin-guide/kernel-parameters.txt +++ b/Documentation/admin-guide/kernel-parameters.txt @@ -5337,6 +5337,14 @@ are running concurrently, especially on systems with rotating-rust storage. + torture.verbose_sleep_frequency= [KNL] + Specifies how many verbose printk()s should be + emitted between each sleep. The default of zero + disables verbose-printk() sleeping. + + torture.verbose_sleep_duration= [KNL] + Duration of each verbose-printk() sleep in jiffies. + tp720= [HW,PS2] tpm_suspend_pcr=[HW,TPM] diff --git a/include/linux/torture.h b/include/linux/torture.h index 32941f8106b2..d62d13c8c69a 100644 --- a/include/linux/torture.h +++ b/include/linux/torture.h @@ -32,9 +32,20 @@ #define TOROUT_STRING(s) \ pr_alert("%s" TORTURE_FLAG " %s\n", torture_type, s) #define VERBOSE_TOROUT_STRING(s) \ - do { if (verbose) pr_alert("%s" TORTURE_FLAG " %s\n", torture_type, s); } while (0) +do { \ + if (verbose) { \ + verbose_torout_sleep(); \ + pr_alert("%s" TORTURE_FLAG " %s\n", torture_type, s); \ + } \ +} while (0) #define VERBOSE_TOROUT_ERRSTRING(s) \ - do { if (verbose) pr_alert("%s" TORTURE_FLAG "!!! %s\n", torture_type, s); } while (0) +do { \ + if (verbose) { \ + verbose_torout_sleep(); \ + pr_alert("%s" TORTURE_FLAG "!!! %s\n", torture_type, s); \ + } \ +} while (0) +void verbose_torout_sleep(void); /* Definitions for online/offline exerciser. */ typedef void torture_ofl_func(void); diff --git a/kernel/torture.c b/kernel/torture.c index 7ad5c9681580..93eeeb2b3d88 100644 --- a/kernel/torture.c +++ b/kernel/torture.c @@ -48,6 +48,12 @@ module_param(disable_onoff_at_boot, bool, 0444); static bool ftrace_dump_at_shutdown; module_param(ftrace_dump_at_shutdown, bool, 0444); +static int verbose_sleep_frequency; +module_param(verbose_sleep_frequency, int, 0444); + +static int verbose_sleep_duration = 1; +module_param(verbose_sleep_duration, int, 0444); + static char *torture_type; static int verbose; @@ -58,6 +64,20 @@ static int verbose; static int fullstop = FULLSTOP_RMMOD; static DEFINE_MUTEX(fullstop_mutex); +static atomic_t verbose_sleep_counter; + +/* + * Sleep if needed from VERBOSE_TOROUT*(). + */ +void verbose_torout_sleep(void) +{ + if (verbose_sleep_frequency > 0 && + verbose_sleep_duration > 0 && + !(atomic_inc_return(&verbose_sleep_counter) % verbose_sleep_frequency)) + schedule_timeout_uninterruptible(verbose_sleep_duration); +} +EXPORT_SYMBOL_GPL(verbose_torout_sleep); + /* * Schedule a high-resolution-timer sleep in nanoseconds, with a 32-bit * nanosecond random fuzz. This function and its friends desynchronize -- cgit v1.2.3 From d3c83bcab3186eba6eecc852b9858678fe9c2e6f Mon Sep 17 00:00:00 2001 From: Oleksij Rempel Date: Mon, 7 Dec 2020 15:09:32 +0100 Subject: dt-bindings: display: simple: fix alphabetical order for EDT compatibles Reorder it alphabetically and remove one double entry. Signed-off-by: Oleksij Rempel Reviewed-by: Rob Herring Signed-off-by: Shawn Guo --- .../devicetree/bindings/display/panel/panel-simple.yaml | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/display/panel/panel-simple.yaml b/Documentation/devicetree/bindings/display/panel/panel-simple.yaml index 27fffafe5b5c..5c4c61676dff 100644 --- a/Documentation/devicetree/bindings/display/panel/panel-simple.yaml +++ b/Documentation/devicetree/bindings/display/panel/panel-simple.yaml @@ -105,26 +105,24 @@ properties: - dlc,dlc1010gig # Emerging Display Technology Corp. 3.5" QVGA TFT LCD panel - edt,et035012dm6 + # Emerging Display Technology Corp. 5.7" VGA TFT LCD panel + - edt,et057090dhu # Emerging Display Technology Corp. 480x272 TFT Display with capacitive touch - edt,etm043080dh6gp # Emerging Display Technology Corp. 480x272 TFT Display - edt,etm0430g0dh6 - # Emerging Display Technology Corp. 5.7" VGA TFT LCD panel - - edt,et057090dhu - # Emerging Display Technology Corp. WVGA TFT Display with capacitive touch - - edt,etm070080dh6 - # Emerging Display Technology Corp. WVGA TFT Display with capacitive touch - - edt,etm0700g0dh6 # Emerging Display Technology Corp. WVGA TFT Display with capacitive touch # Same as ETM0700G0DH6 but with inverted pixel clock. - edt,etm070080bdh6 + # Emerging Display Technology Corp. WVGA TFT Display with capacitive touch + # Same timings as the ETM0700G0DH6, but with resistive touch. + - edt,etm070080dh6 # Emerging Display Technology Corp. WVGA TFT Display with capacitive touch # Same display as the ETM0700G0BDH6, but with changed hardware for the # backlight and the touch interface. - edt,etm070080edh6 # Emerging Display Technology Corp. WVGA TFT Display with capacitive touch - # Same timings as the ETM0700G0DH6, but with resistive touch. - - edt,etm070080dh6 + - edt,etm0700g0dh6 # Evervision Electronics Co. Ltd. VGG804821 5.0" WVGA TFT LCD Panel - evervision,vgg804821 # Foxlink Group 5" WVGA TFT LCD panel -- cgit v1.2.3 From 279ebba7fbf0380c27f74b5d21d61639a8b65dd2 Mon Sep 17 00:00:00 2001 From: Oleksij Rempel Date: Mon, 7 Dec 2020 15:09:33 +0100 Subject: dt-bindings: display: simple: add EDT compatibles already supported by the driver Some EDT compatibles are already supported by the driver but will fail on checkpatch script. Fix it by syncing dt-bindings documentation with the driver. Signed-off-by: Oleksij Rempel Reviewed-by: Rob Herring Signed-off-by: Shawn Guo --- Documentation/devicetree/bindings/display/panel/panel-simple.yaml | 3 +++ 1 file changed, 3 insertions(+) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/display/panel/panel-simple.yaml b/Documentation/devicetree/bindings/display/panel/panel-simple.yaml index 5c4c61676dff..cb52948188f1 100644 --- a/Documentation/devicetree/bindings/display/panel/panel-simple.yaml +++ b/Documentation/devicetree/bindings/display/panel/panel-simple.yaml @@ -107,6 +107,7 @@ properties: - edt,et035012dm6 # Emerging Display Technology Corp. 5.7" VGA TFT LCD panel - edt,et057090dhu + - edt,et070080dh6 # Emerging Display Technology Corp. 480x272 TFT Display with capacitive touch - edt,etm043080dh6gp # Emerging Display Technology Corp. 480x272 TFT Display @@ -121,8 +122,10 @@ properties: # Same display as the ETM0700G0BDH6, but with changed hardware for the # backlight and the touch interface. - edt,etm070080edh6 + - edt,etm0700g0bdh6 # Emerging Display Technology Corp. WVGA TFT Display with capacitive touch - edt,etm0700g0dh6 + - edt,etm0700g0edh6 # Evervision Electronics Co. Ltd. VGG804821 5.0" WVGA TFT LCD Panel - evervision,vgg804821 # Foxlink Group 5" WVGA TFT LCD panel -- cgit v1.2.3 From 922fb2db02871671c49afeaa73166553edf5a00c Mon Sep 17 00:00:00 2001 From: Oleksij Rempel Date: Mon, 7 Dec 2020 15:09:34 +0100 Subject: dt-bindings: display: simple: Add Kyocera tcg070wvlq panel So far, this panel seems to be compatible with "lg,lb070wv8", on other hand it is better to set this compatible in the devicetree. So, let's add it for now only to the dt-binding documentation to fix the checkpatch warnings. Signed-off-by: Oleksij Rempel Reviewed-by: Rob Herring Signed-off-by: Shawn Guo --- Documentation/devicetree/bindings/display/panel/panel-simple.yaml | 2 ++ 1 file changed, 2 insertions(+) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/display/panel/panel-simple.yaml b/Documentation/devicetree/bindings/display/panel/panel-simple.yaml index cb52948188f1..3207608d1178 100644 --- a/Documentation/devicetree/bindings/display/panel/panel-simple.yaml +++ b/Documentation/devicetree/bindings/display/panel/panel-simple.yaml @@ -174,6 +174,8 @@ properties: - koe,tx26d202vm0bwa # Kaohsiung Opto-Electronics. TX31D200VM0BAA 12.3" HSXGA LVDS panel - koe,tx31d200vm0baa + # Kyocera Corporation 7" WVGA (800x480) transmissive color TFT + - kyo,tcg070wvlq # Kyocera Corporation 12.1" XGA (1024x768) TFT LCD panel - kyo,tcg121xglp # LeMaker BL035-RGB-002 3.5" QVGA TFT LCD panel -- cgit v1.2.3 From 7ae786b05f7eae83dc61e60d32a3a013b1844f9a Mon Sep 17 00:00:00 2001 From: Oleksij Rempel Date: Mon, 7 Dec 2020 15:09:35 +0100 Subject: dt-bindings: vendor-prefixes: Add an entry for Plymovent Add "ply" entry for Plymovent Group BV: https://www.plymovent.com/ Signed-off-by: Oleksij Rempel Acked-by: Rob Herring Signed-off-by: Shawn Guo --- Documentation/devicetree/bindings/vendor-prefixes.yaml | 2 ++ 1 file changed, 2 insertions(+) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/vendor-prefixes.yaml b/Documentation/devicetree/bindings/vendor-prefixes.yaml index 041ae90b0d8f..f03ba0c4ae5e 100644 --- a/Documentation/devicetree/bindings/vendor-prefixes.yaml +++ b/Documentation/devicetree/bindings/vendor-prefixes.yaml @@ -866,6 +866,8 @@ patternProperties: description: PLDA "^plx,.*": description: Broadcom Corporation (formerly PLX Technology) + "^ply,.*": + description: Plymovent Group BV "^pni,.*": description: PNI Sensor Corporation "^pocketbook,.*": -- cgit v1.2.3 From 94e17a03395314312f868c0695ca65e9ec719c6b Mon Sep 17 00:00:00 2001 From: Oleksij Rempel Date: Mon, 7 Dec 2020 15:09:36 +0100 Subject: dt-bindings: arm: fsl: add Plymovent M2M board Add Plymovent Group BV M2M iMX6dl based board Signed-off-by: Oleksij Rempel Acked-by: Rob Herring Signed-off-by: Shawn Guo --- Documentation/devicetree/bindings/arm/fsl.yaml | 1 + 1 file changed, 1 insertion(+) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/arm/fsl.yaml b/Documentation/devicetree/bindings/arm/fsl.yaml index cee74fc0c115..cd76a7933700 100644 --- a/Documentation/devicetree/bindings/arm/fsl.yaml +++ b/Documentation/devicetree/bindings/arm/fsl.yaml @@ -364,6 +364,7 @@ properties: - fsl,imx6dl-sabresd # i.MX6 DualLite SABRE Smart Device Board - karo,imx6dl-tx6dl # Ka-Ro electronics TX6U Modules - kontron,imx6dl-samx6i # Kontron i.MX6 Solo SMARC Module + - ply,plym2m # Plymovent M2M board - poslab,imx6dl-savageboard # Poslab SavageBoard Dual - prt,prtrvt # Protonic RVT board - prt,prtvt7 # Protonic VT7 board -- cgit v1.2.3 From f1b8d58d3188108fd4ce066886594dc27a6d09c9 Mon Sep 17 00:00:00 2001 From: Oleksij Rempel Date: Mon, 7 Dec 2020 15:09:38 +0100 Subject: dt-bindings: arm: fsl: add Plymovent BAS board Add Plymovent Group BV BAS iMX6dl based board Signed-off-by: Oleksij Rempel Acked-by: Rob Herring Signed-off-by: Shawn Guo --- Documentation/devicetree/bindings/arm/fsl.yaml | 1 + 1 file changed, 1 insertion(+) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/arm/fsl.yaml b/Documentation/devicetree/bindings/arm/fsl.yaml index cd76a7933700..51b8d6fac792 100644 --- a/Documentation/devicetree/bindings/arm/fsl.yaml +++ b/Documentation/devicetree/bindings/arm/fsl.yaml @@ -364,6 +364,7 @@ properties: - fsl,imx6dl-sabresd # i.MX6 DualLite SABRE Smart Device Board - karo,imx6dl-tx6dl # Ka-Ro electronics TX6U Modules - kontron,imx6dl-samx6i # Kontron i.MX6 Solo SMARC Module + - ply,plybas # Plymovent BAS board - ply,plym2m # Plymovent M2M board - poslab,imx6dl-savageboard # Poslab SavageBoard Dual - prt,prtrvt # Protonic RVT board -- cgit v1.2.3 From 3069a84fd67b05a3125e80cd7e2f7ea516421137 Mon Sep 17 00:00:00 2001 From: Jernej Skrabec Date: Wed, 6 Jan 2021 19:19:00 +0100 Subject: dt-bindings: media: Add Allwinner R40 deinterlace compatible Allwinner R40 SoC also contains deinterlace core, compatible to H3. Add compatible string for it. Signed-off-by: Jernej Skrabec Signed-off-by: Maxime Ripard Link: https://lore.kernel.org/r/20210106181901.1324075-2-jernej.skrabec@siol.net --- .../devicetree/bindings/media/allwinner,sun8i-h3-deinterlace.yaml | 3 +++ 1 file changed, 3 insertions(+) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/media/allwinner,sun8i-h3-deinterlace.yaml b/Documentation/devicetree/bindings/media/allwinner,sun8i-h3-deinterlace.yaml index 6a56214c6cfd..b80980b1908e 100644 --- a/Documentation/devicetree/bindings/media/allwinner,sun8i-h3-deinterlace.yaml +++ b/Documentation/devicetree/bindings/media/allwinner,sun8i-h3-deinterlace.yaml @@ -19,6 +19,9 @@ properties: compatible: oneOf: - const: allwinner,sun8i-h3-deinterlace + - items: + - const: allwinner,sun8i-r40-deinterlace + - const: allwinner,sun8i-h3-deinterlace - items: - const: allwinner,sun50i-a64-deinterlace - const: allwinner,sun8i-h3-deinterlace -- cgit v1.2.3 From 87f2eb1b215885a25da94538345f2ddcf951318d Mon Sep 17 00:00:00 2001 From: Yongqiang Niu Date: Thu, 7 Jan 2021 11:11:12 +0800 Subject: dt-bindings: mediatek: add description for mt8183 display add description for mt8183 display Signed-off-by: Yongqiang Niu Acked-by: Rob Herring Signed-off-by: Chun-Kuang Hu --- Documentation/devicetree/bindings/display/mediatek/mediatek,disp.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,disp.txt b/Documentation/devicetree/bindings/display/mediatek/mediatek,disp.txt index 33977e15bebd..f71ed2eae3e7 100644 --- a/Documentation/devicetree/bindings/display/mediatek/mediatek,disp.txt +++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,disp.txt @@ -43,7 +43,7 @@ Required properties (all function blocks): "mediatek,-dpi" - DPI controller, see mediatek,dpi.txt "mediatek,-disp-mutex" - display mutex "mediatek,-disp-od" - overdrive - the supported chips are mt2701, mt7623, mt2712, mt8167 and mt8173. + the supported chips are mt2701, mt7623, mt2712, mt8167, mt8173 and mt8183. - reg: Physical base address and length of the function block register space - interrupts: The interrupt signal from the function block (required, except for merge and split function blocks). -- cgit v1.2.3 From fa41d10589be124404492b5181a818a509d8cb1c Mon Sep 17 00:00:00 2001 From: Matthew Gerlach Date: Wed, 6 Jan 2021 20:37:08 -0800 Subject: fpga: dfl-pci: locate DFLs by PCIe vendor specific capability A PCIe vendor specific extended capability is introduced by Intel to specify the start of a number of DFLs. Signed-off-by: Matthew Gerlach Signed-off-by: Moritz Fischer Link: https://lore.kernel.org/r/20210107043714.991646-3-mdf@kernel.org Signed-off-by: Greg Kroah-Hartman --- Documentation/fpga/dfl.rst | 27 ++++++++++++++ drivers/fpga/dfl-pci.c | 87 +++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 113 insertions(+), 1 deletion(-) (limited to 'Documentation') diff --git a/Documentation/fpga/dfl.rst b/Documentation/fpga/dfl.rst index 0404fe6ffc74..ea8cefc18bdb 100644 --- a/Documentation/fpga/dfl.rst +++ b/Documentation/fpga/dfl.rst @@ -501,6 +501,33 @@ Developer only needs to provide a sub feature driver with matched feature id. FME Partial Reconfiguration Sub Feature driver (see drivers/fpga/dfl-fme-pr.c) could be a reference. +Location of DFLs on a PCI Device +=========================== +The original method for finding a DFL on a PCI device assumed the start of the +first DFL to offset 0 of bar 0. If the first node of the DFL is an FME, +then further DFLs in the port(s) are specified in FME header registers. +Alternatively, a PCIe vendor specific capability structure can be used to +specify the location of all the DFLs on the device, providing flexibility +for the type of starting node in the DFL. Intel has reserved the +VSEC ID of 0x43 for this purpose. The vendor specific +data begins with a 4 byte vendor specific register for the number of DFLs followed 4 byte +Offset/BIR vendor specific registers for each DFL. Bits 2:0 of Offset/BIR register +indicates the BAR, and bits 31:3 form the 8 byte aligned offset where bits 2:0 are +zero. + + +----------------------------+ + |31 Number of DFLS 0| + +----------------------------+ + |31 Offset 3|2 BIR 0| + +----------------------------+ + . . . + +----------------------------+ + |31 Offset 3|2 BIR 0| + +----------------------------+ + +Being able to specify more than one DFL per BAR has been considered, but it +was determined the use case did not provide value. Specifying a single DFL +per BAR simplifies the implementation and allows for extra error checking. Open discussion =============== diff --git a/drivers/fpga/dfl-pci.c b/drivers/fpga/dfl-pci.c index 5100695e27cd..04e47e266f26 100644 --- a/drivers/fpga/dfl-pci.c +++ b/drivers/fpga/dfl-pci.c @@ -27,6 +27,14 @@ #define DRV_VERSION "0.8" #define DRV_NAME "dfl-pci" +#define PCI_VSEC_ID_INTEL_DFLS 0x43 + +#define PCI_VNDR_DFLS_CNT 0x8 +#define PCI_VNDR_DFLS_RES 0xc + +#define PCI_VNDR_DFLS_RES_BAR_MASK GENMASK(2, 0) +#define PCI_VNDR_DFLS_RES_OFF_MASK GENMASK(31, 3) + struct cci_drvdata { struct dfl_fpga_cdev *cdev; /* container device */ }; @@ -119,6 +127,80 @@ static int *cci_pci_create_irq_table(struct pci_dev *pcidev, unsigned int nvec) return table; } +static int find_dfls_by_vsec(struct pci_dev *pcidev, struct dfl_fpga_enum_info *info) +{ + u32 bir, offset, vndr_hdr, dfl_cnt, dfl_res; + int dfl_res_off, i, bars, voff = 0; + resource_size_t start, len; + + while ((voff = pci_find_next_ext_capability(pcidev, voff, PCI_EXT_CAP_ID_VNDR))) { + vndr_hdr = 0; + pci_read_config_dword(pcidev, voff + PCI_VNDR_HEADER, &vndr_hdr); + + if (PCI_VNDR_HEADER_ID(vndr_hdr) == PCI_VSEC_ID_INTEL_DFLS && + pcidev->vendor == PCI_VENDOR_ID_INTEL) + break; + } + + if (!voff) { + dev_dbg(&pcidev->dev, "%s no DFL VSEC found\n", __func__); + return -ENODEV; + } + + dfl_cnt = 0; + pci_read_config_dword(pcidev, voff + PCI_VNDR_DFLS_CNT, &dfl_cnt); + if (dfl_cnt > PCI_STD_NUM_BARS) { + dev_err(&pcidev->dev, "%s too many DFLs %d > %d\n", + __func__, dfl_cnt, PCI_STD_NUM_BARS); + return -EINVAL; + } + + dfl_res_off = voff + PCI_VNDR_DFLS_RES; + if (dfl_res_off + (dfl_cnt * sizeof(u32)) > PCI_CFG_SPACE_EXP_SIZE) { + dev_err(&pcidev->dev, "%s DFL VSEC too big for PCIe config space\n", + __func__); + return -EINVAL; + } + + for (i = 0, bars = 0; i < dfl_cnt; i++, dfl_res_off += sizeof(u32)) { + dfl_res = GENMASK(31, 0); + pci_read_config_dword(pcidev, dfl_res_off, &dfl_res); + + bir = dfl_res & PCI_VNDR_DFLS_RES_BAR_MASK; + if (bir >= PCI_STD_NUM_BARS) { + dev_err(&pcidev->dev, "%s bad bir number %d\n", + __func__, bir); + return -EINVAL; + } + + if (bars & BIT(bir)) { + dev_err(&pcidev->dev, "%s DFL for BAR %d already specified\n", + __func__, bir); + return -EINVAL; + } + + bars |= BIT(bir); + + len = pci_resource_len(pcidev, bir); + offset = dfl_res & PCI_VNDR_DFLS_RES_OFF_MASK; + if (offset >= len) { + dev_err(&pcidev->dev, "%s bad offset %u >= %pa\n", + __func__, offset, &len); + return -EINVAL; + } + + dev_dbg(&pcidev->dev, "%s BAR %d offset 0x%x\n", __func__, bir, offset); + + len -= offset; + + start = pci_resource_start(pcidev, bir) + offset; + + dfl_fpga_enum_info_add_dfl(info, start, len); + } + + return 0; +} + /* default method of finding dfls starting at offset 0 of bar 0 */ static int find_dfls_by_default(struct pci_dev *pcidev, struct dfl_fpga_enum_info *info) @@ -220,7 +302,10 @@ static int cci_enumerate_feature_devs(struct pci_dev *pcidev) goto irq_free_exit; } - ret = find_dfls_by_default(pcidev, info); + ret = find_dfls_by_vsec(pcidev, info); + if (ret == -ENODEV) + ret = find_dfls_by_default(pcidev, info); + if (ret) goto irq_free_exit; -- cgit v1.2.3 From 56172ab35338e3bb13c6bff65dea96b12e8c41ea Mon Sep 17 00:00:00 2001 From: Xu Yilun Date: Wed, 6 Jan 2021 20:37:13 -0800 Subject: fpga: dfl: add support for N3000 Nios private feature This patch adds support for the Nios handshake private feature on Intel PAC (Programmable Acceleration Card) N3000. The Nios is the embedded processor on the FPGA card. This private feature provides a handshake interface to FPGA Nios firmware, which receives retimer configuration command from host and executes via an internal SPI master (spi-altera). When Nios finishes the configuration, host takes over the ownership of the SPI master to control an Intel MAX10 BMC (Board Management Controller) Chip on the SPI bus. For Nios firmware handshake part, this driver requests the retimer configuration for Nios firmware on probe, and adds some sysfs nodes for user to query the onboard retimer's working mode and Nios firmware version. For SPI part, this driver adds a spi-altera platform device as well as the MAX10 BMC spi slave info. A spi-altera driver will be matched to handle the following SPI work. [mdf@kernel.org: Fixed up ABI doc kernel release] Reviewed-by: Tom Rix Signed-off-by: Xu Yilun Signed-off-by: Wu Hao Signed-off-by: Matthew Gerlach Signed-off-by: Russ Weight Signed-off-by: YueHaibing Link: https://lore.kernel.org/r/20210107043714.991646-8-mdf@kernel.org Signed-off-by: Greg Kroah-Hartman --- .../ABI/testing/sysfs-bus-dfl-devices-n3000-nios | 47 ++ MAINTAINERS | 2 +- drivers/fpga/Kconfig | 11 + drivers/fpga/Makefile | 2 + drivers/fpga/dfl-n3000-nios.c | 588 +++++++++++++++++++++ 5 files changed, 649 insertions(+), 1 deletion(-) create mode 100644 Documentation/ABI/testing/sysfs-bus-dfl-devices-n3000-nios create mode 100644 drivers/fpga/dfl-n3000-nios.c (limited to 'Documentation') diff --git a/Documentation/ABI/testing/sysfs-bus-dfl-devices-n3000-nios b/Documentation/ABI/testing/sysfs-bus-dfl-devices-n3000-nios new file mode 100644 index 000000000000..5335d742bcaf --- /dev/null +++ b/Documentation/ABI/testing/sysfs-bus-dfl-devices-n3000-nios @@ -0,0 +1,47 @@ +What: /sys/bus/dfl/devices/dfl_dev.X/fec_mode +Date: Oct 2020 +KernelVersion: 5.12 +Contact: Xu Yilun +Description: Read-only. Returns the FEC mode of the 25G links of the + ethernet retimers configured by Nios firmware. "rs" for Reed + Solomon FEC, "kr" for Fire Code FEC, "no" for NO FEC. + "not supported" if the FEC mode setting is not supported, this + happens when the Nios firmware version major < 3, or no link is + configured to 25G. + Format: string + +What: /sys/bus/dfl/devices/dfl_dev.X/retimer_A_mode +Date: Oct 2020 +KernelVersion: 5.12 +Contact: Xu Yilun +Description: Read-only. Returns the enumeration value of the working mode of + the retimer A configured by the Nios firmware. The value is + read out from shared registers filled by the Nios firmware. Now + the values could be: + + - "0": Reset + - "1": 4x10G + - "2": 4x25G + - "3": 2x25G + - "4": 2x25G+2x10G + - "5": 1x25G + + If the Nios firmware is updated in future to support more + retimer modes, more enumeration value is expected. + Format: 0x%x + +What: /sys/bus/dfl/devices/dfl_dev.X/retimer_B_mode +Date: Oct 2020 +KernelVersion: 5.12 +Contact: Xu Yilun +Description: Read-only. Returns the enumeration value of the working mode of + the retimer B configured by the Nios firmware. The value format + is the same as retimer_A_mode. + +What: /sys/bus/dfl/devices/dfl_dev.X/nios_fw_version +Date: Oct 2020 +KernelVersion: 5.12 +Contact: Xu Yilun +Description: Read-only. Returns the version of the Nios firmware in the + FPGA. Its format is "major.minor.patch". + Format: %x.%x.%x diff --git a/MAINTAINERS b/MAINTAINERS index a044b58eb9ac..aebb26a7d8f2 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -6954,7 +6954,7 @@ M: Wu Hao R: Tom Rix L: linux-fpga@vger.kernel.org S: Maintained -F: Documentation/ABI/testing/sysfs-bus-dfl +F: Documentation/ABI/testing/sysfs-bus-dfl* F: Documentation/fpga/dfl.rst F: drivers/fpga/dfl* F: include/linux/dfl.h diff --git a/drivers/fpga/Kconfig b/drivers/fpga/Kconfig index 5645226ca3ce..5ff9438b7b46 100644 --- a/drivers/fpga/Kconfig +++ b/drivers/fpga/Kconfig @@ -192,6 +192,17 @@ config FPGA_DFL_AFU to the FPGA infrastructure via a Port. There may be more than one Port/AFU per DFL based FPGA device. +config FPGA_DFL_NIOS_INTEL_PAC_N3000 + tristate "FPGA DFL NIOS Driver for Intel PAC N3000" + depends on FPGA_DFL + select REGMAP + help + This is the driver for the N3000 Nios private feature on Intel + PAC (Programmable Acceleration Card) N3000. It communicates + with the embedded Nios processor to configure the retimers on + the card. It also instantiates the SPI master (spi-altera) for + the card's BMC (Board Management Controller). + config FPGA_DFL_PCI tristate "FPGA DFL PCIe Device Driver" depends on PCI && FPGA_DFL diff --git a/drivers/fpga/Makefile b/drivers/fpga/Makefile index d8e21dfc6778..18dc9885883a 100644 --- a/drivers/fpga/Makefile +++ b/drivers/fpga/Makefile @@ -44,5 +44,7 @@ dfl-fme-objs += dfl-fme-perf.o dfl-afu-objs := dfl-afu-main.o dfl-afu-region.o dfl-afu-dma-region.o dfl-afu-objs += dfl-afu-error.o +obj-$(CONFIG_FPGA_DFL_NIOS_INTEL_PAC_N3000) += dfl-n3000-nios.o + # Drivers for FPGAs which implement DFL obj-$(CONFIG_FPGA_DFL_PCI) += dfl-pci.o diff --git a/drivers/fpga/dfl-n3000-nios.c b/drivers/fpga/dfl-n3000-nios.c new file mode 100644 index 000000000000..7a95366f6516 --- /dev/null +++ b/drivers/fpga/dfl-n3000-nios.c @@ -0,0 +1,588 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * DFL device driver for Nios private feature on Intel PAC (Programmable + * Acceleration Card) N3000 + * + * Copyright (C) 2019-2020 Intel Corporation, Inc. + * + * Authors: + * Wu Hao + * Xu Yilun + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* + * N3000 Nios private feature registers, named as NIOS_SPI_XX on spec. + * NS is the abbreviation of NIOS_SPI. + */ +#define N3000_NS_PARAM 0x8 +#define N3000_NS_PARAM_SHIFT_MODE_MSK BIT_ULL(1) +#define N3000_NS_PARAM_SHIFT_MODE_MSB 0 +#define N3000_NS_PARAM_SHIFT_MODE_LSB 1 +#define N3000_NS_PARAM_DATA_WIDTH GENMASK_ULL(7, 2) +#define N3000_NS_PARAM_NUM_CS GENMASK_ULL(13, 8) +#define N3000_NS_PARAM_CLK_POL BIT_ULL(14) +#define N3000_NS_PARAM_CLK_PHASE BIT_ULL(15) +#define N3000_NS_PARAM_PERIPHERAL_ID GENMASK_ULL(47, 32) + +#define N3000_NS_CTRL 0x10 +#define N3000_NS_CTRL_WR_DATA GENMASK_ULL(31, 0) +#define N3000_NS_CTRL_ADDR GENMASK_ULL(44, 32) +#define N3000_NS_CTRL_CMD_MSK GENMASK_ULL(63, 62) +#define N3000_NS_CTRL_CMD_NOP 0 +#define N3000_NS_CTRL_CMD_RD 1 +#define N3000_NS_CTRL_CMD_WR 2 + +#define N3000_NS_STAT 0x18 +#define N3000_NS_STAT_RD_DATA GENMASK_ULL(31, 0) +#define N3000_NS_STAT_RW_VAL BIT_ULL(32) + +/* Nios handshake registers, indirect access */ +#define N3000_NIOS_INIT 0x1000 +#define N3000_NIOS_INIT_DONE BIT(0) +#define N3000_NIOS_INIT_START BIT(1) +/* Mode for retimer A, link 0, the same below */ +#define N3000_NIOS_INIT_REQ_FEC_MODE_A0_MSK GENMASK(9, 8) +#define N3000_NIOS_INIT_REQ_FEC_MODE_A1_MSK GENMASK(11, 10) +#define N3000_NIOS_INIT_REQ_FEC_MODE_A2_MSK GENMASK(13, 12) +#define N3000_NIOS_INIT_REQ_FEC_MODE_A3_MSK GENMASK(15, 14) +#define N3000_NIOS_INIT_REQ_FEC_MODE_B0_MSK GENMASK(17, 16) +#define N3000_NIOS_INIT_REQ_FEC_MODE_B1_MSK GENMASK(19, 18) +#define N3000_NIOS_INIT_REQ_FEC_MODE_B2_MSK GENMASK(21, 20) +#define N3000_NIOS_INIT_REQ_FEC_MODE_B3_MSK GENMASK(23, 22) +#define N3000_NIOS_INIT_REQ_FEC_MODE_NO 0x0 +#define N3000_NIOS_INIT_REQ_FEC_MODE_KR 0x1 +#define N3000_NIOS_INIT_REQ_FEC_MODE_RS 0x2 + +#define N3000_NIOS_FW_VERSION 0x1004 +#define N3000_NIOS_FW_VERSION_PATCH GENMASK(23, 20) +#define N3000_NIOS_FW_VERSION_MINOR GENMASK(27, 24) +#define N3000_NIOS_FW_VERSION_MAJOR GENMASK(31, 28) + +/* The retimers we use on Intel PAC N3000 is Parkvale, abbreviated to PKVL */ +#define N3000_NIOS_PKVL_A_MODE_STS 0x1020 +#define N3000_NIOS_PKVL_B_MODE_STS 0x1024 +#define N3000_NIOS_PKVL_MODE_STS_GROUP_MSK GENMASK(15, 8) +#define N3000_NIOS_PKVL_MODE_STS_GROUP_OK 0x0 +#define N3000_NIOS_PKVL_MODE_STS_ID_MSK GENMASK(7, 0) +/* When GROUP MASK field == GROUP_OK */ +#define N3000_NIOS_PKVL_MODE_ID_RESET 0x0 +#define N3000_NIOS_PKVL_MODE_ID_4X10G 0x1 +#define N3000_NIOS_PKVL_MODE_ID_4X25G 0x2 +#define N3000_NIOS_PKVL_MODE_ID_2X25G 0x3 +#define N3000_NIOS_PKVL_MODE_ID_2X25G_2X10G 0x4 +#define N3000_NIOS_PKVL_MODE_ID_1X25G 0x5 + +#define N3000_NIOS_REGBUS_RETRY_COUNT 10000 /* loop count */ + +#define N3000_NIOS_INIT_TIMEOUT 10000000 /* usec */ +#define N3000_NIOS_INIT_TIME_INTV 100000 /* usec */ + +#define N3000_NIOS_INIT_REQ_FEC_MODE_MSK_ALL \ + (N3000_NIOS_INIT_REQ_FEC_MODE_A0_MSK | \ + N3000_NIOS_INIT_REQ_FEC_MODE_A1_MSK | \ + N3000_NIOS_INIT_REQ_FEC_MODE_A2_MSK | \ + N3000_NIOS_INIT_REQ_FEC_MODE_A3_MSK | \ + N3000_NIOS_INIT_REQ_FEC_MODE_B0_MSK | \ + N3000_NIOS_INIT_REQ_FEC_MODE_B1_MSK | \ + N3000_NIOS_INIT_REQ_FEC_MODE_B2_MSK | \ + N3000_NIOS_INIT_REQ_FEC_MODE_B3_MSK) + +#define N3000_NIOS_INIT_REQ_FEC_MODE_NO_ALL \ + (FIELD_PREP(N3000_NIOS_INIT_REQ_FEC_MODE_A0_MSK, \ + N3000_NIOS_INIT_REQ_FEC_MODE_NO) | \ + FIELD_PREP(N3000_NIOS_INIT_REQ_FEC_MODE_A1_MSK, \ + N3000_NIOS_INIT_REQ_FEC_MODE_NO) | \ + FIELD_PREP(N3000_NIOS_INIT_REQ_FEC_MODE_A2_MSK, \ + N3000_NIOS_INIT_REQ_FEC_MODE_NO) | \ + FIELD_PREP(N3000_NIOS_INIT_REQ_FEC_MODE_A3_MSK, \ + N3000_NIOS_INIT_REQ_FEC_MODE_NO) | \ + FIELD_PREP(N3000_NIOS_INIT_REQ_FEC_MODE_B0_MSK, \ + N3000_NIOS_INIT_REQ_FEC_MODE_NO) | \ + FIELD_PREP(N3000_NIOS_INIT_REQ_FEC_MODE_B1_MSK, \ + N3000_NIOS_INIT_REQ_FEC_MODE_NO) | \ + FIELD_PREP(N3000_NIOS_INIT_REQ_FEC_MODE_B2_MSK, \ + N3000_NIOS_INIT_REQ_FEC_MODE_NO) | \ + FIELD_PREP(N3000_NIOS_INIT_REQ_FEC_MODE_B3_MSK, \ + N3000_NIOS_INIT_REQ_FEC_MODE_NO)) + +#define N3000_NIOS_INIT_REQ_FEC_MODE_KR_ALL \ + (FIELD_PREP(N3000_NIOS_INIT_REQ_FEC_MODE_A0_MSK, \ + N3000_NIOS_INIT_REQ_FEC_MODE_KR) | \ + FIELD_PREP(N3000_NIOS_INIT_REQ_FEC_MODE_A1_MSK, \ + N3000_NIOS_INIT_REQ_FEC_MODE_KR) | \ + FIELD_PREP(N3000_NIOS_INIT_REQ_FEC_MODE_A2_MSK, \ + N3000_NIOS_INIT_REQ_FEC_MODE_KR) | \ + FIELD_PREP(N3000_NIOS_INIT_REQ_FEC_MODE_A3_MSK, \ + N3000_NIOS_INIT_REQ_FEC_MODE_KR) | \ + FIELD_PREP(N3000_NIOS_INIT_REQ_FEC_MODE_B0_MSK, \ + N3000_NIOS_INIT_REQ_FEC_MODE_KR) | \ + FIELD_PREP(N3000_NIOS_INIT_REQ_FEC_MODE_B1_MSK, \ + N3000_NIOS_INIT_REQ_FEC_MODE_KR) | \ + FIELD_PREP(N3000_NIOS_INIT_REQ_FEC_MODE_B2_MSK, \ + N3000_NIOS_INIT_REQ_FEC_MODE_KR) | \ + FIELD_PREP(N3000_NIOS_INIT_REQ_FEC_MODE_B3_MSK, \ + N3000_NIOS_INIT_REQ_FEC_MODE_KR)) + +#define N3000_NIOS_INIT_REQ_FEC_MODE_RS_ALL \ + (FIELD_PREP(N3000_NIOS_INIT_REQ_FEC_MODE_A0_MSK, \ + N3000_NIOS_INIT_REQ_FEC_MODE_RS) | \ + FIELD_PREP(N3000_NIOS_INIT_REQ_FEC_MODE_A1_MSK, \ + N3000_NIOS_INIT_REQ_FEC_MODE_RS) | \ + FIELD_PREP(N3000_NIOS_INIT_REQ_FEC_MODE_A2_MSK, \ + N3000_NIOS_INIT_REQ_FEC_MODE_RS) | \ + FIELD_PREP(N3000_NIOS_INIT_REQ_FEC_MODE_A3_MSK, \ + N3000_NIOS_INIT_REQ_FEC_MODE_RS) | \ + FIELD_PREP(N3000_NIOS_INIT_REQ_FEC_MODE_B0_MSK, \ + N3000_NIOS_INIT_REQ_FEC_MODE_RS) | \ + FIELD_PREP(N3000_NIOS_INIT_REQ_FEC_MODE_B1_MSK, \ + N3000_NIOS_INIT_REQ_FEC_MODE_RS) | \ + FIELD_PREP(N3000_NIOS_INIT_REQ_FEC_MODE_B2_MSK, \ + N3000_NIOS_INIT_REQ_FEC_MODE_RS) | \ + FIELD_PREP(N3000_NIOS_INIT_REQ_FEC_MODE_B3_MSK, \ + N3000_NIOS_INIT_REQ_FEC_MODE_RS)) + +struct n3000_nios { + void __iomem *base; + struct regmap *regmap; + struct device *dev; + struct platform_device *altera_spi; +}; + +static ssize_t nios_fw_version_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct n3000_nios *nn = dev_get_drvdata(dev); + unsigned int val; + int ret; + + ret = regmap_read(nn->regmap, N3000_NIOS_FW_VERSION, &val); + if (ret) + return ret; + + return sysfs_emit(buf, "%x.%x.%x\n", + (u8)FIELD_GET(N3000_NIOS_FW_VERSION_MAJOR, val), + (u8)FIELD_GET(N3000_NIOS_FW_VERSION_MINOR, val), + (u8)FIELD_GET(N3000_NIOS_FW_VERSION_PATCH, val)); +} +static DEVICE_ATTR_RO(nios_fw_version); + +#define IS_MODE_STATUS_OK(mode_stat) \ + (FIELD_GET(N3000_NIOS_PKVL_MODE_STS_GROUP_MSK, (mode_stat)) == \ + N3000_NIOS_PKVL_MODE_STS_GROUP_OK) + +#define IS_RETIMER_FEC_SUPPORTED(retimer_mode) \ + ((retimer_mode) != N3000_NIOS_PKVL_MODE_ID_RESET && \ + (retimer_mode) != N3000_NIOS_PKVL_MODE_ID_4X10G) + +static int get_retimer_mode(struct n3000_nios *nn, unsigned int mode_stat_reg, + unsigned int *retimer_mode) +{ + unsigned int val; + int ret; + + ret = regmap_read(nn->regmap, mode_stat_reg, &val); + if (ret) + return ret; + + if (!IS_MODE_STATUS_OK(val)) + return -EFAULT; + + *retimer_mode = FIELD_GET(N3000_NIOS_PKVL_MODE_STS_ID_MSK, val); + + return 0; +} + +static ssize_t retimer_A_mode_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct n3000_nios *nn = dev_get_drvdata(dev); + unsigned int mode; + int ret; + + ret = get_retimer_mode(nn, N3000_NIOS_PKVL_A_MODE_STS, &mode); + if (ret) + return ret; + + return sysfs_emit(buf, "0x%x\n", mode); +} +static DEVICE_ATTR_RO(retimer_A_mode); + +static ssize_t retimer_B_mode_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct n3000_nios *nn = dev_get_drvdata(dev); + unsigned int mode; + int ret; + + ret = get_retimer_mode(nn, N3000_NIOS_PKVL_B_MODE_STS, &mode); + if (ret) + return ret; + + return sysfs_emit(buf, "0x%x\n", mode); +} +static DEVICE_ATTR_RO(retimer_B_mode); + +static ssize_t fec_mode_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + unsigned int val, retimer_a_mode, retimer_b_mode, fec_modes; + struct n3000_nios *nn = dev_get_drvdata(dev); + int ret; + + /* FEC mode setting is not supported in early FW versions */ + ret = regmap_read(nn->regmap, N3000_NIOS_FW_VERSION, &val); + if (ret) + return ret; + + if (FIELD_GET(N3000_NIOS_FW_VERSION_MAJOR, val) < 3) + return sysfs_emit(buf, "not supported\n"); + + /* If no 25G links, FEC mode setting is not supported either */ + ret = get_retimer_mode(nn, N3000_NIOS_PKVL_A_MODE_STS, &retimer_a_mode); + if (ret) + return ret; + + ret = get_retimer_mode(nn, N3000_NIOS_PKVL_B_MODE_STS, &retimer_b_mode); + if (ret) + return ret; + + if (!IS_RETIMER_FEC_SUPPORTED(retimer_a_mode) && + !IS_RETIMER_FEC_SUPPORTED(retimer_b_mode)) + return sysfs_emit(buf, "not supported\n"); + + /* get the valid FEC mode for 25G links */ + ret = regmap_read(nn->regmap, N3000_NIOS_INIT, &val); + if (ret) + return ret; + + /* + * FEC mode should always be the same for all links, as we set them + * in this way. + */ + fec_modes = (val & N3000_NIOS_INIT_REQ_FEC_MODE_MSK_ALL); + if (fec_modes == N3000_NIOS_INIT_REQ_FEC_MODE_NO_ALL) + return sysfs_emit(buf, "no\n"); + else if (fec_modes == N3000_NIOS_INIT_REQ_FEC_MODE_KR_ALL) + return sysfs_emit(buf, "kr\n"); + else if (fec_modes == N3000_NIOS_INIT_REQ_FEC_MODE_RS_ALL) + return sysfs_emit(buf, "rs\n"); + + return -EFAULT; +} +static DEVICE_ATTR_RO(fec_mode); + +static struct attribute *n3000_nios_attrs[] = { + &dev_attr_nios_fw_version.attr, + &dev_attr_retimer_A_mode.attr, + &dev_attr_retimer_B_mode.attr, + &dev_attr_fec_mode.attr, + NULL, +}; +ATTRIBUTE_GROUPS(n3000_nios); + +static int n3000_nios_init_done_check(struct n3000_nios *nn) +{ + unsigned int val, state_a, state_b; + struct device *dev = nn->dev; + int ret, ret2; + + /* + * The SPI is shared by the Nios core inside the FPGA, Nios will use + * this SPI master to do some one time initialization after power up, + * and then release the control to OS. The driver needs to poll on + * INIT_DONE to see when driver could take the control. + * + * Please note that after Nios firmware version 3.0.0, INIT_START is + * introduced, so driver needs to trigger START firstly and then check + * INIT_DONE. + */ + + ret = regmap_read(nn->regmap, N3000_NIOS_FW_VERSION, &val); + if (ret) + return ret; + + /* + * If Nios version register is totally uninitialized(== 0x0), then the + * Nios firmware is missing. So host could take control of SPI master + * safely, but initialization work for Nios is not done. To restore the + * card, we need to reprogram a new Nios firmware via the BMC chip on + * SPI bus. So the driver doesn't error out, it continues to create the + * spi controller device and spi_board_info for BMC. + */ + if (val == 0) { + dev_err(dev, "Nios version reg = 0x%x, skip INIT_DONE check, but the retimer may be uninitialized\n", + val); + return 0; + } + + if (FIELD_GET(N3000_NIOS_FW_VERSION_MAJOR, val) >= 3) { + /* read NIOS_INIT to check if retimer initialization is done */ + ret = regmap_read(nn->regmap, N3000_NIOS_INIT, &val); + if (ret) + return ret; + + /* check if retimers are initialized already */ + if (val & (N3000_NIOS_INIT_DONE | N3000_NIOS_INIT_START)) + goto nios_init_done; + + /* configure FEC mode per module param */ + val = N3000_NIOS_INIT_START; + + /* + * When the retimer is to be set to 10G mode, there is no FEC + * mode setting, so the REQ_FEC_MODE field will be ignored by + * Nios firmware in this case. But we should still fill the FEC + * mode field cause host could not get the retimer working mode + * until the Nios init is done. + * + * For now the driver doesn't support the retimer FEC mode + * switching per user's request. It is always set to Reed + * Solomon FEC. + * + * The driver will set the same FEC mode for all links. + */ + val |= N3000_NIOS_INIT_REQ_FEC_MODE_RS_ALL; + + ret = regmap_write(nn->regmap, N3000_NIOS_INIT, val); + if (ret) + return ret; + } + +nios_init_done: + /* polls on NIOS_INIT_DONE */ + ret = regmap_read_poll_timeout(nn->regmap, N3000_NIOS_INIT, val, + val & N3000_NIOS_INIT_DONE, + N3000_NIOS_INIT_TIME_INTV, + N3000_NIOS_INIT_TIMEOUT); + if (ret) + dev_err(dev, "NIOS_INIT_DONE %s\n", + (ret == -ETIMEDOUT) ? "timed out" : "check error"); + + ret2 = regmap_read(nn->regmap, N3000_NIOS_PKVL_A_MODE_STS, &state_a); + if (ret2) + return ret2; + + ret2 = regmap_read(nn->regmap, N3000_NIOS_PKVL_B_MODE_STS, &state_b); + if (ret2) + return ret2; + + if (!ret) { + /* + * After INIT_DONE is detected, it still needs to check if the + * Nios firmware reports any error during the retimer + * configuration. + */ + if (IS_MODE_STATUS_OK(state_a) && IS_MODE_STATUS_OK(state_b)) + return 0; + + /* + * If the retimer configuration is failed, the Nios firmware + * will still release the spi controller for host to + * communicate with the BMC. It makes possible for people to + * reprogram a new Nios firmware and restore the card. So the + * driver doesn't error out, it continues to create the spi + * controller device and spi_board_info for BMC. + */ + dev_err(dev, "NIOS_INIT_DONE OK, but err on retimer init\n"); + } + + dev_err(nn->dev, "PKVL_A_MODE_STS 0x%x\n", state_a); + dev_err(nn->dev, "PKVL_B_MODE_STS 0x%x\n", state_b); + + return ret; +} + +static struct spi_board_info m10_n3000_info = { + .modalias = "m10-n3000", + .max_speed_hz = 12500000, + .bus_num = 0, + .chip_select = 0, +}; + +static int create_altera_spi_controller(struct n3000_nios *nn) +{ + struct altera_spi_platform_data pdata = { 0 }; + struct platform_device_info pdevinfo = { 0 }; + void __iomem *base = nn->base; + u64 v; + + v = readq(base + N3000_NS_PARAM); + + pdata.mode_bits = SPI_CS_HIGH; + if (FIELD_GET(N3000_NS_PARAM_CLK_POL, v)) + pdata.mode_bits |= SPI_CPOL; + if (FIELD_GET(N3000_NS_PARAM_CLK_PHASE, v)) + pdata.mode_bits |= SPI_CPHA; + + pdata.num_chipselect = FIELD_GET(N3000_NS_PARAM_NUM_CS, v); + pdata.bits_per_word_mask = + SPI_BPW_RANGE_MASK(1, FIELD_GET(N3000_NS_PARAM_DATA_WIDTH, v)); + + pdata.num_devices = 1; + pdata.devices = &m10_n3000_info; + + dev_dbg(nn->dev, "%s cs %u bpm 0x%x mode 0x%x\n", __func__, + pdata.num_chipselect, pdata.bits_per_word_mask, + pdata.mode_bits); + + pdevinfo.name = "subdev_spi_altera"; + pdevinfo.id = PLATFORM_DEVID_AUTO; + pdevinfo.parent = nn->dev; + pdevinfo.data = &pdata; + pdevinfo.size_data = sizeof(pdata); + + nn->altera_spi = platform_device_register_full(&pdevinfo); + return PTR_ERR_OR_ZERO(nn->altera_spi); +} + +static void destroy_altera_spi_controller(struct n3000_nios *nn) +{ + platform_device_unregister(nn->altera_spi); +} + +static int n3000_nios_poll_stat_timeout(void __iomem *base, u64 *v) +{ + int loops; + + /* + * We don't use the time based timeout here for performance. + * + * The regbus read/write is on the critical path of Intel PAC N3000 + * image programing. The time based timeout checking will add too much + * overhead on it. Usually the state changes in 1 or 2 loops on the + * test server, and we set 10000 times loop here for safety. + */ + for (loops = N3000_NIOS_REGBUS_RETRY_COUNT; loops > 0 ; loops--) { + *v = readq(base + N3000_NS_STAT); + if (*v & N3000_NS_STAT_RW_VAL) + break; + cpu_relax(); + } + + return (loops > 0) ? 0 : -ETIMEDOUT; +} + +static int n3000_nios_reg_write(void *context, unsigned int reg, unsigned int val) +{ + struct n3000_nios *nn = context; + u64 v; + int ret; + + v = FIELD_PREP(N3000_NS_CTRL_CMD_MSK, N3000_NS_CTRL_CMD_WR) | + FIELD_PREP(N3000_NS_CTRL_ADDR, reg) | + FIELD_PREP(N3000_NS_CTRL_WR_DATA, val); + writeq(v, nn->base + N3000_NS_CTRL); + + ret = n3000_nios_poll_stat_timeout(nn->base, &v); + if (ret) + dev_err(nn->dev, "fail to write reg 0x%x val 0x%x: %d\n", + reg, val, ret); + + return ret; +} + +static int n3000_nios_reg_read(void *context, unsigned int reg, unsigned int *val) +{ + struct n3000_nios *nn = context; + u64 v; + int ret; + + v = FIELD_PREP(N3000_NS_CTRL_CMD_MSK, N3000_NS_CTRL_CMD_RD) | + FIELD_PREP(N3000_NS_CTRL_ADDR, reg); + writeq(v, nn->base + N3000_NS_CTRL); + + ret = n3000_nios_poll_stat_timeout(nn->base, &v); + if (ret) + dev_err(nn->dev, "fail to read reg 0x%x: %d\n", reg, ret); + else + *val = FIELD_GET(N3000_NS_STAT_RD_DATA, v); + + return ret; +} + +static const struct regmap_config n3000_nios_regbus_cfg = { + .reg_bits = 32, + .reg_stride = 4, + .val_bits = 32, + .fast_io = true, + + .reg_write = n3000_nios_reg_write, + .reg_read = n3000_nios_reg_read, +}; + +static int n3000_nios_probe(struct dfl_device *ddev) +{ + struct device *dev = &ddev->dev; + struct n3000_nios *nn; + int ret; + + nn = devm_kzalloc(dev, sizeof(*nn), GFP_KERNEL); + if (!nn) + return -ENOMEM; + + dev_set_drvdata(&ddev->dev, nn); + + nn->dev = dev; + + nn->base = devm_ioremap_resource(&ddev->dev, &ddev->mmio_res); + if (IS_ERR(nn->base)) + return PTR_ERR(nn->base); + + nn->regmap = devm_regmap_init(dev, NULL, nn, &n3000_nios_regbus_cfg); + if (IS_ERR(nn->regmap)) + return PTR_ERR(nn->regmap); + + ret = n3000_nios_init_done_check(nn); + if (ret) + return ret; + + ret = create_altera_spi_controller(nn); + if (ret) + dev_err(dev, "altera spi controller create failed: %d\n", ret); + + return ret; +} + +static void n3000_nios_remove(struct dfl_device *ddev) +{ + struct n3000_nios *nn = dev_get_drvdata(&ddev->dev); + + destroy_altera_spi_controller(nn); +} + +#define FME_FEATURE_ID_N3000_NIOS 0xd + +static const struct dfl_device_id n3000_nios_ids[] = { + { FME_ID, FME_FEATURE_ID_N3000_NIOS }, + { } +}; +MODULE_DEVICE_TABLE(dfl, n3000_nios_ids); + +static struct dfl_driver n3000_nios_driver = { + .drv = { + .name = "dfl-n3000-nios", + .dev_groups = n3000_nios_groups, + }, + .id_table = n3000_nios_ids, + .probe = n3000_nios_probe, + .remove = n3000_nios_remove, +}; + +module_dfl_driver(n3000_nios_driver); + +MODULE_DESCRIPTION("Driver for Nios private feature on Intel PAC N3000"); +MODULE_AUTHOR("Intel Corporation"); +MODULE_LICENSE("GPL v2"); -- cgit v1.2.3 From 477dfdccfcae4665f073260446199933369cd50e Mon Sep 17 00:00:00 2001 From: Xu Yilun Date: Wed, 6 Jan 2021 20:37:14 -0800 Subject: memory: dfl-emif: add the DFL EMIF private feature driver This driver is for the EMIF private feature implemented under FPGA Device Feature List (DFL) framework. It is used to expose memory interface status information as well as memory clearing control. The purpose of memory clearing block is to zero out all private memory when FPGA is to be reprogrammed. This gives users a reliable method to prevent potential data leakage. [mdf@kernel.org: Fixed up ABI doc] Reviewed-by: Tom Rix Acked-by: Krzysztof Kozlowski Signed-off-by: Xu Yilun Signed-off-by: Russ Weight Link: https://lore.kernel.org/r/20210107043714.991646-9-mdf@kernel.org Signed-off-by: Greg Kroah-Hartman --- .../ABI/testing/sysfs-bus-dfl-devices-emif | 25 +++ drivers/memory/Kconfig | 9 + drivers/memory/Makefile | 2 + drivers/memory/dfl-emif.c | 207 +++++++++++++++++++++ 4 files changed, 243 insertions(+) create mode 100644 Documentation/ABI/testing/sysfs-bus-dfl-devices-emif create mode 100644 drivers/memory/dfl-emif.c (limited to 'Documentation') diff --git a/Documentation/ABI/testing/sysfs-bus-dfl-devices-emif b/Documentation/ABI/testing/sysfs-bus-dfl-devices-emif new file mode 100644 index 000000000000..817d14126d4d --- /dev/null +++ b/Documentation/ABI/testing/sysfs-bus-dfl-devices-emif @@ -0,0 +1,25 @@ +What: /sys/bus/dfl/devices/dfl_dev.X/infX_cal_fail +Date: Oct 2020 +KernelVersion: 5.12 +Contact: Xu Yilun +Description: Read-only. It indicates if the calibration failed on this + memory interface. "1" for calibration failure, "0" for OK. + Format: %u + +What: /sys/bus/dfl/devices/dfl_dev.X/infX_init_done +Date: Oct 2020 +KernelVersion: 5.12 +Contact: Xu Yilun +Description: Read-only. It indicates if the initialization completed on + this memory interface. "1" for initialization complete, "0" + for not yet. + Format: %u + +What: /sys/bus/dfl/devices/dfl_dev.X/infX_clear +Date: Oct 2020 +KernelVersion: 5.12 +Contact: Xu Yilun +Description: Write-only. Writing "1" to this file will zero out all memory + data in this memory interface. Writing of other values is + invalid. + Format: %u diff --git a/drivers/memory/Kconfig b/drivers/memory/Kconfig index 3ea6913df176..3c9a9882ef28 100644 --- a/drivers/memory/Kconfig +++ b/drivers/memory/Kconfig @@ -137,6 +137,15 @@ config TI_EMIF_SRAM sequence so this driver provides several relocatable PM functions for the SoC PM code to use. +config FPGA_DFL_EMIF + tristate "FPGA DFL EMIF Driver" + depends on FPGA_DFL && HAS_IOMEM + help + This driver is for the EMIF private feature implemented under + FPGA Device Feature List (DFL) framework. It is used to expose + memory interface status information as well as memory clearing + control. + config MVEBU_DEVBUS bool "Marvell EBU Device Bus Controller" default y if PLAT_ORION diff --git a/drivers/memory/Makefile b/drivers/memory/Makefile index e71cf7b99641..bc7663ed1c25 100644 --- a/drivers/memory/Makefile +++ b/drivers/memory/Makefile @@ -28,6 +28,8 @@ obj-$(CONFIG_STM32_FMC2_EBI) += stm32-fmc2-ebi.o obj-$(CONFIG_SAMSUNG_MC) += samsung/ obj-$(CONFIG_TEGRA_MC) += tegra/ obj-$(CONFIG_TI_EMIF_SRAM) += ti-emif-sram.o +obj-$(CONFIG_FPGA_DFL_EMIF) += dfl-emif.o + ti-emif-sram-objs := ti-emif-pm.o ti-emif-sram-pm.o AFLAGS_ti-emif-sram-pm.o :=-Wa,-march=armv7-a diff --git a/drivers/memory/dfl-emif.c b/drivers/memory/dfl-emif.c new file mode 100644 index 000000000000..3f719816771d --- /dev/null +++ b/drivers/memory/dfl-emif.c @@ -0,0 +1,207 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * DFL device driver for EMIF private feature + * + * Copyright (C) 2020 Intel Corporation, Inc. + * + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define FME_FEATURE_ID_EMIF 0x9 + +#define EMIF_STAT 0x8 +#define EMIF_STAT_INIT_DONE_SFT 0 +#define EMIF_STAT_CALC_FAIL_SFT 8 +#define EMIF_STAT_CLEAR_BUSY_SFT 16 +#define EMIF_CTRL 0x10 +#define EMIF_CTRL_CLEAR_EN_SFT 0 +#define EMIF_CTRL_CLEAR_EN_MSK GENMASK_ULL(3, 0) + +#define EMIF_POLL_INVL 10000 /* us */ +#define EMIF_POLL_TIMEOUT 5000000 /* us */ + +struct dfl_emif { + struct device *dev; + void __iomem *base; + spinlock_t lock; /* Serialises access to EMIF_CTRL reg */ +}; + +struct emif_attr { + struct device_attribute attr; + u32 shift; + u32 index; +}; + +#define to_emif_attr(dev_attr) \ + container_of(dev_attr, struct emif_attr, attr) + +static ssize_t emif_state_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct emif_attr *eattr = to_emif_attr(attr); + struct dfl_emif *de = dev_get_drvdata(dev); + u64 val; + + val = readq(de->base + EMIF_STAT); + + return sysfs_emit(buf, "%u\n", + !!(val & BIT_ULL(eattr->shift + eattr->index))); +} + +static ssize_t emif_clear_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct emif_attr *eattr = to_emif_attr(attr); + struct dfl_emif *de = dev_get_drvdata(dev); + u64 clear_busy_msk, clear_en_msk, val; + void __iomem *base = de->base; + + if (!sysfs_streq(buf, "1")) + return -EINVAL; + + clear_busy_msk = BIT_ULL(EMIF_STAT_CLEAR_BUSY_SFT + eattr->index); + clear_en_msk = BIT_ULL(EMIF_CTRL_CLEAR_EN_SFT + eattr->index); + + spin_lock(&de->lock); + /* The CLEAR_EN field is WO, but other fields are RW */ + val = readq(base + EMIF_CTRL); + val &= ~EMIF_CTRL_CLEAR_EN_MSK; + val |= clear_en_msk; + writeq(val, base + EMIF_CTRL); + spin_unlock(&de->lock); + + if (readq_poll_timeout(base + EMIF_STAT, val, + !(val & clear_busy_msk), + EMIF_POLL_INVL, EMIF_POLL_TIMEOUT)) { + dev_err(de->dev, "timeout, fail to clear\n"); + return -ETIMEDOUT; + } + + return count; +} + +#define emif_state_attr(_name, _shift, _index) \ + static struct emif_attr emif_attr_##inf##_index##_##_name = \ + { .attr = __ATTR(inf##_index##_##_name, 0444, \ + emif_state_show, NULL), \ + .shift = (_shift), .index = (_index) } + +#define emif_clear_attr(_index) \ + static struct emif_attr emif_attr_##inf##_index##_clear = \ + { .attr = __ATTR(inf##_index##_clear, 0200, \ + NULL, emif_clear_store), \ + .index = (_index) } + +emif_state_attr(init_done, EMIF_STAT_INIT_DONE_SFT, 0); +emif_state_attr(init_done, EMIF_STAT_INIT_DONE_SFT, 1); +emif_state_attr(init_done, EMIF_STAT_INIT_DONE_SFT, 2); +emif_state_attr(init_done, EMIF_STAT_INIT_DONE_SFT, 3); + +emif_state_attr(cal_fail, EMIF_STAT_CALC_FAIL_SFT, 0); +emif_state_attr(cal_fail, EMIF_STAT_CALC_FAIL_SFT, 1); +emif_state_attr(cal_fail, EMIF_STAT_CALC_FAIL_SFT, 2); +emif_state_attr(cal_fail, EMIF_STAT_CALC_FAIL_SFT, 3); + +emif_clear_attr(0); +emif_clear_attr(1); +emif_clear_attr(2); +emif_clear_attr(3); + +static struct attribute *dfl_emif_attrs[] = { + &emif_attr_inf0_init_done.attr.attr, + &emif_attr_inf0_cal_fail.attr.attr, + &emif_attr_inf0_clear.attr.attr, + + &emif_attr_inf1_init_done.attr.attr, + &emif_attr_inf1_cal_fail.attr.attr, + &emif_attr_inf1_clear.attr.attr, + + &emif_attr_inf2_init_done.attr.attr, + &emif_attr_inf2_cal_fail.attr.attr, + &emif_attr_inf2_clear.attr.attr, + + &emif_attr_inf3_init_done.attr.attr, + &emif_attr_inf3_cal_fail.attr.attr, + &emif_attr_inf3_clear.attr.attr, + + NULL, +}; + +static umode_t dfl_emif_visible(struct kobject *kobj, + struct attribute *attr, int n) +{ + struct dfl_emif *de = dev_get_drvdata(kobj_to_dev(kobj)); + struct emif_attr *eattr = container_of(attr, struct emif_attr, + attr.attr); + u64 val; + + /* + * This device supports upto 4 memory interfaces, but not all + * interfaces are used on different platforms. The read out value of + * CLEAN_EN field (which is a bitmap) could tell how many interfaces + * are available. + */ + val = FIELD_GET(EMIF_CTRL_CLEAR_EN_MSK, readq(de->base + EMIF_CTRL)); + + return (val & BIT_ULL(eattr->index)) ? attr->mode : 0; +} + +static const struct attribute_group dfl_emif_group = { + .is_visible = dfl_emif_visible, + .attrs = dfl_emif_attrs, +}; + +static const struct attribute_group *dfl_emif_groups[] = { + &dfl_emif_group, + NULL, +}; + +static int dfl_emif_probe(struct dfl_device *ddev) +{ + struct device *dev = &ddev->dev; + struct dfl_emif *de; + + de = devm_kzalloc(dev, sizeof(*de), GFP_KERNEL); + if (!de) + return -ENOMEM; + + de->base = devm_ioremap_resource(dev, &ddev->mmio_res); + if (IS_ERR(de->base)) + return PTR_ERR(de->base); + + de->dev = dev; + spin_lock_init(&de->lock); + dev_set_drvdata(dev, de); + + return 0; +} + +static const struct dfl_device_id dfl_emif_ids[] = { + { FME_ID, FME_FEATURE_ID_EMIF }, + { } +}; +MODULE_DEVICE_TABLE(dfl, dfl_emif_ids); + +static struct dfl_driver dfl_emif_driver = { + .drv = { + .name = "dfl-emif", + .dev_groups = dfl_emif_groups, + }, + .id_table = dfl_emif_ids, + .probe = dfl_emif_probe, +}; +module_dfl_driver(dfl_emif_driver); + +MODULE_DESCRIPTION("DFL EMIF driver"); +MODULE_AUTHOR("Intel Corporation"); +MODULE_LICENSE("GPL v2"); -- cgit v1.2.3 From 0bc1bd092af3c7c0b025ece93c3a86916f89f3ca Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Tue, 5 Jan 2021 13:02:38 +0100 Subject: tty_port: drop last traces of low_latency The main purpose of tty_port::low_latency was removed in commit a9c3f68f3cd8 (tty: Fix low_latency BUG) back in 2014. It was left in place for drivers as an optional tune knob. But only one driver has been using it until the previous commit. So remove this misconcept completely, given there are no users. Signed-off-by: Jiri Slaby Link: https://lore.kernel.org/r/20210105120239.28031-11-jslaby@suse.cz Signed-off-by: Greg Kroah-Hartman --- Documentation/networking/caif/caif.rst | 1 - drivers/char/pcmcia/synclink_cs.c | 2 -- drivers/net/caif/caif_serial.c | 3 +-- drivers/s390/char/con3215.c | 1 - drivers/s390/char/sclp_tty.c | 1 - drivers/s390/char/sclp_vt220.c | 1 - drivers/s390/char/tty3270.c | 2 -- drivers/tty/amiserial.c | 3 --- drivers/tty/hvc/hvcs.c | 2 +- drivers/tty/ipwireless/tty.c | 1 - drivers/tty/mxser.c | 1 - drivers/tty/serial/ifx6x60.c | 3 --- drivers/tty/serial/max3100.c | 3 --- drivers/tty/serial/serial_core.c | 3 --- drivers/tty/synclink_gt.c | 1 - include/linux/tty.h | 3 +-- 16 files changed, 3 insertions(+), 28 deletions(-) (limited to 'Documentation') diff --git a/Documentation/networking/caif/caif.rst b/Documentation/networking/caif/caif.rst index a07213030ccf..81a14373d780 100644 --- a/Documentation/networking/caif/caif.rst +++ b/Documentation/networking/caif/caif.rst @@ -68,7 +68,6 @@ There are debugfs parameters provided for serial communication. * tty_status: Prints the bit-mask tty status information - 0x01 - tty->warned is on. - - 0x02 - tty->low_latency is on. - 0x04 - tty->packed is on. - 0x08 - tty->flow_stopped is on. - 0x10 - tty->hw_stopped is on. diff --git a/drivers/char/pcmcia/synclink_cs.c b/drivers/char/pcmcia/synclink_cs.c index e342daa73d1b..2be8d9a8eec5 100644 --- a/drivers/char/pcmcia/synclink_cs.c +++ b/drivers/char/pcmcia/synclink_cs.c @@ -2494,8 +2494,6 @@ static int mgslpc_open(struct tty_struct *tty, struct file * filp) printk("%s(%d):mgslpc_open(%s), old ref count = %d\n", __FILE__, __LINE__, tty->driver->name, port->count); - port->low_latency = (port->flags & ASYNC_LOW_LATENCY) ? 1 : 0; - spin_lock_irqsave(&info->netlock, flags); if (info->netcount) { retval = -EBUSY; diff --git a/drivers/net/caif/caif_serial.c b/drivers/net/caif/caif_serial.c index bcc14c5875bf..8215cd77301f 100644 --- a/drivers/net/caif/caif_serial.c +++ b/drivers/net/caif/caif_serial.c @@ -89,8 +89,7 @@ static inline void update_tty_status(struct ser_device *ser) ser->tty_status = ser->tty->stopped << 5 | ser->tty->flow_stopped << 3 | - ser->tty->packet << 2 | - ser->tty->port->low_latency << 1; + ser->tty->packet << 2; } static inline void debugfs_init(struct ser_device *ser, struct tty_struct *tty) { diff --git a/drivers/s390/char/con3215.c b/drivers/s390/char/con3215.c index 1354c42d95aa..671efee612af 100644 --- a/drivers/s390/char/con3215.c +++ b/drivers/s390/char/con3215.c @@ -914,7 +914,6 @@ static int tty3215_open(struct tty_struct *tty, struct file * filp) tty_port_tty_set(&raw->port, tty); - raw->port.low_latency = 0; /* don't use bottom half for pushing chars */ /* * Start up 3215 device */ diff --git a/drivers/s390/char/sclp_tty.c b/drivers/s390/char/sclp_tty.c index 5aff8b684eb2..013bcc331305 100644 --- a/drivers/s390/char/sclp_tty.c +++ b/drivers/s390/char/sclp_tty.c @@ -65,7 +65,6 @@ sclp_tty_open(struct tty_struct *tty, struct file *filp) { tty_port_tty_set(&sclp_port, tty); tty->driver_data = NULL; - sclp_port.low_latency = 0; return 0; } diff --git a/drivers/s390/char/sclp_vt220.c b/drivers/s390/char/sclp_vt220.c index 3f9a6ef650fa..047f812d1a1c 100644 --- a/drivers/s390/char/sclp_vt220.c +++ b/drivers/s390/char/sclp_vt220.c @@ -560,7 +560,6 @@ sclp_vt220_open(struct tty_struct *tty, struct file *filp) { if (tty->count == 1) { tty_port_tty_set(&sclp_vt220_port, tty); - sclp_vt220_port.low_latency = 0; if (!tty->winsize.ws_row && !tty->winsize.ws_col) { tty->winsize.ws_row = 24; tty->winsize.ws_col = 80; diff --git a/drivers/s390/char/tty3270.c b/drivers/s390/char/tty3270.c index aec996de44d9..15692449a1c3 100644 --- a/drivers/s390/char/tty3270.c +++ b/drivers/s390/char/tty3270.c @@ -967,7 +967,6 @@ static int tty3270_install(struct tty_driver *driver, struct tty_struct *tty) tty->driver_data = tp; tty->winsize.ws_row = tp->view.rows - 2; tty->winsize.ws_col = tp->view.cols; - tp->port.low_latency = 0; tp->inattr = TF_INPUT; goto port_install; } @@ -996,7 +995,6 @@ static int tty3270_install(struct tty_driver *driver, struct tty_struct *tty) return rc; } - tp->port.low_latency = 0; tty->winsize.ws_row = tp->view.rows - 2; tty->winsize.ws_col = tp->view.cols; diff --git a/drivers/tty/amiserial.c b/drivers/tty/amiserial.c index 13f63c01c589..18b78ea110ef 100644 --- a/drivers/tty/amiserial.c +++ b/drivers/tty/amiserial.c @@ -998,7 +998,6 @@ static int set_serial_info(struct tty_struct *tty, struct serial_struct *ss) state->custom_divisor = ss->custom_divisor; port->close_delay = ss->close_delay * HZ/100; port->closing_wait = ss->closing_wait * HZ/100; - port->low_latency = (port->flags & ASYNC_LOW_LATENCY) ? 1 : 0; check_and_exit: if (tty_port_initialized(port)) { @@ -1386,8 +1385,6 @@ static int rs_open(struct tty_struct *tty, struct file * filp) tty->driver_data = info; tty->port = port; - port->low_latency = (port->flags & ASYNC_LOW_LATENCY) ? 1 : 0; - retval = startup(tty, info); if (retval) { return retval; diff --git a/drivers/tty/hvc/hvcs.c b/drivers/tty/hvc/hvcs.c index 509d1042825a..dfe02283ed23 100644 --- a/drivers/tty/hvc/hvcs.c +++ b/drivers/tty/hvc/hvcs.c @@ -605,7 +605,7 @@ static int hvcs_io(struct hvcs_struct *hvcsd) hvcsd->todo_mask |= HVCS_QUICK_READ; spin_unlock_irqrestore(&hvcsd->lock, flags); - /* This is synch because tty->low_latency == 1 */ + /* This is synch -- FIXME :js: it is not! */ if(got) tty_flip_buffer_push(&hvcsd->port); diff --git a/drivers/tty/ipwireless/tty.c b/drivers/tty/ipwireless/tty.c index 23584769fc29..6dacbc5e286c 100644 --- a/drivers/tty/ipwireless/tty.c +++ b/drivers/tty/ipwireless/tty.c @@ -101,7 +101,6 @@ static int ipw_open(struct tty_struct *linux_tty, struct file *filp) tty->port.tty = linux_tty; linux_tty->driver_data = tty; - tty->port.low_latency = 1; if (tty->tty_type == TTYTYPE_MODEM) ipwireless_ppp_open(tty->network); diff --git a/drivers/tty/mxser.c b/drivers/tty/mxser.c index 3703987c4666..4203b64bccdb 100644 --- a/drivers/tty/mxser.c +++ b/drivers/tty/mxser.c @@ -1273,7 +1273,6 @@ static int mxser_set_serial_info(struct tty_struct *tty, (ss->flags & ASYNC_FLAGS)); port->close_delay = ss->close_delay * HZ / 100; port->closing_wait = ss->closing_wait * HZ / 100; - port->low_latency = (port->flags & ASYNC_LOW_LATENCY) ? 1 : 0; if ((port->flags & ASYNC_SPD_MASK) == ASYNC_SPD_CUST && (ss->baud_base != info->baud_base || ss->custom_divisor != diff --git a/drivers/tty/serial/ifx6x60.c b/drivers/tty/serial/ifx6x60.c index 182e0ccd60b2..d4ef88ee22d0 100644 --- a/drivers/tty/serial/ifx6x60.c +++ b/drivers/tty/serial/ifx6x60.c @@ -565,9 +565,6 @@ static int ifx_port_activate(struct tty_port *port, struct tty_struct *tty) /* put port data into this tty */ tty->driver_data = ifx_dev; - /* allows flip string push from int context */ - port->low_latency = 1; - /* set flag to allows data transfer */ set_bit(IFX_SPI_STATE_IO_AVAILABLE, &ifx_dev->flags); diff --git a/drivers/tty/serial/max3100.c b/drivers/tty/serial/max3100.c index 371569a0fd00..3c92d4e01488 100644 --- a/drivers/tty/serial/max3100.c +++ b/drivers/tty/serial/max3100.c @@ -521,9 +521,6 @@ max3100_set_termios(struct uart_port *port, struct ktermios *termios, MAX3100_STATUS_PE | MAX3100_STATUS_FE | MAX3100_STATUS_OE; - /* we are sending char from a workqueue so enable */ - s->port.state->port.low_latency = 1; - if (s->poll_time > 0) del_timer_sync(&s->timer); diff --git a/drivers/tty/serial/serial_core.c b/drivers/tty/serial/serial_core.c index 828f9ad1be49..7dacdb6a8534 100644 --- a/drivers/tty/serial/serial_core.c +++ b/drivers/tty/serial/serial_core.c @@ -975,7 +975,6 @@ static int uart_set_info(struct tty_struct *tty, struct tty_port *port, port->closing_wait = closing_wait; if (new_info->xmit_fifo_size) uport->fifosize = new_info->xmit_fifo_size; - port->low_latency = (uport->flags & UPF_LOW_LATENCY) ? 1 : 0; check_and_exit: retval = 0; @@ -1795,8 +1794,6 @@ static int uart_port_activate(struct tty_port *port, struct tty_struct *tty) if (!uport || uport->flags & UPF_DEAD) return -ENXIO; - port->low_latency = (uport->flags & UPF_LOW_LATENCY) ? 1 : 0; - /* * Start up the serial port. */ diff --git a/drivers/tty/synclink_gt.c b/drivers/tty/synclink_gt.c index c0b384e3ed4d..644173786bf0 100644 --- a/drivers/tty/synclink_gt.c +++ b/drivers/tty/synclink_gt.c @@ -672,7 +672,6 @@ static int open(struct tty_struct *tty, struct file *filp) DBGINFO(("%s open, old ref count = %d\n", info->device_name, info->port.count)); mutex_lock(&info->port.mutex); - info->port.low_latency = (info->port.flags & ASYNC_LOW_LATENCY) ? 1 : 0; spin_lock_irqsave(&info->netlock, flags); if (info->netcount) { diff --git a/include/linux/tty.h b/include/linux/tty.h index 12be8b16cdef..b57f6812b3ba 100644 --- a/include/linux/tty.h +++ b/include/linux/tty.h @@ -240,8 +240,7 @@ struct tty_port { wait_queue_head_t delta_msr_wait; /* Modem status change */ unsigned long flags; /* User TTY flags ASYNC_ */ unsigned long iflags; /* Internal flags TTY_PORT_ */ - unsigned char console:1, /* port is a console */ - low_latency:1; /* optional: tune for latency */ + unsigned char console:1; /* port is a console */ struct mutex mutex; /* Locking */ struct mutex buf_mutex; /* Buffer alloc lock */ unsigned char *xmit_buf; /* Optional buffer */ -- cgit v1.2.3 From 9ba8377c3aadf4dba94da1e9f98faad2eb72737d Mon Sep 17 00:00:00 2001 From: Erwan Le Ray Date: Wed, 6 Jan 2021 17:22:00 +0100 Subject: dt-bindings: serial: stm32: update rts-gpios and cts-gpios Update rts-gpios and cts-gpios: - remove max-items as already defined in serial.yaml - add a note describing rts-gpios and cts-gpios usage with stm32 Document the use of cts-gpios and rts-gpios for flow control in STM32 UART controller. These properties can be used instead of 'uart-has-rtscts' or 'st,hw-flow-ctrl' (deprecated) for making use of any gpio pins for flow control instead of dedicated pins. It should be noted that both cts-gpios/rts-gpios and 'uart-has-rtscts' or 'st,hw-flow-ctrl' (deprecated) properties cannot co-exist in a design. Acked-by: Rob Herring Signed-off-by: Erwan Le Ray Link: https://lore.kernel.org/r/20210106162203.28854-6-erwan.leray@foss.st.com Signed-off-by: Greg Kroah-Hartman --- Documentation/devicetree/bindings/serial/st,stm32-uart.yaml | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/serial/st,stm32-uart.yaml b/Documentation/devicetree/bindings/serial/st,stm32-uart.yaml index 06d5f251ec88..8631678283f9 100644 --- a/Documentation/devicetree/bindings/serial/st,stm32-uart.yaml +++ b/Documentation/devicetree/bindings/serial/st,stm32-uart.yaml @@ -50,11 +50,14 @@ properties: minItems: 1 maxItems: 2 - cts-gpios: - maxItems: 1 - - rts-gpios: - maxItems: 1 +# cts-gpios and rts-gpios properties can be used instead of 'uart-has-rtscts' +# or 'st,hw-flow-ctrl' (deprecated) for making use of any gpio pins for flow +# control instead of dedicated pins. +# +# It should be noted that both cts-gpios/rts-gpios and 'uart-has-rtscts' or +# 'st,hw-flow-ctrl' (deprecated) properties cannot co-exist in a design. + cts-gpios: true + rts-gpios: true wakeup-source: true -- cgit v1.2.3 From eea0b4e213232b28a25de5b88af9e25667e8d2f2 Mon Sep 17 00:00:00 2001 From: Claudiu Beznea Date: Thu, 7 Jan 2021 16:15:25 +0200 Subject: regulator: mcp16502: document lpm as optional Document LPM pin as optional. Signed-off-by: Claudiu Beznea Link: https://lore.kernel.org/r/1610028927-9842-2-git-send-email-claudiu.beznea@microchip.com Signed-off-by: Mark Brown --- Documentation/devicetree/bindings/regulator/mcp16502-regulator.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/regulator/mcp16502-regulator.txt b/Documentation/devicetree/bindings/regulator/mcp16502-regulator.txt index d86584ed4d93..451cc4e86b01 100644 --- a/Documentation/devicetree/bindings/regulator/mcp16502-regulator.txt +++ b/Documentation/devicetree/bindings/regulator/mcp16502-regulator.txt @@ -4,7 +4,8 @@ Required properties: - compatible: "microchip,mcp16502" - reg: I2C slave address - lpm-gpios: GPIO for LPM pin. Note that this GPIO *must* remain high during - suspend-to-ram, keeping the PMIC into HIBERNATE mode. + suspend-to-ram, keeping the PMIC into HIBERNATE mode; this + property is optional; - regulators: A node that houses a sub-node for each regulator within the device. Each sub-node is identified using the node's name. The content of each sub-node is defined by the -- cgit v1.2.3 From a1cd0d4d8678c3e7afda7819597fc4d3fb886f9e Mon Sep 17 00:00:00 2001 From: Stephan Gerhold Date: Wed, 6 Jan 2021 11:21:32 +0100 Subject: dt-bindings: remoteproc: qcom,wcnss: Add qcom,wcn3660b compatible WCN3660B is a variant of WCN3660, but with the same regulator requirements as WCN3620/WCN3680. Add a new qcom,wcn3660b compatible to describe it from device trees. Signed-off-by: Stephan Gerhold Link: https://lore.kernel.org/r/20210106102134.59801-2-stephan@gerhold.net Signed-off-by: Bjorn Andersson --- Documentation/devicetree/bindings/remoteproc/qcom,wcnss-pil.txt | 1 + 1 file changed, 1 insertion(+) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/remoteproc/qcom,wcnss-pil.txt b/Documentation/devicetree/bindings/remoteproc/qcom,wcnss-pil.txt index cc0b7fc1c29b..da09c0d79ac0 100644 --- a/Documentation/devicetree/bindings/remoteproc/qcom,wcnss-pil.txt +++ b/Documentation/devicetree/bindings/remoteproc/qcom,wcnss-pil.txt @@ -80,6 +80,7 @@ and its resource dependencies. It is described by the following properties: Definition: must be one of: "qcom,wcn3620", "qcom,wcn3660", + "qcom,wcn3660b", "qcom,wcn3680" - clocks: -- cgit v1.2.3 From 6b5903f58df44d4cb35319555b974d6a10f1b03f Mon Sep 17 00:00:00 2001 From: Martin Blumenstingl Date: Wed, 6 Jan 2021 14:42:47 +0100 Subject: dt-bindings: net: dwmac-meson: use picoseconds for the RGMII RX delay Amlogic Meson G12A, G12B and SM1 SoCs have a more advanced RGMII RX delay register which allows picoseconds precision. Deprecate the old "amlogic,rx-delay-ns" in favour of the generic "rx-internal-delay-ps" property. For older SoCs the only known supported values were 0ns and 2ns. The new SoCs have support for RGMII RX delays between 0ps and 3000ps in 200ps steps. Don't carry over the description for the "rx-internal-delay-ps" property and inherit that from ethernet-controller.yaml instead. Reviewed-by: Florian Fainelli Signed-off-by: Martin Blumenstingl Signed-off-by: Jakub Kicinski --- .../bindings/net/amlogic,meson-dwmac.yaml | 55 +++++++++++++++++++--- 1 file changed, 49 insertions(+), 6 deletions(-) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/net/amlogic,meson-dwmac.yaml b/Documentation/devicetree/bindings/net/amlogic,meson-dwmac.yaml index 1f133f4a2924..0467441d7037 100644 --- a/Documentation/devicetree/bindings/net/amlogic,meson-dwmac.yaml +++ b/Documentation/devicetree/bindings/net/amlogic,meson-dwmac.yaml @@ -74,17 +74,60 @@ allOf: Any configuration is ignored when the phy-mode is set to "rmii". amlogic,rx-delay-ns: + deprecated: true enum: - 0 - 2 default: 0 description: - The internal RGMII RX clock delay (provided by this IP block) in - nanoseconds. When phy-mode is set to "rgmii" then the RX delay - should be explicitly configured. When the phy-mode is set to - either "rgmii-id" or "rgmii-rxid" the RX clock delay is already - provided by the PHY. Any configuration is ignored when the - phy-mode is set to "rmii". + The internal RGMII RX clock delay in nanoseconds. Deprecated, use + rx-internal-delay-ps instead. + + rx-internal-delay-ps: + default: 0 + + - if: + properties: + compatible: + contains: + enum: + - amlogic,meson8b-dwmac + - amlogic,meson8m2-dwmac + - amlogic,meson-gxbb-dwmac + - amlogic,meson-axg-dwmac + then: + properties: + rx-internal-delay-ps: + enum: + - 0 + - 2000 + + - if: + properties: + compatible: + contains: + enum: + - amlogic,meson-g12a-dwmac + then: + properties: + rx-internal-delay-ps: + enum: + - 0 + - 200 + - 400 + - 600 + - 800 + - 1000 + - 1200 + - 1400 + - 1600 + - 1800 + - 2000 + - 2200 + - 2400 + - 2600 + - 2800 + - 3000 properties: compatible: -- cgit v1.2.3 From af951c3a113bc2cc0419e39f5752ca77f7ddf228 Mon Sep 17 00:00:00 2001 From: Yash Shah Date: Thu, 10 Dec 2020 15:58:02 +0530 Subject: dt-bindings: riscv: Update l2 cache DT documentation to add support for SiFive FU740 The L2 cache controller in SiFive FU740 has 4 ECC interrupt sources as compared to 3 in FU540. Update the DT documentation accordingly with "compatible" and "interrupt" property changes. Signed-off-by: Yash Shah Signed-off-by: Palmer Dabbelt --- .../devicetree/bindings/riscv/sifive-l2-cache.yaml | 34 +++++++++++++++++++--- 1 file changed, 30 insertions(+), 4 deletions(-) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/riscv/sifive-l2-cache.yaml b/Documentation/devicetree/bindings/riscv/sifive-l2-cache.yaml index efc0198eeb74..6a576dce1f31 100644 --- a/Documentation/devicetree/bindings/riscv/sifive-l2-cache.yaml +++ b/Documentation/devicetree/bindings/riscv/sifive-l2-cache.yaml @@ -27,6 +27,7 @@ select: items: - enum: - sifive,fu540-c000-ccache + - sifive,fu740-c000-ccache required: - compatible @@ -34,7 +35,9 @@ select: properties: compatible: items: - - const: sifive,fu540-c000-ccache + - enum: + - sifive,fu540-c000-ccache + - sifive,fu740-c000-ccache - const: cache cache-block-size: @@ -52,10 +55,13 @@ properties: cache-unified: true interrupts: - description: | - Must contain entries for DirError, DataError and DataFail signals. minItems: 3 - maxItems: 3 + maxItems: 4 + items: + - description: DirError interrupt + - description: DataError interrupt + - description: DataFail interrupt + - description: DirFail interrupt reg: maxItems: 1 @@ -67,6 +73,26 @@ properties: The reference to the reserved-memory for the L2 Loosely Integrated Memory region. The reserved memory node should be defined as per the bindings in reserved-memory.txt. +if: + properties: + compatible: + contains: + const: sifive,fu540-c000-ccache + +then: + properties: + interrupts: + description: | + Must contain entries for DirError, DataError and DataFail signals. + maxItems: 3 + +else: + properties: + interrupts: + description: | + Must contain entries for DirError, DataError, DataFail, DirFail signals. + minItems: 4 + additionalProperties: false required: -- cgit v1.2.3 From 75e6d7248efccc2b13d0f3811b29d3e5cb04bcad Mon Sep 17 00:00:00 2001 From: Yash Shah Date: Tue, 8 Dec 2020 10:25:33 +0530 Subject: dt-bindings: riscv: Update DT binding docs to support SiFive FU740 SoC Add new compatible strings in cpus.yaml to support the E71 and U74 CPU cores ("harts") that are present on FU740-C000 SoC. Signed-off-by: Yash Shah Signed-off-by: Palmer Dabbelt --- Documentation/devicetree/bindings/riscv/cpus.yaml | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/riscv/cpus.yaml b/Documentation/devicetree/bindings/riscv/cpus.yaml index c6925e0b16e4..eb6843f69f7c 100644 --- a/Documentation/devicetree/bindings/riscv/cpus.yaml +++ b/Documentation/devicetree/bindings/riscv/cpus.yaml @@ -28,11 +28,17 @@ properties: - items: - enum: - sifive,rocket0 + - sifive,bullet0 - sifive,e5 + - sifive,e7 - sifive,e51 + - sifive,e71 - sifive,u54-mc + - sifive,u74-mc - sifive,u54 + - sifive,u74 - sifive,u5 + - sifive,u7 - const: riscv - const: riscv # Simulator only description: -- cgit v1.2.3 From b1f592d5c1e31dfa46a161c52740f3bff1b1e963 Mon Sep 17 00:00:00 2001 From: Yash Shah Date: Tue, 8 Dec 2020 10:25:35 +0530 Subject: dt-bindings: pwm: Update DT binding docs to support SiFive FU740 SoC Add new compatible strings to the DT binding documents to support SiFive FU740-C000. Signed-off-by: Yash Shah Signed-off-by: Palmer Dabbelt --- Documentation/devicetree/bindings/pwm/pwm-sifive.yaml | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/pwm/pwm-sifive.yaml b/Documentation/devicetree/bindings/pwm/pwm-sifive.yaml index 5ac25275d8bf..84e66913d042 100644 --- a/Documentation/devicetree/bindings/pwm/pwm-sifive.yaml +++ b/Documentation/devicetree/bindings/pwm/pwm-sifive.yaml @@ -25,12 +25,15 @@ description: properties: compatible: items: - - const: sifive,fu540-c000-pwm + - enum: + - sifive,fu540-c000-pwm + - sifive,fu740-c000-pwm - const: sifive,pwm0 description: Should be "sifive,-pwm" and "sifive,pwm". Supported - compatible strings are "sifive,fu540-c000-pwm" for the SiFive PWM v0 - as integrated onto the SiFive FU540 chip, and "sifive,pwm0" for the + compatible strings are "sifive,fu540-c000-pwm" and + "sifive,fu740-c000-pwm" for the SiFive PWM v0 as integrated onto the + SiFive FU540 and FU740 chip respectively, and "sifive,pwm0" for the SiFive PWM v0 IP block with no chip integration tweaks. Please refer to sifive-blocks-ip-versioning.txt for details. -- cgit v1.2.3 From 42cf244c8f03cc8a801333fe2fa3b7efa760d119 Mon Sep 17 00:00:00 2001 From: Yash Shah Date: Tue, 8 Dec 2020 10:25:37 +0530 Subject: dt-bindings: gpio: Update DT binding docs to support SiFive FU740 SoC Add new compatible strings to the DT binding documents to support SiFive FU740-C000. Signed-off-by: Yash Shah Signed-off-by: Palmer Dabbelt --- Documentation/devicetree/bindings/gpio/sifive,gpio.yaml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/gpio/sifive,gpio.yaml b/Documentation/devicetree/bindings/gpio/sifive,gpio.yaml index a0efd8dc2538..ab22056f8b44 100644 --- a/Documentation/devicetree/bindings/gpio/sifive,gpio.yaml +++ b/Documentation/devicetree/bindings/gpio/sifive,gpio.yaml @@ -13,7 +13,9 @@ maintainers: properties: compatible: items: - - const: sifive,fu540-c000-gpio + - enum: + - sifive,fu540-c000-gpio + - sifive,fu740-c000-gpio - const: sifive,gpio0 reg: -- cgit v1.2.3 From 3489c030102fee69ef423f71f279d7bfe547aed8 Mon Sep 17 00:00:00 2001 From: Yash Shah Date: Tue, 8 Dec 2020 10:25:40 +0530 Subject: dt-bindings: riscv: Update YAML doc to support SiFive HiFive Unmatched board Add new compatible strings to the YAML DT binding document to support SiFive's HiFive Unmatched board Signed-off-by: Yash Shah Signed-off-by: Palmer Dabbelt --- Documentation/devicetree/bindings/riscv/sifive.yaml | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/riscv/sifive.yaml b/Documentation/devicetree/bindings/riscv/sifive.yaml index 3a8647d1da4c..ee0a239af4c2 100644 --- a/Documentation/devicetree/bindings/riscv/sifive.yaml +++ b/Documentation/devicetree/bindings/riscv/sifive.yaml @@ -17,11 +17,18 @@ properties: $nodename: const: '/' compatible: - items: - - enum: - - sifive,hifive-unleashed-a00 - - const: sifive,fu540-c000 - - const: sifive,fu540 + oneOf: + - items: + - enum: + - sifive,hifive-unleashed-a00 + - const: sifive,fu540-c000 + - const: sifive,fu540 + + - items: + - enum: + - sifive,hifive-unmatched-a00 + - const: sifive,fu740-c000 + - const: sifive,fu740 additionalProperties: true -- cgit v1.2.3 From 9e9eb85e43e7a7eb9b98d64b003f689778944a3c Mon Sep 17 00:00:00 2001 From: Cristian Ciocaltea Date: Tue, 29 Dec 2020 23:17:19 +0200 Subject: dt-bindings: dma: owl: Add compatible string for Actions Semi S500 SoC Add a new compatible string corresponding to the DMA controller found in the S500 variant of the Actions Semi Owl SoCs family. Additionally, order the entries alphabetically. Signed-off-by: Cristian Ciocaltea Reviewed-by: Manivannan Sadhasivam Reviewed-by: Rob Herring Link: https://lore.kernel.org/r/2bd23ef5dad5dd613006c20d714b1be3c4d38e7a.1609263738.git.cristian.ciocaltea@gmail.com Signed-off-by: Vinod Koul --- Documentation/devicetree/bindings/dma/owl-dma.yaml | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/dma/owl-dma.yaml b/Documentation/devicetree/bindings/dma/owl-dma.yaml index 256d62af2c64..93b4847554fb 100644 --- a/Documentation/devicetree/bindings/dma/owl-dma.yaml +++ b/Documentation/devicetree/bindings/dma/owl-dma.yaml @@ -8,8 +8,8 @@ title: Actions Semi Owl SoCs DMA controller description: | The OWL DMA is a general-purpose direct memory access controller capable of - supporting 10 and 12 independent DMA channels for S700 and S900 SoCs - respectively. + supporting 10 independent DMA channels for the Actions Semi S700 SoC and 12 + independent DMA channels for the S500 and S900 SoC variants. maintainers: - Manivannan Sadhasivam @@ -20,8 +20,9 @@ allOf: properties: compatible: enum: - - actions,s900-dma + - actions,s500-dma - actions,s700-dma + - actions,s900-dma reg: maxItems: 1 -- cgit v1.2.3 From 9fc33807ad2967e3acd848a8be1b11bb082d87e6 Mon Sep 17 00:00:00 2001 From: Rafał Miłecki Date: Fri, 27 Nov 2020 12:14:41 +0100 Subject: dt-bindings: reset: document Broadcom's BCM4908 PCIe reset binding MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BCM4908 was built using older PCIe hardware block that requires using external reset block controlling PERST# signals. Signed-off-by: Rafał Miłecki Acked-by: Florian Fainelli Reviewed-by: Rob Herring Signed-off-by: Philipp Zabel --- .../reset/brcm,bcm4908-misc-pcie-reset.yaml | 39 ++++++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 Documentation/devicetree/bindings/reset/brcm,bcm4908-misc-pcie-reset.yaml (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/reset/brcm,bcm4908-misc-pcie-reset.yaml b/Documentation/devicetree/bindings/reset/brcm,bcm4908-misc-pcie-reset.yaml new file mode 100644 index 000000000000..88aebb370838 --- /dev/null +++ b/Documentation/devicetree/bindings/reset/brcm,bcm4908-misc-pcie-reset.yaml @@ -0,0 +1,39 @@ +# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/reset/brcm,bcm4908-misc-pcie-reset.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Broadcom MISC block PCIe reset controller + +description: This document describes reset controller handling PCIe PERST# + signals. On BCM4908 it's a part of the MISC block. + +maintainers: + - Rafał Miłecki + +properties: + compatible: + const: brcm,bcm4908-misc-pcie-reset + + reg: + maxItems: 1 + + "#reset-cells": + description: PCIe core id + const: 1 + +required: + - compatible + - reg + - "#reset-cells" + +additionalProperties: false + +examples: + - | + reset-controller@ff802644 { + compatible = "brcm,bcm4908-misc-pcie-reset"; + reg = <0xff802644 0x04>; + #reset-cells = <1>; + }; -- cgit v1.2.3 From 0cafb846a326e838d41db22f96e625c0ad0b6fc8 Mon Sep 17 00:00:00 2001 From: Zhen Lei Date: Tue, 8 Dec 2020 20:46:40 +0800 Subject: dt-bindings: reset: correct vendor prefix hisi to hisilicon The vendor prefix of "Hisilicon Limited" is "hisilicon", it is clearly stated in "vendor-prefixes.yaml". Fixes: 836e23549583 ("dt-bindings: Document the hi3660 reset bindings") Signed-off-by: Zhen Lei Cc: Zhangfei Gao Reviewed-by: Rob Herring Signed-off-by: Philipp Zabel --- Documentation/devicetree/bindings/reset/hisilicon,hi3660-reset.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/reset/hisilicon,hi3660-reset.txt b/Documentation/devicetree/bindings/reset/hisilicon,hi3660-reset.txt index 2df4bddeb688..aefd26710f9e 100644 --- a/Documentation/devicetree/bindings/reset/hisilicon,hi3660-reset.txt +++ b/Documentation/devicetree/bindings/reset/hisilicon,hi3660-reset.txt @@ -11,7 +11,7 @@ Required properties: - compatible: should be one of the following: "hisilicon,hi3660-reset" for HI3660 "hisilicon,hi3670-reset", "hisilicon,hi3660-reset" for HI3670 -- hisi,rst-syscon: phandle of the reset's syscon. +- hisilicon,rst-syscon: phandle of the reset's syscon. - #reset-cells : Specifies the number of cells needed to encode a reset source. The type shall be a and the value shall be 2. @@ -29,7 +29,7 @@ Example: iomcu_rst: iomcu_rst_controller { compatible = "hisilicon,hi3660-reset"; - hisi,rst-syscon = <&iomcu>; + hisilicon,rst-syscon = <&iomcu>; #reset-cells = <2>; }; -- cgit v1.2.3 From f2ad9bfd4dda69175b8ed2c38f115c8138239780 Mon Sep 17 00:00:00 2001 From: Zhen Lei Date: Tue, 8 Dec 2020 20:46:41 +0800 Subject: dt-bindings: reset: convert Hisilicon reset controller bindings to json-schema Convert the Hisilicon reset controller binding to DT schema format using json-schema. Signed-off-by: Zhen Lei Reviewed-by: Rob Herring Signed-off-by: Philipp Zabel --- .../bindings/reset/hisilicon,hi3660-reset.txt | 44 ------------- .../bindings/reset/hisilicon,hi3660-reset.yaml | 77 ++++++++++++++++++++++ 2 files changed, 77 insertions(+), 44 deletions(-) delete mode 100644 Documentation/devicetree/bindings/reset/hisilicon,hi3660-reset.txt create mode 100644 Documentation/devicetree/bindings/reset/hisilicon,hi3660-reset.yaml (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/reset/hisilicon,hi3660-reset.txt b/Documentation/devicetree/bindings/reset/hisilicon,hi3660-reset.txt deleted file mode 100644 index aefd26710f9e..000000000000 --- a/Documentation/devicetree/bindings/reset/hisilicon,hi3660-reset.txt +++ /dev/null @@ -1,44 +0,0 @@ -Hisilicon System Reset Controller -====================================== - -Please also refer to reset.txt in this directory for common reset -controller binding usage. - -The reset controller registers are part of the system-ctl block on -hi3660 and hi3670 SoCs. - -Required properties: -- compatible: should be one of the following: - "hisilicon,hi3660-reset" for HI3660 - "hisilicon,hi3670-reset", "hisilicon,hi3660-reset" for HI3670 -- hisilicon,rst-syscon: phandle of the reset's syscon. -- #reset-cells : Specifies the number of cells needed to encode a - reset source. The type shall be a and the value shall be 2. - - Cell #1 : offset of the reset assert control - register from the syscon register base - offset + 4: deassert control register - offset + 8: status control register - Cell #2 : bit position of the reset in the reset control register - -Example: - iomcu: iomcu@ffd7e000 { - compatible = "hisilicon,hi3660-iomcu", "syscon"; - reg = <0x0 0xffd7e000 0x0 0x1000>; - }; - - iomcu_rst: iomcu_rst_controller { - compatible = "hisilicon,hi3660-reset"; - hisilicon,rst-syscon = <&iomcu>; - #reset-cells = <2>; - }; - -Specifying reset lines connected to IP modules -============================================== -example: - - i2c0: i2c@..... { - ... - resets = <&iomcu_rst 0x20 3>; /* offset: 0x20; bit: 3 */ - ... - }; diff --git a/Documentation/devicetree/bindings/reset/hisilicon,hi3660-reset.yaml b/Documentation/devicetree/bindings/reset/hisilicon,hi3660-reset.yaml new file mode 100644 index 000000000000..9bf40952e5b7 --- /dev/null +++ b/Documentation/devicetree/bindings/reset/hisilicon,hi3660-reset.yaml @@ -0,0 +1,77 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/reset/hisilicon,hi3660-reset.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Hisilicon System Reset Controller + +maintainers: + - Wei Xu + +description: | + Please also refer to reset.txt in this directory for common reset + controller binding usage. + The reset controller registers are part of the system-ctl block on + hi3660 and hi3670 SoCs. + +properties: + compatible: + oneOf: + - items: + - const: hisilicon,hi3660-reset + - items: + - const: hisilicon,hi3670-reset + - const: hisilicon,hi3660-reset + + hisilicon,rst-syscon: + description: phandle of the reset's syscon. + $ref: /schemas/types.yaml#/definitions/phandle + + '#reset-cells': + description: | + Specifies the number of cells needed to encode a reset source. + Cell #1 : offset of the reset assert control register from the syscon + register base + offset + 4: deassert control register + offset + 8: status control register + Cell #2 : bit position of the reset in the reset control register + const: 2 + +required: + - compatible + +additionalProperties: false + +examples: + - | + #include + #include + #include + + iomcu: iomcu@ffd7e000 { + compatible = "hisilicon,hi3660-iomcu", "syscon"; + reg = <0xffd7e000 0x1000>; + }; + + iomcu_rst: iomcu_rst_controller { + compatible = "hisilicon,hi3660-reset"; + hisilicon,rst-syscon = <&iomcu>; + #reset-cells = <2>; + }; + + /* Specifying reset lines connected to IP modules */ + i2c@ffd71000 { + compatible = "snps,designware-i2c"; + reg = <0xffd71000 0x1000>; + interrupts = ; + #address-cells = <1>; + #size-cells = <0>; + clock-frequency = <400000>; + clocks = <&crg_ctrl HI3660_CLK_GATE_I2C0>; + resets = <&iomcu_rst 0x20 3>; + pinctrl-names = "default"; + pinctrl-0 = <&i2c0_pmx_func &i2c0_cfg_func>; + status = "disabled"; + }; +... -- cgit v1.2.3 From 6be69293196c1700de2df3b32417c6eda2b12009 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Fri, 8 Jan 2021 11:35:22 +0100 Subject: spi: renesas,sh-msiof: Add r8a779a0 support Document R-Car V3U (R8A779A0) SoC bindings. Signed-off-by: Wolfram Sang Signed-off-by: Geert Uytterhoeven Link: https://lore.kernel.org/r/20210108103522.2025880-1-geert+renesas@glider.be Signed-off-by: Mark Brown --- Documentation/devicetree/bindings/spi/renesas,sh-msiof.yaml | 1 + 1 file changed, 1 insertion(+) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/spi/renesas,sh-msiof.yaml b/Documentation/devicetree/bindings/spi/renesas,sh-msiof.yaml index 44c7ddb4b109..b104899205f6 100644 --- a/Documentation/devicetree/bindings/spi/renesas,sh-msiof.yaml +++ b/Documentation/devicetree/bindings/spi/renesas,sh-msiof.yaml @@ -47,6 +47,7 @@ properties: - renesas,msiof-r8a77980 # R-Car V3H - renesas,msiof-r8a77990 # R-Car E3 - renesas,msiof-r8a77995 # R-Car D3 + - renesas,msiof-r8a779a0 # R-Car V3U - const: renesas,rcar-gen3-msiof # generic R-Car Gen3 and RZ/G2 # compatible device - items: -- cgit v1.2.3 From 9ddaa1e6181b3d33080f2ed7c27cb0bba819e562 Mon Sep 17 00:00:00 2001 From: Michael Sit Wei Hong Date: Fri, 8 Jan 2021 11:12:47 +0800 Subject: ASoC: intel, keembay-i2s: Add info for device to use DMA Add descriptions for entries needed for audio device to use DMA channels for audio playback and capture. Signed-off-by: Michael Sit Wei Hong Reviewed-by: Pierre-Louis Bossart Link: https://lore.kernel.org/r/20210108031248.20520-5-michael.wei.hong.sit@intel.com Signed-off-by: Mark Brown --- .../devicetree/bindings/sound/intel,keembay-i2s.yaml | 14 ++++++++++++++ 1 file changed, 14 insertions(+) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/sound/intel,keembay-i2s.yaml b/Documentation/devicetree/bindings/sound/intel,keembay-i2s.yaml index d346e61ab708..e0658f122cbb 100644 --- a/Documentation/devicetree/bindings/sound/intel,keembay-i2s.yaml +++ b/Documentation/devicetree/bindings/sound/intel,keembay-i2s.yaml @@ -45,6 +45,18 @@ properties: - const: osc - const: apb_clk + dmas: + items: + - description: DMA controller phandle and DMA channel + for TX and RX + + dma-names: + items: + - description: "tx" for the transmit channel + "rx" for the receive channel + - const: tx + - const: rx + required: - compatible - "#sound-dai-cells" @@ -70,4 +82,6 @@ examples: interrupts = ; clock-names = "osc", "apb_clk"; clocks = <&scmi_clk KEEM_BAY_PSS_AUX_I2S3>, <&scmi_clk KEEM_BAY_PSS_I2S3>; + dmas = <&axi_dma0 29 &axi_dma0 33>; + dma-names = "tx", "rx"; }; -- cgit v1.2.3 From d0dc4c80b9ee667bfe9c3e5735707cfec085df3b Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Tue, 22 Sep 2020 15:46:23 +0200 Subject: dt-bindings:iio:xilinx-xadc: Add Xilinx System Management Wizard binding docs Add binding documentation for the Xilinx System Management Wizard. The Xilinx System Management Wizard is a AXI frontend for the Xilinx System Monitor found in the UltraScale and UltraScale+ FPGAs. The System Monitor is the equivalent to the Xilinx XADC found in their previous generation of FPGAs and their external and internal interfaces are very similar. For this reason the share the same binding documentation. But since they are not 100% compatible and software will have to know about the differences they use a different compatible string. Signed-off-by: Lars-Peter Clausen Link: https://lore.kernel.org/r/20200922134624.13191-1-lars@metafoo.de Signed-off-by: Jonathan Cameron --- .../devicetree/bindings/iio/adc/xilinx-xadc.txt | 49 +++++++++++++++++----- 1 file changed, 39 insertions(+), 10 deletions(-) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/iio/adc/xilinx-xadc.txt b/Documentation/devicetree/bindings/iio/adc/xilinx-xadc.txt index e0e0755cabd8..f42e18078376 100644 --- a/Documentation/devicetree/bindings/iio/adc/xilinx-xadc.txt +++ b/Documentation/devicetree/bindings/iio/adc/xilinx-xadc.txt @@ -1,13 +1,22 @@ Xilinx XADC device driver -This binding document describes the bindings for both of them since the -bindings are very similar. The Xilinx XADC is a ADC that can be found in the -series 7 FPGAs from Xilinx. The XADC has a DRP interface for communication. -Currently two different frontends for the DRP interface exist. One that is only -available on the ZYNQ family as a hardmacro in the SoC portion of the ZYNQ. The -other one is available on all series 7 platforms and is a softmacro with a AXI -interface. This binding document describes the bindings for both of them since -the bindings are very similar. +This binding document describes the bindings for the Xilinx 7 Series XADC as well +as the UltraScale/UltraScale+ System Monitor. + +The Xilinx XADC is an ADC that can be found in the Series 7 FPGAs from Xilinx. +The XADC has a DRP interface for communication. Currently two different +frontends for the DRP interface exist. One that is only available on the ZYNQ +family as a hardmacro in the SoC portion of the ZYNQ. The other one is available +on all series 7 platforms and is a softmacro with a AXI interface. This binding +document describes the bindings for both of them since the bindings are very +similar. + +The Xilinx System Monitor is an ADC that is found in the UltraScale and +UltraScale+ FPGAs from Xilinx. The System Monitor provides a DRP interface for +communication. Xilinx provides a standard IP core that can be used to access the +System Monitor through an AXI interface in the FPGA fabric. This IP core is +called the Xilinx System Management Wizard. This document describes the bindings +for this IP. Required properties: - compatible: Should be one of @@ -15,11 +24,14 @@ Required properties: configuration interface to interface to the XADC hardmacro. * "xlnx,axi-xadc-1.00.a": When using the axi-xadc pcore to interface to the XADC hardmacro. + * "xlnx,system-management-wiz-1.3": When using the + Xilinx System Management Wizard fabric IP core to access the + UltraScale and UltraScale+ System Monitor. - reg: Address and length of the register set for the device - interrupts: Interrupt for the XADC control interface. - clocks: When using the ZYNQ this must be the ZYNQ PCAP clock, - when using the AXI-XADC pcore this must be the clock that provides the - clock to the AXI bus interface of the core. + when using the axi-xadc or the axi-system-management-wizard this must be + the clock that provides the clock to the AXI bus interface of the core. Optional properties: - xlnx,external-mux: @@ -110,3 +122,20 @@ Examples: }; }; }; + + adc@80000000 { + compatible = "xlnx,system-management-wiz-1.3"; + reg = <0x80000000 0x1000>; + interrupts = <0 81 4>; + interrupt-parent = <&gic>; + clocks = <&fpga1_clk>; + + xlnx,channels { + #address-cells = <1>; + #size-cells = <0>; + channel@0 { + reg = <0>; + xlnx,bipolar; + }; + }; + }; -- cgit v1.2.3 From 44fd881338b7c5149d195a0425aec8a781312659 Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Sat, 28 Nov 2020 17:33:42 +0000 Subject: dt-bindings:iio:imu:invensense,mpu6050: txt to yaml conversion As Rob Herring suggested, this no long requires the explicit i2c-gate binding, but instead just used i2c-controller.yaml directly. 2 prior examples combinded into one as a single example can show all of the binding elements as long as the right part is selected. Signed-off-by: Jonathan Cameron Reviewed-by: Rob Herring Cc: Jean-Baptiste Maneyrol Cc: Wolfram Sang Cc: Peter Rosin Link: https://lore.kernel.org/r/20201128173343.390165-3-jic23@kernel.org --- .../devicetree/bindings/iio/imu/inv_mpu6050.txt | 67 -------------- .../bindings/iio/imu/invensense,mpu6050.yaml | 103 +++++++++++++++++++++ 2 files changed, 103 insertions(+), 67 deletions(-) delete mode 100644 Documentation/devicetree/bindings/iio/imu/inv_mpu6050.txt create mode 100644 Documentation/devicetree/bindings/iio/imu/invensense,mpu6050.yaml (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/iio/imu/inv_mpu6050.txt b/Documentation/devicetree/bindings/iio/imu/inv_mpu6050.txt deleted file mode 100644 index f2f64749e818..000000000000 --- a/Documentation/devicetree/bindings/iio/imu/inv_mpu6050.txt +++ /dev/null @@ -1,67 +0,0 @@ -InvenSense MPU-6050 Six-Axis (Gyro + Accelerometer) MEMS MotionTracking Device - -http://www.invensense.com/mems/gyro/mpu6050.html - -Required properties: - - compatible : should be one of - "invensense,mpu6000" - "invensense,mpu6050" - "invensense,mpu6500" - "invensense,mpu6515" - "invensense,mpu9150" - "invensense,mpu9250" - "invensense,mpu9255" - "invensense,icm20608" - "invensense,icm20609" - "invensense,icm20689" - "invensense,icm20602" - "invensense,icm20690" - "invensense,iam20680" - - reg : the I2C address of the sensor - - interrupts: interrupt mapping for IRQ. It should be configured with flags - IRQ_TYPE_LEVEL_HIGH, IRQ_TYPE_EDGE_RISING, IRQ_TYPE_LEVEL_LOW or - IRQ_TYPE_EDGE_FALLING. - - Refer to interrupt-controller/interrupts.txt for generic interrupt client node - bindings. - -Optional properties: - - vdd-supply: regulator phandle for VDD supply - - vddio-supply: regulator phandle for VDDIO supply - - mount-matrix: an optional 3x3 mounting rotation matrix - - i2c-gate node. These devices also support an auxiliary i2c bus. This is - simple enough to be described using the i2c-gate binding. See - i2c/i2c-gate.txt for more details. - -Example: - mpu6050@68 { - compatible = "invensense,mpu6050"; - reg = <0x68>; - interrupt-parent = <&gpio1>; - interrupts = <18 IRQ_TYPE_EDGE_RISING>; - mount-matrix = "-0.984807753012208", /* x0 */ - "0", /* y0 */ - "-0.173648177666930", /* z0 */ - "0", /* x1 */ - "-1", /* y1 */ - "0", /* z1 */ - "-0.173648177666930", /* x2 */ - "0", /* y2 */ - "0.984807753012208"; /* z2 */ - }; - - - mpu9250@68 { - compatible = "invensense,mpu9250"; - reg = <0x68>; - interrupt-parent = <&gpio3>; - interrupts = <21 IRQ_TYPE_LEVEL_HIGH>; - i2c-gate { - #address-cells = <1>; - #size-cells = <0>; - ax8975@c { - compatible = "ak,ak8975"; - reg = <0x0c>; - }; - }; - }; diff --git a/Documentation/devicetree/bindings/iio/imu/invensense,mpu6050.yaml b/Documentation/devicetree/bindings/iio/imu/invensense,mpu6050.yaml new file mode 100644 index 000000000000..9268b6ca2afe --- /dev/null +++ b/Documentation/devicetree/bindings/iio/imu/invensense,mpu6050.yaml @@ -0,0 +1,103 @@ +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/iio/imu/invensense,mpu6050.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: InvenSense MPU-6050 Six-Axis (Gyro + Accelerometer) MEMS MotionTracking Device + +maintainers: + - Jean-Baptiste Maneyrol + +description: | + These devices support both I2C and SPI bus interfaces. + +properties: + compatible: + enum: + - invensense,iam20680 + - invensense,icm20608 + - invensense,icm20609 + - invensense,icm20689 + - invensense,icm20602 + - invensense,icm20690 + - invensense,mpu6000 + - invensense,mpu6050 + - invensense,mpu6500 + - invensense,mpu6515 + - invensense,mpu9150 + - invensense,mpu9250 + - invensense,mpu9255 + + reg: + maxItems: 1 + + interrupts: + maxItems: 1 + + spi-max-frequency: true + + vdd-supply: true + vddio-supply: true + + mount-matrix: true + + i2c-gate: + $ref: /schemas/i2c/i2c-controller.yaml + unevaluatedProperties: false + description: | + These devices also support an auxiliary i2c bus via an i2c-gate. + +allOf: + - if: + not: + properties: + compatible: + contains: + enum: + - invensense,mpu9150 + - invensense,mpu9250 + - invensense,mpu9255 + then: + properties: + i2c-gate: false + +additionalProperties: false + +required: + - compatible + - reg + - interrupts + +examples: + - | + #include + i2c { + #address-cells = <1>; + #size-cells = <0>; + + imu@68 { + compatible = "invensense,mpu9250"; + reg = <0x68>; + interrupt-parent = <&gpio3>; + interrupts = <21 IRQ_TYPE_LEVEL_HIGH>; + mount-matrix = "-0.984807753012208", /* x0 */ + "0", /* y0 */ + "-0.173648177666930", /* z0 */ + "0", /* x1 */ + "-1", /* y1 */ + "0", /* z1 */ + "-0.173648177666930", /* x2 */ + "0", /* y2 */ + "0.984807753012208"; /* z2 */ + i2c-gate { + #address-cells = <1>; + #size-cells = <0>; + magnetometer@c { + compatible = "ak,ak8975"; + reg = <0x0c>; + }; + }; + }; + }; +... -- cgit v1.2.3 From 749787477ae43339ade941dc252563dd97cc7621 Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Sat, 28 Nov 2020 17:33:43 +0000 Subject: dt-bindings:iio:gyro:invensense,mpu3050: txt to yaml format conversion. Very similar to the mpu6050 binding. Only unusual element is the i2c-gate section. Example tweaked a little to include a real device behind the gate. As Rob Herring suggested, dropped use of explicit i2c-gate yaml binding in favour of just using the i2c-controller.yaml binding directly. Signed-off-by: Jonathan Cameron Reviewed-by: Linus Walleij Reviewed-by: Rob Herring Link: https://lore.kernel.org/r/20201128173343.390165-4-jic23@kernel.org --- .../bindings/iio/gyroscope/invensense,mpu3050.txt | 45 -------------- .../bindings/iio/gyroscope/invensense,mpu3050.yaml | 70 ++++++++++++++++++++++ 2 files changed, 70 insertions(+), 45 deletions(-) delete mode 100644 Documentation/devicetree/bindings/iio/gyroscope/invensense,mpu3050.txt create mode 100644 Documentation/devicetree/bindings/iio/gyroscope/invensense,mpu3050.yaml (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/iio/gyroscope/invensense,mpu3050.txt b/Documentation/devicetree/bindings/iio/gyroscope/invensense,mpu3050.txt deleted file mode 100644 index 233fe207aded..000000000000 --- a/Documentation/devicetree/bindings/iio/gyroscope/invensense,mpu3050.txt +++ /dev/null @@ -1,45 +0,0 @@ -Invensense MPU-3050 Gyroscope device tree bindings - -Required properties: - - compatible : should be "invensense,mpu3050" - - reg : the I2C address of the sensor - -Optional properties: - - interrupts : interrupt mapping for the trigger interrupt from the - internal oscillator. The following IRQ modes are supported: - IRQ_TYPE_EDGE_RISING, IRQ_TYPE_EDGE_FALLING, IRQ_TYPE_LEVEL_HIGH and - IRQ_TYPE_LEVEL_LOW. The driver should detect and configure the hardware - for the desired interrupt type. - - vdd-supply : supply regulator for the main power voltage. - - vlogic-supply : supply regulator for the signal voltage. - - mount-matrix : see iio/mount-matrix.txt - -Optional subnodes: - - The MPU-3050 will pass through and forward the I2C signals from the - incoming I2C bus, alternatively drive traffic to a slave device (usually - an accelerometer) on its own initiative. Therefore is supports a subnode - i2c gate node. For details see: i2c/i2c-gate.txt - -Example: - -mpu3050@68 { - compatible = "invensense,mpu3050"; - reg = <0x68>; - interrupt-parent = <&foo>; - interrupts = <12 IRQ_TYPE_EDGE_FALLING>; - vdd-supply = <&bar>; - vlogic-supply = <&baz>; - - /* External I2C interface */ - i2c-gate { - #address-cells = <1>; - #size-cells = <0>; - - fnord@18 { - compatible = "fnord"; - reg = <0x18>; - interrupt-parent = <&foo>; - interrupts = <13 IRQ_TYPE_EDGE_FALLING>; - }; - }; -}; diff --git a/Documentation/devicetree/bindings/iio/gyroscope/invensense,mpu3050.yaml b/Documentation/devicetree/bindings/iio/gyroscope/invensense,mpu3050.yaml new file mode 100644 index 000000000000..7e2accc3d5ce --- /dev/null +++ b/Documentation/devicetree/bindings/iio/gyroscope/invensense,mpu3050.yaml @@ -0,0 +1,70 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/iio/gyroscope/invensense,mpu3050.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Invensense MPU-3050 Gyroscope + +maintainers: + - Linus Walleij + +properties: + compatible: + const: invensense,mpu3050 + + reg: + maxItems: 1 + + vdd-supply: true + + vlogic-supply: true + + interrupts: + minItems: 1 + description: + Interrupt mapping for the trigger interrupt from the internal oscillator. + + mount-matrix: true + + i2c-gate: + $ref: /schemas/i2c/i2c-controller.yaml + unevaluatedProperties: false + description: | + The MPU-3050 will pass through and forward the I2C signals from the + incoming I2C bus, alternatively drive traffic to a slave device (usually + an accelerometer) on its own initiative. Therefore is supports an + i2c-gate subnode. + +required: + - compatible + - reg + +additionalProperties: false + +examples: + - | + #include + i2c { + #address-cells = <1>; + #size-cells = <0>; + gyroscope@68 { + compatible = "invensense,mpu3050"; + reg = <0x68>; + interrupt-parent = <&foo>; + interrupts = <12 IRQ_TYPE_EDGE_FALLING>; + vdd-supply = <&bar>; + vlogic-supply = <&baz>; + + i2c-gate { + #address-cells = <1>; + #size-cells = <0>; + + magnetometer@c { + compatible = "ak,ak8975"; + reg = <0x0c>; + }; + }; + }; + }; +... -- cgit v1.2.3 From af73caa71a67ebd1c9a884a6f2c892df43c8d8e1 Mon Sep 17 00:00:00 2001 From: Stephan Gerhold Date: Wed, 2 Dec 2020 11:46:55 +0100 Subject: dt-bindings: iio: imu: mpu6050: Document invensense,mpu6880 MPU-6880 seems to be very similar to MPU-6500 / MPU-6050 and it works fine with some minor additions for the mpu6050 driver. Add a compatible for it to the binding documentation. Signed-off-by: Stephan Gerhold Acked-by: Rob Herring Acked-by: Jean-Baptiste Maneyrol Cc: Jean-Baptiste Maneyrol Link: https://lore.kernel.org/r/20201202104656.5119-1-stephan@gerhold.net Signed-off-by: Jonathan Cameron --- Documentation/devicetree/bindings/iio/imu/invensense,mpu6050.yaml | 1 + 1 file changed, 1 insertion(+) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/iio/imu/invensense,mpu6050.yaml b/Documentation/devicetree/bindings/iio/imu/invensense,mpu6050.yaml index 9268b6ca2afe..edbc2921aabd 100644 --- a/Documentation/devicetree/bindings/iio/imu/invensense,mpu6050.yaml +++ b/Documentation/devicetree/bindings/iio/imu/invensense,mpu6050.yaml @@ -25,6 +25,7 @@ properties: - invensense,mpu6050 - invensense,mpu6500 - invensense,mpu6515 + - invensense,mpu6880 - invensense,mpu9150 - invensense,mpu9250 - invensense,mpu9255 -- cgit v1.2.3 From 165c514797129c6c68285721ea971b039bf665c5 Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Thu, 24 Dec 2020 13:08:19 +0100 Subject: iio: accel: yamaha-yas530: Add DT bindings This adds device tree bindings for the Yamaha YAS530 family of magnetometers/compass sensors. Signed-off-by: Linus Walleij Reviewed-by: Rob Herring Cc: devicetree@vger.kernel.org Cc: phone-devel@vger.kernel.org Cc: Andy Shevchenko Cc: Jonathan Bakker Link: https://lore.kernel.org/r/20201224120820.1120099-1-linus.walleij@linaro.org Signed-off-by: Jonathan Cameron --- .../bindings/iio/magnetometer/yamaha,yas530.yaml | 112 +++++++++++++++++++++ .../devicetree/bindings/vendor-prefixes.yaml | 2 + 2 files changed, 114 insertions(+) create mode 100644 Documentation/devicetree/bindings/iio/magnetometer/yamaha,yas530.yaml (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/iio/magnetometer/yamaha,yas530.yaml b/Documentation/devicetree/bindings/iio/magnetometer/yamaha,yas530.yaml new file mode 100644 index 000000000000..4b0ef1ef5445 --- /dev/null +++ b/Documentation/devicetree/bindings/iio/magnetometer/yamaha,yas530.yaml @@ -0,0 +1,112 @@ +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/iio/magnetometer/yamaha,yas530.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Yamaha YAS530 family of magnetometer sensors + +maintainers: + - Linus Walleij + +description: + The Yamaha YAS530 magnetometers is a line of 3-axis magnetometers + first introduced by Yamaha in 2009 with the YAS530. They are successors + of Yamaha's first magnetometer YAS529. Over the years this magnetometer + has been miniaturized and appeared in a number of different variants. + +properties: + $nodename: + pattern: '^magnetometer@[0-9a-f]+$' + + compatible: + items: + - enum: + - yamaha,yas530 + - yamaha,yas532 + - yamaha,yas533 + - yamaha,yas535 + - yamaha,yas536 + - yamaha,yas537 + - yamaha,yas539 + + reg: + maxItems: 1 + + reset-gpios: + maxItems: 1 + description: The YAS530 sensor has a RSTN pin used to reset + the logic inside the sensor. This GPIO line should connect + to that pin and be marked as GPIO_ACTIVE_LOW. + + interrupts: + maxItems: 1 + description: Interrupt for INT pin for interrupt generation. + The polarity, whether the interrupt is active on the rising + or the falling edge, is software-configurable in the hardware. + + vdd-supply: + description: An optional regulator providing core power supply + on the VDD pin, typically 1.8 V or 3.0 V. + + iovdd-supply: + description: An optional regulator providing I/O power supply + for the I2C interface on the IOVDD pin, typically 1.8 V. + + mount-matrix: + description: An optional 3x3 mounting rotation matrix. + +allOf: + - if: + not: + properties: + compatible: + items: + const: yamaha,yas530 + then: + properties: + reset-gpios: false + + - if: + properties: + compatible: + items: + const: yamaha,yas539 + then: + properties: + interrupts: false + +required: + - compatible + - reg + +additionalProperties: false + +examples: + - | + #include + #include + i2c-0 { + #address-cells = <1>; + #size-cells = <0>; + + magnetometer@2e { + compatible = "yamaha,yas530"; + reg = <0x2e>; + vdd-supply = <&ldo1_reg>; + iovdd-supply = <&ldo2_reg>; + reset-gpios = <&gpio6 12 GPIO_ACTIVE_LOW>; + interrupts = <&gpio6 13 IRQ_TYPE_EDGE_RISING>; + }; + }; + + i2c-1 { + #address-cells = <1>; + #size-cells = <0>; + + magnetometer@2e { + compatible = "yamaha,yas539"; + reg = <0x2e>; + vdd-supply = <&ldo1_reg>; + }; + }; diff --git a/Documentation/devicetree/bindings/vendor-prefixes.yaml b/Documentation/devicetree/bindings/vendor-prefixes.yaml index 041ae90b0d8f..b515b899b357 100644 --- a/Documentation/devicetree/bindings/vendor-prefixes.yaml +++ b/Documentation/devicetree/bindings/vendor-prefixes.yaml @@ -1252,6 +1252,8 @@ patternProperties: description: Shenzhen Xunlong Software CO.,Limited "^xylon,.*": description: Xylon + "^yamaha,.*": + description: Yamaha Corporation "^yes-optoelectronics,.*": description: Yes Optoelectronics Co.,Ltd. "^ylm,.*": -- cgit v1.2.3 From a363bfb986baf9f097c54f03def6a988d7b05ec8 Mon Sep 17 00:00:00 2001 From: Tomas Novotny Date: Wed, 16 Dec 2020 11:13:16 +0100 Subject: dt-bindings:iio:dac:microchip,mcp4725: fix properties for mcp4726 The vdd-supply property is optional if vref-supply is provided for mcp4726. Also the microchip,vref-buffered makes sense only if vref-supply is specified. Spotted by Jonathan during conversion to yaml. Reported-by: Jonathan Cameron Signed-off-by: Tomas Novotny Reviewed-by: Rob Herring Link: https://lore.kernel.org/r/20201216101316.1403-1-tomas@novotny.cz Signed-off-by: Jonathan Cameron --- .../bindings/iio/dac/microchip,mcp4725.yaml | 31 +++++++++++++++++----- 1 file changed, 25 insertions(+), 6 deletions(-) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/iio/dac/microchip,mcp4725.yaml b/Documentation/devicetree/bindings/iio/dac/microchip,mcp4725.yaml index 271998610ceb..5f5b578316bc 100644 --- a/Documentation/devicetree/bindings/iio/dac/microchip,mcp4725.yaml +++ b/Documentation/devicetree/bindings/iio/dac/microchip,mcp4725.yaml @@ -39,20 +39,39 @@ properties: allOf: - if: - not: - properties: - compatible: - contains: - const: microchip,mcp4726 + properties: + compatible: + contains: + const: microchip,mcp4725 then: properties: vref-supply: false + required: + - vdd-supply + + - if: + properties: + compatible: + contains: + const: microchip,mcp4726 + then: + anyOf: + - required: + - vdd-supply + - required: + - vref-supply + + - if: + not: + required: + - vref-supply + then: + properties: microchip,vref-buffered: false required: - compatible - reg - - vdd-supply additionalProperties: false -- cgit v1.2.3 From c7ee3a40e76c06e1e9a78d8f1a50bc06e63753de Mon Sep 17 00:00:00 2001 From: Rafał Miłecki Date: Wed, 6 Jan 2021 22:32:00 +0100 Subject: dt-bindings: net: convert Broadcom Starfighter 2 binding to the json-schema MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This helps validating DTS files. Only the current (not deprecated one) binding was converted. Minor changes: 1. Dropped dsa/dsa.txt references 2. Updated node name to match dsa.yaml requirement 3. Fixed 2 typos in examples The new binding was validated using the dt_binding_check. Signed-off-by: Rafał Miłecki Link: https://lore.kernel.org/r/20210106213202.17459-1-zajec5@gmail.com Signed-off-by: Jakub Kicinski --- .../bindings/net/brcm,bcm7445-switch-v4.0.txt | 101 +----------- .../devicetree/bindings/net/dsa/brcm,sf2.yaml | 172 +++++++++++++++++++++ 2 files changed, 175 insertions(+), 98 deletions(-) create mode 100644 Documentation/devicetree/bindings/net/dsa/brcm,sf2.yaml (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/net/brcm,bcm7445-switch-v4.0.txt b/Documentation/devicetree/bindings/net/brcm,bcm7445-switch-v4.0.txt index 97ca62b0e14d..d0935d2afef8 100644 --- a/Documentation/devicetree/bindings/net/brcm,bcm7445-switch-v4.0.txt +++ b/Documentation/devicetree/bindings/net/brcm,bcm7445-switch-v4.0.txt @@ -1,108 +1,13 @@ * Broadcom Starfighter 2 integrated swich -Required properties: +See dsa/brcm,bcm7445-switch-v4.0.yaml for the documentation. -- compatible: should be one of - "brcm,bcm7445-switch-v4.0" - "brcm,bcm7278-switch-v4.0" - "brcm,bcm7278-switch-v4.8" -- reg: addresses and length of the register sets for the device, must be 6 - pairs of register addresses and lengths -- interrupts: interrupts for the devices, must be two interrupts -- #address-cells: must be 1, see dsa/dsa.txt -- #size-cells: must be 0, see dsa/dsa.txt - -Deprecated binding required properties: +*Deprecated* binding required properties: - dsa,mii-bus: phandle to the MDIO bus controller, see dsa/dsa.txt - dsa,ethernet: phandle to the CPU network interface controller, see dsa/dsa.txt - #address-cells: must be 2, see dsa/dsa.txt -Subnodes: - -The integrated switch subnode should be specified according to the binding -described in dsa/dsa.txt. - -Optional properties: - -- reg-names: litteral names for the device base register addresses, when present - must be: "core", "reg", "intrl2_0", "intrl2_1", "fcb", "acb" - -- interrupt-names: litternal names for the device interrupt lines, when present - must be: "switch_0" and "switch_1" - -- brcm,num-gphy: specify the maximum number of integrated gigabit PHYs in the - switch - -- brcm,num-rgmii-ports: specify the maximum number of RGMII interfaces supported - by the switch - -- brcm,fcb-pause-override: boolean property, if present indicates that the switch - supports Failover Control Block pause override capability - -- brcm,acb-packets-inflight: boolean property, if present indicates that the switch - Admission Control Block supports reporting the number of packets in-flight in a - switch queue - -- resets: a single phandle and reset identifier pair. See - Documentation/devicetree/bindings/reset/reset.txt for details. - -- reset-names: If the "reset" property is specified, this property should have - the value "switch" to denote the switch reset line. - -- clocks: when provided, the first phandle is to the switch's main clock and - is valid for both BCM7445 and BCM7278. The second phandle is only applicable - to BCM7445 and is to support dividing the switch core clock. - -- clock-names: when provided, the first phandle must be "sw_switch", and the - second must be named "sw_switch_mdiv". - -Port subnodes: - -Optional properties: - -- brcm,use-bcm-hdr: boolean property, if present, indicates that the switch - port has Broadcom tags enabled (per-packet metadata) - -Example: - -switch_top@f0b00000 { - compatible = "simple-bus"; - #size-cells = <1>; - #address-cells = <1>; - ranges = <0 0xf0b00000 0x40804>; - - ethernet_switch@0 { - compatible = "brcm,bcm7445-switch-v4.0"; - #size-cells = <0>; - #address-cells = <1>; - reg = <0x0 0x40000 - 0x40000 0x110 - 0x40340 0x30 - 0x40380 0x30 - 0x40400 0x34 - 0x40600 0x208>; - reg-names = "core", "reg", intrl2_0", "intrl2_1", - "fcb, "acb"; - interrupts = <0 0x18 0 - 0 0x19 0>; - brcm,num-gphy = <1>; - brcm,num-rgmii-ports = <2>; - brcm,fcb-pause-override; - brcm,acb-packets-inflight; - - ports { - #address-cells = <1>; - #size-cells = <0>; - - port@0 { - label = "gphy"; - reg = <0>; - }; - }; - }; -}; - Example using the old DSA DeviceTree binding: switch_top@f0b00000 { @@ -132,7 +37,7 @@ switch_top@f0b00000 { switch@0 { reg = <0 0>; #size-cells = <0>; - #address-cells <1>; + #address-cells = <1>; port@0 { label = "gphy"; diff --git a/Documentation/devicetree/bindings/net/dsa/brcm,sf2.yaml b/Documentation/devicetree/bindings/net/dsa/brcm,sf2.yaml new file mode 100644 index 000000000000..9de69243cf79 --- /dev/null +++ b/Documentation/devicetree/bindings/net/dsa/brcm,sf2.yaml @@ -0,0 +1,172 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/net/dsa/brcm,sf2.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Broadcom Starfighter 2 integrated swich + +maintainers: + - Florian Fainelli + +properties: + compatible: + items: + - enum: + - brcm,bcm7278-switch-v4.0 + - brcm,bcm7278-switch-v4.8 + - brcm,bcm7445-switch-v4.0 + + reg: + minItems: 6 + maxItems: 6 + + reg-names: + items: + - const: core + - const: reg + - const: intrl2_0 + - const: intrl2_1 + - const: fcb + - const: acb + + interrupts: + minItems: 2 + maxItems: 2 + + interrupt-names: + items: + - const: switch_0 + - const: switch_1 + + resets: + maxItems: 1 + + reset-names: + const: switch + + clocks: + minItems: 1 + maxItems: 2 + items: + - description: switch's main clock + - description: dividing of the switch core clock + + clock-names: + minItems: 1 + maxItems: 2 + items: + - const: sw_switch + - const: sw_switch_mdiv + + brcm,num-gphy: + $ref: /schemas/types.yaml#/definitions/uint32 + description: maximum number of integrated gigabit PHYs in the switch + + brcm,num-rgmii-ports: + $ref: /schemas/types.yaml#/definitions/uint32 + description: maximum number of RGMII interfaces supported by the switch + + brcm,fcb-pause-override: + description: if present indicates that the switch supports Failover Control + Block pause override capability + type: boolean + + brcm,acb-packets-inflight: + description: if present indicates that the switch Admission Control Block + supports reporting the number of packets in-flight in a switch queue + type: boolean + + "#address-cells": + const: 1 + + "#size-cells": + const: 0 + + ports: + type: object + + properties: + brcm,use-bcm-hdr: + description: if present, indicates that the switch port has Broadcom + tags enabled (per-packet metadata) + type: boolean + +required: + - reg + - interrupts + - "#address-cells" + - "#size-cells" + +allOf: + - $ref: "dsa.yaml#" + - if: + properties: + compatible: + contains: + enum: + - brcm,bcm7278-switch-v4.0 + - brcm,bcm7278-switch-v4.8 + then: + properties: + clocks: + minItems: 1 + maxItems: 1 + clock-names: + minItems: 1 + maxItems: 1 + required: + - clocks + - clock-names + - if: + properties: + compatible: + contains: + const: brcm,bcm7445-switch-v4.0 + then: + properties: + clocks: + minItems: 2 + maxItems: 2 + clock-names: + minItems: 2 + maxItems: 2 + required: + - clocks + - clock-names + +additionalProperties: false + +examples: + - | + switch@f0b00000 { + compatible = "brcm,bcm7445-switch-v4.0"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0xf0b00000 0x40000>, + <0xf0b40000 0x110>, + <0xf0b40340 0x30>, + <0xf0b40380 0x30>, + <0xf0b40400 0x34>, + <0xf0b40600 0x208>; + reg-names = "core", "reg", "intrl2_0", "intrl2_1", + "fcb", "acb"; + interrupts = <0 0x18 0>, + <0 0x19 0>; + clocks = <&sw_switch>, <&sw_switch_mdiv>; + clock-names = "sw_switch", "sw_switch_mdiv"; + brcm,num-gphy = <1>; + brcm,num-rgmii-ports = <2>; + brcm,fcb-pause-override; + brcm,acb-packets-inflight; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + label = "gphy"; + reg = <0>; + }; + }; + }; -- cgit v1.2.3 From 41bb4b08778351f2f1ae01a0bc46cd33cb95da6a Mon Sep 17 00:00:00 2001 From: Rafał Miłecki Date: Wed, 6 Jan 2021 22:32:01 +0100 Subject: dt-bindings: net: dsa: sf2: add BCM4908 switch binding MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BCM4908 family SoCs have integrated Starfighter 2 switch. Signed-off-by: Rafał Miłecki Acked-by: Florian Fainelli Link: https://lore.kernel.org/r/20210106213202.17459-2-zajec5@gmail.com Signed-off-by: Jakub Kicinski --- Documentation/devicetree/bindings/net/dsa/brcm,sf2.yaml | 1 + 1 file changed, 1 insertion(+) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/net/dsa/brcm,sf2.yaml b/Documentation/devicetree/bindings/net/dsa/brcm,sf2.yaml index 9de69243cf79..d730fe5a4355 100644 --- a/Documentation/devicetree/bindings/net/dsa/brcm,sf2.yaml +++ b/Documentation/devicetree/bindings/net/dsa/brcm,sf2.yaml @@ -13,6 +13,7 @@ properties: compatible: items: - enum: + - brcm,bcm4908-switch - brcm,bcm7278-switch-v4.0 - brcm,bcm7278-switch-v4.8 - brcm,bcm7445-switch-v4.0 -- cgit v1.2.3 From 25669e943e06c56750fb2347cce4f3343379e4b2 Mon Sep 17 00:00:00 2001 From: AngeloGioacchino Del Regno Date: Sat, 9 Jan 2021 22:13:56 -0800 Subject: dt-bindings: input: touchscreen: goodix: Add binding for GT9286 IC Support for this chip is being added to the goodix driver: add the DT binding for it. Signed-off-by: AngeloGioacchino Del Regno Link: https://lore.kernel.org/r/20210109135512.149032-3-angelogioacchino.delregno@somainline.org Reviewed-by: Bastien Nocera Signed-off-by: Dmitry Torokhov --- Documentation/devicetree/bindings/input/touchscreen/goodix.yaml | 1 + 1 file changed, 1 insertion(+) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/input/touchscreen/goodix.yaml b/Documentation/devicetree/bindings/input/touchscreen/goodix.yaml index da5b0d87e16d..93f2ce3130ae 100644 --- a/Documentation/devicetree/bindings/input/touchscreen/goodix.yaml +++ b/Documentation/devicetree/bindings/input/touchscreen/goodix.yaml @@ -26,6 +26,7 @@ properties: - goodix,gt927 - goodix,gt9271 - goodix,gt928 + - goodix,gt9286 - goodix,gt967 reg: -- cgit v1.2.3 From 267d46714054bcffe0925adc90043712795156d5 Mon Sep 17 00:00:00 2001 From: Alice Guo Date: Mon, 4 Jan 2021 17:15:41 +0800 Subject: dt-bindings: soc: imx8m: add DT Binding doc for soc unique ID Add DT Binding doc for the Unique ID of i.MX 8M series. Reviewed-by: Krzysztof Kozlowski Reviewed-by: Rob Herring Signed-off-by: Alice Guo Signed-off-by: Shawn Guo --- .../devicetree/bindings/soc/imx/imx8m-soc.yaml | 86 ++++++++++++++++++++++ 1 file changed, 86 insertions(+) create mode 100644 Documentation/devicetree/bindings/soc/imx/imx8m-soc.yaml (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/soc/imx/imx8m-soc.yaml b/Documentation/devicetree/bindings/soc/imx/imx8m-soc.yaml new file mode 100644 index 000000000000..effcc72f9425 --- /dev/null +++ b/Documentation/devicetree/bindings/soc/imx/imx8m-soc.yaml @@ -0,0 +1,86 @@ +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/soc/imx/imx8m-soc.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: NXP i.MX8M Series SoC + +maintainers: + - Alice Guo + +description: | + NXP i.MX8M series SoCs contain fuse entries from which SoC Unique ID can be + obtained. + +select: + properties: + compatible: + contains: + enum: + - fsl,imx8mm + - fsl,imx8mn + - fsl,imx8mp + - fsl,imx8mq + required: + - compatible + +patternProperties: + "^soc@[0-9a-f]+$": + type: object + properties: + compatible: + items: + - enum: + - fsl,imx8mm-soc + - fsl,imx8mn-soc + - fsl,imx8mp-soc + - fsl,imx8mq-soc + - const: simple-bus + + "#address-cells": + const: 1 + + "#size-cells": + const: 1 + + ranges: true + + dma-ranges: true + + nvmem-cells: + maxItems: 1 + description: Phandle to the SOC Unique ID provided by a nvmem node + + nvmem-cell-names: + const: soc_unique_id + + required: + - compatible + - nvmem-cells + - nvmem-cell-names + + additionalProperties: + type: object + +additionalProperties: true + +examples: + - | + / { + model = "FSL i.MX8MM EVK board"; + compatible = "fsl,imx8mm-evk", "fsl,imx8mm"; + #address-cells = <2>; + #size-cells = <2>; + + soc@0 { + compatible = "fsl,imx8mm-soc", "simple-bus"; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0x0 0x0 0x0 0x3e000000>; + nvmem-cells = <&imx8mm_uid>; + nvmem-cell-names = "soc_unique_id"; + }; + }; + +... -- cgit v1.2.3 From 46a7867dd704d1700d0e7491f71892becce8b654 Mon Sep 17 00:00:00 2001 From: Tim Harvey Date: Mon, 4 Jan 2021 09:36:46 -0800 Subject: dt-bindings: arm: fsl: Add binding for Gateworks boards with IMX8MM Add bindings for the Gateworks Venice Development kit boards with IMX8MM System on Module. Signed-off-by: Tim Harvey Signed-off-by: Shawn Guo --- Documentation/devicetree/bindings/arm/fsl.yaml | 3 +++ 1 file changed, 3 insertions(+) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/arm/fsl.yaml b/Documentation/devicetree/bindings/arm/fsl.yaml index 51b8d6fac792..c4a81884a8af 100644 --- a/Documentation/devicetree/bindings/arm/fsl.yaml +++ b/Documentation/devicetree/bindings/arm/fsl.yaml @@ -674,6 +674,9 @@ properties: - beacon,imx8mm-beacon-kit # i.MX8MM Beacon Development Kit - fsl,imx8mm-ddr4-evk # i.MX8MM DDR4 EVK Board - fsl,imx8mm-evk # i.MX8MM EVK Board + - gw,imx8mm-gw71xx-0x # i.MX8MM Gateworks Development Kit + - gw,imx8mm-gw72xx-0x # i.MX8MM Gateworks Development Kit + - gw,imx8mm-gw73xx-0x # i.MX8MM Gateworks Development Kit - kontron,imx8mm-n801x-som # i.MX8MM Kontron SL (N801X) SOM - variscite,var-som-mx8mm # i.MX8MM Variscite VAR-SOM-MX8MM module - const: fsl,imx8mm -- cgit v1.2.3 From 002c73209e9dfbfb8ba997610e1f63e2e62335e2 Mon Sep 17 00:00:00 2001 From: Oleksij Rempel Date: Wed, 6 Jan 2021 10:04:13 +0100 Subject: dt-bindings: arm: fsl: add Protonic MVT board Add Protonic MVT imx6dl based board Signed-off-by: Oleksij Rempel Acked-by: Rob Herring Signed-off-by: Shawn Guo --- Documentation/devicetree/bindings/arm/fsl.yaml | 1 + 1 file changed, 1 insertion(+) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/arm/fsl.yaml b/Documentation/devicetree/bindings/arm/fsl.yaml index c4a81884a8af..c39840f0f3aa 100644 --- a/Documentation/devicetree/bindings/arm/fsl.yaml +++ b/Documentation/devicetree/bindings/arm/fsl.yaml @@ -367,6 +367,7 @@ properties: - ply,plybas # Plymovent BAS board - ply,plym2m # Plymovent M2M board - poslab,imx6dl-savageboard # Poslab SavageBoard Dual + - prt,prtmvt # Protonic MVT board - prt,prtrvt # Protonic RVT board - prt,prtvt7 # Protonic VT7 board - rex,imx6dl-rex-basic # Rex Basic i.MX6 Dual Lite Board -- cgit v1.2.3 From 60f95bf61edda3abfc5b01f1093e98ebc87439f4 Mon Sep 17 00:00:00 2001 From: Oleksij Rempel Date: Thu, 7 Jan 2021 09:52:32 +0100 Subject: dt-bindings: arm: fsl: add Protonic PRTI6G board Add Protonic Holland PRTI6G, iMX6UL based board Signed-off-by: Oleksij Rempel Acked-by: Rob Herring Signed-off-by: Shawn Guo --- Documentation/devicetree/bindings/arm/fsl.yaml | 1 + 1 file changed, 1 insertion(+) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/arm/fsl.yaml b/Documentation/devicetree/bindings/arm/fsl.yaml index c39840f0f3aa..b99137c80a5a 100644 --- a/Documentation/devicetree/bindings/arm/fsl.yaml +++ b/Documentation/devicetree/bindings/arm/fsl.yaml @@ -491,6 +491,7 @@ properties: - karo,imx6ul-tx6ul # Ka-Ro electronics TXUL-0010 Module - kontron,imx6ul-n6310-som # Kontron N6310 SOM - kontron,imx6ul-n6311-som # Kontron N6311 SOM + - prt,prti6g # Protonic PRTI6G Board - technexion,imx6ul-pico-dwarf # TechNexion i.MX6UL Pico-Dwarf - technexion,imx6ul-pico-hobbit # TechNexion i.MX6UL Pico-Hobbit - technexion,imx6ul-pico-pi # TechNexion i.MX6UL Pico-Pi -- cgit v1.2.3 From d22782c03d896da9dc2f4df45ba1620912ec9e17 Mon Sep 17 00:00:00 2001 From: Teresa Remmet Date: Thu, 7 Jan 2021 10:12:10 +0100 Subject: bindings: arm: fsl: Add PHYTEC i.MX8MP devicetree bindings Add devicetree bindings for i.MX8MP based phyCORE-i.MX8MP and phyBOARD-Pollux RDK. Signed-off-by: Teresa Remmet Reviewed-by: Krzysztof Kozlowski Acked-by: Rob Herring Signed-off-by: Shawn Guo --- Documentation/devicetree/bindings/arm/fsl.yaml | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/arm/fsl.yaml b/Documentation/devicetree/bindings/arm/fsl.yaml index b99137c80a5a..2ae66407e2aa 100644 --- a/Documentation/devicetree/bindings/arm/fsl.yaml +++ b/Documentation/devicetree/bindings/arm/fsl.yaml @@ -715,6 +715,12 @@ properties: - fsl,imx8mp-evk # i.MX8MP EVK Board - const: fsl,imx8mp + - description: PHYTEC phyCORE-i.MX8MP SoM based boards + items: + - const: phytec,imx8mp-phyboard-pollux-rdk # phyBOARD-Pollux RDK + - const: phytec,imx8mp-phycore-som # phyCORE-i.MX8MP SoM + - const: fsl,imx8mp + - description: i.MX8MQ based Boards items: - enum: -- cgit v1.2.3 From 3a4928cf5e3c91fc9703992358db23202ee3e82f Mon Sep 17 00:00:00 2001 From: Joe Pater <02joepater06@gmail.com> Date: Mon, 11 Jan 2021 10:32:41 +0000 Subject: Documentation: kernel-hacking: change 'current()' to 'current' Change 'current()' heading to 'current' to reflect usage. Signed-off-by: Joe Pater <02joepater06@gmail.com> Link: https://lore.kernel.org/r/20210111103240.7445-1-02joepater06@gmail.com Signed-off-by: Jonathan Corbet --- Documentation/kernel-hacking/hacking.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'Documentation') diff --git a/Documentation/kernel-hacking/hacking.rst b/Documentation/kernel-hacking/hacking.rst index eed2136d847f..451523424942 100644 --- a/Documentation/kernel-hacking/hacking.rst +++ b/Documentation/kernel-hacking/hacking.rst @@ -346,8 +346,8 @@ routine. Before inventing your own cache of often-used objects consider using a slab cache in ``include/linux/slab.h`` -:c:func:`current()` -------------------- +:c:macro:`current` +------------------ Defined in ``include/asm/current.h`` -- cgit v1.2.3 From 05a5f51ca566674e6a6ee9cef0af1b00bf100d67 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Sun, 10 Jan 2021 12:41:44 -0800 Subject: Documentation: Replace lkml.org links with lore Replace the lkml.org links with lore to better use a single source that's more likely to stay available long-term. Done by bash script: cvt_lkml_to_lore () { tmpfile=$(mktemp ./.cvt_links.XXXXXXX) header=$(echo $1 | sed 's@/lkml/@/lkml/headers/@') wget -qO - $header > $tmpfile if [[ $? == 0 ]] ; then link=$(grep -i '^Message-Id:' $tmpfile | head -1 | \ sed -r -e 's/^\s*Message-Id:\s*<\s*//' -e 's/\s*>\s*$//' -e 's@^@https://lore.kernel.org/r/@') # echo "testlink: $link" if [ -n "$link" ] ; then wget -qO - $link > /dev/null if [[ $? == 0 ]] ; then echo $link fi fi fi rm -f $tmpfile } git grep -P -o "\bhttps?://(?:www.)?lkml.org/lkml[\/\w]+" $@ | while read line ; do echo $line file=$(echo $line | cut -f1 -d':') link=$(echo $line | cut -f2- -d':') newlink=$(cvt_lkml_to_lore $link) if [[ -n "$newlink" ]] ; then sed -i -e "s#\b$link\b#$newlink#" $file fi done Link: https://lore.kernel.org/patchwork/patch/1265849/#1462688 Signed-off-by: Joe Perches Link: https://lore.kernel.org/r/77cdb7f32cfb087955bfc3600b86c40bed5d4104.camel@perches.com Signed-off-by: Jonathan Corbet --- Documentation/RCU/RTFP.txt | 94 +++++++++++----------- Documentation/accounting/cgroupstats.rst | 4 +- Documentation/admin-guide/cgroup-v1/memory.rst | 14 ++-- Documentation/admin-guide/cpu-load.rst | 2 +- .../admin-guide/kernel-per-CPU-kthreads.rst | 2 +- Documentation/driver-api/gpio/driver.rst | 4 +- Documentation/gpu/todo.rst | 2 +- Documentation/power/freezing-of-tasks.rst | 2 +- Documentation/process/adding-syscalls.rst | 18 ++--- Documentation/process/submitting-patches.rst | 4 +- Documentation/scheduler/sched-deadline.rst | 2 +- Documentation/security/lsm-development.rst | 2 +- Documentation/timers/timers-howto.rst | 2 +- .../translations/it_IT/process/adding-syscalls.rst | 18 ++--- .../it_IT/process/submitting-patches.rst | 4 +- Documentation/translations/ja_JP/SubmittingPatches | 4 +- .../translations/zh_CN/admin-guide/cpu-load.rst | 2 +- .../zh_CN/process/submitting-patches.rst | 4 +- 18 files changed, 92 insertions(+), 92 deletions(-) (limited to 'Documentation') diff --git a/Documentation/RCU/RTFP.txt b/Documentation/RCU/RTFP.txt index 9bccf16736f7..3b0876c77355 100644 --- a/Documentation/RCU/RTFP.txt +++ b/Documentation/RCU/RTFP.txt @@ -683,7 +683,7 @@ Orran Krieger and Rusty Russell and Dipankar Sarma and Maneesh Soni" ,month="October" ,year="2001" ,note="Available: -\url{http://lkml.org/lkml/2001/10/13/105} +\url{https://lore.kernel.org/r/Pine.LNX.4.33.0110131015410.8707-100000@penguin.transmeta.com} [Viewed August 21, 2004]" ,annotation={ } @@ -826,7 +826,7 @@ Symposium on Distributed Computing} ,month="October" ,year="2002" ,note="Available: -\url{https://lkml.org/lkml/2002/10/24/262} +\url{https://lore.kernel.org/r/3DB86B05.447E7410@us.ibm.com} [Viewed February 15, 2014]" ,annotation={ Mingming Cao's patch to introduce RCU to SysV IPC. @@ -839,7 +839,7 @@ Symposium on Distributed Computing} ,month="March" ,year="2003" ,note="Available: -\url{http://lkml.org/lkml/2003/3/9/205} +\url{https://lore.kernel.org/r/Pine.LNX.4.44.0303091831560.2129-100000@home.transmeta.com} [Viewed March 13, 2006]" ,annotation={ Linus suggests replacing brlock with RCU and/or seqlocks: @@ -1036,15 +1036,15 @@ Add per-cpu batch counter" ,annotation={ RCU runs reasonably on a 512-CPU SGI using Manfred Spraul's patches, which may be found at: - https://lkml.org/lkml/2004/5/20/49 (split vars into cachelines) - https://lkml.org/lkml/2004/5/22/114 (cpu_quiet() patch) - https://lkml.org/lkml/2004/5/25/24 (0/5) - https://lkml.org/lkml/2004/5/25/23 (1/5) - https://lkml.org/lkml/2004/5/25/265 (works for Jack) - https://lkml.org/lkml/2004/5/25/20 (2/5) - https://lkml.org/lkml/2004/5/25/22 (3/5) - https://lkml.org/lkml/2004/5/25/19 (4/5) - https://lkml.org/lkml/2004/5/25/21 (5/5) + https://lore.kernel.org/r/40AC9823.6020709@colorfullife.com (split vars into cachelines) + https://lore.kernel.org/r/Pine.LNX.4.44.0405222141260.11106-100000@dbl.q-ag.de (cpu_quiet() patch) + https://lore.kernel.org/r/200405250535.i4P5ZJo8017583@dbl.q-ag.de (0/5) + https://lore.kernel.org/r/200405250535.i4P5ZKAQ017591@dbl.q-ag.de (1/5) + https://lore.kernel.org/r/20040525203215.GB5127@sgi.com (works for Jack) + https://lore.kernel.org/r/200405250535.i4P5ZLiR017599@dbl.q-ag.de (2/5) + https://lore.kernel.org/r/200405250535.i4P5ZMFt017607@dbl.q-ag.de (3/5) + https://lore.kernel.org/r/200405250535.i4P5ZN6g017615@dbl.q-ag.de (4/5) + https://lore.kernel.org/r/200405250535.i4P5ZO7I017623@dbl.q-ag.de (5/5) } } @@ -1106,7 +1106,7 @@ Oregon Health and Sciences University" ,month="August" ,year="2004" ,note="Available: -\url{http://lkml.org/lkml/2004/8/6/237} +\url{https://lore.kernel.org/r/20040807192424.GF3936@in.ibm.com} [Viewed June 8, 2010]" ,annotation={ Introduce rcu_dereference(). @@ -1119,7 +1119,7 @@ Oregon Health and Sciences University" ,month="August" ,year="2004" ,note="Available: -\url{http://lkml.org/lkml/2004/8/30/87} +\url{https://lore.kernel.org/r/1093873222.984.12.camel@new.localdomain} [Viewed February 17, 2005]" ,annotation={ Uses active code in rcu_read_lock() and rcu_read_unlock() to @@ -1186,7 +1186,7 @@ Oregon Health and Sciences University" ,month="October" ,year="2004" ,note="Available: -\url{http://lkml.org/lkml/2004/10/23/241} +\url{https://lore.kernel.org/r/20041023202723.GA1930@us.ibm.com} [Viewed June 8, 2010]" ,annotation={ Introduce rcu_assign_pointer(). @@ -1203,7 +1203,7 @@ Oregon Health and Sciences University" ,annotation={ James Morris posts Kaigai Kohei's patch to LKML. [Viewed December 10, 2004] - Kaigai's patch is at https://lkml.org/lkml/2004/9/27/52 + Kaigai's patch is at https://lore.kernel.org/r/200409271057.i8RAvcA1007873@mailsv.bs1.fc.nec.co.jp } } @@ -1241,7 +1241,7 @@ Oregon Health and Sciences University" ,year="2005" ,day="17" ,note="Available: -\url{http://lkml.org/lkml/2005/3/17/199} +\url{https://lore.kernel.org/r/20050318002026.GA2693@us.ibm.com} [Viewed September 5, 2005]" ,annotation={ First posting showing how RCU can be safely adapted for @@ -1256,7 +1256,7 @@ Oregon Health and Sciences University" ,year="2005" ,day="18" ,note="Available: -\url{http://lkml.org/lkml/2005/3/18/122} +\url{https://lore.kernel.org/r/Pine.OSF.4.05.10503181336310.2466-100000@da410.phys.au.dk} [Viewed March 30, 2006]" ,annotation={ Esben Neilsen suggests read-side suppression of grace-period @@ -1302,7 +1302,7 @@ Data Structures" ,month="May" ,year="2005" ,note="Available: -\url{http://lkml.org/lkml/2005/5/9/185} +\url{https://lore.kernel.org/r/20050510012444.GA3011@us.ibm.com} [Viewed May 13, 2005]" ,annotation={ First publication of working lock-based deferred free patches @@ -1385,7 +1385,7 @@ Data Structures" ,day="1" ,year="2005" ,note="Available: -\url{http://lkml.org/lkml/2005/8/1/155} +\url{https://lore.kernel.org/r/20050801171137.GA1754@us.ibm.com} [Viewed March 14, 2006]" ,annotation={ First operating counter-based realtime RCU patch posted to LKML. @@ -1399,7 +1399,7 @@ Data Structures" ,day="8" ,year="2005" ,note="Available: -\url{http://lkml.org/lkml/2005/8/8/108} +\url{https://lore.kernel.org/r/20050808144216.GA1307@us.ibm.com} [Viewed March 14, 2006]" ,annotation={ First operating counter-based realtime RCU patch posted to LKML, @@ -1415,7 +1415,7 @@ Data Structures" ,day="1" ,year="2005" ,note="Available: -\url{http://lkml.org/lkml/2005/10/1/70} +\url{https://lore.kernel.org/r/20051001182056.GA1613@us.ibm.com} [Viewed March 14, 2006]" ,annotation={ First rcutorture patch. @@ -1429,7 +1429,7 @@ Data Structures" ,day="6" ,year="2006" ,note="Available: -\url{https://lkml.org/lkml/2006/1/7/22} +\url{https://lore.kernel.org/r/20060106.231054.43576567.davem@davemloft.net} [Viewed February 29, 2012]" ,annotation={ David Miller's view on hashed arrays of locks: used to really @@ -1464,7 +1464,7 @@ Distributed Processing Symposium" ,day="20" ,year="2006" ,note="Available: -\url{http://lkml.org/lkml/2006/6/20/238} +\url{https://lore.kernel.org/r/20060408134707.22479.33814.sendpatchset@linux.site} [Viewed March 25, 2008]" ,annotation={ RCU-protected radix tree. @@ -1554,7 +1554,7 @@ Revised: ,day="28" ,year="2006" ,note="Available: -\url{http://lkml.org/lkml/2006/9/28/160} +\url{https://lore.kernel.org/r/20060928142616.GA20185@infradead.org} [Viewed March 27, 2008]" } @@ -1593,7 +1593,7 @@ Revised: ,year="2006" ,day=26 ,note="Available: -\url{http://lkml.org/lkml/2006/10/26/73} +\url{https://lore.kernel.org/r/20061026105731.GE11803@in.ibm.com} [Viewed January 26, 2009]" ,annotation={ RCU-based reader-writer lock that allows readers to proceed with @@ -1612,12 +1612,12 @@ Revised: ,year="2006" ,day=17 ,note="Available: -\url{http://lkml.org/lkml/2006/11/17/56} +\url{https://lore.kernel.org/r/20061117092925.GT7164@kernel.dk} [Viewed May 28, 2007]" ,annotation={ SRCU's grace periods are too slow for Jens, even after a factor-of-three speedup. - Sped-up version of SRCU at http://lkml.org/lkml/2006/11/17/359. + Sped-up version of SRCU at https://lore.kernel.org/r/20061118002845.GF2632@us.ibm.com. } } @@ -1629,7 +1629,7 @@ Revised: ,year="2006" ,day=19 ,note="Available: -\url{http://lkml.org/lkml/2006/11/19/69} +\url{https://lore.kernel.org/r/20061119190027.GA3676@oleg} [Viewed May 28, 2007]" ,annotation={ First cut of QRCU. Expanded/corrected versions followed. @@ -1644,7 +1644,7 @@ Revised: ,year="2006" ,day=30 ,note="Available: -\url{http://lkml.org/lkml/2006/11/29/330} +\url{https://lore.kernel.org/r/20061130015714.GC1350@oleg} [Viewed November 26, 2008]" ,annotation={ Expanded/corrected version of QRCU. @@ -1709,7 +1709,7 @@ Revised: ,year="2007" ,day=3 ,note="Available: -\url{http://lkml.org/lkml/2007/1/3/112} +\url{https://lore.kernel.org/r/20070103152738.GA16063@localdomain} [Viewed May 28, 2007]" ,annotation={ Patch for list_splice_rcu(). @@ -1737,7 +1737,7 @@ Revised: ,year="2007" ,day=28 ,note="Available: -\url{http://lkml.org/lkml/2007/1/28/34} +\url{https://lore.kernel.org/r/20070128120509.719287000@programming.kicks-ass.net} [Viewed March 27, 2008]" ,annotation={ RCU-like implementation for frequent updaters and rare readers(!). @@ -1767,7 +1767,7 @@ Revised: ,year="2007" ,day=24 ,note="Available: -\url{http://lkml.org/lkml/2007/2/25/18} +\url{https://lore.kernel.org/r/20070225062349.GA17468@linux.vnet.ibm.com} [Viewed March 27, 2008]" ,annotation={ Patch for QRCU supplying lock-free fast path. @@ -1846,7 +1846,7 @@ Revised: ,annotation={ LWN article describing Promela and spin, and also using Oleg Nesterov's QRCU as an example (with Paul McKenney's fastpath). - Merged patch at: http://lkml.org/lkml/2007/2/25/18 + Merged patch at: https://lore.kernel.org/r/20070225062349.GA17468@linux.vnet.ibm.com } } @@ -1885,7 +1885,7 @@ Revised: ,day="10" ,year="2007" ,note="Available: -\url{http://lkml.org/lkml/2007/9/10/213} +\url{https://lore.kernel.org/r/20070910183004.GA3299@linux.vnet.ibm.com} [Viewed October 25, 2007]" ,annotation={ Final patch for preemptable RCU to -rt. (Later patches were @@ -1933,7 +1933,7 @@ Revised: ,day="20" ,year="2007" ,note="Available: -\url{http://lkml.org/lkml/2007/12/20/244} +\url{https://lore.kernel.org/r/20071220142540.GB22523@Krystal} [Viewed March 27, 2008]" ,annotation={ Request for call_rcu_sched() and rcu_barrier_sched(). @@ -2013,7 +2013,7 @@ Revised: ,day="29" ,year="2008" ,note="Available: -\url{http://lkml.org/lkml/2008/1/29/208} +\url{https://lore.kernel.org/r/Pine.LNX.4.58.0801291113350.20371@gandalf.stny.rr.com} [Viewed March 27, 2008]" ,annotation={ Patch that prevents preemptible RCU from unnecessarily waking @@ -2028,7 +2028,7 @@ Revised: ,day="1" ,year="2008" ,note="Available: -\url{http://lkml.org/lkml/2008/2/2/255} +\url{https://lore.kernel.org/r/20080202214124.GA28612@linux.vnet.ibm.com} [Viewed October 18, 2008]" ,annotation={ Explanation of compilers violating dependency ordering. @@ -2088,7 +2088,7 @@ lot of {Linux} into your technology!!!" ,day="3" ,year="2008" ,note="Available: -\url{http://lkml.org/lkml/2008/6/2/539} +\url{https://lore.kernel.org/r/4844BE83.5010401@cn.fujitsu.com} [Viewed December 10, 2008]" ,annotation={ Updated RCU classic algorithm. Introduced multi-tailed list @@ -2122,7 +2122,7 @@ lot of {Linux} into your technology!!!" ,day="21" ,year="2008" ,note="Available: -\url{http://lkml.org/lkml/2008/8/21/336} +\url{https://lore.kernel.org/r/48AD8969.7060900@colorfullife.com} [Viewed December 8, 2008]" ,annotation={ State-based RCU. One key thing that this patch does is to @@ -2137,7 +2137,7 @@ lot of {Linux} into your technology!!!" ,day="6" ,year="2008" ,note="Available: -\url{http://lkml.org/lkml/2008/9/6/86} +\url{https://lore.kernel.org/r/48C2B1D2.5070801@colorfullife.com} [Viewed December 8, 2008]" ,annotation={ Manfred notes a fix required to my attempt to separate irq @@ -2183,7 +2183,7 @@ lot of {Linux} into your technology!!!" ,day="14" ,year="2009" ,note="Available: -\url{http://lkml.org/lkml/2009/1/14/449} +\url{https://lore.kernel.org/r/20090114202044.GJ6734@linux.vnet.ibm.com} [Viewed January 15, 2009]" ,annotation={ Small-footprint implementation of RCU for uniprocessor @@ -2218,7 +2218,7 @@ lot of {Linux} into your technology!!!" git://lttng.org/userspace-rcu.git http://lttng.org/cgi-bin/gitweb.cgi?p=userspace-rcu.git http://lttng.org/urcu - http://lkml.org/lkml/2009/2/5/572 + https://lore.kernel.org/r/20090206030543.GB8560@Krystal } } @@ -2258,7 +2258,7 @@ lot of {Linux} into your technology!!!" ,day="25" ,year="2009" ,note="Available: -\url{http://lkml.org/lkml/2009/6/25/306} +\url{https://lore.kernel.org/r/20090625160706.GA9467@linux.vnet.ibm.com} [Viewed August 16, 2009]" ,annotation={ First posting of expedited RCU to be accepted into -tip. @@ -2272,7 +2272,7 @@ lot of {Linux} into your technology!!!" ,day="23" ,year="2009" ,note="Available: -\url{http://lkml.org/lkml/2009/7/23/294} +\url{https://lore.kernel.org/r/20090724001429.GA17374@linux.vnet.ibm.com} [Viewed August 15, 2009]" ,annotation={ First posting of simple and fast preemptable RCU. @@ -2350,7 +2350,7 @@ lot of {Linux} into your technology!!!" ,month="December" ,year="2009" ,note="Available: -\url{http://lkml.org/lkml/2009/10/18/129} +\url{https://lore.kernel.org/r/20091018232918.GA7385@Krystal} [Viewed December 29, 2009]" ,annotation={ Mathieu proposed defer_rcu() with fixed-size per-thread pool @@ -2518,7 +2518,7 @@ lot of {Linux} into your technology!!!" ,month="January" ,year="2011" ,note="Available: -\url{https://lkml.org/lkml/2011/1/18/322} +\url{https://lore.kernel.org/r/AANLkTimajU0x1v6y3rH2+jr-bZ=tNLs1S_agXdGGAa3S@mail.gmail.com} [Viewed March 4, 2011]" ,annotation={ "The RCU-based name lookup is at the other end of the spectrum - the diff --git a/Documentation/accounting/cgroupstats.rst b/Documentation/accounting/cgroupstats.rst index b9afc48f4ea2..85186e7d4035 100644 --- a/Documentation/accounting/cgroupstats.rst +++ b/Documentation/accounting/cgroupstats.rst @@ -3,8 +3,8 @@ Control Groupstats ================== Control Groupstats is inspired by the discussion at -http://lkml.org/lkml/2007/4/11/187 and implements per cgroup statistics as -suggested by Andrew Morton in http://lkml.org/lkml/2007/4/11/263. +https://lore.kernel.org/r/461CF883.2030308@sw.ru and implements per cgroup statistics as +suggested by Andrew Morton in https://lore.kernel.org/r/20070411114927.1277d7c9.akpm@linux-foundation.org. Per cgroup statistics infrastructure re-uses code from the taskstats interface. A new set of cgroup operations are registered with commands diff --git a/Documentation/admin-guide/cgroup-v1/memory.rst b/Documentation/admin-guide/cgroup-v1/memory.rst index 52688ae34461..0936412e044e 100644 --- a/Documentation/admin-guide/cgroup-v1/memory.rst +++ b/Documentation/admin-guide/cgroup-v1/memory.rst @@ -963,21 +963,21 @@ References 2. Singh, Balbir. Memory Controller (RSS Control), http://lwn.net/Articles/222762/ 3. Emelianov, Pavel. Resource controllers based on process cgroups - http://lkml.org/lkml/2007/3/6/198 + https://lore.kernel.org/r/45ED7DEC.7010403@sw.ru 4. Emelianov, Pavel. RSS controller based on process cgroups (v2) - http://lkml.org/lkml/2007/4/9/78 + https://lore.kernel.org/r/461A3010.90403@sw.ru 5. Emelianov, Pavel. RSS controller based on process cgroups (v3) - http://lkml.org/lkml/2007/5/30/244 + https://lore.kernel.org/r/465D9739.8070209@openvz.org 6. Menage, Paul. Control Groups v10, http://lwn.net/Articles/236032/ 7. Vaidyanathan, Srinivasan, Control Groups: Pagecache accounting and control subsystem (v3), http://lwn.net/Articles/235534/ 8. Singh, Balbir. RSS controller v2 test results (lmbench), - http://lkml.org/lkml/2007/5/17/232 + https://lore.kernel.org/r/464C95D4.7070806@linux.vnet.ibm.com 9. Singh, Balbir. RSS controller v2 AIM9 results - http://lkml.org/lkml/2007/5/18/1 + https://lore.kernel.org/r/464D267A.50107@linux.vnet.ibm.com 10. Singh, Balbir. Memory controller v6 test results, - http://lkml.org/lkml/2007/8/19/36 + https://lore.kernel.org/r/20070819094658.654.84837.sendpatchset@balbir-laptop 11. Singh, Balbir. Memory controller introduction (v6), - http://lkml.org/lkml/2007/8/17/69 + https://lore.kernel.org/r/20070817084228.26003.12568.sendpatchset@balbir-laptop 12. Corbet, Jonathan, Controlling memory use in cgroups, http://lwn.net/Articles/243795/ diff --git a/Documentation/admin-guide/cpu-load.rst b/Documentation/admin-guide/cpu-load.rst index f3ada90e9ca8..21a984337080 100644 --- a/Documentation/admin-guide/cpu-load.rst +++ b/Documentation/admin-guide/cpu-load.rst @@ -107,7 +107,7 @@ will lead to quite erratic information inside ``/proc/stat``:: References ---------- -- http://lkml.org/lkml/2007/2/12/6 +- https://lore.kernel.org/r/loom.20070212T063225-663@post.gmane.org - Documentation/filesystems/proc.rst (1.8) diff --git a/Documentation/admin-guide/kernel-per-CPU-kthreads.rst b/Documentation/admin-guide/kernel-per-CPU-kthreads.rst index dc36aeb65d0a..531f689311f2 100644 --- a/Documentation/admin-guide/kernel-per-CPU-kthreads.rst +++ b/Documentation/admin-guide/kernel-per-CPU-kthreads.rst @@ -273,7 +273,7 @@ To reduce its OS jitter, do any of the following: However, there is an RFC patch from Christoph Lameter (based on an earlier one from Gilad Ben-Yossef) that reduces or even eliminates vmstat overhead for some - workloads at https://lkml.org/lkml/2013/9/4/379. + workloads at https://lore.kernel.org/r/00000140e9dfd6bd-40db3d4f-c1be-434f-8132-7820f81bb586-000000@email.amazonses.com. e. If running on high-end powerpc servers, build with CONFIG_PPC_RTAS_DAEMON=n. This prevents the RTAS daemon from running on each CPU every second or so. diff --git a/Documentation/driver-api/gpio/driver.rst b/Documentation/driver-api/gpio/driver.rst index 0fb57e298b41..d6b0d779859b 100644 --- a/Documentation/driver-api/gpio/driver.rst +++ b/Documentation/driver-api/gpio/driver.rst @@ -640,8 +640,8 @@ compliance: level and edge IRQs * [1] http://www.spinics.net/lists/linux-omap/msg120425.html -* [2] https://lkml.org/lkml/2015/9/25/494 -* [3] https://lkml.org/lkml/2015/9/25/495 +* [2] https://lore.kernel.org/r/1443209283-20781-2-git-send-email-grygorii.strashko@ti.com +* [3] https://lore.kernel.org/r/1443209283-20781-3-git-send-email-grygorii.strashko@ti.com Requesting self-owned GPIO pins diff --git a/Documentation/gpu/todo.rst b/Documentation/gpu/todo.rst index 009d8e6c7e3c..d42c22567c5d 100644 --- a/Documentation/gpu/todo.rst +++ b/Documentation/gpu/todo.rst @@ -669,7 +669,7 @@ for fbdev. https://patchwork.freedesktop.org/patch/306579/ - [RFC PATCH v2 00/13] Kernel based bootsplash - https://lkml.org/lkml/2017/12/13/764 + https://lore.kernel.org/r/20171213194755.3409-1-mstaudt@suse.de Contact: Sam Ravnborg diff --git a/Documentation/power/freezing-of-tasks.rst b/Documentation/power/freezing-of-tasks.rst index 8bd693399834..53b6a56c4635 100644 --- a/Documentation/power/freezing-of-tasks.rst +++ b/Documentation/power/freezing-of-tasks.rst @@ -134,7 +134,7 @@ Generally speaking, there is a couple of reasons to use the freezing of tasks: safeguards against race conditions that might occur in such a case. Although Linus Torvalds doesn't like the freezing of tasks, he said this in one -of the discussions on LKML (http://lkml.org/lkml/2007/4/27/608): +of the discussions on LKML (https://lore.kernel.org/r/alpine.LFD.0.98.0704271801020.9964@woody.linux-foundation.org): "RJW:> Why we freeze tasks at all or why we freeze kernel threads? diff --git a/Documentation/process/adding-syscalls.rst b/Documentation/process/adding-syscalls.rst index a3ecb236576c..02857b5ad2b5 100644 --- a/Documentation/process/adding-syscalls.rst +++ b/Documentation/process/adding-syscalls.rst @@ -548,18 +548,18 @@ References and Sources https://lwn.net/Articles/486306/ - Recommendation from Andrew Morton that all related information for a new system call should come in the same email thread: - https://lkml.org/lkml/2014/7/24/641 + https://lore.kernel.org/r/20140724144747.3041b208832bbdf9fbce5d96@linux-foundation.org - Recommendation from Michael Kerrisk that a new system call should come with - a man page: https://lkml.org/lkml/2014/6/13/309 + a man page: https://lore.kernel.org/r/CAKgNAkgMA39AfoSoA5Pe1r9N+ZzfYQNvNPvcRN7tOvRb8+v06Q@mail.gmail.com - Suggestion from Thomas Gleixner that x86 wire-up should be in a separate - commit: https://lkml.org/lkml/2014/11/19/254 + commit: https://lore.kernel.org/r/alpine.DEB.2.11.1411191249560.3909@nanos - Suggestion from Greg Kroah-Hartman that it's good for new system calls to - come with a man-page & selftest: https://lkml.org/lkml/2014/3/19/710 + come with a man-page & selftest: https://lore.kernel.org/r/20140320025530.GA25469@kroah.com - Discussion from Michael Kerrisk of new system call vs. :manpage:`prctl(2)` extension: - https://lkml.org/lkml/2014/6/3/411 + https://lore.kernel.org/r/CAHO5Pa3F2MjfTtfNxa8LbnkeeU8=YJ+9tDqxZpw7Gz59E-4AUg@mail.gmail.com - Suggestion from Ingo Molnar that system calls that involve multiple arguments should encapsulate those arguments in a struct, which includes a - size field for future extensibility: https://lkml.org/lkml/2015/7/30/117 + size field for future extensibility: https://lore.kernel.org/r/20150730083831.GA22182@gmail.com - Numbering oddities arising from (re-)use of O_* numbering space flags: - commit 75069f2b5bfb ("vfs: renumber FMODE_NONOTIFY and add to uniqueness @@ -569,9 +569,9 @@ References and Sources - commit bb458c644a59 ("Safer ABI for O_TMPFILE") - Discussion from Matthew Wilcox about restrictions on 64-bit arguments: - https://lkml.org/lkml/2008/12/12/187 + https://lore.kernel.org/r/20081212152929.GM26095@parisc-linux.org - Recommendation from Greg Kroah-Hartman that unknown flags should be - policed: https://lkml.org/lkml/2014/7/17/577 + policed: https://lore.kernel.org/r/20140717193330.GB4703@kroah.com - Recommendation from Linus Torvalds that x32 system calls should prefer compatibility with 64-bit versions rather than 32-bit versions: - https://lkml.org/lkml/2011/8/31/244 + https://lore.kernel.org/r/CA+55aFxfmwfB7jbbrXxa=K7VBYPfAvmu3XOkGrLbB1UFjX1+Ew@mail.gmail.com diff --git a/Documentation/process/submitting-patches.rst b/Documentation/process/submitting-patches.rst index 5ba54120bef7..7c97ad580e7d 100644 --- a/Documentation/process/submitting-patches.rst +++ b/Documentation/process/submitting-patches.rst @@ -769,13 +769,13 @@ Greg Kroah-Hartman, "How to piss off a kernel subsystem maintainer". NO!!!! No more huge patch bombs to linux-kernel@vger.kernel.org people! - + Kernel Documentation/process/coding-style.rst: :ref:`Documentation/process/coding-style.rst ` Linus Torvalds's mail on the canonical patch format: - + Andi Kleen, "On submitting kernel patches" Some strategies to get difficult or controversial changes in. diff --git a/Documentation/scheduler/sched-deadline.rst b/Documentation/scheduler/sched-deadline.rst index 14a2f7bf63fe..9d9be52f221a 100644 --- a/Documentation/scheduler/sched-deadline.rst +++ b/Documentation/scheduler/sched-deadline.rst @@ -707,7 +707,7 @@ Deadline Task Scheduling and how to prevent non-root users "cheat" the system? As already discussed, we are planning also to merge this work with the EDF - throttling patches [https://lkml.org/lkml/2010/2/23/239] but we still are in + throttling patches [https://lore.kernel.org/r/cover.1266931410.git.fabio@helm.retis] but we still are in the preliminary phases of the merge and we really seek feedback that would help us decide on the direction it should take. diff --git a/Documentation/security/lsm-development.rst b/Documentation/security/lsm-development.rst index 31d92bc5fdd2..ac53e5065f79 100644 --- a/Documentation/security/lsm-development.rst +++ b/Documentation/security/lsm-development.rst @@ -2,7 +2,7 @@ Linux Security Module Development ================================= -Based on https://lkml.org/lkml/2007/10/26/215, +Based on https://lore.kernel.org/r/20071026073721.618b4778@laptopd505.fenrus.org, a new LSM is accepted into the kernel when its intent (a description of what it tries to protect against and in what cases one would expect to use it) has been appropriately documented in ``Documentation/admin-guide/LSM/``. diff --git a/Documentation/timers/timers-howto.rst b/Documentation/timers/timers-howto.rst index afb0a43b8cdf..5c169e3d29a8 100644 --- a/Documentation/timers/timers-howto.rst +++ b/Documentation/timers/timers-howto.rst @@ -75,7 +75,7 @@ NON-ATOMIC CONTEXT: - Why not msleep for (1ms - 20ms)? Explained originally here: - http://lkml.org/lkml/2007/8/3/250 + https://lore.kernel.org/r/15327.1186166232@lwn.net msleep(1~20) may not do what the caller intends, and will often sleep longer (~20 ms actual sleep for any diff --git a/Documentation/translations/it_IT/process/adding-syscalls.rst b/Documentation/translations/it_IT/process/adding-syscalls.rst index bff0a82bf127..c478b6e8c292 100644 --- a/Documentation/translations/it_IT/process/adding-syscalls.rst +++ b/Documentation/translations/it_IT/process/adding-syscalls.rst @@ -611,21 +611,21 @@ Riferimenti e fonti https://lwn.net/Articles/486306/ - Raccomandazioni da Andrew Morton circa il fatto che tutte le informazioni su una nuova chiamata di sistema dovrebbero essere contenute nello stesso - filone di discussione di email: https://lkml.org/lkml/2014/7/24/641 + filone di discussione di email: https://lore.kernel.org/r/20140724144747.3041b208832bbdf9fbce5d96@linux-foundation.org - Raccomandazioni da Michael Kerrisk circa il fatto che le nuove chiamate di - sistema dovrebbero avere una pagina man: https://lkml.org/lkml/2014/6/13/309 + sistema dovrebbero avere una pagina man: https://lore.kernel.org/r/CAKgNAkgMA39AfoSoA5Pe1r9N+ZzfYQNvNPvcRN7tOvRb8+v06Q@mail.gmail.com - Consigli da Thomas Gleixner sul fatto che il collegamento all'architettura x86 dovrebbe avvenire in un *commit* differente: - https://lkml.org/lkml/2014/11/19/254 + https://lore.kernel.org/r/alpine.DEB.2.11.1411191249560.3909@nanos - Consigli da Greg Kroah-Hartman circa la bontà d'avere una pagina man e un programma di auto-verifica per le nuove chiamate di sistema: - https://lkml.org/lkml/2014/3/19/710 + https://lore.kernel.org/r/20140320025530.GA25469@kroah.com - Discussione di Michael Kerrisk sulle nuove chiamate di sistema contro - le estensioni :manpage:`prctl(2)`: https://lkml.org/lkml/2014/6/3/411 + le estensioni :manpage:`prctl(2)`: https://lore.kernel.org/r/CAHO5Pa3F2MjfTtfNxa8LbnkeeU8=YJ+9tDqxZpw7Gz59E-4AUg@mail.gmail.com - Consigli da Ingo Molnar che le chiamate di sistema con più argomenti dovrebbero incapsularli in una struttura che includa un argomento *size* per garantire l'estensibilità futura: - https://lkml.org/lkml/2015/7/30/117 + https://lore.kernel.org/r/20150730083831.GA22182@gmail.com - Un certo numero di casi strani emersi dall'uso (riuso) dei flag O_*: - commit 75069f2b5bfb ("vfs: renumber FMODE_NONOTIFY and add to uniqueness @@ -635,9 +635,9 @@ Riferimenti e fonti - commit bb458c644a59 ("Safer ABI for O_TMPFILE") - Discussion from Matthew Wilcox about restrictions on 64-bit arguments: - https://lkml.org/lkml/2008/12/12/187 + https://lore.kernel.org/r/20081212152929.GM26095@parisc-linux.org - Raccomandazioni da Greg Kroah-Hartman sul fatto che i flag sconosciuti dovrebbero - essere controllati: https://lkml.org/lkml/2014/7/17/577 + essere controllati: https://lore.kernel.org/r/20140717193330.GB4703@kroah.com - Raccomandazioni da Linus Torvalds che le chiamate di sistema x32 dovrebbero favorire la compatibilità con le versioni a 64-bit piuttosto che quelle a 32-bit: - https://lkml.org/lkml/2011/8/31/244 + https://lore.kernel.org/r/CA+55aFxfmwfB7jbbrXxa=K7VBYPfAvmu3XOkGrLbB1UFjX1+Ew@mail.gmail.com diff --git a/Documentation/translations/it_IT/process/submitting-patches.rst b/Documentation/translations/it_IT/process/submitting-patches.rst index 966cd3242a60..ae00352346ed 100644 --- a/Documentation/translations/it_IT/process/submitting-patches.rst +++ b/Documentation/translations/it_IT/process/submitting-patches.rst @@ -731,13 +731,13 @@ Greg Kroah-Hartman, "Come scocciare un manutentore di un sottosistema" No!!!! Basta gigantesche bombe patch alle persone sulla lista linux-kernel@vger.kernel.org! - + Kernel Documentation/translations/it_IT/process/coding-style.rst: :ref:`Documentation/translations/it_IT/process/coding-style.rst ` E-mail di Linus Torvalds sul formato canonico di una patch: - + Andi Kleen, "Su come sottomettere patch del kernel" Alcune strategie su come sottomettere modifiche toste o controverse. diff --git a/Documentation/translations/ja_JP/SubmittingPatches b/Documentation/translations/ja_JP/SubmittingPatches index dd0c3280ba5a..6854f5add72e 100644 --- a/Documentation/translations/ja_JP/SubmittingPatches +++ b/Documentation/translations/ja_JP/SubmittingPatches @@ -702,13 +702,13 @@ Greg Kroah-Hartman, "How to piss off a kernel subsystem maintainer". NO!!!! No more huge patch bombs to linux-kernel@vger.kernel.org people! - + Kernel Documentation/process/coding-style.rst: Linus Torvalds's mail on the canonical patch format: - + Andi Kleen, "On submitting kernel patches" Some strategies to get difficult or controversial changes in. diff --git a/Documentation/translations/zh_CN/admin-guide/cpu-load.rst b/Documentation/translations/zh_CN/admin-guide/cpu-load.rst index c972731c0e57..a73400a054ff 100644 --- a/Documentation/translations/zh_CN/admin-guide/cpu-load.rst +++ b/Documentation/translations/zh_CN/admin-guide/cpu-load.rst @@ -95,7 +95,7 @@ Linux通过``/proc/stat``和``/proc/uptime``导出各种信息,用户空间工 参考 --- -- http://lkml.org/lkml/2007/2/12/6 +- https://lore.kernel.org/r/loom.20070212T063225-663@post.gmane.org - Documentation/filesystems/proc.rst (1.8) diff --git a/Documentation/translations/zh_CN/process/submitting-patches.rst b/Documentation/translations/zh_CN/process/submitting-patches.rst index 2e7dbaad4028..4fc6d16f5196 100644 --- a/Documentation/translations/zh_CN/process/submitting-patches.rst +++ b/Documentation/translations/zh_CN/process/submitting-patches.rst @@ -668,13 +668,13 @@ Greg Kroah-Hartman, "How to piss off a kernel subsystem maintainer". NO!!!! No more huge patch bombs to linux-kernel@vger.kernel.org people! - + Kernel Documentation/process/coding-style.rst: :ref:`Documentation/translations/zh_CN/process/coding-style.rst ` Linus Torvalds's mail on the canonical patch format: - + Andi Kleen, "On submitting kernel patches" Some strategies to get difficult or controversial changes in. -- cgit v1.2.3 From 6a2195a104a4c2ca5c428169700ed8a45fbe6893 Mon Sep 17 00:00:00 2001 From: Liao Pingfang Date: Sun, 10 Jan 2021 15:59:59 +0800 Subject: docs: filesystems: vfs: Correct the struct name The struct name should be file_system_type instead of file_system_operations. Signed-off-by: Liao Pingfang Link: https://lore.kernel.org/r/1610265599-5101-1-git-send-email-winndows@163.com Signed-off-by: Jonathan Corbet --- Documentation/filesystems/vfs.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Documentation') diff --git a/Documentation/filesystems/vfs.rst b/Documentation/filesystems/vfs.rst index ca52c82e5bb5..18d69a4559d6 100644 --- a/Documentation/filesystems/vfs.rst +++ b/Documentation/filesystems/vfs.rst @@ -112,7 +112,7 @@ members are defined: .. code-block:: c - struct file_system_operations { + struct file_system_type { const char *name; int fs_flags; struct dentry *(*mount) (struct file_system_type *, int, -- cgit v1.2.3 From c4c6b86acff7b3465e537fd6d9fce63f85584e78 Mon Sep 17 00:00:00 2001 From: Jiang Biao Date: Thu, 7 Jan 2021 22:11:18 +0800 Subject: Documentation: Fix typos found in cgroup-v2.rst Fix typos found in Documentation/admin-guide/cgroup-v2.rst. Signed-off-by: Jiang Biao Link: https://lore.kernel.org/r/20210107141118.9530-1-benbjiang@tencent.com Signed-off-by: Jonathan Corbet --- Documentation/admin-guide/cgroup-v2.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'Documentation') diff --git a/Documentation/admin-guide/cgroup-v2.rst b/Documentation/admin-guide/cgroup-v2.rst index 63521cd36ce5..e0f6ff7cfa93 100644 --- a/Documentation/admin-guide/cgroup-v2.rst +++ b/Documentation/admin-guide/cgroup-v2.rst @@ -1558,7 +1558,7 @@ IO Interface Files 8:0 rbytes=90430464 wbytes=299008000 rios=8950 wios=1252 dbytes=50331648 dios=3021 io.cost.qos - A read-write nested-keyed file with exists only on the root + A read-write nested-keyed file which exists only on the root cgroup. This file configures the Quality of Service of the IO cost @@ -1613,7 +1613,7 @@ IO Interface Files automatic mode can be restored by setting "ctrl" to "auto". io.cost.model - A read-write nested-keyed file with exists only on the root + A read-write nested-keyed file which exists only on the root cgroup. This file configures the cost model of the IO cost model based -- cgit v1.2.3 From 85430c22e5ae87eff7b491d7a363c81325b94b8a Mon Sep 17 00:00:00 2001 From: Hao Li Date: Wed, 6 Jan 2021 09:50:00 +0800 Subject: Documentation/dax: Update description of DAX policy changing After commit 77573fa310d9 ("fs: Kill DCACHE_DONTCACHE dentry even if DCACHE_REFERENCED is set"), changes to DAX policy will take effect as soon as all references to this file are gone. Update the documentation accordingly. Signed-off-by: Hao Li Reviewed-by: Ira Weiny Link: https://lore.kernel.org/r/20210106015000.5263-1-lihao2018.fnst@cn.fujitsu.com Signed-off-by: Jonathan Corbet --- Documentation/filesystems/dax.txt | 17 +++-------------- 1 file changed, 3 insertions(+), 14 deletions(-) (limited to 'Documentation') diff --git a/Documentation/filesystems/dax.txt b/Documentation/filesystems/dax.txt index 8fdb78f3c6c9..e03c20564f3a 100644 --- a/Documentation/filesystems/dax.txt +++ b/Documentation/filesystems/dax.txt @@ -83,20 +83,9 @@ Summary directories. This has runtime constraints and limitations that are described in 6) below. - 6. When changing the S_DAX policy via toggling the persistent FS_XFLAG_DAX flag, - the change in behaviour for existing regular files may not occur - immediately. If the change must take effect immediately, the administrator - needs to: - - a) stop the application so there are no active references to the data set - the policy change will affect - - b) evict the data set from kernel caches so it will be re-instantiated when - the application is restarted. This can be achieved by: - - i. drop-caches - ii. a filesystem unmount and mount cycle - iii. a system reboot + 6. When changing the S_DAX policy via toggling the persistent FS_XFLAG_DAX + flag, the change to existing regular files won't take effect until the + files are closed by all processes. Details -- cgit v1.2.3 From 7178b4a7d69ca96db6e0bb3593c202c2dd323089 Mon Sep 17 00:00:00 2001 From: Jonathan Neuschäfer Date: Fri, 1 Jan 2021 22:52:13 +0100 Subject: docs: Include ext4 documentation via filesystems/ MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The documentation for other filesystems is already included via filesystems/index.rst. Include ext4 in the same way and remove it from the top-level table of contents. Signed-off-by: Jonathan Neuschäfer Link: https://lore.kernel.org/r/20210101215215.1047826-1-j.neuschaefer@gmx.net Signed-off-by: Jonathan Corbet --- Documentation/filesystems/index.rst | 1 + Documentation/index.rst | 11 ----------- 2 files changed, 1 insertion(+), 11 deletions(-) (limited to 'Documentation') diff --git a/Documentation/filesystems/index.rst b/Documentation/filesystems/index.rst index 7be9b46d85d9..1f76b1cb3348 100644 --- a/Documentation/filesystems/index.rst +++ b/Documentation/filesystems/index.rst @@ -83,6 +83,7 @@ Documentation for filesystem implementations. erofs ext2 ext3 + ext4/index f2fs gfs2 gfs2-uevents diff --git a/Documentation/index.rst b/Documentation/index.rst index 5888e8a7272f..31f2adc8542d 100644 --- a/Documentation/index.rst +++ b/Documentation/index.rst @@ -171,17 +171,6 @@ implementation. x86/index xtensa/index -Filesystem Documentation ------------------------- - -The documentation in this section are provided by specific filesystem -subprojects. - -.. toctree:: - :maxdepth: 2 - - filesystems/ext4/index - Other documentation ------------------- -- cgit v1.2.3 From 7594bb08fb68ffe7e77c2e77ecc33c1e21631ead Mon Sep 17 00:00:00 2001 From: Johannes Thumshirn Date: Sat, 19 Dec 2020 00:35:25 +0900 Subject: Documentation: document dma device use for mcb Hannes reported a problem with setting up dma transfers on a mcb device. The problem boiled down to the use of a wrong 'device' for the dma functions. Document how to setup dma transfers for a IP core on a mcb carrier. Reported-by: Hannes Duerr Signed-off-by: Johannes Thumshirn Link: https://lore.kernel.org/r/3bdc8f76b30c2b0e2a2bfab06c2e73797ddc9384.1608305690.git.johannes.thumshirn@wdc.com Signed-off-by: Jonathan Corbet --- Documentation/driver-api/men-chameleon-bus.rst | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'Documentation') diff --git a/Documentation/driver-api/men-chameleon-bus.rst b/Documentation/driver-api/men-chameleon-bus.rst index 1b1f048aa748..6f0b9ee47595 100644 --- a/Documentation/driver-api/men-chameleon-bus.rst +++ b/Documentation/driver-api/men-chameleon-bus.rst @@ -18,6 +18,7 @@ MEN Chameleon Bus 4.1 The driver structure 4.2 Probing and attaching 4.3 Initializing the driver + 4.4 Using DMA Introduction @@ -173,3 +174,14 @@ module at the MCB core:: The module_mcb_driver() macro can be used to reduce the above code:: module_mcb_driver(foo_driver); + +Using DMA +--------- + +To make use of the kernel's DMA-API's function, you will need to use the +carrier device's 'struct device'. Fortunately 'struct mcb_device' embeds a +pointer (->dma_dev) to the carrier's device for DMA purposes:: + + ret = dma_set_mask_and_coherent(&mdev->dma_dev, DMA_BIT_MASK(dma_bits)); + if (rc) + /* Handle errors */ -- cgit v1.2.3 From ca880a15ef5c98d987b06ae73eee4d6ee1c1a906 Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Wed, 30 Dec 2020 12:19:19 +0000 Subject: dt-bindings:iio:health:ti,afe4404: Fix wrong compatible value. Cut and paste error. Documentation/devicetree/bindings/iio/health/ti,afe4403.example.dt.yaml: heart_mon@0: 'spi-max-frequency' does not match any of the regexes: 'pinctrl-[0-9]+' Reported-by: Rob Herring Signed-off-by: Jonathan Cameron Fixes: f494151b5eba ("dt-bindings:iio:health:ti,afe4404: txt to yaml conversion") Link: https://lore.kernel.org/r/20201230121919.238335-1-jic23@kernel.org Signed-off-by: Rob Herring --- Documentation/devicetree/bindings/iio/health/ti,afe4404.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/iio/health/ti,afe4404.yaml b/Documentation/devicetree/bindings/iio/health/ti,afe4404.yaml index 3b4d6c48b8bb..c0e815d9999e 100644 --- a/Documentation/devicetree/bindings/iio/health/ti,afe4404.yaml +++ b/Documentation/devicetree/bindings/iio/health/ti,afe4404.yaml @@ -11,7 +11,7 @@ maintainers: properties: compatible: - const: ti,afe4403 + const: ti,afe4404 reg: maxItems: 1 -- cgit v1.2.3 From 5b9576e202e174ccd099e16b9e9367036247edb8 Mon Sep 17 00:00:00 2001 From: Yongqiang Niu Date: Mon, 11 Jan 2021 15:43:38 +0800 Subject: dt-bindings: mediatek: add description for mt8192 display add description for mt8192 display Signed-off-by: Yongqiang Niu Acked-by: Rob Herring Signed-off-by: Chun-Kuang Hu --- Documentation/devicetree/bindings/display/mediatek/mediatek,disp.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,disp.txt b/Documentation/devicetree/bindings/display/mediatek/mediatek,disp.txt index f71ed2eae3e7..c40f900de59d 100644 --- a/Documentation/devicetree/bindings/display/mediatek/mediatek,disp.txt +++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,disp.txt @@ -43,7 +43,7 @@ Required properties (all function blocks): "mediatek,-dpi" - DPI controller, see mediatek,dpi.txt "mediatek,-disp-mutex" - display mutex "mediatek,-disp-od" - overdrive - the supported chips are mt2701, mt7623, mt2712, mt8167, mt8173 and mt8183. + the supported chips are mt2701, mt7623, mt2712, mt8167, mt8173, mt8183 and mt8192. - reg: Physical base address and length of the function block register space - interrupts: The interrupt signal from the function block (required, except for merge and split function blocks). -- cgit v1.2.3 From 0499220d6dadafa50d10c748ab88bbe4ebf39c05 Mon Sep 17 00:00:00 2001 From: Rob Herring Date: Mon, 4 Jan 2021 16:02:53 -0700 Subject: dt-bindings: Add missing array size constraints DT properties which can have multiple entries need to specify what the entries are and define how many entries there can be. In the case of only a single entry, just 'maxItems: 1' is sufficient. Add the missing entry constraints. These were found with a modified meta-schema. Unfortunately, there are a few cases where the size constraints are not defined such as common bindings, so the meta-schema can't be part of the normal checks. Cc: Jens Axboe Cc: Stephen Boyd Cc: Thierry Reding Cc: MyungJoo Ham Cc: Chanwoo Choi Cc: Linus Walleij Cc: Bartosz Golaszewski Cc: Jonathan Cameron Cc: Dmitry Torokhov Cc: Thomas Gleixner Cc: Marc Zyngier Cc: Mauro Carvalho Chehab Cc: Chen-Yu Tsai Cc: Ulf Hansson Cc: "David S. Miller" Cc: Jakub Kicinski Cc: Sebastian Reichel Cc: Ohad Ben-Cohen Cc: Bjorn Andersson Cc: Greg Kroah-Hartman Acked-by: Sebastian Reichel Acked-by: Jonathan Cameron #for-iio Acked-by: Chanwoo Choi Reviewed-by: Suman Anna Acked-by: Paul Cercueil Acked-by: Dmitry Torokhov Acked-by: Bartosz Golaszewski Reviewed-by: Linus Walleij Link: https://lore.kernel.org/r/20210104230253.2805217-1-robh@kernel.org Signed-off-by: Rob Herring --- .../socionext/socionext,uniphier-system-cache.yaml | 4 ++-- .../devicetree/bindings/ata/sata_highbank.yaml | 1 + .../devicetree/bindings/clock/canaan,k210-clk.yaml | 1 + .../bindings/display/brcm,bcm2711-hdmi.yaml | 1 + .../bindings/display/brcm,bcm2835-hdmi.yaml | 1 + .../bindings/display/panel/jdi,lt070me05000.yaml | 1 + .../bindings/display/panel/mantix,mlaf057we51-x.yaml | 3 ++- .../bindings/display/panel/novatek,nt36672a.yaml | 1 + Documentation/devicetree/bindings/dsp/fsl,dsp.yaml | 2 +- Documentation/devicetree/bindings/eeprom/at25.yaml | 3 +-- .../devicetree/bindings/extcon/extcon-ptn5150.yaml | 2 ++ .../devicetree/bindings/gpio/gpio-pca95xx.yaml | 1 + .../devicetree/bindings/iio/adc/adi,ad7768-1.yaml | 2 ++ .../bindings/iio/adc/aspeed,ast2400-adc.yaml | 1 + .../devicetree/bindings/iio/adc/lltc,ltc2496.yaml | 2 +- .../devicetree/bindings/iio/adc/qcom,spmi-vadc.yaml | 1 + .../devicetree/bindings/iio/adc/st,stm32-adc.yaml | 2 ++ .../bindings/iio/magnetometer/asahi-kasei,ak8975.yaml | 1 + .../bindings/iio/potentiometer/adi,ad5272.yaml | 1 + .../bindings/input/touchscreen/elan,elants_i2c.yaml | 1 + .../bindings/interrupt-controller/fsl,intmux.yaml | 2 +- .../bindings/interrupt-controller/st,stm32-exti.yaml | 2 ++ .../media/allwinner,sun4i-a10-video-engine.yaml | 1 + .../devicetree/bindings/media/i2c/imx219.yaml | 1 + .../bindings/memory-controllers/exynos-srom.yaml | 2 ++ .../devicetree/bindings/misc/fsl,dpaa2-console.yaml | 1 + .../devicetree/bindings/mmc/mmc-controller.yaml | 2 ++ .../bindings/net/ti,k3-am654-cpsw-nuss.yaml | 1 + .../devicetree/bindings/net/ti,k3-am654-cpts.yaml | 1 + .../bindings/phy/allwinner,sun4i-a10-usb-phy.yaml | 2 ++ .../bindings/phy/allwinner,sun50i-a64-usb-phy.yaml | 2 ++ .../bindings/phy/allwinner,sun50i-h6-usb-phy.yaml | 2 ++ .../bindings/phy/allwinner,sun5i-a13-usb-phy.yaml | 2 ++ .../bindings/phy/allwinner,sun6i-a31-usb-phy.yaml | 2 ++ .../bindings/phy/allwinner,sun8i-a23-usb-phy.yaml | 2 ++ .../bindings/phy/allwinner,sun8i-a83t-usb-phy.yaml | 2 ++ .../bindings/phy/allwinner,sun8i-h3-usb-phy.yaml | 2 ++ .../bindings/phy/allwinner,sun8i-r40-usb-phy.yaml | 2 ++ .../bindings/phy/allwinner,sun8i-v3s-usb-phy.yaml | 2 ++ .../bindings/phy/allwinner,sun9i-a80-usb-phy.yaml | 19 ++++++++----------- .../bindings/phy/socionext,uniphier-ahci-phy.yaml | 2 +- .../bindings/phy/socionext,uniphier-pcie-phy.yaml | 2 +- .../bindings/phy/socionext,uniphier-usb3hs-phy.yaml | 2 +- .../bindings/phy/socionext,uniphier-usb3ss-phy.yaml | 2 +- .../devicetree/bindings/phy/ti,phy-gmii-sel.yaml | 2 +- .../bindings/pinctrl/aspeed,ast2400-pinctrl.yaml | 3 +-- .../bindings/pinctrl/aspeed,ast2500-pinctrl.yaml | 4 ++-- .../devicetree/bindings/power/supply/bq25980.yaml | 1 + .../devicetree/bindings/remoteproc/ingenic,vpu.yaml | 2 +- .../bindings/remoteproc/ti,omap-remoteproc.yaml | 3 +++ .../devicetree/bindings/riscv/sifive-l2-cache.yaml | 1 + .../devicetree/bindings/serial/renesas,hscif.yaml | 2 ++ .../devicetree/bindings/serial/renesas,scif.yaml | 2 ++ .../devicetree/bindings/serial/renesas,scifa.yaml | 2 ++ .../devicetree/bindings/serial/renesas,scifb.yaml | 2 ++ .../bindings/sound/allwinner,sun4i-a10-codec.yaml | 1 + .../bindings/sound/google,sc7180-trogdor.yaml | 1 + .../bindings/sound/samsung,aries-wm8994.yaml | 3 +++ .../bindings/sound/samsung,midas-audio.yaml | 2 ++ Documentation/devicetree/bindings/sound/tas2562.yaml | 2 ++ Documentation/devicetree/bindings/sound/tas2770.yaml | 2 ++ .../devicetree/bindings/sound/tlv320adcx140.yaml | 1 + .../devicetree/bindings/spi/renesas,rspi.yaml | 2 ++ Documentation/devicetree/bindings/sram/sram.yaml | 2 ++ .../bindings/timer/allwinner,sun4i-a10-timer.yaml | 2 ++ .../devicetree/bindings/timer/intel,ixp4xx-timer.yaml | 2 +- .../bindings/usb/allwinner,sun4i-a10-musb.yaml | 2 +- .../devicetree/bindings/usb/brcm,usb-pinmap.yaml | 3 +++ .../devicetree/bindings/usb/generic-ehci.yaml | 2 +- .../devicetree/bindings/usb/generic-ohci.yaml | 2 +- .../devicetree/bindings/usb/ingenic,musb.yaml | 2 +- .../devicetree/bindings/usb/renesas,usbhs.yaml | 1 + .../devicetree/bindings/usb/ti,j721e-usb.yaml | 3 ++- .../devicetree/bindings/usb/ti,keystone-dwc3.yaml | 2 ++ 74 files changed, 118 insertions(+), 35 deletions(-) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/arm/socionext/socionext,uniphier-system-cache.yaml b/Documentation/devicetree/bindings/arm/socionext/socionext,uniphier-system-cache.yaml index 2e765bb3e6f6..7ca5375f278f 100644 --- a/Documentation/devicetree/bindings/arm/socionext/socionext,uniphier-system-cache.yaml +++ b/Documentation/devicetree/bindings/arm/socionext/socionext,uniphier-system-cache.yaml @@ -30,8 +30,8 @@ properties: Interrupts can be used to notify the completion of cache operations. The number of interrupts should match to the number of CPU cores. The specified interrupts correspond to CPU0, CPU1, ... in this order. - minItems: 1 - maxItems: 4 + minItems: 1 + maxItems: 4 cache-unified: true diff --git a/Documentation/devicetree/bindings/ata/sata_highbank.yaml b/Documentation/devicetree/bindings/ata/sata_highbank.yaml index 5e2a2394e600..ce75d77e9289 100644 --- a/Documentation/devicetree/bindings/ata/sata_highbank.yaml +++ b/Documentation/devicetree/bindings/ata/sata_highbank.yaml @@ -61,6 +61,7 @@ properties: maxItems: 8 calxeda,sgpio-gpio: + maxItems: 3 description: | phandle-gpio bank, bit offset, and default on or off, which indicates that the driver supports SGPIO indicator lights using the indicated diff --git a/Documentation/devicetree/bindings/clock/canaan,k210-clk.yaml b/Documentation/devicetree/bindings/clock/canaan,k210-clk.yaml index 565ca468cb44..7f5cf4001f76 100644 --- a/Documentation/devicetree/bindings/clock/canaan,k210-clk.yaml +++ b/Documentation/devicetree/bindings/clock/canaan,k210-clk.yaml @@ -22,6 +22,7 @@ properties: const: canaan,k210-clk clocks: + maxItems: 1 description: Phandle of the SoC 26MHz fixed-rate oscillator clock. diff --git a/Documentation/devicetree/bindings/display/brcm,bcm2711-hdmi.yaml b/Documentation/devicetree/bindings/display/brcm,bcm2711-hdmi.yaml index 7ce06f9f9f8e..767edc0a7978 100644 --- a/Documentation/devicetree/bindings/display/brcm,bcm2711-hdmi.yaml +++ b/Documentation/devicetree/bindings/display/brcm,bcm2711-hdmi.yaml @@ -60,6 +60,7 @@ properties: Phandle of the I2C controller used for DDC EDID probing hpd-gpios: + maxItems: 1 description: > The GPIO pin for the HDMI hotplug detect (if it doesn't appear as an interrupt/status bit in the HDMI controller itself) diff --git a/Documentation/devicetree/bindings/display/brcm,bcm2835-hdmi.yaml b/Documentation/devicetree/bindings/display/brcm,bcm2835-hdmi.yaml index f54b4e4808f0..031e35e76db2 100644 --- a/Documentation/devicetree/bindings/display/brcm,bcm2835-hdmi.yaml +++ b/Documentation/devicetree/bindings/display/brcm,bcm2835-hdmi.yaml @@ -37,6 +37,7 @@ properties: Phandle of the I2C controller used for DDC EDID probing hpd-gpios: + maxItems: 1 description: > The GPIO pin for the HDMI hotplug detect (if it doesn't appear as an interrupt/status bit in the HDMI controller itself) diff --git a/Documentation/devicetree/bindings/display/panel/jdi,lt070me05000.yaml b/Documentation/devicetree/bindings/display/panel/jdi,lt070me05000.yaml index b8b9435e464c..4f92365e888a 100644 --- a/Documentation/devicetree/bindings/display/panel/jdi,lt070me05000.yaml +++ b/Documentation/devicetree/bindings/display/panel/jdi,lt070me05000.yaml @@ -30,6 +30,7 @@ properties: power supply for LCM (1.8V) dcdc-en-gpios: + maxItems: 1 description: | phandle of the gpio for power ic line Power IC supply enable, High active diff --git a/Documentation/devicetree/bindings/display/panel/mantix,mlaf057we51-x.yaml b/Documentation/devicetree/bindings/display/panel/mantix,mlaf057we51-x.yaml index 51f423297ec8..aa5a0dc391a4 100644 --- a/Documentation/devicetree/bindings/display/panel/mantix,mlaf057we51-x.yaml +++ b/Documentation/devicetree/bindings/display/panel/mantix,mlaf057we51-x.yaml @@ -37,7 +37,8 @@ properties: reset-gpios: true - 'mantix,tp-rstn-gpios': + mantix,tp-rstn-gpios: + maxItems: 1 description: second reset line that triggers DSI config load backlight: true diff --git a/Documentation/devicetree/bindings/display/panel/novatek,nt36672a.yaml b/Documentation/devicetree/bindings/display/panel/novatek,nt36672a.yaml index 2f5df1d235ae..ef4c0a24512d 100644 --- a/Documentation/devicetree/bindings/display/panel/novatek,nt36672a.yaml +++ b/Documentation/devicetree/bindings/display/panel/novatek,nt36672a.yaml @@ -30,6 +30,7 @@ properties: panel. The novatek,nt36672a compatible shall always be provided as a fallback. reset-gpios: + maxItems: 1 description: phandle of gpio for reset line - This should be 8mA, gpio can be configured using mux, pinctrl, pinctrl-names (active high) diff --git a/Documentation/devicetree/bindings/dsp/fsl,dsp.yaml b/Documentation/devicetree/bindings/dsp/fsl,dsp.yaml index 4cc011230153..7afc9f2be13a 100644 --- a/Documentation/devicetree/bindings/dsp/fsl,dsp.yaml +++ b/Documentation/devicetree/bindings/dsp/fsl,dsp.yaml @@ -21,7 +21,7 @@ properties: - fsl,imx8mp-dsp reg: - description: Should contain register location and length + maxItems: 1 clocks: items: diff --git a/Documentation/devicetree/bindings/eeprom/at25.yaml b/Documentation/devicetree/bindings/eeprom/at25.yaml index 121a601db22e..6a2dc8b3ed14 100644 --- a/Documentation/devicetree/bindings/eeprom/at25.yaml +++ b/Documentation/devicetree/bindings/eeprom/at25.yaml @@ -39,8 +39,7 @@ properties: - const: atmel,at25 reg: - description: - Chip select number. + maxItems: 1 spi-max-frequency: true diff --git a/Documentation/devicetree/bindings/extcon/extcon-ptn5150.yaml b/Documentation/devicetree/bindings/extcon/extcon-ptn5150.yaml index 4b0f414486d2..d5cfa32ea52d 100644 --- a/Documentation/devicetree/bindings/extcon/extcon-ptn5150.yaml +++ b/Documentation/devicetree/bindings/extcon/extcon-ptn5150.yaml @@ -19,6 +19,7 @@ properties: const: nxp,ptn5150 int-gpios: + maxItems: 1 deprecated: true description: GPIO pin (input) connected to the PTN5150's INTB pin. @@ -31,6 +32,7 @@ properties: maxItems: 1 vbus-gpios: + maxItems: 1 description: GPIO pin (output) used to control VBUS. If skipped, no such control takes place. diff --git a/Documentation/devicetree/bindings/gpio/gpio-pca95xx.yaml b/Documentation/devicetree/bindings/gpio/gpio-pca95xx.yaml index f5ee23c2df60..57cdcfd4ff3c 100644 --- a/Documentation/devicetree/bindings/gpio/gpio-pca95xx.yaml +++ b/Documentation/devicetree/bindings/gpio/gpio-pca95xx.yaml @@ -81,6 +81,7 @@ properties: const: 2 reset-gpios: + maxItems: 1 description: GPIO specification for the RESET input. This is an active low signal to the PCA953x. Not valid for Maxim MAX732x devices. diff --git a/Documentation/devicetree/bindings/iio/adc/adi,ad7768-1.yaml b/Documentation/devicetree/bindings/iio/adc/adi,ad7768-1.yaml index 924477dfb833..a85a28145ef6 100644 --- a/Documentation/devicetree/bindings/iio/adc/adi,ad7768-1.yaml +++ b/Documentation/devicetree/bindings/iio/adc/adi,ad7768-1.yaml @@ -40,6 +40,7 @@ properties: ADC reference voltage supply adi,sync-in-gpios: + maxItems: 1 description: Enables synchronization of multiple devices that require simultaneous sampling. A pulse is always required if the configuration is changed @@ -76,6 +77,7 @@ patternProperties: properties: reg: + maxItems: 1 description: | The channel number. diff --git a/Documentation/devicetree/bindings/iio/adc/aspeed,ast2400-adc.yaml b/Documentation/devicetree/bindings/iio/adc/aspeed,ast2400-adc.yaml index 7f534a933e92..a726b6c2ab65 100644 --- a/Documentation/devicetree/bindings/iio/adc/aspeed,ast2400-adc.yaml +++ b/Documentation/devicetree/bindings/iio/adc/aspeed,ast2400-adc.yaml @@ -23,6 +23,7 @@ properties: maxItems: 1 clocks: + maxItems: 1 description: Input clock used to derive the sample clock. Expected to be the SoC's APB clock. diff --git a/Documentation/devicetree/bindings/iio/adc/lltc,ltc2496.yaml b/Documentation/devicetree/bindings/iio/adc/lltc,ltc2496.yaml index 2716d4e95329..0bd2fc0356c8 100644 --- a/Documentation/devicetree/bindings/iio/adc/lltc,ltc2496.yaml +++ b/Documentation/devicetree/bindings/iio/adc/lltc,ltc2496.yaml @@ -20,7 +20,7 @@ properties: description: Power supply for the reference voltage reg: - description: spi chipselect number according to the usual spi bindings + maxItems: 1 spi-max-frequency: description: maximal spi bus frequency supported diff --git a/Documentation/devicetree/bindings/iio/adc/qcom,spmi-vadc.yaml b/Documentation/devicetree/bindings/iio/adc/qcom,spmi-vadc.yaml index 95cc705b961b..74a4a9d95798 100644 --- a/Documentation/devicetree/bindings/iio/adc/qcom,spmi-vadc.yaml +++ b/Documentation/devicetree/bindings/iio/adc/qcom,spmi-vadc.yaml @@ -68,6 +68,7 @@ patternProperties: properties: reg: + maxItems: 1 description: | ADC channel number. See include/dt-bindings/iio/qcom,spmi-vadc.h diff --git a/Documentation/devicetree/bindings/iio/adc/st,stm32-adc.yaml b/Documentation/devicetree/bindings/iio/adc/st,stm32-adc.yaml index 28417b31b558..6364ede9bb5f 100644 --- a/Documentation/devicetree/bindings/iio/adc/st,stm32-adc.yaml +++ b/Documentation/devicetree/bindings/iio/adc/st,stm32-adc.yaml @@ -41,6 +41,8 @@ properties: maxItems: 2 clocks: + minItems: 1 + maxItems: 2 description: | Core can use up to two clocks, depending on part used: - "adc" clock: for the analog circuitry, common to all ADCs. diff --git a/Documentation/devicetree/bindings/iio/magnetometer/asahi-kasei,ak8975.yaml b/Documentation/devicetree/bindings/iio/magnetometer/asahi-kasei,ak8975.yaml index a25590a16ba7..a0a1ffe017df 100644 --- a/Documentation/devicetree/bindings/iio/magnetometer/asahi-kasei,ak8975.yaml +++ b/Documentation/devicetree/bindings/iio/magnetometer/asahi-kasei,ak8975.yaml @@ -47,6 +47,7 @@ properties: description: an optional 3x3 mounting rotation matrix. reset-gpios: + maxItems: 1 description: | an optional pin needed for AK09911 to set the reset state. This should be usually active low diff --git a/Documentation/devicetree/bindings/iio/potentiometer/adi,ad5272.yaml b/Documentation/devicetree/bindings/iio/potentiometer/adi,ad5272.yaml index 1aee9f9be951..0ebb6725a1af 100644 --- a/Documentation/devicetree/bindings/iio/potentiometer/adi,ad5272.yaml +++ b/Documentation/devicetree/bindings/iio/potentiometer/adi,ad5272.yaml @@ -25,6 +25,7 @@ properties: maxItems: 1 reset-gpios: + maxItems: 1 description: Active low signal to the AD5272 RESET input. diff --git a/Documentation/devicetree/bindings/input/touchscreen/elan,elants_i2c.yaml b/Documentation/devicetree/bindings/input/touchscreen/elan,elants_i2c.yaml index a792d6377b1d..a9b53c2e6f0a 100644 --- a/Documentation/devicetree/bindings/input/touchscreen/elan,elants_i2c.yaml +++ b/Documentation/devicetree/bindings/input/touchscreen/elan,elants_i2c.yaml @@ -29,6 +29,7 @@ properties: description: touchscreen can be used as a wakeup source. reset-gpios: + maxItems: 1 description: reset gpio the chip is connected to. vcc33-supply: diff --git a/Documentation/devicetree/bindings/interrupt-controller/fsl,intmux.yaml b/Documentation/devicetree/bindings/interrupt-controller/fsl,intmux.yaml index 43c6effbb5bd..1d6e0f64a807 100644 --- a/Documentation/devicetree/bindings/interrupt-controller/fsl,intmux.yaml +++ b/Documentation/devicetree/bindings/interrupt-controller/fsl,intmux.yaml @@ -31,7 +31,7 @@ properties: The 1st cell is hw interrupt number, the 2nd cell is channel index. clocks: - description: ipg clock. + maxItems: 1 clock-names: const: ipg diff --git a/Documentation/devicetree/bindings/interrupt-controller/st,stm32-exti.yaml b/Documentation/devicetree/bindings/interrupt-controller/st,stm32-exti.yaml index 2a5b29567926..6d3e68eb2e8b 100644 --- a/Documentation/devicetree/bindings/interrupt-controller/st,stm32-exti.yaml +++ b/Documentation/devicetree/bindings/interrupt-controller/st,stm32-exti.yaml @@ -36,6 +36,8 @@ properties: Reference to a phandle of a hardware spinlock provider node. interrupts: + minItems: 1 + maxItems: 96 description: Interrupts references to primary interrupt controller diff --git a/Documentation/devicetree/bindings/media/allwinner,sun4i-a10-video-engine.yaml b/Documentation/devicetree/bindings/media/allwinner,sun4i-a10-video-engine.yaml index 2f7058f7760c..c34303b87a5b 100644 --- a/Documentation/devicetree/bindings/media/allwinner,sun4i-a10-video-engine.yaml +++ b/Documentation/devicetree/bindings/media/allwinner,sun4i-a10-video-engine.yaml @@ -53,6 +53,7 @@ properties: maxItems: 1 memory-region: + maxItems: 1 description: CMA pool to use for buffers allocation instead of the default CMA pool. diff --git a/Documentation/devicetree/bindings/media/i2c/imx219.yaml b/Documentation/devicetree/bindings/media/i2c/imx219.yaml index dfc4d29a4f04..184d33bd3828 100644 --- a/Documentation/devicetree/bindings/media/i2c/imx219.yaml +++ b/Documentation/devicetree/bindings/media/i2c/imx219.yaml @@ -40,6 +40,7 @@ properties: Digital core voltage supply, 1.2 volts reset-gpios: + maxItems: 1 description: |- Reference to the GPIO connected to the xclr pin, if any. Must be released (set high) after all supplies are applied. diff --git a/Documentation/devicetree/bindings/memory-controllers/exynos-srom.yaml b/Documentation/devicetree/bindings/memory-controllers/exynos-srom.yaml index 637e24f0f73b..c6e44f47ce7c 100644 --- a/Documentation/devicetree/bindings/memory-controllers/exynos-srom.yaml +++ b/Documentation/devicetree/bindings/memory-controllers/exynos-srom.yaml @@ -28,6 +28,8 @@ properties: const: 1 ranges: + minItems: 1 + maxItems: 4 description: | Reflects the memory layout with four integer values per bank. Format: 0 diff --git a/Documentation/devicetree/bindings/misc/fsl,dpaa2-console.yaml b/Documentation/devicetree/bindings/misc/fsl,dpaa2-console.yaml index 271a3eafc054..8cc951feb7df 100644 --- a/Documentation/devicetree/bindings/misc/fsl,dpaa2-console.yaml +++ b/Documentation/devicetree/bindings/misc/fsl,dpaa2-console.yaml @@ -15,6 +15,7 @@ properties: const: "fsl,dpaa2-console" reg: + maxItems: 1 description: A standard property. Specifies the region where the MCFBA (MC firmware base address) register can be found. diff --git a/Documentation/devicetree/bindings/mmc/mmc-controller.yaml b/Documentation/devicetree/bindings/mmc/mmc-controller.yaml index 186f04ba9357..df4ee4c778ae 100644 --- a/Documentation/devicetree/bindings/mmc/mmc-controller.yaml +++ b/Documentation/devicetree/bindings/mmc/mmc-controller.yaml @@ -40,6 +40,7 @@ properties: There is no card detection available; polling must be used. cd-gpios: + maxItems: 1 description: The card detection will be done using the GPIO provided. @@ -104,6 +105,7 @@ properties: line. Not used in combination with eMMC or SDIO. wp-gpios: + maxItems: 1 description: GPIO to use for the write-protect detection. diff --git a/Documentation/devicetree/bindings/net/ti,k3-am654-cpsw-nuss.yaml b/Documentation/devicetree/bindings/net/ti,k3-am654-cpsw-nuss.yaml index c47b58f3e3f6..097c5cc6c853 100644 --- a/Documentation/devicetree/bindings/net/ti,k3-am654-cpsw-nuss.yaml +++ b/Documentation/devicetree/bindings/net/ti,k3-am654-cpsw-nuss.yaml @@ -66,6 +66,7 @@ properties: dma-coherent: true clocks: + maxItems: 1 description: CPSW2G NUSS functional clock clock-names: diff --git a/Documentation/devicetree/bindings/net/ti,k3-am654-cpts.yaml b/Documentation/devicetree/bindings/net/ti,k3-am654-cpts.yaml index 9b7117920d90..2a42a27fb911 100644 --- a/Documentation/devicetree/bindings/net/ti,k3-am654-cpts.yaml +++ b/Documentation/devicetree/bindings/net/ti,k3-am654-cpts.yaml @@ -59,6 +59,7 @@ properties: - const: cpts clocks: + maxItems: 1 description: CPTS reference clock clock-names: diff --git a/Documentation/devicetree/bindings/phy/allwinner,sun4i-a10-usb-phy.yaml b/Documentation/devicetree/bindings/phy/allwinner,sun4i-a10-usb-phy.yaml index 94ac23687b7e..77606c899fe2 100644 --- a/Documentation/devicetree/bindings/phy/allwinner,sun4i-a10-usb-phy.yaml +++ b/Documentation/devicetree/bindings/phy/allwinner,sun4i-a10-usb-phy.yaml @@ -51,9 +51,11 @@ properties: - const: usb2_reset usb0_id_det-gpios: + maxItems: 1 description: GPIO to the USB OTG ID pin usb0_vbus_det-gpios: + maxItems: 1 description: GPIO to the USB OTG VBUS detect pin usb0_vbus_power-supply: diff --git a/Documentation/devicetree/bindings/phy/allwinner,sun50i-a64-usb-phy.yaml b/Documentation/devicetree/bindings/phy/allwinner,sun50i-a64-usb-phy.yaml index fd6e126fcf18..078af52b16ed 100644 --- a/Documentation/devicetree/bindings/phy/allwinner,sun50i-a64-usb-phy.yaml +++ b/Documentation/devicetree/bindings/phy/allwinner,sun50i-a64-usb-phy.yaml @@ -50,9 +50,11 @@ properties: - const: usb1_reset usb0_id_det-gpios: + maxItems: 1 description: GPIO to the USB OTG ID pin usb0_vbus_det-gpios: + maxItems: 1 description: GPIO to the USB OTG VBUS detect pin usb0_vbus_power-supply: diff --git a/Documentation/devicetree/bindings/phy/allwinner,sun50i-h6-usb-phy.yaml b/Documentation/devicetree/bindings/phy/allwinner,sun50i-h6-usb-phy.yaml index 7670411002c9..e632140722a2 100644 --- a/Documentation/devicetree/bindings/phy/allwinner,sun50i-h6-usb-phy.yaml +++ b/Documentation/devicetree/bindings/phy/allwinner,sun50i-h6-usb-phy.yaml @@ -50,9 +50,11 @@ properties: - const: usb3_reset usb0_id_det-gpios: + maxItems: 1 description: GPIO to the USB OTG ID pin usb0_vbus_det-gpios: + maxItems: 1 description: GPIO to the USB OTG VBUS detect pin usb0_vbus_power-supply: diff --git a/Documentation/devicetree/bindings/phy/allwinner,sun5i-a13-usb-phy.yaml b/Documentation/devicetree/bindings/phy/allwinner,sun5i-a13-usb-phy.yaml index 9b319381d1ad..5bad9b06e2e7 100644 --- a/Documentation/devicetree/bindings/phy/allwinner,sun5i-a13-usb-phy.yaml +++ b/Documentation/devicetree/bindings/phy/allwinner,sun5i-a13-usb-phy.yaml @@ -45,9 +45,11 @@ properties: - const: usb1_reset usb0_id_det-gpios: + maxItems: 1 description: GPIO to the USB OTG ID pin usb0_vbus_det-gpios: + maxItems: 1 description: GPIO to the USB OTG VBUS detect pin usb0_vbus_power-supply: diff --git a/Documentation/devicetree/bindings/phy/allwinner,sun6i-a31-usb-phy.yaml b/Documentation/devicetree/bindings/phy/allwinner,sun6i-a31-usb-phy.yaml index b0ed01bbf3db..922b4665e00d 100644 --- a/Documentation/devicetree/bindings/phy/allwinner,sun6i-a31-usb-phy.yaml +++ b/Documentation/devicetree/bindings/phy/allwinner,sun6i-a31-usb-phy.yaml @@ -54,9 +54,11 @@ properties: - const: usb2_reset usb0_id_det-gpios: + maxItems: 1 description: GPIO to the USB OTG ID pin usb0_vbus_det-gpios: + maxItems: 1 description: GPIO to the USB OTG VBUS detect pin usb0_vbus_power-supply: diff --git a/Documentation/devicetree/bindings/phy/allwinner,sun8i-a23-usb-phy.yaml b/Documentation/devicetree/bindings/phy/allwinner,sun8i-a23-usb-phy.yaml index b0674406f8aa..a94019efc2f3 100644 --- a/Documentation/devicetree/bindings/phy/allwinner,sun8i-a23-usb-phy.yaml +++ b/Documentation/devicetree/bindings/phy/allwinner,sun8i-a23-usb-phy.yaml @@ -50,9 +50,11 @@ properties: - const: usb1_reset usb0_id_det-gpios: + maxItems: 1 description: GPIO to the USB OTG ID pin usb0_vbus_det-gpios: + maxItems: 1 description: GPIO to the USB OTG VBUS detect pin usb0_vbus_power-supply: diff --git a/Documentation/devicetree/bindings/phy/allwinner,sun8i-a83t-usb-phy.yaml b/Documentation/devicetree/bindings/phy/allwinner,sun8i-a83t-usb-phy.yaml index 48dc9c834a9b..33f3ddc0492d 100644 --- a/Documentation/devicetree/bindings/phy/allwinner,sun8i-a83t-usb-phy.yaml +++ b/Documentation/devicetree/bindings/phy/allwinner,sun8i-a83t-usb-phy.yaml @@ -56,9 +56,11 @@ properties: - const: usb2_reset usb0_id_det-gpios: + maxItems: 1 description: GPIO to the USB OTG ID pin usb0_vbus_det-gpios: + maxItems: 1 description: GPIO to the USB OTG VBUS detect pin usb0_vbus_power-supply: diff --git a/Documentation/devicetree/bindings/phy/allwinner,sun8i-h3-usb-phy.yaml b/Documentation/devicetree/bindings/phy/allwinner,sun8i-h3-usb-phy.yaml index 60c344585276..f80431060803 100644 --- a/Documentation/devicetree/bindings/phy/allwinner,sun8i-h3-usb-phy.yaml +++ b/Documentation/devicetree/bindings/phy/allwinner,sun8i-h3-usb-phy.yaml @@ -62,9 +62,11 @@ properties: - const: usb3_reset usb0_id_det-gpios: + maxItems: 1 description: GPIO to the USB OTG ID pin usb0_vbus_det-gpios: + maxItems: 1 description: GPIO to the USB OTG VBUS detect pin usb0_vbus_power-supply: diff --git a/Documentation/devicetree/bindings/phy/allwinner,sun8i-r40-usb-phy.yaml b/Documentation/devicetree/bindings/phy/allwinner,sun8i-r40-usb-phy.yaml index a2bb36790fbd..d947e50a49d2 100644 --- a/Documentation/devicetree/bindings/phy/allwinner,sun8i-r40-usb-phy.yaml +++ b/Documentation/devicetree/bindings/phy/allwinner,sun8i-r40-usb-phy.yaml @@ -56,9 +56,11 @@ properties: - const: usb2_reset usb0_id_det-gpios: + maxItems: 1 description: GPIO to the USB OTG ID pin usb0_vbus_det-gpios: + maxItems: 1 description: GPIO to the USB OTG VBUS detect pin usb0_vbus_power-supply: diff --git a/Documentation/devicetree/bindings/phy/allwinner,sun8i-v3s-usb-phy.yaml b/Documentation/devicetree/bindings/phy/allwinner,sun8i-v3s-usb-phy.yaml index eadfd0c9493c..a2836c296cc4 100644 --- a/Documentation/devicetree/bindings/phy/allwinner,sun8i-v3s-usb-phy.yaml +++ b/Documentation/devicetree/bindings/phy/allwinner,sun8i-v3s-usb-phy.yaml @@ -42,9 +42,11 @@ properties: const: usb0_reset usb0_id_det-gpios: + maxItems: 1 description: GPIO to the USB OTG ID pin usb0_vbus_det-gpios: + maxItems: 1 description: GPIO to the USB OTG VBUS detect pin usb0_vbus_power-supply: diff --git a/Documentation/devicetree/bindings/phy/allwinner,sun9i-a80-usb-phy.yaml b/Documentation/devicetree/bindings/phy/allwinner,sun9i-a80-usb-phy.yaml index ded7d6f0a119..2eb493fa64fd 100644 --- a/Documentation/devicetree/bindings/phy/allwinner,sun9i-a80-usb-phy.yaml +++ b/Documentation/devicetree/bindings/phy/allwinner,sun9i-a80-usb-phy.yaml @@ -22,7 +22,8 @@ properties: clocks: anyOf: - - description: Main PHY Clock + - maxItems: 1 + description: Main PHY Clock - items: - description: Main PHY clock @@ -39,20 +40,16 @@ properties: - const: hsic_480M resets: - anyOf: + minItems: 1 + items: - description: Normal USB PHY reset - - - items: - - description: Normal USB PHY reset - - description: HSIC Reset + - description: HSIC Reset reset-names: - oneOf: + minItems: 1 + items: - const: phy - - - items: - - const: phy - - const: hsic + - const: hsic phy_type: const: hsic diff --git a/Documentation/devicetree/bindings/phy/socionext,uniphier-ahci-phy.yaml b/Documentation/devicetree/bindings/phy/socionext,uniphier-ahci-phy.yaml index 34756347a14e..745c525ce6b9 100644 --- a/Documentation/devicetree/bindings/phy/socionext,uniphier-ahci-phy.yaml +++ b/Documentation/devicetree/bindings/phy/socionext,uniphier-ahci-phy.yaml @@ -20,7 +20,7 @@ properties: - socionext,uniphier-pxs3-ahci-phy reg: - description: PHY register region (offset and length) + maxItems: 1 "#phy-cells": const: 0 diff --git a/Documentation/devicetree/bindings/phy/socionext,uniphier-pcie-phy.yaml b/Documentation/devicetree/bindings/phy/socionext,uniphier-pcie-phy.yaml index a06831fd64b9..3e0566899041 100644 --- a/Documentation/devicetree/bindings/phy/socionext,uniphier-pcie-phy.yaml +++ b/Documentation/devicetree/bindings/phy/socionext,uniphier-pcie-phy.yaml @@ -21,7 +21,7 @@ properties: - socionext,uniphier-pxs3-pcie-phy reg: - description: PHY register region (offset and length) + maxItems: 1 "#phy-cells": const: 0 diff --git a/Documentation/devicetree/bindings/phy/socionext,uniphier-usb3hs-phy.yaml b/Documentation/devicetree/bindings/phy/socionext,uniphier-usb3hs-phy.yaml index 6fa5caab1487..a681cbc3b4ef 100644 --- a/Documentation/devicetree/bindings/phy/socionext,uniphier-usb3hs-phy.yaml +++ b/Documentation/devicetree/bindings/phy/socionext,uniphier-usb3hs-phy.yaml @@ -24,7 +24,7 @@ properties: - socionext,uniphier-pxs3-usb3-hsphy reg: - description: PHY register region (offset and length) + maxItems: 1 "#phy-cells": const: 0 diff --git a/Documentation/devicetree/bindings/phy/socionext,uniphier-usb3ss-phy.yaml b/Documentation/devicetree/bindings/phy/socionext,uniphier-usb3ss-phy.yaml index 9d46715ed036..41c0dd68ee25 100644 --- a/Documentation/devicetree/bindings/phy/socionext,uniphier-usb3ss-phy.yaml +++ b/Documentation/devicetree/bindings/phy/socionext,uniphier-usb3ss-phy.yaml @@ -25,7 +25,7 @@ properties: - socionext,uniphier-pxs3-usb3-ssphy reg: - description: PHY register region (offset and length) + maxItems: 1 "#phy-cells": const: 0 diff --git a/Documentation/devicetree/bindings/phy/ti,phy-gmii-sel.yaml b/Documentation/devicetree/bindings/phy/ti,phy-gmii-sel.yaml index bcec422d7734..ff8a6d9eb153 100644 --- a/Documentation/devicetree/bindings/phy/ti,phy-gmii-sel.yaml +++ b/Documentation/devicetree/bindings/phy/ti,phy-gmii-sel.yaml @@ -55,7 +55,7 @@ properties: - ti,am654-phy-gmii-sel reg: - description: Address and length of the register set for the device + maxItems: 1 '#phy-cells': true diff --git a/Documentation/devicetree/bindings/pinctrl/aspeed,ast2400-pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/aspeed,ast2400-pinctrl.yaml index 54631dc1adb0..91be5720d094 100644 --- a/Documentation/devicetree/bindings/pinctrl/aspeed,ast2400-pinctrl.yaml +++ b/Documentation/devicetree/bindings/pinctrl/aspeed,ast2400-pinctrl.yaml @@ -23,8 +23,7 @@ properties: compatible: const: aspeed,ast2400-pinctrl reg: - description: | - A hint for the memory regions associated with the pin-controller + maxItems: 2 patternProperties: '^.*$': diff --git a/Documentation/devicetree/bindings/pinctrl/aspeed,ast2500-pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/aspeed,ast2500-pinctrl.yaml index a90c0fe0495f..40e9e8d4be5a 100644 --- a/Documentation/devicetree/bindings/pinctrl/aspeed,ast2500-pinctrl.yaml +++ b/Documentation/devicetree/bindings/pinctrl/aspeed,ast2500-pinctrl.yaml @@ -24,8 +24,8 @@ properties: compatible: const: aspeed,ast2500-pinctrl reg: - description: | - A hint for the memory regions associated with the pin-controller + maxItems: 2 + aspeed,external-nodes: minItems: 2 maxItems: 2 diff --git a/Documentation/devicetree/bindings/power/supply/bq25980.yaml b/Documentation/devicetree/bindings/power/supply/bq25980.yaml index f6b3dd4093ca..06eca6667f67 100644 --- a/Documentation/devicetree/bindings/power/supply/bq25980.yaml +++ b/Documentation/devicetree/bindings/power/supply/bq25980.yaml @@ -70,6 +70,7 @@ properties: description: Enables bypass mode at boot time interrupts: + maxItems: 1 description: | Indicates that the device state has changed. diff --git a/Documentation/devicetree/bindings/remoteproc/ingenic,vpu.yaml b/Documentation/devicetree/bindings/remoteproc/ingenic,vpu.yaml index c019f9fbe916..d0aa91bbf5e5 100644 --- a/Documentation/devicetree/bindings/remoteproc/ingenic,vpu.yaml +++ b/Documentation/devicetree/bindings/remoteproc/ingenic,vpu.yaml @@ -44,7 +44,7 @@ properties: - const: vpu interrupts: - description: VPU hardware interrupt + maxItems: 1 required: - compatible diff --git a/Documentation/devicetree/bindings/remoteproc/ti,omap-remoteproc.yaml b/Documentation/devicetree/bindings/remoteproc/ti,omap-remoteproc.yaml index 084960a8f17a..1a1159097a2a 100644 --- a/Documentation/devicetree/bindings/remoteproc/ti,omap-remoteproc.yaml +++ b/Documentation/devicetree/bindings/remoteproc/ti,omap-remoteproc.yaml @@ -70,10 +70,13 @@ properties: the firmware image. clocks: + maxItems: 1 description: | Main functional clock for the remote processor resets: + minItems: 1 + maxItems: 2 description: | Reset handles for the remote processor diff --git a/Documentation/devicetree/bindings/riscv/sifive-l2-cache.yaml b/Documentation/devicetree/bindings/riscv/sifive-l2-cache.yaml index efc0198eeb74..2ece8630dc68 100644 --- a/Documentation/devicetree/bindings/riscv/sifive-l2-cache.yaml +++ b/Documentation/devicetree/bindings/riscv/sifive-l2-cache.yaml @@ -63,6 +63,7 @@ properties: next-level-cache: true memory-region: + maxItems: 1 description: | The reference to the reserved-memory for the L2 Loosely Integrated Memory region. The reserved memory node should be defined as per the bindings in reserved-memory.txt. diff --git a/Documentation/devicetree/bindings/serial/renesas,hscif.yaml b/Documentation/devicetree/bindings/serial/renesas,hscif.yaml index c139c5edb93e..69533347aa57 100644 --- a/Documentation/devicetree/bindings/serial/renesas,hscif.yaml +++ b/Documentation/devicetree/bindings/serial/renesas,hscif.yaml @@ -81,6 +81,8 @@ properties: maxItems: 1 dmas: + minItems: 2 + maxItems: 4 description: Must contain a list of pairs of references to DMA specifiers, one for transmission, and one for reception. diff --git a/Documentation/devicetree/bindings/serial/renesas,scif.yaml b/Documentation/devicetree/bindings/serial/renesas,scif.yaml index 672158906c33..22d76829f7ae 100644 --- a/Documentation/devicetree/bindings/serial/renesas,scif.yaml +++ b/Documentation/devicetree/bindings/serial/renesas,scif.yaml @@ -120,6 +120,8 @@ properties: maxItems: 1 dmas: + minItems: 2 + maxItems: 4 description: Must contain a list of pairs of references to DMA specifiers, one for transmission, and one for reception. diff --git a/Documentation/devicetree/bindings/serial/renesas,scifa.yaml b/Documentation/devicetree/bindings/serial/renesas,scifa.yaml index dbffb9534835..3c67d3202e1b 100644 --- a/Documentation/devicetree/bindings/serial/renesas,scifa.yaml +++ b/Documentation/devicetree/bindings/serial/renesas,scifa.yaml @@ -55,6 +55,8 @@ properties: maxItems: 1 dmas: + minItems: 2 + maxItems: 4 description: Must contain a list of pairs of references to DMA specifiers, one for transmission, and one for reception. diff --git a/Documentation/devicetree/bindings/serial/renesas,scifb.yaml b/Documentation/devicetree/bindings/serial/renesas,scifb.yaml index 147f8a37e02a..d5571c7a4424 100644 --- a/Documentation/devicetree/bindings/serial/renesas,scifb.yaml +++ b/Documentation/devicetree/bindings/serial/renesas,scifb.yaml @@ -55,6 +55,8 @@ properties: maxItems: 1 dmas: + minItems: 2 + maxItems: 4 description: Must contain a list of pairs of references to DMA specifiers, one for transmission, and one for reception. diff --git a/Documentation/devicetree/bindings/sound/allwinner,sun4i-a10-codec.yaml b/Documentation/devicetree/bindings/sound/allwinner,sun4i-a10-codec.yaml index dd47fef9854d..559aff13ae23 100644 --- a/Documentation/devicetree/bindings/sound/allwinner,sun4i-a10-codec.yaml +++ b/Documentation/devicetree/bindings/sound/allwinner,sun4i-a10-codec.yaml @@ -88,6 +88,7 @@ properties: description: Phandle to the codec analog controls in the PRCM allwinner,pa-gpios: + maxItems: 1 description: GPIO to enable the external amplifier required: diff --git a/Documentation/devicetree/bindings/sound/google,sc7180-trogdor.yaml b/Documentation/devicetree/bindings/sound/google,sc7180-trogdor.yaml index 5095b780e2c7..837e3faa63a9 100644 --- a/Documentation/devicetree/bindings/sound/google,sc7180-trogdor.yaml +++ b/Documentation/devicetree/bindings/sound/google,sc7180-trogdor.yaml @@ -55,6 +55,7 @@ patternProperties: maxItems: 1 reg: + maxItems: 1 description: dai link address. cpu: diff --git a/Documentation/devicetree/bindings/sound/samsung,aries-wm8994.yaml b/Documentation/devicetree/bindings/sound/samsung,aries-wm8994.yaml index 1c6947294825..5fff586dc802 100644 --- a/Documentation/devicetree/bindings/sound/samsung,aries-wm8994.yaml +++ b/Documentation/devicetree/bindings/sound/samsung,aries-wm8994.yaml @@ -62,12 +62,15 @@ properties: description: Supply for the micbias on the headset mic earpath-sel-gpios: + maxItems: 1 description: GPIO for switching between tv-out and mic paths headset-detect-gpios: + maxItems: 1 description: GPIO for detection of headset insertion headset-key-gpios: + maxItems: 1 description: GPIO for detection of headset key press io-channels: diff --git a/Documentation/devicetree/bindings/sound/samsung,midas-audio.yaml b/Documentation/devicetree/bindings/sound/samsung,midas-audio.yaml index 578928e67e5c..095775c598fa 100644 --- a/Documentation/devicetree/bindings/sound/samsung,midas-audio.yaml +++ b/Documentation/devicetree/bindings/sound/samsung,midas-audio.yaml @@ -53,9 +53,11 @@ properties: description: Supply for the micbias on the Sub microphone fm-sel-gpios: + maxItems: 1 description: GPIO pin for FM selection lineout-sel-gpios: + maxItems: 1 description: GPIO pin for line out selection required: diff --git a/Documentation/devicetree/bindings/sound/tas2562.yaml b/Documentation/devicetree/bindings/sound/tas2562.yaml index 27f7132ba2ef..acd4bbe69731 100644 --- a/Documentation/devicetree/bindings/sound/tas2562.yaml +++ b/Documentation/devicetree/bindings/sound/tas2562.yaml @@ -36,10 +36,12 @@ properties: I2C address of the device can be one of these 0x4c, 0x4d, 0x4e or 0x4f shut-down-gpios: + maxItems: 1 description: GPIO used to control the state of the device. deprecated: true shutdown-gpios: + maxItems: 1 description: GPIO used to control the state of the device. interrupts: diff --git a/Documentation/devicetree/bindings/sound/tas2770.yaml b/Documentation/devicetree/bindings/sound/tas2770.yaml index 07e7f9951d2e..027bebf4e8cf 100644 --- a/Documentation/devicetree/bindings/sound/tas2770.yaml +++ b/Documentation/devicetree/bindings/sound/tas2770.yaml @@ -27,9 +27,11 @@ properties: I2C address of the device can be between 0x41 to 0x48. reset-gpio: + maxItems: 1 description: GPIO used to reset the device. shutdown-gpios: + maxItems: 1 description: GPIO used to control the state of the device. interrupts: diff --git a/Documentation/devicetree/bindings/sound/tlv320adcx140.yaml b/Documentation/devicetree/bindings/sound/tlv320adcx140.yaml index df18be9d7b15..54d64785aad2 100644 --- a/Documentation/devicetree/bindings/sound/tlv320adcx140.yaml +++ b/Documentation/devicetree/bindings/sound/tlv320adcx140.yaml @@ -35,6 +35,7 @@ properties: I2C addresss of the device can be one of these 0x4c, 0x4d, 0x4e or 0x4f reset-gpios: + maxItems: 1 description: | GPIO used for hardware reset. diff --git a/Documentation/devicetree/bindings/spi/renesas,rspi.yaml b/Documentation/devicetree/bindings/spi/renesas,rspi.yaml index 10e83cb17e8d..8397f60d80a2 100644 --- a/Documentation/devicetree/bindings/spi/renesas,rspi.yaml +++ b/Documentation/devicetree/bindings/spi/renesas,rspi.yaml @@ -68,6 +68,8 @@ properties: maxItems: 1 dmas: + minItems: 2 + maxItems: 4 description: Must contain a list of pairs of references to DMA specifiers, one for transmission, and one for reception. diff --git a/Documentation/devicetree/bindings/sram/sram.yaml b/Documentation/devicetree/bindings/sram/sram.yaml index 19d116ff9ddc..2a62bb204bbe 100644 --- a/Documentation/devicetree/bindings/sram/sram.yaml +++ b/Documentation/devicetree/bindings/sram/sram.yaml @@ -35,6 +35,7 @@ properties: maxItems: 1 clocks: + maxItems: 1 description: A list of phandle and clock specifier pair that controls the single SRAM clock. @@ -46,6 +47,7 @@ properties: const: 1 ranges: + maxItems: 1 description: Should translate from local addresses within the sram to bus addresses. diff --git a/Documentation/devicetree/bindings/timer/allwinner,sun4i-a10-timer.yaml b/Documentation/devicetree/bindings/timer/allwinner,sun4i-a10-timer.yaml index d918cee100ac..1c7cf32e7ac2 100644 --- a/Documentation/devicetree/bindings/timer/allwinner,sun4i-a10-timer.yaml +++ b/Documentation/devicetree/bindings/timer/allwinner,sun4i-a10-timer.yaml @@ -22,6 +22,8 @@ properties: maxItems: 1 interrupts: + minItems: 2 + maxItems: 6 description: List of timers interrupts diff --git a/Documentation/devicetree/bindings/timer/intel,ixp4xx-timer.yaml b/Documentation/devicetree/bindings/timer/intel,ixp4xx-timer.yaml index 1a721d8af67a..a8de99b0c0f9 100644 --- a/Documentation/devicetree/bindings/timer/intel,ixp4xx-timer.yaml +++ b/Documentation/devicetree/bindings/timer/intel,ixp4xx-timer.yaml @@ -18,7 +18,7 @@ properties: - const: intel,ixp4xx-timer reg: - description: Should contain registers location and length + maxItems: 1 interrupts: minItems: 1 diff --git a/Documentation/devicetree/bindings/usb/allwinner,sun4i-a10-musb.yaml b/Documentation/devicetree/bindings/usb/allwinner,sun4i-a10-musb.yaml index d9207bf9d894..0f520f17735e 100644 --- a/Documentation/devicetree/bindings/usb/allwinner,sun4i-a10-musb.yaml +++ b/Documentation/devicetree/bindings/usb/allwinner,sun4i-a10-musb.yaml @@ -39,7 +39,7 @@ properties: maxItems: 1 phys: - description: PHY specifier for the OTG PHY + maxItems: 1 phy-names: const: usb diff --git a/Documentation/devicetree/bindings/usb/brcm,usb-pinmap.yaml b/Documentation/devicetree/bindings/usb/brcm,usb-pinmap.yaml index ffa148b9eaa8..d4618d15ecc1 100644 --- a/Documentation/devicetree/bindings/usb/brcm,usb-pinmap.yaml +++ b/Documentation/devicetree/bindings/usb/brcm,usb-pinmap.yaml @@ -22,6 +22,8 @@ properties: description: Interrupt for signals mirrored to out-gpios. in-gpios: + minItems: 1 + maxItems: 2 description: Array of one or two GPIO pins used for input signals. brcm,in-functions: @@ -33,6 +35,7 @@ properties: description: Array of enable and mask pairs, one per gpio in-gpios. out-gpios: + maxItems: 1 description: Array of one GPIO pin used for output signals. brcm,out-functions: diff --git a/Documentation/devicetree/bindings/usb/generic-ehci.yaml b/Documentation/devicetree/bindings/usb/generic-ehci.yaml index 247ef00381ea..573dd5879f95 100644 --- a/Documentation/devicetree/bindings/usb/generic-ehci.yaml +++ b/Documentation/devicetree/bindings/usb/generic-ehci.yaml @@ -83,7 +83,7 @@ properties: Phandle of a companion. phys: - description: PHY specifier for the USB PHY + maxItems: 1 phy-names: const: usb diff --git a/Documentation/devicetree/bindings/usb/generic-ohci.yaml b/Documentation/devicetree/bindings/usb/generic-ohci.yaml index 2178bcc401bc..56bca63e02b6 100644 --- a/Documentation/devicetree/bindings/usb/generic-ohci.yaml +++ b/Documentation/devicetree/bindings/usb/generic-ohci.yaml @@ -71,7 +71,7 @@ properties: Overrides the detected port count phys: - description: PHY specifier for the USB PHY + maxItems: 1 phy-names: const: usb diff --git a/Documentation/devicetree/bindings/usb/ingenic,musb.yaml b/Documentation/devicetree/bindings/usb/ingenic,musb.yaml index 678396eeeb78..f506225a4d57 100644 --- a/Documentation/devicetree/bindings/usb/ingenic,musb.yaml +++ b/Documentation/devicetree/bindings/usb/ingenic,musb.yaml @@ -40,7 +40,7 @@ properties: - const: mc phys: - description: PHY specifier for the USB PHY + maxItems: 1 usb-role-switch: type: boolean diff --git a/Documentation/devicetree/bindings/usb/renesas,usbhs.yaml b/Documentation/devicetree/bindings/usb/renesas,usbhs.yaml index 54c361d4a7af..e67223d90bb7 100644 --- a/Documentation/devicetree/bindings/usb/renesas,usbhs.yaml +++ b/Documentation/devicetree/bindings/usb/renesas,usbhs.yaml @@ -68,6 +68,7 @@ properties: Integer to use BUSWAIT register. renesas,enable-gpio: + maxItems: 1 description: | gpio specifier to check GPIO determining if USB function should be enabled. diff --git a/Documentation/devicetree/bindings/usb/ti,j721e-usb.yaml b/Documentation/devicetree/bindings/usb/ti,j721e-usb.yaml index 388245b91a55..adce36e48bc9 100644 --- a/Documentation/devicetree/bindings/usb/ti,j721e-usb.yaml +++ b/Documentation/devicetree/bindings/usb/ti,j721e-usb.yaml @@ -15,13 +15,14 @@ properties: - const: ti,j721e-usb reg: - description: module registers + maxItems: 1 power-domains: description: PM domain provider node and an args specifier containing the USB device id value. See, Documentation/devicetree/bindings/soc/ti/sci-pm-domain.txt + maxItems: 1 clocks: description: Clock phandles to usb2_refclk and lpm_clk diff --git a/Documentation/devicetree/bindings/usb/ti,keystone-dwc3.yaml b/Documentation/devicetree/bindings/usb/ti,keystone-dwc3.yaml index c1b19fc5d0a2..91ef374faba8 100644 --- a/Documentation/devicetree/bindings/usb/ti,keystone-dwc3.yaml +++ b/Documentation/devicetree/bindings/usb/ti,keystone-dwc3.yaml @@ -43,12 +43,14 @@ properties: maxItems: 2 power-domains: + maxItems: 1 description: Should contain a phandle to a PM domain provider node and an args specifier containing the USB device id value. This property is as per the binding, Documentation/devicetree/bindings/soc/ti/sci-pm-domain.txt phys: + maxItems: 1 description: PHY specifier for the USB3.0 PHY. Some SoCs need the USB3.0 PHY to be turned on before the controller. -- cgit v1.2.3 From b67554232307e755c8a24d7a695a321ecd58790b Mon Sep 17 00:00:00 2001 From: Rob Herring Date: Mon, 4 Jan 2021 11:07:23 -0700 Subject: dt-bindings: display: Use OF graph schema Now that we have a graph schema, rework the display related schemas to use it. Mostly this is adding a reference to graph.yaml and dropping duplicate parts from schemas. In panel-common.yaml, 'ports' is dropped. Any binding using 'ports' should be one with more than 1 port node, and the binding must define what each port is. Note that ti,sn65dsi86.yaml, ti,tfp410,yaml and toshiba,tc358768.yaml will need further updates to use video-interfaces.yaml once that lands. Cc: Thierry Reding Cc: Sam Ravnborg Cc: Laurent Pinchart Cc: Maxime Ripard Cc: Maarten Lankhorst Cc: Thomas Zimmermann Signed-off-by: Rob Herring Reviewed-by: Laurent Pinchart Link: https://patchwork.freedesktop.org/patch/msgid/20210104180724.2275098-1-robh@kernel.org --- .../allwinner,sun4i-a10-display-backend.yaml | 23 +---- .../allwinner,sun4i-a10-display-frontend.yaml | 19 +--- .../bindings/display/allwinner,sun4i-a10-hdmi.yaml | 19 +--- .../bindings/display/allwinner,sun4i-a10-tcon.yaml | 25 ++--- .../display/allwinner,sun4i-a10-tv-encoder.yaml | 6 +- .../bindings/display/allwinner,sun6i-a31-drc.yaml | 19 +--- .../display/allwinner,sun6i-a31-mipi-dsi.yaml | 6 +- .../display/allwinner,sun8i-a83t-de2-mixer.yaml | 19 +--- .../display/allwinner,sun8i-a83t-dw-hdmi.yaml | 19 +--- .../display/allwinner,sun8i-r40-tcon-top.yaml | 110 ++------------------- .../bindings/display/allwinner,sun9i-a80-deu.yaml | 19 +--- .../bindings/display/amlogic,meson-dw-hdmi.yaml | 4 +- .../bindings/display/amlogic,meson-vpu.yaml | 4 +- .../bindings/display/brcm,bcm2835-dpi.yaml | 7 +- .../bindings/display/bridge/analogix,anx7625.yaml | 6 +- .../bindings/display/bridge/analogix,anx7814.yaml | 19 +--- .../bindings/display/bridge/anx6345.yaml | 18 +--- .../bindings/display/bridge/cdns,mhdp8546.yaml | 22 ++--- .../bindings/display/bridge/chrontel,ch7033.yaml | 6 +- .../bindings/display/bridge/intel,keembay-dsi.yaml | 14 +-- .../bindings/display/bridge/ite,it6505.yaml | 2 +- .../bindings/display/bridge/lontium,lt9611.yaml | 70 ++----------- .../bindings/display/bridge/lvds-codec.yaml | 18 +--- .../bindings/display/bridge/nwl-dsi.yaml | 41 ++------ .../devicetree/bindings/display/bridge/ps8640.yaml | 24 ++--- .../bindings/display/bridge/renesas,lvds.yaml | 18 +--- .../bindings/display/bridge/simple-bridge.yaml | 18 +--- .../bindings/display/bridge/snps,dw-mipi-dsi.yaml | 7 +- .../display/bridge/thine,thc63lvd1024.yaml | 21 +--- .../bindings/display/bridge/ti,sn65dsi86.yaml | 45 ++------- .../bindings/display/bridge/ti,tfp410.yaml | 24 ++--- .../bindings/display/bridge/toshiba,tc358762.yaml | 52 +--------- .../bindings/display/bridge/toshiba,tc358768.yaml | 48 ++------- .../bindings/display/bridge/toshiba,tc358775.yaml | 19 +--- .../display/connector/analog-tv-connector.yaml | 1 + .../bindings/display/connector/dvi-connector.yaml | 1 + .../bindings/display/connector/hdmi-connector.yaml | 1 + .../bindings/display/connector/vga-connector.yaml | 1 + .../bindings/display/imx/nxp,imx8mq-dcss.yaml | 2 +- .../devicetree/bindings/display/ingenic,ipu.yaml | 5 +- .../devicetree/bindings/display/ingenic,lcd.yaml | 10 +- .../bindings/display/intel,keembay-display.yaml | 2 +- .../display/panel/advantech,idk-2121wr.yaml | 21 ++-- .../bindings/display/panel/panel-common.yaml | 11 +-- .../display/rockchip/rockchip,rk3066-hdmi.yaml | 16 +-- .../bindings/display/rockchip/rockchip-vop.yaml | 5 +- .../devicetree/bindings/display/st,stm32-dsi.yaml | 12 +-- .../devicetree/bindings/display/st,stm32-ltdc.yaml | 8 +- .../devicetree/bindings/display/ste,mcde.yaml | 5 +- .../bindings/display/ti/ti,am65x-dss.yaml | 19 +--- .../bindings/display/ti/ti,j721e-dss.yaml | 23 ++--- .../devicetree/bindings/display/ti/ti,k2g-dss.yaml | 3 +- 52 files changed, 187 insertions(+), 750 deletions(-) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/display/allwinner,sun4i-a10-display-backend.yaml b/Documentation/devicetree/bindings/display/allwinner,sun4i-a10-display-backend.yaml index 86057d541065..12a7df0e38b2 100644 --- a/Documentation/devicetree/bindings/display/allwinner,sun4i-a10-display-backend.yaml +++ b/Documentation/devicetree/bindings/display/allwinner,sun4i-a10-display-backend.yaml @@ -84,36 +84,23 @@ properties: const: dma-mem ports: - type: object - description: | - A ports node with endpoint definitions as defined in - Documentation/devicetree/bindings/media/video-interfaces.txt. + $ref: /schemas/graph.yaml#/properties/ports properties: - "#address-cells": - const: 1 - - "#size-cells": - const: 0 - port@0: - type: object - description: | + $ref: /schemas/graph.yaml#/properties/port + description: Input endpoints of the controller. port@1: - type: object - description: | + $ref: /schemas/graph.yaml#/properties/port + description: Output endpoints of the controller. required: - - "#address-cells" - - "#size-cells" - port@0 - port@1 - additionalProperties: false - required: - compatible - reg diff --git a/Documentation/devicetree/bindings/display/allwinner,sun4i-a10-display-frontend.yaml b/Documentation/devicetree/bindings/display/allwinner,sun4i-a10-display-frontend.yaml index 3eb1c2bbf4e7..055157fbf3bf 100644 --- a/Documentation/devicetree/bindings/display/allwinner,sun4i-a10-display-frontend.yaml +++ b/Documentation/devicetree/bindings/display/allwinner,sun4i-a10-display-frontend.yaml @@ -57,35 +57,22 @@ properties: maxItems: 1 ports: - type: object - description: | - A ports node with endpoint definitions as defined in - Documentation/devicetree/bindings/media/video-interfaces.txt. + $ref: /schemas/graph.yaml#/properties/ports properties: - "#address-cells": - const: 1 - - "#size-cells": - const: 0 - port@0: - type: object + $ref: /schemas/graph.yaml#/properties/port description: | Input endpoints of the controller. port@1: - type: object + $ref: /schemas/graph.yaml#/properties/port description: | Output endpoints of the controller. required: - - "#address-cells" - - "#size-cells" - port@1 - additionalProperties: false - required: - compatible - reg diff --git a/Documentation/devicetree/bindings/display/allwinner,sun4i-a10-hdmi.yaml b/Documentation/devicetree/bindings/display/allwinner,sun4i-a10-hdmi.yaml index 75e6479397a5..7f11452539f4 100644 --- a/Documentation/devicetree/bindings/display/allwinner,sun4i-a10-hdmi.yaml +++ b/Documentation/devicetree/bindings/display/allwinner,sun4i-a10-hdmi.yaml @@ -76,37 +76,24 @@ properties: - const: audio-tx ports: - type: object - description: | - A ports node with endpoint definitions as defined in - Documentation/devicetree/bindings/media/video-interfaces.txt. + $ref: /schemas/graph.yaml#/properties/ports properties: - "#address-cells": - const: 1 - - "#size-cells": - const: 0 - port@0: - type: object + $ref: /schemas/graph.yaml#/properties/port description: | Input endpoints of the controller. port@1: - type: object + $ref: /schemas/graph.yaml#/properties/port description: | Output endpoints of the controller. Usually an HDMI connector. required: - - "#address-cells" - - "#size-cells" - port@0 - port@1 - additionalProperties: false - required: - compatible - reg diff --git a/Documentation/devicetree/bindings/display/allwinner,sun4i-a10-tcon.yaml b/Documentation/devicetree/bindings/display/allwinner,sun4i-a10-tcon.yaml index 4c15a2644a7c..c13faf3e6581 100644 --- a/Documentation/devicetree/bindings/display/allwinner,sun4i-a10-tcon.yaml +++ b/Documentation/devicetree/bindings/display/allwinner,sun4i-a10-tcon.yaml @@ -115,31 +115,24 @@ properties: - const: lvds ports: - type: object - description: | - A ports node with endpoint definitions as defined in - Documentation/devicetree/bindings/media/video-interfaces.txt. + $ref: /schemas/graph.yaml#/properties/ports properties: - "#address-cells": - const: 1 - - "#size-cells": - const: 0 - port@0: - type: object + $ref: /schemas/graph.yaml#/properties/port description: | Input endpoints of the controller. port@1: - type: object + $ref: /schemas/graph.yaml#/$defs/port-base + unevaluatedProperties: false description: | Output endpoints of the controller. patternProperties: "^endpoint(@[0-9])$": - type: object + $ref: /schemas/graph.yaml#/$defs/endpoint-base + unevaluatedProperties: false properties: allwinner,tcon-channel: @@ -156,16 +149,10 @@ properties: property is not present, the endpoint number will be used as the channel number. - unevaluatedProperties: true - required: - - "#address-cells" - - "#size-cells" - port@0 - port@1 - additionalProperties: false - required: - compatible - reg diff --git a/Documentation/devicetree/bindings/display/allwinner,sun4i-a10-tv-encoder.yaml b/Documentation/devicetree/bindings/display/allwinner,sun4i-a10-tv-encoder.yaml index 6009324be967..afc0ed799e0e 100644 --- a/Documentation/devicetree/bindings/display/allwinner,sun4i-a10-tv-encoder.yaml +++ b/Documentation/devicetree/bindings/display/allwinner,sun4i-a10-tv-encoder.yaml @@ -24,11 +24,9 @@ properties: maxItems: 1 port: - type: object + $ref: /schemas/graph.yaml#/properties/port description: - A port node with endpoint definitions as defined in - Documentation/devicetree/bindings/media/video-interfaces.txt. The - first port should be the input endpoint, usually coming from the + The first port should be the input endpoint, usually coming from the associated TCON. required: diff --git a/Documentation/devicetree/bindings/display/allwinner,sun6i-a31-drc.yaml b/Documentation/devicetree/bindings/display/allwinner,sun6i-a31-drc.yaml index 0c1ce55940e1..71cce5687580 100644 --- a/Documentation/devicetree/bindings/display/allwinner,sun6i-a31-drc.yaml +++ b/Documentation/devicetree/bindings/display/allwinner,sun6i-a31-drc.yaml @@ -46,36 +46,23 @@ properties: maxItems: 1 ports: - type: object - description: | - A ports node with endpoint definitions as defined in - Documentation/devicetree/bindings/media/video-interfaces.txt. + $ref: /schemas/graph.yaml#/properties/ports properties: - "#address-cells": - const: 1 - - "#size-cells": - const: 0 - port@0: - type: object + $ref: /schemas/graph.yaml#/properties/port description: | Input endpoints of the controller. port@1: - type: object + $ref: /schemas/graph.yaml#/properties/port description: | Output endpoints of the controller. required: - - "#address-cells" - - "#size-cells" - port@0 - port@1 - additionalProperties: false - required: - compatible - reg diff --git a/Documentation/devicetree/bindings/display/allwinner,sun6i-a31-mipi-dsi.yaml b/Documentation/devicetree/bindings/display/allwinner,sun6i-a31-mipi-dsi.yaml index 7aa330dabc44..a738d7c12a97 100644 --- a/Documentation/devicetree/bindings/display/allwinner,sun6i-a31-mipi-dsi.yaml +++ b/Documentation/devicetree/bindings/display/allwinner,sun6i-a31-mipi-dsi.yaml @@ -47,11 +47,9 @@ properties: const: dphy port: - type: object + $ref: /schemas/graph.yaml#/properties/port description: - A port node with endpoint definitions as defined in - Documentation/devicetree/bindings/media/video-interfaces.txt. That - port should be the input endpoint, usually coming from the + The port should be the input endpoint, usually coming from the associated TCON. required: diff --git a/Documentation/devicetree/bindings/display/allwinner,sun8i-a83t-de2-mixer.yaml b/Documentation/devicetree/bindings/display/allwinner,sun8i-a83t-de2-mixer.yaml index c040eef56518..4f91eec26de9 100644 --- a/Documentation/devicetree/bindings/display/allwinner,sun8i-a83t-de2-mixer.yaml +++ b/Documentation/devicetree/bindings/display/allwinner,sun8i-a83t-de2-mixer.yaml @@ -43,35 +43,22 @@ properties: maxItems: 1 ports: - type: object - description: | - A ports node with endpoint definitions as defined in - Documentation/devicetree/bindings/media/video-interfaces.txt. + $ref: /schemas/graph.yaml#/properties/ports properties: - "#address-cells": - const: 1 - - "#size-cells": - const: 0 - port@0: - type: object + $ref: /schemas/graph.yaml#/properties/port description: | Input endpoints of the controller. port@1: - type: object + $ref: /schemas/graph.yaml#/properties/port description: | Output endpoints of the controller. required: - - "#address-cells" - - "#size-cells" - port@1 - additionalProperties: false - required: - compatible - reg diff --git a/Documentation/devicetree/bindings/display/allwinner,sun8i-a83t-dw-hdmi.yaml b/Documentation/devicetree/bindings/display/allwinner,sun8i-a83t-dw-hdmi.yaml index fa4769a0b26e..b3e9992525c2 100644 --- a/Documentation/devicetree/bindings/display/allwinner,sun8i-a83t-dw-hdmi.yaml +++ b/Documentation/devicetree/bindings/display/allwinner,sun8i-a83t-dw-hdmi.yaml @@ -93,38 +93,25 @@ properties: The VCC power supply of the controller ports: - type: object - description: | - A ports node with endpoint definitions as defined in - Documentation/devicetree/bindings/media/video-interfaces.txt. + $ref: /schemas/graph.yaml#/properties/ports properties: - "#address-cells": - const: 1 - - "#size-cells": - const: 0 - port@0: - type: object + $ref: /schemas/graph.yaml#/properties/port description: | Input endpoints of the controller. Usually the associated TCON. port@1: - type: object + $ref: /schemas/graph.yaml#/properties/port description: | Output endpoints of the controller. Usually an HDMI connector. required: - - "#address-cells" - - "#size-cells" - port@0 - port@1 - additionalProperties: false - required: - compatible - reg diff --git a/Documentation/devicetree/bindings/display/allwinner,sun8i-r40-tcon-top.yaml b/Documentation/devicetree/bindings/display/allwinner,sun8i-r40-tcon-top.yaml index b98ca609824b..ec21e8bf2767 100644 --- a/Documentation/devicetree/bindings/display/allwinner,sun8i-r40-tcon-top.yaml +++ b/Documentation/devicetree/bindings/display/allwinner,sun8i-r40-tcon-top.yaml @@ -80,141 +80,45 @@ properties: maxItems: 1 ports: - type: object - description: | - A ports node with endpoint definitions as defined in - Documentation/devicetree/bindings/media/video-interfaces.txt. - All ports should have only one endpoint connected to - remote endpoint. + $ref: /schemas/graph.yaml#/properties/ports properties: - "#address-cells": - const: 1 - - "#size-cells": - const: 0 - port@0: - type: object + $ref: /schemas/graph.yaml#/properties/port description: | Input endpoint for Mixer 0 mux. port@1: - type: object + $ref: /schemas/graph.yaml#/properties/port description: | Output endpoint for Mixer 0 mux - properties: - "#address-cells": - const: 1 - - "#size-cells": - const: 0 - - reg: true - - patternProperties: - "^endpoint@[0-9]$": - type: object - - properties: - reg: - description: | - ID of the target TCON - - required: - - reg - - required: - - "#address-cells" - - "#size-cells" - - additionalProperties: false - port@2: - type: object + $ref: /schemas/graph.yaml#/properties/port description: | Input endpoint for Mixer 1 mux. port@3: - type: object + $ref: /schemas/graph.yaml#/properties/port description: | Output endpoint for Mixer 1 mux - properties: - "#address-cells": - const: 1 - - "#size-cells": - const: 0 - - reg: true - - patternProperties: - "^endpoint@[0-9]$": - type: object - - properties: - reg: - description: | - ID of the target TCON - - required: - - reg - - required: - - "#address-cells" - - "#size-cells" - - additionalProperties: false - port@4: - type: object + $ref: /schemas/graph.yaml#/properties/port description: | Input endpoint for HDMI mux. - properties: - "#address-cells": - const: 1 - - "#size-cells": - const: 0 - - reg: true - - patternProperties: - "^endpoint@[0-9]$": - type: object - - properties: - reg: - description: | - ID of the target TCON - - required: - - reg - - required: - - "#address-cells" - - "#size-cells" - - additionalProperties: false - port@5: - type: object + $ref: /schemas/graph.yaml#/properties/port description: | Output endpoint for HDMI mux required: - - "#address-cells" - - "#size-cells" - port@0 - port@1 - port@4 - port@5 - additionalProperties: false - required: - "#clock-cells" - compatible diff --git a/Documentation/devicetree/bindings/display/allwinner,sun9i-a80-deu.yaml b/Documentation/devicetree/bindings/display/allwinner,sun9i-a80-deu.yaml index 96de41d32b3e..637372ec4614 100644 --- a/Documentation/devicetree/bindings/display/allwinner,sun9i-a80-deu.yaml +++ b/Documentation/devicetree/bindings/display/allwinner,sun9i-a80-deu.yaml @@ -40,36 +40,23 @@ properties: maxItems: 1 ports: - type: object - description: | - A ports node with endpoint definitions as defined in - Documentation/devicetree/bindings/media/video-interfaces.txt. + $ref: /schemas/graph.yaml#/properties/ports properties: - "#address-cells": - const: 1 - - "#size-cells": - const: 0 - port@0: - type: object + $ref: /schemas/graph.yaml#/properties/port description: | Input endpoints of the controller. port@1: - type: object + $ref: /schemas/graph.yaml#/properties/port description: | Output endpoints of the controller. required: - - "#address-cells" - - "#size-cells" - port@0 - port@1 - additionalProperties: false - required: - compatible - reg diff --git a/Documentation/devicetree/bindings/display/amlogic,meson-dw-hdmi.yaml b/Documentation/devicetree/bindings/display/amlogic,meson-dw-hdmi.yaml index 0da42ab8fd3a..cf5a208f2f10 100644 --- a/Documentation/devicetree/bindings/display/amlogic,meson-dw-hdmi.yaml +++ b/Documentation/devicetree/bindings/display/amlogic,meson-dw-hdmi.yaml @@ -81,12 +81,12 @@ properties: description: phandle to an external 5V regulator to power the HDMI logic port@0: - type: object + $ref: /schemas/graph.yaml#/properties/port description: A port node pointing to the VENC Input port node. port@1: - type: object + $ref: /schemas/graph.yaml#/properties/port description: A port node pointing to the TMDS Output port node. diff --git a/Documentation/devicetree/bindings/display/amlogic,meson-vpu.yaml b/Documentation/devicetree/bindings/display/amlogic,meson-vpu.yaml index a8d202c9d004..851cb0781217 100644 --- a/Documentation/devicetree/bindings/display/amlogic,meson-vpu.yaml +++ b/Documentation/devicetree/bindings/display/amlogic,meson-vpu.yaml @@ -83,12 +83,12 @@ properties: description: phandle to the associated power domain port@0: - type: object + $ref: /schemas/graph.yaml#/properties/port description: A port node pointing to the CVBS VDAC port node. port@1: - type: object + $ref: /schemas/graph.yaml#/properties/port description: A port node pointing to the HDMI-TX port node. diff --git a/Documentation/devicetree/bindings/display/brcm,bcm2835-dpi.yaml b/Documentation/devicetree/bindings/display/brcm,bcm2835-dpi.yaml index 5c1024bbc1b3..c9ad0ecc9b6d 100644 --- a/Documentation/devicetree/bindings/display/brcm,bcm2835-dpi.yaml +++ b/Documentation/devicetree/bindings/display/brcm,bcm2835-dpi.yaml @@ -27,10 +27,9 @@ properties: - const: pixel port: - type: object - description: > - Port node with a single endpoint connecting to the panel, as - defined in Documentation/devicetree/bindings/media/video-interfaces.txt. + $ref: /schemas/graph.yaml#/properties/port + description: + Port node with a single endpoint connecting to the panel. required: - compatible diff --git a/Documentation/devicetree/bindings/display/bridge/analogix,anx7625.yaml b/Documentation/devicetree/bindings/display/bridge/analogix,anx7625.yaml index 9392b5502a32..c789784efe30 100644 --- a/Documentation/devicetree/bindings/display/bridge/analogix,anx7625.yaml +++ b/Documentation/devicetree/bindings/display/bridge/analogix,anx7625.yaml @@ -35,16 +35,16 @@ properties: maxItems: 1 ports: - type: object + $ref: /schemas/graph.yaml#/properties/ports properties: port@0: - type: object + $ref: /schemas/graph.yaml#/properties/port description: Video port for MIPI DSI input. port@1: - type: object + $ref: /schemas/graph.yaml#/properties/port description: Video port for panel or connector. diff --git a/Documentation/devicetree/bindings/display/bridge/analogix,anx7814.yaml b/Documentation/devicetree/bindings/display/bridge/analogix,anx7814.yaml index 3ba477aefdd7..8e13f27b28ed 100644 --- a/Documentation/devicetree/bindings/display/bridge/analogix,anx7814.yaml +++ b/Documentation/devicetree/bindings/display/bridge/analogix,anx7814.yaml @@ -42,31 +42,18 @@ properties: description: Regulator for 1.0V digital core power. ports: - type: object - description: - A node containing input and output port nodes with endpoint - definitions as documented in - Documentation/devicetree/bindings/media/video-interfaces.txt - Documentation/devicetree/bindings/graph.txt + $ref: /schemas/graph.yaml#/properties/ports properties: port@0: - type: object + $ref: /schemas/graph.yaml#/properties/port description: Video port for HDMI input. - properties: - reg: - const: 0 - port@1: - type: object + $ref: /schemas/graph.yaml#/properties/port description: Video port for SlimPort, DisplayPort, eDP or MyDP output. - properties: - reg: - const: 1 - required: - port@0 - port@1 diff --git a/Documentation/devicetree/bindings/display/bridge/anx6345.yaml b/Documentation/devicetree/bindings/display/bridge/anx6345.yaml index fccd63521a8c..1c0406c38fe5 100644 --- a/Documentation/devicetree/bindings/display/bridge/anx6345.yaml +++ b/Documentation/devicetree/bindings/display/bridge/anx6345.yaml @@ -32,31 +32,23 @@ properties: description: Regulator for 2.5V digital core power. ports: - type: object + $ref: /schemas/graph.yaml#/properties/ports properties: - '#address-cells': - const: 1 - - '#size-cells': - const: 0 - port@0: - type: object - description: | + $ref: /schemas/graph.yaml#/properties/port + description: Video port for LVTTL input port@1: - type: object - description: | + $ref: /schemas/graph.yaml#/properties/port + description: Video port for eDP output (panel or connector). May be omitted if EDID works reliably. required: - port@0 - additionalProperties: false - required: - compatible - reg diff --git a/Documentation/devicetree/bindings/display/bridge/cdns,mhdp8546.yaml b/Documentation/devicetree/bindings/display/bridge/cdns,mhdp8546.yaml index 74d675fc6e7b..63427878715e 100644 --- a/Documentation/devicetree/bindings/display/bridge/cdns,mhdp8546.yaml +++ b/Documentation/devicetree/bindings/display/bridge/cdns,mhdp8546.yaml @@ -57,47 +57,37 @@ properties: maxItems: 1 ports: - type: object - description: - Ports as described in Documentation/devicetree/bindings/graph.txt. + $ref: /schemas/graph.yaml#/properties/ports properties: - '#address-cells': - const: 1 - - '#size-cells': - const: 0 - port@0: - type: object + $ref: /schemas/graph.yaml#/properties/port description: First input port representing the DP bridge input. port@1: - type: object + $ref: /schemas/graph.yaml#/properties/port description: Second input port representing the DP bridge input. port@2: - type: object + $ref: /schemas/graph.yaml#/properties/port description: Third input port representing the DP bridge input. port@3: - type: object + $ref: /schemas/graph.yaml#/properties/port description: Fourth input port representing the DP bridge input. port@4: - type: object + $ref: /schemas/graph.yaml#/properties/port description: Output port representing the DP bridge output. required: - port@0 - port@4 - - '#address-cells' - - '#size-cells' allOf: - if: diff --git a/Documentation/devicetree/bindings/display/bridge/chrontel,ch7033.yaml b/Documentation/devicetree/bindings/display/bridge/chrontel,ch7033.yaml index 9f38f55fc990..bb6289c7d375 100644 --- a/Documentation/devicetree/bindings/display/bridge/chrontel,ch7033.yaml +++ b/Documentation/devicetree/bindings/display/bridge/chrontel,ch7033.yaml @@ -19,16 +19,16 @@ properties: description: I2C address of the device ports: - type: object + $ref: /schemas/graph.yaml#/properties/ports properties: port@0: - type: object + $ref: /schemas/graph.yaml#/properties/port description: | Video port for RGB input. port@1: - type: object + $ref: /schemas/graph.yaml#/properties/port description: | DVI port, should be connected to a node compatible with the dvi-connector binding. diff --git a/Documentation/devicetree/bindings/display/bridge/intel,keembay-dsi.yaml b/Documentation/devicetree/bindings/display/bridge/intel,keembay-dsi.yaml index 35c9dfd86650..dcb1336ee2a5 100644 --- a/Documentation/devicetree/bindings/display/bridge/intel,keembay-dsi.yaml +++ b/Documentation/devicetree/bindings/display/bridge/intel,keembay-dsi.yaml @@ -35,29 +35,21 @@ properties: - const: clk_mipi_cfg ports: - type: object + $ref: /schemas/graph.yaml#/properties/ports properties: - '#address-cells': - const: 1 - - '#size-cells': - const: 0 - port@0: - type: object + $ref: /schemas/graph.yaml#/properties/port description: MIPI DSI input port. port@1: - type: object + $ref: /schemas/graph.yaml#/properties/port description: DSI output port. required: - port@0 - port@1 - additionalProperties: false - required: - compatible - reg diff --git a/Documentation/devicetree/bindings/display/bridge/ite,it6505.yaml b/Documentation/devicetree/bindings/display/bridge/ite,it6505.yaml index 02cfc0a3b550..833d11b2303a 100644 --- a/Documentation/devicetree/bindings/display/bridge/ite,it6505.yaml +++ b/Documentation/devicetree/bindings/display/bridge/ite,it6505.yaml @@ -53,7 +53,7 @@ properties: description: extcon specifier for the Power Delivery port: - type: object + $ref: /schemas/graph.yaml#/properties/port description: A port node pointing to DPI host port node required: diff --git a/Documentation/devicetree/bindings/display/bridge/lontium,lt9611.yaml b/Documentation/devicetree/bindings/display/bridge/lontium,lt9611.yaml index 7a1c89b995e2..5b9d36f7af30 100644 --- a/Documentation/devicetree/bindings/display/bridge/lontium,lt9611.yaml +++ b/Documentation/devicetree/bindings/display/bridge/lontium,lt9611.yaml @@ -38,82 +38,26 @@ properties: description: Regulator for 3.3V IO power. ports: - type: object + $ref: /schemas/graph.yaml#/properties/ports properties: - "#address-cells": - const: 1 - - "#size-cells": - const: 0 - port@0: - type: object - description: | + $ref: /schemas/graph.yaml#/properties/port + description: Primary MIPI port-1 for MIPI input - properties: - reg: - const: 0 - - patternProperties: - "^endpoint(@[0-9])$": - type: object - additionalProperties: false - - properties: - remote-endpoint: - $ref: /schemas/types.yaml#/definitions/phandle - - required: - - reg - port@1: - type: object - description: | + $ref: /schemas/graph.yaml#/properties/port + description: Additional MIPI port-2 for MIPI input, used in combination with primary MIPI port-1 to drive higher resolution displays - properties: - reg: - const: 1 - - patternProperties: - "^endpoint(@[0-9])$": - type: object - additionalProperties: false - - properties: - remote-endpoint: - $ref: /schemas/types.yaml#/definitions/phandle - - required: - - reg - port@2: - type: object - description: | + $ref: /schemas/graph.yaml#/properties/port + description: HDMI port for HDMI output - properties: - reg: - const: 2 - - patternProperties: - "^endpoint(@[0-9])$": - type: object - additionalProperties: false - - properties: - remote-endpoint: - $ref: /schemas/types.yaml#/definitions/phandle - - required: - - reg - required: - - "#address-cells" - - "#size-cells" - port@0 - port@2 diff --git a/Documentation/devicetree/bindings/display/bridge/lvds-codec.yaml b/Documentation/devicetree/bindings/display/bridge/lvds-codec.yaml index 66a14d60ce1d..304a1367faaa 100644 --- a/Documentation/devicetree/bindings/display/bridge/lvds-codec.yaml +++ b/Documentation/devicetree/bindings/display/bridge/lvds-codec.yaml @@ -45,25 +45,17 @@ properties: - thine,thc63lvdm83d # For the THC63LVDM83D LVDS serializer ports: - type: object - description: | - This device has two video ports. Their connections are modeled using the - OF graph bindings specified in Documentation/devicetree/bindings/graph.txt - properties: - '#address-cells': - const: 1 - - '#size-cells': - const: 0 + $ref: /schemas/graph.yaml#/properties/ports + properties: port@0: - type: object + $ref: /schemas/graph.yaml#/properties/port description: | For LVDS encoders, port 0 is the parallel input For LVDS decoders, port 0 is the LVDS input port@1: - type: object + $ref: /schemas/graph.yaml#/properties/port description: | For LVDS encoders, port 1 is the LVDS output For LVDS decoders, port 1 is the parallel output @@ -72,8 +64,6 @@ properties: - port@0 - port@1 - additionalProperties: false - powerdown-gpios: description: The GPIO used to control the power down line of this device. diff --git a/Documentation/devicetree/bindings/display/bridge/nwl-dsi.yaml b/Documentation/devicetree/bindings/display/bridge/nwl-dsi.yaml index a125b2dd3a2f..350fb8f400f0 100644 --- a/Documentation/devicetree/bindings/display/bridge/nwl-dsi.yaml +++ b/Documentation/devicetree/bindings/display/bridge/nwl-dsi.yaml @@ -84,40 +84,23 @@ properties: - const: pclk ports: - type: object - description: - A node containing DSI input & output port nodes with endpoint - definitions as documented in - Documentation/devicetree/bindings/graph.txt. + $ref: /schemas/graph.yaml#/properties/ports + properties: port@0: - type: object + $ref: /schemas/graph.yaml#/$defs/port-base description: Input port node to receive pixel data from the display controller. Exactly one endpoint must be specified. properties: - '#address-cells': - const: 1 - - '#size-cells': - const: 0 - endpoint@0: + $ref: /schemas/graph.yaml#/properties/endpoint description: sub-node describing the input from LCDIF - type: object endpoint@1: + $ref: /schemas/graph.yaml#/properties/endpoint description: sub-node describing the input from DCSS - type: object - - reg: - const: 0 - - required: - - '#address-cells' - - '#size-cells' - - reg oneOf: - required: @@ -125,28 +108,18 @@ properties: - required: - endpoint@1 - additionalProperties: false + unevaluatedProperties: false port@1: - type: object + $ref: /schemas/graph.yaml#/properties/port description: DSI output port node to the panel or the next bridge in the chain - '#address-cells': - const: 1 - - '#size-cells': - const: 0 - required: - - '#address-cells' - - '#size-cells' - port@0 - port@1 - additionalProperties: false - required: - '#address-cells' - '#size-cells' diff --git a/Documentation/devicetree/bindings/display/bridge/ps8640.yaml b/Documentation/devicetree/bindings/display/bridge/ps8640.yaml index 763c7909473e..fce82b605c8b 100644 --- a/Documentation/devicetree/bindings/display/bridge/ps8640.yaml +++ b/Documentation/devicetree/bindings/display/bridge/ps8640.yaml @@ -41,34 +41,22 @@ properties: description: Regulator for 3.3V digital core power. ports: - type: object - description: - A node containing DSI input & output port nodes with endpoint - definitions as documented in - Documentation/devicetree/bindings/media/video-interfaces.txt - Documentation/devicetree/bindings/graph.txt - properties: - '#address-cells': - const: 1 - - '#size-cells': - const: 0 + $ref: /schemas/graph.yaml#/properties/ports + properties: port@0: - type: object - description: | + $ref: /schemas/graph.yaml#/properties/port + description: Video port for DSI input port@1: - type: object - description: | + $ref: /schemas/graph.yaml#/properties/port + description: Video port for eDP output (panel or connector). required: - port@0 - additionalProperties: false - required: - compatible - reg diff --git a/Documentation/devicetree/bindings/display/bridge/renesas,lvds.yaml b/Documentation/devicetree/bindings/display/bridge/renesas,lvds.yaml index 7eddcdb666dc..acfc327f70a7 100644 --- a/Documentation/devicetree/bindings/display/bridge/renesas,lvds.yaml +++ b/Documentation/devicetree/bindings/display/bridge/renesas,lvds.yaml @@ -49,33 +49,21 @@ properties: maxItems: 1 ports: - type: object - description: | - This device has two video ports. Their connections are modelled using the - OF graph bindings specified in Documentation/devicetree/bindings/graph.txt. - Each port shall have a single endpoint. + $ref: /schemas/graph.yaml#/properties/ports properties: - '#address-cells': - const: 1 - - '#size-cells': - const: 0 - port@0: - type: object + $ref: /schemas/graph.yaml#/properties/port description: Parallel RGB input port port@1: - type: object + $ref: /schemas/graph.yaml#/properties/port description: LVDS output port required: - port@0 - port@1 - additionalProperties: false - power-domains: maxItems: 1 diff --git a/Documentation/devicetree/bindings/display/bridge/simple-bridge.yaml b/Documentation/devicetree/bindings/display/bridge/simple-bridge.yaml index 64e8a1c24b40..6c7b577fd471 100644 --- a/Documentation/devicetree/bindings/display/bridge/simple-bridge.yaml +++ b/Documentation/devicetree/bindings/display/bridge/simple-bridge.yaml @@ -30,31 +30,21 @@ properties: - ti,ths8135 ports: - type: object - description: | - This device has two video ports. Their connections are modeled using the - OF graph bindings specified in Documentation/devicetree/bindings/graph.txt. - properties: - '#address-cells': - const: 1 - - '#size-cells': - const: 0 + $ref: /schemas/graph.yaml#/properties/ports + properties: port@0: - type: object + $ref: /schemas/graph.yaml#/properties/port description: The bridge input port@1: - type: object + $ref: /schemas/graph.yaml#/properties/port description: The bridge output required: - port@0 - port@1 - additionalProperties: false - enable-gpios: maxItems: 1 description: GPIO controlling bridge enable diff --git a/Documentation/devicetree/bindings/display/bridge/snps,dw-mipi-dsi.yaml b/Documentation/devicetree/bindings/display/bridge/snps,dw-mipi-dsi.yaml index e42cb610f545..3c3e51af154b 100644 --- a/Documentation/devicetree/bindings/display/bridge/snps,dw-mipi-dsi.yaml +++ b/Documentation/devicetree/bindings/display/bridge/snps,dw-mipi-dsi.yaml @@ -47,14 +47,15 @@ properties: const: apb ports: - type: object + $ref: /schemas/graph.yaml#/properties/ports properties: port@0: - type: object + $ref: /schemas/graph.yaml#/properties/port description: Input node to receive pixel data. + port@1: - type: object + $ref: /schemas/graph.yaml#/properties/port description: DSI output node to panel. required: diff --git a/Documentation/devicetree/bindings/display/bridge/thine,thc63lvd1024.yaml b/Documentation/devicetree/bindings/display/bridge/thine,thc63lvd1024.yaml index ac5a3a673a18..8ae382429d2b 100644 --- a/Documentation/devicetree/bindings/display/bridge/thine,thc63lvd1024.yaml +++ b/Documentation/devicetree/bindings/display/bridge/thine,thc63lvd1024.yaml @@ -25,11 +25,8 @@ properties: const: thine,thc63lvd1024 ports: - type: object + $ref: /schemas/graph.yaml#/properties/ports description: | - This device has four video ports. Their connections are modeled using the - OF graph bindings specified in Documentation/devicetree/bindings/graph.txt. - The device can operate in single or dual input and output modes. When operating in single input mode, all pixels are received on port@0, @@ -43,34 +40,26 @@ properties: port@3 shall contain endpoints. properties: - '#address-cells': - const: 1 - - '#size-cells': - const: 0 - port@0: - type: object + $ref: /schemas/graph.yaml#/properties/port description: First LVDS input port port@1: - type: object + $ref: /schemas/graph.yaml#/properties/port description: Second LVDS input port port@2: - type: object + $ref: /schemas/graph.yaml#/properties/port description: First digital CMOS/TTL parallel output port@3: - type: object + $ref: /schemas/graph.yaml#/properties/port description: Second digital CMOS/TTL parallel output required: - port@0 - port@2 - additionalProperties: false - oe-gpios: maxItems: 1 description: Output enable GPIO signal, pin name "OE", active high. diff --git a/Documentation/devicetree/bindings/display/bridge/ti,sn65dsi86.yaml b/Documentation/devicetree/bindings/display/bridge/ti,sn65dsi86.yaml index f8622bd0f61e..26932d2e86ab 100644 --- a/Documentation/devicetree/bindings/display/bridge/ti,sn65dsi86.yaml +++ b/Documentation/devicetree/bindings/display/bridge/ti,sn65dsi86.yaml @@ -71,54 +71,26 @@ properties: description: See ../../pwm/pwm.yaml for description of the cell formats. ports: - type: object - additionalProperties: false + $ref: /schemas/graph.yaml#/properties/ports properties: - "#address-cells": - const: 1 - - "#size-cells": - const: 0 - port@0: - type: object - additionalProperties: false - + $ref: /schemas/graph.yaml#/properties/port description: Video port for MIPI DSI input - properties: - reg: - const: 0 - - endpoint: - type: object - additionalProperties: false - properties: - remote-endpoint: true - - required: - - reg - port@1: - type: object - additionalProperties: false - + $ref: /schemas/graph.yaml#/$defs/port-base + unevaluatedProperties: false description: Video port for eDP output (panel or connector). properties: - reg: - const: 1 - endpoint: - type: object - additionalProperties: false + $ref: /schemas/graph.yaml#/$defs/endpoint-base + unevaluatedProperties: false properties: - remote-endpoint: true - data-lanes: oneOf: - minItems: 1 @@ -171,12 +143,7 @@ properties: dependencies: lane-polarities: [data-lanes] - required: - - reg - required: - - "#address-cells" - - "#size-cells" - port@0 - port@1 diff --git a/Documentation/devicetree/bindings/display/bridge/ti,tfp410.yaml b/Documentation/devicetree/bindings/display/bridge/ti,tfp410.yaml index 605831c1e836..4c5dd8ec2951 100644 --- a/Documentation/devicetree/bindings/display/bridge/ti,tfp410.yaml +++ b/Documentation/devicetree/bindings/display/bridge/ti,tfp410.yaml @@ -31,23 +31,18 @@ properties: maximum: 7 ports: - description: - A node containing input and output port nodes with endpoint - definitions as documented in - Documentation/devicetree/bindings/media/video-interfaces.txt - type: object + $ref: /schemas/graph.yaml#/properties/ports properties: port@0: + $ref: /schemas/graph.yaml#/$defs/port-base + unevaluatedProperties: false description: DPI input port. - type: object properties: - reg: - const: 0 - endpoint: - type: object + $ref: /schemas/graph.yaml#/$defs/endpoint-base + unevaluatedProperties: false properties: pclk-sample: @@ -67,15 +62,8 @@ properties: default: 24 port@1: + $ref: /schemas/graph.yaml#/properties/port description: DVI output port. - type: object - - properties: - reg: - const: 1 - - endpoint: - type: object required: - port@0 diff --git a/Documentation/devicetree/bindings/display/bridge/toshiba,tc358762.yaml b/Documentation/devicetree/bindings/display/bridge/toshiba,tc358762.yaml index 195025e6803c..5216c27fc0ad 100644 --- a/Documentation/devicetree/bindings/display/bridge/toshiba,tc358762.yaml +++ b/Documentation/devicetree/bindings/display/bridge/toshiba,tc358762.yaml @@ -25,62 +25,20 @@ properties: description: Regulator for 1.2V internal core power. ports: - type: object + $ref: /schemas/graph.yaml#/properties/ports properties: - "#address-cells": - const: 1 - - "#size-cells": - const: 0 - port@0: - type: object - additionalProperties: false - - description: | + $ref: /schemas/graph.yaml#/properties/port + description: Video port for MIPI DSI input - properties: - reg: - const: 0 - - patternProperties: - endpoint: - type: object - additionalProperties: false - - properties: - remote-endpoint: true - - required: - - reg - port@1: - type: object - additionalProperties: false - - description: | + $ref: /schemas/graph.yaml#/properties/port + description: Video port for MIPI DPI output (panel or connector). - properties: - reg: - const: 1 - - patternProperties: - endpoint: - type: object - additionalProperties: false - - properties: - remote-endpoint: true - - required: - - reg - required: - - "#address-cells" - - "#size-cells" - port@0 - port@1 diff --git a/Documentation/devicetree/bindings/display/bridge/toshiba,tc358768.yaml b/Documentation/devicetree/bindings/display/bridge/toshiba,tc358768.yaml index c036a75db8f7..eacfe7165083 100644 --- a/Documentation/devicetree/bindings/display/bridge/toshiba,tc358768.yaml +++ b/Documentation/devicetree/bindings/display/bridge/toshiba,tc358768.yaml @@ -42,65 +42,30 @@ properties: const: refclk ports: - type: object + $ref: /schemas/graph.yaml#/properties/ports properties: - "#address-cells": - const: 1 - - "#size-cells": - const: 0 - port@0: - type: object - additionalProperties: false - + $ref: /schemas/graph.yaml#/$defs/port-base + unevaluatedProperties: false description: | Video port for RGB input properties: - reg: - const: 0 - - patternProperties: endpoint: - type: object - additionalProperties: false + $ref: /schemas/graph.yaml#/$defs/endpoint-base + unevaluatedProperties: false properties: data-lines: enum: [ 16, 18, 24 ] - remote-endpoint: true - - required: - - reg - port@1: - type: object - additionalProperties: false - + $ref: /schemas/graph.yaml#/properties/port description: | Video port for DSI output (panel or connector). - properties: - reg: - const: 1 - - patternProperties: - endpoint: - type: object - additionalProperties: false - - properties: - remote-endpoint: true - - required: - - reg - required: - - "#address-cells" - - "#size-cells" - port@0 - port@1 @@ -156,4 +121,3 @@ examples: }; }; }; - diff --git a/Documentation/devicetree/bindings/display/bridge/toshiba,tc358775.yaml b/Documentation/devicetree/bindings/display/bridge/toshiba,tc358775.yaml index b5959cc78b8d..10471c6c1ff9 100644 --- a/Documentation/devicetree/bindings/display/bridge/toshiba,tc358775.yaml +++ b/Documentation/devicetree/bindings/display/bridge/toshiba,tc358775.yaml @@ -42,31 +42,22 @@ properties: description: Hardware reset, Low active ports: - type: object - description: - A node containing input and output port nodes with endpoint definitions - as documented in - Documentation/devicetree/bindings/media/video-interfaces.txt - properties: - "#address-cells": - const: 1 - - "#size-cells": - const: 0 + $ref: /schemas/graph.yaml#/properties/ports + properties: port@0: - type: object + $ref: /schemas/graph.yaml#/properties/port description: | DSI Input. The remote endpoint phandle should be a reference to a valid mipi_dsi_host device node. port@1: - type: object + $ref: /schemas/graph.yaml#/properties/port description: | Video port for LVDS output (panel or connector). port@2: - type: object + $ref: /schemas/graph.yaml#/properties/port description: | Video port for Dual link LVDS output (panel or connector). diff --git a/Documentation/devicetree/bindings/display/connector/analog-tv-connector.yaml b/Documentation/devicetree/bindings/display/connector/analog-tv-connector.yaml index eebe88fed999..a31ca2d52b86 100644 --- a/Documentation/devicetree/bindings/display/connector/analog-tv-connector.yaml +++ b/Documentation/devicetree/bindings/display/connector/analog-tv-connector.yaml @@ -25,6 +25,7 @@ properties: $ref: /schemas/types.yaml#/definitions/uint32 port: + $ref: /schemas/graph.yaml#/properties/port description: Connection to controller providing analog TV signals required: diff --git a/Documentation/devicetree/bindings/display/connector/dvi-connector.yaml b/Documentation/devicetree/bindings/display/connector/dvi-connector.yaml index 71cb9220fa59..93eb14294e68 100644 --- a/Documentation/devicetree/bindings/display/connector/dvi-connector.yaml +++ b/Documentation/devicetree/bindings/display/connector/dvi-connector.yaml @@ -36,6 +36,7 @@ properties: description: the connector has pins for DVI dual-link port: + $ref: /schemas/graph.yaml#/properties/port description: Connection to controller providing DVI signals required: diff --git a/Documentation/devicetree/bindings/display/connector/hdmi-connector.yaml b/Documentation/devicetree/bindings/display/connector/hdmi-connector.yaml index 14d7128af592..83c0d008265b 100644 --- a/Documentation/devicetree/bindings/display/connector/hdmi-connector.yaml +++ b/Documentation/devicetree/bindings/display/connector/hdmi-connector.yaml @@ -37,6 +37,7 @@ properties: maxItems: 1 port: + $ref: /schemas/graph.yaml#/properties/port description: Connection to controller providing HDMI signals required: diff --git a/Documentation/devicetree/bindings/display/connector/vga-connector.yaml b/Documentation/devicetree/bindings/display/connector/vga-connector.yaml index 5782c4bb3252..25f868002000 100644 --- a/Documentation/devicetree/bindings/display/connector/vga-connector.yaml +++ b/Documentation/devicetree/bindings/display/connector/vga-connector.yaml @@ -20,6 +20,7 @@ properties: $ref: /schemas/types.yaml#/definitions/phandle port: + $ref: /schemas/graph.yaml#/properties/port description: Connection to controller providing VGA signals required: diff --git a/Documentation/devicetree/bindings/display/imx/nxp,imx8mq-dcss.yaml b/Documentation/devicetree/bindings/display/imx/nxp,imx8mq-dcss.yaml index f1f25aa794d9..0091df9dd73b 100644 --- a/Documentation/devicetree/bindings/display/imx/nxp,imx8mq-dcss.yaml +++ b/Documentation/devicetree/bindings/display/imx/nxp,imx8mq-dcss.yaml @@ -74,7 +74,7 @@ properties: - description: Must be 400 MHz port: - type: object + $ref: /schemas/graph.yaml#/properties/port description: A port node pointing to the input port of a HDMI/DP or MIPI display bridge. diff --git a/Documentation/devicetree/bindings/display/ingenic,ipu.yaml b/Documentation/devicetree/bindings/display/ingenic,ipu.yaml index 12064a8e7a92..e679f48a3886 100644 --- a/Documentation/devicetree/bindings/display/ingenic,ipu.yaml +++ b/Documentation/devicetree/bindings/display/ingenic,ipu.yaml @@ -31,9 +31,8 @@ properties: clock-names: const: ipu -patternProperties: - "^ports?$": - description: OF graph bindings (specified in bindings/graph.txt). + port: + $ref: /schemas/graph.yaml#/properties/port required: - compatible diff --git a/Documentation/devicetree/bindings/display/ingenic,lcd.yaml b/Documentation/devicetree/bindings/display/ingenic,lcd.yaml index 768050f30dba..50d2b0a50e8a 100644 --- a/Documentation/devicetree/bindings/display/ingenic,lcd.yaml +++ b/Documentation/devicetree/bindings/display/ingenic,lcd.yaml @@ -39,18 +39,18 @@ properties: minItems: 1 port: - description: OF graph bindings (specified in bindings/graph.txt). + $ref: /schemas/graph.yaml#/properties/port ports: - description: OF graph bindings (specified in bindings/graph.txt). - type: object + $ref: /schemas/graph.yaml#/properties/ports + properties: port@0: - type: object + $ref: /schemas/graph.yaml#/properties/port description: DPI output, to interface with TFT panels. port@8: - type: object + $ref: /schemas/graph.yaml#/properties/port description: Link to the Image Processing Unit (IPU). (See ingenic,ipu.yaml). diff --git a/Documentation/devicetree/bindings/display/intel,keembay-display.yaml b/Documentation/devicetree/bindings/display/intel,keembay-display.yaml index 0a697d45c2ad..bc6622b010ca 100644 --- a/Documentation/devicetree/bindings/display/intel,keembay-display.yaml +++ b/Documentation/devicetree/bindings/display/intel,keembay-display.yaml @@ -36,7 +36,7 @@ properties: maxItems: 1 port: - type: object + $ref: /schemas/graph.yaml#/properties/port description: Display output node to DSI. required: diff --git a/Documentation/devicetree/bindings/display/panel/advantech,idk-2121wr.yaml b/Documentation/devicetree/bindings/display/panel/advantech,idk-2121wr.yaml index 6b7fddc80c41..67682fe77f10 100644 --- a/Documentation/devicetree/bindings/display/panel/advantech,idk-2121wr.yaml +++ b/Documentation/devicetree/bindings/display/panel/advantech,idk-2121wr.yaml @@ -37,34 +37,33 @@ properties: panel-timing: true ports: - type: object + $ref: /schemas/graph.yaml#/properties/ports + properties: port@0: - type: object + $ref: /schemas/graph.yaml#/$defs/port-base + unevaluatedProperties: false description: The sink for odd pixels. properties: - reg: - const: 0 - dual-lvds-odd-pixels: true required: - - reg - dual-lvds-odd-pixels port@1: - type: object + $ref: /schemas/graph.yaml#/$defs/port-base + unevaluatedProperties: false description: The sink for even pixels. properties: - reg: - const: 1 - dual-lvds-even-pixels: true required: - - reg - dual-lvds-even-pixels + required: + - port@0 + - port@1 + additionalProperties: false required: diff --git a/Documentation/devicetree/bindings/display/panel/panel-common.yaml b/Documentation/devicetree/bindings/display/panel/panel-common.yaml index cd6dc5461721..5b38dc89cb21 100644 --- a/Documentation/devicetree/bindings/display/panel/panel-common.yaml +++ b/Documentation/devicetree/bindings/display/panel/panel-common.yaml @@ -68,16 +68,7 @@ properties: # Connectivity port: - type: object - - ports: - type: object - description: - Panels receive video data through one or multiple connections. While - the nature of those connections is specific to the panel type, the - connectivity is expressed in a standard fashion using ports as specified - in the device graph bindings defined in - Documentation/devicetree/bindings/graph.txt. + $ref: /schemas/graph.yaml#/properties/port ddc-i2c-bus: $ref: /schemas/types.yaml#/definitions/phandle diff --git a/Documentation/devicetree/bindings/display/rockchip/rockchip,rk3066-hdmi.yaml b/Documentation/devicetree/bindings/display/rockchip/rockchip,rk3066-hdmi.yaml index 4110d003ce1f..008c144257cb 100644 --- a/Documentation/devicetree/bindings/display/rockchip/rockchip,rk3066-hdmi.yaml +++ b/Documentation/devicetree/bindings/display/rockchip/rockchip,rk3066-hdmi.yaml @@ -43,34 +43,24 @@ properties: This soc uses GRF regs to switch the HDMI TX input between vop0 and vop1. ports: - type: object + $ref: /schemas/graph.yaml#/properties/ports properties: - "#address-cells": - const: 1 - - "#size-cells": - const: 0 - port@0: - type: object + $ref: /schemas/graph.yaml#/properties/port description: Port node with two endpoints, numbered 0 and 1, connected respectively to vop0 and vop1. port@1: - type: object + $ref: /schemas/graph.yaml#/properties/port description: Port node with one endpoint connected to a hdmi-connector node. required: - - "#address-cells" - - "#size-cells" - port@0 - port@1 - additionalProperties: false - required: - compatible - reg diff --git a/Documentation/devicetree/bindings/display/rockchip/rockchip-vop.yaml b/Documentation/devicetree/bindings/display/rockchip/rockchip-vop.yaml index ed8148e26e24..6f43d885c9b3 100644 --- a/Documentation/devicetree/bindings/display/rockchip/rockchip-vop.yaml +++ b/Documentation/devicetree/bindings/display/rockchip/rockchip-vop.yaml @@ -70,10 +70,7 @@ properties: - const: dclk port: - type: object - description: - A port node with endpoint definitions as defined in - Documentation/devicetree/bindings/media/video-interfaces.txt. + $ref: /schemas/graph.yaml#/properties/port assigned-clocks: maxItems: 2 diff --git a/Documentation/devicetree/bindings/display/st,stm32-dsi.yaml b/Documentation/devicetree/bindings/display/st,stm32-dsi.yaml index 327a14d85df8..679daed4124e 100644 --- a/Documentation/devicetree/bindings/display/st,stm32-dsi.yaml +++ b/Documentation/devicetree/bindings/display/st,stm32-dsi.yaml @@ -51,20 +51,16 @@ properties: Phandle of the regulator that provides the supply voltage. ports: - type: object - description: - A node containing DSI input & output port nodes with endpoint - definitions as documented in - Documentation/devicetree/bindings/media/video-interfaces.txt - Documentation/devicetree/bindings/graph.txt + $ref: /schemas/graph.yaml#/properties/ports + properties: port@0: - type: object + $ref: /schemas/graph.yaml#/properties/port description: DSI input port node, connected to the ltdc rgb output port. port@1: - type: object + $ref: /schemas/graph.yaml#/properties/port description: DSI output port node, connected to a panel or a bridge input port" diff --git a/Documentation/devicetree/bindings/display/st,stm32-ltdc.yaml b/Documentation/devicetree/bindings/display/st,stm32-ltdc.yaml index bf8ad916e9b0..d54f9ca207af 100644 --- a/Documentation/devicetree/bindings/display/st,stm32-ltdc.yaml +++ b/Documentation/devicetree/bindings/display/st,stm32-ltdc.yaml @@ -35,15 +35,13 @@ properties: maxItems: 1 port: - type: object - description: - "Video port for DPI RGB output. + $ref: /schemas/graph.yaml#/properties/port + description: | + Video port for DPI RGB output. ltdc has one video port with up to 2 endpoints: - for external dpi rgb panel or bridge, using gpios. - for internal dpi input of the MIPI DSI host controller. Note: These 2 endpoints cannot be activated simultaneously. - Please refer to the bindings defined in - Documentation/devicetree/bindings/media/video-interfaces.txt." required: - compatible diff --git a/Documentation/devicetree/bindings/display/ste,mcde.yaml b/Documentation/devicetree/bindings/display/ste,mcde.yaml index 830c9b4091cc..de0c678b3c29 100644 --- a/Documentation/devicetree/bindings/display/ste,mcde.yaml +++ b/Documentation/devicetree/bindings/display/ste,mcde.yaml @@ -42,10 +42,9 @@ properties: description: a phandle to the analog voltage regulator port: - type: object + $ref: /schemas/graph.yaml#/properties/port description: - A DPI port node with endpoint definitions as defined in - Documentation/devicetree/bindings/media/video-interfaces.txt + A DPI port node "#address-cells": const: 1 diff --git a/Documentation/devicetree/bindings/display/ti/ti,am65x-dss.yaml b/Documentation/devicetree/bindings/display/ti/ti,am65x-dss.yaml index 4dc30738ee57..781c1868b0b8 100644 --- a/Documentation/devicetree/bindings/display/ti/ti,am65x-dss.yaml +++ b/Documentation/devicetree/bindings/display/ti/ti,am65x-dss.yaml @@ -74,30 +74,19 @@ properties: type: boolean ports: - type: object - description: - Ports as described in Documentation/devicetree/bindings/graph.txt - properties: - "#address-cells": - const: 1 - - "#size-cells": - const: 0 + $ref: /schemas/graph.yaml#/properties/ports + properties: port@0: - type: object + $ref: /schemas/graph.yaml#/properties/port description: The DSS OLDI output port node form video port 1 port@1: - type: object + $ref: /schemas/graph.yaml#/properties/port description: The DSS DPI output port node from video port 2 - required: - - "#address-cells" - - "#size-cells" - ti,am65x-oldi-io-ctrl: $ref: "/schemas/types.yaml#/definitions/phandle-array" maxItems: 1 diff --git a/Documentation/devicetree/bindings/display/ti/ti,j721e-dss.yaml b/Documentation/devicetree/bindings/display/ti/ti,j721e-dss.yaml index c9a947d55fa4..2986f9acc9f0 100644 --- a/Documentation/devicetree/bindings/display/ti/ti,j721e-dss.yaml +++ b/Documentation/devicetree/bindings/display/ti/ti,j721e-dss.yaml @@ -107,40 +107,29 @@ properties: type: boolean ports: - type: object - description: - Ports as described in Documentation/devicetree/bindings/graph.txt - properties: - "#address-cells": - const: 1 - - "#size-cells": - const: 0 + $ref: /schemas/graph.yaml#/properties/ports + properties: port@0: - type: object + $ref: /schemas/graph.yaml#/properties/port description: The output port node form video port 1 port@1: - type: object + $ref: /schemas/graph.yaml#/properties/port description: The output port node from video port 2 port@2: - type: object + $ref: /schemas/graph.yaml#/properties/port description: The output port node from video port 3 port@3: - type: object + $ref: /schemas/graph.yaml#/properties/port description: The output port node from video port 4 - required: - - "#address-cells" - - "#size-cells" - max-memory-bandwidth: $ref: /schemas/types.yaml#/definitions/uint32 description: diff --git a/Documentation/devicetree/bindings/display/ti/ti,k2g-dss.yaml b/Documentation/devicetree/bindings/display/ti/ti,k2g-dss.yaml index 8f87b82c6695..7ce7bbad5780 100644 --- a/Documentation/devicetree/bindings/display/ti/ti,k2g-dss.yaml +++ b/Documentation/devicetree/bindings/display/ti/ti,k2g-dss.yaml @@ -54,9 +54,8 @@ properties: description: phandle to the associated power domain port: - type: object + $ref: /schemas/graph.yaml#/properties/port description: - Port as described in Documentation/devicetree/bindings/graph.txt. The DSS DPI output port node max-memory-bandwidth: -- cgit v1.2.3 From 1316b6e460ff38d697ce4f4b8c20f8d915c88175 Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Fri, 1 Jan 2021 12:45:22 +0100 Subject: dt-bindings: display: Augment s6e63m0 bindings This fixes the following problems with the s6e63m0 display bindings: - When used on the DSI bus, the panel is listed directly as a subnode on the DSI host so the "port" node is not compulsory. Remove "port" from required properties. - The panel contains its own backlight control, so reference the backlight common properties and list default-brightness and max-brightness as supported but optional properties. Cc: devicetree@vger.kernel.org Signed-off-by: Linus Walleij Reviewed-by: Rob Herring Link: https://patchwork.freedesktop.org/patch/msgid/20210101114522.1981838-1-linus.walleij@linaro.org --- Documentation/devicetree/bindings/display/panel/samsung,s6e63m0.yaml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/display/panel/samsung,s6e63m0.yaml b/Documentation/devicetree/bindings/display/panel/samsung,s6e63m0.yaml index 1dab80ae1d0a..ea58df49263a 100644 --- a/Documentation/devicetree/bindings/display/panel/samsung,s6e63m0.yaml +++ b/Documentation/devicetree/bindings/display/panel/samsung,s6e63m0.yaml @@ -11,6 +11,7 @@ maintainers: allOf: - $ref: panel-common.yaml# + - $ref: /schemas/leds/backlight/common.yaml# properties: compatible: @@ -19,6 +20,8 @@ properties: reg: true reset-gpios: true port: true + default-brightness: true + max-brightness: true vdd3-supply: description: VDD regulator @@ -31,7 +34,6 @@ required: - reset-gpios - vdd3-supply - vci-supply - - port unevaluatedProperties: false -- cgit v1.2.3 From c706121386fe8414ac0a0acab37c74aac698c51d Mon Sep 17 00:00:00 2001 From: Adam Ford Date: Mon, 28 Dec 2020 14:22:20 -0600 Subject: dt-bindings: clock: renesas: rcar-usb2-clock-sel: Add support for RZ/G2 M/N/H The datasheet for the RZ/G2 Series show the bit for choosing between a crystal oscillator and an external oscillator is present. Add the bindings for r8a774a1 (RZ/G2M), r8a774b1 (RZ/G2N), and r8a774e1 (RZ/G2H) Signed-off-by: Adam Ford Acked-by: Rob Herring Link: https://lore.kernel.org/r/20201228202221.2327468-1-aford173@gmail.com Signed-off-by: Geert Uytterhoeven --- .../devicetree/bindings/clock/renesas,rcar-usb2-clock-sel.yaml | 3 +++ 1 file changed, 3 insertions(+) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/clock/renesas,rcar-usb2-clock-sel.yaml b/Documentation/devicetree/bindings/clock/renesas,rcar-usb2-clock-sel.yaml index 5be1229b3d6e..6eaabb4d82ec 100644 --- a/Documentation/devicetree/bindings/clock/renesas,rcar-usb2-clock-sel.yaml +++ b/Documentation/devicetree/bindings/clock/renesas,rcar-usb2-clock-sel.yaml @@ -35,6 +35,9 @@ properties: compatible: items: - enum: + - renesas,r8a774a1-rcar-usb2-clock-sel # RZ/G2M + - renesas,r8a774b1-rcar-usb2-clock-sel # RZ/G2N + - renesas,r8a774e1-rcar-usb2-clock-sel # RZ/G2H - renesas,r8a7795-rcar-usb2-clock-sel # R-Car H3 - renesas,r8a7796-rcar-usb2-clock-sel # R-Car M3-W - renesas,r8a77961-rcar-usb2-clock-sel # R-Car M3-W+ -- cgit v1.2.3 From aa62401644b32f5229183c375bcc03e02a0888ac Mon Sep 17 00:00:00 2001 From: Serge Semin Date: Thu, 10 Dec 2020 12:09:25 +0300 Subject: dt-bindings: usb: usb-hcd: Detach generic USB controller properties There can be three distinctive types of the USB controllers: USB hosts, USB peripherals/gadgets and USB OTG, which can switch from one role to another. In order to have that hierarchy handled in the DT binding files, we need to collect common properties in a common DT schema and specific properties in dedicated schemas. Seeing the usb-hcd.yaml DT schema is dedicated for the USB host controllers only, let's move some common properties from there into the usb.yaml schema. So the later would be available to evaluate all currently supported types of the USB controllers. While at it add an explicit "additionalProperties: true" into the usb-hcd.yaml as setting the additionalProperties/unevaluateProperties properties is going to be get mandatory soon. Reviewed-by: Rob Herring Signed-off-by: Serge Semin Link: https://lore.kernel.org/r/20201210090944.16283-2-Sergey.Semin@baikalelectronics.ru Signed-off-by: Greg Kroah-Hartman --- Documentation/devicetree/bindings/usb/usb-hcd.yaml | 14 ++--------- Documentation/devicetree/bindings/usb/usb.yaml | 29 ++++++++++++++++++++++ 2 files changed, 31 insertions(+), 12 deletions(-) create mode 100644 Documentation/devicetree/bindings/usb/usb.yaml (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/usb/usb-hcd.yaml b/Documentation/devicetree/bindings/usb/usb-hcd.yaml index b545b087b342..81f3ad1419d8 100644 --- a/Documentation/devicetree/bindings/usb/usb-hcd.yaml +++ b/Documentation/devicetree/bindings/usb/usb-hcd.yaml @@ -9,18 +9,8 @@ title: Generic USB Host Controller Device Tree Bindings maintainers: - Greg Kroah-Hartman -properties: - $nodename: - pattern: "^usb(@.*)?" - - phys: - $ref: /schemas/types.yaml#/definitions/phandle-array - description: - List of all the USB PHYs on this HCD - - phy-names: - description: - Name specifier for the USB PHY +allOf: + - $ref: usb.yaml# additionalProperties: true diff --git a/Documentation/devicetree/bindings/usb/usb.yaml b/Documentation/devicetree/bindings/usb/usb.yaml new file mode 100644 index 000000000000..941ad59fbac5 --- /dev/null +++ b/Documentation/devicetree/bindings/usb/usb.yaml @@ -0,0 +1,29 @@ +# SPDX-License-Identifier: GPL-2.0 +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/usb/usb.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Generic USB Controller Device Tree Bindings + +maintainers: + - Greg Kroah-Hartman + +select: false + +properties: + $nodename: + pattern: "^usb(@.*)?" + + phys: + $ref: /schemas/types.yaml#/definitions/phandle-array + description: + List of all the USB PHYs on this HCD + + phy-names: + description: + Name specifier for the USB PHY + +additionalProperties: true + +... -- cgit v1.2.3 From b0864e1a4d9d2f030cf143f324f52f77d7bc68ab Mon Sep 17 00:00:00 2001 From: Serge Semin Date: Thu, 10 Dec 2020 12:09:26 +0300 Subject: dt-bindings: usb: Convert generic USB properties to DT schemas The generic USB properties have been described in the legacy bindings text file: Documentation/devicetree/bindings/usb/generic.txt . Let's convert its content into the generic USB, USB HCD and USB DRD DT schemas. So the Generic USB schema will be applicable to all USB controllers, USB HCD - for the generic USB Host controllers and the USB DRD - for the USB Dual-role controllers. Note the USB DRD schema is supposed to work in conjunction with the USB peripheral/gadget and USB host controllers DT schemas. Reviewed-by: Rob Herring Signed-off-by: Serge Semin Link: https://lore.kernel.org/r/20201210090944.16283-3-Sergey.Semin@baikalelectronics.ru Signed-off-by: Greg Kroah-Hartman --- Documentation/devicetree/bindings/usb/generic.txt | 57 ---------------- Documentation/devicetree/bindings/usb/usb-drd.yaml | 77 ++++++++++++++++++++++ Documentation/devicetree/bindings/usb/usb-hcd.yaml | 5 ++ Documentation/devicetree/bindings/usb/usb.yaml | 22 +++++++ 4 files changed, 104 insertions(+), 57 deletions(-) delete mode 100644 Documentation/devicetree/bindings/usb/generic.txt create mode 100644 Documentation/devicetree/bindings/usb/usb-drd.yaml (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/usb/generic.txt b/Documentation/devicetree/bindings/usb/generic.txt deleted file mode 100644 index ba472e7aefc9..000000000000 --- a/Documentation/devicetree/bindings/usb/generic.txt +++ /dev/null @@ -1,57 +0,0 @@ -Generic USB Properties - -Optional properties: - - maximum-speed: tells USB controllers we want to work up to a certain - speed. Valid arguments are "super-speed-plus", - "super-speed", "high-speed", "full-speed" and - "low-speed". In case this isn't passed via DT, USB - controllers should default to their maximum HW - capability. - - dr_mode: tells Dual-Role USB controllers that we want to work on a - particular mode. Valid arguments are "host", - "peripheral" and "otg". In case this attribute isn't - passed via DT, USB DRD controllers should default to - OTG. - - phy_type: tells USB controllers that we want to configure the core to support - a UTMI+ PHY with an 8- or 16-bit interface if UTMI+ is - selected. Valid arguments are "utmi" and "utmi_wide". - In case this isn't passed via DT, USB controllers should - default to HW capability. - - otg-rev: tells usb driver the release number of the OTG and EH supplement - with which the device and its descriptors are compliant, - in binary-coded decimal (i.e. 2.0 is 0200H). This - property is used if any real OTG features(HNP/SRP/ADP) - is enabled, if ADP is required, otg-rev should be - 0x0200 or above. - - companion: phandle of a companion - - hnp-disable: tells OTG controllers we want to disable OTG HNP, normally HNP - is the basic function of real OTG except you want it - to be a srp-capable only B device. - - srp-disable: tells OTG controllers we want to disable OTG SRP, SRP is - optional for OTG device. - - adp-disable: tells OTG controllers we want to disable OTG ADP, ADP is - optional for OTG device. - - usb-role-switch: boolean, indicates that the device is capable of assigning - the USB data role (USB host or USB device) for a given - USB connector, such as Type-C, Type-B(micro). - see connector/usb-connector.yaml. - - role-switch-default-mode: indicating if usb-role-switch is enabled, the - device default operation mode of controller while usb - role is USB_ROLE_NONE. Valid arguments are "host" and - "peripheral". Defaults to "peripheral" if not - specified. - - -This is an attribute to a USB controller such as: - -dwc3@4a030000 { - compatible = "synopsys,dwc3"; - reg = <0x4a030000 0xcfff>; - interrupts = <0 92 4> - usb-phy = <&usb2_phy>, <&usb3,phy>; - maximum-speed = "super-speed"; - dr_mode = "otg"; - phy_type = "utmi_wide"; - otg-rev = <0x0200>; - adp-disable; -}; diff --git a/Documentation/devicetree/bindings/usb/usb-drd.yaml b/Documentation/devicetree/bindings/usb/usb-drd.yaml new file mode 100644 index 000000000000..f3a64c46dcd0 --- /dev/null +++ b/Documentation/devicetree/bindings/usb/usb-drd.yaml @@ -0,0 +1,77 @@ +# SPDX-License-Identifier: GPL-2.0 +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/usb/usb-drd.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Generic USB OTG Controller Device Tree Bindings + +maintainers: + - Greg Kroah-Hartman + +properties: + otg-rev: + description: + Tells usb driver the release number of the OTG and EH supplement with + which the device and its descriptors are compliant, in binary-coded + decimal (i.e. 2.0 is 0200H). This property is used if any real OTG + features (HNP/SRP/ADP) is enabled. If ADP is required, otg-rev should be + 0x0200 or above. + $ref: /schemas/types.yaml#/definitions/uint32 + + dr_mode: + description: + Tells Dual-Role USB controllers that we want to work on a particular + mode. In case this attribute isn't passed via DT, USB DRD controllers + should default to OTG. + $ref: /schemas/types.yaml#/definitions/string + enum: [host, peripheral, otg] + + hnp-disable: + description: + Tells OTG controllers we want to disable OTG HNP. Normally HNP is the + basic function of real OTG except you want it to be a srp-capable only B + device. + type: boolean + + srp-disable: + description: + Tells OTG controllers we want to disable OTG SRP. SRP is optional for OTG + device. + type: boolean + + adp-disable: + description: + Tells OTG controllers we want to disable OTG ADP. ADP is optional for OTG + device. + type: boolean + + usb-role-switch: + description: + Indicates that the device is capable of assigning the USB data role + (USB host or USB device) for a given USB connector, such as Type-C, + Type-B(micro). See connector/usb-connector.yaml. + + role-switch-default-mode: + description: + Indicates if usb-role-switch is enabled, the device default operation + mode of controller while usb role is USB_ROLE_NONE. + $ref: /schemas/types.yaml#/definitions/string + enum: [host, peripheral] + default: peripheral + +additionalProperties: true + +examples: + - | + usb@4a030000 { + compatible = "snps,dwc3"; + reg = <0x4a030000 0xcfff>; + interrupts = <0 92 4>; + usb-phy = <&usb2_phy>, <&usb3_phy>; + maximum-speed = "super-speed"; + dr_mode = "otg"; + phy_type = "utmi_wide"; + otg-rev = <0x0200>; + adp-disable; + }; diff --git a/Documentation/devicetree/bindings/usb/usb-hcd.yaml b/Documentation/devicetree/bindings/usb/usb-hcd.yaml index 81f3ad1419d8..52cc84c400c0 100644 --- a/Documentation/devicetree/bindings/usb/usb-hcd.yaml +++ b/Documentation/devicetree/bindings/usb/usb-hcd.yaml @@ -12,6 +12,11 @@ maintainers: allOf: - $ref: usb.yaml# +properties: + companion: + description: Phandle of a companion device + $ref: /schemas/types.yaml#/definitions/phandle + additionalProperties: true examples: diff --git a/Documentation/devicetree/bindings/usb/usb.yaml b/Documentation/devicetree/bindings/usb/usb.yaml index 941ad59fbac5..aab74c671ccc 100644 --- a/Documentation/devicetree/bindings/usb/usb.yaml +++ b/Documentation/devicetree/bindings/usb/usb.yaml @@ -24,6 +24,28 @@ properties: description: Name specifier for the USB PHY + phy_type: + description: + Tells USB controllers that we want to configure the core to support a + UTMI+ PHY with an 8- or 16-bit interface if UTMI+ is selected. In case + this isn't passed via DT, USB controllers should default to HW + capability. + $ref: /schemas/types.yaml#/definitions/string + enum: [utmi, utmi_wide] + + maximum-speed: + description: + Tells USB controllers we want to work up to a certain speed. In case this + isn't passed via DT, USB controllers should default to their maximum HW + capability. + $ref: /schemas/types.yaml#/definitions/string + enum: + - low-speed + - full-speed + - high-speed + - super-speed + - super-speed-plus + additionalProperties: true ... -- cgit v1.2.3 From 5c67b97ecfa72b75bf5b562ce6448b18c309bf56 Mon Sep 17 00:00:00 2001 From: Serge Semin Date: Thu, 10 Dec 2020 12:09:27 +0300 Subject: dt-bindings: usb: usb-drd: Add "otg-rev" property constraints There are only four OTG revisions are currently supported by the kernel: 0x0100, 0x0120, 0x0130, 0x0200. Any another value is considered as invalid. Reviewed-by: Rob Herring Signed-off-by: Serge Semin Link: https://lore.kernel.org/r/20201210090944.16283-4-Sergey.Semin@baikalelectronics.ru Signed-off-by: Greg Kroah-Hartman --- Documentation/devicetree/bindings/usb/usb-drd.yaml | 1 + 1 file changed, 1 insertion(+) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/usb/usb-drd.yaml b/Documentation/devicetree/bindings/usb/usb-drd.yaml index f3a64c46dcd0..f229fc8068d9 100644 --- a/Documentation/devicetree/bindings/usb/usb-drd.yaml +++ b/Documentation/devicetree/bindings/usb/usb-drd.yaml @@ -18,6 +18,7 @@ properties: features (HNP/SRP/ADP) is enabled. If ADP is required, otg-rev should be 0x0200 or above. $ref: /schemas/types.yaml#/definitions/uint32 + enum: [0x0100, 0x0120, 0x0130, 0x0200] dr_mode: description: -- cgit v1.2.3 From 99581ba863f914bec762f679bd2c2c9031a2ba2a Mon Sep 17 00:00:00 2001 From: Serge Semin Date: Thu, 10 Dec 2020 12:09:28 +0300 Subject: dt-bindings: usb: Add "ulpi/serial/hsic" PHY types Aside from the UTMI+ there are also ULPI, Serial and HSIC PHY types that can be specified in the phy_type HCD property. Add them to the enumeration of the acceptable values. Reviewed-by: Rob Herring Signed-off-by: Serge Semin Link: https://lore.kernel.org/r/20201210090944.16283-5-Sergey.Semin@baikalelectronics.ru Signed-off-by: Greg Kroah-Hartman --- Documentation/devicetree/bindings/usb/usb.yaml | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/usb/usb.yaml b/Documentation/devicetree/bindings/usb/usb.yaml index aab74c671ccc..53144c4600c0 100644 --- a/Documentation/devicetree/bindings/usb/usb.yaml +++ b/Documentation/devicetree/bindings/usb/usb.yaml @@ -27,11 +27,13 @@ properties: phy_type: description: Tells USB controllers that we want to configure the core to support a - UTMI+ PHY with an 8- or 16-bit interface if UTMI+ is selected. In case - this isn't passed via DT, USB controllers should default to HW - capability. + UTMI+ PHY with an 8- or 16-bit interface if UTMI+ is selected, UTMI+ low + pin interface if ULPI is specified, Serial core/PHY interconnect if + serial is specified and High-Speed Inter-Chip feature if HSIC is + selected. In case this isn't passed via DT, USB controllers should + default to HW capability. $ref: /schemas/types.yaml#/definitions/string - enum: [utmi, utmi_wide] + enum: [utmi, utmi_wide, ulpi, serial, hsic] maximum-speed: description: -- cgit v1.2.3 From e692cc354415d6ad8dc6d05be8c2e6435b281066 Mon Sep 17 00:00:00 2001 From: Serge Semin Date: Thu, 10 Dec 2020 12:09:29 +0300 Subject: dt-bindings: usb: usb-hcd: Add "tpl-support" property The host controller device might be designed to work for the particular products or applications. In that case its DT node is supposed to be equipped with the tpl-support property. Reviewed-by: Rob Herring Signed-off-by: Serge Semin Link: https://lore.kernel.org/r/20201210090944.16283-6-Sergey.Semin@baikalelectronics.ru Signed-off-by: Greg Kroah-Hartman --- Documentation/devicetree/bindings/usb/usb-hcd.yaml | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/usb/usb-hcd.yaml b/Documentation/devicetree/bindings/usb/usb-hcd.yaml index 52cc84c400c0..9881ac10380d 100644 --- a/Documentation/devicetree/bindings/usb/usb-hcd.yaml +++ b/Documentation/devicetree/bindings/usb/usb-hcd.yaml @@ -17,6 +17,12 @@ properties: description: Phandle of a companion device $ref: /schemas/types.yaml#/definitions/phandle + tpl-support: + description: + Indicates if the Targeted Peripheral List is supported for given + targeted hosts (non-PC hosts). + type: boolean + additionalProperties: true examples: -- cgit v1.2.3 From c26835071c18b9285eec1e8c6f4b36935d0d9fcf Mon Sep 17 00:00:00 2001 From: Serge Semin Date: Thu, 10 Dec 2020 12:09:30 +0300 Subject: dt-bindings: usb: Add generic "usb-phy" property Even though the Generic PHY framework is the more preferable way of setting the USB PHY up, there are still many dts-files and DT bindings which rely on having the legacy "usb-phy" specified to attach particular USB PHYs to USB cores. Let's have the "usb-phy" property described in the generic USB HCD binding file so it would be validated against the nodes in which it's specified. Mark the property as deprecated to discourage the developers from using it. Reviewed-by: Rob Herring Acked-by: Martin Blumenstingl Signed-off-by: Serge Semin Link: https://lore.kernel.org/r/20201210090944.16283-7-Sergey.Semin@baikalelectronics.ru Signed-off-by: Greg Kroah-Hartman --- Documentation/devicetree/bindings/usb/usb.yaml | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/usb/usb.yaml b/Documentation/devicetree/bindings/usb/usb.yaml index 53144c4600c0..ebe7f4275c59 100644 --- a/Documentation/devicetree/bindings/usb/usb.yaml +++ b/Documentation/devicetree/bindings/usb/usb.yaml @@ -24,6 +24,13 @@ properties: description: Name specifier for the USB PHY + usb-phy: + $ref: /schemas/types.yaml#/definitions/phandle-array + description: + List of all the USB PHYs on this HCD to be accepted by the legacy USB + Physical Layer subsystem. + deprecated: true + phy_type: description: Tells USB controllers that we want to configure the core to support a -- cgit v1.2.3 From 17c01b82819e38cbd8a7720ae2b378a11b4e9699 Mon Sep 17 00:00:00 2001 From: Serge Semin Date: Thu, 10 Dec 2020 12:09:31 +0300 Subject: dt-bindings: usb: Convert xHCI bindings to DT schema Currently the DT bindings of Generic xHCI Controllers are described by means of the legacy text file. Since such format is deprecated in favor of the DT schema, let's convert the Generic xHCI Controllers bindings file to the corresponding yaml files. There will be two of them: a DT schema for the xHCI controllers on a generic platform and a DT schema validating a generic xHCI controllers properties. The later will be used to validate the xHCI controllers, which aside from some vendor-specific features support the basic xHCI functionality. An xHCI-compatible DT node shall support the standard USB HCD properties and custom ones like: usb2-lpm-disable, usb3-lpm-capable, quirk-broken-port-ped and imod-interval-ns. In addition if a generic xHCI controller is being validated against the DT schema it is also supposed to be equipped with mandatory compatible string, single registers range, single interrupts source, and is supposed to optionally contain up to two reference clocks for the controller core and CSRs. Reviewed-by: Rob Herring Signed-off-by: Serge Semin Link: https://lore.kernel.org/r/20201210090944.16283-8-Sergey.Semin@baikalelectronics.ru Signed-off-by: Greg Kroah-Hartman --- .../devicetree/bindings/usb/generic-xhci.yaml | 63 ++++++++++++++++++++++ Documentation/devicetree/bindings/usb/usb-xhci.txt | 41 -------------- .../devicetree/bindings/usb/usb-xhci.yaml | 42 +++++++++++++++ 3 files changed, 105 insertions(+), 41 deletions(-) create mode 100644 Documentation/devicetree/bindings/usb/generic-xhci.yaml delete mode 100644 Documentation/devicetree/bindings/usb/usb-xhci.txt create mode 100644 Documentation/devicetree/bindings/usb/usb-xhci.yaml (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/usb/generic-xhci.yaml b/Documentation/devicetree/bindings/usb/generic-xhci.yaml new file mode 100644 index 000000000000..1ea1d49a8175 --- /dev/null +++ b/Documentation/devicetree/bindings/usb/generic-xhci.yaml @@ -0,0 +1,63 @@ +# SPDX-License-Identifier: GPL-2.0 +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/usb/generic-xhci.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: USB xHCI Controller Device Tree Bindings + +maintainers: + - Mathias Nyman + +allOf: + - $ref: "usb-xhci.yaml#" + +properties: + compatible: + oneOf: + - description: Generic xHCI device + const: generic-xhci + - description: Armada 37xx/375/38x/8k SoCs + items: + - enum: + - marvell,armada3700-xhci + - marvell,armada-375-xhci + - marvell,armada-380-xhci + - marvell,armada-8k-xhci + - const: generic-xhci + - description: Broadcom STB SoCs with xHCI + const: brcm,bcm7445-xhci + - description: Generic xHCI device + const: xhci-platform + deprecated: true + + reg: + maxItems: 1 + + interrupts: + maxItems: 1 + + clocks: + minItems: 1 + maxItems: 2 + + clock-names: + minItems: 1 + items: + - const: core + - const: reg + +unevaluatedProperties: false + +required: + - compatible + - reg + - interrupts + +examples: + - | + usb@f0931000 { + compatible = "generic-xhci"; + reg = <0xf0931000 0x8c8>; + interrupts = <0x0 0x4e 0x0>; + }; diff --git a/Documentation/devicetree/bindings/usb/usb-xhci.txt b/Documentation/devicetree/bindings/usb/usb-xhci.txt deleted file mode 100644 index 0c5cff84a969..000000000000 --- a/Documentation/devicetree/bindings/usb/usb-xhci.txt +++ /dev/null @@ -1,41 +0,0 @@ -USB xHCI controllers - -Required properties: - - compatible: should be one or more of - - - "generic-xhci" for generic XHCI device - - "marvell,armada3700-xhci" for Armada 37xx SoCs - - "marvell,armada-375-xhci" for Armada 375 SoCs - - "marvell,armada-380-xhci" for Armada 38x SoCs - - "brcm,bcm7445-xhci" for Broadcom STB SoCs with XHCI - - "xhci-platform" (deprecated) - - When compatible with the generic version, nodes must list the - SoC-specific version corresponding to the platform first - followed by the generic version. - - - reg: should contain address and length of the standard XHCI - register set for the device. - - interrupts: one XHCI interrupt should be described here. - -Optional properties: - - clocks: reference to the clocks - - clock-names: mandatory if there is a second clock, in this case - the name must be "core" for the first clock and "reg" for the - second one - - usb2-lpm-disable: indicate if we don't want to enable USB2 HW LPM - - usb3-lpm-capable: determines if platform is USB3 LPM capable - - quirk-broken-port-ped: set if the controller has broken port disable mechanism - - imod-interval-ns: default interrupt moderation interval is 5000ns - - phys : see usb-hcd.yaml in the current directory - -additionally the properties from usb-hcd.yaml (in the current directory) are -supported. - - -Example: - usb@f0931000 { - compatible = "generic-xhci"; - reg = <0xf0931000 0x8c8>; - interrupts = <0x0 0x4e 0x0>; - }; diff --git a/Documentation/devicetree/bindings/usb/usb-xhci.yaml b/Documentation/devicetree/bindings/usb/usb-xhci.yaml new file mode 100644 index 000000000000..965f87fef702 --- /dev/null +++ b/Documentation/devicetree/bindings/usb/usb-xhci.yaml @@ -0,0 +1,42 @@ +# SPDX-License-Identifier: GPL-2.0 +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/usb/usb-xhci.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Generic USB xHCI Controller Device Tree Bindings + +maintainers: + - Mathias Nyman + +allOf: + - $ref: "usb-hcd.yaml#" + +properties: + usb2-lpm-disable: + description: Indicates if we don't want to enable USB2 HW LPM + type: boolean + + usb3-lpm-capable: + description: Determines if platform is USB3 LPM capable + type: boolean + + quirk-broken-port-ped: + description: Set if the controller has broken port disable mechanism + type: boolean + + imod-interval-ns: + description: Interrupt moderation interval + default: 5000 + +additionalProperties: true + +examples: + - | + usb@f0930000 { + compatible = "generic-xhci"; + reg = <0xf0930000 0x8c8>; + interrupts = <0x0 0x4e 0x0>; + usb2-lpm-disable; + usb3-lpm-capable; + }; -- cgit v1.2.3 From 5b7e1bfd882ff6c0440eb5b25153253d5db1c552 Mon Sep 17 00:00:00 2001 From: Serge Semin Date: Thu, 10 Dec 2020 12:09:32 +0300 Subject: dt-bindings: usb: xhci: Add Broadcom STB v2 compatible device For some reason the "brcm,xhci-brcm-v2" compatible string has been missing in the original bindings file. Add it to the Generic xHCI Controllers DT schema since the controller driver expects it to be supported. Reviewed-by: Rob Herring Acked-by: Florian Fainelli Signed-off-by: Serge Semin Link: https://lore.kernel.org/r/20201210090944.16283-9-Sergey.Semin@baikalelectronics.ru Signed-off-by: Greg Kroah-Hartman --- Documentation/devicetree/bindings/usb/generic-xhci.yaml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/usb/generic-xhci.yaml b/Documentation/devicetree/bindings/usb/generic-xhci.yaml index 1ea1d49a8175..23d73df96ea3 100644 --- a/Documentation/devicetree/bindings/usb/generic-xhci.yaml +++ b/Documentation/devicetree/bindings/usb/generic-xhci.yaml @@ -26,7 +26,9 @@ properties: - marvell,armada-8k-xhci - const: generic-xhci - description: Broadcom STB SoCs with xHCI - const: brcm,bcm7445-xhci + enum: + - brcm,xhci-brcm-v2 + - brcm,bcm7445-xhci - description: Generic xHCI device const: xhci-platform deprecated: true -- cgit v1.2.3 From 55e945593b0af8220af90761d511a4844c463983 Mon Sep 17 00:00:00 2001 From: Serge Semin Date: Thu, 10 Dec 2020 12:09:33 +0300 Subject: dt-bindings: usb: renesas-xhci: Refer to the usb-xhci.yaml file With minor peculiarities (like uploading some vendor-specific firmware) these are just Generic xHCI controllers fully compatible with its properties. Make sure the Renesas USB xHCI DT nodes are also validated against the Generic xHCI DT schema. Reviewed-by: Rob Herring Reviewed-by: Yoshihiro Shimoda Reviewed-by: Lad Prabhakar Signed-off-by: Serge Semin Link: https://lore.kernel.org/r/20201210090944.16283-10-Sergey.Semin@baikalelectronics.ru Signed-off-by: Greg Kroah-Hartman --- Documentation/devicetree/bindings/usb/renesas,usb-xhci.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/usb/renesas,usb-xhci.yaml b/Documentation/devicetree/bindings/usb/renesas,usb-xhci.yaml index 22603256ddf8..4c5efaf02308 100644 --- a/Documentation/devicetree/bindings/usb/renesas,usb-xhci.yaml +++ b/Documentation/devicetree/bindings/usb/renesas,usb-xhci.yaml @@ -11,7 +11,7 @@ maintainers: - Yoshihiro Shimoda allOf: - - $ref: "usb-hcd.yaml" + - $ref: "usb-xhci.yaml" properties: compatible: @@ -68,7 +68,7 @@ required: - power-domains - resets -additionalProperties: false +unevaluatedProperties: false examples: - | -- cgit v1.2.3 From 389d7765880143e18139a9c5428b67bc9d3a617e Mon Sep 17 00:00:00 2001 From: Serge Semin Date: Thu, 10 Dec 2020 12:09:34 +0300 Subject: dt-bindings: usb: Convert DWC USB3 bindings to DT schema DWC USB3 DT node is supposed to be compliant with the Generic xHCI Controller schema, but with additional vendor-specific properties, the controller-specific reference clocks and PHYs. So let's convert the currently available legacy text-based DWC USB3 bindings to the DT schema and make sure the DWC USB3 nodes are also validated against the usb-xhci.yaml schema. Note 1. we have to discard the nodename restriction of being prefixed with "dwc3@" string, since in accordance with the usb-hcd.yaml schema USB nodes are supposed to be named as "^usb(@.*)". Note 2. The clock-related properties are marked as optional to match the DWC USB3 driver expectation and to improve the bindings mainainability so in case if there is a glue-node it would the responsible for the clocks initialization. Reviewed-by: Rob Herring Signed-off-by: Serge Semin Link: https://lore.kernel.org/r/20201210090944.16283-11-Sergey.Semin@baikalelectronics.ru Signed-off-by: Greg Kroah-Hartman --- Documentation/devicetree/bindings/usb/dwc3.txt | 128 --------- .../devicetree/bindings/usb/snps,dwc3.yaml | 312 +++++++++++++++++++++ 2 files changed, 312 insertions(+), 128 deletions(-) delete mode 100644 Documentation/devicetree/bindings/usb/dwc3.txt create mode 100644 Documentation/devicetree/bindings/usb/snps,dwc3.yaml (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/usb/dwc3.txt b/Documentation/devicetree/bindings/usb/dwc3.txt deleted file mode 100644 index 1aae2b6160c1..000000000000 --- a/Documentation/devicetree/bindings/usb/dwc3.txt +++ /dev/null @@ -1,128 +0,0 @@ -synopsys DWC3 CORE - -DWC3- USB3 CONTROLLER. Complies to the generic USB binding properties - as described in 'usb/generic.txt' - -Required properties: - - compatible: must be "snps,dwc3" - - reg : Address and length of the register set for the device - - interrupts: Interrupts used by the dwc3 controller. - - clock-names: list of clock names. Ideally should be "ref", - "bus_early", "suspend" but may be less or more. - - clocks: list of phandle and clock specifier pairs corresponding to - entries in the clock-names property. - -Exception for clocks: - clocks are optional if the parent node (i.e. glue-layer) is compatible to - one of the following: - "cavium,octeon-7130-usb-uctl" - "qcom,dwc3" - "samsung,exynos5250-dwusb3" - "samsung,exynos5433-dwusb3" - "samsung,exynos7-dwusb3" - "sprd,sc9860-dwc3" - "st,stih407-dwc3" - "ti,am437x-dwc3" - "ti,dwc3" - "ti,keystone-dwc3" - "rockchip,rk3399-dwc3" - "xlnx,zynqmp-dwc3" - -Optional properties: - - usb-phy : array of phandle for the PHY device. The first element - in the array is expected to be a handle to the USB2/HS PHY and - the second element is expected to be a handle to the USB3/SS PHY - - phys: from the *Generic PHY* bindings - - phy-names: from the *Generic PHY* bindings; supported names are "usb2-phy" - or "usb3-phy". - - resets: set of phandle and reset specifier pairs - - snps,usb2-lpm-disable: indicate if we don't want to enable USB2 HW LPM - - snps,usb3_lpm_capable: determines if platform is USB3 LPM capable - - snps,dis-start-transfer-quirk: when set, disable isoc START TRANSFER command - failure SW work-around for DWC_usb31 version 1.70a-ea06 - and prior. - - snps,disable_scramble_quirk: true when SW should disable data scrambling. - Only really useful for FPGA builds. - - snps,has-lpm-erratum: true when DWC3 was configured with LPM Erratum enabled - - snps,lpm-nyet-threshold: LPM NYET threshold - - snps,u2exit_lfps_quirk: set if we want to enable u2exit lfps quirk - - snps,u2ss_inp3_quirk: set if we enable P3 OK for U2/SS Inactive quirk - - snps,req_p1p2p3_quirk: when set, the core will always request for - P1/P2/P3 transition sequence. - - snps,del_p1p2p3_quirk: when set core will delay P1/P2/P3 until a certain - amount of 8B10B errors occur. - - snps,del_phy_power_chg_quirk: when set core will delay PHY power change - from P0 to P1/P2/P3. - - snps,lfps_filter_quirk: when set core will filter LFPS reception. - - snps,rx_detect_poll_quirk: when set core will disable a 400us delay to start - Polling LFPS after RX.Detect. - - snps,tx_de_emphasis_quirk: when set core will set Tx de-emphasis value. - - snps,tx_de_emphasis: the value driven to the PHY is controlled by the - LTSSM during USB3 Compliance mode. - - snps,dis_u3_susphy_quirk: when set core will disable USB3 suspend phy. - - snps,dis_u2_susphy_quirk: when set core will disable USB2 suspend phy. - - snps,dis_enblslpm_quirk: when set clears the enblslpm in GUSB2PHYCFG, - disabling the suspend signal to the PHY. - - snps,dis-u1-entry-quirk: set if link entering into U1 needs to be disabled. - - snps,dis-u2-entry-quirk: set if link entering into U2 needs to be disabled. - - snps,dis_rxdet_inp3_quirk: when set core will disable receiver detection - in PHY P3 power state. - - snps,dis-u2-freeclk-exists-quirk: when set, clear the u2_freeclk_exists - in GUSB2PHYCFG, specify that USB2 PHY doesn't provide - a free-running PHY clock. - - snps,dis-del-phy-power-chg-quirk: when set core will change PHY power - from P0 to P1/P2/P3 without delay. - - snps,dis-tx-ipgap-linecheck-quirk: when set, disable u2mac linestate check - during HS transmit. - - snps,parkmode-disable-ss-quirk: when set, all SuperSpeed bus instances in - park mode are disabled. - - snps,dis_metastability_quirk: when set, disable metastability workaround. - CAUTION: use only if you are absolutely sure of it. - - snps,dis-split-quirk: when set, change the way URBs are handled by the - driver. Needed to avoid -EPROTO errors with usbhid - on some devices (Hikey 970). - - snps,is-utmi-l1-suspend: true when DWC3 asserts output signal - utmi_l1_suspend_n, false when asserts utmi_sleep_n - - snps,hird-threshold: HIRD threshold - - snps,hsphy_interface: High-Speed PHY interface selection between "utmi" for - UTMI+ and "ulpi" for ULPI when the DWC_USB3_HSPHY_INTERFACE has value 3. - - snps,quirk-frame-length-adjustment: Value for GFLADJ_30MHZ field of GFLADJ - register for post-silicon frame length adjustment when the - fladj_30mhz_sdbnd signal is invalid or incorrect. - - snps,rx-thr-num-pkt-prd: periodic ESS RX packet threshold count - host mode - only. Set this and rx-max-burst-prd to a valid, - non-zero value 1-16 (DWC_usb31 programming guide - section 1.2.4) to enable periodic ESS RX threshold. - - snps,rx-max-burst-prd: max periodic ESS RX burst size - host mode only. Set - this and rx-thr-num-pkt-prd to a valid, non-zero value - 1-16 (DWC_usb31 programming guide section 1.2.4) to - enable periodic ESS RX threshold. - - snps,tx-thr-num-pkt-prd: periodic ESS TX packet threshold count - host mode - only. Set this and tx-max-burst-prd to a valid, - non-zero value 1-16 (DWC_usb31 programming guide - section 1.2.3) to enable periodic ESS TX threshold. - - snps,tx-max-burst-prd: max periodic ESS TX burst size - host mode only. Set - this and tx-thr-num-pkt-prd to a valid, non-zero value - 1-16 (DWC_usb31 programming guide section 1.2.3) to - enable periodic ESS TX threshold. - - - tx-fifo-resize: determines if the FIFO *has* to be reallocated. - - snps,incr-burst-type-adjustment: Value for INCR burst type of GSBUSCFG0 - register, undefined length INCR burst type enable and INCRx type. - When just one value, which means INCRX burst mode enabled. When - more than one value, which means undefined length INCR burst type - enabled. The values can be 1, 4, 8, 16, 32, 64, 128 and 256. - - - in addition all properties from usb-xhci.txt from the current directory are - supported as well - - -This is usually a subnode to DWC3 glue to which it is connected. - -dwc3@4a030000 { - compatible = "snps,dwc3"; - reg = <0x4a030000 0xcfff>; - interrupts = <0 92 4> - usb-phy = <&usb2_phy>, <&usb3,phy>; - snps,incr-burst-type-adjustment = <1>, <4>, <8>, <16>; -}; diff --git a/Documentation/devicetree/bindings/usb/snps,dwc3.yaml b/Documentation/devicetree/bindings/usb/snps,dwc3.yaml new file mode 100644 index 000000000000..57caca8339ae --- /dev/null +++ b/Documentation/devicetree/bindings/usb/snps,dwc3.yaml @@ -0,0 +1,312 @@ +# SPDX-License-Identifier: GPL-2.0 +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/usb/snps,dwc3.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Synopsys DesignWare USB3 Controller + +maintainers: + - Felipe Balbi + +description: + This is usually a subnode to DWC3 glue to which it is connected, but can also + be presented as a standalone DT node with an optional vendor-specific + compatible string. + +allOf: + - $ref: usb-drd.yaml# + - if: + properties: + dr_mode: + const: peripheral + + required: + - dr_mode + then: + $ref: usb.yaml# + else: + $ref: usb-xhci.yaml# + +properties: + compatible: + contains: + const: snps,dwc3 + + interrupts: + minItems: 1 + maxItems: 3 + + clocks: + description: + In general the core supports three types of clocks. bus_early is a + SoC Bus Clock (AHB/AXI/Native). ref generates ITP when the UTMI/ULPI + PHY is suspended. suspend clocks a small part of the USB3 core when + SS PHY in P3. But particular cases may differ from that having less + or more clock sources with another names. + + clock-names: + contains: + anyOf: + - enum: [bus_early, ref, suspend] + - true + + usb-phy: + minItems: 1 + items: + - description: USB2/HS PHY + - description: USB3/SS PHY + + phys: + minItems: 1 + items: + - description: USB2/HS PHY + - description: USB3/SS PHY + + phy-names: + minItems: 1 + items: + - const: usb2-phy + - const: usb3-phy + + resets: + minItems: 1 + + snps,usb2-lpm-disable: + description: Indicate if we don't want to enable USB2 HW LPM + type: boolean + + snps,usb3_lpm_capable: + description: Determines if platform is USB3 LPM capable + type: boolean + + snps,dis-start-transfer-quirk: + description: + When set, disable isoc START TRANSFER command failure SW work-around + for DWC_usb31 version 1.70a-ea06 and prior. + type: boolean + + snps,disable_scramble_quirk: + description: + True when SW should disable data scrambling. Only really useful for FPGA + builds. + type: boolean + + snps,has-lpm-erratum: + description: True when DWC3 was configured with LPM Erratum enabled + type: boolean + + snps,lpm-nyet-threshold: + description: LPM NYET threshold + $ref: /schemas/types.yaml#/definitions/uint8 + + snps,u2exit_lfps_quirk: + description: Set if we want to enable u2exit lfps quirk + type: boolean + + snps,u2ss_inp3_quirk: + description: Set if we enable P3 OK for U2/SS Inactive quirk + type: boolean + + snps,req_p1p2p3_quirk: + description: + When set, the core will always request for P1/P2/P3 transition sequence. + type: boolean + + snps,del_p1p2p3_quirk: + description: + When set core will delay P1/P2/P3 until a certain amount of 8B10B errors + occur. + type: boolean + + snps,del_phy_power_chg_quirk: + description: When set core will delay PHY power change from P0 to P1/P2/P3. + type: boolean + + snps,lfps_filter_quirk: + description: When set core will filter LFPS reception. + type: boolean + + snps,rx_detect_poll_quirk: + description: + when set core will disable a 400us delay to start Polling LFPS after + RX.Detect. + type: boolean + + snps,tx_de_emphasis_quirk: + description: When set core will set Tx de-emphasis value + type: boolean + + snps,tx_de_emphasis: + description: + The value driven to the PHY is controlled by the LTSSM during USB3 + Compliance mode. + $ref: /schemas/types.yaml#/definitions/uint8 + + snps,dis_u3_susphy_quirk: + description: When set core will disable USB3 suspend phy + type: boolean + + snps,dis_u2_susphy_quirk: + description: When set core will disable USB2 suspend phy + type: boolean + + snps,dis_enblslpm_quirk: + description: + When set clears the enblslpm in GUSB2PHYCFG, disabling the suspend signal + to the PHY. + type: boolean + + snps,dis-u1-entry-quirk: + description: Set if link entering into U1 needs to be disabled + type: boolean + + snps,dis-u2-entry-quirk: + description: Set if link entering into U2 needs to be disabled + type: boolean + + snps,dis_rxdet_inp3_quirk: + description: + When set core will disable receiver detection in PHY P3 power state. + type: boolean + + snps,dis-u2-freeclk-exists-quirk: + description: + When set, clear the u2_freeclk_exists in GUSB2PHYCFG, specify that USB2 + PHY doesn't provide a free-running PHY clock. + type: boolean + + snps,dis-del-phy-power-chg-quirk: + description: + When set core will change PHY power from P0 to P1/P2/P3 without delay. + type: boolean + + snps,dis-tx-ipgap-linecheck-quirk: + description: When set, disable u2mac linestate check during HS transmit + type: boolean + + snps,parkmode-disable-ss-quirk: + description: + When set, all SuperSpeed bus instances in park mode are disabled. + type: boolean + + snps,dis_metastability_quirk: + description: + When set, disable metastability workaround. CAUTION! Use only if you are + absolutely sure of it. + type: boolean + + snps,dis-split-quirk: + description: + When set, change the way URBs are handled by the driver. Needed to + avoid -EPROTO errors with usbhid on some devices (Hikey 970). + type: boolean + + snps,is-utmi-l1-suspend: + description: + True when DWC3 asserts output signal utmi_l1_suspend_n, false when + asserts utmi_sleep_n. + type: boolean + + snps,hird-threshold: + description: HIRD threshold + $ref: /schemas/types.yaml#/definitions/uint8 + + snps,hsphy_interface: + description: + High-Speed PHY interface selection between UTMI+ and ULPI when the + DWC_USB3_HSPHY_INTERFACE has value 3. + $ref: /schemas/types.yaml#/definitions/uint8 + enum: [utmi, ulpi] + + snps,quirk-frame-length-adjustment: + description: + Value for GFLADJ_30MHZ field of GFLADJ register for post-silicon frame + length adjustment when the fladj_30mhz_sdbnd signal is invalid or + incorrect. + $ref: /schemas/types.yaml#/definitions/uint32 + + snps,rx-thr-num-pkt-prd: + description: + Periodic ESS RX packet threshold count (host mode only). Set this and + snps,rx-max-burst-prd to a valid, non-zero value 1-16 (DWC_usb31 + programming guide section 1.2.4) to enable periodic ESS RX threshold. + $ref: /schemas/types.yaml#/definitions/uint8 + minimum: 1 + maximum: 16 + + snps,rx-max-burst-prd: + description: + Max periodic ESS RX burst size (host mode only). Set this and + snps,rx-thr-num-pkt-prd to a valid, non-zero value 1-16 (DWC_usb31 + programming guide section 1.2.4) to enable periodic ESS RX threshold. + $ref: /schemas/types.yaml#/definitions/uint8 + minimum: 1 + maximum: 16 + + snps,tx-thr-num-pkt-prd: + description: + Periodic ESS TX packet threshold count (host mode only). Set this and + snps,tx-max-burst-prd to a valid, non-zero value 1-16 (DWC_usb31 + programming guide section 1.2.3) to enable periodic ESS TX threshold. + $ref: /schemas/types.yaml#/definitions/uint8 + minimum: 1 + maximum: 16 + + snps,tx-max-burst-prd: + description: + Max periodic ESS TX burst size (host mode only). Set this and + snps,tx-thr-num-pkt-prd to a valid, non-zero value 1-16 (DWC_usb31 + programming guide section 1.2.3) to enable periodic ESS TX threshold. + $ref: /schemas/types.yaml#/definitions/uint8 + minimum: 1 + maximum: 16 + + tx-fifo-resize: + description: Determines if the FIFO *has* to be reallocated + deprecated: true + type: boolean + + snps,incr-burst-type-adjustment: + description: + Value for INCR burst type of GSBUSCFG0 register, undefined length INCR + burst type enable and INCRx type. A single value means INCRX burst mode + enabled. If more than one value specified, undefined length INCR burst + type will be enabled with burst lengths utilized up to the maximum + of the values passed in this property. + $ref: /schemas/types.yaml#/definitions/uint32-array + minItems: 1 + maxItems: 8 + uniqueItems: true + items: + enum: [1, 4, 8, 16, 32, 64, 128, 256] + +unevaluatedProperties: false + +required: + - compatible + - reg + - interrupts + +examples: + - | + usb@4a030000 { + compatible = "snps,dwc3"; + reg = <0x4a030000 0xcfff>; + interrupts = <0 92 4>; + usb-phy = <&usb2_phy>, <&usb3_phy>; + snps,incr-burst-type-adjustment = <1>, <4>, <8>, <16>; + }; + - | + usb@4a000000 { + compatible = "snps,dwc3"; + reg = <0x4a000000 0xcfff>; + interrupts = <0 92 4>; + clocks = <&clk 1>, <&clk 2>, <&clk 3>; + clock-names = "bus_early", "ref", "suspend"; + phys = <&usb2_phy>, <&usb3_phy>; + phy-names = "usb2-phy", "usb3-phy"; + snps,dis_u2_susphy_quirk; + snps,dis_enblslpm_quirk; + }; +... -- cgit v1.2.3 From 53f5ef5d622b7f2b5cf3e53d965b12c38082f974 Mon Sep 17 00:00:00 2001 From: Serge Semin Date: Thu, 10 Dec 2020 12:09:35 +0300 Subject: dt-bindings: usb: dwc3: Add interrupt-names property support The controller driver supports two types of DWC USB3 devices: with a common interrupt lane and with individual interrupts for each mode. Add support for both these cases to the DWC USB3 DT schema. Reviewed-by: Rob Herring Signed-off-by: Serge Semin Link: https://lore.kernel.org/r/20201210090944.16283-12-Sergey.Semin@baikalelectronics.ru Signed-off-by: Greg Kroah-Hartman --- Documentation/devicetree/bindings/usb/snps,dwc3.yaml | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/usb/snps,dwc3.yaml b/Documentation/devicetree/bindings/usb/snps,dwc3.yaml index 57caca8339ae..87a92e313d24 100644 --- a/Documentation/devicetree/bindings/usb/snps,dwc3.yaml +++ b/Documentation/devicetree/bindings/usb/snps,dwc3.yaml @@ -34,8 +34,19 @@ properties: const: snps,dwc3 interrupts: + description: + It's either a single common DWC3 interrupt (dwc_usb3) or individual + interrupts for the host, gadget and DRD modes. + minItems: 1 + maxItems: 3 + + interrupt-names: minItems: 1 maxItems: 3 + oneOf: + - const: dwc_usb3 + - items: + enum: [host, peripheral, otg] clocks: description: -- cgit v1.2.3 From f82dc55719963a214a33946c8c2cd9932ca19b8d Mon Sep 17 00:00:00 2001 From: Serge Semin Date: Thu, 10 Dec 2020 12:09:36 +0300 Subject: dt-bindings: usb: dwc3: Add synopsys, dwc3 compatible string The DWC USB3 driver and some DTS files like Exynos 5250, Keystone k2e, etc expects the DWC USB3 DT node to have the compatible string with the "synopsys" vendor prefix. Let's add the corresponding compatible string to the controller DT schema, but mark it as deprecated seeing the Synopsys, Inc. is presented with just "snps" vendor prefix. Reviewed-by: Rob Herring Signed-off-by: Serge Semin Link: https://lore.kernel.org/r/20201210090944.16283-13-Sergey.Semin@baikalelectronics.ru Signed-off-by: Greg Kroah-Hartman --- Documentation/devicetree/bindings/usb/snps,dwc3.yaml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/usb/snps,dwc3.yaml b/Documentation/devicetree/bindings/usb/snps,dwc3.yaml index 87a92e313d24..6253bc5fb18e 100644 --- a/Documentation/devicetree/bindings/usb/snps,dwc3.yaml +++ b/Documentation/devicetree/bindings/usb/snps,dwc3.yaml @@ -31,7 +31,10 @@ allOf: properties: compatible: contains: - const: snps,dwc3 + oneOf: + - const: snps,dwc3 + - const: synopsys,dwc3 + deprecated: true interrupts: description: -- cgit v1.2.3 From 6f84a28df802cd23e3a526a49a6417462bdbbed3 Mon Sep 17 00:00:00 2001 From: Serge Semin Date: Thu, 10 Dec 2020 12:09:37 +0300 Subject: dt-bindings: usb: dwc3: Add Tx De-emphasis constraints In accordance with the driver comments the PIPE3 de-emphasis can be tuned to be either -6dB, -2.5dB or disabled. Let's add the de-emphasis property constraints so the DT schema would make sure the controller DT node is equipped with correct value. Reviewed-by: Rob Herring Signed-off-by: Serge Semin Link: https://lore.kernel.org/r/20201210090944.16283-14-Sergey.Semin@baikalelectronics.ru Signed-off-by: Greg Kroah-Hartman --- Documentation/devicetree/bindings/usb/snps,dwc3.yaml | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/usb/snps,dwc3.yaml b/Documentation/devicetree/bindings/usb/snps,dwc3.yaml index 6253bc5fb18e..e01a9a93d74a 100644 --- a/Documentation/devicetree/bindings/usb/snps,dwc3.yaml +++ b/Documentation/devicetree/bindings/usb/snps,dwc3.yaml @@ -156,6 +156,10 @@ properties: The value driven to the PHY is controlled by the LTSSM during USB3 Compliance mode. $ref: /schemas/types.yaml#/definitions/uint8 + enum: + - 0 # -6dB de-emphasis + - 1 # -3.5dB de-emphasis + - 2 # No de-emphasis snps,dis_u3_susphy_quirk: description: When set core will disable USB3 suspend phy -- cgit v1.2.3 From dc87c87126d14fdce1986c4b3e8674a6dcbe7bfb Mon Sep 17 00:00:00 2001 From: Serge Semin Date: Thu, 10 Dec 2020 12:09:38 +0300 Subject: dt-bindings: usb: dwc3: Add Frame Length Adj constraints In accordance with the IP core databook the snps,quirk-frame-length-adjustment property can be set within [0, 0x3F]. Let's make sure the DT schema applies a correct constraints on the property. Reviewed-by: Rob Herring Signed-off-by: Serge Semin Link: https://lore.kernel.org/r/20201210090944.16283-15-Sergey.Semin@baikalelectronics.ru Signed-off-by: Greg Kroah-Hartman --- Documentation/devicetree/bindings/usb/snps,dwc3.yaml | 2 ++ 1 file changed, 2 insertions(+) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/usb/snps,dwc3.yaml b/Documentation/devicetree/bindings/usb/snps,dwc3.yaml index e01a9a93d74a..2247da77eac1 100644 --- a/Documentation/devicetree/bindings/usb/snps,dwc3.yaml +++ b/Documentation/devicetree/bindings/usb/snps,dwc3.yaml @@ -243,6 +243,8 @@ properties: length adjustment when the fladj_30mhz_sdbnd signal is invalid or incorrect. $ref: /schemas/types.yaml#/definitions/uint32 + minimum: 0 + maximum: 0x3f snps,rx-thr-num-pkt-prd: description: -- cgit v1.2.3 From 042cdcd6c9234e464792234ca95870ad797580be Mon Sep 17 00:00:00 2001 From: Serge Semin Date: Thu, 10 Dec 2020 12:09:39 +0300 Subject: dt-bindings: usb: meson-g12a-usb: Fix FL-adj property value An empty snps,quirk-frame-length-adjustment won't cause any change performed by the driver. Moreover the DT schema validation will fail, since it expects the property being assigned with some value. So set fix the example by setting a valid FL-adj value in accordance with Neil Armstrong comment. Link: https://lore.kernel.org/linux-usb/20201010224121.12672-16-Sergey.Semin@baikalelectronics.ru/ Reviewed-by: Rob Herring Reviewed-by: Martin Blumenstingl Acked-by: Neil Armstrong Signed-off-by: Serge Semin Link: https://lore.kernel.org/r/20201210090944.16283-16-Sergey.Semin@baikalelectronics.ru Signed-off-by: Greg Kroah-Hartman --- Documentation/devicetree/bindings/usb/amlogic,meson-g12a-usb-ctrl.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/usb/amlogic,meson-g12a-usb-ctrl.yaml b/Documentation/devicetree/bindings/usb/amlogic,meson-g12a-usb-ctrl.yaml index c0058332b967..1eda16dd4ee0 100644 --- a/Documentation/devicetree/bindings/usb/amlogic,meson-g12a-usb-ctrl.yaml +++ b/Documentation/devicetree/bindings/usb/amlogic,meson-g12a-usb-ctrl.yaml @@ -229,6 +229,6 @@ examples: interrupts = <30>; dr_mode = "host"; snps,dis_u2_susphy_quirk; - snps,quirk-frame-length-adjustment; + snps,quirk-frame-length-adjustment = <0x20>; }; }; -- cgit v1.2.3 From 3b34a58969b2b6e3831d0117fd2a3a0839ada988 Mon Sep 17 00:00:00 2001 From: Serge Semin Date: Thu, 10 Dec 2020 12:09:40 +0300 Subject: dt-bindings: usb: meson-g12a-usb: Validate DWC2/DWC3 sub-nodes Amlogic G12A USB DT sub-nodes are supposed to be compatible with the generic DWC USB2 and USB3 devices. Since now we've got DT schemas for both of the later IP cores let's make sure that the Amlogic G12A USB DT nodes are fully evaluated including the DWC sub-nodes. Reviewed-by: Neil Armstrong Reviewed-by: Rob Herring Reviewed-by: Martin Blumenstingl Signed-off-by: Serge Semin Link: https://lore.kernel.org/r/20201210090944.16283-17-Sergey.Semin@baikalelectronics.ru Signed-off-by: Greg Kroah-Hartman --- .../devicetree/bindings/usb/amlogic,meson-g12a-usb-ctrl.yaml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/usb/amlogic,meson-g12a-usb-ctrl.yaml b/Documentation/devicetree/bindings/usb/amlogic,meson-g12a-usb-ctrl.yaml index 1eda16dd4ee0..e349fa5de606 100644 --- a/Documentation/devicetree/bindings/usb/amlogic,meson-g12a-usb-ctrl.yaml +++ b/Documentation/devicetree/bindings/usb/amlogic,meson-g12a-usb-ctrl.yaml @@ -79,7 +79,9 @@ properties: patternProperties: "^usb@[0-9a-f]+$": - type: object + oneOf: + - $ref: dwc2.yaml# + - $ref: snps,dwc3.yaml# additionalProperties: false -- cgit v1.2.3 From e9cd063547a115acd6ca8ad436748c16d8d98821 Mon Sep 17 00:00:00 2001 From: Serge Semin Date: Thu, 10 Dec 2020 12:09:41 +0300 Subject: dt-bindings: usb: keystone-dwc3: Validate DWC3 sub-node TI Keystone DWC3 compatible DT node is supposed to have a DWC USB3 compatible sub-node to describe a fully functioning USB interface. Since DWC USB3 has now got a DT schema describing its DT node, let's make sure the TI Keystone DWC3 sub-node passes validation against it. Reviewed-by: Rob Herring Signed-off-by: Serge Semin Link: https://lore.kernel.org/r/20201210090944.16283-18-Sergey.Semin@baikalelectronics.ru Signed-off-by: Greg Kroah-Hartman --- Documentation/devicetree/bindings/usb/ti,keystone-dwc3.yaml | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/usb/ti,keystone-dwc3.yaml b/Documentation/devicetree/bindings/usb/ti,keystone-dwc3.yaml index c1b19fc5d0a2..ca7fbe3ed22e 100644 --- a/Documentation/devicetree/bindings/usb/ti,keystone-dwc3.yaml +++ b/Documentation/devicetree/bindings/usb/ti,keystone-dwc3.yaml @@ -64,9 +64,7 @@ properties: patternProperties: "usb@[a-f0-9]+$": - type: object - description: This is the node representing the DWC3 controller instance - Documentation/devicetree/bindings/usb/dwc3.txt + $ref: snps,dwc3.yaml# required: - compatible -- cgit v1.2.3 From 1fd7b103451e7662712a315faf8e5f41e0e8bb00 Mon Sep 17 00:00:00 2001 From: Serge Semin Date: Thu, 10 Dec 2020 12:09:42 +0300 Subject: dt-bindings: usb: qcom,dwc3: Validate DWC3 sub-node Qualcomm msm8996/sc7180/sdm845 DWC3 compatible DT nodes are supposed to have a DWC USB3 compatible sub-node to describe a fully functioning USB interface. Let's use the available DWC USB3 DT schema to validate the Qualcomm DWC3 sub-nodes. Note since the generic DWC USB3 DT node is supposed to be named as generic USB HCD ("^usb(@.*)?") one we have to accordingly fix the sub-nodes name regexp and fix the DT node example. Reviewed-by: Rob Herring Signed-off-by: Serge Semin Link: https://lore.kernel.org/r/20201210090944.16283-19-Sergey.Semin@baikalelectronics.ru Signed-off-by: Greg Kroah-Hartman --- Documentation/devicetree/bindings/usb/qcom,dwc3.yaml | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/usb/qcom,dwc3.yaml b/Documentation/devicetree/bindings/usb/qcom,dwc3.yaml index 2cf525d21e05..b336662e838c 100644 --- a/Documentation/devicetree/bindings/usb/qcom,dwc3.yaml +++ b/Documentation/devicetree/bindings/usb/qcom,dwc3.yaml @@ -103,11 +103,8 @@ properties: # Required child node: patternProperties: - "^dwc3@[0-9a-f]+$": - type: object - description: - A child node must exist to represent the core DWC3 IP block - The content of the node is defined in dwc3.txt. + "^usb@[0-9a-f]+$": + $ref: snps,dwc3.yaml# required: - compatible @@ -162,7 +159,7 @@ examples: resets = <&gcc GCC_USB30_PRIM_BCR>; - dwc3@a600000 { + usb@a600000 { compatible = "snps,dwc3"; reg = <0 0x0a600000 0 0xcd00>; interrupts = ; -- cgit v1.2.3 From 492d3d246203592f7ce4c21ab069a59be106b07a Mon Sep 17 00:00:00 2001 From: Serge Semin Date: Thu, 10 Dec 2020 12:09:43 +0300 Subject: dt-bindings: usb: intel, keembay-dwc3: Validate DWC3 sub-node Intel Keem Bay DWC3 compatible DT nodes are supposed to have a DWC USB3 compatible sub-node to describe a fully functioning USB interface. Let's use the available DWC USB3 DT schema to validate the Intel Keem Bay DWC3 sub-nodes. Note since the generic DWC USB3 DT node is supposed to be named as generic USB HCD ("^usb(@.*)?") one we have to accordingly fix the sub-nodes name regexp and fix the DT node example. Reviewed-by: Rob Herring Acked-by: Wan Ahmad Zainie Signed-off-by: Serge Semin Link: https://lore.kernel.org/r/20201210090944.16283-20-Sergey.Semin@baikalelectronics.ru Signed-off-by: Greg Kroah-Hartman --- Documentation/devicetree/bindings/usb/intel,keembay-dwc3.yaml | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/usb/intel,keembay-dwc3.yaml b/Documentation/devicetree/bindings/usb/intel,keembay-dwc3.yaml index dd32c10ce6c7..43b91ab62004 100644 --- a/Documentation/devicetree/bindings/usb/intel,keembay-dwc3.yaml +++ b/Documentation/devicetree/bindings/usb/intel,keembay-dwc3.yaml @@ -34,11 +34,8 @@ properties: # Required child node: patternProperties: - "^dwc3@[0-9a-f]+$": - type: object - description: - A child node must exist to represent the core DWC3 IP block. - The content of the node is defined in dwc3.txt. + "^usb@[0-9a-f]+$": + $ref: snps,dwc3.yaml# required: - compatible @@ -68,7 +65,7 @@ examples: #address-cells = <1>; #size-cells = <1>; - dwc3@34000000 { + usb@34000000 { compatible = "snps,dwc3"; reg = <0x34000000 0x10000>; interrupts = ; -- cgit v1.2.3 From afd4df85602da464674a818df7b0de9610525022 Mon Sep 17 00:00:00 2001 From: Amireddy Mallikarjuna reddy Date: Thu, 3 Dec 2020 12:10:43 +0800 Subject: dt-bindings: dma: Add bindings for Intel LGM SoC Add DT bindings YAML schema for DMA controller driver of Lightning Mountain (LGM) SoC. Signed-off-by: Amireddy Mallikarjuna reddy Reviewed-by: Rob Herring Link: https://lore.kernel.org/r/f307e9012680a300a4dbaf4c7e0e83ca05fd9459.1606905330.git.mallikarjunax.reddy@linux.intel.com Signed-off-by: Vinod Koul --- .../devicetree/bindings/dma/intel,ldma.yaml | 116 +++++++++++++++++++++ 1 file changed, 116 insertions(+) create mode 100644 Documentation/devicetree/bindings/dma/intel,ldma.yaml (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/dma/intel,ldma.yaml b/Documentation/devicetree/bindings/dma/intel,ldma.yaml new file mode 100644 index 000000000000..866d4c758a7a --- /dev/null +++ b/Documentation/devicetree/bindings/dma/intel,ldma.yaml @@ -0,0 +1,116 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/dma/intel,ldma.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Lightning Mountain centralized DMA controllers. + +maintainers: + - chuanhua.lei@intel.com + - mallikarjunax.reddy@intel.com + +allOf: + - $ref: "dma-controller.yaml#" + +properties: + compatible: + enum: + - intel,lgm-cdma + - intel,lgm-dma2tx + - intel,lgm-dma1rx + - intel,lgm-dma1tx + - intel,lgm-dma0tx + - intel,lgm-dma3 + - intel,lgm-toe-dma30 + - intel,lgm-toe-dma31 + + reg: + maxItems: 1 + + "#dma-cells": + const: 3 + description: + The first cell is the peripheral's DMA request line. + The second cell is the peripheral's (port) number corresponding to the channel. + The third cell is the burst length of the channel. + + dma-channels: + minimum: 1 + maximum: 16 + + dma-channel-mask: + maxItems: 1 + + clocks: + maxItems: 1 + + resets: + maxItems: 1 + + reset-names: + items: + - const: ctrl + + interrupts: + maxItems: 1 + + intel,dma-poll-cnt: + $ref: /schemas/types.yaml#definitions/uint32 + description: + DMA descriptor polling counter is used to control the poling mechanism + for the descriptor fetching for all channels. + + intel,dma-byte-en: + type: boolean + description: + DMA byte enable is only valid for DMA write(RX). + Byte enable(1) means DMA write will be based on the number of dwords + instead of the whole burst. + + intel,dma-drb: + type: boolean + description: + DMA descriptor read back to make sure data and desc synchronization. + + intel,dma-dburst-wr: + type: boolean + description: + Enable RX dynamic burst write. When it is enabled, the DMA does RX dynamic burst; + if it is disabled, the DMA RX will still support programmable fixed burst size of 2,4,8,16. + It only applies to RX DMA and memcopy DMA. + +required: + - compatible + - reg + +additionalProperties: false + +examples: + - | + dma0: dma-controller@e0e00000 { + compatible = "intel,lgm-cdma"; + reg = <0xe0e00000 0x1000>; + #dma-cells = <3>; + dma-channels = <16>; + dma-channel-mask = <0xFFFF>; + interrupt-parent = <&ioapic1>; + interrupts = <82 1>; + resets = <&rcu0 0x30 0>; + reset-names = "ctrl"; + clocks = <&cgu0 80>; + intel,dma-poll-cnt = <4>; + intel,dma-byte-en; + intel,dma-drb; + }; + - | + dma3: dma-controller@ec800000 { + compatible = "intel,lgm-dma3"; + reg = <0xec800000 0x1000>; + clocks = <&cgu0 71>; + resets = <&rcu0 0x10 9>; + #dma-cells = <3>; + intel,dma-poll-cnt = <16>; + intel,dma-byte-en; + intel,dma-dburst-wr; + }; -- cgit v1.2.3 From 352cf679c73d30c2262aa337d7e2ce93c66dd2b6 Mon Sep 17 00:00:00 2001 From: Sakari Ailus Date: Mon, 30 Nov 2020 14:44:32 +0100 Subject: media: Documentation: v4l: Remove reference to video ops We no longer have format related callbacks in video ops. Remove the reference to them. Signed-off-by: Sakari Ailus Reviewed-by: Jacopo Mondi Signed-off-by: Mauro Carvalho Chehab --- Documentation/driver-api/media/v4l2-subdev.rst | 4 ---- 1 file changed, 4 deletions(-) (limited to 'Documentation') diff --git a/Documentation/driver-api/media/v4l2-subdev.rst b/Documentation/driver-api/media/v4l2-subdev.rst index bb5b1a7cdfd9..d4cba0d6c4ca 100644 --- a/Documentation/driver-api/media/v4l2-subdev.rst +++ b/Documentation/driver-api/media/v4l2-subdev.rst @@ -122,10 +122,6 @@ Don't forget to cleanup the media entity before the sub-device is destroyed: media_entity_cleanup(&sd->entity); -If the subdev driver intends to process video and integrate with the media -framework, it must implement format related functionality using -:c:type:`v4l2_subdev_pad_ops` instead of :c:type:`v4l2_subdev_video_ops`. - In that case, the subdev driver may set the link_validate field to provide its own link validation function. The link validation function is called for every link in the pipeline where both of the ends of the links are V4L2 -- cgit v1.2.3 From 25c8d9a7689ed2ee092a618fff718d62eed07489 Mon Sep 17 00:00:00 2001 From: Sakari Ailus Date: Mon, 30 Nov 2020 14:46:06 +0100 Subject: media: Documentation: v4l: Document that link_validate op is valid for sink only The link_validate pad op will only be called on sink pads. Document this. Signed-off-by: Sakari Ailus Reviewed-by: Jacopo Mondi Signed-off-by: Mauro Carvalho Chehab --- Documentation/driver-api/media/v4l2-subdev.rst | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) (limited to 'Documentation') diff --git a/Documentation/driver-api/media/v4l2-subdev.rst b/Documentation/driver-api/media/v4l2-subdev.rst index d4cba0d6c4ca..6d5c799c49fe 100644 --- a/Documentation/driver-api/media/v4l2-subdev.rst +++ b/Documentation/driver-api/media/v4l2-subdev.rst @@ -122,11 +122,12 @@ Don't forget to cleanup the media entity before the sub-device is destroyed: media_entity_cleanup(&sd->entity); -In that case, the subdev driver may set the link_validate field to provide -its own link validation function. The link validation function is called for -every link in the pipeline where both of the ends of the links are V4L2 -sub-devices. The driver is still responsible for validating the correctness -of the format configuration between sub-devices and video nodes. +If a sub-device driver implements sink pads, the subdev driver may set the +link_validate field in :c:type:`v4l2_subdev_pad_ops`to provide its own link +validation function. For every link in the pipeline, the link_validate pad +operation of the sink end of the link is called. In both cases the driver is +still responsible for validating the correctness of the format configuration +between sub-devices and video nodes. If link_validate op is not set, the default function :c:func:`v4l2_subdev_link_validate_default` is used instead. This function -- cgit v1.2.3 From 1b5071af824039cb71592d5b2a60773ee1ee94be Mon Sep 17 00:00:00 2001 From: Jacopo Mondi Date: Thu, 19 Nov 2020 17:19:27 +0100 Subject: media: dt-bindings: media: i2c: Rename ov5647.yaml Rename 'ov5647.yaml' as 'ovti,ov5647.yaml' and update the MAINTAINERS file entry accordingly. Signed-off-by: Jacopo Mondi Signed-off-by: Sakari Ailus Signed-off-by: Mauro Carvalho Chehab --- .../devicetree/bindings/media/i2c/ov5647.yaml | 88 ---------------------- .../devicetree/bindings/media/i2c/ovti,ov5647.yaml | 88 ++++++++++++++++++++++ MAINTAINERS | 2 +- 3 files changed, 89 insertions(+), 89 deletions(-) delete mode 100644 Documentation/devicetree/bindings/media/i2c/ov5647.yaml create mode 100644 Documentation/devicetree/bindings/media/i2c/ovti,ov5647.yaml (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/media/i2c/ov5647.yaml b/Documentation/devicetree/bindings/media/i2c/ov5647.yaml deleted file mode 100644 index 280c62afae13..000000000000 --- a/Documentation/devicetree/bindings/media/i2c/ov5647.yaml +++ /dev/null @@ -1,88 +0,0 @@ -# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) -%YAML 1.2 ---- -$id: http://devicetree.org/schemas/media/i2c/ov5647.yaml# -$schema: http://devicetree.org/meta-schemas/core.yaml# - -title: Omnivision OV5647 raw image sensor - -maintainers: - - Dave Stevenson - - Jacopo Mondi - -description: |- - The OV5647 is a raw image sensor with MIPI CSI-2 and CCP2 image data - interfaces and CCI (I2C compatible) control bus. - -properties: - compatible: - const: ovti,ov5647 - - reg: - description: I2C device address. - maxItems: 1 - - clocks: - description: Reference to the xclk clock. - maxItems: 1 - - pwdn-gpios: - description: Reference to the GPIO connected to the pwdn pin. Active high. - maxItems: 1 - - port: - type: object - description: |- - Should contain one endpoint sub-node used to model connection to the - video receiver according to the specification defined in - Documentation/devicetree/bindings/media/video-interfaces.txt. - - properties: - endpoint: - type: object - - properties: - remote-endpoint: - description: |- - phandle to the video receiver input port. - - clock-noncontinuous: - type: boolean - description: |- - Set to true to allow MIPI CSI-2 non-continuous clock operations. - - additionalProperties: false - - additionalProperties: false - -required: - - compatible - - reg - - clocks - - port - -additionalProperties: false - -examples: - - | - #include - - i2c { - #address-cells = <1>; - #size-cells = <0>; - - ov5647: camera@36 { - compatible = "ovti,ov5647"; - reg = <0x36>; - clocks = <&camera_clk>; - pwdn-gpios = <&pioE 29 GPIO_ACTIVE_HIGH>; - - port { - camera_out: endpoint { - remote-endpoint = <&csi1_ep1>; - }; - }; - }; - }; - -... diff --git a/Documentation/devicetree/bindings/media/i2c/ovti,ov5647.yaml b/Documentation/devicetree/bindings/media/i2c/ovti,ov5647.yaml new file mode 100644 index 000000000000..280c62afae13 --- /dev/null +++ b/Documentation/devicetree/bindings/media/i2c/ovti,ov5647.yaml @@ -0,0 +1,88 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/media/i2c/ov5647.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Omnivision OV5647 raw image sensor + +maintainers: + - Dave Stevenson + - Jacopo Mondi + +description: |- + The OV5647 is a raw image sensor with MIPI CSI-2 and CCP2 image data + interfaces and CCI (I2C compatible) control bus. + +properties: + compatible: + const: ovti,ov5647 + + reg: + description: I2C device address. + maxItems: 1 + + clocks: + description: Reference to the xclk clock. + maxItems: 1 + + pwdn-gpios: + description: Reference to the GPIO connected to the pwdn pin. Active high. + maxItems: 1 + + port: + type: object + description: |- + Should contain one endpoint sub-node used to model connection to the + video receiver according to the specification defined in + Documentation/devicetree/bindings/media/video-interfaces.txt. + + properties: + endpoint: + type: object + + properties: + remote-endpoint: + description: |- + phandle to the video receiver input port. + + clock-noncontinuous: + type: boolean + description: |- + Set to true to allow MIPI CSI-2 non-continuous clock operations. + + additionalProperties: false + + additionalProperties: false + +required: + - compatible + - reg + - clocks + - port + +additionalProperties: false + +examples: + - | + #include + + i2c { + #address-cells = <1>; + #size-cells = <0>; + + ov5647: camera@36 { + compatible = "ovti,ov5647"; + reg = <0x36>; + clocks = <&camera_clk>; + pwdn-gpios = <&pioE 29 GPIO_ACTIVE_HIGH>; + + port { + camera_out: endpoint { + remote-endpoint = <&csi1_ep1>; + }; + }; + }; + }; + +... diff --git a/MAINTAINERS b/MAINTAINERS index 471561d9d55f..be80b8142ac8 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -13115,7 +13115,7 @@ M: Jacopo Mondi L: linux-media@vger.kernel.org S: Maintained T: git git://linuxtv.org/media_tree.git -F: Documentation/devicetree/bindings/media/i2c/ov5647.yaml +F: Documentation/devicetree/bindings/media/i2c/ovti,ov5647.yaml F: drivers/media/i2c/ov5647.c OMNIVISION OV5670 SENSOR DRIVER -- cgit v1.2.3 From b8e724fd71173fad2d7d6d70d18d8b3379cd4626 Mon Sep 17 00:00:00 2001 From: Yanteng Si Date: Tue, 12 Jan 2021 19:52:56 +0800 Subject: doc/zh_CN: add mips index.rst translation This patch translates Documentation/mips/index.rst into Chinese. Signed-off-by: Yanteng Si Reviewed-by: Alex Shi Reviewed-by: Jiaxun Yang Link: https://lore.kernel.org/r/20210112115259.217944-1-siyanteng@loongson.cn Signed-off-by: Jonathan Corbet --- Documentation/translations/zh_CN/mips/index.rst | 29 +++++++++++++++++++++++++ 1 file changed, 29 insertions(+) create mode 100644 Documentation/translations/zh_CN/mips/index.rst (limited to 'Documentation') diff --git a/Documentation/translations/zh_CN/mips/index.rst b/Documentation/translations/zh_CN/mips/index.rst new file mode 100644 index 000000000000..2c7b836a3da5 --- /dev/null +++ b/Documentation/translations/zh_CN/mips/index.rst @@ -0,0 +1,29 @@ +.. SPDX-License-Identifier: GPL-2.0 + +.. include:: ../disclaimer-zh_CN.rst + +:Original: :ref:`Documentation/mips/index.rst ` +:Translator: Yanteng Si + +.. _cn_index: + + +=========================== +MIPS特性文档 +=========================== + +.. toctree:: + :maxdepth: 2 + :numbered: + + booting + ingenic-tcu + + features + +.. only:: subproject and html + + Indices + ======= + + * :ref:`genindex` -- cgit v1.2.3 From 7fd3954b0c523bdfdf98bf8e637387e33d497bf1 Mon Sep 17 00:00:00 2001 From: Yanteng Si Date: Tue, 12 Jan 2021 19:52:57 +0800 Subject: doc/zh_CN: add mips booting.rst translation This patch translates Documentation/mips/booting.rst into Chinese. Signed-off-by: Yanteng Si Reviewed-by: Alex Shi Link: https://lore.kernel.org/r/20210112115259.217944-2-siyanteng@loongson.cn Signed-off-by: Jonathan Corbet --- Documentation/translations/zh_CN/mips/booting.rst | 31 +++++++++++++++++++++++ 1 file changed, 31 insertions(+) create mode 100644 Documentation/translations/zh_CN/mips/booting.rst (limited to 'Documentation') diff --git a/Documentation/translations/zh_CN/mips/booting.rst b/Documentation/translations/zh_CN/mips/booting.rst new file mode 100644 index 000000000000..3099d0fff7a6 --- /dev/null +++ b/Documentation/translations/zh_CN/mips/booting.rst @@ -0,0 +1,31 @@ +.. SPDX-License-Identifier: GPL-2.0 + +.. include:: ../disclaimer-zh_CN.rst + +:Original: :ref:`Documentation/mips/booting.rst ` +:Translator: Yanteng Si + +.. _cn_booting: + +BMIPS设备树引导 +------------------------ + + 一些bootloaders只支持在内核镜像开始地址处的单一入口点。而其它 + bootloaders将跳转到ELF的开始地址处。两种方案都支持的;因为 + CONFIG_BOOT_RAW=y and CONFIG_NO_EXCEPT_FILL=y, 所以第一条指令 + 会立即跳转到kernel_entry()入口处执行。 + + 与arch/arm情况(b)类似,dt感知的引导加载程序需要设置以下寄存器: + + a0 : 0 + + a1 : 0xffffffff + + a2 : RAM中指向设备树块的物理指针(在chapterII中定义)。 + 设备树可以位于前512MB物理地址空间(0x00000000 - + 0x1fffffff)的任何位置,以64位边界对齐。 + + 传统bootloaders不会使用这样的约定,并且它们不传入DT块。 + 在这种情况下,Linux将通过选中CONFIG_DT_*查找DTB。 + + 以上约定只在32位系统中定义,因为目前没有任何64位的BMIPS实现。 -- cgit v1.2.3 From 72bc9d08868d267d36a5be511f7e1e0a23e75cd5 Mon Sep 17 00:00:00 2001 From: Yanteng Si Date: Tue, 12 Jan 2021 19:52:58 +0800 Subject: doc/zh_CN: add mips features.rst translation This patch translates Documentation/mips/features.rst into Chinese. Signed-off-by: Yanteng Si Reviewed-by: Alex Shi Link: https://lore.kernel.org/r/20210112115259.217944-3-siyanteng@loongson.cn Signed-off-by: Jonathan Corbet --- Documentation/translations/zh_CN/mips/features.rst | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 Documentation/translations/zh_CN/mips/features.rst (limited to 'Documentation') diff --git a/Documentation/translations/zh_CN/mips/features.rst b/Documentation/translations/zh_CN/mips/features.rst new file mode 100644 index 000000000000..7e67f81a0982 --- /dev/null +++ b/Documentation/translations/zh_CN/mips/features.rst @@ -0,0 +1,10 @@ +.. SPDX-License-Identifier: GPL-2.0 + +.. include:: ../disclaimer-zh_CN.rst + +:Original: :ref:`Documentation/mips/features.rst ` +:Translator: Yanteng Si + +.. _cn_features: + +.. kernel-feat:: $srctree/Documentation/features mips -- cgit v1.2.3 From 419b1d4ed1cb9a7167b53ec2d9ae5ff56c6ee4a8 Mon Sep 17 00:00:00 2001 From: Yanteng Si Date: Tue, 12 Jan 2021 19:52:59 +0800 Subject: doc/zh_CN: add mips ingenic-tcu.rst translation This patch translates Documentation/mips/ingenic-tcu.rst into Chinese. Signed-off-by: Yanteng Si Reviewed-by: Alex Shi Link: https://lore.kernel.org/r/20210112115259.217944-4-siyanteng@loongson.cn Signed-off-by: Jonathan Corbet --- .../translations/zh_CN/mips/ingenic-tcu.rst | 69 ++++++++++++++++++++++ 1 file changed, 69 insertions(+) create mode 100644 Documentation/translations/zh_CN/mips/ingenic-tcu.rst (limited to 'Documentation') diff --git a/Documentation/translations/zh_CN/mips/ingenic-tcu.rst b/Documentation/translations/zh_CN/mips/ingenic-tcu.rst new file mode 100644 index 000000000000..72b5d409ed89 --- /dev/null +++ b/Documentation/translations/zh_CN/mips/ingenic-tcu.rst @@ -0,0 +1,69 @@ +.. SPDX-License-Identifier: GPL-2.0 + +.. include:: ../disclaimer-zh_CN.rst + +:Original: :ref:`Documentation/mips/ingenic-tcu.rst ` +:Translator: Yanteng Si + +.. _cn_ingenic-tcu: + +=============================================== +君正 JZ47xx SoC定时器/计数器硬件单元 +=============================================== + +君正 JZ47xx SoC中的定时器/计数器单元(TCU)是一个多功能硬件块。它有多达 +8个通道,可以用作计数器,计时器,或脉冲宽度调制器。 + +- JZ4725B, JZ4750, JZ4755 只有6个TCU通道。其它SoC都有8个通道。 + +- JZ4725B引入了一个独立的通道,称为操作系统计时器(OST)。这是一个32位可 + 编程定时器。在JZ4760B及以上型号上,它是64位的。 + +- 每个TCU通道都有自己的时钟源,可以通过 TCSR 寄存器设置通道的父级时钟 + 源(pclk、ext、rtc)、开关以及分频。 + + - 看门狗和OST硬件模块在它们的寄存器空间中也有相同形式的TCSR寄存器。 + - 用于关闭/开启的 TCU 寄存器也可以关闭/开启看门狗和 OST 时钟。 + +- 每个TCU通道在两种模式的其中一种模式下运行: + + - 模式 TCU1:通道无法在睡眠模式下运行,但更易于操作。 + - 模式 TCU2:通道可以在睡眠模式下运行,但操作比 TCU1 通道复杂一些。 + +- 每个 TCU 通道的模式取决于使用的SoC: + + - 在最老的SoC(高于JZ4740),八个通道都运行在TCU1模式。 + - 在 JZ4725B,通道5运行在TCU2,其它通道则运行在TCU1。 + - 在最新的SoC(JZ4750及之后),通道1-2运行在TCU2,其它通道则运行 + 在TCU1。 + +- 每个通道都可以生成中断。有些通道共享一条中断线,而有些没有,其在SoC型 + 号之间的变更: + + - 在很老的SoC(JZ4740及更低),通道0和通道1有它们自己的中断线;通 + 道2-7共享最后一条中断线。 + - 在 JZ4725B,通道0有它自己的中断线;通道1-5共享一条中断线;OST + 使用最后一条中断线。 + - 在比较新的SoC(JZ4750及以后),通道5有它自己的中断线;通 + 道0-4和(如果是8通道)6-7全部共享一条中断线;OST使用最后一条中 + 断线。 + +实现 +==== + +TCU硬件的功能分布在多个驱动程序: + +=========== ===== +时钟 drivers/clk/ingenic/tcu.c +中断 drivers/irqchip/irq-ingenic-tcu.c +定时器 drivers/clocksource/ingenic-timer.c +OST drivers/clocksource/ingenic-ost.c +脉冲宽度调制器 drivers/pwm/pwm-jz4740.c +看门狗 drivers/watchdog/jz4740_wdt.c +=========== ===== + +因为可以从相同的寄存器控制属于不同驱动程序和框架的TCU的各种功能,所以 +所有这些驱动程序都通过相同的控制总线通用接口访问它们的寄存器。 + +有关TCU驱动程序的设备树绑定的更多信息,请参阅: +Documentation/devicetree/bindings/timer/ingenic,tcu.yaml. -- cgit v1.2.3 From 9428d93e49196e67213bd8d173563b9044dfd28d Mon Sep 17 00:00:00 2001 From: Rob Herring Date: Mon, 2 Nov 2020 13:51:25 -0600 Subject: dt-bindings: usb-connector: Use OF graph schema Now that we have a graph schema, reference it from the usb-connector schema. Reviewed-by: Laurent Pinchart Link: https://lore.kernel.org/r/20201102203656.220187-3-robh@kernel.org Signed-off-by: Rob Herring --- .../devicetree/bindings/connector/usb-connector.yaml | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/connector/usb-connector.yaml b/Documentation/devicetree/bindings/connector/usb-connector.yaml index 4286ed767a0a..63d90b398c01 100644 --- a/Documentation/devicetree/bindings/connector/usb-connector.yaml +++ b/Documentation/devicetree/bindings/connector/usb-connector.yaml @@ -143,22 +143,23 @@ properties: power dual role. ports: - description: OF graph bindings (specified in bindings/graph.txt) that model - any data bus to the connector unless the bus is between parent node and - the connector. Since a single connector can have multiple data buses every - bus has an assigned OF graph port number as described below. - type: object + $ref: /schemas/graph.yaml#/properties/ports + description: OF graph bindings modeling any data bus to the connector + unless the bus is between parent node and the connector. Since a single + connector can have multiple data buses every bus has an assigned OF graph + port number as described below. + properties: port@0: - type: object + $ref: /schemas/graph.yaml#/properties/port description: High Speed (HS), present in all connectors. port@1: - type: object + $ref: /schemas/graph.yaml#/properties/port description: Super Speed (SS), present in SS capable connectors. port@2: - type: object + $ref: /schemas/graph.yaml#/properties/port description: Sideband Use (SBU), present in USB-C. This describes the alternate mode connection of which SBU is a part. -- cgit v1.2.3 From 44c1febd7e6018b279d83e2c9725333be6b00f83 Mon Sep 17 00:00:00 2001 From: Sakari Ailus Date: Fri, 11 Dec 2020 23:15:04 +0100 Subject: media: Documentation: media: Update pixel rate formula for C-PHY Update the formula to calculate the pixel rate on the link for C-PHY. Signed-off-by: Sakari Ailus Signed-off-by: Mauro Carvalho Chehab --- Documentation/driver-api/media/csi2.rst | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'Documentation') diff --git a/Documentation/driver-api/media/csi2.rst b/Documentation/driver-api/media/csi2.rst index e3bbc6baf0f0..11c52b0be8b8 100644 --- a/Documentation/driver-api/media/csi2.rst +++ b/Documentation/driver-api/media/csi2.rst @@ -35,7 +35,7 @@ ability to start and stop the stream. The value of the V4L2_CID_PIXEL_RATE is calculated as follows:: - pixel_rate = link_freq * 2 * nr_of_lanes / bits_per_sample + pixel_rate = link_freq * 2 * nr_of_lanes * 16 / k / bits_per_sample where @@ -53,6 +53,8 @@ where - Two bits are transferred per clock cycle per lane. * - bits_per_sample - Number of bits per sample. + * - k + - 16 for D-PHY and 7 for C-PHY The transmitter drivers must, if possible, configure the CSI-2 transmitter to *LP-11 mode* whenever the transmitter is powered on but -- cgit v1.2.3 From f7c7d6ccc503c0a5f4e5debb570b55bf2eb24c73 Mon Sep 17 00:00:00 2001 From: Sakari Ailus Date: Thu, 17 Dec 2020 19:27:08 +0100 Subject: media: uapi: Add an entity type for Image Signal Processors Add and document a media entity type for Image Signal Processor devices. Surprisingly we didn't have one, so add one now. More or less all ISP drivers should use this type instead of what they currently are using (or not using anything). Signed-off-by: Sakari Ailus Reviewed-by: Laurent Pinchart Signed-off-by: Mauro Carvalho Chehab --- Documentation/userspace-api/media/mediactl/media-types.rst | 7 +++++++ include/uapi/linux/media.h | 1 + 2 files changed, 8 insertions(+) (limited to 'Documentation') diff --git a/Documentation/userspace-api/media/mediactl/media-types.rst b/Documentation/userspace-api/media/mediactl/media-types.rst index 7b24a213cae7..e1e4043b3b1c 100644 --- a/Documentation/userspace-api/media/mediactl/media-types.rst +++ b/Documentation/userspace-api/media/mediactl/media-types.rst @@ -39,6 +39,7 @@ Types and flags used to represent the media graph elements .. _MEDIA-ENT-F-PROC-VIDEO-STATISTICS: .. _MEDIA-ENT-F-PROC-VIDEO-ENCODER: .. _MEDIA-ENT-F-PROC-VIDEO-DECODER: +.. _MEDIA-ENT-F-PROC-VIDEO-ISP: .. _MEDIA-ENT-F-VID-MUX: .. _MEDIA-ENT-F-VID-IF-BRIDGE: .. _MEDIA-ENT-F-DV-DECODER: @@ -201,6 +202,12 @@ Types and flags used to represent the media graph elements decompressing a compressed video stream into uncompressed video frames. Must have one sink pad and at least one source pad. + * - ``MEDIA_ENT_F_PROC_VIDEO_ISP`` + - An Image Signal Processor (ISP) device. ISPs generally are one of a + kind devices that have their specific control interfaces using a + combination of custom V4L2 controls and IOCTLs, and parameters + supplied in a metadata buffer. + * - ``MEDIA_ENT_F_VID_MUX`` - Video multiplexer. An entity capable of multiplexing must have at least two sink pads and one source pad, and must pass the video diff --git a/include/uapi/linux/media.h b/include/uapi/linux/media.h index 383ac7b7d8f0..200fa8462b90 100644 --- a/include/uapi/linux/media.h +++ b/include/uapi/linux/media.h @@ -127,6 +127,7 @@ struct media_device_info { #define MEDIA_ENT_F_PROC_VIDEO_STATISTICS (MEDIA_ENT_F_BASE + 0x4006) #define MEDIA_ENT_F_PROC_VIDEO_ENCODER (MEDIA_ENT_F_BASE + 0x4007) #define MEDIA_ENT_F_PROC_VIDEO_DECODER (MEDIA_ENT_F_BASE + 0x4008) +#define MEDIA_ENT_F_PROC_VIDEO_ISP (MEDIA_ENT_F_BASE + 0x4009) /* * Switch and bridge entity functions -- cgit v1.2.3 From 2225cf449294ebba4e03a300636e1a8b20953c0b Mon Sep 17 00:00:00 2001 From: Sakari Ailus Date: Fri, 11 Dec 2020 18:56:04 +0100 Subject: media: Documentation: media: Document clock handling in camera sensor drivers Document pratices of handling clocks in camera sensor drivers on both DT and ACPI. Signed-off-by: Sakari Ailus Signed-off-by: Mauro Carvalho Chehab --- Documentation/driver-api/media/camera-sensor.rst | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) (limited to 'Documentation') diff --git a/Documentation/driver-api/media/camera-sensor.rst b/Documentation/driver-api/media/camera-sensor.rst index ffb0cad8137a..3fc378b3b269 100644 --- a/Documentation/driver-api/media/camera-sensor.rst +++ b/Documentation/driver-api/media/camera-sensor.rst @@ -15,7 +15,7 @@ Camera sensors have an internal clock tree including a PLL and a number of divisors. The clock tree is generally configured by the driver based on a few input parameters that are specific to the hardware:: the external clock frequency and the link frequency. The two parameters generally are obtained from system -firmware. No other frequencies should be used in any circumstances. +firmware. **No other frequencies should be used in any circumstances.** The reason why the clock frequencies are so important is that the clock signals come out of the SoC, and in many cases a specific frequency is designed to be @@ -23,6 +23,24 @@ used in the system. Using another frequency may cause harmful effects elsewhere. Therefore only the pre-determined frequencies are configurable by the user. +ACPI +~~~~ + +Read the "clock-frequency" _DSD property to denote the frequency. The driver can +rely on this frequency being used. + +Devicetree +~~~~~~~~~~ + +The currently preferred way to achieve this is using "assigned-clock-rates" +property. See Documentation/devicetree/bindings/clock/clock-bindings.txt for +more information. The driver then gets the frequency using clk_get_rate(). + +This approach has the drawback that there's no guarantee that the frequency +hasn't been modified directly or indirectly by another driver, or supported by +the board's clock tree to begin with. Changes to the Common Clock Framework API +are required to ensure reliability. + Frame size ---------- -- cgit v1.2.3 From 29a202fa7accd6b1ca617b765d02068e77a71731 Mon Sep 17 00:00:00 2001 From: Paul Kocialkowski Date: Thu, 31 Dec 2020 15:23:56 +0100 Subject: media: dt-bindings: media: i2c: Add OV5648 bindings documentation This introduces YAML bindings documentation for the OV5648 image sensor. Signed-off-by: Paul Kocialkowski Reviewed-by: Rob Herring Signed-off-by: Sakari Ailus Signed-off-by: Mauro Carvalho Chehab --- .../devicetree/bindings/media/i2c/ovti,ov5648.yaml | 115 +++++++++++++++++++++ 1 file changed, 115 insertions(+) create mode 100644 Documentation/devicetree/bindings/media/i2c/ovti,ov5648.yaml (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/media/i2c/ovti,ov5648.yaml b/Documentation/devicetree/bindings/media/i2c/ovti,ov5648.yaml new file mode 100644 index 000000000000..f8783f77cc54 --- /dev/null +++ b/Documentation/devicetree/bindings/media/i2c/ovti,ov5648.yaml @@ -0,0 +1,115 @@ +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/media/i2c/ovti,ov5648.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: OmniVision OV5648 Image Sensor Device Tree Bindings + +maintainers: + - Paul Kocialkowski + +properties: + compatible: + const: ovti,ov5648 + + reg: + maxItems: 1 + + clocks: + items: + - description: XVCLK Clock + + assigned-clocks: + maxItems: 1 + + assigned-clock-rates: + maxItems: 1 + + dvdd-supply: + description: Digital Domain Power Supply + + avdd-supply: + description: Analog Domain Power Supply (internal AVDD is used if missing) + + dovdd-supply: + description: I/O Domain Power Supply + + powerdown-gpios: + maxItems: 1 + description: Power Down Pin GPIO Control (active low) + + reset-gpios: + maxItems: 1 + description: Reset Pin GPIO Control (active low) + + port: + type: object + description: MIPI CSI-2 transmitter port + + properties: + endpoint: + type: object + + properties: + remote-endpoint: true + + link-frequencies: + $ref: /schemas/types.yaml#/definitions/uint64-array + description: Allowed MIPI CSI-2 link frequencies + + data-lanes: + minItems: 1 + maxItems: 2 + + required: + - data-lanes + - link-frequencies + - remote-endpoint + + required: + - endpoint + +required: + - compatible + - reg + - clocks + - assigned-clocks + - assigned-clock-rates + - dvdd-supply + - dovdd-supply + - port + +additionalProperties: false + +examples: + - | + #include + #include + + i2c0 { + #address-cells = <1>; + #size-cells = <0>; + + ov5648: camera@36 { + compatible = "ovti,ov5648"; + reg = <0x36>; + + dvdd-supply = <&ov5648_dvdd>; + avdd-supply = <&ov5648_avdd>; + dovdd-supply = <&ov5648_dovdd>; + clocks = <&ov5648_xvclk 0>; + assigned-clocks = <&ov5648_xvclk 0>; + assigned-clock-rates = <24000000>; + + + ov5648_out: port { + ov5648_out_mipi_csi2: endpoint { + data-lanes = <1 2>; + link-frequencies = /bits/ 64 <210000000 168000000>; + + remote-endpoint = <&mipi_csi2_in_ov5648>; + }; + }; + }; + }; -- cgit v1.2.3 From 22f2b47517a64c405422db380a93b0829b282b87 Mon Sep 17 00:00:00 2001 From: Paul Kocialkowski Date: Thu, 31 Dec 2020 15:27:00 +0100 Subject: media: dt-bindings: media: i2c: Add OV8865 bindings documentation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This introduces YAML bindings documentation for the OV8865 image sensor. Co-developed-by: Kévin L'hôpital Signed-off-by: Kévin L'hôpital Signed-off-by: Paul Kocialkowski Reviewed-by: Rob Herring Signed-off-by: Sakari Ailus Signed-off-by: Mauro Carvalho Chehab --- .../devicetree/bindings/media/i2c/ovti,ov8865.yaml | 124 +++++++++++++++++++++ 1 file changed, 124 insertions(+) create mode 100644 Documentation/devicetree/bindings/media/i2c/ovti,ov8865.yaml (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/media/i2c/ovti,ov8865.yaml b/Documentation/devicetree/bindings/media/i2c/ovti,ov8865.yaml new file mode 100644 index 000000000000..c0ba28aa30c4 --- /dev/null +++ b/Documentation/devicetree/bindings/media/i2c/ovti,ov8865.yaml @@ -0,0 +1,124 @@ +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/media/i2c/ovti,ov8865.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: OmniVision OV8865 Image Sensor Device Tree Bindings + +maintainers: + - Paul Kocialkowski + +properties: + compatible: + const: ovti,ov8865 + + reg: + maxItems: 1 + + clocks: + items: + - description: EXTCLK Clock + + assigned-clocks: + maxItems: 1 + + assigned-clock-rates: + maxItems: 1 + + dvdd-supply: + description: Digital Domain Power Supply + + avdd-supply: + description: Analog Domain Power Supply + + dovdd-supply: + description: I/O Domain Power Supply + + powerdown-gpios: + maxItems: 1 + description: Power Down Pin GPIO Control (active low) + + reset-gpios: + maxItems: 1 + description: Reset Pin GPIO Control (active low) + + port: + type: object + description: MIPI CSI-2 transmitter port + + properties: + endpoint: + type: object + + properties: + remote-endpoint: true + + link-frequencies: + $ref: /schemas/types.yaml#/definitions/uint64-array + description: Allowed MIPI CSI-2 link frequencies + + data-lanes: + minItems: 1 + maxItems: 4 + + required: + - data-lanes + - link-frequencies + - remote-endpoint + + required: + - endpoint + +required: + - compatible + - reg + - clocks + - assigned-clocks + - assigned-clock-rates + - dvdd-supply + - avdd-supply + - dovdd-supply + - port + +additionalProperties: false + +examples: + - | + #include + #include + + i2c2 { + #address-cells = <1>; + #size-cells = <0>; + + ov8865: camera@36 { + compatible = "ovti,ov8865"; + reg = <0x36>; + + pinctrl-names = "default"; + pinctrl-0 = <&csi_mclk_pin>; + + clocks = <&ccu CLK_CSI_MCLK>; + assigned-clocks = <&ccu CLK_CSI_MCLK>; + assigned-clock-rates = <24000000>; + + avdd-supply = <®_ov8865_avdd>; + dovdd-supply = <®_ov8865_dovdd>; + dvdd-supply = <®_ov8865_dvdd>; + + powerdown-gpios = <&pio 4 17 GPIO_ACTIVE_LOW>; /* PE17 */ + reset-gpios = <&pio 4 16 GPIO_ACTIVE_LOW>; /* PE16 */ + + port { + ov8865_out_mipi_csi2: endpoint { + data-lanes = <1 2 3 4>; + link-frequencies = /bits/ 64 <360000000>; + + remote-endpoint = <&mipi_csi2_in_ov8865>; + }; + }; + }; + }; + +... -- cgit v1.2.3 From db08f69ef8205dc4bcc2af2a24bcfc8f9da47899 Mon Sep 17 00:00:00 2001 From: Sakari Ailus Date: Fri, 13 Nov 2020 17:12:28 +0100 Subject: media: Documentation: ccs: Add user documentation for the CCS driver Add user documentation for the CCS driver. This includes e.g. sub-devices implemented by the driver. Signed-off-by: Sakari Ailus Signed-off-by: Mauro Carvalho Chehab --- Documentation/userspace-api/media/drivers/ccs.rst | 59 ++++++++++++++++++++++ .../userspace-api/media/drivers/index.rst | 1 + MAINTAINERS | 1 + 3 files changed, 61 insertions(+) create mode 100644 Documentation/userspace-api/media/drivers/ccs.rst (limited to 'Documentation') diff --git a/Documentation/userspace-api/media/drivers/ccs.rst b/Documentation/userspace-api/media/drivers/ccs.rst new file mode 100644 index 000000000000..00bb3a6288f5 --- /dev/null +++ b/Documentation/userspace-api/media/drivers/ccs.rst @@ -0,0 +1,59 @@ +.. SPDX-License-Identifier: GPL-2.0-only + +.. include:: + +MIPI CCS camera sensor driver +============================= + +The MIPI CCS camera sensor driver is a generic driver for `MIPI CCS +`_ compliant +camera sensors. It exposes three sub-devices representing the pixel array, +the binner and the scaler. + +As the capabilities of individual devices vary, the driver exposes +interfaces based on the capabilities that exist in hardware. + +Pixel Array sub-device +---------------------- + +The pixel array sub-device represents the camera sensor's pixel matrix, as well +as analogue crop functionality present in many compliant devices. The analogue +crop is configured using the ``V4L2_SEL_TGT_CROP`` on the source pad (0) of the +entity. The size of the pixel matrix can be obtained by getting the +``V4L2_SEL_TGT_NATIVE_SIZE`` target. + +Binner +------ + +The binner sub-device represents the binning functionality on the sensor. For +that purpose, selection target ``V4L2_SEL_TGT_COMPOSE`` is supported on the +sink pad (0). + +Additionally, if a device has no scaler or digital crop functionality, the +source pad (1) expses another digital crop selection rectangle that can only +crop at the end of the lines and frames. + +Scaler +------ + +The scaler sub-device represents the digital crop and scaling functionality of +the sensor. The V4L2 selection target ``V4L2_SEL_TGT_CROP`` is used to +configure the digital crop on the sink pad (0) when digital crop is supported. +Scaling is configured using selection target ``V4L2_SEL_TGT_COMPOSE`` on the +sink pad (0) as well. + +Additionally, if the scaler sub-device exists, its source pad (1) exposes +another digital crop selection rectangle that can only crop at the end of the +lines and frames. + +Digital and analogue crop +------------------------- + +Digital crop functionality is referred to as cropping that effectively works by +dropping some data on the floor. Analogue crop, on the other hand, means that +the cropped information is never retrieved. In case of camera sensors, the +analogue data is never read from the pixel matrix that are outside the +configured selection rectangle that designates crop. The difference has an +effect in device timing and likely also in power consumption. + +**Copyright** |copy| 2020 Intel Corporation diff --git a/Documentation/userspace-api/media/drivers/index.rst b/Documentation/userspace-api/media/drivers/index.rst index 05a82f8c0c99..1a9038f5f9fa 100644 --- a/Documentation/userspace-api/media/drivers/index.rst +++ b/Documentation/userspace-api/media/drivers/index.rst @@ -31,6 +31,7 @@ For more details see the file COPYING in the source distribution of Linux. :maxdepth: 5 :numbered: + ccs cx2341x-uapi imx-uapi max2175 diff --git a/MAINTAINERS b/MAINTAINERS index be80b8142ac8..906ef1373285 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -11836,6 +11836,7 @@ L: linux-media@vger.kernel.org S: Maintained F: Documentation/devicetree/bindings/media/i2c/mipi-ccs.yaml F: Documentation/driver-api/media/drivers/ccs/ +F: Documentation/userspace-api/media/drivers/ccs.rst F: drivers/media/i2c/ccs-pll.c F: drivers/media/i2c/ccs-pll.h F: drivers/media/i2c/ccs/ -- cgit v1.2.3 From a8a2d75b0897fc359ada5fb9f8b62f985351882b Mon Sep 17 00:00:00 2001 From: Sakari Ailus Date: Thu, 24 Sep 2020 00:21:32 +0200 Subject: media: v4l: uapi: ccs: Add controls for analogue gain constants Add V4L2 controls for analogue gain constants required to control analogue gain. The values are device specific and thus need to be obtained from the driver. Signed-off-by: Sakari Ailus Signed-off-by: Mauro Carvalho Chehab --- Documentation/userspace-api/media/drivers/ccs.rst | 25 +++++++++++++++++++++++ MAINTAINERS | 1 + include/uapi/linux/ccs.h | 14 +++++++++++++ 3 files changed, 40 insertions(+) create mode 100644 include/uapi/linux/ccs.h (limited to 'Documentation') diff --git a/Documentation/userspace-api/media/drivers/ccs.rst b/Documentation/userspace-api/media/drivers/ccs.rst index 00bb3a6288f5..a95d7941533d 100644 --- a/Documentation/userspace-api/media/drivers/ccs.rst +++ b/Documentation/userspace-api/media/drivers/ccs.rst @@ -56,4 +56,29 @@ analogue data is never read from the pixel matrix that are outside the configured selection rectangle that designates crop. The difference has an effect in device timing and likely also in power consumption. +Private controls +---------------- + +The MIPI CCS driver implements a number of private controls under +``V4L2_CID_USER_BASE_CCS`` to control the MIPI CCS compliant camera sensors. + +Analogue gain model +~~~~~~~~~~~~~~~~~~~ + +The CCS defines an analogue gain model where the gain can be calculated using +the following formula: + + gain = m0 * x + c0 / (m1 * x + c1) + +Either m0 or c0 will be zero. The constants that are device specific, can be +obtained from the following controls: + + V4L2_CID_CCS_ANALOGUE_GAIN_M0 + V4L2_CID_CCS_ANALOGUE_GAIN_M1 + V4L2_CID_CCS_ANALOGUE_GAIN_C0 + V4L2_CID_CCS_ANALOGUE_GAIN_C1 + +The analogue gain (``x`` in the formula) is controlled through +``V4L2_CID_ANALOGUE_GAIN`` in this case. + **Copyright** |copy| 2020 Intel Corporation diff --git a/MAINTAINERS b/MAINTAINERS index 906ef1373285..7faa7ae50716 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -11840,6 +11840,7 @@ F: Documentation/userspace-api/media/drivers/ccs.rst F: drivers/media/i2c/ccs-pll.c F: drivers/media/i2c/ccs-pll.h F: drivers/media/i2c/ccs/ +F: include/uapi/linux/ccs.h F: include/uapi/linux/smiapp.h MIPS diff --git a/include/uapi/linux/ccs.h b/include/uapi/linux/ccs.h new file mode 100644 index 000000000000..57515ed7aaab --- /dev/null +++ b/include/uapi/linux/ccs.h @@ -0,0 +1,14 @@ +/* SPDX-License-Identifier: GPL-2.0-only WITH Linux-syscall-note */ +/* Copyright (C) 2020 Intel Corporation */ + +#ifndef __UAPI_CCS_H__ +#define __UAPI_CCS_H__ + +#include + +#define V4L2_CID_CCS_ANALOGUE_GAIN_M0 (V4L2_CID_USER_CCS_BASE + 1) +#define V4L2_CID_CCS_ANALOGUE_GAIN_C0 (V4L2_CID_USER_CCS_BASE + 2) +#define V4L2_CID_CCS_ANALOGUE_GAIN_M1 (V4L2_CID_USER_CCS_BASE + 3) +#define V4L2_CID_CCS_ANALOGUE_GAIN_C1 (V4L2_CID_USER_CCS_BASE + 4) + +#endif -- cgit v1.2.3 From a75210a62b81ce8cfbe9e10e29880d870ce94b8d Mon Sep 17 00:00:00 2001 From: Sakari Ailus Date: Thu, 24 Sep 2020 21:57:52 +0200 Subject: media: v4l: uapi: ccs: Add controls for CCS alternative analogue gain Add two new controls for alternative analogue gain some CCS compliant camera sensors support. Signed-off-by: Sakari Ailus Signed-off-by: Mauro Carvalho Chehab --- Documentation/userspace-api/media/drivers/ccs.rst | 13 +++++++++++++ include/uapi/linux/ccs.h | 2 ++ 2 files changed, 15 insertions(+) (limited to 'Documentation') diff --git a/Documentation/userspace-api/media/drivers/ccs.rst b/Documentation/userspace-api/media/drivers/ccs.rst index a95d7941533d..ea09c8139c23 100644 --- a/Documentation/userspace-api/media/drivers/ccs.rst +++ b/Documentation/userspace-api/media/drivers/ccs.rst @@ -81,4 +81,17 @@ obtained from the following controls: The analogue gain (``x`` in the formula) is controlled through ``V4L2_CID_ANALOGUE_GAIN`` in this case. +Alternate analogue gain model +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The CCS defines another analogue gain model called alternate analogue gain. In +this case, the formula to calculate actual gain consists of linear and +exponential parts: + + gain = linear * 2 ^ exponent + +The ``linear`` and ``exponent`` factors can be set using the +``V4L2_CID_CCS_ANALOGUE_LINEAR_GAIN`` and +``V4L2_CID_CCS_ANALOGUE_EXPONENTIAL_GAIN`` controls, respectively + **Copyright** |copy| 2020 Intel Corporation diff --git a/include/uapi/linux/ccs.h b/include/uapi/linux/ccs.h index 57515ed7aaab..9ddec24c1401 100644 --- a/include/uapi/linux/ccs.h +++ b/include/uapi/linux/ccs.h @@ -10,5 +10,7 @@ #define V4L2_CID_CCS_ANALOGUE_GAIN_C0 (V4L2_CID_USER_CCS_BASE + 2) #define V4L2_CID_CCS_ANALOGUE_GAIN_M1 (V4L2_CID_USER_CCS_BASE + 3) #define V4L2_CID_CCS_ANALOGUE_GAIN_C1 (V4L2_CID_USER_CCS_BASE + 4) +#define V4L2_CID_CCS_ANALOGUE_LINEAR_GAIN (V4L2_CID_USER_CCS_BASE + 5) +#define V4L2_CID_CCS_ANALOGUE_EXPONENTIAL_GAIN (V4L2_CID_USER_CCS_BASE + 6) #endif -- cgit v1.2.3 From 7c0ed600f04d247cbb4c4030d87a8d36b12d44a4 Mon Sep 17 00:00:00 2001 From: Sakari Ailus Date: Fri, 25 Sep 2020 10:28:56 +0200 Subject: media: v4l: uapi: ccs: Add CCS controls for shading correction Add V4L2 controls for controlling CCS lens shading correction as well as conveying its capabilities. Signed-off-by: Sakari Ailus Signed-off-by: Mauro Carvalho Chehab --- Documentation/userspace-api/media/drivers/ccs.rst | 13 +++++++++++++ include/uapi/linux/ccs.h | 2 ++ 2 files changed, 15 insertions(+) (limited to 'Documentation') diff --git a/Documentation/userspace-api/media/drivers/ccs.rst b/Documentation/userspace-api/media/drivers/ccs.rst index ea09c8139c23..161cb65f4d98 100644 --- a/Documentation/userspace-api/media/drivers/ccs.rst +++ b/Documentation/userspace-api/media/drivers/ccs.rst @@ -94,4 +94,17 @@ The ``linear`` and ``exponent`` factors can be set using the ``V4L2_CID_CCS_ANALOGUE_LINEAR_GAIN`` and ``V4L2_CID_CCS_ANALOGUE_EXPONENTIAL_GAIN`` controls, respectively +Shading correction +~~~~~~~~~~~~~~~~~~ + +The CCS standard supports lens shading correction. The feature can be controlled +using ``V4L2_CID_CCS_SHADING_CORRECTION``. Additionally, the luminance +correction level may be changed using +``V4L2_CID_CCS_LUMINANCE_CORRECTION_LEVEL``, where value 0 indicates no +correction and 128 indicates correcting the luminance in corners to 10 % less +than in the centre. + +Shading correction needs to be enabled for luminance correction level to have an +effect. + **Copyright** |copy| 2020 Intel Corporation diff --git a/include/uapi/linux/ccs.h b/include/uapi/linux/ccs.h index 9ddec24c1401..2896d3bfdb5e 100644 --- a/include/uapi/linux/ccs.h +++ b/include/uapi/linux/ccs.h @@ -12,5 +12,7 @@ #define V4L2_CID_CCS_ANALOGUE_GAIN_C1 (V4L2_CID_USER_CCS_BASE + 4) #define V4L2_CID_CCS_ANALOGUE_LINEAR_GAIN (V4L2_CID_USER_CCS_BASE + 5) #define V4L2_CID_CCS_ANALOGUE_EXPONENTIAL_GAIN (V4L2_CID_USER_CCS_BASE + 6) +#define V4L2_CID_CCS_SHADING_CORRECTION (V4L2_CID_USER_CCS_BASE + 8) +#define V4L2_CID_CCS_LUMINANCE_CORRECTION_LEVEL (V4L2_CID_USER_CCS_BASE + 9) #endif -- cgit v1.2.3 From 81499d338995fa288464c585f49211cfaa6ffdce Mon Sep 17 00:00:00 2001 From: Sakari Ailus Date: Mon, 16 Nov 2020 18:25:12 +0100 Subject: media: Documentation: Include CCS PLL calculator to CCS driver documentation Include existing CCS PLL calculator kerneldoc documentation to the documentation build. Signed-off-by: Sakari Ailus Signed-off-by: Mauro Carvalho Chehab --- Documentation/driver-api/media/drivers/ccs/ccs.rst | 13 +++++++++++++ 1 file changed, 13 insertions(+) (limited to 'Documentation') diff --git a/Documentation/driver-api/media/drivers/ccs/ccs.rst b/Documentation/driver-api/media/drivers/ccs/ccs.rst index f49e971f2d92..b461c8aa2a16 100644 --- a/Documentation/driver-api/media/drivers/ccs/ccs.rst +++ b/Documentation/driver-api/media/drivers/ccs/ccs.rst @@ -79,4 +79,17 @@ definitions: -l drivers/media/i2c/ccs/ccs-limits.c \ -c Documentation/driver-api/media/drivers/ccs/ccs-regs.asc +CCS PLL calculator +================== + +The CCS PLL calculator is used to compute the PLL configuration, given sensor's +capabilities as well as board configuration and user specified configuration. As +the configuration space that encompasses all these configurations is vast, the +PLL calculator isn't entirely trivial. Yet it is relatively simple to use for a +driver. + +The PLL model implemented by the PLL calculator corresponds to MIPI CCS 1.1. + +.. kernel-doc:: drivers/media/i2c/ccs-pll.h + **Copyright** |copy| 2020 Intel Corporation -- cgit v1.2.3 From af20724c68633f2343506f17e0308b2e07d0a71c Mon Sep 17 00:00:00 2001 From: Sumera Priyadarsini Date: Tue, 12 Jan 2021 00:38:22 +0530 Subject: drm/vkms: Add information about module options Update vkms documentation to contain usage of `modinfo` command and steps to load vkms with module options enabled. Signed-off-by: Sumera Priyadarsini Reviewed-by: Melissa Wen Signed-off-by: Melissa Wen Link: https://patchwork.freedesktop.org/patch/msgid/4fbc6459377c1dcbe8e6648718453d5693f6451c.1610391685.git.sylphrenadin@gmail.com --- Documentation/gpu/vkms.rst | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'Documentation') diff --git a/Documentation/gpu/vkms.rst b/Documentation/gpu/vkms.rst index 9e030c74a82e..2c9b376da5ca 100644 --- a/Documentation/gpu/vkms.rst +++ b/Documentation/gpu/vkms.rst @@ -35,6 +35,18 @@ Now, to load the driver, use:: On running the lsmod command now, the VKMS driver will appear listed. You can also observe the driver being loaded in the dmesg logs. +The VKMS driver has optional features to simulate different kinds of hardware, +which are exposed as module options. You can use the `modinfo` command +to see the module options for vkms:: + + modinfo vkms + +Module options are helpful when testing, and enabling modules +can be done while loading vkms. For example, to load vkms with cursor enabled, +use:: + + sudo modprobe vkms enable_cursor=1 + To disable the driver, use :: sudo modprobe -r vkms -- cgit v1.2.3 From 5250f8f37b7ebbeaeab13517d6c08c703c95a687 Mon Sep 17 00:00:00 2001 From: Rob Herring Date: Tue, 12 Jan 2021 09:35:27 -0600 Subject: dt-bindings: usb: Use OF graph schema Now that we have a graph schema, rework the USB related schemas to use it. Mostly this is adding a reference to graph.yaml and dropping duplicate parts from schemas. Cc: Greg Kroah-Hartman Cc: Yoshihiro Shimoda Cc: Biju Das Cc: linux-usb@vger.kernel.org Reviewed-by: Greg Kroah-Hartman Reviewed-by: Biju Das Link: https://lore.kernel.org/r/20210112153527.391232-1-robh@kernel.org Signed-off-by: Rob Herring --- Documentation/devicetree/bindings/usb/renesas,usb3-peri.yaml | 7 ++++--- Documentation/devicetree/bindings/usb/ti,hd3ss3220.yaml | 8 ++++---- 2 files changed, 8 insertions(+), 7 deletions(-) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/usb/renesas,usb3-peri.yaml b/Documentation/devicetree/bindings/usb/renesas,usb3-peri.yaml index 929a3f413b44..9fcf54b10b07 100644 --- a/Documentation/devicetree/bindings/usb/renesas,usb3-peri.yaml +++ b/Documentation/devicetree/bindings/usb/renesas,usb3-peri.yaml @@ -54,18 +54,19 @@ properties: description: phandle of a companion. ports: + $ref: /schemas/graph.yaml#/properties/ports description: | any connector to the data bus of this controller should be modelled using the OF graph bindings specified, if the "usb-role-switch" property is used. - type: object + properties: port@0: - type: object + $ref: /schemas/graph.yaml#/properties/port description: High Speed (HS) data bus. port@1: - type: object + $ref: /schemas/graph.yaml#/properties/port description: Super Speed (SS) data bus. required: diff --git a/Documentation/devicetree/bindings/usb/ti,hd3ss3220.yaml b/Documentation/devicetree/bindings/usb/ti,hd3ss3220.yaml index 52ceb07294a3..b86bf6bc9cd6 100644 --- a/Documentation/devicetree/bindings/usb/ti,hd3ss3220.yaml +++ b/Documentation/devicetree/bindings/usb/ti,hd3ss3220.yaml @@ -26,17 +26,17 @@ properties: maxItems: 1 ports: + $ref: /schemas/graph.yaml#/properties/ports description: OF graph bindings (specified in bindings/graph.txt) that model SS data bus to the SS capable connector. - type: object + properties: port@0: - type: object + $ref: /schemas/graph.yaml#/properties/port description: Super Speed (SS) MUX inputs connected to SS capable connector. - $ref: /connector/usb-connector.yaml#/properties/ports/properties/port@1 port@1: - type: object + $ref: /schemas/graph.yaml#/properties/port description: Output of 2:1 MUX connected to Super Speed (SS) data bus. required: -- cgit v1.2.3 From 4b52be0ce6ad1be3c1fc380d2386252d5ee6218b Mon Sep 17 00:00:00 2001 From: Rob Herring Date: Tue, 12 Jan 2021 09:46:31 -0600 Subject: dt-bindings: Remove plain text OF graph binding A schema for the OF graph binding has been added to the dt-schema repo based on graph.txt contents. Let's replace graph.txt now duplicated contents with a reference to the schema. For users of the graph binding, they should reference to the graph schema from either 'ports' or 'port' property: properties: ports: $ref: /schemas/graph.yaml#/properties/ports properties: port@0: $ref: /schemas/graph.yaml#/properties/port description: What data this port has ... Or: properties: port: description: What data this port has $ref: /schemas/graph.yaml#/properties/port Acked-by: Philipp Zabel Reviewed-by: Sam Ravnborg Reviewed-by: Laurent Pinchart Acked-by: Sameer Pujar Link: https://lore.kernel.org/r/20210112154631.406250-1-robh@kernel.org Signed-off-by: Rob Herring --- Documentation/devicetree/bindings/graph.txt | 129 +--------------------------- 1 file changed, 1 insertion(+), 128 deletions(-) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/graph.txt b/Documentation/devicetree/bindings/graph.txt index 0415e2c53ba0..14733b5cb61e 100644 --- a/Documentation/devicetree/bindings/graph.txt +++ b/Documentation/devicetree/bindings/graph.txt @@ -1,128 +1 @@ -Common bindings for device graphs - -General concept ---------------- - -The hierarchical organisation of the device tree is well suited to describe -control flow to devices, but there can be more complex connections between -devices that work together to form a logical compound device, following an -arbitrarily complex graph. -There already is a simple directed graph between devices tree nodes using -phandle properties pointing to other nodes to describe connections that -can not be inferred from device tree parent-child relationships. The device -tree graph bindings described herein abstract more complex devices that can -have multiple specifiable ports, each of which can be linked to one or more -ports of other devices. - -These common bindings do not contain any information about the direction or -type of the connections, they just map their existence. Specific properties -may be described by specialized bindings depending on the type of connection. - -To see how this binding applies to video pipelines, for example, see -Documentation/devicetree/bindings/media/video-interfaces.txt. -Here the ports describe data interfaces, and the links between them are -the connecting data buses. A single port with multiple connections can -correspond to multiple devices being connected to the same physical bus. - -Organisation of ports and endpoints ------------------------------------ - -Ports are described by child 'port' nodes contained in the device node. -Each port node contains an 'endpoint' subnode for each remote device port -connected to this port. If a single port is connected to more than one -remote device, an 'endpoint' child node must be provided for each link. -If more than one port is present in a device node or there is more than one -endpoint at a port, or a port node needs to be associated with a selected -hardware interface, a common scheme using '#address-cells', '#size-cells' -and 'reg' properties is used to number the nodes. - -device { - ... - #address-cells = <1>; - #size-cells = <0>; - - port@0 { - #address-cells = <1>; - #size-cells = <0>; - reg = <0>; - - endpoint@0 { - reg = <0>; - ... - }; - endpoint@1 { - reg = <1>; - ... - }; - }; - - port@1 { - reg = <1>; - - endpoint { ... }; - }; -}; - -All 'port' nodes can be grouped under an optional 'ports' node, which -allows to specify #address-cells, #size-cells properties for the 'port' -nodes independently from any other child device nodes a device might -have. - -device { - ... - ports { - #address-cells = <1>; - #size-cells = <0>; - - port@0 { - ... - endpoint@0 { ... }; - endpoint@1 { ... }; - }; - - port@1 { ... }; - }; -}; - -Links between endpoints ------------------------ - -Each endpoint should contain a 'remote-endpoint' phandle property that points -to the corresponding endpoint in the port of the remote device. In turn, the -remote endpoint should contain a 'remote-endpoint' property. If it has one, it -must not point to anything other than the local endpoint. Two endpoints with -their 'remote-endpoint' phandles pointing at each other form a link between the -containing ports. - -device-1 { - port { - device_1_output: endpoint { - remote-endpoint = <&device_2_input>; - }; - }; -}; - -device-2 { - port { - device_2_input: endpoint { - remote-endpoint = <&device_1_output>; - }; - }; -}; - -Required properties -------------------- - -If there is more than one 'port' or more than one 'endpoint' node or 'reg' -property present in the port and/or endpoint nodes then the following -properties are required in a relevant parent node: - - - #address-cells : number of cells required to define port/endpoint - identifier, should be 1. - - #size-cells : should be zero. - -Optional endpoint properties ----------------------------- - -- remote-endpoint: phandle to an 'endpoint' subnode of a remote device node. - +This file has moved to graph.yaml in dt-schema repo -- cgit v1.2.3 From 51f9b1f8ee3a066f2f874cf64afea24ae762ff93 Mon Sep 17 00:00:00 2001 From: Claudiu Beznea Date: Thu, 7 Jan 2021 12:46:12 +0200 Subject: dt-bindings: rtc: at91rm9200: add sama7g5 compatible Add compatible for SAMA7G5 RTC. At the moment the driver is falling back on SAM9X60's compatible but SAMA7G5 doesn't have the tamper mode register and tamper debounce period register thus the need for a new compatible to differentiate b/w these two in case tamper feature will be implemented in future. Signed-off-by: Claudiu Beznea Acked-by: Nicolas Ferre Signed-off-by: Alexandre Belloni Link: https://lore.kernel.org/r/1610016372-31784-1-git-send-email-claudiu.beznea@microchip.com --- Documentation/devicetree/bindings/rtc/atmel,at91rm9200-rtc.yaml | 1 + 1 file changed, 1 insertion(+) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/rtc/atmel,at91rm9200-rtc.yaml b/Documentation/devicetree/bindings/rtc/atmel,at91rm9200-rtc.yaml index 02bbfe726c62..994de43d17fa 100644 --- a/Documentation/devicetree/bindings/rtc/atmel,at91rm9200-rtc.yaml +++ b/Documentation/devicetree/bindings/rtc/atmel,at91rm9200-rtc.yaml @@ -20,6 +20,7 @@ properties: - atmel,sama5d4-rtc - atmel,sama5d2-rtc - microchip,sam9x60-rtc + - microchip,sama7g5-rtc reg: maxItems: 1 -- cgit v1.2.3 From cd900f181ad6b548a8feded5dd224f789f09b1c6 Mon Sep 17 00:00:00 2001 From: Mike Looijmans Date: Thu, 7 Jan 2021 15:32:48 +0100 Subject: power/supply: Add ltc4162-l-charger Add support for the LTC4162-L Li-Ion battery charger. The driver allows reading back telemetry and to set some charging options like the input current limit. Signed-off-by: Mike Looijmans Signed-off-by: Sebastian Reichel --- .../ABI/testing/sysfs-class-power-ltc4162l | 82 ++ drivers/power/supply/Kconfig | 8 + drivers/power/supply/Makefile | 1 + drivers/power/supply/ltc4162-l-charger.c | 931 +++++++++++++++++++++ 4 files changed, 1022 insertions(+) create mode 100644 Documentation/ABI/testing/sysfs-class-power-ltc4162l create mode 100644 drivers/power/supply/ltc4162-l-charger.c (limited to 'Documentation') diff --git a/Documentation/ABI/testing/sysfs-class-power-ltc4162l b/Documentation/ABI/testing/sysfs-class-power-ltc4162l new file mode 100644 index 000000000000..ba30db93052b --- /dev/null +++ b/Documentation/ABI/testing/sysfs-class-power-ltc4162l @@ -0,0 +1,82 @@ +What: /sys/class/power_supply/ltc4162-l/charge_status +Date: Januari 2021 +KernelVersion: 5.11 +Description: + Detailed charge status information as reported by the chip. + + Access: Read + + Valid values: + ilim_reg_active + thermal_reg_active + vin_uvcl_active + iin_limit_active + constant_current + constant_voltage + charger_off + +What: /sys/class/power_supply/ltc4162-l/ibat +Date: Januari 2021 +KernelVersion: 5.11 +Description: + Battery input current as measured by the charger. Negative value + means that the battery is discharging. + + Access: Read + + Valid values: Signed value in microamps + +What: /sys/class/power_supply/ltc4162-l/vbat +Date: Januari 2021 +KernelVersion: 5.11 +Description: + Battery voltage as measured by the charger. + + Access: Read + + Valid values: In microvolts + +What: /sys/class/power_supply/ltc4162-l/vbat_avg +Date: Januari 2021 +KernelVersion: 5.11 +Description: + Battery voltage, averaged over time, as measured by the charger. + + Access: Read + + Valid values: In microvolts + +What: /sys/class/power_supply/ltc4162-l/force_telemetry +Date: Januari 2021 +KernelVersion: 5.11 +Description: + To save battery current, the measurement system is disabled if + the battery is the only source of power. This affects all + voltage, current and temperature measurements. + Write a "1" to this to keep performing telemetry once every few + seconds, even when running on battery (as reported by the online + property, which is "1" when external power is available and "0" + when the system runs on battery). + + Access: Read, Write + + Valid values: 0 (disabled) or 1 (enabled) + +What: /sys/class/power_supply/ltc4162-l/arm_ship_mode +Date: Januari 2021 +KernelVersion: 5.11 +Description: + The charger will normally drain the battery while inactive, + typically drawing about 54 microamps. Write a "1" to this + property to arm a special "ship" mode that extends shelf life + by reducing the leakage to about 2.8 microamps. The chip will + remain in this mode (and no longer respond to I2C commands) + until some external power-supply is attached raising the input + voltage above 1V. It will then automatically revert to "0". + Writing a "0" to the property cancels the "ship" mode request. + The ship mode, when armed, activates once the input voltage + drops below 1V. + + Access: Read, Write + + Valid values: 0 (disable) or 1 (enable) diff --git a/drivers/power/supply/Kconfig b/drivers/power/supply/Kconfig index ef1d69b019ee..c95ba6c8c111 100644 --- a/drivers/power/supply/Kconfig +++ b/drivers/power/supply/Kconfig @@ -513,6 +513,14 @@ config CHARGER_LT3651 Say Y to include support for the Analog Devices (Linear Technology) LT3651 battery charger which reports its status via GPIO lines. +config CHARGER_LTC4162L + tristate "LTC4162-L charger" + depends on I2C + select REGMAP_I2C + help + Say Y to include support for the Analog Devices (Linear Technology) + LTC4162-L battery charger connected to I2C. + config CHARGER_MAX14577 tristate "Maxim MAX14577/77836 battery charger driver" depends on MFD_MAX14577 diff --git a/drivers/power/supply/Makefile b/drivers/power/supply/Makefile index ae322b1da1ed..ae3d9c83c790 100644 --- a/drivers/power/supply/Makefile +++ b/drivers/power/supply/Makefile @@ -70,6 +70,7 @@ obj-$(CONFIG_CHARGER_LP8788) += lp8788-charger.o obj-$(CONFIG_CHARGER_GPIO) += gpio-charger.o obj-$(CONFIG_CHARGER_MANAGER) += charger-manager.o obj-$(CONFIG_CHARGER_LT3651) += lt3651-charger.o +obj-$(CONFIG_CHARGER_LTC4162L) += ltc4162-l-charger.o obj-$(CONFIG_CHARGER_MAX14577) += max14577_charger.o obj-$(CONFIG_CHARGER_DETECTOR_MAX14656) += max14656_charger_detector.o obj-$(CONFIG_CHARGER_MAX77650) += max77650-charger.o diff --git a/drivers/power/supply/ltc4162-l-charger.c b/drivers/power/supply/ltc4162-l-charger.c new file mode 100644 index 000000000000..cded6484febb --- /dev/null +++ b/drivers/power/supply/ltc4162-l-charger.c @@ -0,0 +1,931 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Driver for Analog Devices (Linear Technology) LTC4162-L charger IC. + * Copyright (C) 2020, Topic Embedded Products + */ + +#include +#include +#include +#include +#include +#include +#include + +/* Registers (names based on what datasheet uses) */ +#define LTC4162L_EN_LIMIT_ALERTS_REG 0x0D +#define LTC4162L_EN_CHARGER_STATE_ALERTS_REG 0x0E +#define LTC4162L_EN_CHARGE_STATUS_ALERTS_REG 0x0F +#define LTC4162L_CONFIG_BITS_REG 0x14 +#define LTC4162L_IIN_LIMIT_TARGET 0x15 +#define LTC4162L_ARM_SHIP_MODE 0x19 +#define LTC4162L_CHARGE_CURRENT_SETTING 0X1A +#define LTC4162L_VCHARGE_SETTING 0X1B +#define LTC4162L_C_OVER_X_THRESHOLD 0x1C +#define LTC4162L_MAX_CV_TIME 0X1D +#define LTC4162L_MAX_CHARGE_TIME 0X1E +#define LTC4162L_CHARGER_CONFIG_BITS 0x29 +#define LTC4162L_CHARGER_STATE 0x34 +#define LTC4162L_CHARGE_STATUS 0x35 +#define LTC4162L_LIMIT_ALERTS_REG 0x36 +#define LTC4162L_CHARGER_STATE_ALERTS_REG 0x37 +#define LTC4162L_CHARGE_STATUS_ALERTS_REG 0x38 +#define LTC4162L_SYSTEM_STATUS_REG 0x39 +#define LTC4162L_VBAT 0x3A +#define LTC4162L_VIN 0x3B +#define LTC4162L_VOUT 0x3C +#define LTC4162L_IBAT 0x3D +#define LTC4162L_IIN 0x3E +#define LTC4162L_DIE_TEMPERATURE 0x3F +#define LTC4162L_THERMISTOR_VOLTAGE 0x40 +#define LTC4162L_BSR 0x41 +#define LTC4162L_JEITA_REGION 0x42 +#define LTC4162L_CHEM_CELLS_REG 0x43 +#define LTC4162L_ICHARGE_DAC 0x44 +#define LTC4162L_VCHARGE_DAC 0x45 +#define LTC4162L_IIN_LIMIT_DAC 0x46 +#define LTC4162L_VBAT_FILT 0x47 +#define LTC4162L_INPUT_UNDERVOLTAGE_DAC 0x4B + +/* Enumeration as in datasheet. Individual bits are mutually exclusive. */ +enum ltc4162l_state { + battery_detection = 2048, + charger_suspended = 256, + precharge = 128, /* trickle on low bat voltage */ + cc_cv_charge = 64, /* normal charge */ + ntc_pause = 32, + timer_term = 16, + c_over_x_term = 8, /* battery is full */ + max_charge_time_fault = 4, + bat_missing_fault = 2, + bat_short_fault = 1 +}; + +/* Individual bits are mutually exclusive. Only active in charging states.*/ +enum ltc4162l_charge_status { + ilim_reg_active = 32, + thermal_reg_active = 16, + vin_uvcl_active = 8, + iin_limit_active = 4, + constant_current = 2, + constant_voltage = 1, + charger_off = 0 +}; + +/* Magic number to write to ARM_SHIP_MODE register */ +#define LTC4162L_ARM_SHIP_MODE_MAGIC 21325 + +struct ltc4162l_info { + struct i2c_client *client; + struct regmap *regmap; + struct power_supply *charger; + u32 rsnsb; /* Series resistor that sets charge current, microOhm */ + u32 rsnsi; /* Series resistor to measure input current, microOhm */ + u8 cell_count; /* Number of connected cells, 0 while unknown */ +}; + +static u8 ltc4162l_get_cell_count(struct ltc4162l_info *info) +{ + int ret; + unsigned int val; + + /* Once read successfully */ + if (info->cell_count) + return info->cell_count; + + ret = regmap_read(info->regmap, LTC4162L_CHEM_CELLS_REG, &val); + if (ret) + return 0; + + /* Lower 4 bits is the cell count, or 0 if the chip doesn't know yet */ + val &= 0x0f; + if (!val) + return 0; + + /* Once determined, keep the value */ + info->cell_count = val; + + return val; +}; + +/* Convert enum value to POWER_SUPPLY_STATUS value */ +static int ltc4162l_state_decode(enum ltc4162l_state value) +{ + switch (value) { + case precharge: + case cc_cv_charge: + return POWER_SUPPLY_STATUS_CHARGING; + case c_over_x_term: + return POWER_SUPPLY_STATUS_FULL; + case bat_missing_fault: + case bat_short_fault: + return POWER_SUPPLY_STATUS_UNKNOWN; + default: + return POWER_SUPPLY_STATUS_NOT_CHARGING; + } +}; + +static int ltc4162l_get_status(struct ltc4162l_info *info, + union power_supply_propval *val) +{ + unsigned int regval; + int ret; + + ret = regmap_read(info->regmap, LTC4162L_CHARGER_STATE, ®val); + if (ret) { + dev_err(&info->client->dev, "Failed to read CHARGER_STATE\n"); + return ret; + } + + val->intval = ltc4162l_state_decode(regval); + + return 0; +} + +static int ltc4162l_charge_status_decode(enum ltc4162l_charge_status value) +{ + if (!value) + return POWER_SUPPLY_CHARGE_TYPE_NONE; + + /* constant voltage/current and input_current limit are "fast" modes */ + if (value <= iin_limit_active) + return POWER_SUPPLY_CHARGE_TYPE_FAST; + + /* Anything that's not fast we'll return as trickle */ + return POWER_SUPPLY_CHARGE_TYPE_TRICKLE; +} + +static int ltc4162l_get_charge_type(struct ltc4162l_info *info, + union power_supply_propval *val) +{ + unsigned int regval; + int ret; + + ret = regmap_read(info->regmap, LTC4162L_CHARGE_STATUS, ®val); + if (ret) + return ret; + + val->intval = ltc4162l_charge_status_decode(regval); + + return 0; +} + +static int ltc4162l_state_to_health(enum ltc4162l_state value) +{ + switch (value) { + case ntc_pause: + return POWER_SUPPLY_HEALTH_OVERHEAT; + case timer_term: + return POWER_SUPPLY_HEALTH_SAFETY_TIMER_EXPIRE; + case max_charge_time_fault: + return POWER_SUPPLY_HEALTH_WATCHDOG_TIMER_EXPIRE; + case bat_missing_fault: + return POWER_SUPPLY_HEALTH_UNSPEC_FAILURE; + case bat_short_fault: + return POWER_SUPPLY_HEALTH_DEAD; + default: + return POWER_SUPPLY_HEALTH_GOOD; + } +} + +static int ltc4162l_get_health(struct ltc4162l_info *info, + union power_supply_propval *val) +{ + unsigned int regval; + int ret; + + ret = regmap_read(info->regmap, LTC4162L_CHARGER_STATE, ®val); + if (ret) + return ret; + + val->intval = ltc4162l_state_to_health(regval); + + return 0; +} + +static int ltc4162l_get_online(struct ltc4162l_info *info, + union power_supply_propval *val) +{ + unsigned int regval; + int ret; + + ret = regmap_read(info->regmap, LTC4162L_SYSTEM_STATUS_REG, ®val); + if (ret) + return ret; + + /* BIT(2) indicates if input voltage is sufficient to charge */ + val->intval = !!(regval & BIT(2)); + + return 0; +} + +static int ltc4162l_get_vbat(struct ltc4162l_info *info, + unsigned int reg, + union power_supply_propval *val) +{ + unsigned int regval; + int ret; + + ret = regmap_read(info->regmap, reg, ®val); + if (ret) + return ret; + + /* cell_count × 192.4μV/LSB */ + regval *= 1924; + regval *= ltc4162l_get_cell_count(info); + regval /= 10; + val->intval = regval; + + return 0; +} + +static int ltc4162l_get_ibat(struct ltc4162l_info *info, + union power_supply_propval *val) +{ + unsigned int regval; + int ret; + + ret = regmap_read(info->regmap, LTC4162L_IBAT, ®val); + if (ret) + return ret; + + /* Signed 16-bit number, 1.466μV / RSNSB amperes/LSB. */ + ret = (s16)(regval & 0xFFFF); + val->intval = 100 * mult_frac(ret, 14660, (int)info->rsnsb); + + return 0; +} + + +static int ltc4162l_get_input_voltage(struct ltc4162l_info *info, + union power_supply_propval *val) +{ + unsigned int regval; + int ret; + + ret = regmap_read(info->regmap, LTC4162L_VIN, ®val); + if (ret) + return ret; + + /* 1.649mV/LSB */ + val->intval = regval * 1694; + + return 0; +} + +static int ltc4162l_get_input_current(struct ltc4162l_info *info, + union power_supply_propval *val) +{ + unsigned int regval; + int ret; + + ret = regmap_read(info->regmap, LTC4162L_IIN, ®val); + if (ret) + return ret; + + /* Signed 16-bit number, 1.466μV / RSNSI amperes/LSB. */ + ret = (s16)(regval & 0xFFFF); + ret *= 14660; + ret /= info->rsnsi; + ret *= 100; + + val->intval = ret; + + return 0; +} + +static int ltc4162l_get_icharge(struct ltc4162l_info *info, + unsigned int reg, + union power_supply_propval *val) +{ + unsigned int regval; + int ret; + + ret = regmap_read(info->regmap, reg, ®val); + if (ret) + return ret; + + regval &= BIT(6) - 1; /* Only the lower 5 bits */ + + /* The charge current servo level: (icharge_dac + 1) × 1mV/RSNSB */ + ++regval; + val->intval = 10000u * mult_frac(regval, 100000u, info->rsnsb); + + return 0; +} + +static int ltc4162l_set_icharge(struct ltc4162l_info *info, + unsigned int reg, + unsigned int value) +{ + value = mult_frac(value, info->rsnsb, 100000u); + value /= 10000u; + + /* Round to lowest possible */ + if (value) + --value; + + if (value > 31) + return -EINVAL; + + return regmap_write(info->regmap, reg, value); +} + + +static int ltc4162l_get_vcharge(struct ltc4162l_info *info, + unsigned int reg, + union power_supply_propval *val) +{ + unsigned int regval; + int ret; + u32 voltage; + + ret = regmap_read(info->regmap, reg, ®val); + if (ret) + return ret; + + regval &= BIT(6) - 1; /* Only the lower 5 bits */ + + /* + * charge voltage setting can be computed from + * cell_count × (vcharge_setting × 12.5mV + 3.8125V) + * where vcharge_setting ranges from 0 to 31 (4.2V max). + */ + voltage = 3812500 + (regval * 12500); + voltage *= ltc4162l_get_cell_count(info); + val->intval = voltage; + + return 0; +} + +static int ltc4162l_set_vcharge(struct ltc4162l_info *info, + unsigned int reg, + unsigned int value) +{ + u8 cell_count = ltc4162l_get_cell_count(info); + + if (!cell_count) + return -EBUSY; /* Not available yet, try again later */ + + value /= cell_count; + + if (value < 3812500) + return -EINVAL; + + value -= 3812500; + value /= 12500; + + if (value > 31) + return -EINVAL; + + return regmap_write(info->regmap, reg, value); +} + +static int ltc4162l_get_iin_limit_dac(struct ltc4162l_info *info, + union power_supply_propval *val) +{ + unsigned int regval; + int ret; + + ret = regmap_read(info->regmap, LTC4162L_IIN_LIMIT_DAC, ®val); + if (ret) + return ret; + + regval &= BIT(6) - 1; /* Only 6 bits */ + + /* (iin_limit_dac + 1) × 500μV / RSNSI */ + ++regval; + regval *= 5000000u; + regval /= info->rsnsi; + val->intval = 100u * regval; + + return 0; +} + +static int ltc4162l_set_iin_limit(struct ltc4162l_info *info, + unsigned int value) +{ + unsigned int regval; + + regval = mult_frac(value, info->rsnsi, 50000u); + regval /= 10000u; + if (regval) + --regval; + if (regval > 63) + regval = 63; + + return regmap_write(info->regmap, LTC4162L_IIN_LIMIT_TARGET, regval); +} + +static int ltc4162l_get_die_temp(struct ltc4162l_info *info, + union power_supply_propval *val) +{ + unsigned int regval; + int ret; + + ret = regmap_read(info->regmap, LTC4162L_DIE_TEMPERATURE, ®val); + if (ret) + return ret; + + /* die_temp × 0.0215°C/LSB - 264.4°C */ + ret = (s16)(regval & 0xFFFF); + ret *= 215; + ret /= 100; /* Centidegrees scale */ + ret -= 26440; + val->intval = ret; + + return 0; +} + +static int ltc4162l_get_term_current(struct ltc4162l_info *info, + union power_supply_propval *val) +{ + unsigned int regval; + int ret; + + ret = regmap_read(info->regmap, LTC4162L_CHARGER_CONFIG_BITS, ®val); + if (ret) + return ret; + + /* Check if C_OVER_X_THRESHOLD is enabled */ + if (!(regval & BIT(2))) { + val->intval = 0; + return 0; + } + + ret = regmap_read(info->regmap, LTC4162L_C_OVER_X_THRESHOLD, ®val); + if (ret) + return ret; + + /* 1.466μV / RSNSB amperes/LSB */ + regval *= 14660u; + regval /= info->rsnsb; + val->intval = 100 * regval; + + return 0; +} + +static int ltc4162l_set_term_current(struct ltc4162l_info *info, + unsigned int value) +{ + int ret; + unsigned int regval; + + if (!value) { + /* Disable en_c_over_x_term when set to zero */ + return regmap_update_bits(info->regmap, + LTC4162L_CHARGER_CONFIG_BITS, + BIT(2), 0); + } + + regval = mult_frac(value, info->rsnsb, 14660u); + regval /= 100u; + + ret = regmap_write(info->regmap, LTC4162L_C_OVER_X_THRESHOLD, regval); + if (ret) + return ret; + + /* Set en_c_over_x_term after changing the threshold value */ + return regmap_update_bits(info->regmap, LTC4162L_CHARGER_CONFIG_BITS, + BIT(2), BIT(2)); +} + +/* Custom properties */ +static const char * const ltc4162l_charge_status_name[] = { + "ilim_reg_active", /* 32 */ + "thermal_reg_active", + "vin_uvcl_active", + "iin_limit_active", + "constant_current", + "constant_voltage", + "charger_off" /* 0 */ +}; + +static ssize_t charge_status_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct power_supply *psy = to_power_supply(dev); + struct ltc4162l_info *info = power_supply_get_drvdata(psy); + const char *result = ltc4162l_charge_status_name[ + ARRAY_SIZE(ltc4162l_charge_status_name) - 1]; + unsigned int regval; + unsigned int mask; + unsigned int index; + int ret; + + ret = regmap_read(info->regmap, LTC4162L_CHARGE_STATUS, ®val); + if (ret) + return ret; + + /* Only one bit is set according to datasheet, let's be safe here */ + for (mask = 32, index = 0; mask != 0; mask >>= 1, ++index) { + if (regval & mask) { + result = ltc4162l_charge_status_name[index]; + break; + } + } + + return sprintf(buf, "%s\n", result); +} +static DEVICE_ATTR_RO(charge_status); + +static ssize_t vbat_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct power_supply *psy = to_power_supply(dev); + struct ltc4162l_info *info = power_supply_get_drvdata(psy); + union power_supply_propval val; + int ret; + + ret = ltc4162l_get_vbat(info, LTC4162L_VBAT, &val); + if (ret) + return ret; + + return sprintf(buf, "%d\n", val.intval); +} +static DEVICE_ATTR_RO(vbat); + +static ssize_t vbat_avg_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct power_supply *psy = to_power_supply(dev); + struct ltc4162l_info *info = power_supply_get_drvdata(psy); + union power_supply_propval val; + int ret; + + ret = ltc4162l_get_vbat(info, LTC4162L_VBAT_FILT, &val); + if (ret) + return ret; + + return sprintf(buf, "%d\n", val.intval); +} +static DEVICE_ATTR_RO(vbat_avg); + +static ssize_t ibat_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct power_supply *psy = to_power_supply(dev); + struct ltc4162l_info *info = power_supply_get_drvdata(psy); + union power_supply_propval val; + int ret; + + ret = ltc4162l_get_ibat(info, &val); + if (ret) + return ret; + + return sprintf(buf, "%d\n", val.intval); +} +static DEVICE_ATTR_RO(ibat); + +static ssize_t force_telemetry_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct power_supply *psy = to_power_supply(dev); + struct ltc4162l_info *info = power_supply_get_drvdata(psy); + unsigned int regval; + int ret; + + ret = regmap_read(info->regmap, LTC4162L_CONFIG_BITS_REG, ®val); + if (ret) + return ret; + + return sprintf(buf, "%u\n", regval & BIT(2) ? 1 : 0); +} + +static ssize_t force_telemetry_store(struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t count) +{ + struct power_supply *psy = to_power_supply(dev); + struct ltc4162l_info *info = power_supply_get_drvdata(psy); + int ret; + unsigned int value; + + ret = kstrtouint(buf, 0, &value); + if (ret < 0) + return ret; + + ret = regmap_update_bits(info->regmap, LTC4162L_CONFIG_BITS_REG, + BIT(2), value ? BIT(2) : 0); + if (ret < 0) + return ret; + + return count; +} + +static DEVICE_ATTR_RW(force_telemetry); + +static ssize_t arm_ship_mode_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct power_supply *psy = to_power_supply(dev); + struct ltc4162l_info *info = power_supply_get_drvdata(psy); + unsigned int regval; + int ret; + + ret = regmap_read(info->regmap, LTC4162L_ARM_SHIP_MODE, ®val); + if (ret) + return ret; + + return sprintf(buf, "%u\n", + regval == LTC4162L_ARM_SHIP_MODE_MAGIC ? 1 : 0); +} + +static ssize_t arm_ship_mode_store(struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t count) +{ + struct power_supply *psy = to_power_supply(dev); + struct ltc4162l_info *info = power_supply_get_drvdata(psy); + int ret; + unsigned int value; + + ret = kstrtouint(buf, 0, &value); + if (ret < 0) + return ret; + + ret = regmap_write(info->regmap, LTC4162L_ARM_SHIP_MODE, + value ? LTC4162L_ARM_SHIP_MODE_MAGIC : 0); + if (ret < 0) + return ret; + + return count; +} + +static DEVICE_ATTR_RW(arm_ship_mode); + +static struct attribute *ltc4162l_sysfs_entries[] = { + &dev_attr_charge_status.attr, + &dev_attr_ibat.attr, + &dev_attr_vbat.attr, + &dev_attr_vbat_avg.attr, + &dev_attr_force_telemetry.attr, + &dev_attr_arm_ship_mode.attr, + NULL, +}; + +static struct attribute_group ltc4162l_attr_group = { + .name = NULL, /* put in device directory */ + .attrs = ltc4162l_sysfs_entries, +}; + +static const struct attribute_group *ltc4162l_attr_groups[] = { + <c4162l_attr_group, + NULL, +}; + +static int ltc4162l_get_property(struct power_supply *psy, + enum power_supply_property psp, + union power_supply_propval *val) +{ + struct ltc4162l_info *info = power_supply_get_drvdata(psy); + + switch (psp) { + case POWER_SUPPLY_PROP_STATUS: + return ltc4162l_get_status(info, val); + case POWER_SUPPLY_PROP_CHARGE_TYPE: + return ltc4162l_get_charge_type(info, val); + case POWER_SUPPLY_PROP_HEALTH: + return ltc4162l_get_health(info, val); + case POWER_SUPPLY_PROP_ONLINE: + return ltc4162l_get_online(info, val); + case POWER_SUPPLY_PROP_VOLTAGE_NOW: + return ltc4162l_get_input_voltage(info, val); + case POWER_SUPPLY_PROP_CURRENT_NOW: + return ltc4162l_get_input_current(info, val); + case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT: + return ltc4162l_get_icharge(info, + LTC4162L_ICHARGE_DAC, val); + case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX: + return ltc4162l_get_icharge(info, + LTC4162L_CHARGE_CURRENT_SETTING, val); + case POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE: + return ltc4162l_get_vcharge(info, + LTC4162L_VCHARGE_DAC, val); + case POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE_MAX: + return ltc4162l_get_vcharge(info, + LTC4162L_VCHARGE_SETTING, val); + case POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT: + return ltc4162l_get_iin_limit_dac(info, val); + case POWER_SUPPLY_PROP_TEMP: + return ltc4162l_get_die_temp(info, val); + case POWER_SUPPLY_PROP_CHARGE_TERM_CURRENT: + return ltc4162l_get_term_current(info, val); + default: + return -EINVAL; + } +} + +static int ltc4162l_set_property(struct power_supply *psy, + enum power_supply_property psp, + const union power_supply_propval *val) +{ + struct ltc4162l_info *info = power_supply_get_drvdata(psy); + + switch (psp) { + case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX: + return ltc4162l_set_icharge(info, + LTC4162L_CHARGE_CURRENT_SETTING, val->intval); + case POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE_MAX: + return ltc4162l_set_vcharge(info, + LTC4162L_VCHARGE_SETTING, val->intval); + case POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT: + return ltc4162l_set_iin_limit(info, val->intval); + case POWER_SUPPLY_PROP_CHARGE_TERM_CURRENT: + return ltc4162l_set_term_current(info, val->intval); + default: + return -EINVAL; + } +} + +static int ltc4162l_property_is_writeable(struct power_supply *psy, + enum power_supply_property psp) +{ + switch (psp) { + case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX: + case POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE_MAX: + case POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT: + case POWER_SUPPLY_PROP_CHARGE_TERM_CURRENT: + return 1; + default: + return 0; + } +} + +/* Charger power supply property routines */ +static enum power_supply_property ltc4162l_properties[] = { + POWER_SUPPLY_PROP_STATUS, + POWER_SUPPLY_PROP_CHARGE_TYPE, + POWER_SUPPLY_PROP_HEALTH, + POWER_SUPPLY_PROP_ONLINE, + POWER_SUPPLY_PROP_VOLTAGE_NOW, + POWER_SUPPLY_PROP_CURRENT_NOW, + POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT, + POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX, + POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE, + POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE_MAX, + POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT, + POWER_SUPPLY_PROP_TEMP, + POWER_SUPPLY_PROP_CHARGE_TERM_CURRENT, +}; + +static const struct power_supply_desc ltc4162l_desc = { + .name = "ltc4162-l", + .type = POWER_SUPPLY_TYPE_MAINS, + .properties = ltc4162l_properties, + .num_properties = ARRAY_SIZE(ltc4162l_properties), + .get_property = ltc4162l_get_property, + .set_property = ltc4162l_set_property, + .property_is_writeable = ltc4162l_property_is_writeable, +}; + +static bool ltc4162l_is_writeable_reg(struct device *dev, unsigned int reg) +{ + /* all registers up to this one are writeable */ + if (reg <= LTC4162L_CHARGER_CONFIG_BITS) + return true; + + /* The ALERTS registers can be written to clear alerts */ + if (reg >= LTC4162L_LIMIT_ALERTS_REG && + reg <= LTC4162L_CHARGE_STATUS_ALERTS_REG) + return true; + + return false; +} + +static bool ltc4162l_is_volatile_reg(struct device *dev, unsigned int reg) +{ + /* all registers after this one are read-only status registers */ + return reg > LTC4162L_CHARGER_CONFIG_BITS; +} + +static const struct regmap_config ltc4162l_regmap_config = { + .reg_bits = 8, + .val_bits = 16, + .val_format_endian = REGMAP_ENDIAN_LITTLE, + .writeable_reg = ltc4162l_is_writeable_reg, + .volatile_reg = ltc4162l_is_volatile_reg, + .max_register = LTC4162L_INPUT_UNDERVOLTAGE_DAC, + .cache_type = REGCACHE_RBTREE, +}; + +static void ltc4162l_clear_interrupts(struct ltc4162l_info *info) +{ + /* Acknowledge interrupt to chip by clearing all events */ + regmap_write(info->regmap, LTC4162L_LIMIT_ALERTS_REG, 0); + regmap_write(info->regmap, LTC4162L_CHARGER_STATE_ALERTS_REG, 0); + regmap_write(info->regmap, LTC4162L_CHARGE_STATUS_ALERTS_REG, 0); +} + +static int ltc4162l_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + struct i2c_adapter *adapter = client->adapter; + struct device *dev = &client->dev; + struct ltc4162l_info *info; + struct power_supply_config ltc4162l_config = {}; + u32 value; + int ret; + + if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_WORD_DATA)) { + dev_err(dev, "No support for SMBUS_WORD_DATA\n"); + return -ENODEV; + } + info = devm_kzalloc(dev, sizeof(*info), GFP_KERNEL); + if (!info) + return -ENOMEM; + + info->client = client; + i2c_set_clientdata(client, info); + + info->regmap = devm_regmap_init_i2c(client, <c4162l_regmap_config); + if (IS_ERR(info->regmap)) { + dev_err(dev, "Failed to initialize register map\n"); + return PTR_ERR(info->regmap); + } + + ret = device_property_read_u32(dev, "lltc,rsnsb-micro-ohms", + &info->rsnsb); + if (ret) { + dev_err(dev, "Missing lltc,rsnsb-micro-ohms property\n"); + return ret; + } + if (!info->rsnsb) + return -EINVAL; + + ret = device_property_read_u32(dev, "lltc,rsnsi-micro-ohms", + &info->rsnsi); + if (ret) { + dev_err(dev, "Missing lltc,rsnsi-micro-ohms property\n"); + return ret; + } + if (!info->rsnsi) + return -EINVAL; + + if (!device_property_read_u32(dev, "lltc,cell-count", &value)) + info->cell_count = value; + + ltc4162l_config.of_node = dev->of_node; + ltc4162l_config.drv_data = info; + ltc4162l_config.attr_grp = ltc4162l_attr_groups; + + info->charger = devm_power_supply_register(dev, <c4162l_desc, + <c4162l_config); + if (IS_ERR(info->charger)) { + dev_err(dev, "Failed to register charger\n"); + return PTR_ERR(info->charger); + } + + /* Disable the threshold alerts, we're not using them */ + regmap_write(info->regmap, LTC4162L_EN_LIMIT_ALERTS_REG, 0); + + /* Enable interrupts on all status changes */ + regmap_write(info->regmap, LTC4162L_EN_CHARGER_STATE_ALERTS_REG, + 0x1fff); + regmap_write(info->regmap, LTC4162L_EN_CHARGE_STATUS_ALERTS_REG, 0x1f); + + ltc4162l_clear_interrupts(info); + + return 0; +} + +static void ltc4162l_alert(struct i2c_client *client, + enum i2c_alert_protocol type, unsigned int flag) +{ + struct ltc4162l_info *info = i2c_get_clientdata(client); + + if (type != I2C_PROTOCOL_SMBUS_ALERT) + return; + + ltc4162l_clear_interrupts(info); + power_supply_changed(info->charger); +} + +static const struct i2c_device_id ltc4162l_i2c_id_table[] = { + { "ltc4162-l", 0 }, + { }, +}; +MODULE_DEVICE_TABLE(i2c, ltc4162l_i2c_id_table); + +static const struct of_device_id ltc4162l_of_match[] = { + { .compatible = "lltc,ltc4162-l", }, + { }, +}; +MODULE_DEVICE_TABLE(of, ltc4162l_of_match); + +static struct i2c_driver ltc4162l_driver = { + .probe = ltc4162l_probe, + .alert = ltc4162l_alert, + .id_table = ltc4162l_i2c_id_table, + .driver = { + .name = "ltc4162-l-charger", + .of_match_table = of_match_ptr(ltc4162l_of_match), + }, +}; +module_i2c_driver(ltc4162l_driver); + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Mike Looijmans "); +MODULE_DESCRIPTION("LTC4162-L charger driver"); -- cgit v1.2.3 From 82853543057f78d8a331272b70bc3f1e8cb0cbf4 Mon Sep 17 00:00:00 2001 From: Rafał Miłecki Date: Mon, 14 Dec 2020 19:07:42 +0100 Subject: dt-bindings: power: document Broadcom's PMB binding MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Broadcom's PMB is power controller used for disabling and enabling SoC devices. Signed-off-by: Rafał Miłecki Reviewed-by: Rob Herring Acked-by: Florian Fainelli Acked-by: Ulf Hansson Signed-off-by: Florian Fainelli --- .../devicetree/bindings/power/brcm,bcm-pmb.yaml | 50 ++++++++++++++++++++++ include/dt-bindings/soc/bcm-pmb.h | 11 +++++ 2 files changed, 61 insertions(+) create mode 100644 Documentation/devicetree/bindings/power/brcm,bcm-pmb.yaml create mode 100644 include/dt-bindings/soc/bcm-pmb.h (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/power/brcm,bcm-pmb.yaml b/Documentation/devicetree/bindings/power/brcm,bcm-pmb.yaml new file mode 100644 index 000000000000..40b08d83c80b --- /dev/null +++ b/Documentation/devicetree/bindings/power/brcm,bcm-pmb.yaml @@ -0,0 +1,50 @@ +# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/power/brcm,bcm-pmb.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Broadcom PMB (Power Management Bus) controller + +description: This document describes Broadcom's PMB controller. It supports + powering various types of connected devices (e.g. PCIe, USB, SATA). + +maintainers: + - Rafał Miłecki + +properties: + compatible: + enum: + - brcm,bcm4908-pmb + + reg: + description: register space of one or more buses + maxItems: 1 + + big-endian: + $ref: /schemas/types.yaml#/definitions/flag + description: Flag to use for block working in big endian mode. + + "#power-domain-cells": + description: cell specifies device ID (see bcm-pmb.h) + const: 1 + +required: + - reg + - "#power-domain-cells" + +additionalProperties: false + +examples: + - | + #include + + pmb: power-controller@802800e0 { + compatible = "brcm,bcm4908-pmb"; + reg = <0x802800e0 0x40>; + #power-domain-cells = <1>; + }; + + foo { + power-domains = <&pmb BCM_PMB_PCIE0>; + }; diff --git a/include/dt-bindings/soc/bcm-pmb.h b/include/dt-bindings/soc/bcm-pmb.h new file mode 100644 index 000000000000..744dc3af4d41 --- /dev/null +++ b/include/dt-bindings/soc/bcm-pmb.h @@ -0,0 +1,11 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later OR MIT */ + +#ifndef __DT_BINDINGS_SOC_BCM_PMB_H +#define __DT_BINDINGS_SOC_BCM_PMB_H + +#define BCM_PMB_PCIE0 0x01 +#define BCM_PMB_PCIE1 0x02 +#define BCM_PMB_PCIE2 0x03 +#define BCM_PMB_HOST_USB 0x04 + +#endif -- cgit v1.2.3 From 6f6b3ed55aef08b296cb1a2add01c61e8dd677c7 Mon Sep 17 00:00:00 2001 From: Aleksander Jan Bajkowski Date: Thu, 31 Dec 2020 17:31:53 +0100 Subject: dt-bindings: mips: lantiq: Document Lantiq Xway PMU bindings Document the Lantiq Xway SoC series Power Management Unit (PMU) bindings. Signed-off-by: Aleksander Jan Bajkowski Reviewed-by: Rob Herring Signed-off-by: Thomas Bogendoerfer --- .../bindings/mips/lantiq/lantiq,pmu.yaml | 32 ++++++++++++++++++++++ 1 file changed, 32 insertions(+) create mode 100644 Documentation/devicetree/bindings/mips/lantiq/lantiq,pmu.yaml (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/mips/lantiq/lantiq,pmu.yaml b/Documentation/devicetree/bindings/mips/lantiq/lantiq,pmu.yaml new file mode 100644 index 000000000000..4982b458ac12 --- /dev/null +++ b/Documentation/devicetree/bindings/mips/lantiq/lantiq,pmu.yaml @@ -0,0 +1,32 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/mips/lantiq/lantiq,pmu.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Lantiq Xway SoC series Power Management Unit (PMU) + +maintainers: + - John Crispin + +properties: + compatible: + items: + - enum: + - lantiq,pmu-xway + + reg: + maxItems: 1 + +required: + - compatible + - reg + +additionalProperties: false + +examples: + - | + pmu@102000 { + compatible = "lantiq,pmu-xway"; + reg = <0x102000 0x1000>; + }; -- cgit v1.2.3 From b212b45da3bd0662e92cae107ad83bdfb8b1a1dd Mon Sep 17 00:00:00 2001 From: Aleksander Jan Bajkowski Date: Fri, 1 Jan 2021 19:01:18 +0100 Subject: dt-bindings: mips: lantiq: Document Lantiq Xway CGU bindings Document the Lantiq Xway SoC series Clock Generation Unit (CGU) bindings. Signed-off-by: Aleksander Jan Bajkowski Reviewed-by: Rob Herring Signed-off-by: Thomas Bogendoerfer --- .../bindings/mips/lantiq/lantiq,cgu.yaml | 32 ++++++++++++++++++++++ 1 file changed, 32 insertions(+) create mode 100644 Documentation/devicetree/bindings/mips/lantiq/lantiq,cgu.yaml (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/mips/lantiq/lantiq,cgu.yaml b/Documentation/devicetree/bindings/mips/lantiq/lantiq,cgu.yaml new file mode 100644 index 000000000000..d5805725befb --- /dev/null +++ b/Documentation/devicetree/bindings/mips/lantiq/lantiq,cgu.yaml @@ -0,0 +1,32 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/mips/lantiq/lantiq,cgu.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Lantiq Xway SoC series Clock Generation Unit (CGU) + +maintainers: + - John Crispin + +properties: + compatible: + items: + - enum: + - lantiq,cgu-xway + + reg: + maxItems: 1 + +required: + - compatible + - reg + +additionalProperties: false + +examples: + - | + cgu@103000 { + compatible = "lantiq,cgu-xway"; + reg = <0x103000 0x1000>; + }; -- cgit v1.2.3 From dea44af8d2ae89b8c1e95f7abf1cfb4132a2bc4e Mon Sep 17 00:00:00 2001 From: Aleksander Jan Bajkowski Date: Fri, 1 Jan 2021 22:37:59 +0100 Subject: dt-bindings: mips: lantiq: Document Lantiq Xway EBU bindings Document the Lantiq Xway SoC series External Bus Unit (EBU) bindings. Signed-off-by: Aleksander Jan Bajkowski Reviewed-by: Rob Herring Signed-off-by: Thomas Bogendoerfer --- .../bindings/mips/lantiq/lantiq,ebu.yaml | 32 ++++++++++++++++++++++ 1 file changed, 32 insertions(+) create mode 100644 Documentation/devicetree/bindings/mips/lantiq/lantiq,ebu.yaml (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/mips/lantiq/lantiq,ebu.yaml b/Documentation/devicetree/bindings/mips/lantiq/lantiq,ebu.yaml new file mode 100644 index 000000000000..0fada1f085a9 --- /dev/null +++ b/Documentation/devicetree/bindings/mips/lantiq/lantiq,ebu.yaml @@ -0,0 +1,32 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/mips/lantiq/lantiq,ebu.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Lantiq Xway SoC series External Bus Unit (EBU) + +maintainers: + - John Crispin + +properties: + compatible: + items: + - enum: + - lantiq,ebu-xway + + reg: + maxItems: 1 + +required: + - compatible + - reg + +additionalProperties: false + +examples: + - | + ebu@105300 { + compatible = "lantiq,ebu-xway"; + reg = <0x105300 0x100>; + }; -- cgit v1.2.3 From 6b5ea5b7a7fa35582b1a28bd8853427fb03e1e29 Mon Sep 17 00:00:00 2001 From: Aleksander Jan Bajkowski Date: Sun, 3 Jan 2021 11:18:03 +0100 Subject: dt-bindings: mips: lantiq: Document Lantiq Xway DMA bindings Document the Lantiq Xway SoC DMA Controller DT bindings. Signed-off-by: Aleksander Jan Bajkowski Reviewed-by: Rob Herring Signed-off-by: Thomas Bogendoerfer --- .../bindings/mips/lantiq/lantiq,dma-xway.yaml | 32 ++++++++++++++++++++++ 1 file changed, 32 insertions(+) create mode 100644 Documentation/devicetree/bindings/mips/lantiq/lantiq,dma-xway.yaml (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/mips/lantiq/lantiq,dma-xway.yaml b/Documentation/devicetree/bindings/mips/lantiq/lantiq,dma-xway.yaml new file mode 100644 index 000000000000..40130fefa2b4 --- /dev/null +++ b/Documentation/devicetree/bindings/mips/lantiq/lantiq,dma-xway.yaml @@ -0,0 +1,32 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/mips/lantiq/lantiq,dma-xway.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Lantiq Xway SoCs DMA Controller DT bindings + +maintainers: + - John Crispin + +properties: + compatible: + items: + - enum: + - lantiq,dma-xway + + reg: + maxItems: 1 + +required: + - compatible + - reg + +additionalProperties: false + +examples: + - | + dma@e104100 { + compatible = "lantiq,dma-xway"; + reg = <0xe104100 0x800>; + }; -- cgit v1.2.3 From eb4aadc31ef4224b926d5165048cb297f4bda34f Mon Sep 17 00:00:00 2001 From: Ramuthevar Vadivel Murugan Date: Tue, 24 Nov 2020 12:18:39 +0800 Subject: spi: Move cadence-quadspi.txt to Documentation/devicetree/bindings/spi Move the Documentation/devicetree/bindings/mtd/cadence-quadspi.txt to Documentation/devicetree/bindings/spi/ Signed-off-by: Ramuthevar Vadivel Murugan Acked-by: Rob Herring Link: https://lore.kernel.org/r/20201124041840.31066-5-vadivel.muruganx.ramuthevar@linux.intel.com Signed-off-by: Mark Brown --- .../devicetree/bindings/mtd/cadence-quadspi.txt | 67 ---------------------- .../devicetree/bindings/spi/cadence-quadspi.txt | 67 ++++++++++++++++++++++ 2 files changed, 67 insertions(+), 67 deletions(-) delete mode 100644 Documentation/devicetree/bindings/mtd/cadence-quadspi.txt create mode 100644 Documentation/devicetree/bindings/spi/cadence-quadspi.txt (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/mtd/cadence-quadspi.txt b/Documentation/devicetree/bindings/mtd/cadence-quadspi.txt deleted file mode 100644 index 945be7d5b236..000000000000 --- a/Documentation/devicetree/bindings/mtd/cadence-quadspi.txt +++ /dev/null @@ -1,67 +0,0 @@ -* Cadence Quad SPI controller - -Required properties: -- compatible : should be one of the following: - Generic default - "cdns,qspi-nor". - For TI 66AK2G SoC - "ti,k2g-qspi", "cdns,qspi-nor". - For TI AM654 SoC - "ti,am654-ospi", "cdns,qspi-nor". -- reg : Contains two entries, each of which is a tuple consisting of a - physical address and length. The first entry is the address and - length of the controller register set. The second entry is the - address and length of the QSPI Controller data area. -- interrupts : Unit interrupt specifier for the controller interrupt. -- clocks : phandle to the Quad SPI clock. -- cdns,fifo-depth : Size of the data FIFO in words. -- cdns,fifo-width : Bus width of the data FIFO in bytes. -- cdns,trigger-address : 32-bit indirect AHB trigger address. - -Optional properties: -- cdns,is-decoded-cs : Flag to indicate whether decoder is used or not. -- cdns,rclk-en : Flag to indicate that QSPI return clock is used to latch - the read data rather than the QSPI clock. Make sure that QSPI return - clock is populated on the board before using this property. - -Optional subnodes: -Subnodes of the Cadence Quad SPI controller are spi slave nodes with additional -custom properties: -- cdns,read-delay : Delay for read capture logic, in clock cycles -- cdns,tshsl-ns : Delay in nanoseconds for the length that the master - mode chip select outputs are de-asserted between - transactions. -- cdns,tsd2d-ns : Delay in nanoseconds between one chip select being - de-activated and the activation of another. -- cdns,tchsh-ns : Delay in nanoseconds between last bit of current - transaction and deasserting the device chip select - (qspi_n_ss_out). -- cdns,tslch-ns : Delay in nanoseconds between setting qspi_n_ss_out low - and first bit transfer. -- resets : Must contain an entry for each entry in reset-names. - See ../reset/reset.txt for details. -- reset-names : Must include either "qspi" and/or "qspi-ocp". - -Example: - - qspi: spi@ff705000 { - compatible = "cdns,qspi-nor"; - #address-cells = <1>; - #size-cells = <0>; - reg = <0xff705000 0x1000>, - <0xffa00000 0x1000>; - interrupts = <0 151 4>; - clocks = <&qspi_clk>; - cdns,is-decoded-cs; - cdns,fifo-depth = <128>; - cdns,fifo-width = <4>; - cdns,trigger-address = <0x00000000>; - resets = <&rst QSPI_RESET>, <&rst QSPI_OCP_RESET>; - reset-names = "qspi", "qspi-ocp"; - - flash0: n25q00@0 { - ... - cdns,read-delay = <4>; - cdns,tshsl-ns = <50>; - cdns,tsd2d-ns = <50>; - cdns,tchsh-ns = <4>; - cdns,tslch-ns = <4>; - }; - }; diff --git a/Documentation/devicetree/bindings/spi/cadence-quadspi.txt b/Documentation/devicetree/bindings/spi/cadence-quadspi.txt new file mode 100644 index 000000000000..945be7d5b236 --- /dev/null +++ b/Documentation/devicetree/bindings/spi/cadence-quadspi.txt @@ -0,0 +1,67 @@ +* Cadence Quad SPI controller + +Required properties: +- compatible : should be one of the following: + Generic default - "cdns,qspi-nor". + For TI 66AK2G SoC - "ti,k2g-qspi", "cdns,qspi-nor". + For TI AM654 SoC - "ti,am654-ospi", "cdns,qspi-nor". +- reg : Contains two entries, each of which is a tuple consisting of a + physical address and length. The first entry is the address and + length of the controller register set. The second entry is the + address and length of the QSPI Controller data area. +- interrupts : Unit interrupt specifier for the controller interrupt. +- clocks : phandle to the Quad SPI clock. +- cdns,fifo-depth : Size of the data FIFO in words. +- cdns,fifo-width : Bus width of the data FIFO in bytes. +- cdns,trigger-address : 32-bit indirect AHB trigger address. + +Optional properties: +- cdns,is-decoded-cs : Flag to indicate whether decoder is used or not. +- cdns,rclk-en : Flag to indicate that QSPI return clock is used to latch + the read data rather than the QSPI clock. Make sure that QSPI return + clock is populated on the board before using this property. + +Optional subnodes: +Subnodes of the Cadence Quad SPI controller are spi slave nodes with additional +custom properties: +- cdns,read-delay : Delay for read capture logic, in clock cycles +- cdns,tshsl-ns : Delay in nanoseconds for the length that the master + mode chip select outputs are de-asserted between + transactions. +- cdns,tsd2d-ns : Delay in nanoseconds between one chip select being + de-activated and the activation of another. +- cdns,tchsh-ns : Delay in nanoseconds between last bit of current + transaction and deasserting the device chip select + (qspi_n_ss_out). +- cdns,tslch-ns : Delay in nanoseconds between setting qspi_n_ss_out low + and first bit transfer. +- resets : Must contain an entry for each entry in reset-names. + See ../reset/reset.txt for details. +- reset-names : Must include either "qspi" and/or "qspi-ocp". + +Example: + + qspi: spi@ff705000 { + compatible = "cdns,qspi-nor"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0xff705000 0x1000>, + <0xffa00000 0x1000>; + interrupts = <0 151 4>; + clocks = <&qspi_clk>; + cdns,is-decoded-cs; + cdns,fifo-depth = <128>; + cdns,fifo-width = <4>; + cdns,trigger-address = <0x00000000>; + resets = <&rst QSPI_RESET>, <&rst QSPI_OCP_RESET>; + reset-names = "qspi", "qspi-ocp"; + + flash0: n25q00@0 { + ... + cdns,read-delay = <4>; + cdns,tshsl-ns = <50>; + cdns,tsd2d-ns = <50>; + cdns,tchsh-ns = <4>; + cdns,tslch-ns = <4>; + }; + }; -- cgit v1.2.3 From fcebca39938fa9f6ed03f27fc75645ad7fd489e9 Mon Sep 17 00:00:00 2001 From: Ramuthevar Vadivel Murugan Date: Tue, 24 Nov 2020 12:18:40 +0800 Subject: dt-bindings: spi: cadence-qspi: Add support for Intel lgm-qspi Add new vendor specific compatible string to check Intel's Lightning Mountain(LGM) QSPI features enablement in cadence-quadspi driver. Signed-off-by: Ramuthevar Vadivel Murugan Acked-by: Rob Herring Link: https://lore.kernel.org/r/20201124041840.31066-6-vadivel.muruganx.ramuthevar@linux.intel.com Signed-off-by: Mark Brown --- Documentation/devicetree/bindings/spi/cadence-quadspi.txt | 1 + 1 file changed, 1 insertion(+) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/spi/cadence-quadspi.txt b/Documentation/devicetree/bindings/spi/cadence-quadspi.txt index 945be7d5b236..8ace832a2d80 100644 --- a/Documentation/devicetree/bindings/spi/cadence-quadspi.txt +++ b/Documentation/devicetree/bindings/spi/cadence-quadspi.txt @@ -5,6 +5,7 @@ Required properties: Generic default - "cdns,qspi-nor". For TI 66AK2G SoC - "ti,k2g-qspi", "cdns,qspi-nor". For TI AM654 SoC - "ti,am654-ospi", "cdns,qspi-nor". + For Intel LGM SoC - "intel,lgm-qspi", "cdns,qspi-nor". - reg : Contains two entries, each of which is a tuple consisting of a physical address and length. The first entry is the address and length of the controller register set. The second entry is the -- cgit v1.2.3 From 88d9f40c4b715aa8bf8d08a5188e032e9426219d Mon Sep 17 00:00:00 2001 From: Chris Ruehl Date: Tue, 15 Dec 2020 09:44:07 +0800 Subject: devicetree: phy: rockchip-emmc optional add vendor prefix Update the documentation and add the vendor prefix to the optional properties referred in vendor-prefixes.yaml. Follow up with commit 8b5c2b45b8f0a ("phy: rockchip: set pulldown for strobe line in dts") commit a8cef928276bb ("phy: rockchip-emmc: output tap delay dt property") Signed-off-by: Chris Ruehl Reviewed-by: Rob Herring Link: https://lore.kernel.org/r/20201215014409.905-2-chris.ruehl@gtsys.com.hk Signed-off-by: Vinod Koul --- Documentation/devicetree/bindings/phy/rockchip-emmc-phy.txt | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/phy/rockchip-emmc-phy.txt b/Documentation/devicetree/bindings/phy/rockchip-emmc-phy.txt index 00aa2d349e55..57d28c0d5696 100644 --- a/Documentation/devicetree/bindings/phy/rockchip-emmc-phy.txt +++ b/Documentation/devicetree/bindings/phy/rockchip-emmc-phy.txt @@ -16,11 +16,11 @@ Optional properties: - drive-impedance-ohm: Specifies the drive impedance in Ohm. Possible values are 33, 40, 50, 66 and 100. If not set, the default value of 50 will be applied. - - enable-strobe-pulldown: Enable internal pull-down for the strobe line. - If not set, pull-down is not used. - - output-tapdelay-select: Specifies the phyctrl_otapdlysec register. - If not set, the register defaults to 0x4. - Maximum value 0xf. + - rockchip,enable-strobe-pulldown: Enable internal pull-down for the strobe + line. If not set, pull-down is not used. + - rockchip,output-tapdelay-select: Specifies the phyctrl_otapdlysec register. + If not set, the register defaults to 0x4. + Maximum value 0xf. Example: -- cgit v1.2.3 From a8ec9e048bf3b748b9c4bb679c6513a9d8be36c0 Mon Sep 17 00:00:00 2001 From: Chunfeng Yun Date: Fri, 25 Dec 2020 15:52:50 +0800 Subject: dt-bindings: phy: convert phy-mtk-xsphy.txt to YAML schema Convert phy-mtk-xsphy.txt to YAML schema mediatek,xsphy.yaml Signed-off-by: Chunfeng Yun Reviewed-by: Rob Herring Link: https://lore.kernel.org/r/20201225075258.33352-3-chunfeng.yun@mediatek.com Signed-off-by: Vinod Koul --- .../devicetree/bindings/phy/mediatek,xsphy.yaml | 199 +++++++++++++++++++++ .../devicetree/bindings/phy/phy-mtk-xsphy.txt | 109 ----------- 2 files changed, 199 insertions(+), 109 deletions(-) create mode 100644 Documentation/devicetree/bindings/phy/mediatek,xsphy.yaml delete mode 100644 Documentation/devicetree/bindings/phy/phy-mtk-xsphy.txt (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/phy/mediatek,xsphy.yaml b/Documentation/devicetree/bindings/phy/mediatek,xsphy.yaml new file mode 100644 index 000000000000..598fd2b95c29 --- /dev/null +++ b/Documentation/devicetree/bindings/phy/mediatek,xsphy.yaml @@ -0,0 +1,199 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +# Copyright (c) 2020 MediaTek +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/phy/mediatek,xsphy.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: MediaTek XS-PHY Controller Device Tree Bindings + +maintainers: + - Chunfeng Yun + +description: | + The XS-PHY controller supports physical layer functionality for USB3.1 + GEN2 controller on MediaTek SoCs. + + Banks layout of xsphy + ---------------------------------- + port offset bank + u2 port0 0x0000 MISC + 0x0100 FMREG + 0x0300 U2PHY_COM + u2 port1 0x1000 MISC + 0x1100 FMREG + 0x1300 U2PHY_COM + u2 port2 0x2000 MISC + ... + u31 common 0x3000 DIG_GLB + 0x3100 PHYA_GLB + u31 port0 0x3400 DIG_LN_TOP + 0x3500 DIG_LN_TX0 + 0x3600 DIG_LN_RX0 + 0x3700 DIG_LN_DAIF + 0x3800 PHYA_LN + u31 port1 0x3a00 DIG_LN_TOP + 0x3b00 DIG_LN_TX0 + 0x3c00 DIG_LN_RX0 + 0x3d00 DIG_LN_DAIF + 0x3e00 PHYA_LN + ... + DIG_GLB & PHYA_GLB are shared by U31 ports. + +properties: + $nodename: + pattern: "^xs-phy@[0-9a-f]+$" + + compatible: + items: + - enum: + - mediatek,mt3611-xsphy + - mediatek,mt3612-xsphy + - const: mediatek,xsphy + + reg: + description: + Register shared by multiple U3 ports, exclude port's private register, + if only U2 ports provided, shouldn't use the property. + maxItems: 1 + + "#address-cells": + enum: [1, 2] + + "#size-cells": + enum: [1, 2] + + ranges: true + + mediatek,src-ref-clk-mhz: + description: + Frequency of reference clock for slew rate calibrate + default: 26 + + mediatek,src-coef: + description: + Coefficient for slew rate calibrate, depends on SoC process + $ref: /schemas/types.yaml#/definitions/uint32 + default: 17 + +# Required child node: +patternProperties: + "^usb-phy@[0-9a-f]+$": + type: object + description: + A sub-node is required for each port the controller provides. + Address range information including the usual 'reg' property + is used inside these nodes to describe the controller's topology. + + properties: + reg: + maxItems: 1 + + clocks: + items: + - description: Reference clock, (HS is 48Mhz, SS/P is 24~27Mhz) + + clock-names: + items: + - const: ref + + "#phy-cells": + const: 1 + description: | + The cells contain the following arguments. + + - description: The PHY type + enum: + - PHY_TYPE_USB2 + - PHY_TYPE_USB3 + + # The following optional vendor properties are only for debug or HQA test + mediatek,eye-src: + description: + The value of slew rate calibrate (U2 phy) + $ref: /schemas/types.yaml#/definitions/uint32 + minimum: 1 + maximum: 7 + + mediatek,eye-vrt: + description: + The selection of VRT reference voltage (U2 phy) + $ref: /schemas/types.yaml#/definitions/uint32 + minimum: 1 + maximum: 7 + + mediatek,eye-term: + description: + The selection of HS_TX TERM reference voltage (U2 phy) + $ref: /schemas/types.yaml#/definitions/uint32 + minimum: 1 + maximum: 7 + + mediatek,efuse-intr: + description: + The selection of Internal Resistor (U2/U3 phy) + $ref: /schemas/types.yaml#/definitions/uint32 + minimum: 1 + maximum: 63 + + mediatek,efuse-tx-imp: + description: + The selection of TX Impedance (U3 phy) + $ref: /schemas/types.yaml#/definitions/uint32 + minimum: 1 + maximum: 31 + + mediatek,efuse-rx-imp: + description: + The selection of RX Impedance (U3 phy) + $ref: /schemas/types.yaml#/definitions/uint32 + minimum: 1 + maximum: 31 + + required: + - reg + - clocks + - clock-names + - "#phy-cells" + + additionalProperties: false + +required: + - compatible + - "#address-cells" + - "#size-cells" + - ranges + +additionalProperties: false + +examples: + - | + #include + + u3phy: xs-phy@11c40000 { + compatible = "mediatek,mt3611-xsphy", "mediatek,xsphy"; + reg = <0x11c43000 0x0200>; + mediatek,src-ref-clk-mhz = <26>; + mediatek,src-coef = <17>; + #address-cells = <1>; + #size-cells = <1>; + ranges; + + u2port0: usb-phy@11c40000 { + reg = <0x11c40000 0x0400>; + clocks = <&clk48m>; + clock-names = "ref"; + mediatek,eye-src = <4>; + #phy-cells = <1>; + }; + + u3port0: usb-phy@11c43000 { + reg = <0x11c43400 0x0500>; + clocks = <&clk26m>; + clock-names = "ref"; + mediatek,efuse-intr = <28>; + #phy-cells = <1>; + }; + }; + +... diff --git a/Documentation/devicetree/bindings/phy/phy-mtk-xsphy.txt b/Documentation/devicetree/bindings/phy/phy-mtk-xsphy.txt deleted file mode 100644 index e7caefa0b9c2..000000000000 --- a/Documentation/devicetree/bindings/phy/phy-mtk-xsphy.txt +++ /dev/null @@ -1,109 +0,0 @@ -MediaTek XS-PHY binding --------------------------- - -The XS-PHY controller supports physical layer functionality for USB3.1 -GEN2 controller on MediaTek SoCs. - -Required properties (controller (parent) node): - - compatible : should be "mediatek,-xsphy", "mediatek,xsphy", - soc-model is the name of SoC, such as mt3611 etc; - when using "mediatek,xsphy" compatible string, you need SoC specific - ones in addition, one of: - - "mediatek,mt3611-xsphy" - - - #address-cells, #size-cells : should use the same values as the root node - - ranges: must be present - -Optional properties (controller (parent) node): - - reg : offset and length of register shared by multiple U3 ports, - exclude port's private register, if only U2 ports provided, - shouldn't use the property. - - mediatek,src-ref-clk-mhz : u32, frequency of reference clock for slew rate - calibrate - - mediatek,src-coef : u32, coefficient for slew rate calibrate, depends on - SoC process - -Required nodes : a sub-node is required for each port the controller - provides. Address range information including the usual - 'reg' property is used inside these nodes to describe - the controller's topology. - -Required properties (port (child) node): -- reg : address and length of the register set for the port. -- clocks : a list of phandle + clock-specifier pairs, one for each - entry in clock-names -- clock-names : must contain - "ref": 48M reference clock for HighSpeed analog phy; and 26M - reference clock for SuperSpeedPlus analog phy, sometimes is - 24M, 25M or 27M, depended on platform. -- #phy-cells : should be 1 - cell after port phandle is phy type from: - - PHY_TYPE_USB2 - - PHY_TYPE_USB3 - -The following optional properties are only for debug or HQA test -Optional properties (PHY_TYPE_USB2 port (child) node): -- mediatek,eye-src : u32, the value of slew rate calibrate -- mediatek,eye-vrt : u32, the selection of VRT reference voltage -- mediatek,eye-term : u32, the selection of HS_TX TERM reference voltage -- mediatek,efuse-intr : u32, the selection of Internal Resistor - -Optional properties (PHY_TYPE_USB3 port (child) node): -- mediatek,efuse-intr : u32, the selection of Internal Resistor -- mediatek,efuse-tx-imp : u32, the selection of TX Impedance -- mediatek,efuse-rx-imp : u32, the selection of RX Impedance - -Banks layout of xsphy -------------------------------------------------------------- -port offset bank -u2 port0 0x0000 MISC - 0x0100 FMREG - 0x0300 U2PHY_COM -u2 port1 0x1000 MISC - 0x1100 FMREG - 0x1300 U2PHY_COM -u2 port2 0x2000 MISC - ... -u31 common 0x3000 DIG_GLB - 0x3100 PHYA_GLB -u31 port0 0x3400 DIG_LN_TOP - 0x3500 DIG_LN_TX0 - 0x3600 DIG_LN_RX0 - 0x3700 DIG_LN_DAIF - 0x3800 PHYA_LN -u31 port1 0x3a00 DIG_LN_TOP - 0x3b00 DIG_LN_TX0 - 0x3c00 DIG_LN_RX0 - 0x3d00 DIG_LN_DAIF - 0x3e00 PHYA_LN - ... - -DIG_GLB & PHYA_GLB are shared by U31 ports. - -Example: - -u3phy: usb-phy@11c40000 { - compatible = "mediatek,mt3611-xsphy", "mediatek,xsphy"; - reg = <0 0x11c43000 0 0x0200>; - mediatek,src-ref-clk-mhz = <26>; - mediatek,src-coef = <17>; - #address-cells = <2>; - #size-cells = <2>; - ranges; - - u2port0: usb-phy@11c40000 { - reg = <0 0x11c40000 0 0x0400>; - clocks = <&clk48m>; - clock-names = "ref"; - mediatek,eye-src = <4>; - #phy-cells = <1>; - }; - - u3port0: usb-phy@11c43000 { - reg = <0 0x11c43400 0 0x0500>; - clocks = <&clk26m>; - clock-names = "ref"; - mediatek,efuse-intr = <28>; - #phy-cells = <1>; - }; -}; -- cgit v1.2.3 From cbdf8f5080173fcf5d521c0e04403144b12b29eb Mon Sep 17 00:00:00 2001 From: Chunfeng Yun Date: Fri, 25 Dec 2020 15:52:51 +0800 Subject: dt-bindings: phy: convert phy-mtk-tphy.txt to YAML schema Convert phy-mtk-tphy.txt to YAML schema mediatek,tphy.yaml Signed-off-by: Chunfeng Yun Reviewed-by: Rob Herring Link: https://lore.kernel.org/r/20201225075258.33352-4-chunfeng.yun@mediatek.com Signed-off-by: Vinod Koul --- .../devicetree/bindings/phy/mediatek,tphy.yaml | 260 +++++++++++++++++++++ .../devicetree/bindings/phy/phy-mtk-tphy.txt | 162 ------------- 2 files changed, 260 insertions(+), 162 deletions(-) create mode 100644 Documentation/devicetree/bindings/phy/mediatek,tphy.yaml delete mode 100644 Documentation/devicetree/bindings/phy/phy-mtk-tphy.txt (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/phy/mediatek,tphy.yaml b/Documentation/devicetree/bindings/phy/mediatek,tphy.yaml new file mode 100644 index 000000000000..602e6ff45785 --- /dev/null +++ b/Documentation/devicetree/bindings/phy/mediatek,tphy.yaml @@ -0,0 +1,260 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +# Copyright (c) 2020 MediaTek +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/phy/mediatek,tphy.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: MediaTek T-PHY Controller Device Tree Bindings + +maintainers: + - Chunfeng Yun + +description: | + The T-PHY controller supports physical layer functionality for a number of + controllers on MediaTek SoCs, includes USB2.0, USB3.0, PCIe and SATA. + + Layout differences of banks between T-PHY V1 (mt8173/mt2701) and + T-PHY V2 (mt2712) when works on USB mode: + ----------------------------------- + Version 1: + port offset bank + shared 0x0000 SPLLC + 0x0100 FMREG + u2 port0 0x0800 U2PHY_COM + u3 port0 0x0900 U3PHYD + 0x0a00 U3PHYD_BANK2 + 0x0b00 U3PHYA + 0x0c00 U3PHYA_DA + u2 port1 0x1000 U2PHY_COM + u3 port1 0x1100 U3PHYD + 0x1200 U3PHYD_BANK2 + 0x1300 U3PHYA + 0x1400 U3PHYA_DA + u2 port2 0x1800 U2PHY_COM + ... + + Version 2: + port offset bank + u2 port0 0x0000 MISC + 0x0100 FMREG + 0x0300 U2PHY_COM + u3 port0 0x0700 SPLLC + 0x0800 CHIP + 0x0900 U3PHYD + 0x0a00 U3PHYD_BANK2 + 0x0b00 U3PHYA + 0x0c00 U3PHYA_DA + u2 port1 0x1000 MISC + 0x1100 FMREG + 0x1300 U2PHY_COM + u3 port1 0x1700 SPLLC + 0x1800 CHIP + 0x1900 U3PHYD + 0x1a00 U3PHYD_BANK2 + 0x1b00 U3PHYA + 0x1c00 U3PHYA_DA + u2 port2 0x2000 MISC + ... + + SPLLC shared by u3 ports and FMREG shared by u2 ports on V1 are put back + into each port; a new bank MISC for u2 ports and CHIP for u3 ports are + added on V2. + +properties: + $nodename: + pattern: "^t-phy@[0-9a-f]+$" + + compatible: + oneOf: + - items: + - enum: + - mediatek,mt2701-tphy + - mediatek,mt7623-tphy + - mediatek,mt7622-tphy + - mediatek,mt8516-tphy + - const: mediatek,generic-tphy-v1 + - items: + - enum: + - mediatek,mt2712-tphy + - mediatek,mt7629-tphy + - mediatek,mt8183-tphy + - const: mediatek,generic-tphy-v2 + - const: mediatek,mt2701-u3phy + deprecated: true + - const: mediatek,mt2712-u3phy + deprecated: true + - const: mediatek,mt8173-u3phy + + reg: + description: + Register shared by multiple ports, exclude port's private register. + It is needed for T-PHY V1, such as mt2701 and mt8173, but not for + T-PHY V2, such as mt2712. + maxItems: 1 + + "#address-cells": + enum: [1, 2] + + "#size-cells": + enum: [1, 2] + + # Used with non-empty value if optional 'reg' is not provided. + # The format of the value is an arbitrary number of triplets of + # (child-bus-address, parent-bus-address, length). + ranges: true + + mediatek,src-ref-clk-mhz: + description: + Frequency of reference clock for slew rate calibrate + default: 26 + + mediatek,src-coef: + description: + Coefficient for slew rate calibrate, depends on SoC process + $ref: /schemas/types.yaml#/definitions/uint32 + default: 28 + +# Required child node: +patternProperties: + "^usb-phy@[0-9a-f]+$": + type: object + description: + A sub-node is required for each port the controller provides. + Address range information including the usual 'reg' property + is used inside these nodes to describe the controller's topology. + + properties: + reg: + maxItems: 1 + + clocks: + minItems: 1 + maxItems: 2 + items: + - description: Reference clock, (HS is 48Mhz, SS/P is 24~27Mhz) + - description: Reference clock of analog phy + description: + Uses both clocks if the clock of analog and digital phys are + separated, otherwise uses "ref" clock only if needed. + + clock-names: + minItems: 1 + maxItems: 2 + items: + - const: ref + - const: da_ref + + "#phy-cells": + const: 1 + description: | + The cells contain the following arguments. + + - description: The PHY type + enum: + - PHY_TYPE_USB2 + - PHY_TYPE_USB3 + - PHY_TYPE_PCIE + - PHY_TYPE_SATA + + # The following optional vendor properties are only for debug or HQA test + mediatek,eye-src: + description: + The value of slew rate calibrate (U2 phy) + $ref: /schemas/types.yaml#/definitions/uint32 + minimum: 1 + maximum: 7 + + mediatek,eye-vrt: + description: + The selection of VRT reference voltage (U2 phy) + $ref: /schemas/types.yaml#/definitions/uint32 + minimum: 1 + maximum: 7 + + mediatek,eye-term: + description: + The selection of HS_TX TERM reference voltage (U2 phy) + $ref: /schemas/types.yaml#/definitions/uint32 + minimum: 1 + maximum: 7 + + mediatek,intr: + description: + The selection of internal resistor (U2 phy) + $ref: /schemas/types.yaml#/definitions/uint32 + minimum: 1 + maximum: 31 + + mediatek,discth: + description: + The selection of disconnect threshold (U2 phy) + $ref: /schemas/types.yaml#/definitions/uint32 + minimum: 1 + maximum: 15 + + mediatek,bc12: + description: + Specify the flag to enable BC1.2 if support it + type: boolean + + required: + - reg + - "#phy-cells" + + additionalProperties: false + +required: + - compatible + - "#address-cells" + - "#size-cells" + - ranges + +additionalProperties: false + +examples: + - | + #include + #include + #include + #include + usb@11271000 { + compatible = "mediatek,mt8173-mtu3", "mediatek,mtu3"; + reg = <0x11271000 0x3000>, <0x11280700 0x0100>; + reg-names = "mac", "ippc"; + phys = <&u2port0 PHY_TYPE_USB2>, + <&u3port0 PHY_TYPE_USB3>, + <&u2port1 PHY_TYPE_USB2>; + interrupts = ; + clocks = <&topckgen CLK_TOP_USB30_SEL>; + clock-names = "sys_ck"; + }; + + t-phy@11290000 { + compatible = "mediatek,mt8173-u3phy"; + reg = <0x11290000 0x800>; + #address-cells = <1>; + #size-cells = <1>; + ranges; + + u2port0: usb-phy@11290800 { + reg = <0x11290800 0x100>; + clocks = <&apmixedsys CLK_APMIXED_REF2USB_TX>, <&clk48m>; + clock-names = "ref", "da_ref"; + #phy-cells = <1>; + }; + + u3port0: usb-phy@11290900 { + reg = <0x11290900 0x700>; + clocks = <&clk26m>; + clock-names = "ref"; + #phy-cells = <1>; + }; + + u2port1: usb-phy@11291000 { + reg = <0x11291000 0x100>; + #phy-cells = <1>; + }; + }; + +... diff --git a/Documentation/devicetree/bindings/phy/phy-mtk-tphy.txt b/Documentation/devicetree/bindings/phy/phy-mtk-tphy.txt deleted file mode 100644 index dd75b676b71d..000000000000 --- a/Documentation/devicetree/bindings/phy/phy-mtk-tphy.txt +++ /dev/null @@ -1,162 +0,0 @@ -MediaTek T-PHY binding --------------------------- - -T-phy controller supports physical layer functionality for a number of -controllers on MediaTek SoCs, such as, USB2.0, USB3.0, PCIe, and SATA. - -Required properties (controller (parent) node): - - compatible : should be one of - "mediatek,generic-tphy-v1" - "mediatek,generic-tphy-v2" - "mediatek,mt2701-u3phy" (deprecated) - "mediatek,mt2712-u3phy" (deprecated) - "mediatek,mt8173-u3phy"; - make use of "mediatek,generic-tphy-v1" on mt2701 instead and - "mediatek,generic-tphy-v2" on mt2712 instead. - -- #address-cells: the number of cells used to represent physical - base addresses. -- #size-cells: the number of cells used to represent the size of an address. -- ranges: the address mapping relationship to the parent, defined with - - empty value: if optional 'reg' is used. - - non-empty value: if optional 'reg' is not used. should set - the child's base address to 0, the physical address - within parent's address space, and the length of - the address map. - -Required nodes : a sub-node is required for each port the controller - provides. Address range information including the usual - 'reg' property is used inside these nodes to describe - the controller's topology. - -Optional properties (controller (parent) node): - - reg : offset and length of register shared by multiple ports, - exclude port's private register. It is needed on mt2701 - and mt8173, but not on mt2712. - - mediatek,src-ref-clk-mhz : frequency of reference clock for slew rate - calibrate - - mediatek,src-coef : coefficient for slew rate calibrate, depends on - SoC process - -Required properties (port (child) node): -- reg : address and length of the register set for the port. -- #phy-cells : should be 1 (See second example) - cell after port phandle is phy type from: - - PHY_TYPE_USB2 - - PHY_TYPE_USB3 - - PHY_TYPE_PCIE - - PHY_TYPE_SATA - -Optional properties (PHY_TYPE_USB2 port (child) node): -- clocks : a list of phandle + clock-specifier pairs, one for each - entry in clock-names -- clock-names : may contain - "ref": 48M reference clock for HighSpeed (digital) phy; and 26M - reference clock for SuperSpeed (digital) phy, sometimes is - 24M, 25M or 27M, depended on platform. - "da_ref": the reference clock of analog phy, used if the clocks - of analog and digital phys are separated, otherwise uses - "ref" clock only if needed. - -- mediatek,eye-src : u32, the value of slew rate calibrate -- mediatek,eye-vrt : u32, the selection of VRT reference voltage -- mediatek,eye-term : u32, the selection of HS_TX TERM reference voltage -- mediatek,bc12 : bool, enable BC12 of u2phy if support it -- mediatek,discth : u32, the selection of disconnect threshold -- mediatek,intr : u32, the selection of internal R (resistance) - -Example: - -u3phy: usb-phy@11290000 { - compatible = "mediatek,mt8173-u3phy"; - reg = <0 0x11290000 0 0x800>; - #address-cells = <2>; - #size-cells = <2>; - ranges; - - u2port0: usb-phy@11290800 { - reg = <0 0x11290800 0 0x100>; - clocks = <&apmixedsys CLK_APMIXED_REF2USB_TX>; - clock-names = "ref"; - #phy-cells = <1>; - }; - - u3port0: usb-phy@11290900 { - reg = <0 0x11290800 0 0x700>; - clocks = <&clk26m>; - clock-names = "ref"; - #phy-cells = <1>; - }; - - u2port1: usb-phy@11291000 { - reg = <0 0x11291000 0 0x100>; - clocks = <&apmixedsys CLK_APMIXED_REF2USB_TX>; - clock-names = "ref"; - #phy-cells = <1>; - }; -}; - -Specifying phy control of devices ---------------------------------- - -Device nodes should specify the configuration required in their "phys" -property, containing a phandle to the phy port node and a device type; -phy-names for each port are optional. - -Example: - -#include - -usb30: usb@11270000 { - ... - phys = <&u2port0 PHY_TYPE_USB2>, <&u3port0 PHY_TYPE_USB3>; - phy-names = "usb2-0", "usb3-0"; - ... -}; - - -Layout differences of banks between mt8173/mt2701 and mt2712 -------------------------------------------------------------- -mt8173 and mt2701: -port offset bank -shared 0x0000 SPLLC - 0x0100 FMREG -u2 port0 0x0800 U2PHY_COM -u3 port0 0x0900 U3PHYD - 0x0a00 U3PHYD_BANK2 - 0x0b00 U3PHYA - 0x0c00 U3PHYA_DA -u2 port1 0x1000 U2PHY_COM -u3 port1 0x1100 U3PHYD - 0x1200 U3PHYD_BANK2 - 0x1300 U3PHYA - 0x1400 U3PHYA_DA -u2 port2 0x1800 U2PHY_COM - ... - -mt2712: -port offset bank -u2 port0 0x0000 MISC - 0x0100 FMREG - 0x0300 U2PHY_COM -u3 port0 0x0700 SPLLC - 0x0800 CHIP - 0x0900 U3PHYD - 0x0a00 U3PHYD_BANK2 - 0x0b00 U3PHYA - 0x0c00 U3PHYA_DA -u2 port1 0x1000 MISC - 0x1100 FMREG - 0x1300 U2PHY_COM -u3 port1 0x1700 SPLLC - 0x1800 CHIP - 0x1900 U3PHYD - 0x1a00 U3PHYD_BANK2 - 0x1b00 U3PHYA - 0x1c00 U3PHYA_DA -u2 port2 0x2000 MISC - ... - - SPLLC shared by u3 ports and FMREG shared by u2 ports on -mt8173/mt2701 are put back into each port; a new bank MISC for -u2 ports and CHIP for u3 ports are added on mt2712. -- cgit v1.2.3 From 67038ec1bdfbb36a54d24cd5dec108aec2cf3827 Mon Sep 17 00:00:00 2001 From: Chunfeng Yun Date: Fri, 25 Dec 2020 15:52:52 +0800 Subject: dt-bindings: phy: convert phy-mtk-ufs.txt to YAML schema Convert phy-mtk-ufs.txt to YAML schema mediatek,ufs-phy.yaml Signed-off-by: Chunfeng Yun Reviewed-by: Rob Herring Reviewed-by: Stanley Chu Cc: Stanley Chu Link: https://lore.kernel.org/r/20201225075258.33352-5-chunfeng.yun@mediatek.com Signed-off-by: Vinod Koul --- .../devicetree/bindings/phy/mediatek,ufs-phy.yaml | 64 ++++++++++++++++++++++ .../devicetree/bindings/phy/phy-mtk-ufs.txt | 38 ------------- 2 files changed, 64 insertions(+), 38 deletions(-) create mode 100644 Documentation/devicetree/bindings/phy/mediatek,ufs-phy.yaml delete mode 100644 Documentation/devicetree/bindings/phy/phy-mtk-ufs.txt (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/phy/mediatek,ufs-phy.yaml b/Documentation/devicetree/bindings/phy/mediatek,ufs-phy.yaml new file mode 100644 index 000000000000..3a9be82e7f13 --- /dev/null +++ b/Documentation/devicetree/bindings/phy/mediatek,ufs-phy.yaml @@ -0,0 +1,64 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +# Copyright (c) 2020 MediaTek +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/phy/mediatek,ufs-phy.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: MediaTek Universal Flash Storage (UFS) M-PHY binding + +maintainers: + - Stanley Chu + - Chunfeng Yun + +description: | + UFS M-PHY nodes are defined to describe on-chip UFS M-PHY hardware macro. + Each UFS M-PHY node should have its own node. + To bind UFS M-PHY with UFS host controller, the controller node should + contain a phandle reference to UFS M-PHY node. + +properties: + $nodename: + pattern: "^ufs-phy@[0-9a-f]+$" + + compatible: + const: mediatek,mt8183-ufsphy + + reg: + maxItems: 1 + + clocks: + items: + - description: Unipro core control clock. + - description: M-PHY core control clock. + + clock-names: + items: + - const: unipro + - const: mp + + "#phy-cells": + const: 0 + +required: + - compatible + - reg + - "#phy-cells" + - clocks + - clock-names + +additionalProperties: false + +examples: + - | + #include + ufsphy: ufs-phy@11fa0000 { + compatible = "mediatek,mt8183-ufsphy"; + reg = <0x11fa0000 0xc000>; + clocks = <&infracfg CLK_INFRA_UNIPRO_SCK>, + <&infracfg CLK_INFRA_UFS_MP_SAP_BCLK>; + clock-names = "unipro", "mp"; + #phy-cells = <0>; + }; + +... diff --git a/Documentation/devicetree/bindings/phy/phy-mtk-ufs.txt b/Documentation/devicetree/bindings/phy/phy-mtk-ufs.txt deleted file mode 100644 index 5789029a1d42..000000000000 --- a/Documentation/devicetree/bindings/phy/phy-mtk-ufs.txt +++ /dev/null @@ -1,38 +0,0 @@ -MediaTek Universal Flash Storage (UFS) M-PHY binding --------------------------------------------------------- - -UFS M-PHY nodes are defined to describe on-chip UFS M-PHY hardware macro. -Each UFS M-PHY node should have its own node. - -To bind UFS M-PHY with UFS host controller, the controller node should -contain a phandle reference to UFS M-PHY node. - -Required properties for UFS M-PHY nodes: -- compatible : Compatible list, contains the following controller: - "mediatek,mt8183-ufsphy" for ufs phy - persent on MT81xx chipsets. -- reg : Address and length of the UFS M-PHY register set. -- #phy-cells : This property shall be set to 0. -- clocks : List of phandle and clock specifier pairs. -- clock-names : List of clock input name strings sorted in the same - order as the clocks property. Following clocks are - mandatory. - "unipro": Unipro core control clock. - "mp": M-PHY core control clock. - -Example: - - ufsphy: phy@11fa0000 { - compatible = "mediatek,mt8183-ufsphy"; - reg = <0 0x11fa0000 0 0xc000>; - #phy-cells = <0>; - - clocks = <&infracfg_ao INFRACFG_AO_UNIPRO_SCK_CG>, - <&infracfg_ao INFRACFG_AO_UFS_MP_SAP_BCLK_CG>; - clock-names = "unipro", "mp"; - }; - - ufshci@11270000 { - ... - phys = <&ufsphy>; - }; -- cgit v1.2.3 From 5ada755de9db0053740e73ea264393a20fc5eded Mon Sep 17 00:00:00 2001 From: Chunfeng Yun Date: Fri, 25 Dec 2020 15:52:53 +0800 Subject: dt-bindings: phy: convert HDMI PHY binding to YAML schema Convert HDMI PHY binding to YAML schema mediatek,hdmi-phy.yaml Signed-off-by: Chunfeng Yun Reviewed-by: Rob Herring Reviewed-by: Chun-Kuang Hu Cc: Chun-Kuang Hu Cc: Philipp Zabel Link: https://lore.kernel.org/r/20201225075258.33352-6-chunfeng.yun@mediatek.com Signed-off-by: Vinod Koul --- .../bindings/display/mediatek/mediatek,hdmi.txt | 18 +---- .../devicetree/bindings/phy/mediatek,hdmi-phy.yaml | 92 ++++++++++++++++++++++ 2 files changed, 93 insertions(+), 17 deletions(-) create mode 100644 Documentation/devicetree/bindings/phy/mediatek,hdmi-phy.yaml (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,hdmi.txt b/Documentation/devicetree/bindings/display/mediatek/mediatek,hdmi.txt index 6b1c586403e4..b284ca51b913 100644 --- a/Documentation/devicetree/bindings/display/mediatek/mediatek,hdmi.txt +++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,hdmi.txt @@ -53,23 +53,7 @@ Required properties: HDMI PHY ======== - -The HDMI PHY serializes the HDMI encoder's three channel 10-bit parallel -output and drives the HDMI pads. - -Required properties: -- compatible: "mediatek,-hdmi-phy" -- the supported chips are mt2701, mt7623 and mt8173 -- reg: Physical base address and length of the module's registers -- clocks: PLL reference clock -- clock-names: must contain "pll_ref" -- clock-output-names: must be "hdmitx_dig_cts" on mt8173 -- #phy-cells: must be <0> -- #clock-cells: must be <0> - -Optional properties: -- mediatek,ibias: TX DRV bias current for <1.65Gbps, defaults to 0xa -- mediatek,ibias_up: TX DRV bias current for >1.65Gbps, defaults to 0x1c +See phy/mediatek,hdmi-phy.yaml Example: diff --git a/Documentation/devicetree/bindings/phy/mediatek,hdmi-phy.yaml b/Documentation/devicetree/bindings/phy/mediatek,hdmi-phy.yaml new file mode 100644 index 000000000000..4752517a1446 --- /dev/null +++ b/Documentation/devicetree/bindings/phy/mediatek,hdmi-phy.yaml @@ -0,0 +1,92 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +# Copyright (c) 2020 MediaTek +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/phy/mediatek,hdmi-phy.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: MediaTek High Definition Multimedia Interface (HDMI) PHY binding + +maintainers: + - Chun-Kuang Hu + - Philipp Zabel + - Chunfeng Yun + +description: | + The HDMI PHY serializes the HDMI encoder's three channel 10-bit parallel + output and drives the HDMI pads. + +properties: + $nodename: + pattern: "^hdmi-phy@[0-9a-f]+$" + + compatible: + enum: + - mediatek,mt2701-hdmi-phy + - mediatek,mt7623-hdmi-phy + - mediatek,mt8173-hdmi-phy + + reg: + maxItems: 1 + + clocks: + items: + - description: PLL reference clock + + clock-names: + items: + - const: pll_ref + + clock-output-names: + items: + - const: hdmitx_dig_cts + + "#phy-cells": + const: 0 + + "#clock-cells": + const: 0 + + mediatek,ibias: + description: + TX DRV bias current for < 1.65Gbps + $ref: /schemas/types.yaml#/definitions/uint32 + minimum: 0 + maximum: 63 + default: 0xa + + mediatek,ibias_up: + description: + TX DRV bias current for >= 1.65Gbps + $ref: /schemas/types.yaml#/definitions/uint32 + minimum: 0 + maximum: 63 + default: 0x1c + +required: + - compatible + - reg + - clocks + - clock-names + - clock-output-names + - "#phy-cells" + - "#clock-cells" + +additionalProperties: false + +examples: + - | + #include + hdmi_phy: hdmi-phy@10209100 { + compatible = "mediatek,mt8173-hdmi-phy"; + reg = <0x10209100 0x24>; + clocks = <&apmixedsys CLK_APMIXED_HDMI_REF>; + clock-names = "pll_ref"; + clock-output-names = "hdmitx_dig_cts"; + mediatek,ibias = <0xa>; + mediatek,ibias_up = <0x1c>; + #clock-cells = <0>; + #phy-cells = <0>; + }; + +... -- cgit v1.2.3 From dc8423a879b169e992e9abc3b00ba4e6c53783ab Mon Sep 17 00:00:00 2001 From: Chunfeng Yun Date: Fri, 25 Dec 2020 15:52:54 +0800 Subject: dt-bindings: phy: convert MIPI DSI PHY binding to YAML schema Convert MIPI DSI PHY binding to YAML schema mediatek,dsi-phy.yaml Signed-off-by: Chunfeng Yun Reviewed-by: Rob Herring Reviewed-by: Chun-Kuang Hu Cc: Chun-Kuang Hu Cc: Philipp Zabel Link: https://lore.kernel.org/r/20201225075258.33352-7-chunfeng.yun@mediatek.com Signed-off-by: Vinod Koul --- .../bindings/display/mediatek/mediatek,dsi.txt | 18 +---- .../devicetree/bindings/phy/mediatek,dsi-phy.yaml | 85 ++++++++++++++++++++++ 2 files changed, 86 insertions(+), 17 deletions(-) create mode 100644 Documentation/devicetree/bindings/phy/mediatek,dsi-phy.yaml (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,dsi.txt b/Documentation/devicetree/bindings/display/mediatek/mediatek,dsi.txt index f06f24d405a5..8238a86686be 100644 --- a/Documentation/devicetree/bindings/display/mediatek/mediatek,dsi.txt +++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,dsi.txt @@ -22,23 +22,7 @@ Required properties: MIPI TX Configuration Module ============================ -The MIPI TX configuration module controls the MIPI D-PHY. - -Required properties: -- compatible: "mediatek,-mipi-tx" -- the supported chips are mt2701, 7623, mt8173 and mt8183. -- reg: Physical base address and length of the controller's registers -- clocks: PLL reference clock -- clock-output-names: name of the output clock line to the DSI encoder -- #clock-cells: must be <0>; -- #phy-cells: must be <0>. - -Optional properties: -- drive-strength-microamp: adjust driving current, should be 3000 ~ 6000. And - the step is 200. -- nvmem-cells: A phandle to the calibration data provided by a nvmem device. If - unspecified default values shall be used. -- nvmem-cell-names: Should be "calibration-data" +See phy/mediatek,dsi-phy.yaml Example: diff --git a/Documentation/devicetree/bindings/phy/mediatek,dsi-phy.yaml b/Documentation/devicetree/bindings/phy/mediatek,dsi-phy.yaml new file mode 100644 index 000000000000..71d4acea1f66 --- /dev/null +++ b/Documentation/devicetree/bindings/phy/mediatek,dsi-phy.yaml @@ -0,0 +1,85 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +# Copyright (c) 2020 MediaTek +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/phy/mediatek,dsi-phy.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: MediaTek MIPI Display Serial Interface (DSI) PHY binding + +maintainers: + - Chun-Kuang Hu + - Philipp Zabel + - Chunfeng Yun + +description: The MIPI DSI PHY supports up to 4-lane output. + +properties: + $nodename: + pattern: "^dsi-phy@[0-9a-f]+$" + + compatible: + enum: + - mediatek,mt2701-mipi-tx + - mediatek,mt7623-mipi-tx + - mediatek,mt8173-mipi-tx + - mediatek,mt8183-mipi-tx + + reg: + maxItems: 1 + + clocks: + items: + - description: PLL reference clock + + clock-output-names: + maxItems: 1 + + "#phy-cells": + const: 0 + + "#clock-cells": + const: 0 + + nvmem-cells: + maxItems: 1 + description: A phandle to the calibration data provided by a nvmem device, + if unspecified, default values shall be used. + + nvmem-cell-names: + items: + - const: calibration-data + + drive-strength-microamp: + description: adjust driving current + multipleOf: 200 + minimum: 2000 + maximum: 6000 + default: 4600 + +required: + - compatible + - reg + - clocks + - clock-output-names + - "#phy-cells" + - "#clock-cells" + +additionalProperties: false + +examples: + - | + #include + dsi-phy@10215000 { + compatible = "mediatek,mt8173-mipi-tx"; + reg = <0x10215000 0x1000>; + clocks = <&clk26m>; + clock-output-names = "mipi_tx0_pll"; + drive-strength-microamp = <4000>; + nvmem-cells= <&mipi_tx_calibration>; + nvmem-cell-names = "calibration-data"; + #clock-cells = <0>; + #phy-cells = <0>; + }; + +... -- cgit v1.2.3 From b39069a482ade0c5e18c407c3218ba1aeed371b6 Mon Sep 17 00:00:00 2001 From: Rafał Miłecki Date: Wed, 6 Jan 2021 21:58:36 +0100 Subject: dt-bindings: phy: brcm, brcmstb-usb-phy: convert to the json-schema MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Changes that require mentioning: 1. interrupt-names Name "wakeup" was changed to the "wake". It matches example and what Linux driver looks for in the first place 2. brcm,ipp and brcm,ioc Both were described as booleans with 0 / 1 values. In examples they were integers and Linux checks for int as well. Both got uint32. 3. Added minimal description Signed-off-by: Rafał Miłecki Reviewed-by: Florian Fainelli Reviewed-by: Rob Herring Link: https://lore.kernel.org/r/20210106205838.10964-1-zajec5@gmail.com Signed-off-by: Vinod Koul --- .../bindings/phy/brcm,brcmstb-usb-phy.txt | 86 --------- .../bindings/phy/brcm,brcmstb-usb-phy.yaml | 193 +++++++++++++++++++++ 2 files changed, 193 insertions(+), 86 deletions(-) delete mode 100644 Documentation/devicetree/bindings/phy/brcm,brcmstb-usb-phy.txt create mode 100644 Documentation/devicetree/bindings/phy/brcm,brcmstb-usb-phy.yaml (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/phy/brcm,brcmstb-usb-phy.txt b/Documentation/devicetree/bindings/phy/brcm,brcmstb-usb-phy.txt deleted file mode 100644 index 698aacbdcfc4..000000000000 --- a/Documentation/devicetree/bindings/phy/brcm,brcmstb-usb-phy.txt +++ /dev/null @@ -1,86 +0,0 @@ -Broadcom STB USB PHY - -Required properties: -- compatible: should be one of - "brcm,brcmstb-usb-phy" - "brcm,bcm7216-usb-phy" - "brcm,bcm7211-usb-phy" - -- reg and reg-names properties requirements are specific to the - compatible string. - "brcm,brcmstb-usb-phy": - - reg: 1 or 2 offset and length pairs. One for the base CTRL registers - and an optional pair for systems with USB 3.x support - - reg-names: not specified - "brcm,bcm7216-usb-phy": - - reg: 3 offset and length pairs for CTRL, XHCI_EC and XHCI_GBL - registers - - reg-names: "ctrl", "xhci_ec", "xhci_gbl" - "brcm,bcm7211-usb-phy": - - reg: 5 offset and length pairs for CTRL, XHCI_EC, XHCI_GBL, - USB_PHY and USB_MDIO registers and an optional pair - for the BDC registers - - reg-names: "ctrl", "xhci_ec", "xhci_gbl", "usb_phy", "usb_mdio", "bdc_ec" - -- #phy-cells: Shall be 1 as it expects one argument for setting - the type of the PHY. Possible values are: - - PHY_TYPE_USB2 for USB1.1/2.0 PHY - - PHY_TYPE_USB3 for USB3.x PHY - -Optional Properties: -- clocks : clock phandles. -- clock-names: String, clock name. -- interrupts: wakeup interrupt -- interrupt-names: "wakeup" -- brcm,ipp: Boolean, Invert Port Power. - Possible values are: 0 (Don't invert), 1 (Invert) -- brcm,ioc: Boolean, Invert Over Current detection. - Possible values are: 0 (Don't invert), 1 (Invert) -- dr_mode: String, PHY Device mode. - Possible values are: "host", "peripheral ", "drd" or "typec-pd" - If this property is not defined, the phy will default to "host" mode. -- brcm,syscon-piarbctl: phandle to syscon for handling config registers -NOTE: one or both of the following two properties must be set -- brcm,has-xhci: Boolean indicating the phy has an XHCI phy. -- brcm,has-eohci: Boolean indicating the phy has an EHCI/OHCI phy. - - -Example: - -usbphy_0: usb-phy@f0470200 { - reg = <0xf0470200 0xb8>, - <0xf0471940 0x6c0>; - compatible = "brcm,brcmstb-usb-phy"; - #phy-cells = <1>; - dr_mode = "host" - brcm,ioc = <1>; - brcm,ipp = <1>; - brcm,has-xhci; - brcm,has-eohci; - clocks = <&usb20>, <&usb30>; - clock-names = "sw_usb", "sw_usb3"; -}; - -usb-phy@29f0200 { - reg = <0x29f0200 0x200>, - <0x29c0880 0x30>, - <0x29cc100 0x534>, - <0x2808000 0x24>, - <0x2980080 0x8>; - reg-names = "ctrl", - "xhci_ec", - "xhci_gbl", - "usb_phy", - "usb_mdio"; - brcm,ioc = <0x0>; - brcm,ipp = <0x0>; - compatible = "brcm,bcm7211-usb-phy"; - interrupts = <0x30>; - interrupt-parent = <&vpu_intr1_nosec_intc>; - interrupt-names = "wake"; - #phy-cells = <0x1>; - brcm,has-xhci; - syscon-piarbctl = <&syscon_piarbctl>; - clocks = <&scmi_clk 256>; - clock-names = "sw_usb"; -}; diff --git a/Documentation/devicetree/bindings/phy/brcm,brcmstb-usb-phy.yaml b/Documentation/devicetree/bindings/phy/brcm,brcmstb-usb-phy.yaml new file mode 100644 index 000000000000..a5780beadf97 --- /dev/null +++ b/Documentation/devicetree/bindings/phy/brcm,brcmstb-usb-phy.yaml @@ -0,0 +1,193 @@ +# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/phy/brcm,brcmstb-usb-phy.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Broadcom STB USB PHY + +description: Broadcom's PHY that handles EHCI/OHCI and/or XHCI + +maintainers: + - Al Cooper + - Rafał Miłecki + +properties: + compatible: + enum: + - brcm,bcm7211-usb-phy + - brcm,bcm7216-usb-phy + - brcm,brcmstb-usb-phy + + reg: + minItems: 1 + maxItems: 6 + items: + - description: the base CTRL register + - description: XHCI EC register + - description: XHCI GBL register + - description: USB PHY register + - description: USB MDIO register + - description: BDC register + + reg-names: + minItems: 1 + maxItems: 6 + items: + - const: ctrl + - const: xhci_ec + - const: xhci_gbl + - const: usb_phy + - const: usb_mdio + - const: bdc_ec + + clocks: + minItems: 1 + maxItems: 2 + + clock-names: + minItems: 1 + maxItems: 2 + items: + - const: sw_usb + - const: sw_usb3 + + interrupts: + description: wakeup interrupt + + interrupt-names: + const: wake + + brcm,ipp: + $ref: /schemas/types.yaml#/definitions/uint32 + description: Invert Port Power + minimum: 0 + maximum: 1 + + brcm,ioc: + $ref: /schemas/types.yaml#/definitions/uint32 + description: Invert Over Current detection + minimum: 0 + maximum: 1 + + dr_mode: + description: PHY Device mode. If this property is not defined, the PHY will + default to "host" mode. + enum: + - host + - peripheral + - drd + - typec-pd + + brcm,syscon-piarbctl: + description: phandle to syscon for handling config registers + $ref: /schemas/types.yaml#/definitions/phandle + + brcm,has-xhci: + description: Indicates the PHY has an XHCI PHY. + type: boolean + + brcm,has-eohci: + description: Indicates the PHY has an EHCI/OHCI PHY. + type: boolean + + "#phy-cells": + description: | + Cell allows setting the type of the PHY. Possible values are: + - PHY_TYPE_USB2 for USB1.1/2.0 PHY + - PHY_TYPE_USB3 for USB3.x PHY + const: 1 + +required: + - reg + - "#phy-cells" + +anyOf: + - required: + - brcm,has-xhci + - required: + - brcm,has-eohci + +allOf: + - if: + properties: + compatible: + contains: + const: brcm,brcmstb-usb-phy + then: + properties: + reg: + minItems: 1 + maxItems: 2 + - if: + properties: + compatible: + contains: + const: brcm,bcm7211-usb-phy + then: + properties: + reg: + minItems: 5 + maxItems: 6 + reg-names: + minItems: 5 + maxItems: 6 + - if: + properties: + compatible: + contains: + const: brcm,bcm7216-usb-phy + then: + properties: + reg: + minItems: 3 + maxItems: 3 + reg-names: + minItems: 3 + maxItems: 3 + +additionalProperties: false + +examples: + - | + #include + + usb-phy@f0470200 { + compatible = "brcm,brcmstb-usb-phy"; + reg = <0xf0470200 0xb8>, + <0xf0471940 0x6c0>; + #phy-cells = <1>; + dr_mode = "host"; + brcm,ioc = <1>; + brcm,ipp = <1>; + brcm,has-xhci; + brcm,has-eohci; + clocks = <&usb20>, <&usb30>; + clock-names = "sw_usb", "sw_usb3"; + }; + - | + #include + + usb-phy@29f0200 { + compatible = "brcm,bcm7211-usb-phy"; + reg = <0x29f0200 0x200>, + <0x29c0880 0x30>, + <0x29cc100 0x534>, + <0x2808000 0x24>, + <0x2980080 0x8>; + reg-names = "ctrl", + "xhci_ec", + "xhci_gbl", + "usb_phy", + "usb_mdio"; + brcm,ioc = <0x0>; + brcm,ipp = <0x0>; + interrupts = <0x30>; + interrupt-parent = <&vpu_intr1_nosec_intc>; + interrupt-names = "wake"; + #phy-cells = <0x1>; + brcm,has-xhci; + brcm,syscon-piarbctl = <&syscon_piarbctl>; + clocks = <&scmi_clk 256>; + clock-names = "sw_usb"; + }; -- cgit v1.2.3 From 46b616c1574def7a1629bdeded3d44e76382f950 Mon Sep 17 00:00:00 2001 From: Rafał Miłecki Date: Wed, 6 Jan 2021 21:58:37 +0100 Subject: dt-bindings: phy: brcm, brcmstb-usb-phy: add BCM4908 binding MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BCM4908 uses the same PHY and may require just a slightly different programming. Signed-off-by: Rafał Miłecki Acked-by: Florian Fainelli Acked-by: Rob Herring Link: https://lore.kernel.org/r/20210106205838.10964-2-zajec5@gmail.com Signed-off-by: Vinod Koul --- Documentation/devicetree/bindings/phy/brcm,brcmstb-usb-phy.yaml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/phy/brcm,brcmstb-usb-phy.yaml b/Documentation/devicetree/bindings/phy/brcm,brcmstb-usb-phy.yaml index a5780beadf97..0497368d1fca 100644 --- a/Documentation/devicetree/bindings/phy/brcm,brcmstb-usb-phy.yaml +++ b/Documentation/devicetree/bindings/phy/brcm,brcmstb-usb-phy.yaml @@ -15,6 +15,7 @@ maintainers: properties: compatible: enum: + - brcm,bcm4908-usb-phy - brcm,bcm7211-usb-phy - brcm,bcm7216-usb-phy - brcm,brcmstb-usb-phy @@ -113,7 +114,9 @@ allOf: properties: compatible: contains: - const: brcm,brcmstb-usb-phy + enum: + - const: brcm,bcm4908-usb-phy + - const: brcm,brcmstb-usb-phy then: properties: reg: -- cgit v1.2.3 From 34168172eb9f8e444caa843eca59813e60379f91 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Wed, 13 Jan 2021 11:59:25 +0100 Subject: dt-bindings: phy: update phy-cadence-sierra.yaml reference Changeset ba2bf1f090eb ("dt-bindings: phy: Add Cadence Sierra PHY bindings in YAML format") renamed: Documentation/devicetree/bindings/phy/phy-cadence-sierra.txt to: Documentation/devicetree/bindings/phy/phy-cadence-sierra.yaml. Update its cross-reference accordingly. Signed-off-by: Mauro Carvalho Chehab Link: https://lore.kernel.org/r/3550b08d4e8312e7d4a247a3515a93a5f0fd04c5.1610535350.git.mchehab+huawei@kernel.org Signed-off-by: Vinod Koul --- Documentation/devicetree/bindings/phy/ti,phy-j721e-wiz.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/phy/ti,phy-j721e-wiz.yaml b/Documentation/devicetree/bindings/phy/ti,phy-j721e-wiz.yaml index c33e9bc79521..bbbd85501ada 100644 --- a/Documentation/devicetree/bindings/phy/ti,phy-j721e-wiz.yaml +++ b/Documentation/devicetree/bindings/phy/ti,phy-j721e-wiz.yaml @@ -151,7 +151,7 @@ patternProperties: WIZ node should have '1' subnode for the SERDES. It could be either Sierra SERDES or Torrent SERDES. Sierra SERDES should follow the bindings specified in - Documentation/devicetree/bindings/phy/phy-cadence-sierra.txt + Documentation/devicetree/bindings/phy/phy-cadence-sierra.yaml Torrent SERDES should follow the bindings specified in Documentation/devicetree/bindings/phy/phy-cadence-torrent.yaml -- cgit v1.2.3 From 00a9f71760376749e0857b43a8573803b1a075dc Mon Sep 17 00:00:00 2001 From: Amelie Delaunay Date: Tue, 5 Jan 2021 10:05:20 +0100 Subject: dt-bindings: phy: phy-stm32-usbphyc: move PLL supplies to parent node PLL block requires to be powered with 1v1 and 1v8 supplies to catch ENABLE signal. Currently, supplies are managed through phy_ops .power_on/off, and PLL activation/deactivation is managed through phy_ops .init/exit. The sequence of phy_ops .power_on/.phy_init, .power_off/.exit is USB drivers dependent. To ensure a good behavior of the PLL, supplies have to be managed at PLL activation/deactivation. That means the supplies need to be put in usbphyc parent node and not in phy children nodes. Signed-off-by: Amelie Delaunay Reviewed-by: Rob Herring Link: https://lore.kernel.org/r/20210105090525.23164-2-amelie.delaunay@foss.st.com Signed-off-by: Vinod Koul --- .../devicetree/bindings/phy/phy-stm32-usbphyc.yaml | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/phy/phy-stm32-usbphyc.yaml b/Documentation/devicetree/bindings/phy/phy-stm32-usbphyc.yaml index 0ba61979b970..46df6786727a 100644 --- a/Documentation/devicetree/bindings/phy/phy-stm32-usbphyc.yaml +++ b/Documentation/devicetree/bindings/phy/phy-stm32-usbphyc.yaml @@ -45,6 +45,12 @@ properties: "#size-cells": const: 0 + vdda1v1-supply: + description: regulator providing 1V1 power supply to the PLL block + + vdda1v8-supply: + description: regulator providing 1V8 power supply to the PLL block + #Required child nodes: patternProperties: @@ -61,12 +67,6 @@ patternProperties: phy-supply: description: regulator providing 3V3 power supply to the PHY. - vdda1v1-supply: - description: regulator providing 1V1 power supply to the PLL block - - vdda1v8-supply: - description: regulator providing 1V8 power supply to the PLL block - "#phy-cells": enum: [ 0x0, 0x1 ] @@ -90,8 +90,6 @@ patternProperties: required: - reg - phy-supply - - vdda1v1-supply - - vdda1v8-supply - "#phy-cells" additionalProperties: false @@ -102,6 +100,8 @@ required: - clocks - "#address-cells" - "#size-cells" + - vdda1v1-supply + - vdda1v8-supply - usb-phy@0 - usb-phy@1 @@ -116,22 +116,20 @@ examples: reg = <0x5a006000 0x1000>; clocks = <&rcc USBPHY_K>; resets = <&rcc USBPHY_R>; + vdda1v1-supply = <®11>; + vdda1v8-supply = <®18>; #address-cells = <1>; #size-cells = <0>; usbphyc_port0: usb-phy@0 { reg = <0>; phy-supply = <&vdd_usb>; - vdda1v1-supply = <®11>; - vdda1v8-supply = <®18>; #phy-cells = <0>; }; usbphyc_port1: usb-phy@1 { reg = <1>; phy-supply = <&vdd_usb>; - vdda1v1-supply = <®11>; - vdda1v8-supply = <®18>; #phy-cells = <1>; }; }; -- cgit v1.2.3 From a38ed483a72672ee6bdb5d8cf17fc0838377baa0 Mon Sep 17 00:00:00 2001 From: Eric Biggers Date: Tue, 12 Jan 2021 11:02:48 -0800 Subject: fs: pass only I_DIRTY_INODE flags to ->dirty_inode ->dirty_inode is now only called when I_DIRTY_INODE (I_DIRTY_SYNC and/or I_DIRTY_DATASYNC) is set. However it may still be passed other dirty flags at the same time, provided that these other flags happened to be passed to __mark_inode_dirty() at the same time as I_DIRTY_INODE. This doesn't make sense because there is no reason for filesystems to care about these extra flags. Nor are filesystems notified about all updates to these other flags. Therefore, mask the flags before passing them to ->dirty_inode. Also properly document ->dirty_inode in vfs.rst. Link: https://lore.kernel.org/r/20210112190253.64307-7-ebiggers@kernel.org Reviewed-by: Christoph Hellwig Reviewed-by: Jan Kara Signed-off-by: Eric Biggers Signed-off-by: Jan Kara --- Documentation/filesystems/vfs.rst | 5 ++++- fs/fs-writeback.c | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) (limited to 'Documentation') diff --git a/Documentation/filesystems/vfs.rst b/Documentation/filesystems/vfs.rst index ca52c82e5bb5..287b80948a40 100644 --- a/Documentation/filesystems/vfs.rst +++ b/Documentation/filesystems/vfs.rst @@ -270,7 +270,10 @@ or bottom half). ->alloc_inode. ``dirty_inode`` - this method is called by the VFS to mark an inode dirty. + this method is called by the VFS when an inode is marked dirty. + This is specifically for the inode itself being marked dirty, + not its data. If the update needs to be persisted by fdatasync(), + then I_DIRTY_DATASYNC will be set in the flags argument. ``write_inode`` this method is called when the VFS needs to write an inode to diff --git a/fs/fs-writeback.c b/fs/fs-writeback.c index b7616bbd5533..2e6064012f7d 100644 --- a/fs/fs-writeback.c +++ b/fs/fs-writeback.c @@ -2259,7 +2259,7 @@ void __mark_inode_dirty(struct inode *inode, int flags) trace_writeback_dirty_inode_start(inode, flags); if (sb->s_op->dirty_inode) - sb->s_op->dirty_inode(inode, flags); + sb->s_op->dirty_inode(inode, flags & I_DIRTY_INODE); trace_writeback_dirty_inode(inode, flags); -- cgit v1.2.3 From 174a6db25f0da2784f55fcaaca494e3fd1d1029f Mon Sep 17 00:00:00 2001 From: Lukas Bulwahn Date: Wed, 13 Jan 2021 08:00:23 +0100 Subject: doc/zh_CN: adjust table markup in mips/ingenic-tcu.rst Commit 419b1d4ed1cb ("doc/zh_CN: add mips ingenic-tcu.rst translation") introduces a warning with make htmldocs: ./Documentation/translations/zh_CN/mips/ingenic-tcu.rst: 61: WARNING: Malformed table. Text in column margin in table line 6. Adjust the table markup to address this warning. Signed-off-by: Lukas Bulwahn Fixes: 419b1d4ed1cb ("doc/zh_CN: add mips ingenic-tcu.rst translation") Reviewed-by: Alex Shi Reported-by: Stephen Rothwell Link: https://lore.kernel.org/r/20210113070023.25064-1-lukas.bulwahn@gmail.com Signed-off-by: Jonathan Corbet --- Documentation/translations/zh_CN/mips/ingenic-tcu.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'Documentation') diff --git a/Documentation/translations/zh_CN/mips/ingenic-tcu.rst b/Documentation/translations/zh_CN/mips/ingenic-tcu.rst index 72b5d409ed89..9324a0a26430 100644 --- a/Documentation/translations/zh_CN/mips/ingenic-tcu.rst +++ b/Documentation/translations/zh_CN/mips/ingenic-tcu.rst @@ -53,14 +53,14 @@ TCU硬件的功能分布在多个驱动程序: -=========== ===== +============== =================================== 时钟 drivers/clk/ingenic/tcu.c 中断 drivers/irqchip/irq-ingenic-tcu.c 定时器 drivers/clocksource/ingenic-timer.c OST drivers/clocksource/ingenic-ost.c 脉冲宽度调制器 drivers/pwm/pwm-jz4740.c 看门狗 drivers/watchdog/jz4740_wdt.c -=========== ===== +============== =================================== 因为可以从相同的寄存器控制属于不同驱动程序和框架的TCU的各种功能,所以 所有这些驱动程序都通过相同的控制总线通用接口访问它们的寄存器。 -- cgit v1.2.3 From f302589b2d2a02f911f46e4d5e7ab9841da4eebc Mon Sep 17 00:00:00 2001 From: Lukas Bulwahn Date: Wed, 13 Jan 2021 08:05:57 +0100 Subject: doc/zh_CN: mips: use doc references instead The Chinese mips translations refer to non-existing labels in the original documentation. Hence, make htmldocs warns about those undefined labels on all files in ./Documentation/translations/zh_CN/mips/. Replace the references to non-existing labels with suitable doc references. Signed-off-by: Lukas Bulwahn Fixes: 419b1d4ed1cb ("doc/zh_CN: add mips ingenic-tcu.rst translation") Fixes: 72bc9d08868d ("doc/zh_CN: add mips features.rst translation") Fixes: 7fd3954b0c52 ("doc/zh_CN: add mips booting.rst translation") Fixes: b8e724fd7117 ("doc/zh_CN: add mips index.rst translation") Reported-by: Stephen Rothwell Link: https://lore.kernel.org/r/20210113070557.28792-1-lukas.bulwahn@gmail.com Signed-off-by: Jonathan Corbet --- Documentation/translations/zh_CN/mips/booting.rst | 2 +- Documentation/translations/zh_CN/mips/features.rst | 2 +- Documentation/translations/zh_CN/mips/index.rst | 2 +- Documentation/translations/zh_CN/mips/ingenic-tcu.rst | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) (limited to 'Documentation') diff --git a/Documentation/translations/zh_CN/mips/booting.rst b/Documentation/translations/zh_CN/mips/booting.rst index 3099d0fff7a6..96453e1b962e 100644 --- a/Documentation/translations/zh_CN/mips/booting.rst +++ b/Documentation/translations/zh_CN/mips/booting.rst @@ -2,7 +2,7 @@ .. include:: ../disclaimer-zh_CN.rst -:Original: :ref:`Documentation/mips/booting.rst ` +:Original: :doc:`../../../mips/booting` :Translator: Yanteng Si .. _cn_booting: diff --git a/Documentation/translations/zh_CN/mips/features.rst b/Documentation/translations/zh_CN/mips/features.rst index 7e67f81a0982..93d93d06b1b3 100644 --- a/Documentation/translations/zh_CN/mips/features.rst +++ b/Documentation/translations/zh_CN/mips/features.rst @@ -2,7 +2,7 @@ .. include:: ../disclaimer-zh_CN.rst -:Original: :ref:`Documentation/mips/features.rst ` +:Original: :doc:`../../../mips/features` :Translator: Yanteng Si .. _cn_features: diff --git a/Documentation/translations/zh_CN/mips/index.rst b/Documentation/translations/zh_CN/mips/index.rst index 2c7b836a3da5..27a2eae8484a 100644 --- a/Documentation/translations/zh_CN/mips/index.rst +++ b/Documentation/translations/zh_CN/mips/index.rst @@ -2,7 +2,7 @@ .. include:: ../disclaimer-zh_CN.rst -:Original: :ref:`Documentation/mips/index.rst ` +:Original: :doc:`../../../mips/index` :Translator: Yanteng Si .. _cn_index: diff --git a/Documentation/translations/zh_CN/mips/ingenic-tcu.rst b/Documentation/translations/zh_CN/mips/ingenic-tcu.rst index 9324a0a26430..f04ba407384a 100644 --- a/Documentation/translations/zh_CN/mips/ingenic-tcu.rst +++ b/Documentation/translations/zh_CN/mips/ingenic-tcu.rst @@ -2,7 +2,7 @@ .. include:: ../disclaimer-zh_CN.rst -:Original: :ref:`Documentation/mips/ingenic-tcu.rst ` +:Original: :doc:`../../../mips/ingenic-tcu` :Translator: Yanteng Si .. _cn_ingenic-tcu: -- cgit v1.2.3 From 16bcc58e1dabc4db0e14de259cd5c60c77f47250 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Thu, 14 Jan 2021 07:25:59 +0100 Subject: Documentation/devicetree/bindings/usb/dwc3-st.txt: update usb-drd.yaml reference Changeset b0864e1a4d9d ("dt-bindings: usb: Convert generic USB properties to DT schemas") renamed: Documentation/devicetree/bindings/usb/generic.txt to: Documentation/devicetree/bindings/usb/usb-drd.yaml. Update its cross-reference accordingly. Signed-off-by: Mauro Carvalho Chehab Link: https://lore.kernel.org/r/43d5049a8ed688980bee12ecf18ef9937981de39.1610605373.git.mchehab+huawei@kernel.org Signed-off-by: Greg Kroah-Hartman --- Documentation/devicetree/bindings/usb/dwc3-st.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/usb/dwc3-st.txt b/Documentation/devicetree/bindings/usb/dwc3-st.txt index df0e02e1ee43..4ec74c1ee33f 100644 --- a/Documentation/devicetree/bindings/usb/dwc3-st.txt +++ b/Documentation/devicetree/bindings/usb/dwc3-st.txt @@ -37,7 +37,7 @@ NB: The dr_mode property described in [1] is NOT optional for this driver, as th is "otg", which isn't supported by this SoC. Valid dr_mode values for dwc3-st are either "host" or "device". -[1] Documentation/devicetree/bindings/usb/generic.txt +[1] Documentation/devicetree/bindings/usb/usb-drd.yaml Example: -- cgit v1.2.3 From e793c2a3d376fdb2fd3524215ca9f4927d933118 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Thu, 14 Jan 2021 07:25:58 +0100 Subject: dt-bindings: usb: update snps,dwc3.yaml references Changeset 389d77658801 ("dt-bindings: usb: Convert DWC USB3 bindings to DT schema") renamed: Documentation/devicetree/bindings/usb/dwc3.txt to: Documentation/devicetree/bindings/usb/snps,dwc3.yaml. Update its cross-references accordingly. Signed-off-by: Mauro Carvalho Chehab Link: https://lore.kernel.org/r/97704f110f0282fb47eb85dea430cc94cfd93a4b.1610605373.git.mchehab+huawei@kernel.org Signed-off-by: Greg Kroah-Hartman --- Documentation/devicetree/bindings/usb/dwc3-st.txt | 2 +- Documentation/devicetree/bindings/usb/exynos-usb.txt | 2 +- Documentation/devicetree/bindings/usb/omap-usb.txt | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/usb/dwc3-st.txt b/Documentation/devicetree/bindings/usb/dwc3-st.txt index 4ec74c1ee33f..bf73de0d5b4a 100644 --- a/Documentation/devicetree/bindings/usb/dwc3-st.txt +++ b/Documentation/devicetree/bindings/usb/dwc3-st.txt @@ -31,7 +31,7 @@ See: Documentation/devicetree/bindings/pinctrl/pinctrl-bindings.txt Sub-nodes: The dwc3 core should be added as subnode to ST DWC3 glue as shown in the example below. The DT binding details of dwc3 can be found in: -Documentation/devicetree/bindings/usb/dwc3.txt +Documentation/devicetree/bindings/usb/snps,dwc3.yaml NB: The dr_mode property described in [1] is NOT optional for this driver, as the default value is "otg", which isn't supported by this SoC. Valid dr_mode values for dwc3-st are either "host" diff --git a/Documentation/devicetree/bindings/usb/exynos-usb.txt b/Documentation/devicetree/bindings/usb/exynos-usb.txt index 6aae1544f240..f7ae79825d7d 100644 --- a/Documentation/devicetree/bindings/usb/exynos-usb.txt +++ b/Documentation/devicetree/bindings/usb/exynos-usb.txt @@ -93,7 +93,7 @@ Sub-nodes: The dwc3 core should be added as subnode to Exynos dwc3 glue. - dwc3 : The binding details of dwc3 can be found in: - Documentation/devicetree/bindings/usb/dwc3.txt + Documentation/devicetree/bindings/usb/snps,dwc3.yaml Example: usb@12000000 { diff --git a/Documentation/devicetree/bindings/usb/omap-usb.txt b/Documentation/devicetree/bindings/usb/omap-usb.txt index 38d9bb8507cf..f0dbc5ae45ae 100644 --- a/Documentation/devicetree/bindings/usb/omap-usb.txt +++ b/Documentation/devicetree/bindings/usb/omap-usb.txt @@ -65,7 +65,7 @@ Sub-nodes: The dwc3 core should be added as subnode to omap dwc3 glue. - dwc3 : The binding details of dwc3 can be found in: - Documentation/devicetree/bindings/usb/dwc3.txt + Documentation/devicetree/bindings/usb/snps,dwc3.yaml omap_dwc3 { compatible = "ti,dwc3"; -- cgit v1.2.3 From 0301925dd004539adbcf11f68a3a785472376e27 Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Fri, 18 Dec 2020 11:28:12 +0100 Subject: sched: Add schedutil overview Signed-off-by: Peter Zijlstra (Intel) Reviewed-by: Morten Rasmussen Link: https://lkml.kernel.org/r/20201218103258.GA3040@hirez.programming.kicks-ass.net --- Documentation/scheduler/schedutil.txt | 169 ++++++++++++++++++++++++++++++++++ 1 file changed, 169 insertions(+) create mode 100644 Documentation/scheduler/schedutil.txt (limited to 'Documentation') diff --git a/Documentation/scheduler/schedutil.txt b/Documentation/scheduler/schedutil.txt new file mode 100644 index 000000000000..78f6b91e2291 --- /dev/null +++ b/Documentation/scheduler/schedutil.txt @@ -0,0 +1,169 @@ + + +NOTE; all this assumes a linear relation between frequency and work capacity, +we know this is flawed, but it is the best workable approximation. + + +PELT (Per Entity Load Tracking) +------------------------------- + +With PELT we track some metrics across the various scheduler entities, from +individual tasks to task-group slices to CPU runqueues. As the basis for this +we use an Exponentially Weighted Moving Average (EWMA), each period (1024us) +is decayed such that y^32 = 0.5. That is, the most recent 32ms contribute +half, while the rest of history contribute the other half. + +Specifically: + + ewma_sum(u) := u_0 + u_1*y + u_2*y^2 + ... + + ewma(u) = ewma_sum(u) / ewma_sum(1) + +Since this is essentially a progression of an infinite geometric series, the +results are composable, that is ewma(A) + ewma(B) = ewma(A+B). This property +is key, since it gives the ability to recompose the averages when tasks move +around. + +Note that blocked tasks still contribute to the aggregates (task-group slices +and CPU runqueues), which reflects their expected contribution when they +resume running. + +Using this we track 2 key metrics: 'running' and 'runnable'. 'Running' +reflects the time an entity spends on the CPU, while 'runnable' reflects the +time an entity spends on the runqueue. When there is only a single task these +two metrics are the same, but once there is contention for the CPU 'running' +will decrease to reflect the fraction of time each task spends on the CPU +while 'runnable' will increase to reflect the amount of contention. + +For more detail see: kernel/sched/pelt.c + + +Frequency- / CPU Invariance +--------------------------- + +Because consuming the CPU for 50% at 1GHz is not the same as consuming the CPU +for 50% at 2GHz, nor is running 50% on a LITTLE CPU the same as running 50% on +a big CPU, we allow architectures to scale the time delta with two ratios, one +Dynamic Voltage and Frequency Scaling (DVFS) ratio and one microarch ratio. + +For simple DVFS architectures (where software is in full control) we trivially +compute the ratio as: + + f_cur + r_dvfs := ----- + f_max + +For more dynamic systems where the hardware is in control of DVFS we use +hardware counters (Intel APERF/MPERF, ARMv8.4-AMU) to provide us this ratio. +For Intel specifically, we use: + + APERF + f_cur := ----- * P0 + MPERF + + 4C-turbo; if available and turbo enabled + f_max := { 1C-turbo; if turbo enabled + P0; otherwise + + f_cur + r_dvfs := min( 1, ----- ) + f_max + +We pick 4C turbo over 1C turbo to make it slightly more sustainable. + +r_cpu is determined as the ratio of highest performance level of the current +CPU vs the highest performance level of any other CPU in the system. + + r_tot = r_dvfs * r_cpu + +The result is that the above 'running' and 'runnable' metrics become invariant +of DVFS and CPU type. IOW. we can transfer and compare them between CPUs. + +For more detail see: + + - kernel/sched/pelt.h:update_rq_clock_pelt() + - arch/x86/kernel/smpboot.c:"APERF/MPERF frequency ratio computation." + - Documentation/scheduler/sched-capacity.rst:"1. CPU Capacity + 2. Task utilization" + + +UTIL_EST / UTIL_EST_FASTUP +-------------------------- + +Because periodic tasks have their averages decayed while they sleep, even +though when running their expected utilization will be the same, they suffer a +(DVFS) ramp-up after they are running again. + +To alleviate this (a default enabled option) UTIL_EST drives an Infinite +Impulse Response (IIR) EWMA with the 'running' value on dequeue -- when it is +highest. A further default enabled option UTIL_EST_FASTUP modifies the IIR +filter to instantly increase and only decay on decrease. + +A further runqueue wide sum (of runnable tasks) is maintained of: + + util_est := \Sum_t max( t_running, t_util_est_ewma ) + +For more detail see: kernel/sched/fair.c:util_est_dequeue() + + +UCLAMP +------ + +It is possible to set effective u_min and u_max clamps on each CFS or RT task; +the runqueue keeps an max aggregate of these clamps for all running tasks. + +For more detail see: include/uapi/linux/sched/types.h + + +Schedutil / DVFS +---------------- + +Every time the scheduler load tracking is updated (task wakeup, task +migration, time progression) we call out to schedutil to update the hardware +DVFS state. + +The basis is the CPU runqueue's 'running' metric, which per the above it is +the frequency invariant utilization estimate of the CPU. From this we compute +a desired frequency like: + + max( running, util_est ); if UTIL_EST + u_cfs := { running; otherwise + + clamp( u_cfs + u_rt , u_min, u_max ); if UCLAMP_TASK + u_clamp := { u_cfs + u_rt; otherwise + + u := u_clamp + u_irq + u_dl; [approx. see source for more detail] + + f_des := min( f_max, 1.25 u * f_max ) + +XXX IO-wait; when the update is due to a task wakeup from IO-completion we +boost 'u' above. + +This frequency is then used to select a P-state/OPP or directly munged into a +CPPC style request to the hardware. + +XXX: deadline tasks (Sporadic Task Model) allows us to calculate a hard f_min +required to satisfy the workload. + +Because these callbacks are directly from the scheduler, the DVFS hardware +interaction should be 'fast' and non-blocking. Schedutil supports +rate-limiting DVFS requests for when hardware interaction is slow and +expensive, this reduces effectiveness. + +For more information see: kernel/sched/cpufreq_schedutil.c + + +NOTES +----- + + - On low-load scenarios, where DVFS is most relevant, the 'running' numbers + will closely reflect utilization. + + - In saturated scenarios task movement will cause some transient dips, + suppose we have a CPU saturated with 4 tasks, then when we migrate a task + to an idle CPU, the old CPU will have a 'running' value of 0.75 while the + new CPU will gain 0.25. This is inevitable and time progression will + correct this. XXX do we still guarantee f_max due to no idle-time? + + - Much of the above is about avoiding DVFS dips, and independent DVFS domains + having to re-learn / ramp-up when load shifts. + -- cgit v1.2.3 From 5831c0f71d6664c6aa7b58ba969bf645c89ecb85 Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Wed, 9 Dec 2020 16:42:57 +0100 Subject: locking/selftests: More granular debug_locks_verbose Showing all tests all the time is tiresome. Signed-off-by: Peter Zijlstra (Intel) --- Documentation/admin-guide/kernel-parameters.txt | 11 ++++++----- lib/locking-selftest.c | 5 +++-- 2 files changed, 9 insertions(+), 7 deletions(-) (limited to 'Documentation') diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt index c722ec19cd00..611a5c3034e7 100644 --- a/Documentation/admin-guide/kernel-parameters.txt +++ b/Documentation/admin-guide/kernel-parameters.txt @@ -802,13 +802,14 @@ insecure, please do not use on production kernels. debug_locks_verbose= - [KNL] verbose self-tests - Format=<0|1> + [KNL] verbose locking self-tests + Format: Print debugging info while doing the locking API self-tests. - We default to 0 (no extra messages), setting it to - 1 will print _a lot_ more information - normally - only useful to kernel developers. + Bitmask for the various LOCKTYPE_ tests. Defaults to 0 + (no extra messages), setting it to -1 (all bits set) + will print _a_lot_ more information - normally only + useful to lockdep developers. debug_objects [KNL] Enable object debugging diff --git a/lib/locking-selftest.c b/lib/locking-selftest.c index 23376eeccf7c..3306f43b0007 100644 --- a/lib/locking-selftest.c +++ b/lib/locking-selftest.c @@ -1390,6 +1390,8 @@ static void dotest(void (*testcase_fn)(void), int expected, int lockclass_mask) WARN_ON(irqs_disabled()); + debug_locks_silent = !(debug_locks_verbose & lockclass_mask); + testcase_fn(); /* * Filter out expected failures: @@ -1410,7 +1412,7 @@ static void dotest(void (*testcase_fn)(void), int expected, int lockclass_mask) } testcase_total++; - if (debug_locks_verbose) + if (debug_locks_verbose & lockclass_mask) pr_cont(" lockclass mask: %x, debug_locks: %d, expected: %d\n", lockclass_mask, debug_locks, expected); /* @@ -2674,7 +2676,6 @@ void locking_selftest(void) printk(" --------------------------------------------------------------------------\n"); init_shared_classes(); - debug_locks_silent = !debug_locks_verbose; lockdep_set_selftest_task(current); DO_TESTCASE_6R("A-A deadlock", AA); -- cgit v1.2.3 From 88a1590b1407207a51788d56746f46cbd6e6ab4e Mon Sep 17 00:00:00 2001 From: Ulrich Hecht Date: Tue, 12 Jan 2021 17:59:12 +0100 Subject: dt-bindings: pinctrl: renesas,pfc: Document r8a779a0 PFC support Document PFC support for the R-Car V3U (R8A779A0) SoC. Signed-off-by: Ulrich Hecht Link: https://lore.kernel.org/r/20210112165912.30876-7-uli+renesas@fpond.eu [geert: increase reg maxItems to 10] Signed-off-by: Geert Uytterhoeven --- Documentation/devicetree/bindings/pinctrl/renesas,pfc.yaml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/pinctrl/renesas,pfc.yaml b/Documentation/devicetree/bindings/pinctrl/renesas,pfc.yaml index 5b5b1b9d2ec7..5a45e7d78ce4 100644 --- a/Documentation/devicetree/bindings/pinctrl/renesas,pfc.yaml +++ b/Documentation/devicetree/bindings/pinctrl/renesas,pfc.yaml @@ -43,11 +43,12 @@ properties: - renesas,pfc-r8a77980 # R-Car V3H - renesas,pfc-r8a77990 # R-Car E3 - renesas,pfc-r8a77995 # R-Car D3 + - renesas,pfc-r8a779a0 # R-Car V3U - renesas,pfc-sh73a0 # SH-Mobile AG5 reg: minItems: 1 - maxItems: 2 + maxItems: 10 gpio-controller: true -- cgit v1.2.3 From 99d0cbe4be78ca33f06089521a8a0d76a20cdbb7 Mon Sep 17 00:00:00 2001 From: Dikshita Agarwal Date: Thu, 24 Dec 2020 12:25:33 +0100 Subject: media: v4l2-ctrl: Add frame-specific min/max qp controls for hevc - Adds min/max qp controls for B frame for h264. - Adds min/max qp controls for I/P/B frames for hevc similar to h264. - Update valid range of min/max qp for hevc to accommodate 10 bit. Signed-off-by: Dikshita Agarwal Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- .../userspace-api/media/v4l/ext-ctrls-codec.rst | 52 +++++++++++++++++++++- drivers/media/v4l2-core/v4l2-ctrls.c | 8 ++++ include/uapi/linux/v4l2-controls.h | 9 ++++ 3 files changed, 67 insertions(+), 2 deletions(-) (limited to 'Documentation') diff --git a/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst b/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst index 454ecd9a0f83..90c60add3fc0 100644 --- a/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst +++ b/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst @@ -1182,6 +1182,18 @@ enum v4l2_mpeg_video_h264_entropy_mode - V4L2_CID_MPEG_VIDEO_H264_MAX_QP is also set, the quantization parameter should be chosen to meet both requirements. +``V4L2_CID_MPEG_VIDEO_H264_B_FRAME_MIN_QP (integer)`` + Minimum quantization parameter for the H264 B frame to limit B frame + quality to a range. Valid range: from 0 to 51. If + V4L2_CID_MPEG_VIDEO_H264_MIN_QP is also set, the quantization parameter + should be chosen to meet both requirements. + +``V4L2_CID_MPEG_VIDEO_H264_B_FRAME_MAX_QP (integer)`` + Maximum quantization parameter for the H264 B frame to limit B frame + quality to a range. Valid range: from 0 to 51. If + V4L2_CID_MPEG_VIDEO_H264_MAX_QP is also set, the quantization parameter + should be chosen to meet both requirements. + ``V4L2_CID_MPEG_VIDEO_MPEG4_I_FRAME_QP (integer)`` Quantization parameter for an I frame for MPEG4. Valid range: from 1 to 31. @@ -2628,11 +2640,11 @@ HEVC/H.265 Control IDs ``V4L2_CID_MPEG_VIDEO_HEVC_MIN_QP (integer)`` Minimum quantization parameter for HEVC. - Valid range: from 0 to 51. + Valid range: from 0 to 51 for 8 bit and from 0 to 63 for 10 bit. ``V4L2_CID_MPEG_VIDEO_HEVC_MAX_QP (integer)`` Maximum quantization parameter for HEVC. - Valid range: from 0 to 51. + Valid range: from 0 to 51 for 8 bit and from 0 to 63 for 10 bit. ``V4L2_CID_MPEG_VIDEO_HEVC_I_FRAME_QP (integer)`` Quantization parameter for an I frame for HEVC. @@ -2649,6 +2661,42 @@ HEVC/H.265 Control IDs Valid range: [V4L2_CID_MPEG_VIDEO_HEVC_MIN_QP, V4L2_CID_MPEG_VIDEO_HEVC_MAX_QP]. +``V4L2_CID_MPEG_VIDEO_HEVC_I_FRAME_MIN_QP (integer)`` + Minimum quantization parameter for the HEVC I frame to limit I frame + quality to a range. Valid range: from 0 to 51 for 8 bit and from 0 to 63 for 10 bit. + If V4L2_CID_MPEG_VIDEO_HEVC_MIN_QP is also set, the quantization parameter + should be chosen to meet both requirements. + +``V4L2_CID_MPEG_VIDEO_HEVC_I_FRAME_MAX_QP (integer)`` + Maximum quantization parameter for the HEVC I frame to limit I frame + quality to a range. Valid range: from 0 to 51 for 8 bit and from 0 to 63 for 10 bit. + If V4L2_CID_MPEG_VIDEO_HEVC_MAX_QP is also set, the quantization parameter + should be chosen to meet both requirements. + +``V4L2_CID_MPEG_VIDEO_HEVC_P_FRAME_MIN_QP (integer)`` + Minimum quantization parameter for the HEVC P frame to limit P frame + quality to a range. Valid range: from 0 to 51 for 8 bit and from 0 to 63 for 10 bit. + If V4L2_CID_MPEG_VIDEO_HEVC_MIN_QP is also set, the quantization parameter + should be chosen to meet both requirements. + +``V4L2_CID_MPEG_VIDEO_HEVC_P_FRAME_MAX_QP (integer)`` + Maximum quantization parameter for the HEVC P frame to limit P frame + quality to a range. Valid range: from 0 to 51 for 8 bit and from 0 to 63 for 10 bit. + If V4L2_CID_MPEG_VIDEO_HEVC_MAX_QP is also set, the quantization parameter + should be chosen to meet both requirements. + +``V4L2_CID_MPEG_VIDEO_HEVC_B_FRAME_MIN_QP (integer)`` + Minimum quantization parameter for the HEVC B frame to limit B frame + quality to a range. Valid range: from 0 to 51 for 8 bit and from 0 to 63 for 10 bit. + If V4L2_CID_MPEG_VIDEO_HEVC_MIN_QP is also set, the quantization parameter + should be chosen to meet both requirements. + +``V4L2_CID_MPEG_VIDEO_HEVC_B_FRAME_MAX_QP (integer)`` + Maximum quantization parameter for the HEVC B frame to limit B frame + quality to a range. Valid range: from 0 to 51 for 8 bit and from 0 to 63 for 10 bit. + If V4L2_CID_MPEG_VIDEO_HEVC_MAX_QP is also set, the quantization parameter + should be chosen to meet both requirements. + ``V4L2_CID_MPEG_VIDEO_HEVC_HIER_QP (boolean)`` HIERARCHICAL_QP allows the host to specify the quantization parameter values for each temporal layer through HIERARCHICAL_QP_LAYER. This is diff --git a/drivers/media/v4l2-core/v4l2-ctrls.c b/drivers/media/v4l2-core/v4l2-ctrls.c index 5cbe0ffbf501..410e54141c21 100644 --- a/drivers/media/v4l2-core/v4l2-ctrls.c +++ b/drivers/media/v4l2-core/v4l2-ctrls.c @@ -920,6 +920,8 @@ const char *v4l2_ctrl_get_name(u32 id) case V4L2_CID_MPEG_VIDEO_H264_I_FRAME_MAX_QP: return "H264 I-Frame Maximum QP Value"; case V4L2_CID_MPEG_VIDEO_H264_P_FRAME_MIN_QP: return "H264 P-Frame Minimum QP Value"; case V4L2_CID_MPEG_VIDEO_H264_P_FRAME_MAX_QP: return "H264 P-Frame Maximum QP Value"; + case V4L2_CID_MPEG_VIDEO_H264_B_FRAME_MIN_QP: return "H264 B-Frame Minimum QP Value"; + case V4L2_CID_MPEG_VIDEO_H264_B_FRAME_MAX_QP: return "H264 B-Frame Maximum QP Value"; case V4L2_CID_MPEG_VIDEO_MPEG2_LEVEL: return "MPEG2 Level"; case V4L2_CID_MPEG_VIDEO_MPEG2_PROFILE: return "MPEG2 Profile"; case V4L2_CID_MPEG_VIDEO_MPEG4_I_FRAME_QP: return "MPEG4 I-Frame QP Value"; @@ -969,6 +971,12 @@ const char *v4l2_ctrl_get_name(u32 id) case V4L2_CID_MPEG_VIDEO_HEVC_B_FRAME_QP: return "HEVC B-Frame QP Value"; case V4L2_CID_MPEG_VIDEO_HEVC_MIN_QP: return "HEVC Minimum QP Value"; case V4L2_CID_MPEG_VIDEO_HEVC_MAX_QP: return "HEVC Maximum QP Value"; + case V4L2_CID_MPEG_VIDEO_HEVC_I_FRAME_MIN_QP: return "HEVC I-Frame Minimum QP Value"; + case V4L2_CID_MPEG_VIDEO_HEVC_I_FRAME_MAX_QP: return "HEVC I-Frame Maximum QP Value"; + case V4L2_CID_MPEG_VIDEO_HEVC_P_FRAME_MIN_QP: return "HEVC P-Frame Minimum QP Value"; + case V4L2_CID_MPEG_VIDEO_HEVC_P_FRAME_MAX_QP: return "HEVC P-Frame Maximum QP Value"; + case V4L2_CID_MPEG_VIDEO_HEVC_B_FRAME_MIN_QP: return "HEVC B-Frame Minimum QP Value"; + case V4L2_CID_MPEG_VIDEO_HEVC_B_FRAME_MAX_QP: return "HEVC B-Frame Maximum QP Value"; case V4L2_CID_MPEG_VIDEO_HEVC_PROFILE: return "HEVC Profile"; case V4L2_CID_MPEG_VIDEO_HEVC_LEVEL: return "HEVC Level"; case V4L2_CID_MPEG_VIDEO_HEVC_TIER: return "HEVC Tier"; diff --git a/include/uapi/linux/v4l2-controls.h b/include/uapi/linux/v4l2-controls.h index 9ead7a8386c8..a7130f47199e 100644 --- a/include/uapi/linux/v4l2-controls.h +++ b/include/uapi/linux/v4l2-controls.h @@ -590,6 +590,8 @@ enum v4l2_mpeg_video_h264_hierarchical_coding_type { #define V4L2_CID_MPEG_VIDEO_H264_I_FRAME_MAX_QP (V4L2_CID_CODEC_BASE+386) #define V4L2_CID_MPEG_VIDEO_H264_P_FRAME_MIN_QP (V4L2_CID_CODEC_BASE+387) #define V4L2_CID_MPEG_VIDEO_H264_P_FRAME_MAX_QP (V4L2_CID_CODEC_BASE+388) +#define V4L2_CID_MPEG_VIDEO_H264_B_FRAME_MIN_QP (V4L2_CID_CODEC_BASE+389) +#define V4L2_CID_MPEG_VIDEO_H264_B_FRAME_MAX_QP (V4L2_CID_CODEC_BASE+390) #define V4L2_CID_MPEG_VIDEO_MPEG4_I_FRAME_QP (V4L2_CID_CODEC_BASE+400) #define V4L2_CID_MPEG_VIDEO_MPEG4_P_FRAME_QP (V4L2_CID_CODEC_BASE+401) #define V4L2_CID_MPEG_VIDEO_MPEG4_B_FRAME_QP (V4L2_CID_CODEC_BASE+402) @@ -780,6 +782,13 @@ enum v4l2_mpeg_video_frame_skip_mode { V4L2_MPEG_VIDEO_FRAME_SKIP_MODE_BUF_LIMIT = 2, }; +#define V4L2_CID_MPEG_VIDEO_HEVC_I_FRAME_MIN_QP (V4L2_CID_CODEC_BASE + 647) +#define V4L2_CID_MPEG_VIDEO_HEVC_I_FRAME_MAX_QP (V4L2_CID_CODEC_BASE + 648) +#define V4L2_CID_MPEG_VIDEO_HEVC_P_FRAME_MIN_QP (V4L2_CID_CODEC_BASE + 649) +#define V4L2_CID_MPEG_VIDEO_HEVC_P_FRAME_MAX_QP (V4L2_CID_CODEC_BASE + 650) +#define V4L2_CID_MPEG_VIDEO_HEVC_B_FRAME_MIN_QP (V4L2_CID_CODEC_BASE + 651) +#define V4L2_CID_MPEG_VIDEO_HEVC_B_FRAME_MAX_QP (V4L2_CID_CODEC_BASE + 652) + /* MPEG-class control IDs specific to the CX2341x driver as defined by V4L2 */ #define V4L2_CID_CODEC_CX2341X_BASE (V4L2_CTRL_CLASS_CODEC | 0x1000) #define V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE (V4L2_CID_CODEC_CX2341X_BASE+0) -- cgit v1.2.3 From 4ca134ee98238c3aaf0bb51094716373d8ae8720 Mon Sep 17 00:00:00 2001 From: Dikshita Agarwal Date: Thu, 24 Dec 2020 12:25:34 +0100 Subject: media: v4l2-ctrl: Add layer wise bitrate controls for h264 Adds bitrate control for all coding layers for h264 same as hevc. Signed-off-by: Dikshita Agarwal Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- .../userspace-api/media/v4l/ext-ctrls-codec.rst | 20 ++++++++++++++++++++ drivers/media/v4l2-core/v4l2-ctrls.c | 7 +++++++ include/uapi/linux/v4l2-controls.h | 7 +++++++ 3 files changed, 34 insertions(+) (limited to 'Documentation') diff --git a/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst b/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst index 90c60add3fc0..400774ceffaa 100644 --- a/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst +++ b/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst @@ -1513,6 +1513,26 @@ enum v4l2_mpeg_video_h264_hierarchical_coding_type - * - Bit 16:32 - Layer number +``V4L2_CID_MPEG_VIDEO_H264_HIER_CODING_L0_BR (integer)`` + Indicates bit rate (bps) for hierarchical coding layer 0 for H264 encoder. + +``V4L2_CID_MPEG_VIDEO_H264_HIER_CODING_L1_BR (integer)`` + Indicates bit rate (bps) for hierarchical coding layer 1 for H264 encoder. + +``V4L2_CID_MPEG_VIDEO_H264_HIER_CODING_L2_BR (integer)`` + Indicates bit rate (bps) for hierarchical coding layer 2 for H264 encoder. + +``V4L2_CID_MPEG_VIDEO_H264_HIER_CODING_L3_BR (integer)`` + Indicates bit rate (bps) for hierarchical coding layer 3 for H264 encoder. + +``V4L2_CID_MPEG_VIDEO_H264_HIER_CODING_L4_BR (integer)`` + Indicates bit rate (bps) for hierarchical coding layer 4 for H264 encoder. + +``V4L2_CID_MPEG_VIDEO_H264_HIER_CODING_L5_BR (integer)`` + Indicates bit rate (bps) for hierarchical coding layer 5 for H264 encoder. + +``V4L2_CID_MPEG_VIDEO_H264_HIER_CODING_L6_BR (integer)`` + Indicates bit rate (bps) for hierarchical coding layer 6 for H264 encoder. .. _v4l2-mpeg-mpeg2: diff --git a/drivers/media/v4l2-core/v4l2-ctrls.c b/drivers/media/v4l2-core/v4l2-ctrls.c index 410e54141c21..16ab54f676e2 100644 --- a/drivers/media/v4l2-core/v4l2-ctrls.c +++ b/drivers/media/v4l2-core/v4l2-ctrls.c @@ -922,6 +922,13 @@ const char *v4l2_ctrl_get_name(u32 id) case V4L2_CID_MPEG_VIDEO_H264_P_FRAME_MAX_QP: return "H264 P-Frame Maximum QP Value"; case V4L2_CID_MPEG_VIDEO_H264_B_FRAME_MIN_QP: return "H264 B-Frame Minimum QP Value"; case V4L2_CID_MPEG_VIDEO_H264_B_FRAME_MAX_QP: return "H264 B-Frame Maximum QP Value"; + case V4L2_CID_MPEG_VIDEO_H264_HIER_CODING_L0_BR: return "H264 Hierarchical Lay 0 Bitrate"; + case V4L2_CID_MPEG_VIDEO_H264_HIER_CODING_L1_BR: return "H264 Hierarchical Lay 1 Bitrate"; + case V4L2_CID_MPEG_VIDEO_H264_HIER_CODING_L2_BR: return "H264 Hierarchical Lay 2 Bitrate"; + case V4L2_CID_MPEG_VIDEO_H264_HIER_CODING_L3_BR: return "H264 Hierarchical Lay 3 Bitrate"; + case V4L2_CID_MPEG_VIDEO_H264_HIER_CODING_L4_BR: return "H264 Hierarchical Lay 4 Bitrate"; + case V4L2_CID_MPEG_VIDEO_H264_HIER_CODING_L5_BR: return "H264 Hierarchical Lay 5 Bitrate"; + case V4L2_CID_MPEG_VIDEO_H264_HIER_CODING_L6_BR: return "H264 Hierarchical Lay 6 Bitrate"; case V4L2_CID_MPEG_VIDEO_MPEG2_LEVEL: return "MPEG2 Level"; case V4L2_CID_MPEG_VIDEO_MPEG2_PROFILE: return "MPEG2 Profile"; case V4L2_CID_MPEG_VIDEO_MPEG4_I_FRAME_QP: return "MPEG4 I-Frame QP Value"; diff --git a/include/uapi/linux/v4l2-controls.h b/include/uapi/linux/v4l2-controls.h index a7130f47199e..0bd967543357 100644 --- a/include/uapi/linux/v4l2-controls.h +++ b/include/uapi/linux/v4l2-controls.h @@ -592,6 +592,13 @@ enum v4l2_mpeg_video_h264_hierarchical_coding_type { #define V4L2_CID_MPEG_VIDEO_H264_P_FRAME_MAX_QP (V4L2_CID_CODEC_BASE+388) #define V4L2_CID_MPEG_VIDEO_H264_B_FRAME_MIN_QP (V4L2_CID_CODEC_BASE+389) #define V4L2_CID_MPEG_VIDEO_H264_B_FRAME_MAX_QP (V4L2_CID_CODEC_BASE+390) +#define V4L2_CID_MPEG_VIDEO_H264_HIER_CODING_L0_BR (V4L2_CID_CODEC_BASE+391) +#define V4L2_CID_MPEG_VIDEO_H264_HIER_CODING_L1_BR (V4L2_CID_CODEC_BASE+392) +#define V4L2_CID_MPEG_VIDEO_H264_HIER_CODING_L2_BR (V4L2_CID_CODEC_BASE+393) +#define V4L2_CID_MPEG_VIDEO_H264_HIER_CODING_L3_BR (V4L2_CID_CODEC_BASE+394) +#define V4L2_CID_MPEG_VIDEO_H264_HIER_CODING_L4_BR (V4L2_CID_CODEC_BASE+395) +#define V4L2_CID_MPEG_VIDEO_H264_HIER_CODING_L5_BR (V4L2_CID_CODEC_BASE+396) +#define V4L2_CID_MPEG_VIDEO_H264_HIER_CODING_L6_BR (V4L2_CID_CODEC_BASE+397) #define V4L2_CID_MPEG_VIDEO_MPEG4_I_FRAME_QP (V4L2_CID_CODEC_BASE+400) #define V4L2_CID_MPEG_VIDEO_MPEG4_P_FRAME_QP (V4L2_CID_CODEC_BASE+401) #define V4L2_CID_MPEG_VIDEO_MPEG4_B_FRAME_QP (V4L2_CID_CODEC_BASE+402) -- cgit v1.2.3 From 6bde70da98f6b5f5dbd61d2fa9c1e7efe83b0402 Mon Sep 17 00:00:00 2001 From: Dikshita Agarwal Date: Mon, 4 Jan 2021 06:41:53 +0100 Subject: media: v4l2-ctrl: Add base layer priority id control. This control indicates the priority id to be applied to base layer. [hverkuil: renumbered V4L2_CID_MPEG_VIDEO_BASELAYER_PRIORITY_ID] Signed-off-by: Dikshita Agarwal Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst | 9 +++++++++ drivers/media/v4l2-core/v4l2-ctrls.c | 1 + include/uapi/linux/v4l2-controls.h | 1 + 3 files changed, 11 insertions(+) (limited to 'Documentation') diff --git a/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst b/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst index 400774ceffaa..00944e97d638 100644 --- a/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst +++ b/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst @@ -3637,3 +3637,12 @@ enum v4l2_mpeg_video_hevc_size_of_length_field - - Selecting this value specifies that HEVC slices are expected to be prefixed by Annex B start codes. According to :ref:`hevc` valid start codes can be 3-bytes 0x000001 or 4-bytes 0x00000001. + +``V4L2_CID_MPEG_VIDEO_BASELAYER_PRIORITY_ID (integer)`` + Specifies a priority identifier for the NAL unit, which will be applied to + the base layer. By default this value is set to 0 for the base layer, + and the next layer will have the priority ID assigned as 1, 2, 3 and so on. + The video encoder can't decide the priority id to be applied to a layer, + so this has to come from client. + This is applicable to H264 and valid Range is from 0 to 63. + Source Rec. ITU-T H.264 (06/2019); G.7.4.1.1, G.8.8.1. diff --git a/drivers/media/v4l2-core/v4l2-ctrls.c b/drivers/media/v4l2-core/v4l2-ctrls.c index 16ab54f676e2..f7b310240af2 100644 --- a/drivers/media/v4l2-core/v4l2-ctrls.c +++ b/drivers/media/v4l2-core/v4l2-ctrls.c @@ -950,6 +950,7 @@ const char *v4l2_ctrl_get_name(u32 id) case V4L2_CID_MPEG_VIDEO_MV_V_SEARCH_RANGE: return "Vertical MV Search Range"; case V4L2_CID_MPEG_VIDEO_REPEAT_SEQ_HEADER: return "Repeat Sequence Header"; case V4L2_CID_MPEG_VIDEO_FORCE_KEY_FRAME: return "Force Key Frame"; + case V4L2_CID_MPEG_VIDEO_BASELAYER_PRIORITY_ID: return "Base Layer Priority ID"; case V4L2_CID_MPEG_VIDEO_MPEG2_SLICE_PARAMS: return "MPEG-2 Slice Parameters"; case V4L2_CID_MPEG_VIDEO_MPEG2_QUANTIZATION: return "MPEG-2 Quantization Matrices"; case V4L2_CID_FWHT_I_FRAME_QP: return "FWHT I-Frame QP Value"; diff --git a/include/uapi/linux/v4l2-controls.h b/include/uapi/linux/v4l2-controls.h index 0bd967543357..039c0d7add1b 100644 --- a/include/uapi/linux/v4l2-controls.h +++ b/include/uapi/linux/v4l2-controls.h @@ -427,6 +427,7 @@ enum v4l2_mpeg_video_multi_slice_mode { #define V4L2_CID_MPEG_VIDEO_MV_H_SEARCH_RANGE (V4L2_CID_CODEC_BASE+227) #define V4L2_CID_MPEG_VIDEO_MV_V_SEARCH_RANGE (V4L2_CID_CODEC_BASE+228) #define V4L2_CID_MPEG_VIDEO_FORCE_KEY_FRAME (V4L2_CID_CODEC_BASE+229) +#define V4L2_CID_MPEG_VIDEO_BASELAYER_PRIORITY_ID (V4L2_CID_CODEC_BASE+230) /* CIDs for the MPEG-2 Part 2 (H.262) codec */ #define V4L2_CID_MPEG_VIDEO_MPEG2_LEVEL (V4L2_CID_CODEC_BASE+270) -- cgit v1.2.3 From e413c27e2ec8276ac0f25e7d1203f29adcfd8758 Mon Sep 17 00:00:00 2001 From: Yoshihiro Shimoda Date: Tue, 12 Jan 2021 18:00:57 +0900 Subject: dt-bindings: mfd: bd9571mwv: Document BD9574MWF Document other similar specification chip BD9574MWF. Signed-off-by: Yoshihiro Shimoda Acked-for-MFD-by: Lee Jones Signed-off-by: Lee Jones --- Documentation/devicetree/bindings/mfd/bd9571mwv.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/mfd/bd9571mwv.txt b/Documentation/devicetree/bindings/mfd/bd9571mwv.txt index 8c4678650d1a..1d6413e96c37 100644 --- a/Documentation/devicetree/bindings/mfd/bd9571mwv.txt +++ b/Documentation/devicetree/bindings/mfd/bd9571mwv.txt @@ -1,7 +1,7 @@ -* ROHM BD9571MWV Power Management Integrated Circuit (PMIC) bindings +* ROHM BD9571MWV/BD9574MWF Power Management Integrated Circuit (PMIC) bindings Required properties: - - compatible : Should be "rohm,bd9571mwv". + - compatible : Should be "rohm,bd9571mwv" or "rohm,bd9574mwf". - reg : I2C slave address. - interrupts : The interrupt line the device is connected to. - interrupt-controller : Marks the device node as an interrupt controller. -- cgit v1.2.3 From 5e6dca82bcaa49348f9e5fcb48df4881f6d6c4ae Mon Sep 17 00:00:00 2001 From: Nick Desaulniers Date: Tue, 12 Jan 2021 11:46:24 -0800 Subject: x86/entry: Emit a symbol for register restoring thunk Arnd found a randconfig that produces the warning: arch/x86/entry/thunk_64.o: warning: objtool: missing symbol for insn at offset 0x3e when building with LLVM_IAS=1 (Clang's integrated assembler). Josh notes: With the LLVM assembler not generating section symbols, objtool has no way to reference this code when it generates ORC unwinder entries, because this code is outside of any ELF function. The limitation now being imposed by objtool is that all code must be contained in an ELF symbol. And .L symbols don't create such symbols. So basically, you can use an .L symbol *inside* a function or a code segment, you just can't use the .L symbol to contain the code using a SYM_*_START/END annotation pair. Fangrui notes that this optimization is helpful for reducing image size when compiling with -ffunction-sections and -fdata-sections. I have observed on the order of tens of thousands of symbols for the kernel images built with those flags. A patch has been authored against GNU binutils to match this behavior of not generating unused section symbols ([1]), so this will also become a problem for users of GNU binutils once they upgrade to 2.36. Omit the .L prefix on a label so that the assembler will emit an entry into the symbol table for the label, with STB_LOCAL binding. This enables objtool to generate proper unwind info here with LLVM_IAS=1 or GNU binutils 2.36+. [ bp: Massage commit message. ] Reported-by: Arnd Bergmann Suggested-by: Josh Poimboeuf Suggested-by: Borislav Petkov Suggested-by: Mark Brown Signed-off-by: Nick Desaulniers Signed-off-by: Borislav Petkov Acked-by: Peter Zijlstra (Intel) Acked-by: Josh Poimboeuf Link: https://lkml.kernel.org/r/20210112194625.4181814-1-ndesaulniers@google.com Link: https://github.com/ClangBuiltLinux/linux/issues/1209 Link: https://reviews.llvm.org/D93783 Link: https://sourceware.org/binutils/docs/as/Symbol-Names.html Link: https://sourceware.org/git/?p=binutils-gdb.git;a=commit;h=d1bcae833b32f1408485ce69f844dcd7ded093a8 [1] --- Documentation/asm-annotations.rst | 5 +++++ arch/x86/entry/thunk_64.S | 8 ++++---- include/linux/linkage.h | 5 +++++ 3 files changed, 14 insertions(+), 4 deletions(-) (limited to 'Documentation') diff --git a/Documentation/asm-annotations.rst b/Documentation/asm-annotations.rst index 32ea57483378..76424e0431f4 100644 --- a/Documentation/asm-annotations.rst +++ b/Documentation/asm-annotations.rst @@ -100,6 +100,11 @@ Instruction Macros ~~~~~~~~~~~~~~~~~~ This section covers ``SYM_FUNC_*`` and ``SYM_CODE_*`` enumerated above. +``objtool`` requires that all code must be contained in an ELF symbol. Symbol +names that have a ``.L`` prefix do not emit symbol table entries. ``.L`` +prefixed symbols can be used within a code region, but should be avoided for +denoting a range of code via ``SYM_*_START/END`` annotations. + * ``SYM_FUNC_START`` and ``SYM_FUNC_START_LOCAL`` are supposed to be **the most frequent markings**. They are used for functions with standard calling conventions -- global and local. Like in C, they both align the functions to diff --git a/arch/x86/entry/thunk_64.S b/arch/x86/entry/thunk_64.S index ccd32877a3c4..c9a9fbf1655f 100644 --- a/arch/x86/entry/thunk_64.S +++ b/arch/x86/entry/thunk_64.S @@ -31,7 +31,7 @@ SYM_FUNC_START_NOALIGN(\name) .endif call \func - jmp .L_restore + jmp __thunk_restore SYM_FUNC_END(\name) _ASM_NOKPROBE(\name) .endm @@ -44,7 +44,7 @@ SYM_FUNC_END(\name) #endif #ifdef CONFIG_PREEMPTION -SYM_CODE_START_LOCAL_NOALIGN(.L_restore) +SYM_CODE_START_LOCAL_NOALIGN(__thunk_restore) popq %r11 popq %r10 popq %r9 @@ -56,6 +56,6 @@ SYM_CODE_START_LOCAL_NOALIGN(.L_restore) popq %rdi popq %rbp ret - _ASM_NOKPROBE(.L_restore) -SYM_CODE_END(.L_restore) + _ASM_NOKPROBE(__thunk_restore) +SYM_CODE_END(__thunk_restore) #endif diff --git a/include/linux/linkage.h b/include/linux/linkage.h index 5bcfbd972e97..dbf8506decca 100644 --- a/include/linux/linkage.h +++ b/include/linux/linkage.h @@ -178,6 +178,11 @@ * Objtool generates debug info for both FUNC & CODE, but needs special * annotations for each CODE's start (to describe the actual stack frame). * + * Objtool requires that all code must be contained in an ELF symbol. Symbol + * names that have a .L prefix do not emit symbol table entries. .L + * prefixed symbols can be used within a code region, but should be avoided for + * denoting a range of code via ``SYM_*_START/END`` annotations. + * * ALIAS -- does not generate debug info -- the aliased function will */ -- cgit v1.2.3 From 20612d2428c3cdd191d45d548e930f41785f62cc Mon Sep 17 00:00:00 2001 From: Lukas Bulwahn Date: Mon, 11 Jan 2021 12:21:13 +0100 Subject: fpga: dfl-pci: rectify ReST formatting Commit fa41d10589be ("fpga: dfl-pci: locate DFLs by PCIe vendor specific capability") provides documentation to the FPGA Device Feature List (DFL) Framework Overview, but introduced new documentation warnings: ./Documentation/fpga/dfl.rst: 505: WARNING: Title underline too short. 523: WARNING: Unexpected indentation. 523: WARNING: Blank line required after table. 524: WARNING: Block quote ends without a blank line; unexpected unindent. Rectify ReST formatting in ./Documentation/fpga/dfl.rst. Tested-by: Tom Rix Acked-by: Moritz Fischer Acked-by: Matthew Gerlach Signed-off-by: Lukas Bulwahn Link: https://lore.kernel.org/r/20210111112113.27242-1-lukas.bulwahn@gmail.com Signed-off-by: Greg Kroah-Hartman --- Documentation/fpga/dfl.rst | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'Documentation') diff --git a/Documentation/fpga/dfl.rst b/Documentation/fpga/dfl.rst index ea8cefc18bdb..c41ac76ffaae 100644 --- a/Documentation/fpga/dfl.rst +++ b/Documentation/fpga/dfl.rst @@ -502,7 +502,7 @@ FME Partial Reconfiguration Sub Feature driver (see drivers/fpga/dfl-fme-pr.c) could be a reference. Location of DFLs on a PCI Device -=========================== +================================ The original method for finding a DFL on a PCI device assumed the start of the first DFL to offset 0 of bar 0. If the first node of the DFL is an FME, then further DFLs in the port(s) are specified in FME header registers. @@ -514,6 +514,7 @@ data begins with a 4 byte vendor specific register for the number of DFLs follow Offset/BIR vendor specific registers for each DFL. Bits 2:0 of Offset/BIR register indicates the BAR, and bits 31:3 form the 8 byte aligned offset where bits 2:0 are zero. +:: +----------------------------+ |31 Number of DFLS 0| -- cgit v1.2.3 From 23fb08e72a0e3cb0509337e3322a7b57d73fbb82 Mon Sep 17 00:00:00 2001 From: Damien Le Moal Date: Sun, 13 Dec 2020 22:50:45 +0900 Subject: dt-binding: mfd: Document canaan,k210-sysctl bindings Document the device tree bindings of the Canaan Kendryte K210 SoC system controller driver in Documentation/devicetree/bindings/mfd/canaan,k210-sysctl.yaml. Signed-off-by: Damien Le Moal Reviewed-by: Rob Herring Signed-off-by: Palmer Dabbelt --- .../bindings/mfd/canaan,k210-sysctl.yaml | 109 +++++++++++++++++++++ 1 file changed, 109 insertions(+) create mode 100644 Documentation/devicetree/bindings/mfd/canaan,k210-sysctl.yaml (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/mfd/canaan,k210-sysctl.yaml b/Documentation/devicetree/bindings/mfd/canaan,k210-sysctl.yaml new file mode 100644 index 000000000000..c24ad45cabb5 --- /dev/null +++ b/Documentation/devicetree/bindings/mfd/canaan,k210-sysctl.yaml @@ -0,0 +1,109 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/mfd/canaan,k210-sysctl.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Canaan Kendryte K210 System Controller Device Tree Bindings + +maintainers: + - Damien Le Moal + +description: + Canaan Inc. Kendryte K210 SoC system controller which provides a + register map for controlling the clocks, reset signals and pin power + domains of the SoC. + +properties: + compatible: + items: + - const: canaan,k210-sysctl + - const: syscon + - const: simple-mfd + + clocks: + maxItems: 1 + description: + System controller Advanced Power Bus (APB) interface clock source. + + clock-names: + items: + - const: pclk + + reg: + maxItems: 1 + + clock-controller: + # Child node + type: object + $ref: "../clock/canaan,k210-clk.yaml" + description: + Clock controller for the SoC clocks. This child node definition + should follow the bindings specified in + Documentation/devicetree/bindings/clock/canaan,k210-clk.yaml. + + reset-controller: + # Child node + type: object + $ref: "../reset/canaan,k210-rst.yaml" + description: + Reset controller for the SoC. This child node definition + should follow the bindings specified in + Documentation/devicetree/bindings/reset/canaan,k210-rst.yaml. + + syscon-reboot: + # Child node + type: object + $ref: "../power/reset/syscon-reboot.yaml" + description: + Reboot method for the SoC. This child node definition + should follow the bindings specified in + Documentation/devicetree/bindings/power/reset/syscon-reboot.yaml. + +required: + - compatible + - clocks + - reg + - clock-controller + +additionalProperties: false + +examples: + - | + #include + #include + + clocks { + in0: oscllator { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <26000000>; + }; + }; + + sysctl: syscon@50440000 { + compatible = "canaan,k210-sysctl", + "syscon", "simple-mfd"; + reg = <0x50440000 0x100>; + clocks = <&sysclk K210_CLK_APB1>; + clock-names = "pclk"; + + sysclk: clock-controller { + #clock-cells = <1>; + compatible = "canaan,k210-clk"; + clocks = <&in0>; + }; + + sysrst: reset-controller { + compatible = "canaan,k210-rst"; + #reset-cells = <1>; + }; + + reboot: syscon-reboot { + compatible = "syscon-reboot"; + regmap = <&sysctl>; + offset = <48>; + mask = <1>; + value = <1>; + }; + }; -- cgit v1.2.3 From 1d7c9d093ed58b8cf4ae23986cd01272667d412a Mon Sep 17 00:00:00 2001 From: Damien Le Moal Date: Sun, 13 Dec 2020 22:50:43 +0900 Subject: dt-bindings: reset: Document canaan,k210-rst bindings Document the device tree bindings for the Canaan Kendryte K210 SoC reset controller driver in Documentation/devicetree/bindings/reset/canaan,k210-rst.yaml. The header file include/dt-bindings/reset/k210-rst.h is added to define all possible reset lines of the SoC. Signed-off-by: Damien Le Moal Reviewed-by: Rob Herring Signed-off-by: Palmer Dabbelt --- .../devicetree/bindings/reset/canaan,k210-rst.yaml | 40 +++++++++++++++++++++ include/dt-bindings/reset/k210-rst.h | 42 ++++++++++++++++++++++ 2 files changed, 82 insertions(+) create mode 100644 Documentation/devicetree/bindings/reset/canaan,k210-rst.yaml create mode 100644 include/dt-bindings/reset/k210-rst.h (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/reset/canaan,k210-rst.yaml b/Documentation/devicetree/bindings/reset/canaan,k210-rst.yaml new file mode 100644 index 000000000000..53e4ede9c0bd --- /dev/null +++ b/Documentation/devicetree/bindings/reset/canaan,k210-rst.yaml @@ -0,0 +1,40 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/reset/canaan,k210-rst.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Canaan Kendryte K210 Reset Controller Device Tree Bindings + +maintainers: + - Damien Le Moal + +description: | + Canaan Kendryte K210 reset controller driver which supports the SoC + system controller supplied reset registers for the various peripherals + of the SoC. The K210 reset controller node must be defined as a child + node of the K210 system controller node. + + See also: + - dt-bindings/reset/k210-rst.h + +properties: + compatible: + const: canaan,k210-rst + + '#reset-cells': + const: 1 + +required: + - '#reset-cells' + - compatible + +additionalProperties: false + +examples: + - | + #include + sysrst: reset-controller { + compatible = "canaan,k210-rst"; + #reset-cells = <1>; + }; diff --git a/include/dt-bindings/reset/k210-rst.h b/include/dt-bindings/reset/k210-rst.h new file mode 100644 index 000000000000..883c1aed50e8 --- /dev/null +++ b/include/dt-bindings/reset/k210-rst.h @@ -0,0 +1,42 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright (C) 2019 Sean Anderson + * Copyright (c) 2020 Western Digital Corporation or its affiliates. + */ +#ifndef RESET_K210_SYSCTL_H +#define RESET_K210_SYSCTL_H + +/* + * Kendryte K210 SoC system controller K210_SYSCTL_SOFT_RESET register bits. + * Taken from Kendryte SDK (kendryte-standalone-sdk). + */ +#define K210_RST_ROM 0 +#define K210_RST_DMA 1 +#define K210_RST_AI 2 +#define K210_RST_DVP 3 +#define K210_RST_FFT 4 +#define K210_RST_GPIO 5 +#define K210_RST_SPI0 6 +#define K210_RST_SPI1 7 +#define K210_RST_SPI2 8 +#define K210_RST_SPI3 9 +#define K210_RST_I2S0 10 +#define K210_RST_I2S1 11 +#define K210_RST_I2S2 12 +#define K210_RST_I2C0 13 +#define K210_RST_I2C1 14 +#define K210_RST_I2C2 15 +#define K210_RST_UART1 16 +#define K210_RST_UART2 17 +#define K210_RST_UART3 18 +#define K210_RST_AES 19 +#define K210_RST_FPIOA 20 +#define K210_RST_TIMER0 21 +#define K210_RST_TIMER1 22 +#define K210_RST_TIMER2 23 +#define K210_RST_WDT0 24 +#define K210_RST_WDT1 25 +#define K210_RST_SHA 26 +#define K210_RST_RTC 29 + +#endif /* RESET_K210_SYSCTL_H */ -- cgit v1.2.3 From ed3137edb31b86702511e7ad12b4abe8686b6805 Mon Sep 17 00:00:00 2001 From: Damien Le Moal Date: Sun, 13 Dec 2020 22:50:44 +0900 Subject: dt-bindings: pinctrl: Document canaan,k210-fpioa bindings Document the device tree bindings for the Canaan Kendryte K210 SoC Fully Programmable IO Array (FPIOA) pinctrl driver in Documentation/devicetree/bindings/pinctrl/canaan,k210-fpioa.yaml. The new header file include/dt-bindings/pinctrl/k210-fpioa.h is added to define all 256 possible pin functions of the SoC IO pins, as well as macros simplifying the definition of pin functions in a device tree. Signed-off-by: Damien Le Moal Reviewed-by: Rob Herring Signed-off-by: Palmer Dabbelt --- .../bindings/pinctrl/canaan,k210-fpioa.yaml | 171 +++++++++++++ include/dt-bindings/pinctrl/k210-fpioa.h | 276 +++++++++++++++++++++ 2 files changed, 447 insertions(+) create mode 100644 Documentation/devicetree/bindings/pinctrl/canaan,k210-fpioa.yaml create mode 100644 include/dt-bindings/pinctrl/k210-fpioa.h (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/pinctrl/canaan,k210-fpioa.yaml b/Documentation/devicetree/bindings/pinctrl/canaan,k210-fpioa.yaml new file mode 100644 index 000000000000..46fbc73ab26b --- /dev/null +++ b/Documentation/devicetree/bindings/pinctrl/canaan,k210-fpioa.yaml @@ -0,0 +1,171 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/pinctrl/canaan,k210-fpioa.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Canaan Kendryte K210 FPIOA Device Tree Bindings + +maintainers: + - Damien Le Moal + +description: + The Canaan Kendryte K210 SoC Fully Programmable IO Array (FPIOA) + controller allows assiging any of 256 possible functions to any of + 48 IO pins of the SoC. Pin function configuration is performed on + a per-pin basis. + +properties: + compatible: + const: canaan,k210-fpioa + + reg: + maxItems: 1 + description: + Address and length of the register set for the FPIOA controller. + + clocks: + items: + - description: Controller reference clock source + - description: APB interface clock source + + clock-names: + items: + - const: ref + - const: pclk + + resets: + maxItems: 1 + + canaan,k210-sysctl-power: + $ref: /schemas/types.yaml#/definitions/phandle-array + description: | + phandle of the K210 system controller node and offset of its + power domain control register. + +patternProperties: + '-pinmux$': + type: object + $ref: /schemas/pinctrl/pinmux-node.yaml + description: + FPIOA client devices use sub-nodes to define the desired pin + configuration. Client device sub-nodes use the pinux property + below. + + properties: + pinmux: + description: + List of IO pins alternate functions. The values for each IO + pin is a combination of an IO pin number (0 to 47) with the + desired function for the IO pin. Functions are defined as + macros in include/dt-bindings/pinctrl/k210-fpioa.h. + The K210_FPIOA(IO pin, function) macro is provided to + facilitate the combination of IO pin numbers and functions. + + required: + - pinmux + + additionalProperties: false + + '-pins$': + type: object + $ref: /schemas/pinctrl/pincfg-node.yaml + description: + FPIOA client devices use sub-nodes to define the desired + configuration of pins. Client device sub-nodes use the + properties below. + + properties: + pins: + description: + List of IO pins affected by the properties specified in this + subnode. IO pins are identified using the pin names "IO_xx". + Pin configuration nodes can also define the power domain to + be used for the SoC pin groups A0 (IO pins 0-5), + A1 (IO pins 6-11), A2 (IO pins 12-17), B0 (IO pins 18-23), + B1 (IO pins 24-29), B2 (IO pins 30-35), B3 (IO pins 30-35), + C0 (IO pins 36-41) and C1 (IO pins 42-47) using the + power-source property. + items: + anyOf: + - pattern: "^(IO_([0-9]*))|(A[0-2])|(B[3-5])|(C[6-7])$" + - enum: [ IO_0, IO_1, IO_2, IO_3, IO_4, IO_5, IO_6, IO_7, + IO_8, IO_9, IO_10, IO_11, IO_12, IO_13, IO_14, + IO_15, IO_16, IO_17, IO_18, IO_19, IO_20, IO_21, + IO_22, IO_23, IO_24, IO_25, IO_26, IO_27, IO_28, + IO_29, IO_30, IO_31, IO_32, IO_33, IO_34, IO_35, + IO_36, IO_37, IO_38, IO_39, IO_40, IO_41, IO_42, + IO_43, IO_44, IO_45, IO_46, IO_47, + A0, A1, A2, B3, B4, B5, C6, C7 ] + bias-disable: true + + bias-pull-down: true + + bias-pull-up: true + + drive-strength: true + + drive-strength-microamp: true + + input-enable: true + + input-disable: true + + input-schmitt-enable: true + + input-schmitt-disable: true + + input-polarity-invert: + description: + Enable or disable pin input polarity inversion. + + output-enable: true + + output-disable: true + + output-high: true + + output-low: true + + output-polarity-invert: + description: + Enable or disable pin output polarity inversion. + + slew-rate: true + + power-source: true + + additionalProperties: false + +required: + - compatible + - reg + - clocks + - canaan,k210-sysctl-power + +additionalProperties: false + +examples: + - | + #include + #include + #include + + fpioa: pinmux@502B0000 { + compatible = "canaan,k210-fpioa"; + reg = <0x502B0000 0x100>; + clocks = <&sysclk K210_CLK_FPIOA>, + <&sysclk K210_CLK_APB0>; + clock-names = "ref", "pclk"; + resets = <&sysrst K210_RST_FPIOA>; + canaan,k210-sysctl-power = <&sysctl 108>; + pinctrl-0 = <&jtag_pinctrl>; + pinctrl-names = "default"; + + jtag_pinctrl: jtag-pinmux { + pinmux = , + , + , + ; + }; + }; diff --git a/include/dt-bindings/pinctrl/k210-fpioa.h b/include/dt-bindings/pinctrl/k210-fpioa.h new file mode 100644 index 000000000000..314285eab3a1 --- /dev/null +++ b/include/dt-bindings/pinctrl/k210-fpioa.h @@ -0,0 +1,276 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright (C) 2020 Sean Anderson + * Copyright (c) 2020 Western Digital Corporation or its affiliates. + */ +#ifndef PINCTRL_K210_FPIOA_H +#define PINCTRL_K210_FPIOA_H + +/* + * Full list of FPIOA functions from + * kendryte-standalone-sdk/lib/drivers/include/fpioa.h + */ +#define K210_PCF_MASK GENMASK(7, 0) +#define K210_PCF_JTAG_TCLK 0 /* JTAG Test Clock */ +#define K210_PCF_JTAG_TDI 1 /* JTAG Test Data In */ +#define K210_PCF_JTAG_TMS 2 /* JTAG Test Mode Select */ +#define K210_PCF_JTAG_TDO 3 /* JTAG Test Data Out */ +#define K210_PCF_SPI0_D0 4 /* SPI0 Data 0 */ +#define K210_PCF_SPI0_D1 5 /* SPI0 Data 1 */ +#define K210_PCF_SPI0_D2 6 /* SPI0 Data 2 */ +#define K210_PCF_SPI0_D3 7 /* SPI0 Data 3 */ +#define K210_PCF_SPI0_D4 8 /* SPI0 Data 4 */ +#define K210_PCF_SPI0_D5 9 /* SPI0 Data 5 */ +#define K210_PCF_SPI0_D6 10 /* SPI0 Data 6 */ +#define K210_PCF_SPI0_D7 11 /* SPI0 Data 7 */ +#define K210_PCF_SPI0_SS0 12 /* SPI0 Chip Select 0 */ +#define K210_PCF_SPI0_SS1 13 /* SPI0 Chip Select 1 */ +#define K210_PCF_SPI0_SS2 14 /* SPI0 Chip Select 2 */ +#define K210_PCF_SPI0_SS3 15 /* SPI0 Chip Select 3 */ +#define K210_PCF_SPI0_ARB 16 /* SPI0 Arbitration */ +#define K210_PCF_SPI0_SCLK 17 /* SPI0 Serial Clock */ +#define K210_PCF_UARTHS_RX 18 /* UART High speed Receiver */ +#define K210_PCF_UARTHS_TX 19 /* UART High speed Transmitter */ +#define K210_PCF_RESV6 20 /* Reserved function */ +#define K210_PCF_RESV7 21 /* Reserved function */ +#define K210_PCF_CLK_SPI1 22 /* Clock SPI1 */ +#define K210_PCF_CLK_I2C1 23 /* Clock I2C1 */ +#define K210_PCF_GPIOHS0 24 /* GPIO High speed 0 */ +#define K210_PCF_GPIOHS1 25 /* GPIO High speed 1 */ +#define K210_PCF_GPIOHS2 26 /* GPIO High speed 2 */ +#define K210_PCF_GPIOHS3 27 /* GPIO High speed 3 */ +#define K210_PCF_GPIOHS4 28 /* GPIO High speed 4 */ +#define K210_PCF_GPIOHS5 29 /* GPIO High speed 5 */ +#define K210_PCF_GPIOHS6 30 /* GPIO High speed 6 */ +#define K210_PCF_GPIOHS7 31 /* GPIO High speed 7 */ +#define K210_PCF_GPIOHS8 32 /* GPIO High speed 8 */ +#define K210_PCF_GPIOHS9 33 /* GPIO High speed 9 */ +#define K210_PCF_GPIOHS10 34 /* GPIO High speed 10 */ +#define K210_PCF_GPIOHS11 35 /* GPIO High speed 11 */ +#define K210_PCF_GPIOHS12 36 /* GPIO High speed 12 */ +#define K210_PCF_GPIOHS13 37 /* GPIO High speed 13 */ +#define K210_PCF_GPIOHS14 38 /* GPIO High speed 14 */ +#define K210_PCF_GPIOHS15 39 /* GPIO High speed 15 */ +#define K210_PCF_GPIOHS16 40 /* GPIO High speed 16 */ +#define K210_PCF_GPIOHS17 41 /* GPIO High speed 17 */ +#define K210_PCF_GPIOHS18 42 /* GPIO High speed 18 */ +#define K210_PCF_GPIOHS19 43 /* GPIO High speed 19 */ +#define K210_PCF_GPIOHS20 44 /* GPIO High speed 20 */ +#define K210_PCF_GPIOHS21 45 /* GPIO High speed 21 */ +#define K210_PCF_GPIOHS22 46 /* GPIO High speed 22 */ +#define K210_PCF_GPIOHS23 47 /* GPIO High speed 23 */ +#define K210_PCF_GPIOHS24 48 /* GPIO High speed 24 */ +#define K210_PCF_GPIOHS25 49 /* GPIO High speed 25 */ +#define K210_PCF_GPIOHS26 50 /* GPIO High speed 26 */ +#define K210_PCF_GPIOHS27 51 /* GPIO High speed 27 */ +#define K210_PCF_GPIOHS28 52 /* GPIO High speed 28 */ +#define K210_PCF_GPIOHS29 53 /* GPIO High speed 29 */ +#define K210_PCF_GPIOHS30 54 /* GPIO High speed 30 */ +#define K210_PCF_GPIOHS31 55 /* GPIO High speed 31 */ +#define K210_PCF_GPIO0 56 /* GPIO pin 0 */ +#define K210_PCF_GPIO1 57 /* GPIO pin 1 */ +#define K210_PCF_GPIO2 58 /* GPIO pin 2 */ +#define K210_PCF_GPIO3 59 /* GPIO pin 3 */ +#define K210_PCF_GPIO4 60 /* GPIO pin 4 */ +#define K210_PCF_GPIO5 61 /* GPIO pin 5 */ +#define K210_PCF_GPIO6 62 /* GPIO pin 6 */ +#define K210_PCF_GPIO7 63 /* GPIO pin 7 */ +#define K210_PCF_UART1_RX 64 /* UART1 Receiver */ +#define K210_PCF_UART1_TX 65 /* UART1 Transmitter */ +#define K210_PCF_UART2_RX 66 /* UART2 Receiver */ +#define K210_PCF_UART2_TX 67 /* UART2 Transmitter */ +#define K210_PCF_UART3_RX 68 /* UART3 Receiver */ +#define K210_PCF_UART3_TX 69 /* UART3 Transmitter */ +#define K210_PCF_SPI1_D0 70 /* SPI1 Data 0 */ +#define K210_PCF_SPI1_D1 71 /* SPI1 Data 1 */ +#define K210_PCF_SPI1_D2 72 /* SPI1 Data 2 */ +#define K210_PCF_SPI1_D3 73 /* SPI1 Data 3 */ +#define K210_PCF_SPI1_D4 74 /* SPI1 Data 4 */ +#define K210_PCF_SPI1_D5 75 /* SPI1 Data 5 */ +#define K210_PCF_SPI1_D6 76 /* SPI1 Data 6 */ +#define K210_PCF_SPI1_D7 77 /* SPI1 Data 7 */ +#define K210_PCF_SPI1_SS0 78 /* SPI1 Chip Select 0 */ +#define K210_PCF_SPI1_SS1 79 /* SPI1 Chip Select 1 */ +#define K210_PCF_SPI1_SS2 80 /* SPI1 Chip Select 2 */ +#define K210_PCF_SPI1_SS3 81 /* SPI1 Chip Select 3 */ +#define K210_PCF_SPI1_ARB 82 /* SPI1 Arbitration */ +#define K210_PCF_SPI1_SCLK 83 /* SPI1 Serial Clock */ +#define K210_PCF_SPI2_D0 84 /* SPI2 Data 0 */ +#define K210_PCF_SPI2_SS 85 /* SPI2 Select */ +#define K210_PCF_SPI2_SCLK 86 /* SPI2 Serial Clock */ +#define K210_PCF_I2S0_MCLK 87 /* I2S0 Master Clock */ +#define K210_PCF_I2S0_SCLK 88 /* I2S0 Serial Clock(BCLK) */ +#define K210_PCF_I2S0_WS 89 /* I2S0 Word Select(LRCLK) */ +#define K210_PCF_I2S0_IN_D0 90 /* I2S0 Serial Data Input 0 */ +#define K210_PCF_I2S0_IN_D1 91 /* I2S0 Serial Data Input 1 */ +#define K210_PCF_I2S0_IN_D2 92 /* I2S0 Serial Data Input 2 */ +#define K210_PCF_I2S0_IN_D3 93 /* I2S0 Serial Data Input 3 */ +#define K210_PCF_I2S0_OUT_D0 94 /* I2S0 Serial Data Output 0 */ +#define K210_PCF_I2S0_OUT_D1 95 /* I2S0 Serial Data Output 1 */ +#define K210_PCF_I2S0_OUT_D2 96 /* I2S0 Serial Data Output 2 */ +#define K210_PCF_I2S0_OUT_D3 97 /* I2S0 Serial Data Output 3 */ +#define K210_PCF_I2S1_MCLK 98 /* I2S1 Master Clock */ +#define K210_PCF_I2S1_SCLK 99 /* I2S1 Serial Clock(BCLK) */ +#define K210_PCF_I2S1_WS 100 /* I2S1 Word Select(LRCLK) */ +#define K210_PCF_I2S1_IN_D0 101 /* I2S1 Serial Data Input 0 */ +#define K210_PCF_I2S1_IN_D1 102 /* I2S1 Serial Data Input 1 */ +#define K210_PCF_I2S1_IN_D2 103 /* I2S1 Serial Data Input 2 */ +#define K210_PCF_I2S1_IN_D3 104 /* I2S1 Serial Data Input 3 */ +#define K210_PCF_I2S1_OUT_D0 105 /* I2S1 Serial Data Output 0 */ +#define K210_PCF_I2S1_OUT_D1 106 /* I2S1 Serial Data Output 1 */ +#define K210_PCF_I2S1_OUT_D2 107 /* I2S1 Serial Data Output 2 */ +#define K210_PCF_I2S1_OUT_D3 108 /* I2S1 Serial Data Output 3 */ +#define K210_PCF_I2S2_MCLK 109 /* I2S2 Master Clock */ +#define K210_PCF_I2S2_SCLK 110 /* I2S2 Serial Clock(BCLK) */ +#define K210_PCF_I2S2_WS 111 /* I2S2 Word Select(LRCLK) */ +#define K210_PCF_I2S2_IN_D0 112 /* I2S2 Serial Data Input 0 */ +#define K210_PCF_I2S2_IN_D1 113 /* I2S2 Serial Data Input 1 */ +#define K210_PCF_I2S2_IN_D2 114 /* I2S2 Serial Data Input 2 */ +#define K210_PCF_I2S2_IN_D3 115 /* I2S2 Serial Data Input 3 */ +#define K210_PCF_I2S2_OUT_D0 116 /* I2S2 Serial Data Output 0 */ +#define K210_PCF_I2S2_OUT_D1 117 /* I2S2 Serial Data Output 1 */ +#define K210_PCF_I2S2_OUT_D2 118 /* I2S2 Serial Data Output 2 */ +#define K210_PCF_I2S2_OUT_D3 119 /* I2S2 Serial Data Output 3 */ +#define K210_PCF_RESV0 120 /* Reserved function */ +#define K210_PCF_RESV1 121 /* Reserved function */ +#define K210_PCF_RESV2 122 /* Reserved function */ +#define K210_PCF_RESV3 123 /* Reserved function */ +#define K210_PCF_RESV4 124 /* Reserved function */ +#define K210_PCF_RESV5 125 /* Reserved function */ +#define K210_PCF_I2C0_SCLK 126 /* I2C0 Serial Clock */ +#define K210_PCF_I2C0_SDA 127 /* I2C0 Serial Data */ +#define K210_PCF_I2C1_SCLK 128 /* I2C1 Serial Clock */ +#define K210_PCF_I2C1_SDA 129 /* I2C1 Serial Data */ +#define K210_PCF_I2C2_SCLK 130 /* I2C2 Serial Clock */ +#define K210_PCF_I2C2_SDA 131 /* I2C2 Serial Data */ +#define K210_PCF_DVP_XCLK 132 /* DVP System Clock */ +#define K210_PCF_DVP_RST 133 /* DVP System Reset */ +#define K210_PCF_DVP_PWDN 134 /* DVP Power Down Mode */ +#define K210_PCF_DVP_VSYNC 135 /* DVP Vertical Sync */ +#define K210_PCF_DVP_HSYNC 136 /* DVP Horizontal Sync */ +#define K210_PCF_DVP_PCLK 137 /* Pixel Clock */ +#define K210_PCF_DVP_D0 138 /* Data Bit 0 */ +#define K210_PCF_DVP_D1 139 /* Data Bit 1 */ +#define K210_PCF_DVP_D2 140 /* Data Bit 2 */ +#define K210_PCF_DVP_D3 141 /* Data Bit 3 */ +#define K210_PCF_DVP_D4 142 /* Data Bit 4 */ +#define K210_PCF_DVP_D5 143 /* Data Bit 5 */ +#define K210_PCF_DVP_D6 144 /* Data Bit 6 */ +#define K210_PCF_DVP_D7 145 /* Data Bit 7 */ +#define K210_PCF_SCCB_SCLK 146 /* Serial Camera Control Bus Clock */ +#define K210_PCF_SCCB_SDA 147 /* Serial Camera Control Bus Data */ +#define K210_PCF_UART1_CTS 148 /* UART1 Clear To Send */ +#define K210_PCF_UART1_DSR 149 /* UART1 Data Set Ready */ +#define K210_PCF_UART1_DCD 150 /* UART1 Data Carrier Detect */ +#define K210_PCF_UART1_RI 151 /* UART1 Ring Indicator */ +#define K210_PCF_UART1_SIR_IN 152 /* UART1 Serial Infrared Input */ +#define K210_PCF_UART1_DTR 153 /* UART1 Data Terminal Ready */ +#define K210_PCF_UART1_RTS 154 /* UART1 Request To Send */ +#define K210_PCF_UART1_OUT2 155 /* UART1 User-designated Output 2 */ +#define K210_PCF_UART1_OUT1 156 /* UART1 User-designated Output 1 */ +#define K210_PCF_UART1_SIR_OUT 157 /* UART1 Serial Infrared Output */ +#define K210_PCF_UART1_BAUD 158 /* UART1 Transmit Clock Output */ +#define K210_PCF_UART1_RE 159 /* UART1 Receiver Output Enable */ +#define K210_PCF_UART1_DE 160 /* UART1 Driver Output Enable */ +#define K210_PCF_UART1_RS485_EN 161 /* UART1 RS485 Enable */ +#define K210_PCF_UART2_CTS 162 /* UART2 Clear To Send */ +#define K210_PCF_UART2_DSR 163 /* UART2 Data Set Ready */ +#define K210_PCF_UART2_DCD 164 /* UART2 Data Carrier Detect */ +#define K210_PCF_UART2_RI 165 /* UART2 Ring Indicator */ +#define K210_PCF_UART2_SIR_IN 166 /* UART2 Serial Infrared Input */ +#define K210_PCF_UART2_DTR 167 /* UART2 Data Terminal Ready */ +#define K210_PCF_UART2_RTS 168 /* UART2 Request To Send */ +#define K210_PCF_UART2_OUT2 169 /* UART2 User-designated Output 2 */ +#define K210_PCF_UART2_OUT1 170 /* UART2 User-designated Output 1 */ +#define K210_PCF_UART2_SIR_OUT 171 /* UART2 Serial Infrared Output */ +#define K210_PCF_UART2_BAUD 172 /* UART2 Transmit Clock Output */ +#define K210_PCF_UART2_RE 173 /* UART2 Receiver Output Enable */ +#define K210_PCF_UART2_DE 174 /* UART2 Driver Output Enable */ +#define K210_PCF_UART2_RS485_EN 175 /* UART2 RS485 Enable */ +#define K210_PCF_UART3_CTS 176 /* UART3 Clear To Send */ +#define K210_PCF_UART3_DSR 177 /* UART3 Data Set Ready */ +#define K210_PCF_UART3_DCD 178 /* UART3 Data Carrier Detect */ +#define K210_PCF_UART3_RI 179 /* UART3 Ring Indicator */ +#define K210_PCF_UART3_SIR_IN 180 /* UART3 Serial Infrared Input */ +#define K210_PCF_UART3_DTR 181 /* UART3 Data Terminal Ready */ +#define K210_PCF_UART3_RTS 182 /* UART3 Request To Send */ +#define K210_PCF_UART3_OUT2 183 /* UART3 User-designated Output 2 */ +#define K210_PCF_UART3_OUT1 184 /* UART3 User-designated Output 1 */ +#define K210_PCF_UART3_SIR_OUT 185 /* UART3 Serial Infrared Output */ +#define K210_PCF_UART3_BAUD 186 /* UART3 Transmit Clock Output */ +#define K210_PCF_UART3_RE 187 /* UART3 Receiver Output Enable */ +#define K210_PCF_UART3_DE 188 /* UART3 Driver Output Enable */ +#define K210_PCF_UART3_RS485_EN 189 /* UART3 RS485 Enable */ +#define K210_PCF_TIMER0_TOGGLE1 190 /* TIMER0 Toggle Output 1 */ +#define K210_PCF_TIMER0_TOGGLE2 191 /* TIMER0 Toggle Output 2 */ +#define K210_PCF_TIMER0_TOGGLE3 192 /* TIMER0 Toggle Output 3 */ +#define K210_PCF_TIMER0_TOGGLE4 193 /* TIMER0 Toggle Output 4 */ +#define K210_PCF_TIMER1_TOGGLE1 194 /* TIMER1 Toggle Output 1 */ +#define K210_PCF_TIMER1_TOGGLE2 195 /* TIMER1 Toggle Output 2 */ +#define K210_PCF_TIMER1_TOGGLE3 196 /* TIMER1 Toggle Output 3 */ +#define K210_PCF_TIMER1_TOGGLE4 197 /* TIMER1 Toggle Output 4 */ +#define K210_PCF_TIMER2_TOGGLE1 198 /* TIMER2 Toggle Output 1 */ +#define K210_PCF_TIMER2_TOGGLE2 199 /* TIMER2 Toggle Output 2 */ +#define K210_PCF_TIMER2_TOGGLE3 200 /* TIMER2 Toggle Output 3 */ +#define K210_PCF_TIMER2_TOGGLE4 201 /* TIMER2 Toggle Output 4 */ +#define K210_PCF_CLK_SPI2 202 /* Clock SPI2 */ +#define K210_PCF_CLK_I2C2 203 /* Clock I2C2 */ +#define K210_PCF_INTERNAL0 204 /* Internal function signal 0 */ +#define K210_PCF_INTERNAL1 205 /* Internal function signal 1 */ +#define K210_PCF_INTERNAL2 206 /* Internal function signal 2 */ +#define K210_PCF_INTERNAL3 207 /* Internal function signal 3 */ +#define K210_PCF_INTERNAL4 208 /* Internal function signal 4 */ +#define K210_PCF_INTERNAL5 209 /* Internal function signal 5 */ +#define K210_PCF_INTERNAL6 210 /* Internal function signal 6 */ +#define K210_PCF_INTERNAL7 211 /* Internal function signal 7 */ +#define K210_PCF_INTERNAL8 212 /* Internal function signal 8 */ +#define K210_PCF_INTERNAL9 213 /* Internal function signal 9 */ +#define K210_PCF_INTERNAL10 214 /* Internal function signal 10 */ +#define K210_PCF_INTERNAL11 215 /* Internal function signal 11 */ +#define K210_PCF_INTERNAL12 216 /* Internal function signal 12 */ +#define K210_PCF_INTERNAL13 217 /* Internal function signal 13 */ +#define K210_PCF_INTERNAL14 218 /* Internal function signal 14 */ +#define K210_PCF_INTERNAL15 219 /* Internal function signal 15 */ +#define K210_PCF_INTERNAL16 220 /* Internal function signal 16 */ +#define K210_PCF_INTERNAL17 221 /* Internal function signal 17 */ +#define K210_PCF_CONSTANT 222 /* Constant function */ +#define K210_PCF_INTERNAL18 223 /* Internal function signal 18 */ +#define K210_PCF_DEBUG0 224 /* Debug function 0 */ +#define K210_PCF_DEBUG1 225 /* Debug function 1 */ +#define K210_PCF_DEBUG2 226 /* Debug function 2 */ +#define K210_PCF_DEBUG3 227 /* Debug function 3 */ +#define K210_PCF_DEBUG4 228 /* Debug function 4 */ +#define K210_PCF_DEBUG5 229 /* Debug function 5 */ +#define K210_PCF_DEBUG6 230 /* Debug function 6 */ +#define K210_PCF_DEBUG7 231 /* Debug function 7 */ +#define K210_PCF_DEBUG8 232 /* Debug function 8 */ +#define K210_PCF_DEBUG9 233 /* Debug function 9 */ +#define K210_PCF_DEBUG10 234 /* Debug function 10 */ +#define K210_PCF_DEBUG11 235 /* Debug function 11 */ +#define K210_PCF_DEBUG12 236 /* Debug function 12 */ +#define K210_PCF_DEBUG13 237 /* Debug function 13 */ +#define K210_PCF_DEBUG14 238 /* Debug function 14 */ +#define K210_PCF_DEBUG15 239 /* Debug function 15 */ +#define K210_PCF_DEBUG16 240 /* Debug function 16 */ +#define K210_PCF_DEBUG17 241 /* Debug function 17 */ +#define K210_PCF_DEBUG18 242 /* Debug function 18 */ +#define K210_PCF_DEBUG19 243 /* Debug function 19 */ +#define K210_PCF_DEBUG20 244 /* Debug function 20 */ +#define K210_PCF_DEBUG21 245 /* Debug function 21 */ +#define K210_PCF_DEBUG22 246 /* Debug function 22 */ +#define K210_PCF_DEBUG23 247 /* Debug function 23 */ +#define K210_PCF_DEBUG24 248 /* Debug function 24 */ +#define K210_PCF_DEBUG25 249 /* Debug function 25 */ +#define K210_PCF_DEBUG26 250 /* Debug function 26 */ +#define K210_PCF_DEBUG27 251 /* Debug function 27 */ +#define K210_PCF_DEBUG28 252 /* Debug function 28 */ +#define K210_PCF_DEBUG29 253 /* Debug function 29 */ +#define K210_PCF_DEBUG30 254 /* Debug function 30 */ +#define K210_PCF_DEBUG31 255 /* Debug function 31 */ + +#define K210_FPIOA(pin, func) (((pin) << 16) | (func)) + +#define K210_PC_POWER_3V3 0 +#define K210_PC_POWER_1V8 1 + +#endif /* PINCTRL_K210_FPIOA_H */ -- cgit v1.2.3 From b1ae3587d16a8c8fc9453e147c8708d6f006ffbb Mon Sep 17 00:00:00 2001 From: Bjarni Jonasson Date: Wed, 13 Jan 2021 12:56:25 +0100 Subject: net: phy: Add 100 base-x mode Sparx-5 supports this mode and it is missing in the PHY core. Signed-off-by: Bjarni Jonasson Reviewed-by: Russell King Signed-off-by: Jakub Kicinski --- Documentation/networking/phy.rst | 5 +++++ include/linux/phy.h | 4 ++++ 2 files changed, 9 insertions(+) (limited to 'Documentation') diff --git a/Documentation/networking/phy.rst b/Documentation/networking/phy.rst index b2f7ec794bc8..399f17976a6c 100644 --- a/Documentation/networking/phy.rst +++ b/Documentation/networking/phy.rst @@ -286,6 +286,11 @@ Some of the interface modes are described below: Note: due to legacy usage, some 10GBASE-R usage incorrectly makes use of this definition. +``PHY_INTERFACE_MODE_100BASEX`` + This defines IEEE 802.3 Clause 24. The link operates at a fixed data + rate of 125Mpbs using a 4B/5B encoding scheme, resulting in an underlying + data rate of 100Mpbs. + Pause frames / flow control =========================== diff --git a/include/linux/phy.h b/include/linux/phy.h index 9effb511acde..24fcc6456a9e 100644 --- a/include/linux/phy.h +++ b/include/linux/phy.h @@ -104,6 +104,7 @@ extern const int phy_10gbit_features_array[1]; * @PHY_INTERFACE_MODE_MOCA: Multimedia over Coax * @PHY_INTERFACE_MODE_QSGMII: Quad SGMII * @PHY_INTERFACE_MODE_TRGMII: Turbo RGMII + * @PHY_INTERFACE_MODE_100BASEX: 100 BaseX * @PHY_INTERFACE_MODE_1000BASEX: 1000 BaseX * @PHY_INTERFACE_MODE_2500BASEX: 2500 BaseX * @PHY_INTERFACE_MODE_RXAUI: Reduced XAUI @@ -135,6 +136,7 @@ typedef enum { PHY_INTERFACE_MODE_MOCA, PHY_INTERFACE_MODE_QSGMII, PHY_INTERFACE_MODE_TRGMII, + PHY_INTERFACE_MODE_100BASEX, PHY_INTERFACE_MODE_1000BASEX, PHY_INTERFACE_MODE_2500BASEX, PHY_INTERFACE_MODE_RXAUI, @@ -217,6 +219,8 @@ static inline const char *phy_modes(phy_interface_t interface) return "usxgmii"; case PHY_INTERFACE_MODE_10GKR: return "10gbase-kr"; + case PHY_INTERFACE_MODE_100BASEX: + return "100base-x"; default: return "unknown"; } -- cgit v1.2.3 From 91c960b0056672e74627776655c926388350fa30 Mon Sep 17 00:00:00 2001 From: Brendan Jackman Date: Thu, 14 Jan 2021 18:17:44 +0000 Subject: bpf: Rename BPF_XADD and prepare to encode other atomics in .imm MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit A subsequent patch will add additional atomic operations. These new operations will use the same opcode field as the existing XADD, with the immediate discriminating different operations. In preparation, rename the instruction mode BPF_ATOMIC and start calling the zero immediate BPF_ADD. This is possible (doesn't break existing valid BPF progs) because the immediate field is currently reserved MBZ and BPF_ADD is zero. All uses are removed from the tree but the BPF_XADD definition is kept around to avoid breaking builds for people including kernel headers. Signed-off-by: Brendan Jackman Signed-off-by: Alexei Starovoitov Acked-by: Björn Töpel Link: https://lore.kernel.org/bpf/20210114181751.768687-5-jackmanb@google.com --- Documentation/networking/filter.rst | 30 ++++++++------ arch/arm/net/bpf_jit_32.c | 7 ++-- arch/arm64/net/bpf_jit_comp.c | 16 ++++++-- arch/mips/net/ebpf_jit.c | 11 ++++-- arch/powerpc/net/bpf_jit_comp64.c | 25 +++++++++--- arch/riscv/net/bpf_jit_comp32.c | 20 ++++++++-- arch/riscv/net/bpf_jit_comp64.c | 16 ++++++-- arch/s390/net/bpf_jit_comp.c | 27 +++++++------ arch/sparc/net/bpf_jit_comp_64.c | 17 ++++++-- arch/x86/net/bpf_jit_comp.c | 46 ++++++++++++++++------ arch/x86/net/bpf_jit_comp32.c | 6 +-- drivers/net/ethernet/netronome/nfp/bpf/jit.c | 14 +++++-- drivers/net/ethernet/netronome/nfp/bpf/main.h | 4 +- drivers/net/ethernet/netronome/nfp/bpf/verifier.c | 15 ++++--- include/linux/filter.h | 16 ++++++-- include/uapi/linux/bpf.h | 5 ++- kernel/bpf/core.c | 31 ++++++++++----- kernel/bpf/disasm.c | 6 ++- kernel/bpf/verifier.c | 24 ++++++----- lib/test_bpf.c | 14 +++---- samples/bpf/bpf_insn.h | 4 +- samples/bpf/cookie_uid_helper_example.c | 8 ++-- samples/bpf/sock_example.c | 2 +- samples/bpf/test_cgrp2_attach.c | 5 ++- tools/include/linux/filter.h | 15 +++++-- tools/include/uapi/linux/bpf.h | 5 ++- .../selftests/bpf/prog_tests/cgroup_attach_multi.c | 4 +- tools/testing/selftests/bpf/test_cgroup_storage.c | 2 +- tools/testing/selftests/bpf/verifier/ctx.c | 7 ++-- .../selftests/bpf/verifier/direct_packet_access.c | 4 +- tools/testing/selftests/bpf/verifier/leak_ptr.c | 10 ++--- tools/testing/selftests/bpf/verifier/meta_access.c | 4 +- tools/testing/selftests/bpf/verifier/unpriv.c | 3 +- .../selftests/bpf/verifier/value_illegal_alu.c | 2 +- tools/testing/selftests/bpf/verifier/xadd.c | 18 ++++----- 35 files changed, 291 insertions(+), 152 deletions(-) (limited to 'Documentation') diff --git a/Documentation/networking/filter.rst b/Documentation/networking/filter.rst index debb59e374de..1583d59d806d 100644 --- a/Documentation/networking/filter.rst +++ b/Documentation/networking/filter.rst @@ -1006,13 +1006,13 @@ Size modifier is one of ... Mode modifier is one of:: - BPF_IMM 0x00 /* used for 32-bit mov in classic BPF and 64-bit in eBPF */ - BPF_ABS 0x20 - BPF_IND 0x40 - BPF_MEM 0x60 - BPF_LEN 0x80 /* classic BPF only, reserved in eBPF */ - BPF_MSH 0xa0 /* classic BPF only, reserved in eBPF */ - BPF_XADD 0xc0 /* eBPF only, exclusive add */ + BPF_IMM 0x00 /* used for 32-bit mov in classic BPF and 64-bit in eBPF */ + BPF_ABS 0x20 + BPF_IND 0x40 + BPF_MEM 0x60 + BPF_LEN 0x80 /* classic BPF only, reserved in eBPF */ + BPF_MSH 0xa0 /* classic BPF only, reserved in eBPF */ + BPF_ATOMIC 0xc0 /* eBPF only, atomic operations */ eBPF has two non-generic instructions: (BPF_ABS | | BPF_LD) and (BPF_IND | | BPF_LD) which are used to access packet data. @@ -1044,11 +1044,19 @@ Unlike classic BPF instruction set, eBPF has generic load/store operations:: BPF_MEM | | BPF_STX: *(size *) (dst_reg + off) = src_reg BPF_MEM | | BPF_ST: *(size *) (dst_reg + off) = imm32 BPF_MEM | | BPF_LDX: dst_reg = *(size *) (src_reg + off) - BPF_XADD | BPF_W | BPF_STX: lock xadd *(u32 *)(dst_reg + off16) += src_reg - BPF_XADD | BPF_DW | BPF_STX: lock xadd *(u64 *)(dst_reg + off16) += src_reg -Where size is one of: BPF_B or BPF_H or BPF_W or BPF_DW. Note that 1 and -2 byte atomic increments are not supported. +Where size is one of: BPF_B or BPF_H or BPF_W or BPF_DW. + +It also includes atomic operations, which use the immediate field for extra +encoding. + + .imm = BPF_ADD, .code = BPF_ATOMIC | BPF_W | BPF_STX: lock xadd *(u32 *)(dst_reg + off16) += src_reg + .imm = BPF_ADD, .code = BPF_ATOMIC | BPF_DW | BPF_STX: lock xadd *(u64 *)(dst_reg + off16) += src_reg + +Note that 1 and 2 byte atomic operations are not supported. + +You may encounter BPF_XADD - this is a legacy name for BPF_ATOMIC, referring to +the exclusive-add operation encoded when the immediate field is zero. eBPF has one 16-byte instruction: BPF_LD | BPF_DW | BPF_IMM which consists of two consecutive ``struct bpf_insn`` 8-byte blocks and interpreted as single diff --git a/arch/arm/net/bpf_jit_32.c b/arch/arm/net/bpf_jit_32.c index 0207b6ea6e8a..897634d0a67c 100644 --- a/arch/arm/net/bpf_jit_32.c +++ b/arch/arm/net/bpf_jit_32.c @@ -1620,10 +1620,9 @@ exit: } emit_str_r(dst_lo, tmp2, off, ctx, BPF_SIZE(code)); break; - /* STX XADD: lock *(u32 *)(dst + off) += src */ - case BPF_STX | BPF_XADD | BPF_W: - /* STX XADD: lock *(u64 *)(dst + off) += src */ - case BPF_STX | BPF_XADD | BPF_DW: + /* Atomic ops */ + case BPF_STX | BPF_ATOMIC | BPF_W: + case BPF_STX | BPF_ATOMIC | BPF_DW: goto notyet; /* STX: *(size *)(dst + off) = src */ case BPF_STX | BPF_MEM | BPF_W: diff --git a/arch/arm64/net/bpf_jit_comp.c b/arch/arm64/net/bpf_jit_comp.c index ef9f1d5e989d..f7b194878a99 100644 --- a/arch/arm64/net/bpf_jit_comp.c +++ b/arch/arm64/net/bpf_jit_comp.c @@ -875,10 +875,18 @@ emit_cond_jmp: } break; - /* STX XADD: lock *(u32 *)(dst + off) += src */ - case BPF_STX | BPF_XADD | BPF_W: - /* STX XADD: lock *(u64 *)(dst + off) += src */ - case BPF_STX | BPF_XADD | BPF_DW: + case BPF_STX | BPF_ATOMIC | BPF_W: + case BPF_STX | BPF_ATOMIC | BPF_DW: + if (insn->imm != BPF_ADD) { + pr_err_once("unknown atomic op code %02x\n", insn->imm); + return -EINVAL; + } + + /* STX XADD: lock *(u32 *)(dst + off) += src + * and + * STX XADD: lock *(u64 *)(dst + off) += src + */ + if (!off) { reg = dst; } else { diff --git a/arch/mips/net/ebpf_jit.c b/arch/mips/net/ebpf_jit.c index 561154cbcc40..939dd06764bc 100644 --- a/arch/mips/net/ebpf_jit.c +++ b/arch/mips/net/ebpf_jit.c @@ -1423,8 +1423,8 @@ jeq_common: case BPF_STX | BPF_H | BPF_MEM: case BPF_STX | BPF_W | BPF_MEM: case BPF_STX | BPF_DW | BPF_MEM: - case BPF_STX | BPF_W | BPF_XADD: - case BPF_STX | BPF_DW | BPF_XADD: + case BPF_STX | BPF_W | BPF_ATOMIC: + case BPF_STX | BPF_DW | BPF_ATOMIC: if (insn->dst_reg == BPF_REG_10) { ctx->flags |= EBPF_SEEN_FP; dst = MIPS_R_SP; @@ -1438,7 +1438,12 @@ jeq_common: src = ebpf_to_mips_reg(ctx, insn, src_reg_no_fp); if (src < 0) return src; - if (BPF_MODE(insn->code) == BPF_XADD) { + if (BPF_MODE(insn->code) == BPF_ATOMIC) { + if (insn->imm != BPF_ADD) { + pr_err("ATOMIC OP %02x NOT HANDLED\n", insn->imm); + return -EINVAL; + } + /* * If mem_off does not fit within the 9 bit ll/sc * instruction immediate field, use a temp reg. diff --git a/arch/powerpc/net/bpf_jit_comp64.c b/arch/powerpc/net/bpf_jit_comp64.c index 022103c6a201..aaf1a887f653 100644 --- a/arch/powerpc/net/bpf_jit_comp64.c +++ b/arch/powerpc/net/bpf_jit_comp64.c @@ -683,10 +683,18 @@ emit_clear: break; /* - * BPF_STX XADD (atomic_add) + * BPF_STX ATOMIC (atomic ops) */ - /* *(u32 *)(dst + off) += src */ - case BPF_STX | BPF_XADD | BPF_W: + case BPF_STX | BPF_ATOMIC | BPF_W: + if (insn->imm != BPF_ADD) { + pr_err_ratelimited( + "eBPF filter atomic op code %02x (@%d) unsupported\n", + code, i); + return -ENOTSUPP; + } + + /* *(u32 *)(dst + off) += src */ + /* Get EA into TMP_REG_1 */ EMIT(PPC_RAW_ADDI(b2p[TMP_REG_1], dst_reg, off)); tmp_idx = ctx->idx * 4; @@ -699,8 +707,15 @@ emit_clear: /* we're done if this succeeded */ PPC_BCC_SHORT(COND_NE, tmp_idx); break; - /* *(u64 *)(dst + off) += src */ - case BPF_STX | BPF_XADD | BPF_DW: + case BPF_STX | BPF_ATOMIC | BPF_DW: + if (insn->imm != BPF_ADD) { + pr_err_ratelimited( + "eBPF filter atomic op code %02x (@%d) unsupported\n", + code, i); + return -ENOTSUPP; + } + /* *(u64 *)(dst + off) += src */ + EMIT(PPC_RAW_ADDI(b2p[TMP_REG_1], dst_reg, off)); tmp_idx = ctx->idx * 4; EMIT(PPC_RAW_LDARX(b2p[TMP_REG_2], 0, b2p[TMP_REG_1], 0)); diff --git a/arch/riscv/net/bpf_jit_comp32.c b/arch/riscv/net/bpf_jit_comp32.c index 579575f9cdae..81de865f4c7c 100644 --- a/arch/riscv/net/bpf_jit_comp32.c +++ b/arch/riscv/net/bpf_jit_comp32.c @@ -881,7 +881,7 @@ static int emit_store_r64(const s8 *dst, const s8 *src, s16 off, const s8 *rd = bpf_get_reg64(dst, tmp1, ctx); const s8 *rs = bpf_get_reg64(src, tmp2, ctx); - if (mode == BPF_XADD && size != BPF_W) + if (mode == BPF_ATOMIC && size != BPF_W) return -1; emit_imm(RV_REG_T0, off, ctx); @@ -899,7 +899,7 @@ static int emit_store_r64(const s8 *dst, const s8 *src, s16 off, case BPF_MEM: emit(rv_sw(RV_REG_T0, 0, lo(rs)), ctx); break; - case BPF_XADD: + case BPF_ATOMIC: /* Only BPF_ADD supported */ emit(rv_amoadd_w(RV_REG_ZERO, lo(rs), RV_REG_T0, 0, 0), ctx); break; @@ -1260,7 +1260,6 @@ int bpf_jit_emit_insn(const struct bpf_insn *insn, struct rv_jit_context *ctx, case BPF_STX | BPF_MEM | BPF_H: case BPF_STX | BPF_MEM | BPF_W: case BPF_STX | BPF_MEM | BPF_DW: - case BPF_STX | BPF_XADD | BPF_W: if (BPF_CLASS(code) == BPF_ST) { emit_imm32(tmp2, imm, ctx); src = tmp2; @@ -1271,8 +1270,21 @@ int bpf_jit_emit_insn(const struct bpf_insn *insn, struct rv_jit_context *ctx, return -1; break; + case BPF_STX | BPF_ATOMIC | BPF_W: + if (insn->imm != BPF_ADD) { + pr_info_once( + "bpf-jit: not supported: atomic operation %02x ***\n", + insn->imm); + return -EFAULT; + } + + if (emit_store_r64(dst, src, off, ctx, BPF_SIZE(code), + BPF_MODE(code))) + return -1; + break; + /* No hardware support for 8-byte atomics in RV32. */ - case BPF_STX | BPF_XADD | BPF_DW: + case BPF_STX | BPF_ATOMIC | BPF_DW: /* Fallthrough. */ notsupported: diff --git a/arch/riscv/net/bpf_jit_comp64.c b/arch/riscv/net/bpf_jit_comp64.c index 8a56b5293117..b44ff52f84a6 100644 --- a/arch/riscv/net/bpf_jit_comp64.c +++ b/arch/riscv/net/bpf_jit_comp64.c @@ -1027,10 +1027,18 @@ out_be: emit_add(RV_REG_T1, RV_REG_T1, rd, ctx); emit_sd(RV_REG_T1, 0, rs, ctx); break; - /* STX XADD: lock *(u32 *)(dst + off) += src */ - case BPF_STX | BPF_XADD | BPF_W: - /* STX XADD: lock *(u64 *)(dst + off) += src */ - case BPF_STX | BPF_XADD | BPF_DW: + case BPF_STX | BPF_ATOMIC | BPF_W: + case BPF_STX | BPF_ATOMIC | BPF_DW: + if (insn->imm != BPF_ADD) { + pr_err("bpf-jit: not supported: atomic operation %02x ***\n", + insn->imm); + return -EINVAL; + } + + /* atomic_add: lock *(u32 *)(dst + off) += src + * atomic_add: lock *(u64 *)(dst + off) += src + */ + if (off) { if (is_12b_int(off)) { emit_addi(RV_REG_T1, rd, off, ctx); diff --git a/arch/s390/net/bpf_jit_comp.c b/arch/s390/net/bpf_jit_comp.c index 0a4182792876..f973e2ead197 100644 --- a/arch/s390/net/bpf_jit_comp.c +++ b/arch/s390/net/bpf_jit_comp.c @@ -1205,18 +1205,23 @@ static noinline int bpf_jit_insn(struct bpf_jit *jit, struct bpf_prog *fp, jit->seen |= SEEN_MEM; break; /* - * BPF_STX XADD (atomic_add) + * BPF_ATOMIC */ - case BPF_STX | BPF_XADD | BPF_W: /* *(u32 *)(dst + off) += src */ - /* laal %w0,%src,off(%dst) */ - EMIT6_DISP_LH(0xeb000000, 0x00fa, REG_W0, src_reg, - dst_reg, off); - jit->seen |= SEEN_MEM; - break; - case BPF_STX | BPF_XADD | BPF_DW: /* *(u64 *)(dst + off) += src */ - /* laalg %w0,%src,off(%dst) */ - EMIT6_DISP_LH(0xeb000000, 0x00ea, REG_W0, src_reg, - dst_reg, off); + case BPF_STX | BPF_ATOMIC | BPF_DW: + case BPF_STX | BPF_ATOMIC | BPF_W: + if (insn->imm != BPF_ADD) { + pr_err("Unknown atomic operation %02x\n", insn->imm); + return -1; + } + + /* *(u32/u64 *)(dst + off) += src + * + * BFW_W: laal %w0,%src,off(%dst) + * BPF_DW: laalg %w0,%src,off(%dst) + */ + EMIT6_DISP_LH(0xeb000000, + BPF_SIZE(insn->code) == BPF_W ? 0x00fa : 0x00ea, + REG_W0, src_reg, dst_reg, off); jit->seen |= SEEN_MEM; break; /* diff --git a/arch/sparc/net/bpf_jit_comp_64.c b/arch/sparc/net/bpf_jit_comp_64.c index 3364e2a00989..4b8d3c65d266 100644 --- a/arch/sparc/net/bpf_jit_comp_64.c +++ b/arch/sparc/net/bpf_jit_comp_64.c @@ -1366,12 +1366,18 @@ static int build_insn(const struct bpf_insn *insn, struct jit_ctx *ctx) break; } - /* STX XADD: lock *(u32 *)(dst + off) += src */ - case BPF_STX | BPF_XADD | BPF_W: { + case BPF_STX | BPF_ATOMIC | BPF_W: { const u8 tmp = bpf2sparc[TMP_REG_1]; const u8 tmp2 = bpf2sparc[TMP_REG_2]; const u8 tmp3 = bpf2sparc[TMP_REG_3]; + if (insn->imm != BPF_ADD) { + pr_err_once("unknown atomic op %02x\n", insn->imm); + return -EINVAL; + } + + /* lock *(u32 *)(dst + off) += src */ + if (insn->dst_reg == BPF_REG_FP) ctx->saw_frame_pointer = true; @@ -1390,11 +1396,16 @@ static int build_insn(const struct bpf_insn *insn, struct jit_ctx *ctx) break; } /* STX XADD: lock *(u64 *)(dst + off) += src */ - case BPF_STX | BPF_XADD | BPF_DW: { + case BPF_STX | BPF_ATOMIC | BPF_DW: { const u8 tmp = bpf2sparc[TMP_REG_1]; const u8 tmp2 = bpf2sparc[TMP_REG_2]; const u8 tmp3 = bpf2sparc[TMP_REG_3]; + if (insn->imm != BPF_ADD) { + pr_err_once("unknown atomic op %02x\n", insn->imm); + return -EINVAL; + } + if (insn->dst_reg == BPF_REG_FP) ctx->saw_frame_pointer = true; diff --git a/arch/x86/net/bpf_jit_comp.c b/arch/x86/net/bpf_jit_comp.c index 93f32e0ba0ef..b1829a534da1 100644 --- a/arch/x86/net/bpf_jit_comp.c +++ b/arch/x86/net/bpf_jit_comp.c @@ -795,6 +795,33 @@ static void emit_stx(u8 **pprog, u32 size, u32 dst_reg, u32 src_reg, int off) *pprog = prog; } +static int emit_atomic(u8 **pprog, u8 atomic_op, + u32 dst_reg, u32 src_reg, s16 off, u8 bpf_size) +{ + u8 *prog = *pprog; + int cnt = 0; + + EMIT1(0xF0); /* lock prefix */ + + maybe_emit_mod(&prog, dst_reg, src_reg, bpf_size == BPF_DW); + + /* emit opcode */ + switch (atomic_op) { + case BPF_ADD: + /* lock *(u32/u64*)(dst_reg + off) = src_reg */ + EMIT1(simple_alu_opcodes[atomic_op]); + break; + default: + pr_err("bpf_jit: unknown atomic opcode %02x\n", atomic_op); + return -EFAULT; + } + + emit_insn_suffix(&prog, dst_reg, src_reg, off); + + *pprog = prog; + return 0; +} + static bool ex_handler_bpf(const struct exception_table_entry *x, struct pt_regs *regs, int trapnr, unsigned long error_code, unsigned long fault_addr) @@ -839,6 +866,7 @@ static int do_jit(struct bpf_prog *bpf_prog, int *addrs, u8 *image, int i, cnt = 0, excnt = 0; int proglen = 0; u8 *prog = temp; + int err; detect_reg_usage(insn, insn_cnt, callee_regs_used, &tail_call_seen); @@ -1250,18 +1278,12 @@ st: if (is_imm8(insn->off)) } break; - /* STX XADD: lock *(u32*)(dst_reg + off) += src_reg */ - case BPF_STX | BPF_XADD | BPF_W: - /* Emit 'lock add dword ptr [rax + off], eax' */ - if (is_ereg(dst_reg) || is_ereg(src_reg)) - EMIT3(0xF0, add_2mod(0x40, dst_reg, src_reg), 0x01); - else - EMIT2(0xF0, 0x01); - goto xadd; - case BPF_STX | BPF_XADD | BPF_DW: - EMIT3(0xF0, add_2mod(0x48, dst_reg, src_reg), 0x01); -xadd: - emit_modrm_dstoff(&prog, dst_reg, src_reg, insn->off); + case BPF_STX | BPF_ATOMIC | BPF_W: + case BPF_STX | BPF_ATOMIC | BPF_DW: + err = emit_atomic(&prog, insn->imm, dst_reg, src_reg, + insn->off, BPF_SIZE(insn->code)); + if (err) + return err; break; /* call */ diff --git a/arch/x86/net/bpf_jit_comp32.c b/arch/x86/net/bpf_jit_comp32.c index 96fde03aa987..d17b67c69f89 100644 --- a/arch/x86/net/bpf_jit_comp32.c +++ b/arch/x86/net/bpf_jit_comp32.c @@ -2243,10 +2243,8 @@ emit_jmp: return -EFAULT; } break; - /* STX XADD: lock *(u32 *)(dst + off) += src */ - case BPF_STX | BPF_XADD | BPF_W: - /* STX XADD: lock *(u64 *)(dst + off) += src */ - case BPF_STX | BPF_XADD | BPF_DW: + case BPF_STX | BPF_ATOMIC | BPF_W: + case BPF_STX | BPF_ATOMIC | BPF_DW: goto notyet; case BPF_JMP | BPF_EXIT: if (seen_exit) { diff --git a/drivers/net/ethernet/netronome/nfp/bpf/jit.c b/drivers/net/ethernet/netronome/nfp/bpf/jit.c index 0a721f6e8676..e31f8fbbc696 100644 --- a/drivers/net/ethernet/netronome/nfp/bpf/jit.c +++ b/drivers/net/ethernet/netronome/nfp/bpf/jit.c @@ -3109,13 +3109,19 @@ mem_xadd(struct nfp_prog *nfp_prog, struct nfp_insn_meta *meta, bool is64) return 0; } -static int mem_xadd4(struct nfp_prog *nfp_prog, struct nfp_insn_meta *meta) +static int mem_atomic4(struct nfp_prog *nfp_prog, struct nfp_insn_meta *meta) { + if (meta->insn.imm != BPF_ADD) + return -EOPNOTSUPP; + return mem_xadd(nfp_prog, meta, false); } -static int mem_xadd8(struct nfp_prog *nfp_prog, struct nfp_insn_meta *meta) +static int mem_atomic8(struct nfp_prog *nfp_prog, struct nfp_insn_meta *meta) { + if (meta->insn.imm != BPF_ADD) + return -EOPNOTSUPP; + return mem_xadd(nfp_prog, meta, true); } @@ -3475,8 +3481,8 @@ static const instr_cb_t instr_cb[256] = { [BPF_STX | BPF_MEM | BPF_H] = mem_stx2, [BPF_STX | BPF_MEM | BPF_W] = mem_stx4, [BPF_STX | BPF_MEM | BPF_DW] = mem_stx8, - [BPF_STX | BPF_XADD | BPF_W] = mem_xadd4, - [BPF_STX | BPF_XADD | BPF_DW] = mem_xadd8, + [BPF_STX | BPF_ATOMIC | BPF_W] = mem_atomic4, + [BPF_STX | BPF_ATOMIC | BPF_DW] = mem_atomic8, [BPF_ST | BPF_MEM | BPF_B] = mem_st1, [BPF_ST | BPF_MEM | BPF_H] = mem_st2, [BPF_ST | BPF_MEM | BPF_W] = mem_st4, diff --git a/drivers/net/ethernet/netronome/nfp/bpf/main.h b/drivers/net/ethernet/netronome/nfp/bpf/main.h index fac9c6f9e197..d0e17eebddd9 100644 --- a/drivers/net/ethernet/netronome/nfp/bpf/main.h +++ b/drivers/net/ethernet/netronome/nfp/bpf/main.h @@ -428,9 +428,9 @@ static inline bool is_mbpf_classic_store_pkt(const struct nfp_insn_meta *meta) return is_mbpf_classic_store(meta) && meta->ptr.type == PTR_TO_PACKET; } -static inline bool is_mbpf_xadd(const struct nfp_insn_meta *meta) +static inline bool is_mbpf_atomic(const struct nfp_insn_meta *meta) { - return (meta->insn.code & ~BPF_SIZE_MASK) == (BPF_STX | BPF_XADD); + return (meta->insn.code & ~BPF_SIZE_MASK) == (BPF_STX | BPF_ATOMIC); } static inline bool is_mbpf_mul(const struct nfp_insn_meta *meta) diff --git a/drivers/net/ethernet/netronome/nfp/bpf/verifier.c b/drivers/net/ethernet/netronome/nfp/bpf/verifier.c index e92ee510fd52..9d235c0ce46a 100644 --- a/drivers/net/ethernet/netronome/nfp/bpf/verifier.c +++ b/drivers/net/ethernet/netronome/nfp/bpf/verifier.c @@ -479,7 +479,7 @@ nfp_bpf_check_ptr(struct nfp_prog *nfp_prog, struct nfp_insn_meta *meta, pr_vlog(env, "map writes not supported\n"); return -EOPNOTSUPP; } - if (is_mbpf_xadd(meta)) { + if (is_mbpf_atomic(meta)) { err = nfp_bpf_map_mark_used(env, meta, reg, NFP_MAP_USE_ATOMIC_CNT); if (err) @@ -523,12 +523,17 @@ exit_check_ptr: } static int -nfp_bpf_check_xadd(struct nfp_prog *nfp_prog, struct nfp_insn_meta *meta, - struct bpf_verifier_env *env) +nfp_bpf_check_atomic(struct nfp_prog *nfp_prog, struct nfp_insn_meta *meta, + struct bpf_verifier_env *env) { const struct bpf_reg_state *sreg = cur_regs(env) + meta->insn.src_reg; const struct bpf_reg_state *dreg = cur_regs(env) + meta->insn.dst_reg; + if (meta->insn.imm != BPF_ADD) { + pr_vlog(env, "atomic op not implemented: %d\n", meta->insn.imm); + return -EOPNOTSUPP; + } + if (dreg->type != PTR_TO_MAP_VALUE) { pr_vlog(env, "atomic add not to a map value pointer: %d\n", dreg->type); @@ -655,8 +660,8 @@ int nfp_verify_insn(struct bpf_verifier_env *env, int insn_idx, if (is_mbpf_store(meta)) return nfp_bpf_check_store(nfp_prog, meta, env); - if (is_mbpf_xadd(meta)) - return nfp_bpf_check_xadd(nfp_prog, meta, env); + if (is_mbpf_atomic(meta)) + return nfp_bpf_check_atomic(nfp_prog, meta, env); if (is_mbpf_alu(meta)) return nfp_bpf_check_alu(nfp_prog, meta, env); diff --git a/include/linux/filter.h b/include/linux/filter.h index 5edf2b660881..392e94b79668 100644 --- a/include/linux/filter.h +++ b/include/linux/filter.h @@ -259,15 +259,23 @@ static inline bool insn_is_zext(const struct bpf_insn *insn) .off = OFF, \ .imm = 0 }) -/* Atomic memory add, *(uint *)(dst_reg + off16) += src_reg */ -#define BPF_STX_XADD(SIZE, DST, SRC, OFF) \ +/* + * Atomic operations: + * + * BPF_ADD *(uint *) (dst_reg + off16) += src_reg + */ + +#define BPF_ATOMIC_OP(SIZE, OP, DST, SRC, OFF) \ ((struct bpf_insn) { \ - .code = BPF_STX | BPF_SIZE(SIZE) | BPF_XADD, \ + .code = BPF_STX | BPF_SIZE(SIZE) | BPF_ATOMIC, \ .dst_reg = DST, \ .src_reg = SRC, \ .off = OFF, \ - .imm = 0 }) + .imm = OP }) + +/* Legacy alias */ +#define BPF_STX_XADD(SIZE, DST, SRC, OFF) BPF_ATOMIC_OP(SIZE, BPF_ADD, DST, SRC, OFF) /* Memory store, *(uint *) (dst_reg + off16) = imm32 */ diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h index a1ad32456f89..6b3996343e63 100644 --- a/include/uapi/linux/bpf.h +++ b/include/uapi/linux/bpf.h @@ -19,7 +19,8 @@ /* ld/ldx fields */ #define BPF_DW 0x18 /* double word (64-bit) */ -#define BPF_XADD 0xc0 /* exclusive add */ +#define BPF_ATOMIC 0xc0 /* atomic memory ops - op type in immediate */ +#define BPF_XADD 0xc0 /* exclusive add - legacy name */ /* alu/jmp fields */ #define BPF_MOV 0xb0 /* mov reg to reg */ @@ -2448,7 +2449,7 @@ union bpf_attr { * running simultaneously. * * A user should care about the synchronization by himself. - * For example, by using the **BPF_STX_XADD** instruction to alter + * For example, by using the **BPF_ATOMIC** instructions to alter * the shared data. * Return * A pointer to the local storage area. diff --git a/kernel/bpf/core.c b/kernel/bpf/core.c index 69c3c308de5e..4836ebf459cf 100644 --- a/kernel/bpf/core.c +++ b/kernel/bpf/core.c @@ -1309,8 +1309,8 @@ EXPORT_SYMBOL_GPL(__bpf_call_base); INSN_3(STX, MEM, H), \ INSN_3(STX, MEM, W), \ INSN_3(STX, MEM, DW), \ - INSN_3(STX, XADD, W), \ - INSN_3(STX, XADD, DW), \ + INSN_3(STX, ATOMIC, W), \ + INSN_3(STX, ATOMIC, DW), \ /* Immediate based. */ \ INSN_3(ST, MEM, B), \ INSN_3(ST, MEM, H), \ @@ -1618,13 +1618,25 @@ out: LDX_PROBE(DW, 8) #undef LDX_PROBE - STX_XADD_W: /* lock xadd *(u32 *)(dst_reg + off16) += src_reg */ - atomic_add((u32) SRC, (atomic_t *)(unsigned long) - (DST + insn->off)); + STX_ATOMIC_W: + switch (IMM) { + case BPF_ADD: + /* lock xadd *(u32 *)(dst_reg + off16) += src_reg */ + atomic_add((u32) SRC, (atomic_t *)(unsigned long) + (DST + insn->off)); + default: + goto default_label; + } CONT; - STX_XADD_DW: /* lock xadd *(u64 *)(dst_reg + off16) += src_reg */ - atomic64_add((u64) SRC, (atomic64_t *)(unsigned long) - (DST + insn->off)); + STX_ATOMIC_DW: + switch (IMM) { + case BPF_ADD: + /* lock xadd *(u64 *)(dst_reg + off16) += src_reg */ + atomic64_add((u64) SRC, (atomic64_t *)(unsigned long) + (DST + insn->off)); + default: + goto default_label; + } CONT; default_label: @@ -1634,7 +1646,8 @@ out: * * Note, verifier whitelists all opcodes in bpf_opcode_in_insntable(). */ - pr_warn("BPF interpreter: unknown opcode %02x\n", insn->code); + pr_warn("BPF interpreter: unknown opcode %02x (imm: 0x%x)\n", + insn->code, insn->imm); BUG_ON(1); return 0; } diff --git a/kernel/bpf/disasm.c b/kernel/bpf/disasm.c index b44d8c447afd..37c8d6e9b4cc 100644 --- a/kernel/bpf/disasm.c +++ b/kernel/bpf/disasm.c @@ -153,14 +153,16 @@ void print_bpf_insn(const struct bpf_insn_cbs *cbs, bpf_ldst_string[BPF_SIZE(insn->code) >> 3], insn->dst_reg, insn->off, insn->src_reg); - else if (BPF_MODE(insn->code) == BPF_XADD) + else if (BPF_MODE(insn->code) == BPF_ATOMIC && + insn->imm == BPF_ADD) { verbose(cbs->private_data, "(%02x) lock *(%s *)(r%d %+d) += r%d\n", insn->code, bpf_ldst_string[BPF_SIZE(insn->code) >> 3], insn->dst_reg, insn->off, insn->src_reg); - else + } else { verbose(cbs->private_data, "BUG_%02x\n", insn->code); + } } else if (class == BPF_ST) { if (BPF_MODE(insn->code) != BPF_MEM) { verbose(cbs->private_data, "BUG_st_%02x\n", insn->code); diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c index ae2aee48cf82..cfc137b81ac6 100644 --- a/kernel/bpf/verifier.c +++ b/kernel/bpf/verifier.c @@ -3604,13 +3604,17 @@ static int check_mem_access(struct bpf_verifier_env *env, int insn_idx, u32 regn return err; } -static int check_xadd(struct bpf_verifier_env *env, int insn_idx, struct bpf_insn *insn) +static int check_atomic(struct bpf_verifier_env *env, int insn_idx, struct bpf_insn *insn) { int err; - if ((BPF_SIZE(insn->code) != BPF_W && BPF_SIZE(insn->code) != BPF_DW) || - insn->imm != 0) { - verbose(env, "BPF_XADD uses reserved fields\n"); + if (insn->imm != BPF_ADD) { + verbose(env, "BPF_ATOMIC uses invalid atomic opcode %02x\n", insn->imm); + return -EINVAL; + } + + if (BPF_SIZE(insn->code) != BPF_W && BPF_SIZE(insn->code) != BPF_DW) { + verbose(env, "invalid atomic operand size\n"); return -EINVAL; } @@ -3633,19 +3637,19 @@ static int check_xadd(struct bpf_verifier_env *env, int insn_idx, struct bpf_ins is_pkt_reg(env, insn->dst_reg) || is_flow_key_reg(env, insn->dst_reg) || is_sk_reg(env, insn->dst_reg)) { - verbose(env, "BPF_XADD stores into R%d %s is not allowed\n", + verbose(env, "BPF_ATOMIC stores into R%d %s is not allowed\n", insn->dst_reg, reg_type_str[reg_state(env, insn->dst_reg)->type]); return -EACCES; } - /* check whether atomic_add can read the memory */ + /* check whether we can read the memory */ err = check_mem_access(env, insn_idx, insn->dst_reg, insn->off, BPF_SIZE(insn->code), BPF_READ, -1, true); if (err) return err; - /* check whether atomic_add can write into the same memory */ + /* check whether we can write into the same memory */ return check_mem_access(env, insn_idx, insn->dst_reg, insn->off, BPF_SIZE(insn->code), BPF_WRITE, -1, true); } @@ -9524,8 +9528,8 @@ static int do_check(struct bpf_verifier_env *env) } else if (class == BPF_STX) { enum bpf_reg_type *prev_dst_type, dst_reg_type; - if (BPF_MODE(insn->code) == BPF_XADD) { - err = check_xadd(env, env->insn_idx, insn); + if (BPF_MODE(insn->code) == BPF_ATOMIC) { + err = check_atomic(env, env->insn_idx, insn); if (err) return err; env->insn_idx++; @@ -10010,7 +10014,7 @@ static int resolve_pseudo_ldimm64(struct bpf_verifier_env *env) if (BPF_CLASS(insn->code) == BPF_STX && ((BPF_MODE(insn->code) != BPF_MEM && - BPF_MODE(insn->code) != BPF_XADD) || insn->imm != 0)) { + BPF_MODE(insn->code) != BPF_ATOMIC) || insn->imm != 0)) { verbose(env, "BPF_STX uses reserved fields\n"); return -EINVAL; } diff --git a/lib/test_bpf.c b/lib/test_bpf.c index ca7d635bccd9..49ec9e8d8aed 100644 --- a/lib/test_bpf.c +++ b/lib/test_bpf.c @@ -4295,13 +4295,13 @@ static struct bpf_test tests[] = { { { 0, 0xffffffff } }, .stack_depth = 40, }, - /* BPF_STX | BPF_XADD | BPF_W/DW */ + /* BPF_STX | BPF_ATOMIC | BPF_W/DW */ { "STX_XADD_W: Test: 0x12 + 0x10 = 0x22", .u.insns_int = { BPF_ALU32_IMM(BPF_MOV, R0, 0x12), BPF_ST_MEM(BPF_W, R10, -40, 0x10), - BPF_STX_XADD(BPF_W, R10, R0, -40), + BPF_ATOMIC_OP(BPF_W, BPF_ADD, R10, R0, -40), BPF_LDX_MEM(BPF_W, R0, R10, -40), BPF_EXIT_INSN(), }, @@ -4316,7 +4316,7 @@ static struct bpf_test tests[] = { BPF_ALU64_REG(BPF_MOV, R1, R10), BPF_ALU32_IMM(BPF_MOV, R0, 0x12), BPF_ST_MEM(BPF_W, R10, -40, 0x10), - BPF_STX_XADD(BPF_W, R10, R0, -40), + BPF_ATOMIC_OP(BPF_W, BPF_ADD, R10, R0, -40), BPF_ALU64_REG(BPF_MOV, R0, R10), BPF_ALU64_REG(BPF_SUB, R0, R1), BPF_EXIT_INSN(), @@ -4331,7 +4331,7 @@ static struct bpf_test tests[] = { .u.insns_int = { BPF_ALU32_IMM(BPF_MOV, R0, 0x12), BPF_ST_MEM(BPF_W, R10, -40, 0x10), - BPF_STX_XADD(BPF_W, R10, R0, -40), + BPF_ATOMIC_OP(BPF_W, BPF_ADD, R10, R0, -40), BPF_EXIT_INSN(), }, INTERNAL, @@ -4352,7 +4352,7 @@ static struct bpf_test tests[] = { .u.insns_int = { BPF_ALU32_IMM(BPF_MOV, R0, 0x12), BPF_ST_MEM(BPF_DW, R10, -40, 0x10), - BPF_STX_XADD(BPF_DW, R10, R0, -40), + BPF_ATOMIC_OP(BPF_DW, BPF_ADD, R10, R0, -40), BPF_LDX_MEM(BPF_DW, R0, R10, -40), BPF_EXIT_INSN(), }, @@ -4367,7 +4367,7 @@ static struct bpf_test tests[] = { BPF_ALU64_REG(BPF_MOV, R1, R10), BPF_ALU32_IMM(BPF_MOV, R0, 0x12), BPF_ST_MEM(BPF_DW, R10, -40, 0x10), - BPF_STX_XADD(BPF_DW, R10, R0, -40), + BPF_ATOMIC_OP(BPF_DW, BPF_ADD, R10, R0, -40), BPF_ALU64_REG(BPF_MOV, R0, R10), BPF_ALU64_REG(BPF_SUB, R0, R1), BPF_EXIT_INSN(), @@ -4382,7 +4382,7 @@ static struct bpf_test tests[] = { .u.insns_int = { BPF_ALU32_IMM(BPF_MOV, R0, 0x12), BPF_ST_MEM(BPF_DW, R10, -40, 0x10), - BPF_STX_XADD(BPF_DW, R10, R0, -40), + BPF_ATOMIC_OP(BPF_DW, BPF_ADD, R10, R0, -40), BPF_EXIT_INSN(), }, INTERNAL, diff --git a/samples/bpf/bpf_insn.h b/samples/bpf/bpf_insn.h index 544237980582..db67a2847395 100644 --- a/samples/bpf/bpf_insn.h +++ b/samples/bpf/bpf_insn.h @@ -138,11 +138,11 @@ struct bpf_insn; #define BPF_STX_XADD(SIZE, DST, SRC, OFF) \ ((struct bpf_insn) { \ - .code = BPF_STX | BPF_SIZE(SIZE) | BPF_XADD, \ + .code = BPF_STX | BPF_SIZE(SIZE) | BPF_ATOMIC, \ .dst_reg = DST, \ .src_reg = SRC, \ .off = OFF, \ - .imm = 0 }) + .imm = BPF_ADD }) /* Memory store, *(uint *) (dst_reg + off16) = imm32 */ diff --git a/samples/bpf/cookie_uid_helper_example.c b/samples/bpf/cookie_uid_helper_example.c index deb0e3e0324d..c5ff7a13918c 100644 --- a/samples/bpf/cookie_uid_helper_example.c +++ b/samples/bpf/cookie_uid_helper_example.c @@ -147,12 +147,12 @@ static void prog_load(void) */ BPF_MOV64_REG(BPF_REG_9, BPF_REG_0), BPF_MOV64_IMM(BPF_REG_1, 1), - BPF_STX_XADD(BPF_DW, BPF_REG_9, BPF_REG_1, - offsetof(struct stats, packets)), + BPF_ATOMIC_OP(BPF_DW, BPF_ADD, BPF_REG_9, BPF_REG_1, + offsetof(struct stats, packets)), BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_6, offsetof(struct __sk_buff, len)), - BPF_STX_XADD(BPF_DW, BPF_REG_9, BPF_REG_1, - offsetof(struct stats, bytes)), + BPF_ATOMIC_OP(BPF_DW, BPF_ADD, BPF_REG_9, BPF_REG_1, + offsetof(struct stats, bytes)), BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_6, offsetof(struct __sk_buff, len)), BPF_EXIT_INSN(), diff --git a/samples/bpf/sock_example.c b/samples/bpf/sock_example.c index 00aae1d33fca..23d1930e1927 100644 --- a/samples/bpf/sock_example.c +++ b/samples/bpf/sock_example.c @@ -54,7 +54,7 @@ static int test_sock(void) BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem), BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 2), BPF_MOV64_IMM(BPF_REG_1, 1), /* r1 = 1 */ - BPF_RAW_INSN(BPF_STX | BPF_XADD | BPF_DW, BPF_REG_0, BPF_REG_1, 0, 0), /* xadd r0 += r1 */ + BPF_ATOMIC_OP(BPF_DW, BPF_ADD, BPF_REG_0, BPF_REG_1, 0), BPF_MOV64_IMM(BPF_REG_0, 0), /* r0 = 0 */ BPF_EXIT_INSN(), }; diff --git a/samples/bpf/test_cgrp2_attach.c b/samples/bpf/test_cgrp2_attach.c index 20fbd1241db3..390ff38d2ac6 100644 --- a/samples/bpf/test_cgrp2_attach.c +++ b/samples/bpf/test_cgrp2_attach.c @@ -53,7 +53,7 @@ static int prog_load(int map_fd, int verdict) BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem), BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 2), BPF_MOV64_IMM(BPF_REG_1, 1), /* r1 = 1 */ - BPF_RAW_INSN(BPF_STX | BPF_XADD | BPF_DW, BPF_REG_0, BPF_REG_1, 0, 0), /* xadd r0 += r1 */ + BPF_ATOMIC_OP(BPF_DW, BPF_ADD, BPF_REG_0, BPF_REG_1, 0), /* Count bytes */ BPF_MOV64_IMM(BPF_REG_0, MAP_KEY_BYTES), /* r0 = 1 */ @@ -64,7 +64,8 @@ static int prog_load(int map_fd, int verdict) BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem), BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 2), BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_6, offsetof(struct __sk_buff, len)), /* r1 = skb->len */ - BPF_RAW_INSN(BPF_STX | BPF_XADD | BPF_DW, BPF_REG_0, BPF_REG_1, 0, 0), /* xadd r0 += r1 */ + + BPF_ATOMIC_OP(BPF_DW, BPF_ADD, BPF_REG_0, BPF_REG_1, 0), BPF_MOV64_IMM(BPF_REG_0, verdict), /* r0 = verdict */ BPF_EXIT_INSN(), diff --git a/tools/include/linux/filter.h b/tools/include/linux/filter.h index ca28b6ab8db7..e870c9039f0d 100644 --- a/tools/include/linux/filter.h +++ b/tools/include/linux/filter.h @@ -169,15 +169,22 @@ .off = OFF, \ .imm = 0 }) -/* Atomic memory add, *(uint *)(dst_reg + off16) += src_reg */ +/* + * Atomic operations: + * + * BPF_ADD *(uint *) (dst_reg + off16) += src_reg + */ -#define BPF_STX_XADD(SIZE, DST, SRC, OFF) \ +#define BPF_ATOMIC_OP(SIZE, OP, DST, SRC, OFF) \ ((struct bpf_insn) { \ - .code = BPF_STX | BPF_SIZE(SIZE) | BPF_XADD, \ + .code = BPF_STX | BPF_SIZE(SIZE) | BPF_ATOMIC, \ .dst_reg = DST, \ .src_reg = SRC, \ .off = OFF, \ - .imm = 0 }) + .imm = OP }) + +/* Legacy alias */ +#define BPF_STX_XADD(SIZE, DST, SRC, OFF) BPF_ATOMIC_OP(SIZE, BPF_ADD, DST, SRC, OFF) /* Memory store, *(uint *) (dst_reg + off16) = imm32 */ diff --git a/tools/include/uapi/linux/bpf.h b/tools/include/uapi/linux/bpf.h index a1ad32456f89..6b3996343e63 100644 --- a/tools/include/uapi/linux/bpf.h +++ b/tools/include/uapi/linux/bpf.h @@ -19,7 +19,8 @@ /* ld/ldx fields */ #define BPF_DW 0x18 /* double word (64-bit) */ -#define BPF_XADD 0xc0 /* exclusive add */ +#define BPF_ATOMIC 0xc0 /* atomic memory ops - op type in immediate */ +#define BPF_XADD 0xc0 /* exclusive add - legacy name */ /* alu/jmp fields */ #define BPF_MOV 0xb0 /* mov reg to reg */ @@ -2448,7 +2449,7 @@ union bpf_attr { * running simultaneously. * * A user should care about the synchronization by himself. - * For example, by using the **BPF_STX_XADD** instruction to alter + * For example, by using the **BPF_ATOMIC** instructions to alter * the shared data. * Return * A pointer to the local storage area. diff --git a/tools/testing/selftests/bpf/prog_tests/cgroup_attach_multi.c b/tools/testing/selftests/bpf/prog_tests/cgroup_attach_multi.c index b549fcfacc0b..0a1fc9816cef 100644 --- a/tools/testing/selftests/bpf/prog_tests/cgroup_attach_multi.c +++ b/tools/testing/selftests/bpf/prog_tests/cgroup_attach_multi.c @@ -45,13 +45,13 @@ static int prog_load_cnt(int verdict, int val) BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem), BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 2), BPF_MOV64_IMM(BPF_REG_1, val), /* r1 = 1 */ - BPF_RAW_INSN(BPF_STX | BPF_XADD | BPF_DW, BPF_REG_0, BPF_REG_1, 0, 0), /* xadd r0 += r1 */ + BPF_ATOMIC_OP(BPF_DW, BPF_ADD, BPF_REG_0, BPF_REG_1, 0), BPF_LD_MAP_FD(BPF_REG_1, cgroup_storage_fd), BPF_MOV64_IMM(BPF_REG_2, 0), BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_get_local_storage), BPF_MOV64_IMM(BPF_REG_1, val), - BPF_RAW_INSN(BPF_STX | BPF_XADD | BPF_W, BPF_REG_0, BPF_REG_1, 0, 0), + BPF_ATOMIC_OP(BPF_W, BPF_ADD, BPF_REG_0, BPF_REG_1, 0), BPF_LD_MAP_FD(BPF_REG_1, percpu_cgroup_storage_fd), BPF_MOV64_IMM(BPF_REG_2, 0), diff --git a/tools/testing/selftests/bpf/test_cgroup_storage.c b/tools/testing/selftests/bpf/test_cgroup_storage.c index d946252a25bb..0cda61da5d39 100644 --- a/tools/testing/selftests/bpf/test_cgroup_storage.c +++ b/tools/testing/selftests/bpf/test_cgroup_storage.c @@ -29,7 +29,7 @@ int main(int argc, char **argv) BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_get_local_storage), BPF_MOV64_IMM(BPF_REG_1, 1), - BPF_STX_XADD(BPF_DW, BPF_REG_0, BPF_REG_1, 0), + BPF_ATOMIC_OP(BPF_DW, BPF_ADD, BPF_REG_0, BPF_REG_1, 0), BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_0, 0), BPF_ALU64_IMM(BPF_AND, BPF_REG_1, 0x1), BPF_MOV64_REG(BPF_REG_0, BPF_REG_1), diff --git a/tools/testing/selftests/bpf/verifier/ctx.c b/tools/testing/selftests/bpf/verifier/ctx.c index 93d6b1641481..23080862aafd 100644 --- a/tools/testing/selftests/bpf/verifier/ctx.c +++ b/tools/testing/selftests/bpf/verifier/ctx.c @@ -10,14 +10,13 @@ .prog_type = BPF_PROG_TYPE_SCHED_CLS, }, { - "context stores via XADD", + "context stores via BPF_ATOMIC", .insns = { BPF_MOV64_IMM(BPF_REG_0, 0), - BPF_RAW_INSN(BPF_STX | BPF_XADD | BPF_W, BPF_REG_1, - BPF_REG_0, offsetof(struct __sk_buff, mark), 0), + BPF_ATOMIC_OP(BPF_W, BPF_ADD, BPF_REG_1, BPF_REG_0, offsetof(struct __sk_buff, mark)), BPF_EXIT_INSN(), }, - .errstr = "BPF_XADD stores into R1 ctx is not allowed", + .errstr = "BPF_ATOMIC stores into R1 ctx is not allowed", .result = REJECT, .prog_type = BPF_PROG_TYPE_SCHED_CLS, }, diff --git a/tools/testing/selftests/bpf/verifier/direct_packet_access.c b/tools/testing/selftests/bpf/verifier/direct_packet_access.c index ae72536603fe..ac1e19d0f520 100644 --- a/tools/testing/selftests/bpf/verifier/direct_packet_access.c +++ b/tools/testing/selftests/bpf/verifier/direct_packet_access.c @@ -333,7 +333,7 @@ BPF_MOV64_REG(BPF_REG_4, BPF_REG_10), BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, -8), BPF_STX_MEM(BPF_DW, BPF_REG_4, BPF_REG_2, 0), - BPF_STX_XADD(BPF_DW, BPF_REG_4, BPF_REG_5, 0), + BPF_ATOMIC_OP(BPF_DW, BPF_ADD, BPF_REG_4, BPF_REG_5, 0), BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_4, 0), BPF_STX_MEM(BPF_W, BPF_REG_2, BPF_REG_5, 0), BPF_MOV64_IMM(BPF_REG_0, 0), @@ -488,7 +488,7 @@ BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 11), BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_10, -8), BPF_MOV64_IMM(BPF_REG_4, 0xffffffff), - BPF_STX_XADD(BPF_DW, BPF_REG_10, BPF_REG_4, -8), + BPF_ATOMIC_OP(BPF_DW, BPF_ADD, BPF_REG_10, BPF_REG_4, -8), BPF_LDX_MEM(BPF_DW, BPF_REG_4, BPF_REG_10, -8), BPF_ALU64_IMM(BPF_RSH, BPF_REG_4, 49), BPF_ALU64_REG(BPF_ADD, BPF_REG_4, BPF_REG_2), diff --git a/tools/testing/selftests/bpf/verifier/leak_ptr.c b/tools/testing/selftests/bpf/verifier/leak_ptr.c index d6eec17f2cd2..73f0dea95546 100644 --- a/tools/testing/selftests/bpf/verifier/leak_ptr.c +++ b/tools/testing/selftests/bpf/verifier/leak_ptr.c @@ -5,7 +5,7 @@ BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_0, offsetof(struct __sk_buff, cb[0])), BPF_LD_MAP_FD(BPF_REG_2, 0), - BPF_STX_XADD(BPF_DW, BPF_REG_1, BPF_REG_2, + BPF_ATOMIC_OP(BPF_DW, BPF_ADD, BPF_REG_1, BPF_REG_2, offsetof(struct __sk_buff, cb[0])), BPF_EXIT_INSN(), }, @@ -13,7 +13,7 @@ .errstr_unpriv = "R2 leaks addr into mem", .result_unpriv = REJECT, .result = REJECT, - .errstr = "BPF_XADD stores into R1 ctx is not allowed", + .errstr = "BPF_ATOMIC stores into R1 ctx is not allowed", }, { "leak pointer into ctx 2", @@ -21,14 +21,14 @@ BPF_MOV64_IMM(BPF_REG_0, 0), BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_0, offsetof(struct __sk_buff, cb[0])), - BPF_STX_XADD(BPF_DW, BPF_REG_1, BPF_REG_10, + BPF_ATOMIC_OP(BPF_DW, BPF_ADD, BPF_REG_1, BPF_REG_10, offsetof(struct __sk_buff, cb[0])), BPF_EXIT_INSN(), }, .errstr_unpriv = "R10 leaks addr into mem", .result_unpriv = REJECT, .result = REJECT, - .errstr = "BPF_XADD stores into R1 ctx is not allowed", + .errstr = "BPF_ATOMIC stores into R1 ctx is not allowed", }, { "leak pointer into ctx 3", @@ -56,7 +56,7 @@ BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 3), BPF_MOV64_IMM(BPF_REG_3, 0), BPF_STX_MEM(BPF_DW, BPF_REG_0, BPF_REG_3, 0), - BPF_STX_XADD(BPF_DW, BPF_REG_0, BPF_REG_6, 0), + BPF_ATOMIC_OP(BPF_DW, BPF_ADD, BPF_REG_0, BPF_REG_6, 0), BPF_MOV64_IMM(BPF_REG_0, 0), BPF_EXIT_INSN(), }, diff --git a/tools/testing/selftests/bpf/verifier/meta_access.c b/tools/testing/selftests/bpf/verifier/meta_access.c index 205292b8dd65..b45e8af41420 100644 --- a/tools/testing/selftests/bpf/verifier/meta_access.c +++ b/tools/testing/selftests/bpf/verifier/meta_access.c @@ -171,7 +171,7 @@ BPF_MOV64_IMM(BPF_REG_5, 42), BPF_MOV64_IMM(BPF_REG_6, 24), BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_5, -8), - BPF_STX_XADD(BPF_DW, BPF_REG_10, BPF_REG_6, -8), + BPF_ATOMIC_OP(BPF_DW, BPF_ADD, BPF_REG_10, BPF_REG_6, -8), BPF_LDX_MEM(BPF_DW, BPF_REG_5, BPF_REG_10, -8), BPF_JMP_IMM(BPF_JGT, BPF_REG_5, 100, 6), BPF_ALU64_REG(BPF_ADD, BPF_REG_3, BPF_REG_5), @@ -196,7 +196,7 @@ BPF_MOV64_IMM(BPF_REG_5, 42), BPF_MOV64_IMM(BPF_REG_6, 24), BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_5, -8), - BPF_STX_XADD(BPF_DW, BPF_REG_10, BPF_REG_6, -8), + BPF_ATOMIC_OP(BPF_DW, BPF_ADD, BPF_REG_10, BPF_REG_6, -8), BPF_LDX_MEM(BPF_DW, BPF_REG_5, BPF_REG_10, -8), BPF_JMP_IMM(BPF_JGT, BPF_REG_5, 100, 6), BPF_ALU64_REG(BPF_ADD, BPF_REG_2, BPF_REG_5), diff --git a/tools/testing/selftests/bpf/verifier/unpriv.c b/tools/testing/selftests/bpf/verifier/unpriv.c index a3fe0fbaed41..ee298627abae 100644 --- a/tools/testing/selftests/bpf/verifier/unpriv.c +++ b/tools/testing/selftests/bpf/verifier/unpriv.c @@ -207,7 +207,8 @@ BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -8), BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_1, 0), BPF_MOV64_IMM(BPF_REG_0, 1), - BPF_RAW_INSN(BPF_STX | BPF_XADD | BPF_DW, BPF_REG_10, BPF_REG_0, -8, 0), + BPF_RAW_INSN(BPF_STX | BPF_ATOMIC | BPF_DW, + BPF_REG_10, BPF_REG_0, -8, BPF_ADD), BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_6, 0), BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_get_hash_recalc), BPF_EXIT_INSN(), diff --git a/tools/testing/selftests/bpf/verifier/value_illegal_alu.c b/tools/testing/selftests/bpf/verifier/value_illegal_alu.c index ed1c2cea1dea..489062867218 100644 --- a/tools/testing/selftests/bpf/verifier/value_illegal_alu.c +++ b/tools/testing/selftests/bpf/verifier/value_illegal_alu.c @@ -82,7 +82,7 @@ BPF_MOV64_REG(BPF_REG_2, BPF_REG_10), BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8), BPF_STX_MEM(BPF_DW, BPF_REG_2, BPF_REG_0, 0), - BPF_STX_XADD(BPF_DW, BPF_REG_2, BPF_REG_3, 0), + BPF_ATOMIC_OP(BPF_DW, BPF_ADD, BPF_REG_2, BPF_REG_3, 0), BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_2, 0), BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 22), BPF_EXIT_INSN(), diff --git a/tools/testing/selftests/bpf/verifier/xadd.c b/tools/testing/selftests/bpf/verifier/xadd.c index c5de2e62cc8b..b96ef3526815 100644 --- a/tools/testing/selftests/bpf/verifier/xadd.c +++ b/tools/testing/selftests/bpf/verifier/xadd.c @@ -3,7 +3,7 @@ .insns = { BPF_MOV64_IMM(BPF_REG_0, 1), BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -8), - BPF_STX_XADD(BPF_W, BPF_REG_10, BPF_REG_0, -7), + BPF_ATOMIC_OP(BPF_W, BPF_ADD, BPF_REG_10, BPF_REG_0, -7), BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_10, -8), BPF_EXIT_INSN(), }, @@ -22,7 +22,7 @@ BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1), BPF_EXIT_INSN(), BPF_MOV64_IMM(BPF_REG_1, 1), - BPF_STX_XADD(BPF_W, BPF_REG_0, BPF_REG_1, 3), + BPF_ATOMIC_OP(BPF_W, BPF_ADD, BPF_REG_0, BPF_REG_1, 3), BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_0, 3), BPF_EXIT_INSN(), }, @@ -45,13 +45,13 @@ BPF_MOV64_IMM(BPF_REG_0, 1), BPF_ST_MEM(BPF_W, BPF_REG_2, 0, 0), BPF_ST_MEM(BPF_W, BPF_REG_2, 3, 0), - BPF_STX_XADD(BPF_W, BPF_REG_2, BPF_REG_0, 1), - BPF_STX_XADD(BPF_W, BPF_REG_2, BPF_REG_0, 2), + BPF_ATOMIC_OP(BPF_W, BPF_ADD, BPF_REG_2, BPF_REG_0, 1), + BPF_ATOMIC_OP(BPF_W, BPF_ADD, BPF_REG_2, BPF_REG_0, 2), BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_2, 1), BPF_EXIT_INSN(), }, .result = REJECT, - .errstr = "BPF_XADD stores into R2 pkt is not allowed", + .errstr = "BPF_ATOMIC stores into R2 pkt is not allowed", .prog_type = BPF_PROG_TYPE_XDP, .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS, }, @@ -62,8 +62,8 @@ BPF_MOV64_REG(BPF_REG_6, BPF_REG_0), BPF_MOV64_REG(BPF_REG_7, BPF_REG_10), BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -8), - BPF_STX_XADD(BPF_DW, BPF_REG_10, BPF_REG_0, -8), - BPF_STX_XADD(BPF_DW, BPF_REG_10, BPF_REG_0, -8), + BPF_ATOMIC_OP(BPF_DW, BPF_ADD, BPF_REG_10, BPF_REG_0, -8), + BPF_ATOMIC_OP(BPF_DW, BPF_ADD, BPF_REG_10, BPF_REG_0, -8), BPF_JMP_REG(BPF_JNE, BPF_REG_6, BPF_REG_0, 3), BPF_JMP_REG(BPF_JNE, BPF_REG_7, BPF_REG_10, 2), BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_10, -8), @@ -82,8 +82,8 @@ BPF_MOV64_REG(BPF_REG_6, BPF_REG_0), BPF_MOV64_REG(BPF_REG_7, BPF_REG_10), BPF_STX_MEM(BPF_W, BPF_REG_10, BPF_REG_0, -8), - BPF_STX_XADD(BPF_W, BPF_REG_10, BPF_REG_0, -8), - BPF_STX_XADD(BPF_W, BPF_REG_10, BPF_REG_0, -8), + BPF_ATOMIC_OP(BPF_W, BPF_ADD, BPF_REG_10, BPF_REG_0, -8), + BPF_ATOMIC_OP(BPF_W, BPF_ADD, BPF_REG_10, BPF_REG_0, -8), BPF_JMP_REG(BPF_JNE, BPF_REG_6, BPF_REG_0, 3), BPF_JMP_REG(BPF_JNE, BPF_REG_7, BPF_REG_10, 2), BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_10, -8), -- cgit v1.2.3 From de948576f8e7d7fa1b5db04f56184ffe176177c5 Mon Sep 17 00:00:00 2001 From: Brendan Jackman Date: Thu, 14 Jan 2021 18:17:51 +0000 Subject: bpf: Document new atomic instructions Document new atomic instructions. Signed-off-by: Brendan Jackman Signed-off-by: Alexei Starovoitov Acked-by: Yonghong Song Link: https://lore.kernel.org/bpf/20210114181751.768687-12-jackmanb@google.com --- Documentation/networking/filter.rst | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) (limited to 'Documentation') diff --git a/Documentation/networking/filter.rst b/Documentation/networking/filter.rst index 1583d59d806d..f6d8f90e9a56 100644 --- a/Documentation/networking/filter.rst +++ b/Documentation/networking/filter.rst @@ -1053,8 +1053,39 @@ encoding. .imm = BPF_ADD, .code = BPF_ATOMIC | BPF_W | BPF_STX: lock xadd *(u32 *)(dst_reg + off16) += src_reg .imm = BPF_ADD, .code = BPF_ATOMIC | BPF_DW | BPF_STX: lock xadd *(u64 *)(dst_reg + off16) += src_reg +The basic atomic operations supported are: + + BPF_ADD + BPF_AND + BPF_OR + BPF_XOR + +Each having equivalent semantics with the ``BPF_ADD`` example, that is: the +memory location addresed by ``dst_reg + off`` is atomically modified, with +``src_reg`` as the other operand. If the ``BPF_FETCH`` flag is set in the +immediate, then these operations also overwrite ``src_reg`` with the +value that was in memory before it was modified. + +The more special operations are: + + BPF_XCHG + +This atomically exchanges ``src_reg`` with the value addressed by ``dst_reg + +off``. + + BPF_CMPXCHG + +This atomically compares the value addressed by ``dst_reg + off`` with +``R0``. If they match it is replaced with ``src_reg``, The value that was there +before is loaded back to ``R0``. + Note that 1 and 2 byte atomic operations are not supported. +Except ``BPF_ADD`` _without_ ``BPF_FETCH`` (for legacy reasons), all 4 byte +atomic operations require alu32 mode. Clang enables this mode by default in +architecture v3 (``-mcpu=v3``). For older versions it can be enabled with +``-Xclang -target-feature -Xclang +alu32``. + You may encounter BPF_XADD - this is a legacy name for BPF_ATOMIC, referring to the exclusive-add operation encoded when the immediate field is zero. -- cgit v1.2.3 From c4e43aa2eeb0cffcf0b17e0a60a9d212de9c49df Mon Sep 17 00:00:00 2001 From: Tushar Sugandhi Date: Thu, 7 Jan 2021 20:07:04 -0800 Subject: IMA: add policy rule to measure critical data A new IMA policy rule is needed for the IMA hook ima_measure_critical_data() and the corresponding func CRITICAL_DATA for measuring the input buffer. The policy rule should ensure the buffer would get measured only when the policy rule allows the action. The policy rule should also support the necessary constraints (flags etc.) for integrity critical buffer data measurements. Add policy rule support for measuring integrity critical data. Signed-off-by: Tushar Sugandhi Reviewed-by: Tyler Hicks Signed-off-by: Mimi Zohar --- Documentation/ABI/testing/ima_policy | 2 +- security/integrity/ima/ima_policy.c | 29 +++++++++++++++++++++++++---- 2 files changed, 26 insertions(+), 5 deletions(-) (limited to 'Documentation') diff --git a/Documentation/ABI/testing/ima_policy b/Documentation/ABI/testing/ima_policy index e35263f97fc1..6ec7daa87cba 100644 --- a/Documentation/ABI/testing/ima_policy +++ b/Documentation/ABI/testing/ima_policy @@ -32,7 +32,7 @@ Description: func:= [BPRM_CHECK][MMAP_CHECK][CREDS_CHECK][FILE_CHECK]MODULE_CHECK] [FIRMWARE_CHECK] [KEXEC_KERNEL_CHECK] [KEXEC_INITRAMFS_CHECK] - [KEXEC_CMDLINE] [KEY_CHECK] + [KEXEC_CMDLINE] [KEY_CHECK] [CRITICAL_DATA] mask:= [[^]MAY_READ] [[^]MAY_WRITE] [[^]MAY_APPEND] [[^]MAY_EXEC] fsmagic:= hex value diff --git a/security/integrity/ima/ima_policy.c b/security/integrity/ima/ima_policy.c index b93966034368..96ba4273c4d0 100644 --- a/security/integrity/ima/ima_policy.c +++ b/security/integrity/ima/ima_policy.c @@ -478,6 +478,8 @@ static bool ima_match_rule_data(struct ima_rule_entry *rule, opt_list = rule->keyrings; break; + case CRITICAL_DATA: + return true; default: return false; } @@ -514,13 +516,19 @@ static bool ima_match_rules(struct ima_rule_entry *rule, struct inode *inode, { int i; - if (func == KEY_CHECK) { - return (rule->flags & IMA_FUNC) && (rule->func == func) && - ima_match_rule_data(rule, func_data, cred); - } if ((rule->flags & IMA_FUNC) && (rule->func != func && func != POST_SETATTR)) return false; + + switch (func) { + case KEY_CHECK: + case CRITICAL_DATA: + return ((rule->func == func) && + ima_match_rule_data(rule, func_data, cred)); + default: + break; + } + if ((rule->flags & IMA_MASK) && (rule->mask != mask && func != POST_SETATTR)) return false; @@ -1115,6 +1123,17 @@ static bool ima_validate_rule(struct ima_rule_entry *entry) if (ima_rule_contains_lsm_cond(entry)) return false; + break; + case CRITICAL_DATA: + if (entry->action & ~(MEASURE | DONT_MEASURE)) + return false; + + if (entry->flags & ~(IMA_FUNC | IMA_UID | IMA_PCR)) + return false; + + if (ima_rule_contains_lsm_cond(entry)) + return false; + break; default: return false; @@ -1247,6 +1266,8 @@ static int ima_parse_rule(char *rule, struct ima_rule_entry *entry) else if (IS_ENABLED(CONFIG_IMA_MEASURE_ASYMMETRIC_KEYS) && strcmp(args[0].from, "KEY_CHECK") == 0) entry->func = KEY_CHECK; + else if (strcmp(args[0].from, "CRITICAL_DATA") == 0) + entry->func = CRITICAL_DATA; else result = -EINVAL; if (!result) -- cgit v1.2.3 From 47d76a4840501c1cefb3fbce777a86c58b02532b Mon Sep 17 00:00:00 2001 From: Tushar Sugandhi Date: Thu, 7 Jan 2021 20:07:05 -0800 Subject: IMA: limit critical data measurement based on a label Integrity critical data may belong to a single subsystem or it may arise from cross subsystem interaction. Currently there is no mechanism to group or limit the data based on certain label. Limiting and grouping critical data based on a label would make it flexible and configurable to measure. Define "label:=", a new IMA policy condition, for the IMA func CRITICAL_DATA to allow grouping and limiting measurement of integrity critical data. Limit the measurement to the labels that are specified in the IMA policy - CRITICAL_DATA+"label:=". If "label:=" is not provided with the func CRITICAL_DATA, measure all the input integrity critical data. Signed-off-by: Tushar Sugandhi Reviewed-by: Tyler Hicks Signed-off-by: Mimi Zohar --- Documentation/ABI/testing/ima_policy | 2 ++ security/integrity/ima/ima_policy.c | 37 +++++++++++++++++++++++++++++++++--- 2 files changed, 36 insertions(+), 3 deletions(-) (limited to 'Documentation') diff --git a/Documentation/ABI/testing/ima_policy b/Documentation/ABI/testing/ima_policy index 6ec7daa87cba..54fe1c15ed50 100644 --- a/Documentation/ABI/testing/ima_policy +++ b/Documentation/ABI/testing/ima_policy @@ -52,6 +52,8 @@ Description: template:= name of a defined IMA template type (eg, ima-ng). Only valid when action is "measure". pcr:= decimal value + label:= [data_label] + data_label:= a unique string used for grouping and limiting critical data. default policy: # PROC_SUPER_MAGIC diff --git a/security/integrity/ima/ima_policy.c b/security/integrity/ima/ima_policy.c index 96ba4273c4d0..2c9db2d0b434 100644 --- a/security/integrity/ima/ima_policy.c +++ b/security/integrity/ima/ima_policy.c @@ -34,6 +34,7 @@ #define IMA_PCR 0x0100 #define IMA_FSNAME 0x0200 #define IMA_KEYRINGS 0x0400 +#define IMA_LABEL 0x0800 #define UNKNOWN 0 #define MEASURE 0x0001 /* same as IMA_MEASURE */ @@ -85,6 +86,7 @@ struct ima_rule_entry { } lsm[MAX_LSM_RULES]; char *fsname; struct ima_rule_opt_list *keyrings; /* Measure keys added to these keyrings */ + struct ima_rule_opt_list *label; /* Measure data grouped under this label */ struct ima_template_desc *template; }; @@ -479,7 +481,11 @@ static bool ima_match_rule_data(struct ima_rule_entry *rule, opt_list = rule->keyrings; break; case CRITICAL_DATA: - return true; + if (!rule->label) + return true; + + opt_list = rule->label; + break; default: return false; } @@ -924,7 +930,7 @@ enum { Opt_uid_lt, Opt_euid_lt, Opt_fowner_lt, Opt_appraise_type, Opt_appraise_flag, Opt_permit_directio, Opt_pcr, Opt_template, Opt_keyrings, - Opt_err + Opt_label, Opt_err }; static const match_table_t policy_tokens = { @@ -961,6 +967,7 @@ static const match_table_t policy_tokens = { {Opt_pcr, "pcr=%s"}, {Opt_template, "template=%s"}, {Opt_keyrings, "keyrings=%s"}, + {Opt_label, "label=%s"}, {Opt_err, NULL} }; @@ -1128,7 +1135,8 @@ static bool ima_validate_rule(struct ima_rule_entry *entry) if (entry->action & ~(MEASURE | DONT_MEASURE)) return false; - if (entry->flags & ~(IMA_FUNC | IMA_UID | IMA_PCR)) + if (entry->flags & ~(IMA_FUNC | IMA_UID | IMA_PCR | + IMA_LABEL)) return false; if (ima_rule_contains_lsm_cond(entry)) @@ -1338,6 +1346,23 @@ static int ima_parse_rule(char *rule, struct ima_rule_entry *entry) entry->flags |= IMA_KEYRINGS; break; + case Opt_label: + ima_log_string(ab, "label", args[0].from); + + if (entry->label) { + result = -EINVAL; + break; + } + + entry->label = ima_alloc_rule_opt_list(args); + if (IS_ERR(entry->label)) { + result = PTR_ERR(entry->label); + entry->label = NULL; + break; + } + + entry->flags |= IMA_LABEL; + break; case Opt_fsuuid: ima_log_string(ab, "fsuuid", args[0].from); @@ -1718,6 +1743,12 @@ int ima_policy_show(struct seq_file *m, void *v) seq_puts(m, " "); } + if (entry->flags & IMA_LABEL) { + seq_puts(m, "label="); + ima_show_rule_opt_list(m, entry->label); + seq_puts(m, " "); + } + if (entry->flags & IMA_PCR) { snprintf(tbuf, sizeof(tbuf), "%d", entry->pcr); seq_printf(m, pt(Opt_pcr), tbuf); -- cgit v1.2.3 From 03cee168366621db85000cec47f5cefdb83e049b Mon Sep 17 00:00:00 2001 From: Lakshmi Ramasubramanian Date: Thu, 7 Jan 2021 20:07:07 -0800 Subject: IMA: define a builtin critical data measurement policy Define a new critical data builtin policy to allow measuring early kernel integrity critical data before a custom IMA policy is loaded. Update the documentation on kernel parameters to document the new critical data builtin policy. Signed-off-by: Lakshmi Ramasubramanian Reviewed-by: Tyler Hicks Signed-off-by: Mimi Zohar --- Documentation/admin-guide/kernel-parameters.txt | 5 ++++- security/integrity/ima/ima_policy.c | 12 ++++++++++++ 2 files changed, 16 insertions(+), 1 deletion(-) (limited to 'Documentation') diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt index 9e3cdb271d06..65a0c4c9ab18 100644 --- a/Documentation/admin-guide/kernel-parameters.txt +++ b/Documentation/admin-guide/kernel-parameters.txt @@ -1746,7 +1746,7 @@ ima_policy= [IMA] The builtin policies to load during IMA setup. Format: "tcb | appraise_tcb | secure_boot | - fail_securely" + fail_securely | critical_data" The "tcb" policy measures all programs exec'd, files mmap'd for exec, and all files opened with the read @@ -1765,6 +1765,9 @@ filesystems with the SB_I_UNVERIFIABLE_SIGNATURE flag. + The "critical_data" policy measures kernel integrity + critical data. + ima_tcb [IMA] Deprecated. Use ima_policy= instead. Load a policy which meets the needs of the Trusted Computing Base. This means IMA will measure all diff --git a/security/integrity/ima/ima_policy.c b/security/integrity/ima/ima_policy.c index 2c9db2d0b434..9b45d064a87d 100644 --- a/security/integrity/ima/ima_policy.c +++ b/security/integrity/ima/ima_policy.c @@ -206,6 +206,10 @@ static struct ima_rule_entry secure_boot_rules[] __ro_after_init = { .flags = IMA_FUNC | IMA_DIGSIG_REQUIRED}, }; +static struct ima_rule_entry critical_data_rules[] __ro_after_init = { + {.action = MEASURE, .func = CRITICAL_DATA, .flags = IMA_FUNC}, +}; + /* An array of architecture specific rules */ static struct ima_rule_entry *arch_policy_entry __ro_after_init; @@ -228,6 +232,7 @@ __setup("ima_tcb", default_measure_policy_setup); static bool ima_use_appraise_tcb __initdata; static bool ima_use_secure_boot __initdata; +static bool ima_use_critical_data __initdata; static bool ima_fail_unverifiable_sigs __ro_after_init; static int __init policy_setup(char *str) { @@ -242,6 +247,8 @@ static int __init policy_setup(char *str) ima_use_appraise_tcb = true; else if (strcmp(p, "secure_boot") == 0) ima_use_secure_boot = true; + else if (strcmp(p, "critical_data") == 0) + ima_use_critical_data = true; else if (strcmp(p, "fail_securely") == 0) ima_fail_unverifiable_sigs = true; else @@ -871,6 +878,11 @@ void __init ima_init_policy(void) ARRAY_SIZE(default_appraise_rules), IMA_DEFAULT_POLICY); + if (ima_use_critical_data) + add_rules(critical_data_rules, + ARRAY_SIZE(critical_data_rules), + IMA_DEFAULT_POLICY); + ima_update_policy_flag(); } -- cgit v1.2.3 From fdd1ffe8a812b1109388e4bc389e57b2695ad095 Mon Sep 17 00:00:00 2001 From: Lakshmi Ramasubramanian Date: Thu, 14 Jan 2021 11:15:22 -0800 Subject: selinux: include a consumer of the new IMA critical data hook SELinux stores the active policy in memory, so the changes to this data at runtime would have an impact on the security guarantees provided by SELinux. Measuring in-memory SELinux policy through IMA subsystem provides a secure way for the attestation service to remotely validate the policy contents at runtime. Measure the hash of the loaded policy by calling the IMA hook ima_measure_critical_data(). Since the size of the loaded policy can be large (several MB), measure the hash of the policy instead of the entire policy to avoid bloating the IMA log entry. To enable SELinux data measurement, the following steps are required: 1, Add "ima_policy=critical_data" to the kernel command line arguments to enable measuring SELinux data at boot time. For example, BOOT_IMAGE=/boot/vmlinuz-5.10.0-rc1+ root=UUID=fd643309-a5d2-4ed3-b10d-3c579a5fab2f ro nomodeset security=selinux ima_policy=critical_data 2, Add the following rule to /etc/ima/ima-policy measure func=CRITICAL_DATA label=selinux Sample measurement of the hash of SELinux policy: To verify the measured data with the current SELinux policy run the following commands and verify the output hash values match. sha256sum /sys/fs/selinux/policy | cut -d' ' -f 1 grep "selinux-policy-hash" /sys/kernel/security/integrity/ima/ascii_runtime_measurements | tail -1 | cut -d' ' -f 6 Note that the actual verification of SELinux policy would require loading the expected policy into an identical kernel on a pristine/known-safe system and run the sha256sum /sys/kernel/selinux/policy there to get the expected hash. Signed-off-by: Lakshmi Ramasubramanian Suggested-by: Stephen Smalley Acked-by: Paul Moore Reviewed-by: Tyler Hicks Signed-off-by: Mimi Zohar --- Documentation/ABI/testing/ima_policy | 3 +- security/selinux/Makefile | 2 ++ security/selinux/ima.c | 44 +++++++++++++++++++++++++ security/selinux/include/ima.h | 24 ++++++++++++++ security/selinux/include/security.h | 3 +- security/selinux/ss/services.c | 64 +++++++++++++++++++++++++++++++----- 6 files changed, 129 insertions(+), 11 deletions(-) create mode 100644 security/selinux/ima.c create mode 100644 security/selinux/include/ima.h (limited to 'Documentation') diff --git a/Documentation/ABI/testing/ima_policy b/Documentation/ABI/testing/ima_policy index 54fe1c15ed50..8365596cb42b 100644 --- a/Documentation/ABI/testing/ima_policy +++ b/Documentation/ABI/testing/ima_policy @@ -52,8 +52,9 @@ Description: template:= name of a defined IMA template type (eg, ima-ng). Only valid when action is "measure". pcr:= decimal value - label:= [data_label] + label:= [selinux]|[data_label] data_label:= a unique string used for grouping and limiting critical data. + For example, "selinux" to measure critical data for SELinux. default policy: # PROC_SUPER_MAGIC diff --git a/security/selinux/Makefile b/security/selinux/Makefile index 4d8e0e8adf0b..776162444882 100644 --- a/security/selinux/Makefile +++ b/security/selinux/Makefile @@ -16,6 +16,8 @@ selinux-$(CONFIG_NETLABEL) += netlabel.o selinux-$(CONFIG_SECURITY_INFINIBAND) += ibpkey.o +selinux-$(CONFIG_IMA) += ima.o + ccflags-y := -I$(srctree)/security/selinux -I$(srctree)/security/selinux/include $(addprefix $(obj)/,$(selinux-y)): $(obj)/flask.h diff --git a/security/selinux/ima.c b/security/selinux/ima.c new file mode 100644 index 000000000000..03715893ff97 --- /dev/null +++ b/security/selinux/ima.c @@ -0,0 +1,44 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2021 Microsoft Corporation + * + * Author: Lakshmi Ramasubramanian (nramas@linux.microsoft.com) + * + * Measure critical data structures maintainted by SELinux + * using IMA subsystem. + */ +#include +#include +#include "security.h" +#include "ima.h" + +/* + * selinux_ima_measure_state - Measure hash of the SELinux policy + * + * @state: selinux state struct + * + * NOTE: This function must be called with policy_mutex held. + */ +void selinux_ima_measure_state(struct selinux_state *state) +{ + void *policy = NULL; + size_t policy_len; + int rc = 0; + + /* + * Measure SELinux policy only after initialization is completed. + */ + if (!selinux_initialized(state)) + return; + + rc = security_read_state_kernel(state, &policy, &policy_len); + if (rc) { + pr_err("SELinux: %s: failed to read policy %d.\n", __func__, rc); + return; + } + + ima_measure_critical_data("selinux", "selinux-policy-hash", + policy, policy_len, true); + + vfree(policy); +} diff --git a/security/selinux/include/ima.h b/security/selinux/include/ima.h new file mode 100644 index 000000000000..d69c36611423 --- /dev/null +++ b/security/selinux/include/ima.h @@ -0,0 +1,24 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright (C) 2021 Microsoft Corporation + * + * Author: Lakshmi Ramasubramanian (nramas@linux.microsoft.com) + * + * Measure critical data structures maintainted by SELinux + * using IMA subsystem. + */ + +#ifndef _SELINUX_IMA_H_ +#define _SELINUX_IMA_H_ + +#include "security.h" + +#ifdef CONFIG_IMA +extern void selinux_ima_measure_state(struct selinux_state *selinux_state); +#else +static inline void selinux_ima_measure_state(struct selinux_state *selinux_state) +{ +} +#endif + +#endif /* _SELINUX_IMA_H_ */ diff --git a/security/selinux/include/security.h b/security/selinux/include/security.h index 3cc8bab31ea8..29cae32d3fc5 100644 --- a/security/selinux/include/security.h +++ b/security/selinux/include/security.h @@ -229,7 +229,8 @@ void selinux_policy_cancel(struct selinux_state *state, struct selinux_policy *policy); int security_read_policy(struct selinux_state *state, void **data, size_t *len); - +int security_read_state_kernel(struct selinux_state *state, + void **data, size_t *len); int security_policycap_supported(struct selinux_state *state, unsigned int req_cap); diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c index 597b79703584..2106b5d383e7 100644 --- a/security/selinux/ss/services.c +++ b/security/selinux/ss/services.c @@ -65,6 +65,7 @@ #include "ebitmap.h" #include "audit.h" #include "policycap_names.h" +#include "ima.h" /* Forward declaration. */ static int context_struct_to_string(struct policydb *policydb, @@ -2178,6 +2179,7 @@ static void selinux_notify_policy_change(struct selinux_state *state, selinux_status_update_policyload(state, seqno); selinux_netlbl_cache_invalidate(); selinux_xfrm_notify_policyload(); + selinux_ima_measure_state(state); } void selinux_policy_commit(struct selinux_state *state, @@ -3873,8 +3875,33 @@ out: } #endif /* CONFIG_NETLABEL */ +/** + * __security_read_policy - read the policy. + * @policy: SELinux policy + * @data: binary policy data + * @len: length of data in bytes + * + */ +static int __security_read_policy(struct selinux_policy *policy, + void *data, size_t *len) +{ + int rc; + struct policy_file fp; + + fp.data = data; + fp.len = *len; + + rc = policydb_write(&policy->policydb, &fp); + if (rc) + return rc; + + *len = (unsigned long)fp.data - (unsigned long)data; + return 0; +} + /** * security_read_policy - read the policy. + * @state: selinux_state * @data: binary policy data * @len: length of data in bytes * @@ -3883,8 +3910,6 @@ int security_read_policy(struct selinux_state *state, void **data, size_t *len) { struct selinux_policy *policy; - int rc; - struct policy_file fp; policy = rcu_dereference_protected( state->policy, lockdep_is_held(&state->policy_mutex)); @@ -3896,14 +3921,35 @@ int security_read_policy(struct selinux_state *state, if (!*data) return -ENOMEM; - fp.data = *data; - fp.len = *len; + return __security_read_policy(policy, *data, len); +} - rc = policydb_write(&policy->policydb, &fp); - if (rc) - return rc; +/** + * security_read_state_kernel - read the policy. + * @state: selinux_state + * @data: binary policy data + * @len: length of data in bytes + * + * Allocates kernel memory for reading SELinux policy. + * This function is for internal use only and should not + * be used for returning data to user space. + * + * This function must be called with policy_mutex held. + */ +int security_read_state_kernel(struct selinux_state *state, + void **data, size_t *len) +{ + struct selinux_policy *policy; - *len = (unsigned long)fp.data - (unsigned long)*data; - return 0; + policy = rcu_dereference_protected( + state->policy, lockdep_is_held(&state->policy_mutex)); + if (!policy) + return -EINVAL; + + *len = policy->policydb.len; + *data = vmalloc(*len); + if (!*data) + return -ENOMEM; + return __security_read_policy(policy, *data, len); } -- cgit v1.2.3 From 3da88be249973f7b74e7b24ed559e6abc2fc5af4 Mon Sep 17 00:00:00 2001 From: Mika Westerberg Date: Tue, 10 Nov 2020 11:47:14 +0300 Subject: thunderbolt: Add support for de-authorizing devices In some cases it is useful to be able de-authorize devices. For example if user logs out the userspace can have a policy that disconnects PCIe devices until logged in again. This is only possible for software based connection manager as it directly controls the tunnels. For this reason make the authorized attribute accept writing 0 which makes the software connection manager to tear down the corresponding PCIe tunnel. Userspace can check if this is supported by reading a new domain attribute deauthorization, that holds 1 in that case. While there correct tb_domain_approve_switch() kernel-doc and description of authorized attribute to mention that it is only about PCIe tunnels. Cc: Christian Kellner Signed-off-by: Mika Westerberg Acked-by: Yehezkel Bernat --- Documentation/ABI/testing/sysfs-bus-thunderbolt | 20 ++++++++++++--- Documentation/admin-guide/thunderbolt.rst | 16 ++++++++++++ drivers/thunderbolt/domain.c | 32 +++++++++++++++++++++-- drivers/thunderbolt/switch.c | 34 ++++++++++++++++++++++++- drivers/thunderbolt/tb.c | 20 +++++++++++++++ drivers/thunderbolt/tb.h | 3 +++ 6 files changed, 118 insertions(+), 7 deletions(-) (limited to 'Documentation') diff --git a/Documentation/ABI/testing/sysfs-bus-thunderbolt b/Documentation/ABI/testing/sysfs-bus-thunderbolt index a91b4b24496e..581dea95245b 100644 --- a/Documentation/ABI/testing/sysfs-bus-thunderbolt +++ b/Documentation/ABI/testing/sysfs-bus-thunderbolt @@ -49,6 +49,15 @@ Description: Holds a comma separated list of device unique_ids that If a device is authorized automatically during boot its boot attribute is set to 1. +What: /sys/bus/thunderbolt/devices/.../domainX/deauthorization +Date: May 2021 +KernelVersion: 5.12 +Contact: Mika Westerberg +Description: This attribute tells whether the system supports + de-authorization of devices. Value of 1 means user can + de-authorize PCIe tunnel by writing 0 to authorized + attribute under each device. + What: /sys/bus/thunderbolt/devices/.../domainX/iommu_dma_protection Date: Mar 2019 KernelVersion: 4.21 @@ -84,22 +93,25 @@ KernelVersion: 4.13 Contact: thunderbolt-software@lists.01.org Description: This attribute is used to authorize Thunderbolt devices after they have been connected. If the device is not - authorized, no devices such as PCIe and Display port are - available to the system. + authorized, no PCIe devices are available to the system. Contents of this attribute will be 0 when the device is not yet authorized. Possible values are supported: - == =========================================== + == =================================================== + 0 The device will be de-authorized (only supported if + deauthorization attribute under domain contains 1) 1 The device will be authorized and connected - == =========================================== + == =================================================== When key attribute contains 32 byte hex string the possible values are: == ======================================================== + 0 The device will be de-authorized (only supported if + deauthorization attribute under domain contains 1) 1 The 32 byte hex string is added to the device NVM and the device is authorized. 2 Send a challenge based on the 32 byte hex string. If the diff --git a/Documentation/admin-guide/thunderbolt.rst b/Documentation/admin-guide/thunderbolt.rst index 613cb24c76c7..0d4348445f91 100644 --- a/Documentation/admin-guide/thunderbolt.rst +++ b/Documentation/admin-guide/thunderbolt.rst @@ -153,6 +153,22 @@ If the user still wants to connect the device they can either approve the device without a key or write a new key and write 1 to the ``authorized`` file to get the new key stored on the device NVM. +De-authorizing devices +---------------------- +It is possible to de-authorize devices by writing ``0`` to their +``authorized`` attribute. This requires support from the connection +manager implementation and can be checked by reading domain +``deauthorization`` attribute. If it reads ``1`` then the feature is +supported. + +When a device is de-authorized the PCIe tunnel from the parent device +PCIe downstream (or root) port to the device PCIe upstream port is torn +down. This is essentially the same thing as PCIe hot-remove and the PCIe +toplogy in question will not be accessible anymore until the device is +authorized again. If there is storage such as NVMe or similar involved, +there is a risk for data loss if the filesystem on that storage is not +properly shut down. You have been warned! + DMA protection utilizing IOMMU ------------------------------ Recent systems from 2018 and forward with Thunderbolt ports may natively diff --git a/drivers/thunderbolt/domain.c b/drivers/thunderbolt/domain.c index d2b92a8be577..9ba2181464cc 100644 --- a/drivers/thunderbolt/domain.c +++ b/drivers/thunderbolt/domain.c @@ -238,6 +238,16 @@ err_free_str: } static DEVICE_ATTR_RW(boot_acl); +static ssize_t deauthorization_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + const struct tb *tb = container_of(dev, struct tb, dev); + + return sprintf(buf, "%d\n", !!tb->cm_ops->disapprove_switch); +} +static DEVICE_ATTR_RO(deauthorization); + static ssize_t iommu_dma_protection_show(struct device *dev, struct device_attribute *attr, char *buf) @@ -267,6 +277,7 @@ static DEVICE_ATTR_RO(security); static struct attribute *domain_attrs[] = { &dev_attr_boot_acl.attr, + &dev_attr_deauthorization.attr, &dev_attr_iommu_dma_protection.attr, &dev_attr_security.attr, NULL, @@ -601,14 +612,31 @@ int tb_domain_runtime_resume(struct tb *tb) return 0; } +/** + * tb_domain_disapprove_switch() - Disapprove switch + * @tb: Domain the switch belongs to + * @sw: Switch to disapprove + * + * This will disconnect PCIe tunnel from parent to this @sw. + * + * Return: %0 on success and negative errno in case of failure. + */ +int tb_domain_disapprove_switch(struct tb *tb, struct tb_switch *sw) +{ + if (!tb->cm_ops->disapprove_switch) + return -EPERM; + + return tb->cm_ops->disapprove_switch(tb, sw); +} + /** * tb_domain_approve_switch() - Approve switch * @tb: Domain the switch belongs to * @sw: Switch to approve * * This will approve switch by connection manager specific means. In - * case of success the connection manager will create tunnels for all - * supported protocols. + * case of success the connection manager will create PCIe tunnel from + * parent to @sw. */ int tb_domain_approve_switch(struct tb *tb, struct tb_switch *sw) { diff --git a/drivers/thunderbolt/switch.c b/drivers/thunderbolt/switch.c index ad992e6204d9..cdba05e72486 100644 --- a/drivers/thunderbolt/switch.c +++ b/drivers/thunderbolt/switch.c @@ -1387,6 +1387,30 @@ static ssize_t authorized_show(struct device *dev, return sprintf(buf, "%u\n", sw->authorized); } +static int disapprove_switch(struct device *dev, void *not_used) +{ + struct tb_switch *sw; + + sw = tb_to_switch(dev); + if (sw && sw->authorized) { + int ret; + + /* First children */ + ret = device_for_each_child_reverse(&sw->dev, NULL, disapprove_switch); + if (ret) + return ret; + + ret = tb_domain_disapprove_switch(sw->tb, sw); + if (ret) + return ret; + + sw->authorized = 0; + kobject_uevent(&sw->dev.kobj, KOBJ_CHANGE); + } + + return 0; +} + static int tb_switch_set_authorized(struct tb_switch *sw, unsigned int val) { int ret = -EINVAL; @@ -1394,10 +1418,18 @@ static int tb_switch_set_authorized(struct tb_switch *sw, unsigned int val) if (!mutex_trylock(&sw->tb->lock)) return restart_syscall(); - if (sw->authorized) + if (!!sw->authorized == !!val) goto unlock; switch (val) { + /* Disapprove switch */ + case 0: + if (tb_route(sw)) { + ret = disapprove_switch(&sw->dev, NULL); + goto unlock; + } + break; + /* Approve switch */ case 1: if (sw->key) diff --git a/drivers/thunderbolt/tb.c b/drivers/thunderbolt/tb.c index 51d5b031cada..d08879849abe 100644 --- a/drivers/thunderbolt/tb.c +++ b/drivers/thunderbolt/tb.c @@ -1002,6 +1002,25 @@ static void tb_disconnect_and_release_dp(struct tb *tb) } } +static int tb_disconnect_pci(struct tb *tb, struct tb_switch *sw) +{ + struct tb_tunnel *tunnel; + struct tb_port *up; + + up = tb_switch_find_port(sw, TB_TYPE_PCIE_UP); + if (WARN_ON(!up)) + return -ENODEV; + + tunnel = tb_find_tunnel(tb, TB_TUNNEL_PCI, NULL, up); + if (WARN_ON(!tunnel)) + return -ENODEV; + + tb_tunnel_deactivate(tunnel); + list_del(&tunnel->list); + tb_tunnel_free(tunnel); + return 0; +} + static int tb_tunnel_pci(struct tb *tb, struct tb_switch *sw) { struct tb_port *up, *down, *port; @@ -1512,6 +1531,7 @@ static const struct tb_cm_ops tb_cm_ops = { .runtime_suspend = tb_runtime_suspend, .runtime_resume = tb_runtime_resume, .handle_event = tb_handle_event, + .disapprove_switch = tb_disconnect_pci, .approve_switch = tb_tunnel_pci, .approve_xdomain_paths = tb_approve_xdomain_paths, .disconnect_xdomain_paths = tb_disconnect_xdomain_paths, diff --git a/drivers/thunderbolt/tb.h b/drivers/thunderbolt/tb.h index 34ae83b9e52a..31468de658e4 100644 --- a/drivers/thunderbolt/tb.h +++ b/drivers/thunderbolt/tb.h @@ -361,6 +361,7 @@ struct tb_path { * @handle_event: Handle thunderbolt event * @get_boot_acl: Get boot ACL list * @set_boot_acl: Set boot ACL list + * @disapprove_switch: Disapprove switch (disconnect PCIe tunnel) * @approve_switch: Approve switch * @add_switch_key: Add key to switch * @challenge_switch_key: Challenge switch using key @@ -394,6 +395,7 @@ struct tb_cm_ops { const void *buf, size_t size); int (*get_boot_acl)(struct tb *tb, uuid_t *uuids, size_t nuuids); int (*set_boot_acl)(struct tb *tb, const uuid_t *uuids, size_t nuuids); + int (*disapprove_switch)(struct tb *tb, struct tb_switch *sw); int (*approve_switch)(struct tb *tb, struct tb_switch *sw); int (*add_switch_key)(struct tb *tb, struct tb_switch *sw); int (*challenge_switch_key)(struct tb *tb, struct tb_switch *sw, @@ -629,6 +631,7 @@ int tb_domain_thaw_noirq(struct tb *tb); void tb_domain_complete(struct tb *tb); int tb_domain_runtime_suspend(struct tb *tb); int tb_domain_runtime_resume(struct tb *tb); +int tb_domain_disapprove_switch(struct tb *tb, struct tb_switch *sw); int tb_domain_approve_switch(struct tb *tb, struct tb_switch *sw); int tb_domain_approve_switch_key(struct tb *tb, struct tb_switch *sw); int tb_domain_challenge_switch_key(struct tb *tb, struct tb_switch *sw); -- cgit v1.2.3 From fd4a641ac88fbbaf8b90e00823397597a287cfcd Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Wed, 13 Jan 2021 18:30:18 +0100 Subject: leds: trigger: implement a tty trigger MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Usage is as follows: myled=ledname tty=ttyS0 echo tty > /sys/class/leds/$myled/trigger echo $tty > /sys/class/leds/$myled/ttyname . When this new trigger is active it periodically checks the tty's statistics and when it changed since the last check the led is flashed once. Signed-off-by: Uwe Kleine-König Link: https://lore.kernel.org/r/20210113173018.bq2fkea2o3yp6rf6@pengutronix.de Signed-off-by: Greg Kroah-Hartman --- .../ABI/testing/sysfs-class-led-trigger-tty | 6 + drivers/leds/trigger/Kconfig | 9 + drivers/leds/trigger/Makefile | 1 + drivers/leds/trigger/ledtrig-tty.c | 183 +++++++++++++++++++++ 4 files changed, 199 insertions(+) create mode 100644 Documentation/ABI/testing/sysfs-class-led-trigger-tty create mode 100644 drivers/leds/trigger/ledtrig-tty.c (limited to 'Documentation') diff --git a/Documentation/ABI/testing/sysfs-class-led-trigger-tty b/Documentation/ABI/testing/sysfs-class-led-trigger-tty new file mode 100644 index 000000000000..2bf6b24e781b --- /dev/null +++ b/Documentation/ABI/testing/sysfs-class-led-trigger-tty @@ -0,0 +1,6 @@ +What: /sys/class/leds//ttyname +Date: Dec 2020 +KernelVersion: 5.10 +Contact: linux-leds@vger.kernel.org +Description: + Specifies the tty device name of the triggering tty diff --git a/drivers/leds/trigger/Kconfig b/drivers/leds/trigger/Kconfig index ce9429ca6dde..b77a01bd27f4 100644 --- a/drivers/leds/trigger/Kconfig +++ b/drivers/leds/trigger/Kconfig @@ -144,4 +144,13 @@ config LEDS_TRIGGER_AUDIO the audio mute and mic-mute changes. If unsure, say N +config LEDS_TRIGGER_TTY + tristate "LED Trigger for TTY devices" + depends on TTY + help + This allows LEDs to be controlled by activity on ttys which includes + serial devices like /dev/ttyS0. + + When build as a module this driver will be called ledtrig-tty. + endif # LEDS_TRIGGERS diff --git a/drivers/leds/trigger/Makefile b/drivers/leds/trigger/Makefile index 733a83e2a718..25c4db97cdd4 100644 --- a/drivers/leds/trigger/Makefile +++ b/drivers/leds/trigger/Makefile @@ -15,3 +15,4 @@ obj-$(CONFIG_LEDS_TRIGGER_PANIC) += ledtrig-panic.o obj-$(CONFIG_LEDS_TRIGGER_NETDEV) += ledtrig-netdev.o obj-$(CONFIG_LEDS_TRIGGER_PATTERN) += ledtrig-pattern.o obj-$(CONFIG_LEDS_TRIGGER_AUDIO) += ledtrig-audio.o +obj-$(CONFIG_LEDS_TRIGGER_TTY) += ledtrig-tty.o diff --git a/drivers/leds/trigger/ledtrig-tty.c b/drivers/leds/trigger/ledtrig-tty.c new file mode 100644 index 000000000000..d2ab6ab080ac --- /dev/null +++ b/drivers/leds/trigger/ledtrig-tty.c @@ -0,0 +1,183 @@ +// SPDX-License-Identifier: GPL-2.0 + +#include +#include +#include +#include +#include +#include + +struct ledtrig_tty_data { + struct led_classdev *led_cdev; + struct delayed_work dwork; + struct mutex mutex; + const char *ttyname; + struct tty_struct *tty; + int rx, tx; +}; + +static void ledtrig_tty_restart(struct ledtrig_tty_data *trigger_data) +{ + schedule_delayed_work(&trigger_data->dwork, 0); +} + +static ssize_t ttyname_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct ledtrig_tty_data *trigger_data = led_trigger_get_drvdata(dev); + ssize_t len = 0; + + mutex_lock(&trigger_data->mutex); + + if (trigger_data->ttyname) + len = sprintf(buf, "%s\n", trigger_data->ttyname); + + mutex_unlock(&trigger_data->mutex); + + return len; +} + +static ssize_t ttyname_store(struct device *dev, + struct device_attribute *attr, const char *buf, + size_t size) +{ + struct ledtrig_tty_data *trigger_data = led_trigger_get_drvdata(dev); + char *ttyname; + ssize_t ret = size; + bool running; + + if (size > 0 && buf[size - 1] == '\n') + size -= 1; + + if (size) { + ttyname = kmemdup_nul(buf, size, GFP_KERNEL); + if (!ttyname) { + ret = -ENOMEM; + goto out_unlock; + } + } else { + ttyname = NULL; + } + + mutex_lock(&trigger_data->mutex); + + running = trigger_data->ttyname != NULL; + + kfree(trigger_data->ttyname); + tty_kref_put(trigger_data->tty); + trigger_data->tty = NULL; + + trigger_data->ttyname = ttyname; + +out_unlock: + mutex_unlock(&trigger_data->mutex); + + if (ttyname && !running) + ledtrig_tty_restart(trigger_data); + + return ret; +} +static DEVICE_ATTR_RW(ttyname); + +static void ledtrig_tty_work(struct work_struct *work) +{ + struct ledtrig_tty_data *trigger_data = + container_of(work, struct ledtrig_tty_data, dwork.work); + struct serial_icounter_struct icount; + int ret; + + mutex_lock(&trigger_data->mutex); + + if (!trigger_data->ttyname) { + /* exit without rescheduling */ + mutex_unlock(&trigger_data->mutex); + return; + } + + /* try to get the tty corresponding to $ttyname */ + if (!trigger_data->tty) { + dev_t devno; + struct tty_struct *tty; + int ret; + + ret = tty_dev_name_to_number(trigger_data->ttyname, &devno); + if (ret < 0) + /* + * A device with this name might appear later, so keep + * retrying. + */ + goto out; + + tty = tty_kopen_shared(devno); + if (IS_ERR(tty) || !tty) + /* What to do? retry or abort */ + goto out; + + trigger_data->tty = tty; + } + + ret = tty_get_icount(trigger_data->tty, &icount); + if (ret) { + dev_info(trigger_data->tty->dev, "Failed to get icount, stopped polling\n"); + mutex_unlock(&trigger_data->mutex); + return; + } + + if (icount.rx != trigger_data->rx || + icount.tx != trigger_data->tx) { + led_set_brightness(trigger_data->led_cdev, LED_ON); + + trigger_data->rx = icount.rx; + trigger_data->tx = icount.tx; + } else { + led_set_brightness(trigger_data->led_cdev, LED_OFF); + } + +out: + mutex_unlock(&trigger_data->mutex); + schedule_delayed_work(&trigger_data->dwork, msecs_to_jiffies(100)); +} + +static struct attribute *ledtrig_tty_attrs[] = { + &dev_attr_ttyname.attr, + NULL +}; +ATTRIBUTE_GROUPS(ledtrig_tty); + +static int ledtrig_tty_activate(struct led_classdev *led_cdev) +{ + struct ledtrig_tty_data *trigger_data; + + trigger_data = kzalloc(sizeof(*trigger_data), GFP_KERNEL); + if (!trigger_data) + return -ENOMEM; + + led_set_trigger_data(led_cdev, trigger_data); + + INIT_DELAYED_WORK(&trigger_data->dwork, ledtrig_tty_work); + trigger_data->led_cdev = led_cdev; + mutex_init(&trigger_data->mutex); + + return 0; +} + +static void ledtrig_tty_deactivate(struct led_classdev *led_cdev) +{ + struct ledtrig_tty_data *trigger_data = led_get_trigger_data(led_cdev); + + cancel_delayed_work_sync(&trigger_data->dwork); + + kfree(trigger_data); +} + +static struct led_trigger ledtrig_tty = { + .name = "tty", + .activate = ledtrig_tty_activate, + .deactivate = ledtrig_tty_deactivate, + .groups = ledtrig_tty_groups, +}; +module_led_trigger(ledtrig_tty); + +MODULE_AUTHOR("Uwe Kleine-König "); +MODULE_DESCRIPTION("UART LED trigger"); +MODULE_LICENSE("GPL v2"); -- cgit v1.2.3 From 599bbb639e83029d7237b4114aaf237619c525eb Mon Sep 17 00:00:00 2001 From: Michael Walle Date: Tue, 29 Dec 2020 13:03:20 +0100 Subject: dt-bindings: arm: fsl: add Kontron sl28 variant 1 Add the a new variant for the Kontron SMARC-sAL28 board. Signed-off-by: Michael Walle Acked-by: Rob Herring Signed-off-by: Shawn Guo --- Documentation/devicetree/bindings/arm/fsl.yaml | 3 +++ 1 file changed, 3 insertions(+) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/arm/fsl.yaml b/Documentation/devicetree/bindings/arm/fsl.yaml index 2ae66407e2aa..89ef175ee49f 100644 --- a/Documentation/devicetree/bindings/arm/fsl.yaml +++ b/Documentation/devicetree/bindings/arm/fsl.yaml @@ -848,10 +848,12 @@ properties: Kontron SMARC-sAL28 board on the SMARC Eval Carrier 2.0 items: - enum: + - kontron,sl28-var1-ads2 - kontron,sl28-var2-ads2 - kontron,sl28-var3-ads2 - kontron,sl28-var4-ads2 - enum: + - kontron,sl28-var1 - kontron,sl28-var2 - kontron,sl28-var3 - kontron,sl28-var4 @@ -862,6 +864,7 @@ properties: Kontron SMARC-sAL28 board (on a generic/undefined carrier) items: - enum: + - kontron,sl28-var1 - kontron,sl28-var2 - kontron,sl28-var3 - kontron,sl28-var4 -- cgit v1.2.3 From 988d0d42509a2c1fad0844a6e8f9c7bce7c930dd Mon Sep 17 00:00:00 2001 From: Adrien Grassein Date: Thu, 14 Jan 2021 18:47:10 +0100 Subject: regulator: dt-bindings: pf8x00: fix nxp,phase-shift doc nxp,phase-shift is an enum so use enum format to describe it. Minimum and maximum values are also wrong. Signed-off-by: Adrien Grassein Reviewed-by: Rob Herring Link: https://lore.kernel.org/r/20210114174714.122561-3-adrien.grassein@gmail.com Signed-off-by: Mark Brown --- .../bindings/regulator/nxp,pf8x00-regulator.yaml | 14 ++------------ 1 file changed, 2 insertions(+), 12 deletions(-) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/regulator/nxp,pf8x00-regulator.yaml b/Documentation/devicetree/bindings/regulator/nxp,pf8x00-regulator.yaml index 956156fe52a3..095cfdae7b67 100644 --- a/Documentation/devicetree/bindings/regulator/nxp,pf8x00-regulator.yaml +++ b/Documentation/devicetree/bindings/regulator/nxp,pf8x00-regulator.yaml @@ -73,21 +73,11 @@ properties: nxp,phase-shift: $ref: "/schemas/types.yaml#/definitions/uint32" - minimum: 45 - maximum: 0 + default: 0 + enum: [ 0, 45, 90, 135, 180, 225, 270, 315 ] description: BUCK regulators phase shift control in degrees. - Listed phase shift control values in degrees are, - 45 - 90 - 135 - 180 - 225 - 270 - 315 - 0 (default) - unevaluatedProperties: false "^vsnvs$": -- cgit v1.2.3 From 34b860aa0b6221b21eea6bac76357063f525b561 Mon Sep 17 00:00:00 2001 From: Adrien Grassein Date: Thu, 14 Jan 2021 18:47:11 +0100 Subject: regulator: dt-bindings: pf8x00: mark nxp,ilim-ma property as deprecated This property seems useless because we can use the regulator-max-microamp generic property to do the same and using generic code. As this property was already released in a kernel version, we can't remove it, just mark it as deprecated Signed-off-by: Adrien Grassein Link: https://lore.kernel.org/r/20210114174714.122561-4-adrien.grassein@gmail.com Signed-off-by: Mark Brown --- Documentation/devicetree/bindings/regulator/nxp,pf8x00-regulator.yaml | 3 +++ 1 file changed, 3 insertions(+) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/regulator/nxp,pf8x00-regulator.yaml b/Documentation/devicetree/bindings/regulator/nxp,pf8x00-regulator.yaml index 095cfdae7b67..8761437ed8ad 100644 --- a/Documentation/devicetree/bindings/regulator/nxp,pf8x00-regulator.yaml +++ b/Documentation/devicetree/bindings/regulator/nxp,pf8x00-regulator.yaml @@ -62,8 +62,11 @@ properties: $ref: "/schemas/types.yaml#/definitions/uint32" minimum: 2100 maximum: 4500 + deprecated: true description: BUCK regulators current limit in mA. + This property is deprecated, please use + "regulator-max-microamp" instead. Listed current limits in mA are, 2100 (default) -- cgit v1.2.3 From 63d152149b2d0860ccf8c4e6596b6175b2b7ace6 Mon Sep 17 00:00:00 2001 From: Lorenzo Colitti Date: Thu, 14 Jan 2021 08:42:22 +0900 Subject: usb: gadget: u_ether: support configuring interface names. This patch allows the administrator to configure the interface name of a function using u_ether (e.g., eem, ncm, rndis). Currently, all such interfaces, regardless of function type, are always called usb0, usb1, etc. This makes it very cumbersome to use more than one such type at a time, because userspace cannnot easily tell the interfaces apart and apply the right configuration to each one. Interface renaming in userspace based on driver doesn't help, because the interfaces all have the same driver. Without this patch, doing this require hacks/workarounds such as setting fixed MAC addresses on the functions, and then renaming by MAC address, or scraping configfs after each interface is created to find out what it is. Setting the interface name is done by writing to the same "ifname" configfs attribute that reports the interface name after the function is bound. The write must contain an interface pattern such as "usb%d" (which will cause the net core to pick the next available interface name starting with "usb"). This patch does not allow writing an exact interface name (as opposed to a pattern) because if the interface already exists at bind time, the bind will fail and the whole gadget will fail to activate. This could be allowed in a future patch. For compatibility with current userspace, when reading an ifname that has not currently been set, the result is still "(unnamed net_device)". Once a write to ifname happens, then reading ifname will return whatever was last written. Tested by configuring an rndis function and an ncm function on the same gadget, and writing "rndis%d" to ifname on the rndis function and "ncm%d" to ifname on the ncm function. When the gadget was bound, the rndis interface was rndis0 and the ncm interface was ncm0. Signed-off-by: Lorenzo Colitti Link: https://lore.kernel.org/r/20210113234222.3272933-1-lorenzo@google.com Signed-off-by: Greg Kroah-Hartman --- Documentation/usb/gadget-testing.rst | 30 +++++++++++------------ drivers/usb/gadget/function/u_ether.c | 33 +++++++++++++++++++++++++- drivers/usb/gadget/function/u_ether.h | 12 ++++++++++ drivers/usb/gadget/function/u_ether_configfs.h | 15 +++++++++++- 4 files changed, 73 insertions(+), 17 deletions(-) (limited to 'Documentation') diff --git a/Documentation/usb/gadget-testing.rst b/Documentation/usb/gadget-testing.rst index 2eeb3e9299e4..2085e7b24eeb 100644 --- a/Documentation/usb/gadget-testing.rst +++ b/Documentation/usb/gadget-testing.rst @@ -91,9 +91,9 @@ The ECM function provides these attributes in its function directory: and after creating the functions/ecm. they contain default values: qmult is 5, dev_addr and host_addr are randomly selected. -Except for ifname they can be written to until the function is linked to a -configuration. The ifname is read-only and contains the name of the interface -which was assigned by the net core, e. g. usb0. +The ifname can be written to if the function is not bound. A write must be an +interface pattern such as "usb%d", which will cause the net core to choose the +next free usbX interface. By default, it is set to "usb%d". Testing the ECM function ------------------------ @@ -131,9 +131,9 @@ The ECM subset function provides these attributes in its function directory: and after creating the functions/ecm. they contain default values: qmult is 5, dev_addr and host_addr are randomly selected. -Except for ifname they can be written to until the function is linked to a -configuration. The ifname is read-only and contains the name of the interface -which was assigned by the net core, e. g. usb0. +The ifname can be written to if the function is not bound. A write must be an +interface pattern such as "usb%d", which will cause the net core to choose the +next free usbX interface. By default, it is set to "usb%d". Testing the ECM subset function ------------------------------- @@ -171,9 +171,9 @@ The EEM function provides these attributes in its function directory: and after creating the functions/eem. they contain default values: qmult is 5, dev_addr and host_addr are randomly selected. -Except for ifname they can be written to until the function is linked to a -configuration. The ifname is read-only and contains the name of the interface -which was assigned by the net core, e. g. usb0. +The ifname can be written to if the function is not bound. A write must be an +interface pattern such as "usb%d", which will cause the net core to choose the +next free usbX interface. By default, it is set to "usb%d". Testing the EEM function ------------------------ @@ -453,9 +453,9 @@ The NCM function provides these attributes in its function directory: and after creating the functions/ncm. they contain default values: qmult is 5, dev_addr and host_addr are randomly selected. -Except for ifname they can be written to until the function is linked to a -configuration. The ifname is read-only and contains the name of the interface -which was assigned by the net core, e. g. usb0. +The ifname can be written to if the function is not bound. A write must be an +interface pattern such as "usb%d", which will cause the net core to choose the +next free usbX interface. By default, it is set to "usb%d". Testing the NCM function ------------------------ @@ -591,9 +591,9 @@ The RNDIS function provides these attributes in its function directory: and after creating the functions/rndis. they contain default values: qmult is 5, dev_addr and host_addr are randomly selected. -Except for ifname they can be written to until the function is linked to a -configuration. The ifname is read-only and contains the name of the interface -which was assigned by the net core, e. g. usb0. +The ifname can be written to if the function is not bound. A write must be an +interface pattern such as "usb%d", which will cause the net core to choose the +next free usbX interface. By default, it is set to "usb%d". Testing the RNDIS function -------------------------- diff --git a/drivers/usb/gadget/function/u_ether.c b/drivers/usb/gadget/function/u_ether.c index c019f2b0c0af..d1d044d9f859 100644 --- a/drivers/usb/gadget/function/u_ether.c +++ b/drivers/usb/gadget/function/u_ether.c @@ -80,6 +80,7 @@ struct eth_dev { bool zlp; bool no_skb_reserve; + bool ifname_set; u8 host_mac[ETH_ALEN]; u8 dev_mac[ETH_ALEN]; }; @@ -1004,15 +1005,45 @@ EXPORT_SYMBOL_GPL(gether_get_qmult); int gether_get_ifname(struct net_device *net, char *name, int len) { + struct eth_dev *dev = netdev_priv(net); int ret; rtnl_lock(); - ret = scnprintf(name, len, "%s\n", netdev_name(net)); + ret = scnprintf(name, len, "%s\n", + dev->ifname_set ? net->name : netdev_name(net)); rtnl_unlock(); return ret; } EXPORT_SYMBOL_GPL(gether_get_ifname); +int gether_set_ifname(struct net_device *net, const char *name, int len) +{ + struct eth_dev *dev = netdev_priv(net); + char tmp[IFNAMSIZ]; + const char *p; + + if (name[len - 1] == '\n') + len--; + + if (len >= sizeof(tmp)) + return -E2BIG; + + strscpy(tmp, name, len + 1); + if (!dev_valid_name(tmp)) + return -EINVAL; + + /* Require exactly one %d, so binding will not fail with EEXIST. */ + p = strchr(name, '%'); + if (!p || p[1] != 'd' || strchr(p + 2, '%')) + return -EINVAL; + + strncpy(net->name, tmp, sizeof(net->name)); + dev->ifname_set = true; + + return 0; +} +EXPORT_SYMBOL_GPL(gether_set_ifname); + /* * gether_cleanup - remove Ethernet-over-USB device * Context: may sleep diff --git a/drivers/usb/gadget/function/u_ether.h b/drivers/usb/gadget/function/u_ether.h index 10dd640684e2..40144546d1b0 100644 --- a/drivers/usb/gadget/function/u_ether.h +++ b/drivers/usb/gadget/function/u_ether.h @@ -244,6 +244,18 @@ unsigned gether_get_qmult(struct net_device *net); */ int gether_get_ifname(struct net_device *net, char *name, int len); +/** + * gether_set_ifname - set an ethernet-over-usb link interface name + * @net: device representing this link + * @name: new interface name + * @len: length of @name + * + * This sets the interface name of this ethernet-over-usb link. + * A single terminating newline, if any, is ignored. + * Returns zero on success, else negative errno. + */ +int gether_set_ifname(struct net_device *net, const char *name, int len); + void gether_cleanup(struct eth_dev *dev); /* connect/disconnect is handled by individual functions */ diff --git a/drivers/usb/gadget/function/u_ether_configfs.h b/drivers/usb/gadget/function/u_ether_configfs.h index bd92b5703013..3dfb460908fa 100644 --- a/drivers/usb/gadget/function/u_ether_configfs.h +++ b/drivers/usb/gadget/function/u_ether_configfs.h @@ -148,7 +148,20 @@ out: \ return ret; \ } \ \ - CONFIGFS_ATTR_RO(_f_##_opts_, ifname) + static ssize_t _f_##_opts_ifname_store(struct config_item *item, \ + const char *page, size_t len)\ + { \ + struct f_##_f_##_opts *opts = to_f_##_f_##_opts(item); \ + int ret = -EBUSY; \ + \ + mutex_lock(&opts->lock); \ + if (!opts->refcnt) \ + ret = gether_set_ifname(opts->net, page, len); \ + mutex_unlock(&opts->lock); \ + return ret ?: len; \ + } \ + \ + CONFIGFS_ATTR(_f_##_opts_, ifname) #define USB_ETHER_CONFIGFS_ITEM_ATTR_U8_RW(_f_, _n_) \ static ssize_t _f_##_opts_##_n_##_show(struct config_item *item,\ -- cgit v1.2.3 From 23bf6fc7046c8c694ff774f0532329dd78efe0a2 Mon Sep 17 00:00:00 2001 From: Chunfeng Yun Date: Fri, 25 Dec 2020 15:52:48 +0800 Subject: dt-bindings: usb: convert usb-device.txt to YAML schema Convert usb-device.txt to YAML schema usb-device.yaml Reviewed-by: Rob Herring Signed-off-by: Chunfeng Yun Link: https://lore.kernel.org/r/20201225075258.33352-1-chunfeng.yun@mediatek.com Signed-off-by: Greg Kroah-Hartman --- .../devicetree/bindings/usb/usb-device.txt | 102 ----------------- .../devicetree/bindings/usb/usb-device.yaml | 124 +++++++++++++++++++++ Documentation/devicetree/bindings/usb/usb-hcd.yaml | 19 ++++ 3 files changed, 143 insertions(+), 102 deletions(-) delete mode 100644 Documentation/devicetree/bindings/usb/usb-device.txt create mode 100644 Documentation/devicetree/bindings/usb/usb-device.yaml (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/usb/usb-device.txt b/Documentation/devicetree/bindings/usb/usb-device.txt deleted file mode 100644 index 036be172b1ae..000000000000 --- a/Documentation/devicetree/bindings/usb/usb-device.txt +++ /dev/null @@ -1,102 +0,0 @@ -Generic USB Device Properties - -Usually, we only use device tree for hard wired USB device. -The reference binding doc is from: -http://www.devicetree.org/open-firmware/bindings/usb/usb-1_0.ps - -Four types of device-tree nodes are defined: "host-controller nodes" -representing USB host controllers, "device nodes" representing USB devices, -"interface nodes" representing USB interfaces and "combined nodes" -representing simple USB devices. - -A combined node shall be used instead of a device node and an interface node -for devices of class 0 or 9 (hub) with a single configuration and a single -interface. - -A "hub node" is a combined node or an interface node that represents a USB -hub. - - -Required properties for device nodes: -- compatible: "usbVID,PID", where VID is the vendor id and PID the product id. - The textual representation of VID and PID shall be in lower case hexadecimal - with leading zeroes suppressed. The other compatible strings from the above - standard binding could also be used, but a device adhering to this binding - may leave out all except for "usbVID,PID". -- reg: the number of the USB hub port or the USB host-controller port to which - this device is attached. The range is 1-255. - - -Required properties for device nodes with interface nodes: -- #address-cells: shall be 2 -- #size-cells: shall be 0 - - -Required properties for interface nodes: -- compatible: "usbifVID,PID.configCN.IN", where VID is the vendor id, PID is - the product id, CN is the configuration value and IN is the interface - number. The textual representation of VID, PID, CN and IN shall be in lower - case hexadecimal with leading zeroes suppressed. The other compatible - strings from the above standard binding could also be used, but a device - adhering to this binding may leave out all except for - "usbifVID,PID.configCN.IN". -- reg: the interface number and configuration value - -The configuration component is not included in the textual representation of -an interface-node unit address for configuration 1. - - -Required properties for combined nodes: -- compatible: "usbVID,PID", where VID is the vendor id and PID the product id. - The textual representation of VID and PID shall be in lower case hexadecimal - with leading zeroes suppressed. The other compatible strings from the above - standard binding could also be used, but a device adhering to this binding - may leave out all except for "usbVID,PID". -- reg: the number of the USB hub port or the USB host-controller port to which - this device is attached. The range is 1-255. - - -Required properties for hub nodes with device nodes: -- #address-cells: shall be 1 -- #size-cells: shall be 0 - - -Required properties for host-controller nodes with device nodes: -- #address-cells: shall be 1 -- #size-cells: shall be 0 - - -Example: - -&usb1 { /* host controller */ - #address-cells = <1>; - #size-cells = <0>; - - hub@1 { /* hub connected to port 1 */ - compatible = "usb5e3,608"; - reg = <1>; - }; - - device@2 { /* device connected to port 2 */ - compatible = "usb123,4567"; - reg = <2>; - }; - - device@3 { /* device connected to port 3 */ - compatible = "usb123,abcd"; - reg = <3>; - - #address-cells = <2>; - #size-cells = <0>; - - interface@0 { /* interface 0 of configuration 1 */ - compatible = "usbif123,abcd.config1.0"; - reg = <0 1>; - }; - - interface@0,2 { /* interface 0 of configuration 2 */ - compatible = "usbif123,abcd.config2.0"; - reg = <0 2>; - }; - }; -}; diff --git a/Documentation/devicetree/bindings/usb/usb-device.yaml b/Documentation/devicetree/bindings/usb/usb-device.yaml new file mode 100644 index 000000000000..7bb25a45427d --- /dev/null +++ b/Documentation/devicetree/bindings/usb/usb-device.yaml @@ -0,0 +1,124 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/usb/usb-device.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: The device tree bindings for the Generic USB Device + +maintainers: + - Greg Kroah-Hartman + +description: | + Usually, we only use device tree for hard wired USB device. + The reference binding doc is from: + http://www.devicetree.org/open-firmware/bindings/usb/usb-1_0.ps + + Four types of device-tree nodes are defined: "host-controller nodes" + representing USB host controllers, "device nodes" representing USB devices, + "interface nodes" representing USB interfaces and "combined nodes" + representing simple USB devices. + + A combined node shall be used instead of a device node and an interface node + for devices of class 0 or 9 (hub) with a single configuration and a single + interface. + + A "hub node" is a combined node or an interface node that represents a USB + hub. + +properties: + compatible: + pattern: "^usb[0-9a-f]{1,4},[0-9a-f]{1,4}$" + description: Device nodes or combined nodes. + "usbVID,PID", where VID is the vendor id and PID the product id. + The textual representation of VID and PID shall be in lower case + hexadecimal with leading zeroes suppressed. The other compatible + strings from the above standard binding could also be used, + but a device adhering to this binding may leave out all except + for "usbVID,PID". + + reg: + description: the number of the USB hub port or the USB host-controller + port to which this device is attached. The range is 1-255. + maxItems: 1 + + "#address-cells": + description: should be 1 for hub nodes with device nodes, + should be 2 for device nodes with interface nodes. + enum: [1, 2] + + "#size-cells": + const: 0 + +patternProperties: + "^interface@[0-9a-f]{1,2}(,[0-9a-f]{1,2})$": + type: object + description: USB interface nodes. + The configuration component is not included in the textual + representation of an interface-node unit address for configuration 1. + + properties: + compatible: + pattern: "^usbif[0-9a-f]{1,4},[0-9a-f]{1,4}.config[0-9a-f]{1,2}.[0-9a-f]{1,2}$" + description: Interface nodes. + "usbifVID,PID.configCN.IN", where VID is the vendor id, PID is + the product id, CN is the configuration value and IN is the interface + number. The textual representation of VID, PID, CN and IN shall be + in lower case hexadecimal with leading zeroes suppressed. + The other compatible strings from the above standard binding could + also be used, but a device adhering to this binding may leave out + all except for "usbifVID,PID.configCN.IN". + + reg: + description: should be 2 cells long, the first cell represents + the interface number and the second cell represents the + configuration value. + maxItems: 1 + +required: + - compatile + - reg + +additionalProperties: true + +examples: + #hub connected to port 1 + #device connected to port 2 + #device connected to port 3 + # interface 0 of configuration 1 + # interface 0 of configuration 2 + - | + usb@11270000 { + reg = <0x11270000 0x1000>; + interrupts = <0x0 0x4e 0x0>; + #address-cells = <1>; + #size-cells = <0>; + + hub@1 { + compatible = "usb5e3,608"; + reg = <1>; + }; + + device@2 { + compatible = "usb123,4567"; + reg = <2>; + }; + + device@3 { + compatible = "usb123,abcd"; + reg = <3>; + + #address-cells = <2>; + #size-cells = <0>; + + interface@0 { + compatible = "usbif123,abcd.config1.0"; + reg = <0 1>; + }; + + interface@0,2 { + compatible = "usbif123,abcd.config2.0"; + reg = <0 2>; + }; + }; + }; diff --git a/Documentation/devicetree/bindings/usb/usb-hcd.yaml b/Documentation/devicetree/bindings/usb/usb-hcd.yaml index 9881ac10380d..56853c17af66 100644 --- a/Documentation/devicetree/bindings/usb/usb-hcd.yaml +++ b/Documentation/devicetree/bindings/usb/usb-hcd.yaml @@ -23,6 +23,18 @@ properties: targeted hosts (non-PC hosts). type: boolean + "#address-cells": + const: 1 + + "#size-cells": + const: 0 + +patternProperties: + "^.*@[0-9a-f]{1,2}$": + description: The hard wired USB devices + type: object + $ref: /usb/usb-device.yaml + additionalProperties: true examples: @@ -30,4 +42,11 @@ examples: usb { phys = <&usb2_phy1>, <&usb3_phy1>; phy-names = "usb"; + #address-cells = <1>; + #size-cells = <0>; + + hub@1 { + compatible = "usb5e3,610"; + reg = <1>; + }; }; -- cgit v1.2.3 From 6a0d64fc5a4ecd968188cb4b4842a3d29634f027 Mon Sep 17 00:00:00 2001 From: Chunfeng Yun Date: Fri, 25 Dec 2020 15:52:49 +0800 Subject: dt-bindings: net: btusb: change reference file name Due to usb-device.txt is converted into usb-device.yaml, so modify reference file names at the same time. Acked-by: Rob Herring Signed-off-by: Chunfeng Yun Link: https://lore.kernel.org/r/20201225075258.33352-2-chunfeng.yun@mediatek.com Signed-off-by: Greg Kroah-Hartman --- Documentation/devicetree/bindings/net/btusb.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/net/btusb.txt b/Documentation/devicetree/bindings/net/btusb.txt index b1ad6ee68e90..a9c3f4277f69 100644 --- a/Documentation/devicetree/bindings/net/btusb.txt +++ b/Documentation/devicetree/bindings/net/btusb.txt @@ -4,7 +4,7 @@ Generic Bluetooth controller over USB (btusb driver) Required properties: - compatible : should comply with the format "usbVID,PID" specified in - Documentation/devicetree/bindings/usb/usb-device.txt + Documentation/devicetree/bindings/usb/usb-device.yaml At the time of writing, the only OF supported devices (more may be added later) are: -- cgit v1.2.3 From f9924caf5d952594b2d912e2ec318189ce64cf04 Mon Sep 17 00:00:00 2001 From: Chunfeng Yun Date: Fri, 25 Dec 2020 15:52:55 +0800 Subject: dt-bindings: usb: convert mediatek, musb.txt to YAML schema Convert mediatek,musb.txt to YAML schema mediatek,musb.yaml Cc: Min Guo Reviewed-by: Rob Herring Signed-off-by: Chunfeng Yun Link: https://lore.kernel.org/r/20201225075258.33352-8-chunfeng.yun@mediatek.com Signed-off-by: Greg Kroah-Hartman --- .../devicetree/bindings/usb/mediatek,musb.txt | 57 ----------- .../devicetree/bindings/usb/mediatek,musb.yaml | 113 +++++++++++++++++++++ 2 files changed, 113 insertions(+), 57 deletions(-) delete mode 100644 Documentation/devicetree/bindings/usb/mediatek,musb.txt create mode 100644 Documentation/devicetree/bindings/usb/mediatek,musb.yaml (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/usb/mediatek,musb.txt b/Documentation/devicetree/bindings/usb/mediatek,musb.txt deleted file mode 100644 index 5eedb0296562..000000000000 --- a/Documentation/devicetree/bindings/usb/mediatek,musb.txt +++ /dev/null @@ -1,57 +0,0 @@ -MediaTek musb DRD/OTG controller -------------------------------------------- - -Required properties: - - compatible : should be one of: - "mediatek,mt2701-musb" - ... - followed by "mediatek,mtk-musb" - - reg : specifies physical base address and size of - the registers - - interrupts : interrupt used by musb controller - - interrupt-names : must be "mc" - - phys : PHY specifier for the OTG phy - - dr_mode : should be one of "host", "peripheral" or "otg", - refer to usb/generic.txt - - clocks : a list of phandle + clock-specifier pairs, one for - each entry in clock-names - - clock-names : must contain "main", "mcu", "univpll" - for clocks of controller - -Optional properties: - - power-domains : a phandle to USB power domain node to control USB's - MTCMOS - -Required child nodes: - usb connector node as defined in bindings/connector/usb-connector.yaml -Optional properties: - - id-gpios : input GPIO for USB ID pin. - - vbus-gpios : input GPIO for USB VBUS pin. - - vbus-supply : reference to the VBUS regulator, needed when supports - dual-role mode - - usb-role-switch : use USB Role Switch to support dual-role switch, see - usb/generic.txt. - -Example: - -usb2: usb@11200000 { - compatible = "mediatek,mt2701-musb", - "mediatek,mtk-musb"; - reg = <0 0x11200000 0 0x1000>; - interrupts = ; - interrupt-names = "mc"; - phys = <&u2port2 PHY_TYPE_USB2>; - dr_mode = "otg"; - clocks = <&pericfg CLK_PERI_USB0>, - <&pericfg CLK_PERI_USB0_MCU>, - <&pericfg CLK_PERI_USB_SLV>; - clock-names = "main","mcu","univpll"; - power-domains = <&scpsys MT2701_POWER_DOMAIN_IFR_MSC>; - usb-role-switch; - connector{ - compatible = "gpio-usb-b-connector", "usb-b-connector"; - type = "micro"; - id-gpios = <&pio 44 GPIO_ACTIVE_HIGH>; - vbus-supply = <&usb_vbus>; - }; -}; diff --git a/Documentation/devicetree/bindings/usb/mediatek,musb.yaml b/Documentation/devicetree/bindings/usb/mediatek,musb.yaml new file mode 100644 index 000000000000..790efe8b6274 --- /dev/null +++ b/Documentation/devicetree/bindings/usb/mediatek,musb.yaml @@ -0,0 +1,113 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +# Copyright (c) 2020 MediaTek +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/usb/mediatek,musb.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: MediaTek MUSB DRD/OTG Controller Device Tree Bindings + +maintainers: + - Min Guo + +properties: + $nodename: + pattern: '^usb@[0-9a-f]+$' + + compatible: + items: + - enum: + - mediatek,mt2701-musb + - const: mediatek,mtk-musb + + reg: + maxItems: 1 + + interrupts: + maxItems: 1 + + interrupt-names: + items: + - const: mc + + clocks: + items: + - description: The main/core clock + - description: The system bus clock + - description: The 48Mhz clock + + clock-names: + items: + - const: main + - const: mcu + - const: univpll + + phys: + maxItems: 1 + + usb-role-switch: + $ref: /schemas/types.yaml#/definitions/flag + description: Support role switch. See usb/generic.txt + type: boolean + + dr_mode: + enum: + - host + - otg + - peripheral + + power-domains: + description: A phandle to USB power domain node to control USB's MTCMOS + maxItems: 1 + + connector: + $ref: /connector/usb-connector.yaml# + description: Connector for dual role switch + type: object + +dependencies: + usb-role-switch: [ 'connector' ] + connector: [ 'usb-role-switch' ] + +required: + - compatible + - reg + - interrupts + - interrupt-names + - phys + - clocks + - clock-names + +additionalProperties: false + +examples: + - | + #include + #include + #include + #include + #include + #include + + usb@11200000 { + compatible = "mediatek,mt2701-musb", "mediatek,mtk-musb"; + reg = <0x11200000 0x1000>; + interrupts = ; + interrupt-names = "mc"; + phys = <&u2port2 PHY_TYPE_USB2>; + dr_mode = "otg"; + clocks = <&pericfg CLK_PERI_USB0>, + <&pericfg CLK_PERI_USB0_MCU>, + <&pericfg CLK_PERI_USB_SLV>; + clock-names = "main","mcu","univpll"; + power-domains = <&scpsys MT2701_POWER_DOMAIN_IFR_MSC>; + usb-role-switch; + + connector { + compatible = "gpio-usb-b-connector", "usb-b-connector"; + type = "micro"; + id-gpios = <&pio 44 GPIO_ACTIVE_HIGH>; + vbus-supply = <&usb_vbus>; + }; + }; +... -- cgit v1.2.3 From d93b29c8097144d9911ad0116610d971937748a8 Mon Sep 17 00:00:00 2001 From: Chunfeng Yun Date: Fri, 25 Dec 2020 15:52:56 +0800 Subject: dt-bindings: usb: convert mediatek, mtk-xhci.txt to YAML schema Convert mediatek,mtk-xhci.txt to YAML schema mediatek,mtk-xhci.yaml Reviewed-by: Rob Herring Signed-off-by: Chunfeng Yun Link: https://lore.kernel.org/r/20201225075258.33352-9-chunfeng.yun@mediatek.com Signed-off-by: Greg Kroah-Hartman --- .../devicetree/bindings/usb/mediatek,mtk-xhci.txt | 121 -------------- .../devicetree/bindings/usb/mediatek,mtk-xhci.yaml | 178 +++++++++++++++++++++ 2 files changed, 178 insertions(+), 121 deletions(-) delete mode 100644 Documentation/devicetree/bindings/usb/mediatek,mtk-xhci.txt create mode 100644 Documentation/devicetree/bindings/usb/mediatek,mtk-xhci.yaml (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/usb/mediatek,mtk-xhci.txt b/Documentation/devicetree/bindings/usb/mediatek,mtk-xhci.txt deleted file mode 100644 index 42d8814f903a..000000000000 --- a/Documentation/devicetree/bindings/usb/mediatek,mtk-xhci.txt +++ /dev/null @@ -1,121 +0,0 @@ -MT8173 xHCI - -The device node for Mediatek SOC USB3.0 host controller - -There are two scenarios: the first one only supports xHCI driver; -the second one supports dual-role mode, and the host is based on xHCI -driver. Take account of backward compatibility, we divide bindings -into two parts. - -1st: only supports xHCI driver ------------------------------------------------------------------------- - -Required properties: - - compatible : should be "mediatek,-xhci", "mediatek,mtk-xhci", - soc-model is the name of SoC, such as mt8173, mt2712 etc, when using - "mediatek,mtk-xhci" compatible string, you need SoC specific ones in - addition, one of: - - "mediatek,mt8173-xhci" - - reg : specifies physical base address and size of the registers - - reg-names: should be "mac" for xHCI MAC and "ippc" for IP port control - - interrupts : interrupt used by the controller - - power-domains : a phandle to USB power domain node to control USB's - mtcmos - - vusb33-supply : regulator of USB avdd3.3v - - - clocks : a list of phandle + clock-specifier pairs, one for each - entry in clock-names - - clock-names : must contain - "sys_ck": controller clock used by normal mode, - the following ones are optional: - "ref_ck": reference clock used by low power mode etc, - "mcu_ck": mcu_bus clock for register access, - "dma_ck": dma_bus clock for data transfer by DMA, - "xhci_ck": controller clock - - - phys : see usb-hcd.yaml in the current directory - -Optional properties: - - wakeup-source : enable USB remote wakeup; - - mediatek,syscon-wakeup : phandle to syscon used to access the register - of the USB wakeup glue layer between xHCI and SPM; it depends on - "wakeup-source", and has two arguments: - - the first one : register base address of the glue layer in syscon; - - the second one : hardware version of the glue layer - - 1 : used by mt8173 etc - - 2 : used by mt2712 etc - - mediatek,u3p-dis-msk : mask to disable u3ports, bit0 for u3port0, - bit1 for u3port1, ... etc; - - vbus-supply : reference to the VBUS regulator; - - usb3-lpm-capable : supports USB3.0 LPM - - pinctrl-names : a pinctrl state named "default" must be defined - - pinctrl-0 : pin control group - See: Documentation/devicetree/bindings/pinctrl/pinctrl-bindings.txt - - imod-interval-ns: default interrupt moderation interval is 5000ns - -additionally the properties from usb-hcd.yaml (in the current directory) are -supported. - -Example: -usb30: usb@11270000 { - compatible = "mediatek,mt8173-xhci"; - reg = <0 0x11270000 0 0x1000>, - <0 0x11280700 0 0x0100>; - reg-names = "mac", "ippc"; - interrupts = ; - power-domains = <&scpsys MT8173_POWER_DOMAIN_USB>; - clocks = <&topckgen CLK_TOP_USB30_SEL>, <&clk26m>, - <&pericfg CLK_PERI_USB0>, - <&pericfg CLK_PERI_USB1>; - clock-names = "sys_ck", "ref_ck"; - phys = <&phy_port0 PHY_TYPE_USB3>, - <&phy_port1 PHY_TYPE_USB2>; - vusb33-supply = <&mt6397_vusb_reg>; - vbus-supply = <&usb_p1_vbus>; - usb3-lpm-capable; - mediatek,syscon-wakeup = <&pericfg 0x400 1>; - wakeup-source; - imod-interval-ns = <10000>; -}; - -2nd: dual-role mode with xHCI driver ------------------------------------------------------------------------- - -In the case, xhci is added as subnode to mtu3. An example and the DT binding -details of mtu3 can be found in: -Documentation/devicetree/bindings/usb/mediatek,mtu3.txt - -Required properties: - - compatible : should be "mediatek,-xhci", "mediatek,mtk-xhci", - soc-model is the name of SoC, such as mt8173, mt2712 etc, when using - "mediatek,mtk-xhci" compatible string, you need SoC specific ones in - addition, one of: - - "mediatek,mt8173-xhci" - - reg : specifies physical base address and size of the registers - - reg-names: should be "mac" for xHCI MAC - - interrupts : interrupt used by the host controller - - power-domains : a phandle to USB power domain node to control USB's - mtcmos - - vusb33-supply : regulator of USB avdd3.3v - - - clocks : a list of phandle + clock-specifier pairs, one for each - entry in clock-names - - clock-names : must contain "sys_ck", and the following ones are optional: - "ref_ck", "mcu_ck" and "dma_ck", "xhci_ck" - -Optional properties: - - vbus-supply : reference to the VBUS regulator; - - usb3-lpm-capable : supports USB3.0 LPM - -Example: -usb30: usb@11270000 { - compatible = "mediatek,mt8173-xhci"; - reg = <0 0x11270000 0 0x1000>; - reg-names = "mac"; - interrupts = ; - power-domains = <&scpsys MT8173_POWER_DOMAIN_USB>; - clocks = <&topckgen CLK_TOP_USB30_SEL>, <&clk26m>; - clock-names = "sys_ck", "ref_ck"; - vusb33-supply = <&mt6397_vusb_reg>; - usb3-lpm-capable; -}; diff --git a/Documentation/devicetree/bindings/usb/mediatek,mtk-xhci.yaml b/Documentation/devicetree/bindings/usb/mediatek,mtk-xhci.yaml new file mode 100644 index 000000000000..38b1fe18aa79 --- /dev/null +++ b/Documentation/devicetree/bindings/usb/mediatek,mtk-xhci.yaml @@ -0,0 +1,178 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +# Copyright (c) 2020 MediaTek +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/usb/mediatek,mtk-xhci.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: MediaTek USB3 xHCI Device Tree Bindings + +maintainers: + - Chunfeng Yun + +allOf: + - $ref: "usb-xhci.yaml" + +description: | + There are two scenarios: + case 1: only supports xHCI driver; + case 2: supports dual-role mode, and the host is based on xHCI driver. + +properties: + # common properties for both case 1 and case 2 + compatible: + items: + - enum: + - mediatek,mt2712-xhci + - mediatek,mt7622-xhci + - mediatek,mt7629-xhci + - mediatek,mt8173-xhci + - mediatek,mt8183-xhci + - const: mediatek,mtk-xhci + + reg: + minItems: 1 + items: + - description: the registers of xHCI MAC + - description: the registers of IP Port Control + + reg-names: + minItems: 1 + items: + - const: mac + - const: ippc # optional, only needed for case 1. + + interrupts: + maxItems: 1 + + power-domains: + description: A phandle to USB power domain node to control USB's MTCMOS + maxItems: 1 + + clocks: + minItems: 1 + items: + - description: Controller clock used by normal mode + - description: Reference clock used by low power mode etc + - description: Mcu bus clock for register access + - description: DMA bus clock for data transfer + - description: controller clock + + clock-names: + minItems: 1 + items: + - const: sys_ck # required, the following ones are optional + - const: ref_ck + - const: mcu_ck + - const: dma_ck + - const: xhci_ck + + phys: + description: + List of all PHYs used on this HCD, it's better to keep PHYs in order + as the hardware layout + minItems: 1 + items: + - description: USB2/HS PHY # required, others are optional + - description: USB3/SS(P) PHY + - description: USB2/HS PHY + - description: USB3/SS(P) PHY + - description: USB2/HS PHY + - description: USB3/SS(P) PHY + - description: USB2/HS PHY + - description: USB3/SS(P) PHY + - description: USB2/HS PHY + + vusb33-supply: + description: Regulator of USB AVDD3.3v + + vbus-supply: + description: Regulator of USB VBUS5v + + usb3-lpm-capable: + description: supports USB3.0 LPM + type: boolean + + imod-interval-ns: + description: + Interrupt moderation interval value, it is 8 times as much as that + defined in the xHCI spec on MTK's controller. + default: 5000 + + # the following properties are only used for case 1 + wakeup-source: + description: enable USB remote wakeup, see power/wakeup-source.txt + type: boolean + + mediatek,syscon-wakeup: + $ref: /schemas/types.yaml#/definitions/phandle-array + maxItems: 1 + description: + A phandle to syscon used to access the register of the USB wakeup glue + layer between xHCI and SPM, the field should always be 3 cells long. + items: + items: + - description: + The first cell represents a phandle to syscon + - description: + The second cell represents the register base address of the glue + layer in syscon + - description: + The third cell represents the hardware version of the glue layer, + 1 is used by mt8173 etc, 2 is used by mt2712 etc + enum: [1, 2] + + mediatek,u3p-dis-msk: + $ref: /schemas/types.yaml#/definitions/uint32 + description: The mask to disable u3ports, bit0 for u3port0, + bit1 for u3port1, ... etc + + "#address-cells": + const: 1 + + "#size-cells": + const: 0 + +patternProperties: + "@[0-9a-f]{1}$": + type: object + description: The hard wired USB devices. + +dependencies: + wakeup-source: [ 'mediatek,syscon-wakeup' ] + +required: + - compatible + - reg + - reg-names + - interrupts + - clocks + - clock-names + +additionalProperties: false + +examples: + - | + #include + #include + #include + #include + #include + + usb@11270000 { + compatible = "mediatek,mt8173-xhci", "mediatek,mtk-xhci"; + reg = <0x11270000 0x1000>, <0x11280700 0x0100>; + reg-names = "mac", "ippc"; + interrupts = ; + power-domains = <&scpsys MT8173_POWER_DOMAIN_USB>; + clocks = <&topckgen CLK_TOP_USB30_SEL>, <&clk26m>; + clock-names = "sys_ck", "ref_ck"; + phys = <&u3port0 PHY_TYPE_USB3>, <&u2port1 PHY_TYPE_USB2>; + vusb33-supply = <&mt6397_vusb_reg>; + vbus-supply = <&usb_p1_vbus>; + imod-interval-ns = <10000>; + mediatek,syscon-wakeup = <&pericfg 0x400 1>; + wakeup-source; + usb3-lpm-capable; + }; +... -- cgit v1.2.3 From 717774eb5273658e01543f6f648a4f6427741ed0 Mon Sep 17 00:00:00 2001 From: Chunfeng Yun Date: Fri, 25 Dec 2020 15:52:57 +0800 Subject: dt-bindings: usb: convert mediatek, mtu3.txt to YAML schema Convert mediatek,mtu3.txt to YAML schema mediatek,mtu3.yaml Reviewed-by: Rob Herring Signed-off-by: Chunfeng Yun Link: https://lore.kernel.org/r/20201225075258.33352-10-chunfeng.yun@mediatek.com Signed-off-by: Greg Kroah-Hartman --- .../devicetree/bindings/usb/mediatek,mtu3.txt | 108 -------- .../devicetree/bindings/usb/mediatek,mtu3.yaml | 287 +++++++++++++++++++++ 2 files changed, 287 insertions(+), 108 deletions(-) delete mode 100644 Documentation/devicetree/bindings/usb/mediatek,mtu3.txt create mode 100644 Documentation/devicetree/bindings/usb/mediatek,mtu3.yaml (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/usb/mediatek,mtu3.txt b/Documentation/devicetree/bindings/usb/mediatek,mtu3.txt deleted file mode 100644 index a82ca438aec1..000000000000 --- a/Documentation/devicetree/bindings/usb/mediatek,mtu3.txt +++ /dev/null @@ -1,108 +0,0 @@ -The device node for Mediatek USB3.0 DRD controller - -Required properties: - - compatible : should be "mediatek,-mtu3", "mediatek,mtu3", - soc-model is the name of SoC, such as mt8173, mt2712 etc, - when using "mediatek,mtu3" compatible string, you need SoC specific - ones in addition, one of: - - "mediatek,mt8173-mtu3" - - reg : specifies physical base address and size of the registers - - reg-names: should be "mac" for device IP and "ippc" for IP port control - - interrupts : interrupt used by the device IP - - power-domains : a phandle to USB power domain node to control USB's - mtcmos - - vusb33-supply : regulator of USB avdd3.3v - - clocks : a list of phandle + clock-specifier pairs, one for each - entry in clock-names - - clock-names : must contain "sys_ck" for clock of controller, - the following clocks are optional: - "ref_ck", "mcu_ck" and "dma_ck"; - - phys : see usb-hcd.yaml in the current directory - - dr_mode : should be one of "host", "peripheral" or "otg", - refer to usb/generic.txt - -Optional properties: - - #address-cells, #size-cells : should be '2' if the device has sub-nodes - with 'reg' property - - ranges : allows valid 1:1 translation between child's address space and - parent's address space - - extcon : external connector for vbus and idpin changes detection, needed - when supports dual-role mode. - it's considered valid for compatibility reasons, not allowed for - new bindings, and use "usb-role-switch" property instead. - - vbus-supply : reference to the VBUS regulator, needed when supports - dual-role mode. - it's considered valid for compatibility reasons, not allowed for - new bindings, and put into a usb-connector node. - see connector/usb-connector.yaml. - - pinctrl-names : a pinctrl state named "default" is optional, and need be - defined if auto drd switch is enabled, that means the property dr_mode - is set as "otg", and meanwhile the property "mediatek,enable-manual-drd" - is not set. - - pinctrl-0 : pin control group - See: Documentation/devicetree/bindings/pinctrl/pinctrl-bindings.txt - - - maximum-speed : valid arguments are "super-speed", "high-speed" and - "full-speed"; refer to usb/generic.txt - - usb-role-switch : use USB Role Switch to support dual-role switch, but - not extcon; see usb/generic.txt. - - enable-manual-drd : supports manual dual-role switch via debugfs; usually - used when receptacle is TYPE-A and also wants to support dual-role - mode. - - wakeup-source: enable USB remote wakeup of host mode. - - mediatek,syscon-wakeup : phandle to syscon used to access the register - of the USB wakeup glue layer between SSUSB and SPM; it depends on - "wakeup-source", and has two arguments: - - the first one : register base address of the glue layer in syscon; - - the second one : hardware version of the glue layer - - 1 : used by mt8173 etc - - 2 : used by mt2712 etc - - mediatek,u3p-dis-msk : mask to disable u3ports, bit0 for u3port0, - bit1 for u3port1, ... etc; - -additionally the properties from usb-hcd.yaml (in the current directory) are -supported. - -Sub-nodes: -The xhci should be added as subnode to mtu3 as shown in the following example -if host mode is enabled. The DT binding details of xhci can be found in: -Documentation/devicetree/bindings/usb/mediatek,mtk-xhci.txt - -The port would be added as subnode if use "usb-role-switch" property. - see graph.txt - -Example: -ssusb: usb@11271000 { - compatible = "mediatek,mt8173-mtu3"; - reg = <0 0x11271000 0 0x3000>, - <0 0x11280700 0 0x0100>; - reg-names = "mac", "ippc"; - interrupts = ; - phys = <&phy_port0 PHY_TYPE_USB3>, - <&phy_port1 PHY_TYPE_USB2>; - power-domains = <&scpsys MT8173_POWER_DOMAIN_USB>; - clocks = <&topckgen CLK_TOP_USB30_SEL>, <&clk26m>, - <&pericfg CLK_PERI_USB0>, - <&pericfg CLK_PERI_USB1>; - clock-names = "sys_ck", "ref_ck"; - vusb33-supply = <&mt6397_vusb_reg>; - vbus-supply = <&usb_p0_vbus>; - extcon = <&extcon_usb>; - dr_mode = "otg"; - wakeup-source; - mediatek,syscon-wakeup = <&pericfg 0x400 1>; - #address-cells = <2>; - #size-cells = <2>; - ranges; - - usb_host: xhci@11270000 { - compatible = "mediatek,mt8173-xhci"; - reg = <0 0x11270000 0 0x1000>; - reg-names = "mac"; - interrupts = ; - power-domains = <&scpsys MT8173_POWER_DOMAIN_USB>; - clocks = <&topckgen CLK_TOP_USB30_SEL>, <&clk26m>; - clock-names = "sys_ck", "ref_ck"; - vusb33-supply = <&mt6397_vusb_reg>; - }; -}; diff --git a/Documentation/devicetree/bindings/usb/mediatek,mtu3.yaml b/Documentation/devicetree/bindings/usb/mediatek,mtu3.yaml new file mode 100644 index 000000000000..f5c04b9d2de9 --- /dev/null +++ b/Documentation/devicetree/bindings/usb/mediatek,mtu3.yaml @@ -0,0 +1,287 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +# Copyright (c) 2020 MediaTek +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/usb/mediatek,mtu3.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: MediaTek USB3 DRD Controller Device Tree Bindings + +maintainers: + - Chunfeng Yun + +allOf: + - $ref: "usb-drd.yaml" + +description: | + The DRD controller has a glue layer IPPC (IP Port Control), and its host is + based on xHCI. + +properties: + compatible: + items: + - enum: + - mediatek,mt2712-mtu3 + - mediatek,mt8173-mtu3 + - mediatek,mt8183-mtu3 + - const: mediatek,mtu3 + + reg: + items: + - description: the registers of device MAC + - description: the registers of IP Port Control + + reg-names: + items: + - const: mac + - const: ippc + + interrupts: + maxItems: 1 + + power-domains: + description: A phandle to USB power domain node to control USB's MTCMOS + maxItems: 1 + + clocks: + minItems: 1 + items: + - description: Controller clock used by normal mode + - description: Reference clock used by low power mode etc + - description: Mcu bus clock for register access + - description: DMA bus clock for data transfer + + clock-names: + minItems: 1 + items: + - const: sys_ck # required, others are optional + - const: ref_ck + - const: mcu_ck + - const: dma_ck + + phys: + description: + List of all the USB PHYs used, it's better to keep the sequence + as the hardware layout. + minItems: 1 + items: + - description: USB2/HS PHY # required, others are optional + - description: USB3/SS(P) PHY + - description: USB2/HS PHY # the following for backward compatible + - description: USB3/SS(P) PHY + - description: USB2/HS PHY + - description: USB3/SS(P) PHY + - description: USB2/HS PHY + - description: USB3/SS(P) PHY + - description: USB2/HS PHY + + vusb33-supply: + description: Regulator of USB AVDD3.3v + + vbus-supply: + deprecated: true + description: | + Regulator of USB VBUS5v, needed when supports dual-role mode. + Particularly, if use an output GPIO to control a VBUS regulator, should + model it as a regulator. See bindings/regulator/fixed-regulator.yaml + It's considered valid for compatibility reasons, not allowed for + new bindings, and put into a usb-connector node. + + dr_mode: + enum: [host, peripheral, otg] + default: otg + + maximum-speed: + enum: [super-speed-plus, super-speed, high-speed, full-speed] + + "#address-cells": + enum: [1, 2] + + "#size-cells": + enum: [1, 2] + + ranges: true + + extcon: + deprecated: true + description: | + Phandle to the extcon device detecting the IDDIG/VBUS state, neede + when supports dual-role mode. + It's considered valid for compatibility reasons, not allowed for + new bindings, and use "usb-role-switch" property instead. + + usb-role-switch: + $ref: /schemas/types.yaml#/definitions/flag + description: Support role switch. + type: boolean + + connector: + $ref: /connector/usb-connector.yaml# + description: + Connector for dual role switch, especially for "gpio-usb-b-connector" + type: object + + port: + description: + Any connector to the data bus of this controller should be modelled + using the OF graph bindings specified, if the "usb-role-switch" + property is used. See graph.txt + type: object + + enable-manual-drd: + $ref: /schemas/types.yaml#/definitions/flag + description: + supports manual dual-role switch via debugfs; usually used when + receptacle is TYPE-A and also wants to support dual-role mode. + type: boolean + + wakeup-source: + description: enable USB remote wakeup, see power/wakeup-source.txt + type: boolean + + mediatek,syscon-wakeup: + $ref: /schemas/types.yaml#/definitions/phandle-array + maxItems: 1 + description: + A phandle to syscon used to access the register of the USB wakeup glue + layer between xHCI and SPM, the field should always be 3 cells long. + items: + items: + - description: + The first cell represents a phandle to syscon + - description: + The second cell represents the register base address of the glue + layer in syscon + - description: + The third cell represents the hardware version of the glue layer, + 1 is used by mt8173 etc, 2 is used by mt2712 etc + enum: [1, 2] + + mediatek,u3p-dis-msk: + $ref: /schemas/types.yaml#/definitions/uint32 + description: The mask to disable u3ports, bit0 for u3port0, + bit1 for u3port1, ... etc + +# Required child node when support dual-role +patternProperties: + "^usb@[0-9a-f]+$": + type: object + $ref: /usb/mediatek,mtk-xhci.yaml# + description: + The xhci should be added as subnode to mtu3 as shown in the following + example if the host mode is enabled. + +dependencies: + connector: [ 'usb-role-switch' ] + port: [ 'usb-role-switch' ] + wakeup-source: [ 'mediatek,syscon-wakeup' ] + +required: + - compatible + - reg + - reg-names + - interrupts + - clocks + - clock-names + +additionalProperties: false + +examples: + # Dual role switch by extcon + - | + #include + #include + #include + #include + #include + + usb@11271000 { + compatible = "mediatek,mt8173-mtu3", "mediatek,mtu3"; + reg = <0x11271000 0x3000>, <0x11280700 0x0100>; + reg-names = "mac", "ippc"; + interrupts = ; + phys = <&phy_port0 PHY_TYPE_USB3>, <&phy_port1 PHY_TYPE_USB2>; + power-domains = <&scpsys MT8173_POWER_DOMAIN_USB>; + clocks = <&topckgen CLK_TOP_USB30_SEL>; + clock-names = "sys_ck"; + vusb33-supply = <&mt6397_vusb_reg>; + vbus-supply = <&usb_p0_vbus>; + extcon = <&extcon_usb>; + dr_mode = "otg"; + wakeup-source; + mediatek,syscon-wakeup = <&pericfg 0x400 1>; + #address-cells = <1>; + #size-cells = <1>; + ranges; + + xhci: usb@11270000 { + compatible = "mediatek,mt8173-xhci", "mediatek,mtk-xhci"; + reg = <0x11270000 0x1000>; + reg-names = "mac"; + interrupts = ; + power-domains = <&scpsys MT8173_POWER_DOMAIN_USB>; + clocks = <&topckgen CLK_TOP_USB30_SEL>, <&clk26m>; + clock-names = "sys_ck", "ref_ck"; + vusb33-supply = <&mt6397_vusb_reg>; + }; + }; + + # Enable/disable device by an input gpio for VBUS pin + - | + #include + #include + + usb@112c1000 { + compatible = "mediatek,mt2712-mtu3", "mediatek,mtu3"; + reg = <0x112c1000 0x3000>, <0x112d0700 0x0100>; + reg-names = "mac", "ippc"; + interrupts = ; + phys = <&u2port2 PHY_TYPE_USB2>; + power-domains = <&scpsys MT2712_POWER_DOMAIN_USB2>; + clocks = <&topckgen CLK_TOP_USB30_SEL>; + clock-names = "sys_ck"; + dr_mode = "peripheral"; + usb-role-switch; + + connector { + compatible = "gpio-usb-b-connector", "usb-b-connector"; + type = "micro"; + vbus-gpios = <&pio 13 GPIO_ACTIVE_HIGH>; + }; + }; + + # Dual role switch with type-c + - | + usb@11201000 { + compatible ="mediatek,mt8183-mtu3", "mediatek,mtu3"; + reg = <0x11201000 0x2e00>, <0x11203e00 0x0100>; + reg-names = "mac", "ippc"; + interrupts = ; + phys = <&u2port0 PHY_TYPE_USB2>; + clocks = <&clk26m>; + clock-names = "sys_ck"; + mediatek,syscon-wakeup = <&pericfg 0x400 1>; + wakeup-source; + dr_mode = "otg"; + usb-role-switch; + #address-cells = <1>; + #size-cells = <1>; + ranges; + + host: usb@11200000 { + compatible = "mediatek,mt8183-xhci", "mediatek,mtk-xhci"; + reg = <0x11200000 0x1000>; + reg-names = "mac"; + interrupts = ; + clocks = <&clk26m>; + clock-names = "sys_ck"; + }; + + port { + usb_role_sw: endpoint { + remote-endpoint = <&hs_ep>; + }; + }; + }; + +... -- cgit v1.2.3 From f791f1a498fbef783e7711db9f597de7d85b661a Mon Sep 17 00:00:00 2001 From: Daniel Palmer Date: Sat, 12 Dec 2020 10:22:53 +0900 Subject: dt-bindings: vendor-prefixes: Fix misordering introduced by honestar prefix The prefix for honestar should come before honeywell. Fixes: 43181b5d8072 ("dt-bindings: vendor-prefixes: Add honestar vendor prefix") Signed-off-by: Daniel Palmer Link: https://lore.kernel.org/linux-arm-kernel/CAFr9PXmwOEuHHA-kDeL1YS8bWvovrt43MXxyy1J+hGbXwPUFSA@mail.gmail.com/ Link: https://lore.kernel.org/r/20201212012253.373074-1-daniel@0x0f.com' Signed-off-by: Arnd Bergmann --- Documentation/devicetree/bindings/vendor-prefixes.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/vendor-prefixes.yaml b/Documentation/devicetree/bindings/vendor-prefixes.yaml index 041ae90b0d8f..308512262009 100644 --- a/Documentation/devicetree/bindings/vendor-prefixes.yaml +++ b/Documentation/devicetree/bindings/vendor-prefixes.yaml @@ -467,10 +467,10 @@ patternProperties: description: Hitex Development Tools "^holt,.*": description: Holt Integrated Circuits, Inc. - "^honeywell,.*": - description: Honeywell "^honestar,.*": description: Honestar Technologies Co., Ltd. + "^honeywell,.*": + description: Honeywell "^hoperun,.*": description: Jiangsu HopeRun Software Co., Ltd. "^hp,.*": -- cgit v1.2.3 From 623c13295cf4e2d6ee80a6e8bae43529c0f020c9 Mon Sep 17 00:00:00 2001 From: Russell King Date: Thu, 14 Jan 2021 10:45:44 +0000 Subject: dt: ar803x: document SmartEEE properties The SmartEEE feature of Atheros AR803x PHYs can cause the link to bounce. Add DT properties to allow SmartEEE to be disabled, and to allow the Tw parameters for 100M and 1G links to be configured. Signed-off-by: Russell King Reviewed-by: Rob Herring Signed-off-by: Jakub Kicinski --- Documentation/devicetree/bindings/net/qca,ar803x.yaml | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/net/qca,ar803x.yaml b/Documentation/devicetree/bindings/net/qca,ar803x.yaml index 64b3357ade8a..b3d4013b7ca6 100644 --- a/Documentation/devicetree/bindings/net/qca,ar803x.yaml +++ b/Documentation/devicetree/bindings/net/qca,ar803x.yaml @@ -28,6 +28,10 @@ properties: $ref: /schemas/types.yaml#/definitions/uint32 enum: [0, 1, 2] + qca,disable-smarteee: + description: Disable Atheros SmartEEE feature. + type: boolean + qca,keep-pll-enabled: description: | If set, keep the PLL enabled even if there is no link. Useful if you @@ -36,6 +40,18 @@ properties: Only supported on the AR8031. type: boolean + qca,smarteee-tw-us-100m: + description: EEE Tw parameter for 100M links. + $ref: /schemas/types.yaml#/definitions/uint32 + minimum: 1 + maximum: 255 + + qca,smarteee-tw-us-1g: + description: EEE Tw parameter for gigabit links. + $ref: /schemas/types.yaml#/definitions/uint32 + minimum: 1 + maximum: 255 + vddio-supply: description: | RGMII I/O voltage regulator (see regulator/regulator.yaml). -- cgit v1.2.3 From 8204c2b01cf998a28901af819227b46f0e4c67a8 Mon Sep 17 00:00:00 2001 From: George McCollister Date: Thu, 14 Jan 2021 13:57:34 -0600 Subject: dt-bindings: net: dsa: add bindings for xrs700x switches Add documentation and an example for Arrow SpeedChips XRS7000 Series single chip Ethernet switches. Signed-off-by: George McCollister Reviewed-by: Florian Fainelli Signed-off-by: Jakub Kicinski --- .../devicetree/bindings/net/dsa/arrow,xrs700x.yaml | 73 ++++++++++++++++++++++ 1 file changed, 73 insertions(+) create mode 100644 Documentation/devicetree/bindings/net/dsa/arrow,xrs700x.yaml (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/net/dsa/arrow,xrs700x.yaml b/Documentation/devicetree/bindings/net/dsa/arrow,xrs700x.yaml new file mode 100644 index 000000000000..3f01b65f3b22 --- /dev/null +++ b/Documentation/devicetree/bindings/net/dsa/arrow,xrs700x.yaml @@ -0,0 +1,73 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/net/dsa/arrow,xrs700x.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Arrow SpeedChips XRS7000 Series Switch Device Tree Bindings + +allOf: + - $ref: dsa.yaml# + +maintainers: + - George McCollister + +description: + The Arrow SpeedChips XRS7000 Series of single chip gigabit Ethernet switches + are designed for critical networking applications. They have up to three + RGMII ports and one RMII port and are managed via i2c or mdio. + +properties: + compatible: + oneOf: + - enum: + - arrow,xrs7003e + - arrow,xrs7003f + - arrow,xrs7004e + - arrow,xrs7004f + + reg: + maxItems: 1 + +required: + - compatible + - reg + +unevaluatedProperties: false + +examples: + - | + i2c { + #address-cells = <1>; + #size-cells = <0>; + switch@8 { + compatible = "arrow,xrs7004e"; + reg = <0x8>; + + ethernet-ports { + #address-cells = <1>; + #size-cells = <0>; + ethernet-port@1 { + reg = <1>; + label = "lan0"; + phy-handle = <&swphy0>; + phy-mode = "rgmii-id"; + }; + ethernet-port@2 { + reg = <2>; + label = "lan1"; + phy-handle = <&swphy1>; + phy-mode = "rgmii-id"; + }; + ethernet-port@3 { + reg = <3>; + label = "cpu"; + ethernet = <&fec1>; + fixed-link { + speed = <1000>; + full-duplex; + }; + }; + }; + }; + }; -- cgit v1.2.3 From 26fe7d1da95be29a9a6d5cc73ffead9c6b8fd965 Mon Sep 17 00:00:00 2001 From: Mike Looijmans Date: Tue, 3 Nov 2020 09:37:06 +0100 Subject: dt-bindings: power/supply: Add ltc4162-l-charger Add support for the LTC4162-L Li-Ion battery charger. The driver allows reading back telemetry and to set some charging options like the input current limit. This adds the devicetree bindings. Signed-off-by: Mike Looijmans Reviewed-by: Rob Herring Signed-off-by: Sebastian Reichel --- .../bindings/power/supply/ltc4162-l.yaml | 69 ++++++++++++++++++++++ 1 file changed, 69 insertions(+) create mode 100644 Documentation/devicetree/bindings/power/supply/ltc4162-l.yaml (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/power/supply/ltc4162-l.yaml b/Documentation/devicetree/bindings/power/supply/ltc4162-l.yaml new file mode 100644 index 000000000000..1f88c9e013f4 --- /dev/null +++ b/Documentation/devicetree/bindings/power/supply/ltc4162-l.yaml @@ -0,0 +1,69 @@ +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) +# Copyright (C) 2020 Topic Embedded Products +%YAML 1.2 +--- +$id: "http://devicetree.org/schemas/power/supply/ltc4162-l.yaml#" +$schema: "http://devicetree.org/meta-schemas/core.yaml#" + +title: Linear Technology (Analog Devices) LTC4162-L Charger + +maintainers: + - Mike Looijmans + +description: | + The LTC ® 4162-L is an advanced monolithic synchronous step-down switching + battery charger and PowerPath (TM) manager that seamlessly manages power + distribution between input sources such as wall adapters, backplanes, solar + panels, etc., and a rechargeable Lithium-Ion/Polymer battery. + + Specifications about the charger can be found at: + https://www.analog.com/en/products/ltc4162-s.html + +properties: + compatible: + enum: + - lltc,ltc4162-l + + reg: + maxItems: 1 + description: I2C address of the charger. + + lltc,rsnsb-micro-ohms: + $ref: /schemas/types.yaml#/definitions/uint32 + description: Battery sense resistor in microohm. + minimum: 1000 + + lltc,rsnsi-micro-ohms: + $ref: /schemas/types.yaml#/definitions/uint32 + description: Input current sense resistor in microohm. + minimum: 1000 + + lltc,cell-count: + $ref: /schemas/types.yaml#/definitions/uint32 + description: | + Number of battery cells. If not provided, will be obtained from the chip + once the external power is applied. Omit this when the number of cells + is somewhat dynamic. Without it, several measurements will return 0 until + the charger is connected to an external supply. + +required: + - compatible + - reg + - lltc,rsnsb-micro-ohms + - lltc,rsnsi-micro-ohms + +additionalProperties: false + +examples: + - | + i2c0 { + #address-cells = <1>; + #size-cells = <0>; + charger: battery-charger@68 { + compatible = "lltc,ltc4162-l"; + reg = <0x68>; + lltc,rsnsb-micro-ohms = <10000>; + lltc,rsnsi-micro-ohms = <16000>; + lltc,cell-count = <2>; + }; + }; -- cgit v1.2.3 From fe487c75a4531ed528cc69324c5ea4ab4f92a7fa Mon Sep 17 00:00:00 2001 From: Claudiu Beznea Date: Wed, 16 Dec 2020 14:57:32 +0200 Subject: dt-bindings: atmel-sysreg: add microchip,sama7g5-shdwc Add compatible for Microchip SAMA7G5's shutdown controller. Signed-off-by: Claudiu Beznea Acked-by: Rob Herring Signed-off-by: Sebastian Reichel --- Documentation/devicetree/bindings/arm/atmel-sysregs.txt | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/arm/atmel-sysregs.txt b/Documentation/devicetree/bindings/arm/atmel-sysregs.txt index 62cd4e89817c..7990358ac06e 100644 --- a/Documentation/devicetree/bindings/arm/atmel-sysregs.txt +++ b/Documentation/devicetree/bindings/arm/atmel-sysregs.txt @@ -91,7 +91,8 @@ SHDWC SAMA5D2-Compatible Shutdown Controller 1) shdwc node required properties: -- compatible: should be "atmel,sama5d2-shdwc" or "microchip,sam9x60-shdwc". +- compatible: should be "atmel,sama5d2-shdwc", "microchip,sam9x60-shdwc" or + "microchip,sama7g5-shdwc" - reg: should contain registers location and length - clocks: phandle to input clock. - #address-cells: should be one. The cell is the wake-up input index. @@ -103,7 +104,7 @@ optional properties: microseconds. It's usually a board-related property. - atmel,wakeup-rtc-timer: boolean to enable Real-Time Clock wake-up. -optional microchip,sam9x60-shdwc properties: +optional microchip,sam9x60-shdwc or microchip,sama7g5-shdwc properties: - atmel,wakeup-rtt-timer: boolean to enable Real-time Timer Wake-up. The node contains child nodes for each wake-up input that the platform uses. -- cgit v1.2.3 From aa4731c8b5f41bbc7931f44a68e803fcca576dd3 Mon Sep 17 00:00:00 2001 From: Manivannan Sadhasivam Date: Mon, 11 Jan 2021 17:00:09 +0530 Subject: dt-bindings: phy: qcom,qmp: Add SDX55 USB PHY binding Add devicetree YAML binding for Qualcomm QMP Super Speed (SS) PHY found in SDX55. Signed-off-by: Manivannan Sadhasivam Reviewed-by: Rob Herring Link: https://lore.kernel.org/r/20210111113010.32056-2-manivannan.sadhasivam@linaro.org Signed-off-by: Vinod Koul --- .../devicetree/bindings/phy/qcom,qmp-phy.yaml | 27 ++++++++++++++++++++++ 1 file changed, 27 insertions(+) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/phy/qcom,qmp-phy.yaml b/Documentation/devicetree/bindings/phy/qcom,qmp-phy.yaml index ec05db374645..0f00d82461fd 100644 --- a/Documentation/devicetree/bindings/phy/qcom,qmp-phy.yaml +++ b/Documentation/devicetree/bindings/phy/qcom,qmp-phy.yaml @@ -34,6 +34,7 @@ properties: - qcom,sm8250-qmp-gen3x1-pcie-phy - qcom,sm8250-qmp-gen3x2-pcie-phy - qcom,sm8250-qmp-modem-pcie-phy + - qcom,sdx55-qmp-usb3-uni-phy reg: items: @@ -131,6 +132,32 @@ allOf: items: - const: phy - const: common + - if: + properties: + compatible: + contains: + enum: + - qcom,sdx55-qmp-usb3-uni-phy + then: + properties: + clocks: + items: + - description: Phy aux clock. + - description: Phy config clock. + - description: 19.2 MHz ref clk. + clock-names: + items: + - const: aux + - const: cfg_ahb + - const: ref + resets: + items: + - description: reset of phy block. + - description: phy common block reset. + reset-names: + items: + - const: phy + - const: common - if: properties: compatible: -- cgit v1.2.3 From 8627537ce04483641ca783c10578d0fb33bd239a Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Wed, 23 Dec 2020 18:25:00 +0100 Subject: dt-bindings: i2c: renesas,i2c: add r8a779a0 (V3U) support Signed-off-by: Wolfram Sang Reviewed-by: Geert Uytterhoeven Acked-by: Rob Herring Signed-off-by: Wolfram Sang --- Documentation/devicetree/bindings/i2c/renesas,i2c.txt | 1 + 1 file changed, 1 insertion(+) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/i2c/renesas,i2c.txt b/Documentation/devicetree/bindings/i2c/renesas,i2c.txt index 96d869ac3839..5762d2d1ab9c 100644 --- a/Documentation/devicetree/bindings/i2c/renesas,i2c.txt +++ b/Documentation/devicetree/bindings/i2c/renesas,i2c.txt @@ -26,6 +26,7 @@ Required properties: "renesas,i2c-r8a77980" if the device is a part of a R8A77980 SoC. "renesas,i2c-r8a77990" if the device is a part of a R8A77990 SoC. "renesas,i2c-r8a77995" if the device is a part of a R8A77995 SoC. + "renesas,i2c-r8a779a0" if the device is a part of a R8A779A0 SoC. "renesas,rcar-gen1-i2c" for a generic R-Car Gen1 compatible device. "renesas,rcar-gen2-i2c" for a generic R-Car Gen2 or RZ/G1 compatible device. -- cgit v1.2.3 From 18df346b66e56eb51fa423bda3fe4d413a7028ff Mon Sep 17 00:00:00 2001 From: Oleksij Rempel Date: Mon, 11 Jan 2021 11:18:51 +0100 Subject: dt-bindings: vendor-prefixes: Add an entry for Kverneland Group Add "kvg" entry for Kverneland Group: https://ien.kvernelandgroup.com/ Signed-off-by: Oleksij Rempel Acked-by: Rob Herring Signed-off-by: Shawn Guo --- Documentation/devicetree/bindings/vendor-prefixes.yaml | 2 ++ 1 file changed, 2 insertions(+) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/vendor-prefixes.yaml b/Documentation/devicetree/bindings/vendor-prefixes.yaml index f03ba0c4ae5e..115d859927f8 100644 --- a/Documentation/devicetree/bindings/vendor-prefixes.yaml +++ b/Documentation/devicetree/bindings/vendor-prefixes.yaml @@ -581,6 +581,8 @@ patternProperties: description: Kontron S&T AG "^kosagi,.*": description: Sutajio Ko-Usagi PTE Ltd. + "^kvg,.*": + description: Kverneland Group "^kyo,.*": description: Kyocera Corporation "^lacie,.*": -- cgit v1.2.3 From 55d743d1067bea8630c885b4f0078c66205ea005 Mon Sep 17 00:00:00 2001 From: Oleksij Rempel Date: Mon, 11 Jan 2021 11:18:52 +0100 Subject: dt-bindings: arm: fsl: add Kverneland UT1, UT1Q and UI1P boards Add Kverneland UT1 (imx6dl), UT1Q (imx6q) and UT1P (imx6dp) based boards Signed-off-by: Oleksij Rempel Acked-by: Rob Herring Signed-off-by: Shawn Guo --- Documentation/devicetree/bindings/arm/fsl.yaml | 3 +++ 1 file changed, 3 insertions(+) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/arm/fsl.yaml b/Documentation/devicetree/bindings/arm/fsl.yaml index 89ef175ee49f..2eced2f84df2 100644 --- a/Documentation/devicetree/bindings/arm/fsl.yaml +++ b/Documentation/devicetree/bindings/arm/fsl.yaml @@ -210,6 +210,7 @@ properties: - kiebackpeter,imx6q-tpc # K+P i.MX6 Quad TPC Board - kontron,imx6q-samx6i # Kontron i.MX6 Dual/Quad SMARC Module - kosagi,imx6q-novena # Kosagi Novena Dual/Quad + - kvg,vicut1q # Kverneland UT1Q board - logicpd,imx6q-logicpd - lwn,display5 # Liebherr Display5 i.MX6 Quad Board - lwn,mccmon6 # Liebherr Monitor6 i.MX6 Quad Board @@ -331,6 +332,7 @@ properties: - fsl,imx6qp-sabreauto # i.MX6 Quad Plus SABRE Automotive Board - fsl,imx6qp-sabresd # i.MX6 Quad Plus SABRE Smart Device Board - karo,imx6qp-tx6qp # Ka-Ro electronics TX6QP-8037 Module + - kvg,vicutp # Kverneland UT1P board - prt,prtwd3 # Protonic WD3 board - wand,imx6qp-wandboard # Wandboard i.MX6 QuadPlus Board - zii,imx6qp-zii-rdu2 # ZII RDU2+ Board @@ -364,6 +366,7 @@ properties: - fsl,imx6dl-sabresd # i.MX6 DualLite SABRE Smart Device Board - karo,imx6dl-tx6dl # Ka-Ro electronics TX6U Modules - kontron,imx6dl-samx6i # Kontron i.MX6 Solo SMARC Module + - kvg,vicut1 # Kverneland UT1 board - ply,plybas # Plymovent BAS board - ply,plym2m # Plymovent M2M board - poslab,imx6dl-savageboard # Poslab SavageBoard Dual -- cgit v1.2.3 From 6e73bfbb2ed099da744587cbd0b5416ce378c575 Mon Sep 17 00:00:00 2001 From: Oleksij Rempel Date: Mon, 11 Jan 2021 11:18:54 +0100 Subject: dt-bindings: arm: fsl: add Kverneland TGO board Add Kverneland TGO imx6dl based board Signed-off-by: Oleksij Rempel Acked-by: Rob Herring Signed-off-by: Shawn Guo --- Documentation/devicetree/bindings/arm/fsl.yaml | 1 + 1 file changed, 1 insertion(+) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/arm/fsl.yaml b/Documentation/devicetree/bindings/arm/fsl.yaml index 2eced2f84df2..65038b16302e 100644 --- a/Documentation/devicetree/bindings/arm/fsl.yaml +++ b/Documentation/devicetree/bindings/arm/fsl.yaml @@ -366,6 +366,7 @@ properties: - fsl,imx6dl-sabresd # i.MX6 DualLite SABRE Smart Device Board - karo,imx6dl-tx6dl # Ka-Ro electronics TX6U Modules - kontron,imx6dl-samx6i # Kontron i.MX6 Solo SMARC Module + - kvg,victgo # Kverneland TGO - kvg,vicut1 # Kverneland UT1 board - ply,plybas # Plymovent BAS board - ply,plym2m # Plymovent M2M board -- cgit v1.2.3 From e0ab5bf98208294f7fb39d8ce3746eaf39d38dfe Mon Sep 17 00:00:00 2001 From: Maxime Ripard Date: Thu, 14 Jan 2021 12:35:20 +0100 Subject: dt-bindings: sunxi: Fix the pinecube compatible Commit 6ab48105aae7 ("ARM: dts: s3: pinecube: align compatible property to other S3 boards") changed the pinecube compatible to make it similar to the other S3 boards we have, but failed to update the bindings documentation. Fixes: 6ab48105aae7 ("ARM: dts: s3: pinecube: align compatible property to other S3 boards") Signed-off-by: Maxime Ripard Acked-by: Jernej Skrabec Acked-by: Chen-Yu Tsai Link: https://lore.kernel.org/r/20210114113538.1233933-1-maxime@cerno.tech --- Documentation/devicetree/bindings/arm/sunxi.yaml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/arm/sunxi.yaml b/Documentation/devicetree/bindings/arm/sunxi.yaml index 7ea4d9645e93..08607c7ec1bf 100644 --- a/Documentation/devicetree/bindings/arm/sunxi.yaml +++ b/Documentation/devicetree/bindings/arm/sunxi.yaml @@ -657,7 +657,8 @@ properties: - description: Pine64 PineCube items: - const: pine64,pinecube - - const: allwinner,sun8i-s3 + - const: sochip,s3 + - const: allwinner,sun8i-v3 - description: Pine64 PineH64 model A items: -- cgit v1.2.3 From dcd80eaf74ef781ee6e2585622d7b4956c47bb9a Mon Sep 17 00:00:00 2001 From: Maxime Ripard Date: Thu, 14 Jan 2021 12:35:21 +0100 Subject: dt-bindings: iio: adc: Add AXP803 compatible The AXP803 compatible was introduced recently with a fallback to the AXP813, but it was never documented. Cc: Jonathan Cameron Cc: Lars-Peter Clausen Cc: Peter Meerwald-Stadler Signed-off-by: Maxime Ripard Acked-by: Chen-Yu Tsai Acked-by: Jernej Skrabec Acked-by: Jonathan Cameron Link: https://lore.kernel.org/r/20210114113538.1233933-2-maxime@cerno.tech --- .../devicetree/bindings/iio/adc/x-powers,axp209-adc.yaml | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/iio/adc/x-powers,axp209-adc.yaml b/Documentation/devicetree/bindings/iio/adc/x-powers,axp209-adc.yaml index 5ccbb1f81960..e759a5da708d 100644 --- a/Documentation/devicetree/bindings/iio/adc/x-powers,axp209-adc.yaml +++ b/Documentation/devicetree/bindings/iio/adc/x-powers,axp209-adc.yaml @@ -46,10 +46,14 @@ description: | properties: compatible: - enum: - - x-powers,axp209-adc - - x-powers,axp221-adc - - x-powers,axp813-adc + oneOf: + - const: x-powers,axp209-adc + - const: x-powers,axp221-adc + - const: x-powers,axp813-adc + + - items: + - const: x-powers,axp803-adc + - const: x-powers,axp813-adc "#io-channel-cells": const: 1 -- cgit v1.2.3 From 48b47749e334b3891f33b9425b470a3c92be8dae Mon Sep 17 00:00:00 2001 From: Maxime Ripard Date: Thu, 14 Jan 2021 12:35:22 +0100 Subject: dt-bindings: rtc: sun6i-a31-rtc: Loosen the requirements on the clocks The commit ec98a87509f4 ("rtc: sun6i: Make external 32k oscillator optional") loosened the requirement of the clocks property, making it optional. However, the binding still required it to be present. Cc: Alexandre Belloni Fixes: ec98a87509f4 ("rtc: sun6i: Make external 32k oscillator optional") Signed-off-by: Maxime Ripard Acked-by: Jernej Skrabec Acked-by: Chen-Yu Tsai Link: https://lore.kernel.org/r/20210114113538.1233933-3-maxime@cerno.tech --- Documentation/devicetree/bindings/rtc/allwinner,sun6i-a31-rtc.yaml | 1 - 1 file changed, 1 deletion(-) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/rtc/allwinner,sun6i-a31-rtc.yaml b/Documentation/devicetree/bindings/rtc/allwinner,sun6i-a31-rtc.yaml index 37c2a601c3fa..b1b0ee769b71 100644 --- a/Documentation/devicetree/bindings/rtc/allwinner,sun6i-a31-rtc.yaml +++ b/Documentation/devicetree/bindings/rtc/allwinner,sun6i-a31-rtc.yaml @@ -128,7 +128,6 @@ required: - compatible - reg - interrupts - - clocks - clock-output-names additionalProperties: false -- cgit v1.2.3 From 31b8e8592f6663c0937d1408f1fd6ed566fbde5c Mon Sep 17 00:00:00 2001 From: Chen-Yu Tsai Date: Sun, 17 Jan 2021 18:07:09 +0800 Subject: dt-bindings: arm: rockchip: Add Radxa ROCK Pi E Radxa ROCK Pi E is a router oriented SBC based on Rockchip's RK3328 SoC. As the official wiki page puts it, "E for Ethernets". It features the RK3328 SoC, gigabit and fast Ethernet RJ45 ports, both directly served by Ethernet controllers in the SoC, a USB 3.0 host port, a power-only USB type-C port, a 3.5mm headphone jack for audio output, two LEDs, a 40-pin Raspberry Pi style GPIO header, and optional WiFi+BT and PoE header. The board comes in multiple configurations, differing in the amount of onboard RAM, the level of WiFi+BT (none, 802.11n 2.4GHz, or 802.11ac 2.4 GHz & 5 GHz), and whether PoE is supported or not. These variants can all share the same device tree. The USB 2.0 OTG controller is available on the 40-pin header. This is not enabled in the device tree, since it is possible to use it in a host-only configuration, or in OTG mode with an extra pin from the header as the ID pin. The device tree is based on the one of the Rock64, with various parts modified to match the ROCK Pi E, and some parts updated to newer styles, such as the gmac2io node's mdio sub-node. Add a compatible string for the new board. Acked-by: Rob Herring Signed-off-by: Chen-Yu Tsai Link: https://lore.kernel.org/r/20210117100710.4857-3-wens@kernel.org Signed-off-by: Heiko Stuebner --- Documentation/devicetree/bindings/arm/rockchip.yaml | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/arm/rockchip.yaml b/Documentation/devicetree/bindings/arm/rockchip.yaml index ef4544ad6f82..8a2dd9f1cff2 100644 --- a/Documentation/devicetree/bindings/arm/rockchip.yaml +++ b/Documentation/devicetree/bindings/arm/rockchip.yaml @@ -467,6 +467,11 @@ properties: - const: radxa,rockpi4 - const: rockchip,rk3399 + - description: Radxa ROCK Pi E + items: + - const: radxa,rockpi-e + - const: rockchip,rk3328 + - description: Radxa ROCK Pi N8 items: - const: radxa,rockpi-n8 -- cgit v1.2.3 From e36626bb099e5159a7868dbfad6957ff6b0e4102 Mon Sep 17 00:00:00 2001 From: Jonathan Neuschäfer Date: Sat, 16 Jan 2021 02:34:03 +0100 Subject: ASoC: dt-bindings: mt8192-mt6359: Fix indentation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The items of the 'maintainers' list are indented with three spaces. Use the usual two spaces instead, for consistency and to silence yamllint. Signed-off-by: Jonathan Neuschäfer Link: https://lore.kernel.org/r/20210116013403.3490518-1-j.neuschaefer@gmx.net Signed-off-by: Mark Brown --- .../devicetree/bindings/sound/mt8192-mt6359-rt1015-rt5682.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/sound/mt8192-mt6359-rt1015-rt5682.yaml b/Documentation/devicetree/bindings/sound/mt8192-mt6359-rt1015-rt5682.yaml index bf8c8ba25009..54650823b29a 100644 --- a/Documentation/devicetree/bindings/sound/mt8192-mt6359-rt1015-rt5682.yaml +++ b/Documentation/devicetree/bindings/sound/mt8192-mt6359-rt1015-rt5682.yaml @@ -7,8 +7,8 @@ $schema: http://devicetree.org/meta-schemas/core.yaml# title: Mediatek MT8192 with MT6359, RT1015 and RT5682 ASoC sound card driver maintainers: - - Jiaxin Yu - - Shane Chien + - Jiaxin Yu + - Shane Chien description: This binding describes the MT8192 sound card. -- cgit v1.2.3 From 160e8f96c626ae2bfeef18df467fd9f3814ec89a Mon Sep 17 00:00:00 2001 From: Michael Sit Wei Hong Date: Mon, 18 Jan 2021 18:27:06 +0800 Subject: ASoC: intel, keembay-i2s: Fix dt binding errors Fix devicetree binding errors caused by newly added parameters Signed-off-by: Michael Sit Wei Hong Link: https://lore.kernel.org/r/20210118102706.6125-1-michael.wei.hong.sit@intel.com Signed-off-by: Mark Brown --- Documentation/devicetree/bindings/sound/intel,keembay-i2s.yaml | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/sound/intel,keembay-i2s.yaml b/Documentation/devicetree/bindings/sound/intel,keembay-i2s.yaml index e0658f122cbb..dba25c33f0b0 100644 --- a/Documentation/devicetree/bindings/sound/intel,keembay-i2s.yaml +++ b/Documentation/devicetree/bindings/sound/intel,keembay-i2s.yaml @@ -47,13 +47,11 @@ properties: dmas: items: - - description: DMA controller phandle and DMA channel - for TX and RX + - description: DMA TX channel + - description: DMA RX channel dma-names: items: - - description: "tx" for the transmit channel - "rx" for the receive channel - const: tx - const: rx -- cgit v1.2.3 From 57c412d43d71b12df9aa414ec27cd793e9821274 Mon Sep 17 00:00:00 2001 From: Sameer Pujar Date: Mon, 18 Jan 2021 11:13:05 +0530 Subject: ASoC: audio-graph-card: Drop remote-endpoint as required property The remote-endpoint may not be available if it is part of some pluggable module. One such example would be an audio card, the Codec endpoint will not be available until it is plugged in. Hence drop 'remote-endpoint' as a required property. Cc: Rob Herring Cc: Kuninori Morimoto Signed-off-by: Sameer Pujar Link: https://lore.kernel.org/r/1610948585-16286-1-git-send-email-spujar@nvidia.com Signed-off-by: Mark Brown --- Documentation/devicetree/bindings/sound/audio-graph-port.yaml | 3 --- 1 file changed, 3 deletions(-) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/sound/audio-graph-port.yaml b/Documentation/devicetree/bindings/sound/audio-graph-port.yaml index 2005014161be..766e9109b2f7 100644 --- a/Documentation/devicetree/bindings/sound/audio-graph-port.yaml +++ b/Documentation/devicetree/bindings/sound/audio-graph-port.yaml @@ -71,9 +71,6 @@ properties: description: CPU to Codec rate channels. $ref: /schemas/types.yaml#/definitions/uint32 - required: - - remote-endpoint - ports: description: multi OF-Graph subnode type: object -- cgit v1.2.3 From df1bdee806f3387c03a3944a30edf8e9f45b5088 Mon Sep 17 00:00:00 2001 From: Jonathan Neuschäfer Date: Sat, 16 Jan 2021 02:53:49 +0100 Subject: dt-bindings: pinctrl: pinctrl-microchip-sgpio: Fix indentation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit yamllint warns: ./Documentation/devicetree/bindings/pinctrl/microchip,sparx5-sgpio.yaml 102:10 error wrong indentation: expected 10 but found 9 (indentation) Signed-off-by: Jonathan Neuschäfer Link: https://lore.kernel.org/r/20210116015350.3501927-1-j.neuschaefer@gmx.net Signed-off-by: Linus Walleij --- Documentation/devicetree/bindings/pinctrl/microchip,sparx5-sgpio.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/pinctrl/microchip,sparx5-sgpio.yaml b/Documentation/devicetree/bindings/pinctrl/microchip,sparx5-sgpio.yaml index df0c83cb1c6e..4fe35e650909 100644 --- a/Documentation/devicetree/bindings/pinctrl/microchip,sparx5-sgpio.yaml +++ b/Documentation/devicetree/bindings/pinctrl/microchip,sparx5-sgpio.yaml @@ -99,8 +99,8 @@ patternProperties: '#interrupt-cells': description: - Specifies the pin (port and bit) and flags, as defined in - defined in include/dt-bindings/interrupt-controller/irq.h + Specifies the pin (port and bit) and flags, as defined in + defined in include/dt-bindings/interrupt-controller/irq.h const: 3 ngpios: -- cgit v1.2.3 From e1922b5da0e6869f1850c4447bed0b9cb1cf5034 Mon Sep 17 00:00:00 2001 From: Jonathan Neuschäfer Date: Fri, 8 Jan 2021 17:30:04 +0100 Subject: dt-bindings: timer: nuvoton: Clarify that interrupt of timer 0 should be specified MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The NPCM750 Timer/Watchdog Controller has multiple interrupt lines, connected to multiple timers. The driver uses timer 0 for timer interrupts, so the interrupt line corresponding to timer 0 should be specified in DT. I removed the mention of "flags for falling edge", because the timer controller uses high-level interrupts rather than falling-edge interrupts, and whether flags should be specified is up the interrupt controller's DT binding. Signed-off-by: Jonathan Neuschäfer Acked-by: Rob Herring Signed-off-by: Daniel Lezcano Link: https://lore.kernel.org/r/20210108163004.492649-1-j.neuschaefer@gmx.net --- Documentation/devicetree/bindings/timer/nuvoton,npcm7xx-timer.txt | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/timer/nuvoton,npcm7xx-timer.txt b/Documentation/devicetree/bindings/timer/nuvoton,npcm7xx-timer.txt index ea22dfe485be..97258f1a1505 100644 --- a/Documentation/devicetree/bindings/timer/nuvoton,npcm7xx-timer.txt +++ b/Documentation/devicetree/bindings/timer/nuvoton,npcm7xx-timer.txt @@ -6,8 +6,7 @@ timer counters. Required properties: - compatible : "nuvoton,npcm750-timer" for Poleg NPCM750. - reg : Offset and length of the register set for the device. -- interrupts : Contain the timer interrupt with flags for - falling edge. +- interrupts : Contain the timer interrupt of timer 0. - clocks : phandle of timer reference clock (usually a 25 MHz clock). Example: -- cgit v1.2.3 From f9a056e002a2eaab1b3e86f9855047a06c89ec14 Mon Sep 17 00:00:00 2001 From: Douglas Anderson Date: Fri, 15 Jan 2021 09:06:39 -0800 Subject: dt-bindings: input: HID: i2c-hid: Introduce bindings for the Goodix GT7375P This adds new bindings for the Goodix GT7375P touchscreen. While this touchscreen's communications are based on the generic "i2c-over-hid" protocol, it needs special power sequencing and thus gets its own compatible and bindings. Signed-off-by: Douglas Anderson Reviewed-by: Rob Herring Signed-off-by: Benjamin Tissoires --- .../devicetree/bindings/input/goodix,gt7375p.yaml | 65 ++++++++++++++++++++++ 1 file changed, 65 insertions(+) create mode 100644 Documentation/devicetree/bindings/input/goodix,gt7375p.yaml (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/input/goodix,gt7375p.yaml b/Documentation/devicetree/bindings/input/goodix,gt7375p.yaml new file mode 100644 index 000000000000..fe1c5016f7f3 --- /dev/null +++ b/Documentation/devicetree/bindings/input/goodix,gt7375p.yaml @@ -0,0 +1,65 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/input/goodix,gt7375p.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Goodix GT7375P touchscreen + +maintainers: + - Douglas Anderson + +description: + Supports the Goodix GT7375P touchscreen. + This touchscreen uses the i2c-hid protocol but has some non-standard + power sequencing required. + +properties: + compatible: + items: + - const: goodix,gt7375p + + reg: + enum: + - 0x5d + - 0x14 + + interrupts: + maxItems: 1 + + reset-gpios: + true + + vdd-supply: + description: The 3.3V supply to the touchscreen. + +required: + - compatible + - reg + - interrupts + - reset-gpios + - vdd-supply + +additionalProperties: false + +examples: + - | + #include + #include + #include + + i2c { + #address-cells = <1>; + #size-cells = <0>; + + ap_ts: touchscreen@5d { + compatible = "goodix,gt7375p"; + reg = <0x5d>; + + interrupt-parent = <&tlmm>; + interrupts = <9 IRQ_TYPE_LEVEL_LOW>; + + reset-gpios = <&tlmm 8 GPIO_ACTIVE_LOW>; + vdd-supply = <&pp3300_ts>; + }; + }; -- cgit v1.2.3 From cf6d6fc27936025e851b3dc88be3b68c40d5fd08 Mon Sep 17 00:00:00 2001 From: Thorsten Leemhuis Date: Sat, 16 Jan 2021 15:35:42 +0100 Subject: docs: process/howto.rst: make sections on bug reporting match practice The file Documentation/process/howto.rst points to bugzilla.kernel.org as the primary place to report kernel bugs to. For most of the kernel that's the wrong place, as the MAINTAINERS file shows. Adjust those sections to make them match current practice. This change also removes a contradiction with the recently added text Documentation/admin-guide/reporting-issues.rst, which is a reason for a 'this needs further discussion' warning note in there. The change is thus a prerequisite to remove that warning, nevertheless it is left for now to make sure people review the text's approach more carefully. Signed-off-by: Thorsten Leemhuis Acked-by: Randy Dunlap Link: https://lore.kernel.org/r/20210116143542.69199-1-linux@leemhuis.info Signed-off-by: Jonathan Corbet --- Documentation/process/howto.rst | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) (limited to 'Documentation') diff --git a/Documentation/process/howto.rst b/Documentation/process/howto.rst index 7a5c105e34d4..e4beeca57e5f 100644 --- a/Documentation/process/howto.rst +++ b/Documentation/process/howto.rst @@ -342,16 +342,10 @@ Adventurous testers are very welcome to runtime-test the linux-next. Bug Reporting ------------- -https://bugzilla.kernel.org is where the Linux kernel developers track kernel -bugs. Users are encouraged to report all bugs that they find in this -tool. For details on how to use the kernel bugzilla, please see: - - https://bugzilla.kernel.org/page.cgi?id=faq.html - The file 'Documentation/admin-guide/reporting-issues.rst' in the main kernel -source directory has a good template for how to report a possible kernel bug, -and details what kind of information is needed by the kernel developers to help -track down the problem. +source directory describes how to report a possible kernel bug, and details +what kind of information is needed by the kernel developers to help track +down the problem. Managing bug reports @@ -364,7 +358,13 @@ improve your skills, and other developers will be aware of your presence. Fixing bugs is one of the best ways to get merits among other developers, because not many people like wasting time fixing other people's bugs. -To work in the already reported bug reports, go to https://bugzilla.kernel.org. +To work on already reported bug reports, find a subsystem you are interested in. +Check the MAINTAINERS file where bugs for that subsystem get reported to; often +it will be a mailing list, rarely a bugtracker. Search the archives of said +place for recent reports and help where you see fit. You may also want to check +https://bugzilla.kernel.org for bug reports; only a handful of kernel subsystems +use it actively for reporting or tracking, nevertheless bugs for the whole +kernel get filed there. Mailing lists -- cgit v1.2.3 From c305f1b408dc0eac0a4a65a3c92e50a0086ee71d Mon Sep 17 00:00:00 2001 From: SeongJae Park Date: Sun, 17 Jan 2021 11:09:29 +0100 Subject: Documentation/kokr/howto: Replace HTTP links with HTTPS ones: Documentation/process Apply this commit to Korean: e7b4311ebcac ("Replace HTTP links with HTTPS ones: Documentation/process") Signed-off-by: SeongJae Park Link: https://lore.kernel.org/r/20210117100931.9347-2-sj38.park@gmail.com Signed-off-by: Jonathan Corbet --- Documentation/translations/ko_KR/howto.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Documentation') diff --git a/Documentation/translations/ko_KR/howto.rst b/Documentation/translations/ko_KR/howto.rst index 240d29be38f2..0a42ffdea918 100644 --- a/Documentation/translations/ko_KR/howto.rst +++ b/Documentation/translations/ko_KR/howto.rst @@ -583,7 +583,7 @@ Pat이라는 이름을 가진 여자가 있을 수도 있는 것이다. 리눅 "The Perfect Patch" - http://www.ozlabs.org/~akpm/stuff/tpp.txt + https://www.ozlabs.org/~akpm/stuff/tpp.txt 이 모든 것을 하는 것은 매우 어려운 일이다. 완벽히 소화하는 데는 적어도 몇년이 -- cgit v1.2.3 From 0a610e5cd930cb7e09264d8e85ddb7fafa1cfc4b Mon Sep 17 00:00:00 2001 From: SeongJae Park Date: Sun, 17 Jan 2021 11:09:30 +0100 Subject: docs/kokr: make reporting-bugs.rst obsolete Translate this commit to Korean: da514157c4f0 ("docs: make reporting-bugs.rst obsolete") Signed-off-by: SeongJae Park Link: https://lore.kernel.org/r/20210117100931.9347-3-sj38.park@gmail.com Signed-off-by: Jonathan Corbet --- Documentation/translations/ko_KR/howto.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Documentation') diff --git a/Documentation/translations/ko_KR/howto.rst b/Documentation/translations/ko_KR/howto.rst index 0a42ffdea918..787f1e85f8a0 100644 --- a/Documentation/translations/ko_KR/howto.rst +++ b/Documentation/translations/ko_KR/howto.rst @@ -345,7 +345,7 @@ https://bugzilla.kernel.org 는 리눅스 커널 개발자들이 커널의 버 https://bugzilla.kernel.org/page.cgi?id=faq.html -메인 커널 소스 디렉토리에 있는 :ref:`admin-guide/reporting-bugs.rst ` +메인 커널 소스 디렉토리에 있는 'Documentation/admin-guide/reporting-issues.rst' 파일은 커널 버그라고 생각되는 것을 보고하는 방법에 관한 좋은 템플릿이며 문제를 추적하기 위해서 커널 개발자들이 필요로 하는 정보가 무엇들인지를 상세히 설명하고 있다. -- cgit v1.2.3 From e651fdb281854a718eea438c70c0e1c1d336fc0c Mon Sep 17 00:00:00 2001 From: SeongJae Park Date: Sun, 17 Jan 2021 11:09:31 +0100 Subject: docs/kokr: Link memory-barriers.txt to rst This commit links Korean translation of 'memory-barriers.txt' in the translations index rst file as the original version is linked in 'Documentation/staging/index.rst'. Signed-off-by: SeongJae Park Link: https://lore.kernel.org/r/20210117100931.9347-4-sj38.park@gmail.com Signed-off-by: Jonathan Corbet --- Documentation/translations/ko_KR/index.rst | 15 +++++++++++++++ 1 file changed, 15 insertions(+) (limited to 'Documentation') diff --git a/Documentation/translations/ko_KR/index.rst b/Documentation/translations/ko_KR/index.rst index 27995c4233de..b9e27d20b039 100644 --- a/Documentation/translations/ko_KR/index.rst +++ b/Documentation/translations/ko_KR/index.rst @@ -10,3 +10,18 @@ :maxdepth: 1 howto + + +리눅스 커널 메모리 배리어 +------------------------- + +.. raw:: latex + + \footnotesize + +.. include:: ./memory-barriers.txt + :literal: + +.. raw:: latex + + \normalsize -- cgit v1.2.3 From f0ea149eee6bce70f7c55ebf8bca93a0b02bfbd0 Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Wed, 13 Jan 2021 16:33:15 +0000 Subject: docs: submitting-patches: Emphasise the requirement to Cc: stable when using Fixes: tag Clear-up any confusion surrounding the Fixes: tag with regards to the need to Cc: the stable mailing list when submitting stable patch candidates. Signed-off-by: Lee Jones Reviewed-by: Greg Kroah-Hartman Cc: Greg Kroah-Hartman Cc: Jonathan Corbet Cc: linux-doc@vger.kernel.org Link: https://lore.kernel.org/r/20210113163315.1331064-1-lee.jones@linaro.org Signed-off-by: Jonathan Corbet --- Documentation/process/submitting-patches.rst | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'Documentation') diff --git a/Documentation/process/submitting-patches.rst b/Documentation/process/submitting-patches.rst index 7c97ad580e7d..7f48cccc75cd 100644 --- a/Documentation/process/submitting-patches.rst +++ b/Documentation/process/submitting-patches.rst @@ -556,6 +556,11 @@ which stable kernel versions should receive your fix. This is the preferred method for indicating a bug fixed by the patch. See :ref:`describe_changes` for more details. +Note: Attaching a Fixes: tag does not subvert the stable kernel rules +process nor the requirement to Cc: stable@vger.kernel.org on all stable +patch candidates. For more information, please read +:ref:`Documentation/process/stable-kernel-rules.rst ` + .. _the_canonical_patch_format: The canonical patch format -- cgit v1.2.3 From 1a63f9cce7b7872567f9a40708689e263d948b21 Mon Sep 17 00:00:00 2001 From: Milan Lakhani Date: Tue, 12 Jan 2021 13:41:01 +0000 Subject: docs: Remove make headers_check from checklist Remove the make headers_check step from submit-checklist.rst as this is no longer functional. Signed-off-by: Milan Lakhani Link: https://lore.kernel.org/r/1610458861-2832-1-git-send-email-milan.lakhani@codethink.co.uk Signed-off-by: Jonathan Corbet --- Documentation/process/submit-checklist.rst | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) (limited to 'Documentation') diff --git a/Documentation/process/submit-checklist.rst b/Documentation/process/submit-checklist.rst index 230ee42f872f..f709beaf02c9 100644 --- a/Documentation/process/submit-checklist.rst +++ b/Documentation/process/submit-checklist.rst @@ -89,30 +89,28 @@ and elsewhere regarding submitting Linux kernel patches. Patches that change userspace interfaces should be CCed to linux-api@vger.kernel.org. -19) Check that it all passes ``make headers_check``. - -20) Has been checked with injection of at least slab and page-allocation +19) Has been checked with injection of at least slab and page-allocation failures. See ``Documentation/fault-injection/``. If the new code is substantial, addition of subsystem-specific fault injection might be appropriate. -21) Newly-added code has been compiled with ``gcc -W`` (use +20) Newly-added code has been compiled with ``gcc -W`` (use ``make EXTRA_CFLAGS=-W``). This will generate lots of noise, but is good for finding bugs like "warning: comparison between signed and unsigned". -22) Tested after it has been merged into the -mm patchset to make sure +21) Tested after it has been merged into the -mm patchset to make sure that it still works with all of the other queued patches and various changes in the VM, VFS, and other subsystems. -23) All memory barriers {e.g., ``barrier()``, ``rmb()``, ``wmb()``} need a +22) All memory barriers {e.g., ``barrier()``, ``rmb()``, ``wmb()``} need a comment in the source code that explains the logic of what they are doing and why. -24) If any ioctl's are added by the patch, then also update +23) If any ioctl's are added by the patch, then also update ``Documentation/userspace-api/ioctl/ioctl-number.rst``. -25) If your modified source code depends on or uses any of the kernel +24) If your modified source code depends on or uses any of the kernel APIs or features that are related to the following ``Kconfig`` symbols, then test multiple builds with the related ``Kconfig`` symbols disabled and/or ``=m`` (if that option is available) [not all of these at the -- cgit v1.2.3 From 96c0f7c0b9ac00fff928b9e81d134639a4e4ba56 Mon Sep 17 00:00:00 2001 From: Rolf Eike Beer Date: Tue, 12 Jan 2021 14:19:36 +0100 Subject: Documentation: fix typos in split page table lock description Signed-off-by: Rolf Eike Beer Link: https://lore.kernel.org/r/2338863.uUFqZTUbry@devpool47 Signed-off-by: Jonathan Corbet --- Documentation/vm/split_page_table_lock.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Documentation') diff --git a/Documentation/vm/split_page_table_lock.rst b/Documentation/vm/split_page_table_lock.rst index ff51f4a5494d..c08919662704 100644 --- a/Documentation/vm/split_page_table_lock.rst +++ b/Documentation/vm/split_page_table_lock.rst @@ -32,7 +32,7 @@ There are helpers to lock/unlock a table and other accessor functions: Split page table lock for PTE tables is enabled compile-time if CONFIG_SPLIT_PTLOCK_CPUS (usually 4) is less or equal to NR_CPUS. -If split lock is disabled, all tables guaded by mm->page_table_lock. +If split lock is disabled, all tables are guarded by mm->page_table_lock. Split page table lock for PMD tables is enabled, if it's enabled for PTE tables and the architecture supports it (see below). -- cgit v1.2.3 From f435ce7ebf8c6fa7d962a34842a57500d6db5733 Mon Sep 17 00:00:00 2001 From: Rafał Miłecki Date: Thu, 10 Dec 2020 19:04:20 +0100 Subject: dt-bindings: PCI: brcmstb: add BCM4908 binding MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BCM4908 is a SoC family with PCIe controller sharing design with the one for STB. BCM4908 has different power management and memory controller so few tweaks are required. PERST# signal on BCM4908 is handled by an external MISC block so it needs specifying a reset phandle. Link: https://lore.kernel.org/r/20201210180421.7230-2-zajec5@gmail.com Signed-off-by: Rafał Miłecki Signed-off-by: Lorenzo Pieralisi Reviewed-by: Rob Herring Acked-by: Florian Fainelli --- .../devicetree/bindings/pci/brcm,stb-pcie.yaml | 37 ++++++++++++++++------ 1 file changed, 28 insertions(+), 9 deletions(-) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/pci/brcm,stb-pcie.yaml b/Documentation/devicetree/bindings/pci/brcm,stb-pcie.yaml index 807694b4f41f..f90557f6deb8 100644 --- a/Documentation/devicetree/bindings/pci/brcm,stb-pcie.yaml +++ b/Documentation/devicetree/bindings/pci/brcm,stb-pcie.yaml @@ -14,6 +14,7 @@ properties: items: - enum: - brcm,bcm2711-pcie # The Raspberry Pi 4 + - brcm,bcm4908-pcie - brcm,bcm7211-pcie # Broadcom STB version of RPi4 - brcm,bcm7278-pcie # Broadcom 7278 Arm - brcm,bcm7216-pcie # Broadcom 7216 Arm @@ -63,15 +64,6 @@ properties: aspm-no-l0s: true - resets: - description: for "brcm,bcm7216-pcie", must be a valid reset - phandle pointing to the RESCAL reset controller provider node. - $ref: "/schemas/types.yaml#/definitions/phandle" - - reset-names: - items: - - const: rescal - brcm,scb-sizes: description: u64 giving the 64bit PCIe memory viewport size of a memory controller. There may be up to @@ -98,12 +90,39 @@ required: allOf: - $ref: /schemas/pci/pci-bus.yaml# + - if: + properties: + compatible: + contains: + const: brcm,bcm4908-pcie + then: + properties: + resets: + items: + - description: reset controller handling the PERST# signal + + reset-names: + items: + - const: perst + + required: + - resets + - reset-names - if: properties: compatible: contains: const: brcm,bcm7216-pcie then: + properties: + resets: + items: + - description: phandle pointing to the RESCAL reset controller + + reset-names: + items: + - const: rescal + required: - resets - reset-names -- cgit v1.2.3 From 1c17cc47d764c802c4fa74b46e29fa515ea7acc7 Mon Sep 17 00:00:00 2001 From: Manivannan Sadhasivam Date: Mon, 18 Jan 2021 10:39:59 +0530 Subject: dt-bindings: usb: qcom,dwc3: Add binding for SDX55 Add devicetree binding for SDX55 USB controller based on Qcom designware IP. Cc: Rob Herring Cc: devicetree@vger.kernel.org Cc: linux-usb@vger.kernel.org Acked-by: Felipe Balbi Signed-off-by: Manivannan Sadhasivam Link: https://lore.kernel.org/r/20210118051005.55958-2-manivannan.sadhasivam@linaro.org Signed-off-by: Greg Kroah-Hartman --- Documentation/devicetree/bindings/usb/qcom,dwc3.yaml | 1 + 1 file changed, 1 insertion(+) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/usb/qcom,dwc3.yaml b/Documentation/devicetree/bindings/usb/qcom,dwc3.yaml index b336662e838c..dd1d8bcd9254 100644 --- a/Documentation/devicetree/bindings/usb/qcom,dwc3.yaml +++ b/Documentation/devicetree/bindings/usb/qcom,dwc3.yaml @@ -17,6 +17,7 @@ properties: - qcom,msm8998-dwc3 - qcom,sc7180-dwc3 - qcom,sdm845-dwc3 + - qcom,sdx55-dwc3 - const: qcom,dwc3 reg: -- cgit v1.2.3 From 9e0f86fdcdab6a0e183ad4ec2410453985b4cf3c Mon Sep 17 00:00:00 2001 From: Sameer Pujar Date: Tue, 19 Jan 2021 14:58:11 +0530 Subject: ASoC: dt-bindings: tegra: Add graph bindings Add device tree binding properties of generic graph to ASoC component devices. This allows to define audio ports out of these components or DAIs and audio graph based sound card can be realised with this. Signed-off-by: Sameer Pujar Reviewed-by: Jon Hunter Link: https://lore.kernel.org/r/1611048496-24650-2-git-send-email-spujar@nvidia.com Signed-off-by: Mark Brown --- .../bindings/sound/nvidia,tegra186-dspk.yaml | 18 +++++++++++++++++- .../bindings/sound/nvidia,tegra210-admaif.yaml | 13 ++++++++++++- .../bindings/sound/nvidia,tegra210-ahub.yaml | 13 +++++++++++-- .../bindings/sound/nvidia,tegra210-dmic.yaml | 18 +++++++++++++++++- .../devicetree/bindings/sound/nvidia,tegra210-i2s.yaml | 18 +++++++++++++++++- 5 files changed, 74 insertions(+), 6 deletions(-) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/sound/nvidia,tegra186-dspk.yaml b/Documentation/devicetree/bindings/sound/nvidia,tegra186-dspk.yaml index ed2fb32fcdd4..b8645d9c38ac 100644 --- a/Documentation/devicetree/bindings/sound/nvidia,tegra186-dspk.yaml +++ b/Documentation/devicetree/bindings/sound/nvidia,tegra186-dspk.yaml @@ -17,6 +17,9 @@ maintainers: - Jon Hunter - Sameer Pujar +allOf: + - $ref: audio-graph-port.yaml# + properties: $nodename: pattern: "^dspk@[0-9a-f]*$" @@ -55,6 +58,19 @@ properties: The name can be "DSPK1" or "DSPKx", where x depends on the maximum available instances on a Tegra SoC. + ports: + type: object + properties: + port@0: + description: | + DSPK ACIF (Audio Client Interface) port connected to the + corresponding AHUB (Audio Hub) ACIF port. + + port@1: + description: | + DSPK DAP (Digital Audio Port) interface which can be connected + to external audio codec for playback. + required: - compatible - reg @@ -64,7 +80,7 @@ required: - assigned-clock-parents - sound-name-prefix -additionalProperties: false +unevaluatedProperties: false examples: - | diff --git a/Documentation/devicetree/bindings/sound/nvidia,tegra210-admaif.yaml b/Documentation/devicetree/bindings/sound/nvidia,tegra210-admaif.yaml index c028b259e822..7cee7722df41 100644 --- a/Documentation/devicetree/bindings/sound/nvidia,tegra210-admaif.yaml +++ b/Documentation/devicetree/bindings/sound/nvidia,tegra210-admaif.yaml @@ -17,6 +17,9 @@ maintainers: - Jon Hunter - Sameer Pujar +allOf: + - $ref: audio-graph-port.yaml# + properties: $nodename: pattern: "^admaif@[0-9a-f]*$" @@ -37,6 +40,14 @@ properties: dma-names: true + ports: + description: | + Contains list of ACIF (Audio CIF) port nodes for ADMAIF channels. + The number of port nodes depends on the number of ADMAIF channels + that SoC may have. These are interfaced with respective ACIF ports + in AHUB (Audio Hub). Each port is capable of data transfers in + both directions. + if: properties: compatible: @@ -81,7 +92,7 @@ required: - dmas - dma-names -additionalProperties: false +unevaluatedProperties: false examples: - | diff --git a/Documentation/devicetree/bindings/sound/nvidia,tegra210-ahub.yaml b/Documentation/devicetree/bindings/sound/nvidia,tegra210-ahub.yaml index d77219727768..31f3e51974bb 100644 --- a/Documentation/devicetree/bindings/sound/nvidia,tegra210-ahub.yaml +++ b/Documentation/devicetree/bindings/sound/nvidia,tegra210-ahub.yaml @@ -17,6 +17,9 @@ maintainers: - Jon Hunter - Sameer Pujar +allOf: + - $ref: audio-graph-port.yaml# + properties: $nodename: pattern: "^ahub@[0-9a-f]*$" @@ -56,6 +59,13 @@ properties: ranges: true + ports: + description: | + Contains list of ACIF (Audio CIF) port nodes for AHUB (Audio Hub). + These are connected to ACIF interfaces of AHUB clients. Thus the + number of port nodes depend on the number of clients that AHUB may + have depending on the SoC revision. + required: - compatible - reg @@ -67,8 +77,7 @@ required: - "#size-cells" - ranges -additionalProperties: - type: object +unevaluatedProperties: false examples: - | diff --git a/Documentation/devicetree/bindings/sound/nvidia,tegra210-dmic.yaml b/Documentation/devicetree/bindings/sound/nvidia,tegra210-dmic.yaml index 2a3207b550e7..89f4f471be24 100644 --- a/Documentation/devicetree/bindings/sound/nvidia,tegra210-dmic.yaml +++ b/Documentation/devicetree/bindings/sound/nvidia,tegra210-dmic.yaml @@ -16,6 +16,9 @@ maintainers: - Jon Hunter - Sameer Pujar +allOf: + - $ref: audio-graph-port.yaml# + properties: $nodename: pattern: "^dmic@[0-9a-f]*$" @@ -56,6 +59,19 @@ properties: The name can be "DMIC1" or "DMIC2" ... "DMICx", where x depends on the maximum available instances on a Tegra SoC. + ports: + type: object + properties: + port@0: + description: | + DMIC ACIF (Audio Client Interface) port connected to the + corresponding AHUB (Audio Hub) ACIF port. + + port@1: + description: | + DMIC DAP (Digital Audio Port) interface which can be connected + to external audio codec for capture. + required: - compatible - reg @@ -64,7 +80,7 @@ required: - assigned-clocks - assigned-clock-parents -additionalProperties: false +unevaluatedProperties: false examples: - | diff --git a/Documentation/devicetree/bindings/sound/nvidia,tegra210-i2s.yaml b/Documentation/devicetree/bindings/sound/nvidia,tegra210-i2s.yaml index dfc1bf7b7722..556460332ffb 100644 --- a/Documentation/devicetree/bindings/sound/nvidia,tegra210-i2s.yaml +++ b/Documentation/devicetree/bindings/sound/nvidia,tegra210-i2s.yaml @@ -16,6 +16,9 @@ maintainers: - Jon Hunter - Sameer Pujar +allOf: + - $ref: audio-graph-port.yaml# + properties: $nodename: pattern: "^i2s@[0-9a-f]*$" @@ -74,6 +77,19 @@ properties: The name can be "I2S1" or "I2S2" ... "I2Sx", where x depends on the maximum available instances on a Tegra SoC. + ports: + type: object + properties: + port@0: + description: | + I2S ACIF (Audio Client Interface) port connected to the + corresponding AHUB (Audio Hub) ACIF port. + + port@1: + description: | + I2S DAP (Digital Audio Port) interface which can be connected + to external audio codec for playback or capture. + required: - compatible - reg @@ -82,7 +98,7 @@ required: - assigned-clocks - assigned-clock-parents -additionalProperties: false +unevaluatedProperties: false examples: - | -- cgit v1.2.3 From a9f22c03a8ac5d21ce7a9b9307d9654c963a1f9c Mon Sep 17 00:00:00 2001 From: Sameer Pujar Date: Tue, 19 Jan 2021 14:58:12 +0530 Subject: ASoC: dt-bindings: tegra: Add json-schema for Tegra audio graph card Add YAML schema for Tegra audio graph sound card DT bindings. It uses the same DT bindings provided by generic audio graph driver. Along with this few standard clock DT bindings are added which are specifically required for Tegra audio. Signed-off-by: Sameer Pujar Reviewed-by: Jon Hunter Link: https://lore.kernel.org/r/1611048496-24650-3-git-send-email-spujar@nvidia.com Signed-off-by: Mark Brown --- .../sound/nvidia,tegra-audio-graph-card.yaml | 187 +++++++++++++++++++++ 1 file changed, 187 insertions(+) create mode 100644 Documentation/devicetree/bindings/sound/nvidia,tegra-audio-graph-card.yaml (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/sound/nvidia,tegra-audio-graph-card.yaml b/Documentation/devicetree/bindings/sound/nvidia,tegra-audio-graph-card.yaml new file mode 100644 index 000000000000..fc271f644aaf --- /dev/null +++ b/Documentation/devicetree/bindings/sound/nvidia,tegra-audio-graph-card.yaml @@ -0,0 +1,187 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/sound/nvidia,tegra-audio-graph-card.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Audio Graph based Tegra sound card driver + +description: | + This is based on generic audio graph card driver along with additional + customizations for Tegra platforms. It uses the same bindings with + additional standard clock DT bindings required for Tegra. + +maintainers: + - Jon Hunter + - Sameer Pujar + +allOf: + - $ref: audio-graph.yaml# + +properties: + compatible: + enum: + - nvidia,tegra210-audio-graph-card + - nvidia,tegra186-audio-graph-card + + clocks: + minItems: 2 + + clock-names: + minItems: 2 + items: + - const: pll_a + - const: plla_out0 + + assigned-clocks: + minItems: 1 + maxItems: 3 + + assigned-clock-parents: + minItems: 1 + maxItems: 3 + + assigned-clock-rates: + minItems: 1 + maxItems: 3 + +required: + - clocks + - clock-names + - assigned-clocks + - assigned-clock-parents + +unevaluatedProperties: false + +examples: + - | + #include + + tegra_sound { + compatible = "nvidia,tegra210-audio-graph-card"; + + clocks = <&tegra_car TEGRA210_CLK_PLL_A>, + <&tegra_car TEGRA210_CLK_PLL_A_OUT0>; + clock-names = "pll_a", "plla_out0"; + + assigned-clocks = <&tegra_car TEGRA210_CLK_PLL_A>, + <&tegra_car TEGRA210_CLK_PLL_A_OUT0>, + <&tegra_car TEGRA210_CLK_EXTERN1>; + assigned-clock-parents = <0>, <0>, <&tegra_car TEGRA210_CLK_PLL_A_OUT0>; + assigned-clock-rates = <368640000>, <49152000>, <12288000>; + + dais = /* FE */ + <&admaif1_port>, + /* Router */ + <&xbar_i2s1_port>, + /* I/O DAP Ports */ + <&i2s1_port>; + + label = "jetson-tx1-ape"; + }; + + // The ports are defined for AHUB and its child devices. + ahub@702d0800 { + compatible = "nvidia,tegra210-ahub"; + reg = <0x702d0800 0x800>; + clocks = <&tegra_car TEGRA210_CLK_D_AUDIO>; + clock-names = "ahub"; + assigned-clocks = <&tegra_car TEGRA210_CLK_D_AUDIO>; + assigned-clock-parents = <&tegra_car TEGRA210_CLK_PLL_A_OUT0>; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0x702d0000 0x702d0000 0x0000e400>; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0x0>; + xbar_admaif1_ep: endpoint { + remote-endpoint = <&admaif1_ep>; + }; + }; + + // ... + + xbar_i2s1_port: port@a { + reg = <0xa>; + xbar_i2s1_ep: endpoint { + remote-endpoint = <&i2s1_cif_ep>; + }; + }; + }; + + admaif@702d0000 { + compatible = "nvidia,tegra210-admaif"; + reg = <0x702d0000 0x800>; + dmas = <&adma 1>, <&adma 1>, + <&adma 2>, <&adma 2>, + <&adma 3>, <&adma 3>, + <&adma 4>, <&adma 4>, + <&adma 5>, <&adma 5>, + <&adma 6>, <&adma 6>, + <&adma 7>, <&adma 7>, + <&adma 8>, <&adma 8>, + <&adma 9>, <&adma 9>, + <&adma 10>, <&adma 10>; + dma-names = "rx1", "tx1", + "rx2", "tx2", + "rx3", "tx3", + "rx4", "tx4", + "rx5", "tx5", + "rx6", "tx6", + "rx7", "tx7", + "rx8", "tx8", + "rx9", "tx9", + "rx10", "tx10"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + admaif1_port: port@0 { + reg = <0x0>; + admaif1_ep: endpoint { + remote-endpoint = <&xbar_admaif1_ep>; + }; + }; + + // More ADMAIF ports to follow + }; + }; + + i2s@702d1000 { + compatible = "nvidia,tegra210-i2s"; + clocks = <&tegra_car TEGRA210_CLK_I2S0>; + clock-names = "i2s"; + assigned-clocks = <&tegra_car TEGRA210_CLK_I2S0>; + assigned-clock-parents = <&tegra_car TEGRA210_CLK_PLL_A_OUT0>; + assigned-clock-rates = <1536000>; + reg = <0x702d1000 0x100>; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0x0>; + + i2s1_cif_ep: endpoint { + remote-endpoint = <&xbar_i2s1_ep>; + }; + }; + + i2s1_port: port@1 { + reg = <0x1>; + + i2s1_dap: endpoint { + dai-format = "i2s"; + }; + }; + }; + }; + }; + +... -- cgit v1.2.3 From c149ced37667da5c0ca32c7ca67b9fe38fa07562 Mon Sep 17 00:00:00 2001 From: Jack Pham Date: Fri, 15 Jan 2021 09:47:20 -0800 Subject: dt-bindings: phy: qcom,qmp: Add SM8150, SM8250 and SM8350 USB PHY bindings Add the compatible strings for the USB3 PHYs found on SM8150, SM8250 and SM8350 SoCs. These require separate subschemas due to the different required clock entries. Note the SM8150 and SM8250 compatibles have already been in place in the dts as well as the driver implementation but were missing from the documentation. Signed-off-by: Jack Pham Reviewed-by: Bjorn Andersson Link: https://lore.kernel.org/r/20210115174723.7424-2-jackp@codeaurora.org Signed-off-by: Vinod Koul --- .../devicetree/bindings/phy/qcom,qmp-phy.yaml | 67 ++++++++++++++++++++++ 1 file changed, 67 insertions(+) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/phy/qcom,qmp-phy.yaml b/Documentation/devicetree/bindings/phy/qcom,qmp-phy.yaml index 0f00d82461fd..f578677886c4 100644 --- a/Documentation/devicetree/bindings/phy/qcom,qmp-phy.yaml +++ b/Documentation/devicetree/bindings/phy/qcom,qmp-phy.yaml @@ -30,15 +30,24 @@ properties: - qcom,sdm845-qmp-ufs-phy - qcom,sdm845-qmp-usb3-uni-phy - qcom,sm8150-qmp-ufs-phy + - qcom,sm8150-qmp-usb3-phy + - qcom,sm8150-qmp-usb3-uni-phy - qcom,sm8250-qmp-ufs-phy - qcom,sm8250-qmp-gen3x1-pcie-phy - qcom,sm8250-qmp-gen3x2-pcie-phy - qcom,sm8250-qmp-modem-pcie-phy + - qcom,sm8250-qmp-usb3-phy + - qcom,sm8250-qmp-usb3-uni-phy + - qcom,sm8350-qmp-usb3-phy + - qcom,sm8350-qmp-usb3-uni-phy - qcom,sdx55-qmp-usb3-uni-phy reg: + minItems: 1 + maxItems: 2 items: - description: Address and length of PHY's common serdes block. + - description: Address and length of PHY's DP_COM control block. "#clock-cells": enum: [ 1, 2 ] @@ -312,6 +321,64 @@ allOf: reset-names: items: - const: phy + - if: + properties: + compatible: + contains: + enum: + - qcom,sm8150-qmp-usb3-phy + - qcom,sm8150-qmp-usb3-uni-phy + - qcom,sm8250-qmp-usb3-uni-phy + - qcom,sm8350-qmp-usb3-uni-phy + then: + properties: + clocks: + items: + - description: Phy aux clock. + - description: 19.2 MHz ref clk source. + - description: 19.2 MHz ref clk. + - description: Phy common block aux clock. + clock-names: + items: + - const: aux + - const: ref_clk_src + - const: ref + - const: com_aux + resets: + items: + - description: reset of phy block. + - description: phy common block reset. + reset-names: + items: + - const: phy + - const: common + - if: + properties: + compatible: + contains: + enum: + - qcom,sm8250-qmp-usb3-phy + - qcom,sm8350-qmp-usb3-phy + then: + properties: + clocks: + items: + - description: Phy aux clock. + - description: 19.2 MHz ref clk. + - description: Phy common block aux clock. + clock-names: + items: + - const: aux + - const: ref_clk_src + - const: com_aux + resets: + items: + - description: reset of phy block. + - description: phy common block reset. + reset-names: + items: + - const: phy + - const: common examples: - | -- cgit v1.2.3 From fcba632d8148ab3ec19f6c7dd015cca866357d7e Mon Sep 17 00:00:00 2001 From: Jack Pham Date: Fri, 15 Jan 2021 09:47:22 -0800 Subject: dt-bindings: phy: qcom,usb-snps-femto-v2: Add SM8250 and SM8350 bindings Add the compatible strings for the USB2 PHYs found on QCOM SM8250 & SM8350 SoCs. Note that the SM8250 compatible is already in use in the dts and driver implementation but was missing from the documentation. Signed-off-by: Jack Pham Reviewed-by: Bjorn Andersson Link: https://lore.kernel.org/r/20210115174723.7424-4-jackp@codeaurora.org Signed-off-by: Vinod Koul --- Documentation/devicetree/bindings/phy/qcom,usb-snps-femto-v2.yaml | 2 ++ 1 file changed, 2 insertions(+) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/phy/qcom,usb-snps-femto-v2.yaml b/Documentation/devicetree/bindings/phy/qcom,usb-snps-femto-v2.yaml index 4949a2851532..ee77c6458326 100644 --- a/Documentation/devicetree/bindings/phy/qcom,usb-snps-femto-v2.yaml +++ b/Documentation/devicetree/bindings/phy/qcom,usb-snps-femto-v2.yaml @@ -17,6 +17,8 @@ properties: enum: - qcom,usb-snps-hs-7nm-phy - qcom,sm8150-usb-hs-phy + - qcom,sm8250-usb-hs-phy + - qcom,sm8350-usb-hs-phy - qcom,usb-snps-femto-v2-phy reg: -- cgit v1.2.3 From 71edb0b4fa0e3bc248df564ba01a0f7c41607c8e Mon Sep 17 00:00:00 2001 From: AngeloGioacchino Del Regno Date: Thu, 14 Jan 2021 18:47:18 +0100 Subject: dt-bindings: phy: qcom-qusb2: Document SDM660 compatible Support for the SDM630/660 series of SoCs was added to the driver: document the qcom,sdm660-qusb2-phy compatible here. Signed-off-by: AngeloGioacchino Del Regno Reviewed-by: Bjorn Andersson Link: https://lore.kernel.org/r/20210114174718.398638-3-angelogioacchino.delregno@somainline.org Signed-off-by: Vinod Koul --- Documentation/devicetree/bindings/phy/qcom,qusb2-phy.yaml | 1 + 1 file changed, 1 insertion(+) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/phy/qcom,qusb2-phy.yaml b/Documentation/devicetree/bindings/phy/qcom,qusb2-phy.yaml index d457fb6a4779..582abbbd8b32 100644 --- a/Documentation/devicetree/bindings/phy/qcom,qusb2-phy.yaml +++ b/Documentation/devicetree/bindings/phy/qcom,qusb2-phy.yaml @@ -21,6 +21,7 @@ properties: - qcom,ipq8074-qusb2-phy - qcom,msm8996-qusb2-phy - qcom,msm8998-qusb2-phy + - qcom,sdm660-qusb2-phy - items: - enum: - qcom,sc7180-qusb2-phy -- cgit v1.2.3 From 74bdd45c85d02f695a1cd1c3dccf8b3960a86d8f Mon Sep 17 00:00:00 2001 From: Odin Ugedal Date: Sat, 16 Jan 2021 18:36:34 +0100 Subject: cgroup: update PSI file description in docs Update PSI file description in cgroup-v2 docs to reflect the current implementation. tj: Changed cpu.pressure from read-only to read-write as suggested by Johannes. Signed-off-by: Odin Ugedal Acked-by: Dan Schatzberg Acked-by: Johannes Weiner Signed-off-by: Tejun Heo --- Documentation/admin-guide/cgroup-v2.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'Documentation') diff --git a/Documentation/admin-guide/cgroup-v2.rst b/Documentation/admin-guide/cgroup-v2.rst index 63521cd36ce5..1de8695c264b 100644 --- a/Documentation/admin-guide/cgroup-v2.rst +++ b/Documentation/admin-guide/cgroup-v2.rst @@ -1029,7 +1029,7 @@ All time durations are in microseconds. one number is written, $MAX is updated. cpu.pressure - A read-only nested-key file which exists on non-root cgroups. + A read-write nested-keyed file. Shows pressure stall information for CPU. See :ref:`Documentation/accounting/psi.rst ` for details. @@ -1475,7 +1475,7 @@ PAGE_SIZE multiple when read back. reduces the impact on the workload and memory management. memory.pressure - A read-only nested-key file which exists on non-root cgroups. + A read-only nested-keyed file. Shows pressure stall information for memory. See :ref:`Documentation/accounting/psi.rst ` for details. @@ -1714,7 +1714,7 @@ IO Interface Files 8:16 rbps=2097152 wbps=max riops=max wiops=max io.pressure - A read-only nested-key file which exists on non-root cgroups. + A read-only nested-keyed file. Shows pressure stall information for IO. See :ref:`Documentation/accounting/psi.rst ` for details. -- cgit v1.2.3 From 7a79f1f7f7e75e532c5a803ab3ebf42a3e79497c Mon Sep 17 00:00:00 2001 From: Jack Pham Date: Tue, 19 Jan 2021 09:37:48 -0800 Subject: dt-bindings: usb: qcom,dwc3: Add bindings for SM8150, SM8250, SM8350 Add compatible strings for the USB DWC3 controller on QCOM SM8150, SM8250 and SM8350 SoCs. Note the SM8150 & SM8250 compatibles are already being used in the dts but was missing from the documentation. Acked-by: Felipe Balbi Signed-off-by: Jack Pham Link: https://lore.kernel.org/r/20210119173748.6729-1-jackp@codeaurora.org Signed-off-by: Greg Kroah-Hartman --- Documentation/devicetree/bindings/usb/qcom,dwc3.yaml | 3 +++ 1 file changed, 3 insertions(+) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/usb/qcom,dwc3.yaml b/Documentation/devicetree/bindings/usb/qcom,dwc3.yaml index dd1d8bcd9254..c3cbd1fa9944 100644 --- a/Documentation/devicetree/bindings/usb/qcom,dwc3.yaml +++ b/Documentation/devicetree/bindings/usb/qcom,dwc3.yaml @@ -18,6 +18,9 @@ properties: - qcom,sc7180-dwc3 - qcom,sdm845-dwc3 - qcom,sdx55-dwc3 + - qcom,sm8150-dwc3 + - qcom,sm8250-dwc3 + - qcom,sm8350-dwc3 - const: qcom,dwc3 reg: -- cgit v1.2.3 From a7d6ba14efb778fc8c65c627a057d5dd29debd04 Mon Sep 17 00:00:00 2001 From: Daniel Lezcano Date: Tue, 15 Dec 2020 00:38:04 +0100 Subject: thermal/core: Remove the 'forced_passive' option The code was reorganized in 2012 with the commit 0c01ebbfd3caf1. The main change is a loop on the trip points array and a unconditional call to the throttle() ops of the governors for each of them even if the trip temperature is not reached yet. With this change, the 'forced_passive' is no longer checked in the thermal_zone_device_update() function but in the step wise governor's throttle() callback. As the force_passive does no belong to the trip point array, the thermal_zone_device_update() can not compare with the specified passive temperature, thus does not detect the passive limit has been crossed. Consequently, throttle() is never called and the 'forced_passive' branch is unreached. In addition, the default processor cooling device is not automatically bound to the thermal zone if there is not passive trip point, thus the 'forced_passive' can not operate. If there is an active trip point, then the throttle function will be called to mitigate at this temperature and the 'forced_passive' will override the mitigation of the active trip point in this case but with the default cooling device bound to the thermal zone, so usually a fan, and that is not a passive cooling effect. Given the regression exists since more than 8 years, nobody complained and at the best of my knowledge there is no bug open in https://bugzilla.kernel.org, it is reasonable to say it is unused. Remove the 'forced_passive' related code. Signed-off-by: Daniel Lezcano Reviewed-by: Thara Gopinath Link: https://lore.kernel.org/r/20201214233811.485669-1-daniel.lezcano@linaro.org --- Documentation/driver-api/thermal/sysfs-api.rst | 13 ----- drivers/thermal/gov_step_wise.c | 14 +---- drivers/thermal/thermal_sysfs.c | 80 -------------------------- include/linux/thermal.h | 4 -- 4 files changed, 3 insertions(+), 108 deletions(-) (limited to 'Documentation') diff --git a/Documentation/driver-api/thermal/sysfs-api.rst b/Documentation/driver-api/thermal/sysfs-api.rst index e7520cb439ac..a4969c474cc3 100644 --- a/Documentation/driver-api/thermal/sysfs-api.rst +++ b/Documentation/driver-api/thermal/sysfs-api.rst @@ -520,19 +520,6 @@ available_policies RW, Optional -passive - Attribute is only present for zones in which the passive cooling - policy is not supported by native thermal driver. Default is zero - and can be set to a temperature (in millidegrees) to enable a - passive trip point for the zone. Activation is done by polling with - an interval of 1 second. - - Unit: millidegrees Celsius - - Valid values: 0 (disabled) or greater than 1000 - - RW, Optional - emul_temp Interface to set the emulated temperature method in thermal zone (sensor). After setting this temperature, the thermal zone may pass diff --git a/drivers/thermal/gov_step_wise.c b/drivers/thermal/gov_step_wise.c index 2ae7198d3067..12acb12aac50 100644 --- a/drivers/thermal/gov_step_wise.c +++ b/drivers/thermal/gov_step_wise.c @@ -109,7 +109,7 @@ static void update_passive_instance(struct thermal_zone_device *tz, * If value is +1, activate a passive instance. * If value is -1, deactivate a passive instance. */ - if (type == THERMAL_TRIP_PASSIVE || type == THERMAL_TRIPS_NONE) + if (type == THERMAL_TRIP_PASSIVE) tz->passive += value; } @@ -122,13 +122,8 @@ static void thermal_zone_trip_update(struct thermal_zone_device *tz, int trip) bool throttle = false; int old_target; - if (trip == THERMAL_TRIPS_NONE) { - trip_temp = tz->forced_passive; - trip_type = THERMAL_TRIPS_NONE; - } else { - tz->ops->get_trip_temp(tz, trip, &trip_temp); - tz->ops->get_trip_type(tz, trip, &trip_type); - } + tz->ops->get_trip_temp(tz, trip, &trip_temp); + tz->ops->get_trip_type(tz, trip, &trip_type); trend = get_tz_trend(tz, trip); @@ -189,9 +184,6 @@ static int step_wise_throttle(struct thermal_zone_device *tz, int trip) thermal_zone_trip_update(tz, trip); - if (tz->forced_passive) - thermal_zone_trip_update(tz, THERMAL_TRIPS_NONE); - mutex_lock(&tz->lock); list_for_each_entry(instance, &tz->thermal_instances, tz_node) diff --git a/drivers/thermal/thermal_sysfs.c b/drivers/thermal/thermal_sysfs.c index 0866e949339b..4e7f9e880d76 100644 --- a/drivers/thermal/thermal_sysfs.c +++ b/drivers/thermal/thermal_sysfs.c @@ -216,49 +216,6 @@ trip_point_hyst_show(struct device *dev, struct device_attribute *attr, return ret ? ret : sprintf(buf, "%d\n", temperature); } -static ssize_t -passive_store(struct device *dev, struct device_attribute *attr, - const char *buf, size_t count) -{ - struct thermal_zone_device *tz = to_thermal_zone(dev); - int state; - - if (sscanf(buf, "%d\n", &state) != 1) - return -EINVAL; - - /* sanity check: values below 1000 millicelcius don't make sense - * and can cause the system to go into a thermal heart attack - */ - if (state && state < 1000) - return -EINVAL; - - if (state && !tz->forced_passive) { - if (!tz->passive_delay) - tz->passive_delay = 1000; - thermal_zone_device_rebind_exception(tz, "Processor", - sizeof("Processor")); - } else if (!state && tz->forced_passive) { - tz->passive_delay = 0; - thermal_zone_device_unbind_exception(tz, "Processor", - sizeof("Processor")); - } - - tz->forced_passive = state; - - thermal_zone_device_update(tz, THERMAL_EVENT_UNSPECIFIED); - - return count; -} - -static ssize_t -passive_show(struct device *dev, struct device_attribute *attr, - char *buf) -{ - struct thermal_zone_device *tz = to_thermal_zone(dev); - - return sprintf(buf, "%d\n", tz->forced_passive); -} - static ssize_t policy_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) @@ -403,7 +360,6 @@ static DEVICE_ATTR_RW(sustainable_power); /* These thermal zone device attributes are created based on conditions */ static DEVICE_ATTR_RW(mode); -static DEVICE_ATTR_RW(passive); /* These attributes are unconditionally added to a thermal zone */ static struct attribute *thermal_zone_dev_attrs[] = { @@ -438,45 +394,9 @@ static const struct attribute_group thermal_zone_mode_attribute_group = { .attrs = thermal_zone_mode_attrs, }; -/* We expose passive only if passive trips are present */ -static struct attribute *thermal_zone_passive_attrs[] = { - &dev_attr_passive.attr, - NULL, -}; - -static umode_t thermal_zone_passive_is_visible(struct kobject *kobj, - struct attribute *attr, - int attrno) -{ - struct device *dev = kobj_to_dev(kobj); - struct thermal_zone_device *tz; - enum thermal_trip_type trip_type; - int count, passive = 0; - - tz = container_of(dev, struct thermal_zone_device, device); - - for (count = 0; count < tz->trips && !passive; count++) { - tz->ops->get_trip_type(tz, count, &trip_type); - - if (trip_type == THERMAL_TRIP_PASSIVE) - passive = 1; - } - - if (!passive) - return attr->mode; - - return 0; -} - -static const struct attribute_group thermal_zone_passive_attribute_group = { - .attrs = thermal_zone_passive_attrs, - .is_visible = thermal_zone_passive_is_visible, -}; - static const struct attribute_group *thermal_zone_attribute_groups[] = { &thermal_zone_attribute_group, &thermal_zone_mode_attribute_group, - &thermal_zone_passive_attribute_group, /* This is not NULL terminated as we create the group dynamically */ }; diff --git a/include/linux/thermal.h b/include/linux/thermal.h index c80032322158..a57232a9a6f9 100644 --- a/include/linux/thermal.h +++ b/include/linux/thermal.h @@ -131,9 +131,6 @@ struct thermal_cooling_device { trip point. * @prev_high_trip: the above current temperature if you've crossed a passive trip point. - * @forced_passive: If > 0, temperature at which to switch on all ACPI - * processor cooling devices. Currently only used by the - * step-wise governor. * @need_update: if equals 1, thermal_zone_device_update needs to be invoked. * @ops: operations this &thermal_zone_device supports * @tzp: thermal zone parameters @@ -167,7 +164,6 @@ struct thermal_zone_device { int passive; int prev_low_trip; int prev_high_trip; - unsigned int forced_passive; atomic_t need_update; struct thermal_zone_device_ops *ops; struct thermal_zone_params *tzp; -- cgit v1.2.3 From b3228c74e0d24976604e8550e9cccb83135f5302 Mon Sep 17 00:00:00 2001 From: Grygorii Strashko Date: Fri, 15 Jan 2021 21:28:48 +0200 Subject: dt-binding: ti: am65x-cpts: add assigned-clock and power-domains props The CPTS clock is usually a clk-mux which allows to select CPTS reference clock by using 'assigned-clock-parents', 'assigned-clocks' DT properties. Also depending on integration the power-domains has to be specified to enable CPTS IP. Hence add 'assigned-clock-parents', 'assigned-clocks' and 'power-domains' properties to the CPTS DT bindings to avoid dtbs_check warnings: cpts@310d0000: 'assigned-clock-parents', 'assigned-clocks' do not match any of the regexes: 'pinctrl-[0-9]+' cpts@310d0000: 'power-domains' does not match any of the regexes: 'pinctrl-[0-9]+' Signed-off-by: Grygorii Strashko Signed-off-by: Jakub Kicinski --- Documentation/devicetree/bindings/net/ti,k3-am654-cpts.yaml | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/net/ti,k3-am654-cpts.yaml b/Documentation/devicetree/bindings/net/ti,k3-am654-cpts.yaml index 9b7117920d90..ce43a1c58a57 100644 --- a/Documentation/devicetree/bindings/net/ti,k3-am654-cpts.yaml +++ b/Documentation/devicetree/bindings/net/ti,k3-am654-cpts.yaml @@ -73,6 +73,13 @@ properties: items: - const: cpts + assigned-clock-parents: true + + assigned-clocks: true + + power-domains: + maxItems: 1 + ti,cpts-ext-ts-inputs: $ref: /schemas/types.yaml#/definitions/uint32 maximum: 8 -- cgit v1.2.3 From 19d9a846d9fcdfd30b1500339e09ec8dc898feea Mon Sep 17 00:00:00 2001 From: Grygorii Strashko Date: Fri, 15 Jan 2021 21:28:49 +0200 Subject: dt-binding: net: ti: k3-am654-cpsw-nuss: update bindings for am64x cpsw3g Update DT binding for recently introduced TI K3 AM642x SoC [1] which contains 3 port (2 external ports) CPSW3g module. The CPSW3g integrated in MAIN domain and can be configured in multi port or switch modes. The overall functionality and DT bindings are similar to other K3 CPSWxg versions, so DT binding changes are minimal: - reword description - add new compatible 'ti,am642-cpsw-nuss' - allow 2 external ports child nodes - add missed 'assigned-clock' props [1] https://www.ti.com/lit/pdf/spruim2 Signed-off-by: Grygorii Strashko Signed-off-by: Jakub Kicinski --- .../bindings/net/ti,k3-am654-cpsw-nuss.yaml | 50 +++++++++++++--------- 1 file changed, 30 insertions(+), 20 deletions(-) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/net/ti,k3-am654-cpsw-nuss.yaml b/Documentation/devicetree/bindings/net/ti,k3-am654-cpsw-nuss.yaml index c47b58f3e3f6..3fae9a5f0c6a 100644 --- a/Documentation/devicetree/bindings/net/ti,k3-am654-cpsw-nuss.yaml +++ b/Documentation/devicetree/bindings/net/ti,k3-am654-cpsw-nuss.yaml @@ -4,7 +4,7 @@ $id: http://devicetree.org/schemas/net/ti,k3-am654-cpsw-nuss.yaml# $schema: http://devicetree.org/meta-schemas/core.yaml# -title: The TI AM654x/J721E SoC Gigabit Ethernet MAC (Media Access Controller) Device Tree Bindings +title: The TI AM654x/J721E/AM642x SoC Gigabit Ethernet MAC (Media Access Controller) Device Tree Bindings maintainers: - Grygorii Strashko @@ -13,19 +13,16 @@ maintainers: description: The TI AM654x/J721E SoC Gigabit Ethernet MAC (CPSW2G NUSS) has two ports (one external) and provides Ethernet packet communication for the device. - CPSW2G NUSS features - the Reduced Gigabit Media Independent Interface (RGMII), - Reduced Media Independent Interface (RMII), the Management Data - Input/Output (MDIO) interface for physical layer device (PHY) management, - new version of Common Platform Time Sync (CPTS), updated Address Lookup - Engine (ALE). - One external Ethernet port (port 1) with selectable RGMII/RMII interfaces and - an internal Communications Port Programming Interface (CPPI5) (Host port 0). + The TI AM642x SoC Gigabit Ethernet MAC (CPSW3G NUSS) has three ports + (two external) and provides Ethernet packet communication and switching. + + The internal Communications Port Programming Interface (CPPI5) (Host port 0). Host Port 0 CPPI Packet Streaming Interface interface supports 8 TX channels - and one RX channels and operating by TI AM654x/J721E NAVSS Unified DMA - Peripheral Root Complex (UDMA-P) controller. - The CPSW2G NUSS is integrated into device MCU domain named MCU_CPSW0. + and one RX channels and operating by NAVSS Unified DMA Peripheral Root + Complex (UDMA-P) controller. - Additional features + CPSWxG features + updated Address Lookup Engine (ALE). priority level Quality Of Service (QOS) support (802.1p) Support for Audio/Video Bridging (P802.1Qav/D6.0) Support for IEEE 1588 Clock Synchronization (2008 Annex D, Annex E and Annex F) @@ -38,10 +35,18 @@ description: VLAN support, 802.1Q compliant, Auto add port VLAN for untagged frames on ingress, Auto VLAN removal on egress and auto pad to minimum frame size. RX/TX csum offload + Management Data Input/Output (MDIO) interface for PHYs management + RMII/RGMII Interfaces support + new version of Common Platform Time Sync (CPTS) + + The CPSWxG NUSS is integrated into + device MCU domain named MCU_CPSW0 on AM654x/J721E SoC. + device MAIN domain named CPSW0 on AM642x SoC. Specifications can be found at - http://www.ti.com/lit/ug/spruid7e/spruid7e.pdf - http://www.ti.com/lit/ug/spruil1a/spruil1a.pdf + https://www.ti.com/lit/pdf/spruid7 + https://www.ti.com/lit/zip/spruil1 + https://www.ti.com/lit/pdf/spruim2 properties: "#address-cells": true @@ -51,11 +56,12 @@ properties: oneOf: - const: ti,am654-cpsw-nuss - const: ti,j721e-cpsw-nuss + - const: ti,am642-cpsw-nuss reg: maxItems: 1 description: - The physical base address and size of full the CPSW2G NUSS IO range + The physical base address and size of full the CPSWxG NUSS IO range reg-names: items: @@ -66,12 +72,16 @@ properties: dma-coherent: true clocks: - description: CPSW2G NUSS functional clock + description: CPSWxG NUSS functional clock clock-names: items: - const: fck + assigned-clock-parents: true + + assigned-clocks: true + power-domains: maxItems: 1 @@ -99,16 +109,16 @@ properties: const: 0 patternProperties: - port@1: + port@[1-2]: type: object - description: CPSW2G NUSS external ports + description: CPSWxG NUSS external ports $ref: ethernet-controller.yaml# properties: reg: - items: - - const: 1 + minimum: 1 + maximum: 2 description: CPSW port number phys: -- cgit v1.2.3 From 7b8fc0103bb51d1d3e1fb5fd67958612e709f883 Mon Sep 17 00:00:00 2001 From: Jarod Wilson Date: Mon, 18 Jan 2021 20:09:27 -0500 Subject: bonding: add a vlan+srcmac tx hashing option This comes from an end-user request, where they're running multiple VMs on hosts with bonded interfaces connected to some interest switch topologies, where 802.3ad isn't an option. They're currently running a proprietary solution that effectively achieves load-balancing of VMs and bandwidth utilization improvements with a similar form of transmission algorithm. Basically, each VM has it's own vlan, so it always sends its traffic out the same interface, unless that interface fails. Traffic gets split between the interfaces, maintaining a consistent path, with failover still available if an interface goes down. Unlike bond_eth_hash(), this hash function is using the full source MAC address instead of just the last byte, as there are so few components to the hash, and in the no-vlan case, we would be returning just the last byte of the source MAC as the hash value. It's entirely possible to have two NICs in a bond with the same last byte of their MAC, but not the same MAC, so this adjustment should guarantee distinct hashes in all cases. This has been rudimetarily tested to provide similar results to the proprietary solution it is aiming to replace. A patch for iproute2 is also posted, to properly support the new mode there as well. Cc: Jay Vosburgh Cc: Veaceslav Falico Cc: Andy Gospodarek Cc: Thomas Davis Signed-off-by: Jarod Wilson Link: https://lore.kernel.org/r/20210119010927.1191922-1-jarod@redhat.com Signed-off-by: Jakub Kicinski --- Documentation/networking/bonding.rst | 13 +++++++++++++ drivers/net/bonding/bond_main.c | 34 ++++++++++++++++++++++++++++++++-- drivers/net/bonding/bond_options.c | 13 +++++++------ include/linux/netdevice.h | 1 + include/uapi/linux/if_bonding.h | 1 + 5 files changed, 54 insertions(+), 8 deletions(-) (limited to 'Documentation') diff --git a/Documentation/networking/bonding.rst b/Documentation/networking/bonding.rst index adc314639085..5f690f0ad0e4 100644 --- a/Documentation/networking/bonding.rst +++ b/Documentation/networking/bonding.rst @@ -951,6 +951,19 @@ xmit_hash_policy packets will be distributed according to the encapsulated flows. + vlan+srcmac + + This policy uses a very rudimentary vlan ID and source mac + hash to load-balance traffic per-vlan, with failover + should one leg fail. The intended use case is for a bond + shared by multiple virtual machines, all configured to + use their own vlan, to give lacp-like functionality + without requiring lacp-capable switching hardware. + + The formula for the hash is simply + + hash = (vlan ID) XOR (source MAC vendor) XOR (source MAC dev) + The default value is layer2. This option was added in bonding version 2.6.3. In earlier versions of bonding, this parameter does not exist, and the layer2 policy is the only policy. The diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index 539c6bc218df..74cbbb22470b 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c @@ -167,7 +167,7 @@ module_param(xmit_hash_policy, charp, 0); MODULE_PARM_DESC(xmit_hash_policy, "balance-alb, balance-tlb, balance-xor, 802.3ad hashing method; " "0 for layer 2 (default), 1 for layer 3+4, " "2 for layer 2+3, 3 for encap layer 2+3, " - "4 for encap layer 3+4"); + "4 for encap layer 3+4, 5 for vlan+srcmac"); module_param(arp_interval, int, 0); MODULE_PARM_DESC(arp_interval, "arp interval in milliseconds"); module_param_array(arp_ip_target, charp, NULL, 0); @@ -1457,6 +1457,8 @@ static enum netdev_lag_hash bond_lag_hash_type(struct bonding *bond, return NETDEV_LAG_HASH_E23; case BOND_XMIT_POLICY_ENCAP34: return NETDEV_LAG_HASH_E34; + case BOND_XMIT_POLICY_VLAN_SRCMAC: + return NETDEV_LAG_HASH_VLAN_SRCMAC; default: return NETDEV_LAG_HASH_UNKNOWN; } @@ -3519,6 +3521,27 @@ static bool bond_flow_ip(struct sk_buff *skb, struct flow_keys *fk, return true; } +static u32 bond_vlan_srcmac_hash(struct sk_buff *skb) +{ + struct ethhdr *mac_hdr = (struct ethhdr *)skb_mac_header(skb); + u32 srcmac_vendor = 0, srcmac_dev = 0; + u16 vlan; + int i; + + for (i = 0; i < 3; i++) + srcmac_vendor = (srcmac_vendor << 8) | mac_hdr->h_source[i]; + + for (i = 3; i < ETH_ALEN; i++) + srcmac_dev = (srcmac_dev << 8) | mac_hdr->h_source[i]; + + if (!skb_vlan_tag_present(skb)) + return srcmac_vendor ^ srcmac_dev; + + vlan = skb_vlan_tag_get(skb); + + return vlan ^ srcmac_vendor ^ srcmac_dev; +} + /* Extract the appropriate headers based on bond's xmit policy */ static bool bond_flow_dissect(struct bonding *bond, struct sk_buff *skb, struct flow_keys *fk) @@ -3526,10 +3549,14 @@ static bool bond_flow_dissect(struct bonding *bond, struct sk_buff *skb, bool l34 = bond->params.xmit_policy == BOND_XMIT_POLICY_LAYER34; int noff, proto = -1; - if (bond->params.xmit_policy > BOND_XMIT_POLICY_LAYER23) { + switch (bond->params.xmit_policy) { + case BOND_XMIT_POLICY_ENCAP23: + case BOND_XMIT_POLICY_ENCAP34: memset(fk, 0, sizeof(*fk)); return __skb_flow_dissect(NULL, skb, &flow_keys_bonding, fk, NULL, 0, 0, 0, 0); + default: + break; } fk->ports.ports = 0; @@ -3591,6 +3618,9 @@ u32 bond_xmit_hash(struct bonding *bond, struct sk_buff *skb) skb->l4_hash) return skb->hash; + if (bond->params.xmit_policy == BOND_XMIT_POLICY_VLAN_SRCMAC) + return bond_vlan_srcmac_hash(skb); + if (bond->params.xmit_policy == BOND_XMIT_POLICY_LAYER2 || !bond_flow_dissect(bond, skb, &flow)) return bond_eth_hash(skb); diff --git a/drivers/net/bonding/bond_options.c b/drivers/net/bonding/bond_options.c index 8fcbf7f9c7b2..77d7c38bd435 100644 --- a/drivers/net/bonding/bond_options.c +++ b/drivers/net/bonding/bond_options.c @@ -96,12 +96,13 @@ static const struct bond_opt_value bond_pps_tbl[] = { }; static const struct bond_opt_value bond_xmit_hashtype_tbl[] = { - { "layer2", BOND_XMIT_POLICY_LAYER2, BOND_VALFLAG_DEFAULT}, - { "layer3+4", BOND_XMIT_POLICY_LAYER34, 0}, - { "layer2+3", BOND_XMIT_POLICY_LAYER23, 0}, - { "encap2+3", BOND_XMIT_POLICY_ENCAP23, 0}, - { "encap3+4", BOND_XMIT_POLICY_ENCAP34, 0}, - { NULL, -1, 0}, + { "layer2", BOND_XMIT_POLICY_LAYER2, BOND_VALFLAG_DEFAULT}, + { "layer3+4", BOND_XMIT_POLICY_LAYER34, 0}, + { "layer2+3", BOND_XMIT_POLICY_LAYER23, 0}, + { "encap2+3", BOND_XMIT_POLICY_ENCAP23, 0}, + { "encap3+4", BOND_XMIT_POLICY_ENCAP34, 0}, + { "vlan+srcmac", BOND_XMIT_POLICY_VLAN_SRCMAC, 0}, + { NULL, -1, 0}, }; static const struct bond_opt_value bond_arp_validate_tbl[] = { diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index 02dcef4d66e2..ef517254367d 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h @@ -2617,6 +2617,7 @@ enum netdev_lag_hash { NETDEV_LAG_HASH_L23, NETDEV_LAG_HASH_E23, NETDEV_LAG_HASH_E34, + NETDEV_LAG_HASH_VLAN_SRCMAC, NETDEV_LAG_HASH_UNKNOWN, }; diff --git a/include/uapi/linux/if_bonding.h b/include/uapi/linux/if_bonding.h index 45f3750aa861..e8eb4ad03cf1 100644 --- a/include/uapi/linux/if_bonding.h +++ b/include/uapi/linux/if_bonding.h @@ -94,6 +94,7 @@ #define BOND_XMIT_POLICY_LAYER23 2 /* layer 2+3 (IP ^ MAC) */ #define BOND_XMIT_POLICY_ENCAP23 3 /* encapsulated layer 2+3 */ #define BOND_XMIT_POLICY_ENCAP34 4 /* encapsulated layer 3+4 */ +#define BOND_XMIT_POLICY_VLAN_SRCMAC 5 /* vlan + source MAC */ /* 802.3ad port state definitions (43.4.2.2 in the 802.3ad standard) */ #define LACP_STATE_LACP_ACTIVITY 0x1 -- cgit v1.2.3 From a579fcfa8e49cc77ad59211bb18bc5004133e6a0 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Mon, 18 Jan 2021 12:45:46 +0100 Subject: c6x: remove architecture The c6x architecture was added to the kernel in 2011 at a time when running Linux on DSPs was widely seen as the logical evolution. It appears the trend has gone back to running Linux on Arm based SoCs with DSP, using a better supported software ecosystem, and having better real-time behavior for the DSP code. An example of this is TI's own Keystone2 platform. The upstream kernel port appears to no longer have any users. Mark Salter remained avaialable to review patches, but mentioned that he no longer has access to working hardware himself. Without any users, it's best to just remove the code completely to reduce the work for cross-architecture code changes. Many thanks to Mark for maintaining the code for the past ten years. Link: https://lore.kernel.org/lkml/41dc7795afda9f776d8cd0d3075f776cf586e97c.camel@redhat.com/ Signed-off-by: Arnd Bergmann --- Documentation/devicetree/bindings/c6x/clocks.txt | 40 -- Documentation/devicetree/bindings/c6x/dscr.txt | 127 ---- Documentation/devicetree/bindings/c6x/emifa.txt | 62 -- Documentation/devicetree/bindings/c6x/soc.txt | 28 - .../interrupt-controller/ti,c64x+megamod-pic.txt | 103 --- .../devicetree/bindings/timer/ti,c64x+timer64.txt | 25 - MAINTAINERS | 8 - arch/c6x/Kconfig | 113 ---- arch/c6x/Kconfig.debug | 10 - arch/c6x/Makefile | 60 -- arch/c6x/boot/Makefile | 11 - arch/c6x/boot/dts/Makefile | 16 - arch/c6x/boot/dts/dsk6455.dts | 57 -- arch/c6x/boot/dts/evmc6457.dts | 43 -- arch/c6x/boot/dts/evmc6472.dts | 68 -- arch/c6x/boot/dts/evmc6474.dts | 53 -- arch/c6x/boot/dts/evmc6678.dts | 78 --- arch/c6x/boot/dts/tms320c6455.dtsi | 97 --- arch/c6x/boot/dts/tms320c6457.dtsi | 69 -- arch/c6x/boot/dts/tms320c6472.dtsi | 135 ---- arch/c6x/boot/dts/tms320c6474.dtsi | 90 --- arch/c6x/boot/dts/tms320c6678.dtsi | 147 ---- arch/c6x/configs/dsk6455_defconfig | 42 -- arch/c6x/configs/evmc6457_defconfig | 39 -- arch/c6x/configs/evmc6472_defconfig | 40 -- arch/c6x/configs/evmc6474_defconfig | 40 -- arch/c6x/configs/evmc6678_defconfig | 40 -- arch/c6x/include/asm/Kbuild | 5 - arch/c6x/include/asm/asm-offsets.h | 1 - arch/c6x/include/asm/bitops.h | 95 --- arch/c6x/include/asm/bug.h | 20 - arch/c6x/include/asm/cache.h | 94 --- arch/c6x/include/asm/cacheflush.h | 45 -- arch/c6x/include/asm/checksum.h | 34 - arch/c6x/include/asm/clock.h | 145 ---- arch/c6x/include/asm/cmpxchg.h | 63 -- arch/c6x/include/asm/delay.h | 64 -- arch/c6x/include/asm/dscr.h | 30 - arch/c6x/include/asm/elf.h | 117 ---- arch/c6x/include/asm/flat.h | 19 - arch/c6x/include/asm/ftrace.h | 6 - arch/c6x/include/asm/hardirq.h | 17 - arch/c6x/include/asm/irq.h | 50 -- arch/c6x/include/asm/irqflags.h | 68 -- arch/c6x/include/asm/linkage.h | 31 - arch/c6x/include/asm/megamod-pic.h | 10 - arch/c6x/include/asm/mmu_context.h | 6 - arch/c6x/include/asm/module.h | 20 - arch/c6x/include/asm/page.h | 9 - arch/c6x/include/asm/pgtable.h | 66 -- arch/c6x/include/asm/processor.h | 114 ---- arch/c6x/include/asm/procinfo.h | 24 - arch/c6x/include/asm/ptrace.h | 32 - arch/c6x/include/asm/sections.h | 12 - arch/c6x/include/asm/setup.h | 31 - arch/c6x/include/asm/soc.h | 35 - arch/c6x/include/asm/special_insns.h | 60 -- arch/c6x/include/asm/string.h | 18 - arch/c6x/include/asm/switch_to.h | 30 - arch/c6x/include/asm/syscall.h | 75 --- arch/c6x/include/asm/syscalls.h | 46 -- arch/c6x/include/asm/thread_info.h | 94 --- arch/c6x/include/asm/timer64.h | 7 - arch/c6x/include/asm/timex.h | 30 - arch/c6x/include/asm/tlb.h | 7 - arch/c6x/include/asm/traps.h | 33 - arch/c6x/include/asm/uaccess.h | 97 --- arch/c6x/include/asm/unaligned.h | 104 --- arch/c6x/include/asm/vmalloc.h | 4 - arch/c6x/include/uapi/asm/Kbuild | 2 - arch/c6x/include/uapi/asm/byteorder.h | 13 - arch/c6x/include/uapi/asm/ptrace.h | 164 ----- arch/c6x/include/uapi/asm/setup.h | 7 - arch/c6x/include/uapi/asm/sigcontext.h | 81 --- arch/c6x/include/uapi/asm/swab.h | 55 -- arch/c6x/include/uapi/asm/unistd.h | 29 - arch/c6x/kernel/Makefile | 13 - arch/c6x/kernel/asm-offsets.c | 123 ---- arch/c6x/kernel/c6x_ksyms.c | 62 -- arch/c6x/kernel/devicetree.c | 14 - arch/c6x/kernel/entry.S | 736 --------------------- arch/c6x/kernel/head.S | 81 --- arch/c6x/kernel/irq.c | 127 ---- arch/c6x/kernel/module.c | 119 ---- arch/c6x/kernel/process.c | 151 ----- arch/c6x/kernel/ptrace.c | 139 ---- arch/c6x/kernel/setup.c | 476 ------------- arch/c6x/kernel/signal.c | 322 --------- arch/c6x/kernel/soc.c | 87 --- arch/c6x/kernel/switch_to.S | 71 -- arch/c6x/kernel/sys_c6x.c | 71 -- arch/c6x/kernel/time.c | 63 -- arch/c6x/kernel/traps.c | 409 ------------ arch/c6x/kernel/vectors.S | 78 --- arch/c6x/kernel/vmlinux.lds.S | 151 ----- arch/c6x/lib/Makefile | 8 - arch/c6x/lib/checksum.c | 11 - arch/c6x/lib/csum_64plus.S | 414 ------------ arch/c6x/lib/divi.S | 41 -- arch/c6x/lib/divremi.S | 34 - arch/c6x/lib/divremu.S | 75 --- arch/c6x/lib/divu.S | 86 --- arch/c6x/lib/llshl.S | 25 - arch/c6x/lib/llshr.S | 26 - arch/c6x/lib/llshru.S | 26 - arch/c6x/lib/memcpy_64plus.S | 43 -- arch/c6x/lib/mpyll.S | 37 -- arch/c6x/lib/negll.S | 19 - arch/c6x/lib/pop_rts.S | 20 - arch/c6x/lib/push_rts.S | 19 - arch/c6x/lib/remi.S | 52 -- arch/c6x/lib/remu.S | 70 -- arch/c6x/lib/strasgi.S | 77 --- arch/c6x/lib/strasgi_64plus.S | 27 - arch/c6x/mm/Makefile | 6 - arch/c6x/mm/dma-coherent.c | 173 ----- arch/c6x/mm/init.c | 65 -- arch/c6x/platforms/Kconfig | 21 - arch/c6x/platforms/Makefile | 13 - arch/c6x/platforms/cache.c | 444 ------------- arch/c6x/platforms/dscr.c | 595 ----------------- arch/c6x/platforms/emif.c | 84 --- arch/c6x/platforms/megamod-pic.c | 344 ---------- arch/c6x/platforms/pll.c | 440 ------------ arch/c6x/platforms/plldata.c | 467 ------------- arch/c6x/platforms/timer64.c | 241 ------- drivers/bus/Kconfig | 2 +- fs/Kconfig.binfmt | 2 +- include/asm-generic/page.h | 4 - 129 files changed, 2 insertions(+), 11162 deletions(-) delete mode 100644 Documentation/devicetree/bindings/c6x/clocks.txt delete mode 100644 Documentation/devicetree/bindings/c6x/dscr.txt delete mode 100644 Documentation/devicetree/bindings/c6x/emifa.txt delete mode 100644 Documentation/devicetree/bindings/c6x/soc.txt delete mode 100644 Documentation/devicetree/bindings/interrupt-controller/ti,c64x+megamod-pic.txt delete mode 100644 Documentation/devicetree/bindings/timer/ti,c64x+timer64.txt delete mode 100644 arch/c6x/Kconfig delete mode 100644 arch/c6x/Kconfig.debug delete mode 100644 arch/c6x/Makefile delete mode 100644 arch/c6x/boot/Makefile delete mode 100644 arch/c6x/boot/dts/Makefile delete mode 100644 arch/c6x/boot/dts/dsk6455.dts delete mode 100644 arch/c6x/boot/dts/evmc6457.dts delete mode 100644 arch/c6x/boot/dts/evmc6472.dts delete mode 100644 arch/c6x/boot/dts/evmc6474.dts delete mode 100644 arch/c6x/boot/dts/evmc6678.dts delete mode 100644 arch/c6x/boot/dts/tms320c6455.dtsi delete mode 100644 arch/c6x/boot/dts/tms320c6457.dtsi delete mode 100644 arch/c6x/boot/dts/tms320c6472.dtsi delete mode 100644 arch/c6x/boot/dts/tms320c6474.dtsi delete mode 100644 arch/c6x/boot/dts/tms320c6678.dtsi delete mode 100644 arch/c6x/configs/dsk6455_defconfig delete mode 100644 arch/c6x/configs/evmc6457_defconfig delete mode 100644 arch/c6x/configs/evmc6472_defconfig delete mode 100644 arch/c6x/configs/evmc6474_defconfig delete mode 100644 arch/c6x/configs/evmc6678_defconfig delete mode 100644 arch/c6x/include/asm/Kbuild delete mode 100644 arch/c6x/include/asm/asm-offsets.h delete mode 100644 arch/c6x/include/asm/bitops.h delete mode 100644 arch/c6x/include/asm/bug.h delete mode 100644 arch/c6x/include/asm/cache.h delete mode 100644 arch/c6x/include/asm/cacheflush.h delete mode 100644 arch/c6x/include/asm/checksum.h delete mode 100644 arch/c6x/include/asm/clock.h delete mode 100644 arch/c6x/include/asm/cmpxchg.h delete mode 100644 arch/c6x/include/asm/delay.h delete mode 100644 arch/c6x/include/asm/dscr.h delete mode 100644 arch/c6x/include/asm/elf.h delete mode 100644 arch/c6x/include/asm/flat.h delete mode 100644 arch/c6x/include/asm/ftrace.h delete mode 100644 arch/c6x/include/asm/hardirq.h delete mode 100644 arch/c6x/include/asm/irq.h delete mode 100644 arch/c6x/include/asm/irqflags.h delete mode 100644 arch/c6x/include/asm/linkage.h delete mode 100644 arch/c6x/include/asm/megamod-pic.h delete mode 100644 arch/c6x/include/asm/mmu_context.h delete mode 100644 arch/c6x/include/asm/module.h delete mode 100644 arch/c6x/include/asm/page.h delete mode 100644 arch/c6x/include/asm/pgtable.h delete mode 100644 arch/c6x/include/asm/processor.h delete mode 100644 arch/c6x/include/asm/procinfo.h delete mode 100644 arch/c6x/include/asm/ptrace.h delete mode 100644 arch/c6x/include/asm/sections.h delete mode 100644 arch/c6x/include/asm/setup.h delete mode 100644 arch/c6x/include/asm/soc.h delete mode 100644 arch/c6x/include/asm/special_insns.h delete mode 100644 arch/c6x/include/asm/string.h delete mode 100644 arch/c6x/include/asm/switch_to.h delete mode 100644 arch/c6x/include/asm/syscall.h delete mode 100644 arch/c6x/include/asm/syscalls.h delete mode 100644 arch/c6x/include/asm/thread_info.h delete mode 100644 arch/c6x/include/asm/timer64.h delete mode 100644 arch/c6x/include/asm/timex.h delete mode 100644 arch/c6x/include/asm/tlb.h delete mode 100644 arch/c6x/include/asm/traps.h delete mode 100644 arch/c6x/include/asm/uaccess.h delete mode 100644 arch/c6x/include/asm/unaligned.h delete mode 100644 arch/c6x/include/asm/vmalloc.h delete mode 100644 arch/c6x/include/uapi/asm/Kbuild delete mode 100644 arch/c6x/include/uapi/asm/byteorder.h delete mode 100644 arch/c6x/include/uapi/asm/ptrace.h delete mode 100644 arch/c6x/include/uapi/asm/setup.h delete mode 100644 arch/c6x/include/uapi/asm/sigcontext.h delete mode 100644 arch/c6x/include/uapi/asm/swab.h delete mode 100644 arch/c6x/include/uapi/asm/unistd.h delete mode 100644 arch/c6x/kernel/Makefile delete mode 100644 arch/c6x/kernel/asm-offsets.c delete mode 100644 arch/c6x/kernel/c6x_ksyms.c delete mode 100644 arch/c6x/kernel/devicetree.c delete mode 100644 arch/c6x/kernel/entry.S delete mode 100644 arch/c6x/kernel/head.S delete mode 100644 arch/c6x/kernel/irq.c delete mode 100644 arch/c6x/kernel/module.c delete mode 100644 arch/c6x/kernel/process.c delete mode 100644 arch/c6x/kernel/ptrace.c delete mode 100644 arch/c6x/kernel/setup.c delete mode 100644 arch/c6x/kernel/signal.c delete mode 100644 arch/c6x/kernel/soc.c delete mode 100644 arch/c6x/kernel/switch_to.S delete mode 100644 arch/c6x/kernel/sys_c6x.c delete mode 100644 arch/c6x/kernel/time.c delete mode 100644 arch/c6x/kernel/traps.c delete mode 100644 arch/c6x/kernel/vectors.S delete mode 100644 arch/c6x/kernel/vmlinux.lds.S delete mode 100644 arch/c6x/lib/Makefile delete mode 100644 arch/c6x/lib/checksum.c delete mode 100644 arch/c6x/lib/csum_64plus.S delete mode 100644 arch/c6x/lib/divi.S delete mode 100644 arch/c6x/lib/divremi.S delete mode 100644 arch/c6x/lib/divremu.S delete mode 100644 arch/c6x/lib/divu.S delete mode 100644 arch/c6x/lib/llshl.S delete mode 100644 arch/c6x/lib/llshr.S delete mode 100644 arch/c6x/lib/llshru.S delete mode 100644 arch/c6x/lib/memcpy_64plus.S delete mode 100644 arch/c6x/lib/mpyll.S delete mode 100644 arch/c6x/lib/negll.S delete mode 100644 arch/c6x/lib/pop_rts.S delete mode 100644 arch/c6x/lib/push_rts.S delete mode 100644 arch/c6x/lib/remi.S delete mode 100644 arch/c6x/lib/remu.S delete mode 100644 arch/c6x/lib/strasgi.S delete mode 100644 arch/c6x/lib/strasgi_64plus.S delete mode 100644 arch/c6x/mm/Makefile delete mode 100644 arch/c6x/mm/dma-coherent.c delete mode 100644 arch/c6x/mm/init.c delete mode 100644 arch/c6x/platforms/Kconfig delete mode 100644 arch/c6x/platforms/Makefile delete mode 100644 arch/c6x/platforms/cache.c delete mode 100644 arch/c6x/platforms/dscr.c delete mode 100644 arch/c6x/platforms/emif.c delete mode 100644 arch/c6x/platforms/megamod-pic.c delete mode 100644 arch/c6x/platforms/pll.c delete mode 100644 arch/c6x/platforms/plldata.c delete mode 100644 arch/c6x/platforms/timer64.c (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/c6x/clocks.txt b/Documentation/devicetree/bindings/c6x/clocks.txt deleted file mode 100644 index a04f5fd30122..000000000000 --- a/Documentation/devicetree/bindings/c6x/clocks.txt +++ /dev/null @@ -1,40 +0,0 @@ -C6X PLL Clock Controllers -------------------------- - -This is a first-cut support for the SoC clock controllers. This is still -under development and will probably change as the common device tree -clock support is added to the kernel. - -Required properties: - -- compatible: "ti,c64x+pll" - May also have SoC-specific value to support SoC-specific initialization - in the driver. One of: - "ti,c6455-pll" - "ti,c6457-pll" - "ti,c6472-pll" - "ti,c6474-pll" - -- reg: base address and size of register area -- clock-frequency: input clock frequency in hz - - -Optional properties: - -- ti,c64x+pll-bypass-delay: CPU cycles to delay when entering bypass mode - -- ti,c64x+pll-reset-delay: CPU cycles to delay after PLL reset - -- ti,c64x+pll-lock-delay: CPU cycles to delay after PLL frequency change - -Example: - - clock-controller@29a0000 { - compatible = "ti,c6472-pll", "ti,c64x+pll"; - reg = <0x029a0000 0x200>; - clock-frequency = <25000000>; - - ti,c64x+pll-bypass-delay = <200>; - ti,c64x+pll-reset-delay = <12000>; - ti,c64x+pll-lock-delay = <80000>; - }; diff --git a/Documentation/devicetree/bindings/c6x/dscr.txt b/Documentation/devicetree/bindings/c6x/dscr.txt deleted file mode 100644 index 92672235de57..000000000000 --- a/Documentation/devicetree/bindings/c6x/dscr.txt +++ /dev/null @@ -1,127 +0,0 @@ -Device State Configuration Registers ------------------------------------- - -TI C6X SoCs contain a region of miscellaneous registers which provide various -function for SoC control or status. Details vary considerably among from SoC -to SoC with no two being alike. - -In general, the Device State Configuration Registers (DSCR) will provide one or -more configuration registers often protected by a lock register where one or -more key values must be written to a lock register in order to unlock the -configuration register for writes. These configuration register may be used to -enable (and disable in some cases) SoC pin drivers, select peripheral clock -sources (internal or pin), etc. In some cases, a configuration register is -write once or the individual bits are write once. In addition to device config, -the DSCR block may provide registers which are used to reset peripherals, -provide device ID information, provide ethernet MAC addresses, as well as other -miscellaneous functions. - -For device state control (enable/disable), each device control is assigned an -id which is used by individual device drivers to control the state as needed. - -Required properties: - -- compatible: must be "ti,c64x+dscr" -- reg: register area base and size - -Optional properties: - - NOTE: These are optional in that not all SoCs will have all properties. For - SoCs which do support a given property, leaving the property out of the - device tree will result in reduced functionality or possibly driver - failure. - -- ti,dscr-devstat - offset of the devstat register - -- ti,dscr-silicon-rev - offset, start bit, and bitsize of silicon revision field - -- ti,dscr-rmii-resets - offset and bitmask of RMII reset field. May have multiple tuples if more - than one ethernet port is available. - -- ti,dscr-locked-regs - possibly multiple tuples describing registers which are write protected by - a lock register. Each tuple consists of the register offset, lock register - offsset, and the key value used to unlock the register. - -- ti,dscr-kick-regs - offset and key values of two "kick" registers used to write protect other - registers in DSCR. On SoCs using kick registers, the first key must be - written to the first kick register and the second key must be written to - the second register before other registers in the area are write-enabled. - -- ti,dscr-mac-fuse-regs - MAC addresses are contained in two registers. Each element of a MAC address - is contained in a single byte. This property has two tuples. Each tuple has - a register offset and four cells representing bytes in the register from - most significant to least. The value of these four cells is the MAC byte - index (1-6) of the byte within the register. A value of 0 means the byte - is unused in the MAC address. - -- ti,dscr-devstate-ctl-regs - This property describes the bitfields used to control the state of devices. - Each tuple describes a range of identical bitfields used to control one or - more devices (one bitfield per device). The layout of each tuple is: - - start_id num_ids reg enable disable start_bit nbits - - Where: - start_id is device id for the first device control in the range - num_ids is the number of device controls in the range - reg is the offset of the register holding the control bits - enable is the value to enable a device - disable is the value to disable a device (0xffffffff if cannot disable) - start_bit is the bit number of the first bit in the range - nbits is the number of bits per device control - -- ti,dscr-devstate-stat-regs - This property describes the bitfields used to provide device state status - for device states controlled by the DSCR. Each tuple describes a range of - identical bitfields used to provide status for one or more devices (one - bitfield per device). The layout of each tuple is: - - start_id num_ids reg enable disable start_bit nbits - - Where: - start_id is device id for the first device status in the range - num_ids is the number of devices covered by the range - reg is the offset of the register holding the status bits - enable is the value indicating device is enabled - disable is the value indicating device is disabled - start_bit is the bit number of the first bit in the range - nbits is the number of bits per device status - -- ti,dscr-privperm - Offset and default value for register used to set access privilege for - some SoC devices. - - -Example: - - device-state-config-regs@2a80000 { - compatible = "ti,c64x+dscr"; - reg = <0x02a80000 0x41000>; - - ti,dscr-devstat = <0>; - ti,dscr-silicon-rev = <8 28 0xf>; - ti,dscr-rmii-resets = <0x40020 0x00040000>; - - ti,dscr-locked-regs = <0x40008 0x40004 0x0f0a0b00>; - ti,dscr-devstate-ctl-regs = - <0 12 0x40008 1 0 0 2 - 12 1 0x40008 3 0 30 2 - 13 2 0x4002c 1 0xffffffff 0 1>; - ti,dscr-devstate-stat-regs = - <0 10 0x40014 1 0 0 3 - 10 2 0x40018 1 0 0 3>; - - ti,dscr-mac-fuse-regs = <0x700 1 2 3 4 - 0x704 5 6 0 0>; - - ti,dscr-privperm = <0x41c 0xaaaaaaaa>; - - ti,dscr-kick-regs = <0x38 0x83E70B13 - 0x3c 0x95A4F1E0>; - }; diff --git a/Documentation/devicetree/bindings/c6x/emifa.txt b/Documentation/devicetree/bindings/c6x/emifa.txt deleted file mode 100644 index 0ff6e9b9a13f..000000000000 --- a/Documentation/devicetree/bindings/c6x/emifa.txt +++ /dev/null @@ -1,62 +0,0 @@ -External Memory Interface -------------------------- - -The emifa node describes a simple external bus controller found on some C6X -SoCs. This interface provides external busses with a number of chip selects. - -Required properties: - -- compatible: must be "ti,c64x+emifa", "simple-bus" -- reg: register area base and size -- #address-cells: must be 2 (chip-select + offset) -- #size-cells: must be 1 -- ranges: mapping from EMIFA space to parent space - - -Optional properties: - -- ti,dscr-dev-enable: Device ID if EMIF is enabled/disabled from DSCR - -- ti,emifa-burst-priority: - Number of memory transfers after which the EMIF will elevate the priority - of the oldest command in the command FIFO. Setting this field to 255 - disables this feature, thereby allowing old commands to stay in the FIFO - indefinitely. - -- ti,emifa-ce-config: - Configuration values for each of the supported chip selects. - -Example: - - emifa@70000000 { - compatible = "ti,c64x+emifa", "simple-bus"; - #address-cells = <2>; - #size-cells = <1>; - reg = <0x70000000 0x100>; - ranges = <0x2 0x0 0xa0000000 0x00000008 - 0x3 0x0 0xb0000000 0x00400000 - 0x4 0x0 0xc0000000 0x10000000 - 0x5 0x0 0xD0000000 0x10000000>; - - ti,dscr-dev-enable = <13>; - ti,emifa-burst-priority = <255>; - ti,emifa-ce-config = <0x00240120 - 0x00240120 - 0x00240122 - 0x00240122>; - - flash@3,0 { - #address-cells = <1>; - #size-cells = <1>; - compatible = "cfi-flash"; - reg = <0x3 0x0 0x400000>; - bank-width = <1>; - device-width = <1>; - partition@0 { - reg = <0x0 0x400000>; - label = "NOR"; - }; - }; - }; - -This shows a flash chip attached to chip select 3. diff --git a/Documentation/devicetree/bindings/c6x/soc.txt b/Documentation/devicetree/bindings/c6x/soc.txt deleted file mode 100644 index b1e4973b5769..000000000000 --- a/Documentation/devicetree/bindings/c6x/soc.txt +++ /dev/null @@ -1,28 +0,0 @@ -C6X System-on-Chip ------------------- - -Required properties: - -- compatible: "simple-bus" -- #address-cells: must be 1 -- #size-cells: must be 1 -- ranges - -Optional properties: - -- model: specific SoC model - -- nodes for IP blocks within SoC - - -Example: - - soc { - compatible = "simple-bus"; - model = "tms320c6455"; - #address-cells = <1>; - #size-cells = <1>; - ranges; - - ... - }; diff --git a/Documentation/devicetree/bindings/interrupt-controller/ti,c64x+megamod-pic.txt b/Documentation/devicetree/bindings/interrupt-controller/ti,c64x+megamod-pic.txt deleted file mode 100644 index ee3f9c351501..000000000000 --- a/Documentation/devicetree/bindings/interrupt-controller/ti,c64x+megamod-pic.txt +++ /dev/null @@ -1,103 +0,0 @@ -C6X Interrupt Chips -------------------- - -* C64X+ Core Interrupt Controller - - The core interrupt controller provides 16 prioritized interrupts to the - C64X+ core. Priority 0 and 1 are used for reset and NMI respectively. - Priority 2 and 3 are reserved. Priority 4-15 are used for interrupt - sources coming from outside the core. - - Required properties: - -------------------- - - compatible: Should be "ti,c64x+core-pic"; - - #interrupt-cells: <1> - - Interrupt Specifier Definition - ------------------------------ - Single cell specifying the core interrupt priority level (4-15) where - 4 is highest priority and 15 is lowest priority. - - Example - ------- - core_pic: interrupt-controller@0 { - interrupt-controller; - #interrupt-cells = <1>; - compatible = "ti,c64x+core-pic"; - }; - - - -* C64x+ Megamodule Interrupt Controller - - The megamodule PIC consists of four interrupt mupliplexers each of which - combine up to 32 interrupt inputs into a single interrupt output which - may be cascaded into the core interrupt controller. The megamodule PIC - has a total of 12 outputs cascading into the core interrupt controller. - One for each core interrupt priority level. In addition to the combined - interrupt sources, individual megamodule interrupts may be cascaded to - the core interrupt controller. When an individual interrupt is cascaded, - it is no longer handled through a megamodule interrupt combiner and is - considered to have the core interrupt controller as the parent. - - Required properties: - -------------------- - - compatible: "ti,c64x+megamod-pic" - - interrupt-controller - - #interrupt-cells: <1> - - reg: base address and size of register area - - interrupts: This should have four cells; one for each interrupt combiner. - The cells contain the core priority interrupt to which the - corresponding combiner output is wired. - - Optional properties: - -------------------- - - ti,c64x+megamod-pic-mux: Array of 12 cells correspnding to the 12 core - priority interrupts. The first cell corresponds to - core priority 4 and the last cell corresponds to - core priority 15. The value of each cell is the - megamodule interrupt source which is MUXed to - the core interrupt corresponding to the cell - position. Allowed values are 4 - 127. Mapping for - interrupts 0 - 3 (combined interrupt sources) are - ignored. - - Interrupt Specifier Definition - ------------------------------ - Single cell specifying the megamodule interrupt source (4-127). Note that - interrupts mapped directly to the core with "ti,c64x+megamod-pic-mux" will - use the core interrupt controller as their parent and the specifier will - be the core priority level, not the megamodule interrupt number. - - Examples - -------- - megamod_pic: interrupt-controller@1800000 { - compatible = "ti,c64x+megamod-pic"; - interrupt-controller; - #interrupt-cells = <1>; - reg = <0x1800000 0x1000>; - interrupt-parent = <&core_pic>; - interrupts = < 12 13 14 15 >; - }; - - This is a minimal example where all individual interrupts go through a - combiner. Combiner-0 is mapped to core interrupt 12, combiner-1 is mapped - to interrupt 13, etc. - - - megamod_pic: interrupt-controller@1800000 { - compatible = "ti,c64x+megamod-pic"; - interrupt-controller; - #interrupt-cells = <1>; - reg = <0x1800000 0x1000>; - interrupt-parent = <&core_pic>; - interrupts = < 12 13 14 15 >; - ti,c64x+megamod-pic-mux = < 0 0 0 0 - 32 0 0 0 - 0 0 0 0 >; - }; - - This the same as the first example except that megamodule interrupt 32 is - mapped directly to core priority interrupt 8. The node using this interrupt - must set the core controller as its interrupt parent and use 8 in the - interrupt specifier value. diff --git a/Documentation/devicetree/bindings/timer/ti,c64x+timer64.txt b/Documentation/devicetree/bindings/timer/ti,c64x+timer64.txt deleted file mode 100644 index d96c1e283e73..000000000000 --- a/Documentation/devicetree/bindings/timer/ti,c64x+timer64.txt +++ /dev/null @@ -1,25 +0,0 @@ -Timer64 -------- - -The timer64 node describes C6X event timers. - -Required properties: - -- compatible: must be "ti,c64x+timer64" -- reg: base address and size of register region -- interrupts: interrupt id - -Optional properties: - -- ti,dscr-dev-enable: Device ID used to enable timer IP through DSCR interface. - -- ti,core-mask: on multi-core SoCs, bitmask of cores allowed to use this timer. - -Example: - timer0: timer@25e0000 { - compatible = "ti,c64x+timer64"; - ti,core-mask = < 0x01 >; - reg = <0x25e0000 0x40>; - interrupt-parent = <&megamod_pic>; - interrupts = < 16 >; - }; diff --git a/MAINTAINERS b/MAINTAINERS index fb971f5f6f0c..7c3eadb185f9 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -3837,14 +3837,6 @@ F: drivers/irqchip/irq-csky-* N: csky K: csky -C6X ARCHITECTURE -M: Mark Salter -M: Aurelien Jacquiot -L: linux-c6x-dev@linux-c6x.org -S: Maintained -W: http://www.linux-c6x.org/wiki/index.php/Main_Page -F: arch/c6x/ - CA8210 IEEE-802.15.4 RADIO DRIVER M: Harry Morris L: linux-wpan@vger.kernel.org diff --git a/arch/c6x/Kconfig b/arch/c6x/Kconfig deleted file mode 100644 index bdeeac28b1be..000000000000 --- a/arch/c6x/Kconfig +++ /dev/null @@ -1,113 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0 -# -# For a description of the syntax of this configuration file, -# see Documentation/kbuild/kconfig-language.rst. -# - -config C6X - def_bool y - select ARCH_32BIT_OFF_T - select ARCH_HAS_BINFMT_FLAT - select ARCH_HAS_SYNC_DMA_FOR_CPU - select ARCH_HAS_SYNC_DMA_FOR_DEVICE - select CLKDEV_LOOKUP - select HAVE_LEGACY_CLK - select GENERIC_ATOMIC64 - select GENERIC_IRQ_SHOW - select HAVE_ARCH_TRACEHOOK - select SPARSE_IRQ - select IRQ_DOMAIN - select OF - select OF_EARLY_FLATTREE - select MODULES_USE_ELF_RELA - select MMU_GATHER_NO_RANGE if MMU - select SET_FS - -config MMU - def_bool n - -config FPU - def_bool n - -config GENERIC_CALIBRATE_DELAY - def_bool y - -config GENERIC_HWEIGHT - def_bool y - -config GENERIC_BUG - def_bool y - depends on BUG - -config C6X_BIG_KERNEL - bool "Build a big kernel" - help - The C6X function call instruction has a limited range of +/- 2MiB. - This is sufficient for most kernels, but some kernel configurations - with lots of compiled-in functionality may require a larger range - for function calls. Use this option to have the compiler generate - function calls with 32-bit range. This will make the kernel both - larger and slower. - - If unsure, say N. - -# Use the generic interrupt handling code in kernel/irq/ - -config CMDLINE_BOOL - bool "Default bootloader kernel arguments" - -config CMDLINE - string "Kernel command line" - depends on CMDLINE_BOOL - default "console=ttyS0,57600" - help - On some architectures there is currently no way for the boot loader - to pass arguments to the kernel. For these architectures, you should - supply some command-line options at build time by entering them - here. - -config CMDLINE_FORCE - bool "Force default kernel command string" - depends on CMDLINE_BOOL - default n - help - Set this to have arguments from the default kernel command string - override those passed by the boot loader. - -config CPU_BIG_ENDIAN - bool "Build big-endian kernel" - default n - help - Say Y if you plan on running a kernel in big-endian mode. - Note that your board must be properly built and your board - port must properly enable any big-endian related features - of your chipset/board/processor. - -config FORCE_MAX_ZONEORDER - int "Maximum zone order" - default "13" - help - The kernel memory allocator divides physically contiguous memory - blocks into "zones", where each zone is a power of two number of - pages. This option selects the largest power of two that the kernel - keeps in the memory allocator. If you need to allocate very large - blocks of physically contiguous memory, then you may need to - increase this value. - - This config option is actually maximum order plus one. For example, - a value of 11 means that the largest free memory block is 2^10 pages. - -menu "Processor type and features" - -source "arch/c6x/platforms/Kconfig" - -config KERNEL_RAM_BASE_ADDRESS - hex "Virtual address of memory base" - default 0xe0000000 if SOC_TMS320C6455 - default 0xe0000000 if SOC_TMS320C6457 - default 0xe0000000 if SOC_TMS320C6472 - default 0x80000000 - -source "kernel/Kconfig.hz" - -endmenu diff --git a/arch/c6x/Kconfig.debug b/arch/c6x/Kconfig.debug deleted file mode 100644 index c299e0d8eca3..000000000000 --- a/arch/c6x/Kconfig.debug +++ /dev/null @@ -1,10 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0 - -config ACCESS_CHECK - bool "Check the user pointer address" - default y - help - Usually the pointer transfer from user space is checked to see if its - address is in the kernel space. - - Say N here to disable that check to improve the performance. diff --git a/arch/c6x/Makefile b/arch/c6x/Makefile deleted file mode 100644 index b7aa854f7008..000000000000 --- a/arch/c6x/Makefile +++ /dev/null @@ -1,60 +0,0 @@ -# -# linux/arch/c6x/Makefile -# -# This file is subject to the terms and conditions of the GNU General Public -# License. See the file "COPYING" in the main directory of this archive -# for more details. -# - -KBUILD_DEFCONFIG := dsk6455_defconfig - -cflags-y += -mno-dsbt -msdata=none -D__linux__ - -cflags-$(CONFIG_C6X_BIG_KERNEL) += -mlong-calls - -KBUILD_CFLAGS_MODULE += -mlong-calls -mno-dsbt -msdata=none - -CHECKFLAGS += - -KBUILD_CFLAGS += $(cflags-y) -KBUILD_AFLAGS += $(cflags-y) - -ifdef CONFIG_CPU_BIG_ENDIAN -KBUILD_CFLAGS += -mbig-endian -KBUILD_AFLAGS += -mbig-endian -LINKFLAGS += -mbig-endian -KBUILD_LDFLAGS += -mbig-endian -EB -CHECKFLAGS += -D_BIG_ENDIAN -endif - -head-y := arch/c6x/kernel/head.o -core-y += arch/c6x/kernel/ arch/c6x/mm/ arch/c6x/platforms/ -libs-y += arch/c6x/lib/ - -# Default to vmlinux.bin, override when needed -all: vmlinux.bin - -boot := arch/$(ARCH)/boot - -# Are we making a dtbImage. target? If so, crack out the boardname -DTB:=$(subst dtbImage.,,$(filter dtbImage.%, $(MAKECMDGOALS))) -export DTB - -core-y += $(boot)/dts/ - -# With make 3.82 we cannot mix normal and wildcard targets - -vmlinux.bin: vmlinux - $(Q)$(MAKE) $(build)=$(boot) $(patsubst %,$(boot)/%,$@) - -dtbImage.%: vmlinux - $(Q)$(MAKE) $(build)=$(boot) $(patsubst %,$(boot)/%,$@) - -archclean: - $(Q)$(MAKE) $(clean)=$(boot) - -define archhelp - @echo ' vmlinux.bin - Binary kernel image (arch/$(ARCH)/boot/vmlinux.bin)' - @echo ' dtbImage.
- ELF image with $(arch)/boot/dts/
.dts linked in' - @echo ' - stripped elf with fdt blob' -endef diff --git a/arch/c6x/boot/Makefile b/arch/c6x/boot/Makefile deleted file mode 100644 index 842b7b0bfe80..000000000000 --- a/arch/c6x/boot/Makefile +++ /dev/null @@ -1,11 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0 -# -# Makefile for bootable kernel images -# - -OBJCOPYFLAGS_vmlinux.bin := -O binary -$(obj)/vmlinux.bin: vmlinux FORCE - $(call if_changed,objcopy) - -$(obj)/dtbImage.%: vmlinux - $(call if_changed,objcopy) diff --git a/arch/c6x/boot/dts/Makefile b/arch/c6x/boot/dts/Makefile deleted file mode 100644 index f438285c3640..000000000000 --- a/arch/c6x/boot/dts/Makefile +++ /dev/null @@ -1,16 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0 -# -# Makefile for device trees -# - -DTC_FLAGS ?= -p 1024 - -dtb-$(CONFIG_SOC_TMS320C6455) += dsk6455.dtb -dtb-$(CONFIG_SOC_TMS320C6457) += evmc6457.dtb -dtb-$(CONFIG_SOC_TMS320C6472) += evmc6472.dtb -dtb-$(CONFIG_SOC_TMS320C6474) += evmc6474.dtb -dtb-$(CONFIG_SOC_TMS320C6678) += evmc6678.dtb - -ifneq ($(DTB),) -obj-y += $(DTB).dtb.o -endif diff --git a/arch/c6x/boot/dts/dsk6455.dts b/arch/c6x/boot/dts/dsk6455.dts deleted file mode 100644 index fa904f2916b5..000000000000 --- a/arch/c6x/boot/dts/dsk6455.dts +++ /dev/null @@ -1,57 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * arch/c6x/boot/dts/dsk6455.dts - * - * DSK6455 Evaluation Platform For TMS320C6455 - * Copyright (C) 2011 Texas Instruments Incorporated - * - * Author: Mark Salter - */ - -/dts-v1/; - -/include/ "tms320c6455.dtsi" - -/ { - model = "Spectrum Digital DSK6455"; - compatible = "spectrum-digital,dsk6455"; - - chosen { - bootargs = "root=/dev/nfs ip=dhcp rw"; - }; - - memory { - device_type = "memory"; - reg = <0xE0000000 0x08000000>; - }; - - soc { - megamod_pic: interrupt-controller@1800000 { - interrupts = < 12 13 14 15 >; - }; - - emifa@70000000 { - flash@3,0 { - #address-cells = <1>; - #size-cells = <1>; - compatible = "cfi-flash"; - reg = <0x3 0x0 0x400000>; - bank-width = <1>; - device-width = <1>; - partition@0 { - reg = <0x0 0x400000>; - label = "NOR"; - }; - }; - }; - - timer1: timer@2980000 { - interrupt-parent = <&megamod_pic>; - interrupts = < 69 >; - }; - - clock-controller@029a0000 { - clock-frequency = <50000000>; - }; - }; -}; diff --git a/arch/c6x/boot/dts/evmc6457.dts b/arch/c6x/boot/dts/evmc6457.dts deleted file mode 100644 index 73e1d43b51ce..000000000000 --- a/arch/c6x/boot/dts/evmc6457.dts +++ /dev/null @@ -1,43 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * arch/c6x/boot/dts/evmc6457.dts - * - * EVMC6457 Evaluation Platform For TMS320C6457 - * - * Copyright (C) 2011 Texas Instruments Incorporated - * - * Author: Mark Salter - */ - -/dts-v1/; - -/include/ "tms320c6457.dtsi" - -/ { - model = "eInfochips EVMC6457"; - compatible = "einfochips,evmc6457"; - - chosen { - bootargs = "console=hvc root=/dev/nfs ip=dhcp rw"; - }; - - memory { - device_type = "memory"; - reg = <0xE0000000 0x10000000>; - }; - - soc { - megamod_pic: interrupt-controller@1800000 { - interrupts = < 12 13 14 15 >; - }; - - timer0: timer@2940000 { - interrupt-parent = <&megamod_pic>; - interrupts = < 67 >; - }; - - clock-controller@29a0000 { - clock-frequency = <60000000>; - }; - }; -}; diff --git a/arch/c6x/boot/dts/evmc6472.dts b/arch/c6x/boot/dts/evmc6472.dts deleted file mode 100644 index 4878b78919fa..000000000000 --- a/arch/c6x/boot/dts/evmc6472.dts +++ /dev/null @@ -1,68 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * arch/c6x/boot/dts/evmc6472.dts - * - * EVMC6472 Evaluation Platform For TMS320C6472 - * - * Copyright (C) 2011 Texas Instruments Incorporated - * - * Author: Mark Salter - */ - -/dts-v1/; - -/include/ "tms320c6472.dtsi" - -/ { - model = "eInfochips EVMC6472"; - compatible = "einfochips,evmc6472"; - - chosen { - bootargs = "console=hvc root=/dev/nfs ip=dhcp rw"; - }; - - memory { - device_type = "memory"; - reg = <0xE0000000 0x10000000>; - }; - - soc { - megamod_pic: interrupt-controller@1800000 { - interrupts = < 12 13 14 15 >; - }; - - timer0: timer@25e0000 { - interrupt-parent = <&megamod_pic>; - interrupts = < 16 >; - }; - - timer1: timer@25f0000 { - interrupt-parent = <&megamod_pic>; - interrupts = < 16 >; - }; - - timer2: timer@2600000 { - interrupt-parent = <&megamod_pic>; - interrupts = < 16 >; - }; - - timer3: timer@2610000 { - interrupt-parent = <&megamod_pic>; - interrupts = < 16 >; - }; - - timer4: timer@2620000 { - interrupt-parent = <&megamod_pic>; - interrupts = < 16 >; - }; - - timer5: timer@2630000 { - interrupt-parent = <&megamod_pic>; - interrupts = < 16 >; - }; - - clock-controller@29a0000 { - clock-frequency = <25000000>; - }; - }; -}; diff --git a/arch/c6x/boot/dts/evmc6474.dts b/arch/c6x/boot/dts/evmc6474.dts deleted file mode 100644 index d10746453217..000000000000 --- a/arch/c6x/boot/dts/evmc6474.dts +++ /dev/null @@ -1,53 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * arch/c6x/boot/dts/evmc6474.dts - * - * EVMC6474 Evaluation Platform For TMS320C6474 - * - * Copyright (C) 2011 Texas Instruments Incorporated - * - * Author: Mark Salter - */ - -/dts-v1/; - -/include/ "tms320c6474.dtsi" - -/ { - model = "Spectrum Digital EVMC6474"; - compatible = "spectrum-digital,evmc6474"; - - chosen { - bootargs = "console=hvc root=/dev/nfs ip=dhcp rw"; - }; - - memory { - device_type = "memory"; - reg = <0x80000000 0x08000000>; - }; - - soc { - megamod_pic: interrupt-controller@1800000 { - interrupts = < 12 13 14 15 >; - }; - - timer3: timer@2940000 { - interrupt-parent = <&megamod_pic>; - interrupts = < 39 >; - }; - - timer4: timer@2950000 { - interrupt-parent = <&megamod_pic>; - interrupts = < 41 >; - }; - - timer5: timer@2960000 { - interrupt-parent = <&megamod_pic>; - interrupts = < 43 >; - }; - - clock-controller@29a0000 { - clock-frequency = <50000000>; - }; - }; -}; diff --git a/arch/c6x/boot/dts/evmc6678.dts b/arch/c6x/boot/dts/evmc6678.dts deleted file mode 100644 index 5e6c0961e7b2..000000000000 --- a/arch/c6x/boot/dts/evmc6678.dts +++ /dev/null @@ -1,78 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * arch/c6x/boot/dts/evmc6678.dts - * - * EVMC6678 Evaluation Platform For TMS320C6678 - * - * Copyright (C) 2012 Texas Instruments Incorporated - * - * Author: Ken Cox - */ - -/dts-v1/; - -/include/ "tms320c6678.dtsi" - -/ { - model = "Advantech EVMC6678"; - compatible = "advantech,evmc6678"; - - chosen { - bootargs = "root=/dev/nfs ip=dhcp rw"; - }; - - memory { - device_type = "memory"; - reg = <0x80000000 0x20000000>; - }; - - soc { - megamod_pic: interrupt-controller@1800000 { - interrupts = < 12 13 14 15 >; - }; - - timer8: timer@2280000 { - interrupt-parent = <&megamod_pic>; - interrupts = < 66 >; - }; - - timer9: timer@2290000 { - interrupt-parent = <&megamod_pic>; - interrupts = < 68 >; - }; - - timer10: timer@22A0000 { - interrupt-parent = <&megamod_pic>; - interrupts = < 70 >; - }; - - timer11: timer@22B0000 { - interrupt-parent = <&megamod_pic>; - interrupts = < 72 >; - }; - - timer12: timer@22C0000 { - interrupt-parent = <&megamod_pic>; - interrupts = < 74 >; - }; - - timer13: timer@22D0000 { - interrupt-parent = <&megamod_pic>; - interrupts = < 76 >; - }; - - timer14: timer@22E0000 { - interrupt-parent = <&megamod_pic>; - interrupts = < 78 >; - }; - - timer15: timer@22F0000 { - interrupt-parent = <&megamod_pic>; - interrupts = < 80 >; - }; - - clock-controller@2310000 { - clock-frequency = <100000000>; - }; - }; -}; diff --git a/arch/c6x/boot/dts/tms320c6455.dtsi b/arch/c6x/boot/dts/tms320c6455.dtsi deleted file mode 100644 index 0b21cb30343b..000000000000 --- a/arch/c6x/boot/dts/tms320c6455.dtsi +++ /dev/null @@ -1,97 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 - -/ { - #address-cells = <1>; - #size-cells = <1>; - - cpus { - #address-cells = <1>; - #size-cells = <0>; - - cpu@0 { - device_type = "cpu"; - model = "ti,c64x+"; - reg = <0>; - }; - }; - - soc { - compatible = "simple-bus"; - model = "tms320c6455"; - #address-cells = <1>; - #size-cells = <1>; - ranges; - - core_pic: interrupt-controller { - interrupt-controller; - #interrupt-cells = <1>; - compatible = "ti,c64x+core-pic"; - }; - - /* - * Megamodule interrupt controller - */ - megamod_pic: interrupt-controller@1800000 { - compatible = "ti,c64x+megamod-pic"; - interrupt-controller; - #interrupt-cells = <1>; - reg = <0x1800000 0x1000>; - interrupt-parent = <&core_pic>; - }; - - cache-controller@1840000 { - compatible = "ti,c64x+cache"; - reg = <0x01840000 0x8400>; - }; - - emifa@70000000 { - compatible = "ti,c64x+emifa", "simple-bus"; - #address-cells = <2>; - #size-cells = <1>; - reg = <0x70000000 0x100>; - ranges = <0x2 0x0 0xa0000000 0x00000008 - 0x3 0x0 0xb0000000 0x00400000 - 0x4 0x0 0xc0000000 0x10000000 - 0x5 0x0 0xD0000000 0x10000000>; - - ti,dscr-dev-enable = <13>; - ti,emifa-burst-priority = <255>; - ti,emifa-ce-config = <0x00240120 - 0x00240120 - 0x00240122 - 0x00240122>; - }; - - timer1: timer@2980000 { - compatible = "ti,c64x+timer64"; - reg = <0x2980000 0x40>; - ti,dscr-dev-enable = <4>; - }; - - clock-controller@029a0000 { - compatible = "ti,c6455-pll", "ti,c64x+pll"; - reg = <0x029a0000 0x200>; - ti,c64x+pll-bypass-delay = <1440>; - ti,c64x+pll-reset-delay = <15360>; - ti,c64x+pll-lock-delay = <24000>; - }; - - device-state-config-regs@2a80000 { - compatible = "ti,c64x+dscr"; - reg = <0x02a80000 0x41000>; - - ti,dscr-devstat = <0>; - ti,dscr-silicon-rev = <8 28 0xf>; - ti,dscr-rmii-resets = <0 0x40020 0x00040000>; - - ti,dscr-locked-regs = <0x40008 0x40004 0x0f0a0b00>; - ti,dscr-devstate-ctl-regs = - <0 12 0x40008 1 0 0 2 - 12 1 0x40008 3 0 30 2 - 13 2 0x4002c 1 0xffffffff 0 1>; - ti,dscr-devstate-stat-regs = - <0 10 0x40014 1 0 0 3 - 10 2 0x40018 1 0 0 3>; - }; - }; -}; diff --git a/arch/c6x/boot/dts/tms320c6457.dtsi b/arch/c6x/boot/dts/tms320c6457.dtsi deleted file mode 100644 index e49f7ae19124..000000000000 --- a/arch/c6x/boot/dts/tms320c6457.dtsi +++ /dev/null @@ -1,69 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 - -/ { - #address-cells = <1>; - #size-cells = <1>; - - cpus { - #address-cells = <1>; - #size-cells = <0>; - - cpu@0 { - device_type = "cpu"; - model = "ti,c64x+"; - reg = <0>; - }; - }; - - soc { - compatible = "simple-bus"; - model = "tms320c6457"; - #address-cells = <1>; - #size-cells = <1>; - ranges; - - core_pic: interrupt-controller { - interrupt-controller; - #interrupt-cells = <1>; - compatible = "ti,c64x+core-pic"; - }; - - megamod_pic: interrupt-controller@1800000 { - compatible = "ti,c64x+megamod-pic"; - interrupt-controller; - #interrupt-cells = <1>; - interrupt-parent = <&core_pic>; - reg = <0x1800000 0x1000>; - }; - - cache-controller@1840000 { - compatible = "ti,c64x+cache"; - reg = <0x01840000 0x8400>; - }; - - device-state-controller@2880800 { - compatible = "ti,c64x+dscr"; - reg = <0x02880800 0x400>; - - ti,dscr-devstat = <0x20>; - ti,dscr-silicon-rev = <0x18 28 0xf>; - ti,dscr-mac-fuse-regs = <0x114 3 4 5 6 - 0x118 0 0 1 2>; - ti,dscr-kick-regs = <0x38 0x83E70B13 - 0x3c 0x95A4F1E0>; - }; - - timer0: timer@2940000 { - compatible = "ti,c64x+timer64"; - reg = <0x2940000 0x40>; - }; - - clock-controller@29a0000 { - compatible = "ti,c6457-pll", "ti,c64x+pll"; - reg = <0x029a0000 0x200>; - ti,c64x+pll-bypass-delay = <300>; - ti,c64x+pll-reset-delay = <24000>; - ti,c64x+pll-lock-delay = <50000>; - }; - }; -}; diff --git a/arch/c6x/boot/dts/tms320c6472.dtsi b/arch/c6x/boot/dts/tms320c6472.dtsi deleted file mode 100644 index 9dd4b04e78ef..000000000000 --- a/arch/c6x/boot/dts/tms320c6472.dtsi +++ /dev/null @@ -1,135 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 - -/ { - #address-cells = <1>; - #size-cells = <1>; - - cpus { - #address-cells = <1>; - #size-cells = <0>; - - cpu@0 { - device_type = "cpu"; - reg = <0>; - model = "ti,c64x+"; - }; - cpu@1 { - device_type = "cpu"; - reg = <1>; - model = "ti,c64x+"; - }; - cpu@2 { - device_type = "cpu"; - reg = <2>; - model = "ti,c64x+"; - }; - cpu@3 { - device_type = "cpu"; - reg = <3>; - model = "ti,c64x+"; - }; - cpu@4 { - device_type = "cpu"; - reg = <4>; - model = "ti,c64x+"; - }; - cpu@5 { - device_type = "cpu"; - reg = <5>; - model = "ti,c64x+"; - }; - }; - - soc { - compatible = "simple-bus"; - model = "tms320c6472"; - #address-cells = <1>; - #size-cells = <1>; - ranges; - - core_pic: interrupt-controller { - compatible = "ti,c64x+core-pic"; - interrupt-controller; - #interrupt-cells = <1>; - }; - - megamod_pic: interrupt-controller@1800000 { - compatible = "ti,c64x+megamod-pic"; - interrupt-controller; - #interrupt-cells = <1>; - reg = <0x1800000 0x1000>; - interrupt-parent = <&core_pic>; - }; - - cache-controller@1840000 { - compatible = "ti,c64x+cache"; - reg = <0x01840000 0x8400>; - }; - - timer0: timer@25e0000 { - compatible = "ti,c64x+timer64"; - ti,core-mask = < 0x01 >; - reg = <0x25e0000 0x40>; - }; - - timer1: timer@25f0000 { - compatible = "ti,c64x+timer64"; - ti,core-mask = < 0x02 >; - reg = <0x25f0000 0x40>; - }; - - timer2: timer@2600000 { - compatible = "ti,c64x+timer64"; - ti,core-mask = < 0x04 >; - reg = <0x2600000 0x40>; - }; - - timer3: timer@2610000 { - compatible = "ti,c64x+timer64"; - ti,core-mask = < 0x08 >; - reg = <0x2610000 0x40>; - }; - - timer4: timer@2620000 { - compatible = "ti,c64x+timer64"; - ti,core-mask = < 0x10 >; - reg = <0x2620000 0x40>; - }; - - timer5: timer@2630000 { - compatible = "ti,c64x+timer64"; - ti,core-mask = < 0x20 >; - reg = <0x2630000 0x40>; - }; - - clock-controller@29a0000 { - compatible = "ti,c6472-pll", "ti,c64x+pll"; - reg = <0x029a0000 0x200>; - ti,c64x+pll-bypass-delay = <200>; - ti,c64x+pll-reset-delay = <12000>; - ti,c64x+pll-lock-delay = <80000>; - }; - - device-state-controller@2a80000 { - compatible = "ti,c64x+dscr"; - reg = <0x02a80000 0x1000>; - - ti,dscr-devstat = <0>; - ti,dscr-silicon-rev = <0x70c 16 0xff>; - - ti,dscr-mac-fuse-regs = <0x700 1 2 3 4 - 0x704 5 6 0 0>; - - ti,dscr-rmii-resets = <0x208 1 - 0x20c 1>; - - ti,dscr-locked-regs = <0x200 0x204 0x0a1e183a - 0x40c 0x420 0xbea7 - 0x41c 0x420 0xbea7>; - - ti,dscr-privperm = <0x41c 0xaaaaaaaa>; - - ti,dscr-devstate-ctl-regs = <0 13 0x200 1 0 0 1>; - }; - }; -}; diff --git a/arch/c6x/boot/dts/tms320c6474.dtsi b/arch/c6x/boot/dts/tms320c6474.dtsi deleted file mode 100644 index 0ef5333629a6..000000000000 --- a/arch/c6x/boot/dts/tms320c6474.dtsi +++ /dev/null @@ -1,90 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 - -/ { - #address-cells = <1>; - #size-cells = <1>; - - cpus { - #address-cells = <1>; - #size-cells = <0>; - - cpu@0 { - device_type = "cpu"; - reg = <0>; - model = "ti,c64x+"; - }; - cpu@1 { - device_type = "cpu"; - reg = <1>; - model = "ti,c64x+"; - }; - cpu@2 { - device_type = "cpu"; - reg = <2>; - model = "ti,c64x+"; - }; - }; - - soc { - compatible = "simple-bus"; - model = "tms320c6474"; - #address-cells = <1>; - #size-cells = <1>; - ranges; - - core_pic: interrupt-controller { - interrupt-controller; - #interrupt-cells = <1>; - compatible = "ti,c64x+core-pic"; - }; - - megamod_pic: interrupt-controller@1800000 { - compatible = "ti,c64x+megamod-pic"; - interrupt-controller; - #interrupt-cells = <1>; - reg = <0x1800000 0x1000>; - interrupt-parent = <&core_pic>; - }; - - cache-controller@1840000 { - compatible = "ti,c64x+cache"; - reg = <0x01840000 0x8400>; - }; - - timer3: timer@2940000 { - compatible = "ti,c64x+timer64"; - ti,core-mask = < 0x04 >; - reg = <0x2940000 0x40>; - }; - - timer4: timer@2950000 { - compatible = "ti,c64x+timer64"; - ti,core-mask = < 0x02 >; - reg = <0x2950000 0x40>; - }; - - timer5: timer@2960000 { - compatible = "ti,c64x+timer64"; - ti,core-mask = < 0x01 >; - reg = <0x2960000 0x40>; - }; - - device-state-controller@2880800 { - compatible = "ti,c64x+dscr"; - reg = <0x02880800 0x400>; - - ti,dscr-devstat = <0x004>; - ti,dscr-silicon-rev = <0x014 28 0xf>; - ti,dscr-mac-fuse-regs = <0x34 3 4 5 6 - 0x38 0 0 1 2>; - }; - - clock-controller@29a0000 { - compatible = "ti,c6474-pll", "ti,c64x+pll"; - reg = <0x029a0000 0x200>; - ti,c64x+pll-bypass-delay = <120>; - ti,c64x+pll-reset-delay = <30000>; - ti,c64x+pll-lock-delay = <60000>; - }; - }; -}; diff --git a/arch/c6x/boot/dts/tms320c6678.dtsi b/arch/c6x/boot/dts/tms320c6678.dtsi deleted file mode 100644 index da1e3f2bf062..000000000000 --- a/arch/c6x/boot/dts/tms320c6678.dtsi +++ /dev/null @@ -1,147 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 - -/ { - #address-cells = <1>; - #size-cells = <1>; - - cpus { - #address-cells = <1>; - #size-cells = <0>; - - cpu@0 { - device_type = "cpu"; - reg = <0>; - model = "ti,c66x"; - }; - cpu@1 { - device_type = "cpu"; - reg = <1>; - model = "ti,c66x"; - }; - cpu@2 { - device_type = "cpu"; - reg = <2>; - model = "ti,c66x"; - }; - cpu@3 { - device_type = "cpu"; - reg = <3>; - model = "ti,c66x"; - }; - cpu@4 { - device_type = "cpu"; - reg = <4>; - model = "ti,c66x"; - }; - cpu@5 { - device_type = "cpu"; - reg = <5>; - model = "ti,c66x"; - }; - cpu@6 { - device_type = "cpu"; - reg = <6>; - model = "ti,c66x"; - }; - cpu@7 { - device_type = "cpu"; - reg = <7>; - model = "ti,c66x"; - }; - }; - - soc { - compatible = "simple-bus"; - model = "tms320c6678"; - #address-cells = <1>; - #size-cells = <1>; - ranges; - - core_pic: interrupt-controller { - compatible = "ti,c64x+core-pic"; - interrupt-controller; - #interrupt-cells = <1>; - }; - - megamod_pic: interrupt-controller@1800000 { - compatible = "ti,c64x+megamod-pic"; - interrupt-controller; - #interrupt-cells = <1>; - reg = <0x1800000 0x1000>; - interrupt-parent = <&core_pic>; - }; - - cache-controller@1840000 { - compatible = "ti,c64x+cache"; - reg = <0x01840000 0x8400>; - }; - - timer8: timer@2280000 { - compatible = "ti,c64x+timer64"; - ti,core-mask = < 0x01 >; - reg = <0x2280000 0x40>; - }; - - timer9: timer@2290000 { - compatible = "ti,c64x+timer64"; - ti,core-mask = < 0x02 >; - reg = <0x2290000 0x40>; - }; - - timer10: timer@22A0000 { - compatible = "ti,c64x+timer64"; - ti,core-mask = < 0x04 >; - reg = <0x22A0000 0x40>; - }; - - timer11: timer@22B0000 { - compatible = "ti,c64x+timer64"; - ti,core-mask = < 0x08 >; - reg = <0x22B0000 0x40>; - }; - - timer12: timer@22C0000 { - compatible = "ti,c64x+timer64"; - ti,core-mask = < 0x10 >; - reg = <0x22C0000 0x40>; - }; - - timer13: timer@22D0000 { - compatible = "ti,c64x+timer64"; - ti,core-mask = < 0x20 >; - reg = <0x22D0000 0x40>; - }; - - timer14: timer@22E0000 { - compatible = "ti,c64x+timer64"; - ti,core-mask = < 0x40 >; - reg = <0x22E0000 0x40>; - }; - - timer15: timer@22F0000 { - compatible = "ti,c64x+timer64"; - ti,core-mask = < 0x80 >; - reg = <0x22F0000 0x40>; - }; - - clock-controller@2310000 { - compatible = "ti,c6678-pll", "ti,c64x+pll"; - reg = <0x02310000 0x200>; - ti,c64x+pll-bypass-delay = <200>; - ti,c64x+pll-reset-delay = <12000>; - ti,c64x+pll-lock-delay = <80000>; - }; - - device-state-controller@2620000 { - compatible = "ti,c64x+dscr"; - reg = <0x02620000 0x1000>; - - ti,dscr-devstat = <0x20>; - ti,dscr-silicon-rev = <0x18 28 0xf>; - - ti,dscr-mac-fuse-regs = <0x110 1 2 3 4 - 0x114 5 6 0 0>; - - }; - }; -}; diff --git a/arch/c6x/configs/dsk6455_defconfig b/arch/c6x/configs/dsk6455_defconfig deleted file mode 100644 index d764ea4cce7f..000000000000 --- a/arch/c6x/configs/dsk6455_defconfig +++ /dev/null @@ -1,42 +0,0 @@ -CONFIG_SOC_TMS320C6455=y -# CONFIG_LOCALVERSION_AUTO is not set -CONFIG_SYSVIPC=y -CONFIG_SPARSE_IRQ=y -CONFIG_LOG_BUF_SHIFT=14 -CONFIG_NAMESPACES=y -# CONFIG_UTS_NS is not set -# CONFIG_USER_NS is not set -# CONFIG_PID_NS is not set -CONFIG_BLK_DEV_INITRD=y -CONFIG_CC_OPTIMIZE_FOR_SIZE=y -CONFIG_EXPERT=y -# CONFIG_FUTEX is not set -# CONFIG_SLUB_DEBUG is not set -CONFIG_MODULES=y -CONFIG_MODULE_FORCE_LOAD=y -CONFIG_MODULE_UNLOAD=y -CONFIG_MODULE_FORCE_UNLOAD=y -CONFIG_CMDLINE_BOOL=y -CONFIG_CMDLINE="" -CONFIG_NO_HZ=y -CONFIG_HIGH_RES_TIMERS=y -CONFIG_BLK_DEV_LOOP=y -CONFIG_BLK_DEV_RAM=y -CONFIG_BLK_DEV_RAM_COUNT=2 -CONFIG_BLK_DEV_RAM_SIZE=17000 -# CONFIG_INPUT is not set -# CONFIG_SERIO is not set -# CONFIG_VT is not set -# CONFIG_HW_RANDOM is not set -# CONFIG_HWMON is not set -# CONFIG_USB_SUPPORT is not set -# CONFIG_IOMMU_SUPPORT is not set -# CONFIG_MISC_FILESYSTEMS is not set -CONFIG_CRC16=y -# CONFIG_ENABLE_MUST_CHECK is not set -# CONFIG_SCHED_DEBUG is not set -# CONFIG_DEBUG_BUGVERBOSE is not set -CONFIG_MTD=y -CONFIG_MTD_CFI=y -CONFIG_MTD_CFI_AMDSTD=y -CONFIG_MTD_PHYSMAP_OF=y diff --git a/arch/c6x/configs/evmc6457_defconfig b/arch/c6x/configs/evmc6457_defconfig deleted file mode 100644 index 05d0b4a25ab1..000000000000 --- a/arch/c6x/configs/evmc6457_defconfig +++ /dev/null @@ -1,39 +0,0 @@ -CONFIG_SOC_TMS320C6457=y -# CONFIG_LOCALVERSION_AUTO is not set -CONFIG_SYSVIPC=y -CONFIG_SPARSE_IRQ=y -CONFIG_LOG_BUF_SHIFT=14 -CONFIG_NAMESPACES=y -# CONFIG_UTS_NS is not set -# CONFIG_USER_NS is not set -# CONFIG_PID_NS is not set -CONFIG_BLK_DEV_INITRD=y -CONFIG_CC_OPTIMIZE_FOR_SIZE=y -CONFIG_EXPERT=y -# CONFIG_FUTEX is not set -# CONFIG_SLUB_DEBUG is not set -CONFIG_MODULES=y -CONFIG_MODULE_FORCE_LOAD=y -CONFIG_MODULE_UNLOAD=y -CONFIG_MODULE_FORCE_UNLOAD=y -CONFIG_CMDLINE_BOOL=y -CONFIG_CMDLINE="" -CONFIG_BOARD_EVM6457=y -CONFIG_NO_HZ=y -CONFIG_HIGH_RES_TIMERS=y -CONFIG_BLK_DEV_LOOP=y -CONFIG_BLK_DEV_RAM=y -CONFIG_BLK_DEV_RAM_COUNT=2 -CONFIG_BLK_DEV_RAM_SIZE=17000 -# CONFIG_INPUT is not set -# CONFIG_SERIO is not set -# CONFIG_VT is not set -# CONFIG_HW_RANDOM is not set -# CONFIG_HWMON is not set -# CONFIG_USB_SUPPORT is not set -# CONFIG_IOMMU_SUPPORT is not set -# CONFIG_MISC_FILESYSTEMS is not set -CONFIG_CRC16=y -# CONFIG_ENABLE_MUST_CHECK is not set -# CONFIG_SCHED_DEBUG is not set -# CONFIG_DEBUG_BUGVERBOSE is not set diff --git a/arch/c6x/configs/evmc6472_defconfig b/arch/c6x/configs/evmc6472_defconfig deleted file mode 100644 index 8d81fcf86b0e..000000000000 --- a/arch/c6x/configs/evmc6472_defconfig +++ /dev/null @@ -1,40 +0,0 @@ -CONFIG_SOC_TMS320C6472=y -# CONFIG_LOCALVERSION_AUTO is not set -CONFIG_SYSVIPC=y -CONFIG_SPARSE_IRQ=y -CONFIG_LOG_BUF_SHIFT=14 -CONFIG_NAMESPACES=y -# CONFIG_UTS_NS is not set -# CONFIG_USER_NS is not set -# CONFIG_PID_NS is not set -CONFIG_BLK_DEV_INITRD=y -CONFIG_CC_OPTIMIZE_FOR_SIZE=y -CONFIG_EXPERT=y -# CONFIG_FUTEX is not set -# CONFIG_SLUB_DEBUG is not set -CONFIG_MODULES=y -CONFIG_MODULE_FORCE_LOAD=y -CONFIG_MODULE_UNLOAD=y -CONFIG_MODULE_FORCE_UNLOAD=y -CONFIG_CMDLINE_BOOL=y -CONFIG_CMDLINE="" -# CONFIG_CMDLINE_FORCE is not set -CONFIG_BOARD_EVM6472=y -CONFIG_NO_HZ=y -CONFIG_HIGH_RES_TIMERS=y -CONFIG_BLK_DEV_LOOP=y -CONFIG_BLK_DEV_RAM=y -CONFIG_BLK_DEV_RAM_COUNT=2 -CONFIG_BLK_DEV_RAM_SIZE=17000 -# CONFIG_INPUT is not set -# CONFIG_SERIO is not set -# CONFIG_VT is not set -# CONFIG_HW_RANDOM is not set -# CONFIG_HWMON is not set -# CONFIG_USB_SUPPORT is not set -# CONFIG_IOMMU_SUPPORT is not set -# CONFIG_MISC_FILESYSTEMS is not set -CONFIG_CRC16=y -# CONFIG_ENABLE_MUST_CHECK is not set -# CONFIG_SCHED_DEBUG is not set -# CONFIG_DEBUG_BUGVERBOSE is not set diff --git a/arch/c6x/configs/evmc6474_defconfig b/arch/c6x/configs/evmc6474_defconfig deleted file mode 100644 index 8156a98f3958..000000000000 --- a/arch/c6x/configs/evmc6474_defconfig +++ /dev/null @@ -1,40 +0,0 @@ -CONFIG_SOC_TMS320C6474=y -# CONFIG_LOCALVERSION_AUTO is not set -CONFIG_SYSVIPC=y -CONFIG_SPARSE_IRQ=y -CONFIG_LOG_BUF_SHIFT=14 -CONFIG_NAMESPACES=y -# CONFIG_UTS_NS is not set -# CONFIG_USER_NS is not set -# CONFIG_PID_NS is not set -CONFIG_BLK_DEV_INITRD=y -CONFIG_CC_OPTIMIZE_FOR_SIZE=y -CONFIG_EXPERT=y -# CONFIG_FUTEX is not set -# CONFIG_SLUB_DEBUG is not set -CONFIG_MODULES=y -CONFIG_MODULE_FORCE_LOAD=y -CONFIG_MODULE_UNLOAD=y -CONFIG_MODULE_FORCE_UNLOAD=y -CONFIG_CMDLINE_BOOL=y -CONFIG_CMDLINE="" -# CONFIG_CMDLINE_FORCE is not set -CONFIG_BOARD_EVM6474=y -CONFIG_NO_HZ=y -CONFIG_HIGH_RES_TIMERS=y -CONFIG_BLK_DEV_LOOP=y -CONFIG_BLK_DEV_RAM=y -CONFIG_BLK_DEV_RAM_COUNT=2 -CONFIG_BLK_DEV_RAM_SIZE=17000 -# CONFIG_INPUT is not set -# CONFIG_SERIO is not set -# CONFIG_VT is not set -# CONFIG_HW_RANDOM is not set -# CONFIG_HWMON is not set -# CONFIG_USB_SUPPORT is not set -# CONFIG_IOMMU_SUPPORT is not set -# CONFIG_MISC_FILESYSTEMS is not set -CONFIG_CRC16=y -# CONFIG_ENABLE_MUST_CHECK is not set -# CONFIG_SCHED_DEBUG is not set -# CONFIG_DEBUG_BUGVERBOSE is not set diff --git a/arch/c6x/configs/evmc6678_defconfig b/arch/c6x/configs/evmc6678_defconfig deleted file mode 100644 index c4f433c25b69..000000000000 --- a/arch/c6x/configs/evmc6678_defconfig +++ /dev/null @@ -1,40 +0,0 @@ -CONFIG_SOC_TMS320C6678=y -# CONFIG_LOCALVERSION_AUTO is not set -CONFIG_SYSVIPC=y -CONFIG_SPARSE_IRQ=y -CONFIG_LOG_BUF_SHIFT=14 -CONFIG_NAMESPACES=y -# CONFIG_UTS_NS is not set -# CONFIG_USER_NS is not set -# CONFIG_PID_NS is not set -CONFIG_BLK_DEV_INITRD=y -CONFIG_CC_OPTIMIZE_FOR_SIZE=y -CONFIG_EXPERT=y -# CONFIG_FUTEX is not set -# CONFIG_SLUB_DEBUG is not set -CONFIG_MODULES=y -CONFIG_MODULE_FORCE_LOAD=y -CONFIG_MODULE_UNLOAD=y -CONFIG_MODULE_FORCE_UNLOAD=y -CONFIG_CMDLINE_BOOL=y -CONFIG_CMDLINE="" -# CONFIG_CMDLINE_FORCE is not set -CONFIG_BOARD_EVM6678=y -CONFIG_NO_HZ=y -CONFIG_HIGH_RES_TIMERS=y -CONFIG_BLK_DEV_LOOP=y -CONFIG_BLK_DEV_RAM=y -CONFIG_BLK_DEV_RAM_COUNT=2 -CONFIG_BLK_DEV_RAM_SIZE=17000 -# CONFIG_INPUT is not set -# CONFIG_SERIO is not set -# CONFIG_VT is not set -# CONFIG_HW_RANDOM is not set -# CONFIG_HWMON is not set -# CONFIG_USB_SUPPORT is not set -# CONFIG_IOMMU_SUPPORT is not set -# CONFIG_MISC_FILESYSTEMS is not set -CONFIG_CRC16=y -# CONFIG_ENABLE_MUST_CHECK is not set -# CONFIG_SCHED_DEBUG is not set -# CONFIG_DEBUG_BUGVERBOSE is not set diff --git a/arch/c6x/include/asm/Kbuild b/arch/c6x/include/asm/Kbuild deleted file mode 100644 index a4ef93a1f7ae..000000000000 --- a/arch/c6x/include/asm/Kbuild +++ /dev/null @@ -1,5 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0 -generic-y += extable.h -generic-y += kvm_para.h -generic-y += mcs_spinlock.h -generic-y += user.h diff --git a/arch/c6x/include/asm/asm-offsets.h b/arch/c6x/include/asm/asm-offsets.h deleted file mode 100644 index d370ee36a182..000000000000 --- a/arch/c6x/include/asm/asm-offsets.h +++ /dev/null @@ -1 +0,0 @@ -#include diff --git a/arch/c6x/include/asm/bitops.h b/arch/c6x/include/asm/bitops.h deleted file mode 100644 index 50e618f38a11..000000000000 --- a/arch/c6x/include/asm/bitops.h +++ /dev/null @@ -1,95 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ -/* - * Port on Texas Instruments TMS320C6x architecture - * - * Copyright (C) 2004, 2009, 2010 Texas Instruments Incorporated - * Author: Aurelien Jacquiot (aurelien.jacquiot@jaluna.com) - */ -#ifndef _ASM_C6X_BITOPS_H -#define _ASM_C6X_BITOPS_H - -#ifdef __KERNEL__ - -#include -#include -#include - -/* - * We are lucky, DSP is perfect for bitops: do it in 3 cycles - */ - -/** - * __ffs - find first bit in word. - * @word: The word to search - * - * Undefined if no bit exists, so code should check against 0 first. - * Note __ffs(0) = undef, __ffs(1) = 0, __ffs(0x80000000) = 31. - * - */ -static inline unsigned long __ffs(unsigned long x) -{ - asm (" bitr .M1 %0,%0\n" - " nop\n" - " lmbd .L1 1,%0,%0\n" - : "+a"(x)); - - return x; -} - -/* - * ffz - find first zero in word. - * @word: The word to search - * - * Undefined if no zero exists, so code should check against ~0UL first. - */ -#define ffz(x) __ffs(~(x)) - -/** - * fls - find last (most-significant) bit set - * @x: the word to search - * - * This is defined the same way as ffs. - * Note fls(0) = 0, fls(1) = 1, fls(0x80000000) = 32. - */ -static inline int fls(unsigned int x) -{ - if (!x) - return 0; - - asm (" lmbd .L1 1,%0,%0\n" : "+a"(x)); - - return 32 - x; -} - -/** - * ffs - find first bit set - * @x: the word to search - * - * This is defined the same way as - * the libc and compiler builtin ffs routines, therefore - * differs in spirit from the above ffz (man ffs). - * Note ffs(0) = 0, ffs(1) = 1, ffs(0x80000000) = 32. - */ -static inline int ffs(int x) -{ - if (!x) - return 0; - - return __ffs(x) + 1; -} - -#include -#include -#include - -#include -#include -#include - -#include -#include -#include -#include - -#endif /* __KERNEL__ */ -#endif /* _ASM_C6X_BITOPS_H */ diff --git a/arch/c6x/include/asm/bug.h b/arch/c6x/include/asm/bug.h deleted file mode 100644 index 1a68676256ee..000000000000 --- a/arch/c6x/include/asm/bug.h +++ /dev/null @@ -1,20 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ -/* - * Port on Texas Instruments TMS320C6x architecture - * - * Copyright (C) 2004, 2009, 2010, 2011 Texas Instruments Incorporated - * Author: Aurelien Jacquiot (aurelien.jacquiot@jaluna.com) - */ -#ifndef _ASM_C6X_BUG_H -#define _ASM_C6X_BUG_H - -#include -#include - -struct pt_regs; - -extern void die(char *str, struct pt_regs *fp, int nr); -extern asmlinkage int process_exception(struct pt_regs *regs); -extern asmlinkage void enable_exception(void); - -#endif /* _ASM_C6X_BUG_H */ diff --git a/arch/c6x/include/asm/cache.h b/arch/c6x/include/asm/cache.h deleted file mode 100644 index 0fa8bf77c954..000000000000 --- a/arch/c6x/include/asm/cache.h +++ /dev/null @@ -1,94 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ -/* - * Port on Texas Instruments TMS320C6x architecture - * - * Copyright (C) 2005, 2006, 2009, 2010, 2012 Texas Instruments Incorporated - * Author: Aurelien Jacquiot (aurelien.jacquiot@jaluna.com) - */ -#ifndef _ASM_C6X_CACHE_H -#define _ASM_C6X_CACHE_H - -#include -#include - -/* - * Cache line size - */ -#define L1D_CACHE_SHIFT 6 -#define L1D_CACHE_BYTES (1 << L1D_CACHE_SHIFT) - -#define L1P_CACHE_SHIFT 5 -#define L1P_CACHE_BYTES (1 << L1P_CACHE_SHIFT) - -#define L2_CACHE_SHIFT 7 -#define L2_CACHE_BYTES (1 << L2_CACHE_SHIFT) - -/* - * L2 used as cache - */ -#define L2MODE_SIZE L2MODE_256K_CACHE - -/* - * For practical reasons the L1_CACHE_BYTES defines should not be smaller than - * the L2 line size - */ -#define L1_CACHE_SHIFT L2_CACHE_SHIFT -#define L1_CACHE_BYTES (1 << L1_CACHE_SHIFT) - -#define L2_CACHE_ALIGN_LOW(x) \ - (((x) & ~(L2_CACHE_BYTES - 1))) -#define L2_CACHE_ALIGN_UP(x) \ - (((x) + (L2_CACHE_BYTES - 1)) & ~(L2_CACHE_BYTES - 1)) -#define L2_CACHE_ALIGN_CNT(x) \ - (((x) + (sizeof(int) - 1)) & ~(sizeof(int) - 1)) - -#define ARCH_DMA_MINALIGN L1_CACHE_BYTES -#define ARCH_SLAB_MINALIGN L1_CACHE_BYTES - -/* - * This is the granularity of hardware cacheability control. - */ -#define CACHEABILITY_ALIGN 0x01000000 - -/* - * Align a physical address to MAR regions - */ -#define CACHE_REGION_START(v) \ - (((u32) (v)) & ~(CACHEABILITY_ALIGN - 1)) -#define CACHE_REGION_END(v) \ - (((u32) (v) + (CACHEABILITY_ALIGN - 1)) & ~(CACHEABILITY_ALIGN - 1)) - -extern void __init c6x_cache_init(void); - -extern void enable_caching(unsigned long start, unsigned long end); -extern void disable_caching(unsigned long start, unsigned long end); - -extern void L1_cache_off(void); -extern void L1_cache_on(void); - -extern void L1P_cache_global_invalidate(void); -extern void L1D_cache_global_invalidate(void); -extern void L1D_cache_global_writeback(void); -extern void L1D_cache_global_writeback_invalidate(void); -extern void L2_cache_set_mode(unsigned int mode); -extern void L2_cache_global_writeback_invalidate(void); -extern void L2_cache_global_writeback(void); - -extern void L1P_cache_block_invalidate(unsigned int start, unsigned int end); -extern void L1D_cache_block_invalidate(unsigned int start, unsigned int end); -extern void L1D_cache_block_writeback_invalidate(unsigned int start, - unsigned int end); -extern void L1D_cache_block_writeback(unsigned int start, unsigned int end); -extern void L2_cache_block_invalidate(unsigned int start, unsigned int end); -extern void L2_cache_block_writeback(unsigned int start, unsigned int end); -extern void L2_cache_block_writeback_invalidate(unsigned int start, - unsigned int end); -extern void L2_cache_block_invalidate_nowait(unsigned int start, - unsigned int end); -extern void L2_cache_block_writeback_nowait(unsigned int start, - unsigned int end); - -extern void L2_cache_block_writeback_invalidate_nowait(unsigned int start, - unsigned int end); - -#endif /* _ASM_C6X_CACHE_H */ diff --git a/arch/c6x/include/asm/cacheflush.h b/arch/c6x/include/asm/cacheflush.h deleted file mode 100644 index 10922d528de6..000000000000 --- a/arch/c6x/include/asm/cacheflush.h +++ /dev/null @@ -1,45 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ -/* - * Port on Texas Instruments TMS320C6x architecture - * - * Copyright (C) 2004, 2009, 2010 Texas Instruments Incorporated - * Author: Aurelien Jacquiot (aurelien.jacquiot@jaluna.com) - */ -#ifndef _ASM_C6X_CACHEFLUSH_H -#define _ASM_C6X_CACHEFLUSH_H - -#include - -#include -#include -#include -#include -#include - -/* - * physically-indexed cache management - */ -#define flush_icache_range(s, e) \ -do { \ - L1D_cache_block_writeback((s), (e)); \ - L1P_cache_block_invalidate((s), (e)); \ -} while (0) - -#define flush_icache_page(vma, page) \ -do { \ - if ((vma)->vm_flags & PROT_EXEC) \ - L1D_cache_block_writeback_invalidate(page_address(page), \ - (unsigned long) page_address(page) + PAGE_SIZE)); \ - L1P_cache_block_invalidate(page_address(page), \ - (unsigned long) page_address(page) + PAGE_SIZE)); \ -} while (0) - -#define copy_to_user_page(vma, page, vaddr, dst, src, len) \ -do { \ - memcpy(dst, src, len); \ - flush_icache_range((unsigned) (dst), (unsigned) (dst) + (len)); \ -} while (0) - -#include - -#endif /* _ASM_C6X_CACHEFLUSH_H */ diff --git a/arch/c6x/include/asm/checksum.h b/arch/c6x/include/asm/checksum.h deleted file mode 100644 index 934918def632..000000000000 --- a/arch/c6x/include/asm/checksum.h +++ /dev/null @@ -1,34 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ -/* - * Copyright (C) 2011 Texas Instruments Incorporated - * Author: Mark Salter - */ -#ifndef _ASM_C6X_CHECKSUM_H -#define _ASM_C6X_CHECKSUM_H - -static inline __wsum -csum_tcpudp_nofold(__be32 saddr, __be32 daddr, __u32 len, - __u8 proto, __wsum sum) -{ - unsigned long long tmp; - - asm ("add .d1 %1,%5,%1\n" - "|| addu .l1 %3,%4,%0\n" - "addu .l1 %2,%0,%0\n" -#ifndef CONFIG_CPU_BIG_ENDIAN - "|| shl .s1 %1,8,%1\n" -#endif - "addu .l1 %1,%0,%0\n" - "add .l1 %P0,%p0,%2\n" - : "=&a"(tmp), "+a"(len), "+a"(sum) - : "a" (saddr), "a" (daddr), "a" (proto)); - return sum; -} -#define csum_tcpudp_nofold csum_tcpudp_nofold - -#define _HAVE_ARCH_CSUM_AND_COPY -extern __wsum csum_partial_copy_nocheck(const void *src, void *dst, int len); - -#include - -#endif /* _ASM_C6X_CHECKSUM_H */ diff --git a/arch/c6x/include/asm/clock.h b/arch/c6x/include/asm/clock.h deleted file mode 100644 index 7b6c42a52ec9..000000000000 --- a/arch/c6x/include/asm/clock.h +++ /dev/null @@ -1,145 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ -/* - * TI C64X clock definitions - * - * Copyright (C) 2010, 2011 Texas Instruments. - * Contributed by: Mark Salter - * - * Copied heavily from arm/mach-davinci/clock.h, so: - * - * Copyright (C) 2006-2007 Texas Instruments. - * Copyright (C) 2008-2009 Deep Root Systems, LLC - */ - -#ifndef _ASM_C6X_CLOCK_H -#define _ASM_C6X_CLOCK_H - -#ifndef __ASSEMBLER__ - -#include - -/* PLL/Reset register offsets */ -#define PLLCTL 0x100 -#define PLLM 0x110 -#define PLLPRE 0x114 -#define PLLDIV1 0x118 -#define PLLDIV2 0x11c -#define PLLDIV3 0x120 -#define PLLPOST 0x128 -#define PLLCMD 0x138 -#define PLLSTAT 0x13c -#define PLLALNCTL 0x140 -#define PLLDCHANGE 0x144 -#define PLLCKEN 0x148 -#define PLLCKSTAT 0x14c -#define PLLSYSTAT 0x150 -#define PLLDIV4 0x160 -#define PLLDIV5 0x164 -#define PLLDIV6 0x168 -#define PLLDIV7 0x16c -#define PLLDIV8 0x170 -#define PLLDIV9 0x174 -#define PLLDIV10 0x178 -#define PLLDIV11 0x17c -#define PLLDIV12 0x180 -#define PLLDIV13 0x184 -#define PLLDIV14 0x188 -#define PLLDIV15 0x18c -#define PLLDIV16 0x190 - -/* PLLM register bits */ -#define PLLM_PLLM_MASK 0xff -#define PLLM_VAL(x) ((x) - 1) - -/* PREDIV register bits */ -#define PLLPREDIV_EN BIT(15) -#define PLLPREDIV_VAL(x) ((x) - 1) - -/* PLLCTL register bits */ -#define PLLCTL_PLLEN BIT(0) -#define PLLCTL_PLLPWRDN BIT(1) -#define PLLCTL_PLLRST BIT(3) -#define PLLCTL_PLLDIS BIT(4) -#define PLLCTL_PLLENSRC BIT(5) -#define PLLCTL_CLKMODE BIT(8) - -/* PLLCMD register bits */ -#define PLLCMD_GOSTAT BIT(0) - -/* PLLSTAT register bits */ -#define PLLSTAT_GOSTAT BIT(0) - -/* PLLDIV register bits */ -#define PLLDIV_EN BIT(15) -#define PLLDIV_RATIO_MASK 0x1f -#define PLLDIV_RATIO(x) ((x) - 1) - -struct pll_data; - -struct clk { - struct list_head node; - struct module *owner; - const char *name; - unsigned long rate; - int usecount; - u32 flags; - struct clk *parent; - struct list_head children; /* list of children */ - struct list_head childnode; /* parent's child list node */ - struct pll_data *pll_data; - u32 div; - unsigned long (*recalc) (struct clk *); - int (*set_rate) (struct clk *clk, unsigned long rate); - int (*round_rate) (struct clk *clk, unsigned long rate); -}; - -/* Clock flags: SoC-specific flags start at BIT(16) */ -#define ALWAYS_ENABLED BIT(1) -#define CLK_PLL BIT(2) /* PLL-derived clock */ -#define PRE_PLL BIT(3) /* source is before PLL mult/div */ -#define FIXED_DIV_PLL BIT(4) /* fixed divisor from PLL */ -#define FIXED_RATE_PLL BIT(5) /* fixed output rate PLL */ - -#define MAX_PLL_SYSCLKS 16 - -struct pll_data { - void __iomem *base; - u32 num; - u32 flags; - u32 input_rate; - u32 bypass_delay; /* in loops */ - u32 reset_delay; /* in loops */ - u32 lock_delay; /* in loops */ - struct clk sysclks[MAX_PLL_SYSCLKS + 1]; -}; - -/* pll_data flag bit */ -#define PLL_HAS_PRE BIT(0) -#define PLL_HAS_MUL BIT(1) -#define PLL_HAS_POST BIT(2) - -#define CLK(dev, con, ck) \ - { \ - .dev_id = dev, \ - .con_id = con, \ - .clk = ck, \ - } \ - -extern void c6x_clks_init(struct clk_lookup *clocks); -extern int clk_register(struct clk *clk); -extern void clk_unregister(struct clk *clk); -extern void c64x_setup_clocks(void); - -extern struct pll_data c6x_soc_pll1; - -extern struct clk clkin1; -extern struct clk c6x_core_clk; -extern struct clk c6x_i2c_clk; -extern struct clk c6x_watchdog_clk; -extern struct clk c6x_mcbsp1_clk; -extern struct clk c6x_mcbsp2_clk; -extern struct clk c6x_mdio_clk; - -#endif - -#endif /* _ASM_C6X_CLOCK_H */ diff --git a/arch/c6x/include/asm/cmpxchg.h b/arch/c6x/include/asm/cmpxchg.h deleted file mode 100644 index 6eed628a9e7f..000000000000 --- a/arch/c6x/include/asm/cmpxchg.h +++ /dev/null @@ -1,63 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ -/* - * Port on Texas Instruments TMS320C6x architecture - * - * Copyright (C) 2004, 2009, 2010, 2011 Texas Instruments Incorporated - * Author: Aurelien Jacquiot (aurelien.jacquiot@jaluna.com) - */ -#ifndef _ASM_C6X_CMPXCHG_H -#define _ASM_C6X_CMPXCHG_H - -#include - -/* - * Misc. functions - */ -static inline unsigned int __xchg(unsigned int x, volatile void *ptr, int size) -{ - unsigned int tmp; - unsigned long flags; - - local_irq_save(flags); - - switch (size) { - case 1: - tmp = 0; - tmp = *((unsigned char *) ptr); - *((unsigned char *) ptr) = (unsigned char) x; - break; - case 2: - tmp = 0; - tmp = *((unsigned short *) ptr); - *((unsigned short *) ptr) = x; - break; - case 4: - tmp = 0; - tmp = *((unsigned int *) ptr); - *((unsigned int *) ptr) = x; - break; - } - local_irq_restore(flags); - return tmp; -} - -#define xchg(ptr, x) \ - ((__typeof__(*(ptr)))__xchg((unsigned int)(x), (void *) (ptr), \ - sizeof(*(ptr)))) - -#include - -/* - * cmpxchg_local and cmpxchg64_local are atomic wrt current CPU. Always make - * them available. - */ -#define cmpxchg_local(ptr, o, n) \ - ((__typeof__(*(ptr)))__cmpxchg_local_generic((ptr), \ - (unsigned long)(o), \ - (unsigned long)(n), \ - sizeof(*(ptr)))) -#define cmpxchg64_local(ptr, o, n) __cmpxchg64_local_generic((ptr), (o), (n)) - -#include - -#endif /* _ASM_C6X_CMPXCHG_H */ diff --git a/arch/c6x/include/asm/delay.h b/arch/c6x/include/asm/delay.h deleted file mode 100644 index 455fc713ae54..000000000000 --- a/arch/c6x/include/asm/delay.h +++ /dev/null @@ -1,64 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ -/* - * Port on Texas Instruments TMS320C6x architecture - * - * Copyright (C) 2004, 2009, 2010, 2011 Texas Instruments Incorporated - * Author: Aurelien Jacquiot (aurelien.jacquiot@jaluna.com) - */ -#ifndef _ASM_C6X_DELAY_H -#define _ASM_C6X_DELAY_H - -#include - -extern unsigned int ticks_per_ns_scaled; - -static inline void __delay(unsigned long loops) -{ - uint32_t tmp; - - /* 6 cycles per loop */ - asm volatile (" mv .s1 %0,%1\n" - "0: [%1] b .s1 0b\n" - " add .l1 -6,%0,%0\n" - " cmplt .l1 1,%0,%1\n" - " nop 3\n" - : "+a"(loops), "=A"(tmp)); -} - -static inline void _c6x_tickdelay(unsigned int x) -{ - uint32_t cnt, endcnt; - - asm volatile (" mvc .s2 TSCL,%0\n" - " add .s2x %0,%1,%2\n" - " || mvk .l2 1,B0\n" - "0: [B0] b .s2 0b\n" - " mvc .s2 TSCL,%0\n" - " sub .s2 %0,%2,%0\n" - " cmpgt .l2 0,%0,B0\n" - " nop 2\n" - : "=b"(cnt), "+a"(x), "=b"(endcnt) : : "B0"); -} - -/* use scaled math to avoid slow division */ -#define C6X_NDELAY_SCALE 10 - -static inline void _ndelay(unsigned int n) -{ - _c6x_tickdelay((ticks_per_ns_scaled * n) >> C6X_NDELAY_SCALE); -} - -static inline void _udelay(unsigned int n) -{ - while (n >= 10) { - _ndelay(10000); - n -= 10; - } - while (n-- > 0) - _ndelay(1000); -} - -#define udelay(x) _udelay((unsigned int)(x)) -#define ndelay(x) _ndelay((unsigned int)(x)) - -#endif /* _ASM_C6X_DELAY_H */ diff --git a/arch/c6x/include/asm/dscr.h b/arch/c6x/include/asm/dscr.h deleted file mode 100644 index f6b095c3d3f5..000000000000 --- a/arch/c6x/include/asm/dscr.h +++ /dev/null @@ -1,30 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ -/* - * Copyright (C) 2011 Texas Instruments Incorporated - * Author: Mark Salter - */ -#ifndef _ASM_C6X_DSCR_H -#define _ASM_C6X_DSCR_H - -enum dscr_devstate_t { - DSCR_DEVSTATE_ENABLED, - DSCR_DEVSTATE_DISABLED, -}; - -/* - * Set the device state of the device with the given ID. - * - * Individual drivers should use this to enable or disable the - * hardware device. The devid used to identify the device being - * controlled should be a property in the device's tree node. - */ -extern void dscr_set_devstate(int devid, enum dscr_devstate_t state); - -/* - * Assert or de-assert an RMII reset. - */ -extern void dscr_rmii_reset(int id, int assert); - -extern void dscr_probe(void); - -#endif /* _ASM_C6X_DSCR_H */ diff --git a/arch/c6x/include/asm/elf.h b/arch/c6x/include/asm/elf.h deleted file mode 100644 index ca88acbf560b..000000000000 --- a/arch/c6x/include/asm/elf.h +++ /dev/null @@ -1,117 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ -/* - * Port on Texas Instruments TMS320C6x architecture - * - * Copyright (C) 2004, 2009, 2010 Texas Instruments Incorporated - * Author: Aurelien Jacquiot (aurelien.jacquiot@jaluna.com) - */ -#ifndef _ASM_C6X_ELF_H -#define _ASM_C6X_ELF_H - -/* - * ELF register definitions.. - */ -#include - -typedef unsigned long elf_greg_t; -typedef unsigned long elf_fpreg_t; - -#define ELF_NGREG 58 -#define ELF_NFPREG 1 - -typedef elf_greg_t elf_gregset_t[ELF_NGREG]; -typedef elf_fpreg_t elf_fpregset_t[ELF_NFPREG]; - -/* - * This is used to ensure we don't load something for the wrong architecture. - */ -#define elf_check_arch(x) ((x)->e_machine == EM_TI_C6000) - -#define elf_check_fdpic(x) (1) -#define elf_check_const_displacement(x) (0) - -#define ELF_FDPIC_PLAT_INIT(_regs, _exec_map, _interp_map, _dynamic_addr) \ -do { \ - _regs->b4 = (_exec_map); \ - _regs->a6 = (_interp_map); \ - _regs->b6 = (_dynamic_addr); \ -} while (0) - -#define ELF_FDPIC_CORE_EFLAGS 0 - -/* - * These are used to set parameters in the core dumps. - */ -#ifdef __LITTLE_ENDIAN__ -#define ELF_DATA ELFDATA2LSB -#else -#define ELF_DATA ELFDATA2MSB -#endif - -#define ELF_CLASS ELFCLASS32 -#define ELF_ARCH EM_TI_C6000 - -/* Nothing for now. Need to setup DP... */ -#define ELF_PLAT_INIT(_r) - -#define ELF_EXEC_PAGESIZE 4096 - -#define ELF_CORE_COPY_REGS(_dest, _regs) \ - memcpy((char *) &_dest, (char *) _regs, \ - sizeof(struct pt_regs)); - -/* This yields a mask that user programs can use to figure out what - instruction set this cpu supports. */ - -#define ELF_HWCAP (0) - -/* This yields a string that ld.so will use to load implementation - specific libraries for optimization. This is more specific in - intent than poking at uname or /proc/cpuinfo. */ - -#define ELF_PLATFORM (NULL) - -/* C6X specific section types */ -#define SHT_C6000_UNWIND 0x70000001 -#define SHT_C6000_PREEMPTMAP 0x70000002 -#define SHT_C6000_ATTRIBUTES 0x70000003 - -/* C6X specific DT_ tags */ -#define DT_C6000_DSBT_BASE 0x70000000 -#define DT_C6000_DSBT_SIZE 0x70000001 -#define DT_C6000_PREEMPTMAP 0x70000002 -#define DT_C6000_DSBT_INDEX 0x70000003 - -/* C6X specific relocs */ -#define R_C6000_NONE 0 -#define R_C6000_ABS32 1 -#define R_C6000_ABS16 2 -#define R_C6000_ABS8 3 -#define R_C6000_PCR_S21 4 -#define R_C6000_PCR_S12 5 -#define R_C6000_PCR_S10 6 -#define R_C6000_PCR_S7 7 -#define R_C6000_ABS_S16 8 -#define R_C6000_ABS_L16 9 -#define R_C6000_ABS_H16 10 -#define R_C6000_SBR_U15_B 11 -#define R_C6000_SBR_U15_H 12 -#define R_C6000_SBR_U15_W 13 -#define R_C6000_SBR_S16 14 -#define R_C6000_SBR_L16_B 15 -#define R_C6000_SBR_L16_H 16 -#define R_C6000_SBR_L16_W 17 -#define R_C6000_SBR_H16_B 18 -#define R_C6000_SBR_H16_H 19 -#define R_C6000_SBR_H16_W 20 -#define R_C6000_SBR_GOT_U15_W 21 -#define R_C6000_SBR_GOT_L16_W 22 -#define R_C6000_SBR_GOT_H16_W 23 -#define R_C6000_DSBT_INDEX 24 -#define R_C6000_PREL31 25 -#define R_C6000_COPY 26 -#define R_C6000_ALIGN 253 -#define R_C6000_FPHEAD 254 -#define R_C6000_NOCMP 255 - -#endif /*_ASM_C6X_ELF_H */ diff --git a/arch/c6x/include/asm/flat.h b/arch/c6x/include/asm/flat.h deleted file mode 100644 index 9e6544b51386..000000000000 --- a/arch/c6x/include/asm/flat.h +++ /dev/null @@ -1,19 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -#ifndef __ASM_C6X_FLAT_H -#define __ASM_C6X_FLAT_H - -#include - -static inline int flat_get_addr_from_rp(u32 __user *rp, u32 relval, u32 flags, - u32 *addr) -{ - *addr = get_unaligned((__force u32 *)rp); - return 0; -} -static inline int flat_put_addr_at_rp(u32 __user *rp, u32 addr, u32 rel) -{ - put_unaligned(addr, (__force u32 *)rp); - return 0; -} - -#endif /* __ASM_C6X_FLAT_H */ diff --git a/arch/c6x/include/asm/ftrace.h b/arch/c6x/include/asm/ftrace.h deleted file mode 100644 index 3701958d3d1c..000000000000 --- a/arch/c6x/include/asm/ftrace.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef _ASM_C6X_FTRACE_H -#define _ASM_C6X_FTRACE_H - -/* empty */ - -#endif /* _ASM_C6X_FTRACE_H */ diff --git a/arch/c6x/include/asm/hardirq.h b/arch/c6x/include/asm/hardirq.h deleted file mode 100644 index f37d07d31040..000000000000 --- a/arch/c6x/include/asm/hardirq.h +++ /dev/null @@ -1,17 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ -/* - * Port on Texas Instruments TMS320C6x architecture - * - * Copyright (C) 2004, 2009, 2010 Texas Instruments Incorporated - * Author: Aurelien Jacquiot (aurelien.jacquiot@jaluna.com) - */ - -#ifndef _ASM_C6X_HARDIRQ_H -#define _ASM_C6X_HARDIRQ_H - -extern void ack_bad_irq(int irq); -#define ack_bad_irq ack_bad_irq - -#include - -#endif /* _ASM_C6X_HARDIRQ_H */ diff --git a/arch/c6x/include/asm/irq.h b/arch/c6x/include/asm/irq.h deleted file mode 100644 index 9da4d1afd0d7..000000000000 --- a/arch/c6x/include/asm/irq.h +++ /dev/null @@ -1,50 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ -/* - * Port on Texas Instruments TMS320C6x architecture - * - * Copyright (C) 2004, 2006, 2009, 2010, 2011 Texas Instruments Incorporated - * Author: Aurelien Jacquiot (aurelien.jacquiot@jaluna.com) - * - * Large parts taken directly from powerpc. - */ -#ifndef _ASM_C6X_IRQ_H -#define _ASM_C6X_IRQ_H - -#include -#include -#include -#include -#include - -#define irq_canonicalize(irq) (irq) - -/* - * The C64X+ core has 16 IRQ vectors. One each is used by Reset and NMI. Two - * are reserved. The remaining 12 vectors are used to route SoC interrupts. - * These interrupt vectors are prioritized with IRQ 4 having the highest - * priority and IRQ 15 having the lowest. - * - * The C64x+ megamodule provides a PIC which combines SoC IRQ sources into a - * single core IRQ vector. There are four combined sources, each of which - * feed into one of the 12 general interrupt vectors. The remaining 8 vectors - * can each route a single SoC interrupt directly. - */ -#define NR_PRIORITY_IRQS 16 - -/* Total number of virq in the platform */ -#define NR_IRQS 256 - -/* This number is used when no interrupt has been assigned */ -#define NO_IRQ 0 - -extern void __init init_pic_c64xplus(void); - -extern void init_IRQ(void); - -struct pt_regs; - -extern asmlinkage void c6x_do_IRQ(unsigned int prio, struct pt_regs *regs); - -extern unsigned long irq_err_count; - -#endif /* _ASM_C6X_IRQ_H */ diff --git a/arch/c6x/include/asm/irqflags.h b/arch/c6x/include/asm/irqflags.h deleted file mode 100644 index d6cd71c02629..000000000000 --- a/arch/c6x/include/asm/irqflags.h +++ /dev/null @@ -1,68 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-or-later */ -/* - * C6X IRQ flag handling - * - * Copyright (C) 2010 Texas Instruments Incorporated - * Written by Mark Salter (msalter@redhat.com) - */ - -#ifndef _ASM_IRQFLAGS_H -#define _ASM_IRQFLAGS_H - -#ifndef __ASSEMBLY__ - -/* read interrupt enabled status */ -static inline unsigned long arch_local_save_flags(void) -{ - unsigned long flags; - - asm volatile (" mvc .s2 CSR,%0\n" : "=b"(flags)); - return flags; -} - -/* set interrupt enabled status */ -static inline void arch_local_irq_restore(unsigned long flags) -{ - asm volatile (" mvc .s2 %0,CSR\n" : : "b"(flags) : "memory"); -} - -/* unconditionally enable interrupts */ -static inline void arch_local_irq_enable(void) -{ - unsigned long flags = arch_local_save_flags(); - flags |= 1; - arch_local_irq_restore(flags); -} - -/* unconditionally disable interrupts */ -static inline void arch_local_irq_disable(void) -{ - unsigned long flags = arch_local_save_flags(); - flags &= ~1; - arch_local_irq_restore(flags); -} - -/* get status and disable interrupts */ -static inline unsigned long arch_local_irq_save(void) -{ - unsigned long flags; - - flags = arch_local_save_flags(); - arch_local_irq_restore(flags & ~1); - return flags; -} - -/* test flags */ -static inline int arch_irqs_disabled_flags(unsigned long flags) -{ - return (flags & 1) == 0; -} - -/* test hardware interrupt enable bit */ -static inline int arch_irqs_disabled(void) -{ - return arch_irqs_disabled_flags(arch_local_save_flags()); -} - -#endif /* __ASSEMBLY__ */ -#endif /* __ASM_IRQFLAGS_H */ diff --git a/arch/c6x/include/asm/linkage.h b/arch/c6x/include/asm/linkage.h deleted file mode 100644 index 1ad615da6479..000000000000 --- a/arch/c6x/include/asm/linkage.h +++ /dev/null @@ -1,31 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -#ifndef _ASM_C6X_LINKAGE_H -#define _ASM_C6X_LINKAGE_H - -#ifdef __ASSEMBLER__ - -#define __ALIGN .align 2 -#define __ALIGN_STR ".align 2" - -#ifndef __DSBT__ -#define ENTRY(name) \ - .global name @ \ - __ALIGN @ \ -name: -#else -#define ENTRY(name) \ - .global name @ \ - .hidden name @ \ - __ALIGN @ \ -name: -#endif - -#define ENDPROC(name) \ - .type name, @function @ \ - .size name, . - name - -#endif - -#include - -#endif /* _ASM_C6X_LINKAGE_H */ diff --git a/arch/c6x/include/asm/megamod-pic.h b/arch/c6x/include/asm/megamod-pic.h deleted file mode 100644 index a0a6d596bf9b..000000000000 --- a/arch/c6x/include/asm/megamod-pic.h +++ /dev/null @@ -1,10 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -#ifndef _C6X_MEGAMOD_PIC_H -#define _C6X_MEGAMOD_PIC_H - -#ifdef __KERNEL__ - -extern void __init megamod_pic_init(void); - -#endif /* __KERNEL__ */ -#endif /* _C6X_MEGAMOD_PIC_H */ diff --git a/arch/c6x/include/asm/mmu_context.h b/arch/c6x/include/asm/mmu_context.h deleted file mode 100644 index d2659d0a3297..000000000000 --- a/arch/c6x/include/asm/mmu_context.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef _ASM_C6X_MMU_CONTEXT_H -#define _ASM_C6X_MMU_CONTEXT_H - -#include - -#endif /* _ASM_C6X_MMU_CONTEXT_H */ diff --git a/arch/c6x/include/asm/module.h b/arch/c6x/include/asm/module.h deleted file mode 100644 index 9fc9f4a8ecc2..000000000000 --- a/arch/c6x/include/asm/module.h +++ /dev/null @@ -1,20 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ -/* - * Port on Texas Instruments TMS320C6x architecture - * - * Copyright (C) 2004, 2009, 2010 Texas Instruments Incorporated - * Author: Aurelien Jacquiot (aurelien.jacquiot@jaluna.com) - * - * Updated for 2.6.34 by: Mark Salter (msalter@redhat.com) - */ -#ifndef _ASM_C6X_MODULE_H -#define _ASM_C6X_MODULE_H - -#include - -struct loaded_sections { - unsigned int new_vaddr; - unsigned int loaded; -}; - -#endif /* _ASM_C6X_MODULE_H */ diff --git a/arch/c6x/include/asm/page.h b/arch/c6x/include/asm/page.h deleted file mode 100644 index 40079899084d..000000000000 --- a/arch/c6x/include/asm/page.h +++ /dev/null @@ -1,9 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -#ifndef _ASM_C6X_PAGE_H -#define _ASM_C6X_PAGE_H - -#define VM_DATA_DEFAULT_FLAGS VM_DATA_FLAGS_TSK_EXEC - -#include - -#endif /* _ASM_C6X_PAGE_H */ diff --git a/arch/c6x/include/asm/pgtable.h b/arch/c6x/include/asm/pgtable.h deleted file mode 100644 index 8a91ceda39fa..000000000000 --- a/arch/c6x/include/asm/pgtable.h +++ /dev/null @@ -1,66 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ -/* - * Port on Texas Instruments TMS320C6x architecture - * - * Copyright (C) 2004, 2009, 2010 Texas Instruments Incorporated - * Author: Aurelien Jacquiot (aurelien.jacquiot@jaluna.com) - */ -#ifndef _ASM_C6X_PGTABLE_H -#define _ASM_C6X_PGTABLE_H - -#include - -#include -#include - -/* - * All 32bit addresses are effectively valid for vmalloc... - * Sort of meaningless for non-VM targets. - */ -#define VMALLOC_START 0 -#define VMALLOC_END 0xffffffff - -#define pgd_present(pgd) (1) -#define pgd_none(pgd) (0) -#define pgd_bad(pgd) (0) -#define pgd_clear(pgdp) -#define kern_addr_valid(addr) (1) - -#define pmd_none(x) (!pmd_val(x)) -#define pmd_present(x) (pmd_val(x)) -#define pmd_clear(xp) do { set_pmd(xp, __pmd(0)); } while (0) -#define pmd_bad(x) (pmd_val(x) & ~PAGE_MASK) - -#define PAGE_NONE __pgprot(0) /* these mean nothing to NO_MM */ -#define PAGE_SHARED __pgprot(0) /* these mean nothing to NO_MM */ -#define PAGE_COPY __pgprot(0) /* these mean nothing to NO_MM */ -#define PAGE_READONLY __pgprot(0) /* these mean nothing to NO_MM */ -#define PAGE_KERNEL __pgprot(0) /* these mean nothing to NO_MM */ -#define pgprot_noncached(prot) (prot) - -extern void paging_init(void); - -#define __swp_type(x) (0) -#define __swp_offset(x) (0) -#define __swp_entry(typ, off) ((swp_entry_t) { ((typ) | ((off) << 7)) }) -#define __pte_to_swp_entry(pte) ((swp_entry_t) { pte_val(pte) }) -#define __swp_entry_to_pte(x) ((pte_t) { (x).val }) - -#define set_pte(pteptr, pteval) (*(pteptr) = pteval) -#define set_pte_at(mm, addr, ptep, pteval) set_pte(ptep, pteval) - -/* - * ZERO_PAGE is a global shared page that is always zero: used - * for zero-mapped memory areas etc.. - */ -#define ZERO_PAGE(vaddr) virt_to_page(empty_zero_page) -extern unsigned long empty_zero_page; - -#define swapper_pg_dir ((pgd_t *) 0) - -/* - * c6x is !MMU, so define the simpliest implementation - */ -#define pgprot_writecombine pgprot_noncached - -#endif /* _ASM_C6X_PGTABLE_H */ diff --git a/arch/c6x/include/asm/processor.h b/arch/c6x/include/asm/processor.h deleted file mode 100644 index 1456f5e11de3..000000000000 --- a/arch/c6x/include/asm/processor.h +++ /dev/null @@ -1,114 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ -/* - * Port on Texas Instruments TMS320C6x architecture - * - * Copyright (C) 2004, 2009, 2010, 2011 Texas Instruments Incorporated - * Author: Aurelien Jacquiot (aurelien.jacquiot@jaluna.com) - * - * Updated for 2.6.34: Mark Salter - */ -#ifndef _ASM_C6X_PROCESSOR_H -#define _ASM_C6X_PROCESSOR_H - -#include -#include -#include - -/* - * User space process size. This is mostly meaningless for NOMMU - * but some C6X processors may have RAM addresses up to 0xFFFFFFFF. - * Since calls like mmap() can return an address or an error, we - * have to allow room for error returns when code does something - * like: - * - * addr = do_mmap(...) - * if ((unsigned long)addr >= TASK_SIZE) - * ... its an error code, not an address ... - * - * Here, we allow for 4096 error codes which means we really can't - * use the last 4K page on systems with RAM extending all the way - * to the end of the 32-bit address space. - */ -#define TASK_SIZE 0xFFFFF000 - -/* - * This decides where the kernel will search for a free chunk of vm - * space during mmap's. We won't be using it - */ -#define TASK_UNMAPPED_BASE 0 - -struct thread_struct { - unsigned long long b15_14; - unsigned long long a15_14; - unsigned long long b13_12; - unsigned long long a13_12; - unsigned long long b11_10; - unsigned long long a11_10; - unsigned long long ricl_icl; - unsigned long usp; /* user stack pointer */ - unsigned long pc; /* kernel pc */ - unsigned long wchan; -}; - -#define INIT_THREAD \ -{ \ - .usp = 0, \ - .wchan = 0, \ -} - -#define INIT_MMAP { \ - &init_mm, 0, 0, NULL, PAGE_SHARED, VM_READ | VM_WRITE | VM_EXEC, 1, \ - NULL, NULL } - -#define task_pt_regs(task) \ - ((struct pt_regs *)(THREAD_START_SP + task_stack_page(task)) - 1) - -#define alloc_kernel_stack() __get_free_page(GFP_KERNEL) -#define free_kernel_stack(page) free_page((page)) - - -/* Forward declaration, a strange C thing */ -struct task_struct; - -extern void start_thread(struct pt_regs *regs, unsigned int pc, - unsigned long usp); - -/* Free all resources held by a thread. */ -static inline void release_thread(struct task_struct *dead_task) -{ -} - -/* - * saved kernel SP and DP of a blocked thread. - */ -#ifdef _BIG_ENDIAN -#define thread_saved_ksp(tsk) \ - (*(unsigned long *)&(tsk)->thread.b15_14) -#define thread_saved_dp(tsk) \ - (*(((unsigned long *)&(tsk)->thread.b15_14) + 1)) -#else -#define thread_saved_ksp(tsk) \ - (*(((unsigned long *)&(tsk)->thread.b15_14) + 1)) -#define thread_saved_dp(tsk) \ - (*(unsigned long *)&(tsk)->thread.b15_14) -#endif - -extern unsigned long get_wchan(struct task_struct *p); - -#define KSTK_EIP(task) (task_pt_regs(task)->pc) -#define KSTK_ESP(task) (task_pt_regs(task)->sp) - -#define cpu_relax() do { } while (0) - -extern const struct seq_operations cpuinfo_op; - -/* Reset the board */ -#define HARD_RESET_NOW() - -extern unsigned int c6x_core_freq; - - -extern void (*c6x_restart)(void); -extern void (*c6x_halt)(void); - -#endif /* ASM_C6X_PROCESSOR_H */ diff --git a/arch/c6x/include/asm/procinfo.h b/arch/c6x/include/asm/procinfo.h deleted file mode 100644 index aaa3cb902c43..000000000000 --- a/arch/c6x/include/asm/procinfo.h +++ /dev/null @@ -1,24 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ -/* - * Copyright (C) 2010 Texas Instruments Incorporated - * Author: Mark Salter (msalter@redhat.com) - */ -#ifndef _ASM_C6X_PROCINFO_H -#define _ASM_C6X_PROCINFO_H - -#ifdef __KERNEL__ - -struct proc_info_list { - unsigned int cpu_val; - unsigned int cpu_mask; - const char *arch_name; - const char *elf_name; - unsigned int elf_hwcap; -}; - -#else /* __KERNEL__ */ -#include -#warning "Please include asm/elf.h instead" -#endif /* __KERNEL__ */ - -#endif /* _ASM_C6X_PROCINFO_H */ diff --git a/arch/c6x/include/asm/ptrace.h b/arch/c6x/include/asm/ptrace.h deleted file mode 100644 index 7cbae382cf37..000000000000 --- a/arch/c6x/include/asm/ptrace.h +++ /dev/null @@ -1,32 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ -/* - * Copyright (C) 2004, 2006, 2009, 2010 Texas Instruments Incorporated - * Author: Aurelien Jacquiot (aurelien.jacquiot@jaluna.com) - * - * Updated for 2.6.34: Mark Salter - */ -#ifndef _ASM_C6X_PTRACE_H -#define _ASM_C6X_PTRACE_H - -#include - -#ifndef __ASSEMBLY__ -#ifdef _BIG_ENDIAN -#else -#endif - -#include - -#define user_mode(regs) ((((regs)->tsr) & 0x40) != 0) - -#define instruction_pointer(regs) ((regs)->pc) -#define profile_pc(regs) instruction_pointer(regs) -#define user_stack_pointer(regs) ((regs)->sp) - -extern void show_regs(struct pt_regs *); - -extern asmlinkage unsigned long syscall_trace_entry(struct pt_regs *regs); -extern asmlinkage void syscall_trace_exit(struct pt_regs *regs); - -#endif /* __ASSEMBLY__ */ -#endif /* _ASM_C6X_PTRACE_H */ diff --git a/arch/c6x/include/asm/sections.h b/arch/c6x/include/asm/sections.h deleted file mode 100644 index dc2f15eb3bde..000000000000 --- a/arch/c6x/include/asm/sections.h +++ /dev/null @@ -1,12 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -#ifndef _ASM_C6X_SECTIONS_H -#define _ASM_C6X_SECTIONS_H - -#include - -extern char _vectors_start[]; -extern char _vectors_end[]; - -extern char _data_lma[]; - -#endif /* _ASM_C6X_SECTIONS_H */ diff --git a/arch/c6x/include/asm/setup.h b/arch/c6x/include/asm/setup.h deleted file mode 100644 index 5496bccecaa0..000000000000 --- a/arch/c6x/include/asm/setup.h +++ /dev/null @@ -1,31 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ -/* - * Port on Texas Instruments TMS320C6x architecture - * - * Copyright (C) 2004, 2009, 2010 2011 Texas Instruments Incorporated - * Author: Aurelien Jacquiot (aurelien.jacquiot@jaluna.com) - */ -#ifndef _ASM_C6X_SETUP_H -#define _ASM_C6X_SETUP_H - -#include -#include - -#ifndef __ASSEMBLY__ -extern int c6x_add_memory(phys_addr_t start, unsigned long size); - -extern unsigned long ram_start; -extern unsigned long ram_end; - -extern int c6x_num_cores; -extern unsigned int c6x_silicon_rev; -extern unsigned int c6x_devstat; -extern unsigned char c6x_fuse_mac[6]; - -extern void machine_init(unsigned long dt_ptr); -extern void time_init(void); - -extern void coherent_mem_init(u32 start, u32 size); - -#endif /* !__ASSEMBLY__ */ -#endif /* _ASM_C6X_SETUP_H */ diff --git a/arch/c6x/include/asm/soc.h b/arch/c6x/include/asm/soc.h deleted file mode 100644 index 43f50159e59b..000000000000 --- a/arch/c6x/include/asm/soc.h +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Miscellaneous SoC-specific hooks. - * - * Copyright (C) 2011 Texas Instruments Incorporated - * - * Author: Mark Salter - * - * This file is licensed under the terms of the GNU General Public License - * version 2. This program is licensed "as is" without any warranty of any - * kind, whether express or implied. - */ -#ifndef _ASM_C6X_SOC_H -#define _ASM_C6X_SOC_H - -struct soc_ops { - /* Return active exception event or -1 if none */ - int (*get_exception)(void); - - /* Assert an event */ - void (*assert_event)(unsigned int evt); -}; - -extern struct soc_ops soc_ops; - -extern int soc_get_exception(void); -extern void soc_assert_event(unsigned int event); -extern int soc_mac_addr(unsigned int index, u8 *addr); - -/* - * for mmio on SoC devices. regs are always same byte order as cpu. - */ -#define soc_readl(addr) __raw_readl(addr) -#define soc_writel(b, addr) __raw_writel((b), (addr)) - -#endif /* _ASM_C6X_SOC_H */ diff --git a/arch/c6x/include/asm/special_insns.h b/arch/c6x/include/asm/special_insns.h deleted file mode 100644 index d233160aefd4..000000000000 --- a/arch/c6x/include/asm/special_insns.h +++ /dev/null @@ -1,60 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ -/* - * Port on Texas Instruments TMS320C6x architecture - * - * Copyright (C) 2004, 2009, 2010, 2011 Texas Instruments Incorporated - * Author: Aurelien Jacquiot (aurelien.jacquiot@jaluna.com) - */ -#ifndef _ASM_C6X_SPECIAL_INSNS_H -#define _ASM_C6X_SPECIAL_INSNS_H - - -#define get_creg(reg) \ - ({ unsigned int __x; \ - asm volatile ("mvc .s2 " #reg ",%0\n" : "=b"(__x)); __x; }) - -#define set_creg(reg, v) \ - do { unsigned int __x = (unsigned int)(v); \ - asm volatile ("mvc .s2 %0," #reg "\n" : : "b"(__x)); \ - } while (0) - -#define or_creg(reg, n) \ - do { unsigned __x, __n = (unsigned)(n); \ - asm volatile ("mvc .s2 " #reg ",%0\n" \ - "or .l2 %1,%0,%0\n" \ - "mvc .s2 %0," #reg "\n" \ - "nop\n" \ - : "=&b"(__x) : "b"(__n)); \ - } while (0) - -#define and_creg(reg, n) \ - do { unsigned __x, __n = (unsigned)(n); \ - asm volatile ("mvc .s2 " #reg ",%0\n" \ - "and .l2 %1,%0,%0\n" \ - "mvc .s2 %0," #reg "\n" \ - "nop\n" \ - : "=&b"(__x) : "b"(__n)); \ - } while (0) - -#define get_coreid() (get_creg(DNUM) & 0xff) - -/* Set/get IST */ -#define set_ist(x) set_creg(ISTP, x) -#define get_ist() get_creg(ISTP) - -/* - * Exception management - */ -#define disable_exception() -#define get_except_type() get_creg(EFR) -#define ack_exception(type) set_creg(ECR, 1 << (type)) -#define get_iexcept() get_creg(IERR) -#define set_iexcept(mask) set_creg(IERR, (mask)) - -#define _extu(x, s, e) \ - ({ unsigned int __x; \ - asm volatile ("extu .S2 %3,%1,%2,%0\n" : \ - "=b"(__x) : "n"(s), "n"(e), "b"(x)); \ - __x; }) - -#endif /* _ASM_C6X_SPECIAL_INSNS_H */ diff --git a/arch/c6x/include/asm/string.h b/arch/c6x/include/asm/string.h deleted file mode 100644 index b290ead40f68..000000000000 --- a/arch/c6x/include/asm/string.h +++ /dev/null @@ -1,18 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ -/* - * Port on Texas Instruments TMS320C6x architecture - * - * Copyright (C) 2004, 2009, 2011 Texas Instruments Incorporated - * Author: Aurelien Jacquiot (aurelien.jacquiot@jaluna.com) - */ -#ifndef _ASM_C6X_STRING_H -#define _ASM_C6X_STRING_H - -#include -#include - -asmlinkage extern void *memcpy(void *to, const void *from, size_t n); - -#define __HAVE_ARCH_MEMCPY - -#endif /* _ASM_C6X_STRING_H */ diff --git a/arch/c6x/include/asm/switch_to.h b/arch/c6x/include/asm/switch_to.h deleted file mode 100644 index 36c5332fadae..000000000000 --- a/arch/c6x/include/asm/switch_to.h +++ /dev/null @@ -1,30 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ -/* - * Port on Texas Instruments TMS320C6x architecture - * - * Copyright (C) 2004, 2009, 2010, 2011 Texas Instruments Incorporated - * Author: Aurelien Jacquiot (aurelien.jacquiot@jaluna.com) - */ -#ifndef _ASM_C6X_SWITCH_TO_H -#define _ASM_C6X_SWITCH_TO_H - -#include - -#define prepare_to_switch() do { } while (0) - -struct task_struct; -struct thread_struct; -asmlinkage void *__switch_to(struct thread_struct *prev, - struct thread_struct *next, - struct task_struct *tsk); - -#define switch_to(prev, next, last) \ - do { \ - current->thread.wchan = (u_long) __builtin_return_address(0); \ - (last) = __switch_to(&(prev)->thread, \ - &(next)->thread, (prev)); \ - mb(); \ - current->thread.wchan = 0; \ - } while (0) - -#endif /* _ASM_C6X_SWITCH_TO_H */ diff --git a/arch/c6x/include/asm/syscall.h b/arch/c6x/include/asm/syscall.h deleted file mode 100644 index 38f3e2284ecd..000000000000 --- a/arch/c6x/include/asm/syscall.h +++ /dev/null @@ -1,75 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-or-later */ -/* - * Copyright (C) 2011 Texas Instruments Incorporated - * Author: Mark Salter - */ - -#ifndef __ASM_C6X_SYSCALL_H -#define __ASM_C6X_SYSCALL_H - -#include -#include -#include - -static inline int syscall_get_nr(struct task_struct *task, - struct pt_regs *regs) -{ - return regs->b0; -} - -static inline void syscall_rollback(struct task_struct *task, - struct pt_regs *regs) -{ - /* do nothing */ -} - -static inline long syscall_get_error(struct task_struct *task, - struct pt_regs *regs) -{ - return IS_ERR_VALUE(regs->a4) ? regs->a4 : 0; -} - -static inline long syscall_get_return_value(struct task_struct *task, - struct pt_regs *regs) -{ - return regs->a4; -} - -static inline void syscall_set_return_value(struct task_struct *task, - struct pt_regs *regs, - int error, long val) -{ - regs->a4 = error ?: val; -} - -static inline void syscall_get_arguments(struct task_struct *task, - struct pt_regs *regs, - unsigned long *args) -{ - *args++ = regs->a4; - *args++ = regs->b4; - *args++ = regs->a6; - *args++ = regs->b6; - *args++ = regs->a8; - *args = regs->b8; -} - -static inline void syscall_set_arguments(struct task_struct *task, - struct pt_regs *regs, - const unsigned long *args) -{ - regs->a4 = *args++; - regs->b4 = *args++; - regs->a6 = *args++; - regs->b6 = *args++; - regs->a8 = *args++; - regs->a9 = *args; -} - -static inline int syscall_get_arch(struct task_struct *task) -{ - return IS_ENABLED(CONFIG_CPU_BIG_ENDIAN) - ? AUDIT_ARCH_C6XBE : AUDIT_ARCH_C6X; -} - -#endif /* __ASM_C6X_SYSCALLS_H */ diff --git a/arch/c6x/include/asm/syscalls.h b/arch/c6x/include/asm/syscalls.h deleted file mode 100644 index df3d05feb153..000000000000 --- a/arch/c6x/include/asm/syscalls.h +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright (C) 2011 Texas Instruments Incorporated - * Author: Mark Salter - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation, version 2. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or - * NON INFRINGEMENT. See the GNU General Public License for - * more details. - */ - -#ifndef __ASM_C6X_SYSCALLS_H -#define __ASM_C6X_SYSCALLS_H - -#include -#include -#include - -/* The array of function pointers for syscalls. */ -extern void *sys_call_table[]; - -/* The following are trampolines in entry.S to handle 64-bit arguments */ -extern long sys_pread_c6x(unsigned int fd, char __user *buf, - size_t count, off_t pos_low, off_t pos_high); -extern long sys_pwrite_c6x(unsigned int fd, const char __user *buf, - size_t count, off_t pos_low, off_t pos_high); -extern long sys_truncate64_c6x(const char __user *path, - off_t length_low, off_t length_high); -extern long sys_ftruncate64_c6x(unsigned int fd, - off_t length_low, off_t length_high); -extern long sys_fadvise64_c6x(int fd, u32 offset_lo, u32 offset_hi, - u32 len, int advice); -extern long sys_fadvise64_64_c6x(int fd, u32 offset_lo, u32 offset_hi, - u32 len_lo, u32 len_hi, int advice); -extern long sys_fallocate_c6x(int fd, int mode, - u32 offset_lo, u32 offset_hi, - u32 len_lo, u32 len_hi); -extern int sys_cache_sync(unsigned long s, unsigned long e); - -#include - -#endif /* __ASM_C6X_SYSCALLS_H */ diff --git a/arch/c6x/include/asm/thread_info.h b/arch/c6x/include/asm/thread_info.h deleted file mode 100644 index dd8913d57189..000000000000 --- a/arch/c6x/include/asm/thread_info.h +++ /dev/null @@ -1,94 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ -/* - * Port on Texas Instruments TMS320C6x architecture - * - * Copyright (C) 2004, 2009, 2010, 2011 Texas Instruments Incorporated - * Author: Aurelien Jacquiot (aurelien.jacquiot@jaluna.com) - * - * Updated for 2.6.3x: Mark Salter - */ -#ifndef _ASM_C6X_THREAD_INFO_H -#define _ASM_C6X_THREAD_INFO_H - -#ifdef __KERNEL__ - -#include - -#ifdef CONFIG_4KSTACKS -#define THREAD_SIZE 4096 -#define THREAD_SHIFT 12 -#define THREAD_SIZE_ORDER 0 -#else -#define THREAD_SIZE 8192 -#define THREAD_SHIFT 13 -#define THREAD_SIZE_ORDER 1 -#endif - -#define THREAD_START_SP (THREAD_SIZE - 8) - -#ifndef __ASSEMBLY__ - -typedef struct { - unsigned long seg; -} mm_segment_t; - -/* - * low level task data. - */ -struct thread_info { - struct task_struct *task; /* main task structure */ - unsigned long flags; /* low level flags */ - int cpu; /* cpu we're on */ - int preempt_count; /* 0 = preemptable, <0 = BUG */ - mm_segment_t addr_limit; /* thread address space */ -}; - -/* - * macros/functions for gaining access to the thread information structure - * - * preempt_count needs to be 1 initially, until the scheduler is functional. - */ -#define INIT_THREAD_INFO(tsk) \ -{ \ - .task = &tsk, \ - .flags = 0, \ - .cpu = 0, \ - .preempt_count = INIT_PREEMPT_COUNT, \ - .addr_limit = KERNEL_DS, \ -} - -/* get the thread information struct of current task */ -static inline __attribute__((const)) -struct thread_info *current_thread_info(void) -{ - struct thread_info *ti; - asm volatile (" clr .s2 B15,0,%1,%0\n" - : "=b" (ti) - : "Iu5" (THREAD_SHIFT - 1)); - return ti; -} - -#define get_thread_info(ti) get_task_struct((ti)->task) -#define put_thread_info(ti) put_task_struct((ti)->task) -#endif /* __ASSEMBLY__ */ - -/* - * thread information flag bit numbers - * - pending work-to-be-done flags are in LSW - * - other flags in MSW - */ -#define TIF_SYSCALL_TRACE 0 /* syscall trace active */ -#define TIF_NOTIFY_RESUME 1 /* resumption notification requested */ -#define TIF_SIGPENDING 2 /* signal pending */ -#define TIF_NEED_RESCHED 3 /* rescheduling necessary */ -#define TIF_RESTORE_SIGMASK 4 /* restore signal mask in do_signal() */ -#define TIF_NOTIFY_SIGNAL 5 /* signal notifications exist */ - -#define TIF_MEMDIE 17 /* OOM killer killed process */ - -#define TIF_WORK_MASK 0x00007FFE /* work on irq/exception return */ -#define TIF_ALLWORK_MASK 0x00007FFF /* work on any return to u-space */ - -#endif /* __KERNEL__ */ - -#endif /* _ASM_C6X_THREAD_INFO_H */ diff --git a/arch/c6x/include/asm/timer64.h b/arch/c6x/include/asm/timer64.h deleted file mode 100644 index b850dfef1f79..000000000000 --- a/arch/c6x/include/asm/timer64.h +++ /dev/null @@ -1,7 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -#ifndef _C6X_TIMER64_H -#define _C6X_TIMER64_H - -extern void __init timer64_init(void); - -#endif /* _C6X_TIMER64_H */ diff --git a/arch/c6x/include/asm/timex.h b/arch/c6x/include/asm/timex.h deleted file mode 100644 index f946ce297e13..000000000000 --- a/arch/c6x/include/asm/timex.h +++ /dev/null @@ -1,30 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ -/* - * Port on Texas Instruments TMS320C6x architecture - * - * Copyright (C) 2004, 2009, 2010, 2011 Texas Instruments Incorporated - * Author: Aurelien Jacquiot (aurelien.jacquiot@jaluna.com) - * - * Modified for 2.6.34: Mark Salter - */ -#ifndef _ASM_C6X_TIMEX_H -#define _ASM_C6X_TIMEX_H - -#define CLOCK_TICK_RATE ((1000 * 1000000UL) / 6) - -/* 64-bit timestamp */ -typedef unsigned long long cycles_t; - -static inline cycles_t get_cycles(void) -{ - unsigned l, h; - - asm volatile (" dint\n" - " mvc .s2 TSCL,%0\n" - " mvc .s2 TSCH,%1\n" - " rint\n" - : "=b"(l), "=b"(h)); - return ((cycles_t)h << 32) | l; -} - -#endif /* _ASM_C6X_TIMEX_H */ diff --git a/arch/c6x/include/asm/tlb.h b/arch/c6x/include/asm/tlb.h deleted file mode 100644 index 240ba0febb57..000000000000 --- a/arch/c6x/include/asm/tlb.h +++ /dev/null @@ -1,7 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -#ifndef _ASM_C6X_TLB_H -#define _ASM_C6X_TLB_H - -#include - -#endif /* _ASM_C6X_TLB_H */ diff --git a/arch/c6x/include/asm/traps.h b/arch/c6x/include/asm/traps.h deleted file mode 100644 index 7e1d31c47680..000000000000 --- a/arch/c6x/include/asm/traps.h +++ /dev/null @@ -1,33 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ -/* - * Port on Texas Instruments TMS320C6x architecture - * - * Copyright (C) 2004, 2009, 2011 Texas Instruments Incorporated - * Author: Aurelien Jacquiot (aurelien.jacquiot@jaluna.com) - */ -#ifndef _ASM_C6X_TRAPS_H -#define _ASM_C6X_TRAPS_H - -#define EXCEPT_TYPE_NXF 31 /* NMI */ -#define EXCEPT_TYPE_EXC 30 /* external exception */ -#define EXCEPT_TYPE_IXF 1 /* internal exception */ -#define EXCEPT_TYPE_SXF 0 /* software exception */ - -#define EXCEPT_CAUSE_LBX (1 << 7) /* loop buffer exception */ -#define EXCEPT_CAUSE_PRX (1 << 6) /* privilege exception */ -#define EXCEPT_CAUSE_RAX (1 << 5) /* resource access exception */ -#define EXCEPT_CAUSE_RCX (1 << 4) /* resource conflict exception */ -#define EXCEPT_CAUSE_OPX (1 << 3) /* opcode exception */ -#define EXCEPT_CAUSE_EPX (1 << 2) /* execute packet exception */ -#define EXCEPT_CAUSE_FPX (1 << 1) /* fetch packet exception */ -#define EXCEPT_CAUSE_IFX (1 << 0) /* instruction fetch exception */ - -struct exception_info { - char *kernel_str; - int signo; - int code; -}; - -extern int (*c6x_nmi_handler)(struct pt_regs *regs); - -#endif /* _ASM_C6X_TRAPS_H */ diff --git a/arch/c6x/include/asm/uaccess.h b/arch/c6x/include/asm/uaccess.h deleted file mode 100644 index 585adf9201b7..000000000000 --- a/arch/c6x/include/asm/uaccess.h +++ /dev/null @@ -1,97 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ -/* - * Copyright (C) 2011 Texas Instruments Incorporated - * Author: Mark Salter - */ -#ifndef _ASM_C6X_UACCESS_H -#define _ASM_C6X_UACCESS_H - -#include -#include -#include - -/* - * C6X supports unaligned 32 and 64 bit loads and stores. - */ -static inline __must_check unsigned long -raw_copy_from_user(void *to, const void __user *from, unsigned long n) -{ - u32 tmp32; - u64 tmp64; - - if (__builtin_constant_p(n)) { - switch (n) { - case 1: - *(u8 *)to = *(u8 __force *)from; - return 0; - case 4: - asm volatile ("ldnw .d1t1 *%2,%0\n" - "nop 4\n" - "stnw .d1t1 %0,*%1\n" - : "=&a"(tmp32) - : "A"(to), "a"(from) - : "memory"); - return 0; - case 8: - asm volatile ("ldndw .d1t1 *%2,%0\n" - "nop 4\n" - "stndw .d1t1 %0,*%1\n" - : "=&a"(tmp64) - : "a"(to), "a"(from) - : "memory"); - return 0; - default: - break; - } - } - - memcpy(to, (const void __force *)from, n); - return 0; -} - -static inline __must_check unsigned long -raw_copy_to_user(void __user *to, const void *from, unsigned long n) -{ - u32 tmp32; - u64 tmp64; - - if (__builtin_constant_p(n)) { - switch (n) { - case 1: - *(u8 __force *)to = *(u8 *)from; - return 0; - case 4: - asm volatile ("ldnw .d1t1 *%2,%0\n" - "nop 4\n" - "stnw .d1t1 %0,*%1\n" - : "=&a"(tmp32) - : "a"(to), "a"(from) - : "memory"); - return 0; - case 8: - asm volatile ("ldndw .d1t1 *%2,%0\n" - "nop 4\n" - "stndw .d1t1 %0,*%1\n" - : "=&a"(tmp64) - : "a"(to), "a"(from) - : "memory"); - return 0; - default: - break; - } - } - - memcpy((void __force *)to, from, n); - return 0; -} -#define INLINE_COPY_FROM_USER -#define INLINE_COPY_TO_USER - -extern int _access_ok(unsigned long addr, unsigned long size); -#ifdef CONFIG_ACCESS_CHECK -#define __access_ok _access_ok -#endif - -#include - -#endif /* _ASM_C6X_UACCESS_H */ diff --git a/arch/c6x/include/asm/unaligned.h b/arch/c6x/include/asm/unaligned.h deleted file mode 100644 index d628cc170564..000000000000 --- a/arch/c6x/include/asm/unaligned.h +++ /dev/null @@ -1,104 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ -/* - * Port on Texas Instruments TMS320C6x architecture - * - * Copyright (C) 2004, 2009, 2010 Texas Instruments Incorporated - * Author: Aurelien Jacquiot (aurelien.jacquiot@jaluna.com) - * Rewritten for 2.6.3x: Mark Salter - */ -#ifndef _ASM_C6X_UNALIGNED_H -#define _ASM_C6X_UNALIGNED_H - -#include -#include - -/* - * The C64x+ can do unaligned word and dword accesses in hardware - * using special load/store instructions. - */ - -static inline u16 get_unaligned_le16(const void *p) -{ - const u8 *_p = p; - return _p[0] | _p[1] << 8; -} - -static inline u16 get_unaligned_be16(const void *p) -{ - const u8 *_p = p; - return _p[0] << 8 | _p[1]; -} - -static inline void put_unaligned_le16(u16 val, void *p) -{ - u8 *_p = p; - _p[0] = val; - _p[1] = val >> 8; -} - -static inline void put_unaligned_be16(u16 val, void *p) -{ - u8 *_p = p; - _p[0] = val >> 8; - _p[1] = val; -} - -static inline u32 get_unaligned32(const void *p) -{ - u32 val = (u32) p; - asm (" ldnw .d1t1 *%0,%0\n" - " nop 4\n" - : "+a"(val)); - return val; -} - -static inline void put_unaligned32(u32 val, void *p) -{ - asm volatile (" stnw .d2t1 %0,*%1\n" - : : "a"(val), "b"(p) : "memory"); -} - -static inline u64 get_unaligned64(const void *p) -{ - u64 val; - asm volatile (" ldndw .d1t1 *%1,%0\n" - " nop 4\n" - : "=a"(val) : "a"(p)); - return val; -} - -static inline void put_unaligned64(u64 val, const void *p) -{ - asm volatile (" stndw .d2t1 %0,*%1\n" - : : "a"(val), "b"(p) : "memory"); -} - -#ifdef CONFIG_CPU_BIG_ENDIAN - -#define get_unaligned_le32(p) __swab32(get_unaligned32(p)) -#define get_unaligned_le64(p) __swab64(get_unaligned64(p)) -#define get_unaligned_be32(p) get_unaligned32(p) -#define get_unaligned_be64(p) get_unaligned64(p) -#define put_unaligned_le32(v, p) put_unaligned32(__swab32(v), (p)) -#define put_unaligned_le64(v, p) put_unaligned64(__swab64(v), (p)) -#define put_unaligned_be32(v, p) put_unaligned32((v), (p)) -#define put_unaligned_be64(v, p) put_unaligned64((v), (p)) -#define get_unaligned __get_unaligned_be -#define put_unaligned __put_unaligned_be - -#else - -#define get_unaligned_le32(p) get_unaligned32(p) -#define get_unaligned_le64(p) get_unaligned64(p) -#define get_unaligned_be32(p) __swab32(get_unaligned32(p)) -#define get_unaligned_be64(p) __swab64(get_unaligned64(p)) -#define put_unaligned_le32(v, p) put_unaligned32((v), (p)) -#define put_unaligned_le64(v, p) put_unaligned64((v), (p)) -#define put_unaligned_be32(v, p) put_unaligned32(__swab32(v), (p)) -#define put_unaligned_be64(v, p) put_unaligned64(__swab64(v), (p)) -#define get_unaligned __get_unaligned_le -#define put_unaligned __put_unaligned_le - -#endif - -#endif /* _ASM_C6X_UNALIGNED_H */ diff --git a/arch/c6x/include/asm/vmalloc.h b/arch/c6x/include/asm/vmalloc.h deleted file mode 100644 index 26c6c6696bbd..000000000000 --- a/arch/c6x/include/asm/vmalloc.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifndef _ASM_C6X_VMALLOC_H -#define _ASM_C6X_VMALLOC_H - -#endif /* _ASM_C6X_VMALLOC_H */ diff --git a/arch/c6x/include/uapi/asm/Kbuild b/arch/c6x/include/uapi/asm/Kbuild deleted file mode 100644 index e78470141932..000000000000 --- a/arch/c6x/include/uapi/asm/Kbuild +++ /dev/null @@ -1,2 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0 -generic-y += ucontext.h diff --git a/arch/c6x/include/uapi/asm/byteorder.h b/arch/c6x/include/uapi/asm/byteorder.h deleted file mode 100644 index ab61f867391c..000000000000 --- a/arch/c6x/include/uapi/asm/byteorder.h +++ /dev/null @@ -1,13 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ -#ifndef _ASM_C6X_BYTEORDER_H -#define _ASM_C6X_BYTEORDER_H - -#include - -#ifdef _BIG_ENDIAN -#include -#else /* _BIG_ENDIAN */ -#include -#endif /* _BIG_ENDIAN */ - -#endif /* _ASM_BYTEORDER_H */ diff --git a/arch/c6x/include/uapi/asm/ptrace.h b/arch/c6x/include/uapi/asm/ptrace.h deleted file mode 100644 index 9b51110a0842..000000000000 --- a/arch/c6x/include/uapi/asm/ptrace.h +++ /dev/null @@ -1,164 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ -/* - * Copyright (C) 2004, 2006, 2009, 2010 Texas Instruments Incorporated - * Author: Aurelien Jacquiot (aurelien.jacquiot@jaluna.com) - * - * Updated for 2.6.34: Mark Salter - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ -#ifndef _UAPI_ASM_C6X_PTRACE_H -#define _UAPI_ASM_C6X_PTRACE_H - -#define BKPT_OPCODE 0x56454314 /* illegal opcode */ - -#ifdef _BIG_ENDIAN -#define PT_LO(odd, even) odd -#define PT_HI(odd, even) even -#else -#define PT_LO(odd, even) even -#define PT_HI(odd, even) odd -#endif - -#define PT_A4_ORG PT_LO(1, 0) -#define PT_TSR PT_HI(1, 0) -#define PT_ILC PT_LO(3, 2) -#define PT_RILC PT_HI(3, 2) -#define PT_CSR PT_LO(5, 4) -#define PT_PC PT_HI(5, 4) -#define PT_B16 PT_LO(7, 6) -#define PT_B17 PT_HI(7, 6) -#define PT_B18 PT_LO(9, 8) -#define PT_B19 PT_HI(9, 8) -#define PT_B20 PT_LO(11, 10) -#define PT_B21 PT_HI(11, 10) -#define PT_B22 PT_LO(13, 12) -#define PT_B23 PT_HI(13, 12) -#define PT_B24 PT_LO(15, 14) -#define PT_B25 PT_HI(15, 14) -#define PT_B26 PT_LO(17, 16) -#define PT_B27 PT_HI(17, 16) -#define PT_B28 PT_LO(19, 18) -#define PT_B29 PT_HI(19, 18) -#define PT_B30 PT_LO(21, 20) -#define PT_B31 PT_HI(21, 20) -#define PT_B0 PT_LO(23, 22) -#define PT_B1 PT_HI(23, 22) -#define PT_B2 PT_LO(25, 24) -#define PT_B3 PT_HI(25, 24) -#define PT_B4 PT_LO(27, 26) -#define PT_B5 PT_HI(27, 26) -#define PT_B6 PT_LO(29, 28) -#define PT_B7 PT_HI(29, 28) -#define PT_B8 PT_LO(31, 30) -#define PT_B9 PT_HI(31, 30) -#define PT_B10 PT_LO(33, 32) -#define PT_B11 PT_HI(33, 32) -#define PT_B12 PT_LO(35, 34) -#define PT_B13 PT_HI(35, 34) -#define PT_A16 PT_LO(37, 36) -#define PT_A17 PT_HI(37, 36) -#define PT_A18 PT_LO(39, 38) -#define PT_A19 PT_HI(39, 38) -#define PT_A20 PT_LO(41, 40) -#define PT_A21 PT_HI(41, 40) -#define PT_A22 PT_LO(43, 42) -#define PT_A23 PT_HI(43, 42) -#define PT_A24 PT_LO(45, 44) -#define PT_A25 PT_HI(45, 44) -#define PT_A26 PT_LO(47, 46) -#define PT_A27 PT_HI(47, 46) -#define PT_A28 PT_LO(49, 48) -#define PT_A29 PT_HI(49, 48) -#define PT_A30 PT_LO(51, 50) -#define PT_A31 PT_HI(51, 50) -#define PT_A0 PT_LO(53, 52) -#define PT_A1 PT_HI(53, 52) -#define PT_A2 PT_LO(55, 54) -#define PT_A3 PT_HI(55, 54) -#define PT_A4 PT_LO(57, 56) -#define PT_A5 PT_HI(57, 56) -#define PT_A6 PT_LO(59, 58) -#define PT_A7 PT_HI(59, 58) -#define PT_A8 PT_LO(61, 60) -#define PT_A9 PT_HI(61, 60) -#define PT_A10 PT_LO(63, 62) -#define PT_A11 PT_HI(63, 62) -#define PT_A12 PT_LO(65, 64) -#define PT_A13 PT_HI(65, 64) -#define PT_A14 PT_LO(67, 66) -#define PT_A15 PT_HI(67, 66) -#define PT_B14 PT_LO(69, 68) -#define PT_B15 PT_HI(69, 68) - -#define NR_PTREGS 70 - -#define PT_DP PT_B14 /* Data Segment Pointer (B14) */ -#define PT_SP PT_B15 /* Stack Pointer (B15) */ - -#define PTRACE_GETFDPIC 31 /* get the ELF fdpic loadmap address */ - -#define PTRACE_GETFDPIC_EXEC 0 /* [addr] request the executable loadmap */ -#define PTRACE_GETFDPIC_INTERP 1 /* [addr] request the interpreter loadmap */ - -#ifndef __ASSEMBLY__ - -#ifdef _BIG_ENDIAN -#define REG_PAIR(odd, even) unsigned long odd; unsigned long even -#else -#define REG_PAIR(odd, even) unsigned long even; unsigned long odd -#endif - -/* - * this struct defines the way the registers are stored on the - * stack during a system call. fields defined with REG_PAIR - * are saved and restored using double-word memory operations - * which means the word ordering of the pair depends on endianess. - */ -struct pt_regs { - REG_PAIR(tsr, orig_a4); - REG_PAIR(rilc, ilc); - REG_PAIR(pc, csr); - - REG_PAIR(b17, b16); - REG_PAIR(b19, b18); - REG_PAIR(b21, b20); - REG_PAIR(b23, b22); - REG_PAIR(b25, b24); - REG_PAIR(b27, b26); - REG_PAIR(b29, b28); - REG_PAIR(b31, b30); - - REG_PAIR(b1, b0); - REG_PAIR(b3, b2); - REG_PAIR(b5, b4); - REG_PAIR(b7, b6); - REG_PAIR(b9, b8); - REG_PAIR(b11, b10); - REG_PAIR(b13, b12); - - REG_PAIR(a17, a16); - REG_PAIR(a19, a18); - REG_PAIR(a21, a20); - REG_PAIR(a23, a22); - REG_PAIR(a25, a24); - REG_PAIR(a27, a26); - REG_PAIR(a29, a28); - REG_PAIR(a31, a30); - - REG_PAIR(a1, a0); - REG_PAIR(a3, a2); - REG_PAIR(a5, a4); - REG_PAIR(a7, a6); - REG_PAIR(a9, a8); - REG_PAIR(a11, a10); - REG_PAIR(a13, a12); - - REG_PAIR(a15, a14); - REG_PAIR(sp, dp); -}; - -#endif /* __ASSEMBLY__ */ -#endif /* _UAPI_ASM_C6X_PTRACE_H */ diff --git a/arch/c6x/include/uapi/asm/setup.h b/arch/c6x/include/uapi/asm/setup.h deleted file mode 100644 index e90548cebec3..000000000000 --- a/arch/c6x/include/uapi/asm/setup.h +++ /dev/null @@ -1,7 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ -#ifndef _UAPI_ASM_C6X_SETUP_H -#define _UAPI_ASM_C6X_SETUP_H - -#define COMMAND_LINE_SIZE 1024 - -#endif /* _UAPI_ASM_C6X_SETUP_H */ diff --git a/arch/c6x/include/uapi/asm/sigcontext.h b/arch/c6x/include/uapi/asm/sigcontext.h deleted file mode 100644 index 4e5a9a260861..000000000000 --- a/arch/c6x/include/uapi/asm/sigcontext.h +++ /dev/null @@ -1,81 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ -/* - * Port on Texas Instruments TMS320C6x architecture - * - * Copyright (C) 2004, 2009 Texas Instruments Incorporated - * Author: Aurelien Jacquiot (aurelien.jacquiot@jaluna.com) - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ -#ifndef _ASM_C6X_SIGCONTEXT_H -#define _ASM_C6X_SIGCONTEXT_H - - -struct sigcontext { - unsigned long sc_mask; /* old sigmask */ - unsigned long sc_sp; /* old user stack pointer */ - - unsigned long sc_a4; - unsigned long sc_b4; - unsigned long sc_a6; - unsigned long sc_b6; - unsigned long sc_a8; - unsigned long sc_b8; - - unsigned long sc_a0; - unsigned long sc_a1; - unsigned long sc_a2; - unsigned long sc_a3; - unsigned long sc_a5; - unsigned long sc_a7; - unsigned long sc_a9; - - unsigned long sc_b0; - unsigned long sc_b1; - unsigned long sc_b2; - unsigned long sc_b3; - unsigned long sc_b5; - unsigned long sc_b7; - unsigned long sc_b9; - - unsigned long sc_a16; - unsigned long sc_a17; - unsigned long sc_a18; - unsigned long sc_a19; - unsigned long sc_a20; - unsigned long sc_a21; - unsigned long sc_a22; - unsigned long sc_a23; - unsigned long sc_a24; - unsigned long sc_a25; - unsigned long sc_a26; - unsigned long sc_a27; - unsigned long sc_a28; - unsigned long sc_a29; - unsigned long sc_a30; - unsigned long sc_a31; - - unsigned long sc_b16; - unsigned long sc_b17; - unsigned long sc_b18; - unsigned long sc_b19; - unsigned long sc_b20; - unsigned long sc_b21; - unsigned long sc_b22; - unsigned long sc_b23; - unsigned long sc_b24; - unsigned long sc_b25; - unsigned long sc_b26; - unsigned long sc_b27; - unsigned long sc_b28; - unsigned long sc_b29; - unsigned long sc_b30; - unsigned long sc_b31; - - unsigned long sc_csr; - unsigned long sc_pc; -}; - -#endif /* _ASM_C6X_SIGCONTEXT_H */ diff --git a/arch/c6x/include/uapi/asm/swab.h b/arch/c6x/include/uapi/asm/swab.h deleted file mode 100644 index c407c0497718..000000000000 --- a/arch/c6x/include/uapi/asm/swab.h +++ /dev/null @@ -1,55 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ -/* - * Copyright (C) 2011 Texas Instruments Incorporated - * Author: Mark Salter - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ -#ifndef _ASM_C6X_SWAB_H -#define _ASM_C6X_SWAB_H - -static inline __attribute_const__ __u16 __c6x_swab16(__u16 val) -{ - asm("swap4 .l1 %0,%0\n" : "+a"(val)); - return val; -} - -static inline __attribute_const__ __u32 __c6x_swab32(__u32 val) -{ - asm("swap4 .l1 %0,%0\n" - "swap2 .l1 %0,%0\n" - : "+a"(val)); - return val; -} - -static inline __attribute_const__ __u64 __c6x_swab64(__u64 val) -{ - asm(" swap2 .s1 %p0,%P0\n" - "|| swap2 .l1 %P0,%p0\n" - " swap4 .l1 %p0,%p0\n" - " swap4 .l1 %P0,%P0\n" - : "+a"(val)); - return val; -} - -static inline __attribute_const__ __u32 __c6x_swahw32(__u32 val) -{ - asm("swap2 .l1 %0,%0\n" : "+a"(val)); - return val; -} - -static inline __attribute_const__ __u32 __c6x_swahb32(__u32 val) -{ - asm("swap4 .l1 %0,%0\n" : "+a"(val)); - return val; -} - -#define __arch_swab16 __c6x_swab16 -#define __arch_swab32 __c6x_swab32 -#define __arch_swab64 __c6x_swab64 -#define __arch_swahw32 __c6x_swahw32 -#define __arch_swahb32 __c6x_swahb32 - -#endif /* _ASM_C6X_SWAB_H */ diff --git a/arch/c6x/include/uapi/asm/unistd.h b/arch/c6x/include/uapi/asm/unistd.h deleted file mode 100644 index 79b724c39d9b..000000000000 --- a/arch/c6x/include/uapi/asm/unistd.h +++ /dev/null @@ -1,29 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ -/* - * Copyright (C) 2011 Texas Instruments Incorporated - * - * Based on arch/tile version. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation, version 2. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or - * NON INFRINGEMENT. See the GNU General Public License for - * more details. - */ - -#define __ARCH_WANT_RENAMEAT -#define __ARCH_WANT_STAT64 -#define __ARCH_WANT_SET_GET_RLIMIT -#define __ARCH_WANT_SYS_CLONE -#define __ARCH_WANT_TIME32_SYSCALLS - -/* Use the standard ABI for syscalls. */ -#include - -/* C6X-specific syscalls. */ -#define __NR_cache_sync (__NR_arch_specific_syscall + 0) -__SYSCALL(__NR_cache_sync, sys_cache_sync) diff --git a/arch/c6x/kernel/Makefile b/arch/c6x/kernel/Makefile deleted file mode 100644 index fbe74174de87..000000000000 --- a/arch/c6x/kernel/Makefile +++ /dev/null @@ -1,13 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0 -# -# Makefile for arch/c6x/kernel/ -# - -extra-y := head.o vmlinux.lds - -obj-y := process.o traps.o irq.o signal.o ptrace.o -obj-y += setup.o sys_c6x.o time.o devicetree.o -obj-y += switch_to.o entry.o vectors.o c6x_ksyms.o -obj-y += soc.o - -obj-$(CONFIG_MODULES) += module.o diff --git a/arch/c6x/kernel/asm-offsets.c b/arch/c6x/kernel/asm-offsets.c deleted file mode 100644 index 4a264ef87dcb..000000000000 --- a/arch/c6x/kernel/asm-offsets.c +++ /dev/null @@ -1,123 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* - * Generate definitions needed by assembly language modules. - * This code generates raw asm output which is post-processed - * to extract and format the required data. - */ - -#include -#include -#include -#include -#include - -void foo(void) -{ - OFFSET(REGS_A16, pt_regs, a16); - OFFSET(REGS_A17, pt_regs, a17); - OFFSET(REGS_A18, pt_regs, a18); - OFFSET(REGS_A19, pt_regs, a19); - OFFSET(REGS_A20, pt_regs, a20); - OFFSET(REGS_A21, pt_regs, a21); - OFFSET(REGS_A22, pt_regs, a22); - OFFSET(REGS_A23, pt_regs, a23); - OFFSET(REGS_A24, pt_regs, a24); - OFFSET(REGS_A25, pt_regs, a25); - OFFSET(REGS_A26, pt_regs, a26); - OFFSET(REGS_A27, pt_regs, a27); - OFFSET(REGS_A28, pt_regs, a28); - OFFSET(REGS_A29, pt_regs, a29); - OFFSET(REGS_A30, pt_regs, a30); - OFFSET(REGS_A31, pt_regs, a31); - - OFFSET(REGS_B16, pt_regs, b16); - OFFSET(REGS_B17, pt_regs, b17); - OFFSET(REGS_B18, pt_regs, b18); - OFFSET(REGS_B19, pt_regs, b19); - OFFSET(REGS_B20, pt_regs, b20); - OFFSET(REGS_B21, pt_regs, b21); - OFFSET(REGS_B22, pt_regs, b22); - OFFSET(REGS_B23, pt_regs, b23); - OFFSET(REGS_B24, pt_regs, b24); - OFFSET(REGS_B25, pt_regs, b25); - OFFSET(REGS_B26, pt_regs, b26); - OFFSET(REGS_B27, pt_regs, b27); - OFFSET(REGS_B28, pt_regs, b28); - OFFSET(REGS_B29, pt_regs, b29); - OFFSET(REGS_B30, pt_regs, b30); - OFFSET(REGS_B31, pt_regs, b31); - - OFFSET(REGS_A0, pt_regs, a0); - OFFSET(REGS_A1, pt_regs, a1); - OFFSET(REGS_A2, pt_regs, a2); - OFFSET(REGS_A3, pt_regs, a3); - OFFSET(REGS_A4, pt_regs, a4); - OFFSET(REGS_A5, pt_regs, a5); - OFFSET(REGS_A6, pt_regs, a6); - OFFSET(REGS_A7, pt_regs, a7); - OFFSET(REGS_A8, pt_regs, a8); - OFFSET(REGS_A9, pt_regs, a9); - OFFSET(REGS_A10, pt_regs, a10); - OFFSET(REGS_A11, pt_regs, a11); - OFFSET(REGS_A12, pt_regs, a12); - OFFSET(REGS_A13, pt_regs, a13); - OFFSET(REGS_A14, pt_regs, a14); - OFFSET(REGS_A15, pt_regs, a15); - - OFFSET(REGS_B0, pt_regs, b0); - OFFSET(REGS_B1, pt_regs, b1); - OFFSET(REGS_B2, pt_regs, b2); - OFFSET(REGS_B3, pt_regs, b3); - OFFSET(REGS_B4, pt_regs, b4); - OFFSET(REGS_B5, pt_regs, b5); - OFFSET(REGS_B6, pt_regs, b6); - OFFSET(REGS_B7, pt_regs, b7); - OFFSET(REGS_B8, pt_regs, b8); - OFFSET(REGS_B9, pt_regs, b9); - OFFSET(REGS_B10, pt_regs, b10); - OFFSET(REGS_B11, pt_regs, b11); - OFFSET(REGS_B12, pt_regs, b12); - OFFSET(REGS_B13, pt_regs, b13); - OFFSET(REGS_DP, pt_regs, dp); - OFFSET(REGS_SP, pt_regs, sp); - - OFFSET(REGS_TSR, pt_regs, tsr); - OFFSET(REGS_ORIG_A4, pt_regs, orig_a4); - - DEFINE(REGS__END, sizeof(struct pt_regs)); - BLANK(); - - OFFSET(THREAD_PC, thread_struct, pc); - OFFSET(THREAD_B15_14, thread_struct, b15_14); - OFFSET(THREAD_A15_14, thread_struct, a15_14); - OFFSET(THREAD_B13_12, thread_struct, b13_12); - OFFSET(THREAD_A13_12, thread_struct, a13_12); - OFFSET(THREAD_B11_10, thread_struct, b11_10); - OFFSET(THREAD_A11_10, thread_struct, a11_10); - OFFSET(THREAD_RICL_ICL, thread_struct, ricl_icl); - BLANK(); - - OFFSET(TASK_STATE, task_struct, state); - BLANK(); - - OFFSET(THREAD_INFO_FLAGS, thread_info, flags); - OFFSET(THREAD_INFO_PREEMPT_COUNT, thread_info, preempt_count); - BLANK(); - - /* These would be unneccessary if we ran asm files - * through the preprocessor. - */ - DEFINE(KTHREAD_SHIFT, THREAD_SHIFT); - DEFINE(KTHREAD_START_SP, THREAD_START_SP); - DEFINE(ENOSYS_, ENOSYS); - DEFINE(NR_SYSCALLS_, __NR_syscalls); - - DEFINE(_TIF_SYSCALL_TRACE, (1< -#include -#include - -/* - * libgcc functions - used internally by the compiler... - */ -extern int __c6xabi_divi(int dividend, int divisor); -EXPORT_SYMBOL(__c6xabi_divi); - -extern unsigned __c6xabi_divu(unsigned dividend, unsigned divisor); -EXPORT_SYMBOL(__c6xabi_divu); - -extern int __c6xabi_remi(int dividend, int divisor); -EXPORT_SYMBOL(__c6xabi_remi); - -extern unsigned __c6xabi_remu(unsigned dividend, unsigned divisor); -EXPORT_SYMBOL(__c6xabi_remu); - -extern int __c6xabi_divremi(int dividend, int divisor); -EXPORT_SYMBOL(__c6xabi_divremi); - -extern unsigned __c6xabi_divremu(unsigned dividend, unsigned divisor); -EXPORT_SYMBOL(__c6xabi_divremu); - -extern unsigned long long __c6xabi_mpyll(unsigned long long src1, - unsigned long long src2); -EXPORT_SYMBOL(__c6xabi_mpyll); - -extern long long __c6xabi_negll(long long src); -EXPORT_SYMBOL(__c6xabi_negll); - -extern unsigned long long __c6xabi_llshl(unsigned long long src1, uint src2); -EXPORT_SYMBOL(__c6xabi_llshl); - -extern long long __c6xabi_llshr(long long src1, uint src2); -EXPORT_SYMBOL(__c6xabi_llshr); - -extern unsigned long long __c6xabi_llshru(unsigned long long src1, uint src2); -EXPORT_SYMBOL(__c6xabi_llshru); - -extern void __c6xabi_strasgi(int *dst, const int *src, unsigned cnt); -EXPORT_SYMBOL(__c6xabi_strasgi); - -extern void __c6xabi_push_rts(void); -EXPORT_SYMBOL(__c6xabi_push_rts); - -extern void __c6xabi_pop_rts(void); -EXPORT_SYMBOL(__c6xabi_pop_rts); - -extern void __c6xabi_strasgi_64plus(int *dst, const int *src, unsigned cnt); -EXPORT_SYMBOL(__c6xabi_strasgi_64plus); - -/* lib functions */ -EXPORT_SYMBOL(memcpy); diff --git a/arch/c6x/kernel/devicetree.c b/arch/c6x/kernel/devicetree.c deleted file mode 100644 index a0c73f0545b2..000000000000 --- a/arch/c6x/kernel/devicetree.c +++ /dev/null @@ -1,14 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Architecture specific OF callbacks. - * - * Copyright (C) 2011 Texas Instruments Incorporated - * Author: Mark Salter - */ -#include -#include - -void __init early_init_dt_add_memory_arch(u64 base, u64 size) -{ - c6x_add_memory(base, size); -} diff --git a/arch/c6x/kernel/entry.S b/arch/c6x/kernel/entry.S deleted file mode 100644 index fb154d19625b..000000000000 --- a/arch/c6x/kernel/entry.S +++ /dev/null @@ -1,736 +0,0 @@ -; SPDX-License-Identifier: GPL-2.0-only -; -; Port on Texas Instruments TMS320C6x architecture -; -; Copyright (C) 2004-2011 Texas Instruments Incorporated -; Author: Aurelien Jacquiot (aurelien.jacquiot@virtuallogix.com) -; Updated for 2.6.34: Mark Salter -; - -#include -#include -#include -#include -#include -#include - -; Registers naming -#define DP B14 -#define SP B15 - -#ifndef CONFIG_PREEMPTION -#define resume_kernel restore_all -#endif - - .altmacro - - .macro MASK_INT reg - MVC .S2 CSR,reg - CLR .S2 reg,0,0,reg - MVC .S2 reg,CSR - .endm - - .macro UNMASK_INT reg - MVC .S2 CSR,reg - SET .S2 reg,0,0,reg - MVC .S2 reg,CSR - .endm - - .macro GET_THREAD_INFO reg - SHR .S1X SP,THREAD_SHIFT,reg - SHL .S1 reg,THREAD_SHIFT,reg - .endm - - ;; - ;; This defines the normal kernel pt_regs layout. - ;; - .macro SAVE_ALL __rp __tsr - STW .D2T2 B0,*SP--[2] ; save original B0 - MVKL .S2 current_ksp,B0 - MVKH .S2 current_ksp,B0 - LDW .D2T2 *B0,B1 ; KSP - - NOP 3 - STW .D2T2 B1,*+SP[1] ; save original B1 - XOR .D2 SP,B1,B0 ; (SP ^ KSP) - LDW .D2T2 *+SP[1],B1 ; restore B0/B1 - LDW .D2T2 *++SP[2],B0 - SHR .S2 B0,THREAD_SHIFT,B0 ; 0 if already using kstack - [B0] STDW .D2T2 SP:DP,*--B1[1] ; user: save user sp/dp kstack - [B0] MV .S2 B1,SP ; and switch to kstack -||[!B0] STDW .D2T2 SP:DP,*--SP[1] ; kernel: save on current stack - - SUBAW .D2 SP,2,SP - - ADD .D1X SP,-8,A15 - || STDW .D2T1 A15:A14,*SP--[16] ; save A15:A14 - - STDW .D2T2 B13:B12,*SP--[1] - || STDW .D1T1 A13:A12,*A15--[1] - || MVC .S2 __rp,B13 - - STDW .D2T2 B11:B10,*SP--[1] - || STDW .D1T1 A11:A10,*A15--[1] - || MVC .S2 CSR,B12 - - STDW .D2T2 B9:B8,*SP--[1] - || STDW .D1T1 A9:A8,*A15--[1] - || MVC .S2 RILC,B11 - STDW .D2T2 B7:B6,*SP--[1] - || STDW .D1T1 A7:A6,*A15--[1] - || MVC .S2 ILC,B10 - - STDW .D2T2 B5:B4,*SP--[1] - || STDW .D1T1 A5:A4,*A15--[1] - - STDW .D2T2 B3:B2,*SP--[1] - || STDW .D1T1 A3:A2,*A15--[1] - || MVC .S2 __tsr,B5 - - STDW .D2T2 B1:B0,*SP--[1] - || STDW .D1T1 A1:A0,*A15--[1] - || MV .S1X B5,A5 - - STDW .D2T2 B31:B30,*SP--[1] - || STDW .D1T1 A31:A30,*A15--[1] - STDW .D2T2 B29:B28,*SP--[1] - || STDW .D1T1 A29:A28,*A15--[1] - STDW .D2T2 B27:B26,*SP--[1] - || STDW .D1T1 A27:A26,*A15--[1] - STDW .D2T2 B25:B24,*SP--[1] - || STDW .D1T1 A25:A24,*A15--[1] - STDW .D2T2 B23:B22,*SP--[1] - || STDW .D1T1 A23:A22,*A15--[1] - STDW .D2T2 B21:B20,*SP--[1] - || STDW .D1T1 A21:A20,*A15--[1] - STDW .D2T2 B19:B18,*SP--[1] - || STDW .D1T1 A19:A18,*A15--[1] - STDW .D2T2 B17:B16,*SP--[1] - || STDW .D1T1 A17:A16,*A15--[1] - - STDW .D2T2 B13:B12,*SP--[1] ; save PC and CSR - - STDW .D2T2 B11:B10,*SP--[1] ; save RILC and ILC - STDW .D2T1 A5:A4,*SP--[1] ; save TSR and orig A4 - - ;; We left an unused word on the stack just above pt_regs. - ;; It is used to save whether or not this frame is due to - ;; a syscall. It is cleared here, but the syscall handler - ;; sets it to a non-zero value. - MVK .L2 0,B1 - STW .D2T2 B1,*+SP(REGS__END+8) ; clear syscall flag - .endm - - .macro RESTORE_ALL __rp __tsr - LDDW .D2T2 *++SP[1],B9:B8 ; get TSR (B9) - LDDW .D2T2 *++SP[1],B11:B10 ; get RILC (B11) and ILC (B10) - LDDW .D2T2 *++SP[1],B13:B12 ; get PC (B13) and CSR (B12) - - ADDAW .D1X SP,30,A15 - - LDDW .D1T1 *++A15[1],A17:A16 - || LDDW .D2T2 *++SP[1],B17:B16 - LDDW .D1T1 *++A15[1],A19:A18 - || LDDW .D2T2 *++SP[1],B19:B18 - LDDW .D1T1 *++A15[1],A21:A20 - || LDDW .D2T2 *++SP[1],B21:B20 - LDDW .D1T1 *++A15[1],A23:A22 - || LDDW .D2T2 *++SP[1],B23:B22 - LDDW .D1T1 *++A15[1],A25:A24 - || LDDW .D2T2 *++SP[1],B25:B24 - LDDW .D1T1 *++A15[1],A27:A26 - || LDDW .D2T2 *++SP[1],B27:B26 - LDDW .D1T1 *++A15[1],A29:A28 - || LDDW .D2T2 *++SP[1],B29:B28 - LDDW .D1T1 *++A15[1],A31:A30 - || LDDW .D2T2 *++SP[1],B31:B30 - - LDDW .D1T1 *++A15[1],A1:A0 - || LDDW .D2T2 *++SP[1],B1:B0 - - LDDW .D1T1 *++A15[1],A3:A2 - || LDDW .D2T2 *++SP[1],B3:B2 - || MVC .S2 B9,__tsr - LDDW .D1T1 *++A15[1],A5:A4 - || LDDW .D2T2 *++SP[1],B5:B4 - || MVC .S2 B11,RILC - LDDW .D1T1 *++A15[1],A7:A6 - || LDDW .D2T2 *++SP[1],B7:B6 - || MVC .S2 B10,ILC - - LDDW .D1T1 *++A15[1],A9:A8 - || LDDW .D2T2 *++SP[1],B9:B8 - || MVC .S2 B13,__rp - - LDDW .D1T1 *++A15[1],A11:A10 - || LDDW .D2T2 *++SP[1],B11:B10 - || MVC .S2 B12,CSR - - LDDW .D1T1 *++A15[1],A13:A12 - || LDDW .D2T2 *++SP[1],B13:B12 - - MV .D2X A15,SP - || MVKL .S1 current_ksp,A15 - MVKH .S1 current_ksp,A15 - || ADDAW .D1X SP,6,A14 - STW .D1T1 A14,*A15 ; save kernel stack pointer - - LDDW .D2T1 *++SP[1],A15:A14 - - B .S2 __rp ; return from interruption - LDDW .D2T2 *+SP[1],SP:DP - NOP 4 - .endm - - .section .text - - ;; - ;; Jump to schedule() then return to ret_from_exception - ;; -_reschedule: -#ifdef CONFIG_C6X_BIG_KERNEL - MVKL .S1 schedule,A0 - MVKH .S1 schedule,A0 - B .S2X A0 -#else - B .S1 schedule -#endif - ADDKPC .S2 ret_from_exception,B3,4 - - ;; - ;; Called before syscall handler when process is being debugged - ;; -tracesys_on: -#ifdef CONFIG_C6X_BIG_KERNEL - MVKL .S1 syscall_trace_entry,A0 - MVKH .S1 syscall_trace_entry,A0 - B .S2X A0 -#else - B .S1 syscall_trace_entry -#endif - ADDKPC .S2 ret_from_syscall_trace,B3,3 - ADD .S1X 8,SP,A4 - -ret_from_syscall_trace: - ;; tracing returns (possibly new) syscall number - MV .D2X A4,B0 - || MVK .S2 __NR_syscalls,B1 - CMPLTU .L2 B0,B1,B1 - - [!B1] BNOP .S2 ret_from_syscall_function,5 - || MVK .S1 -ENOSYS,A4 - - ;; reload syscall args from (possibly modified) stack frame - ;; and get syscall handler addr from sys_call_table: - LDW .D2T2 *+SP(REGS_B4+8),B4 - || MVKL .S2 sys_call_table,B1 - LDW .D2T1 *+SP(REGS_A6+8),A6 - || MVKH .S2 sys_call_table,B1 - LDW .D2T2 *+B1[B0],B0 - || MVKL .S2 ret_from_syscall_function,B3 - LDW .D2T2 *+SP(REGS_B6+8),B6 - || MVKH .S2 ret_from_syscall_function,B3 - LDW .D2T1 *+SP(REGS_A8+8),A8 - LDW .D2T2 *+SP(REGS_B8+8),B8 - NOP - ; B0 = sys_call_table[__NR_*] - BNOP .S2 B0,5 ; branch to syscall handler - || LDW .D2T1 *+SP(REGS_ORIG_A4+8),A4 - -syscall_exit_work: - AND .D1 _TIF_SYSCALL_TRACE,A2,A0 - [!A0] BNOP .S1 work_pending,5 - [A0] B .S2 syscall_trace_exit - ADDKPC .S2 resume_userspace,B3,1 - MVC .S2 CSR,B1 - SET .S2 B1,0,0,B1 - MVC .S2 B1,CSR ; enable ints - -work_pending: - AND .D1 _TIF_NEED_RESCHED,A2,A0 - [!A0] BNOP .S1 work_notifysig,5 - -work_resched: -#ifdef CONFIG_C6X_BIG_KERNEL - MVKL .S1 schedule,A1 - MVKH .S1 schedule,A1 - B .S2X A1 -#else - B .S2 schedule -#endif - ADDKPC .S2 work_rescheduled,B3,4 -work_rescheduled: - ;; make sure we don't miss an interrupt setting need_resched or - ;; sigpending between sampling and the rti - MASK_INT B2 - GET_THREAD_INFO A12 - LDW .D1T1 *+A12(THREAD_INFO_FLAGS),A2 - MVK .S1 _TIF_WORK_MASK,A1 - MVK .S1 _TIF_NEED_RESCHED,A3 - NOP 2 - AND .D1 A1,A2,A0 - || AND .S1 A3,A2,A1 - [!A0] BNOP .S1 restore_all,5 - [A1] BNOP .S1 work_resched,5 - -work_notifysig: - ;; enable interrupts for do_notify_resume() - UNMASK_INT B2 - B .S2 do_notify_resume - LDW .D2T1 *+SP(REGS__END+8),A6 ; syscall flag - ADDKPC .S2 resume_userspace,B3,1 - ADD .S1X 8,SP,A4 ; pt_regs pointer is first arg - MV .D2X A2,B4 ; thread_info flags is second arg - - ;; - ;; On C64x+, the return way from exception and interrupt - ;; is a little bit different - ;; -ENTRY(ret_from_exception) -#ifdef CONFIG_PREEMPTION - MASK_INT B2 -#endif - -ENTRY(ret_from_interrupt) - ;; - ;; Check if we are comming from user mode. - ;; - LDW .D2T2 *+SP(REGS_TSR+8),B0 - MVK .S2 0x40,B1 - NOP 3 - AND .D2 B0,B1,B0 - [!B0] BNOP .S2 resume_kernel,5 - -resume_userspace: - ;; make sure we don't miss an interrupt setting need_resched or - ;; sigpending between sampling and the rti - MASK_INT B2 - GET_THREAD_INFO A12 - LDW .D1T1 *+A12(THREAD_INFO_FLAGS),A2 - MVK .S1 _TIF_WORK_MASK,A1 - MVK .S1 _TIF_NEED_RESCHED,A3 - NOP 2 - AND .D1 A1,A2,A0 - [A0] BNOP .S1 work_pending,5 - BNOP .S1 restore_all,5 - - ;; - ;; System call handling - ;; B0 = syscall number (in sys_call_table) - ;; A4,B4,A6,B6,A8,B8 = arguments of the syscall function - ;; A4 is the return value register - ;; -system_call_saved: - MVK .L2 1,B2 - STW .D2T2 B2,*+SP(REGS__END+8) ; set syscall flag - MVC .S2 B2,ECR ; ack the software exception - - UNMASK_INT B2 ; re-enable global IT - -system_call_saved_noack: - ;; Check system call number - MVK .S2 __NR_syscalls,B1 -#ifdef CONFIG_C6X_BIG_KERNEL - || MVKL .S1 sys_ni_syscall,A0 -#endif - CMPLTU .L2 B0,B1,B1 -#ifdef CONFIG_C6X_BIG_KERNEL - || MVKH .S1 sys_ni_syscall,A0 -#endif - - ;; Check for ptrace - GET_THREAD_INFO A12 - -#ifdef CONFIG_C6X_BIG_KERNEL - [!B1] B .S2X A0 -#else - [!B1] B .S2 sys_ni_syscall -#endif - [!B1] ADDKPC .S2 ret_from_syscall_function,B3,4 - - ;; Get syscall handler addr from sys_call_table - ;; call tracesys_on or call syscall handler - LDW .D1T1 *+A12(THREAD_INFO_FLAGS),A2 - || MVKL .S2 sys_call_table,B1 - MVKH .S2 sys_call_table,B1 - LDW .D2T2 *+B1[B0],B0 - NOP 2 - ; A2 = thread_info flags - AND .D1 _TIF_SYSCALL_TRACE,A2,A2 - [A2] BNOP .S1 tracesys_on,5 - ;; B0 = _sys_call_table[__NR_*] - B .S2 B0 - ADDKPC .S2 ret_from_syscall_function,B3,4 - -ret_from_syscall_function: - STW .D2T1 A4,*+SP(REGS_A4+8) ; save return value in A4 - ; original A4 is in orig_A4 -syscall_exit: - ;; make sure we don't miss an interrupt setting need_resched or - ;; sigpending between sampling and the rti - MASK_INT B2 - LDW .D1T1 *+A12(THREAD_INFO_FLAGS),A2 - MVK .S1 _TIF_ALLWORK_MASK,A1 - NOP 3 - AND .D1 A1,A2,A2 ; check for work to do - [A2] BNOP .S1 syscall_exit_work,5 - -restore_all: - RESTORE_ALL NRP,NTSR - - ;; - ;; After a fork we jump here directly from resume, - ;; so that A4 contains the previous task structure. - ;; -ENTRY(ret_from_fork) -#ifdef CONFIG_C6X_BIG_KERNEL - MVKL .S1 schedule_tail,A0 - MVKH .S1 schedule_tail,A0 - B .S2X A0 -#else - B .S2 schedule_tail -#endif - ADDKPC .S2 ret_from_fork_2,B3,4 -ret_from_fork_2: - ;; return 0 in A4 for child process - GET_THREAD_INFO A12 - BNOP .S2 syscall_exit,3 - MVK .L2 0,B0 - STW .D2T2 B0,*+SP(REGS_A4+8) -ENDPROC(ret_from_fork) - -ENTRY(ret_from_kernel_thread) -#ifdef CONFIG_C6X_BIG_KERNEL - MVKL .S1 schedule_tail,A0 - MVKH .S1 schedule_tail,A0 - B .S2X A0 -#else - B .S2 schedule_tail -#endif - LDW .D2T2 *+SP(REGS_A0+8),B10 /* get fn */ - ADDKPC .S2 0f,B3,3 -0: - B .S2 B10 /* call fn */ - LDW .D2T1 *+SP(REGS_A1+8),A4 /* get arg */ - ADDKPC .S2 ret_from_fork_2,B3,3 -ENDPROC(ret_from_kernel_thread) - - ;; - ;; These are the interrupt handlers, responsible for calling c6x_do_IRQ() - ;; - .macro SAVE_ALL_INT - SAVE_ALL IRP,ITSR - .endm - - .macro CALL_INT int -#ifdef CONFIG_C6X_BIG_KERNEL - MVKL .S1 c6x_do_IRQ,A0 - MVKH .S1 c6x_do_IRQ,A0 - BNOP .S2X A0,1 - MVK .S1 int,A4 - ADDAW .D2 SP,2,B4 - MVKL .S2 ret_from_interrupt,B3 - MVKH .S2 ret_from_interrupt,B3 -#else - CALLP .S2 c6x_do_IRQ,B3 - || MVK .S1 int,A4 - || ADDAW .D2 SP,2,B4 - B .S1 ret_from_interrupt - NOP 5 -#endif - .endm - -ENTRY(_int4_handler) - SAVE_ALL_INT - CALL_INT 4 -ENDPROC(_int4_handler) - -ENTRY(_int5_handler) - SAVE_ALL_INT - CALL_INT 5 -ENDPROC(_int5_handler) - -ENTRY(_int6_handler) - SAVE_ALL_INT - CALL_INT 6 -ENDPROC(_int6_handler) - -ENTRY(_int7_handler) - SAVE_ALL_INT - CALL_INT 7 -ENDPROC(_int7_handler) - -ENTRY(_int8_handler) - SAVE_ALL_INT - CALL_INT 8 -ENDPROC(_int8_handler) - -ENTRY(_int9_handler) - SAVE_ALL_INT - CALL_INT 9 -ENDPROC(_int9_handler) - -ENTRY(_int10_handler) - SAVE_ALL_INT - CALL_INT 10 -ENDPROC(_int10_handler) - -ENTRY(_int11_handler) - SAVE_ALL_INT - CALL_INT 11 -ENDPROC(_int11_handler) - -ENTRY(_int12_handler) - SAVE_ALL_INT - CALL_INT 12 -ENDPROC(_int12_handler) - -ENTRY(_int13_handler) - SAVE_ALL_INT - CALL_INT 13 -ENDPROC(_int13_handler) - -ENTRY(_int14_handler) - SAVE_ALL_INT - CALL_INT 14 -ENDPROC(_int14_handler) - -ENTRY(_int15_handler) - SAVE_ALL_INT - CALL_INT 15 -ENDPROC(_int15_handler) - - ;; - ;; Handler for uninitialized and spurious interrupts - ;; -ENTRY(_bad_interrupt) - B .S2 IRP - NOP 5 -ENDPROC(_bad_interrupt) - - ;; - ;; Entry for NMI/exceptions/syscall - ;; -ENTRY(_nmi_handler) - SAVE_ALL NRP,NTSR - - MVC .S2 EFR,B2 - CMPEQ .L2 1,B2,B2 - || MVC .S2 TSR,B1 - CLR .S2 B1,10,10,B1 - MVC .S2 B1,TSR -#ifdef CONFIG_C6X_BIG_KERNEL - [!B2] MVKL .S1 process_exception,A0 - [!B2] MVKH .S1 process_exception,A0 - [!B2] B .S2X A0 -#else - [!B2] B .S2 process_exception -#endif - [B2] B .S2 system_call_saved - [!B2] ADDAW .D2 SP,2,B1 - [!B2] MV .D1X B1,A4 - ADDKPC .S2 ret_from_trap,B3,2 - -ret_from_trap: - MV .D2X A4,B0 - [!B0] BNOP .S2 ret_from_exception,5 - -#ifdef CONFIG_C6X_BIG_KERNEL - MVKL .S2 system_call_saved_noack,B3 - MVKH .S2 system_call_saved_noack,B3 -#endif - LDW .D2T2 *+SP(REGS_B0+8),B0 - LDW .D2T1 *+SP(REGS_A4+8),A4 - LDW .D2T2 *+SP(REGS_B4+8),B4 - LDW .D2T1 *+SP(REGS_A6+8),A6 - LDW .D2T2 *+SP(REGS_B6+8),B6 - LDW .D2T1 *+SP(REGS_A8+8),A8 -#ifdef CONFIG_C6X_BIG_KERNEL - || B .S2 B3 -#else - || B .S2 system_call_saved_noack -#endif - LDW .D2T2 *+SP(REGS_B8+8),B8 - NOP 4 -ENDPROC(_nmi_handler) - - ;; - ;; Jump to schedule() then return to ret_from_isr - ;; -#ifdef CONFIG_PREEMPTION -resume_kernel: - GET_THREAD_INFO A12 - LDW .D1T1 *+A12(THREAD_INFO_PREEMPT_COUNT),A1 - NOP 4 - [A1] BNOP .S2 restore_all,5 - -preempt_schedule: - GET_THREAD_INFO A2 - LDW .D1T1 *+A2(THREAD_INFO_FLAGS),A1 -#ifdef CONFIG_C6X_BIG_KERNEL - MVKL .S2 preempt_schedule_irq,B0 - MVKH .S2 preempt_schedule_irq,B0 - NOP 2 -#else - NOP 4 -#endif - AND .D1 _TIF_NEED_RESCHED,A1,A1 - [!A1] BNOP .S2 restore_all,5 -#ifdef CONFIG_C6X_BIG_KERNEL - B .S2 B0 -#else - B .S2 preempt_schedule_irq -#endif - ADDKPC .S2 preempt_schedule,B3,4 -#endif /* CONFIG_PREEMPTION */ - -ENTRY(enable_exception) - DINT - MVC .S2 TSR,B0 - MVC .S2 B3,NRP - MVK .L2 0xc,B1 - OR .D2 B0,B1,B0 - MVC .S2 B0,TSR ; Set GEE and XEN in TSR - B .S2 NRP - NOP 5 -ENDPROC(enable_exception) - - ;; - ;; Special system calls - ;; return address is in B3 - ;; -ENTRY(sys_rt_sigreturn) - ADD .D1X SP,8,A4 -#ifdef CONFIG_C6X_BIG_KERNEL - || MVKL .S1 do_rt_sigreturn,A0 - MVKH .S1 do_rt_sigreturn,A0 - BNOP .S2X A0,5 -#else - || B .S2 do_rt_sigreturn - NOP 5 -#endif -ENDPROC(sys_rt_sigreturn) - -ENTRY(sys_pread_c6x) - MV .D2X A8,B7 -#ifdef CONFIG_C6X_BIG_KERNEL - || MVKL .S1 sys_pread64,A0 - MVKH .S1 sys_pread64,A0 - BNOP .S2X A0,5 -#else - || B .S2 sys_pread64 - NOP 5 -#endif -ENDPROC(sys_pread_c6x) - -ENTRY(sys_pwrite_c6x) - MV .D2X A8,B7 -#ifdef CONFIG_C6X_BIG_KERNEL - || MVKL .S1 sys_pwrite64,A0 - MVKH .S1 sys_pwrite64,A0 - BNOP .S2X A0,5 -#else - || B .S2 sys_pwrite64 - NOP 5 -#endif -ENDPROC(sys_pwrite_c6x) - -;; On Entry -;; A4 - path -;; B4 - offset_lo (LE), offset_hi (BE) -;; A6 - offset_lo (BE), offset_hi (LE) -ENTRY(sys_truncate64_c6x) -#ifdef CONFIG_CPU_BIG_ENDIAN - MV .S2 B4,B5 - MV .D2X A6,B4 -#else - MV .D2X A6,B5 -#endif -#ifdef CONFIG_C6X_BIG_KERNEL - || MVKL .S1 sys_truncate64,A0 - MVKH .S1 sys_truncate64,A0 - BNOP .S2X A0,5 -#else - || B .S2 sys_truncate64 - NOP 5 -#endif -ENDPROC(sys_truncate64_c6x) - -;; On Entry -;; A4 - fd -;; B4 - offset_lo (LE), offset_hi (BE) -;; A6 - offset_lo (BE), offset_hi (LE) -ENTRY(sys_ftruncate64_c6x) -#ifdef CONFIG_CPU_BIG_ENDIAN - MV .S2 B4,B5 - MV .D2X A6,B4 -#else - MV .D2X A6,B5 -#endif -#ifdef CONFIG_C6X_BIG_KERNEL - || MVKL .S1 sys_ftruncate64,A0 - MVKH .S1 sys_ftruncate64,A0 - BNOP .S2X A0,5 -#else - || B .S2 sys_ftruncate64 - NOP 5 -#endif -ENDPROC(sys_ftruncate64_c6x) - -;; On Entry -;; A4 - fd -;; B4 - offset_lo (LE), offset_hi (BE) -;; A6 - offset_lo (BE), offset_hi (LE) -;; B6 - len_lo (LE), len_hi (BE) -;; A8 - len_lo (BE), len_hi (LE) -;; B8 - advice -ENTRY(sys_fadvise64_64_c6x) -#ifdef CONFIG_C6X_BIG_KERNEL - MVKL .S1 sys_fadvise64_64,A0 - MVKH .S1 sys_fadvise64_64,A0 - BNOP .S2X A0,2 -#else - B .S2 sys_fadvise64_64 - NOP 2 -#endif -#ifdef CONFIG_CPU_BIG_ENDIAN - MV .L2 B4,B5 - || MV .D2X A6,B4 - MV .L1 A8,A6 - || MV .D1X B6,A7 -#else - MV .D2X A6,B5 - MV .L1 A8,A7 - || MV .D1X B6,A6 -#endif - MV .L2 B8,B6 -ENDPROC(sys_fadvise64_64_c6x) - -;; On Entry -;; A4 - fd -;; B4 - mode -;; A6 - offset_hi -;; B6 - offset_lo -;; A8 - len_hi -;; B8 - len_lo -ENTRY(sys_fallocate_c6x) -#ifdef CONFIG_C6X_BIG_KERNEL - MVKL .S1 sys_fallocate,A0 - MVKH .S1 sys_fallocate,A0 - BNOP .S2X A0,1 -#else - B .S2 sys_fallocate - NOP -#endif - MV .D1 A6,A7 - MV .D1X B6,A6 - MV .D2X A8,B7 - MV .D2 B8,B6 -ENDPROC(sys_fallocate_c6x) - - ;; put this in .neardata for faster access when using DSBT mode - .section .neardata,"aw",@progbits - .global current_ksp - .hidden current_ksp -current_ksp: - .word init_thread_union + THREAD_START_SP diff --git a/arch/c6x/kernel/head.S b/arch/c6x/kernel/head.S deleted file mode 100644 index fecbeef827bc..000000000000 --- a/arch/c6x/kernel/head.S +++ /dev/null @@ -1,81 +0,0 @@ -; SPDX-License-Identifier: GPL-2.0-only -; -; Port on Texas Instruments TMS320C6x architecture -; -; Copyright (C) 2004, 2009, 2010, 2011 Texas Instruments Incorporated -; Author: Aurelien Jacquiot (aurelien.jacquiot@jaluna.com) -; -#include -#include -#include - - __HEAD -ENTRY(_c_int00) - ;; Save magic and pointer - MV .S1 A4,A10 - MV .S2 B4,B10 - MVKL .S2 __bss_start,B5 - MVKH .S2 __bss_start,B5 - MVKL .S2 __bss_stop,B6 - MVKH .S2 __bss_stop,B6 - SUB .L2 B6,B5,B6 ; bss size - - ;; Set the stack pointer - MVKL .S2 current_ksp,B0 - MVKH .S2 current_ksp,B0 - LDW .D2T2 *B0,B15 - - ;; clear bss - SHR .S2 B6,3,B0 ; number of dwords to clear - ZERO .L2 B13 - ZERO .L2 B12 -bss_loop: - BDEC .S2 bss_loop,B0 - NOP 3 - CMPLT .L2 B0,0,B1 - [!B1] STDW .D2T2 B13:B12,*B5++[1] - - NOP 4 - AND .D2 ~7,B15,B15 - - ;; Clear GIE and PGIE - MVC .S2 CSR,B2 - CLR .S2 B2,0,1,B2 - MVC .S2 B2,CSR - MVC .S2 TSR,B2 - CLR .S2 B2,0,1,B2 - MVC .S2 B2,TSR - MVC .S2 ITSR,B2 - CLR .S2 B2,0,1,B2 - MVC .S2 B2,ITSR - MVC .S2 NTSR,B2 - CLR .S2 B2,0,1,B2 - MVC .S2 B2,NTSR - - ;; pass DTB pointer to machine_init (or zero if none) - MVKL .S1 OF_DT_HEADER,A0 - MVKH .S1 OF_DT_HEADER,A0 - CMPEQ .L1 A10,A0,A0 - [A0] MV .S1X B10,A4 - [!A0] MVK .S1 0,A4 - -#ifdef CONFIG_C6X_BIG_KERNEL - MVKL .S1 machine_init,A0 - MVKH .S1 machine_init,A0 - B .S2X A0 - ADDKPC .S2 0f,B3,4 -0: -#else - CALLP .S2 machine_init,B3 -#endif - - ;; Jump to Linux init -#ifdef CONFIG_C6X_BIG_KERNEL - MVKL .S1 start_kernel,A0 - MVKH .S1 start_kernel,A0 - B .S2X A0 -#else - B .S2 start_kernel -#endif - NOP 5 -L1: BNOP .S2 L1,5 diff --git a/arch/c6x/kernel/irq.c b/arch/c6x/kernel/irq.c deleted file mode 100644 index e4c53d185b62..000000000000 --- a/arch/c6x/kernel/irq.c +++ /dev/null @@ -1,127 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * Copyright (C) 2011-2012 Texas Instruments Incorporated - * - * This borrows heavily from powerpc version, which is: - * - * Derived from arch/i386/kernel/irq.c - * Copyright (C) 1992 Linus Torvalds - * Adapted from arch/i386 by Gary Thomas - * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org) - * Updated and modified by Cort Dougan - * Copyright (C) 1996-2001 Cort Dougan - * Adapted for Power Macintosh by Paul Mackerras - * Copyright (C) 1996 Paul Mackerras (paulus@cs.anu.edu.au) - */ -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -unsigned long irq_err_count; - -static DEFINE_RAW_SPINLOCK(core_irq_lock); - -static void mask_core_irq(struct irq_data *data) -{ - unsigned int prio = data->hwirq; - - raw_spin_lock(&core_irq_lock); - and_creg(IER, ~(1 << prio)); - raw_spin_unlock(&core_irq_lock); -} - -static void unmask_core_irq(struct irq_data *data) -{ - unsigned int prio = data->hwirq; - - raw_spin_lock(&core_irq_lock); - or_creg(IER, 1 << prio); - raw_spin_unlock(&core_irq_lock); -} - -static struct irq_chip core_chip = { - .name = "core", - .irq_mask = mask_core_irq, - .irq_unmask = unmask_core_irq, -}; - -static int prio_to_virq[NR_PRIORITY_IRQS]; - -asmlinkage void c6x_do_IRQ(unsigned int prio, struct pt_regs *regs) -{ - struct pt_regs *old_regs = set_irq_regs(regs); - - irq_enter(); - - generic_handle_irq(prio_to_virq[prio]); - - irq_exit(); - - set_irq_regs(old_regs); -} - -static struct irq_domain *core_domain; - -static int core_domain_map(struct irq_domain *h, unsigned int virq, - irq_hw_number_t hw) -{ - if (hw < 4 || hw >= NR_PRIORITY_IRQS) - return -EINVAL; - - prio_to_virq[hw] = virq; - - irq_set_status_flags(virq, IRQ_LEVEL); - irq_set_chip_and_handler(virq, &core_chip, handle_level_irq); - return 0; -} - -static const struct irq_domain_ops core_domain_ops = { - .map = core_domain_map, - .xlate = irq_domain_xlate_onecell, -}; - -void __init init_IRQ(void) -{ - struct device_node *np; - - /* Mask all priority IRQs */ - and_creg(IER, ~0xfff0); - - np = of_find_compatible_node(NULL, NULL, "ti,c64x+core-pic"); - if (np != NULL) { - /* create the core host */ - core_domain = irq_domain_add_linear(np, NR_PRIORITY_IRQS, - &core_domain_ops, NULL); - if (core_domain) - irq_set_default_host(core_domain); - of_node_put(np); - } - - printk(KERN_INFO "Core interrupt controller initialized\n"); - - /* now we're ready for other SoC controllers */ - megamod_pic_init(); - - /* Clear all general IRQ flags */ - set_creg(ICR, 0xfff0); -} - -void ack_bad_irq(int irq) -{ - printk(KERN_ERR "IRQ: spurious interrupt %d\n", irq); - irq_err_count++; -} - -int arch_show_interrupts(struct seq_file *p, int prec) -{ - seq_printf(p, "%*s: %10lu\n", prec, "Err", irq_err_count); - return 0; -} diff --git a/arch/c6x/kernel/module.c b/arch/c6x/kernel/module.c deleted file mode 100644 index 09b4c6bfe877..000000000000 --- a/arch/c6x/kernel/module.c +++ /dev/null @@ -1,119 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Port on Texas Instruments TMS320C6x architecture - * - * Copyright (C) 2005, 2009, 2010, 2011 Texas Instruments Incorporated - * Author: Thomas Charleux (thomas.charleux@jaluna.com) - */ -#include -#include -#include -#include - -static inline int fixup_pcr(u32 *ip, Elf32_Addr dest, u32 maskbits, int shift) -{ - u32 opcode; - long ep = (long)ip & ~31; - long delta = ((long)dest - ep) >> 2; - long mask = (1 << maskbits) - 1; - - if ((delta >> (maskbits - 1)) == 0 || - (delta >> (maskbits - 1)) == -1) { - opcode = *ip; - opcode &= ~(mask << shift); - opcode |= ((delta & mask) << shift); - *ip = opcode; - - pr_debug("REL PCR_S%d[%p] dest[%p] opcode[%08x]\n", - maskbits, ip, (void *)dest, opcode); - - return 0; - } - pr_err("PCR_S%d reloc %p -> %p out of range!\n", - maskbits, ip, (void *)dest); - - return -1; -} - -/* - * apply a RELA relocation - */ -int apply_relocate_add(Elf32_Shdr *sechdrs, - const char *strtab, - unsigned int symindex, - unsigned int relsec, - struct module *me) -{ - Elf32_Rela *rel = (void *) sechdrs[relsec].sh_addr; - Elf_Sym *sym; - u32 *location, opcode; - unsigned int i; - Elf32_Addr v; - Elf_Addr offset = 0; - - pr_debug("Applying relocate section %u to %u with offset 0x%x\n", - relsec, sechdrs[relsec].sh_info, offset); - - for (i = 0; i < sechdrs[relsec].sh_size / sizeof(*rel); i++) { - /* This is where to make the change */ - location = (void *)sechdrs[sechdrs[relsec].sh_info].sh_addr - + rel[i].r_offset - offset; - - /* This is the symbol it is referring to. Note that all - undefined symbols have been resolved. */ - sym = (Elf_Sym *)sechdrs[symindex].sh_addr - + ELF32_R_SYM(rel[i].r_info); - - /* this is the adjustment to be made */ - v = sym->st_value + rel[i].r_addend; - - switch (ELF32_R_TYPE(rel[i].r_info)) { - case R_C6000_ABS32: - pr_debug("RELA ABS32: [%p] = 0x%x\n", location, v); - *location = v; - break; - case R_C6000_ABS16: - pr_debug("RELA ABS16: [%p] = 0x%x\n", location, v); - *(u16 *)location = v; - break; - case R_C6000_ABS8: - pr_debug("RELA ABS8: [%p] = 0x%x\n", location, v); - *(u8 *)location = v; - break; - case R_C6000_ABS_L16: - opcode = *location; - opcode &= ~0x7fff80; - opcode |= ((v & 0xffff) << 7); - pr_debug("RELA ABS_L16[%p] v[0x%x] opcode[0x%x]\n", - location, v, opcode); - *location = opcode; - break; - case R_C6000_ABS_H16: - opcode = *location; - opcode &= ~0x7fff80; - opcode |= ((v >> 9) & 0x7fff80); - pr_debug("RELA ABS_H16[%p] v[0x%x] opcode[0x%x]\n", - location, v, opcode); - *location = opcode; - break; - case R_C6000_PCR_S21: - if (fixup_pcr(location, v, 21, 7)) - return -ENOEXEC; - break; - case R_C6000_PCR_S12: - if (fixup_pcr(location, v, 12, 16)) - return -ENOEXEC; - break; - case R_C6000_PCR_S10: - if (fixup_pcr(location, v, 10, 13)) - return -ENOEXEC; - break; - default: - pr_err("module %s: Unknown RELA relocation: %u\n", - me->name, ELF32_R_TYPE(rel[i].r_info)); - return -ENOEXEC; - } - } - - return 0; -} diff --git a/arch/c6x/kernel/process.c b/arch/c6x/kernel/process.c deleted file mode 100644 index 9f4fd6a40a10..000000000000 --- a/arch/c6x/kernel/process.c +++ /dev/null @@ -1,151 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Port on Texas Instruments TMS320C6x architecture - * - * Copyright (C) 2004, 2006, 2009, 2010, 2011 Texas Instruments Incorporated - * Author: Aurelien Jacquiot (aurelien.jacquiot@jaluna.com) - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -/* hooks for board specific support */ -void (*c6x_restart)(void); -void (*c6x_halt)(void); - -extern asmlinkage void ret_from_fork(void); -extern asmlinkage void ret_from_kernel_thread(void); - -/* - * power off function, if any - */ -void (*pm_power_off)(void); -EXPORT_SYMBOL(pm_power_off); - -void arch_cpu_idle(void) -{ - unsigned long tmp; - - /* - * Put local_irq_enable and idle in same execute packet - * to make them atomic and avoid race to idle with - * interrupts enabled. - */ - asm volatile (" mvc .s2 CSR,%0\n" - " or .d2 1,%0,%0\n" - " mvc .s2 %0,CSR\n" - "|| idle\n" - : "=b"(tmp)); -} - -static void halt_loop(void) -{ - printk(KERN_EMERG "System Halted, OK to turn off power\n"); - local_irq_disable(); - while (1) - asm volatile("idle\n"); -} - -void machine_restart(char *__unused) -{ - if (c6x_restart) - c6x_restart(); - halt_loop(); -} - -void machine_halt(void) -{ - if (c6x_halt) - c6x_halt(); - halt_loop(); -} - -void machine_power_off(void) -{ - if (pm_power_off) - pm_power_off(); - halt_loop(); -} - -void flush_thread(void) -{ -} - -/* - * Do necessary setup to start up a newly executed thread. - */ -void start_thread(struct pt_regs *regs, unsigned int pc, unsigned long usp) -{ - /* - * The binfmt loader will setup a "full" stack, but the C6X - * operates an "empty" stack. So we adjust the usp so that - * argc doesn't get destroyed if an interrupt is taken before - * it is read from the stack. - * - * NB: Library startup code needs to match this. - */ - usp -= 8; - - regs->pc = pc; - regs->sp = usp; - regs->tsr |= 0x40; /* set user mode */ - current->thread.usp = usp; -} - -/* - * Copy a new thread context in its stack. - */ -int copy_thread(unsigned long clone_flags, unsigned long usp, - unsigned long ustk_size, struct task_struct *p, - unsigned long tls) -{ - struct pt_regs *childregs; - - childregs = task_pt_regs(p); - - if (unlikely(p->flags & PF_KTHREAD)) { - /* case of __kernel_thread: we return to supervisor space */ - memset(childregs, 0, sizeof(struct pt_regs)); - childregs->sp = (unsigned long)(childregs + 1); - p->thread.pc = (unsigned long) ret_from_kernel_thread; - childregs->a0 = usp; /* function */ - childregs->a1 = ustk_size; /* argument */ - } else { - /* Otherwise use the given stack */ - *childregs = *current_pt_regs(); - if (usp) - childregs->sp = usp; - p->thread.pc = (unsigned long) ret_from_fork; - } - - /* Set usp/ksp */ - p->thread.usp = childregs->sp; - thread_saved_ksp(p) = (unsigned long)childregs - 8; - p->thread.wchan = p->thread.pc; -#ifdef __DSBT__ - { - unsigned long dp; - - asm volatile ("mv .S2 b14,%0\n" : "=b"(dp)); - - thread_saved_dp(p) = dp; - if (usp == -1) - childregs->dp = dp; - } -#endif - return 0; -} - -unsigned long get_wchan(struct task_struct *p) -{ - return p->thread.wchan; -} diff --git a/arch/c6x/kernel/ptrace.c b/arch/c6x/kernel/ptrace.c deleted file mode 100644 index 3cdaa8cf0ed6..000000000000 --- a/arch/c6x/kernel/ptrace.c +++ /dev/null @@ -1,139 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Port on Texas Instruments TMS320C6x architecture - * - * Copyright (C) 2004, 2006, 2009, 2010, 2011 Texas Instruments Incorporated - * Author: Aurelien Jacquiot (aurelien.jacquiot@jaluna.com) - * - * Updated for 2.6.34: Mark Salter - */ -#include -#include -#include -#include -#include - -#include - -#define PT_REG_SIZE (sizeof(struct pt_regs)) - -/* - * Called by kernel/ptrace.c when detaching. - */ -void ptrace_disable(struct task_struct *child) -{ - /* nothing to do */ -} - -/* - * Get a register number from live pt_regs for the specified task. - */ -static inline long get_reg(struct task_struct *task, int regno) -{ - long *addr = (long *)task_pt_regs(task); - - if (regno == PT_TSR || regno == PT_CSR) - return 0; - - return addr[regno]; -} - -/* - * Write contents of register REGNO in task TASK. - */ -static inline int put_reg(struct task_struct *task, - int regno, - unsigned long data) -{ - unsigned long *addr = (unsigned long *)task_pt_regs(task); - - if (regno != PT_TSR && regno != PT_CSR) - addr[regno] = data; - - return 0; -} - -/* regset get/set implementations */ - -static int gpr_get(struct task_struct *target, - const struct user_regset *regset, - struct membuf to) -{ - return membuf_write(&to, task_pt_regs(target), sizeof(struct pt_regs)); -} - -enum c6x_regset { - REGSET_GPR, -}; - -static const struct user_regset c6x_regsets[] = { - [REGSET_GPR] = { - .core_note_type = NT_PRSTATUS, - .n = ELF_NGREG, - .size = sizeof(u32), - .align = sizeof(u32), - .regset_get = gpr_get, - }, -}; - -static const struct user_regset_view user_c6x_native_view = { - .name = "tic6x", - .e_machine = EM_TI_C6000, - .regsets = c6x_regsets, - .n = ARRAY_SIZE(c6x_regsets), -}; - -const struct user_regset_view *task_user_regset_view(struct task_struct *task) -{ - return &user_c6x_native_view; -} - -/* - * Perform ptrace request - */ -long arch_ptrace(struct task_struct *child, long request, - unsigned long addr, unsigned long data) -{ - int ret = 0; - - switch (request) { - /* - * write the word at location addr. - */ - case PTRACE_POKETEXT: - ret = generic_ptrace_pokedata(child, addr, data); - if (ret == 0 && request == PTRACE_POKETEXT) - flush_icache_range(addr, addr + 4); - break; - default: - ret = ptrace_request(child, request, addr, data); - break; - } - - return ret; -} - -/* - * handle tracing of system call entry - * - return the revised system call number or ULONG_MAX to cause ENOSYS - */ -asmlinkage unsigned long syscall_trace_entry(struct pt_regs *regs) -{ - if (tracehook_report_syscall_entry(regs)) - /* tracing decided this syscall should not happen, so - * We'll return a bogus call number to get an ENOSYS - * error, but leave the original number in - * regs->orig_a4 - */ - return ULONG_MAX; - - return regs->b0; -} - -/* - * handle tracing of system call exit - */ -asmlinkage void syscall_trace_exit(struct pt_regs *regs) -{ - tracehook_report_syscall_exit(regs, 0); -} diff --git a/arch/c6x/kernel/setup.c b/arch/c6x/kernel/setup.c deleted file mode 100644 index 9254c3b794a5..000000000000 --- a/arch/c6x/kernel/setup.c +++ /dev/null @@ -1,476 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Port on Texas Instruments TMS320C6x architecture - * - * Copyright (C) 2004, 2006, 2009, 2010, 2011 Texas Instruments Incorporated - * Author: Aurelien Jacquiot (aurelien.jacquiot@jaluna.com) - */ -#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 - -static const char *c6x_soc_name; - -struct screen_info screen_info; - -int c6x_num_cores; -EXPORT_SYMBOL_GPL(c6x_num_cores); - -unsigned int c6x_silicon_rev; -EXPORT_SYMBOL_GPL(c6x_silicon_rev); - -/* - * Device status register. This holds information - * about device configuration needed by some drivers. - */ -unsigned int c6x_devstat; -EXPORT_SYMBOL_GPL(c6x_devstat); - -/* - * Some SoCs have fuse registers holding a unique MAC - * address. This is parsed out of the device tree with - * the resulting MAC being held here. - */ -unsigned char c6x_fuse_mac[6]; - -unsigned long memory_start; -unsigned long memory_end; -EXPORT_SYMBOL(memory_end); - -unsigned long ram_start; -unsigned long ram_end; - -/* Uncached memory for DMA consistent use (memdma=) */ -static unsigned long dma_start __initdata; -static unsigned long dma_size __initdata; - -struct cpuinfo_c6x { - const char *cpu_name; - const char *cpu_voltage; - const char *mmu; - const char *fpu; - char *cpu_rev; - unsigned int core_id; - char __cpu_rev[5]; -}; - -static DEFINE_PER_CPU(struct cpuinfo_c6x, cpu_data); - -unsigned int ticks_per_ns_scaled; -EXPORT_SYMBOL(ticks_per_ns_scaled); - -unsigned int c6x_core_freq; - -static void __init get_cpuinfo(void) -{ - unsigned cpu_id, rev_id, csr; - struct clk *coreclk = clk_get_sys(NULL, "core"); - unsigned long core_khz; - u64 tmp; - struct cpuinfo_c6x *p; - struct device_node *node; - - p = &per_cpu(cpu_data, smp_processor_id()); - - if (!IS_ERR(coreclk)) - c6x_core_freq = clk_get_rate(coreclk); - else { - printk(KERN_WARNING - "Cannot find core clock frequency. Using 700MHz\n"); - c6x_core_freq = 700000000; - } - - core_khz = c6x_core_freq / 1000; - - tmp = (uint64_t)core_khz << C6X_NDELAY_SCALE; - do_div(tmp, 1000000); - ticks_per_ns_scaled = tmp; - - csr = get_creg(CSR); - cpu_id = csr >> 24; - rev_id = (csr >> 16) & 0xff; - - p->mmu = "none"; - p->fpu = "none"; - p->cpu_voltage = "unknown"; - - switch (cpu_id) { - case 0: - p->cpu_name = "C67x"; - p->fpu = "yes"; - break; - case 2: - p->cpu_name = "C62x"; - break; - case 8: - p->cpu_name = "C64x"; - break; - case 12: - p->cpu_name = "C64x"; - break; - case 16: - p->cpu_name = "C64x+"; - p->cpu_voltage = "1.2"; - break; - case 21: - p->cpu_name = "C66X"; - p->cpu_voltage = "1.2"; - break; - default: - p->cpu_name = "unknown"; - break; - } - - if (cpu_id < 16) { - switch (rev_id) { - case 0x1: - if (cpu_id > 8) { - p->cpu_rev = "DM640/DM641/DM642/DM643"; - p->cpu_voltage = "1.2 - 1.4"; - } else { - p->cpu_rev = "C6201"; - p->cpu_voltage = "2.5"; - } - break; - case 0x2: - p->cpu_rev = "C6201B/C6202/C6211"; - p->cpu_voltage = "1.8"; - break; - case 0x3: - p->cpu_rev = "C6202B/C6203/C6204/C6205"; - p->cpu_voltage = "1.5"; - break; - case 0x201: - p->cpu_rev = "C6701 revision 0 (early CPU)"; - p->cpu_voltage = "1.8"; - break; - case 0x202: - p->cpu_rev = "C6701/C6711/C6712"; - p->cpu_voltage = "1.8"; - break; - case 0x801: - p->cpu_rev = "C64x"; - p->cpu_voltage = "1.5"; - break; - default: - p->cpu_rev = "unknown"; - } - } else { - p->cpu_rev = p->__cpu_rev; - snprintf(p->__cpu_rev, sizeof(p->__cpu_rev), "0x%x", cpu_id); - } - - p->core_id = get_coreid(); - - for_each_of_cpu_node(node) - ++c6x_num_cores; - - node = of_find_node_by_name(NULL, "soc"); - if (node) { - if (of_property_read_string(node, "model", &c6x_soc_name)) - c6x_soc_name = "unknown"; - of_node_put(node); - } else - c6x_soc_name = "unknown"; - - printk(KERN_INFO "CPU%d: %s rev %s, %s volts, %uMHz\n", - p->core_id, p->cpu_name, p->cpu_rev, - p->cpu_voltage, c6x_core_freq / 1000000); -} - -/* - * Early parsing of the command line - */ -static u32 mem_size __initdata; - -/* "mem=" parsing. */ -static int __init early_mem(char *p) -{ - if (!p) - return -EINVAL; - - mem_size = memparse(p, &p); - /* don't remove all of memory when handling "mem={invalid}" */ - if (mem_size == 0) - return -EINVAL; - - return 0; -} -early_param("mem", early_mem); - -/* "memdma=[@
]" parsing. */ -static int __init early_memdma(char *p) -{ - if (!p) - return -EINVAL; - - dma_size = memparse(p, &p); - if (*p == '@') - dma_start = memparse(p, &p); - - return 0; -} -early_param("memdma", early_memdma); - -int __init c6x_add_memory(phys_addr_t start, unsigned long size) -{ - static int ram_found __initdata; - - /* We only handle one bank (the one with PAGE_OFFSET) for now */ - if (ram_found) - return -EINVAL; - - if (start > PAGE_OFFSET || PAGE_OFFSET >= (start + size)) - return 0; - - ram_start = start; - ram_end = start + size; - - ram_found = 1; - return 0; -} - -/* - * Do early machine setup and device tree parsing. This is called very - * early on the boot process. - */ -notrace void __init machine_init(unsigned long dt_ptr) -{ - void *dtb = __va(dt_ptr); - void *fdt = __dtb_start; - - /* interrupts must be masked */ - set_creg(IER, 2); - - /* - * Set the Interrupt Service Table (IST) to the beginning of the - * vector table. - */ - set_ist(_vectors_start); - - /* - * dtb is passed in from bootloader. - * fdt is linked in blob. - */ - if (dtb && dtb != fdt) - fdt = dtb; - - /* Do some early initialization based on the flat device tree */ - early_init_dt_scan(fdt); - - parse_early_param(); -} - -void __init setup_arch(char **cmdline_p) -{ - phys_addr_t start, end; - u64 i; - - printk(KERN_INFO "Initializing kernel\n"); - - /* Initialize command line */ - *cmdline_p = boot_command_line; - - memory_end = ram_end; - memory_end &= ~(PAGE_SIZE - 1); - - if (mem_size && (PAGE_OFFSET + PAGE_ALIGN(mem_size)) < memory_end) - memory_end = PAGE_OFFSET + PAGE_ALIGN(mem_size); - - /* add block that this kernel can use */ - memblock_add(PAGE_OFFSET, memory_end - PAGE_OFFSET); - - /* reserve kernel text/data/bss */ - memblock_reserve(PAGE_OFFSET, - PAGE_ALIGN((unsigned long)&_end - PAGE_OFFSET)); - - if (dma_size) { - /* align to cacheability granularity */ - dma_size = CACHE_REGION_END(dma_size); - - if (!dma_start) - dma_start = memory_end - dma_size; - - /* align to cacheability granularity */ - dma_start = CACHE_REGION_START(dma_start); - - /* reserve DMA memory taken from kernel memory */ - if (memblock_is_region_memory(dma_start, dma_size)) - memblock_reserve(dma_start, dma_size); - } - - memory_start = PAGE_ALIGN((unsigned int) &_end); - - printk(KERN_INFO "Memory Start=%08lx, Memory End=%08lx\n", - memory_start, memory_end); - -#ifdef CONFIG_BLK_DEV_INITRD - /* - * Reserve initrd memory if in kernel memory. - */ - if (initrd_start < initrd_end) - if (memblock_is_region_memory(initrd_start, - initrd_end - initrd_start)) - memblock_reserve(initrd_start, - initrd_end - initrd_start); -#endif - - init_mm.start_code = (unsigned long) &_stext; - init_mm.end_code = (unsigned long) &_etext; - init_mm.end_data = memory_start; - init_mm.brk = memory_start; - - unflatten_and_copy_device_tree(); - - c6x_cache_init(); - - /* Set the whole external memory as non-cacheable */ - disable_caching(ram_start, ram_end - 1); - - /* Set caching of external RAM used by Linux */ - for_each_mem_range(i, &start, &end) - enable_caching(CACHE_REGION_START(start), - CACHE_REGION_START(end - 1)); - -#ifdef CONFIG_BLK_DEV_INITRD - /* - * Enable caching for initrd which falls outside kernel memory. - */ - if (initrd_start < initrd_end) { - if (!memblock_is_region_memory(initrd_start, - initrd_end - initrd_start)) - enable_caching(CACHE_REGION_START(initrd_start), - CACHE_REGION_START(initrd_end - 1)); - } -#endif - - /* - * Disable caching for dma coherent memory taken from kernel memory. - */ - if (dma_size && memblock_is_region_memory(dma_start, dma_size)) - disable_caching(dma_start, - CACHE_REGION_START(dma_start + dma_size - 1)); - - /* Initialize the coherent memory allocator */ - coherent_mem_init(dma_start, dma_size); - - max_low_pfn = PFN_DOWN(memory_end); - min_low_pfn = PFN_UP(memory_start); - max_pfn = max_low_pfn; - max_mapnr = max_low_pfn - min_low_pfn; - - /* Get kmalloc into gear */ - paging_init(); - - /* - * Probe for Device State Configuration Registers. - * We have to do this early in case timer needs to be enabled - * through DSCR. - */ - dscr_probe(); - - /* We do this early for timer and core clock frequency */ - c64x_setup_clocks(); - - /* Get CPU info */ - get_cpuinfo(); - -#if defined(CONFIG_VT) && defined(CONFIG_DUMMY_CONSOLE) - conswitchp = &dummy_con; -#endif -} - -#define cpu_to_ptr(n) ((void *)((long)(n)+1)) -#define ptr_to_cpu(p) ((long)(p) - 1) - -static int show_cpuinfo(struct seq_file *m, void *v) -{ - int n = ptr_to_cpu(v); - struct cpuinfo_c6x *p = &per_cpu(cpu_data, n); - - if (n == 0) { - seq_printf(m, - "soc\t\t: %s\n" - "soc revision\t: 0x%x\n" - "soc cores\t: %d\n", - c6x_soc_name, c6x_silicon_rev, c6x_num_cores); - } - - seq_printf(m, - "\n" - "processor\t: %d\n" - "cpu\t\t: %s\n" - "core revision\t: %s\n" - "core voltage\t: %s\n" - "core id\t\t: %d\n" - "mmu\t\t: %s\n" - "fpu\t\t: %s\n" - "cpu MHz\t\t: %u\n" - "bogomips\t: %lu.%02lu\n\n", - n, - p->cpu_name, p->cpu_rev, p->cpu_voltage, - p->core_id, p->mmu, p->fpu, - (c6x_core_freq + 500000) / 1000000, - (loops_per_jiffy/(500000/HZ)), - (loops_per_jiffy/(5000/HZ))%100); - - return 0; -} - -static void *c_start(struct seq_file *m, loff_t *pos) -{ - return *pos < nr_cpu_ids ? cpu_to_ptr(*pos) : NULL; -} -static void *c_next(struct seq_file *m, void *v, loff_t *pos) -{ - ++*pos; - return NULL; -} -static void c_stop(struct seq_file *m, void *v) -{ -} - -const struct seq_operations cpuinfo_op = { - c_start, - c_stop, - c_next, - show_cpuinfo -}; - -static struct cpu cpu_devices[NR_CPUS]; - -static int __init topology_init(void) -{ - int i; - - for_each_present_cpu(i) - register_cpu(&cpu_devices[i], i); - - return 0; -} - -subsys_initcall(topology_init); diff --git a/arch/c6x/kernel/signal.c b/arch/c6x/kernel/signal.c deleted file mode 100644 index 862460c3b183..000000000000 --- a/arch/c6x/kernel/signal.c +++ /dev/null @@ -1,322 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Port on Texas Instruments TMS320C6x architecture - * - * Copyright (C) 2004, 2006, 2009, 2010, 2011 Texas Instruments Incorporated - * Author: Aurelien Jacquiot (aurelien.jacquiot@jaluna.com) - * - * Updated for 2.6.34: Mark Salter - */ - -#include -#include -#include -#include - -#include -#include -#include - - -/* - * Do a signal return, undo the signal stack. - */ - -#define RETCODE_SIZE (9 << 2) /* 9 instructions = 36 bytes */ - -struct rt_sigframe { - struct siginfo __user *pinfo; - void __user *puc; - struct siginfo info; - struct ucontext uc; - unsigned long retcode[RETCODE_SIZE >> 2]; -}; - -static int restore_sigcontext(struct pt_regs *regs, - struct sigcontext __user *sc) -{ - int err = 0; - - /* The access_ok check was done by caller, so use __get_user here */ -#define COPY(x) (err |= __get_user(regs->x, &sc->sc_##x)) - - COPY(sp); COPY(a4); COPY(b4); COPY(a6); COPY(b6); COPY(a8); COPY(b8); - COPY(a0); COPY(a1); COPY(a2); COPY(a3); COPY(a5); COPY(a7); COPY(a9); - COPY(b0); COPY(b1); COPY(b2); COPY(b3); COPY(b5); COPY(b7); COPY(b9); - - COPY(a16); COPY(a17); COPY(a18); COPY(a19); - COPY(a20); COPY(a21); COPY(a22); COPY(a23); - COPY(a24); COPY(a25); COPY(a26); COPY(a27); - COPY(a28); COPY(a29); COPY(a30); COPY(a31); - COPY(b16); COPY(b17); COPY(b18); COPY(b19); - COPY(b20); COPY(b21); COPY(b22); COPY(b23); - COPY(b24); COPY(b25); COPY(b26); COPY(b27); - COPY(b28); COPY(b29); COPY(b30); COPY(b31); - - COPY(csr); COPY(pc); - -#undef COPY - - return err; -} - -asmlinkage int do_rt_sigreturn(struct pt_regs *regs) -{ - struct rt_sigframe __user *frame; - sigset_t set; - - /* Always make any pending restarted system calls return -EINTR */ - current->restart_block.fn = do_no_restart_syscall; - - /* - * Since we stacked the signal on a dword boundary, - * 'sp' should be dword aligned here. If it's - * not, then the user is trying to mess with us. - */ - if (regs->sp & 7) - goto badframe; - - frame = (struct rt_sigframe __user *) ((unsigned long) regs->sp + 8); - - if (!access_ok(frame, sizeof(*frame))) - goto badframe; - if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set))) - goto badframe; - - set_current_blocked(&set); - - if (restore_sigcontext(regs, &frame->uc.uc_mcontext)) - goto badframe; - - return regs->a4; - -badframe: - force_sig(SIGSEGV); - return 0; -} - -static int setup_sigcontext(struct sigcontext __user *sc, struct pt_regs *regs, - unsigned long mask) -{ - int err = 0; - - err |= __put_user(mask, &sc->sc_mask); - - /* The access_ok check was done by caller, so use __put_user here */ -#define COPY(x) (err |= __put_user(regs->x, &sc->sc_##x)) - - COPY(sp); COPY(a4); COPY(b4); COPY(a6); COPY(b6); COPY(a8); COPY(b8); - COPY(a0); COPY(a1); COPY(a2); COPY(a3); COPY(a5); COPY(a7); COPY(a9); - COPY(b0); COPY(b1); COPY(b2); COPY(b3); COPY(b5); COPY(b7); COPY(b9); - - COPY(a16); COPY(a17); COPY(a18); COPY(a19); - COPY(a20); COPY(a21); COPY(a22); COPY(a23); - COPY(a24); COPY(a25); COPY(a26); COPY(a27); - COPY(a28); COPY(a29); COPY(a30); COPY(a31); - COPY(b16); COPY(b17); COPY(b18); COPY(b19); - COPY(b20); COPY(b21); COPY(b22); COPY(b23); - COPY(b24); COPY(b25); COPY(b26); COPY(b27); - COPY(b28); COPY(b29); COPY(b30); COPY(b31); - - COPY(csr); COPY(pc); - -#undef COPY - - return err; -} - -static inline void __user *get_sigframe(struct ksignal *ksig, - struct pt_regs *regs, - unsigned long framesize) -{ - unsigned long sp = sigsp(regs->sp, ksig); - - /* - * No matter what happens, 'sp' must be dword - * aligned. Otherwise, nasty things will happen - */ - return (void __user *)((sp - framesize) & ~7); -} - -static int setup_rt_frame(struct ksignal *ksig, sigset_t *set, - struct pt_regs *regs) -{ - struct rt_sigframe __user *frame; - unsigned long __user *retcode; - int err = 0; - - frame = get_sigframe(ksig, regs, sizeof(*frame)); - - if (!access_ok(frame, sizeof(*frame))) - return -EFAULT; - - err |= __put_user(&frame->info, &frame->pinfo); - err |= __put_user(&frame->uc, &frame->puc); - err |= copy_siginfo_to_user(&frame->info, &ksig->info); - - /* Clear all the bits of the ucontext we don't use. */ - err |= __clear_user(&frame->uc, offsetof(struct ucontext, uc_mcontext)); - - err |= setup_sigcontext(&frame->uc.uc_mcontext, regs, set->sig[0]); - err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set)); - - /* Set up to return from userspace */ - retcode = (unsigned long __user *) &frame->retcode; - - /* The access_ok check was done above, so use __put_user here */ -#define COPY(x) (err |= __put_user(x, retcode++)) - - COPY(0x0000002AUL | (__NR_rt_sigreturn << 7)); - /* MVK __NR_rt_sigreturn,B0 */ - COPY(0x10000000UL); /* SWE */ - COPY(0x00006000UL); /* NOP 4 */ - COPY(0x00006000UL); /* NOP 4 */ - COPY(0x00006000UL); /* NOP 4 */ - COPY(0x00006000UL); /* NOP 4 */ - COPY(0x00006000UL); /* NOP 4 */ - COPY(0x00006000UL); /* NOP 4 */ - COPY(0x00006000UL); /* NOP 4 */ - -#undef COPY - - if (err) - return -EFAULT; - - flush_icache_range((unsigned long) &frame->retcode, - (unsigned long) &frame->retcode + RETCODE_SIZE); - - retcode = (unsigned long __user *) &frame->retcode; - - /* Change user context to branch to signal handler */ - regs->sp = (unsigned long) frame - 8; - regs->b3 = (unsigned long) retcode; - regs->pc = (unsigned long) ksig->ka.sa.sa_handler; - - /* Give the signal number to the handler */ - regs->a4 = ksig->sig; - - /* - * For realtime signals we must also set the second and third - * arguments for the signal handler. - * -- Peter Maydell 2000-12-06 - */ - regs->b4 = (unsigned long)&frame->info; - regs->a6 = (unsigned long)&frame->uc; - - return 0; -} - -static inline void -handle_restart(struct pt_regs *regs, struct k_sigaction *ka, int has_handler) -{ - switch (regs->a4) { - case -ERESTARTNOHAND: - if (!has_handler) - goto do_restart; - regs->a4 = -EINTR; - break; - - case -ERESTARTSYS: - if (has_handler && !(ka->sa.sa_flags & SA_RESTART)) { - regs->a4 = -EINTR; - break; - } - fallthrough; - case -ERESTARTNOINTR: -do_restart: - regs->a4 = regs->orig_a4; - regs->pc -= 4; - break; - } -} - -/* - * handle the actual delivery of a signal to userspace - */ -static void handle_signal(struct ksignal *ksig, struct pt_regs *regs, - int syscall) -{ - int ret; - - /* Are we from a system call? */ - if (syscall) { - /* If so, check system call restarting.. */ - switch (regs->a4) { - case -ERESTART_RESTARTBLOCK: - case -ERESTARTNOHAND: - regs->a4 = -EINTR; - break; - - case -ERESTARTSYS: - if (!(ksig->ka.sa.sa_flags & SA_RESTART)) { - regs->a4 = -EINTR; - break; - } - - fallthrough; - case -ERESTARTNOINTR: - regs->a4 = regs->orig_a4; - regs->pc -= 4; - } - } - - /* Set up the stack frame */ - ret = setup_rt_frame(ksig, sigmask_to_save(), regs); - signal_setup_done(ret, ksig, 0); -} - -/* - * handle a potential signal - */ -static void do_signal(struct pt_regs *regs, int syscall) -{ - struct ksignal ksig; - - /* we want the common case to go fast, which is why we may in certain - * cases get here from kernel mode */ - if (!user_mode(regs)) - return; - - if (get_signal(&ksig)) { - handle_signal(&ksig, regs, syscall); - return; - } - - /* did we come from a system call? */ - if (syscall) { - /* restart the system call - no handlers present */ - switch (regs->a4) { - case -ERESTARTNOHAND: - case -ERESTARTSYS: - case -ERESTARTNOINTR: - regs->a4 = regs->orig_a4; - regs->pc -= 4; - break; - - case -ERESTART_RESTARTBLOCK: - regs->a4 = regs->orig_a4; - regs->b0 = __NR_restart_syscall; - regs->pc -= 4; - break; - } - } - - /* if there's no signal to deliver, we just put the saved sigmask - * back */ - restore_saved_sigmask(); -} - -/* - * notification of userspace execution resumption - * - triggered by current->work.notify_resume - */ -asmlinkage void do_notify_resume(struct pt_regs *regs, u32 thread_info_flags, - int syscall) -{ - /* deal with pending signal delivery */ - if (thread_info_flags & (_TIF_SIGPENDING | _TIF_NOTIFY_SIGNAL)) - do_signal(regs, syscall); - - if (thread_info_flags & (1 << TIF_NOTIFY_RESUME)) - tracehook_notify_resume(regs); -} diff --git a/arch/c6x/kernel/soc.c b/arch/c6x/kernel/soc.c deleted file mode 100644 index 8362f9390e03..000000000000 --- a/arch/c6x/kernel/soc.c +++ /dev/null @@ -1,87 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Miscellaneous SoC-specific hooks. - * - * Copyright (C) 2011 Texas Instruments Incorporated - * Author: Mark Salter - */ -#include -#include -#include -#include -#include - -struct soc_ops soc_ops; - -int soc_get_exception(void) -{ - if (!soc_ops.get_exception) - return -1; - return soc_ops.get_exception(); -} - -void soc_assert_event(unsigned int evt) -{ - if (soc_ops.assert_event) - soc_ops.assert_event(evt); -} - -static u8 cmdline_mac[6]; - -static int __init get_mac_addr_from_cmdline(char *str) -{ - int count, i, val; - - for (count = 0; count < 6 && *str; count++, str += 3) { - if (!isxdigit(str[0]) || !isxdigit(str[1])) - return 0; - if (str[2] != ((count < 5) ? ':' : '\0')) - return 0; - - for (i = 0, val = 0; i < 2; i++) { - val = val << 4; - val |= isdigit(str[i]) ? - str[i] - '0' : toupper(str[i]) - 'A' + 10; - } - cmdline_mac[count] = val; - } - return 1; -} -__setup("emac_addr=", get_mac_addr_from_cmdline); - -/* - * Setup the MAC address for SoC ethernet devices. - * - * Before calling this function, the ethernet driver will have - * initialized the addr with local-mac-address from the device - * tree (if found). Allow command line to override, but not - * the fused address. - */ -int soc_mac_addr(unsigned int index, u8 *addr) -{ - int i, have_dt_mac = 0, have_cmdline_mac = 0, have_fuse_mac = 0; - - for (i = 0; i < 6; i++) { - if (cmdline_mac[i]) - have_cmdline_mac = 1; - if (c6x_fuse_mac[i]) - have_fuse_mac = 1; - if (addr[i]) - have_dt_mac = 1; - } - - /* cmdline overrides all */ - if (have_cmdline_mac) - memcpy(addr, cmdline_mac, 6); - else if (!have_dt_mac) { - if (have_fuse_mac) - memcpy(addr, c6x_fuse_mac, 6); - else - eth_random_addr(addr); - } - - /* adjust for specific EMAC device */ - addr[5] += index * c6x_num_cores; - return 1; -} -EXPORT_SYMBOL_GPL(soc_mac_addr); diff --git a/arch/c6x/kernel/switch_to.S b/arch/c6x/kernel/switch_to.S deleted file mode 100644 index b7f9f607042e..000000000000 --- a/arch/c6x/kernel/switch_to.S +++ /dev/null @@ -1,71 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ -/* - * Copyright (C) 2011 Texas Instruments Incorporated - * Author: Mark Salter (msalter@redhat.com) - */ - -#include -#include - -#define SP B15 - - /* - * void __switch_to(struct thread_info *prev, - * struct thread_info *next, - * struct task_struct *tsk) ; - */ -ENTRY(__switch_to) - LDDW .D2T2 *+B4(THREAD_B15_14),B7:B6 - || MV .L2X A4,B5 ; prev - || MV .L1X B4,A5 ; next - || MVC .S2 RILC,B1 - - STW .D2T2 B3,*+B5(THREAD_PC) - || STDW .D1T1 A13:A12,*+A4(THREAD_A13_12) - || MVC .S2 ILC,B0 - - LDW .D2T2 *+B4(THREAD_PC),B3 - || LDDW .D1T1 *+A5(THREAD_A13_12),A13:A12 - - STDW .D1T1 A11:A10,*+A4(THREAD_A11_10) - || STDW .D2T2 B1:B0,*+B5(THREAD_RICL_ICL) -#ifndef __DSBT__ - || MVKL .S2 current_ksp,B1 -#endif - - STDW .D2T2 B15:B14,*+B5(THREAD_B15_14) - || STDW .D1T1 A15:A14,*+A4(THREAD_A15_14) -#ifndef __DSBT__ - || MVKH .S2 current_ksp,B1 -#endif - - ;; Switch to next SP - MV .S2 B7,SP -#ifdef __DSBT__ - || STW .D2T2 B7,*+B14(current_ksp) -#else - || STW .D2T2 B7,*B1 - || MV .L2 B6,B14 -#endif - || LDDW .D1T1 *+A5(THREAD_RICL_ICL),A1:A0 - - STDW .D2T2 B11:B10,*+B5(THREAD_B11_10) - || LDDW .D1T1 *+A5(THREAD_A15_14),A15:A14 - - STDW .D2T2 B13:B12,*+B5(THREAD_B13_12) - || LDDW .D1T1 *+A5(THREAD_A11_10),A11:A10 - - B .S2 B3 ; return in next E1 - || LDDW .D2T2 *+B4(THREAD_B13_12),B13:B12 - - LDDW .D2T2 *+B4(THREAD_B11_10),B11:B10 - NOP - - MV .L2X A0,B0 - || MV .S1 A6,A4 - - MVC .S2 B0,ILC - || MV .L2X A1,B1 - - MVC .S2 B1,RILC -ENDPROC(__switch_to) diff --git a/arch/c6x/kernel/sys_c6x.c b/arch/c6x/kernel/sys_c6x.c deleted file mode 100644 index 600277f057cf..000000000000 --- a/arch/c6x/kernel/sys_c6x.c +++ /dev/null @@ -1,71 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Port on Texas Instruments TMS320C6x architecture - * - * Copyright (C) 2004, 2009, 2010, 2011 Texas Instruments Incorporated - * Author: Aurelien Jacquiot (aurelien.jacquiot@jaluna.com) - */ -#include -#include -#include - -#include - -#ifdef CONFIG_ACCESS_CHECK -int _access_ok(unsigned long addr, unsigned long size) -{ - if (!size) - return 1; - - if (!addr || addr > (0xffffffffUL - (size - 1))) - goto _bad_access; - - if (uaccess_kernel()) - return 1; - - if (memory_start <= addr && (addr + size - 1) < memory_end) - return 1; - -_bad_access: - pr_debug("Bad access attempt: pid[%d] addr[%08lx] size[0x%lx]\n", - current->pid, addr, size); - return 0; -} -EXPORT_SYMBOL(_access_ok); -#endif - -/* sys_cache_sync -- sync caches over given range */ -asmlinkage int sys_cache_sync(unsigned long s, unsigned long e) -{ - L1D_cache_block_writeback_invalidate(s, e); - L1P_cache_block_invalidate(s, e); - - return 0; -} - -/* Provide the actual syscall number to call mapping. */ -#undef __SYSCALL -#define __SYSCALL(nr, call) [nr] = (call), - -/* - * Use trampolines - */ -#define sys_pread64 sys_pread_c6x -#define sys_pwrite64 sys_pwrite_c6x -#define sys_truncate64 sys_truncate64_c6x -#define sys_ftruncate64 sys_ftruncate64_c6x -#define sys_fadvise64 sys_fadvise64_c6x -#define sys_fadvise64_64 sys_fadvise64_64_c6x -#define sys_fallocate sys_fallocate_c6x - -/* Use sys_mmap_pgoff directly */ -#define sys_mmap2 sys_mmap_pgoff - -/* - * Note that we can't include here since the header - * guard will defeat us; checks for __SYSCALL as well. - */ -void *sys_call_table[__NR_syscalls] = { - [0 ... __NR_syscalls-1] = sys_ni_syscall, -#include -}; diff --git a/arch/c6x/kernel/time.c b/arch/c6x/kernel/time.c deleted file mode 100644 index f3ec91a87f4f..000000000000 --- a/arch/c6x/kernel/time.c +++ /dev/null @@ -1,63 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Port on Texas Instruments TMS320C6x architecture - * - * Copyright (C) 2004, 2009, 2010, 2011 Texas Instruments Incorporated - * Author: Aurelien Jacquiot (aurelien.jacquiot@jaluna.com) - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -static u32 sched_clock_multiplier; -#define SCHED_CLOCK_SHIFT 16 - -static u64 tsc_read(struct clocksource *cs) -{ - return get_cycles(); -} - -static struct clocksource clocksource_tsc = { - .name = "timestamp", - .rating = 300, - .read = tsc_read, - .mask = CLOCKSOURCE_MASK(64), - .flags = CLOCK_SOURCE_IS_CONTINUOUS, -}; - -/* - * scheduler clock - returns current time in nanoseconds. - */ -u64 sched_clock(void) -{ - u64 tsc = get_cycles(); - - return (tsc * sched_clock_multiplier) >> SCHED_CLOCK_SHIFT; -} - -void __init time_init(void) -{ - u64 tmp = (u64)NSEC_PER_SEC << SCHED_CLOCK_SHIFT; - - do_div(tmp, c6x_core_freq); - sched_clock_multiplier = tmp; - - clocksource_register_hz(&clocksource_tsc, c6x_core_freq); - - /* write anything into TSCL to enable counting */ - set_creg(TSCL, 0); - - /* probe for timer64 event timer */ - timer64_init(); -} diff --git a/arch/c6x/kernel/traps.c b/arch/c6x/kernel/traps.c deleted file mode 100644 index 2b9121c755be..000000000000 --- a/arch/c6x/kernel/traps.c +++ /dev/null @@ -1,409 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Port on Texas Instruments TMS320C6x architecture - * - * Copyright (C) 2004, 2006, 2009, 2010, 2011 Texas Instruments Incorporated - * Author: Aurelien Jacquiot (aurelien.jacquiot@jaluna.com) - */ -#include -#include -#include -#include - -#include -#include -#include - -int (*c6x_nmi_handler)(struct pt_regs *regs); - -void __init trap_init(void) -{ - ack_exception(EXCEPT_TYPE_NXF); - ack_exception(EXCEPT_TYPE_EXC); - ack_exception(EXCEPT_TYPE_IXF); - ack_exception(EXCEPT_TYPE_SXF); - enable_exception(); -} - -void show_regs(struct pt_regs *regs) -{ - pr_err("\n"); - show_regs_print_info(KERN_ERR); - pr_err("PC: %08lx SP: %08lx\n", regs->pc, regs->sp); - pr_err("Status: %08lx ORIG_A4: %08lx\n", regs->csr, regs->orig_a4); - pr_err("A0: %08lx B0: %08lx\n", regs->a0, regs->b0); - pr_err("A1: %08lx B1: %08lx\n", regs->a1, regs->b1); - pr_err("A2: %08lx B2: %08lx\n", regs->a2, regs->b2); - pr_err("A3: %08lx B3: %08lx\n", regs->a3, regs->b3); - pr_err("A4: %08lx B4: %08lx\n", regs->a4, regs->b4); - pr_err("A5: %08lx B5: %08lx\n", regs->a5, regs->b5); - pr_err("A6: %08lx B6: %08lx\n", regs->a6, regs->b6); - pr_err("A7: %08lx B7: %08lx\n", regs->a7, regs->b7); - pr_err("A8: %08lx B8: %08lx\n", regs->a8, regs->b8); - pr_err("A9: %08lx B9: %08lx\n", regs->a9, regs->b9); - pr_err("A10: %08lx B10: %08lx\n", regs->a10, regs->b10); - pr_err("A11: %08lx B11: %08lx\n", regs->a11, regs->b11); - pr_err("A12: %08lx B12: %08lx\n", regs->a12, regs->b12); - pr_err("A13: %08lx B13: %08lx\n", regs->a13, regs->b13); - pr_err("A14: %08lx B14: %08lx\n", regs->a14, regs->dp); - pr_err("A15: %08lx B15: %08lx\n", regs->a15, regs->sp); - pr_err("A16: %08lx B16: %08lx\n", regs->a16, regs->b16); - pr_err("A17: %08lx B17: %08lx\n", regs->a17, regs->b17); - pr_err("A18: %08lx B18: %08lx\n", regs->a18, regs->b18); - pr_err("A19: %08lx B19: %08lx\n", regs->a19, regs->b19); - pr_err("A20: %08lx B20: %08lx\n", regs->a20, regs->b20); - pr_err("A21: %08lx B21: %08lx\n", regs->a21, regs->b21); - pr_err("A22: %08lx B22: %08lx\n", regs->a22, regs->b22); - pr_err("A23: %08lx B23: %08lx\n", regs->a23, regs->b23); - pr_err("A24: %08lx B24: %08lx\n", regs->a24, regs->b24); - pr_err("A25: %08lx B25: %08lx\n", regs->a25, regs->b25); - pr_err("A26: %08lx B26: %08lx\n", regs->a26, regs->b26); - pr_err("A27: %08lx B27: %08lx\n", regs->a27, regs->b27); - pr_err("A28: %08lx B28: %08lx\n", regs->a28, regs->b28); - pr_err("A29: %08lx B29: %08lx\n", regs->a29, regs->b29); - pr_err("A30: %08lx B30: %08lx\n", regs->a30, regs->b30); - pr_err("A31: %08lx B31: %08lx\n", regs->a31, regs->b31); -} - -void die(char *str, struct pt_regs *fp, int nr) -{ - console_verbose(); - pr_err("%s: %08x\n", str, nr); - show_regs(fp); - - pr_err("Process %s (pid: %d, stackpage=%08lx)\n", - current->comm, current->pid, (PAGE_SIZE + - (unsigned long) current)); - - dump_stack(); - while (1) - ; -} - -static void die_if_kernel(char *str, struct pt_regs *fp, int nr) -{ - if (user_mode(fp)) - return; - - die(str, fp, nr); -} - - -/* Internal exceptions */ -static struct exception_info iexcept_table[10] = { - { "Oops - instruction fetch", SIGBUS, BUS_ADRERR }, - { "Oops - fetch packet", SIGBUS, BUS_ADRERR }, - { "Oops - execute packet", SIGILL, ILL_ILLOPC }, - { "Oops - undefined instruction", SIGILL, ILL_ILLOPC }, - { "Oops - resource conflict", SIGILL, ILL_ILLOPC }, - { "Oops - resource access", SIGILL, ILL_PRVREG }, - { "Oops - privilege", SIGILL, ILL_PRVOPC }, - { "Oops - loops buffer", SIGILL, ILL_ILLOPC }, - { "Oops - software exception", SIGILL, ILL_ILLTRP }, - { "Oops - unknown exception", SIGILL, ILL_ILLOPC } -}; - -/* External exceptions */ -static struct exception_info eexcept_table[128] = { - { "Oops - external exception", SIGBUS, BUS_ADRERR }, - { "Oops - external exception", SIGBUS, BUS_ADRERR }, - { "Oops - external exception", SIGBUS, BUS_ADRERR }, - { "Oops - external exception", SIGBUS, BUS_ADRERR }, - { "Oops - external exception", SIGBUS, BUS_ADRERR }, - { "Oops - external exception", SIGBUS, BUS_ADRERR }, - { "Oops - external exception", SIGBUS, BUS_ADRERR }, - { "Oops - external exception", SIGBUS, BUS_ADRERR }, - { "Oops - external exception", SIGBUS, BUS_ADRERR }, - { "Oops - external exception", SIGBUS, BUS_ADRERR }, - { "Oops - external exception", SIGBUS, BUS_ADRERR }, - { "Oops - external exception", SIGBUS, BUS_ADRERR }, - { "Oops - external exception", SIGBUS, BUS_ADRERR }, - { "Oops - external exception", SIGBUS, BUS_ADRERR }, - { "Oops - external exception", SIGBUS, BUS_ADRERR }, - { "Oops - external exception", SIGBUS, BUS_ADRERR }, - { "Oops - external exception", SIGBUS, BUS_ADRERR }, - { "Oops - external exception", SIGBUS, BUS_ADRERR }, - { "Oops - external exception", SIGBUS, BUS_ADRERR }, - { "Oops - external exception", SIGBUS, BUS_ADRERR }, - { "Oops - external exception", SIGBUS, BUS_ADRERR }, - { "Oops - external exception", SIGBUS, BUS_ADRERR }, - { "Oops - external exception", SIGBUS, BUS_ADRERR }, - { "Oops - external exception", SIGBUS, BUS_ADRERR }, - { "Oops - external exception", SIGBUS, BUS_ADRERR }, - { "Oops - external exception", SIGBUS, BUS_ADRERR }, - { "Oops - external exception", SIGBUS, BUS_ADRERR }, - { "Oops - external exception", SIGBUS, BUS_ADRERR }, - { "Oops - external exception", SIGBUS, BUS_ADRERR }, - { "Oops - external exception", SIGBUS, BUS_ADRERR }, - { "Oops - external exception", SIGBUS, BUS_ADRERR }, - { "Oops - external exception", SIGBUS, BUS_ADRERR }, - - { "Oops - external exception", SIGBUS, BUS_ADRERR }, - { "Oops - external exception", SIGBUS, BUS_ADRERR }, - { "Oops - external exception", SIGBUS, BUS_ADRERR }, - { "Oops - external exception", SIGBUS, BUS_ADRERR }, - { "Oops - external exception", SIGBUS, BUS_ADRERR }, - { "Oops - external exception", SIGBUS, BUS_ADRERR }, - { "Oops - external exception", SIGBUS, BUS_ADRERR }, - { "Oops - external exception", SIGBUS, BUS_ADRERR }, - { "Oops - external exception", SIGBUS, BUS_ADRERR }, - { "Oops - external exception", SIGBUS, BUS_ADRERR }, - { "Oops - external exception", SIGBUS, BUS_ADRERR }, - { "Oops - external exception", SIGBUS, BUS_ADRERR }, - { "Oops - external exception", SIGBUS, BUS_ADRERR }, - { "Oops - external exception", SIGBUS, BUS_ADRERR }, - { "Oops - external exception", SIGBUS, BUS_ADRERR }, - { "Oops - external exception", SIGBUS, BUS_ADRERR }, - { "Oops - external exception", SIGBUS, BUS_ADRERR }, - { "Oops - external exception", SIGBUS, BUS_ADRERR }, - { "Oops - external exception", SIGBUS, BUS_ADRERR }, - { "Oops - external exception", SIGBUS, BUS_ADRERR }, - { "Oops - external exception", SIGBUS, BUS_ADRERR }, - { "Oops - external exception", SIGBUS, BUS_ADRERR }, - { "Oops - external exception", SIGBUS, BUS_ADRERR }, - { "Oops - external exception", SIGBUS, BUS_ADRERR }, - { "Oops - external exception", SIGBUS, BUS_ADRERR }, - { "Oops - external exception", SIGBUS, BUS_ADRERR }, - { "Oops - external exception", SIGBUS, BUS_ADRERR }, - { "Oops - external exception", SIGBUS, BUS_ADRERR }, - { "Oops - external exception", SIGBUS, BUS_ADRERR }, - { "Oops - external exception", SIGBUS, BUS_ADRERR }, - { "Oops - external exception", SIGBUS, BUS_ADRERR }, - { "Oops - external exception", SIGBUS, BUS_ADRERR }, - - { "Oops - external exception", SIGBUS, BUS_ADRERR }, - { "Oops - external exception", SIGBUS, BUS_ADRERR }, - { "Oops - external exception", SIGBUS, BUS_ADRERR }, - { "Oops - external exception", SIGBUS, BUS_ADRERR }, - { "Oops - external exception", SIGBUS, BUS_ADRERR }, - { "Oops - external exception", SIGBUS, BUS_ADRERR }, - { "Oops - external exception", SIGBUS, BUS_ADRERR }, - { "Oops - external exception", SIGBUS, BUS_ADRERR }, - { "Oops - external exception", SIGBUS, BUS_ADRERR }, - { "Oops - external exception", SIGBUS, BUS_ADRERR }, - { "Oops - external exception", SIGBUS, BUS_ADRERR }, - { "Oops - external exception", SIGBUS, BUS_ADRERR }, - { "Oops - external exception", SIGBUS, BUS_ADRERR }, - { "Oops - external exception", SIGBUS, BUS_ADRERR }, - { "Oops - external exception", SIGBUS, BUS_ADRERR }, - { "Oops - external exception", SIGBUS, BUS_ADRERR }, - { "Oops - external exception", SIGBUS, BUS_ADRERR }, - { "Oops - external exception", SIGBUS, BUS_ADRERR }, - { "Oops - external exception", SIGBUS, BUS_ADRERR }, - { "Oops - external exception", SIGBUS, BUS_ADRERR }, - { "Oops - external exception", SIGBUS, BUS_ADRERR }, - { "Oops - external exception", SIGBUS, BUS_ADRERR }, - { "Oops - external exception", SIGBUS, BUS_ADRERR }, - { "Oops - external exception", SIGBUS, BUS_ADRERR }, - { "Oops - external exception", SIGBUS, BUS_ADRERR }, - { "Oops - external exception", SIGBUS, BUS_ADRERR }, - { "Oops - external exception", SIGBUS, BUS_ADRERR }, - { "Oops - external exception", SIGBUS, BUS_ADRERR }, - { "Oops - external exception", SIGBUS, BUS_ADRERR }, - { "Oops - external exception", SIGBUS, BUS_ADRERR }, - { "Oops - external exception", SIGBUS, BUS_ADRERR }, - { "Oops - external exception", SIGBUS, BUS_ADRERR }, - - { "Oops - external exception", SIGBUS, BUS_ADRERR }, - { "Oops - external exception", SIGBUS, BUS_ADRERR }, - { "Oops - external exception", SIGBUS, BUS_ADRERR }, - { "Oops - external exception", SIGBUS, BUS_ADRERR }, - { "Oops - external exception", SIGBUS, BUS_ADRERR }, - { "Oops - external exception", SIGBUS, BUS_ADRERR }, - { "Oops - external exception", SIGBUS, BUS_ADRERR }, - { "Oops - external exception", SIGBUS, BUS_ADRERR }, - { "Oops - external exception", SIGBUS, BUS_ADRERR }, - { "Oops - external exception", SIGBUS, BUS_ADRERR }, - { "Oops - external exception", SIGBUS, BUS_ADRERR }, - { "Oops - external exception", SIGBUS, BUS_ADRERR }, - { "Oops - external exception", SIGBUS, BUS_ADRERR }, - { "Oops - external exception", SIGBUS, BUS_ADRERR }, - { "Oops - external exception", SIGBUS, BUS_ADRERR }, - { "Oops - external exception", SIGBUS, BUS_ADRERR }, - { "Oops - external exception", SIGBUS, BUS_ADRERR }, - { "Oops - external exception", SIGBUS, BUS_ADRERR }, - { "Oops - external exception", SIGBUS, BUS_ADRERR }, - { "Oops - external exception", SIGBUS, BUS_ADRERR }, - { "Oops - external exception", SIGBUS, BUS_ADRERR }, - { "Oops - external exception", SIGBUS, BUS_ADRERR }, - { "Oops - external exception", SIGBUS, BUS_ADRERR }, - { "Oops - CPU memory protection fault", SIGSEGV, SEGV_ACCERR }, - { "Oops - CPU memory protection fault in L1P", SIGSEGV, SEGV_ACCERR }, - { "Oops - DMA memory protection fault in L1P", SIGSEGV, SEGV_ACCERR }, - { "Oops - CPU memory protection fault in L1D", SIGSEGV, SEGV_ACCERR }, - { "Oops - DMA memory protection fault in L1D", SIGSEGV, SEGV_ACCERR }, - { "Oops - CPU memory protection fault in L2", SIGSEGV, SEGV_ACCERR }, - { "Oops - DMA memory protection fault in L2", SIGSEGV, SEGV_ACCERR }, - { "Oops - EMC CPU memory protection fault", SIGSEGV, SEGV_ACCERR }, - { "Oops - EMC bus error", SIGBUS, BUS_ADRERR } -}; - -static void do_trap(struct exception_info *except_info, struct pt_regs *regs) -{ - unsigned long addr = instruction_pointer(regs); - - if (except_info->code != TRAP_BRKPT) - pr_err("TRAP: %s PC[0x%lx] signo[%d] code[%d]\n", - except_info->kernel_str, regs->pc, - except_info->signo, except_info->code); - - die_if_kernel(except_info->kernel_str, regs, addr); - - force_sig_fault(except_info->signo, except_info->code, - (void __user *)addr); -} - -/* - * Process an internal exception (non maskable) - */ -static int process_iexcept(struct pt_regs *regs) -{ - unsigned int iexcept_report = get_iexcept(); - unsigned int iexcept_num; - - ack_exception(EXCEPT_TYPE_IXF); - - pr_err("IEXCEPT: PC[0x%lx]\n", regs->pc); - - while (iexcept_report) { - iexcept_num = __ffs(iexcept_report); - iexcept_report &= ~(1 << iexcept_num); - set_iexcept(iexcept_report); - if (*(unsigned int *)regs->pc == BKPT_OPCODE) { - /* This is a breakpoint */ - struct exception_info bkpt_exception = { - "Oops - undefined instruction", - SIGTRAP, TRAP_BRKPT - }; - do_trap(&bkpt_exception, regs); - iexcept_report &= ~(0xFF); - set_iexcept(iexcept_report); - continue; - } - - do_trap(&iexcept_table[iexcept_num], regs); - } - return 0; -} - -/* - * Process an external exception (maskable) - */ -static void process_eexcept(struct pt_regs *regs) -{ - int evt; - - pr_err("EEXCEPT: PC[0x%lx]\n", regs->pc); - - while ((evt = soc_get_exception()) >= 0) - do_trap(&eexcept_table[evt], regs); - - ack_exception(EXCEPT_TYPE_EXC); -} - -/* - * Main exception processing - */ -asmlinkage int process_exception(struct pt_regs *regs) -{ - unsigned int type; - unsigned int type_num; - unsigned int ie_num = 9; /* default is unknown exception */ - - while ((type = get_except_type()) != 0) { - type_num = fls(type) - 1; - - switch (type_num) { - case EXCEPT_TYPE_NXF: - ack_exception(EXCEPT_TYPE_NXF); - if (c6x_nmi_handler) - (c6x_nmi_handler)(regs); - else - pr_alert("NMI interrupt!\n"); - break; - - case EXCEPT_TYPE_IXF: - if (process_iexcept(regs)) - return 1; - break; - - case EXCEPT_TYPE_EXC: - process_eexcept(regs); - break; - - case EXCEPT_TYPE_SXF: - ie_num = 8; - default: - ack_exception(type_num); - do_trap(&iexcept_table[ie_num], regs); - break; - } - } - return 0; -} - -static int kstack_depth_to_print = 48; - -static void show_trace(unsigned long *stack, unsigned long *endstack, - const char *loglvl) -{ - unsigned long addr; - int i; - - printk("%sCall trace:", loglvl); - i = 0; - while (stack + 1 <= endstack) { - addr = *stack++; - /* - * If the address is either in the text segment of the - * kernel, or in the region which contains vmalloc'ed - * memory, it *may* be the address of a calling - * routine; if so, print it so that someone tracing - * down the cause of the crash will be able to figure - * out the call path that was taken. - */ - if (__kernel_text_address(addr)) { -#ifndef CONFIG_KALLSYMS - if (i % 5 == 0) - printk("%s\n ", loglvl); -#endif - printk("%s [<%08lx>] %pS\n", loglvl, addr, (void *)addr); - i++; - } - } - printk("%s\n", loglvl); -} - -void show_stack(struct task_struct *task, unsigned long *stack, - const char *loglvl) -{ - unsigned long *p, *endstack; - int i; - - if (!stack) { - if (task && task != current) - /* We know this is a kernel stack, - so this is the start/end */ - stack = (unsigned long *)thread_saved_ksp(task); - else - stack = (unsigned long *)&stack; - } - endstack = (unsigned long *)(((unsigned long)stack + THREAD_SIZE - 1) - & -THREAD_SIZE); - - pr_debug("Stack from %08lx:", (unsigned long)stack); - for (i = 0, p = stack; i < kstack_depth_to_print; i++) { - if (p + 1 > endstack) - break; - if (i % 8 == 0) - pr_cont("\n "); - pr_cont(" %08lx", *p++); - } - pr_cont("\n"); - show_trace(stack, endstack, loglvl); -} - -int is_valid_bugaddr(unsigned long addr) -{ - return __kernel_text_address(addr); -} diff --git a/arch/c6x/kernel/vectors.S b/arch/c6x/kernel/vectors.S deleted file mode 100644 index ad3dc006a6d3..000000000000 --- a/arch/c6x/kernel/vectors.S +++ /dev/null @@ -1,78 +0,0 @@ -; SPDX-License-Identifier: GPL-2.0-only -; -; Port on Texas Instruments TMS320C6x architecture -; -; Copyright (C) 2004, 2006, 2009, 2010, 2011 Texas Instruments Incorporated -; Author: Aurelien Jacquiot (aurelien.jacquiot@jaluna.com) -; -; This section handles all the interrupt vector routines. -; At RESET the processor sets up the DRAM timing parameters and -; branches to the label _c_int00 which handles initialization for the C code. -; - -#define ALIGNMENT 5 - - .macro IRQVEC name, handler - .align ALIGNMENT - .hidden \name - .global \name -\name: -#ifdef CONFIG_C6X_BIG_KERNEL - STW .D2T1 A0,*B15--[2] - || MVKL .S1 \handler,A0 - MVKH .S1 \handler,A0 - B .S2X A0 - LDW .D2T1 *++B15[2],A0 - NOP 4 - NOP - NOP - .endm -#else /* CONFIG_C6X_BIG_KERNEL */ - B .S2 \handler - NOP - NOP - NOP - NOP - NOP - NOP - NOP - .endm -#endif /* CONFIG_C6X_BIG_KERNEL */ - - .sect ".vectors","ax" - .align ALIGNMENT - .global RESET - .hidden RESET -RESET: -#ifdef CONFIG_C6X_BIG_KERNEL - MVKL .S1 _c_int00,A0 ; branch to _c_int00 - MVKH .S1 _c_int00,A0 - B .S2X A0 -#else - B .S2 _c_int00 - NOP - NOP -#endif - NOP - NOP - NOP - NOP - NOP - - - IRQVEC NMI,_nmi_handler ; NMI interrupt - IRQVEC AINT,_bad_interrupt ; reserved - IRQVEC MSGINT,_bad_interrupt ; reserved - - IRQVEC INT4,_int4_handler - IRQVEC INT5,_int5_handler - IRQVEC INT6,_int6_handler - IRQVEC INT7,_int7_handler - IRQVEC INT8,_int8_handler - IRQVEC INT9,_int9_handler - IRQVEC INT10,_int10_handler - IRQVEC INT11,_int11_handler - IRQVEC INT12,_int12_handler - IRQVEC INT13,_int13_handler - IRQVEC INT14,_int14_handler - IRQVEC INT15,_int15_handler diff --git a/arch/c6x/kernel/vmlinux.lds.S b/arch/c6x/kernel/vmlinux.lds.S deleted file mode 100644 index ac99ba0864bf..000000000000 --- a/arch/c6x/kernel/vmlinux.lds.S +++ /dev/null @@ -1,151 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/* - * ld script for the c6x kernel - * - * Copyright (C) 2010, 2011 Texas Instruments Incorporated - * Mark Salter - */ - -#define RO_EXCEPTION_TABLE_ALIGN 16 - -#include -#include -#include - -ENTRY(_c_int00) - -#if defined(CONFIG_CPU_BIG_ENDIAN) -jiffies = jiffies_64 + 4; -#else -jiffies = jiffies_64; -#endif - -#define READONLY_SEGMENT_START \ - . = PAGE_OFFSET; -#define READWRITE_SEGMENT_START \ - . = ALIGN(128); \ - _data_lma = .; - -SECTIONS -{ - /* - * Start kernel read only segment - */ - READONLY_SEGMENT_START - - .vectors : - { - _vectors_start = .; - *(.vectors) - . = ALIGN(0x400); - _vectors_end = .; - } - - /* - * This section contains data which may be shared with other - * cores. It needs to be a fixed offset from PAGE_OFFSET - * regardless of kernel configuration. - */ - .virtio_ipc_dev : - { - *(.virtio_ipc_dev) - } - - . = ALIGN(PAGE_SIZE); - __init_begin = .; - .init : - { - _sinittext = .; - HEAD_TEXT - INIT_TEXT - _einittext = .; - } - - INIT_DATA_SECTION(16) - - PERCPU_SECTION(128) - - . = ALIGN(PAGE_SIZE); - __init_end = .; - - .text : - { - _text = .; - _stext = .; - TEXT_TEXT - SCHED_TEXT - CPUIDLE_TEXT - LOCK_TEXT - IRQENTRY_TEXT - SOFTIRQENTRY_TEXT - KPROBES_TEXT - *(.fixup) - *(.gnu.warning) - } - - RO_DATA(PAGE_SIZE) - .const : - { - *(.const .const.* .gnu.linkonce.r.*) - *(.switch) - } - - _etext = .; - - /* - * Start kernel read-write segment. - */ - READWRITE_SEGMENT_START - _sdata = .; - - .fardata : AT(ADDR(.fardata) - LOAD_OFFSET) - { - INIT_TASK_DATA(THREAD_SIZE) - NOSAVE_DATA - PAGE_ALIGNED_DATA(PAGE_SIZE) - CACHELINE_ALIGNED_DATA(128) - READ_MOSTLY_DATA(128) - DATA_DATA - CONSTRUCTORS - *(.data1) - *(.fardata .fardata.*) - *(.data.debug_bpt) - } - - .neardata ALIGN(8) : AT(ADDR(.neardata) - LOAD_OFFSET) - { - *(.neardata2 .neardata2.* .gnu.linkonce.s2.*) - *(.neardata .neardata.* .gnu.linkonce.s.*) - . = ALIGN(8); - } - - BUG_TABLE - - _edata = .; - - __bss_start = .; - SBSS(8) - BSS(8) - .far : - { - . = ALIGN(8); - *(.dynfar) - *(.far .far.* .gnu.linkonce.b.*) - . = ALIGN(8); - } - __bss_stop = .; - - _end = .; - - DWARF_DEBUG - - /DISCARD/ : - { - EXIT_TEXT - EXIT_DATA - EXIT_CALL - *(.discard) - *(.discard.*) - *(.interp) - } -} diff --git a/arch/c6x/lib/Makefile b/arch/c6x/lib/Makefile deleted file mode 100644 index e182004f82fe..000000000000 --- a/arch/c6x/lib/Makefile +++ /dev/null @@ -1,8 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0-only -# -# Makefile for arch/c6x/lib/ -# - -lib-y := divu.o divi.o pop_rts.o push_rts.o remi.o remu.o strasgi.o llshru.o -lib-y += llshr.o llshl.o negll.o mpyll.o divremi.o divremu.o -lib-y += checksum.o csum_64plus.o memcpy_64plus.o strasgi_64plus.o diff --git a/arch/c6x/lib/checksum.c b/arch/c6x/lib/checksum.c deleted file mode 100644 index dff2e2ec6e64..000000000000 --- a/arch/c6x/lib/checksum.c +++ /dev/null @@ -1,11 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - */ -#include -#include - -/* These are from csum_64plus.S */ -EXPORT_SYMBOL(csum_partial); -EXPORT_SYMBOL(csum_partial_copy_nocheck); -EXPORT_SYMBOL(ip_compute_csum); -EXPORT_SYMBOL(ip_fast_csum); diff --git a/arch/c6x/lib/csum_64plus.S b/arch/c6x/lib/csum_64plus.S deleted file mode 100644 index 57148866d8d3..000000000000 --- a/arch/c6x/lib/csum_64plus.S +++ /dev/null @@ -1,414 +0,0 @@ -; SPDX-License-Identifier: GPL-2.0-only -; -; linux/arch/c6x/lib/csum_64plus.s -; -; Port on Texas Instruments TMS320C6x architecture -; -; Copyright (C) 2006, 2009, 2010, 2011 Texas Instruments Incorporated -; Author: Aurelien Jacquiot (aurelien.jacquiot@jaluna.com) -; -#include - -; -;unsigned int csum_partial_copy_nocheck(const char *src, char * dst, -; int len, int sum) -; -; A4: src -; B4: dst -; A6: len -; B6: sum -; return csum in A4 -; - - .text -ENTRY(csum_partial_copy_nocheck) - MVC .S2 ILC,B30 - - ZERO .D1 A9 ; csum (a side) -|| ZERO .D2 B9 ; csum (b side) -|| SHRU .S2X A6,2,B5 ; len / 4 - - ;; Check alignment and size - AND .S1 3,A4,A1 -|| AND .S2 3,B4,B0 - OR .L2X B0,A1,B0 ; non aligned condition -|| MVC .S2 B5,ILC -|| MVK .D2 1,B2 -|| MV .D1X B5,A1 ; words condition - [!A1] B .S1 L8 - [B0] BNOP .S1 L6,5 - - SPLOOP 1 - - ;; Main loop for aligned words - LDW .D1T1 *A4++,A7 - NOP 4 - MV .S2X A7,B7 -|| EXTU .S1 A7,0,16,A16 - STW .D2T2 B7,*B4++ -|| MPYU .M2 B7,B2,B8 -|| ADD .L1 A16,A9,A9 - NOP - SPKERNEL 8,0 -|| ADD .L2 B8,B9,B9 - - ZERO .D1 A1 -|| ADD .L1X A9,B9,A9 ; add csum from a and b sides - -L6: - [!A1] BNOP .S1 L8,5 - - ;; Main loop for non-aligned words - SPLOOP 2 - || MVK .L1 1,A2 - - LDNW .D1T1 *A4++,A7 - NOP 3 - - NOP - MV .S2X A7,B7 - || EXTU .S1 A7,0,16,A16 - || MPYU .M1 A7,A2,A8 - - ADD .L1 A16,A9,A9 - SPKERNEL 6,0 - || STNW .D2T2 B7,*B4++ - || ADD .L1 A8,A9,A9 - -L8: AND .S2X 2,A6,B5 - CMPGT .L2 B5,0,B0 - [!B0] BNOP .S1 L82,4 - - ;; Manage half-word - ZERO .L1 A7 -|| ZERO .D1 A8 - -#ifdef CONFIG_CPU_BIG_ENDIAN - - LDBU .D1T1 *A4++,A7 - LDBU .D1T1 *A4++,A8 - NOP 3 - SHL .S1 A7,8,A0 - ADD .S1 A8,A9,A9 - STB .D2T1 A7,*B4++ -|| ADD .S1 A0,A9,A9 - STB .D2T1 A8,*B4++ - -#else - - LDBU .D1T1 *A4++,A7 - LDBU .D1T1 *A4++,A8 - NOP 3 - ADD .S1 A7,A9,A9 - SHL .S1 A8,8,A0 - - STB .D2T1 A7,*B4++ -|| ADD .S1 A0,A9,A9 - STB .D2T1 A8,*B4++ - -#endif - - ;; Manage eventually the last byte -L82: AND .S2X 1,A6,B0 - [!B0] BNOP .S1 L9,5 - -|| ZERO .L1 A7 - -L83: LDBU .D1T1 *A4++,A7 - NOP 4 - - MV .L2X A7,B7 - -#ifdef CONFIG_CPU_BIG_ENDIAN - - STB .D2T2 B7,*B4++ -|| SHL .S1 A7,8,A7 - ADD .S1 A7,A9,A9 - -#else - - STB .D2T2 B7,*B4++ -|| ADD .S1 A7,A9,A9 - -#endif - - ;; Fold the csum -L9: SHRU .S2X A9,16,B0 - [!B0] BNOP .S1 L10,5 - -L91: SHRU .S2X A9,16,B4 -|| EXTU .S1 A9,16,16,A3 - ADD .D1X A3,B4,A9 - - SHRU .S1 A9,16,A0 - [A0] BNOP .S1 L91,5 - -L10: MV .D1 A9,A4 - - BNOP .S2 B3,4 - MVC .S2 B30,ILC -ENDPROC(csum_partial_copy_nocheck) - -; -;unsigned short -;ip_fast_csum(unsigned char *iph, unsigned int ihl) -;{ -; unsigned int checksum = 0; -; unsigned short *tosum = (unsigned short *) iph; -; int len; -; -; len = ihl*4; -; -; if (len <= 0) -; return 0; -; -; while(len) { -; len -= 2; -; checksum += *tosum++; -; } -; if (len & 1) -; checksum += *(unsigned char*) tosum; -; -; while(checksum >> 16) -; checksum = (checksum & 0xffff) + (checksum >> 16); -; -; return ~checksum; -;} -; -; A4: iph -; B4: ihl -; return checksum in A4 -; - .text - -ENTRY(ip_fast_csum) - ZERO .D1 A5 - || MVC .S2 ILC,B30 - SHL .S2 B4,2,B0 - CMPGT .L2 B0,0,B1 - [!B1] BNOP .S1 L15,4 - [!B1] ZERO .D1 A3 - - [!B0] B .S1 L12 - SHRU .S2 B0,1,B0 - MVC .S2 B0,ILC - NOP 3 - - SPLOOP 1 - LDHU .D1T1 *A4++,A3 - NOP 3 - NOP - SPKERNEL 5,0 - || ADD .L1 A3,A5,A5 - -L12: SHRU .S1 A5,16,A0 - [!A0] BNOP .S1 L14,5 - -L13: SHRU .S2X A5,16,B4 - EXTU .S1 A5,16,16,A3 - ADD .D1X A3,B4,A5 - SHRU .S1 A5,16,A0 - [A0] BNOP .S1 L13,5 - -L14: NOT .D1 A5,A3 - EXTU .S1 A3,16,16,A3 - -L15: BNOP .S2 B3,3 - MVC .S2 B30,ILC - MV .D1 A3,A4 -ENDPROC(ip_fast_csum) - -; -;unsigned short -;do_csum(unsigned char *buff, unsigned int len) -;{ -; int odd, count; -; unsigned int result = 0; -; -; if (len <= 0) -; goto out; -; odd = 1 & (unsigned long) buff; -; if (odd) { -;#ifdef __LITTLE_ENDIAN -; result += (*buff << 8); -;#else -; result = *buff; -;#endif -; len--; -; buff++; -; } -; count = len >> 1; /* nr of 16-bit words.. */ -; if (count) { -; if (2 & (unsigned long) buff) { -; result += *(unsigned short *) buff; -; count--; -; len -= 2; -; buff += 2; -; } -; count >>= 1; /* nr of 32-bit words.. */ -; if (count) { -; unsigned int carry = 0; -; do { -; unsigned int w = *(unsigned int *) buff; -; count--; -; buff += 4; -; result += carry; -; result += w; -; carry = (w > result); -; } while (count); -; result += carry; -; result = (result & 0xffff) + (result >> 16); -; } -; if (len & 2) { -; result += *(unsigned short *) buff; -; buff += 2; -; } -; } -; if (len & 1) -;#ifdef __LITTLE_ENDIAN -; result += *buff; -;#else -; result += (*buff << 8); -;#endif -; result = (result & 0xffff) + (result >> 16); -; /* add up carry.. */ -; result = (result & 0xffff) + (result >> 16); -; if (odd) -; result = ((result >> 8) & 0xff) | ((result & 0xff) << 8); -;out: -; return result; -;} -; -; A4: buff -; B4: len -; return checksum in A4 -; - -ENTRY(do_csum) - CMPGT .L2 B4,0,B0 - [!B0] BNOP .S1 L26,3 - EXTU .S1 A4,31,31,A0 - - MV .L1 A0,A3 -|| MV .S1X B3,A5 -|| MV .L2 B4,B3 -|| ZERO .D1 A1 - -#ifdef CONFIG_CPU_BIG_ENDIAN - [A0] SUB .L2 B3,1,B3 -|| [A0] LDBU .D1T1 *A4++,A1 -#else - [!A0] BNOP .S1 L21,5 -|| [A0] LDBU .D1T1 *A4++,A0 - SUB .L2 B3,1,B3 -|| SHL .S1 A0,8,A1 -L21: -#endif - SHR .S2 B3,1,B0 - [!B0] BNOP .S1 L24,3 - MVK .L1 2,A0 - AND .L1 A4,A0,A0 - - [!A0] BNOP .S1 L22,5 -|| [A0] LDHU .D1T1 *A4++,A0 - SUB .L2 B0,1,B0 -|| SUB .S2 B3,2,B3 -|| ADD .L1 A0,A1,A1 -L22: - SHR .S2 B0,1,B0 -|| ZERO .L1 A0 - - [!B0] BNOP .S1 L23,5 -|| [B0] MVC .S2 B0,ILC - - SPLOOP 3 - SPMASK L1 -|| MV .L1 A1,A2 -|| LDW .D1T1 *A4++,A1 - - NOP 4 - ADD .L1 A0,A1,A0 - ADD .L1 A2,A0,A2 - - SPKERNEL 1,2 -|| CMPGTU .L1 A1,A2,A0 - - ADD .L1 A0,A2,A6 - EXTU .S1 A6,16,16,A7 - SHRU .S2X A6,16,B0 - NOP 1 - ADD .L1X A7,B0,A1 -L23: - MVK .L2 2,B0 - AND .L2 B3,B0,B0 - [B0] LDHU .D1T1 *A4++,A0 - NOP 4 - [B0] ADD .L1 A0,A1,A1 -L24: - EXTU .S2 B3,31,31,B0 -#ifdef CONFIG_CPU_BIG_ENDIAN - [!B0] BNOP .S1 L25,4 -|| [B0] LDBU .D1T1 *A4,A0 - SHL .S1 A0,8,A0 - ADD .L1 A0,A1,A1 -L25: -#else - [B0] LDBU .D1T1 *A4,A0 - NOP 4 - [B0] ADD .L1 A0,A1,A1 -#endif - EXTU .S1 A1,16,16,A0 - SHRU .S2X A1,16,B0 - NOP 1 - ADD .L1X A0,B0,A0 - SHRU .S1 A0,16,A1 - ADD .L1 A0,A1,A0 - EXTU .S1 A0,16,16,A1 - EXTU .S1 A1,16,24,A2 - - EXTU .S1 A1,24,16,A0 -|| MV .L2X A3,B0 - - [B0] OR .L1 A0,A2,A1 -L26: - NOP 1 - BNOP .S2X A5,4 - MV .L1 A1,A4 -ENDPROC(do_csum) - -;__wsum csum_partial(const void *buff, int len, __wsum wsum) -;{ -; unsigned int sum = (__force unsigned int)wsum; -; unsigned int result = do_csum(buff, len); -; -; /* add in old sum, and carry.. */ -; result += sum; -; if (sum > result) -; result += 1; -; return (__force __wsum)result; -;} -; -ENTRY(csum_partial) - MV .L1X B3,A9 -|| CALLP .S2 do_csum,B3 -|| MV .S1 A6,A8 - BNOP .S2X A9,2 - ADD .L1 A8,A4,A1 - CMPGTU .L1 A8,A1,A0 - ADD .L1 A1,A0,A4 -ENDPROC(csum_partial) - -;unsigned short -;ip_compute_csum(unsigned char *buff, unsigned int len) -; -; A4: buff -; B4: len -; return checksum in A4 - -ENTRY(ip_compute_csum) - MV .L1X B3,A9 -|| CALLP .S2 do_csum,B3 - BNOP .S2X A9,3 - NOT .S1 A4,A4 - CLR .S1 A4,16,31,A4 -ENDPROC(ip_compute_csum) diff --git a/arch/c6x/lib/divi.S b/arch/c6x/lib/divi.S deleted file mode 100644 index d1764ae0b519..000000000000 --- a/arch/c6x/lib/divi.S +++ /dev/null @@ -1,41 +0,0 @@ -;; SPDX-License-Identifier: GPL-2.0-or-later -;; Copyright 2010 Free Software Foundation, Inc. -;; Contributed by Bernd Schmidt . -;; - -#include - - ;; ABI considerations for the divide functions - ;; The following registers are call-used: - ;; __c6xabi_divi A0,A1,A2,A4,A6,B0,B1,B2,B4,B5 - ;; __c6xabi_divu A0,A1,A2,A4,A6,B0,B1,B2,B4 - ;; __c6xabi_remi A1,A2,A4,A5,A6,B0,B1,B2,B4 - ;; __c6xabi_remu A1,A4,A5,A7,B0,B1,B2,B4 - ;; - ;; In our implementation, divu and remu are leaf functions, - ;; while both divi and remi call into divu. - ;; A0 is not clobbered by any of the functions. - ;; divu does not clobber B2 either, which is taken advantage of - ;; in remi. - ;; divi uses B5 to hold the original return address during - ;; the call to divu. - ;; remi uses B2 and A5 to hold the input values during the - ;; call to divu. It stores B3 in on the stack. - - .text -ENTRY(__c6xabi_divi) - call .s2 __c6xabi_divu -|| mv .d2 B3, B5 -|| cmpgt .l1 0, A4, A1 -|| cmpgt .l2 0, B4, B1 - - [A1] neg .l1 A4, A4 -|| [B1] neg .l2 B4, B4 -|| xor .s1x A1, B1, A1 - [A1] addkpc .s2 _divu_ret, B3, 4 -_divu_ret: - neg .l1 A4, A4 -|| mv .l2 B3,B5 -|| ret .s2 B5 - nop 5 -ENDPROC(__c6xabi_divi) diff --git a/arch/c6x/lib/divremi.S b/arch/c6x/lib/divremi.S deleted file mode 100644 index 575fc57a8a76..000000000000 --- a/arch/c6x/lib/divremi.S +++ /dev/null @@ -1,34 +0,0 @@ -;; SPDX-License-Identifier: GPL-2.0-or-later -;; Copyright 2010 Free Software Foundation, Inc. -;; Contributed by Bernd Schmidt . -;; - -#include - - .text -ENTRY(__c6xabi_divremi) - stw .d2t2 B3, *B15--[2] -|| cmpgt .l1 0, A4, A1 -|| cmpgt .l2 0, B4, B2 -|| mv .s1 A4, A5 -|| call .s2 __c6xabi_divu - - [A1] neg .l1 A4, A4 -|| [B2] neg .l2 B4, B4 -|| xor .s2x B2, A1, B0 -|| mv .d2 B4, B2 - - [B0] addkpc .s2 _divu_ret_1, B3, 1 - [!B0] addkpc .s2 _divu_ret_2, B3, 1 - nop 2 -_divu_ret_1: - neg .l1 A4, A4 -_divu_ret_2: - ldw .d2t2 *++B15[2], B3 - - mpy32 .m1x A4, B2, A6 - nop 3 - ret .s2 B3 - sub .l1 A5, A6, A5 - nop 4 -ENDPROC(__c6xabi_divremi) diff --git a/arch/c6x/lib/divremu.S b/arch/c6x/lib/divremu.S deleted file mode 100644 index 5f6a6a2997ae..000000000000 --- a/arch/c6x/lib/divremu.S +++ /dev/null @@ -1,75 +0,0 @@ -;; SPDX-License-Identifier: GPL-2.0-or-later -;; Copyright 2011 Free Software Foundation, Inc. -;; Contributed by Bernd Schmidt . -;; - -#include - - .text -ENTRY(__c6xabi_divremu) - ;; We use a series of up to 31 subc instructions. First, we find - ;; out how many leading zero bits there are in the divisor. This - ;; gives us both a shift count for aligning (shifting) the divisor - ;; to the, and the number of times we have to execute subc. - - ;; At the end, we have both the remainder and most of the quotient - ;; in A4. The top bit of the quotient is computed first and is - ;; placed in A2. - - ;; Return immediately if the dividend is zero. Setting B4 to 1 - ;; is a trick to allow us to leave the following insns in the jump - ;; delay slot without affecting the result. - mv .s2x A4, B1 - - [b1] lmbd .l2 1, B4, B1 -||[!b1] b .s2 B3 ; RETURN A -||[!b1] mvk .d2 1, B4 - -||[!b1] zero .s1 A5 - mv .l1x B1, A6 -|| shl .s2 B4, B1, B4 - - ;; The loop performs a maximum of 28 steps, so we do the - ;; first 3 here. - cmpltu .l1x A4, B4, A2 - [!A2] sub .l1x A4, B4, A4 -|| shru .s2 B4, 1, B4 -|| xor .s1 1, A2, A2 - - shl .s1 A2, 31, A2 -|| [b1] subc .l1x A4,B4,A4 -|| [b1] add .s2 -1, B1, B1 - [b1] subc .l1x A4,B4,A4 -|| [b1] add .s2 -1, B1, B1 - - ;; RETURN A may happen here (note: must happen before the next branch) -__divremu0: - cmpgt .l2 B1, 7, B0 -|| [b1] subc .l1x A4,B4,A4 -|| [b1] add .s2 -1, B1, B1 - [b1] subc .l1x A4,B4,A4 -|| [b1] add .s2 -1, B1, B1 -|| [b0] b .s1 __divremu0 - [b1] subc .l1x A4,B4,A4 -|| [b1] add .s2 -1, B1, B1 - [b1] subc .l1x A4,B4,A4 -|| [b1] add .s2 -1, B1, B1 - [b1] subc .l1x A4,B4,A4 -|| [b1] add .s2 -1, B1, B1 - [b1] subc .l1x A4,B4,A4 -|| [b1] add .s2 -1, B1, B1 - [b1] subc .l1x A4,B4,A4 -|| [b1] add .s2 -1, B1, B1 - ;; loop backwards branch happens here - - ret .s2 B3 -|| mvk .s1 32, A1 - sub .l1 A1, A6, A6 -|| extu .s1 A4, A6, A5 - shl .s1 A4, A6, A4 - shru .s1 A4, 1, A4 -|| sub .l1 A6, 1, A6 - or .l1 A2, A4, A4 - shru .s1 A4, A6, A4 - nop -ENDPROC(__c6xabi_divremu) diff --git a/arch/c6x/lib/divu.S b/arch/c6x/lib/divu.S deleted file mode 100644 index f0f6082944c2..000000000000 --- a/arch/c6x/lib/divu.S +++ /dev/null @@ -1,86 +0,0 @@ -;; SPDX-License-Identifier: GPL-2.0-or-later -;; Copyright 2010 Free Software Foundation, Inc. -;; Contributed by Bernd Schmidt . -;; - -#include - - ;; ABI considerations for the divide functions - ;; The following registers are call-used: - ;; __c6xabi_divi A0,A1,A2,A4,A6,B0,B1,B2,B4,B5 - ;; __c6xabi_divu A0,A1,A2,A4,A6,B0,B1,B2,B4 - ;; __c6xabi_remi A1,A2,A4,A5,A6,B0,B1,B2,B4 - ;; __c6xabi_remu A1,A4,A5,A7,B0,B1,B2,B4 - ;; - ;; In our implementation, divu and remu are leaf functions, - ;; while both divi and remi call into divu. - ;; A0 is not clobbered by any of the functions. - ;; divu does not clobber B2 either, which is taken advantage of - ;; in remi. - ;; divi uses B5 to hold the original return address during - ;; the call to divu. - ;; remi uses B2 and A5 to hold the input values during the - ;; call to divu. It stores B3 in on the stack. - - .text -ENTRY(__c6xabi_divu) - ;; We use a series of up to 31 subc instructions. First, we find - ;; out how many leading zero bits there are in the divisor. This - ;; gives us both a shift count for aligning (shifting) the divisor - ;; to the, and the number of times we have to execute subc. - - ;; At the end, we have both the remainder and most of the quotient - ;; in A4. The top bit of the quotient is computed first and is - ;; placed in A2. - - ;; Return immediately if the dividend is zero. - mv .s2x A4, B1 - [B1] lmbd .l2 1, B4, B1 -|| [!B1] b .s2 B3 ; RETURN A -|| [!B1] mvk .d2 1, B4 - mv .l1x B1, A6 -|| shl .s2 B4, B1, B4 - - ;; The loop performs a maximum of 28 steps, so we do the - ;; first 3 here. - cmpltu .l1x A4, B4, A2 - [!A2] sub .l1x A4, B4, A4 -|| shru .s2 B4, 1, B4 -|| xor .s1 1, A2, A2 - - shl .s1 A2, 31, A2 -|| [B1] subc .l1x A4,B4,A4 -|| [B1] add .s2 -1, B1, B1 - [B1] subc .l1x A4,B4,A4 -|| [B1] add .s2 -1, B1, B1 - - ;; RETURN A may happen here (note: must happen before the next branch) -_divu_loop: - cmpgt .l2 B1, 7, B0 -|| [B1] subc .l1x A4,B4,A4 -|| [B1] add .s2 -1, B1, B1 - [B1] subc .l1x A4,B4,A4 -|| [B1] add .s2 -1, B1, B1 -|| [B0] b .s1 _divu_loop - [B1] subc .l1x A4,B4,A4 -|| [B1] add .s2 -1, B1, B1 - [B1] subc .l1x A4,B4,A4 -|| [B1] add .s2 -1, B1, B1 - [B1] subc .l1x A4,B4,A4 -|| [B1] add .s2 -1, B1, B1 - [B1] subc .l1x A4,B4,A4 -|| [B1] add .s2 -1, B1, B1 - [B1] subc .l1x A4,B4,A4 -|| [B1] add .s2 -1, B1, B1 - ;; loop backwards branch happens here - - ret .s2 B3 -|| mvk .s1 32, A1 - sub .l1 A1, A6, A6 - shl .s1 A4, A6, A4 - shru .s1 A4, 1, A4 -|| sub .l1 A6, 1, A6 - or .l1 A2, A4, A4 - shru .s1 A4, A6, A4 - nop -ENDPROC(__c6xabi_divu) diff --git a/arch/c6x/lib/llshl.S b/arch/c6x/lib/llshl.S deleted file mode 100644 index 3272499618e0..000000000000 --- a/arch/c6x/lib/llshl.S +++ /dev/null @@ -1,25 +0,0 @@ -;; SPDX-License-Identifier: GPL-2.0-or-later -;; Copyright (C) 2010 Texas Instruments Incorporated -;; Contributed by Mark Salter . -;; - -;; uint64_t __c6xabi_llshl(uint64_t val, uint shift) - -#include - - .text -ENTRY(__c6xabi_llshl) - mv .l1x B4,A1 - [!A1] b .s2 B3 ; just return if zero shift - mvk .s1 32,A0 - sub .d1 A0,A1,A0 - cmplt .l1 0,A0,A2 - [A2] shru .s1 A4,A0,A0 - [!A2] neg .l1 A0,A5 -|| [A2] shl .s1 A5,A1,A5 - [!A2] shl .s1 A4,A5,A5 -|| [A2] or .d1 A5,A0,A5 -|| [!A2] mvk .l1 0,A4 - [A2] shl .s1 A4,A1,A4 - bnop .s2 B3,5 -ENDPROC(__c6xabi_llshl) diff --git a/arch/c6x/lib/llshr.S b/arch/c6x/lib/llshr.S deleted file mode 100644 index 6bfaacd15e73..000000000000 --- a/arch/c6x/lib/llshr.S +++ /dev/null @@ -1,26 +0,0 @@ -;; SPDX-License-Identifier: GPL-2.0-or-later -;; Copyright (C) 2010 Texas Instruments Incorporated -;; Contributed by Mark Salter . -;; - -;; uint64_t __c6xabi_llshr(uint64_t val, uint shift) - -#include - - .text -ENTRY(__c6xabi_llshr) - mv .l1x B4,A1 - [!A1] b .s2 B3 ; return if zero shift count - mvk .s1 32,A0 - sub .d1 A0,A1,A0 - cmplt .l1 0,A0,A2 - [A2] shl .s1 A5,A0,A0 - nop - [!A2] neg .l1 A0,A4 -|| [A2] shru .s1 A4,A1,A4 - [!A2] shr .s1 A5,A4,A4 -|| [A2] or .d1 A4,A0,A4 - [!A2] shr .s1 A5,0x1f,A5 - [A2] shr .s1 A5,A1,A5 - bnop .s2 B3,5 -ENDPROC(__c6xabi_llshr) diff --git a/arch/c6x/lib/llshru.S b/arch/c6x/lib/llshru.S deleted file mode 100644 index 103128f50770..000000000000 --- a/arch/c6x/lib/llshru.S +++ /dev/null @@ -1,26 +0,0 @@ -;; SPDX-License-Identifier: GPL-2.0-or-later -;; Copyright (C) 2010 Texas Instruments Incorporated -;; Contributed by Mark Salter . -;; - -;; uint64_t __c6xabi_llshru(uint64_t val, uint shift) - -#include - - .text -ENTRY(__c6xabi_llshru) - mv .l1x B4,A1 - [!A1] b .s2 B3 ; return if zero shift count - mvk .s1 32,A0 - sub .d1 A0,A1,A0 - cmplt .l1 0,A0,A2 - [A2] shl .s1 A5,A0,A0 - nop - [!A2] neg .l1 A0,A4 -|| [A2] shru .s1 A4,A1,A4 - [!A2] shru .s1 A5,A4,A4 -|| [A2] or .d1 A4,A0,A4 -|| [!A2] mvk .l1 0,A5 - [A2] shru .s1 A5,A1,A5 - bnop .s2 B3,5 -ENDPROC(__c6xabi_llshru) diff --git a/arch/c6x/lib/memcpy_64plus.S b/arch/c6x/lib/memcpy_64plus.S deleted file mode 100644 index 157a30486bfd..000000000000 --- a/arch/c6x/lib/memcpy_64plus.S +++ /dev/null @@ -1,43 +0,0 @@ -; SPDX-License-Identifier: GPL-2.0-only -; Port on Texas Instruments TMS320C6x architecture -; -; Copyright (C) 2006, 2009, 2010 Texas Instruments Incorporated -; Author: Aurelien Jacquiot (aurelien.jacquiot@jaluna.com) -; - -#include - - .text - -ENTRY(memcpy) - AND .L1 0x1,A6,A0 - || AND .S1 0x2,A6,A1 - || AND .L2X 0x4,A6,B0 - || MV .D1 A4,A3 - || MVC .S2 ILC,B2 - - [A0] LDB .D2T1 *B4++,A5 - [A1] LDB .D2T1 *B4++,A7 - [A1] LDB .D2T1 *B4++,A8 - [B0] LDNW .D2T1 *B4++,A9 - || SHRU .S2X A6,0x3,B1 - [!B1] BNOP .S2 B3,1 - - [A0] STB .D1T1 A5,*A3++ - ||[B1] MVC .S2 B1,ILC - [A1] STB .D1T1 A7,*A3++ - [A1] STB .D1T1 A8,*A3++ - [B0] STNW .D1T1 A9,*A3++ ; return when len < 8 - - SPLOOP 2 - - LDNDW .D2T1 *B4++,A9:A8 - NOP 3 - - NOP - SPKERNEL 0,0 - || STNDW .D1T1 A9:A8,*A3++ - - BNOP .S2 B3,4 - MVC .S2 B2,ILC -ENDPROC(memcpy) diff --git a/arch/c6x/lib/mpyll.S b/arch/c6x/lib/mpyll.S deleted file mode 100644 index d07c13ec4fd4..000000000000 --- a/arch/c6x/lib/mpyll.S +++ /dev/null @@ -1,37 +0,0 @@ -;; SPDX-License-Identifier: GPL-2.0-or-later -;; Copyright (C) 2010 Texas Instruments Incorporated -;; Contributed by Mark Salter . -;; - -#include - - ;; uint64_t __c6xabi_mpyll(uint64_t x, uint64_t y) - ;; - ;; 64x64 multiply - ;; First compute partial results using 32-bit parts of x and y: - ;; - ;; b63 b32 b31 b0 - ;; ----------------------------- - ;; | 1 | 0 | - ;; ----------------------------- - ;; - ;; P0 = X0*Y0 - ;; P1 = X0*Y1 + X1*Y0 - ;; P2 = X1*Y1 - ;; - ;; result = (P2 << 64) + (P1 << 32) + P0 - ;; - ;; Since the result is also 64-bit, we can skip the P2 term. - - .text -ENTRY(__c6xabi_mpyll) - mpy32u .m1x A4,B4,A1:A0 ; X0*Y0 - b .s2 B3 - || mpy32u .m2x B5,A4,B1:B0 ; X0*Y1 (don't need upper 32-bits) - || mpy32u .m1x A5,B4,A3:A2 ; X1*Y0 (don't need upper 32-bits) - nop - nop - mv .s1 A0,A4 - add .l1x A2,B0,A5 - add .s1 A1,A5,A5 -ENDPROC(__c6xabi_mpyll) diff --git a/arch/c6x/lib/negll.S b/arch/c6x/lib/negll.S deleted file mode 100644 index 9ba434db5366..000000000000 --- a/arch/c6x/lib/negll.S +++ /dev/null @@ -1,19 +0,0 @@ -;; SPDX-License-Identifier: GPL-2.0-or-later -;; Copyright (C) 2010 Texas Instruments Incorporated -;; Contributed by Mark Salter . -;; - -;; int64_t __c6xabi_negll(int64_t val) - -#include - - .text -ENTRY(__c6xabi_negll) - b .s2 B3 - mvk .l1 0,A0 - subu .l1 A0,A4,A3:A2 - sub .l1 A0,A5,A0 -|| ext .s1 A3,24,24,A5 - add .l1 A5,A0,A5 - mv .s1 A2,A4 -ENDPROC(__c6xabi_negll) diff --git a/arch/c6x/lib/pop_rts.S b/arch/c6x/lib/pop_rts.S deleted file mode 100644 index f129e32943c5..000000000000 --- a/arch/c6x/lib/pop_rts.S +++ /dev/null @@ -1,20 +0,0 @@ -;; SPDX-License-Identifier: GPL-2.0-or-later -;; Copyright 2010 Free Software Foundation, Inc. -;; Contributed by Bernd Schmidt . -;; - -#include - - .text - -ENTRY(__c6xabi_pop_rts) - lddw .d2t2 *++B15, B3:B2 - lddw .d2t1 *++B15, A11:A10 - lddw .d2t2 *++B15, B11:B10 - lddw .d2t1 *++B15, A13:A12 - lddw .d2t2 *++B15, B13:B12 - lddw .d2t1 *++B15, A15:A14 -|| b .s2 B3 - ldw .d2t2 *++B15[2], B14 - nop 4 -ENDPROC(__c6xabi_pop_rts) diff --git a/arch/c6x/lib/push_rts.S b/arch/c6x/lib/push_rts.S deleted file mode 100644 index 40b0a4fe937c..000000000000 --- a/arch/c6x/lib/push_rts.S +++ /dev/null @@ -1,19 +0,0 @@ -;; SPDX-License-Identifier: GPL-2.0-or-later -;; Copyright 2010 Free Software Foundation, Inc. -;; Contributed by Bernd Schmidt . -;; - -#include - - .text - -ENTRY(__c6xabi_push_rts) - stw .d2t2 B14, *B15--[2] - stdw .d2t1 A15:A14, *B15-- -|| b .s2x A3 - stdw .d2t2 B13:B12, *B15-- - stdw .d2t1 A13:A12, *B15-- - stdw .d2t2 B11:B10, *B15-- - stdw .d2t1 A11:A10, *B15-- - stdw .d2t2 B3:B2, *B15-- -ENDPROC(__c6xabi_push_rts) diff --git a/arch/c6x/lib/remi.S b/arch/c6x/lib/remi.S deleted file mode 100644 index 96a1335eac20..000000000000 --- a/arch/c6x/lib/remi.S +++ /dev/null @@ -1,52 +0,0 @@ -;; SPDX-License-Identifier: GPL-2.0-or-later -;; Copyright 2010 Free Software Foundation, Inc. -;; Contributed by Bernd Schmidt . -;; - -#include - - ;; ABI considerations for the divide functions - ;; The following registers are call-used: - ;; __c6xabi_divi A0,A1,A2,A4,A6,B0,B1,B2,B4,B5 - ;; __c6xabi_divu A0,A1,A2,A4,A6,B0,B1,B2,B4 - ;; __c6xabi_remi A1,A2,A4,A5,A6,B0,B1,B2,B4 - ;; __c6xabi_remu A1,A4,A5,A7,B0,B1,B2,B4 - ;; - ;; In our implementation, divu and remu are leaf functions, - ;; while both divi and remi call into divu. - ;; A0 is not clobbered by any of the functions. - ;; divu does not clobber B2 either, which is taken advantage of - ;; in remi. - ;; divi uses B5 to hold the original return address during - ;; the call to divu. - ;; remi uses B2 and A5 to hold the input values during the - ;; call to divu. It stores B3 in on the stack. - - .text - -ENTRY(__c6xabi_remi) - stw .d2t2 B3, *B15--[2] -|| cmpgt .l1 0, A4, A1 -|| cmpgt .l2 0, B4, B2 -|| mv .s1 A4, A5 -|| call .s2 __c6xabi_divu - - [A1] neg .l1 A4, A4 -|| [B2] neg .l2 B4, B4 -|| xor .s2x B2, A1, B0 -|| mv .d2 B4, B2 - - [B0] addkpc .s2 _divu_ret_1, B3, 1 - [!B0] addkpc .s2 _divu_ret_2, B3, 1 - nop 2 -_divu_ret_1: - neg .l1 A4, A4 -_divu_ret_2: - ldw .d2t2 *++B15[2], B3 - - mpy32 .m1x A4, B2, A6 - nop 3 - ret .s2 B3 - sub .l1 A5, A6, A4 - nop 4 -ENDPROC(__c6xabi_remi) diff --git a/arch/c6x/lib/remu.S b/arch/c6x/lib/remu.S deleted file mode 100644 index 428feb9c06c0..000000000000 --- a/arch/c6x/lib/remu.S +++ /dev/null @@ -1,70 +0,0 @@ -;; SPDX-License-Identifier: GPL-2.0-or-later -;; Copyright 2010 Free Software Foundation, Inc. -;; Contributed by Bernd Schmidt . -;; - -#include - - ;; ABI considerations for the divide functions - ;; The following registers are call-used: - ;; __c6xabi_divi A0,A1,A2,A4,A6,B0,B1,B2,B4,B5 - ;; __c6xabi_divu A0,A1,A2,A4,A6,B0,B1,B2,B4 - ;; __c6xabi_remi A1,A2,A4,A5,A6,B0,B1,B2,B4 - ;; __c6xabi_remu A1,A4,A5,A7,B0,B1,B2,B4 - ;; - ;; In our implementation, divu and remu are leaf functions, - ;; while both divi and remi call into divu. - ;; A0 is not clobbered by any of the functions. - ;; divu does not clobber B2 either, which is taken advantage of - ;; in remi. - ;; divi uses B5 to hold the original return address during - ;; the call to divu. - ;; remi uses B2 and A5 to hold the input values during the - ;; call to divu. It stores B3 in on the stack. - - - .text - -ENTRY(__c6xabi_remu) - ;; The ABI seems designed to prevent these functions calling each other, - ;; so we duplicate most of the divsi3 code here. - mv .s2x A4, B1 - lmbd .l2 1, B4, B1 -|| [!B1] b .s2 B3 ; RETURN A -|| [!B1] mvk .d2 1, B4 - - mv .l1x B1, A7 -|| shl .s2 B4, B1, B4 - - cmpltu .l1x A4, B4, A1 - [!A1] sub .l1x A4, B4, A4 - shru .s2 B4, 1, B4 - -_remu_loop: - cmpgt .l2 B1, 7, B0 -|| [B1] subc .l1x A4,B4,A4 -|| [B1] add .s2 -1, B1, B1 - ;; RETURN A may happen here (note: must happen before the next branch) - [B1] subc .l1x A4,B4,A4 -|| [B1] add .s2 -1, B1, B1 -|| [B0] b .s1 _remu_loop - [B1] subc .l1x A4,B4,A4 -|| [B1] add .s2 -1, B1, B1 - [B1] subc .l1x A4,B4,A4 -|| [B1] add .s2 -1, B1, B1 - [B1] subc .l1x A4,B4,A4 -|| [B1] add .s2 -1, B1, B1 - [B1] subc .l1x A4,B4,A4 -|| [B1] add .s2 -1, B1, B1 - [B1] subc .l1x A4,B4,A4 -|| [B1] add .s2 -1, B1, B1 - ;; loop backwards branch happens here - - ret .s2 B3 - [B1] subc .l1x A4,B4,A4 -|| [B1] add .s2 -1, B1, B1 - [B1] subc .l1x A4,B4,A4 - - extu .s1 A4, A7, A4 - nop 2 -ENDPROC(__c6xabi_remu) diff --git a/arch/c6x/lib/strasgi.S b/arch/c6x/lib/strasgi.S deleted file mode 100644 index 715aeb200792..000000000000 --- a/arch/c6x/lib/strasgi.S +++ /dev/null @@ -1,77 +0,0 @@ -;; SPDX-License-Identifier: GPL-2.0-or-later -;; Copyright 2010 Free Software Foundation, Inc. -;; Contributed by Bernd Schmidt . -;; - -#include - - .text - -ENTRY(__c6xabi_strasgi) - ;; This is essentially memcpy, with alignment known to be at least - ;; 4, and the size a multiple of 4 greater than or equal to 28. - ldw .d2t1 *B4++, A0 -|| mvk .s2 16, B1 - ldw .d2t1 *B4++, A1 -|| mvk .s2 20, B2 -|| sub .d1 A6, 24, A6 - ldw .d2t1 *B4++, A5 - ldw .d2t1 *B4++, A7 -|| mv .l2x A6, B7 - ldw .d2t1 *B4++, A8 - ldw .d2t1 *B4++, A9 -|| mv .s2x A0, B5 -|| cmpltu .l2 B2, B7, B0 - -_strasgi_loop: - stw .d1t2 B5, *A4++ -|| [B0] ldw .d2t1 *B4++, A0 -|| mv .s2x A1, B5 -|| mv .l2 B7, B6 - - [B0] sub .d2 B6, 24, B7 -|| [B0] b .s2 _strasgi_loop -|| cmpltu .l2 B1, B6, B0 - - [B0] ldw .d2t1 *B4++, A1 -|| stw .d1t2 B5, *A4++ -|| mv .s2x A5, B5 -|| cmpltu .l2 12, B6, B0 - - [B0] ldw .d2t1 *B4++, A5 -|| stw .d1t2 B5, *A4++ -|| mv .s2x A7, B5 -|| cmpltu .l2 8, B6, B0 - - [B0] ldw .d2t1 *B4++, A7 -|| stw .d1t2 B5, *A4++ -|| mv .s2x A8, B5 -|| cmpltu .l2 4, B6, B0 - - [B0] ldw .d2t1 *B4++, A8 -|| stw .d1t2 B5, *A4++ -|| mv .s2x A9, B5 -|| cmpltu .l2 0, B6, B0 - - [B0] ldw .d2t1 *B4++, A9 -|| stw .d1t2 B5, *A4++ -|| mv .s2x A0, B5 -|| cmpltu .l2 B2, B7, B0 - - ;; loop back branch happens here - - cmpltu .l2 B1, B6, B0 -|| ret .s2 b3 - - [B0] stw .d1t1 A1, *A4++ -|| cmpltu .l2 12, B6, B0 - [B0] stw .d1t1 A5, *A4++ -|| cmpltu .l2 8, B6, B0 - [B0] stw .d1t1 A7, *A4++ -|| cmpltu .l2 4, B6, B0 - [B0] stw .d1t1 A8, *A4++ -|| cmpltu .l2 0, B6, B0 - [B0] stw .d1t1 A9, *A4++ - - ;; return happens here -ENDPROC(__c6xabi_strasgi) diff --git a/arch/c6x/lib/strasgi_64plus.S b/arch/c6x/lib/strasgi_64plus.S deleted file mode 100644 index d10aa2dc3249..000000000000 --- a/arch/c6x/lib/strasgi_64plus.S +++ /dev/null @@ -1,27 +0,0 @@ -;; SPDX-License-Identifier: GPL-2.0-or-later -;; Copyright 2010 Free Software Foundation, Inc. -;; Contributed by Bernd Schmidt . -;; - -#include - - .text - -ENTRY(__c6xabi_strasgi_64plus) - shru .s2x a6, 2, b31 -|| mv .s1 a4, a30 -|| mv .d2 b4, b30 - - add .s2 -4, b31, b31 - - sploopd 1 -|| mvc .s2 b31, ilc - ldw .d2t2 *b30++, b31 - nop 4 - mv .s1x b31,a31 - spkernel 6, 0 -|| stw .d1t1 a31, *a30++ - - ret .s2 b3 - nop 5 -ENDPROC(__c6xabi_strasgi_64plus) diff --git a/arch/c6x/mm/Makefile b/arch/c6x/mm/Makefile deleted file mode 100644 index 19d05e972dd1..000000000000 --- a/arch/c6x/mm/Makefile +++ /dev/null @@ -1,6 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0-only -# -# Makefile for the linux c6x-specific parts of the memory manager. -# - -obj-y := init.o dma-coherent.o diff --git a/arch/c6x/mm/dma-coherent.c b/arch/c6x/mm/dma-coherent.c deleted file mode 100644 index 03df07a831fc..000000000000 --- a/arch/c6x/mm/dma-coherent.c +++ /dev/null @@ -1,173 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Port on Texas Instruments TMS320C6x architecture - * - * Copyright (C) 2004, 2009, 2010, 2011 Texas Instruments Incorporated - * Author: Aurelien Jacquiot - * - * DMA uncached mapping support. - * - * Using code pulled from ARM - * Copyright (C) 2000-2004 Russell King - */ -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -/* - * DMA coherent memory management, can be redefined using the memdma= - * kernel command line - */ - -/* none by default */ -static phys_addr_t dma_base; -static u32 dma_size; -static u32 dma_pages; - -static unsigned long *dma_bitmap; - -/* bitmap lock */ -static DEFINE_SPINLOCK(dma_lock); - -/* - * Return a DMA coherent and contiguous memory chunk from the DMA memory - */ -static inline u32 __alloc_dma_pages(int order) -{ - unsigned long flags; - u32 pos; - - spin_lock_irqsave(&dma_lock, flags); - pos = bitmap_find_free_region(dma_bitmap, dma_pages, order); - spin_unlock_irqrestore(&dma_lock, flags); - - return dma_base + (pos << PAGE_SHIFT); -} - -static void __free_dma_pages(u32 addr, int order) -{ - unsigned long flags; - u32 pos = (addr - dma_base) >> PAGE_SHIFT; - - if (addr < dma_base || (pos + (1 << order)) >= dma_pages) { - printk(KERN_ERR "%s: freeing outside range.\n", __func__); - BUG(); - } - - spin_lock_irqsave(&dma_lock, flags); - bitmap_release_region(dma_bitmap, pos, order); - spin_unlock_irqrestore(&dma_lock, flags); -} - -/* - * Allocate DMA coherent memory space and return both the kernel - * virtual and DMA address for that space. - */ -void *arch_dma_alloc(struct device *dev, size_t size, dma_addr_t *handle, - gfp_t gfp, unsigned long attrs) -{ - void *ret; - u32 paddr; - int order; - - if (!dma_size || !size) - return NULL; - - order = get_count_order(((size - 1) >> PAGE_SHIFT) + 1); - - paddr = __alloc_dma_pages(order); - - if (handle) - *handle = paddr; - - if (!paddr) - return NULL; - - ret = phys_to_virt(paddr); - memset(ret, 0, 1 << order); - return ret; -} - -/* - * Free DMA coherent memory as defined by the above mapping. - */ -void arch_dma_free(struct device *dev, size_t size, void *vaddr, - dma_addr_t dma_handle, unsigned long attrs) -{ - int order; - - if (!dma_size || !size) - return; - - order = get_count_order(((size - 1) >> PAGE_SHIFT) + 1); - - __free_dma_pages(virt_to_phys(vaddr), order); -} - -/* - * Initialise the coherent DMA memory allocator using the given uncached region. - */ -void __init coherent_mem_init(phys_addr_t start, u32 size) -{ - if (!size) - return; - - printk(KERN_INFO - "Coherent memory (DMA) region start=0x%x size=0x%x\n", - start, size); - - dma_base = start; - dma_size = size; - - /* allocate bitmap */ - dma_pages = dma_size >> PAGE_SHIFT; - if (dma_size & (PAGE_SIZE - 1)) - ++dma_pages; - - dma_bitmap = memblock_alloc(BITS_TO_LONGS(dma_pages) * sizeof(long), - sizeof(long)); - if (!dma_bitmap) - panic("%s: Failed to allocate %zu bytes align=0x%zx\n", - __func__, BITS_TO_LONGS(dma_pages) * sizeof(long), - sizeof(long)); -} - -static void c6x_dma_sync(phys_addr_t paddr, size_t size, - enum dma_data_direction dir) -{ - BUG_ON(!valid_dma_direction(dir)); - - switch (dir) { - case DMA_FROM_DEVICE: - L2_cache_block_invalidate(paddr, paddr + size); - break; - case DMA_TO_DEVICE: - L2_cache_block_writeback(paddr, paddr + size); - break; - case DMA_BIDIRECTIONAL: - L2_cache_block_writeback_invalidate(paddr, paddr + size); - break; - default: - break; - } -} - -void arch_sync_dma_for_device(phys_addr_t paddr, size_t size, - enum dma_data_direction dir) -{ - return c6x_dma_sync(paddr, size, dir); -} - -void arch_sync_dma_for_cpu(phys_addr_t paddr, size_t size, - enum dma_data_direction dir) -{ - return c6x_dma_sync(paddr, size, dir); -} diff --git a/arch/c6x/mm/init.c b/arch/c6x/mm/init.c deleted file mode 100644 index a97e51a3e26d..000000000000 --- a/arch/c6x/mm/init.c +++ /dev/null @@ -1,65 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Port on Texas Instruments TMS320C6x architecture - * - * Copyright (C) 2004, 2009, 2010, 2011 Texas Instruments Incorporated - * Author: Aurelien Jacquiot (aurelien.jacquiot@jaluna.com) - */ -#include -#include -#include -#include -#ifdef CONFIG_BLK_DEV_RAM -#include -#endif -#include - -#include -#include - -/* - * ZERO_PAGE is a special page that is used for zero-initialized - * data and COW. - */ -unsigned long empty_zero_page; -EXPORT_SYMBOL(empty_zero_page); - -/* - * paging_init() continues the virtual memory environment setup which - * was begun by the code in arch/head.S. - * The parameters are pointers to where to stick the starting and ending - * addresses of available kernel virtual memory. - */ -void __init paging_init(void) -{ - struct pglist_data *pgdat = NODE_DATA(0); - unsigned long max_zone_pfn[MAX_NR_ZONES] = {0, }; - - empty_zero_page = (unsigned long) memblock_alloc(PAGE_SIZE, - PAGE_SIZE); - if (!empty_zero_page) - panic("%s: Failed to allocate %lu bytes align=0x%lx\n", - __func__, PAGE_SIZE, PAGE_SIZE); - - /* - * Set up user data space - */ - set_fs(KERNEL_DS); - - /* - * Define zones - */ - max_zone_pfn[ZONE_NORMAL] = memory_end >> PAGE_SHIFT; - - free_area_init(max_zone_pfn); -} - -void __init mem_init(void) -{ - high_memory = (void *)(memory_end & PAGE_MASK); - - /* this will put all memory onto the freelists */ - memblock_free_all(); - - mem_init_print_info(NULL); -} diff --git a/arch/c6x/platforms/Kconfig b/arch/c6x/platforms/Kconfig deleted file mode 100644 index f3a9ae6e0e82..000000000000 --- a/arch/c6x/platforms/Kconfig +++ /dev/null @@ -1,21 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0 - -config SOC_TMS320C6455 - bool "TMS320C6455" - default n - -config SOC_TMS320C6457 - bool "TMS320C6457" - default n - -config SOC_TMS320C6472 - bool "TMS320C6472" - default n - -config SOC_TMS320C6474 - bool "TMS320C6474" - default n - -config SOC_TMS320C6678 - bool "TMS320C6678" - default n diff --git a/arch/c6x/platforms/Makefile b/arch/c6x/platforms/Makefile deleted file mode 100644 index b320f1c68884..000000000000 --- a/arch/c6x/platforms/Makefile +++ /dev/null @@ -1,13 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0-only -# -# Makefile for arch/c6x/platforms -# -# Copyright 2010, 2011 Texas Instruments Incorporated -# - -obj-y = cache.o megamod-pic.o pll.o plldata.o timer64.o -obj-y += dscr.o - -# SoC objects -obj-$(CONFIG_SOC_TMS320C6455) += emif.o -obj-$(CONFIG_SOC_TMS320C6457) += emif.o diff --git a/arch/c6x/platforms/cache.c b/arch/c6x/platforms/cache.c deleted file mode 100644 index fff027b72513..000000000000 --- a/arch/c6x/platforms/cache.c +++ /dev/null @@ -1,444 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Copyright (C) 2011 Texas Instruments Incorporated - * Author: Mark Salter - */ -#include -#include -#include - -#include -#include - -/* - * Internal Memory Control Registers for caches - */ -#define IMCR_CCFG 0x0000 -#define IMCR_L1PCFG 0x0020 -#define IMCR_L1PCC 0x0024 -#define IMCR_L1DCFG 0x0040 -#define IMCR_L1DCC 0x0044 -#define IMCR_L2ALLOC0 0x2000 -#define IMCR_L2ALLOC1 0x2004 -#define IMCR_L2ALLOC2 0x2008 -#define IMCR_L2ALLOC3 0x200c -#define IMCR_L2WBAR 0x4000 -#define IMCR_L2WWC 0x4004 -#define IMCR_L2WIBAR 0x4010 -#define IMCR_L2WIWC 0x4014 -#define IMCR_L2IBAR 0x4018 -#define IMCR_L2IWC 0x401c -#define IMCR_L1PIBAR 0x4020 -#define IMCR_L1PIWC 0x4024 -#define IMCR_L1DWIBAR 0x4030 -#define IMCR_L1DWIWC 0x4034 -#define IMCR_L1DWBAR 0x4040 -#define IMCR_L1DWWC 0x4044 -#define IMCR_L1DIBAR 0x4048 -#define IMCR_L1DIWC 0x404c -#define IMCR_L2WB 0x5000 -#define IMCR_L2WBINV 0x5004 -#define IMCR_L2INV 0x5008 -#define IMCR_L1PINV 0x5028 -#define IMCR_L1DWB 0x5040 -#define IMCR_L1DWBINV 0x5044 -#define IMCR_L1DINV 0x5048 -#define IMCR_MAR_BASE 0x8000 -#define IMCR_MAR96_111 0x8180 -#define IMCR_MAR128_191 0x8200 -#define IMCR_MAR224_239 0x8380 -#define IMCR_L2MPFAR 0xa000 -#define IMCR_L2MPFSR 0xa004 -#define IMCR_L2MPFCR 0xa008 -#define IMCR_L2MPLK0 0xa100 -#define IMCR_L2MPLK1 0xa104 -#define IMCR_L2MPLK2 0xa108 -#define IMCR_L2MPLK3 0xa10c -#define IMCR_L2MPLKCMD 0xa110 -#define IMCR_L2MPLKSTAT 0xa114 -#define IMCR_L2MPPA_BASE 0xa200 -#define IMCR_L1PMPFAR 0xa400 -#define IMCR_L1PMPFSR 0xa404 -#define IMCR_L1PMPFCR 0xa408 -#define IMCR_L1PMPLK0 0xa500 -#define IMCR_L1PMPLK1 0xa504 -#define IMCR_L1PMPLK2 0xa508 -#define IMCR_L1PMPLK3 0xa50c -#define IMCR_L1PMPLKCMD 0xa510 -#define IMCR_L1PMPLKSTAT 0xa514 -#define IMCR_L1PMPPA_BASE 0xa600 -#define IMCR_L1DMPFAR 0xac00 -#define IMCR_L1DMPFSR 0xac04 -#define IMCR_L1DMPFCR 0xac08 -#define IMCR_L1DMPLK0 0xad00 -#define IMCR_L1DMPLK1 0xad04 -#define IMCR_L1DMPLK2 0xad08 -#define IMCR_L1DMPLK3 0xad0c -#define IMCR_L1DMPLKCMD 0xad10 -#define IMCR_L1DMPLKSTAT 0xad14 -#define IMCR_L1DMPPA_BASE 0xae00 -#define IMCR_L2PDWAKE0 0xc040 -#define IMCR_L2PDWAKE1 0xc044 -#define IMCR_L2PDSLEEP0 0xc050 -#define IMCR_L2PDSLEEP1 0xc054 -#define IMCR_L2PDSTAT0 0xc060 -#define IMCR_L2PDSTAT1 0xc064 - -/* - * CCFG register values and bits - */ -#define L2MODE_0K_CACHE 0x0 -#define L2MODE_32K_CACHE 0x1 -#define L2MODE_64K_CACHE 0x2 -#define L2MODE_128K_CACHE 0x3 -#define L2MODE_256K_CACHE 0x7 - -#define L2PRIO_URGENT 0x0 -#define L2PRIO_HIGH 0x1 -#define L2PRIO_MEDIUM 0x2 -#define L2PRIO_LOW 0x3 - -#define CCFG_ID 0x100 /* Invalidate L1P bit */ -#define CCFG_IP 0x200 /* Invalidate L1D bit */ - -static void __iomem *cache_base; - -/* - * L1 & L2 caches generic functions - */ -#define imcr_get(reg) soc_readl(cache_base + (reg)) -#define imcr_set(reg, value) \ -do { \ - soc_writel((value), cache_base + (reg)); \ - soc_readl(cache_base + (reg)); \ -} while (0) - -static void cache_block_operation_wait(unsigned int wc_reg) -{ - /* Wait for completion */ - while (imcr_get(wc_reg)) - cpu_relax(); -} - -static DEFINE_SPINLOCK(cache_lock); - -/* - * Generic function to perform a block cache operation as - * invalidate or writeback/invalidate - */ -static void cache_block_operation(unsigned int *start, - unsigned int *end, - unsigned int bar_reg, - unsigned int wc_reg) -{ - unsigned long flags; - unsigned int wcnt = - (L2_CACHE_ALIGN_CNT((unsigned int) end) - - L2_CACHE_ALIGN_LOW((unsigned int) start)) >> 2; - unsigned int wc = 0; - - for (; wcnt; wcnt -= wc, start += wc) { -loop: - spin_lock_irqsave(&cache_lock, flags); - - /* - * If another cache operation is occurring - */ - if (unlikely(imcr_get(wc_reg))) { - spin_unlock_irqrestore(&cache_lock, flags); - - /* Wait for previous operation completion */ - cache_block_operation_wait(wc_reg); - - /* Try again */ - goto loop; - } - - imcr_set(bar_reg, L2_CACHE_ALIGN_LOW((unsigned int) start)); - - if (wcnt > 0xffff) - wc = 0xffff; - else - wc = wcnt; - - /* Set word count value in the WC register */ - imcr_set(wc_reg, wc & 0xffff); - - spin_unlock_irqrestore(&cache_lock, flags); - - /* Wait for completion */ - cache_block_operation_wait(wc_reg); - } -} - -static void cache_block_operation_nowait(unsigned int *start, - unsigned int *end, - unsigned int bar_reg, - unsigned int wc_reg) -{ - unsigned long flags; - unsigned int wcnt = - (L2_CACHE_ALIGN_CNT((unsigned int) end) - - L2_CACHE_ALIGN_LOW((unsigned int) start)) >> 2; - unsigned int wc = 0; - - for (; wcnt; wcnt -= wc, start += wc) { - - spin_lock_irqsave(&cache_lock, flags); - - imcr_set(bar_reg, L2_CACHE_ALIGN_LOW((unsigned int) start)); - - if (wcnt > 0xffff) - wc = 0xffff; - else - wc = wcnt; - - /* Set word count value in the WC register */ - imcr_set(wc_reg, wc & 0xffff); - - spin_unlock_irqrestore(&cache_lock, flags); - - /* Don't wait for completion on last cache operation */ - if (wcnt > 0xffff) - cache_block_operation_wait(wc_reg); - } -} - -/* - * L1 caches management - */ - -/* - * Disable L1 caches - */ -void L1_cache_off(void) -{ - unsigned int dummy; - - imcr_set(IMCR_L1PCFG, 0); - dummy = imcr_get(IMCR_L1PCFG); - - imcr_set(IMCR_L1DCFG, 0); - dummy = imcr_get(IMCR_L1DCFG); -} - -/* - * Enable L1 caches - */ -void L1_cache_on(void) -{ - unsigned int dummy; - - imcr_set(IMCR_L1PCFG, 7); - dummy = imcr_get(IMCR_L1PCFG); - - imcr_set(IMCR_L1DCFG, 7); - dummy = imcr_get(IMCR_L1DCFG); -} - -/* - * L1P global-invalidate all - */ -void L1P_cache_global_invalidate(void) -{ - unsigned int set = 1; - imcr_set(IMCR_L1PINV, set); - while (imcr_get(IMCR_L1PINV) & 1) - cpu_relax(); -} - -/* - * L1D global-invalidate all - * - * Warning: this operation causes all updated data in L1D to - * be discarded rather than written back to the lower levels of - * memory - */ -void L1D_cache_global_invalidate(void) -{ - unsigned int set = 1; - imcr_set(IMCR_L1DINV, set); - while (imcr_get(IMCR_L1DINV) & 1) - cpu_relax(); -} - -void L1D_cache_global_writeback(void) -{ - unsigned int set = 1; - imcr_set(IMCR_L1DWB, set); - while (imcr_get(IMCR_L1DWB) & 1) - cpu_relax(); -} - -void L1D_cache_global_writeback_invalidate(void) -{ - unsigned int set = 1; - imcr_set(IMCR_L1DWBINV, set); - while (imcr_get(IMCR_L1DWBINV) & 1) - cpu_relax(); -} - -/* - * L2 caches management - */ - -/* - * Set L2 operation mode - */ -void L2_cache_set_mode(unsigned int mode) -{ - unsigned int ccfg = imcr_get(IMCR_CCFG); - - /* Clear and set the L2MODE bits in CCFG */ - ccfg &= ~7; - ccfg |= (mode & 7); - imcr_set(IMCR_CCFG, ccfg); - ccfg = imcr_get(IMCR_CCFG); -} - -/* - * L2 global-writeback and global-invalidate all - */ -void L2_cache_global_writeback_invalidate(void) -{ - imcr_set(IMCR_L2WBINV, 1); - while (imcr_get(IMCR_L2WBINV)) - cpu_relax(); -} - -/* - * L2 global-writeback all - */ -void L2_cache_global_writeback(void) -{ - imcr_set(IMCR_L2WB, 1); - while (imcr_get(IMCR_L2WB)) - cpu_relax(); -} - -/* - * Cacheability controls - */ -void enable_caching(unsigned long start, unsigned long end) -{ - unsigned int mar = IMCR_MAR_BASE + ((start >> 24) << 2); - unsigned int mar_e = IMCR_MAR_BASE + ((end >> 24) << 2); - - for (; mar <= mar_e; mar += 4) - imcr_set(mar, imcr_get(mar) | 1); -} - -void disable_caching(unsigned long start, unsigned long end) -{ - unsigned int mar = IMCR_MAR_BASE + ((start >> 24) << 2); - unsigned int mar_e = IMCR_MAR_BASE + ((end >> 24) << 2); - - for (; mar <= mar_e; mar += 4) - imcr_set(mar, imcr_get(mar) & ~1); -} - - -/* - * L1 block operations - */ -void L1P_cache_block_invalidate(unsigned int start, unsigned int end) -{ - cache_block_operation((unsigned int *) start, - (unsigned int *) end, - IMCR_L1PIBAR, IMCR_L1PIWC); -} -EXPORT_SYMBOL(L1P_cache_block_invalidate); - -void L1D_cache_block_invalidate(unsigned int start, unsigned int end) -{ - cache_block_operation((unsigned int *) start, - (unsigned int *) end, - IMCR_L1DIBAR, IMCR_L1DIWC); -} - -void L1D_cache_block_writeback_invalidate(unsigned int start, unsigned int end) -{ - cache_block_operation((unsigned int *) start, - (unsigned int *) end, - IMCR_L1DWIBAR, IMCR_L1DWIWC); -} - -void L1D_cache_block_writeback(unsigned int start, unsigned int end) -{ - cache_block_operation((unsigned int *) start, - (unsigned int *) end, - IMCR_L1DWBAR, IMCR_L1DWWC); -} -EXPORT_SYMBOL(L1D_cache_block_writeback); - -/* - * L2 block operations - */ -void L2_cache_block_invalidate(unsigned int start, unsigned int end) -{ - cache_block_operation((unsigned int *) start, - (unsigned int *) end, - IMCR_L2IBAR, IMCR_L2IWC); -} - -void L2_cache_block_writeback(unsigned int start, unsigned int end) -{ - cache_block_operation((unsigned int *) start, - (unsigned int *) end, - IMCR_L2WBAR, IMCR_L2WWC); -} - -void L2_cache_block_writeback_invalidate(unsigned int start, unsigned int end) -{ - cache_block_operation((unsigned int *) start, - (unsigned int *) end, - IMCR_L2WIBAR, IMCR_L2WIWC); -} - -void L2_cache_block_invalidate_nowait(unsigned int start, unsigned int end) -{ - cache_block_operation_nowait((unsigned int *) start, - (unsigned int *) end, - IMCR_L2IBAR, IMCR_L2IWC); -} - -void L2_cache_block_writeback_nowait(unsigned int start, unsigned int end) -{ - cache_block_operation_nowait((unsigned int *) start, - (unsigned int *) end, - IMCR_L2WBAR, IMCR_L2WWC); -} - -void L2_cache_block_writeback_invalidate_nowait(unsigned int start, - unsigned int end) -{ - cache_block_operation_nowait((unsigned int *) start, - (unsigned int *) end, - IMCR_L2WIBAR, IMCR_L2WIWC); -} - - -/* - * L1 and L2 caches configuration - */ -void __init c6x_cache_init(void) -{ - struct device_node *node; - - node = of_find_compatible_node(NULL, NULL, "ti,c64x+cache"); - if (!node) - return; - - cache_base = of_iomap(node, 0); - - of_node_put(node); - - if (!cache_base) - return; - - /* Set L2 caches on the the whole L2 SRAM memory */ - L2_cache_set_mode(L2MODE_SIZE); - - /* Enable L1 */ - L1_cache_on(); -} diff --git a/arch/c6x/platforms/dscr.c b/arch/c6x/platforms/dscr.c deleted file mode 100644 index 4571615b589f..000000000000 --- a/arch/c6x/platforms/dscr.c +++ /dev/null @@ -1,595 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Device State Control Registers driver - * - * Copyright (C) 2011 Texas Instruments Incorporated - * Author: Mark Salter - */ - -/* - * The Device State Control Registers (DSCR) provide SoC level control over - * a number of peripherals. Details vary considerably among the various SoC - * parts. In general, the DSCR block will provide one or more configuration - * registers often protected by a lock register. One or more key values must - * be written to a lock register in order to unlock the configuration register. - * The configuration register may be used to enable (and disable in some - * cases) SoC pin drivers, peripheral clock sources (internal or pin), etc. - * In some cases, a configuration register is write once or the individual - * bits are write once. That is, you may be able to enable a device, but - * will not be able to disable it. - * - * In addition to device configuration, the DSCR block may provide registers - * which are used to reset SoC peripherals, provide device ID information, - * provide MAC addresses, and other miscellaneous functions. - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -#define MAX_DEVSTATE_IDS 32 -#define MAX_DEVCTL_REGS 8 -#define MAX_DEVSTAT_REGS 8 -#define MAX_LOCKED_REGS 4 -#define MAX_SOC_EMACS 2 - -struct rmii_reset_reg { - u32 reg; - u32 mask; -}; - -/* - * Some registerd may be locked. In order to write to these - * registers, the key value must first be written to the lockreg. - */ -struct locked_reg { - u32 reg; /* offset from base */ - u32 lockreg; /* offset from base */ - u32 key; /* unlock key */ -}; - -/* - * This describes a contiguous area of like control bits used to enable/disable - * SoC devices. Each controllable device is given an ID which is used by the - * individual device drivers to control the device state. These IDs start at - * zero and are assigned sequentially to the control bitfield ranges described - * by this structure. - */ -struct devstate_ctl_reg { - u32 reg; /* register holding the control bits */ - u8 start_id; /* start id of this range */ - u8 num_ids; /* number of devices in this range */ - u8 enable_only; /* bits are write-once to enable only */ - u8 enable; /* value used to enable device */ - u8 disable; /* value used to disable device */ - u8 shift; /* starting (rightmost) bit in range */ - u8 nbits; /* number of bits per device */ -}; - - -/* - * This describes a region of status bits indicating the state of - * various devices. This is used internally to wait for status - * change completion when enabling/disabling a device. Status is - * optional and not all device controls will have a corresponding - * status. - */ -struct devstate_stat_reg { - u32 reg; /* register holding the status bits */ - u8 start_id; /* start id of this range */ - u8 num_ids; /* number of devices in this range */ - u8 enable; /* value indicating enabled state */ - u8 disable; /* value indicating disabled state */ - u8 shift; /* starting (rightmost) bit in range */ - u8 nbits; /* number of bits per device */ -}; - -struct devstate_info { - struct devstate_ctl_reg *ctl; - struct devstate_stat_reg *stat; -}; - -/* These are callbacks to SOC-specific code. */ -struct dscr_ops { - void (*init)(struct device_node *node); -}; - -struct dscr_regs { - spinlock_t lock; - void __iomem *base; - u32 kick_reg[2]; - u32 kick_key[2]; - struct locked_reg locked[MAX_LOCKED_REGS]; - struct devstate_info devstate_info[MAX_DEVSTATE_IDS]; - struct rmii_reset_reg rmii_resets[MAX_SOC_EMACS]; - struct devstate_ctl_reg devctl[MAX_DEVCTL_REGS]; - struct devstate_stat_reg devstat[MAX_DEVSTAT_REGS]; -}; - -static struct dscr_regs dscr; - -static struct locked_reg *find_locked_reg(u32 reg) -{ - int i; - - for (i = 0; i < MAX_LOCKED_REGS; i++) - if (dscr.locked[i].key && reg == dscr.locked[i].reg) - return &dscr.locked[i]; - return NULL; -} - -/* - * Write to a register with one lock - */ -static void dscr_write_locked1(u32 reg, u32 val, - u32 lock, u32 key) -{ - void __iomem *reg_addr = dscr.base + reg; - void __iomem *lock_addr = dscr.base + lock; - - /* - * For some registers, the lock is relocked after a short number - * of cycles. We have to put the lock write and register write in - * the same fetch packet to meet this timing. The .align ensures - * the two stw instructions are in the same fetch packet. - */ - asm volatile ("b .s2 0f\n" - "nop 5\n" - " .align 5\n" - "0:\n" - "stw .D1T2 %3,*%2\n" - "stw .D1T2 %1,*%0\n" - : - : "a"(reg_addr), "b"(val), "a"(lock_addr), "b"(key) - ); - - /* in case the hw doesn't reset the lock */ - soc_writel(0, lock_addr); -} - -/* - * Write to a register protected by two lock registers - */ -static void dscr_write_locked2(u32 reg, u32 val, - u32 lock0, u32 key0, - u32 lock1, u32 key1) -{ - soc_writel(key0, dscr.base + lock0); - soc_writel(key1, dscr.base + lock1); - soc_writel(val, dscr.base + reg); - soc_writel(0, dscr.base + lock0); - soc_writel(0, dscr.base + lock1); -} - -static void dscr_write(u32 reg, u32 val) -{ - struct locked_reg *lock; - - lock = find_locked_reg(reg); - if (lock) - dscr_write_locked1(reg, val, lock->lockreg, lock->key); - else if (dscr.kick_key[0]) - dscr_write_locked2(reg, val, dscr.kick_reg[0], dscr.kick_key[0], - dscr.kick_reg[1], dscr.kick_key[1]); - else - soc_writel(val, dscr.base + reg); -} - - -/* - * Drivers can use this interface to enable/disable SoC IP blocks. - */ -void dscr_set_devstate(int id, enum dscr_devstate_t state) -{ - struct devstate_ctl_reg *ctl; - struct devstate_stat_reg *stat; - struct devstate_info *info; - u32 ctl_val, val; - int ctl_shift, ctl_mask; - unsigned long flags; - - if (!dscr.base) - return; - - if (id < 0 || id >= MAX_DEVSTATE_IDS) - return; - - info = &dscr.devstate_info[id]; - ctl = info->ctl; - stat = info->stat; - - if (ctl == NULL) - return; - - ctl_shift = ctl->shift + ctl->nbits * (id - ctl->start_id); - ctl_mask = ((1 << ctl->nbits) - 1) << ctl_shift; - - switch (state) { - case DSCR_DEVSTATE_ENABLED: - ctl_val = ctl->enable << ctl_shift; - break; - case DSCR_DEVSTATE_DISABLED: - if (ctl->enable_only) - return; - ctl_val = ctl->disable << ctl_shift; - break; - default: - return; - } - - spin_lock_irqsave(&dscr.lock, flags); - - val = soc_readl(dscr.base + ctl->reg); - val &= ~ctl_mask; - val |= ctl_val; - - dscr_write(ctl->reg, val); - - spin_unlock_irqrestore(&dscr.lock, flags); - - if (!stat) - return; - - ctl_shift = stat->shift + stat->nbits * (id - stat->start_id); - - if (state == DSCR_DEVSTATE_ENABLED) - ctl_val = stat->enable; - else - ctl_val = stat->disable; - - do { - val = soc_readl(dscr.base + stat->reg); - val >>= ctl_shift; - val &= ((1 << stat->nbits) - 1); - } while (val != ctl_val); -} -EXPORT_SYMBOL(dscr_set_devstate); - -/* - * Drivers can use this to reset RMII module. - */ -void dscr_rmii_reset(int id, int assert) -{ - struct rmii_reset_reg *r; - unsigned long flags; - u32 val; - - if (id < 0 || id >= MAX_SOC_EMACS) - return; - - r = &dscr.rmii_resets[id]; - if (r->mask == 0) - return; - - spin_lock_irqsave(&dscr.lock, flags); - - val = soc_readl(dscr.base + r->reg); - if (assert) - dscr_write(r->reg, val | r->mask); - else - dscr_write(r->reg, val & ~(r->mask)); - - spin_unlock_irqrestore(&dscr.lock, flags); -} -EXPORT_SYMBOL(dscr_rmii_reset); - -static void __init dscr_parse_devstat(struct device_node *node, - void __iomem *base) -{ - u32 val; - int err; - - err = of_property_read_u32_array(node, "ti,dscr-devstat", &val, 1); - if (!err) - c6x_devstat = soc_readl(base + val); - printk(KERN_INFO "DEVSTAT: %08x\n", c6x_devstat); -} - -static void __init dscr_parse_silicon_rev(struct device_node *node, - void __iomem *base) -{ - u32 vals[3]; - int err; - - err = of_property_read_u32_array(node, "ti,dscr-silicon-rev", vals, 3); - if (!err) { - c6x_silicon_rev = soc_readl(base + vals[0]); - c6x_silicon_rev >>= vals[1]; - c6x_silicon_rev &= vals[2]; - } -} - -/* - * Some SoCs will have a pair of fuse registers which hold - * an ethernet MAC address. The "ti,dscr-mac-fuse-regs" - * property is a mapping from fuse register bytes to MAC - * address bytes. The expected format is: - * - * ti,dscr-mac-fuse-regs = - * - * reg0 and reg1 are the offsets of the two fuse registers. - * b3-b0 positionally represent bytes within the fuse register. - * b3 is the most significant byte and b0 is the least. - * Allowable values for b3-b0 are: - * - * 0 = fuse register byte not used in MAC address - * 1-6 = index+1 into c6x_fuse_mac[] - */ -static void __init dscr_parse_mac_fuse(struct device_node *node, - void __iomem *base) -{ - u32 vals[10], fuse; - int f, i, j, err; - - err = of_property_read_u32_array(node, "ti,dscr-mac-fuse-regs", - vals, 10); - if (err) - return; - - for (f = 0; f < 2; f++) { - fuse = soc_readl(base + vals[f * 5]); - for (j = (f * 5) + 1, i = 24; i >= 0; i -= 8, j++) - if (vals[j] && vals[j] <= 6) - c6x_fuse_mac[vals[j] - 1] = fuse >> i; - } -} - -static void __init dscr_parse_rmii_resets(struct device_node *node, - void __iomem *base) -{ - const __be32 *p; - int i, size; - - /* look for RMII reset registers */ - p = of_get_property(node, "ti,dscr-rmii-resets", &size); - if (p) { - /* parse all the reg/mask pairs we can handle */ - size /= (sizeof(*p) * 2); - if (size > MAX_SOC_EMACS) - size = MAX_SOC_EMACS; - - for (i = 0; i < size; i++) { - dscr.rmii_resets[i].reg = be32_to_cpup(p++); - dscr.rmii_resets[i].mask = be32_to_cpup(p++); - } - } -} - - -static void __init dscr_parse_privperm(struct device_node *node, - void __iomem *base) -{ - u32 vals[2]; - int err; - - err = of_property_read_u32_array(node, "ti,dscr-privperm", vals, 2); - if (err) - return; - dscr_write(vals[0], vals[1]); -} - -/* - * SoCs may have "locked" DSCR registers which can only be written - * to only after writing a key value to a lock registers. These - * regisers can be described with the "ti,dscr-locked-regs" property. - * This property provides a list of register descriptions with each - * description consisting of three values. - * - * ti,dscr-locked-regs = ; - * - * reg is the offset of the locked register - * lockreg is the offset of the lock register - * key is the unlock key written to lockreg - * - */ -static void __init dscr_parse_locked_regs(struct device_node *node, - void __iomem *base) -{ - struct locked_reg *r; - const __be32 *p; - int i, size; - - p = of_get_property(node, "ti,dscr-locked-regs", &size); - if (p) { - /* parse all the register descriptions we can handle */ - size /= (sizeof(*p) * 3); - if (size > MAX_LOCKED_REGS) - size = MAX_LOCKED_REGS; - - for (i = 0; i < size; i++) { - r = &dscr.locked[i]; - - r->reg = be32_to_cpup(p++); - r->lockreg = be32_to_cpup(p++); - r->key = be32_to_cpup(p++); - } - } -} - -/* - * SoCs may have DSCR registers which are only write enabled after - * writing specific key values to two registers. The two key registers - * and the key values can be parsed from a "ti,dscr-kick-regs" - * propety with the following layout: - * - * ti,dscr-kick-regs = - * - * kickreg is the offset of the "kick" register - * key is the value which unlocks writing for protected regs - */ -static void __init dscr_parse_kick_regs(struct device_node *node, - void __iomem *base) -{ - u32 vals[4]; - int err; - - err = of_property_read_u32_array(node, "ti,dscr-kick-regs", vals, 4); - if (!err) { - dscr.kick_reg[0] = vals[0]; - dscr.kick_key[0] = vals[1]; - dscr.kick_reg[1] = vals[2]; - dscr.kick_key[1] = vals[3]; - } -} - - -/* - * SoCs may provide controls to enable/disable individual IP blocks. These - * controls in the DSCR usually control pin drivers but also may control - * clocking and or resets. The device tree is used to describe the bitfields - * in registers used to control device state. The number of bits and their - * values may vary even within the same register. - * - * The layout of these bitfields is described by the ti,dscr-devstate-ctl-regs - * property. This property is a list where each element describes a contiguous - * range of control fields with like properties. Each element of the list - * consists of 7 cells with the following values: - * - * start_id num_ids reg enable disable start_bit nbits - * - * start_id is device id for the first device control in the range - * num_ids is the number of device controls in the range - * reg is the offset of the register holding the control bits - * enable is the value to enable a device - * disable is the value to disable a device (0xffffffff if cannot disable) - * start_bit is the bit number of the first bit in the range - * nbits is the number of bits per device control - */ -static void __init dscr_parse_devstate_ctl_regs(struct device_node *node, - void __iomem *base) -{ - struct devstate_ctl_reg *r; - const __be32 *p; - int i, j, size; - - p = of_get_property(node, "ti,dscr-devstate-ctl-regs", &size); - if (p) { - /* parse all the ranges we can handle */ - size /= (sizeof(*p) * 7); - if (size > MAX_DEVCTL_REGS) - size = MAX_DEVCTL_REGS; - - for (i = 0; i < size; i++) { - r = &dscr.devctl[i]; - - r->start_id = be32_to_cpup(p++); - r->num_ids = be32_to_cpup(p++); - r->reg = be32_to_cpup(p++); - r->enable = be32_to_cpup(p++); - r->disable = be32_to_cpup(p++); - if (r->disable == 0xffffffff) - r->enable_only = 1; - r->shift = be32_to_cpup(p++); - r->nbits = be32_to_cpup(p++); - - for (j = r->start_id; - j < (r->start_id + r->num_ids); - j++) - dscr.devstate_info[j].ctl = r; - } - } -} - -/* - * SoCs may provide status registers indicating the state (enabled/disabled) of - * devices on the SoC. The device tree is used to describe the bitfields in - * registers used to provide device status. The number of bits and their - * values used to provide status may vary even within the same register. - * - * The layout of these bitfields is described by the ti,dscr-devstate-stat-regs - * property. This property is a list where each element describes a contiguous - * range of status fields with like properties. Each element of the list - * consists of 7 cells with the following values: - * - * start_id num_ids reg enable disable start_bit nbits - * - * start_id is device id for the first device status in the range - * num_ids is the number of devices covered by the range - * reg is the offset of the register holding the status bits - * enable is the value indicating device is enabled - * disable is the value indicating device is disabled - * start_bit is the bit number of the first bit in the range - * nbits is the number of bits per device status - */ -static void __init dscr_parse_devstate_stat_regs(struct device_node *node, - void __iomem *base) -{ - struct devstate_stat_reg *r; - const __be32 *p; - int i, j, size; - - p = of_get_property(node, "ti,dscr-devstate-stat-regs", &size); - if (p) { - /* parse all the ranges we can handle */ - size /= (sizeof(*p) * 7); - if (size > MAX_DEVSTAT_REGS) - size = MAX_DEVSTAT_REGS; - - for (i = 0; i < size; i++) { - r = &dscr.devstat[i]; - - r->start_id = be32_to_cpup(p++); - r->num_ids = be32_to_cpup(p++); - r->reg = be32_to_cpup(p++); - r->enable = be32_to_cpup(p++); - r->disable = be32_to_cpup(p++); - r->shift = be32_to_cpup(p++); - r->nbits = be32_to_cpup(p++); - - for (j = r->start_id; - j < (r->start_id + r->num_ids); - j++) - dscr.devstate_info[j].stat = r; - } - } -} - -static struct of_device_id dscr_ids[] __initdata = { - { .compatible = "ti,c64x+dscr" }, - {} -}; - -/* - * Probe for DSCR area. - * - * This has to be done early on in case timer or interrupt controller - * needs something. e.g. On C6455 SoC, timer must be enabled through - * DSCR before it is functional. - */ -void __init dscr_probe(void) -{ - struct device_node *node; - void __iomem *base; - - spin_lock_init(&dscr.lock); - - node = of_find_matching_node(NULL, dscr_ids); - if (!node) - return; - - base = of_iomap(node, 0); - if (!base) { - of_node_put(node); - return; - } - - dscr.base = base; - - dscr_parse_devstat(node, base); - dscr_parse_silicon_rev(node, base); - dscr_parse_mac_fuse(node, base); - dscr_parse_rmii_resets(node, base); - dscr_parse_locked_regs(node, base); - dscr_parse_kick_regs(node, base); - dscr_parse_devstate_ctl_regs(node, base); - dscr_parse_devstate_stat_regs(node, base); - dscr_parse_privperm(node, base); -} diff --git a/arch/c6x/platforms/emif.c b/arch/c6x/platforms/emif.c deleted file mode 100644 index 6142ecc2cd88..000000000000 --- a/arch/c6x/platforms/emif.c +++ /dev/null @@ -1,84 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * External Memory Interface - * - * Copyright (C) 2011 Texas Instruments Incorporated - * Author: Mark Salter - */ -#include -#include -#include -#include -#include - -#define NUM_EMIFA_CHIP_ENABLES 4 - -struct emifa_regs { - u32 midr; - u32 stat; - u32 reserved1[6]; - u32 bprio; - u32 reserved2[23]; - u32 cecfg[NUM_EMIFA_CHIP_ENABLES]; - u32 reserved3[4]; - u32 awcc; - u32 reserved4[7]; - u32 intraw; - u32 intmsk; - u32 intmskset; - u32 intmskclr; -}; - -static struct of_device_id emifa_match[] __initdata = { - { .compatible = "ti,c64x+emifa" }, - {} -}; - -/* - * Parse device tree for existence of an EMIF (External Memory Interface) - * and initialize it if found. - */ -static int __init c6x_emifa_init(void) -{ - struct emifa_regs __iomem *regs; - struct device_node *node; - const __be32 *p; - u32 val; - int i, len, err; - - node = of_find_matching_node(NULL, emifa_match); - if (!node) - return 0; - - regs = of_iomap(node, 0); - if (!regs) - return 0; - - /* look for a dscr-based enable for emifa pin buffers */ - err = of_property_read_u32_array(node, "ti,dscr-dev-enable", &val, 1); - if (!err) - dscr_set_devstate(val, DSCR_DEVSTATE_ENABLED); - - /* set up the chip enables */ - p = of_get_property(node, "ti,emifa-ce-config", &len); - if (p) { - len /= sizeof(u32); - if (len > NUM_EMIFA_CHIP_ENABLES) - len = NUM_EMIFA_CHIP_ENABLES; - for (i = 0; i <= len; i++) - soc_writel(be32_to_cpup(&p[i]), ®s->cecfg[i]); - } - - err = of_property_read_u32_array(node, "ti,emifa-burst-priority", &val, 1); - if (!err) - soc_writel(val, ®s->bprio); - - err = of_property_read_u32_array(node, "ti,emifa-async-wait-control", &val, 1); - if (!err) - soc_writel(val, ®s->awcc); - - iounmap(regs); - of_node_put(node); - return 0; -} -pure_initcall(c6x_emifa_init); diff --git a/arch/c6x/platforms/megamod-pic.c b/arch/c6x/platforms/megamod-pic.c deleted file mode 100644 index 56189e50728c..000000000000 --- a/arch/c6x/platforms/megamod-pic.c +++ /dev/null @@ -1,344 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Support for C64x+ Megamodule Interrupt Controller - * - * Copyright (C) 2010, 2011 Texas Instruments Incorporated - * Contributed by: Mark Salter - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define NR_COMBINERS 4 -#define NR_MUX_OUTPUTS 12 - -#define IRQ_UNMAPPED 0xffff - -/* - * Megamodule Interrupt Controller register layout - */ -struct megamod_regs { - u32 evtflag[8]; - u32 evtset[8]; - u32 evtclr[8]; - u32 reserved0[8]; - u32 evtmask[8]; - u32 mevtflag[8]; - u32 expmask[8]; - u32 mexpflag[8]; - u32 intmux_unused; - u32 intmux[7]; - u32 reserved1[8]; - u32 aegmux[2]; - u32 reserved2[14]; - u32 intxstat; - u32 intxclr; - u32 intdmask; - u32 reserved3[13]; - u32 evtasrt; -}; - -struct megamod_pic { - struct irq_domain *irqhost; - struct megamod_regs __iomem *regs; - raw_spinlock_t lock; - - /* hw mux mapping */ - unsigned int output_to_irq[NR_MUX_OUTPUTS]; -}; - -static struct megamod_pic *mm_pic; - -struct megamod_cascade_data { - struct megamod_pic *pic; - int index; -}; - -static struct megamod_cascade_data cascade_data[NR_COMBINERS]; - -static void mask_megamod(struct irq_data *data) -{ - struct megamod_pic *pic = irq_data_get_irq_chip_data(data); - irq_hw_number_t src = irqd_to_hwirq(data); - u32 __iomem *evtmask = &pic->regs->evtmask[src / 32]; - - raw_spin_lock(&pic->lock); - soc_writel(soc_readl(evtmask) | (1 << (src & 31)), evtmask); - raw_spin_unlock(&pic->lock); -} - -static void unmask_megamod(struct irq_data *data) -{ - struct megamod_pic *pic = irq_data_get_irq_chip_data(data); - irq_hw_number_t src = irqd_to_hwirq(data); - u32 __iomem *evtmask = &pic->regs->evtmask[src / 32]; - - raw_spin_lock(&pic->lock); - soc_writel(soc_readl(evtmask) & ~(1 << (src & 31)), evtmask); - raw_spin_unlock(&pic->lock); -} - -static struct irq_chip megamod_chip = { - .name = "megamod", - .irq_mask = mask_megamod, - .irq_unmask = unmask_megamod, -}; - -static void megamod_irq_cascade(struct irq_desc *desc) -{ - struct megamod_cascade_data *cascade; - struct megamod_pic *pic; - unsigned int irq; - u32 events; - int n, idx; - - cascade = irq_desc_get_handler_data(desc); - - pic = cascade->pic; - idx = cascade->index; - - while ((events = soc_readl(&pic->regs->mevtflag[idx])) != 0) { - n = __ffs(events); - - irq = irq_linear_revmap(pic->irqhost, idx * 32 + n); - - soc_writel(1 << n, &pic->regs->evtclr[idx]); - - generic_handle_irq(irq); - } -} - -static int megamod_map(struct irq_domain *h, unsigned int virq, - irq_hw_number_t hw) -{ - struct megamod_pic *pic = h->host_data; - int i; - - /* We shouldn't see a hwirq which is muxed to core controller */ - for (i = 0; i < NR_MUX_OUTPUTS; i++) - if (pic->output_to_irq[i] == hw) - return -1; - - irq_set_chip_data(virq, pic); - irq_set_chip_and_handler(virq, &megamod_chip, handle_level_irq); - - /* Set default irq type */ - irq_set_irq_type(virq, IRQ_TYPE_NONE); - - return 0; -} - -static const struct irq_domain_ops megamod_domain_ops = { - .map = megamod_map, - .xlate = irq_domain_xlate_onecell, -}; - -static void __init set_megamod_mux(struct megamod_pic *pic, int src, int output) -{ - int index, offset; - u32 val; - - if (src < 0 || src >= (NR_COMBINERS * 32)) { - pic->output_to_irq[output] = IRQ_UNMAPPED; - return; - } - - /* four mappings per mux register */ - index = output / 4; - offset = (output & 3) * 8; - - val = soc_readl(&pic->regs->intmux[index]); - val &= ~(0xff << offset); - val |= src << offset; - soc_writel(val, &pic->regs->intmux[index]); -} - -/* - * Parse the MUX mapping, if one exists. - * - * The MUX map is an array of up to 12 cells; one for each usable core priority - * interrupt. The value of a given cell is the megamodule interrupt source - * which is to me MUXed to the output corresponding to the cell position - * withing the array. The first cell in the array corresponds to priority - * 4 and the last (12th) cell corresponds to priority 15. The allowed - * values are 4 - ((NR_COMBINERS * 32) - 1). Note that the combined interrupt - * sources (0 - 3) are not allowed to be mapped through this property. They - * are handled through the "interrupts" property. This allows us to use a - * value of zero as a "do not map" placeholder. - */ -static void __init parse_priority_map(struct megamod_pic *pic, - int *mapping, int size) -{ - struct device_node *np = irq_domain_get_of_node(pic->irqhost); - const __be32 *map; - int i, maplen; - u32 val; - - map = of_get_property(np, "ti,c64x+megamod-pic-mux", &maplen); - if (map) { - maplen /= 4; - if (maplen > size) - maplen = size; - - for (i = 0; i < maplen; i++) { - val = be32_to_cpup(map); - if (val && val >= 4) - mapping[i] = val; - ++map; - } - } -} - -static struct megamod_pic * __init init_megamod_pic(struct device_node *np) -{ - struct megamod_pic *pic; - int i, irq; - int mapping[NR_MUX_OUTPUTS]; - - pr_info("Initializing C64x+ Megamodule PIC\n"); - - pic = kzalloc(sizeof(struct megamod_pic), GFP_KERNEL); - if (!pic) { - pr_err("%pOF: Could not alloc PIC structure.\n", np); - return NULL; - } - - pic->irqhost = irq_domain_add_linear(np, NR_COMBINERS * 32, - &megamod_domain_ops, pic); - if (!pic->irqhost) { - pr_err("%pOF: Could not alloc host.\n", np); - goto error_free; - } - - pic->irqhost->host_data = pic; - - raw_spin_lock_init(&pic->lock); - - pic->regs = of_iomap(np, 0); - if (!pic->regs) { - pr_err("%pOF: Could not map registers.\n", np); - goto error_free; - } - - /* Initialize MUX map */ - for (i = 0; i < ARRAY_SIZE(mapping); i++) - mapping[i] = IRQ_UNMAPPED; - - parse_priority_map(pic, mapping, ARRAY_SIZE(mapping)); - - /* - * We can have up to 12 interrupts cascading to the core controller. - * These cascades can be from the combined interrupt sources or for - * individual interrupt sources. The "interrupts" property only - * deals with the cascaded combined interrupts. The individual - * interrupts muxed to the core controller use the core controller - * as their interrupt parent. - */ - for (i = 0; i < NR_COMBINERS; i++) { - struct irq_data *irq_data; - irq_hw_number_t hwirq; - - irq = irq_of_parse_and_map(np, i); - if (irq == NO_IRQ) - continue; - - irq_data = irq_get_irq_data(irq); - if (!irq_data) { - pr_err("%pOF: combiner-%d no irq_data for virq %d!\n", - np, i, irq); - continue; - } - - hwirq = irq_data->hwirq; - - /* - * Check that device tree provided something in the range - * of the core priority interrupts (4 - 15). - */ - if (hwirq < 4 || hwirq >= NR_PRIORITY_IRQS) { - pr_err("%pOF: combiner-%d core irq %ld out of range!\n", - np, i, hwirq); - continue; - } - - /* record the mapping */ - mapping[hwirq - 4] = i; - - pr_debug("%pOF: combiner-%d cascading to hwirq %ld\n", - np, i, hwirq); - - cascade_data[i].pic = pic; - cascade_data[i].index = i; - - /* mask and clear all events in combiner */ - soc_writel(~0, &pic->regs->evtmask[i]); - soc_writel(~0, &pic->regs->evtclr[i]); - - irq_set_chained_handler_and_data(irq, megamod_irq_cascade, - &cascade_data[i]); - } - - /* Finally, set up the MUX registers */ - for (i = 0; i < NR_MUX_OUTPUTS; i++) { - if (mapping[i] != IRQ_UNMAPPED) { - pr_debug("%pOF: setting mux %d to priority %d\n", - np, mapping[i], i + 4); - set_megamod_mux(pic, mapping[i], i); - } - } - - return pic; - -error_free: - kfree(pic); - - return NULL; -} - -/* - * Return next active event after ACK'ing it. - * Return -1 if no events active. - */ -static int get_exception(void) -{ - int i, bit; - u32 mask; - - for (i = 0; i < NR_COMBINERS; i++) { - mask = soc_readl(&mm_pic->regs->mexpflag[i]); - if (mask) { - bit = __ffs(mask); - soc_writel(1 << bit, &mm_pic->regs->evtclr[i]); - return (i * 32) + bit; - } - } - return -1; -} - -static void assert_event(unsigned int val) -{ - soc_writel(val, &mm_pic->regs->evtasrt); -} - -void __init megamod_pic_init(void) -{ - struct device_node *np; - - np = of_find_compatible_node(NULL, NULL, "ti,c64x+megamod-pic"); - if (!np) - return; - - mm_pic = init_megamod_pic(np); - of_node_put(np); - - soc_ops.get_exception = get_exception; - soc_ops.assert_event = assert_event; - - return; -} diff --git a/arch/c6x/platforms/pll.c b/arch/c6x/platforms/pll.c deleted file mode 100644 index 6fdf20d64dc7..000000000000 --- a/arch/c6x/platforms/pll.c +++ /dev/null @@ -1,440 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * Clock and PLL control for C64x+ devices - * - * Copyright (C) 2010, 2011 Texas Instruments. - * Contributed by: Mark Salter - * - * Copied heavily from arm/mach-davinci/clock.c, so: - * - * Copyright (C) 2006-2007 Texas Instruments. - * Copyright (C) 2008-2009 Deep Root Systems, LLC - */ - -#include -#include -#include -#include -#include - -#include -#include - -static LIST_HEAD(clocks); -static DEFINE_MUTEX(clocks_mutex); -static DEFINE_SPINLOCK(clockfw_lock); - -static void __clk_enable(struct clk *clk) -{ - if (clk->parent) - __clk_enable(clk->parent); - clk->usecount++; -} - -static void __clk_disable(struct clk *clk) -{ - if (WARN_ON(clk->usecount == 0)) - return; - --clk->usecount; - - if (clk->parent) - __clk_disable(clk->parent); -} - -int clk_enable(struct clk *clk) -{ - unsigned long flags; - - if (clk == NULL || IS_ERR(clk)) - return -EINVAL; - - spin_lock_irqsave(&clockfw_lock, flags); - __clk_enable(clk); - spin_unlock_irqrestore(&clockfw_lock, flags); - - return 0; -} -EXPORT_SYMBOL(clk_enable); - -void clk_disable(struct clk *clk) -{ - unsigned long flags; - - if (clk == NULL || IS_ERR(clk)) - return; - - spin_lock_irqsave(&clockfw_lock, flags); - __clk_disable(clk); - spin_unlock_irqrestore(&clockfw_lock, flags); -} -EXPORT_SYMBOL(clk_disable); - -unsigned long clk_get_rate(struct clk *clk) -{ - if (clk == NULL || IS_ERR(clk)) - return -EINVAL; - - return clk->rate; -} -EXPORT_SYMBOL(clk_get_rate); - -long clk_round_rate(struct clk *clk, unsigned long rate) -{ - if (clk == NULL || IS_ERR(clk)) - return -EINVAL; - - if (clk->round_rate) - return clk->round_rate(clk, rate); - - return clk->rate; -} -EXPORT_SYMBOL(clk_round_rate); - -/* Propagate rate to children */ -static void propagate_rate(struct clk *root) -{ - struct clk *clk; - - list_for_each_entry(clk, &root->children, childnode) { - if (clk->recalc) - clk->rate = clk->recalc(clk); - propagate_rate(clk); - } -} - -int clk_set_rate(struct clk *clk, unsigned long rate) -{ - unsigned long flags; - int ret = -EINVAL; - - if (clk == NULL || IS_ERR(clk)) - return ret; - - if (clk->set_rate) - ret = clk->set_rate(clk, rate); - - spin_lock_irqsave(&clockfw_lock, flags); - if (ret == 0) { - if (clk->recalc) - clk->rate = clk->recalc(clk); - propagate_rate(clk); - } - spin_unlock_irqrestore(&clockfw_lock, flags); - - return ret; -} -EXPORT_SYMBOL(clk_set_rate); - -int clk_set_parent(struct clk *clk, struct clk *parent) -{ - unsigned long flags; - - if (clk == NULL || IS_ERR(clk)) - return -EINVAL; - - /* Cannot change parent on enabled clock */ - if (WARN_ON(clk->usecount)) - return -EINVAL; - - mutex_lock(&clocks_mutex); - clk->parent = parent; - list_del_init(&clk->childnode); - list_add(&clk->childnode, &clk->parent->children); - mutex_unlock(&clocks_mutex); - - spin_lock_irqsave(&clockfw_lock, flags); - if (clk->recalc) - clk->rate = clk->recalc(clk); - propagate_rate(clk); - spin_unlock_irqrestore(&clockfw_lock, flags); - - return 0; -} -EXPORT_SYMBOL(clk_set_parent); - -int clk_register(struct clk *clk) -{ - if (clk == NULL || IS_ERR(clk)) - return -EINVAL; - - if (WARN(clk->parent && !clk->parent->rate, - "CLK: %s parent %s has no rate!\n", - clk->name, clk->parent->name)) - return -EINVAL; - - mutex_lock(&clocks_mutex); - list_add_tail(&clk->node, &clocks); - if (clk->parent) - list_add_tail(&clk->childnode, &clk->parent->children); - mutex_unlock(&clocks_mutex); - - /* If rate is already set, use it */ - if (clk->rate) - return 0; - - /* Else, see if there is a way to calculate it */ - if (clk->recalc) - clk->rate = clk->recalc(clk); - - /* Otherwise, default to parent rate */ - else if (clk->parent) - clk->rate = clk->parent->rate; - - return 0; -} -EXPORT_SYMBOL(clk_register); - -void clk_unregister(struct clk *clk) -{ - if (clk == NULL || IS_ERR(clk)) - return; - - mutex_lock(&clocks_mutex); - list_del(&clk->node); - list_del(&clk->childnode); - mutex_unlock(&clocks_mutex); -} -EXPORT_SYMBOL(clk_unregister); - - -static u32 pll_read(struct pll_data *pll, int reg) -{ - return soc_readl(pll->base + reg); -} - -static unsigned long clk_sysclk_recalc(struct clk *clk) -{ - u32 v, plldiv = 0; - struct pll_data *pll; - unsigned long rate = clk->rate; - - if (WARN_ON(!clk->parent)) - return rate; - - rate = clk->parent->rate; - - /* the parent must be a PLL */ - if (WARN_ON(!clk->parent->pll_data)) - return rate; - - pll = clk->parent->pll_data; - - /* If pre-PLL, source clock is before the multiplier and divider(s) */ - if (clk->flags & PRE_PLL) - rate = pll->input_rate; - - if (!clk->div) { - pr_debug("%s: (no divider) rate = %lu KHz\n", - clk->name, rate / 1000); - return rate; - } - - if (clk->flags & FIXED_DIV_PLL) { - rate /= clk->div; - pr_debug("%s: (fixed divide by %d) rate = %lu KHz\n", - clk->name, clk->div, rate / 1000); - return rate; - } - - v = pll_read(pll, clk->div); - if (v & PLLDIV_EN) - plldiv = (v & PLLDIV_RATIO_MASK) + 1; - - if (plldiv == 0) - plldiv = 1; - - rate /= plldiv; - - pr_debug("%s: (divide by %d) rate = %lu KHz\n", - clk->name, plldiv, rate / 1000); - - return rate; -} - -static unsigned long clk_leafclk_recalc(struct clk *clk) -{ - if (WARN_ON(!clk->parent)) - return clk->rate; - - pr_debug("%s: (parent %s) rate = %lu KHz\n", - clk->name, clk->parent->name, clk->parent->rate / 1000); - - return clk->parent->rate; -} - -static unsigned long clk_pllclk_recalc(struct clk *clk) -{ - u32 ctrl, mult = 0, prediv = 0, postdiv = 0; - u8 bypass; - struct pll_data *pll = clk->pll_data; - unsigned long rate = clk->rate; - - if (clk->flags & FIXED_RATE_PLL) - return rate; - - ctrl = pll_read(pll, PLLCTL); - rate = pll->input_rate = clk->parent->rate; - - if (ctrl & PLLCTL_PLLEN) - bypass = 0; - else - bypass = 1; - - if (pll->flags & PLL_HAS_MUL) { - mult = pll_read(pll, PLLM); - mult = (mult & PLLM_PLLM_MASK) + 1; - } - if (pll->flags & PLL_HAS_PRE) { - prediv = pll_read(pll, PLLPRE); - if (prediv & PLLDIV_EN) - prediv = (prediv & PLLDIV_RATIO_MASK) + 1; - else - prediv = 0; - } - if (pll->flags & PLL_HAS_POST) { - postdiv = pll_read(pll, PLLPOST); - if (postdiv & PLLDIV_EN) - postdiv = (postdiv & PLLDIV_RATIO_MASK) + 1; - else - postdiv = 1; - } - - if (!bypass) { - if (prediv) - rate /= prediv; - if (mult) - rate *= mult; - if (postdiv) - rate /= postdiv; - - pr_debug("PLL%d: input = %luMHz, pre[%d] mul[%d] post[%d] " - "--> %luMHz output.\n", - pll->num, clk->parent->rate / 1000000, - prediv, mult, postdiv, rate / 1000000); - } else - pr_debug("PLL%d: input = %luMHz, bypass mode.\n", - pll->num, clk->parent->rate / 1000000); - - return rate; -} - - -static void __init __init_clk(struct clk *clk) -{ - INIT_LIST_HEAD(&clk->node); - INIT_LIST_HEAD(&clk->children); - INIT_LIST_HEAD(&clk->childnode); - - if (!clk->recalc) { - - /* Check if clock is a PLL */ - if (clk->pll_data) - clk->recalc = clk_pllclk_recalc; - - /* Else, if it is a PLL-derived clock */ - else if (clk->flags & CLK_PLL) - clk->recalc = clk_sysclk_recalc; - - /* Otherwise, it is a leaf clock (PSC clock) */ - else if (clk->parent) - clk->recalc = clk_leafclk_recalc; - } -} - -void __init c6x_clks_init(struct clk_lookup *clocks) -{ - struct clk_lookup *c; - struct clk *clk; - size_t num_clocks = 0; - - for (c = clocks; c->clk; c++) { - clk = c->clk; - - __init_clk(clk); - clk_register(clk); - num_clocks++; - - /* Turn on clocks that Linux doesn't otherwise manage */ - if (clk->flags & ALWAYS_ENABLED) - clk_enable(clk); - } - - clkdev_add_table(clocks, num_clocks); -} - -#ifdef CONFIG_DEBUG_FS - -#include -#include - -#define CLKNAME_MAX 10 /* longest clock name */ -#define NEST_DELTA 2 -#define NEST_MAX 4 - -static void -dump_clock(struct seq_file *s, unsigned nest, struct clk *parent) -{ - char *state; - char buf[CLKNAME_MAX + NEST_DELTA * NEST_MAX]; - struct clk *clk; - unsigned i; - - if (parent->flags & CLK_PLL) - state = "pll"; - else - state = ""; - - /* name */ - memset(buf, ' ', sizeof(buf) - 1); - buf[sizeof(buf) - 1] = 0; - i = strlen(parent->name); - memcpy(buf + nest, parent->name, - min(i, (unsigned)(sizeof(buf) - 1 - nest))); - - seq_printf(s, "%s users=%2d %-3s %9ld Hz\n", - buf, parent->usecount, state, clk_get_rate(parent)); - /* REVISIT show device associations too */ - - /* cost is now small, but not linear... */ - list_for_each_entry(clk, &parent->children, childnode) { - dump_clock(s, nest + NEST_DELTA, clk); - } -} - -static int c6x_ck_show(struct seq_file *m, void *v) -{ - struct clk *clk; - - /* - * Show clock tree; We trust nonzero usecounts equate to PSC enables... - */ - mutex_lock(&clocks_mutex); - list_for_each_entry(clk, &clocks, node) - if (!clk->parent) - dump_clock(m, 0, clk); - mutex_unlock(&clocks_mutex); - - return 0; -} - -static int c6x_ck_open(struct inode *inode, struct file *file) -{ - return single_open(file, c6x_ck_show, NULL); -} - -static const struct file_operations c6x_ck_operations = { - .open = c6x_ck_open, - .read = seq_read, - .llseek = seq_lseek, - .release = single_release, -}; - -static int __init c6x_clk_debugfs_init(void) -{ - debugfs_create_file("c6x_clocks", S_IFREG | S_IRUGO, NULL, NULL, - &c6x_ck_operations); - - return 0; -} -device_initcall(c6x_clk_debugfs_init); -#endif /* CONFIG_DEBUG_FS */ diff --git a/arch/c6x/platforms/plldata.c b/arch/c6x/platforms/plldata.c deleted file mode 100644 index a799e04edefe..000000000000 --- a/arch/c6x/platforms/plldata.c +++ /dev/null @@ -1,467 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Port on Texas Instruments TMS320C6x architecture - * - * Copyright (C) 2011 Texas Instruments Incorporated - * Author: Mark Salter - */ -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -/* - * Common SoC clock support. - */ - -/* Default input for PLL1 */ -struct clk clkin1 = { - .name = "clkin1", - .node = LIST_HEAD_INIT(clkin1.node), - .children = LIST_HEAD_INIT(clkin1.children), - .childnode = LIST_HEAD_INIT(clkin1.childnode), -}; - -struct pll_data c6x_soc_pll1 = { - .num = 1, - .sysclks = { - { - .name = "pll1", - .parent = &clkin1, - .pll_data = &c6x_soc_pll1, - .flags = CLK_PLL, - }, - { - .name = "pll1_sysclk1", - .parent = &c6x_soc_pll1.sysclks[0], - .flags = CLK_PLL, - }, - { - .name = "pll1_sysclk2", - .parent = &c6x_soc_pll1.sysclks[0], - .flags = CLK_PLL, - }, - { - .name = "pll1_sysclk3", - .parent = &c6x_soc_pll1.sysclks[0], - .flags = CLK_PLL, - }, - { - .name = "pll1_sysclk4", - .parent = &c6x_soc_pll1.sysclks[0], - .flags = CLK_PLL, - }, - { - .name = "pll1_sysclk5", - .parent = &c6x_soc_pll1.sysclks[0], - .flags = CLK_PLL, - }, - { - .name = "pll1_sysclk6", - .parent = &c6x_soc_pll1.sysclks[0], - .flags = CLK_PLL, - }, - { - .name = "pll1_sysclk7", - .parent = &c6x_soc_pll1.sysclks[0], - .flags = CLK_PLL, - }, - { - .name = "pll1_sysclk8", - .parent = &c6x_soc_pll1.sysclks[0], - .flags = CLK_PLL, - }, - { - .name = "pll1_sysclk9", - .parent = &c6x_soc_pll1.sysclks[0], - .flags = CLK_PLL, - }, - { - .name = "pll1_sysclk10", - .parent = &c6x_soc_pll1.sysclks[0], - .flags = CLK_PLL, - }, - { - .name = "pll1_sysclk11", - .parent = &c6x_soc_pll1.sysclks[0], - .flags = CLK_PLL, - }, - { - .name = "pll1_sysclk12", - .parent = &c6x_soc_pll1.sysclks[0], - .flags = CLK_PLL, - }, - { - .name = "pll1_sysclk13", - .parent = &c6x_soc_pll1.sysclks[0], - .flags = CLK_PLL, - }, - { - .name = "pll1_sysclk14", - .parent = &c6x_soc_pll1.sysclks[0], - .flags = CLK_PLL, - }, - { - .name = "pll1_sysclk15", - .parent = &c6x_soc_pll1.sysclks[0], - .flags = CLK_PLL, - }, - { - .name = "pll1_sysclk16", - .parent = &c6x_soc_pll1.sysclks[0], - .flags = CLK_PLL, - }, - }, -}; - -/* CPU core clock */ -struct clk c6x_core_clk = { - .name = "core", -}; - -/* miscellaneous IO clocks */ -struct clk c6x_i2c_clk = { - .name = "i2c", -}; - -struct clk c6x_watchdog_clk = { - .name = "watchdog", -}; - -struct clk c6x_mcbsp1_clk = { - .name = "mcbsp1", -}; - -struct clk c6x_mcbsp2_clk = { - .name = "mcbsp2", -}; - -struct clk c6x_mdio_clk = { - .name = "mdio", -}; - - -#ifdef CONFIG_SOC_TMS320C6455 -static struct clk_lookup c6455_clks[] = { - CLK(NULL, "pll1", &c6x_soc_pll1.sysclks[0]), - CLK(NULL, "pll1_sysclk2", &c6x_soc_pll1.sysclks[2]), - CLK(NULL, "pll1_sysclk3", &c6x_soc_pll1.sysclks[3]), - CLK(NULL, "pll1_sysclk4", &c6x_soc_pll1.sysclks[4]), - CLK(NULL, "pll1_sysclk5", &c6x_soc_pll1.sysclks[5]), - CLK(NULL, "core", &c6x_core_clk), - CLK("i2c_davinci.1", NULL, &c6x_i2c_clk), - CLK("watchdog", NULL, &c6x_watchdog_clk), - CLK("2c81800.mdio", NULL, &c6x_mdio_clk), - CLK("", NULL, NULL) -}; - - -static void __init c6455_setup_clocks(struct device_node *node) -{ - struct pll_data *pll = &c6x_soc_pll1; - struct clk *sysclks = pll->sysclks; - - pll->flags = PLL_HAS_PRE | PLL_HAS_MUL; - - sysclks[2].flags |= FIXED_DIV_PLL; - sysclks[2].div = 3; - sysclks[3].flags |= FIXED_DIV_PLL; - sysclks[3].div = 6; - sysclks[4].div = PLLDIV4; - sysclks[5].div = PLLDIV5; - - c6x_core_clk.parent = &sysclks[0]; - c6x_i2c_clk.parent = &sysclks[3]; - c6x_watchdog_clk.parent = &sysclks[3]; - c6x_mdio_clk.parent = &sysclks[3]; - - c6x_clks_init(c6455_clks); -} -#endif /* CONFIG_SOC_TMS320C6455 */ - -#ifdef CONFIG_SOC_TMS320C6457 -static struct clk_lookup c6457_clks[] = { - CLK(NULL, "pll1", &c6x_soc_pll1.sysclks[0]), - CLK(NULL, "pll1_sysclk1", &c6x_soc_pll1.sysclks[1]), - CLK(NULL, "pll1_sysclk2", &c6x_soc_pll1.sysclks[2]), - CLK(NULL, "pll1_sysclk3", &c6x_soc_pll1.sysclks[3]), - CLK(NULL, "pll1_sysclk4", &c6x_soc_pll1.sysclks[4]), - CLK(NULL, "pll1_sysclk5", &c6x_soc_pll1.sysclks[5]), - CLK(NULL, "core", &c6x_core_clk), - CLK("i2c_davinci.1", NULL, &c6x_i2c_clk), - CLK("watchdog", NULL, &c6x_watchdog_clk), - CLK("2c81800.mdio", NULL, &c6x_mdio_clk), - CLK("", NULL, NULL) -}; - -static void __init c6457_setup_clocks(struct device_node *node) -{ - struct pll_data *pll = &c6x_soc_pll1; - struct clk *sysclks = pll->sysclks; - - pll->flags = PLL_HAS_MUL | PLL_HAS_POST; - - sysclks[1].flags |= FIXED_DIV_PLL; - sysclks[1].div = 1; - sysclks[2].flags |= FIXED_DIV_PLL; - sysclks[2].div = 3; - sysclks[3].flags |= FIXED_DIV_PLL; - sysclks[3].div = 6; - sysclks[4].div = PLLDIV4; - sysclks[5].div = PLLDIV5; - - c6x_core_clk.parent = &sysclks[1]; - c6x_i2c_clk.parent = &sysclks[3]; - c6x_watchdog_clk.parent = &sysclks[5]; - c6x_mdio_clk.parent = &sysclks[5]; - - c6x_clks_init(c6457_clks); -} -#endif /* CONFIG_SOC_TMS320C6455 */ - -#ifdef CONFIG_SOC_TMS320C6472 -static struct clk_lookup c6472_clks[] = { - CLK(NULL, "pll1", &c6x_soc_pll1.sysclks[0]), - CLK(NULL, "pll1_sysclk1", &c6x_soc_pll1.sysclks[1]), - CLK(NULL, "pll1_sysclk2", &c6x_soc_pll1.sysclks[2]), - CLK(NULL, "pll1_sysclk3", &c6x_soc_pll1.sysclks[3]), - CLK(NULL, "pll1_sysclk4", &c6x_soc_pll1.sysclks[4]), - CLK(NULL, "pll1_sysclk5", &c6x_soc_pll1.sysclks[5]), - CLK(NULL, "pll1_sysclk6", &c6x_soc_pll1.sysclks[6]), - CLK(NULL, "pll1_sysclk7", &c6x_soc_pll1.sysclks[7]), - CLK(NULL, "pll1_sysclk8", &c6x_soc_pll1.sysclks[8]), - CLK(NULL, "pll1_sysclk9", &c6x_soc_pll1.sysclks[9]), - CLK(NULL, "pll1_sysclk10", &c6x_soc_pll1.sysclks[10]), - CLK(NULL, "core", &c6x_core_clk), - CLK("i2c_davinci.1", NULL, &c6x_i2c_clk), - CLK("watchdog", NULL, &c6x_watchdog_clk), - CLK("2c81800.mdio", NULL, &c6x_mdio_clk), - CLK("", NULL, NULL) -}; - -/* assumptions used for delay loop calculations */ -#define MIN_CLKIN1_KHz 15625 -#define MAX_CORE_KHz 700000 -#define MIN_PLLOUT_KHz MIN_CLKIN1_KHz - -static void __init c6472_setup_clocks(struct device_node *node) -{ - struct pll_data *pll = &c6x_soc_pll1; - struct clk *sysclks = pll->sysclks; - int i; - - pll->flags = PLL_HAS_MUL; - - for (i = 1; i <= 6; i++) { - sysclks[i].flags |= FIXED_DIV_PLL; - sysclks[i].div = 1; - } - - sysclks[7].flags |= FIXED_DIV_PLL; - sysclks[7].div = 3; - sysclks[8].flags |= FIXED_DIV_PLL; - sysclks[8].div = 6; - sysclks[9].flags |= FIXED_DIV_PLL; - sysclks[9].div = 2; - sysclks[10].div = PLLDIV10; - - c6x_core_clk.parent = &sysclks[get_coreid() + 1]; - c6x_i2c_clk.parent = &sysclks[8]; - c6x_watchdog_clk.parent = &sysclks[8]; - c6x_mdio_clk.parent = &sysclks[5]; - - c6x_clks_init(c6472_clks); -} -#endif /* CONFIG_SOC_TMS320C6472 */ - - -#ifdef CONFIG_SOC_TMS320C6474 -static struct clk_lookup c6474_clks[] = { - CLK(NULL, "pll1", &c6x_soc_pll1.sysclks[0]), - CLK(NULL, "pll1_sysclk7", &c6x_soc_pll1.sysclks[7]), - CLK(NULL, "pll1_sysclk9", &c6x_soc_pll1.sysclks[9]), - CLK(NULL, "pll1_sysclk10", &c6x_soc_pll1.sysclks[10]), - CLK(NULL, "pll1_sysclk11", &c6x_soc_pll1.sysclks[11]), - CLK(NULL, "pll1_sysclk12", &c6x_soc_pll1.sysclks[12]), - CLK(NULL, "pll1_sysclk13", &c6x_soc_pll1.sysclks[13]), - CLK(NULL, "core", &c6x_core_clk), - CLK("i2c_davinci.1", NULL, &c6x_i2c_clk), - CLK("mcbsp.1", NULL, &c6x_mcbsp1_clk), - CLK("mcbsp.2", NULL, &c6x_mcbsp2_clk), - CLK("watchdog", NULL, &c6x_watchdog_clk), - CLK("2c81800.mdio", NULL, &c6x_mdio_clk), - CLK("", NULL, NULL) -}; - -static void __init c6474_setup_clocks(struct device_node *node) -{ - struct pll_data *pll = &c6x_soc_pll1; - struct clk *sysclks = pll->sysclks; - - pll->flags = PLL_HAS_MUL; - - sysclks[7].flags |= FIXED_DIV_PLL; - sysclks[7].div = 1; - sysclks[9].flags |= FIXED_DIV_PLL; - sysclks[9].div = 3; - sysclks[10].flags |= FIXED_DIV_PLL; - sysclks[10].div = 6; - - sysclks[11].div = PLLDIV11; - - sysclks[12].flags |= FIXED_DIV_PLL; - sysclks[12].div = 2; - - sysclks[13].div = PLLDIV13; - - c6x_core_clk.parent = &sysclks[7]; - c6x_i2c_clk.parent = &sysclks[10]; - c6x_watchdog_clk.parent = &sysclks[10]; - c6x_mcbsp1_clk.parent = &sysclks[10]; - c6x_mcbsp2_clk.parent = &sysclks[10]; - - c6x_clks_init(c6474_clks); -} -#endif /* CONFIG_SOC_TMS320C6474 */ - -#ifdef CONFIG_SOC_TMS320C6678 -static struct clk_lookup c6678_clks[] = { - CLK(NULL, "pll1", &c6x_soc_pll1.sysclks[0]), - CLK(NULL, "pll1_refclk", &c6x_soc_pll1.sysclks[1]), - CLK(NULL, "pll1_sysclk2", &c6x_soc_pll1.sysclks[2]), - CLK(NULL, "pll1_sysclk3", &c6x_soc_pll1.sysclks[3]), - CLK(NULL, "pll1_sysclk4", &c6x_soc_pll1.sysclks[4]), - CLK(NULL, "pll1_sysclk5", &c6x_soc_pll1.sysclks[5]), - CLK(NULL, "pll1_sysclk6", &c6x_soc_pll1.sysclks[6]), - CLK(NULL, "pll1_sysclk7", &c6x_soc_pll1.sysclks[7]), - CLK(NULL, "pll1_sysclk8", &c6x_soc_pll1.sysclks[8]), - CLK(NULL, "pll1_sysclk9", &c6x_soc_pll1.sysclks[9]), - CLK(NULL, "pll1_sysclk10", &c6x_soc_pll1.sysclks[10]), - CLK(NULL, "pll1_sysclk11", &c6x_soc_pll1.sysclks[11]), - CLK(NULL, "core", &c6x_core_clk), - CLK("", NULL, NULL) -}; - -static void __init c6678_setup_clocks(struct device_node *node) -{ - struct pll_data *pll = &c6x_soc_pll1; - struct clk *sysclks = pll->sysclks; - - pll->flags = PLL_HAS_MUL; - - sysclks[1].flags |= FIXED_DIV_PLL; - sysclks[1].div = 1; - - sysclks[2].div = PLLDIV2; - - sysclks[3].flags |= FIXED_DIV_PLL; - sysclks[3].div = 2; - - sysclks[4].flags |= FIXED_DIV_PLL; - sysclks[4].div = 3; - - sysclks[5].div = PLLDIV5; - - sysclks[6].flags |= FIXED_DIV_PLL; - sysclks[6].div = 64; - - sysclks[7].flags |= FIXED_DIV_PLL; - sysclks[7].div = 6; - - sysclks[8].div = PLLDIV8; - - sysclks[9].flags |= FIXED_DIV_PLL; - sysclks[9].div = 12; - - sysclks[10].flags |= FIXED_DIV_PLL; - sysclks[10].div = 3; - - sysclks[11].flags |= FIXED_DIV_PLL; - sysclks[11].div = 6; - - c6x_core_clk.parent = &sysclks[0]; - c6x_i2c_clk.parent = &sysclks[7]; - - c6x_clks_init(c6678_clks); -} -#endif /* CONFIG_SOC_TMS320C6678 */ - -static struct of_device_id c6x_clkc_match[] __initdata = { -#ifdef CONFIG_SOC_TMS320C6455 - { .compatible = "ti,c6455-pll", .data = c6455_setup_clocks }, -#endif -#ifdef CONFIG_SOC_TMS320C6457 - { .compatible = "ti,c6457-pll", .data = c6457_setup_clocks }, -#endif -#ifdef CONFIG_SOC_TMS320C6472 - { .compatible = "ti,c6472-pll", .data = c6472_setup_clocks }, -#endif -#ifdef CONFIG_SOC_TMS320C6474 - { .compatible = "ti,c6474-pll", .data = c6474_setup_clocks }, -#endif -#ifdef CONFIG_SOC_TMS320C6678 - { .compatible = "ti,c6678-pll", .data = c6678_setup_clocks }, -#endif - { .compatible = "ti,c64x+pll" }, - {} -}; - -void __init c64x_setup_clocks(void) -{ - void (*__setup_clocks)(struct device_node *np); - struct pll_data *pll = &c6x_soc_pll1; - struct device_node *node; - const struct of_device_id *id; - int err; - u32 val; - - node = of_find_matching_node(NULL, c6x_clkc_match); - if (!node) - return; - - pll->base = of_iomap(node, 0); - if (!pll->base) - goto out; - - err = of_property_read_u32(node, "clock-frequency", &val); - if (err || val == 0) { - pr_err("%pOF: no clock-frequency found! Using %dMHz\n", - node, (int)val / 1000000); - val = 25000000; - } - clkin1.rate = val; - - err = of_property_read_u32(node, "ti,c64x+pll-bypass-delay", &val); - if (err) - val = 5000; - pll->bypass_delay = val; - - err = of_property_read_u32(node, "ti,c64x+pll-reset-delay", &val); - if (err) - val = 30000; - pll->reset_delay = val; - - err = of_property_read_u32(node, "ti,c64x+pll-lock-delay", &val); - if (err) - val = 30000; - pll->lock_delay = val; - - /* id->data is a pointer to SoC-specific setup */ - id = of_match_node(c6x_clkc_match, node); - if (id && id->data) { - __setup_clocks = id->data; - __setup_clocks(node); - } - -out: - of_node_put(node); -} diff --git a/arch/c6x/platforms/timer64.c b/arch/c6x/platforms/timer64.c deleted file mode 100644 index 661f4c7c6ef6..000000000000 --- a/arch/c6x/platforms/timer64.c +++ /dev/null @@ -1,241 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Copyright (C) 2010, 2011 Texas Instruments Incorporated - * Contributed by: Mark Salter (msalter@redhat.com) - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -struct timer_regs { - u32 reserved0; - u32 emumgt; - u32 reserved1; - u32 reserved2; - u32 cntlo; - u32 cnthi; - u32 prdlo; - u32 prdhi; - u32 tcr; - u32 tgcr; - u32 wdtcr; -}; - -static struct timer_regs __iomem *timer; - -#define TCR_TSTATLO 0x001 -#define TCR_INVOUTPLO 0x002 -#define TCR_INVINPLO 0x004 -#define TCR_CPLO 0x008 -#define TCR_ENAMODELO_ONCE 0x040 -#define TCR_ENAMODELO_CONT 0x080 -#define TCR_ENAMODELO_MASK 0x0c0 -#define TCR_PWIDLO_MASK 0x030 -#define TCR_CLKSRCLO 0x100 -#define TCR_TIENLO 0x200 -#define TCR_TSTATHI (0x001 << 16) -#define TCR_INVOUTPHI (0x002 << 16) -#define TCR_CPHI (0x008 << 16) -#define TCR_PWIDHI_MASK (0x030 << 16) -#define TCR_ENAMODEHI_ONCE (0x040 << 16) -#define TCR_ENAMODEHI_CONT (0x080 << 16) -#define TCR_ENAMODEHI_MASK (0x0c0 << 16) - -#define TGCR_TIMLORS 0x001 -#define TGCR_TIMHIRS 0x002 -#define TGCR_TIMMODE_UD32 0x004 -#define TGCR_TIMMODE_WDT64 0x008 -#define TGCR_TIMMODE_CD32 0x00c -#define TGCR_TIMMODE_MASK 0x00c -#define TGCR_PSCHI_MASK (0x00f << 8) -#define TGCR_TDDRHI_MASK (0x00f << 12) - -/* - * Timer clocks are divided down from the CPU clock - * The divisor is in the EMUMGTCLKSPD register - */ -#define TIMER_DIVISOR \ - ((soc_readl(&timer->emumgt) & (0xf << 16)) >> 16) - -#define TIMER64_RATE (c6x_core_freq / TIMER_DIVISOR) - -#define TIMER64_MODE_DISABLED 0 -#define TIMER64_MODE_ONE_SHOT TCR_ENAMODELO_ONCE -#define TIMER64_MODE_PERIODIC TCR_ENAMODELO_CONT - -static int timer64_mode; -static int timer64_devstate_id = -1; - -static void timer64_config(unsigned long period) -{ - u32 tcr = soc_readl(&timer->tcr) & ~TCR_ENAMODELO_MASK; - - soc_writel(tcr, &timer->tcr); - soc_writel(period - 1, &timer->prdlo); - soc_writel(0, &timer->cntlo); - tcr |= timer64_mode; - soc_writel(tcr, &timer->tcr); -} - -static void timer64_enable(void) -{ - u32 val; - - if (timer64_devstate_id >= 0) - dscr_set_devstate(timer64_devstate_id, DSCR_DEVSTATE_ENABLED); - - /* disable timer, reset count */ - soc_writel(soc_readl(&timer->tcr) & ~TCR_ENAMODELO_MASK, &timer->tcr); - soc_writel(0, &timer->prdlo); - - /* use internal clock and 1 cycle pulse width */ - val = soc_readl(&timer->tcr); - soc_writel(val & ~(TCR_CLKSRCLO | TCR_PWIDLO_MASK), &timer->tcr); - - /* dual 32-bit unchained mode */ - val = soc_readl(&timer->tgcr) & ~TGCR_TIMMODE_MASK; - soc_writel(val, &timer->tgcr); - soc_writel(val | (TGCR_TIMLORS | TGCR_TIMMODE_UD32), &timer->tgcr); -} - -static void timer64_disable(void) -{ - /* disable timer, reset count */ - soc_writel(soc_readl(&timer->tcr) & ~TCR_ENAMODELO_MASK, &timer->tcr); - soc_writel(0, &timer->prdlo); - - if (timer64_devstate_id >= 0) - dscr_set_devstate(timer64_devstate_id, DSCR_DEVSTATE_DISABLED); -} - -static int next_event(unsigned long delta, - struct clock_event_device *evt) -{ - timer64_config(delta); - return 0; -} - -static int set_periodic(struct clock_event_device *evt) -{ - timer64_enable(); - timer64_mode = TIMER64_MODE_PERIODIC; - timer64_config(TIMER64_RATE / HZ); - return 0; -} - -static int set_oneshot(struct clock_event_device *evt) -{ - timer64_enable(); - timer64_mode = TIMER64_MODE_ONE_SHOT; - return 0; -} - -static int shutdown(struct clock_event_device *evt) -{ - timer64_mode = TIMER64_MODE_DISABLED; - timer64_disable(); - return 0; -} - -static struct clock_event_device t64_clockevent_device = { - .name = "TIMER64_EVT32_TIMER", - .features = CLOCK_EVT_FEAT_ONESHOT | - CLOCK_EVT_FEAT_PERIODIC, - .rating = 200, - .set_state_shutdown = shutdown, - .set_state_periodic = set_periodic, - .set_state_oneshot = set_oneshot, - .set_next_event = next_event, -}; - -static irqreturn_t timer_interrupt(int irq, void *dev_id) -{ - struct clock_event_device *cd = &t64_clockevent_device; - - cd->event_handler(cd); - - return IRQ_HANDLED; -} - -void __init timer64_init(void) -{ - struct clock_event_device *cd = &t64_clockevent_device; - struct device_node *np, *first = NULL; - u32 val; - int err, found = 0; - - for_each_compatible_node(np, NULL, "ti,c64x+timer64") { - err = of_property_read_u32(np, "ti,core-mask", &val); - if (!err) { - if (val & (1 << get_coreid())) { - found = 1; - break; - } - } else if (!first) - first = np; - } - if (!found) { - /* try first one with no core-mask */ - if (first) - np = of_node_get(first); - else { - pr_debug("Cannot find ti,c64x+timer64 timer.\n"); - return; - } - } - - timer = of_iomap(np, 0); - if (!timer) { - pr_debug("%pOF: Cannot map timer registers.\n", np); - goto out; - } - pr_debug("%pOF: Timer registers=%p.\n", np, timer); - - cd->irq = irq_of_parse_and_map(np, 0); - if (cd->irq == NO_IRQ) { - pr_debug("%pOF: Cannot find interrupt.\n", np); - iounmap(timer); - goto out; - } - - /* If there is a device state control, save the ID. */ - err = of_property_read_u32(np, "ti,dscr-dev-enable", &val); - if (!err) { - timer64_devstate_id = val; - - /* - * It is necessary to enable the timer block here because - * the TIMER_DIVISOR macro needs to read a timer register - * to get the divisor. - */ - dscr_set_devstate(timer64_devstate_id, DSCR_DEVSTATE_ENABLED); - } - - pr_debug("%pOF: Timer irq=%d.\n", np, cd->irq); - - clockevents_calc_mult_shift(cd, c6x_core_freq / TIMER_DIVISOR, 5); - - cd->max_delta_ns = clockevent_delta2ns(0x7fffffff, cd); - cd->max_delta_ticks = 0x7fffffff; - cd->min_delta_ns = clockevent_delta2ns(250, cd); - cd->min_delta_ticks = 250; - - cd->cpumask = cpumask_of(smp_processor_id()); - - clockevents_register_device(cd); - if (request_irq(cd->irq, timer_interrupt, IRQF_TIMER, "timer", - &t64_clockevent_device)) - pr_err("Failed to request irq %d (timer)\n", cd->irq); - -out: - of_node_put(np); - return; -} diff --git a/drivers/bus/Kconfig b/drivers/bus/Kconfig index 0c262c2aeaf2..e7f7eee6ee9a 100644 --- a/drivers/bus/Kconfig +++ b/drivers/bus/Kconfig @@ -80,7 +80,7 @@ config MOXTET config HISILICON_LPC bool "Support for ISA I/O space on HiSilicon Hip06/7" - depends on (ARM64 && ARCH_HISI) || (COMPILE_TEST && !ALPHA && !HEXAGON && !PARISC && !C6X) + depends on (ARM64 && ARCH_HISI) || (COMPILE_TEST && !ALPHA && !HEXAGON && !PARISC) depends on HAS_IOMEM select INDIRECT_PIO if ARM64 help diff --git a/fs/Kconfig.binfmt b/fs/Kconfig.binfmt index 885da6d983b4..647439c2c05a 100644 --- a/fs/Kconfig.binfmt +++ b/fs/Kconfig.binfmt @@ -45,7 +45,7 @@ config ARCH_USE_GNU_PROPERTY config BINFMT_ELF_FDPIC bool "Kernel support for FDPIC ELF binaries" default y if !BINFMT_ELF - depends on (ARM || (SUPERH && !MMU) || C6X) + depends on (ARM || (SUPERH && !MMU)) select ELFCORE help ELF FDPIC binaries are based on ELF, but allow the individual load diff --git a/include/asm-generic/page.h b/include/asm-generic/page.h index fe801f01625e..6fc47561814c 100644 --- a/include/asm-generic/page.h +++ b/include/asm-generic/page.h @@ -63,11 +63,7 @@ extern unsigned long memory_end; #endif /* !__ASSEMBLY__ */ -#ifdef CONFIG_KERNEL_RAM_BASE_ADDRESS -#define PAGE_OFFSET (CONFIG_KERNEL_RAM_BASE_ADDRESS) -#else #define PAGE_OFFSET (0) -#endif #ifndef ARCH_PFN_OFFSET #define ARCH_PFN_OFFSET (PAGE_OFFSET >> PAGE_SHIFT) -- cgit v1.2.3 From f3a732843accb04ede91055ffd0b92464fa4d15c Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Mon, 18 Jan 2021 12:53:11 +0100 Subject: ARM: remove sirf prima2/atlas platforms The SiRF Prima2 and Atlas platform code was contributed by Cambridge Silicon Radio (CSR) after aquiring the original SiRF company, and maintained by Barry Song. CSR was subsequently acquired by Qualcomm, who no longer have an interest in maintaining the SoC platform but instead have released more recent SoCs for the same market in the Snapdragon family. As Barry is no longer working for the company, nobody else there wants to maintain it, and there are no third-party users, the best way forward seems to be to completely remove it. Thanks to Barry for maintaining the platform for the past ten years. Cc: Barry Song Link: https://lore.kernel.org/lkml/c969392572604b98bcb3be44048c3165@hisilicon.com/ Signed-off-by: Arnd Bergmann --- Documentation/devicetree/bindings/arm/sirf.yaml | 30 - .../devicetree/bindings/reset/sirf,rstc.txt | 42 - MAINTAINERS | 13 - arch/arm/Kconfig | 2 - arch/arm/Kconfig.debug | 41 +- arch/arm/Makefile | 1 - arch/arm/boot/dts/Makefile | 6 - arch/arm/boot/dts/atlas6-evb.dts | 78 - arch/arm/boot/dts/atlas6.dtsi | 800 -------- arch/arm/boot/dts/atlas7-evb.dts | 127 -- arch/arm/boot/dts/atlas7.dtsi | 1955 -------------------- arch/arm/boot/dts/prima2-evb.dts | 37 - arch/arm/boot/dts/prima2.dtsi | 838 --------- arch/arm/configs/prima2_defconfig | 72 - arch/arm/include/debug/sirf.S | 40 - arch/arm/mach-prima2/Kconfig | 48 - arch/arm/mach-prima2/Makefile | 9 - arch/arm/mach-prima2/common.c | 64 - arch/arm/mach-prima2/common.h | 32 - arch/arm/mach-prima2/headsmp.S | 36 - arch/arm/mach-prima2/hotplug.c | 38 - arch/arm/mach-prima2/platsmp.c | 123 -- arch/arm/mach-prima2/pm.c | 153 -- arch/arm/mach-prima2/pm.h | 28 - arch/arm/mach-prima2/rstc.c | 107 -- arch/arm/mach-prima2/rtciobrg.c | 179 -- arch/arm/mach-prima2/sleep.S | 63 - 27 files changed, 2 insertions(+), 4960 deletions(-) delete mode 100644 Documentation/devicetree/bindings/arm/sirf.yaml delete mode 100644 Documentation/devicetree/bindings/reset/sirf,rstc.txt delete mode 100644 arch/arm/boot/dts/atlas6-evb.dts delete mode 100644 arch/arm/boot/dts/atlas6.dtsi delete mode 100644 arch/arm/boot/dts/atlas7-evb.dts delete mode 100644 arch/arm/boot/dts/atlas7.dtsi delete mode 100644 arch/arm/boot/dts/prima2-evb.dts delete mode 100644 arch/arm/boot/dts/prima2.dtsi delete mode 100644 arch/arm/configs/prima2_defconfig delete mode 100644 arch/arm/include/debug/sirf.S delete mode 100644 arch/arm/mach-prima2/Kconfig delete mode 100644 arch/arm/mach-prima2/Makefile delete mode 100644 arch/arm/mach-prima2/common.c delete mode 100644 arch/arm/mach-prima2/common.h delete mode 100644 arch/arm/mach-prima2/headsmp.S delete mode 100644 arch/arm/mach-prima2/hotplug.c delete mode 100644 arch/arm/mach-prima2/platsmp.c delete mode 100644 arch/arm/mach-prima2/pm.c delete mode 100644 arch/arm/mach-prima2/pm.h delete mode 100644 arch/arm/mach-prima2/rstc.c delete mode 100644 arch/arm/mach-prima2/rtciobrg.c delete mode 100644 arch/arm/mach-prima2/sleep.S (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/arm/sirf.yaml b/Documentation/devicetree/bindings/arm/sirf.yaml deleted file mode 100644 index b25eb35d1b66..000000000000 --- a/Documentation/devicetree/bindings/arm/sirf.yaml +++ /dev/null @@ -1,30 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0 -%YAML 1.2 ---- -$id: http://devicetree.org/schemas/arm/sirf.yaml# -$schema: http://devicetree.org/meta-schemas/core.yaml# - -title: CSR SiRFprimaII and SiRFmarco device tree bindings. - -maintainers: - - Binghua Duan - - Barry Song - -properties: - $nodename: - const: '/' - compatible: - oneOf: - - items: - - const: sirf,atlas6-cb - - const: sirf,atlas6 - - items: - - const: sirf,atlas7-cb - - const: sirf,atlas7 - - items: - - const: sirf,prima2-cb - - const: sirf,prima2 - -additionalProperties: true - -... diff --git a/Documentation/devicetree/bindings/reset/sirf,rstc.txt b/Documentation/devicetree/bindings/reset/sirf,rstc.txt deleted file mode 100644 index 0505de742d30..000000000000 --- a/Documentation/devicetree/bindings/reset/sirf,rstc.txt +++ /dev/null @@ -1,42 +0,0 @@ -CSR SiRFSoC Reset Controller -====================================== - -Please also refer to reset.txt in this directory for common reset -controller binding usage. - -Required properties: -- compatible: Should be "sirf,prima2-rstc" or "sirf,marco-rstc" -- reg: should be register base and length as documented in the - datasheet -- #reset-cells: 1, see below - -example: - -rstc: reset-controller@88010000 { - compatible = "sirf,prima2-rstc"; - reg = <0x88010000 0x1000>; - #reset-cells = <1>; -}; - -Specifying reset lines connected to IP modules -============================================== - -The reset controller(rstc) manages various reset sources. This module provides -reset signals for most blocks in system. Those device nodes should specify the -reset line on the rstc in their resets property, containing a phandle to the -rstc device node and a RESET_INDEX specifying which module to reset, as described -in reset.txt. - -For SiRFSoC, RESET_INDEX is just reset_bit defined in SW_RST0 and SW_RST1 registers. -For modules whose rest_bit is in SW_RST0, its RESET_INDEX is 0~31. For modules whose -rest_bit is in SW_RST1, its RESET_INDEX is 32~63. - -example: - -vpp@90020000 { - compatible = "sirf,prima2-vpp"; - reg = <0x90020000 0x10000>; - interrupts = <31>; - clocks = <&clks 35>; - resets = <&rstc 6>; -}; diff --git a/MAINTAINERS b/MAINTAINERS index 7c3eadb185f9..aeef69cbc7ec 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -1779,19 +1779,6 @@ F: drivers/net/ethernet/cortina/ F: drivers/pinctrl/pinctrl-gemini.c F: drivers/rtc/rtc-ftrtc010.c -ARM/CSR SIRFPRIMA2 MACHINE SUPPORT -M: Barry Song -L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) -S: Maintained -T: git git://git.kernel.org/pub/scm/linux/kernel/git/baohua/linux.git -F: arch/arm/boot/dts/prima2* -F: arch/arm/mach-prima2/ -F: drivers/clk/sirf/ -F: drivers/clocksource/timer-atlas7.c -F: drivers/clocksource/timer-prima2.c -X: drivers/gnss -N: [^a-z]sirf - ARM/CZ.NIC TURRIS MOX SUPPORT M: Marek Behun S: Maintained diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 96f153c5639b..9d9a7060d365 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -671,8 +671,6 @@ source "arch/arm/mach-orion5x/Kconfig" source "arch/arm/mach-oxnas/Kconfig" -source "arch/arm/mach-prima2/Kconfig" - source "arch/arm/mach-pxa/Kconfig" source "arch/arm/plat-pxa/Kconfig" diff --git a/arch/arm/Kconfig.debug b/arch/arm/Kconfig.debug index 23264f7bff72..fe8b95069d31 100644 --- a/arch/arm/Kconfig.debug +++ b/arch/arm/Kconfig.debug @@ -1142,32 +1142,6 @@ choice Say Y here if you want kernel low-level debugging support on Allwinner A31/A23 based platforms on the R_UART. - config DEBUG_SIRFPRIMA2_UART1 - bool "Kernel low-level debugging messages via SiRFprimaII UART1" - depends on ARCH_PRIMA2 - select DEBUG_SIRFSOC_UART - help - Say Y here if you want the debug print routines to direct - their output to the uart1 port on SiRFprimaII devices. - - config DEBUG_SIRFATLAS7_UART0 - bool "Kernel low-level debugging messages via SiRFatlas7 UART0" - depends on ARCH_ATLAS7 - select DEBUG_SIRFSOC_UART - help - Say Y here if you want the debug print routines to direct - their output to the uart0 port on SiRFATLAS7 devices.The uart0 - is used on SiRFATLAS7 as a extra debug port.sometimes an extra - debug port can be very useful. - - config DEBUG_SIRFATLAS7_UART1 - bool "Kernel low-level debugging messages via SiRFatlas7 UART1" - depends on ARCH_ATLAS7 - select DEBUG_SIRFSOC_UART - help - Say Y here if you want the debug print routines to direct - their output to the uart1 port on SiRFATLAS7 devices. - config DEBUG_SPEAR3XX bool "Kernel low-level debugging messages via ST SPEAr 3xx/6xx UART" depends on ARCH_SPEAR3XX || ARCH_SPEAR6XX @@ -1538,10 +1512,6 @@ config DEBUG_STM32_UART bool depends on ARCH_STM32 -config DEBUG_SIRFSOC_UART - bool - depends on ARCH_SIRF - config DEBUG_UART_FLOW_CONTROL bool "Enable flow control (CTS) for the debug UART" depends on DEBUG_LL @@ -1596,7 +1566,6 @@ config DEBUG_LL_INCLUDE default "debug/renesas-scif.S" if DEBUG_RMOBILE_SCIFA4 default "debug/s3c24xx.S" if DEBUG_S3C24XX_UART || DEBUG_S3C64XX_UART default "debug/s5pv210.S" if DEBUG_S5PV210_UART - default "debug/sirf.S" if DEBUG_SIRFSOC_UART default "debug/sti.S" if DEBUG_STI_UART default "debug/stm32.S" if DEBUG_STM32_UART default "debug/tegra.S" if DEBUG_TEGRA_UART @@ -1648,8 +1617,6 @@ config DEBUG_UART_PHYS default 0x1600d000 if DEBUG_SD5203_UART default 0x18000300 if DEBUG_BCM_5301X default 0x18000400 if DEBUG_BCM_HR2 - default 0x18010000 if DEBUG_SIRFATLAS7_UART0 - default 0x18020000 if DEBUG_SIRFATLAS7_UART1 default 0x18023000 if DEBUG_BCM_IPROC_UART3 default 0x1c090000 if DEBUG_VEXPRESS_UART0_RS1 default 0x20001000 if DEBUG_HIP01_UART @@ -1695,7 +1662,6 @@ config DEBUG_UART_PHYS default 0x80074000 if DEBUG_IMX28_UART default 0x808c0000 if DEBUG_EP93XX || ARCH_EP93XX default 0x90020000 if DEBUG_NSPIRE_CLASSIC_UART || DEBUG_NSPIRE_CX_UART - default 0xb0060000 if DEBUG_SIRFPRIMA2_UART1 default 0xb0090000 if DEBUG_VEXPRESS_UART0_CRX default 0xc0013000 if DEBUG_U300_UART default 0xc8000000 if ARCH_IXP4XX && !CPU_BIG_ENDIAN @@ -1754,7 +1720,7 @@ config DEBUG_UART_PHYS DEBUG_RMOBILE_SCIFA4 || DEBUG_S3C24XX_UART || \ DEBUG_S3C64XX_UART || \ DEBUG_BCM63XX_UART || DEBUG_ASM9260_UART || \ - DEBUG_SIRFSOC_UART || DEBUG_DIGICOLOR_UA0 || \ + DEBUG_DIGICOLOR_UA0 || \ DEBUG_AT91_UART || DEBUG_STM32_UART config DEBUG_UART_VIRT @@ -1836,10 +1802,7 @@ config DEBUG_UART_VIRT default 0xfec03000 if DEBUG_SOCFPGA_CYCLONE5_UART1 default 0xfec12000 if DEBUG_MVEBU_UART0 || DEBUG_MVEBU_UART0_ALTERNATE default 0xfec12100 if DEBUG_MVEBU_UART1_ALTERNATE - default 0xfec10000 if DEBUG_SIRFATLAS7_UART0 default 0xfec20000 if DEBUG_DAVINCI_DMx_UART0 - default 0xfec20000 if DEBUG_SIRFATLAS7_UART1 - default 0xfec60000 if DEBUG_SIRFPRIMA2_UART1 default 0xfec90000 if DEBUG_RK32_UART2 default 0xfed0c000 if DEBUG_DAVINCI_DA8XX_UART1 default 0xfed0d000 if DEBUG_DAVINCI_DA8XX_UART2 || DEBUG_SD5203_UART @@ -1863,7 +1826,7 @@ config DEBUG_UART_VIRT DEBUG_QCOM_UARTDM || DEBUG_S3C24XX_UART || \ DEBUG_S3C64XX_UART || \ DEBUG_BCM63XX_UART || DEBUG_ASM9260_UART || \ - DEBUG_SIRFSOC_UART || DEBUG_DIGICOLOR_UA0 || \ + DEBUG_DIGICOLOR_UA0 || \ DEBUG_AT91_UART || DEBUG_STM32_UART config DEBUG_UART_8250_SHIFT diff --git a/arch/arm/Makefile b/arch/arm/Makefile index dd51416cdcd9..7c4b50852a78 100644 --- a/arch/arm/Makefile +++ b/arch/arm/Makefile @@ -209,7 +209,6 @@ machine-$(CONFIG_PLAT_SAMSUNG) += s3c machine-$(CONFIG_ARCH_S5PV210) += s5pv210 machine-$(CONFIG_ARCH_SA1100) += sa1100 machine-$(CONFIG_ARCH_RENESAS) += shmobile -machine-$(CONFIG_ARCH_SIRF) += prima2 machine-$(CONFIG_ARCH_SOCFPGA) += socfpga machine-$(CONFIG_ARCH_STI) += sti machine-$(CONFIG_ARCH_STM32) += stm32 diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile index 2c02cb4c71cb..da413b4d5c3f 100644 --- a/arch/arm/boot/dts/Makefile +++ b/arch/arm/boot/dts/Makefile @@ -74,10 +74,6 @@ dtb-$(CONFIG_SOC_SAM_V7) += \ at91-sama5d4_xplained.dtb \ at91-sama5d4ek.dtb \ at91-vinco.dtb -dtb-$(CONFIG_ARCH_ATLAS6) += \ - atlas6-evb.dtb -dtb-$(CONFIG_ARCH_ATLAS7) += \ - atlas7-evb.dtb dtb-$(CONFIG_ARCH_AXXIA) += \ axm5516-amarillo.dtb dtb-$(CONFIG_ARCH_BCM2835) += \ @@ -886,8 +882,6 @@ dtb-$(CONFIG_ARCH_ACTIONS) += \ owl-s500-labrador-base-m.dtb \ owl-s500-roseapplepi.dtb \ owl-s500-sparky.dtb -dtb-$(CONFIG_ARCH_PRIMA2) += \ - prima2-evb.dtb dtb-$(CONFIG_ARCH_PXA) += \ pxa300-raumfeld-connector.dtb \ pxa300-raumfeld-controller.dtb \ diff --git a/arch/arm/boot/dts/atlas6-evb.dts b/arch/arm/boot/dts/atlas6-evb.dts deleted file mode 100644 index 89e430392f26..000000000000 --- a/arch/arm/boot/dts/atlas6-evb.dts +++ /dev/null @@ -1,78 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * DTS file for CSR SiRFatlas6 Evaluation Board - * - * Copyright (c) 2012 Cambridge Silicon Radio Limited, a CSR plc group company. - */ - -/dts-v1/; - -/include/ "atlas6.dtsi" - -/ { - model = "CSR SiRFatlas6 Evaluation Board"; - compatible = "sirf,atlas6-cb", "sirf,atlas6"; - - memory { - device_type = "memory"; - reg = <0x00000000 0x20000000>; - }; - - axi { - peri-iobg { - uart@b0060000 { - pinctrl-names = "default"; - pinctrl-0 = <&uart1_pins_a>; - }; - spi@b00d0000 { - status = "okay"; - pinctrl-names = "default"; - pinctrl-0 = <&spi0_pins_a>; - spi@0 { - compatible = "spidev"; - reg = <0>; - spi-max-frequency = <1000000>; - }; - }; - spi@b0170000 { - pinctrl-names = "default"; - pinctrl-0 = <&spi1_pins_a>; - }; - i2c0: i2c@b00e0000 { - status = "okay"; - pinctrl-names = "default"; - pinctrl-0 = <&i2c0_pins_a>; - lcd@40 { - compatible = "sirf,lcd"; - reg = <0x40>; - }; - }; - - }; - disp-iobg { - lcd@90010000 { - status = "okay"; - pinctrl-names = "default"; - pinctrl-0 = <&lcd_24pins_a>; - }; - }; - }; - display: display@0 { - panels { - panel0: panel@0 { - panel-name = "Innolux TFT"; - hactive = <800>; - vactive = <480>; - left_margin = <20>; - right_margin = <234>; - upper_margin = <3>; - lower_margin = <41>; - hsync_len = <3>; - vsync_len = <2>; - pixclock = <33264000>; - sync = <3>; - timing = <0x88>; - }; - }; - }; -}; diff --git a/arch/arm/boot/dts/atlas6.dtsi b/arch/arm/boot/dts/atlas6.dtsi deleted file mode 100644 index 8ac5d1524a43..000000000000 --- a/arch/arm/boot/dts/atlas6.dtsi +++ /dev/null @@ -1,800 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * DTS file for CSR SiRFatlas6 SoC - * - * Copyright (c) 2012 Cambridge Silicon Radio Limited, a CSR plc group company. - */ - -/ { - compatible = "sirf,atlas6"; - #address-cells = <1>; - #size-cells = <1>; - interrupt-parent = <&intc>; - - cpus { - #address-cells = <1>; - #size-cells = <0>; - - cpu@0 { - reg = <0x0>; - d-cache-line-size = <32>; - i-cache-line-size = <32>; - d-cache-size = <32768>; - i-cache-size = <32768>; - /* from bootloader */ - timebase-frequency = <0>; - bus-frequency = <0>; - clock-frequency = <0>; - clocks = <&clks 12>; - operating-points = < - /* kHz uV */ - 200000 1025000 - 400000 1025000 - 600000 1050000 - 800000 1100000 - >; - clock-latency = <150000>; - }; - }; - - arm-pmu { - compatible = "arm,cortex-a9-pmu"; - interrupts = <29>; - }; - - axi { - compatible = "simple-bus"; - #address-cells = <1>; - #size-cells = <1>; - ranges = <0x40000000 0x40000000 0x80000000>; - - intc: interrupt-controller@80020000 { - #interrupt-cells = <1>; - interrupt-controller; - compatible = "sirf,prima2-intc"; - reg = <0x80020000 0x1000>; - }; - - sys-iobg { - compatible = "simple-bus"; - #address-cells = <1>; - #size-cells = <1>; - ranges = <0x88000000 0x88000000 0x40000>; - - clks: clock-controller@88000000 { - compatible = "sirf,atlas6-clkc"; - reg = <0x88000000 0x1000>; - interrupts = <3>; - #clock-cells = <1>; - }; - - rstc: reset-controller@88010000 { - compatible = "sirf,prima2-rstc"; - reg = <0x88010000 0x1000>; - #reset-cells = <1>; - }; - - rsc-controller@88020000 { - compatible = "sirf,prima2-rsc"; - reg = <0x88020000 0x1000>; - }; - - cphifbg@88030000 { - compatible = "sirf,prima2-cphifbg"; - reg = <0x88030000 0x1000>; - clocks = <&clks 42>; - }; - }; - - mem-iobg { - compatible = "simple-bus"; - #address-cells = <1>; - #size-cells = <1>; - ranges = <0x90000000 0x90000000 0x10000>; - - memory-controller@90000000 { - compatible = "sirf,prima2-memc"; - reg = <0x90000000 0x2000>; - interrupts = <27>; - clocks = <&clks 5>; - }; - - memc-monitor { - compatible = "sirf,prima2-memcmon"; - reg = <0x90002000 0x200>; - interrupts = <4>; - clocks = <&clks 32>; - }; - }; - - disp-iobg { - compatible = "simple-bus"; - #address-cells = <1>; - #size-cells = <1>; - ranges = <0x90010000 0x90010000 0x30000>; - - lcd@90010000 { - compatible = "sirf,prima2-lcd"; - reg = <0x90010000 0x20000>; - interrupts = <30>; - clocks = <&clks 34>; - display=<&display>; - /* later transfer to pwm */ - bl-gpio = <&gpio 7 0>; - default-panel = <&panel0>; - }; - - vpp@90020000 { - compatible = "sirf,prima2-vpp"; - reg = <0x90020000 0x10000>; - interrupts = <31>; - clocks = <&clks 35>; - resets = <&rstc 6>; - }; - }; - - graphics-iobg { - compatible = "simple-bus"; - #address-cells = <1>; - #size-cells = <1>; - ranges = <0x98000000 0x98000000 0x8000000>; - - graphics@98000000 { - compatible = "powervr,sgx510"; - reg = <0x98000000 0x8000000>; - interrupts = <6>; - clocks = <&clks 32>; - }; - }; - - graphics2d-iobg { - compatible = "simple-bus"; - #address-cells = <1>; - #size-cells = <1>; - ranges = <0xa0000000 0xa0000000 0x8000000>; - - ble@a0000000 { - compatible = "sirf,atlas6-ble"; - reg = <0xa0000000 0x2000>; - interrupts = <5>; - clocks = <&clks 33>; - }; - }; - - dsp-iobg { - compatible = "simple-bus"; - #address-cells = <1>; - #size-cells = <1>; - ranges = <0xa8000000 0xa8000000 0x2000000>; - - dspif@a8000000 { - compatible = "sirf,prima2-dspif"; - reg = <0xa8000000 0x10000>; - interrupts = <9>; - resets = <&rstc 1>; - }; - - gps@a8010000 { - compatible = "sirf,prima2-gps"; - reg = <0xa8010000 0x10000>; - interrupts = <7>; - clocks = <&clks 9>; - resets = <&rstc 2>; - }; - - dsp@a9000000 { - compatible = "sirf,prima2-dsp"; - reg = <0xa9000000 0x1000000>; - interrupts = <8>; - clocks = <&clks 8>; - resets = <&rstc 0>; - }; - }; - - peri-iobg { - compatible = "simple-bus"; - #address-cells = <1>; - #size-cells = <1>; - ranges = <0xb0000000 0xb0000000 0x180000>, - <0x56000000 0x56000000 0x1b00000>; - - timer@b0020000 { - compatible = "sirf,prima2-tick"; - reg = <0xb0020000 0x1000>; - interrupts = <0>; - clocks = <&clks 11>; - }; - - nand@b0030000 { - compatible = "sirf,prima2-nand"; - reg = <0xb0030000 0x10000>; - interrupts = <41>; - clocks = <&clks 26>; - }; - - audio@b0040000 { - compatible = "sirf,prima2-audio"; - reg = <0xb0040000 0x10000>; - interrupts = <35>; - clocks = <&clks 27>; - }; - - uart0: uart@b0050000 { - cell-index = <0>; - compatible = "sirf,prima2-uart"; - reg = <0xb0050000 0x1000>; - interrupts = <17>; - fifosize = <128>; - clocks = <&clks 13>; - dmas = <&dmac1 5>, <&dmac0 2>; - dma-names = "rx", "tx"; - }; - - uart1: uart@b0060000 { - cell-index = <1>; - compatible = "sirf,prima2-uart"; - reg = <0xb0060000 0x1000>; - interrupts = <18>; - fifosize = <32>; - clocks = <&clks 14>; - dma-names = "no-rx", "no-tx"; - }; - - uart2: uart@b0070000 { - cell-index = <2>; - compatible = "sirf,prima2-uart"; - reg = <0xb0070000 0x1000>; - interrupts = <19>; - fifosize = <128>; - clocks = <&clks 15>; - dmas = <&dmac0 6>, <&dmac0 7>; - dma-names = "rx", "tx"; - }; - - usp0: usp@b0080000 { - cell-index = <0>; - compatible = "sirf,prima2-usp"; - reg = <0xb0080000 0x10000>; - interrupts = <20>; - fifosize = <128>; - clocks = <&clks 28>; - dmas = <&dmac1 1>, <&dmac1 2>; - dma-names = "rx", "tx"; - }; - - usp1: usp@b0090000 { - cell-index = <1>; - compatible = "sirf,prima2-usp"; - reg = <0xb0090000 0x10000>; - interrupts = <21>; - fifosize = <128>; - clocks = <&clks 29>; - dmas = <&dmac0 14>, <&dmac0 15>; - dma-names = "rx", "tx"; - }; - - dmac0: dma-controller@b00b0000 { - cell-index = <0>; - compatible = "sirf,prima2-dmac"; - reg = <0xb00b0000 0x10000>; - interrupts = <12>; - clocks = <&clks 24>; - #dma-cells = <1>; - }; - - dmac1: dma-controller@b0160000 { - cell-index = <1>; - compatible = "sirf,prima2-dmac"; - reg = <0xb0160000 0x10000>; - interrupts = <13>; - clocks = <&clks 25>; - #dma-cells = <1>; - }; - - vip@b00C0000 { - compatible = "sirf,prima2-vip"; - reg = <0xb00C0000 0x10000>; - clocks = <&clks 31>; - interrupts = <14>; - sirf,vip-dma-rx-channel = <16>; - }; - - spi0: spi@b00d0000 { - cell-index = <0>; - compatible = "sirf,prima2-spi"; - reg = <0xb00d0000 0x10000>; - interrupts = <15>; - sirf,spi-num-chipselects = <1>; - dmas = <&dmac1 9>, - <&dmac1 4>; - dma-names = "rx", "tx"; - #address-cells = <1>; - #size-cells = <0>; - clocks = <&clks 19>; - resets = <&rstc 26>; - status = "disabled"; - }; - - spi1: spi@b0170000 { - cell-index = <1>; - compatible = "sirf,prima2-spi"; - reg = <0xb0170000 0x10000>; - interrupts = <16>; - sirf,spi-num-chipselects = <1>; - dmas = <&dmac0 12>, - <&dmac0 13>; - dma-names = "rx", "tx"; - #address-cells = <1>; - #size-cells = <0>; - clocks = <&clks 20>; - resets = <&rstc 27>; - status = "disabled"; - }; - - i2c0: i2c@b00e0000 { - cell-index = <0>; - compatible = "sirf,prima2-i2c"; - reg = <0xb00e0000 0x10000>; - interrupts = <24>; - #address-cells = <1>; - #size-cells = <0>; - clocks = <&clks 17>; - }; - - i2c1: i2c@b00f0000 { - cell-index = <1>; - compatible = "sirf,prima2-i2c"; - reg = <0xb00f0000 0x10000>; - interrupts = <25>; - #address-cells = <1>; - #size-cells = <0>; - clocks = <&clks 18>; - }; - - tsc@b0110000 { - compatible = "sirf,prima2-tsc"; - reg = <0xb0110000 0x10000>; - interrupts = <33>; - clocks = <&clks 16>; - }; - - gpio: pinctrl@b0120000 { - #gpio-cells = <2>; - #interrupt-cells = <2>; - compatible = "sirf,atlas6-pinctrl"; - reg = <0xb0120000 0x10000>; - interrupts = <43 44 45 46 47>; - gpio-controller; - interrupt-controller; - - lcd_16pins_a: lcd0@0 { - lcd { - sirf,pins = "lcd_16bitsgrp"; - sirf,function = "lcd_16bits"; - }; - }; - lcd_18pins_a: lcd0@1 { - lcd { - sirf,pins = "lcd_18bitsgrp"; - sirf,function = "lcd_18bits"; - }; - }; - lcd_24pins_a: lcd0@2 { - lcd { - sirf,pins = "lcd_24bitsgrp"; - sirf,function = "lcd_24bits"; - }; - }; - lcdrom_pins_a: lcdrom0@0 { - lcd { - sirf,pins = "lcdromgrp"; - sirf,function = "lcdrom"; - }; - }; - uart0_pins_a: uart0@0 { - uart { - sirf,pins = "uart0grp"; - sirf,function = "uart0"; - }; - }; - uart0_noflow_pins_a: uart0@1 { - uart { - sirf,pins = "uart0_nostreamctrlgrp"; - sirf,function = "uart0_nostreamctrl"; - }; - }; - uart1_pins_a: uart1@0 { - uart { - sirf,pins = "uart1grp"; - sirf,function = "uart1"; - }; - }; - uart2_pins_a: uart2@0 { - uart { - sirf,pins = "uart2grp"; - sirf,function = "uart2"; - }; - }; - uart2_noflow_pins_a: uart2@1 { - uart { - sirf,pins = "uart2_nostreamctrlgrp"; - sirf,function = "uart2_nostreamctrl"; - }; - }; - spi0_pins_a: spi0@0 { - spi { - sirf,pins = "spi0grp"; - sirf,function = "spi0"; - }; - }; - spi1_pins_a: spi1@0 { - spi { - sirf,pins = "spi1grp"; - sirf,function = "spi1"; - }; - }; - i2c0_pins_a: i2c0@0 { - i2c { - sirf,pins = "i2c0grp"; - sirf,function = "i2c0"; - }; - }; - i2c1_pins_a: i2c1@0 { - i2c { - sirf,pins = "i2c1grp"; - sirf,function = "i2c1"; - }; - }; - pwm0_pins_a: pwm0@0 { - pwm { - sirf,pins = "pwm0grp"; - sirf,function = "pwm0"; - }; - }; - pwm1_pins_a: pwm1@0 { - pwm { - sirf,pins = "pwm1grp"; - sirf,function = "pwm1"; - }; - }; - pwm2_pins_a: pwm2@0 { - pwm { - sirf,pins = "pwm2grp"; - sirf,function = "pwm2"; - }; - }; - pwm3_pins_a: pwm3@0 { - pwm { - sirf,pins = "pwm3grp"; - sirf,function = "pwm3"; - }; - }; - pwm4_pins_a: pwm4@0 { - pwm { - sirf,pins = "pwm4grp"; - sirf,function = "pwm4"; - }; - }; - gps_pins_a: gps@0 { - gps { - sirf,pins = "gpsgrp"; - sirf,function = "gps"; - }; - }; - vip_pins_a: vip@0 { - vip { - sirf,pins = "vipgrp"; - sirf,function = "vip"; - }; - }; - sdmmc0_pins_a: sdmmc0@0 { - sdmmc0 { - sirf,pins = "sdmmc0grp"; - sirf,function = "sdmmc0"; - }; - }; - sdmmc1_pins_a: sdmmc1@0 { - sdmmc1 { - sirf,pins = "sdmmc1grp"; - sirf,function = "sdmmc1"; - }; - }; - sdmmc2_pins_a: sdmmc2@0 { - sdmmc2 { - sirf,pins = "sdmmc2grp"; - sirf,function = "sdmmc2"; - }; - }; - sdmmc2_nowp_pins_a: sdmmc2_nowp@0 { - sdmmc2_nowp { - sirf,pins = "sdmmc2_nowpgrp"; - sirf,function = "sdmmc2_nowp"; - }; - }; - sdmmc3_pins_a: sdmmc3@0 { - sdmmc3 { - sirf,pins = "sdmmc3grp"; - sirf,function = "sdmmc3"; - }; - }; - sdmmc5_pins_a: sdmmc5@0 { - sdmmc5 { - sirf,pins = "sdmmc5grp"; - sirf,function = "sdmmc5"; - }; - }; - i2s_mclk_pins_a: i2s_mclk@0 { - i2s_mclk { - sirf,pins = "i2smclkgrp"; - sirf,function = "i2s_mclk"; - }; - }; - i2s_ext_clk_input_pins_a: i2s_ext_clk_input@0 { - i2s_ext_clk_input { - sirf,pins = "i2s_ext_clk_inputgrp"; - sirf,function = "i2s_ext_clk_input"; - }; - }; - i2s_pins_a: i2s@0 { - i2s { - sirf,pins = "i2sgrp"; - sirf,function = "i2s"; - }; - }; - i2s_no_din_pins_a: i2s_no_din@0 { - i2s_no_din { - sirf,pins = "i2s_no_dingrp"; - sirf,function = "i2s_no_din"; - }; - }; - i2s_6chn_pins_a: i2s_6chn@0 { - i2s_6chn { - sirf,pins = "i2s_6chngrp"; - sirf,function = "i2s_6chn"; - }; - }; - ac97_pins_a: ac97@0 { - ac97 { - sirf,pins = "ac97grp"; - sirf,function = "ac97"; - }; - }; - nand_pins_a: nand@0 { - nand { - sirf,pins = "nandgrp"; - sirf,function = "nand"; - }; - }; - usp0_pins_a: usp0@0 { - usp0 { - sirf,pins = "usp0grp"; - sirf,function = "usp0"; - }; - }; - usp0_uart_nostreamctrl_pins_a: usp0@1 { - usp0 { - sirf,pins = "usp0_uart_nostreamctrl_grp"; - sirf,function = "usp0_uart_nostreamctrl"; - }; - }; - usp0_only_utfs_pins_a: usp0@2 { - usp0 { - sirf,pins = "usp0_only_utfs_grp"; - sirf,function = "usp0_only_utfs"; - }; - }; - usp0_only_urfs_pins_a: usp0@3 { - usp0 { - sirf,pins = "usp0_only_urfs_grp"; - sirf,function = "usp0_only_urfs"; - }; - }; - usp1_pins_a: usp1@0 { - usp1 { - sirf,pins = "usp1grp"; - sirf,function = "usp1"; - }; - }; - usp1_uart_nostreamctrl_pins_a: usp1@1 { - usp1 { - sirf,pins = "usp1_uart_nostreamctrl_grp"; - sirf,function = "usp1_uart_nostreamctrl"; - }; - }; - usb0_upli_drvbus_pins_a: usb0_upli_drvbus@0 { - usb0_upli_drvbus { - sirf,pins = "usb0_upli_drvbusgrp"; - sirf,function = "usb0_upli_drvbus"; - }; - }; - usb1_utmi_drvbus_pins_a: usb1_utmi_drvbus@0 { - usb1_utmi_drvbus { - sirf,pins = "usb1_utmi_drvbusgrp"; - sirf,function = "usb1_utmi_drvbus"; - }; - }; - usb1_dp_dn_pins_a: usb1_dp_dn@0 { - usb1_dp_dn { - sirf,pins = "usb1_dp_dngrp"; - sirf,function = "usb1_dp_dn"; - }; - }; - uart1_route_io_usb1_pins_a: uart1_route_io_usb1@0 { - uart1_route_io_usb1 { - sirf,pins = "uart1_route_io_usb1grp"; - sirf,function = "uart1_route_io_usb1"; - }; - }; - warm_rst_pins_a: warm_rst@0 { - warm_rst { - sirf,pins = "warm_rstgrp"; - sirf,function = "warm_rst"; - }; - }; - pulse_count_pins_a: pulse_count@0 { - pulse_count { - sirf,pins = "pulse_countgrp"; - sirf,function = "pulse_count"; - }; - }; - cko0_pins_a: cko0@0 { - cko0 { - sirf,pins = "cko0grp"; - sirf,function = "cko0"; - }; - }; - cko1_pins_a: cko1@0 { - cko1 { - sirf,pins = "cko1grp"; - sirf,function = "cko1"; - }; - }; - }; - - pwm@b0130000 { - compatible = "sirf,prima2-pwm"; - reg = <0xb0130000 0x10000>; - clocks = <&clks 21>; - }; - - efusesys@b0140000 { - compatible = "sirf,prima2-efuse"; - reg = <0xb0140000 0x10000>; - clocks = <&clks 22>; - }; - - pulsec@b0150000 { - compatible = "sirf,prima2-pulsec"; - reg = <0xb0150000 0x10000>; - interrupts = <48>; - clocks = <&clks 23>; - }; - - pci-iobg { - compatible = "sirf,prima2-pciiobg", "simple-bus"; - #address-cells = <1>; - #size-cells = <1>; - ranges = <0x56000000 0x56000000 0x1b00000>; - - sd0: sdhci@56000000 { - cell-index = <0>; - compatible = "sirf,prima2-sdhc"; - reg = <0x56000000 0x100000>; - interrupts = <38>; - bus-width = <8>; - clocks = <&clks 36>; - }; - - sd1: sdhci@56100000 { - cell-index = <1>; - compatible = "sirf,prima2-sdhc"; - reg = <0x56100000 0x100000>; - interrupts = <38>; - status = "disabled"; - bus-width = <4>; - clocks = <&clks 36>; - }; - - sd2: sdhci@56200000 { - cell-index = <2>; - compatible = "sirf,prima2-sdhc"; - reg = <0x56200000 0x100000>; - interrupts = <23>; - status = "disabled"; - bus-width = <4>; - clocks = <&clks 37>; - }; - - sd3: sdhci@56300000 { - cell-index = <3>; - compatible = "sirf,prima2-sdhc"; - reg = <0x56300000 0x100000>; - interrupts = <23>; - status = "disabled"; - bus-width = <4>; - clocks = <&clks 37>; - }; - - sd5: sdhci@56500000 { - cell-index = <5>; - compatible = "sirf,prima2-sdhc"; - reg = <0x56500000 0x100000>; - interrupts = <39>; - status = "disabled"; - bus-width = <4>; - clocks = <&clks 38>; - }; - - pci-copy@57900000 { - compatible = "sirf,prima2-pcicp"; - reg = <0x57900000 0x100000>; - interrupts = <40>; - }; - - rom-interface@57a00000 { - compatible = "sirf,prima2-romif"; - reg = <0x57a00000 0x100000>; - }; - }; - }; - - rtc-iobg { - compatible = "sirf,prima2-rtciobg", "sirf-prima2-rtciobg-bus", "simple-bus"; - #address-cells = <1>; - #size-cells = <1>; - reg = <0x80030000 0x10000>; - - gpsrtc@1000 { - compatible = "sirf,prima2-gpsrtc"; - reg = <0x1000 0x1000>; - interrupts = <55 56 57>; - }; - - sysrtc@2000 { - compatible = "sirf,prima2-sysrtc"; - reg = <0x2000 0x1000>; - interrupts = <52 53 54>; - }; - - minigpsrtc@2000 { - compatible = "sirf,prima2-minigpsrtc"; - reg = <0x2000 0x1000>; - interrupts = <54>; - }; - - pwrc@3000 { - compatible = "sirf,prima2-pwrc"; - reg = <0x3000 0x1000>; - interrupts = <32>; - }; - }; - - uus-iobg { - compatible = "simple-bus"; - #address-cells = <1>; - #size-cells = <1>; - ranges = <0xb8000000 0xb8000000 0x40000>; - - usb0: usb@b00e0000 { - compatible = "chipidea,ci13611a-prima2"; - reg = <0xb8000000 0x10000>; - interrupts = <10>; - clocks = <&clks 40>; - }; - - usb1: usb@b00f0000 { - compatible = "chipidea,ci13611a-prima2"; - reg = <0xb8010000 0x10000>; - interrupts = <11>; - clocks = <&clks 41>; - }; - - security@b00f0000 { - compatible = "sirf,prima2-security"; - reg = <0xb8030000 0x10000>; - interrupts = <42>; - clocks = <&clks 7>; - }; - }; - }; -}; diff --git a/arch/arm/boot/dts/atlas7-evb.dts b/arch/arm/boot/dts/atlas7-evb.dts deleted file mode 100644 index e0515043d145..000000000000 --- a/arch/arm/boot/dts/atlas7-evb.dts +++ /dev/null @@ -1,127 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * DTS file for CSR SiRFatlas7 Evaluation Board - * - * Copyright (c) 2014 Cambridge Silicon Radio Limited, a CSR plc group company. - */ - -/dts-v1/; - -/include/ "atlas7.dtsi" - -#include -#include - -/ { - model = "CSR SiRFatlas7 Evaluation Board"; - compatible = "sirf,atlas7-cb", "sirf,atlas7"; - - chosen { - bootargs = "console=ttySiRF1,115200 earlyprintk"; - }; - - memory { - device_type = "memory"; - reg = <0x40000000 0x20000000>; - }; - - reserved-memory { - #address-cells = <1>; - #size-cells = <1>; - ranges; - - vpp_reserved: vpp_mem@5e800000 { - compatible = "sirf,reserved-memory"; - reg = <0x5e800000 0x800000>; - }; - - nanddisk_reserved: nanddisk@46000000 { - reg = <0x46000000 0x200000>; - no-map; - }; - }; - - - noc { - mediam { - nand@17050000 { - memory-region = <&nanddisk_reserved>; - }; - }; - - gnssm { - spi1: spi@18200000 { - status = "okay"; - spiflash: macronix@0{ - status = "okay"; - compatible = "macronix,mx25l6405d"; - reg = <0>; - spi-max-frequency = <37500000>; - spi-cpha; - spi-cpol; - #address-cells = <1>; - #size-cells = <1>; - partitions@0 { - label = "myspiboot"; - reg = <0x0 0x800000>; - }; - }; - }; - }; - - btm { - uart6: uart@11000000 { - status = "okay"; - uart-has-rtscts; - }; - }; - - disp-iobg { - vpp@13110000 { - memory-region = <&vpp_reserved>; - }; - }; - - display0: display@0 { - compatible = "lvds-panel"; - source = "lvds.0"; - - bl-gpios = <&gpio_1 63 0>; - data-lines = <24>; - - display-timings { - native-mode = <&timing0>; - timing0: timing0 { - clock-frequency = <60000000>; - hactive = <1024>; - vactive = <600>; - hfront-porch = <220>; - hback-porch = <100>; - hsync-len = <1>; - vback-porch = <10>; - vfront-porch = <25>; - vsync-len = <1>; - hsync-active = <0>; - vsync-active = <0>; - de-active = <1>; - pixelclk-active = <1>; - }; - }; - }; - - gpio_keys { - compatible = "gpio-keys"; - status = "okay"; - #address-cells = <1>; - #size-cells = <0>; - - rearview_key { - label = "rearview key"; - linux,code = ; - gpios = <&gpio_1 3 GPIO_ACTIVE_LOW>; - debounce-interval = <100>; - }; - }; - - }; -}; diff --git a/arch/arm/boot/dts/atlas7.dtsi b/arch/arm/boot/dts/atlas7.dtsi deleted file mode 100644 index 99c9d9d9267f..000000000000 --- a/arch/arm/boot/dts/atlas7.dtsi +++ /dev/null @@ -1,1955 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * DTS file for CSR SiRFatlas7 SoC - * - * Copyright (c) 2014 Cambridge Silicon Radio Limited, a CSR plc group company. - */ - -/ { - compatible = "sirf,atlas7"; - #address-cells = <1>; - #size-cells = <1>; - interrupt-parent = <&gic>; - aliases { - serial0 = &uart0; - serial1 = &uart1; - serial2 = &uart2; - serial3 = &uart3; - serial4 = &uart4; - serial5 = &uart5; - serial6 = &uart6; - serial9 = &usp2; - spi1 = &spi1; - spi2 = &usp1; - spi3 = &usp2; - spi4 = &usp3; - }; - cpus { - #address-cells = <1>; - #size-cells = <0>; - - cpu@0 { - device_type = "cpu"; - compatible = "arm,cortex-a7"; - reg = <0>; - }; - cpu@1 { - device_type = "cpu"; - compatible = "arm,cortex-a7"; - reg = <1>; - }; - }; - - clocks { - xinw { - compatible = "fixed-clock"; - #clock-cells = <0>; - clock-frequency = <32768>; - clock-output-names = "xinw"; - }; - xin { - compatible = "fixed-clock"; - #clock-cells = <0>; - clock-frequency = <26000000>; - clock-output-names = "xin"; - }; - }; - - arm-pmu { - compatible = "arm,cortex-a7-pmu"; - interrupts = <0 29 4>, <0 82 4>; - }; - - noc { - compatible = "simple-bus"; - #address-cells = <1>; - #size-cells = <1>; - ranges = <0x10000000 0x10000000 0xc0000000>; - - gic: interrupt-controller@10301000 { - compatible = "arm,cortex-a9-gic"; - interrupt-controller; - #interrupt-cells = <3>; - reg = <0x10301000 0x1000>, - <0x10302000 0x0100>; - }; - - pmu_regulator: pmu_regulator@10E30020 { - compatible = "sirf,atlas7-pmu-ldo"; - reg = <0x10E30020 0x4>; - ldo: ldo { - regulator-name = "ldo"; - }; - }; - - atlas7_codec: atlas7_codec@10E30000 { - #sound-dai-cells = <0>; - compatible = "sirf,atlas7-codec"; - reg = <0x10E30000 0x400>; - clocks = <&car 62>; - ldo-supply = <&ldo>; - }; - - atlas7_iacc: atlas7_iacc@10D01000 { - #sound-dai-cells = <0>; - compatible = "sirf,atlas7-iacc"; - reg = <0x10D01000 0x100>; - dmas = <&dmac3 0>, <&dmac3 7>, <&dmac3 8>, - <&dmac3 3>, <&dmac3 9>; - dma-names = "rx", "tx0", "tx1", "tx2", "tx3"; - clocks = <&car 62>; - }; - - ipc@13240000 { - compatible = "sirf,atlas7-ipc"; - ranges = <0x13240000 0x13240000 0x00010000>; - #address-cells = <1>; - #size-cells = <1>; - - hwspinlock { - compatible = "sirf,hwspinlock"; - reg = <0x13240000 0x00010000>; - - num-spinlocks = <30>; - }; - - ns_m3_rproc@0 { - compatible = "sirf,ns2m30-rproc"; - reg = <0x13240000 0x00010000>; - interrupts = <0 123 0>; - }; - - ns_m3_rproc@1 { - compatible = "sirf,ns2m31-rproc"; - reg = <0x13240000 0x00010000>; - interrupts = <0 126 0>; - }; - - ns_kal_rproc@0 { - compatible = "sirf,ns2kal0-rproc"; - reg = <0x13240000 0x00010000>; - interrupts = <0 124 0>; - }; - - ns_kal_rproc@1 { - compatible = "sirf,ns2kal1-rproc"; - reg = <0x13240000 0x00010000>; - interrupts = <0 127 0>; - }; - }; - - pinctrl: ioc@18880000 { - compatible = "sirf,atlas7-ioc"; - reg = <0x18880000 0x1000>, - <0x10E40000 0x1000>; - - audio_ac97_pmx: audio_ac97@0 { - audio_ac97 { - groups = "audio_ac97_grp"; - function = "audio_ac97"; - }; - }; - - audio_func_dbg_pmx: audio_func_dbg@0 { - audio_func_dbg { - groups = "audio_func_dbg_grp"; - function = "audio_func_dbg"; - }; - }; - - audio_i2s_pmx: audio_i2s@0 { - audio_i2s { - groups = "audio_i2s_grp"; - function = "audio_i2s"; - }; - }; - - audio_i2s_2ch_pmx: audio_i2s_2ch@0 { - audio_i2s_2ch { - groups = "audio_i2s_2ch_grp"; - function = "audio_i2s_2ch"; - }; - }; - - audio_i2s_extclk_pmx: audio_i2s_extclk@0 { - audio_i2s_extclk { - groups = "audio_i2s_extclk_grp"; - function = "audio_i2s_extclk"; - }; - }; - - audio_uart0_pmx: audio_uart0@0 { - audio_uart0 { - groups = "audio_uart0_grp"; - function = "audio_uart0"; - }; - }; - - audio_uart1_pmx: audio_uart1@0 { - audio_uart1 { - groups = "audio_uart1_grp"; - function = "audio_uart1"; - }; - }; - - audio_uart2_pmx0: audio_uart2@0 { - audio_uart2_0 { - groups = "audio_uart2_grp0"; - function = "audio_uart2_m0"; - }; - }; - - audio_uart2_pmx1: audio_uart2@1 { - audio_uart2_1 { - groups = "audio_uart2_grp1"; - function = "audio_uart2_m1"; - }; - }; - - c_can_trnsvr_pmx: c_can_trnsvr@0 { - c_can_trnsvr { - groups = "c_can_trnsvr_grp"; - function = "c_can_trnsvr"; - }; - }; - - c0_can_pmx0: c0_can@0 { - c0_can_0 { - groups = "c0_can_grp0"; - function = "c0_can_m0"; - }; - }; - - c0_can_pmx1: c0_can@1 { - c0_can_1 { - groups = "c0_can_grp1"; - function = "c0_can_m1"; - }; - }; - - c1_can_pmx0: c1_can@0 { - c1_can_0 { - groups = "c1_can_grp0"; - function = "c1_can_m0"; - }; - }; - - c1_can_pmx1: c1_can@1 { - c1_can_1 { - groups = "c1_can_grp1"; - function = "c1_can_m1"; - }; - }; - - c1_can_pmx2: c1_can@2 { - c1_can_2 { - groups = "c1_can_grp2"; - function = "c1_can_m2"; - }; - }; - - ca_audio_lpc_pmx: ca_audio_lpc@0 { - ca_audio_lpc { - groups = "ca_audio_lpc_grp"; - function = "ca_audio_lpc"; - }; - }; - - ca_bt_lpc_pmx: ca_bt_lpc@0 { - ca_bt_lpc { - groups = "ca_bt_lpc_grp"; - function = "ca_bt_lpc"; - }; - }; - - ca_coex_pmx: ca_coex@0 { - ca_coex { - groups = "ca_coex_grp"; - function = "ca_coex"; - }; - }; - - ca_curator_lpc_pmx: ca_curator_lpc@0 { - ca_curator_lpc { - groups = "ca_curator_lpc_grp"; - function = "ca_curator_lpc"; - }; - }; - - ca_pcm_debug_pmx: ca_pcm_debug@0 { - ca_pcm_debug { - groups = "ca_pcm_debug_grp"; - function = "ca_pcm_debug"; - }; - }; - - ca_pio_pmx: ca_pio@0 { - ca_pio { - groups = "ca_pio_grp"; - function = "ca_pio"; - }; - }; - - ca_sdio_debug_pmx: ca_sdio_debug@0 { - ca_sdio_debug { - groups = "ca_sdio_debug_grp"; - function = "ca_sdio_debug"; - }; - }; - - ca_spi_pmx: ca_spi@0 { - ca_spi { - groups = "ca_spi_grp"; - function = "ca_spi"; - }; - }; - - ca_trb_pmx: ca_trb@0 { - ca_trb { - groups = "ca_trb_grp"; - function = "ca_trb"; - }; - }; - - ca_uart_debug_pmx: ca_uart_debug@0 { - ca_uart_debug { - groups = "ca_uart_debug_grp"; - function = "ca_uart_debug"; - }; - }; - - clkc_pmx0: clkc@0 { - clkc_0 { - groups = "clkc_grp0"; - function = "clkc_m0"; - }; - }; - - clkc_pmx1: clkc@1 { - clkc_1 { - groups = "clkc_grp1"; - function = "clkc_m1"; - }; - }; - - gn_gnss_i2c_pmx: gn_gnss_i2c@0 { - gn_gnss_i2c { - groups = "gn_gnss_i2c_grp"; - function = "gn_gnss_i2c"; - }; - }; - - gn_gnss_uart_nopause_pmx: gn_gnss_uart_nopause@0 { - gn_gnss_uart_nopause { - groups = "gn_gnss_uart_nopause_grp"; - function = "gn_gnss_uart_nopause"; - }; - }; - - gn_gnss_uart_pmx: gn_gnss_uart@0 { - gn_gnss_uart { - groups = "gn_gnss_uart_grp"; - function = "gn_gnss_uart"; - }; - }; - - gn_trg_spi_pmx0: gn_trg_spi@0 { - gn_trg_spi_0 { - groups = "gn_trg_spi_grp0"; - function = "gn_trg_spi_m0"; - }; - }; - - gn_trg_spi_pmx1: gn_trg_spi@1 { - gn_trg_spi_1 { - groups = "gn_trg_spi_grp1"; - function = "gn_trg_spi_m1"; - }; - }; - - cvbs_dbg_pmx: cvbs_dbg@0 { - cvbs_dbg { - groups = "cvbs_dbg_grp"; - function = "cvbs_dbg"; - }; - }; - - cvbs_dbg_test_pmx0: cvbs_dbg_test@0 { - cvbs_dbg_test_0 { - groups = "cvbs_dbg_test_grp0"; - function = "cvbs_dbg_test_m0"; - }; - }; - - cvbs_dbg_test_pmx1: cvbs_dbg_test@1 { - cvbs_dbg_test_1 { - groups = "cvbs_dbg_test_grp1"; - function = "cvbs_dbg_test_m1"; - }; - }; - - cvbs_dbg_test_pmx2: cvbs_dbg_test@2 { - cvbs_dbg_test_2 { - groups = "cvbs_dbg_test_grp2"; - function = "cvbs_dbg_test_m2"; - }; - }; - - cvbs_dbg_test_pmx3: cvbs_dbg_test@3 { - cvbs_dbg_test_3 { - groups = "cvbs_dbg_test_grp3"; - function = "cvbs_dbg_test_m3"; - }; - }; - - cvbs_dbg_test_pmx4: cvbs_dbg_test@4 { - cvbs_dbg_test_4 { - groups = "cvbs_dbg_test_grp4"; - function = "cvbs_dbg_test_m4"; - }; - }; - - cvbs_dbg_test_pmx5: cvbs_dbg_test@5 { - cvbs_dbg_test_5 { - groups = "cvbs_dbg_test_grp5"; - function = "cvbs_dbg_test_m5"; - }; - }; - - cvbs_dbg_test_pmx6: cvbs_dbg_test@6 { - cvbs_dbg_test_6 { - groups = "cvbs_dbg_test_grp6"; - function = "cvbs_dbg_test_m6"; - }; - }; - - cvbs_dbg_test_pmx7: cvbs_dbg_test@7 { - cvbs_dbg_test_7 { - groups = "cvbs_dbg_test_grp7"; - function = "cvbs_dbg_test_m7"; - }; - }; - - cvbs_dbg_test_pmx8: cvbs_dbg_test@8 { - cvbs_dbg_test_8 { - groups = "cvbs_dbg_test_grp8"; - function = "cvbs_dbg_test_m8"; - }; - }; - - cvbs_dbg_test_pmx9: cvbs_dbg_test@9 { - cvbs_dbg_test_9 { - groups = "cvbs_dbg_test_grp9"; - function = "cvbs_dbg_test_m9"; - }; - }; - - cvbs_dbg_test_pmx10: cvbs_dbg_test@10 { - cvbs_dbg_test_10 { - groups = "cvbs_dbg_test_grp10"; - function = "cvbs_dbg_test_m10"; - }; - }; - - cvbs_dbg_test_pmx11: cvbs_dbg_test@11 { - cvbs_dbg_test_11 { - groups = "cvbs_dbg_test_grp11"; - function = "cvbs_dbg_test_m11"; - }; - }; - - cvbs_dbg_test_pmx12: cvbs_dbg_test@12 { - cvbs_dbg_test_12 { - groups = "cvbs_dbg_test_grp12"; - function = "cvbs_dbg_test_m12"; - }; - }; - - cvbs_dbg_test_pmx13: cvbs_dbg_test@13 { - cvbs_dbg_test_13 { - groups = "cvbs_dbg_test_grp13"; - function = "cvbs_dbg_test_m13"; - }; - }; - - cvbs_dbg_test_pmx14: cvbs_dbg_test@14 { - cvbs_dbg_test_14 { - groups = "cvbs_dbg_test_grp14"; - function = "cvbs_dbg_test_m14"; - }; - }; - - cvbs_dbg_test_pmx15: cvbs_dbg_test@15 { - cvbs_dbg_test_15 { - groups = "cvbs_dbg_test_grp15"; - function = "cvbs_dbg_test_m15"; - }; - }; - - gn_gnss_power_pmx: gn_gnss_power@0 { - gn_gnss_power { - groups = "gn_gnss_power_grp"; - function = "gn_gnss_power"; - }; - }; - - gn_gnss_sw_status_pmx: gn_gnss_sw_status@0 { - gn_gnss_sw_status { - groups = "gn_gnss_sw_status_grp"; - function = "gn_gnss_sw_status"; - }; - }; - - gn_gnss_eclk_pmx: gn_gnss_eclk@0 { - gn_gnss_eclk { - groups = "gn_gnss_eclk_grp"; - function = "gn_gnss_eclk"; - }; - }; - - gn_gnss_irq1_pmx0: gn_gnss_irq1@0 { - gn_gnss_irq1_0 { - groups = "gn_gnss_irq1_grp0"; - function = "gn_gnss_irq1_m0"; - }; - }; - - gn_gnss_irq2_pmx0: gn_gnss_irq2@0 { - gn_gnss_irq2_0 { - groups = "gn_gnss_irq2_grp0"; - function = "gn_gnss_irq2_m0"; - }; - }; - - gn_gnss_tm_pmx: gn_gnss_tm@0 { - gn_gnss_tm { - groups = "gn_gnss_tm_grp"; - function = "gn_gnss_tm"; - }; - }; - - gn_gnss_tsync_pmx: gn_gnss_tsync@0 { - gn_gnss_tsync { - groups = "gn_gnss_tsync_grp"; - function = "gn_gnss_tsync"; - }; - }; - - gn_io_gnsssys_sw_cfg_pmx: gn_io_gnsssys_sw_cfg@0 { - gn_io_gnsssys_sw_cfg { - groups = "gn_io_gnsssys_sw_cfg_grp"; - function = "gn_io_gnsssys_sw_cfg"; - }; - }; - - gn_trg_pmx0: gn_trg@0 { - gn_trg_0 { - groups = "gn_trg_grp0"; - function = "gn_trg_m0"; - }; - }; - - gn_trg_pmx1: gn_trg@1 { - gn_trg_1 { - groups = "gn_trg_grp1"; - function = "gn_trg_m1"; - }; - }; - - gn_trg_shutdown_pmx0: gn_trg_shutdown@0 { - gn_trg_shutdown_0 { - groups = "gn_trg_shutdown_grp0"; - function = "gn_trg_shutdown_m0"; - }; - }; - - gn_trg_shutdown_pmx1: gn_trg_shutdown@1 { - gn_trg_shutdown_1 { - groups = "gn_trg_shutdown_grp1"; - function = "gn_trg_shutdown_m1"; - }; - }; - - gn_trg_shutdown_pmx2: gn_trg_shutdown@2 { - gn_trg_shutdown_2 { - groups = "gn_trg_shutdown_grp2"; - function = "gn_trg_shutdown_m2"; - }; - }; - - gn_trg_shutdown_pmx3: gn_trg_shutdown@3 { - gn_trg_shutdown_3 { - groups = "gn_trg_shutdown_grp3"; - function = "gn_trg_shutdown_m3"; - }; - }; - - i2c0_pmx: i2c0@0 { - i2c0 { - groups = "i2c0_grp"; - function = "i2c0"; - }; - }; - - i2c1_pmx: i2c1@0 { - i2c1 { - groups = "i2c1_grp"; - function = "i2c1"; - }; - }; - - jtag_pmx0: jtag@0 { - jtag_0 { - groups = "jtag_grp0"; - function = "jtag_m0"; - }; - }; - - ks_kas_spi_pmx0: ks_kas_spi@0 { - ks_kas_spi_0 { - groups = "ks_kas_spi_grp0"; - function = "ks_kas_spi_m0"; - }; - }; - - ld_ldd_pmx: ld_ldd@0 { - ld_ldd { - groups = "ld_ldd_grp"; - function = "ld_ldd"; - }; - }; - - ld_ldd_16bit_pmx: ld_ldd_16bit@0 { - ld_ldd_16bit { - groups = "ld_ldd_16bit_grp"; - function = "ld_ldd_16bit"; - }; - }; - - ld_ldd_fck_pmx: ld_ldd_fck@0 { - ld_ldd_fck { - groups = "ld_ldd_fck_grp"; - function = "ld_ldd_fck"; - }; - }; - - ld_ldd_lck_pmx: ld_ldd_lck@0 { - ld_ldd_lck { - groups = "ld_ldd_lck_grp"; - function = "ld_ldd_lck"; - }; - }; - - lr_lcdrom_pmx: lr_lcdrom@0 { - lr_lcdrom { - groups = "lr_lcdrom_grp"; - function = "lr_lcdrom"; - }; - }; - - lvds_analog_pmx: lvds_analog@0 { - lvds_analog { - groups = "lvds_analog_grp"; - function = "lvds_analog"; - }; - }; - - nd_df_pmx: nd_df@0 { - nd_df { - groups = "nd_df_grp"; - function = "nd_df"; - }; - }; - - nd_df_nowp_pmx: nd_df_nowp@0 { - nd_df_nowp { - groups = "nd_df_nowp_grp"; - function = "nd_df_nowp"; - }; - }; - - ps_pmx: ps@0 { - ps { - groups = "ps_grp"; - function = "ps"; - }; - }; - - pwc_core_on_pmx: pwc_core_on@0 { - pwc_core_on { - groups = "pwc_core_on_grp"; - function = "pwc_core_on"; - }; - }; - - pwc_ext_on_pmx: pwc_ext_on@0 { - pwc_ext_on { - groups = "pwc_ext_on_grp"; - function = "pwc_ext_on"; - }; - }; - - pwc_gpio3_clk_pmx: pwc_gpio3_clk@0 { - pwc_gpio3_clk { - groups = "pwc_gpio3_clk_grp"; - function = "pwc_gpio3_clk"; - }; - }; - - pwc_io_on_pmx: pwc_io_on@0 { - pwc_io_on { - groups = "pwc_io_on_grp"; - function = "pwc_io_on"; - }; - }; - - pwc_lowbatt_b_pmx0: pwc_lowbatt_b@0 { - pwc_lowbatt_b_0 { - groups = "pwc_lowbatt_b_grp0"; - function = "pwc_lowbatt_b_m0"; - }; - }; - - pwc_mem_on_pmx: pwc_mem_on@0 { - pwc_mem_on { - groups = "pwc_mem_on_grp"; - function = "pwc_mem_on"; - }; - }; - - pwc_on_key_b_pmx0: pwc_on_key_b@0 { - pwc_on_key_b_0 { - groups = "pwc_on_key_b_grp0"; - function = "pwc_on_key_b_m0"; - }; - }; - - pwc_wakeup_src0_pmx: pwc_wakeup_src0@0 { - pwc_wakeup_src0 { - groups = "pwc_wakeup_src0_grp"; - function = "pwc_wakeup_src0"; - }; - }; - - pwc_wakeup_src1_pmx: pwc_wakeup_src1@0 { - pwc_wakeup_src1 { - groups = "pwc_wakeup_src1_grp"; - function = "pwc_wakeup_src1"; - }; - }; - - pwc_wakeup_src2_pmx: pwc_wakeup_src2@0 { - pwc_wakeup_src2 { - groups = "pwc_wakeup_src2_grp"; - function = "pwc_wakeup_src2"; - }; - }; - - pwc_wakeup_src3_pmx: pwc_wakeup_src3@0 { - pwc_wakeup_src3 { - groups = "pwc_wakeup_src3_grp"; - function = "pwc_wakeup_src3"; - }; - }; - - pw_cko0_pmx0: pw_cko0@0 { - pw_cko0_0 { - groups = "pw_cko0_grp0"; - function = "pw_cko0_m0"; - }; - }; - - pw_cko0_pmx1: pw_cko0@1 { - pw_cko0_1 { - groups = "pw_cko0_grp1"; - function = "pw_cko0_m1"; - }; - }; - - pw_cko0_pmx2: pw_cko0@2 { - pw_cko0_2 { - groups = "pw_cko0_grp2"; - function = "pw_cko0_m2"; - }; - }; - - pw_cko1_pmx0: pw_cko1@0 { - pw_cko1_0 { - groups = "pw_cko1_grp0"; - function = "pw_cko1_m0"; - }; - }; - - pw_cko1_pmx1: pw_cko1@1 { - pw_cko1_1 { - groups = "pw_cko1_grp1"; - function = "pw_cko1_m1"; - }; - }; - - pw_i2s01_clk_pmx0: pw_i2s01_clk@0 { - pw_i2s01_clk_0 { - groups = "pw_i2s01_clk_grp0"; - function = "pw_i2s01_clk_m0"; - }; - }; - - pw_i2s01_clk_pmx1: pw_i2s01_clk@1 { - pw_i2s01_clk_1 { - groups = "pw_i2s01_clk_grp1"; - function = "pw_i2s01_clk_m1"; - }; - }; - - pw_pwm0_pmx: pw_pwm0@0 { - pw_pwm0 { - groups = "pw_pwm0_grp"; - function = "pw_pwm0"; - }; - }; - - pw_pwm1_pmx: pw_pwm1@0 { - pw_pwm1 { - groups = "pw_pwm1_grp"; - function = "pw_pwm1"; - }; - }; - - pw_pwm2_pmx0: pw_pwm2@0 { - pw_pwm2_0 { - groups = "pw_pwm2_grp0"; - function = "pw_pwm2_m0"; - }; - }; - - pw_pwm2_pmx1: pw_pwm2@1 { - pw_pwm2_1 { - groups = "pw_pwm2_grp1"; - function = "pw_pwm2_m1"; - }; - }; - - pw_pwm3_pmx0: pw_pwm3@0 { - pw_pwm3_0 { - groups = "pw_pwm3_grp0"; - function = "pw_pwm3_m0"; - }; - }; - - pw_pwm3_pmx1: pw_pwm3@1 { - pw_pwm3_1 { - groups = "pw_pwm3_grp1"; - function = "pw_pwm3_m1"; - }; - }; - - pw_pwm_cpu_vol_pmx0: pw_pwm_cpu_vol@0 { - pw_pwm_cpu_vol_0 { - groups = "pw_pwm_cpu_vol_grp0"; - function = "pw_pwm_cpu_vol_m0"; - }; - }; - - pw_pwm_cpu_vol_pmx1: pw_pwm_cpu_vol@1 { - pw_pwm_cpu_vol_1 { - groups = "pw_pwm_cpu_vol_grp1"; - function = "pw_pwm_cpu_vol_m1"; - }; - }; - - pw_backlight_pmx0: pw_backlight@0 { - pw_backlight_0 { - groups = "pw_backlight_grp0"; - function = "pw_backlight_m0"; - }; - }; - - pw_backlight_pmx1: pw_backlight@1 { - pw_backlight_1 { - groups = "pw_backlight_grp1"; - function = "pw_backlight_m1"; - }; - }; - - rg_eth_mac_pmx: rg_eth_mac@0 { - rg_eth_mac { - groups = "rg_eth_mac_grp"; - function = "rg_eth_mac"; - }; - }; - - rg_gmac_phy_intr_n_pmx: rg_gmac_phy_intr_n@0 { - rg_gmac_phy_intr_n { - groups = "rg_gmac_phy_intr_n_grp"; - function = "rg_gmac_phy_intr_n"; - }; - }; - - rg_rgmii_mac_pmx: rg_rgmii_mac@0 { - rg_rgmii_mac { - groups = "rg_rgmii_mac_grp"; - function = "rg_rgmii_mac"; - }; - }; - - rg_rgmii_phy_ref_clk_pmx0: rg_rgmii_phy_ref_clk@0 { - rg_rgmii_phy_ref_clk_0 { - groups = - "rg_rgmii_phy_ref_clk_grp0"; - function = - "rg_rgmii_phy_ref_clk_m0"; - }; - }; - - rg_rgmii_phy_ref_clk_pmx1: rg_rgmii_phy_ref_clk@1 { - rg_rgmii_phy_ref_clk_1 { - groups = - "rg_rgmii_phy_ref_clk_grp1"; - function = - "rg_rgmii_phy_ref_clk_m1"; - }; - }; - - sd0_pmx: sd0@0 { - sd0 { - groups = "sd0_grp"; - function = "sd0"; - }; - }; - - sd0_4bit_pmx: sd0_4bit@0 { - sd0_4bit { - groups = "sd0_4bit_grp"; - function = "sd0_4bit"; - }; - }; - - sd1_pmx: sd1@0 { - sd1 { - groups = "sd1_grp"; - function = "sd1"; - }; - }; - - sd1_4bit_pmx0: sd1_4bit@0 { - sd1_4bit_0 { - groups = "sd1_4bit_grp0"; - function = "sd1_4bit_m0"; - }; - }; - - sd1_4bit_pmx1: sd1_4bit@1 { - sd1_4bit_1 { - groups = "sd1_4bit_grp1"; - function = "sd1_4bit_m1"; - }; - }; - - sd2_pmx0: sd2@0 { - sd2_0 { - groups = "sd2_grp0"; - function = "sd2_m0"; - }; - }; - - sd2_no_cdb_pmx0: sd2_no_cdb@0 { - sd2_no_cdb_0 { - groups = "sd2_no_cdb_grp0"; - function = "sd2_no_cdb_m0"; - }; - }; - - sd3_pmx: sd3@0 { - sd3 { - groups = "sd3_grp"; - function = "sd3"; - }; - }; - - sd5_pmx: sd5@0 { - sd5 { - groups = "sd5_grp"; - function = "sd5"; - }; - }; - - sd6_pmx0: sd6@0 { - sd6_0 { - groups = "sd6_grp0"; - function = "sd6_m0"; - }; - }; - - sd6_pmx1: sd6@1 { - sd6_1 { - groups = "sd6_grp1"; - function = "sd6_m1"; - }; - }; - - sp0_ext_ldo_on_pmx: sp0_ext_ldo_on@0 { - sp0_ext_ldo_on { - groups = "sp0_ext_ldo_on_grp"; - function = "sp0_ext_ldo_on"; - }; - }; - - sp0_qspi_pmx: sp0_qspi@0 { - sp0_qspi { - groups = "sp0_qspi_grp"; - function = "sp0_qspi"; - }; - }; - - sp1_spi_pmx: sp1_spi@0 { - sp1_spi { - groups = "sp1_spi_grp"; - function = "sp1_spi"; - }; - }; - - tpiu_trace_pmx: tpiu_trace@0 { - tpiu_trace { - groups = "tpiu_trace_grp"; - function = "tpiu_trace"; - }; - }; - - uart0_pmx: uart0@0 { - uart0 { - groups = "uart0_grp"; - function = "uart0"; - }; - }; - - uart0_nopause_pmx: uart0_nopause@0 { - uart0_nopause { - groups = "uart0_nopause_grp"; - function = "uart0_nopause"; - }; - }; - - uart1_pmx: uart1@0 { - uart1 { - groups = "uart1_grp"; - function = "uart1"; - }; - }; - - uart2_pmx: uart2@0 { - uart2 { - groups = "uart2_grp"; - function = "uart2"; - }; - }; - - uart3_pmx0: uart3@0 { - uart3_0 { - groups = "uart3_grp0"; - function = "uart3_m0"; - }; - }; - - uart3_pmx1: uart3@1 { - uart3_1 { - groups = "uart3_grp1"; - function = "uart3_m1"; - }; - }; - - uart3_pmx2: uart3@2 { - uart3_2 { - groups = "uart3_grp2"; - function = "uart3_m2"; - }; - }; - - uart3_pmx3: uart3@3 { - uart3_3 { - groups = "uart3_grp3"; - function = "uart3_m3"; - }; - }; - - uart3_nopause_pmx0: uart3_nopause@0 { - uart3_nopause_0 { - groups = "uart3_nopause_grp0"; - function = "uart3_nopause_m0"; - }; - }; - - uart3_nopause_pmx1: uart3_nopause@1 { - uart3_nopause_1 { - groups = "uart3_nopause_grp1"; - function = "uart3_nopause_m1"; - }; - }; - - uart4_pmx0: uart4@0 { - uart4_0 { - groups = "uart4_grp0"; - function = "uart4_m0"; - }; - }; - - uart4_pmx1: uart4@1 { - uart4_1 { - groups = "uart4_grp1"; - function = "uart4_m1"; - }; - }; - - uart4_pmx2: uart4@2 { - uart4_2 { - groups = "uart4_grp2"; - function = "uart4_m2"; - }; - }; - - uart4_nopause_pmx: uart4_nopause@0 { - uart4_nopause { - groups = "uart4_nopause_grp"; - function = "uart4_nopause"; - }; - }; - - usb0_drvvbus_pmx: usb0_drvvbus@0 { - usb0_drvvbus { - groups = "usb0_drvvbus_grp"; - function = "usb0_drvvbus"; - }; - }; - - usb1_drvvbus_pmx: usb1_drvvbus@0 { - usb1_drvvbus { - groups = "usb1_drvvbus_grp"; - function = "usb1_drvvbus"; - }; - }; - - visbus_dout_pmx: visbus_dout@0 { - visbus_dout { - groups = "visbus_dout_grp"; - function = "visbus_dout"; - }; - }; - - vi_vip1_pmx: vi_vip1@0 { - vi_vip1 { - groups = "vi_vip1_grp"; - function = "vi_vip1"; - }; - }; - - vi_vip1_ext_pmx: vi_vip1_ext@0 { - vi_vip1_ext { - groups = "vi_vip1_ext_grp"; - function = "vi_vip1_ext"; - }; - }; - - vi_vip1_low8bit_pmx: vi_vip1_low8bit@0 { - vi_vip1_low8bit { - groups = "vi_vip1_low8bit_grp"; - function = "vi_vip1_low8bit"; - }; - }; - - vi_vip1_high8bit_pmx: vi_vip1_high8bit@0 { - vi_vip1_high8bit { - groups = "vi_vip1_high8bit_grp"; - function = "vi_vip1_high8bit"; - }; - }; - }; - - pmipc { - compatible = "arteris, flexnoc", "simple-bus"; - #address-cells = <1>; - #size-cells = <1>; - ranges = <0x13240000 0x13240000 0x00010000>; - pmipc@0x13240000 { - compatible = "sirf,atlas7-pmipc"; - reg = <0x13240000 0x00010000>; - }; - }; - - dramfw { - compatible = "arteris, flexnoc", "simple-bus"; - #address-cells = <1>; - #size-cells = <1>; - ranges = <0x10830000 0x10830000 0x18000>; - dramfw@10820000 { - compatible = "sirf,nocfw-dramfw"; - reg = <0x10830000 0x18000>; - }; - }; - - spramfw { - compatible = "arteris, flexnoc", "simple-bus"; - #address-cells = <1>; - #size-cells = <1>; - ranges = <0x10250000 0x10250000 0x3000>; - spramfw@10820000 { - compatible = "sirf,nocfw-spramfw"; - reg = <0x10250000 0x3000>; - }; - }; - - cpum { - compatible = "arteris, flexnoc", "simple-bus"; - #address-cells = <1>; - #size-cells = <1>; - ranges = <0x10200000 0x10200000 0x3000>; - cpum@10200000 { - compatible = "sirf,nocfw-cpum"; - reg = <0x10200000 0x3000>; - }; - }; - - cgum { - compatible = "arteris, flexnoc", "simple-bus"; - #address-cells = <1>; - #size-cells = <1>; - ranges = <0x18641000 0x18641000 0x3000>, - <0x18620000 0x18620000 0x1000>, - <0x18630000 0x18630000 0x10000>; - - cgum@18641000 { - compatible = "sirf,nocfw-cgum"; - reg = <0x18641000 0x3000>; - }; - - car: clock-controller@18620000 { - compatible = "sirf,atlas7-car"; - reg = <0x18620000 0x1000>; - #clock-cells = <1>; - #reset-cells = <1>; - }; - pwm: pwm@18630000 { - compatible = "sirf,prima2-pwm"; - #pwm-cells = <2>; - reg = <0x18630000 0x10000>; - clocks = <&car 138>, <&car 139>, <&car 237>, - <&car 240>, <&car 140>, <&car 246>; - clock-names = "pwmc", "sigsrc0", "sigsrc1", - "sigsrc2", "sigsrc3", "sigsrc4"; - }; - }; - - gnssm { - compatible = "arteris, flexnoc", "simple-bus"; - #address-cells = <1>; - #size-cells = <1>; - ranges = <0x18000000 0x18000000 0x0000ffff>, - <0x18010000 0x18010000 0x1000>, - <0x18020000 0x18020000 0x1000>, - <0x18030000 0x18030000 0x1000>, - <0x18040000 0x18040000 0x1000>, - <0x18050000 0x18050000 0x1000>, - <0x18060000 0x18060000 0x1000>, - <0x180b0000 0x180b0000 0x4000>, - <0x18100000 0x18100000 0x3000>, - <0x18250000 0x18250000 0x10000>, - <0x18200000 0x18200000 0x1000>; - - dmac0: dma-controller@18000000 { - cell-index = <0>; - compatible = "sirf,atlas7-dmac"; - reg = <0x18000000 0x1000>; - interrupts = <0 12 0>; - clocks = <&car 89>; - dma-channels = <16>; - #dma-cells = <1>; - }; - - gnssmfw@0x18100000 { - compatible = "sirf,nocfw-gnssm"; - reg = <0x18100000 0x3000>; - }; - - uart0: uart@18010000 { - cell-index = <0>; - compatible = "sirf,atlas7-uart"; - reg = <0x18010000 0x1000>; - interrupts = <0 17 0>; - clocks = <&car 90>; - fifosize = <128>; - dmas = <&dmac0 3>, <&dmac0 2>; - dma-names = "rx", "tx"; - }; - - uart1: uart@18020000 { - cell-index = <1>; - compatible = "sirf,atlas7-uart"; - reg = <0x18020000 0x1000>; - interrupts = <0 18 0>; - clocks = <&car 88>; - fifosize = <32>; - }; - - uart2: uart@18030000 { - cell-index = <2>; - compatible = "sirf,atlas7-uart"; - reg = <0x18030000 0x1000>; - interrupts = <0 19 0>; - clocks = <&car 91>; - fifosize = <128>; - dmas = <&dmac0 6>, <&dmac0 7>; - dma-names = "rx", "tx"; - status = "disabled"; - }; - uart3: uart@18040000 { - cell-index = <3>; - compatible = "sirf,atlas7-uart"; - reg = <0x18040000 0x1000>; - interrupts = <0 66 0>; - clocks = <&car 92>; - fifosize = <128>; - dmas = <&dmac0 4>, <&dmac0 5>; - dma-names = "rx", "tx"; - status = "disabled"; - }; - uart4: uart@18050000 { - cell-index = <4>; - compatible = "sirf,atlas7-uart"; - reg = <0x18050000 0x1000>; - interrupts = <0 69 0>; - clocks = <&car 93>; - fifosize = <128>; - dmas = <&dmac0 0>, <&dmac0 1>; - dma-names = "rx", "tx"; - status = "disabled"; - }; - uart5: uart@18060000 { - cell-index = <5>; - compatible = "sirf,atlas7-uart"; - reg = <0x18060000 0x1000>; - interrupts = <0 71 0>; - clocks = <&car 94>; - fifosize = <128>; - dmas = <&dmac0 8>, <&dmac0 9>; - dma-names = "rx", "tx"; - status = "disabled"; - }; - gmac: eth@180b0000 { - compatible = "snps, dwc-eth-qos"; - reg = <0x180b0000 0x4000>; - interrupts = <0 59 0>, <0 70 0>; - interrupt-names = "macirq", "macpmt"; - clocks = <&car 39>, <&car 45>, - <&car 86>, <&car 87>; - clock-names = "gnssm_rgmii", "gnssm_gmac", - "rgmii", "gmac"; - local-mac-address = [00 00 00 00 00 00]; - phy-mode = "rgmii"; - }; - dspub@18250000 { - compatible = "dx,cc44p"; - reg = <0x18250000 0x10000>; - interrupts = <0 27 0>; - }; - - spi1: spi@18200000 { - compatible = "sirf,prima2-spi"; - reg = <0x18200000 0x1000>; - interrupts = <0 16 0>; - clocks = <&car 95>; - #address-cells = <1>; - #size-cells = <0>; - dmas = <&dmac0 12>, <&dmac0 13>; - dma-names = "rx", "tx"; - status = "disabled"; - }; - }; - - - gpum { - compatible = "arteris, flexnoc", "simple-bus"; - #address-cells = <1>; - #size-cells = <1>; - ranges = <0x13000000 0x13000000 0x3000>, - <0x13010000 0x13010000 0x1400>, - <0x13010800 0x13010800 0x100>, - <0x13011000 0x13011000 0x100>; - gpum@0x13000000 { - compatible = "sirf,nocfw-gpum"; - reg = <0x13000000 0x3000>; - }; - dmacsdrr: dma-controller@13010800 { - cell-index = <5>; - compatible = "sirf,atlas7-dmac-v2"; - reg = <0x13010800 0x100>; - interrupts = <0 8 0>; - clocks = <&car 127>; - #dma-cells = <1>; - #dma-channels = <1>; - }; - dmacsdrw: dma-controller@13011000 { - cell-index = <6>; - compatible = "sirf,atlas7-dmac-v2"; - reg = <0x13011000 0x100>; - interrupts = <0 9 0>; - clocks = <&car 127>; - #dma-cells = <1>; - #dma-channels = <1>; - }; - sdr@0x13010000 { - compatible = "sirf,atlas7-sdr"; - reg = <0x13010000 0x1400>; - interrupts = <0 7 0>, - <0 8 0>, - <0 9 0>; - clocks = <&car 127>; - dmas = <&dmacsdrr 0>, <&dmacsdrw 0>; - dma-names = "tx", "rx"; - }; - }; - - mediam { - compatible = "arteris, flexnoc", "simple-bus"; - #address-cells = <1>; - #size-cells = <1>; - ranges = <0x15000000 0x15000000 0x00600000>, - <0x16000000 0x16000000 0x00200000>, - <0x17000000 0x17000000 0x10000>, - <0x17020000 0x17020000 0x1000>, - <0x17030000 0x17030000 0x1000>, - <0x17040000 0x17040000 0x1000>, - <0x17050000 0x17050000 0x10000>, - <0x17060000 0x17060000 0x200>, - <0x17060200 0x17060200 0x100>, - <0x17070000 0x17070000 0x200>, - <0x17070200 0x17070200 0x100>, - <0x170A0000 0x170A0000 0x3000>; - - multimedia@15000000 { - compatible = "sirf,atlas7-video-codec"; - reg = <0x15000000 0x10000>; - interrupts = <0 5 0>; - clocks = <&car 102>; - }; - - mediam@170A0000 { - compatible = "sirf,nocfw-mediam"; - reg = <0x170A0000 0x3000>; - }; - - gpio_0: gpio_mediam@17040000 { - #gpio-cells = <2>; - #interrupt-cells = <2>; - compatible = "sirf,atlas7-gpio"; - reg = <0x17040000 0x1000>; - interrupts = <0 13 0>, <0 14 0>; - clocks = <&car 107>; - clock-names = "gpio0_io"; - gpio-controller; - interrupt-controller; - - gpio-banks = <2>; - gpio-ranges = <&pinctrl 0 0 0>, - <&pinctrl 32 0 0>; - gpio-ranges-group-names = "lvds_gpio_grp", - "uart_nand_gpio_grp"; - }; - - nand@17050000 { - compatible = "sirf,atlas7-nand"; - reg = <0x17050000 0x10000>; - pinctrl-names = "default"; - pinctrl-0 = <&nd_df_pmx>; - interrupts = <0 41 0>; - clocks = <&car 108>, <&car 112>; - clock-names = "nand_io", "nand_nand"; - }; - - sd0: sdhci@16000000 { - cell-index = <0>; - compatible = "sirf,atlas7-sdhc"; - reg = <0x16000000 0x100000>; - interrupts = <0 38 0>; - clocks = <&car 109>, <&car 111>; - clock-names = "core", "iface"; - wp-inverted; - non-removable; - status = "disabled"; - bus-width = <8>; - }; - - sd1: sdhci@16100000 { - cell-index = <1>; - compatible = "sirf,atlas7-sdhc"; - reg = <0x16100000 0x100000>; - interrupts = <0 38 0>; - clocks = <&car 109>, <&car 111>; - clock-names = "core", "iface"; - non-removable; - status = "disabled"; - bus-width = <8>; - }; - - jpeg@17000000 { - compatible = "sirf,atlas7-jpeg"; - reg = <0x17000000 0x10000>; - interrupts = <0 72 0>, - <0 73 0>; - clocks = <&car 103>; - }; - - usb0: usb@17060000 { - cell-index = <0>; - compatible = "sirf,atlas7-usb"; - reg = <0x17060000 0x200>; - interrupts = <0 10 0>; - clocks = <&car 113>; - sirf,usbphy = <&usbphy0>; - phy_type = "utmi"; - dr_mode = "otg"; - maximum-speed = "high-speed"; - status = "okay"; - }; - - usb1: usb@17070000 { - cell-index = <1>; - compatible = "sirf,atlas7-usb"; - reg = <0x17070000 0x200>; - interrupts = <0 11 0>; - clocks = <&car 114>; - sirf,usbphy = <&usbphy1>; - phy_type = "utmi"; - dr_mode = "host"; - maximum-speed = "high-speed"; - status = "okay"; - }; - - usbphy0: usbphy@0 { - compatible = "sirf,atlas7-usbphy"; - reg = <0x17060200 0x100>; - clocks = <&car 115>; - status = "okay"; - }; - - usbphy1: usbphy@1 { - compatible = "sirf,atlas7-usbphy"; - reg = <0x17070200 0x100>; - clocks = <&car 116>; - status = "okay"; - }; - - i2c0: i2c@17020000 { - cell-index = <0>; - compatible = "sirf,prima2-i2c"; - reg = <0x17020000 0x1000>; - interrupts = <0 24 0>; - clocks = <&car 105>; - #address-cells = <1>; - #size-cells = <0>; - }; - - }; - - vdifm { - compatible = "arteris, flexnoc", "simple-bus"; - #address-cells = <1>; - #size-cells = <1>; - ranges = <0x13290000 0x13290000 0x3000>, - <0x13300000 0x13300000 0x1000>, - <0x14200000 0x14200000 0x600000>; - - vdifm@13290000 { - compatible = "sirf,nocfw-vdifm"; - reg = <0x13290000 0x3000>; - }; - - gpio_1: gpio_vdifm@13300000 { - #gpio-cells = <2>; - #interrupt-cells = <2>; - compatible = "sirf,atlas7-gpio"; - reg = <0x13300000 0x1000>; - interrupts = <0 43 0>, <0 44 0>, - <0 45 0>, <0 46 0>; - clocks = <&car 84>; - clock-names = "gpio1_io"; - gpio-controller; - interrupt-controller; - - gpio-banks = <4>; - gpio-ranges = <&pinctrl 0 0 0>, - <&pinctrl 32 0 0>, - <&pinctrl 64 0 0>, - <&pinctrl 96 0 0>; - gpio-ranges-group-names = "gnss_gpio_grp", - "lcd_vip_gpio_grp", - "sdio_i2s_gpio_grp", - "sp_rgmii_gpio_grp"; - }; - - sd2: sdhci@14200000 { - cell-index = <2>; - compatible = "sirf,atlas7-sdhc"; - reg = <0x14200000 0x100000>; - interrupts = <0 23 0>; - clocks = <&car 70>, <&car 75>; - clock-names = "core", "iface"; - status = "disabled"; - bus-width = <4>; - sd-uhs-sdr50; - vqmmc-supply = <&vqmmc>; - vqmmc: vqmmc@2 { - regulator-min-microvolt = <1650000>; - regulator-max-microvolt = <1950000>; - regulator-name = "vqmmc-ldo"; - regulator-type = "voltage"; - regulator-boot-on; - regulator-allow-bypass; - }; - }; - - sd3: sdhci@14300000 { - cell-index = <3>; - compatible = "sirf,atlas7-sdhc"; - reg = <0x14300000 0x100000>; - interrupts = <0 23 0>; - clocks = <&car 76>, <&car 81>; - clock-names = "core", "iface"; - status = "disabled"; - bus-width = <4>; - }; - - sd5: sdhci@14500000 { - cell-index = <5>; - compatible = "sirf,atlas7-sdhc"; - reg = <0x14500000 0x100000>; - interrupts = <0 39 0>; - clocks = <&car 71>, <&car 76>; - clock-names = "core", "iface"; - status = "disabled"; - bus-width = <4>; - loop-dma; - }; - - sd6: sdhci@14600000 { - cell-index = <6>; - compatible = "sirf,atlas7-sdhc"; - reg = <0x14600000 0x100000>; - interrupts = <0 98 0>; - clocks = <&car 72>, <&car 77>; - clock-names = "core", "iface"; - status = "disabled"; - bus-width = <4>; - }; - - sd7: sdhci@14700000 { - cell-index = <7>; - compatible = "sirf,atlas7-sdhc"; - reg = <0x14700000 0x100000>; - interrupts = <0 98 0>; - clocks = <&car 72>, <&car 77>; - clock-names = "core", "iface"; - status = "disabled"; - bus-width = <4>; - }; - }; - - audiom { - compatible = "arteris, flexnoc", "simple-bus"; - #address-cells = <1>; - #size-cells = <1>; - ranges = <0x10d50000 0x10d50000 0x0000ffff>, - <0x10d60000 0x10d60000 0x0000ffff>, - <0x10d80000 0x10d80000 0x0000ffff>, - <0x10d90000 0x10d90000 0x0000ffff>, - <0x10ED0000 0x10ED0000 0x3000>, - <0x10dc8000 0x10dc8000 0x1000>, - <0x10dc0000 0x10dc0000 0x1000>, - <0x10db0000 0x10db0000 0x4000>, - <0x10d40000 0x10d40000 0x1000>, - <0x10d30000 0x10d30000 0x1000>; - - timer@10dc0000 { - compatible = "sirf,atlas7-tick"; - reg = <0x10dc0000 0x1000>; - interrupts = <0 0 0>, - <0 1 0>, - <0 2 0>, - <0 49 0>, - <0 50 0>, - <0 51 0>; - clocks = <&car 47>; - }; - - timerb@10dc8000 { - compatible = "sirf,atlas7-tick"; - reg = <0x10dc8000 0x1000>; - interrupts = <0 74 0>, - <0 75 0>, - <0 76 0>, - <0 77 0>, - <0 78 0>, - <0 79 0>; - clocks = <&car 47>; - }; - - vip0@10db0000 { - compatible = "sirf,atlas7-vip0"; - reg = <0x10db0000 0x2000>; - interrupts = <0 85 0>; - sirf,vip_cma_size = <0xC00000>; - }; - - cvd@10db2000 { - compatible = "sirf,cvd"; - reg = <0x10db2000 0x2000>; - clocks = <&car 46>; - }; - - dmac2: dma-controller@10d50000 { - cell-index = <2>; - compatible = "sirf,atlas7-dmac"; - reg = <0x10d50000 0xffff>; - interrupts = <0 55 0>; - clocks = <&car 60>; - dma-channels = <16>; - #dma-cells = <1>; - }; - - dmac3: dma-controller@10d60000 { - cell-index = <3>; - compatible = "sirf,atlas7-dmac"; - reg = <0x10d60000 0xffff>; - interrupts = <0 56 0>; - clocks = <&car 61>; - dma-channels = <16>; - #dma-cells = <1>; - }; - - adc: adc@10d80000 { - compatible = "sirf,atlas7-adc"; - reg = <0x10d80000 0xffff>; - interrupts = <0 34 0>; - clocks = <&car 49>; - #io-channel-cells = <1>; - }; - - pulsec@10d90000 { - compatible = "sirf,prima2-pulsec"; - reg = <0x10d90000 0xffff>; - interrupts = <0 42 0>; - clocks = <&car 54>; - }; - - audiom@10ED0000 { - compatible = "sirf,nocfw-audiom"; - reg = <0x10ED0000 0x3000>; - interrupts = <0 102 0>; - }; - - usp1: usp@10d30000 { - cell-index = <1>; - reg = <0x10d30000 0x1000>; - fifosize = <512>; - clocks = <&car 58>; - dmas = <&dmac2 6>, <&dmac2 7>; - dma-names = "rx", "tx"; - }; - - usp2: usp@10d40000 { - cell-index = <2>; - reg = <0x10d40000 0x1000>; - interrupts = <0 22 0>; - clocks = <&car 59>; - dmas = <&dmac2 12>, <&dmac2 13>; - dma-names = "rx", "tx"; - #address-cells = <1>; - #size-cells = <0>; - status = "disabled"; - }; - }; - - ddrm { - compatible = "arteris, flexnoc", "simple-bus"; - #address-cells = <1>; - #size-cells = <1>; - ranges = <0x10820000 0x10820000 0x3000>, - <0x10800000 0x10800000 0x2000>; - ddrm@10820000 { - compatible = "sirf,nocfw-ddrm"; - reg = <0x10820000 0x3000>; - interrupts = <0 105 0>; - }; - - memory-controller@0x10800000 { - compatible = "sirf,atlas7-memc"; - reg = <0x10800000 0x2000>; - }; - - }; - - btm { - compatible = "arteris, flexnoc", "simple-bus"; - #address-cells = <1>; - #size-cells = <1>; - ranges = <0x11002000 0x11002000 0x0000ffff>, - <0x11010000 0x11010000 0x3000>, - <0x11000000 0x11000000 0x1000>, - <0x11001000 0x11001000 0x1000>; - - dmac4: dma-controller@11002000 { - cell-index = <4>; - compatible = "sirf,atlas7-dmac"; - reg = <0x11002000 0x1000>; - interrupts = <0 99 0>; - clocks = <&car 130>; - dma-channels = <16>; - #dma-cells = <1>; - }; - uart6: uart@11000000 { - cell-index = <6>; - compatible = "sirf,atlas7-bt-uart", - "sirf,atlas7-uart"; - reg = <0x11000000 0x1000>; - interrupts = <0 100 0>; - clocks = <&car 131>, <&car 133>, <&car 134>; - clock-names = "uart", "general", "noc"; - fifosize = <128>; - dmas = <&dmac4 12>, <&dmac4 13>; - dma-names = "rx", "tx"; - status = "disabled"; - }; - - usp3: usp@11001000 { - compatible = "sirf,atlas7-bt-usp", - "sirf,prima2-usp-pcm"; - cell-index = <3>; - reg = <0x11001000 0x1000>; - fifosize = <512>; - clocks = <&car 132>, <&car 129>, <&car 133>, - <&car 134>, <&car 135>; - clock-names = "usp3_io", "a7ca_btss", "a7ca_io", - "noc_btm_io", "thbtm_io"; - dmas = <&dmac4 0>, <&dmac4 1>; - dma-names = "rx", "tx"; - }; - - btm@11010000 { - compatible = "sirf,nocfw-btm"; - reg = <0x11010000 0x3000>; - }; - }; - - rtcm { - compatible = "arteris, flexnoc", "simple-bus"; - #address-cells = <1>; - #size-cells = <1>; - ranges = <0x18810000 0x18810000 0x3000>, - <0x18840000 0x18840000 0x1000>, - <0x18890000 0x18890000 0x1000>, - <0x188B0000 0x188B0000 0x10000>, - <0x188D0000 0x188D0000 0x1000>; - rtcm@18810000 { - compatible = "sirf,nocfw-rtcm"; - reg = <0x18810000 0x3000>; - interrupts = <0 109 0>; - }; - - gpio_2: gpio_rtcm@18890000 { - #gpio-cells = <2>; - #interrupt-cells = <2>; - compatible = "sirf,atlas7-gpio"; - reg = <0x18890000 0x1000>; - interrupts = <0 47 0>; - gpio-controller; - interrupt-controller; - - gpio-banks = <1>; - gpio-ranges = <&pinctrl 0 0 0>; - gpio-ranges-group-names = "rtc_gpio_grp"; - }; - - rtc-iobg@18840000 { - compatible = "sirf,prima2-rtciobg", - "sirf-prima2-rtciobg-bus", - "simple-bus"; - #address-cells = <1>; - #size-cells = <1>; - reg = <0x18840000 0x1000>; - - sysrtc@2000 { - compatible = "sirf,prima2-sysrtc"; - reg = <0x2000 0x100>; - interrupts = <0 52 0>; - }; - pwrc@3000 { - compatible = "sirf,atlas7-pwrc"; - reg = <0x3000 0x100>; - }; - }; - - qspi: flash@188B0000 { - cell-index = <0>; - compatible = "sirf,atlas7-qspi-nor"; - reg = <0x188B0000 0x10000>; - interrupts = <0 15 0>; - #address-cells = <1>; - #size-cells = <0>; - }; - - retain@0x188D0000 { - compatible = "sirf,atlas7-retain"; - reg = <0x188D0000 0x1000>; - }; - - }; - disp-iobg { - /* lcdc0 */ - compatible = "simple-bus"; - #address-cells = <1>; - #size-cells = <1>; - ranges = <0x13100000 0x13100000 0x20000>, - <0x10e10000 0x10e10000 0x10000>, - <0x17010000 0x17010000 0x10000>; - - lcd@13100000 { - compatible = "sirf,atlas7-lcdc"; - reg = <0x13100000 0x10000>; - interrupts = <0 30 0>; - clocks = <&car 79>; - }; - vpp@13110000 { - compatible = "sirf,atlas7-vpp"; - reg = <0x13110000 0x10000>; - interrupts = <0 31 0>; - clocks = <&car 78>; - resets = <&car 29>; - }; - lvds@10e10000 { - compatible = "sirf,atlas7-lvdsc"; - reg = <0x10e10000 0x10000>; - interrupts = <0 64 0>; - clocks = <&car 54>; - resets = <&car 29>; - }; - g2d@17010000 { - compatible = "sirf, atlas7-g2d"; - reg = <0x17010000 0x10000>; - interrupts = <0 61 0>; - clocks = <&car 104>; - }; - - }; - - graphics-iobg { - compatible = "simple-bus"; - #address-cells = <1>; - #size-cells = <1>; - ranges = <0x12000000 0x12000000 0x1000000>; - - graphics@12000000 { - compatible = "powervr,sgx531"; - reg = <0x12000000 0x1000000>; - interrupts = <0 6 0>; - clocks = <&car 126>; - }; - }; - }; -}; diff --git a/arch/arm/boot/dts/prima2-evb.dts b/arch/arm/boot/dts/prima2-evb.dts deleted file mode 100644 index 7394f764df65..000000000000 --- a/arch/arm/boot/dts/prima2-evb.dts +++ /dev/null @@ -1,37 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * DTS file for CSR SiRFprimaII Evaluation Board - * - * Copyright (c) 2012 Cambridge Silicon Radio Limited, a CSR plc group company. - */ - -/dts-v1/; - -/include/ "prima2.dtsi" - -/ { - model = "CSR SiRFprimaII Evaluation Board"; - compatible = "sirf,prima2", "sirf,prima2-cb"; - - memory { - device_type = "memory"; - reg = <0x00000000 0x20000000>; - }; - - axi { - peri-iobg { - uart@b0060000 { - pinctrl-names = "default"; - pinctrl-0 = <&uart1_pins_a>; - }; - spi@b00d0000 { - pinctrl-names = "default"; - pinctrl-0 = <&spi0_pins_a>; - }; - spi@b0170000 { - pinctrl-names = "default"; - pinctrl-0 = <&spi1_pins_a>; - }; - }; - }; -}; diff --git a/arch/arm/boot/dts/prima2.dtsi b/arch/arm/boot/dts/prima2.dtsi deleted file mode 100644 index 7d3d93c22ed9..000000000000 --- a/arch/arm/boot/dts/prima2.dtsi +++ /dev/null @@ -1,838 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * DTS file for CSR SiRFprimaII SoC - * - * Copyright (c) 2012 Cambridge Silicon Radio Limited, a CSR plc group company. - */ - -/ { - compatible = "sirf,prima2"; - #address-cells = <1>; - #size-cells = <1>; - interrupt-parent = <&intc>; - - cpus { - #address-cells = <1>; - #size-cells = <0>; - - cpu@0 { - compatible = "arm,cortex-a9"; - device_type = "cpu"; - reg = <0x0>; - d-cache-line-size = <32>; - i-cache-line-size = <32>; - d-cache-size = <32768>; - i-cache-size = <32768>; - /* from bootloader */ - timebase-frequency = <0>; - bus-frequency = <0>; - clock-frequency = <0>; - clocks = <&clks 12>; - operating-points = < - /* kHz uV */ - 200000 1025000 - 400000 1025000 - 664000 1050000 - 800000 1100000 - >; - clock-latency = <150000>; - }; - }; - - arm-pmu { - compatible = "arm,cortex-a9-pmu"; - interrupts = <29>; - }; - - axi { - compatible = "simple-bus"; - #address-cells = <1>; - #size-cells = <1>; - ranges = <0x40000000 0x40000000 0x80000000>; - - cache-controller@80040000 { - compatible = "arm,pl310-cache"; - reg = <0x80040000 0x1000>; - interrupts = <59>; - arm,tag-latency = <1 1 1>; - arm,data-latency = <1 1 1>; - arm,filter-ranges = <0 0x40000000>; - }; - - intc: interrupt-controller@80020000 { - #interrupt-cells = <1>; - interrupt-controller; - compatible = "sirf,prima2-intc"; - reg = <0x80020000 0x1000>; - }; - - sys-iobg { - compatible = "simple-bus"; - #address-cells = <1>; - #size-cells = <1>; - ranges = <0x88000000 0x88000000 0x40000>; - - clks: clock-controller@88000000 { - compatible = "sirf,prima2-clkc"; - reg = <0x88000000 0x1000>; - interrupts = <3>; - #clock-cells = <1>; - }; - - rstc: reset-controller@88010000 { - compatible = "sirf,prima2-rstc"; - reg = <0x88010000 0x1000>; - #reset-cells = <1>; - }; - - rsc-controller@88020000 { - compatible = "sirf,prima2-rsc"; - reg = <0x88020000 0x1000>; - }; - - cphifbg@88030000 { - compatible = "sirf,prima2-cphifbg"; - reg = <0x88030000 0x1000>; - clocks = <&clks 42>; - }; - }; - - mem-iobg { - compatible = "simple-bus"; - #address-cells = <1>; - #size-cells = <1>; - ranges = <0x90000000 0x90000000 0x10000>; - - memory-controller@90000000 { - compatible = "sirf,prima2-memc"; - reg = <0x90000000 0x2000>; - interrupts = <27>; - clocks = <&clks 5>; - }; - - memc-monitor { - compatible = "sirf,prima2-memcmon"; - reg = <0x90002000 0x200>; - interrupts = <4>; - clocks = <&clks 32>; - }; - }; - - disp-iobg { - compatible = "simple-bus"; - #address-cells = <1>; - #size-cells = <1>; - ranges = <0x90010000 0x90010000 0x30000>; - - display@90010000 { - compatible = "sirf,prima2-lcd"; - reg = <0x90010000 0x20000>; - interrupts = <30>; - }; - - vpp@90020000 { - compatible = "sirf,prima2-vpp"; - reg = <0x90020000 0x10000>; - interrupts = <31>; - clocks = <&clks 35>; - resets = <&rstc 6>; - }; - }; - - graphics-iobg { - compatible = "simple-bus"; - #address-cells = <1>; - #size-cells = <1>; - ranges = <0x98000000 0x98000000 0x8000000>; - - graphics@98000000 { - compatible = "powervr,sgx531"; - reg = <0x98000000 0x8000000>; - interrupts = <6>; - clocks = <&clks 32>; - }; - }; - - multimedia-iobg { - compatible = "simple-bus"; - #address-cells = <1>; - #size-cells = <1>; - ranges = <0xa0000000 0xa0000000 0x8000000>; - - multimedia@a0000000 { - compatible = "sirf,prima2-video-codec"; - reg = <0xa0000000 0x8000000>; - interrupts = <5>; - clocks = <&clks 33>; - }; - }; - - dsp-iobg { - compatible = "simple-bus"; - #address-cells = <1>; - #size-cells = <1>; - ranges = <0xa8000000 0xa8000000 0x2000000>; - - dspif@a8000000 { - compatible = "sirf,prima2-dspif"; - reg = <0xa8000000 0x10000>; - interrupts = <9>; - resets = <&rstc 1>; - }; - - gps@a8010000 { - compatible = "sirf,prima2-gps"; - reg = <0xa8010000 0x10000>; - interrupts = <7>; - clocks = <&clks 9>; - resets = <&rstc 2>; - }; - - dsp@a9000000 { - compatible = "sirf,prima2-dsp"; - reg = <0xa9000000 0x1000000>; - interrupts = <8>; - clocks = <&clks 8>; - resets = <&rstc 0>; - }; - }; - - peri-iobg { - compatible = "simple-bus"; - #address-cells = <1>; - #size-cells = <1>; - ranges = <0xb0000000 0xb0000000 0x180000>, - <0x56000000 0x56000000 0x1b00000>; - - timer@b0020000 { - compatible = "sirf,prima2-tick"; - reg = <0xb0020000 0x1000>; - interrupts = <0>; - clocks = <&clks 11>; - }; - - nand@b0030000 { - compatible = "sirf,prima2-nand"; - reg = <0xb0030000 0x10000>; - interrupts = <41>; - clocks = <&clks 26>; - }; - - audio@b0040000 { - compatible = "sirf,prima2-audio"; - reg = <0xb0040000 0x10000>; - interrupts = <35>; - clocks = <&clks 27>; - }; - - uart0: uart@b0050000 { - cell-index = <0>; - compatible = "sirf,prima2-uart"; - reg = <0xb0050000 0x1000>; - interrupts = <17>; - fifosize = <128>; - clocks = <&clks 13>; - dmas = <&dmac1 5>, <&dmac0 2>; - dma-names = "rx", "tx"; - }; - - uart1: uart@b0060000 { - cell-index = <1>; - compatible = "sirf,prima2-uart"; - reg = <0xb0060000 0x1000>; - interrupts = <18>; - fifosize = <32>; - clocks = <&clks 14>; - }; - - uart2: uart@b0070000 { - cell-index = <2>; - compatible = "sirf,prima2-uart"; - reg = <0xb0070000 0x1000>; - interrupts = <19>; - fifosize = <128>; - clocks = <&clks 15>; - dmas = <&dmac0 6>, <&dmac0 7>; - dma-names = "rx", "tx"; - }; - - usp0: usp@b0080000 { - cell-index = <0>; - compatible = "sirf,prima2-usp"; - reg = <0xb0080000 0x10000>; - interrupts = <20>; - fifosize = <128>; - clocks = <&clks 28>; - dmas = <&dmac1 1>, <&dmac1 2>; - dma-names = "rx", "tx"; - }; - - usp1: usp@b0090000 { - cell-index = <1>; - compatible = "sirf,prima2-usp"; - reg = <0xb0090000 0x10000>; - interrupts = <21>; - fifosize = <128>; - clocks = <&clks 29>; - dmas = <&dmac0 14>, <&dmac0 15>; - dma-names = "rx", "tx"; - }; - - usp2: usp@b00a0000 { - cell-index = <2>; - compatible = "sirf,prima2-usp"; - reg = <0xb00a0000 0x10000>; - interrupts = <22>; - fifosize = <128>; - clocks = <&clks 30>; - dmas = <&dmac0 10>, <&dmac0 11>; - dma-names = "rx", "tx"; - }; - - dmac0: dma-controller@b00b0000 { - cell-index = <0>; - compatible = "sirf,prima2-dmac"; - reg = <0xb00b0000 0x10000>; - interrupts = <12>; - clocks = <&clks 24>; - #dma-cells = <1>; - }; - - dmac1: dma-controller@b0160000 { - cell-index = <1>; - compatible = "sirf,prima2-dmac"; - reg = <0xb0160000 0x10000>; - interrupts = <13>; - clocks = <&clks 25>; - #dma-cells = <1>; - }; - - vip@b00C0000 { - compatible = "sirf,prima2-vip"; - reg = <0xb00C0000 0x10000>; - clocks = <&clks 31>; - interrupts = <14>; - sirf,vip-dma-rx-channel = <16>; - }; - - spi0: spi@b00d0000 { - cell-index = <0>; - compatible = "sirf,prima2-spi"; - reg = <0xb00d0000 0x10000>; - interrupts = <15>; - sirf,spi-num-chipselects = <1>; - dmas = <&dmac1 9>, - <&dmac1 4>; - dma-names = "rx", "tx"; - #address-cells = <1>; - #size-cells = <0>; - clocks = <&clks 19>; - status = "disabled"; - }; - - spi1: spi@b0170000 { - cell-index = <1>; - compatible = "sirf,prima2-spi"; - reg = <0xb0170000 0x10000>; - interrupts = <16>; - sirf,spi-num-chipselects = <1>; - dmas = <&dmac0 12>, - <&dmac0 13>; - dma-names = "rx", "tx"; - #address-cells = <1>; - #size-cells = <0>; - clocks = <&clks 20>; - status = "disabled"; - }; - - i2c0: i2c@b00e0000 { - cell-index = <0>; - compatible = "sirf,prima2-i2c"; - reg = <0xb00e0000 0x10000>; - interrupts = <24>; - clocks = <&clks 17>; - #address-cells = <1>; - #size-cells = <0>; - }; - - i2c1: i2c@b00f0000 { - cell-index = <1>; - compatible = "sirf,prima2-i2c"; - reg = <0xb00f0000 0x10000>; - interrupts = <25>; - clocks = <&clks 18>; - #address-cells = <1>; - #size-cells = <0>; - }; - - tsc@b0110000 { - compatible = "sirf,prima2-tsc"; - reg = <0xb0110000 0x10000>; - interrupts = <33>; - clocks = <&clks 16>; - }; - - gpio: pinctrl@b0120000 { - #gpio-cells = <2>; - #interrupt-cells = <2>; - compatible = "sirf,prima2-pinctrl"; - reg = <0xb0120000 0x10000>; - interrupts = <43 44 45 46 47>; - gpio-controller; - interrupt-controller; - - lcd_16pins_a: lcd0@0 { - lcd { - sirf,pins = "lcd_16bitsgrp"; - sirf,function = "lcd_16bits"; - }; - }; - lcd_18pins_a: lcd0@1 { - lcd { - sirf,pins = "lcd_18bitsgrp"; - sirf,function = "lcd_18bits"; - }; - }; - lcd_24pins_a: lcd0@2 { - lcd { - sirf,pins = "lcd_24bitsgrp"; - sirf,function = "lcd_24bits"; - }; - }; - lcdrom_pins_a: lcdrom0@0 { - lcd { - sirf,pins = "lcdromgrp"; - sirf,function = "lcdrom"; - }; - }; - uart0_pins_a: uart0@0 { - uart { - sirf,pins = "uart0grp"; - sirf,function = "uart0"; - }; - }; - uart0_noflow_pins_a: uart0@1 { - uart { - sirf,pins = "uart0_nostreamctrlgrp"; - sirf,function = "uart0_nostreamctrl"; - }; - }; - uart1_pins_a: uart1@0 { - uart { - sirf,pins = "uart1grp"; - sirf,function = "uart1"; - }; - }; - uart2_pins_a: uart2@0 { - uart { - sirf,pins = "uart2grp"; - sirf,function = "uart2"; - }; - }; - uart2_noflow_pins_a: uart2@1 { - uart { - sirf,pins = "uart2_nostreamctrlgrp"; - sirf,function = "uart2_nostreamctrl"; - }; - }; - spi0_pins_a: spi0@0 { - spi { - sirf,pins = "spi0grp"; - sirf,function = "spi0"; - }; - }; - spi1_pins_a: spi1@0 { - spi { - sirf,pins = "spi1grp"; - sirf,function = "spi1"; - }; - }; - i2c0_pins_a: i2c0@0 { - i2c { - sirf,pins = "i2c0grp"; - sirf,function = "i2c0"; - }; - }; - i2c1_pins_a: i2c1@0 { - i2c { - sirf,pins = "i2c1grp"; - sirf,function = "i2c1"; - }; - }; - pwm0_pins_a: pwm0@0 { - pwm { - sirf,pins = "pwm0grp"; - sirf,function = "pwm0"; - }; - }; - pwm1_pins_a: pwm1@0 { - pwm { - sirf,pins = "pwm1grp"; - sirf,function = "pwm1"; - }; - }; - pwm2_pins_a: pwm2@0 { - pwm { - sirf,pins = "pwm2grp"; - sirf,function = "pwm2"; - }; - }; - pwm3_pins_a: pwm3@0 { - pwm { - sirf,pins = "pwm3grp"; - sirf,function = "pwm3"; - }; - }; - gps_pins_a: gps@0 { - gps { - sirf,pins = "gpsgrp"; - sirf,function = "gps"; - }; - }; - vip_pins_a: vip@0 { - vip { - sirf,pins = "vipgrp"; - sirf,function = "vip"; - }; - }; - sdmmc0_pins_a: sdmmc0@0 { - sdmmc0 { - sirf,pins = "sdmmc0grp"; - sirf,function = "sdmmc0"; - }; - }; - sdmmc1_pins_a: sdmmc1@0 { - sdmmc1 { - sirf,pins = "sdmmc1grp"; - sirf,function = "sdmmc1"; - }; - }; - sdmmc2_pins_a: sdmmc2@0 { - sdmmc2 { - sirf,pins = "sdmmc2grp"; - sirf,function = "sdmmc2"; - }; - }; - sdmmc3_pins_a: sdmmc3@0 { - sdmmc3 { - sirf,pins = "sdmmc3grp"; - sirf,function = "sdmmc3"; - }; - }; - sdmmc4_pins_a: sdmmc4@0 { - sdmmc4 { - sirf,pins = "sdmmc4grp"; - sirf,function = "sdmmc4"; - }; - }; - sdmmc5_pins_a: sdmmc5@0 { - sdmmc5 { - sirf,pins = "sdmmc5grp"; - sirf,function = "sdmmc5"; - }; - }; - i2s_mclk_pins_a: i2s_mclk@0 { - i2s_mclk { - sirf,pins = "i2smclkgrp"; - sirf,function = "i2s_mclk"; - }; - }; - i2s_ext_clk_input_pins_a: i2s_ext_clk_input@0 { - i2s_ext_clk_input { - sirf,pins = "i2s_ext_clk_inputgrp"; - sirf,function = "i2s_ext_clk_input"; - }; - }; - i2s_pins_a: i2s@0 { - i2s { - sirf,pins = "i2sgrp"; - sirf,function = "i2s"; - }; - }; - i2s_no_din_pins_a: i2s_no_din@0 { - i2s_no_din { - sirf,pins = "i2s_no_dingrp"; - sirf,function = "i2s_no_din"; - }; - }; - i2s_6chn_pins_a: i2s_6chn@0 { - i2s_6chn { - sirf,pins = "i2s_6chngrp"; - sirf,function = "i2s_6chn"; - }; - }; - ac97_pins_a: ac97@0 { - ac97 { - sirf,pins = "ac97grp"; - sirf,function = "ac97"; - }; - }; - nand_pins_a: nand@0 { - nand { - sirf,pins = "nandgrp"; - sirf,function = "nand"; - }; - }; - usp0_pins_a: usp0@0 { - usp0 { - sirf,pins = "usp0grp"; - sirf,function = "usp0"; - }; - }; - usp0_uart_nostreamctrl_pins_a: usp0@1 { - usp0 { - sirf,pins = - "usp0_uart_nostreamctrl_grp"; - sirf,function = - "usp0_uart_nostreamctrl"; - }; - }; - usp0_only_utfs_pins_a: usp0@2 { - usp0 { - sirf,pins = "usp0_only_utfs_grp"; - sirf,function = "usp0_only_utfs"; - }; - }; - usp0_only_urfs_pins_a: usp0@3 { - usp0 { - sirf,pins = "usp0_only_urfs_grp"; - sirf,function = "usp0_only_urfs"; - }; - }; - usp1_pins_a: usp1@0 { - usp1 { - sirf,pins = "usp1grp"; - sirf,function = "usp1"; - }; - }; - usp1_uart_nostreamctrl_pins_a: usp1@1 { - usp1 { - sirf,pins = - "usp1_uart_nostreamctrl_grp"; - sirf,function = - "usp1_uart_nostreamctrl"; - }; - }; - usp2_pins_a: usp2@0 { - usp2 { - sirf,pins = "usp2grp"; - sirf,function = "usp2"; - }; - }; - usp2_uart_nostreamctrl_pins_a: usp2@1 { - usp2 { - sirf,pins = - "usp2_uart_nostreamctrl_grp"; - sirf,function = - "usp2_uart_nostreamctrl"; - }; - }; - usb0_utmi_drvbus_pins_a: usb0_utmi_drvbus@0 { - usb0_utmi_drvbus { - sirf,pins = "usb0_utmi_drvbusgrp"; - sirf,function = "usb0_utmi_drvbus"; - }; - }; - usb1_utmi_drvbus_pins_a: usb1_utmi_drvbus@0 { - usb1_utmi_drvbus { - sirf,pins = "usb1_utmi_drvbusgrp"; - sirf,function = "usb1_utmi_drvbus"; - }; - }; - usb1_dp_dn_pins_a: usb1_dp_dn@0 { - usb1_dp_dn { - sirf,pins = "usb1_dp_dngrp"; - sirf,function = "usb1_dp_dn"; - }; - }; - uart1_route_io_usb1_pins_a: uart1_route_io_usb1@0 { - uart1_route_io_usb1 { - sirf,pins = "uart1_route_io_usb1grp"; - sirf,function = "uart1_route_io_usb1"; - }; - }; - warm_rst_pins_a: warm_rst@0 { - warm_rst { - sirf,pins = "warm_rstgrp"; - sirf,function = "warm_rst"; - }; - }; - pulse_count_pins_a: pulse_count@0 { - pulse_count { - sirf,pins = "pulse_countgrp"; - sirf,function = "pulse_count"; - }; - }; - cko0_pins_a: cko0@0 { - cko0 { - sirf,pins = "cko0grp"; - sirf,function = "cko0"; - }; - }; - cko1_pins_a: cko1@0 { - cko1 { - sirf,pins = "cko1grp"; - sirf,function = "cko1"; - }; - }; - }; - - pwm@b0130000 { - compatible = "sirf,prima2-pwm"; - reg = <0xb0130000 0x10000>; - clocks = <&clks 21>; - }; - - efusesys@b0140000 { - compatible = "sirf,prima2-efuse"; - reg = <0xb0140000 0x10000>; - clocks = <&clks 22>; - }; - - pulsec@b0150000 { - compatible = "sirf,prima2-pulsec"; - reg = <0xb0150000 0x10000>; - interrupts = <48>; - clocks = <&clks 23>; - }; - - pci-iobg { - compatible = "sirf,prima2-pciiobg", "simple-bus"; - #address-cells = <1>; - #size-cells = <1>; - ranges = <0x56000000 0x56000000 0x1b00000>; - - sd0: sdhci@56000000 { - cell-index = <0>; - compatible = "sirf,prima2-sdhc"; - reg = <0x56000000 0x100000>; - interrupts = <38>; - status = "disabled"; - bus-width = <8>; - clocks = <&clks 36>; - }; - - sd1: sdhci@56100000 { - cell-index = <1>; - compatible = "sirf,prima2-sdhc"; - reg = <0x56100000 0x100000>; - interrupts = <38>; - status = "disabled"; - bus-width = <4>; - clocks = <&clks 36>; - }; - - sd2: sdhci@56200000 { - cell-index = <2>; - compatible = "sirf,prima2-sdhc"; - reg = <0x56200000 0x100000>; - interrupts = <23>; - status = "disabled"; - clocks = <&clks 37>; - }; - - sd3: sdhci@56300000 { - cell-index = <3>; - compatible = "sirf,prima2-sdhc"; - reg = <0x56300000 0x100000>; - interrupts = <23>; - status = "disabled"; - clocks = <&clks 37>; - }; - - sd4: sdhci@56400000 { - cell-index = <4>; - compatible = "sirf,prima2-sdhc"; - reg = <0x56400000 0x100000>; - interrupts = <39>; - status = "disabled"; - clocks = <&clks 38>; - }; - - sd5: sdhci@56500000 { - cell-index = <5>; - compatible = "sirf,prima2-sdhc"; - reg = <0x56500000 0x100000>; - interrupts = <39>; - clocks = <&clks 38>; - }; - - pci-copy@57900000 { - compatible = "sirf,prima2-pcicp"; - reg = <0x57900000 0x100000>; - interrupts = <40>; - }; - - rom-interface@57a00000 { - compatible = "sirf,prima2-romif"; - reg = <0x57a00000 0x100000>; - }; - }; - }; - - rtc-iobg { - compatible = "sirf,prima2-rtciobg", "sirf-prima2-rtciobg-bus", "simple-bus"; - #address-cells = <1>; - #size-cells = <1>; - reg = <0x80030000 0x10000>; - - gpsrtc@1000 { - compatible = "sirf,prima2-gpsrtc"; - reg = <0x1000 0x1000>; - interrupts = <55 56 57>; - }; - - sysrtc@2000 { - compatible = "sirf,prima2-sysrtc"; - reg = <0x2000 0x1000>; - interrupts = <52 53 54>; - }; - - minigpsrtc@2000 { - compatible = "sirf,prima2-minigpsrtc"; - reg = <0x2000 0x1000>; - interrupts = <54>; - }; - - pwrc@3000 { - compatible = "sirf,prima2-pwrc"; - reg = <0x3000 0x1000>; - interrupts = <32>; - }; - }; - - uus-iobg { - compatible = "simple-bus"; - #address-cells = <1>; - #size-cells = <1>; - ranges = <0xb8000000 0xb8000000 0x40000>; - - usb0: usb@b00e0000 { - compatible = "chipidea,ci13611a-prima2"; - reg = <0xb8000000 0x10000>; - interrupts = <10>; - clocks = <&clks 40>; - }; - - usb1: usb@b00f0000 { - compatible = "chipidea,ci13611a-prima2"; - reg = <0xb8010000 0x10000>; - interrupts = <11>; - clocks = <&clks 41>; - }; - - sata@b00f0000 { - compatible = "synopsys,dwc-ahsata"; - reg = <0xb8020000 0x10000>; - interrupts = <37>; - }; - - security@b00f0000 { - compatible = "sirf,prima2-security"; - reg = <0xb8030000 0x10000>; - interrupts = <42>; - clocks = <&clks 7>; - }; - }; - }; -}; diff --git a/arch/arm/configs/prima2_defconfig b/arch/arm/configs/prima2_defconfig deleted file mode 100644 index be19aa127595..000000000000 --- a/arch/arm/configs/prima2_defconfig +++ /dev/null @@ -1,72 +0,0 @@ -CONFIG_NO_HZ=y -CONFIG_HIGH_RES_TIMERS=y -CONFIG_RELAY=y -CONFIG_BLK_DEV_INITRD=y -CONFIG_KALLSYMS_ALL=y -CONFIG_MODULES=y -CONFIG_MODULE_UNLOAD=y -# CONFIG_BLK_DEV_BSG is not set -CONFIG_PARTITION_ADVANCED=y -CONFIG_BSD_DISKLABEL=y -CONFIG_SOLARIS_X86_PARTITION=y -CONFIG_ARCH_SIRF=y -CONFIG_SMP=y -CONFIG_SCHED_MC=y -CONFIG_PREEMPT=y -CONFIG_AEABI=y -CONFIG_KEXEC=y -CONFIG_BINFMT_MISC=y -CONFIG_BLK_DEV_LOOP=y -CONFIG_BLK_DEV_RAM=y -CONFIG_BLK_DEV_RAM_SIZE=8192 -CONFIG_SCSI=y -CONFIG_BLK_DEV_SD=y -CONFIG_CHR_DEV_SG=y -CONFIG_INPUT_EVDEV=y -# CONFIG_INPUT_MOUSE is not set -CONFIG_INPUT_TOUCHSCREEN=y -CONFIG_INPUT_MISC=y -CONFIG_SERIAL_SIRFSOC=y -CONFIG_SERIAL_SIRFSOC_CONSOLE=y -CONFIG_HW_RANDOM=y -CONFIG_I2C=y -CONFIG_I2C_CHARDEV=y -CONFIG_I2C_SIRF=y -CONFIG_SPI=y -CONFIG_SPI_SIRF=y -CONFIG_SPI_SPIDEV=y -# CONFIG_HWMON is not set -CONFIG_WATCHDOG=y -CONFIG_USB_GADGET=y -CONFIG_USB_MASS_STORAGE=m -CONFIG_MMC=y -CONFIG_MMC_SDHCI=y -CONFIG_MMC_SDHCI_PLTFM=y -CONFIG_MMC_SDHCI_SIRF=y -CONFIG_RTC_CLASS=y -CONFIG_RTC_DRV_SIRFSOC=y -CONFIG_DMADEVICES=y -CONFIG_DMADEVICES_DEBUG=y -CONFIG_DMADEVICES_VDEBUG=y -CONFIG_SIRF_DMA=y -CONFIG_HWSPINLOCK_SIRF=y -# CONFIG_IOMMU_SUPPORT is not set -CONFIG_EXT2_FS=y -CONFIG_MSDOS_FS=y -CONFIG_VFAT_FS=y -CONFIG_TMPFS=y -CONFIG_TMPFS_POSIX_ACL=y -CONFIG_CRAMFS=y -CONFIG_ROMFS_FS=y -CONFIG_NLS_CODEPAGE_437=y -CONFIG_NLS_ASCII=y -CONFIG_NLS_ISO8859_1=y -CONFIG_DEBUG_INFO=y -CONFIG_DEBUG_SECTION_MISMATCH=y -CONFIG_MAGIC_SYSRQ=y -CONFIG_DEBUG_KERNEL=y -# CONFIG_DEBUG_PREEMPT is not set -CONFIG_DEBUG_RT_MUTEXES=y -CONFIG_DEBUG_SPINLOCK=y -CONFIG_DEBUG_MUTEXES=y -CONFIG_CRC_CCITT=y diff --git a/arch/arm/include/debug/sirf.S b/arch/arm/include/debug/sirf.S deleted file mode 100644 index 3612c7b9cbe7..000000000000 --- a/arch/arm/include/debug/sirf.S +++ /dev/null @@ -1,40 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-or-later */ -/* - * arch/arm/mach-prima2/include/mach/debug-macro.S - * - * Copyright (c) 2011 Cambridge Silicon Radio Limited, a CSR plc group company. - */ - -#define SIRF_LLUART_TXFIFO_STATUS 0x0114 -#define SIRF_LLUART_TXFIFO_DATA 0x0118 - -#define SIRF_LLUART_TXFIFO_FULL (1 << 5) - -#ifdef CONFIG_DEBUG_SIRFATLAS7_UART0 -#define SIRF_LLUART_TXFIFO_EMPTY (1 << 8) -#else -#define SIRF_LLUART_TXFIFO_EMPTY (1 << 6) -#endif - - - .macro addruart, rp, rv, tmp - ldr \rp, =CONFIG_DEBUG_UART_PHYS @ physical - ldr \rv, =CONFIG_DEBUG_UART_VIRT @ virtual - .endm - - .macro senduart,rd,rx - str \rd, [\rx, #SIRF_LLUART_TXFIFO_DATA] - .endm - - .macro busyuart,rd,rx - .endm - - .macro waituartcts,rd,rx - .endm - - .macro waituarttxrdy,rd,rx -1001: ldr \rd, [\rx, #SIRF_LLUART_TXFIFO_STATUS] - tst \rd, #SIRF_LLUART_TXFIFO_EMPTY - beq 1001b - .endm - diff --git a/arch/arm/mach-prima2/Kconfig b/arch/arm/mach-prima2/Kconfig deleted file mode 100644 index ea077f66372d..000000000000 --- a/arch/arm/mach-prima2/Kconfig +++ /dev/null @@ -1,48 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0-only -menuconfig ARCH_SIRF - bool "CSR SiRF" - depends on ARCH_MULTI_V7 - select ARCH_HAS_RESET_CONTROLLER - select RESET_CONTROLLER - select GENERIC_IRQ_CHIP - select GPIOLIB - select NO_IOPORT_MAP - select REGMAP - select PINCTRL - select PINCTRL_SIRF - help - Support for CSR SiRFprimaII/Marco/Polo platforms - -if ARCH_SIRF - -comment "CSR SiRF atlas6/primaII/Atlas7 Specific Features" - -config ARCH_ATLAS6 - bool "CSR SiRFSoC ATLAS6 ARM Cortex A9 Platform" - default y - select SIRF_IRQ - help - Support for CSR SiRFSoC ARM Cortex A9 Platform - -config ARCH_ATLAS7 - bool "CSR SiRFSoC ATLAS7 ARM Cortex A7 Platform" - default y - select ARM_GIC - select ATLAS7_TIMER - select HAVE_ARM_SCU if SMP - help - Support for CSR SiRFSoC ARM Cortex A7 Platform - -config ARCH_PRIMA2 - bool "CSR SiRFSoC PRIMA2 ARM Cortex A9 Platform" - default y - select SIRF_IRQ - select ZONE_DMA - select PRIMA2_TIMER - help - Support for CSR SiRFSoC ARM Cortex A9 Platform - -config SIRF_IRQ - bool - -endif diff --git a/arch/arm/mach-prima2/Makefile b/arch/arm/mach-prima2/Makefile deleted file mode 100644 index 0fd2763031e9..000000000000 --- a/arch/arm/mach-prima2/Makefile +++ /dev/null @@ -1,9 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0 -obj-y += rstc.o -obj-y += common.o -obj-y += rtciobrg.o -obj-$(CONFIG_SUSPEND) += pm.o sleep.o -obj-$(CONFIG_SMP) += platsmp.o headsmp.o -obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o - -CFLAGS_hotplug.o += -march=armv7-a diff --git a/arch/arm/mach-prima2/common.c b/arch/arm/mach-prima2/common.c deleted file mode 100644 index e2d158e331e2..000000000000 --- a/arch/arm/mach-prima2/common.c +++ /dev/null @@ -1,64 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * Defines machines for CSR SiRFprimaII - * - * Copyright (c) 2011 Cambridge Silicon Radio Limited, a CSR plc group company. - */ - -#include -#include -#include -#include -#include -#include -#include -#include "common.h" - -static void __init __maybe_unused sirfsoc_init_late(void) -{ - sirfsoc_pm_init(); -} - -#ifdef CONFIG_ARCH_ATLAS6 -static const char *const atlas6_dt_match[] __initconst = { - "sirf,atlas6", - NULL -}; - -DT_MACHINE_START(ATLAS6_DT, "Generic ATLAS6 (Flattened Device Tree)") - /* Maintainer: Barry Song */ - .l2c_aux_val = 0, - .l2c_aux_mask = ~0, - .init_late = sirfsoc_init_late, - .dt_compat = atlas6_dt_match, -MACHINE_END -#endif - -#ifdef CONFIG_ARCH_PRIMA2 -static const char *const prima2_dt_match[] __initconst = { - "sirf,prima2", - NULL -}; - -DT_MACHINE_START(PRIMA2_DT, "Generic PRIMA2 (Flattened Device Tree)") - /* Maintainer: Barry Song */ - .l2c_aux_val = 0, - .l2c_aux_mask = ~0, - .dma_zone_size = SZ_256M, - .init_late = sirfsoc_init_late, - .dt_compat = prima2_dt_match, -MACHINE_END -#endif - -#ifdef CONFIG_ARCH_ATLAS7 -static const char *const atlas7_dt_match[] __initconst = { - "sirf,atlas7", - NULL -}; - -DT_MACHINE_START(ATLAS7_DT, "Generic ATLAS7 (Flattened Device Tree)") - /* Maintainer: Barry Song */ - .smp = smp_ops(sirfsoc_smp_ops), - .dt_compat = atlas7_dt_match, -MACHINE_END -#endif diff --git a/arch/arm/mach-prima2/common.h b/arch/arm/mach-prima2/common.h deleted file mode 100644 index 3bab7e571ded..000000000000 --- a/arch/arm/mach-prima2/common.h +++ /dev/null @@ -1,32 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-or-later */ -/* - * This file contains common function prototypes to avoid externs in the c files. - * - * Copyright (c) 2011 Cambridge Silicon Radio Limited, a CSR plc group company. - */ - -#ifndef __MACH_PRIMA2_COMMON_H__ -#define __MACH_PRIMA2_COMMON_H__ - -#include -#include - -#include -#include - -extern volatile int prima2_pen_release; - -extern const struct smp_operations sirfsoc_smp_ops; -extern void sirfsoc_secondary_startup(void); -extern void sirfsoc_cpu_die(unsigned int cpu); - -extern void __init sirfsoc_of_irq_init(void); -extern asmlinkage void __exception_irq_entry sirfsoc_handle_irq(struct pt_regs *regs); - -#ifdef CONFIG_SUSPEND -extern int sirfsoc_pm_init(void); -#else -static inline int sirfsoc_pm_init(void) { return 0; } -#endif - -#endif diff --git a/arch/arm/mach-prima2/headsmp.S b/arch/arm/mach-prima2/headsmp.S deleted file mode 100644 index 88ea1243942a..000000000000 --- a/arch/arm/mach-prima2/headsmp.S +++ /dev/null @@ -1,36 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-or-later */ -/* - * Entry of the second core for CSR Marco dual-core SMP SoCs - * - * Copyright (c) 2012 Cambridge Silicon Radio Limited, a CSR plc group company. - */ - -#include -#include - -/* - * SIRFSOC specific entry point for secondary CPUs. This provides - * a "holding pen" into which all secondary cores are held until we're - * ready for them to initialise. - */ -ENTRY(sirfsoc_secondary_startup) - mrc p15, 0, r0, c0, c0, 5 - and r0, r0, #15 - adr r4, 1f - ldmia r4, {r5, r6} - sub r4, r4, r5 - add r6, r6, r4 -pen: ldr r7, [r6] - cmp r7, r0 - bne pen - - /* - * we've been released from the holding pen: secondary_stack - * should now contain the SVC stack for this core - */ - b secondary_startup -ENDPROC(sirfsoc_secondary_startup) - - .align -1: .long . - .long prima2_pen_release diff --git a/arch/arm/mach-prima2/hotplug.c b/arch/arm/mach-prima2/hotplug.c deleted file mode 100644 index bc0d957e89ac..000000000000 --- a/arch/arm/mach-prima2/hotplug.c +++ /dev/null @@ -1,38 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * CPU hotplug support for CSR Marco dual-core SMP SoCs - * - * Copyright (c) 2012 Cambridge Silicon Radio Limited, a CSR plc group company. - */ - -#include -#include -#include - -#include -#include "common.h" - -static inline void platform_do_lowpower(unsigned int cpu) -{ - /* we put the platform to just WFI */ - for (;;) { - __asm__ __volatile__("dsb\n\t" "wfi\n\t" - : : : "memory"); - if (prima2_pen_release == cpu_logical_map(cpu)) { - /* - * OK, proper wakeup, we're done - */ - break; - } - } -} - -/* - * platform-specific code to shutdown a CPU - * - * Called with IRQs disabled - */ -void sirfsoc_cpu_die(unsigned int cpu) -{ - platform_do_lowpower(cpu); -} diff --git a/arch/arm/mach-prima2/platsmp.c b/arch/arm/mach-prima2/platsmp.c deleted file mode 100644 index 8f7bbb57fb20..000000000000 --- a/arch/arm/mach-prima2/platsmp.c +++ /dev/null @@ -1,123 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * plat smp support for CSR Marco dual-core SMP SoCs - * - * Copyright (c) 2012 Cambridge Silicon Radio Limited, a CSR plc group company. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "common.h" - -static void __iomem *clk_base; - -static DEFINE_SPINLOCK(boot_lock); - -/* XXX prima2_pen_release is cargo culted code - DO NOT COPY XXX */ -volatile int prima2_pen_release = -1; - -static void sirfsoc_secondary_init(unsigned int cpu) -{ - /* - * let the primary processor know we're out of the - * pen, then head off into the C entry point - */ - prima2_pen_release = -1; - smp_wmb(); - - /* - * Synchronise with the boot thread. - */ - spin_lock(&boot_lock); - spin_unlock(&boot_lock); -} - -static const struct of_device_id clk_ids[] = { - { .compatible = "sirf,atlas7-clkc" }, - {}, -}; - -static int sirfsoc_boot_secondary(unsigned int cpu, struct task_struct *idle) -{ - unsigned long timeout; - struct device_node *np; - - np = of_find_matching_node(NULL, clk_ids); - if (!np) - return -ENODEV; - - clk_base = of_iomap(np, 0); - if (!clk_base) - return -ENOMEM; - - /* - * write the address of secondary startup into the clkc register - * at offset 0x2bC, then write the magic number 0x3CAF5D62 to the - * clkc register at offset 0x2b8, which is what boot rom code is - * waiting for. This would wake up the secondary core from WFE - */ -#define SIRFSOC_CPU1_JUMPADDR_OFFSET 0x2bc - __raw_writel(__pa_symbol(sirfsoc_secondary_startup), - clk_base + SIRFSOC_CPU1_JUMPADDR_OFFSET); - -#define SIRFSOC_CPU1_WAKEMAGIC_OFFSET 0x2b8 - __raw_writel(0x3CAF5D62, - clk_base + SIRFSOC_CPU1_WAKEMAGIC_OFFSET); - - /* make sure write buffer is drained */ - mb(); - - spin_lock(&boot_lock); - - /* - * The secondary processor is waiting to be released from - * the holding pen - release it, then wait for it to flag - * that it has been released by resetting prima2_pen_release. - * - * Note that "prima2_pen_release" is the hardware CPU ID, whereas - * "cpu" is Linux's internal ID. - */ - prima2_pen_release = cpu_logical_map(cpu); - sync_cache_w(&prima2_pen_release); - - /* - * Send the secondary CPU SEV, thereby causing the boot monitor to read - * the JUMPADDR and WAKEMAGIC, and branch to the address found there. - */ - dsb_sev(); - - timeout = jiffies + (1 * HZ); - while (time_before(jiffies, timeout)) { - smp_rmb(); - if (prima2_pen_release == -1) - break; - - udelay(10); - } - - /* - * now the secondary core is starting up let it run its - * calibrations, then wait for it to finish - */ - spin_unlock(&boot_lock); - - return prima2_pen_release != -1 ? -ENOSYS : 0; -} - -const struct smp_operations sirfsoc_smp_ops __initconst = { - .smp_secondary_init = sirfsoc_secondary_init, - .smp_boot_secondary = sirfsoc_boot_secondary, -#ifdef CONFIG_HOTPLUG_CPU - .cpu_die = sirfsoc_cpu_die, -#endif -}; diff --git a/arch/arm/mach-prima2/pm.c b/arch/arm/mach-prima2/pm.c deleted file mode 100644 index c24bc89f320b..000000000000 --- a/arch/arm/mach-prima2/pm.c +++ /dev/null @@ -1,153 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * power management entry for CSR SiRFprimaII - * - * Copyright (c) 2011 Cambridge Silicon Radio Limited, a CSR plc group company. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "pm.h" - -/* - * suspend asm codes will access these to make DRAM become self-refresh and - * system sleep - */ -u32 sirfsoc_pwrc_base; -void __iomem *sirfsoc_memc_base; - -static void sirfsoc_set_wakeup_source(void) -{ - u32 pwr_trigger_en_reg; - pwr_trigger_en_reg = sirfsoc_rtc_iobrg_readl(sirfsoc_pwrc_base + - SIRFSOC_PWRC_TRIGGER_EN); -#define X_ON_KEY_B (1 << 0) -#define RTC_ALARM0_B (1 << 2) -#define RTC_ALARM1_B (1 << 3) - sirfsoc_rtc_iobrg_writel(pwr_trigger_en_reg | X_ON_KEY_B | - RTC_ALARM0_B | RTC_ALARM1_B, - sirfsoc_pwrc_base + SIRFSOC_PWRC_TRIGGER_EN); -} - -static void sirfsoc_set_sleep_mode(u32 mode) -{ - u32 sleep_mode = sirfsoc_rtc_iobrg_readl(sirfsoc_pwrc_base + - SIRFSOC_PWRC_PDN_CTRL); - sleep_mode &= ~(SIRFSOC_SLEEP_MODE_MASK << 1); - sleep_mode |= mode << 1; - sirfsoc_rtc_iobrg_writel(sleep_mode, sirfsoc_pwrc_base + - SIRFSOC_PWRC_PDN_CTRL); -} - -static int sirfsoc_pre_suspend_power_off(void) -{ - u32 wakeup_entry = __pa_symbol(cpu_resume); - - sirfsoc_rtc_iobrg_writel(wakeup_entry, sirfsoc_pwrc_base + - SIRFSOC_PWRC_SCRATCH_PAD1); - - sirfsoc_set_wakeup_source(); - - sirfsoc_set_sleep_mode(SIRFSOC_DEEP_SLEEP_MODE); - - return 0; -} - -static int sirfsoc_pm_enter(suspend_state_t state) -{ - switch (state) { - case PM_SUSPEND_MEM: - sirfsoc_pre_suspend_power_off(); - - outer_disable(); - /* go zzz */ - cpu_suspend(0, sirfsoc_finish_suspend); - outer_resume(); - break; - default: - return -EINVAL; - } - return 0; -} - -static const struct platform_suspend_ops sirfsoc_pm_ops = { - .enter = sirfsoc_pm_enter, - .valid = suspend_valid_only_mem, -}; - -static const struct of_device_id pwrc_ids[] = { - { .compatible = "sirf,prima2-pwrc" }, - {} -}; - -static int __init sirfsoc_of_pwrc_init(void) -{ - struct device_node *np; - - np = of_find_matching_node(NULL, pwrc_ids); - if (!np) { - pr_err("unable to find compatible sirf pwrc node in dtb\n"); - return -ENOENT; - } - - /* - * pwrc behind rtciobrg is not located in memory space - * though the property is named reg. reg only means base - * offset for pwrc. then of_iomap is not suitable here. - */ - if (of_property_read_u32(np, "reg", &sirfsoc_pwrc_base)) - panic("unable to find base address of pwrc node in dtb\n"); - - of_node_put(np); - - return 0; -} - -static const struct of_device_id memc_ids[] = { - { .compatible = "sirf,prima2-memc" }, - {} -}; - -static int sirfsoc_memc_probe(struct platform_device *op) -{ - struct device_node *np = op->dev.of_node; - - sirfsoc_memc_base = of_iomap(np, 0); - if (!sirfsoc_memc_base) - panic("unable to map memc registers\n"); - - return 0; -} - -static struct platform_driver sirfsoc_memc_driver = { - .probe = sirfsoc_memc_probe, - .driver = { - .name = "sirfsoc-memc", - .of_match_table = memc_ids, - }, -}; - -static int __init sirfsoc_memc_init(void) -{ - return platform_driver_register(&sirfsoc_memc_driver); -} - -int __init sirfsoc_pm_init(void) -{ - sirfsoc_of_pwrc_init(); - sirfsoc_memc_init(); - suspend_set_ops(&sirfsoc_pm_ops); - return 0; -} diff --git a/arch/arm/mach-prima2/pm.h b/arch/arm/mach-prima2/pm.h deleted file mode 100644 index 0aff6cb876be..000000000000 --- a/arch/arm/mach-prima2/pm.h +++ /dev/null @@ -1,28 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-or-later */ -/* - * arch/arm/mach-prima2/pm.h - * - * Copyright (c) 2011 Cambridge Silicon Radio Limited, a CSR plc group company. - */ - -#ifndef _MACH_PRIMA2_PM_H_ -#define _MACH_PRIMA2_PM_H_ - -#define SIRFSOC_PWR_SLEEPFORCE 0x01 - -#define SIRFSOC_SLEEP_MODE_MASK 0x3 -#define SIRFSOC_DEEP_SLEEP_MODE 0x1 - -#define SIRFSOC_PWRC_PDN_CTRL 0x0 -#define SIRFSOC_PWRC_PON_OFF 0x4 -#define SIRFSOC_PWRC_TRIGGER_EN 0x8 -#define SIRFSOC_PWRC_PIN_STATUS 0x14 -#define SIRFSOC_PWRC_SCRATCH_PAD1 0x18 -#define SIRFSOC_PWRC_SCRATCH_PAD2 0x1C - -#ifndef __ASSEMBLY__ -extern int sirfsoc_finish_suspend(unsigned long); -#endif - -#endif - diff --git a/arch/arm/mach-prima2/rstc.c b/arch/arm/mach-prima2/rstc.c deleted file mode 100644 index 9d56606ac87f..000000000000 --- a/arch/arm/mach-prima2/rstc.c +++ /dev/null @@ -1,107 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * reset controller for CSR SiRFprimaII - * - * Copyright (c) 2011 Cambridge Silicon Radio Limited, a CSR plc group company. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#define SIRFSOC_RSTBIT_NUM 64 - -static void __iomem *sirfsoc_rstc_base; -static DEFINE_MUTEX(rstc_lock); - -static int sirfsoc_reset_module(struct reset_controller_dev *rcdev, - unsigned long sw_reset_idx) -{ - u32 reset_bit = sw_reset_idx; - - if (reset_bit >= SIRFSOC_RSTBIT_NUM) - return -EINVAL; - - mutex_lock(&rstc_lock); - - /* - * Writing 1 to this bit resets corresponding block. - * Writing 0 to this bit de-asserts reset signal of the - * corresponding block. datasheet doesn't require explicit - * delay between the set and clear of reset bit. it could - * be shorter if tests pass. - */ - writel(readl(sirfsoc_rstc_base + - (reset_bit / 32) * 4) | (1 << reset_bit), - sirfsoc_rstc_base + (reset_bit / 32) * 4); - msleep(20); - writel(readl(sirfsoc_rstc_base + - (reset_bit / 32) * 4) & ~(1 << reset_bit), - sirfsoc_rstc_base + (reset_bit / 32) * 4); - - mutex_unlock(&rstc_lock); - - return 0; -} - -static struct reset_control_ops sirfsoc_rstc_ops = { - .reset = sirfsoc_reset_module, -}; - -static struct reset_controller_dev sirfsoc_reset_controller = { - .ops = &sirfsoc_rstc_ops, - .nr_resets = SIRFSOC_RSTBIT_NUM, -}; - -#define SIRFSOC_SYS_RST_BIT BIT(31) - -static void sirfsoc_restart(enum reboot_mode mode, const char *cmd) -{ - writel(SIRFSOC_SYS_RST_BIT, sirfsoc_rstc_base); -} - -static int sirfsoc_rstc_probe(struct platform_device *pdev) -{ - struct device_node *np = pdev->dev.of_node; - sirfsoc_rstc_base = of_iomap(np, 0); - if (!sirfsoc_rstc_base) { - dev_err(&pdev->dev, "unable to map rstc cpu registers\n"); - return -ENOMEM; - } - - sirfsoc_reset_controller.of_node = np; - arm_pm_restart = sirfsoc_restart; - - if (IS_ENABLED(CONFIG_RESET_CONTROLLER)) - reset_controller_register(&sirfsoc_reset_controller); - - return 0; -} - -static const struct of_device_id rstc_ids[] = { - { .compatible = "sirf,prima2-rstc" }, - {}, -}; - -static struct platform_driver sirfsoc_rstc_driver = { - .probe = sirfsoc_rstc_probe, - .driver = { - .name = "sirfsoc_rstc", - .of_match_table = rstc_ids, - }, -}; - -static int __init sirfsoc_rstc_init(void) -{ - return platform_driver_register(&sirfsoc_rstc_driver); -} -subsys_initcall(sirfsoc_rstc_init); diff --git a/arch/arm/mach-prima2/rtciobrg.c b/arch/arm/mach-prima2/rtciobrg.c deleted file mode 100644 index 97c0e333e3b9..000000000000 --- a/arch/arm/mach-prima2/rtciobrg.c +++ /dev/null @@ -1,179 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * RTC I/O Bridge interfaces for CSR SiRFprimaII/atlas7 - * ARM access the registers of SYSRTC, GPSRTC and PWRC through this module - * - * Copyright (c) 2011 Cambridge Silicon Radio Limited, a CSR plc group company. - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -#define SIRFSOC_CPUIOBRG_CTRL 0x00 -#define SIRFSOC_CPUIOBRG_WRBE 0x04 -#define SIRFSOC_CPUIOBRG_ADDR 0x08 -#define SIRFSOC_CPUIOBRG_DATA 0x0c - -/* - * suspend asm codes will access this address to make system deepsleep - * after DRAM becomes self-refresh - */ -void __iomem *sirfsoc_rtciobrg_base; -static DEFINE_SPINLOCK(rtciobrg_lock); - -/* - * symbols without lock are only used by suspend asm codes - * and these symbols are not exported too - */ -void sirfsoc_rtc_iobrg_wait_sync(void) -{ - while (readl_relaxed(sirfsoc_rtciobrg_base + SIRFSOC_CPUIOBRG_CTRL)) - cpu_relax(); -} - -void sirfsoc_rtc_iobrg_besyncing(void) -{ - unsigned long flags; - - spin_lock_irqsave(&rtciobrg_lock, flags); - - sirfsoc_rtc_iobrg_wait_sync(); - - spin_unlock_irqrestore(&rtciobrg_lock, flags); -} -EXPORT_SYMBOL_GPL(sirfsoc_rtc_iobrg_besyncing); - -u32 __sirfsoc_rtc_iobrg_readl(u32 addr) -{ - sirfsoc_rtc_iobrg_wait_sync(); - - writel_relaxed(0x00, sirfsoc_rtciobrg_base + SIRFSOC_CPUIOBRG_WRBE); - writel_relaxed(addr, sirfsoc_rtciobrg_base + SIRFSOC_CPUIOBRG_ADDR); - writel_relaxed(0x01, sirfsoc_rtciobrg_base + SIRFSOC_CPUIOBRG_CTRL); - - sirfsoc_rtc_iobrg_wait_sync(); - - return readl_relaxed(sirfsoc_rtciobrg_base + SIRFSOC_CPUIOBRG_DATA); -} - -u32 sirfsoc_rtc_iobrg_readl(u32 addr) -{ - unsigned long flags, val; - - /* TODO: add hwspinlock to sync with M3 */ - spin_lock_irqsave(&rtciobrg_lock, flags); - - val = __sirfsoc_rtc_iobrg_readl(addr); - - spin_unlock_irqrestore(&rtciobrg_lock, flags); - - return val; -} -EXPORT_SYMBOL_GPL(sirfsoc_rtc_iobrg_readl); - -void sirfsoc_rtc_iobrg_pre_writel(u32 val, u32 addr) -{ - sirfsoc_rtc_iobrg_wait_sync(); - - writel_relaxed(0xf1, sirfsoc_rtciobrg_base + SIRFSOC_CPUIOBRG_WRBE); - writel_relaxed(addr, sirfsoc_rtciobrg_base + SIRFSOC_CPUIOBRG_ADDR); - - writel_relaxed(val, sirfsoc_rtciobrg_base + SIRFSOC_CPUIOBRG_DATA); -} - -void sirfsoc_rtc_iobrg_writel(u32 val, u32 addr) -{ - unsigned long flags; - - /* TODO: add hwspinlock to sync with M3 */ - spin_lock_irqsave(&rtciobrg_lock, flags); - - sirfsoc_rtc_iobrg_pre_writel(val, addr); - - writel_relaxed(0x01, sirfsoc_rtciobrg_base + SIRFSOC_CPUIOBRG_CTRL); - - sirfsoc_rtc_iobrg_wait_sync(); - - spin_unlock_irqrestore(&rtciobrg_lock, flags); -} -EXPORT_SYMBOL_GPL(sirfsoc_rtc_iobrg_writel); - - -static int regmap_iobg_regwrite(void *context, unsigned int reg, - unsigned int val) -{ - sirfsoc_rtc_iobrg_writel(val, reg); - return 0; -} - -static int regmap_iobg_regread(void *context, unsigned int reg, - unsigned int *val) -{ - *val = (u32)sirfsoc_rtc_iobrg_readl(reg); - return 0; -} - -static struct regmap_bus regmap_iobg = { - .reg_write = regmap_iobg_regwrite, - .reg_read = regmap_iobg_regread, -}; - -/** - * devm_regmap_init_iobg(): Initialise managed register map - * - * @iobg: Device that will be interacted with - * @config: Configuration for register map - * - * The return value will be an ERR_PTR() on error or a valid pointer - * to a struct regmap. The regmap will be automatically freed by the - * device management code. - */ -struct regmap *devm_regmap_init_iobg(struct device *dev, - const struct regmap_config *config) -{ - const struct regmap_bus *bus = ®map_iobg; - - return devm_regmap_init(dev, bus, dev, config); -} -EXPORT_SYMBOL_GPL(devm_regmap_init_iobg); - -static const struct of_device_id rtciobrg_ids[] = { - { .compatible = "sirf,prima2-rtciobg" }, - {} -}; - -static int sirfsoc_rtciobrg_probe(struct platform_device *op) -{ - struct device_node *np = op->dev.of_node; - - sirfsoc_rtciobrg_base = of_iomap(np, 0); - if (!sirfsoc_rtciobrg_base) - panic("unable to map rtc iobrg registers\n"); - - return 0; -} - -static struct platform_driver sirfsoc_rtciobrg_driver = { - .probe = sirfsoc_rtciobrg_probe, - .driver = { - .name = "sirfsoc-rtciobrg", - .of_match_table = rtciobrg_ids, - }, -}; - -static int __init sirfsoc_rtciobrg_init(void) -{ - return platform_driver_register(&sirfsoc_rtciobrg_driver); -} -postcore_initcall(sirfsoc_rtciobrg_init); - -MODULE_AUTHOR("Zhiwu Song "); -MODULE_AUTHOR("Barry Song "); -MODULE_DESCRIPTION("CSR SiRFprimaII rtc io bridge"); -MODULE_LICENSE("GPL v2"); diff --git a/arch/arm/mach-prima2/sleep.S b/arch/arm/mach-prima2/sleep.S deleted file mode 100644 index d9bbc5ca39ef..000000000000 --- a/arch/arm/mach-prima2/sleep.S +++ /dev/null @@ -1,63 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-or-later */ -/* - * sleep mode for CSR SiRFprimaII - * - * Copyright (c) 2011 Cambridge Silicon Radio Limited, a CSR plc group company. - */ - -#include -#include -#include - -#include "pm.h" - -#define DENALI_CTL_22_OFF 0x58 -#define DENALI_CTL_112_OFF 0x1c0 - - .text - -ENTRY(sirfsoc_finish_suspend) - @ r5: mem controller - ldr r0, =sirfsoc_memc_base - ldr r5, [r0] - @ r6: pwrc base offset - ldr r0, =sirfsoc_pwrc_base - ldr r6, [r0] - @ r7: rtc iobrg controller - ldr r0, =sirfsoc_rtciobrg_base - ldr r7, [r0] - - @ Read the power control register and set the - @ sleep force bit. - add r0, r6, #SIRFSOC_PWRC_PDN_CTRL - bl __sirfsoc_rtc_iobrg_readl - orr r0,r0,#SIRFSOC_PWR_SLEEPFORCE - add r1, r6, #SIRFSOC_PWRC_PDN_CTRL - bl sirfsoc_rtc_iobrg_pre_writel - mov r1, #0x1 - - @ read the MEM ctl register and set the self - @ refresh bit - - ldr r2, [r5, #DENALI_CTL_22_OFF] - orr r2, r2, #0x1 - - @ Following code has to run from cache since - @ the RAM is going to self refresh mode - .align 5 - str r2, [r5, #DENALI_CTL_22_OFF] - -1: - ldr r4, [r5, #DENALI_CTL_112_OFF] - tst r4, #0x1 - bne 1b - - @ write SLEEPFORCE through rtc iobridge - - str r1, [r7] - @ wait rtc io bridge sync -1: - ldr r3, [r7] - tst r3, #0x01 - bne 1b - b . -- cgit v1.2.3 From 89d4f98ae90d95716009bb89823118a8cfbb94dd Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Mon, 18 Jan 2021 14:06:09 +0100 Subject: ARM: remove zte zx platform The ZTE ZX set-top-box SoC platform was added in 2015 by Jun Nie, with Baoyou Xie and Shawn Guo subsequently becoming maintainers after the addition of the 64-bit variant. However, the only machines that were ever supported upstream are the reference designs, not actual set-top-box devices that would benefit from this support. All ZTE set-top-boxes from the past few years seem to be based on third-party SoCs. While there is very little information about zx296702 and zx296718 on the web, I found some references to other chips from the same family, such as zx296716 and zx296719, which were never submitted for upstream support. Finally, there is no support for the GPU on either of them, with the lima and panfrost device drivers having been added after work on the zx platform had stopped. Shawn confirmed that he has not seen any interest in this platform for the past four years, and that it can be removed. Thanks to Jun and Shawn for maintaining this platform over the past five years. Cc: Jun Nie Cc: Shawn Guo Signed-off-by: Arnd Bergmann --- .../devicetree/bindings/arm/zte,sysctrl.txt | 30 - Documentation/devicetree/bindings/arm/zte.yaml | 28 - .../devicetree/bindings/reset/zte,zx2967-reset.txt | 20 - .../devicetree/bindings/serial/pl011.yaml | 2 - .../devicetree/bindings/soc/zte/pd-2967xx.txt | 19 - MAINTAINERS | 42 -- arch/arm/Kconfig | 2 - arch/arm/Kconfig.debug | 14 - arch/arm/Makefile | 1 - arch/arm/boot/dts/Makefile | 1 - arch/arm/boot/dts/zx296702-ad1.dts | 48 -- arch/arm/boot/dts/zx296702.dtsi | 142 ----- arch/arm/configs/zx_defconfig | 122 ---- arch/arm/mach-zx/Kconfig | 21 - arch/arm/mach-zx/Makefile | 3 - arch/arm/mach-zx/core.h | 16 - arch/arm/mach-zx/headsmp.S | 30 - arch/arm/mach-zx/platsmp.c | 186 ------ arch/arm/mach-zx/zx296702-pm-domain.c | 202 ------- arch/arm/mach-zx/zx296702.c | 22 - arch/arm64/Kconfig.platforms | 6 - arch/arm64/boot/dts/Makefile | 1 - arch/arm64/boot/dts/zte/Makefile | 3 - arch/arm64/boot/dts/zte/zx296718-evb.dts | 144 ----- arch/arm64/boot/dts/zte/zx296718-pcbox.dts | 143 ----- arch/arm64/boot/dts/zte/zx296718.dtsi | 627 --------------------- drivers/reset/Kconfig | 2 +- drivers/soc/Kconfig | 1 - drivers/soc/Makefile | 1 - drivers/soc/zte/Kconfig | 15 - drivers/soc/zte/Makefile | 6 - drivers/soc/zte/zx296718_pm_domains.c | 181 ------ drivers/soc/zte/zx2967_pm_domains.c | 141 ----- drivers/soc/zte/zx2967_pm_domains.h | 44 -- 34 files changed, 1 insertion(+), 2265 deletions(-) delete mode 100644 Documentation/devicetree/bindings/arm/zte,sysctrl.txt delete mode 100644 Documentation/devicetree/bindings/arm/zte.yaml delete mode 100644 Documentation/devicetree/bindings/reset/zte,zx2967-reset.txt delete mode 100644 Documentation/devicetree/bindings/soc/zte/pd-2967xx.txt delete mode 100644 arch/arm/boot/dts/zx296702-ad1.dts delete mode 100644 arch/arm/boot/dts/zx296702.dtsi delete mode 100644 arch/arm/configs/zx_defconfig delete mode 100644 arch/arm/mach-zx/Kconfig delete mode 100644 arch/arm/mach-zx/Makefile delete mode 100644 arch/arm/mach-zx/core.h delete mode 100644 arch/arm/mach-zx/headsmp.S delete mode 100644 arch/arm/mach-zx/platsmp.c delete mode 100644 arch/arm/mach-zx/zx296702-pm-domain.c delete mode 100644 arch/arm/mach-zx/zx296702.c delete mode 100644 arch/arm64/boot/dts/zte/Makefile delete mode 100644 arch/arm64/boot/dts/zte/zx296718-evb.dts delete mode 100644 arch/arm64/boot/dts/zte/zx296718-pcbox.dts delete mode 100644 arch/arm64/boot/dts/zte/zx296718.dtsi delete mode 100644 drivers/soc/zte/Kconfig delete mode 100644 drivers/soc/zte/Makefile delete mode 100644 drivers/soc/zte/zx296718_pm_domains.c delete mode 100644 drivers/soc/zte/zx2967_pm_domains.c delete mode 100644 drivers/soc/zte/zx2967_pm_domains.h (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/arm/zte,sysctrl.txt b/Documentation/devicetree/bindings/arm/zte,sysctrl.txt deleted file mode 100644 index 7e66b7f7ba96..000000000000 --- a/Documentation/devicetree/bindings/arm/zte,sysctrl.txt +++ /dev/null @@ -1,30 +0,0 @@ -ZTE sysctrl Registers - -Registers for 'zte,zx296702' SoC: - -System management required properties: - - compatible = "zte,sysctrl" - -Low power management required properties: - - compatible = "zte,zx296702-pcu" - -Bus matrix required properties: - - compatible = "zte,zx-bus-matrix" - - -Registers for 'zte,zx296718' SoC: - -System management required properties: - - compatible = "zte,zx296718-aon-sysctrl" - - compatible = "zte,zx296718-sysctrl" - -Example: -aon_sysctrl: aon-sysctrl@116000 { - compatible = "zte,zx296718-aon-sysctrl", "syscon"; - reg = <0x116000 0x1000>; -}; - -sysctrl: sysctrl@1463000 { - compatible = "zte,zx296718-sysctrl", "syscon"; - reg = <0x1463000 0x1000>; -}; diff --git a/Documentation/devicetree/bindings/arm/zte.yaml b/Documentation/devicetree/bindings/arm/zte.yaml deleted file mode 100644 index 672f8129cd31..000000000000 --- a/Documentation/devicetree/bindings/arm/zte.yaml +++ /dev/null @@ -1,28 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0 -%YAML 1.2 ---- -$id: http://devicetree.org/schemas/arm/zte.yaml# -$schema: http://devicetree.org/meta-schemas/core.yaml# - -title: ZTE platforms device tree bindings - -maintainers: - - Jun Nie - -properties: - $nodename: - const: '/' - compatible: - oneOf: - - items: - - enum: - - zte,zx296702-ad1 - - const: zte,zx296702 - - items: - - enum: - - zte,zx296718-evb - - const: zte,zx296718 - -additionalProperties: true - -... diff --git a/Documentation/devicetree/bindings/reset/zte,zx2967-reset.txt b/Documentation/devicetree/bindings/reset/zte,zx2967-reset.txt deleted file mode 100644 index b015508f9780..000000000000 --- a/Documentation/devicetree/bindings/reset/zte,zx2967-reset.txt +++ /dev/null @@ -1,20 +0,0 @@ -ZTE zx2967 SoCs Reset Controller -======================================= - -Please also refer to reset.txt in this directory for common reset -controller binding usage. - -Required properties: -- compatible: should be one of the following. - * zte,zx296718-reset -- reg: physical base address of the controller and length of memory mapped - region. -- #reset-cells: must be 1. - -example: - - reset: reset-controller@1461060 { - compatible = "zte,zx296718-reset"; - reg = <0x01461060 0x8>; - #reset-cells = <1>; - }; diff --git a/Documentation/devicetree/bindings/serial/pl011.yaml b/Documentation/devicetree/bindings/serial/pl011.yaml index c23c93b400f0..1a51c532e8d2 100644 --- a/Documentation/devicetree/bindings/serial/pl011.yaml +++ b/Documentation/devicetree/bindings/serial/pl011.yaml @@ -19,7 +19,6 @@ select: contains: enum: - arm,pl011 - - zte,zx296702-uart required: - compatible @@ -30,7 +29,6 @@ properties: - const: arm,pl011 - const: arm,primecell - items: - - const: zte,zx296702-uart - const: arm,primecell reg: diff --git a/Documentation/devicetree/bindings/soc/zte/pd-2967xx.txt b/Documentation/devicetree/bindings/soc/zte/pd-2967xx.txt deleted file mode 100644 index 7629de1c2c72..000000000000 --- a/Documentation/devicetree/bindings/soc/zte/pd-2967xx.txt +++ /dev/null @@ -1,19 +0,0 @@ -* ZTE zx2967 family Power Domains - -zx2967 family includes support for multiple power domains which are used -to gate power to one or more peripherals on the processor. - -Required Properties: - - compatible: should be one of the following. - * zte,zx296718-pcu - for zx296718 power domain. - - reg: physical base address of the controller and length of memory mapped - region. - - #power-domain-cells: Must be 1. - -Example: - - pcu_domain: pcu@117000 { - compatible = "zte,zx296718-pcu"; - reg = <0x00117000 0x1000>; - #power-domain-cells = <1>; - }; diff --git a/MAINTAINERS b/MAINTAINERS index aeef69cbc7ec..54b5e6dee017 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -2704,40 +2704,6 @@ S: Maintained F: arch/arm/mach-pxa/include/mach/z2.h F: arch/arm/mach-pxa/z2.c -ARM/ZTE ARCHITECTURE -M: Jun Nie -M: Shawn Guo -L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) -S: Maintained -F: Documentation/devicetree/bindings/arm/zte.yaml -F: Documentation/devicetree/bindings/clock/zx2967*.txt -F: Documentation/devicetree/bindings/dma/zxdma.txt -F: Documentation/devicetree/bindings/gpio/zx296702-gpio.txt -F: Documentation/devicetree/bindings/i2c/i2c-zx2967.txt -F: Documentation/devicetree/bindings/mmc/zx-dw-mshc.txt -F: Documentation/devicetree/bindings/pinctrl/pinctrl-zx.txt -F: Documentation/devicetree/bindings/reset/zte,zx2967-reset.txt -F: Documentation/devicetree/bindings/soc/zte/ -F: Documentation/devicetree/bindings/sound/zte,*.txt -F: Documentation/devicetree/bindings/thermal/zx2967-thermal.txt -F: Documentation/devicetree/bindings/watchdog/zte,zx2967-wdt.txt -F: arch/arm/boot/dts/zx2967* -F: arch/arm/mach-zx/ -F: arch/arm64/boot/dts/zte/ -F: drivers/clk/zte/ -F: drivers/dma/zx_dma.c -F: drivers/gpio/gpio-zx.c -F: drivers/i2c/busses/i2c-zx2967.c -F: drivers/mmc/host/dw_mmc-zx.* -F: drivers/pinctrl/zte/ -F: drivers/soc/zte/ -F: drivers/thermal/zx2967_thermal.c -F: drivers/watchdog/zx2967_wdt.c -F: include/dt-bindings/clock/zx2967*.h -F: include/dt-bindings/soc/zte,*.h -F: sound/soc/codecs/zx_aud96p22.c -F: sound/soc/zte/ - ARM/ZYNQ ARCHITECTURE M: Michal Simek L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) @@ -6029,14 +5995,6 @@ T: git git://anongit.freedesktop.org/drm/drm-misc F: Documentation/devicetree/bindings/display/xlnx/ F: drivers/gpu/drm/xlnx/ -DRM DRIVERS FOR ZTE ZX -M: Shawn Guo -L: dri-devel@lists.freedesktop.org -S: Maintained -T: git git://anongit.freedesktop.org/drm/drm-misc -F: Documentation/devicetree/bindings/display/zte,vou.txt -F: drivers/gpu/drm/zte/ - DRM PANEL DRIVERS M: Thierry Reding R: Sam Ravnborg diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 9d9a7060d365..9f605ab54570 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -718,8 +718,6 @@ source "arch/arm/mach-vexpress/Kconfig" source "arch/arm/mach-vt8500/Kconfig" -source "arch/arm/mach-zx/Kconfig" - source "arch/arm/mach-zynq/Kconfig" # ARMv7-M architecture diff --git a/arch/arm/Kconfig.debug b/arch/arm/Kconfig.debug index fe8b95069d31..543e29068c08 100644 --- a/arch/arm/Kconfig.debug +++ b/arch/arm/Kconfig.debug @@ -1353,18 +1353,6 @@ choice This option selects UART0 on VIA/Wondermedia System-on-a-chip devices, including VT8500, WM8505, WM8650 and WM8850. - config DEBUG_ZTE_ZX - bool "Use ZTE ZX UART" - select DEBUG_UART_PL01X - depends on ARCH_ZX - help - Say Y here if you are enabling ZTE ZX296702 SOC and need - debug uart support. - - This option is preferred over the platform specific - options; the platform specific options are deprecated - and will be soon removed. - config DEBUG_ZYNQ_UART0 bool "Kernel low-level debugging on Xilinx Zynq using UART0" depends on ARCH_ZYNQ @@ -1599,7 +1587,6 @@ config DEBUG_UART_PHYS default 0x02531000 if DEBUG_KEYSTONE_UART1 default 0x03010fe0 if ARCH_RPC default 0x07000000 if DEBUG_SUN9I_UART0 - default 0x09405000 if DEBUG_ZTE_ZX default 0x10009000 if DEBUG_REALVIEW_STD_PORT || \ DEBUG_VEXPRESS_UART0_CA9 default 0x1010c000 if DEBUG_REALVIEW_PB1176_PORT @@ -1782,7 +1769,6 @@ config DEBUG_UART_VIRT default 0xfb020000 if DEBUG_OMAP3UART3 default 0xfb042000 if DEBUG_OMAP3UART4 default 0xfb10c000 if DEBUG_REALVIEW_PB1176_PORT - default 0xfc705000 if DEBUG_ZTE_ZX default 0xfcfe8600 if DEBUG_BCM63XX_UART default 0xfd000000 if DEBUG_SPEAR3XX || DEBUG_SPEAR13XX default 0xfd883000 if DEBUG_ALPINE_UART0 diff --git a/arch/arm/Makefile b/arch/arm/Makefile index 7c4b50852a78..7b8eed93f1fa 100644 --- a/arch/arm/Makefile +++ b/arch/arm/Makefile @@ -220,7 +220,6 @@ machine-$(CONFIG_ARCH_U8500) += ux500 machine-$(CONFIG_ARCH_VERSATILE) += versatile machine-$(CONFIG_ARCH_VEXPRESS) += vexpress machine-$(CONFIG_ARCH_VT8500) += vt8500 -machine-$(CONFIG_ARCH_ZX) += zx machine-$(CONFIG_ARCH_ZYNQ) += zynq machine-$(CONFIG_PLAT_SPEAR) += spear diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile index da413b4d5c3f..5fcae846aa00 100644 --- a/arch/arm/boot/dts/Makefile +++ b/arch/arm/boot/dts/Makefile @@ -1387,7 +1387,6 @@ dtb-$(CONFIG_ARCH_MSTARV7) += \ mstar-infinity2m-ssd202d-ssd201htv2.dtb \ mstar-infinity3-msc313e-breadbee.dtb \ mstar-mercury5-ssc8336n-midrived08.dtb -dtb-$(CONFIG_ARCH_ZX) += zx296702-ad1.dtb dtb-$(CONFIG_ARCH_ASPEED) += \ aspeed-ast2500-evb.dtb \ aspeed-ast2600-evb.dtb \ diff --git a/arch/arm/boot/dts/zx296702-ad1.dts b/arch/arm/boot/dts/zx296702-ad1.dts deleted file mode 100644 index bd9400840023..000000000000 --- a/arch/arm/boot/dts/zx296702-ad1.dts +++ /dev/null @@ -1,48 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 - -/dts-v1/; - -#include "zx296702.dtsi" - -/ { - model = "ZTE ZX296702 AD1 Board"; - compatible = "zte,zx296702-ad1", "zte,zx296702"; - - aliases { - serial0 = &uart0; - serial1 = &uart1; - }; - - memory { - device_type = "memory"; - reg = <0x50000000 0x20000000>; - }; -}; - -&mmc0 { - supports-highspeed; - non-removable; - disable-wp; - status = "okay"; - - slot@0 { - reg = <0>; - bus-width = <4>; - }; -}; - -&mmc1 { - supports-highspeed; - non-removable; - disable-wp; - status = "okay"; - - slot@0 { - reg = <0>; - bus-width = <8>; - }; -}; - -&uart0 { - status = "okay"; -}; diff --git a/arch/arm/boot/dts/zx296702.dtsi b/arch/arm/boot/dts/zx296702.dtsi deleted file mode 100644 index f378c661b3bf..000000000000 --- a/arch/arm/boot/dts/zx296702.dtsi +++ /dev/null @@ -1,142 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 - -#include -#include - -/ { - #address-cells = <1>; - #size-cells = <1>; - - cpus { - #address-cells = <1>; - #size-cells = <0>; - enable-method = "zte,zx296702-smp"; - - cpu@0 { - compatible = "arm,cortex-a9"; - device_type = "cpu"; - next-level-cache = <&l2cc>; - reg = <0>; - }; - - cpu@1 { - compatible = "arm,cortex-a9"; - device_type = "cpu"; - next-level-cache = <&l2cc>; - reg = <1>; - }; - }; - - - soc { - #address-cells = <1>; - #size-cells = <1>; - compatible = "simple-bus"; - interrupt-parent = <&intc>; - ranges; - - matrix: bus-matrix@400000 { - compatible = "zte,zx-bus-matrix"; - reg = <0x00400000 0x1000>; - }; - - intc: interrupt-controller@801000 { - compatible = "arm,cortex-a9-gic"; - #interrupt-cells = <3>; - #address-cells = <1>; - #size-cells = <1>; - interrupt-controller; - reg = <0x00801000 0x1000>, - <0x00800100 0x100>; - }; - - global_timer: timer@8000200 { - compatible = "arm,cortex-a9-global-timer"; - reg = <0x00800200 0x20>; - interrupts = ; - interrupt-parent = <&intc>; - clocks = <&topclk ZX296702_A9_PERIPHCLK>; - }; - - l2cc: cache-controller@c00000 { - compatible = "arm,pl310-cache"; - reg = <0x00c00000 0x1000>; - cache-unified; - cache-level = <2>; - arm,data-latency = <1 1 1>; - arm,tag-latency = <1 1 1>; - arm,double-linefill = <1>; - arm,double-linefill-incr = <0>; - }; - - pcu: pcu@a0008000 { - compatible = "zte,zx296702-pcu"; - reg = <0xa0008000 0x1000>; - }; - - topclk: topclk@9800000 { - compatible = "zte,zx296702-topcrm-clk"; - reg = <0x09800000 0x1000>; - #clock-cells = <1>; - }; - - lsp1clk: lsp1clk@9400000 { - compatible = "zte,zx296702-lsp1crpm-clk"; - reg = <0x09400000 0x1000>; - #clock-cells = <1>; - }; - - lsp0clk: lsp0clk@b000000 { - compatible = "zte,zx296702-lsp0crpm-clk"; - reg = <0x0b000000 0x1000>; - #clock-cells = <1>; - }; - - uart0: serial@9405000 { - compatible = "zte,zx296702-uart"; - reg = <0x09405000 0x1000>; - interrupts = ; - clocks = <&lsp1clk ZX296702_UART0_WCLK>; - status = "disabled"; - }; - - uart1: serial@9406000 { - compatible = "zte,zx296702-uart"; - reg = <0x09406000 0x1000>; - interrupts = ; - clocks = <&lsp1clk ZX296702_UART1_WCLK>; - status = "disabled"; - }; - - mmc0: mmc@9408000 { - compatible = "snps,dw-mshc"; - #address-cells = <1>; - #size-cells = <0>; - reg = <0x09408000 0x1000>; - interrupts = ; - fifo-depth = <32>; - clocks = <&lsp1clk ZX296702_SDMMC0_PCLK>, - <&lsp1clk ZX296702_SDMMC0_WCLK>; - clock-names = "biu", "ciu"; - status = "disabled"; - }; - - mmc1: mmc@b003000 { - compatible = "snps,dw-mshc"; - #address-cells = <1>; - #size-cells = <0>; - reg = <0x0b003000 0x1000>; - interrupts = ; - fifo-depth = <32>; - clocks = <&lsp0clk ZX296702_SDMMC1_PCLK>, - <&lsp0clk ZX296702_SDMMC1_WCLK>; - clock-names = "biu", "ciu"; - status = "disabled"; - }; - - sysctrl: sysctrl@a0007000 { - compatible = "zte,sysctrl", "syscon"; - reg = <0xa0007000 0x1000>; - }; - }; -}; diff --git a/arch/arm/configs/zx_defconfig b/arch/arm/configs/zx_defconfig deleted file mode 100644 index a046a492bfa7..000000000000 --- a/arch/arm/configs/zx_defconfig +++ /dev/null @@ -1,122 +0,0 @@ -CONFIG_SYSVIPC=y -CONFIG_NO_HZ=y -CONFIG_HIGH_RES_TIMERS=y -CONFIG_LOG_BUF_SHIFT=14 -CONFIG_CGROUPS=y -CONFIG_CGROUP_DEBUG=y -CONFIG_CGROUP_FREEZER=y -CONFIG_CGROUP_CPUACCT=y -CONFIG_CGROUP_SCHED=y -CONFIG_RT_GROUP_SCHED=y -CONFIG_NAMESPACES=y -CONFIG_USER_NS=y -CONFIG_BLK_DEV_INITRD=y -CONFIG_KALLSYMS_ALL=y -CONFIG_EMBEDDED=y -CONFIG_PERF_EVENTS=y -CONFIG_SLAB=y -# CONFIG_BLK_DEV_BSG is not set -CONFIG_ARCH_ZX=y -CONFIG_SOC_ZX296702=y -# CONFIG_SWP_EMULATE is not set -CONFIG_ARM_ERRATA_754322=y -CONFIG_ARM_ERRATA_775420=y -CONFIG_SMP=y -CONFIG_VMSPLIT_2G=y -CONFIG_PREEMPT=y -CONFIG_AEABI=y -CONFIG_KSM=y -# CONFIG_IOMMU_SUPPORT is not set -CONFIG_VFP=y -CONFIG_NEON=y -CONFIG_KERNEL_MODE_NEON=y -# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set -CONFIG_HIBERNATION=y -CONFIG_PM_RUNTIME=y -CONFIG_PM_DEBUG=y -CONFIG_SUSPEND_TIME=y -CONFIG_ZBOOT_ROM_TEXT=0x0 -CONFIG_ZBOOT_ROM_BSS=0x0 -CONFIG_CMDLINE="console=ttyAMA0,115200 debug earlyprintk root=/dev/ram rw rootwait" -#CONFIG_NET is not set -CONFIG_DEVTMPFS=y -CONFIG_DEVTMPFS_MOUNT=y -CONFIG_DMA_CMA=y -CONFIG_CMA_SIZE_MBYTES=192 -CONFIG_BLK_DEV_LOOP=y -CONFIG_BLK_DEV_RAM=y -CONFIG_BLK_DEV_RAM_COUNT=1 -CONFIG_BLK_DEV_RAM_SIZE=8192 -CONFIG_UID_STAT=y -CONFIG_SCSI=y -CONFIG_BLK_DEV_SD=y -CONFIG_CHR_DEV_SG=y -CONFIG_CHR_DEV_SCH=y -CONFIG_SCSI_MULTI_LUN=y -CONFIG_MD=y -CONFIG_BLK_DEV_DM=y -CONFIG_DM_CRYPT=y -CONFIG_DM_UEVENT=y -CONFIG_DM_VERITY=y -CONFIG_NETDEVICES=y -# CONFIG_INPUT_MOUSE is not set -CONFIG_SERIO=y -CONFIG_SERIO_LIBPS2=y -CONFIG_SPI=y -CONFIG_LOGO=y -CONFIG_SERIAL_CORE=y -CONFIG_SERIAL_CORE_CONSOLE=y -CONFIG_CONSOLE_POLL=y -CONFIG_SERIAL_AMBA_PL011=y -CONFIG_SERIAL_AMBA_PL011_CONSOLE=y -CONFIG_SERIAL_OF_PLATFORM=y -# CONFIG_LEGACY_PTYS is not set -# CONFIG_HW_RANDOM is not set -# CONFIG_HWMON is not set -# CONFIG_USB_SUPPORT is not set -CONFIG_MMC=y -CONFIG_MMC_BLOCK_MINORS=16 -CONFIG_MMC_DW=y -CONFIG_EXT2_FS=y -CONFIG_EXT4_FS=y -CONFIG_EXT4_FS_POSIX_ACL=y -CONFIG_EXT4_FS_SECURITY=y -CONFIG_EXT4_DEBUG=y -CONFIG_FUSE_FS=y -CONFIG_MSDOS_FS=y -CONFIG_VFAT_FS=y -CONFIG_FAT_DEFAULT_CODEPAGE=936 -CONFIG_TMPFS=y -CONFIG_TMPFS_POSIX_ACL=y -#CONFIG_NFS_FS is not set -CONFIG_NLS_CODEPAGE_936=y -CONFIG_NLS_ISO8859_1=y -CONFIG_NLS_UTF8=y -CONFIG_PRINTK_TIME=y -CONFIG_MAGIC_SYSRQ=y -CONFIG_DEBUG_KERNEL=y -CONFIG_DEBUG_INFO=y -CONFIG_FRAME_WARN=4096 -CONFIG_DEBUG_FS=y -CONFIG_DEBUG_MEMORY_INIT=y -CONFIG_PANIC_TIMEOUT=5 -# CONFIG_SCHED_DEBUG is not set -CONFIG_SCHEDSTATS=y -CONFIG_TIMER_STATS=y -CONFIG_DEBUG_RT_MUTEXES=y -CONFIG_DEBUG_SPINLOCK=y -CONFIG_DEBUG_MUTEXES=y -CONFIG_RCU_CPU_STALL_TIMEOUT=60 -# CONFIG_FTRACE is not set -CONFIG_KGDB=y -CONFIG_KGDB_KDB=y -# CONFIG_ARM_UNWIND is not set -CONFIG_DEBUG_PREEMPT=y -CONFIG_DEBUG_USER=y -CONFIG_DEBUG_LL=y -CONFIG_DYNAMIC_DEBUG=y -CONFIG_STACKTRACE=y -CONFIG_DEBUG_ZTE_ZX=y -CONFIG_EARLY_PRINTK=y -CONFIG_CRYPTO_LZO=y -CONFIG_GPIOLIB=y diff --git a/arch/arm/mach-zx/Kconfig b/arch/arm/mach-zx/Kconfig deleted file mode 100644 index ea29c84a7849..000000000000 --- a/arch/arm/mach-zx/Kconfig +++ /dev/null @@ -1,21 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0 -menuconfig ARCH_ZX - bool "ZTE ZX family" - depends on ARCH_MULTI_V7 - help - Support for ZTE ZX-based family of processors. TV - set-top-box processor is supported. More will be - added soon. - -if ARCH_ZX - -config SOC_ZX296702 - def_bool y - select ARM_GIC - select ARM_GLOBAL_TIMER - select HAVE_ARM_SCU if SMP - select HAVE_ARM_TWD if SMP - select PM_GENERIC_DOMAINS if PM - help - Support for ZTE ZX296702 SoC which is a dual core CortexA9MP -endif diff --git a/arch/arm/mach-zx/Makefile b/arch/arm/mach-zx/Makefile deleted file mode 100644 index 6f8930cdb8fb..000000000000 --- a/arch/arm/mach-zx/Makefile +++ /dev/null @@ -1,3 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0-only -obj-$(CONFIG_SOC_ZX296702) += zx296702.o zx296702-pm-domain.o -obj-$(CONFIG_SMP) += headsmp.o platsmp.o diff --git a/arch/arm/mach-zx/core.h b/arch/arm/mach-zx/core.h deleted file mode 100644 index 25fe873892c9..000000000000 --- a/arch/arm/mach-zx/core.h +++ /dev/null @@ -1,16 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ -/* - * Copyright 2014 Linaro Ltd. - * Copyright (C) 2014 ZTE Corporation. - */ - -#ifndef __MACH_ZX_CORE_H -#define __MACH_ZX_CORE_H - -extern void zx_resume_jump(void); -extern size_t zx_suspend_iram_sz; -extern unsigned long zx_secondary_startup_pa; - -void zx_secondary_startup(void); - -#endif /* __MACH_ZX_CORE_H */ diff --git a/arch/arm/mach-zx/headsmp.S b/arch/arm/mach-zx/headsmp.S deleted file mode 100644 index 0846859b0573..000000000000 --- a/arch/arm/mach-zx/headsmp.S +++ /dev/null @@ -1,30 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ -/* - * Copyright 2014 Linaro Ltd. - * Copyright (C) 2014 ZTE Corporation. - */ - -#include - - .align 3 - .arm - -/* It runs from physical address */ -ENTRY(zx_resume_jump) - adr r1, zx_secondary_startup_pa - ldr r0, [r1] - bx r0 -ENDPROC(zx_resume_jump) - -ENTRY(zx_secondary_startup_pa) - .word zx_secondary_startup_pa - -ENTRY(zx_suspend_iram_sz) - .word . - zx_resume_jump -ENDPROC(zx_secondary_startup_pa) - - -ENTRY(zx_secondary_startup) - bl v7_invalidate_l1 - b secondary_startup -ENDPROC(zx_secondary_startup) diff --git a/arch/arm/mach-zx/platsmp.c b/arch/arm/mach-zx/platsmp.c deleted file mode 100644 index d4e1d3792224..000000000000 --- a/arch/arm/mach-zx/platsmp.c +++ /dev/null @@ -1,186 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Copyright 2014 Linaro Ltd. - * Copyright (C) 2014 ZTE Corporation. - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -#include "core.h" - -#define AON_SYS_CTRL_RESERVED1 0xa8 - -#define BUS_MATRIX_REMAP_CONFIG 0x00 - -#define PCU_CPU0_CTRL 0x00 -#define PCU_CPU1_CTRL 0x04 -#define PCU_CPU1_ST 0x0c -#define PCU_GLOBAL_CTRL 0x14 -#define PCU_EXPEND_CONTROL 0x34 - -#define ZX_IRAM_BASE 0x00200000 - -static void __iomem *pcu_base; -static void __iomem *matrix_base; -static void __iomem *scu_base; - -void __init zx_smp_prepare_cpus(unsigned int max_cpus) -{ - struct device_node *np; - unsigned long base = 0; - void __iomem *aonsysctrl_base; - void __iomem *sys_iram; - - base = scu_a9_get_base(); - scu_base = ioremap(base, SZ_256); - if (!scu_base) { - pr_err("%s: failed to map scu\n", __func__); - return; - } - - scu_enable(scu_base); - - np = of_find_compatible_node(NULL, NULL, "zte,sysctrl"); - if (!np) { - pr_err("%s: failed to find sysctrl node\n", __func__); - return; - } - - aonsysctrl_base = of_iomap(np, 0); - if (!aonsysctrl_base) { - pr_err("%s: failed to map aonsysctrl\n", __func__); - of_node_put(np); - return; - } - - /* - * Write the address of secondary startup into the - * system-wide flags register. The BootMonitor waits - * until it receives a soft interrupt, and then the - * secondary CPU branches to this address. - */ - __raw_writel(__pa_symbol(zx_secondary_startup), - aonsysctrl_base + AON_SYS_CTRL_RESERVED1); - - iounmap(aonsysctrl_base); - of_node_put(np); - - np = of_find_compatible_node(NULL, NULL, "zte,zx296702-pcu"); - pcu_base = of_iomap(np, 0); - of_node_put(np); - WARN_ON(!pcu_base); - - np = of_find_compatible_node(NULL, NULL, "zte,zx-bus-matrix"); - matrix_base = of_iomap(np, 0); - of_node_put(np); - WARN_ON(!matrix_base); - - /* Map the first 4 KB IRAM for suspend usage */ - sys_iram = __arm_ioremap_exec(ZX_IRAM_BASE, PAGE_SIZE, false); - zx_secondary_startup_pa = __pa_symbol(zx_secondary_startup); - fncpy(sys_iram, &zx_resume_jump, zx_suspend_iram_sz); -} - -static int zx_boot_secondary(unsigned int cpu, struct task_struct *idle) -{ - static bool first_boot = true; - - if (first_boot) { - arch_send_wakeup_ipi_mask(cpumask_of(cpu)); - first_boot = false; - return 0; - } - - /* Swap the base address mapping between IRAM and IROM */ - writel_relaxed(0x1, matrix_base + BUS_MATRIX_REMAP_CONFIG); - - /* Power on CPU1 */ - writel_relaxed(0x0, pcu_base + PCU_CPU1_CTRL); - - /* Wait for power on ack */ - while (readl_relaxed(pcu_base + PCU_CPU1_ST) & 0x4) - cpu_relax(); - - /* Swap back the mapping of IRAM and IROM */ - writel_relaxed(0x0, matrix_base + BUS_MATRIX_REMAP_CONFIG); - - return 0; -} - -#ifdef CONFIG_HOTPLUG_CPU -static inline void cpu_enter_lowpower(void) -{ - unsigned int v; - - asm volatile( - "mcr p15, 0, %1, c7, c5, 0\n" - " mcr p15, 0, %1, c7, c10, 4\n" - /* - * Turn off coherency - */ - " mrc p15, 0, %0, c1, c0, 1\n" - " bic %0, %0, %3\n" - " mcr p15, 0, %0, c1, c0, 1\n" - " mrc p15, 0, %0, c1, c0, 0\n" - " bic %0, %0, %2\n" - " mcr p15, 0, %0, c1, c0, 0\n" - : "=&r" (v) - : "r" (0), "Ir" (CR_C), "Ir" (0x40) - : "cc"); -} - -static int zx_cpu_kill(unsigned int cpu) -{ - unsigned long timeout = jiffies + msecs_to_jiffies(2000); - - writel_relaxed(0x2, pcu_base + PCU_CPU1_CTRL); - - while ((readl_relaxed(pcu_base + PCU_CPU1_ST) & 0x3) != 0x0) { - if (time_after(jiffies, timeout)) { - pr_err("*** cpu1 poweroff timeout\n"); - break; - } - } - return 1; -} - -static void zx_cpu_die(unsigned int cpu) -{ - scu_power_mode(scu_base, SCU_PM_POWEROFF); - cpu_enter_lowpower(); - - while (1) - cpu_do_idle(); -} -#endif - -static void zx_secondary_init(unsigned int cpu) -{ - scu_power_mode(scu_base, SCU_PM_NORMAL); -} - -static const struct smp_operations zx_smp_ops __initconst = { - .smp_prepare_cpus = zx_smp_prepare_cpus, - .smp_secondary_init = zx_secondary_init, - .smp_boot_secondary = zx_boot_secondary, -#ifdef CONFIG_HOTPLUG_CPU - .cpu_kill = zx_cpu_kill, - .cpu_die = zx_cpu_die, -#endif -}; - -CPU_METHOD_OF_DECLARE(zx_smp, "zte,zx296702-smp", &zx_smp_ops); diff --git a/arch/arm/mach-zx/zx296702-pm-domain.c b/arch/arm/mach-zx/zx296702-pm-domain.c deleted file mode 100644 index 7a08bf9dd792..000000000000 --- a/arch/arm/mach-zx/zx296702-pm-domain.c +++ /dev/null @@ -1,202 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Copyright (C) 2015 Linaro Ltd. - * - * Author: Jun Nie - */ -#include -#include -#include -#include -#include -#include -#include - -#define PCU_DM_CLKEN 0x18 -#define PCU_DM_RSTEN 0x1C -#define PCU_DM_ISOEN 0x20 -#define PCU_DM_PWRDN 0x24 -#define PCU_DM_ACK_SYNC 0x28 - -enum { - PCU_DM_NEON0 = 0, - PCU_DM_NEON1, - PCU_DM_GPU, - PCU_DM_DECPPU, - PCU_DM_VOU, - PCU_DM_R2D, - PCU_DM_TOP, -}; - -static void __iomem *pcubase; - -struct zx_pm_domain { - struct generic_pm_domain dm; - unsigned int bit; -}; - -static int normal_power_off(struct generic_pm_domain *domain) -{ - struct zx_pm_domain *zpd = (struct zx_pm_domain *)domain; - unsigned long loop = 1000; - u32 tmp; - - tmp = readl_relaxed(pcubase + PCU_DM_CLKEN); - tmp &= ~BIT(zpd->bit); - writel_relaxed(tmp, pcubase + PCU_DM_CLKEN); - udelay(5); - - tmp = readl_relaxed(pcubase + PCU_DM_ISOEN); - tmp &= ~BIT(zpd->bit); - writel_relaxed(tmp | BIT(zpd->bit), pcubase + PCU_DM_ISOEN); - udelay(5); - - tmp = readl_relaxed(pcubase + PCU_DM_RSTEN); - tmp &= ~BIT(zpd->bit); - writel_relaxed(tmp, pcubase + PCU_DM_RSTEN); - udelay(5); - - tmp = readl_relaxed(pcubase + PCU_DM_PWRDN); - tmp &= ~BIT(zpd->bit); - writel_relaxed(tmp | BIT(zpd->bit), pcubase + PCU_DM_PWRDN); - do { - tmp = readl_relaxed(pcubase + PCU_DM_ACK_SYNC) & BIT(zpd->bit); - } while (--loop && !tmp); - - if (!loop) { - pr_err("Error: %s %s fail\n", __func__, domain->name); - return -EIO; - } - - return 0; -} - -static int normal_power_on(struct generic_pm_domain *domain) -{ - struct zx_pm_domain *zpd = (struct zx_pm_domain *)domain; - unsigned long loop = 10000; - u32 tmp; - - tmp = readl_relaxed(pcubase + PCU_DM_PWRDN); - tmp &= ~BIT(zpd->bit); - writel_relaxed(tmp, pcubase + PCU_DM_PWRDN); - do { - tmp = readl_relaxed(pcubase + PCU_DM_ACK_SYNC) & BIT(zpd->bit); - } while (--loop && tmp); - - if (!loop) { - pr_err("Error: %s %s fail\n", __func__, domain->name); - return -EIO; - } - - tmp = readl_relaxed(pcubase + PCU_DM_RSTEN); - tmp &= ~BIT(zpd->bit); - writel_relaxed(tmp | BIT(zpd->bit), pcubase + PCU_DM_RSTEN); - udelay(5); - - tmp = readl_relaxed(pcubase + PCU_DM_ISOEN); - tmp &= ~BIT(zpd->bit); - writel_relaxed(tmp, pcubase + PCU_DM_ISOEN); - udelay(5); - - tmp = readl_relaxed(pcubase + PCU_DM_CLKEN); - tmp &= ~BIT(zpd->bit); - writel_relaxed(tmp | BIT(zpd->bit), pcubase + PCU_DM_CLKEN); - udelay(5); - return 0; -} - -static struct zx_pm_domain gpu_domain = { - .dm = { - .name = "gpu_domain", - .power_off = normal_power_off, - .power_on = normal_power_on, - }, - .bit = PCU_DM_GPU, -}; - -static struct zx_pm_domain decppu_domain = { - .dm = { - .name = "decppu_domain", - .power_off = normal_power_off, - .power_on = normal_power_on, - }, - .bit = PCU_DM_DECPPU, -}; - -static struct zx_pm_domain vou_domain = { - .dm = { - .name = "vou_domain", - .power_off = normal_power_off, - .power_on = normal_power_on, - }, - .bit = PCU_DM_VOU, -}; - -static struct zx_pm_domain r2d_domain = { - .dm = { - .name = "r2d_domain", - .power_off = normal_power_off, - .power_on = normal_power_on, - }, - .bit = PCU_DM_R2D, -}; - -static struct generic_pm_domain *zx296702_pm_domains[] = { - &vou_domain.dm, - &gpu_domain.dm, - &decppu_domain.dm, - &r2d_domain.dm, -}; - -static int zx296702_pd_probe(struct platform_device *pdev) -{ - struct genpd_onecell_data *genpd_data; - struct resource *res; - int i; - - genpd_data = devm_kzalloc(&pdev->dev, sizeof(*genpd_data), GFP_KERNEL); - if (!genpd_data) - return -ENOMEM; - - genpd_data->domains = zx296702_pm_domains; - genpd_data->num_domains = ARRAY_SIZE(zx296702_pm_domains); - - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!res) { - dev_err(&pdev->dev, "no memory resource defined\n"); - return -ENODEV; - } - - pcubase = devm_ioremap_resource(&pdev->dev, res); - if (IS_ERR(pcubase)) { - dev_err(&pdev->dev, "ioremap fail.\n"); - return -EIO; - } - - for (i = 0; i < ARRAY_SIZE(zx296702_pm_domains); ++i) - pm_genpd_init(zx296702_pm_domains[i], NULL, false); - - of_genpd_add_provider_onecell(pdev->dev.of_node, genpd_data); - return 0; -} - -static const struct of_device_id zx296702_pm_domain_matches[] __initconst = { - { .compatible = "zte,zx296702-pcu", }, - { }, -}; - -static struct platform_driver zx296702_pd_driver __initdata = { - .driver = { - .name = "zx-powerdomain", - .owner = THIS_MODULE, - .of_match_table = zx296702_pm_domain_matches, - }, - .probe = zx296702_pd_probe, -}; - -static int __init zx296702_pd_init(void) -{ - return platform_driver_register(&zx296702_pd_driver); -} -subsys_initcall(zx296702_pd_init); diff --git a/arch/arm/mach-zx/zx296702.c b/arch/arm/mach-zx/zx296702.c deleted file mode 100644 index fd8fa3a074fa..000000000000 --- a/arch/arm/mach-zx/zx296702.c +++ /dev/null @@ -1,22 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Copyright 2014 Linaro Ltd. - * Copyright (C) 2014 ZTE Corporation. - */ - -#include -#include - -#include -#include - -static const char *const zx296702_dt_compat[] __initconst = { - "zte,zx296702", - NULL, -}; - -DT_MACHINE_START(ZX, "ZTE ZX296702 (Device Tree)") - .dt_compat = zx296702_dt_compat, - .l2c_aux_val = 0, - .l2c_aux_mask = ~0, -MACHINE_END diff --git a/arch/arm64/Kconfig.platforms b/arch/arm64/Kconfig.platforms index 6eecdef538bd..ec3c0cb27d1e 100644 --- a/arch/arm64/Kconfig.platforms +++ b/arch/arm64/Kconfig.platforms @@ -317,12 +317,6 @@ config ARCH_XGENE help This enables support for AppliedMicro X-Gene SOC Family -config ARCH_ZX - bool "ZTE ZX SoC Family" - select PINCTRL - help - This enables support for ZTE ZX SoC Family - config ARCH_ZYNQMP bool "Xilinx ZynqMP Family" help diff --git a/arch/arm64/boot/dts/Makefile b/arch/arm64/boot/dts/Makefile index 9b1170658d60..f1173cd93594 100644 --- a/arch/arm64/boot/dts/Makefile +++ b/arch/arm64/boot/dts/Makefile @@ -29,4 +29,3 @@ subdir-y += synaptics subdir-y += ti subdir-y += toshiba subdir-y += xilinx -subdir-y += zte diff --git a/arch/arm64/boot/dts/zte/Makefile b/arch/arm64/boot/dts/zte/Makefile deleted file mode 100644 index 126896144bda..000000000000 --- a/arch/arm64/boot/dts/zte/Makefile +++ /dev/null @@ -1,3 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0-only -dtb-$(CONFIG_ARCH_ZX) += zx296718-evb.dtb -dtb-$(CONFIG_ARCH_ZX) += zx296718-pcbox.dtb diff --git a/arch/arm64/boot/dts/zte/zx296718-evb.dts b/arch/arm64/boot/dts/zte/zx296718-evb.dts deleted file mode 100644 index cb2519ecd724..000000000000 --- a/arch/arm64/boot/dts/zte/zx296718-evb.dts +++ /dev/null @@ -1,144 +0,0 @@ -/* - * Copyright 2016 ZTE Corporation. - * Copyright 2016 Linaro Ltd. - * - * This file is dual-licensed: you can use it either under the terms - * of the GPL or the X11 license, at your option. Note that this dual - * licensing only applies to this file, and not this project as a - * whole. - * - * a) This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * Or, alternatively, - * - * b) Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following - * conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - */ - -/dts-v1/; -#include "zx296718.dtsi" - -/ { - model = "ZTE zx296718 evaluation board"; - compatible = "zte,zx296718-evb", "zte,zx296718"; - - chosen { - stdout-path = "serial0:115200n8"; - }; - - memory@40000000 { - device_type = "memory"; - reg = <0x40000000 0x40000000>; - }; - - sound-spdif0 { - compatible = "audio-graph-card"; - dais = <&spdif0_port>; - }; - - sound-i2s0 { - compatible = "audio-graph-card"; - dais = <&i2s0_port>; - pinctrl-names = "default"; - pinctrl-0 = <&lifier_pins>; - pa-gpios = <&bgpio4 0 GPIO_ACTIVE_HIGH>; - widgets = "Line", "Line Out Jack"; - routing = "Amplifier", "LINEOUTL", - "Amplifier", "LINEOUTR", - "Line Out Jack", "Amplifier"; - }; -}; - -&aud96p22 { - port { - aud96p22_endpoint: endpoint { - remote-endpoint = <&i2s0_endpoint>; - }; - }; -}; - -&emmc { - status = "okay"; -}; - -&hdmi { - status = "okay"; - - port { - hdmi_endpoint: endpoint { - remote-endpoint = <&spdif0_endpoint>; - }; - }; -}; - -&i2c0 { - status = "okay"; -}; - -&i2s0 { - status = "okay"; - - i2s0_port: port { - i2s0_endpoint: endpoint { - remote-endpoint = <&aud96p22_endpoint>; - dai-format = "i2s"; - frame-master; - bitclock-master; - }; - }; -}; - -&pmm { - amplifier_pins: amplifier { - pins = "TSI3_DATA"; - function = "BGPIO"; - }; -}; - -&sd1 { - status = "okay"; -}; - -&spdif0 { - status = "okay"; - - spdif0_port: port { - spdif0_endpoint: endpoint { - remote-endpoint = <&hdmi_endpoint>; - }; - }; -}; - -&tvenc { - status = "okay"; -}; - -&uart0 { - status = "okay"; -}; diff --git a/arch/arm64/boot/dts/zte/zx296718-pcbox.dts b/arch/arm64/boot/dts/zte/zx296718-pcbox.dts deleted file mode 100644 index e02509f7082b..000000000000 --- a/arch/arm64/boot/dts/zte/zx296718-pcbox.dts +++ /dev/null @@ -1,143 +0,0 @@ -/* - * Copyright (C) 2017 Sanechips Technology Co., Ltd. - * Copyright 2017 Linaro Ltd. - * - * SPDX-License-Identifier: (GPL-2.0+ OR MIT) - */ - -/dts-v1/; -#include "zx296718.dtsi" -#include - -/ { - model = "ZTE ZX296718 PCBOX Board"; - compatible = "zte,zx296718-pcbox", "zte,zx296718"; - - chosen { - stdout-path = "serial0:115200n8"; - }; - - memory@80000000 { - device_type = "memory"; - reg = <0x80000000 0x80000000>; - }; - - a53_vdd0v9: regulator-a53 { - compatible = "pwm-regulator"; - pwms = <&pwm 3 1250 PWM_POLARITY_INVERTED>; - regulator-name = "A53_VDD0V9"; - regulator-min-microvolt = <855000>; - regulator-max-microvolt = <1183000>; - pwm-dutycycle-unit = <100>; - pwm-dutycycle-range = <0 100>; - regulator-always-on; - regulator-boot-on; - }; - - sound-spdif0 { - compatible = "audio-graph-card"; - dais = <&spdif0_port>; - }; - - sound-i2s0 { - compatible = "audio-graph-card"; - dais = <&i2s0_port>; - }; -}; - -&aud96p22 { - port { - aud96p22_endpoint: endpoint { - remote-endpoint = <&i2s0_endpoint>; - }; - }; -}; - -&cpu0 { - cpu-supply = <&a53_vdd0v9>; -}; - -&emmc { - status = "okay"; -}; - -&hdmi { - status = "disabled"; - - port { - hdmi_endpoint: endpoint { - remote-endpoint = <&spdif0_endpoint>; - }; - }; -}; - -&i2c0 { - status = "okay"; -}; - -&i2s0 { - status = "okay"; - - i2s0_port: port { - i2s0_endpoint: endpoint { - remote-endpoint = <&aud96p22_endpoint>; - dai-format = "i2s"; - frame-master; - bitclock-master; - }; - }; -}; - -&irdec { - status = "okay"; -}; - -&pmm { - pwm3_pins: pwm3 { - pins = "KEY_ROW2"; - function = "PWM"; - }; - - vga_pins: vga { - pins = "KEY_COL1", "KEY_COL2", "VGA_HS", "VGA_VS"; - function = "VGA"; - }; -}; - -&pwm { - pinctrl-names = "default"; - pinctrl-0 = <&pwm3_pins>; - status = "okay"; -}; - -&sd0 { - status = "okay"; -}; - -&sd1 { - status = "okay"; -}; - -&spdif0 { - status = "okay"; - - spdif0_port: port { - spdif0_endpoint: endpoint { - remote-endpoint = <&hdmi_endpoint>; - }; - }; -}; - -&tvenc { - status = "disabled"; -}; - -&uart0 { - status = "okay"; -}; - -&vga { - pinctrl-names = "default"; - pinctrl-0 = <&vga_pins>; - status = "okay"; -}; diff --git a/arch/arm64/boot/dts/zte/zx296718.dtsi b/arch/arm64/boot/dts/zte/zx296718.dtsi deleted file mode 100644 index cc54837ff4ba..000000000000 --- a/arch/arm64/boot/dts/zte/zx296718.dtsi +++ /dev/null @@ -1,627 +0,0 @@ -/* - * Copyright 2016 ZTE Corporation. - * Copyright 2016 Linaro Ltd. - * - * This file is dual-licensed: you can use it either under the terms - * of the GPL or the X11 license, at your option. Note that this dual - * licensing only applies to this file, and not this project as a - * whole. - * - * a) This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * Or, alternatively, - * - * b) Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following - * conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - */ - -#include -#include -#include -#include - -/ { - compatible = "zte,zx296718"; - #address-cells = <1>; - #size-cells = <1>; - interrupt-parent = <&gic>; - - aliases { - gpio0 = &bgpio0; - gpio1 = &bgpio1; - gpio2 = &bgpio2; - gpio3 = &bgpio3; - gpio4 = &bgpio4; - gpio5 = &bgpio5; - gpio6 = &bgpio6; - serial0 = &uart0; - }; - - cpus { - #address-cells = <2>; - #size-cells = <0>; - - cpu-map { - cluster0 { - core0 { - cpu = <&cpu0>; - }; - core1 { - cpu = <&cpu1>; - }; - core2 { - cpu = <&cpu2>; - }; - core3 { - cpu = <&cpu3>; - }; - }; - }; - - cpu0: cpu@0 { - device_type = "cpu"; - compatible = "arm,cortex-a53"; - reg = <0x0 0x0>; - enable-method = "psci"; - clocks = <&topcrm A53_GATE>; - operating-points-v2 = <&cluster0_opp>; - }; - - cpu1: cpu@1 { - device_type = "cpu"; - compatible = "arm,cortex-a53"; - reg = <0x0 0x1>; - enable-method = "psci"; - clocks = <&topcrm A53_GATE>; - operating-points-v2 = <&cluster0_opp>; - }; - - cpu2: cpu@2 { - device_type = "cpu"; - compatible = "arm,cortex-a53"; - reg = <0x0 0x2>; - enable-method = "psci"; - clocks = <&topcrm A53_GATE>; - operating-points-v2 = <&cluster0_opp>; - }; - - cpu3: cpu@3 { - device_type = "cpu"; - compatible = "arm,cortex-a53"; - reg = <0x0 0x3>; - enable-method = "psci"; - clocks = <&topcrm A53_GATE>; - operating-points-v2 = <&cluster0_opp>; - }; - }; - - cluster0_opp: opp-table0 { - compatible = "operating-points-v2"; - opp-shared; - - opp-500000000 { - opp-hz = /bits/ 64 <500000000>; - opp-microvolt = <866000>; - clock-latency-ns = <500000>; - }; - - opp-648000000 { - opp-hz = /bits/ 64 <648000000>; - opp-microvolt = <866000>; - clock-latency-ns = <500000>; - }; - - opp-800000000 { - opp-hz = /bits/ 64 <800000000>; - opp-microvolt = <888000>; - clock-latency-ns = <500000>; - }; - - opp-1000000000 { - opp-hz = /bits/ 64 <1000000000>; - opp-microvolt = <898000>; - clock-latency-ns = <500000>; - }; - - opp-1188000000 { - opp-hz = /bits/ 64 <1188000000>; - opp-microvolt = <1015000>; - clock-latency-ns = <500000>; - }; - }; - - clk24k: clk-24k { - compatible = "fixed-clock"; - #clock-cells = <0>; - clock-frequency = <24000>; - clock-output-names = "rtcclk"; - }; - - osc32k: clk-osc32k { - compatible = "fixed-clock"; - #clock-cells = <0>; - clock-frequency = <32000>; - clock-output-names = "osc32k"; - }; - - osc12m: clk-osc12m { - compatible = "fixed-clock"; - #clock-cells = <0>; - clock-frequency = <12000000>; - clock-output-names = "osc12m"; - }; - - osc24m: clk-osc24m { - compatible = "fixed-clock"; - #clock-cells = <0>; - clock-frequency = <24000000>; - clock-output-names = "osc24m"; - }; - - osc25m: clk-osc25m { - compatible = "fixed-clock"; - #clock-cells = <0>; - clock-frequency = <25000000>; - clock-output-names = "osc25m"; - }; - - osc60m: clk-osc60m { - compatible = "fixed-clock"; - #clock-cells = <0>; - clock-frequency = <60000000>; - clock-output-names = "osc60m"; - }; - - osc99m: clk-osc99m { - compatible = "fixed-clock"; - #clock-cells = <0>; - clock-frequency = <99000000>; - clock-output-names = "osc99m"; - }; - - osc125m: clk-osc125m { - compatible = "fixed-clock"; - #clock-cells = <0>; - clock-frequency = <125000000>; - clock-output-names = "osc125m"; - }; - - osc198m: clk-osc198m { - compatible = "fixed-clock"; - #clock-cells = <0>; - clock-frequency = <198000000>; - clock-output-names = "osc198m"; - }; - - pll_audio: clk-pll-884m { - compatible = "fixed-clock"; - #clock-cells = <0>; - clock-frequency = <884000000>; - clock-output-names = "pll_audio"; - }; - - pll_ddr: clk-pll-932m { - compatible = "fixed-clock"; - #clock-cells = <0>; - clock-frequency = <932000000>; - clock-output-names = "pll_ddr"; - }; - - pll_hsic: clk-pll-960m { - compatible = "fixed-clock"; - #clock-cells = <0>; - clock-frequency = <960000000>; - clock-output-names = "pll_hsic"; - }; - - pll_mac: clk-pll-1000m { - compatible = "fixed-clock"; - #clock-cells = <0>; - clock-frequency = <1000000000>; - clock-output-names = "pll_mac"; - }; - - pll_mm0: clk-pll-1188m { - compatible = "fixed-clock"; - #clock-cells = <0>; - clock-frequency = <1188000000>; - clock-output-names = "pll_mm0"; - }; - - pll_mm1: clk-pll-1296m { - compatible = "fixed-clock"; - #clock-cells = <0>; - clock-frequency = <1296000000>; - clock-output-names = "pll_mm1"; - }; - - psci { - compatible = "arm,psci-1.0"; - method = "smc"; - }; - - timer { - compatible = "arm,armv8-timer"; - interrupts = , - , - , - ; - }; - - pmu { - compatible = "arm,cortex-a53-pmu"; - interrupts = ; - }; - - gic: interrupt-controller@2a00000 { - compatible = "arm,gic-v3"; - #interrupt-cells = <3>; - #address-cells = <0>; - interrupt-controller; - reg = <0x02a00000 0x10000>, - <0x02b00000 0xc0000>; - interrupts = ; - }; - - soc { - #address-cells = <1>; - #size-cells = <1>; - compatible = "simple-bus"; - ranges; - - irdec: ir-decoder@111000 { - compatible = "zte,zx296718-irdec"; - reg = <0x111000 0x1000>; - interrupts = ; - status = "disabled"; - }; - - aon_sysctrl: aon-sysctrl@116000 { - compatible = "zte,zx296718-aon-sysctrl", "syscon"; - reg = <0x116000 0x1000>; - }; - - iocfg: pin-controller@119000 { - compatible = "zte,zx296718-iocfg"; - reg = <0x119000 0x1000>; - }; - - uart0: uart@11f000 { - compatible = "arm,pl011", "arm,primecell"; - arm,primecell-periphid = <0x001feffe>; - reg = <0x11f000 0x1000>; - interrupts = ; - clocks = <&osc24m>; - clock-names = "apb_pclk"; - status = "disabled"; - }; - - sd0: mmc@1110000 { - compatible = "zte,zx296718-dw-mshc"; - #address-cells = <1>; - #size-cells = <0>; - reg = <0x01110000 0x1000>; - interrupts = ; - fifo-depth = <32>; - data-addr = <0x200>; - fifo-watermark-aligned; - bus-width = <4>; - clock-frequency = <50000000>; - clocks = <&topcrm SD0_AHB>, <&topcrm SD0_WCLK>; - clock-names = "biu", "ciu"; - max-frequency = <50000000>; - cap-sdio-irq; - cap-sd-highspeed; - sd-uhs-sdr12; - sd-uhs-sdr25; - sd-uhs-sdr50; - sd-uhs-sdr104; - sd-uhs-ddr50; - status = "disabled"; - }; - - sd1: mmc@1111000 { - compatible = "zte,zx296718-dw-mshc"; - #address-cells = <1>; - #size-cells = <0>; - reg = <0x01111000 0x1000>; - interrupts = ; - fifo-depth = <32>; - data-addr = <0x200>; - fifo-watermark-aligned; - bus-width = <4>; - clock-frequency = <167000000>; - clocks = <&topcrm SD1_AHB>, <&topcrm SD1_WCLK>; - clock-names = "biu", "ciu"; - max-frequency = <167000000>; - cap-sdio-irq; - cap-sd-highspeed; - status = "disabled"; - }; - - dma: dma-controller@1460000 { - compatible = "zte,zx296702-dma"; - reg = <0x01460000 0x1000>; - interrupts = ; - clocks = <&osc24m>; - clock-names = "dmaclk"; - #dma-cells = <1>; - dma-channels = <32>; - dma-requests = <32>; - }; - - lsp0crm: clock-controller@1420000 { - compatible = "zte,zx296718-lsp0crm"; - reg = <0x01420000 0x1000>; - #clock-cells = <1>; - }; - - bgpio0: gpio@142d000 { - compatible = "zte,zx296718-gpio", "zte,zx296702-gpio"; - reg = <0x142d000 0x40>; - gpio-controller; - #gpio-cells = <2>; - gpio-ranges = <&pmm 0 48 16>; - interrupts = ; - interrupt-parent = <&gic>; - interrupt-controller; - #interrupt-cells = <2>; - }; - - bgpio1: gpio@142d040 { - compatible = "zte,zx296718-gpio", "zte,zx296702-gpio"; - reg = <0x142d040 0x40>; - gpio-controller; - #gpio-cells = <2>; - gpio-ranges = <&pmm 0 80 16>; - interrupts = ; - interrupt-parent = <&gic>; - interrupt-controller; - #interrupt-cells = <2>; - }; - - bgpio2: gpio@142d080 { - compatible = "zte,zx296718-gpio", "zte,zx296702-gpio"; - reg = <0x142d080 0x40>; - gpio-controller; - #gpio-cells = <2>; - gpio-ranges = <&pmm 0 80 3 - &pmm 3 32 4 - &pmm 7 83 9>; - interrupts = ; - interrupt-parent = <&gic>; - interrupt-controller; - #interrupt-cells = <2>; - }; - - bgpio3: gpio@142d0c0 { - compatible = "zte,zx296718-gpio", "zte,zx296702-gpio"; - reg = <0x142d0c0 0x40>; - gpio-controller; - #gpio-cells = <2>; - gpio-ranges = <&pmm 0 92 16>; - interrupts = ; - interrupt-parent = <&gic>; - interrupt-controller; - #interrupt-cells = <2>; - }; - - bgpio4: gpio@142d100 { - compatible = "zte,zx296718-gpio", "zte,zx296702-gpio"; - reg = <0x142d100 0x40>; - gpio-controller; - #gpio-cells = <2>; - gpio-ranges = <&pmm 0 108 12 - &pmm 12 121 4>; - interrupts = ; - interrupt-parent = <&gic>; - interrupt-controller; - #interrupt-cells = <2>; - }; - - bgpio5: gpio@142d140 { - compatible = "zte,zx296718-gpio", "zte,zx296702-gpio"; - reg = <0x142d140 0x40>; - gpio-controller; - #gpio-cells = <2>; - gpio-ranges = <&pmm 0 125 16>; - interrupts = ; - interrupt-parent = <&gic>; - interrupt-controller; - #interrupt-cells = <2>; - }; - - bgpio6: gpio@142d180 { - compatible = "zte,zx296718-gpio", "zte,zx296702-gpio"; - reg = <0x142d180 0x40>; - gpio-controller; - #gpio-cells = <2>; - gpio-ranges = <&pmm 0 141 2>; - interrupts = ; - interrupt-parent = <&gic>; - interrupt-controller; - #interrupt-cells = <2>; - }; - - lsp1crm: clock-controller@1430000 { - compatible = "zte,zx296718-lsp1crm"; - reg = <0x01430000 0x1000>; - #clock-cells = <1>; - }; - - pwm: pwm@1439000 { - compatible = "zte,zx296718-pwm"; - reg = <0x1439000 0x1000>; - clocks = <&lsp1crm LSP1_PWM_PCLK>, - <&lsp1crm LSP1_PWM_WCLK>; - clock-names = "pclk", "wclk"; - #pwm-cells = <3>; - status = "disabled"; - }; - - vou: vou@1440000 { - compatible = "zte,zx296718-vou"; - #address-cells = <1>; - #size-cells = <1>; - ranges = <0 0x1440000 0x10000>; - - dpc: dpc@0 { - compatible = "zte,zx296718-dpc"; - reg = <0x0000 0x1000>, <0x1000 0x1000>, - <0x5000 0x1000>, <0x6000 0x1000>, - <0xa000 0x1000>; - reg-names = "osd", "timing_ctrl", - "dtrc", "vou_ctrl", - "otfppu"; - interrupts = ; - clocks = <&topcrm VOU_ACLK>, <&topcrm VOU_PPU_WCLK>, - <&topcrm VOU_MAIN_WCLK>, <&topcrm VOU_AUX_WCLK>; - clock-names = "aclk", "ppu_wclk", - "main_wclk", "aux_wclk"; - }; - - vga: vga@8000 { - compatible = "zte,zx296718-vga"; - reg = <0x8000 0x1000>; - interrupts = ; - clocks = <&topcrm VGA_I2C_WCLK>; - clock-names = "i2c_wclk"; - zte,vga-power-control = <&sysctrl 0x170 0xe0>; - status = "disabled"; - }; - - hdmi: hdmi@c000 { - compatible = "zte,zx296718-hdmi"; - reg = <0xc000 0x4000>; - interrupts = ; - clocks = <&topcrm HDMI_OSC_CEC>, - <&topcrm HDMI_OSC_CLK>, - <&topcrm HDMI_XCLK>; - clock-names = "osc_cec", "osc_clk", "xclk"; - #sound-dai-cells = <0>; - status = "disabled"; - }; - - tvenc: tvenc@2000 { - compatible = "zte,zx296718-tvenc"; - reg = <0x2000 0x1000>; - zte,tvenc-power-control = <&sysctrl 0x170 0x10>; - status = "disabled"; - }; - }; - - topcrm: clock-controller@1461000 { - compatible = "zte,zx296718-topcrm"; - reg = <0x01461000 0x1000>; - #clock-cells = <1>; - }; - - pmm: pin-controller@1462000 { - compatible = "zte,zx296718-pmm"; - reg = <0x1462000 0x1000>; - zte,auxiliary-controller = <&iocfg>; - }; - - sysctrl: sysctrl@1463000 { - compatible = "zte,zx296718-sysctrl", "syscon"; - reg = <0x1463000 0x1000>; - }; - - emmc: mmc@1470000{ - compatible = "zte,zx296718-dw-mshc"; - reg = <0x01470000 0x1000>; - interrupts = ; - zte,aon-syscon = <&aon_sysctrl>; - bus-width = <8>; - fifo-depth = <128>; - data-addr = <0x200>; - fifo-watermark-aligned; - clock-frequency = <167000000>; - clocks = <&topcrm EMMC_NAND_AHB>, <&topcrm EMMC_WCLK>; - clock-names = "biu", "ciu"; - max-frequency = <167000000>; - cap-mmc-highspeed; - mmc-ddr-1_8v; - mmc-hs200-1_8v; - non-removable; - disable-wp; - status = "disabled"; - }; - - audiocrm: clock-controller@1480000 { - compatible = "zte,zx296718-audiocrm"; - reg = <0x01480000 0x1000>; - #clock-cells = <1>; - }; - - i2s0: i2s@1482000 { - compatible = "zte,zx296718-i2s", "zte,zx296702-i2s"; - reg = <0x01482000 0x1000>; - clocks = <&audiocrm AUDIO_I2S0_WCLK>, - <&audiocrm AUDIO_I2S0_PCLK>; - clock-names = "wclk", "pclk"; - assigned-clocks = <&audiocrm I2S0_WCLK_MUX>; - assigned-clock-parents = <&topcrm AUDIO_99M>; - interrupts = ; - dmas = <&dma 22>, <&dma 23>; - dma-names = "tx", "rx"; - #sound-dai-cells = <0>; - status = "disabled"; - }; - - i2c0: i2c@1486000 { - compatible = "zte,zx296718-i2c"; - reg = <0x01486000 0x1000>; - interrupts = ; - #address-cells = <1>; - #size-cells = <0>; - clocks = <&audiocrm AUDIO_I2C0_WCLK>; - clock-frequency = <1600000>; - status = "disabled"; - - aud96p22: codec@22 { - compatible = "zte,zx-aud96p22"; - #sound-dai-cells = <0>; - reg = <0x22>; - }; - }; - - spdif0: spdif@1488000 { - compatible = "zte,zx296702-spdif"; - reg = <0x1488000 0x1000>; - clocks = <&audiocrm AUDIO_SPDIF0_WCLK>; - clock-names = "tx"; - interrupts = ; - #sound-dai-cells = <0>; - dmas = <&dma 30>; - dma-names = "tx"; - status = "disabled"; - }; - }; -}; diff --git a/drivers/reset/Kconfig b/drivers/reset/Kconfig index 71ab75a46491..8dd99ca2192c 100644 --- a/drivers/reset/Kconfig +++ b/drivers/reset/Kconfig @@ -173,7 +173,7 @@ config RESET_SCMI config RESET_SIMPLE bool "Simple Reset Controller Driver" if COMPILE_TEST - default ARCH_AGILEX || ARCH_ASPEED || ARCH_BITMAIN || ARCH_REALTEK || ARCH_STM32 || ARCH_STRATIX10 || ARCH_SUNXI || ARCH_ZX || ARC + default ARCH_AGILEX || ARCH_ASPEED || ARCH_BITMAIN || ARCH_REALTEK || ARCH_STM32 || ARCH_STRATIX10 || ARCH_SUNXI || ARC help This enables a simple reset controller driver for reset lines that that can be asserted and deasserted by toggling bits in a contiguous, diff --git a/drivers/soc/Kconfig b/drivers/soc/Kconfig index d097d070f579..f357c6c659d2 100644 --- a/drivers/soc/Kconfig +++ b/drivers/soc/Kconfig @@ -22,7 +22,6 @@ source "drivers/soc/ti/Kconfig" source "drivers/soc/ux500/Kconfig" source "drivers/soc/versatile/Kconfig" source "drivers/soc/xilinx/Kconfig" -source "drivers/soc/zte/Kconfig" source "drivers/soc/kendryte/Kconfig" endmenu diff --git a/drivers/soc/Makefile b/drivers/soc/Makefile index 699b758d28e4..9bceb12b291d 100644 --- a/drivers/soc/Makefile +++ b/drivers/soc/Makefile @@ -28,5 +28,4 @@ obj-y += ti/ obj-$(CONFIG_ARCH_U8500) += ux500/ obj-$(CONFIG_PLAT_VERSATILE) += versatile/ obj-y += xilinx/ -obj-$(CONFIG_ARCH_ZX) += zte/ obj-$(CONFIG_SOC_KENDRYTE) += kendryte/ diff --git a/drivers/soc/zte/Kconfig b/drivers/soc/zte/Kconfig deleted file mode 100644 index 1cf1938da541..000000000000 --- a/drivers/soc/zte/Kconfig +++ /dev/null @@ -1,15 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0-only -# -# ZTE SoC drivers -# -menuconfig SOC_ZTE - depends on ARCH_ZX || COMPILE_TEST - bool "ZTE SoC driver support" - -if SOC_ZTE - -config ZX2967_PM_DOMAINS - bool "ZX2967 PM domains" - depends on PM_GENERIC_DOMAINS - -endif diff --git a/drivers/soc/zte/Makefile b/drivers/soc/zte/Makefile deleted file mode 100644 index 728c677addcd..000000000000 --- a/drivers/soc/zte/Makefile +++ /dev/null @@ -1,6 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0-only -# -# ZTE SOC drivers -# -obj-$(CONFIG_ZX2967_PM_DOMAINS) += zx2967_pm_domains.o -obj-$(CONFIG_ZX2967_PM_DOMAINS) += zx296718_pm_domains.o diff --git a/drivers/soc/zte/zx296718_pm_domains.c b/drivers/soc/zte/zx296718_pm_domains.c deleted file mode 100644 index 4daab06bbc26..000000000000 --- a/drivers/soc/zte/zx296718_pm_domains.c +++ /dev/null @@ -1,181 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Copyright (C) 2017 ZTE Ltd. - * - * Author: Baoyou Xie - */ - -#include -#include "zx2967_pm_domains.h" - -static u16 zx296718_offsets[REG_ARRAY_SIZE] = { - [REG_CLKEN] = 0x18, - [REG_ISOEN] = 0x1c, - [REG_RSTEN] = 0x20, - [REG_PWREN] = 0x24, - [REG_ACK_SYNC] = 0x28, -}; - -enum { - PCU_DM_VOU = 0, - PCU_DM_SAPPU, - PCU_DM_VDE, - PCU_DM_VCE, - PCU_DM_HDE, - PCU_DM_VIU, - PCU_DM_USB20, - PCU_DM_USB21, - PCU_DM_USB30, - PCU_DM_HSIC, - PCU_DM_GMAC, - PCU_DM_TS, -}; - -static struct zx2967_pm_domain vou_domain = { - .dm = { - .name = "vou_domain", - }, - .bit = PCU_DM_VOU, - .polarity = PWREN, - .reg_offset = zx296718_offsets, -}; - -static struct zx2967_pm_domain sappu_domain = { - .dm = { - .name = "sappu_domain", - }, - .bit = PCU_DM_SAPPU, - .polarity = PWREN, - .reg_offset = zx296718_offsets, -}; - -static struct zx2967_pm_domain vde_domain = { - .dm = { - .name = "vde_domain", - }, - .bit = PCU_DM_VDE, - .polarity = PWREN, - .reg_offset = zx296718_offsets, -}; - -static struct zx2967_pm_domain vce_domain = { - .dm = { - .name = "vce_domain", - }, - .bit = PCU_DM_VCE, - .polarity = PWREN, - .reg_offset = zx296718_offsets, -}; - -static struct zx2967_pm_domain hde_domain = { - .dm = { - .name = "hde_domain", - }, - .bit = PCU_DM_HDE, - .polarity = PWREN, - .reg_offset = zx296718_offsets, -}; - -static struct zx2967_pm_domain viu_domain = { - .dm = { - .name = "viu_domain", - }, - .bit = PCU_DM_VIU, - .polarity = PWREN, - .reg_offset = zx296718_offsets, -}; - -static struct zx2967_pm_domain usb20_domain = { - .dm = { - .name = "usb20_domain", - }, - .bit = PCU_DM_USB20, - .polarity = PWREN, - .reg_offset = zx296718_offsets, -}; - -static struct zx2967_pm_domain usb21_domain = { - .dm = { - .name = "usb21_domain", - }, - .bit = PCU_DM_USB21, - .polarity = PWREN, - .reg_offset = zx296718_offsets, -}; - -static struct zx2967_pm_domain usb30_domain = { - .dm = { - .name = "usb30_domain", - }, - .bit = PCU_DM_USB30, - .polarity = PWREN, - .reg_offset = zx296718_offsets, -}; - -static struct zx2967_pm_domain hsic_domain = { - .dm = { - .name = "hsic_domain", - }, - .bit = PCU_DM_HSIC, - .polarity = PWREN, - .reg_offset = zx296718_offsets, -}; - -static struct zx2967_pm_domain gmac_domain = { - .dm = { - .name = "gmac_domain", - }, - .bit = PCU_DM_GMAC, - .polarity = PWREN, - .reg_offset = zx296718_offsets, -}; - -static struct zx2967_pm_domain ts_domain = { - .dm = { - .name = "ts_domain", - }, - .bit = PCU_DM_TS, - .polarity = PWREN, - .reg_offset = zx296718_offsets, -}; - -static struct generic_pm_domain *zx296718_pm_domains[] = { - [DM_ZX296718_VOU] = &vou_domain.dm, - [DM_ZX296718_SAPPU] = &sappu_domain.dm, - [DM_ZX296718_VDE] = &vde_domain.dm, - [DM_ZX296718_VCE] = &vce_domain.dm, - [DM_ZX296718_HDE] = &hde_domain.dm, - [DM_ZX296718_VIU] = &viu_domain.dm, - [DM_ZX296718_USB20] = &usb20_domain.dm, - [DM_ZX296718_USB21] = &usb21_domain.dm, - [DM_ZX296718_USB30] = &usb30_domain.dm, - [DM_ZX296718_HSIC] = &hsic_domain.dm, - [DM_ZX296718_GMAC] = &gmac_domain.dm, - [DM_ZX296718_TS] = &ts_domain.dm, -}; - -static int zx296718_pd_probe(struct platform_device *pdev) -{ - return zx2967_pd_probe(pdev, - zx296718_pm_domains, - ARRAY_SIZE(zx296718_pm_domains)); -} - -static const struct of_device_id zx296718_pm_domain_matches[] = { - { .compatible = "zte,zx296718-pcu", }, - { }, -}; - -static struct platform_driver zx296718_pd_driver = { - .driver = { - .name = "zx296718-powerdomain", - .of_match_table = zx296718_pm_domain_matches, - }, - .probe = zx296718_pd_probe, -}; - -static int __init zx296718_pd_init(void) -{ - return platform_driver_register(&zx296718_pd_driver); -} -subsys_initcall(zx296718_pd_init); diff --git a/drivers/soc/zte/zx2967_pm_domains.c b/drivers/soc/zte/zx2967_pm_domains.c deleted file mode 100644 index a4503e31b616..000000000000 --- a/drivers/soc/zte/zx2967_pm_domains.c +++ /dev/null @@ -1,141 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Copyright (C) 2017 ZTE Ltd. - * - * Author: Baoyou Xie - */ - -#include -#include -#include -#include - -#include "zx2967_pm_domains.h" - -#define PCU_DM_CLKEN(zpd) ((zpd)->reg_offset[REG_CLKEN]) -#define PCU_DM_ISOEN(zpd) ((zpd)->reg_offset[REG_ISOEN]) -#define PCU_DM_RSTEN(zpd) ((zpd)->reg_offset[REG_RSTEN]) -#define PCU_DM_PWREN(zpd) ((zpd)->reg_offset[REG_PWREN]) -#define PCU_DM_ACK_SYNC(zpd) ((zpd)->reg_offset[REG_ACK_SYNC]) - -static void __iomem *pcubase; - -static int zx2967_power_on(struct generic_pm_domain *domain) -{ - struct zx2967_pm_domain *zpd = (struct zx2967_pm_domain *)domain; - unsigned long loop = 1000; - u32 val; - - val = readl_relaxed(pcubase + PCU_DM_PWREN(zpd)); - if (zpd->polarity == PWREN) - val |= BIT(zpd->bit); - else - val &= ~BIT(zpd->bit); - writel_relaxed(val, pcubase + PCU_DM_PWREN(zpd)); - - do { - udelay(1); - val = readl_relaxed(pcubase + PCU_DM_ACK_SYNC(zpd)) - & BIT(zpd->bit); - } while (--loop && !val); - - if (!loop) { - pr_err("Error: %s %s fail\n", __func__, domain->name); - return -EIO; - } - - val = readl_relaxed(pcubase + PCU_DM_RSTEN(zpd)); - val |= BIT(zpd->bit); - writel_relaxed(val, pcubase + PCU_DM_RSTEN(zpd)); - udelay(5); - - val = readl_relaxed(pcubase + PCU_DM_ISOEN(zpd)); - val &= ~BIT(zpd->bit); - writel_relaxed(val, pcubase + PCU_DM_ISOEN(zpd)); - udelay(5); - - val = readl_relaxed(pcubase + PCU_DM_CLKEN(zpd)); - val |= BIT(zpd->bit); - writel_relaxed(val, pcubase + PCU_DM_CLKEN(zpd)); - udelay(5); - - pr_debug("poweron %s\n", domain->name); - - return 0; -} - -static int zx2967_power_off(struct generic_pm_domain *domain) -{ - struct zx2967_pm_domain *zpd = (struct zx2967_pm_domain *)domain; - unsigned long loop = 1000; - u32 val; - - val = readl_relaxed(pcubase + PCU_DM_CLKEN(zpd)); - val &= ~BIT(zpd->bit); - writel_relaxed(val, pcubase + PCU_DM_CLKEN(zpd)); - udelay(5); - - val = readl_relaxed(pcubase + PCU_DM_ISOEN(zpd)); - val |= BIT(zpd->bit); - writel_relaxed(val, pcubase + PCU_DM_ISOEN(zpd)); - udelay(5); - - val = readl_relaxed(pcubase + PCU_DM_RSTEN(zpd)); - val &= ~BIT(zpd->bit); - writel_relaxed(val, pcubase + PCU_DM_RSTEN(zpd)); - udelay(5); - - val = readl_relaxed(pcubase + PCU_DM_PWREN(zpd)); - if (zpd->polarity == PWREN) - val &= ~BIT(zpd->bit); - else - val |= BIT(zpd->bit); - writel_relaxed(val, pcubase + PCU_DM_PWREN(zpd)); - - do { - udelay(1); - val = readl_relaxed(pcubase + PCU_DM_ACK_SYNC(zpd)) - & BIT(zpd->bit); - } while (--loop && val); - - if (!loop) { - pr_err("Error: %s %s fail\n", __func__, domain->name); - return -EIO; - } - - pr_debug("poweroff %s\n", domain->name); - - return 0; -} - -int zx2967_pd_probe(struct platform_device *pdev, - struct generic_pm_domain **zx_pm_domains, - int domain_num) -{ - struct genpd_onecell_data *genpd_data; - struct resource *res; - int i; - - genpd_data = devm_kzalloc(&pdev->dev, sizeof(*genpd_data), GFP_KERNEL); - if (!genpd_data) - return -ENOMEM; - - genpd_data->domains = zx_pm_domains; - genpd_data->num_domains = domain_num; - - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - pcubase = devm_ioremap_resource(&pdev->dev, res); - if (IS_ERR(pcubase)) - return PTR_ERR(pcubase); - - for (i = 0; i < domain_num; ++i) { - zx_pm_domains[i]->power_on = zx2967_power_on; - zx_pm_domains[i]->power_off = zx2967_power_off; - - pm_genpd_init(zx_pm_domains[i], NULL, false); - } - - of_genpd_add_provider_onecell(pdev->dev.of_node, genpd_data); - dev_info(&pdev->dev, "powerdomain init ok\n"); - return 0; -} diff --git a/drivers/soc/zte/zx2967_pm_domains.h b/drivers/soc/zte/zx2967_pm_domains.h deleted file mode 100644 index f586c02410ff..000000000000 --- a/drivers/soc/zte/zx2967_pm_domains.h +++ /dev/null @@ -1,44 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ -/* - * Header for ZTE's Power Domain Driver support - * - * Copyright (C) 2017 ZTE Ltd. - * - * Author: Baoyou Xie - */ - -#ifndef __ZTE_ZX2967_PM_DOMAIN_H -#define __ZTE_ZX2967_PM_DOMAIN_H - -#include -#include - -enum { - REG_CLKEN, - REG_ISOEN, - REG_RSTEN, - REG_PWREN, - REG_PWRDN, - REG_ACK_SYNC, - - /* The size of the array - must be last */ - REG_ARRAY_SIZE, -}; - -enum zx2967_power_polarity { - PWREN, - PWRDN, -}; - -struct zx2967_pm_domain { - struct generic_pm_domain dm; - const u16 bit; - const enum zx2967_power_polarity polarity; - const u16 *reg_offset; -}; - -int zx2967_pd_probe(struct platform_device *pdev, - struct generic_pm_domain **zx_pm_domains, - int domain_num); - -#endif /* __ZTE_ZX2967_PM_DOMAIN_H */ -- cgit v1.2.3 From ce1380c9f4bc48f6e6133ef9fc24dc9f3df500ac Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Mon, 18 Jan 2021 14:20:44 +0100 Subject: ARM: remove u300 platform The Ericsson U300 platform was one of two ARM929 based SoC platforms for mobile phones in ST-Ericsson after the merger of Ericsson with ST-NXP into ST-Ericsson, the other one being the ST Nomadik. The platform was not widely adopted in Linux based systems and was replaced with the far superior ST-Ericsson U8500 in 2011, but Linus Walleij kept maintaining the code for the whole time. Linus continues to use the Nomadik machine, but decided to drop u300 from the kernel as part of this year's spring cleaning. Thanks for having maintained it all these years. Cc: Linus Walleij Link: https://lore.kernel.org/lkml/CACRpkdbJkiHR9FSfJTH_5d_qRU1__dRXHM1TL40iqNRKbGQfrQ@mail.gmail.com/ Signed-off-by: Arnd Bergmann --- Documentation/devicetree/bindings/arm/ste-u300.txt | 46 -- MAINTAINERS | 14 +- arch/arm/Kconfig | 2 - arch/arm/Kconfig.debug | 10 - arch/arm/Makefile | 1 - arch/arm/boot/dts/Makefile | 2 - arch/arm/boot/dts/ste-u300.dts | 464 --------------------- arch/arm/configs/u300_defconfig | 65 --- arch/arm/mach-u300/Kconfig | 32 -- arch/arm/mach-u300/Makefile | 8 - arch/arm/mach-u300/core.c | 413 ------------------ arch/arm/mach-u300/regulator.c | 134 ------ drivers/mtd/nand/raw/Kconfig | 3 +- drivers/spi/Kconfig | 1 - 14 files changed, 2 insertions(+), 1193 deletions(-) delete mode 100644 Documentation/devicetree/bindings/arm/ste-u300.txt delete mode 100644 arch/arm/boot/dts/ste-u300.dts delete mode 100644 arch/arm/configs/u300_defconfig delete mode 100644 arch/arm/mach-u300/Kconfig delete mode 100644 arch/arm/mach-u300/Makefile delete mode 100644 arch/arm/mach-u300/core.c delete mode 100644 arch/arm/mach-u300/regulator.c (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/arm/ste-u300.txt b/Documentation/devicetree/bindings/arm/ste-u300.txt deleted file mode 100644 index d11d80006a19..000000000000 --- a/Documentation/devicetree/bindings/arm/ste-u300.txt +++ /dev/null @@ -1,46 +0,0 @@ -ST-Ericsson U300 Device Tree Bindings - -For various board the "board" node may contain specific properties -that pertain to this particular board, such as board-specific GPIOs -or board power regulator supplies. - -Required root node property: - -compatible="stericsson,u300"; - -Required node: syscon -This contains the system controller. -- compatible: must be "stericsson,u300-syscon". -- reg: the base address and size of the system controller. - -Boards with the U300 SoC include: - -S365 "Small Board U365": - -Required node: s365 -This contains the board-specific information. -- compatible: must be "stericsson,s365". -- vana15-supply: the regulator supplying the 1.5V to drive the - board. -- syscon: a pointer to the syscon node so we can access the - syscon registers to set the board as self-powered. - -Example: - -/ { - model = "ST-Ericsson U300"; - compatible = "stericsson,u300"; - #address-cells = <1>; - #size-cells = <1>; - - s365 { - compatible = "stericsson,s365"; - vana15-supply = <&ab3100_ldo_d_reg>; - syscon = <&syscon>; - }; - - syscon: syscon@c0011000 { - compatible = "stericsson,u300-syscon"; - reg = <0xc0011000 0x1000>; - }; -}; diff --git a/MAINTAINERS b/MAINTAINERS index bb2a153f76d7..908e03f0ed3a 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -2136,7 +2136,7 @@ ARM/NEC MOBILEPRO 900/c MACHINE SUPPORT M: Michael Petchkovsky S: Maintained -ARM/NOMADIK/U300/Ux500 ARCHITECTURES +ARM/NOMADIK/Ux500 ARCHITECTURES M: Linus Walleij L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) S: Maintained @@ -2145,35 +2145,23 @@ F: Documentation/devicetree/bindings/arm/ste-* F: Documentation/devicetree/bindings/arm/ux500.yaml F: Documentation/devicetree/bindings/arm/ux500/ F: Documentation/devicetree/bindings/i2c/i2c-nomadik.txt -F: Documentation/devicetree/bindings/i2c/i2c-stu300.txt F: arch/arm/boot/dts/ste-* F: arch/arm/mach-nomadik/ -F: arch/arm/mach-u300/ F: arch/arm/mach-ux500/ F: drivers/clk/clk-nomadik.c -F: drivers/clk/clk-u300.c F: drivers/clocksource/clksrc-dbx500-prcmu.c -F: drivers/clocksource/timer-u300.c -F: drivers/dma/coh901318* F: drivers/dma/ste_dma40* F: drivers/hwspinlock/u8500_hsem.c F: drivers/i2c/busses/i2c-nomadik.c -F: drivers/i2c/busses/i2c-stu300.c F: drivers/iio/adc/ab8500-gpadc.c -F: drivers/mfd/ab3100* F: drivers/mfd/ab8500* F: drivers/mfd/abx500* F: drivers/mfd/db8500* F: drivers/mfd/dbx500* F: drivers/pinctrl/nomadik/ -F: drivers/pinctrl/pinctrl-coh901* -F: drivers/pinctrl/pinctrl-u300.c -F: drivers/rtc/rtc-ab3100.c F: drivers/rtc/rtc-ab8500.c -F: drivers/rtc/rtc-coh901331.c F: drivers/rtc/rtc-pl031.c F: drivers/soc/ux500/ -F: drivers/watchdog/coh901327_wdt.c ARM/NUVOTON NPCM ARCHITECTURE M: Avi Fishman diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 70d6bfbcd164..6c423ee402ae 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -704,8 +704,6 @@ source "arch/arm/mach-sunxi/Kconfig" source "arch/arm/mach-tegra/Kconfig" -source "arch/arm/mach-u300/Kconfig" - source "arch/arm/mach-uniphier/Kconfig" source "arch/arm/mach-ux500/Kconfig" diff --git a/arch/arm/Kconfig.debug b/arch/arm/Kconfig.debug index 543e29068c08..c36c5d4c6e9c 100644 --- a/arch/arm/Kconfig.debug +++ b/arch/arm/Kconfig.debug @@ -1280,14 +1280,6 @@ choice Say Y here if you want kernel low-level debugging support on Tegra based platforms. - config DEBUG_U300_UART - bool "Kernel low-level debugging messages via U300 UART0" - depends on ARCH_U300 - select DEBUG_UART_PL01X - help - Say Y here if you want the debug print routines to direct - their output to the uart port on U300 devices. - config DEBUG_UX500_UART depends on ARCH_U8500 bool "Use Ux500 UART for low-level debug" @@ -1650,7 +1642,6 @@ config DEBUG_UART_PHYS default 0x808c0000 if DEBUG_EP93XX || ARCH_EP93XX default 0x90020000 if DEBUG_NSPIRE_CLASSIC_UART || DEBUG_NSPIRE_CX_UART default 0xb0090000 if DEBUG_VEXPRESS_UART0_CRX - default 0xc0013000 if DEBUG_U300_UART default 0xc8000000 if ARCH_IXP4XX && !CPU_BIG_ENDIAN default 0xc8000003 if ARCH_IXP4XX && CPU_BIG_ENDIAN default 0xd0000000 if DEBUG_SPEAR3XX @@ -1804,7 +1795,6 @@ config DEBUG_UART_VIRT default 0xfefb0000 if DEBUG_OMAP1UART1 || DEBUG_OMAP7XXUART1 default 0xfefb0800 if DEBUG_OMAP1UART2 || DEBUG_OMAP7XXUART2 default 0xfefb9800 if DEBUG_OMAP1UART3 || DEBUG_OMAP7XXUART3 - default 0xff003000 if DEBUG_U300_UART default 0xffd01000 if DEBUG_HIP01_UART default DEBUG_UART_PHYS if !MMU depends on DEBUG_LL_UART_8250 || DEBUG_LL_UART_PL01X || \ diff --git a/arch/arm/Makefile b/arch/arm/Makefile index 1291fdc869f2..5887de173fc9 100644 --- a/arch/arm/Makefile +++ b/arch/arm/Makefile @@ -214,7 +214,6 @@ machine-$(CONFIG_ARCH_STI) += sti machine-$(CONFIG_ARCH_STM32) += stm32 machine-$(CONFIG_ARCH_SUNXI) += sunxi machine-$(CONFIG_ARCH_TEGRA) += tegra -machine-$(CONFIG_ARCH_U300) += u300 machine-$(CONFIG_ARCH_U8500) += ux500 machine-$(CONFIG_ARCH_VERSATILE) += versatile machine-$(CONFIG_ARCH_VEXPRESS) += vexpress diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile index a13112f8730c..6d8abff55238 100644 --- a/arch/arm/boot/dts/Makefile +++ b/arch/arm/boot/dts/Makefile @@ -1255,8 +1255,6 @@ dtb-$(CONFIG_ARCH_TEGRA_124_SOC) += \ tegra124-nyan-big.dtb \ tegra124-nyan-blaze.dtb \ tegra124-venice2.dtb -dtb-$(CONFIG_ARCH_U300) += \ - ste-u300.dtb dtb-$(CONFIG_ARCH_U8500) += \ ste-snowball.dtb \ ste-hrefprev60-stuib.dtb \ diff --git a/arch/arm/boot/dts/ste-u300.dts b/arch/arm/boot/dts/ste-u300.dts deleted file mode 100644 index f4e7660fead7..000000000000 --- a/arch/arm/boot/dts/ste-u300.dts +++ /dev/null @@ -1,464 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* - * Device Tree for the ST-Ericsson U300 Machine and SoC - */ - -/dts-v1/; - -/ { - model = "ST-Ericsson U300"; - compatible = "stericsson,u300"; - #address-cells = <1>; - #size-cells = <1>; - - chosen { - bootargs = "root=/dev/ram0 console=ttyAMA0,115200n8 earlyprintk"; - }; - - aliases { - serial0 = &uart0; - serial1 = &uart1; - }; - - memory { - device_type = "memory"; - reg = <0x48000000 0x03c00000>; - }; - - s365 { - compatible = "stericsson,s365"; - vana15-supply = <&ab3100_ldo_d_reg>; - syscon = <&syscon>; - }; - - syscon: syscon@c0011000 { - compatible = "stericsson,u300-syscon", "syscon"; - reg = <0xc0011000 0x1000>; - clk32: app_32_clk@32k { - #clock-cells = <0>; - compatible = "fixed-clock"; - clock-frequency = <32768>; - }; - pll13: pll13@13M { - #clock-cells = <0>; - compatible = "fixed-clock"; - clock-frequency = <13000000>; - }; - /* Slow bridge clocks under PLL13 */ - slow_clk: slow_clk@13M { - #clock-cells = <0>; - compatible = "stericsson,u300-syscon-clk"; - clock-type = <0>; /* Slow */ - clock-id = <0>; - clocks = <&pll13>; - }; - uart0_clk: uart0_clk@13M { - #clock-cells = <0>; - compatible = "stericsson,u300-syscon-clk"; - clock-type = <0>; /* Slow */ - clock-id = <1>; - clocks = <&slow_clk>; - }; - gpio_clk: gpio_clk@13M { - #clock-cells = <0>; - compatible = "stericsson,u300-syscon-clk"; - clock-type = <0>; /* Slow */ - clock-id = <4>; - clocks = <&slow_clk>; - }; - rtc_clk: rtc_clk@13M { - #clock-cells = <0>; - compatible = "stericsson,u300-syscon-clk"; - clock-type = <0>; /* Slow */ - clock-id = <6>; - clocks = <&slow_clk>; - }; - apptimer_clk: app_tmr_clk@13M { - #clock-cells = <0>; - compatible = "stericsson,u300-syscon-clk"; - clock-type = <0>; /* Slow */ - clock-id = <7>; - clocks = <&slow_clk>; - }; - acc_tmr_clk@13M { - #clock-cells = <0>; - compatible = "stericsson,u300-syscon-clk"; - clock-type = <0>; /* Slow */ - clock-id = <8>; - clocks = <&slow_clk>; - }; - pll208: pll208@208M { - #clock-cells = <0>; - compatible = "fixed-clock"; - clock-frequency = <208000000>; - }; - app208: app_208_clk@208M { - #clock-cells = <0>; - compatible = "fixed-factor-clock"; - clock-div = <1>; - clock-mult = <1>; - clocks = <&pll208>; - }; - cpu_clk@208M { - #clock-cells = <0>; - compatible = "stericsson,u300-syscon-clk"; - clock-type = <2>; /* Rest */ - clock-id = <3>; - clocks = <&app208>; - }; - app104: app_104_clk@104M { - #clock-cells = <0>; - compatible = "fixed-factor-clock"; - clock-div = <2>; - clock-mult = <1>; - clocks = <&pll208>; - }; - semi_clk@104M { - #clock-cells = <0>; - compatible = "stericsson,u300-syscon-clk"; - clock-type = <2>; /* Rest */ - clock-id = <9>; - clocks = <&app104>; - }; - app52: app_52_clk@52M { - #clock-cells = <0>; - compatible = "fixed-factor-clock"; - clock-div = <4>; - clock-mult = <1>; - clocks = <&pll208>; - }; - /* AHB subsystem clocks */ - ahb_clk: ahb_subsys_clk@52M { - #clock-cells = <0>; - compatible = "stericsson,u300-syscon-clk"; - clock-type = <2>; /* Rest */ - clock-id = <10>; - clocks = <&app52>; - }; - intcon_clk@52M { - #clock-cells = <0>; - compatible = "stericsson,u300-syscon-clk"; - clock-type = <2>; /* Rest */ - clock-id = <12>; - clocks = <&ahb_clk>; - }; - emif_clk@52M { - #clock-cells = <0>; - compatible = "stericsson,u300-syscon-clk"; - clock-type = <2>; /* Rest */ - clock-id = <5>; - clocks = <&ahb_clk>; - }; - dmac_clk: dmac_clk@52M { - #clock-cells = <0>; - compatible = "stericsson,u300-syscon-clk"; - clock-type = <2>; /* Rest */ - clock-id = <4>; - clocks = <&app52>; - }; - fsmc_clk: fsmc_clk@52M { - #clock-cells = <0>; - compatible = "stericsson,u300-syscon-clk"; - clock-type = <2>; /* Rest */ - clock-id = <6>; - clocks = <&app52>; - }; - xgam_clk: xgam_clk@52M { - #clock-cells = <0>; - compatible = "stericsson,u300-syscon-clk"; - clock-type = <2>; /* Rest */ - clock-id = <8>; - clocks = <&app52>; - }; - app26: app_26_clk@26M { - #clock-cells = <0>; - compatible = "fixed-factor-clock"; - clock-div = <2>; - clock-mult = <1>; - clocks = <&app52>; - }; - /* Fast bridge clocks */ - fast_clk: fast_clk@26M { - #clock-cells = <0>; - compatible = "stericsson,u300-syscon-clk"; - clock-type = <1>; /* Fast */ - clock-id = <0>; - clocks = <&app26>; - }; - i2c0_clk: i2c0_clk@26M { - #clock-cells = <0>; - compatible = "stericsson,u300-syscon-clk"; - clock-type = <1>; /* Fast */ - clock-id = <1>; - clocks = <&fast_clk>; - }; - i2c1_clk: i2c1_clk@26M { - #clock-cells = <0>; - compatible = "stericsson,u300-syscon-clk"; - clock-type = <1>; /* Fast */ - clock-id = <2>; - clocks = <&fast_clk>; - }; - mmc_pclk: mmc_p_clk@26M { - #clock-cells = <0>; - compatible = "stericsson,u300-syscon-clk"; - clock-type = <1>; /* Fast */ - clock-id = <5>; - clocks = <&fast_clk>; - }; - mmc_mclk: mmc_mclk { - #clock-cells = <0>; - compatible = "stericsson,u300-syscon-mclk"; - clocks = <&mmc_pclk>; - }; - spi_clk: spi_p_clk@26M { - #clock-cells = <0>; - compatible = "stericsson,u300-syscon-clk"; - clock-type = <1>; /* Fast */ - clock-id = <6>; - clocks = <&fast_clk>; - }; - }; - - timer: timer@c0014000 { - compatible = "stericsson,u300-apptimer"; - reg = <0xc0014000 0x1000>; - interrupt-parent = <&vica>; - interrupts = <24 25 26 27>; - clocks = <&apptimer_clk>; - }; - - gpio: gpio@c0016000 { - compatible = "stericsson,gpio-coh901"; - reg = <0xc0016000 0x1000>; - interrupt-parent = <&vicb>; - interrupts = <0 1 2 18 21 22 23>; - clocks = <&gpio_clk>; - interrupt-names = "gpio0", "gpio1", "gpio2", "gpio3", - "gpio4", "gpio5", "gpio6"; - interrupt-controller; - #interrupt-cells = <2>; - gpio-controller; - #gpio-cells = <2>; - }; - - pinctrl: pinctrl@c0011000 { - compatible = "stericsson,pinctrl-u300"; - reg = <0xc0011000 0x1000>; - }; - - watchdog: watchdog@c0012000 { - compatible = "stericsson,coh901327"; - reg = <0xc0012000 0x1000>; - interrupt-parent = <&vicb>; - interrupts = <3>; - clocks = <&clk32>; - }; - - rtc: rtc@c0017000 { - compatible = "stericsson,coh901331"; - reg = <0xc0017000 0x1000>; - interrupt-parent = <&vicb>; - interrupts = <10>; - clocks = <&rtc_clk>; - }; - - dmac: dma-controller@c00020000 { - compatible = "stericsson,coh901318"; - reg = <0xc0020000 0x1000>; - interrupt-parent = <&vica>; - interrupts = <2>; - #dma-cells = <1>; - dma-channels = <40>; - clocks = <&dmac_clk>; - }; - - /* A NAND flash of 128 MiB */ - fsmc: flash@40000000 { - compatible = "stericsson,fsmc-nand"; - #address-cells = <1>; - #size-cells = <1>; - reg = <0x9f800000 0x1000>, /* FSMC Register*/ - <0x80000000 0x4000>, /* NAND Base DATA */ - <0x80020000 0x4000>, /* NAND Base ADDR */ - <0x80010000 0x4000>; /* NAND Base CMD */ - reg-names = "fsmc_regs", "nand_data", "nand_addr", "nand_cmd"; - nand-skip-bbtscan; - clocks = <&fsmc_clk>; - - partition@0 { - label = "boot records"; - reg = <0x0 0x20000>; - }; - partition@20000 { - label = "free"; - reg = <0x20000 0x7e0000>; - }; - partition@800000 { - label = "platform"; - reg = <0x800000 0xf800000>; - }; - }; - - i2c0: i2c@c0004000 { - compatible = "st,ddci2c"; - reg = <0xc0004000 0x1000>; - interrupt-parent = <&vicb>; - interrupts = <8>; - clocks = <&i2c0_clk>; - #address-cells = <1>; - #size-cells = <0>; - ab3100: ab3100@48 { - compatible = "stericsson,ab3100"; - reg = <0x48>; - interrupt-parent = <&vica>; - interrupts = <0>; /* EXT0 IRQ */ - ab3100-regulators { - compatible = "stericsson,ab3100-regulators"; - ab3100_ldo_a_reg: ab3100_ldo_a { - startup-delay-us = <200>; - regulator-always-on; - regulator-boot-on; - }; - ab3100_ldo_c_reg: ab3100_ldo_c { - startup-delay-us = <200>; - }; - ab3100_ldo_d_reg: ab3100_ldo_d { - startup-delay-us = <200>; - }; - ab3100_ldo_e_reg: ab3100_ldo_e { - regulator-min-microvolt = <1800000>; - regulator-max-microvolt = <1800000>; - startup-delay-us = <200>; - regulator-always-on; - regulator-boot-on; - }; - ab3100_ldo_f_reg: ab3100_ldo_f { - regulator-min-microvolt = <2500000>; - regulator-max-microvolt = <2500000>; - startup-delay-us = <600>; - regulator-always-on; - regulator-boot-on; - }; - ab3100_ldo_g_reg: ab3100_ldo_g { - regulator-min-microvolt = <1500000>; - regulator-max-microvolt = <2850000>; - startup-delay-us = <400>; - }; - ab3100_ldo_h_reg: ab3100_ldo_h { - regulator-min-microvolt = <1200000>; - regulator-max-microvolt = <2750000>; - startup-delay-us = <200>; - }; - ab3100_ldo_k_reg: ab3100_ldo_k { - regulator-min-microvolt = <1800000>; - regulator-max-microvolt = <2750000>; - startup-delay-us = <200>; - }; - ab3100_ext_reg: ab3100_ext { - }; - ab3100_buck_reg: ab3100_buck { - regulator-min-microvolt = <1200000>; - regulator-max-microvolt = <1800000>; - startup-delay-us = <1000>; - regulator-always-on; - regulator-boot-on; - }; - }; - }; - }; - - i2c1: i2c@c0005000 { - compatible = "st,ddci2c"; - reg = <0xc0005000 0x1000>; - interrupt-parent = <&vicb>; - interrupts = <9>; - clocks = <&i2c1_clk>; - #address-cells = <1>; - #size-cells = <0>; - fwcam0: fwcam@10 { - reg = <0x10>; - }; - fwcam1: fwcam@5d { - reg = <0x5d>; - }; - }; - - amba { - compatible = "simple-bus"; - #address-cells = <1>; - #size-cells = <1>; - ranges; - - vica: interrupt-controller@a0001000 { - compatible = "arm,versatile-vic"; - interrupt-controller; - #interrupt-cells = <1>; - reg = <0xa0001000 0x20>; - }; - - vicb: interrupt-controller@a0002000 { - compatible = "arm,versatile-vic"; - interrupt-controller; - #interrupt-cells = <1>; - reg = <0xa0002000 0x20>; - }; - - uart0: serial@c0013000 { - compatible = "arm,pl011", "arm,primecell"; - reg = <0xc0013000 0x1000>; - interrupt-parent = <&vica>; - interrupts = <22>; - clocks = <&uart0_clk>, <&uart0_clk>; - clock-names = "apb_pclk", "uart0_clk"; - dmas = <&dmac 17 &dmac 18>; - dma-names = "tx", "rx"; - }; - - uart1: serial@c0007000 { - compatible = "arm,pl011", "arm,primecell"; - reg = <0xc0007000 0x1000>; - interrupt-parent = <&vicb>; - interrupts = <20>; - dmas = <&dmac 38 &dmac 39>; - dma-names = "tx", "rx"; - }; - - mmcsd: mmcsd@c0001000 { - compatible = "arm,pl18x", "arm,primecell"; - reg = <0xc0001000 0x1000>; - interrupt-parent = <&vicb>; - interrupts = <6 7>; - clocks = <&mmc_pclk>, <&mmc_mclk>; - clock-names = "apb_pclk", "mclk"; - max-frequency = <24000000>; - bus-width = <4>; // SD-card slot - cap-mmc-highspeed; - cap-sd-highspeed; - cd-gpios = <&gpio 12 0x4>; - cd-inverted; - vmmc-supply = <&ab3100_ldo_g_reg>; - dmas = <&dmac 14>; - dma-names = "rx"; - }; - - spi: spi@c0006000 { - compatible = "arm,pl022", "arm,primecell"; - reg = <0xc0006000 0x1000>; - interrupt-parent = <&vica>; - interrupts = <23>; - clocks = <&spi_clk>, <&spi_clk>; - clock-names = "SSPCLK", "apb_pclk"; - dmas = <&dmac 27 &dmac 28>; - dma-names = "tx", "rx"; - num-cs = <3>; - #address-cells = <1>; - #size-cells = <0>; - spi-dummy@1 { - compatible = "arm,pl022-dummy"; - reg = <1>; - spi-max-frequency = <20000000>; - }; - }; - }; -}; diff --git a/arch/arm/configs/u300_defconfig b/arch/arm/configs/u300_defconfig deleted file mode 100644 index 543f07338100..000000000000 --- a/arch/arm/configs/u300_defconfig +++ /dev/null @@ -1,65 +0,0 @@ -# CONFIG_LOCALVERSION_AUTO is not set -# CONFIG_SWAP is not set -CONFIG_SYSVIPC=y -CONFIG_NO_HZ=y -CONFIG_HIGH_RES_TIMERS=y -CONFIG_LOG_BUF_SHIFT=14 -CONFIG_EXPERT=y -# CONFIG_AIO is not set -# CONFIG_VM_EVENT_COUNTERS is not set -CONFIG_MODULES=y -CONFIG_MODULE_UNLOAD=y -# CONFIG_BLK_DEV_BSG is not set -CONFIG_PARTITION_ADVANCED=y -# CONFIG_ARCH_MULTI_V7 is not set -CONFIG_ARCH_U300=y -CONFIG_MACH_U300_SPIDUMMY=y -CONFIG_PREEMPT=y -CONFIG_AEABI=y -CONFIG_ZBOOT_ROM_TEXT=0x0 -CONFIG_ZBOOT_ROM_BSS=0x0 -CONFIG_CMDLINE="root=/dev/ram0 rw rootfstype=rootfs console=ttyAMA0,115200n8 lpj=515072" -CONFIG_CPU_IDLE=y -# CONFIG_SUSPEND is not set -# CONFIG_PREVENT_FIRMWARE_BUILD is not set -CONFIG_MTD=y -CONFIG_MTD_CMDLINE_PARTS=y -CONFIG_MTD_RAW_NAND=y -CONFIG_MTD_NAND_FSMC=y -# CONFIG_INPUT_MOUSEDEV is not set -CONFIG_INPUT_EVDEV=y -# CONFIG_KEYBOARD_ATKBD is not set -# CONFIG_INPUT_MOUSE is not set -# CONFIG_SERIO is not set -CONFIG_LEGACY_PTY_COUNT=16 -CONFIG_SERIAL_AMBA_PL011=y -CONFIG_SERIAL_AMBA_PL011_CONSOLE=y -# CONFIG_HW_RANDOM is not set -CONFIG_I2C=y -# CONFIG_HWMON is not set -CONFIG_WATCHDOG=y -CONFIG_REGULATOR=y -CONFIG_REGULATOR_FIXED_VOLTAGE=y -CONFIG_FB=y -# CONFIG_LCD_CLASS_DEVICE is not set -CONFIG_BACKLIGHT_CLASS_DEVICE=y -# CONFIG_USB_SUPPORT is not set -CONFIG_MMC=y -CONFIG_MMC_ARMMMCI=y -CONFIG_RTC_CLASS=y -# CONFIG_RTC_HCTOSYS is not set -CONFIG_RTC_DRV_COH901331=y -CONFIG_DMADEVICES=y -CONFIG_COH901318=y -# CONFIG_DNOTIFY is not set -CONFIG_FUSE_FS=y -CONFIG_VFAT_FS=y -CONFIG_TMPFS=y -CONFIG_NLS_CODEPAGE_437=y -CONFIG_NLS_ISO8859_1=y -CONFIG_PRINTK_TIME=y -CONFIG_DEBUG_INFO=y -CONFIG_DEBUG_FS=y -# CONFIG_SCHED_DEBUG is not set -CONFIG_TIMER_STATS=y -# CONFIG_DEBUG_PREEMPT is not set diff --git a/arch/arm/mach-u300/Kconfig b/arch/arm/mach-u300/Kconfig deleted file mode 100644 index c3c8bf54f033..000000000000 --- a/arch/arm/mach-u300/Kconfig +++ /dev/null @@ -1,32 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0 -menuconfig ARCH_U300 - bool "ST-Ericsson U300 Series" - depends on ARCH_MULTI_V5 && MMU - select ARM_AMBA - select ARM_VIC - select U300_TIMER - select CPU_ARM926T - select GPIOLIB - select HAVE_TCM - select PINCTRL - select PINCTRL_COH901 - select PINCTRL_U300 - select MFD_SYSCON - help - Support for ST-Ericsson U300 series mobile platforms. - -if ARCH_U300 - -config MACH_U300 - depends on ARCH_U300 - bool "U300" - default y - -config U300_DEBUG - depends on ARCH_U300 - bool "Debug support for U300" - depends on PM - help - Debug support for U300 in sysfs, procfs etc. - -endif diff --git a/arch/arm/mach-u300/Makefile b/arch/arm/mach-u300/Makefile deleted file mode 100644 index 67f71ae45dfc..000000000000 --- a/arch/arm/mach-u300/Makefile +++ /dev/null @@ -1,8 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0-only -# -# Makefile for the linux kernel, U300 machine. -# - -obj-y := core.o - -obj-$(CONFIG_REGULATOR_AB3100) += regulator.o diff --git a/arch/arm/mach-u300/core.c b/arch/arm/mach-u300/core.c deleted file mode 100644 index a1694d977ec9..000000000000 --- a/arch/arm/mach-u300/core.c +++ /dev/null @@ -1,413 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * - * arch/arm/mach-u300/core.c - * - * Copyright (C) 2007-2012 ST-Ericsson SA - * Core platform support, IRQ handling and device definitions. - * Author: Linus Walleij - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -/* - * These are the large blocks of memory allocated for I/O. - * the defines are used for setting up the I/O memory mapping. - */ - -/* NAND Flash CS0 */ -#define U300_NAND_CS0_PHYS_BASE 0x80000000 -/* NFIF */ -#define U300_NAND_IF_PHYS_BASE 0x9f800000 -/* ALE, CLE offset for FSMC NAND */ -#define PLAT_NAND_CLE (1 << 16) -#define PLAT_NAND_ALE (1 << 17) -/* AHB Peripherals */ -#define U300_AHB_PER_PHYS_BASE 0xa0000000 -#define U300_AHB_PER_VIRT_BASE 0xff010000 -/* FAST Peripherals */ -#define U300_FAST_PER_PHYS_BASE 0xc0000000 -#define U300_FAST_PER_VIRT_BASE 0xff020000 -/* SLOW Peripherals */ -#define U300_SLOW_PER_PHYS_BASE 0xc0010000 -#define U300_SLOW_PER_VIRT_BASE 0xff000000 -/* Boot ROM */ -#define U300_BOOTROM_PHYS_BASE 0xffff0000 -#define U300_BOOTROM_VIRT_BASE 0xffff0000 -/* SEMI config base */ -#define U300_SEMI_CONFIG_BASE 0x2FFE0000 - -/* - * AHB peripherals - */ - -/* AHB Peripherals Bridge Controller */ -#define U300_AHB_BRIDGE_BASE (U300_AHB_PER_PHYS_BASE+0x0000) -/* Vectored Interrupt Controller 0, servicing 32 interrupts */ -#define U300_INTCON0_BASE (U300_AHB_PER_PHYS_BASE+0x1000) -#define U300_INTCON0_VBASE IOMEM(U300_AHB_PER_VIRT_BASE+0x1000) -/* Vectored Interrupt Controller 1, servicing 32 interrupts */ -#define U300_INTCON1_BASE (U300_AHB_PER_PHYS_BASE+0x2000) -#define U300_INTCON1_VBASE IOMEM(U300_AHB_PER_VIRT_BASE+0x2000) -/* Memory Stick Pro (MSPRO) controller */ -#define U300_MSPRO_BASE (U300_AHB_PER_PHYS_BASE+0x3000) -/* EMIF Configuration Area */ -#define U300_EMIF_CFG_BASE (U300_AHB_PER_PHYS_BASE+0x4000) - -/* - * FAST peripherals - */ - -/* FAST bridge control */ -#define U300_FAST_BRIDGE_BASE (U300_FAST_PER_PHYS_BASE+0x0000) -/* MMC/SD controller */ -#define U300_MMCSD_BASE (U300_FAST_PER_PHYS_BASE+0x1000) -/* PCM I2S0 controller */ -#define U300_PCM_I2S0_BASE (U300_FAST_PER_PHYS_BASE+0x2000) -/* PCM I2S1 controller */ -#define U300_PCM_I2S1_BASE (U300_FAST_PER_PHYS_BASE+0x3000) -/* I2C0 controller */ -#define U300_I2C0_BASE (U300_FAST_PER_PHYS_BASE+0x4000) -/* I2C1 controller */ -#define U300_I2C1_BASE (U300_FAST_PER_PHYS_BASE+0x5000) -/* SPI controller */ -#define U300_SPI_BASE (U300_FAST_PER_PHYS_BASE+0x6000) -/* Fast UART1 on U335 only */ -#define U300_UART1_BASE (U300_FAST_PER_PHYS_BASE+0x7000) - -/* - * SLOW peripherals - */ - -/* SLOW bridge control */ -#define U300_SLOW_BRIDGE_BASE (U300_SLOW_PER_PHYS_BASE) -/* SYSCON */ -#define U300_SYSCON_BASE (U300_SLOW_PER_PHYS_BASE+0x1000) -#define U300_SYSCON_VBASE IOMEM(U300_SLOW_PER_VIRT_BASE+0x1000) -/* Watchdog */ -#define U300_WDOG_BASE (U300_SLOW_PER_PHYS_BASE+0x2000) -/* UART0 */ -#define U300_UART0_BASE (U300_SLOW_PER_PHYS_BASE+0x3000) -/* APP side special timer */ -#define U300_TIMER_APP_BASE (U300_SLOW_PER_PHYS_BASE+0x4000) -#define U300_TIMER_APP_VBASE IOMEM(U300_SLOW_PER_VIRT_BASE+0x4000) -/* Keypad */ -#define U300_KEYPAD_BASE (U300_SLOW_PER_PHYS_BASE+0x5000) -/* GPIO */ -#define U300_GPIO_BASE (U300_SLOW_PER_PHYS_BASE+0x6000) -/* RTC */ -#define U300_RTC_BASE (U300_SLOW_PER_PHYS_BASE+0x7000) -/* Bus tracer */ -#define U300_BUSTR_BASE (U300_SLOW_PER_PHYS_BASE+0x8000) -/* Event handler (hardware queue) */ -#define U300_EVHIST_BASE (U300_SLOW_PER_PHYS_BASE+0x9000) -/* Genric Timer */ -#define U300_TIMER_BASE (U300_SLOW_PER_PHYS_BASE+0xa000) -/* PPM */ -#define U300_PPM_BASE (U300_SLOW_PER_PHYS_BASE+0xb000) - -/* - * REST peripherals - */ - -/* ISP (image signal processor) */ -#define U300_ISP_BASE (0xA0008000) -/* DMA Controller base */ -#define U300_DMAC_BASE (0xC0020000) -/* MSL Base */ -#define U300_MSL_BASE (0xc0022000) -/* APEX Base */ -#define U300_APEX_BASE (0xc0030000) -/* Video Encoder Base */ -#define U300_VIDEOENC_BASE (0xc0080000) -/* XGAM Base */ -#define U300_XGAM_BASE (0xd0000000) - -/* - * SYSCON addresses applicable to the core machine. - */ - -/* Chip ID register 16bit (R/-) */ -#define U300_SYSCON_CIDR (0x400) -/* SMCR */ -#define U300_SYSCON_SMCR (0x4d0) -#define U300_SYSCON_SMCR_FIELD_MASK (0x000e) -#define U300_SYSCON_SMCR_SEMI_SREFACK_IND (0x0008) -#define U300_SYSCON_SMCR_SEMI_SREFREQ_ENABLE (0x0004) -#define U300_SYSCON_SMCR_SEMI_EXT_BOOT_MODE_ENABLE (0x0002) -/* CPU_SW_DBGEN Software Debug Enable 16bit (R/W) */ -#define U300_SYSCON_CSDR (0x4f0) -#define U300_SYSCON_CSDR_SW_DEBUG_ENABLE (0x0001) -/* PRINT_CONTROL Print Control 16bit (R/-) */ -#define U300_SYSCON_PCR (0x4f8) -#define U300_SYSCON_PCR_SERV_IND (0x0001) -/* BOOT_CONTROL 16bit (R/-) */ -#define U300_SYSCON_BCR (0x4fc) -#define U300_SYSCON_BCR_ACC_CPU_SUBSYS_VINITHI_IND (0x0400) -#define U300_SYSCON_BCR_APP_CPU_SUBSYS_VINITHI_IND (0x0200) -#define U300_SYSCON_BCR_EXTRA_BOOT_OPTION_MASK (0x01FC) -#define U300_SYSCON_BCR_APP_BOOT_SERV_MASK (0x0003) - -static void __iomem *syscon_base; - -/* - * Static I/O mappings that are needed for booting the U300 platforms. The - * only things we need are the areas where we find the timer, syscon and - * intcon, since the remaining device drivers will map their own memory - * physical to virtual as the need arise. - */ -static struct map_desc u300_io_desc[] __initdata = { - { - .virtual = U300_SLOW_PER_VIRT_BASE, - .pfn = __phys_to_pfn(U300_SLOW_PER_PHYS_BASE), - .length = SZ_64K, - .type = MT_DEVICE, - }, - { - .virtual = U300_AHB_PER_VIRT_BASE, - .pfn = __phys_to_pfn(U300_AHB_PER_PHYS_BASE), - .length = SZ_32K, - .type = MT_DEVICE, - }, - { - .virtual = U300_FAST_PER_VIRT_BASE, - .pfn = __phys_to_pfn(U300_FAST_PER_PHYS_BASE), - .length = SZ_32K, - .type = MT_DEVICE, - }, -}; - -static void __init u300_map_io(void) -{ - iotable_init(u300_io_desc, ARRAY_SIZE(u300_io_desc)); -} - -static unsigned long pin_pullup_conf[] = { - PIN_CONF_PACKED(PIN_CONFIG_BIAS_PULL_UP, 1), -}; - -static unsigned long pin_highz_conf[] = { - PIN_CONF_PACKED(PIN_CONFIG_BIAS_HIGH_IMPEDANCE, 0), -}; - -/* Pin control settings */ -static const struct pinctrl_map u300_pinmux_map[] = { - /* anonymous maps for chip power and EMIFs */ - PIN_MAP_MUX_GROUP_HOG_DEFAULT("pinctrl-u300", NULL, "power"), - PIN_MAP_MUX_GROUP_HOG_DEFAULT("pinctrl-u300", NULL, "emif0"), - PIN_MAP_MUX_GROUP_HOG_DEFAULT("pinctrl-u300", NULL, "emif1"), - /* per-device maps for MMC/SD, SPI and UART */ - PIN_MAP_MUX_GROUP_DEFAULT("mmci", "pinctrl-u300", NULL, "mmc0"), - PIN_MAP_MUX_GROUP_DEFAULT("pl022", "pinctrl-u300", NULL, "spi0"), - PIN_MAP_MUX_GROUP_DEFAULT("uart0", "pinctrl-u300", NULL, "uart0"), - /* This pin is used for clock return rather than GPIO */ - PIN_MAP_CONFIGS_PIN_DEFAULT("mmci", "pinctrl-u300", "PIO APP GPIO 11", - pin_pullup_conf), - /* This pin is used for card detect */ - PIN_MAP_CONFIGS_PIN_DEFAULT("mmci", "pinctrl-u300", "PIO MS INS", - pin_highz_conf), -}; - -struct db_chip { - u16 chipid; - const char *name; -}; - -/* - * This is a list of the Digital Baseband chips used in the U300 platform. - */ -static struct db_chip db_chips[] __initdata = { - { - .chipid = 0xb800, - .name = "DB3000", - }, - { - .chipid = 0xc000, - .name = "DB3100", - }, - { - .chipid = 0xc800, - .name = "DB3150", - }, - { - .chipid = 0xd800, - .name = "DB3200", - }, - { - .chipid = 0xe000, - .name = "DB3250", - }, - { - .chipid = 0xe800, - .name = "DB3210", - }, - { - .chipid = 0xf000, - .name = "DB3350 P1x", - }, - { - .chipid = 0xf100, - .name = "DB3350 P2x", - }, - { - .chipid = 0x0000, /* List terminator */ - .name = NULL, - } -}; - -static void __init u300_init_check_chip(void) -{ - - u16 val; - struct db_chip *chip; - const char *chipname; - const char unknown[] = "UNKNOWN"; - - /* Read out and print chip ID */ - val = readw(syscon_base + U300_SYSCON_CIDR); - /* This is in funky bigendian order... */ - val = (val & 0xFFU) << 8 | (val >> 8); - chip = db_chips; - chipname = unknown; - - for ( ; chip->chipid; chip++) { - if (chip->chipid == (val & 0xFF00U)) { - chipname = chip->name; - break; - } - } - printk(KERN_INFO "Initializing U300 system on %s baseband chip " \ - "(chip ID 0x%04x)\n", chipname, val); - - if ((val & 0xFF00U) != 0xf000 && (val & 0xFF00U) != 0xf100) { - printk(KERN_ERR "Platform configured for BS335 " \ - " with DB3350 but %s detected, expect problems!", - chipname); - } -} - -/* Forward declare this function from the watchdog */ -void coh901327_watchdog_reset(void); - -static void u300_restart(enum reboot_mode mode, const char *cmd) -{ - switch (mode) { - case REBOOT_SOFT: - case REBOOT_HARD: -#ifdef CONFIG_COH901327_WATCHDOG - coh901327_watchdog_reset(); -#endif - break; - default: - /* Do nothing */ - break; - } - /* Wait for system do die/reset. */ - while (1); -} - -/* These are mostly to get the right device names for the clock lookups */ -static struct of_dev_auxdata u300_auxdata_lookup[] __initdata = { - OF_DEV_AUXDATA("stericsson,pinctrl-u300", U300_SYSCON_BASE, - "pinctrl-u300", NULL), - OF_DEV_AUXDATA("stericsson,gpio-coh901", U300_GPIO_BASE, - "u300-gpio", NULL), - OF_DEV_AUXDATA("stericsson,coh901327", U300_WDOG_BASE, - "coh901327_wdog", NULL), - OF_DEV_AUXDATA("stericsson,coh901331", U300_RTC_BASE, - "rtc-coh901331", NULL), - OF_DEV_AUXDATA("stericsson,coh901318", U300_DMAC_BASE, - "coh901318", NULL), - OF_DEV_AUXDATA("stericsson,fsmc-nand", U300_NAND_IF_PHYS_BASE, - "fsmc-nand", NULL), - OF_DEV_AUXDATA("arm,primecell", U300_UART0_BASE, - "uart0", NULL), - OF_DEV_AUXDATA("arm,primecell", U300_UART1_BASE, - "uart1", NULL), - OF_DEV_AUXDATA("arm,primecell", U300_SPI_BASE, - "pl022", NULL), - OF_DEV_AUXDATA("st,ddci2c", U300_I2C0_BASE, - "stu300.0", NULL), - OF_DEV_AUXDATA("st,ddci2c", U300_I2C1_BASE, - "stu300.1", NULL), - OF_DEV_AUXDATA("arm,primecell", U300_MMCSD_BASE, - "mmci", NULL), - { /* sentinel */ }, -}; - -static void __init u300_init_irq_dt(void) -{ - struct device_node *syscon; - struct clk *clk; - - syscon = of_find_node_by_path("/syscon@c0011000"); - if (!syscon) { - pr_crit("could not find syscon node\n"); - return; - } - syscon_base = of_iomap(syscon, 0); - if (!syscon_base) { - pr_crit("could not remap syscon\n"); - return; - } - /* initialize clocking early, we want to clock the INTCON */ - u300_clk_init(syscon_base); - - /* Bootstrap EMIF and SEMI clocks */ - clk = clk_get_sys("pl172", NULL); - BUG_ON(IS_ERR(clk)); - clk_prepare_enable(clk); - clk = clk_get_sys("semi", NULL); - BUG_ON(IS_ERR(clk)); - clk_prepare_enable(clk); - - /* Clock the interrupt controller */ - clk = clk_get_sys("intcon", NULL); - BUG_ON(IS_ERR(clk)); - clk_prepare_enable(clk); - - irqchip_init(); -} - -static void __init u300_init_machine_dt(void) -{ - u16 val; - - /* Check what platform we run and print some status information */ - u300_init_check_chip(); - - /* Initialize pinmuxing */ - pinctrl_register_mappings(u300_pinmux_map, - ARRAY_SIZE(u300_pinmux_map)); - - of_platform_default_populate(NULL, u300_auxdata_lookup, NULL); - - /* Enable SEMI self refresh */ - val = readw(syscon_base + U300_SYSCON_SMCR) | - U300_SYSCON_SMCR_SEMI_SREFREQ_ENABLE; - writew(val, syscon_base + U300_SYSCON_SMCR); -} - -static const char * u300_board_compat[] = { - "stericsson,u300", - NULL, -}; - -DT_MACHINE_START(U300_DT, "U300 S335/B335 (Device Tree)") - .map_io = u300_map_io, - .init_irq = u300_init_irq_dt, - .init_time = timer_probe, - .init_machine = u300_init_machine_dt, - .restart = u300_restart, - .dt_compat = u300_board_compat, -MACHINE_END diff --git a/arch/arm/mach-u300/regulator.c b/arch/arm/mach-u300/regulator.c deleted file mode 100644 index c0cc1d82e1b9..000000000000 --- a/arch/arm/mach-u300/regulator.c +++ /dev/null @@ -1,134 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * arch/arm/mach-u300/regulator.c - * - * Copyright (C) 2009 ST-Ericsson AB - * Handle board-bound regulators and board power not related - * to any devices. - * Author: Linus Walleij - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* Power Management Control 16bit (R/W) */ -#define U300_SYSCON_PMCR (0x50) -#define U300_SYSCON_PMCR_DCON_ENABLE (0x0002) -#define U300_SYSCON_PMCR_PWR_MGNT_ENABLE (0x0001) - -/* - * Regulators that power the board and chip and which are - * not copuled to specific drivers are hogged in these - * instances. - */ -static struct regulator *main_power_15; - -/* - * This function is used from pm.h to shut down the system by - * resetting all regulators in turn and then disable regulator - * LDO D (main power). - */ -void u300_pm_poweroff(void) -{ - sigset_t old, all; - - sigfillset(&all); - if (!sigprocmask(SIG_BLOCK, &all, &old)) { - /* Disable LDO D to shut down the system */ - if (main_power_15) - regulator_disable(main_power_15); - else - pr_err("regulator not available to shut down system\n"); - (void) sigprocmask(SIG_SETMASK, &old, NULL); - } - return; -} - -/* - * Hog the regulators needed to power up the board. - */ -static int __init __u300_init_boardpower(struct platform_device *pdev) -{ - struct device_node *np = pdev->dev.of_node; - struct device_node *syscon_np; - struct regmap *regmap; - int err; - - pr_info("U300: setting up board power\n"); - - syscon_np = of_parse_phandle(np, "syscon", 0); - if (!syscon_np) { - pr_crit("U300: no syscon node\n"); - return -ENODEV; - } - regmap = syscon_node_to_regmap(syscon_np); - if (IS_ERR(regmap)) { - pr_crit("U300: could not locate syscon regmap\n"); - return PTR_ERR(regmap); - } - - main_power_15 = regulator_get(&pdev->dev, "vana15"); - - if (IS_ERR(main_power_15)) { - pr_err("could not get vana15"); - return PTR_ERR(main_power_15); - } - err = regulator_enable(main_power_15); - if (err) { - pr_err("could not enable vana15\n"); - return err; - } - - /* - * On U300 a special system controller register pulls up the DC - * until the vana15 (LDO D) regulator comes up. At this point, all - * regulators are set and we do not need power control via - * DC ON anymore. This function will likely be moved whenever - * the rest of the U300 power management is implemented. - */ - pr_info("U300: disable system controller pull-up\n"); - regmap_update_bits(regmap, U300_SYSCON_PMCR, - U300_SYSCON_PMCR_DCON_ENABLE, 0); - - /* Register globally exported PM poweroff hook */ - pm_power_off = u300_pm_poweroff; - - return 0; -} - -static int __init s365_board_probe(struct platform_device *pdev) -{ - return __u300_init_boardpower(pdev); -} - -static const struct of_device_id s365_board_match[] = { - { .compatible = "stericsson,s365" }, - {}, -}; - -static struct platform_driver s365_board_driver = { - .driver = { - .name = "s365-board", - .of_match_table = s365_board_match, - }, -}; - -/* - * So at module init time we hog the regulator! - */ -static int __init u300_init_boardpower(void) -{ - return platform_driver_probe(&s365_board_driver, - s365_board_probe); -} - -device_initcall(u300_init_boardpower); -MODULE_LICENSE("GPL v2"); -MODULE_AUTHOR("Linus Walleij"); diff --git a/drivers/mtd/nand/raw/Kconfig b/drivers/mtd/nand/raw/Kconfig index 442a039b92f3..4b84fd36e384 100644 --- a/drivers/mtd/nand/raw/Kconfig +++ b/drivers/mtd/nand/raw/Kconfig @@ -331,8 +331,7 @@ source "drivers/mtd/nand/raw/ingenic/Kconfig" config MTD_NAND_FSMC tristate "ST Micros FSMC NAND controller" depends on OF && HAS_IOMEM - depends on PLAT_SPEAR || ARCH_NOMADIK || ARCH_U8500 || MACH_U300 || \ - COMPILE_TEST + depends on PLAT_SPEAR || ARCH_NOMADIK || ARCH_U8500 || COMPILE_TEST help Enables support for NAND Flash chips on the ST Microelectronics Flexible Static Memory Controller (FSMC) diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig index aadaea052f51..74ea73a05981 100644 --- a/drivers/spi/Kconfig +++ b/drivers/spi/Kconfig @@ -601,7 +601,6 @@ config SPI_PIC32_SQI config SPI_PL022 tristate "ARM AMBA PL022 SSP controller" depends on ARM_AMBA - default y if MACH_U300 default y if ARCH_REALVIEW default y if INTEGRATOR_IMPD1 default y if ARCH_VERSATILE -- cgit v1.2.3 From a2bc9b21fd3f89b1f9a5df46427855dcf344e6e7 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Wed, 20 Jan 2021 16:09:22 +0100 Subject: pwm: Remove ZTE ZX driver The ZTE ZX platform is getting removed, so this driver is no longer needed. Cc: Jun Nie Cc: Shawn Guo Signed-off-by: Arnd Bergmann Signed-off-by: Thierry Reding --- Documentation/devicetree/bindings/pwm/pwm-zx.txt | 22 -- drivers/pwm/Kconfig | 10 - drivers/pwm/Makefile | 1 - drivers/pwm/pwm-zx.c | 278 ----------------------- 4 files changed, 311 deletions(-) delete mode 100644 Documentation/devicetree/bindings/pwm/pwm-zx.txt delete mode 100644 drivers/pwm/pwm-zx.c (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/pwm/pwm-zx.txt b/Documentation/devicetree/bindings/pwm/pwm-zx.txt deleted file mode 100644 index 3c8fe7aa8269..000000000000 --- a/Documentation/devicetree/bindings/pwm/pwm-zx.txt +++ /dev/null @@ -1,22 +0,0 @@ -ZTE ZX PWM controller - -Required properties: - - compatible: Should be "zte,zx296718-pwm". - - reg: Physical base address and length of the controller's registers. - - clocks : The phandle and specifier referencing the controller's clocks. - - clock-names: "pclk" for PCLK, "wclk" for WCLK to the PWM controller. The - PCLK is for register access, while WCLK is the reference clock for - calculating period and duty cycles. - - #pwm-cells: Should be 3. See pwm.yaml in this directory for a description of - the cells format. - -Example: - - pwm: pwm@1439000 { - compatible = "zte,zx296718-pwm"; - reg = <0x1439000 0x1000>; - clocks = <&lsp1crm LSP1_PWM_PCLK>, - <&lsp1crm LSP1_PWM_WCLK>; - clock-names = "pclk", "wclk"; - #pwm-cells = <3>; - }; diff --git a/drivers/pwm/Kconfig b/drivers/pwm/Kconfig index 0937e1c047ac..9a4f66ae8070 100644 --- a/drivers/pwm/Kconfig +++ b/drivers/pwm/Kconfig @@ -611,14 +611,4 @@ config PWM_VT8500 To compile this driver as a module, choose M here: the module will be called pwm-vt8500. -config PWM_ZX - tristate "ZTE ZX PWM support" - depends on ARCH_ZX || COMPILE_TEST - depends on HAS_IOMEM - help - Generic PWM framework driver for ZTE ZX family SoCs. - - To compile this driver as a module, choose M here: the module - will be called pwm-zx. - endif diff --git a/drivers/pwm/Makefile b/drivers/pwm/Makefile index 18b89d7fd092..6374d3b1d6f3 100644 --- a/drivers/pwm/Makefile +++ b/drivers/pwm/Makefile @@ -57,4 +57,3 @@ obj-$(CONFIG_PWM_TIEHRPWM) += pwm-tiehrpwm.o obj-$(CONFIG_PWM_TWL) += pwm-twl.o obj-$(CONFIG_PWM_TWL_LED) += pwm-twl-led.o obj-$(CONFIG_PWM_VT8500) += pwm-vt8500.o -obj-$(CONFIG_PWM_ZX) += pwm-zx.o diff --git a/drivers/pwm/pwm-zx.c b/drivers/pwm/pwm-zx.c deleted file mode 100644 index 34e91195ce98..000000000000 --- a/drivers/pwm/pwm-zx.c +++ /dev/null @@ -1,278 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Copyright (C) 2017 Sanechips Technology Co., Ltd. - * Copyright 2017 Linaro Ltd. - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -#define ZX_PWM_MODE 0x0 -#define ZX_PWM_CLKDIV_SHIFT 2 -#define ZX_PWM_CLKDIV_MASK GENMASK(11, 2) -#define ZX_PWM_CLKDIV(x) (((x) << ZX_PWM_CLKDIV_SHIFT) & \ - ZX_PWM_CLKDIV_MASK) -#define ZX_PWM_POLAR BIT(1) -#define ZX_PWM_EN BIT(0) -#define ZX_PWM_PERIOD 0x4 -#define ZX_PWM_DUTY 0x8 - -#define ZX_PWM_CLKDIV_MAX 1023 -#define ZX_PWM_PERIOD_MAX 65535 - -struct zx_pwm_chip { - struct pwm_chip chip; - struct clk *pclk; - struct clk *wclk; - void __iomem *base; -}; - -static inline struct zx_pwm_chip *to_zx_pwm_chip(struct pwm_chip *chip) -{ - return container_of(chip, struct zx_pwm_chip, chip); -} - -static inline u32 zx_pwm_readl(struct zx_pwm_chip *zpc, unsigned int hwpwm, - unsigned int offset) -{ - return readl(zpc->base + (hwpwm + 1) * 0x10 + offset); -} - -static inline void zx_pwm_writel(struct zx_pwm_chip *zpc, unsigned int hwpwm, - unsigned int offset, u32 value) -{ - writel(value, zpc->base + (hwpwm + 1) * 0x10 + offset); -} - -static void zx_pwm_set_mask(struct zx_pwm_chip *zpc, unsigned int hwpwm, - unsigned int offset, u32 mask, u32 value) -{ - u32 data; - - data = zx_pwm_readl(zpc, hwpwm, offset); - data &= ~mask; - data |= value & mask; - zx_pwm_writel(zpc, hwpwm, offset, data); -} - -static void zx_pwm_get_state(struct pwm_chip *chip, struct pwm_device *pwm, - struct pwm_state *state) -{ - struct zx_pwm_chip *zpc = to_zx_pwm_chip(chip); - unsigned long rate; - unsigned int div; - u32 value; - u64 tmp; - - value = zx_pwm_readl(zpc, pwm->hwpwm, ZX_PWM_MODE); - - if (value & ZX_PWM_POLAR) - state->polarity = PWM_POLARITY_NORMAL; - else - state->polarity = PWM_POLARITY_INVERSED; - - if (value & ZX_PWM_EN) - state->enabled = true; - else - state->enabled = false; - - div = (value & ZX_PWM_CLKDIV_MASK) >> ZX_PWM_CLKDIV_SHIFT; - rate = clk_get_rate(zpc->wclk); - - tmp = zx_pwm_readl(zpc, pwm->hwpwm, ZX_PWM_PERIOD); - tmp *= div * NSEC_PER_SEC; - state->period = DIV_ROUND_CLOSEST_ULL(tmp, rate); - - tmp = zx_pwm_readl(zpc, pwm->hwpwm, ZX_PWM_DUTY); - tmp *= div * NSEC_PER_SEC; - state->duty_cycle = DIV_ROUND_CLOSEST_ULL(tmp, rate); -} - -static int zx_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm, - unsigned int duty_ns, unsigned int period_ns) -{ - struct zx_pwm_chip *zpc = to_zx_pwm_chip(chip); - unsigned int period_cycles, duty_cycles; - unsigned long long c; - unsigned int div = 1; - unsigned long rate; - - /* Find out the best divider */ - rate = clk_get_rate(zpc->wclk); - - while (1) { - c = rate / div; - c = c * period_ns; - do_div(c, NSEC_PER_SEC); - - if (c < ZX_PWM_PERIOD_MAX) - break; - - div++; - - if (div > ZX_PWM_CLKDIV_MAX) - return -ERANGE; - } - - /* Calculate duty cycles */ - period_cycles = c; - c *= duty_ns; - do_div(c, period_ns); - duty_cycles = c; - - /* - * If the PWM is being enabled, we have to temporarily disable it - * before configuring the registers. - */ - if (pwm_is_enabled(pwm)) - zx_pwm_set_mask(zpc, pwm->hwpwm, ZX_PWM_MODE, ZX_PWM_EN, 0); - - /* Set up registers */ - zx_pwm_set_mask(zpc, pwm->hwpwm, ZX_PWM_MODE, ZX_PWM_CLKDIV_MASK, - ZX_PWM_CLKDIV(div)); - zx_pwm_writel(zpc, pwm->hwpwm, ZX_PWM_PERIOD, period_cycles); - zx_pwm_writel(zpc, pwm->hwpwm, ZX_PWM_DUTY, duty_cycles); - - /* Re-enable the PWM if needed */ - if (pwm_is_enabled(pwm)) - zx_pwm_set_mask(zpc, pwm->hwpwm, ZX_PWM_MODE, - ZX_PWM_EN, ZX_PWM_EN); - - return 0; -} - -static int zx_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm, - const struct pwm_state *state) -{ - struct zx_pwm_chip *zpc = to_zx_pwm_chip(chip); - struct pwm_state cstate; - int ret; - - pwm_get_state(pwm, &cstate); - - if (state->polarity != cstate.polarity) - zx_pwm_set_mask(zpc, pwm->hwpwm, ZX_PWM_MODE, ZX_PWM_POLAR, - (state->polarity == PWM_POLARITY_INVERSED) ? - 0 : ZX_PWM_POLAR); - - if (state->period != cstate.period || - state->duty_cycle != cstate.duty_cycle) { - ret = zx_pwm_config(chip, pwm, state->duty_cycle, - state->period); - if (ret) - return ret; - } - - if (state->enabled != cstate.enabled) { - if (state->enabled) { - ret = clk_prepare_enable(zpc->wclk); - if (ret) - return ret; - - zx_pwm_set_mask(zpc, pwm->hwpwm, ZX_PWM_MODE, - ZX_PWM_EN, ZX_PWM_EN); - } else { - zx_pwm_set_mask(zpc, pwm->hwpwm, ZX_PWM_MODE, - ZX_PWM_EN, 0); - clk_disable_unprepare(zpc->wclk); - } - } - - return 0; -} - -static const struct pwm_ops zx_pwm_ops = { - .apply = zx_pwm_apply, - .get_state = zx_pwm_get_state, - .owner = THIS_MODULE, -}; - -static int zx_pwm_probe(struct platform_device *pdev) -{ - struct zx_pwm_chip *zpc; - unsigned int i; - int ret; - - zpc = devm_kzalloc(&pdev->dev, sizeof(*zpc), GFP_KERNEL); - if (!zpc) - return -ENOMEM; - - zpc->base = devm_platform_ioremap_resource(pdev, 0); - if (IS_ERR(zpc->base)) - return PTR_ERR(zpc->base); - - zpc->pclk = devm_clk_get(&pdev->dev, "pclk"); - if (IS_ERR(zpc->pclk)) - return PTR_ERR(zpc->pclk); - - zpc->wclk = devm_clk_get(&pdev->dev, "wclk"); - if (IS_ERR(zpc->wclk)) - return PTR_ERR(zpc->wclk); - - ret = clk_prepare_enable(zpc->pclk); - if (ret) - return ret; - - zpc->chip.dev = &pdev->dev; - zpc->chip.ops = &zx_pwm_ops; - zpc->chip.base = -1; - zpc->chip.npwm = 4; - zpc->chip.of_xlate = of_pwm_xlate_with_flags; - zpc->chip.of_pwm_n_cells = 3; - - /* - * PWM devices may be enabled by firmware, and let's disable all of - * them initially to save power. - */ - for (i = 0; i < zpc->chip.npwm; i++) - zx_pwm_set_mask(zpc, i, ZX_PWM_MODE, ZX_PWM_EN, 0); - - ret = pwmchip_add(&zpc->chip); - if (ret < 0) { - dev_err(&pdev->dev, "failed to add PWM chip: %d\n", ret); - clk_disable_unprepare(zpc->pclk); - return ret; - } - - platform_set_drvdata(pdev, zpc); - - return 0; -} - -static int zx_pwm_remove(struct platform_device *pdev) -{ - struct zx_pwm_chip *zpc = platform_get_drvdata(pdev); - int ret; - - ret = pwmchip_remove(&zpc->chip); - clk_disable_unprepare(zpc->pclk); - - return ret; -} - -static const struct of_device_id zx_pwm_dt_ids[] = { - { .compatible = "zte,zx296718-pwm", }, - { /* sentinel */ } -}; -MODULE_DEVICE_TABLE(of, zx_pwm_dt_ids); - -static struct platform_driver zx_pwm_driver = { - .driver = { - .name = "zx-pwm", - .of_match_table = zx_pwm_dt_ids, - }, - .probe = zx_pwm_probe, - .remove = zx_pwm_remove, -}; -module_platform_driver(zx_pwm_driver); - -MODULE_ALIAS("platform:zx-pwm"); -MODULE_AUTHOR("Shawn Guo "); -MODULE_DESCRIPTION("ZTE ZX PWM Driver"); -MODULE_LICENSE("GPL v2"); -- cgit v1.2.3 From f754ed71b79cca5b07e76aaf28ce3c8776ab1f7f Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 28 Dec 2020 12:27:10 +0100 Subject: dt-bindings: serial: renesas,hscif: Add r8a779a0 support Reviewed-by: Geert Uytterhoeven Acked-by: Rob Herring Signed-off-by: Wolfram Sang Link: https://lore.kernel.org/r/20201228112715.14947-4-wsa+renesas@sang-engineering.com Signed-off-by: Greg Kroah-Hartman --- Documentation/devicetree/bindings/serial/renesas,hscif.yaml | 1 + 1 file changed, 1 insertion(+) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/serial/renesas,hscif.yaml b/Documentation/devicetree/bindings/serial/renesas,hscif.yaml index c139c5edb93e..512a84942f78 100644 --- a/Documentation/devicetree/bindings/serial/renesas,hscif.yaml +++ b/Documentation/devicetree/bindings/serial/renesas,hscif.yaml @@ -51,6 +51,7 @@ properties: - renesas,hscif-r8a77980 # R-Car V3H - renesas,hscif-r8a77990 # R-Car E3 - renesas,hscif-r8a77995 # R-Car D3 + - renesas,hscif-r8a779a0 # R-Car V3U - const: renesas,rcar-gen3-hscif # R-Car Gen3 and RZ/G2 - const: renesas,hscif # generic HSCIF compatible UART -- cgit v1.2.3 From 4776a4a0a29c64b954a445ff65848bd376a50fcc Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Wed, 20 Jan 2021 17:12:26 +0100 Subject: serial: remove sirf prima/atlas driver The CSR SiRF prima2/atlas platforms are getting removed, so this driver is no longer needed. Cc: Barry Song Signed-off-by: Arnd Bergmann Link: https://lore.kernel.org/r/20210120161324.3728294-1-arnd@kernel.org Signed-off-by: Greg Kroah-Hartman --- .../devicetree/bindings/serial/sirf-uart.txt | 34 - drivers/tty/serial/Kconfig | 22 - drivers/tty/serial/Makefile | 1 - drivers/tty/serial/sirfsoc_uart.c | 1503 -------------------- drivers/tty/serial/sirfsoc_uart.h | 447 ------ 5 files changed, 2007 deletions(-) delete mode 100644 Documentation/devicetree/bindings/serial/sirf-uart.txt delete mode 100644 drivers/tty/serial/sirfsoc_uart.c delete mode 100644 drivers/tty/serial/sirfsoc_uart.h (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/serial/sirf-uart.txt b/Documentation/devicetree/bindings/serial/sirf-uart.txt deleted file mode 100644 index 1e48bbbeecc6..000000000000 --- a/Documentation/devicetree/bindings/serial/sirf-uart.txt +++ /dev/null @@ -1,34 +0,0 @@ -* CSR SiRFprimaII/atlasVI Universal Synchronous Asynchronous Receiver/Transmitter * - -Required properties: -- compatible : Should be "sirf,prima2-uart", "sirf, prima2-usp-uart", - "sirf,atlas7-uart" or "sirf,atlas7-usp-uart". -- reg : Offset and length of the register set for the device -- interrupts : Should contain uart interrupt -- fifosize : Should define hardware rx/tx fifo size -- clocks : Should contain uart clock number - -Optional properties: -- uart-has-rtscts: we have hardware flow controller pins in hardware -- rts-gpios: RTS pin for USP-based UART if uart-has-rtscts is true -- cts-gpios: CTS pin for USP-based UART if uart-has-rtscts is true - -Example: - -uart0: uart@b0050000 { - cell-index = <0>; - compatible = "sirf,prima2-uart"; - reg = <0xb0050000 0x1000>; - interrupts = <17>; - fifosize = <128>; - clocks = <&clks 13>; -}; - -On the board-specific dts, we can put rts-gpios and cts-gpios like - -usp@b0090000 { - compatible = "sirf,prima2-usp-uart"; - uart-has-rtscts; - rts-gpios = <&gpio 15 0>; - cts-gpios = <&gpio 46 0>; -}; diff --git a/drivers/tty/serial/Kconfig b/drivers/tty/serial/Kconfig index 83f6ca4bf210..22e86ba4f827 100644 --- a/drivers/tty/serial/Kconfig +++ b/drivers/tty/serial/Kconfig @@ -276,28 +276,6 @@ config SERIAL_SAMSUNG_CONSOLE your boot loader about how to pass options to the kernel at boot time.) -config SERIAL_SIRFSOC - tristate "SiRF SoC Platform Serial port support" - depends on ARCH_SIRF - select SERIAL_CORE - help - Support for the on-chip UART on the CSR SiRFprimaII series, - providing /dev/ttySiRF0, 1 and 2 (note, some machines may not - provide all of these ports, depending on how the serial port - pins are configured). - -config SERIAL_SIRFSOC_CONSOLE - bool "Support for console on SiRF SoC serial port" - depends on SERIAL_SIRFSOC=y - select SERIAL_CORE_CONSOLE - help - Even if you say Y here, the currently visible virtual console - (/dev/tty0) will still be used as the system console by default, but - you can alter that using a kernel command line option such as - "console=ttySiRFx". (Try "man bootparam" or see the documentation of - your boot loader about how to pass options to the kernel at - boot time.) - config SERIAL_TEGRA tristate "NVIDIA Tegra20/30 SoC serial controller" depends on ARCH_TEGRA && TEGRA20_APB_DMA diff --git a/drivers/tty/serial/Makefile b/drivers/tty/serial/Makefile index ec2b74091f0c..931dc1d6885e 100644 --- a/drivers/tty/serial/Makefile +++ b/drivers/tty/serial/Makefile @@ -69,7 +69,6 @@ obj-$(CONFIG_SERIAL_PCH_UART) += pch_uart.o obj-$(CONFIG_SERIAL_MXS_AUART) += mxs-auart.o obj-$(CONFIG_SERIAL_LANTIQ) += lantiq.o obj-$(CONFIG_SERIAL_XILINX_PS_UART) += xilinx_uartps.o -obj-$(CONFIG_SERIAL_SIRFSOC) += sirfsoc_uart.o obj-$(CONFIG_SERIAL_TEGRA) += serial-tegra.o obj-$(CONFIG_SERIAL_TEGRA_TCU) += tegra-tcu.o obj-$(CONFIG_SERIAL_AR933X) += ar933x_uart.o diff --git a/drivers/tty/serial/sirfsoc_uart.c b/drivers/tty/serial/sirfsoc_uart.c deleted file mode 100644 index 38622f2a30a9..000000000000 --- a/drivers/tty/serial/sirfsoc_uart.c +++ /dev/null @@ -1,1503 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0+ -/* - * Driver for CSR SiRFprimaII onboard UARTs. - * - * Copyright (c) 2011 Cambridge Silicon Radio Limited, a CSR plc group company. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "sirfsoc_uart.h" - -static unsigned int -sirfsoc_uart_pio_tx_chars(struct sirfsoc_uart_port *sirfport, int count); -static unsigned int -sirfsoc_uart_pio_rx_chars(struct uart_port *port, unsigned int max_rx_count); -static struct uart_driver sirfsoc_uart_drv; - -static void sirfsoc_uart_tx_dma_complete_callback(void *param); -static const struct sirfsoc_baudrate_to_regv baudrate_to_regv[] = { - {4000000, 2359296}, - {3500000, 1310721}, - {3000000, 1572865}, - {2500000, 1245186}, - {2000000, 1572866}, - {1500000, 1245188}, - {1152000, 1638404}, - {1000000, 1572869}, - {921600, 1114120}, - {576000, 1245196}, - {500000, 1245198}, - {460800, 1572876}, - {230400, 1310750}, - {115200, 1310781}, - {57600, 1310843}, - {38400, 1114328}, - {19200, 1114545}, - {9600, 1114979}, -}; - -static struct sirfsoc_uart_port *sirf_ports[SIRFSOC_UART_NR]; - -static inline struct sirfsoc_uart_port *to_sirfport(struct uart_port *port) -{ - return container_of(port, struct sirfsoc_uart_port, port); -} - -static inline unsigned int sirfsoc_uart_tx_empty(struct uart_port *port) -{ - unsigned long reg; - struct sirfsoc_uart_port *sirfport = to_sirfport(port); - struct sirfsoc_register *ureg = &sirfport->uart_reg->uart_reg; - struct sirfsoc_fifo_status *ufifo_st = &sirfport->uart_reg->fifo_status; - reg = rd_regl(port, ureg->sirfsoc_tx_fifo_status); - return (reg & ufifo_st->ff_empty(port)) ? TIOCSER_TEMT : 0; -} - -static unsigned int sirfsoc_uart_get_mctrl(struct uart_port *port) -{ - struct sirfsoc_uart_port *sirfport = to_sirfport(port); - struct sirfsoc_register *ureg = &sirfport->uart_reg->uart_reg; - if (!sirfport->hw_flow_ctrl || !sirfport->ms_enabled) - goto cts_asserted; - if (sirfport->uart_reg->uart_type == SIRF_REAL_UART) { - if (!(rd_regl(port, ureg->sirfsoc_afc_ctrl) & - SIRFUART_AFC_CTS_STATUS)) - goto cts_asserted; - else - goto cts_deasserted; - } else { - if (!gpio_get_value(sirfport->cts_gpio)) - goto cts_asserted; - else - goto cts_deasserted; - } -cts_deasserted: - return TIOCM_CAR | TIOCM_DSR; -cts_asserted: - return TIOCM_CAR | TIOCM_DSR | TIOCM_CTS; -} - -static void sirfsoc_uart_set_mctrl(struct uart_port *port, unsigned int mctrl) -{ - struct sirfsoc_uart_port *sirfport = to_sirfport(port); - struct sirfsoc_register *ureg = &sirfport->uart_reg->uart_reg; - unsigned int assert = mctrl & TIOCM_RTS; - unsigned int val = assert ? SIRFUART_AFC_CTRL_RX_THD : 0x0; - unsigned int current_val; - - if (mctrl & TIOCM_LOOP) { - if (sirfport->uart_reg->uart_type == SIRF_REAL_UART) - wr_regl(port, ureg->sirfsoc_line_ctrl, - rd_regl(port, ureg->sirfsoc_line_ctrl) | - SIRFUART_LOOP_BACK); - else - wr_regl(port, ureg->sirfsoc_mode1, - rd_regl(port, ureg->sirfsoc_mode1) | - SIRFSOC_USP_LOOP_BACK_CTRL); - } else { - if (sirfport->uart_reg->uart_type == SIRF_REAL_UART) - wr_regl(port, ureg->sirfsoc_line_ctrl, - rd_regl(port, ureg->sirfsoc_line_ctrl) & - ~SIRFUART_LOOP_BACK); - else - wr_regl(port, ureg->sirfsoc_mode1, - rd_regl(port, ureg->sirfsoc_mode1) & - ~SIRFSOC_USP_LOOP_BACK_CTRL); - } - - if (!sirfport->hw_flow_ctrl || !sirfport->ms_enabled) - return; - if (sirfport->uart_reg->uart_type == SIRF_REAL_UART) { - current_val = rd_regl(port, ureg->sirfsoc_afc_ctrl) & ~0xFF; - val |= current_val; - wr_regl(port, ureg->sirfsoc_afc_ctrl, val); - } else { - if (!val) - gpio_set_value(sirfport->rts_gpio, 1); - else - gpio_set_value(sirfport->rts_gpio, 0); - } -} - -static void sirfsoc_uart_stop_tx(struct uart_port *port) -{ - struct sirfsoc_uart_port *sirfport = to_sirfport(port); - struct sirfsoc_register *ureg = &sirfport->uart_reg->uart_reg; - struct sirfsoc_int_en *uint_en = &sirfport->uart_reg->uart_int_en; - - if (sirfport->tx_dma_chan) { - if (sirfport->tx_dma_state == TX_DMA_RUNNING) { - dmaengine_pause(sirfport->tx_dma_chan); - sirfport->tx_dma_state = TX_DMA_PAUSE; - } else { - if (!sirfport->is_atlas7) - wr_regl(port, ureg->sirfsoc_int_en_reg, - rd_regl(port, ureg->sirfsoc_int_en_reg) & - ~uint_en->sirfsoc_txfifo_empty_en); - else - wr_regl(port, ureg->sirfsoc_int_en_clr_reg, - uint_en->sirfsoc_txfifo_empty_en); - } - } else { - if (sirfport->uart_reg->uart_type == SIRF_USP_UART) - wr_regl(port, ureg->sirfsoc_tx_rx_en, rd_regl(port, - ureg->sirfsoc_tx_rx_en) & ~SIRFUART_TX_EN); - if (!sirfport->is_atlas7) - wr_regl(port, ureg->sirfsoc_int_en_reg, - rd_regl(port, ureg->sirfsoc_int_en_reg) & - ~uint_en->sirfsoc_txfifo_empty_en); - else - wr_regl(port, ureg->sirfsoc_int_en_clr_reg, - uint_en->sirfsoc_txfifo_empty_en); - } -} - -static void sirfsoc_uart_tx_with_dma(struct sirfsoc_uart_port *sirfport) -{ - struct uart_port *port = &sirfport->port; - struct sirfsoc_register *ureg = &sirfport->uart_reg->uart_reg; - struct sirfsoc_int_en *uint_en = &sirfport->uart_reg->uart_int_en; - struct circ_buf *xmit = &port->state->xmit; - unsigned long tran_size; - unsigned long tran_start; - unsigned long pio_tx_size; - - tran_size = CIRC_CNT_TO_END(xmit->head, xmit->tail, UART_XMIT_SIZE); - tran_start = (unsigned long)(xmit->buf + xmit->tail); - if (uart_circ_empty(xmit) || uart_tx_stopped(port) || - !tran_size) - return; - if (sirfport->tx_dma_state == TX_DMA_PAUSE) { - dmaengine_resume(sirfport->tx_dma_chan); - return; - } - if (sirfport->tx_dma_state == TX_DMA_RUNNING) - return; - if (!sirfport->is_atlas7) - wr_regl(port, ureg->sirfsoc_int_en_reg, - rd_regl(port, ureg->sirfsoc_int_en_reg)& - ~(uint_en->sirfsoc_txfifo_empty_en)); - else - wr_regl(port, ureg->sirfsoc_int_en_clr_reg, - uint_en->sirfsoc_txfifo_empty_en); - /* - * DMA requires buffer address and buffer length are both aligned with - * 4 bytes, so we use PIO for - * 1. if address is not aligned with 4bytes, use PIO for the first 1~3 - * bytes, and move to DMA for the left part aligned with 4bytes - * 2. if buffer length is not aligned with 4bytes, use DMA for aligned - * part first, move to PIO for the left 1~3 bytes - */ - if (tran_size < 4 || BYTES_TO_ALIGN(tran_start)) { - wr_regl(port, ureg->sirfsoc_tx_fifo_op, SIRFUART_FIFO_STOP); - wr_regl(port, ureg->sirfsoc_tx_dma_io_ctrl, - rd_regl(port, ureg->sirfsoc_tx_dma_io_ctrl)| - SIRFUART_IO_MODE); - if (BYTES_TO_ALIGN(tran_start)) { - pio_tx_size = sirfsoc_uart_pio_tx_chars(sirfport, - BYTES_TO_ALIGN(tran_start)); - tran_size -= pio_tx_size; - } - if (tran_size < 4) - sirfsoc_uart_pio_tx_chars(sirfport, tran_size); - if (!sirfport->is_atlas7) - wr_regl(port, ureg->sirfsoc_int_en_reg, - rd_regl(port, ureg->sirfsoc_int_en_reg)| - uint_en->sirfsoc_txfifo_empty_en); - else - wr_regl(port, ureg->sirfsoc_int_en_reg, - uint_en->sirfsoc_txfifo_empty_en); - wr_regl(port, ureg->sirfsoc_tx_fifo_op, SIRFUART_FIFO_START); - } else { - /* tx transfer mode switch into dma mode */ - wr_regl(port, ureg->sirfsoc_tx_fifo_op, SIRFUART_FIFO_STOP); - wr_regl(port, ureg->sirfsoc_tx_dma_io_ctrl, - rd_regl(port, ureg->sirfsoc_tx_dma_io_ctrl)& - ~SIRFUART_IO_MODE); - wr_regl(port, ureg->sirfsoc_tx_fifo_op, SIRFUART_FIFO_START); - tran_size &= ~(0x3); - - sirfport->tx_dma_addr = dma_map_single(port->dev, - xmit->buf + xmit->tail, - tran_size, DMA_TO_DEVICE); - sirfport->tx_dma_desc = dmaengine_prep_slave_single( - sirfport->tx_dma_chan, sirfport->tx_dma_addr, - tran_size, DMA_MEM_TO_DEV, DMA_PREP_INTERRUPT); - if (!sirfport->tx_dma_desc) { - dev_err(port->dev, "DMA prep slave single fail\n"); - return; - } - sirfport->tx_dma_desc->callback = - sirfsoc_uart_tx_dma_complete_callback; - sirfport->tx_dma_desc->callback_param = (void *)sirfport; - sirfport->transfer_size = tran_size; - - dmaengine_submit(sirfport->tx_dma_desc); - dma_async_issue_pending(sirfport->tx_dma_chan); - sirfport->tx_dma_state = TX_DMA_RUNNING; - } -} - -static void sirfsoc_uart_start_tx(struct uart_port *port) -{ - struct sirfsoc_uart_port *sirfport = to_sirfport(port); - struct sirfsoc_register *ureg = &sirfport->uart_reg->uart_reg; - struct sirfsoc_int_en *uint_en = &sirfport->uart_reg->uart_int_en; - if (sirfport->tx_dma_chan) - sirfsoc_uart_tx_with_dma(sirfport); - else { - if (sirfport->uart_reg->uart_type == SIRF_USP_UART) - wr_regl(port, ureg->sirfsoc_tx_rx_en, rd_regl(port, - ureg->sirfsoc_tx_rx_en) | SIRFUART_TX_EN); - wr_regl(port, ureg->sirfsoc_tx_fifo_op, SIRFUART_FIFO_STOP); - sirfsoc_uart_pio_tx_chars(sirfport, port->fifosize); - wr_regl(port, ureg->sirfsoc_tx_fifo_op, SIRFUART_FIFO_START); - if (!sirfport->is_atlas7) - wr_regl(port, ureg->sirfsoc_int_en_reg, - rd_regl(port, ureg->sirfsoc_int_en_reg)| - uint_en->sirfsoc_txfifo_empty_en); - else - wr_regl(port, ureg->sirfsoc_int_en_reg, - uint_en->sirfsoc_txfifo_empty_en); - } -} - -static void sirfsoc_uart_stop_rx(struct uart_port *port) -{ - struct sirfsoc_uart_port *sirfport = to_sirfport(port); - struct sirfsoc_register *ureg = &sirfport->uart_reg->uart_reg; - struct sirfsoc_int_en *uint_en = &sirfport->uart_reg->uart_int_en; - - wr_regl(port, ureg->sirfsoc_rx_fifo_op, 0); - if (sirfport->rx_dma_chan) { - if (!sirfport->is_atlas7) - wr_regl(port, ureg->sirfsoc_int_en_reg, - rd_regl(port, ureg->sirfsoc_int_en_reg) & - ~(SIRFUART_RX_DMA_INT_EN(uint_en, - sirfport->uart_reg->uart_type) | - uint_en->sirfsoc_rx_done_en)); - else - wr_regl(port, ureg->sirfsoc_int_en_clr_reg, - SIRFUART_RX_DMA_INT_EN(uint_en, - sirfport->uart_reg->uart_type)| - uint_en->sirfsoc_rx_done_en); - dmaengine_terminate_all(sirfport->rx_dma_chan); - } else { - if (!sirfport->is_atlas7) - wr_regl(port, ureg->sirfsoc_int_en_reg, - rd_regl(port, ureg->sirfsoc_int_en_reg)& - ~(SIRFUART_RX_IO_INT_EN(uint_en, - sirfport->uart_reg->uart_type))); - else - wr_regl(port, ureg->sirfsoc_int_en_clr_reg, - SIRFUART_RX_IO_INT_EN(uint_en, - sirfport->uart_reg->uart_type)); - } -} - -static void sirfsoc_uart_disable_ms(struct uart_port *port) -{ - struct sirfsoc_uart_port *sirfport = to_sirfport(port); - struct sirfsoc_register *ureg = &sirfport->uart_reg->uart_reg; - struct sirfsoc_int_en *uint_en = &sirfport->uart_reg->uart_int_en; - - if (!sirfport->hw_flow_ctrl) - return; - sirfport->ms_enabled = false; - if (sirfport->uart_reg->uart_type == SIRF_REAL_UART) { - wr_regl(port, ureg->sirfsoc_afc_ctrl, - rd_regl(port, ureg->sirfsoc_afc_ctrl) & ~0x3FF); - if (!sirfport->is_atlas7) - wr_regl(port, ureg->sirfsoc_int_en_reg, - rd_regl(port, ureg->sirfsoc_int_en_reg)& - ~uint_en->sirfsoc_cts_en); - else - wr_regl(port, ureg->sirfsoc_int_en_clr_reg, - uint_en->sirfsoc_cts_en); - } else - disable_irq(gpio_to_irq(sirfport->cts_gpio)); -} - -static irqreturn_t sirfsoc_uart_usp_cts_handler(int irq, void *dev_id) -{ - struct sirfsoc_uart_port *sirfport = (struct sirfsoc_uart_port *)dev_id; - struct uart_port *port = &sirfport->port; - spin_lock(&port->lock); - if (gpio_is_valid(sirfport->cts_gpio) && sirfport->ms_enabled) - uart_handle_cts_change(port, - !gpio_get_value(sirfport->cts_gpio)); - spin_unlock(&port->lock); - return IRQ_HANDLED; -} - -static void sirfsoc_uart_enable_ms(struct uart_port *port) -{ - struct sirfsoc_uart_port *sirfport = to_sirfport(port); - struct sirfsoc_register *ureg = &sirfport->uart_reg->uart_reg; - struct sirfsoc_int_en *uint_en = &sirfport->uart_reg->uart_int_en; - - if (!sirfport->hw_flow_ctrl) - return; - sirfport->ms_enabled = true; - if (sirfport->uart_reg->uart_type == SIRF_REAL_UART) { - wr_regl(port, ureg->sirfsoc_afc_ctrl, - rd_regl(port, ureg->sirfsoc_afc_ctrl) | - SIRFUART_AFC_TX_EN | SIRFUART_AFC_RX_EN | - SIRFUART_AFC_CTRL_RX_THD); - if (!sirfport->is_atlas7) - wr_regl(port, ureg->sirfsoc_int_en_reg, - rd_regl(port, ureg->sirfsoc_int_en_reg) - | uint_en->sirfsoc_cts_en); - else - wr_regl(port, ureg->sirfsoc_int_en_reg, - uint_en->sirfsoc_cts_en); - } else - enable_irq(gpio_to_irq(sirfport->cts_gpio)); -} - -static void sirfsoc_uart_break_ctl(struct uart_port *port, int break_state) -{ - struct sirfsoc_uart_port *sirfport = to_sirfport(port); - struct sirfsoc_register *ureg = &sirfport->uart_reg->uart_reg; - if (sirfport->uart_reg->uart_type == SIRF_REAL_UART) { - unsigned long ulcon = rd_regl(port, ureg->sirfsoc_line_ctrl); - if (break_state) - ulcon |= SIRFUART_SET_BREAK; - else - ulcon &= ~SIRFUART_SET_BREAK; - wr_regl(port, ureg->sirfsoc_line_ctrl, ulcon); - } -} - -static unsigned int -sirfsoc_uart_pio_rx_chars(struct uart_port *port, unsigned int max_rx_count) -{ - struct sirfsoc_uart_port *sirfport = to_sirfport(port); - struct sirfsoc_register *ureg = &sirfport->uart_reg->uart_reg; - struct sirfsoc_fifo_status *ufifo_st = &sirfport->uart_reg->fifo_status; - unsigned int ch, rx_count = 0; - struct tty_struct *tty; - tty = tty_port_tty_get(&port->state->port); - if (!tty) - return -ENODEV; - while (!(rd_regl(port, ureg->sirfsoc_rx_fifo_status) & - ufifo_st->ff_empty(port))) { - ch = rd_regl(port, ureg->sirfsoc_rx_fifo_data) | - SIRFUART_DUMMY_READ; - if (unlikely(uart_handle_sysrq_char(port, ch))) - continue; - uart_insert_char(port, 0, 0, ch, TTY_NORMAL); - rx_count++; - if (rx_count >= max_rx_count) - break; - } - - port->icount.rx += rx_count; - - return rx_count; -} - -static unsigned int -sirfsoc_uart_pio_tx_chars(struct sirfsoc_uart_port *sirfport, int count) -{ - struct uart_port *port = &sirfport->port; - struct sirfsoc_register *ureg = &sirfport->uart_reg->uart_reg; - struct sirfsoc_fifo_status *ufifo_st = &sirfport->uart_reg->fifo_status; - struct circ_buf *xmit = &port->state->xmit; - unsigned int num_tx = 0; - while (!uart_circ_empty(xmit) && - !(rd_regl(port, ureg->sirfsoc_tx_fifo_status) & - ufifo_st->ff_full(port)) && - count--) { - wr_regl(port, ureg->sirfsoc_tx_fifo_data, - xmit->buf[xmit->tail]); - xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); - port->icount.tx++; - num_tx++; - } - if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) - uart_write_wakeup(port); - return num_tx; -} - -static void sirfsoc_uart_tx_dma_complete_callback(void *param) -{ - struct sirfsoc_uart_port *sirfport = (struct sirfsoc_uart_port *)param; - struct uart_port *port = &sirfport->port; - struct circ_buf *xmit = &port->state->xmit; - unsigned long flags; - - spin_lock_irqsave(&port->lock, flags); - xmit->tail = (xmit->tail + sirfport->transfer_size) & - (UART_XMIT_SIZE - 1); - port->icount.tx += sirfport->transfer_size; - if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) - uart_write_wakeup(port); - if (sirfport->tx_dma_addr) - dma_unmap_single(port->dev, sirfport->tx_dma_addr, - sirfport->transfer_size, DMA_TO_DEVICE); - sirfport->tx_dma_state = TX_DMA_IDLE; - sirfsoc_uart_tx_with_dma(sirfport); - spin_unlock_irqrestore(&port->lock, flags); -} - -static irqreturn_t sirfsoc_uart_isr(int irq, void *dev_id) -{ - unsigned long intr_status; - unsigned long cts_status; - unsigned long flag = TTY_NORMAL; - struct sirfsoc_uart_port *sirfport = (struct sirfsoc_uart_port *)dev_id; - struct uart_port *port = &sirfport->port; - struct sirfsoc_register *ureg = &sirfport->uart_reg->uart_reg; - struct sirfsoc_fifo_status *ufifo_st = &sirfport->uart_reg->fifo_status; - struct sirfsoc_int_status *uint_st = &sirfport->uart_reg->uart_int_st; - struct sirfsoc_int_en *uint_en = &sirfport->uart_reg->uart_int_en; - struct uart_state *state = port->state; - struct circ_buf *xmit = &port->state->xmit; - spin_lock(&port->lock); - intr_status = rd_regl(port, ureg->sirfsoc_int_st_reg); - wr_regl(port, ureg->sirfsoc_int_st_reg, intr_status); - intr_status &= rd_regl(port, ureg->sirfsoc_int_en_reg); - if (unlikely(intr_status & (SIRFUART_ERR_INT_STAT(uint_st, - sirfport->uart_reg->uart_type)))) { - if (intr_status & uint_st->sirfsoc_rxd_brk) { - port->icount.brk++; - if (uart_handle_break(port)) - goto recv_char; - } - if (intr_status & uint_st->sirfsoc_rx_oflow) { - port->icount.overrun++; - flag = TTY_OVERRUN; - } - if (intr_status & uint_st->sirfsoc_frm_err) { - port->icount.frame++; - flag = TTY_FRAME; - } - if (intr_status & uint_st->sirfsoc_parity_err) { - port->icount.parity++; - flag = TTY_PARITY; - } - wr_regl(port, ureg->sirfsoc_rx_fifo_op, SIRFUART_FIFO_RESET); - wr_regl(port, ureg->sirfsoc_rx_fifo_op, 0); - wr_regl(port, ureg->sirfsoc_rx_fifo_op, SIRFUART_FIFO_START); - intr_status &= port->read_status_mask; - uart_insert_char(port, intr_status, - uint_en->sirfsoc_rx_oflow_en, 0, flag); - } -recv_char: - if ((sirfport->uart_reg->uart_type == SIRF_REAL_UART) && - (intr_status & SIRFUART_CTS_INT_ST(uint_st)) && - !sirfport->tx_dma_state) { - cts_status = rd_regl(port, ureg->sirfsoc_afc_ctrl) & - SIRFUART_AFC_CTS_STATUS; - if (cts_status != 0) - cts_status = 0; - else - cts_status = 1; - uart_handle_cts_change(port, cts_status); - wake_up_interruptible(&state->port.delta_msr_wait); - } - if (!sirfport->rx_dma_chan && - (intr_status & SIRFUART_RX_IO_INT_ST(uint_st))) { - /* - * chip will trigger continuous RX_TIMEOUT interrupt - * in RXFIFO empty and not trigger if RXFIFO recevice - * data in limit time, original method use RX_TIMEOUT - * will trigger lots of useless interrupt in RXFIFO - * empty.RXFIFO received one byte will trigger RX_DONE - * interrupt.use RX_DONE to wait for data received - * into RXFIFO, use RX_THD/RX_FULL for lots data receive - * and use RX_TIMEOUT for the last left data. - */ - if (intr_status & uint_st->sirfsoc_rx_done) { - if (!sirfport->is_atlas7) { - wr_regl(port, ureg->sirfsoc_int_en_reg, - rd_regl(port, ureg->sirfsoc_int_en_reg) - & ~(uint_en->sirfsoc_rx_done_en)); - wr_regl(port, ureg->sirfsoc_int_en_reg, - rd_regl(port, ureg->sirfsoc_int_en_reg) - | (uint_en->sirfsoc_rx_timeout_en)); - } else { - wr_regl(port, ureg->sirfsoc_int_en_clr_reg, - uint_en->sirfsoc_rx_done_en); - wr_regl(port, ureg->sirfsoc_int_en_reg, - uint_en->sirfsoc_rx_timeout_en); - } - } else { - if (intr_status & uint_st->sirfsoc_rx_timeout) { - if (!sirfport->is_atlas7) { - wr_regl(port, ureg->sirfsoc_int_en_reg, - rd_regl(port, ureg->sirfsoc_int_en_reg) - & ~(uint_en->sirfsoc_rx_timeout_en)); - wr_regl(port, ureg->sirfsoc_int_en_reg, - rd_regl(port, ureg->sirfsoc_int_en_reg) - | (uint_en->sirfsoc_rx_done_en)); - } else { - wr_regl(port, - ureg->sirfsoc_int_en_clr_reg, - uint_en->sirfsoc_rx_timeout_en); - wr_regl(port, ureg->sirfsoc_int_en_reg, - uint_en->sirfsoc_rx_done_en); - } - } - sirfsoc_uart_pio_rx_chars(port, port->fifosize); - } - } - spin_unlock(&port->lock); - tty_flip_buffer_push(&state->port); - spin_lock(&port->lock); - if (intr_status & uint_st->sirfsoc_txfifo_empty) { - if (sirfport->tx_dma_chan) - sirfsoc_uart_tx_with_dma(sirfport); - else { - if (uart_circ_empty(xmit) || uart_tx_stopped(port)) { - spin_unlock(&port->lock); - return IRQ_HANDLED; - } else { - sirfsoc_uart_pio_tx_chars(sirfport, - port->fifosize); - if ((uart_circ_empty(xmit)) && - (rd_regl(port, ureg->sirfsoc_tx_fifo_status) & - ufifo_st->ff_empty(port))) - sirfsoc_uart_stop_tx(port); - } - } - } - spin_unlock(&port->lock); - - return IRQ_HANDLED; -} - -static void sirfsoc_uart_rx_dma_complete_callback(void *param) -{ -} - -/* submit rx dma task into dmaengine */ -static void sirfsoc_uart_start_next_rx_dma(struct uart_port *port) -{ - struct sirfsoc_uart_port *sirfport = to_sirfport(port); - struct sirfsoc_register *ureg = &sirfport->uart_reg->uart_reg; - struct sirfsoc_int_en *uint_en = &sirfport->uart_reg->uart_int_en; - wr_regl(port, ureg->sirfsoc_rx_dma_io_ctrl, - rd_regl(port, ureg->sirfsoc_rx_dma_io_ctrl) & - ~SIRFUART_IO_MODE); - sirfport->rx_dma_items.xmit.tail = - sirfport->rx_dma_items.xmit.head = 0; - sirfport->rx_dma_items.desc = - dmaengine_prep_dma_cyclic(sirfport->rx_dma_chan, - sirfport->rx_dma_items.dma_addr, SIRFSOC_RX_DMA_BUF_SIZE, - SIRFSOC_RX_DMA_BUF_SIZE / 2, - DMA_DEV_TO_MEM, DMA_PREP_INTERRUPT); - if (IS_ERR_OR_NULL(sirfport->rx_dma_items.desc)) { - dev_err(port->dev, "DMA slave single fail\n"); - return; - } - sirfport->rx_dma_items.desc->callback = - sirfsoc_uart_rx_dma_complete_callback; - sirfport->rx_dma_items.desc->callback_param = sirfport; - sirfport->rx_dma_items.cookie = - dmaengine_submit(sirfport->rx_dma_items.desc); - dma_async_issue_pending(sirfport->rx_dma_chan); - if (!sirfport->is_atlas7) - wr_regl(port, ureg->sirfsoc_int_en_reg, - rd_regl(port, ureg->sirfsoc_int_en_reg) | - SIRFUART_RX_DMA_INT_EN(uint_en, - sirfport->uart_reg->uart_type)); - else - wr_regl(port, ureg->sirfsoc_int_en_reg, - SIRFUART_RX_DMA_INT_EN(uint_en, - sirfport->uart_reg->uart_type)); -} - -static unsigned int -sirfsoc_usp_calc_sample_div(unsigned long set_rate, - unsigned long ioclk_rate, unsigned long *sample_reg) -{ - unsigned long min_delta = ~0UL; - unsigned short sample_div; - unsigned long ioclk_div = 0; - unsigned long temp_delta; - - for (sample_div = SIRF_USP_MIN_SAMPLE_DIV; - sample_div <= SIRF_MAX_SAMPLE_DIV; sample_div++) { - temp_delta = ioclk_rate - - (ioclk_rate + (set_rate * sample_div) / 2) - / (set_rate * sample_div) * set_rate * sample_div; - - temp_delta = (temp_delta > 0) ? temp_delta : -temp_delta; - if (temp_delta < min_delta) { - ioclk_div = (2 * ioclk_rate / - (set_rate * sample_div) + 1) / 2 - 1; - if (ioclk_div > SIRF_IOCLK_DIV_MAX) - continue; - min_delta = temp_delta; - *sample_reg = sample_div; - if (!temp_delta) - break; - } - } - return ioclk_div; -} - -static unsigned int -sirfsoc_uart_calc_sample_div(unsigned long baud_rate, - unsigned long ioclk_rate, unsigned long *set_baud) -{ - unsigned long min_delta = ~0UL; - unsigned short sample_div; - unsigned int regv = 0; - unsigned long ioclk_div; - unsigned long baud_tmp; - int temp_delta; - - for (sample_div = SIRF_MIN_SAMPLE_DIV; - sample_div <= SIRF_MAX_SAMPLE_DIV; sample_div++) { - ioclk_div = (ioclk_rate / (baud_rate * (sample_div + 1))) - 1; - if (ioclk_div > SIRF_IOCLK_DIV_MAX) - continue; - baud_tmp = ioclk_rate / ((ioclk_div + 1) * (sample_div + 1)); - temp_delta = baud_tmp - baud_rate; - temp_delta = (temp_delta > 0) ? temp_delta : -temp_delta; - if (temp_delta < min_delta) { - regv = regv & (~SIRF_IOCLK_DIV_MASK); - regv = regv | ioclk_div; - regv = regv & (~SIRF_SAMPLE_DIV_MASK); - regv = regv | (sample_div << SIRF_SAMPLE_DIV_SHIFT); - min_delta = temp_delta; - *set_baud = baud_tmp; - } - } - return regv; -} - -static void sirfsoc_uart_set_termios(struct uart_port *port, - struct ktermios *termios, - struct ktermios *old) -{ - struct sirfsoc_uart_port *sirfport = to_sirfport(port); - struct sirfsoc_register *ureg = &sirfport->uart_reg->uart_reg; - struct sirfsoc_int_en *uint_en = &sirfport->uart_reg->uart_int_en; - unsigned long config_reg = 0; - unsigned long baud_rate; - unsigned long set_baud; - unsigned long flags; - unsigned long ic; - unsigned int clk_div_reg = 0; - unsigned long txfifo_op_reg, ioclk_rate; - unsigned long rx_time_out; - int threshold_div; - u32 data_bit_len, stop_bit_len, len_val; - unsigned long sample_div_reg = 0xf; - ioclk_rate = port->uartclk; - - switch (termios->c_cflag & CSIZE) { - default: - case CS8: - data_bit_len = 8; - config_reg |= SIRFUART_DATA_BIT_LEN_8; - break; - case CS7: - data_bit_len = 7; - config_reg |= SIRFUART_DATA_BIT_LEN_7; - break; - case CS6: - data_bit_len = 6; - config_reg |= SIRFUART_DATA_BIT_LEN_6; - break; - case CS5: - data_bit_len = 5; - config_reg |= SIRFUART_DATA_BIT_LEN_5; - break; - } - if (termios->c_cflag & CSTOPB) { - config_reg |= SIRFUART_STOP_BIT_LEN_2; - stop_bit_len = 2; - } else - stop_bit_len = 1; - - spin_lock_irqsave(&port->lock, flags); - port->read_status_mask = uint_en->sirfsoc_rx_oflow_en; - port->ignore_status_mask = 0; - if (sirfport->uart_reg->uart_type == SIRF_REAL_UART) { - if (termios->c_iflag & INPCK) - port->read_status_mask |= uint_en->sirfsoc_frm_err_en | - uint_en->sirfsoc_parity_err_en; - } else { - if (termios->c_iflag & INPCK) - port->read_status_mask |= uint_en->sirfsoc_frm_err_en; - } - if (termios->c_iflag & (IGNBRK | BRKINT | PARMRK)) - port->read_status_mask |= uint_en->sirfsoc_rxd_brk_en; - if (sirfport->uart_reg->uart_type == SIRF_REAL_UART) { - if (termios->c_iflag & IGNPAR) - port->ignore_status_mask |= - uint_en->sirfsoc_frm_err_en | - uint_en->sirfsoc_parity_err_en; - if (termios->c_cflag & PARENB) { - if (termios->c_cflag & CMSPAR) { - if (termios->c_cflag & PARODD) - config_reg |= SIRFUART_STICK_BIT_MARK; - else - config_reg |= SIRFUART_STICK_BIT_SPACE; - } else { - if (termios->c_cflag & PARODD) - config_reg |= SIRFUART_STICK_BIT_ODD; - else - config_reg |= SIRFUART_STICK_BIT_EVEN; - } - } - } else { - if (termios->c_iflag & IGNPAR) - port->ignore_status_mask |= - uint_en->sirfsoc_frm_err_en; - if (termios->c_cflag & PARENB) - dev_warn(port->dev, - "USP-UART not support parity err\n"); - } - if (termios->c_iflag & IGNBRK) { - port->ignore_status_mask |= - uint_en->sirfsoc_rxd_brk_en; - if (termios->c_iflag & IGNPAR) - port->ignore_status_mask |= - uint_en->sirfsoc_rx_oflow_en; - } - if ((termios->c_cflag & CREAD) == 0) - port->ignore_status_mask |= SIRFUART_DUMMY_READ; - /* Hardware Flow Control Settings */ - if (UART_ENABLE_MS(port, termios->c_cflag)) { - if (!sirfport->ms_enabled) - sirfsoc_uart_enable_ms(port); - } else { - if (sirfport->ms_enabled) - sirfsoc_uart_disable_ms(port); - } - baud_rate = uart_get_baud_rate(port, termios, old, 0, 4000000); - if (ioclk_rate == 150000000) { - for (ic = 0; ic < SIRF_BAUD_RATE_SUPPORT_NR; ic++) - if (baud_rate == baudrate_to_regv[ic].baud_rate) - clk_div_reg = baudrate_to_regv[ic].reg_val; - } - set_baud = baud_rate; - if (sirfport->uart_reg->uart_type == SIRF_REAL_UART) { - if (unlikely(clk_div_reg == 0)) - clk_div_reg = sirfsoc_uart_calc_sample_div(baud_rate, - ioclk_rate, &set_baud); - wr_regl(port, ureg->sirfsoc_divisor, clk_div_reg); - } else { - clk_div_reg = sirfsoc_usp_calc_sample_div(baud_rate, - ioclk_rate, &sample_div_reg); - sample_div_reg--; - set_baud = ((ioclk_rate / (clk_div_reg+1) - 1) / - (sample_div_reg + 1)); - /* setting usp mode 2 */ - len_val = ((1 << SIRFSOC_USP_MODE2_RXD_DELAY_OFFSET) | - (1 << SIRFSOC_USP_MODE2_TXD_DELAY_OFFSET)); - len_val |= ((clk_div_reg & SIRFSOC_USP_MODE2_CLK_DIVISOR_MASK) - << SIRFSOC_USP_MODE2_CLK_DIVISOR_OFFSET); - wr_regl(port, ureg->sirfsoc_mode2, len_val); - } - if (tty_termios_baud_rate(termios)) - tty_termios_encode_baud_rate(termios, set_baud, set_baud); - /* set receive timeout && data bits len */ - rx_time_out = SIRFSOC_UART_RX_TIMEOUT(set_baud, 20000); - rx_time_out = SIRFUART_RECV_TIMEOUT_VALUE(rx_time_out); - txfifo_op_reg = rd_regl(port, ureg->sirfsoc_tx_fifo_op); - wr_regl(port, ureg->sirfsoc_tx_fifo_op, - (txfifo_op_reg & ~SIRFUART_FIFO_START)); - if (sirfport->uart_reg->uart_type == SIRF_REAL_UART) { - config_reg |= SIRFUART_UART_RECV_TIMEOUT(rx_time_out); - wr_regl(port, ureg->sirfsoc_line_ctrl, config_reg); - } else { - /*tx frame ctrl*/ - len_val = (data_bit_len - 1) << SIRFSOC_USP_TX_DATA_LEN_OFFSET; - len_val |= (data_bit_len + 1 + stop_bit_len - 1) << - SIRFSOC_USP_TX_FRAME_LEN_OFFSET; - len_val |= ((data_bit_len - 1) << - SIRFSOC_USP_TX_SHIFTER_LEN_OFFSET); - len_val |= (((clk_div_reg & 0xc00) >> 10) << - SIRFSOC_USP_TX_CLK_DIVISOR_OFFSET); - wr_regl(port, ureg->sirfsoc_tx_frame_ctrl, len_val); - /*rx frame ctrl*/ - len_val = (data_bit_len - 1) << SIRFSOC_USP_RX_DATA_LEN_OFFSET; - len_val |= (data_bit_len + 1 + stop_bit_len - 1) << - SIRFSOC_USP_RX_FRAME_LEN_OFFSET; - len_val |= (data_bit_len - 1) << - SIRFSOC_USP_RX_SHIFTER_LEN_OFFSET; - len_val |= (((clk_div_reg & 0xf000) >> 12) << - SIRFSOC_USP_RX_CLK_DIVISOR_OFFSET); - wr_regl(port, ureg->sirfsoc_rx_frame_ctrl, len_val); - /*async param*/ - wr_regl(port, ureg->sirfsoc_async_param_reg, - (SIRFUART_USP_RECV_TIMEOUT(rx_time_out)) | - (sample_div_reg & SIRFSOC_USP_ASYNC_DIV2_MASK) << - SIRFSOC_USP_ASYNC_DIV2_OFFSET); - } - if (sirfport->tx_dma_chan) - wr_regl(port, ureg->sirfsoc_tx_dma_io_ctrl, SIRFUART_DMA_MODE); - else - wr_regl(port, ureg->sirfsoc_tx_dma_io_ctrl, SIRFUART_IO_MODE); - if (sirfport->rx_dma_chan) - wr_regl(port, ureg->sirfsoc_rx_dma_io_ctrl, - rd_regl(port, ureg->sirfsoc_rx_dma_io_ctrl) & - ~SIRFUART_IO_MODE); - else - wr_regl(port, ureg->sirfsoc_rx_dma_io_ctrl, - rd_regl(port, ureg->sirfsoc_rx_dma_io_ctrl) | - SIRFUART_IO_MODE); - sirfport->rx_period_time = 20000000; - /* Reset Rx/Tx FIFO Threshold level for proper baudrate */ - if (set_baud < 1000000) - threshold_div = 1; - else - threshold_div = 2; - wr_regl(port, ureg->sirfsoc_tx_fifo_ctrl, - SIRFUART_FIFO_THD(port) / threshold_div); - wr_regl(port, ureg->sirfsoc_rx_fifo_ctrl, - SIRFUART_FIFO_THD(port) / threshold_div); - txfifo_op_reg |= SIRFUART_FIFO_START; - wr_regl(port, ureg->sirfsoc_tx_fifo_op, txfifo_op_reg); - uart_update_timeout(port, termios->c_cflag, set_baud); - wr_regl(port, ureg->sirfsoc_tx_rx_en, SIRFUART_TX_EN | SIRFUART_RX_EN); - spin_unlock_irqrestore(&port->lock, flags); -} - -static void sirfsoc_uart_pm(struct uart_port *port, unsigned int state, - unsigned int oldstate) -{ - struct sirfsoc_uart_port *sirfport = to_sirfport(port); - if (!state) - clk_prepare_enable(sirfport->clk); - else - clk_disable_unprepare(sirfport->clk); -} - -static int sirfsoc_uart_startup(struct uart_port *port) -{ - struct sirfsoc_uart_port *sirfport = to_sirfport(port); - struct sirfsoc_register *ureg = &sirfport->uart_reg->uart_reg; - struct sirfsoc_int_en *uint_en = &sirfport->uart_reg->uart_int_en; - unsigned int index = port->line; - int ret; - irq_modify_status(port->irq, IRQ_NOREQUEST, IRQ_NOAUTOEN); - ret = request_irq(port->irq, - sirfsoc_uart_isr, - 0, - SIRFUART_PORT_NAME, - sirfport); - if (ret != 0) { - dev_err(port->dev, "UART%d request IRQ line (%d) failed.\n", - index, port->irq); - goto irq_err; - } - /* initial hardware settings */ - wr_regl(port, ureg->sirfsoc_tx_dma_io_ctrl, - rd_regl(port, ureg->sirfsoc_tx_dma_io_ctrl) | - SIRFUART_IO_MODE); - wr_regl(port, ureg->sirfsoc_rx_dma_io_ctrl, - rd_regl(port, ureg->sirfsoc_rx_dma_io_ctrl) | - SIRFUART_IO_MODE); - wr_regl(port, ureg->sirfsoc_rx_dma_io_ctrl, - rd_regl(port, ureg->sirfsoc_rx_dma_io_ctrl) & - ~SIRFUART_RX_DMA_FLUSH); - wr_regl(port, ureg->sirfsoc_tx_dma_io_len, 0); - wr_regl(port, ureg->sirfsoc_rx_dma_io_len, 0); - wr_regl(port, ureg->sirfsoc_tx_rx_en, SIRFUART_RX_EN | SIRFUART_TX_EN); - if (sirfport->uart_reg->uart_type == SIRF_USP_UART) - wr_regl(port, ureg->sirfsoc_mode1, - SIRFSOC_USP_ENDIAN_CTRL_LSBF | - SIRFSOC_USP_EN); - wr_regl(port, ureg->sirfsoc_tx_fifo_op, SIRFUART_FIFO_RESET); - wr_regl(port, ureg->sirfsoc_rx_fifo_op, SIRFUART_FIFO_RESET); - wr_regl(port, ureg->sirfsoc_rx_fifo_op, 0); - wr_regl(port, ureg->sirfsoc_tx_fifo_ctrl, SIRFUART_FIFO_THD(port)); - wr_regl(port, ureg->sirfsoc_rx_fifo_ctrl, SIRFUART_FIFO_THD(port)); - if (sirfport->rx_dma_chan) - wr_regl(port, ureg->sirfsoc_rx_fifo_level_chk, - SIRFUART_RX_FIFO_CHK_SC(port->line, 0x1) | - SIRFUART_RX_FIFO_CHK_LC(port->line, 0x2) | - SIRFUART_RX_FIFO_CHK_HC(port->line, 0x4)); - if (sirfport->tx_dma_chan) { - sirfport->tx_dma_state = TX_DMA_IDLE; - wr_regl(port, ureg->sirfsoc_tx_fifo_level_chk, - SIRFUART_TX_FIFO_CHK_SC(port->line, 0x1b) | - SIRFUART_TX_FIFO_CHK_LC(port->line, 0xe) | - SIRFUART_TX_FIFO_CHK_HC(port->line, 0x4)); - } - sirfport->ms_enabled = false; - if (sirfport->uart_reg->uart_type == SIRF_USP_UART && - sirfport->hw_flow_ctrl) { - irq_modify_status(gpio_to_irq(sirfport->cts_gpio), - IRQ_NOREQUEST, IRQ_NOAUTOEN); - ret = request_irq(gpio_to_irq(sirfport->cts_gpio), - sirfsoc_uart_usp_cts_handler, IRQF_TRIGGER_FALLING | - IRQF_TRIGGER_RISING, "usp_cts_irq", sirfport); - if (ret != 0) { - dev_err(port->dev, "UART-USP:request gpio irq fail\n"); - goto init_rx_err; - } - } - if (sirfport->uart_reg->uart_type == SIRF_REAL_UART && - sirfport->rx_dma_chan) - wr_regl(port, ureg->sirfsoc_swh_dma_io, - SIRFUART_CLEAR_RX_ADDR_EN); - if (sirfport->uart_reg->uart_type == SIRF_USP_UART && - sirfport->rx_dma_chan) - wr_regl(port, ureg->sirfsoc_rx_dma_io_ctrl, - rd_regl(port, ureg->sirfsoc_rx_dma_io_ctrl) | - SIRFSOC_USP_FRADDR_CLR_EN); - if (sirfport->rx_dma_chan && !sirfport->is_hrt_enabled) { - sirfport->is_hrt_enabled = true; - sirfport->rx_period_time = 20000000; - sirfport->rx_last_pos = -1; - sirfport->pio_fetch_cnt = 0; - sirfport->rx_dma_items.xmit.tail = - sirfport->rx_dma_items.xmit.head = 0; - hrtimer_start(&sirfport->hrt, - ns_to_ktime(sirfport->rx_period_time), - HRTIMER_MODE_REL); - } - wr_regl(port, ureg->sirfsoc_rx_fifo_op, SIRFUART_FIFO_START); - if (sirfport->rx_dma_chan) - sirfsoc_uart_start_next_rx_dma(port); - else { - if (!sirfport->is_atlas7) - wr_regl(port, ureg->sirfsoc_int_en_reg, - rd_regl(port, ureg->sirfsoc_int_en_reg) | - SIRFUART_RX_IO_INT_EN(uint_en, - sirfport->uart_reg->uart_type)); - else - wr_regl(port, ureg->sirfsoc_int_en_reg, - SIRFUART_RX_IO_INT_EN(uint_en, - sirfport->uart_reg->uart_type)); - } - enable_irq(port->irq); - - return 0; -init_rx_err: - free_irq(port->irq, sirfport); -irq_err: - return ret; -} - -static void sirfsoc_uart_shutdown(struct uart_port *port) -{ - struct sirfsoc_uart_port *sirfport = to_sirfport(port); - struct sirfsoc_register *ureg = &sirfport->uart_reg->uart_reg; - struct circ_buf *xmit; - - xmit = &sirfport->rx_dma_items.xmit; - if (!sirfport->is_atlas7) - wr_regl(port, ureg->sirfsoc_int_en_reg, 0); - else - wr_regl(port, ureg->sirfsoc_int_en_clr_reg, ~0UL); - - free_irq(port->irq, sirfport); - if (sirfport->ms_enabled) - sirfsoc_uart_disable_ms(port); - if (sirfport->uart_reg->uart_type == SIRF_USP_UART && - sirfport->hw_flow_ctrl) { - gpio_set_value(sirfport->rts_gpio, 1); - free_irq(gpio_to_irq(sirfport->cts_gpio), sirfport); - } - if (sirfport->tx_dma_chan) - sirfport->tx_dma_state = TX_DMA_IDLE; - if (sirfport->rx_dma_chan && sirfport->is_hrt_enabled) { - while (((rd_regl(port, ureg->sirfsoc_rx_fifo_status) & - SIRFUART_RX_FIFO_MASK) > sirfport->pio_fetch_cnt) && - !CIRC_CNT(xmit->head, xmit->tail, - SIRFSOC_RX_DMA_BUF_SIZE)) - ; - sirfport->is_hrt_enabled = false; - hrtimer_cancel(&sirfport->hrt); - } -} - -static const char *sirfsoc_uart_type(struct uart_port *port) -{ - return port->type == SIRFSOC_PORT_TYPE ? SIRFUART_PORT_NAME : NULL; -} - -static int sirfsoc_uart_request_port(struct uart_port *port) -{ - struct sirfsoc_uart_port *sirfport = to_sirfport(port); - struct sirfsoc_uart_param *uart_param = &sirfport->uart_reg->uart_param; - void *ret; - ret = request_mem_region(port->mapbase, - SIRFUART_MAP_SIZE, uart_param->port_name); - return ret ? 0 : -EBUSY; -} - -static void sirfsoc_uart_release_port(struct uart_port *port) -{ - release_mem_region(port->mapbase, SIRFUART_MAP_SIZE); -} - -static void sirfsoc_uart_config_port(struct uart_port *port, int flags) -{ - if (flags & UART_CONFIG_TYPE) { - port->type = SIRFSOC_PORT_TYPE; - sirfsoc_uart_request_port(port); - } -} - -static const struct uart_ops sirfsoc_uart_ops = { - .tx_empty = sirfsoc_uart_tx_empty, - .get_mctrl = sirfsoc_uart_get_mctrl, - .set_mctrl = sirfsoc_uart_set_mctrl, - .stop_tx = sirfsoc_uart_stop_tx, - .start_tx = sirfsoc_uart_start_tx, - .stop_rx = sirfsoc_uart_stop_rx, - .enable_ms = sirfsoc_uart_enable_ms, - .break_ctl = sirfsoc_uart_break_ctl, - .startup = sirfsoc_uart_startup, - .shutdown = sirfsoc_uart_shutdown, - .set_termios = sirfsoc_uart_set_termios, - .pm = sirfsoc_uart_pm, - .type = sirfsoc_uart_type, - .release_port = sirfsoc_uart_release_port, - .request_port = sirfsoc_uart_request_port, - .config_port = sirfsoc_uart_config_port, -}; - -#ifdef CONFIG_SERIAL_SIRFSOC_CONSOLE -static int __init -sirfsoc_uart_console_setup(struct console *co, char *options) -{ - unsigned int baud = 115200; - unsigned int bits = 8; - unsigned int parity = 'n'; - unsigned int flow = 'n'; - struct sirfsoc_uart_port *sirfport; - struct sirfsoc_register *ureg; - if (co->index < 0 || co->index >= SIRFSOC_UART_NR) - co->index = 1; - sirfport = sirf_ports[co->index]; - if (!sirfport) - return -ENODEV; - ureg = &sirfport->uart_reg->uart_reg; - if (!sirfport->port.mapbase) - return -ENODEV; - - /* enable usp in mode1 register */ - if (sirfport->uart_reg->uart_type == SIRF_USP_UART) - wr_regl(&sirfport->port, ureg->sirfsoc_mode1, SIRFSOC_USP_EN | - SIRFSOC_USP_ENDIAN_CTRL_LSBF); - if (options) - uart_parse_options(options, &baud, &parity, &bits, &flow); - sirfport->port.cons = co; - - /* default console tx/rx transfer using io mode */ - sirfport->rx_dma_chan = NULL; - sirfport->tx_dma_chan = NULL; - return uart_set_options(&sirfport->port, co, baud, parity, bits, flow); -} - -static void sirfsoc_uart_console_putchar(struct uart_port *port, int ch) -{ - struct sirfsoc_uart_port *sirfport = to_sirfport(port); - struct sirfsoc_register *ureg = &sirfport->uart_reg->uart_reg; - struct sirfsoc_fifo_status *ufifo_st = &sirfport->uart_reg->fifo_status; - while (rd_regl(port, ureg->sirfsoc_tx_fifo_status) & - ufifo_st->ff_full(port)) - cpu_relax(); - wr_regl(port, ureg->sirfsoc_tx_fifo_data, ch); -} - -static void sirfsoc_uart_console_write(struct console *co, const char *s, - unsigned int count) -{ - struct sirfsoc_uart_port *sirfport = sirf_ports[co->index]; - - uart_console_write(&sirfport->port, s, count, - sirfsoc_uart_console_putchar); -} - -static struct console sirfsoc_uart_console = { - .name = SIRFSOC_UART_NAME, - .device = uart_console_device, - .flags = CON_PRINTBUFFER, - .index = -1, - .write = sirfsoc_uart_console_write, - .setup = sirfsoc_uart_console_setup, - .data = &sirfsoc_uart_drv, -}; - -static int __init sirfsoc_uart_console_init(void) -{ - register_console(&sirfsoc_uart_console); - return 0; -} -console_initcall(sirfsoc_uart_console_init); -#endif - -static struct uart_driver sirfsoc_uart_drv = { - .owner = THIS_MODULE, - .driver_name = SIRFUART_PORT_NAME, - .nr = SIRFSOC_UART_NR, - .dev_name = SIRFSOC_UART_NAME, - .major = SIRFSOC_UART_MAJOR, - .minor = SIRFSOC_UART_MINOR, -#ifdef CONFIG_SERIAL_SIRFSOC_CONSOLE - .cons = &sirfsoc_uart_console, -#else - .cons = NULL, -#endif -}; - -static enum hrtimer_restart - sirfsoc_uart_rx_dma_hrtimer_callback(struct hrtimer *hrt) -{ - struct sirfsoc_uart_port *sirfport; - struct uart_port *port; - int count, inserted; - struct dma_tx_state tx_state; - struct tty_struct *tty; - struct sirfsoc_register *ureg; - struct circ_buf *xmit; - struct sirfsoc_fifo_status *ufifo_st; - int max_pio_cnt; - - sirfport = container_of(hrt, struct sirfsoc_uart_port, hrt); - port = &sirfport->port; - inserted = 0; - tty = port->state->port.tty; - ureg = &sirfport->uart_reg->uart_reg; - xmit = &sirfport->rx_dma_items.xmit; - ufifo_st = &sirfport->uart_reg->fifo_status; - - dmaengine_tx_status(sirfport->rx_dma_chan, - sirfport->rx_dma_items.cookie, &tx_state); - if (SIRFSOC_RX_DMA_BUF_SIZE - tx_state.residue != - sirfport->rx_last_pos) { - xmit->head = SIRFSOC_RX_DMA_BUF_SIZE - tx_state.residue; - sirfport->rx_last_pos = xmit->head; - sirfport->pio_fetch_cnt = 0; - } - count = CIRC_CNT_TO_END(xmit->head, xmit->tail, - SIRFSOC_RX_DMA_BUF_SIZE); - while (count > 0) { - inserted = tty_insert_flip_string(tty->port, - (const unsigned char *)&xmit->buf[xmit->tail], count); - if (!inserted) - goto next_hrt; - port->icount.rx += inserted; - xmit->tail = (xmit->tail + inserted) & - (SIRFSOC_RX_DMA_BUF_SIZE - 1); - count = CIRC_CNT_TO_END(xmit->head, xmit->tail, - SIRFSOC_RX_DMA_BUF_SIZE); - tty_flip_buffer_push(tty->port); - } - /* - * if RX DMA buffer data have all push into tty buffer, and there is - * only little data(less than a dma transfer unit) left in rxfifo, - * fetch it out in pio mode and switch back to dma immediately - */ - if (!inserted && !count && - ((rd_regl(port, ureg->sirfsoc_rx_fifo_status) & - SIRFUART_RX_FIFO_MASK) > sirfport->pio_fetch_cnt)) { - dmaengine_pause(sirfport->rx_dma_chan); - /* switch to pio mode */ - wr_regl(port, ureg->sirfsoc_rx_dma_io_ctrl, - rd_regl(port, ureg->sirfsoc_rx_dma_io_ctrl) | - SIRFUART_IO_MODE); - /* - * UART controller SWH_DMA_IO register have CLEAR_RX_ADDR_EN - * When found changing I/O to DMA mode, it clears - * two low bits of read point; - * USP have similar FRADDR_CLR_EN bit in USP_RX_DMA_IO_CTRL. - * Fetch data out from rxfifo into DMA buffer in PIO mode, - * while switch back to DMA mode, the data fetched will override - * by DMA, as hardware have a strange behaviour: - * after switch back to DMA mode, check rxfifo status it will - * be the number PIO fetched, so record the fetched data count - * to avoid the repeated fetch - */ - max_pio_cnt = 3; - while (!(rd_regl(port, ureg->sirfsoc_rx_fifo_status) & - ufifo_st->ff_empty(port)) && max_pio_cnt--) { - xmit->buf[xmit->head] = - rd_regl(port, ureg->sirfsoc_rx_fifo_data); - xmit->head = (xmit->head + 1) & - (SIRFSOC_RX_DMA_BUF_SIZE - 1); - sirfport->pio_fetch_cnt++; - } - /* switch back to dma mode */ - wr_regl(port, ureg->sirfsoc_rx_dma_io_ctrl, - rd_regl(port, ureg->sirfsoc_rx_dma_io_ctrl) & - ~SIRFUART_IO_MODE); - dmaengine_resume(sirfport->rx_dma_chan); - } -next_hrt: - hrtimer_forward_now(hrt, ns_to_ktime(sirfport->rx_period_time)); - return HRTIMER_RESTART; -} - -static const struct of_device_id sirfsoc_uart_ids[] = { - { .compatible = "sirf,prima2-uart", .data = &sirfsoc_uart,}, - { .compatible = "sirf,atlas7-uart", .data = &sirfsoc_uart}, - { .compatible = "sirf,prima2-usp-uart", .data = &sirfsoc_usp}, - { .compatible = "sirf,atlas7-usp-uart", .data = &sirfsoc_usp}, - {} -}; -MODULE_DEVICE_TABLE(of, sirfsoc_uart_ids); - -static int sirfsoc_uart_probe(struct platform_device *pdev) -{ - struct device_node *np = pdev->dev.of_node; - struct sirfsoc_uart_port *sirfport; - struct uart_port *port; - struct resource *res; - int ret; - struct dma_slave_config slv_cfg = { - .src_maxburst = 1, - }; - struct dma_slave_config tx_slv_cfg = { - .dst_maxburst = 2, - }; - const struct of_device_id *match; - - match = of_match_node(sirfsoc_uart_ids, np); - sirfport = devm_kzalloc(&pdev->dev, sizeof(*sirfport), GFP_KERNEL); - if (!sirfport) { - ret = -ENOMEM; - goto err; - } - sirfport->port.line = of_alias_get_id(np, "serial"); - if (sirfport->port.line >= ARRAY_SIZE(sirf_ports)) { - dev_err(&pdev->dev, "serial%d out of range\n", - sirfport->port.line); - return -EINVAL; - } - sirf_ports[sirfport->port.line] = sirfport; - sirfport->port.iotype = UPIO_MEM; - sirfport->port.flags = UPF_BOOT_AUTOCONF; - port = &sirfport->port; - port->dev = &pdev->dev; - port->private_data = sirfport; - sirfport->uart_reg = (struct sirfsoc_uart_register *)match->data; - - sirfport->hw_flow_ctrl = - of_property_read_bool(np, "uart-has-rtscts") || - of_property_read_bool(np, "sirf,uart-has-rtscts") /* deprecated */; - if (of_device_is_compatible(np, "sirf,prima2-uart") || - of_device_is_compatible(np, "sirf,atlas7-uart")) - sirfport->uart_reg->uart_type = SIRF_REAL_UART; - if (of_device_is_compatible(np, "sirf,prima2-usp-uart") || - of_device_is_compatible(np, "sirf,atlas7-usp-uart")) { - sirfport->uart_reg->uart_type = SIRF_USP_UART; - if (!sirfport->hw_flow_ctrl) - goto usp_no_flow_control; - if (of_find_property(np, "cts-gpios", NULL)) - sirfport->cts_gpio = - of_get_named_gpio(np, "cts-gpios", 0); - else - sirfport->cts_gpio = -1; - if (of_find_property(np, "rts-gpios", NULL)) - sirfport->rts_gpio = - of_get_named_gpio(np, "rts-gpios", 0); - else - sirfport->rts_gpio = -1; - - if ((!gpio_is_valid(sirfport->cts_gpio) || - !gpio_is_valid(sirfport->rts_gpio))) { - ret = -EINVAL; - dev_err(&pdev->dev, - "Usp flow control must have cts and rts gpio"); - goto err; - } - ret = devm_gpio_request(&pdev->dev, sirfport->cts_gpio, - "usp-cts-gpio"); - if (ret) { - dev_err(&pdev->dev, "Unable request cts gpio"); - goto err; - } - gpio_direction_input(sirfport->cts_gpio); - ret = devm_gpio_request(&pdev->dev, sirfport->rts_gpio, - "usp-rts-gpio"); - if (ret) { - dev_err(&pdev->dev, "Unable request rts gpio"); - goto err; - } - gpio_direction_output(sirfport->rts_gpio, 1); - } -usp_no_flow_control: - if (of_device_is_compatible(np, "sirf,atlas7-uart") || - of_device_is_compatible(np, "sirf,atlas7-usp-uart")) - sirfport->is_atlas7 = true; - - if (of_property_read_u32(np, "fifosize", &port->fifosize)) { - dev_err(&pdev->dev, - "Unable to find fifosize in uart node.\n"); - ret = -EFAULT; - goto err; - } - - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (res == NULL) { - dev_err(&pdev->dev, "Insufficient resources.\n"); - ret = -EFAULT; - goto err; - } - port->mapbase = res->start; - port->membase = devm_ioremap(&pdev->dev, - res->start, resource_size(res)); - if (!port->membase) { - dev_err(&pdev->dev, "Cannot remap resource.\n"); - ret = -ENOMEM; - goto err; - } - res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); - if (res == NULL) { - dev_err(&pdev->dev, "Insufficient resources.\n"); - ret = -EFAULT; - goto err; - } - port->irq = res->start; - - sirfport->clk = devm_clk_get(&pdev->dev, NULL); - if (IS_ERR(sirfport->clk)) { - ret = PTR_ERR(sirfport->clk); - goto err; - } - port->uartclk = clk_get_rate(sirfport->clk); - - port->ops = &sirfsoc_uart_ops; - spin_lock_init(&port->lock); - - platform_set_drvdata(pdev, sirfport); - ret = uart_add_one_port(&sirfsoc_uart_drv, port); - if (ret != 0) { - dev_err(&pdev->dev, "Cannot add UART port(%d).\n", pdev->id); - goto err; - } - - sirfport->rx_dma_chan = dma_request_slave_channel(port->dev, "rx"); - sirfport->rx_dma_items.xmit.buf = - dma_alloc_coherent(port->dev, SIRFSOC_RX_DMA_BUF_SIZE, - &sirfport->rx_dma_items.dma_addr, GFP_KERNEL); - if (!sirfport->rx_dma_items.xmit.buf) { - dev_err(port->dev, "Uart alloc bufa failed\n"); - ret = -ENOMEM; - goto alloc_coherent_err; - } - sirfport->rx_dma_items.xmit.head = - sirfport->rx_dma_items.xmit.tail = 0; - if (sirfport->rx_dma_chan) - dmaengine_slave_config(sirfport->rx_dma_chan, &slv_cfg); - sirfport->tx_dma_chan = dma_request_slave_channel(port->dev, "tx"); - if (sirfport->tx_dma_chan) - dmaengine_slave_config(sirfport->tx_dma_chan, &tx_slv_cfg); - if (sirfport->rx_dma_chan) { - hrtimer_init(&sirfport->hrt, CLOCK_MONOTONIC, HRTIMER_MODE_REL); - sirfport->hrt.function = sirfsoc_uart_rx_dma_hrtimer_callback; - sirfport->is_hrt_enabled = false; - } - - return 0; -alloc_coherent_err: - dma_free_coherent(port->dev, SIRFSOC_RX_DMA_BUF_SIZE, - sirfport->rx_dma_items.xmit.buf, - sirfport->rx_dma_items.dma_addr); - dma_release_channel(sirfport->rx_dma_chan); -err: - return ret; -} - -static int sirfsoc_uart_remove(struct platform_device *pdev) -{ - struct sirfsoc_uart_port *sirfport = platform_get_drvdata(pdev); - struct uart_port *port = &sirfport->port; - uart_remove_one_port(&sirfsoc_uart_drv, port); - if (sirfport->rx_dma_chan) { - dmaengine_terminate_all(sirfport->rx_dma_chan); - dma_release_channel(sirfport->rx_dma_chan); - dma_free_coherent(port->dev, SIRFSOC_RX_DMA_BUF_SIZE, - sirfport->rx_dma_items.xmit.buf, - sirfport->rx_dma_items.dma_addr); - } - if (sirfport->tx_dma_chan) { - dmaengine_terminate_all(sirfport->tx_dma_chan); - dma_release_channel(sirfport->tx_dma_chan); - } - return 0; -} - -#ifdef CONFIG_PM_SLEEP -static int -sirfsoc_uart_suspend(struct device *pdev) -{ - struct sirfsoc_uart_port *sirfport = dev_get_drvdata(pdev); - struct uart_port *port = &sirfport->port; - uart_suspend_port(&sirfsoc_uart_drv, port); - return 0; -} - -static int sirfsoc_uart_resume(struct device *pdev) -{ - struct sirfsoc_uart_port *sirfport = dev_get_drvdata(pdev); - struct uart_port *port = &sirfport->port; - uart_resume_port(&sirfsoc_uart_drv, port); - return 0; -} -#endif - -static const struct dev_pm_ops sirfsoc_uart_pm_ops = { - SET_SYSTEM_SLEEP_PM_OPS(sirfsoc_uart_suspend, sirfsoc_uart_resume) -}; - -static struct platform_driver sirfsoc_uart_driver = { - .probe = sirfsoc_uart_probe, - .remove = sirfsoc_uart_remove, - .driver = { - .name = SIRFUART_PORT_NAME, - .of_match_table = sirfsoc_uart_ids, - .pm = &sirfsoc_uart_pm_ops, - }, -}; - -static int __init sirfsoc_uart_init(void) -{ - int ret = 0; - - ret = uart_register_driver(&sirfsoc_uart_drv); - if (ret) - goto out; - - ret = platform_driver_register(&sirfsoc_uart_driver); - if (ret) - uart_unregister_driver(&sirfsoc_uart_drv); -out: - return ret; -} -module_init(sirfsoc_uart_init); - -static void __exit sirfsoc_uart_exit(void) -{ - platform_driver_unregister(&sirfsoc_uart_driver); - uart_unregister_driver(&sirfsoc_uart_drv); -} -module_exit(sirfsoc_uart_exit); - -MODULE_LICENSE("GPL v2"); -MODULE_AUTHOR("Bin Shi , Rong Wang"); -MODULE_DESCRIPTION("CSR SiRFprimaII Uart Driver"); diff --git a/drivers/tty/serial/sirfsoc_uart.h b/drivers/tty/serial/sirfsoc_uart.h deleted file mode 100644 index fb88ac565227..000000000000 --- a/drivers/tty/serial/sirfsoc_uart.h +++ /dev/null @@ -1,447 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0+ */ -/* - * Drivers for CSR SiRFprimaII onboard UARTs. - * - * Copyright (c) 2011 Cambridge Silicon Radio Limited, a CSR plc group company. - */ -#include -#include -#include -struct sirfsoc_uart_param { - const char *uart_name; - const char *port_name; -}; - -struct sirfsoc_register { - /* hardware uart specific */ - u32 sirfsoc_line_ctrl; - u32 sirfsoc_divisor; - /* uart - usp common */ - u32 sirfsoc_tx_rx_en; - u32 sirfsoc_int_en_reg; - u32 sirfsoc_int_st_reg; - u32 sirfsoc_int_en_clr_reg; - u32 sirfsoc_tx_dma_io_ctrl; - u32 sirfsoc_tx_dma_io_len; - u32 sirfsoc_tx_fifo_ctrl; - u32 sirfsoc_tx_fifo_level_chk; - u32 sirfsoc_tx_fifo_op; - u32 sirfsoc_tx_fifo_status; - u32 sirfsoc_tx_fifo_data; - u32 sirfsoc_rx_dma_io_ctrl; - u32 sirfsoc_rx_dma_io_len; - u32 sirfsoc_rx_fifo_ctrl; - u32 sirfsoc_rx_fifo_level_chk; - u32 sirfsoc_rx_fifo_op; - u32 sirfsoc_rx_fifo_status; - u32 sirfsoc_rx_fifo_data; - u32 sirfsoc_afc_ctrl; - u32 sirfsoc_swh_dma_io; - /* hardware usp specific */ - u32 sirfsoc_mode1; - u32 sirfsoc_mode2; - u32 sirfsoc_tx_frame_ctrl; - u32 sirfsoc_rx_frame_ctrl; - u32 sirfsoc_async_param_reg; -}; - -typedef u32 (*fifo_full_mask)(struct uart_port *port); -typedef u32 (*fifo_empty_mask)(struct uart_port *port); - -struct sirfsoc_fifo_status { - fifo_full_mask ff_full; - fifo_empty_mask ff_empty; -}; - -struct sirfsoc_int_en { - u32 sirfsoc_rx_done_en; - u32 sirfsoc_tx_done_en; - u32 sirfsoc_rx_oflow_en; - u32 sirfsoc_tx_allout_en; - u32 sirfsoc_rx_io_dma_en; - u32 sirfsoc_tx_io_dma_en; - u32 sirfsoc_rxfifo_full_en; - u32 sirfsoc_txfifo_empty_en; - u32 sirfsoc_rxfifo_thd_en; - u32 sirfsoc_txfifo_thd_en; - u32 sirfsoc_frm_err_en; - u32 sirfsoc_rxd_brk_en; - u32 sirfsoc_rx_timeout_en; - u32 sirfsoc_parity_err_en; - u32 sirfsoc_cts_en; - u32 sirfsoc_rts_en; -}; - -struct sirfsoc_int_status { - u32 sirfsoc_rx_done; - u32 sirfsoc_tx_done; - u32 sirfsoc_rx_oflow; - u32 sirfsoc_tx_allout; - u32 sirfsoc_rx_io_dma; - u32 sirfsoc_tx_io_dma; - u32 sirfsoc_rxfifo_full; - u32 sirfsoc_txfifo_empty; - u32 sirfsoc_rxfifo_thd; - u32 sirfsoc_txfifo_thd; - u32 sirfsoc_frm_err; - u32 sirfsoc_rxd_brk; - u32 sirfsoc_rx_timeout; - u32 sirfsoc_parity_err; - u32 sirfsoc_cts; - u32 sirfsoc_rts; -}; - -enum sirfsoc_uart_type { - SIRF_REAL_UART, - SIRF_USP_UART, -}; - -struct sirfsoc_uart_register { - struct sirfsoc_register uart_reg; - struct sirfsoc_int_en uart_int_en; - struct sirfsoc_int_status uart_int_st; - struct sirfsoc_fifo_status fifo_status; - struct sirfsoc_uart_param uart_param; - enum sirfsoc_uart_type uart_type; -}; - -static u32 uart_usp_ff_full_mask(struct uart_port *port) -{ - u32 full_bit; - - full_bit = ilog2(port->fifosize); - return (1 << full_bit); -} - -static u32 uart_usp_ff_empty_mask(struct uart_port *port) -{ - u32 empty_bit; - - empty_bit = ilog2(port->fifosize) + 1; - return (1 << empty_bit); -} - -static struct sirfsoc_uart_register sirfsoc_usp = { - .uart_reg = { - .sirfsoc_mode1 = 0x0000, - .sirfsoc_mode2 = 0x0004, - .sirfsoc_tx_frame_ctrl = 0x0008, - .sirfsoc_rx_frame_ctrl = 0x000c, - .sirfsoc_tx_rx_en = 0x0010, - .sirfsoc_int_en_reg = 0x0014, - .sirfsoc_int_st_reg = 0x0018, - .sirfsoc_async_param_reg = 0x0024, - .sirfsoc_tx_dma_io_ctrl = 0x0100, - .sirfsoc_tx_dma_io_len = 0x0104, - .sirfsoc_tx_fifo_ctrl = 0x0108, - .sirfsoc_tx_fifo_level_chk = 0x010c, - .sirfsoc_tx_fifo_op = 0x0110, - .sirfsoc_tx_fifo_status = 0x0114, - .sirfsoc_tx_fifo_data = 0x0118, - .sirfsoc_rx_dma_io_ctrl = 0x0120, - .sirfsoc_rx_dma_io_len = 0x0124, - .sirfsoc_rx_fifo_ctrl = 0x0128, - .sirfsoc_rx_fifo_level_chk = 0x012c, - .sirfsoc_rx_fifo_op = 0x0130, - .sirfsoc_rx_fifo_status = 0x0134, - .sirfsoc_rx_fifo_data = 0x0138, - .sirfsoc_int_en_clr_reg = 0x140, - }, - .uart_int_en = { - .sirfsoc_rx_done_en = BIT(0), - .sirfsoc_tx_done_en = BIT(1), - .sirfsoc_rx_oflow_en = BIT(2), - .sirfsoc_tx_allout_en = BIT(3), - .sirfsoc_rx_io_dma_en = BIT(4), - .sirfsoc_tx_io_dma_en = BIT(5), - .sirfsoc_rxfifo_full_en = BIT(6), - .sirfsoc_txfifo_empty_en = BIT(7), - .sirfsoc_rxfifo_thd_en = BIT(8), - .sirfsoc_txfifo_thd_en = BIT(9), - .sirfsoc_frm_err_en = BIT(10), - .sirfsoc_rx_timeout_en = BIT(11), - .sirfsoc_rxd_brk_en = BIT(15), - }, - .uart_int_st = { - .sirfsoc_rx_done = BIT(0), - .sirfsoc_tx_done = BIT(1), - .sirfsoc_rx_oflow = BIT(2), - .sirfsoc_tx_allout = BIT(3), - .sirfsoc_rx_io_dma = BIT(4), - .sirfsoc_tx_io_dma = BIT(5), - .sirfsoc_rxfifo_full = BIT(6), - .sirfsoc_txfifo_empty = BIT(7), - .sirfsoc_rxfifo_thd = BIT(8), - .sirfsoc_txfifo_thd = BIT(9), - .sirfsoc_frm_err = BIT(10), - .sirfsoc_rx_timeout = BIT(11), - .sirfsoc_rxd_brk = BIT(15), - }, - .fifo_status = { - .ff_full = uart_usp_ff_full_mask, - .ff_empty = uart_usp_ff_empty_mask, - }, - .uart_param = { - .uart_name = "ttySiRF", - .port_name = "sirfsoc-uart", - }, -}; - -static struct sirfsoc_uart_register sirfsoc_uart = { - .uart_reg = { - .sirfsoc_line_ctrl = 0x0040, - .sirfsoc_tx_rx_en = 0x004c, - .sirfsoc_divisor = 0x0050, - .sirfsoc_int_en_reg = 0x0054, - .sirfsoc_int_st_reg = 0x0058, - .sirfsoc_int_en_clr_reg = 0x0060, - .sirfsoc_tx_dma_io_ctrl = 0x0100, - .sirfsoc_tx_dma_io_len = 0x0104, - .sirfsoc_tx_fifo_ctrl = 0x0108, - .sirfsoc_tx_fifo_level_chk = 0x010c, - .sirfsoc_tx_fifo_op = 0x0110, - .sirfsoc_tx_fifo_status = 0x0114, - .sirfsoc_tx_fifo_data = 0x0118, - .sirfsoc_rx_dma_io_ctrl = 0x0120, - .sirfsoc_rx_dma_io_len = 0x0124, - .sirfsoc_rx_fifo_ctrl = 0x0128, - .sirfsoc_rx_fifo_level_chk = 0x012c, - .sirfsoc_rx_fifo_op = 0x0130, - .sirfsoc_rx_fifo_status = 0x0134, - .sirfsoc_rx_fifo_data = 0x0138, - .sirfsoc_afc_ctrl = 0x0140, - .sirfsoc_swh_dma_io = 0x0148, - }, - .uart_int_en = { - .sirfsoc_rx_done_en = BIT(0), - .sirfsoc_tx_done_en = BIT(1), - .sirfsoc_rx_oflow_en = BIT(2), - .sirfsoc_tx_allout_en = BIT(3), - .sirfsoc_rx_io_dma_en = BIT(4), - .sirfsoc_tx_io_dma_en = BIT(5), - .sirfsoc_rxfifo_full_en = BIT(6), - .sirfsoc_txfifo_empty_en = BIT(7), - .sirfsoc_rxfifo_thd_en = BIT(8), - .sirfsoc_txfifo_thd_en = BIT(9), - .sirfsoc_frm_err_en = BIT(10), - .sirfsoc_rxd_brk_en = BIT(11), - .sirfsoc_rx_timeout_en = BIT(12), - .sirfsoc_parity_err_en = BIT(13), - .sirfsoc_cts_en = BIT(14), - .sirfsoc_rts_en = BIT(15), - }, - .uart_int_st = { - .sirfsoc_rx_done = BIT(0), - .sirfsoc_tx_done = BIT(1), - .sirfsoc_rx_oflow = BIT(2), - .sirfsoc_tx_allout = BIT(3), - .sirfsoc_rx_io_dma = BIT(4), - .sirfsoc_tx_io_dma = BIT(5), - .sirfsoc_rxfifo_full = BIT(6), - .sirfsoc_txfifo_empty = BIT(7), - .sirfsoc_rxfifo_thd = BIT(8), - .sirfsoc_txfifo_thd = BIT(9), - .sirfsoc_frm_err = BIT(10), - .sirfsoc_rxd_brk = BIT(11), - .sirfsoc_rx_timeout = BIT(12), - .sirfsoc_parity_err = BIT(13), - .sirfsoc_cts = BIT(14), - .sirfsoc_rts = BIT(15), - }, - .fifo_status = { - .ff_full = uart_usp_ff_full_mask, - .ff_empty = uart_usp_ff_empty_mask, - }, - .uart_param = { - .uart_name = "ttySiRF", - .port_name = "sirfsoc_uart", - }, -}; -/* uart io ctrl */ -#define SIRFUART_DATA_BIT_LEN_MASK 0x3 -#define SIRFUART_DATA_BIT_LEN_5 BIT(0) -#define SIRFUART_DATA_BIT_LEN_6 1 -#define SIRFUART_DATA_BIT_LEN_7 2 -#define SIRFUART_DATA_BIT_LEN_8 3 -#define SIRFUART_STOP_BIT_LEN_1 0 -#define SIRFUART_STOP_BIT_LEN_2 BIT(2) -#define SIRFUART_PARITY_EN BIT(3) -#define SIRFUART_EVEN_BIT BIT(4) -#define SIRFUART_STICK_BIT_MASK (7 << 3) -#define SIRFUART_STICK_BIT_NONE (0 << 3) -#define SIRFUART_STICK_BIT_EVEN BIT(3) -#define SIRFUART_STICK_BIT_ODD (3 << 3) -#define SIRFUART_STICK_BIT_MARK (5 << 3) -#define SIRFUART_STICK_BIT_SPACE (7 << 3) -#define SIRFUART_SET_BREAK BIT(6) -#define SIRFUART_LOOP_BACK BIT(7) -#define SIRFUART_PARITY_MASK (7 << 3) -#define SIRFUART_DUMMY_READ BIT(16) -#define SIRFUART_AFC_CTRL_RX_THD 0x70 -#define SIRFUART_AFC_RX_EN BIT(8) -#define SIRFUART_AFC_TX_EN BIT(9) -#define SIRFUART_AFC_CTS_CTRL BIT(10) -#define SIRFUART_AFC_RTS_CTRL BIT(11) -#define SIRFUART_AFC_CTS_STATUS BIT(12) -#define SIRFUART_AFC_RTS_STATUS BIT(13) -/* UART FIFO Register */ -#define SIRFUART_FIFO_STOP 0x0 -#define SIRFUART_FIFO_RESET BIT(0) -#define SIRFUART_FIFO_START BIT(1) - -#define SIRFUART_RX_EN BIT(0) -#define SIRFUART_TX_EN BIT(1) - -#define SIRFUART_IO_MODE BIT(0) -#define SIRFUART_DMA_MODE 0x0 -#define SIRFUART_RX_DMA_FLUSH 0x4 - -#define SIRFUART_CLEAR_RX_ADDR_EN 0x2 -/* Baud Rate Calculation */ -#define SIRF_USP_MIN_SAMPLE_DIV 0x1 -#define SIRF_MIN_SAMPLE_DIV 0xf -#define SIRF_MAX_SAMPLE_DIV 0x3f -#define SIRF_IOCLK_DIV_MAX 0xffff -#define SIRF_SAMPLE_DIV_SHIFT 16 -#define SIRF_IOCLK_DIV_MASK 0xffff -#define SIRF_SAMPLE_DIV_MASK 0x3f0000 -#define SIRF_BAUD_RATE_SUPPORT_NR 18 - -/* USP SPEC */ -#define SIRFSOC_USP_ENDIAN_CTRL_LSBF BIT(4) -#define SIRFSOC_USP_EN BIT(5) -#define SIRFSOC_USP_MODE2_RXD_DELAY_OFFSET 0 -#define SIRFSOC_USP_MODE2_TXD_DELAY_OFFSET 8 -#define SIRFSOC_USP_MODE2_CLK_DIVISOR_MASK 0x3ff -#define SIRFSOC_USP_MODE2_CLK_DIVISOR_OFFSET 21 -#define SIRFSOC_USP_TX_DATA_LEN_OFFSET 0 -#define SIRFSOC_USP_TX_SYNC_LEN_OFFSET 8 -#define SIRFSOC_USP_TX_FRAME_LEN_OFFSET 16 -#define SIRFSOC_USP_TX_SHIFTER_LEN_OFFSET 24 -#define SIRFSOC_USP_TX_CLK_DIVISOR_OFFSET 30 -#define SIRFSOC_USP_RX_DATA_LEN_OFFSET 0 -#define SIRFSOC_USP_RX_FRAME_LEN_OFFSET 8 -#define SIRFSOC_USP_RX_SHIFTER_LEN_OFFSET 16 -#define SIRFSOC_USP_RX_CLK_DIVISOR_OFFSET 24 -#define SIRFSOC_USP_ASYNC_DIV2_MASK 0x3f -#define SIRFSOC_USP_ASYNC_DIV2_OFFSET 16 -#define SIRFSOC_USP_LOOP_BACK_CTRL BIT(2) -#define SIRFSOC_USP_FRADDR_CLR_EN BIT(1) -/* USP-UART Common */ -#define SIRFSOC_UART_RX_TIMEOUT(br, to) (((br) * (((to) + 999) / 1000)) / 1000) -#define SIRFUART_RECV_TIMEOUT_VALUE(x) \ - (((x) > 0xFFFF) ? 0xFFFF : ((x) & 0xFFFF)) -#define SIRFUART_USP_RECV_TIMEOUT(x) (x & 0xFFFF) -#define SIRFUART_UART_RECV_TIMEOUT(x) ((x & 0xFFFF) << 16) - -#define SIRFUART_FIFO_THD(port) (port->fifosize >> 1) -#define SIRFUART_ERR_INT_STAT(unit_st, uart_type) \ - (uint_st->sirfsoc_rx_oflow | \ - uint_st->sirfsoc_frm_err | \ - uint_st->sirfsoc_rxd_brk | \ - ((uart_type != SIRF_REAL_UART) ? \ - 0 : uint_st->sirfsoc_parity_err)) -#define SIRFUART_RX_IO_INT_EN(uint_en, uart_type) \ - (uint_en->sirfsoc_rx_done_en |\ - uint_en->sirfsoc_rxfifo_thd_en |\ - uint_en->sirfsoc_rxfifo_full_en |\ - uint_en->sirfsoc_frm_err_en |\ - uint_en->sirfsoc_rx_oflow_en |\ - uint_en->sirfsoc_rxd_brk_en |\ - ((uart_type != SIRF_REAL_UART) ? \ - 0 : uint_en->sirfsoc_parity_err_en)) -#define SIRFUART_RX_IO_INT_ST(uint_st) \ - (uint_st->sirfsoc_rxfifo_thd |\ - uint_st->sirfsoc_rxfifo_full|\ - uint_st->sirfsoc_rx_done |\ - uint_st->sirfsoc_rx_timeout) -#define SIRFUART_CTS_INT_ST(uint_st) (uint_st->sirfsoc_cts) -#define SIRFUART_RX_DMA_INT_EN(uint_en, uart_type) \ - (uint_en->sirfsoc_frm_err_en |\ - uint_en->sirfsoc_rx_oflow_en |\ - uint_en->sirfsoc_rxd_brk_en |\ - ((uart_type != SIRF_REAL_UART) ? \ - 0 : uint_en->sirfsoc_parity_err_en)) -/* Generic Definitions */ -#define SIRFSOC_UART_NAME "ttySiRF" -#define SIRFSOC_UART_MAJOR 0 -#define SIRFSOC_UART_MINOR 0 -#define SIRFUART_PORT_NAME "sirfsoc-uart" -#define SIRFUART_MAP_SIZE 0x200 -#define SIRFSOC_UART_NR 11 -#define SIRFSOC_PORT_TYPE 0xa5 - -/* Uart Common Use Macro*/ -#define SIRFSOC_RX_DMA_BUF_SIZE (1024 * 32) -#define BYTES_TO_ALIGN(dma_addr) ((unsigned long)(dma_addr) & 0x3) -/* Uart Fifo Level Chk */ -#define SIRFUART_TX_FIFO_SC_OFFSET 0 -#define SIRFUART_TX_FIFO_LC_OFFSET 10 -#define SIRFUART_TX_FIFO_HC_OFFSET 20 -#define SIRFUART_TX_FIFO_CHK_SC(line, value) ((((line) == 1) ? (value & 0x3) :\ - (value & 0x1f)) << SIRFUART_TX_FIFO_SC_OFFSET) -#define SIRFUART_TX_FIFO_CHK_LC(line, value) ((((line) == 1) ? (value & 0x3) :\ - (value & 0x1f)) << SIRFUART_TX_FIFO_LC_OFFSET) -#define SIRFUART_TX_FIFO_CHK_HC(line, value) ((((line) == 1) ? (value & 0x3) :\ - (value & 0x1f)) << SIRFUART_TX_FIFO_HC_OFFSET) - -#define SIRFUART_RX_FIFO_CHK_SC SIRFUART_TX_FIFO_CHK_SC -#define SIRFUART_RX_FIFO_CHK_LC SIRFUART_TX_FIFO_CHK_LC -#define SIRFUART_RX_FIFO_CHK_HC SIRFUART_TX_FIFO_CHK_HC -#define SIRFUART_RX_FIFO_MASK 0x7f -/* Indicate how many buffers used */ - -/* For Fast Baud Rate Calculation */ -struct sirfsoc_baudrate_to_regv { - unsigned int baud_rate; - unsigned int reg_val; -}; - -enum sirfsoc_tx_state { - TX_DMA_IDLE, - TX_DMA_RUNNING, - TX_DMA_PAUSE, -}; - -struct sirfsoc_rx_buffer { - struct circ_buf xmit; - dma_cookie_t cookie; - struct dma_async_tx_descriptor *desc; - dma_addr_t dma_addr; -}; - -struct sirfsoc_uart_port { - bool hw_flow_ctrl; - bool ms_enabled; - - struct uart_port port; - struct clk *clk; - /* for SiRFatlas7, there are SET/CLR for UART_INT_EN */ - bool is_atlas7; - struct sirfsoc_uart_register *uart_reg; - struct dma_chan *rx_dma_chan; - struct dma_chan *tx_dma_chan; - dma_addr_t tx_dma_addr; - struct dma_async_tx_descriptor *tx_dma_desc; - unsigned long transfer_size; - enum sirfsoc_tx_state tx_dma_state; - unsigned int cts_gpio; - unsigned int rts_gpio; - - struct sirfsoc_rx_buffer rx_dma_items; - struct hrtimer hrt; - bool is_hrt_enabled; - unsigned long rx_period_time; - unsigned long rx_last_pos; - unsigned long pio_fetch_cnt; -}; - -/* Register Access Control */ -#define portaddr(port, reg) ((port)->membase + (reg)) -#define rd_regl(port, reg) (__raw_readl(portaddr(port, reg))) -#define wr_regl(port, reg, val) __raw_writel(val, portaddr(port, reg)) - -/* UART Port Mask */ -#define SIRFUART_FIFOLEVEL_MASK(port) ((port->fifosize - 1) & 0xFFF) -#define SIRFUART_FIFOFULL_MASK(port) (port->fifosize & 0xFFF) -#define SIRFUART_FIFOEMPTY_MASK(port) ((port->fifosize & 0xFFF) << 1) -- cgit v1.2.3 From 6805822954f0fd24de4d6febc4c84afdcb6f9baa Mon Sep 17 00:00:00 2001 From: Aswath Govindraju Date: Tue, 5 Jan 2021 16:28:11 +0530 Subject: Documentation: devicetree: Add new compatible string for eeprom microchip 93LC46B Add a new compatible string for eeprom microchip 93LC46B in eeprom-93xx46 dt-binding file as it belongs to the 93xx46 family of devices. Reviewed-by: Rob Herring Signed-off-by: Aswath Govindraju Link: https://lore.kernel.org/r/20210105105817.17644-2-a-govindraju@ti.com Signed-off-by: Greg Kroah-Hartman --- Documentation/devicetree/bindings/misc/eeprom-93xx46.txt | 1 + 1 file changed, 1 insertion(+) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/misc/eeprom-93xx46.txt b/Documentation/devicetree/bindings/misc/eeprom-93xx46.txt index a8ebb4621f79..7b636b7a8311 100644 --- a/Documentation/devicetree/bindings/misc/eeprom-93xx46.txt +++ b/Documentation/devicetree/bindings/misc/eeprom-93xx46.txt @@ -4,6 +4,7 @@ Required properties: - compatible : shall be one of: "atmel,at93c46d" "eeprom-93xx46" + "microchip,93lc46b" - data-size : number of data bits per word (either 8 or 16) Optional properties: -- cgit v1.2.3 From 9bc20e8076c96a54c9fb20228d12ff35c88447d5 Mon Sep 17 00:00:00 2001 From: Tzung-Bi Shih Date: Wed, 20 Jan 2021 16:08:49 +0800 Subject: ASoC: dt-bindings: mt8192-mt6359: add hdmi-codec property Adds optional property "hdmi-codec". If specified, the machine driver should: - Exposes a device that can write audio data to the DP bridge. - Detects jack plug events. Signed-off-by: Tzung-Bi Shih Link: https://lore.kernel.org/r/20210120080850.699354-5-tzungbi@google.com Signed-off-by: Mark Brown --- .../devicetree/bindings/sound/mt8192-mt6359-rt1015-rt5682.yaml | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/sound/mt8192-mt6359-rt1015-rt5682.yaml b/Documentation/devicetree/bindings/sound/mt8192-mt6359-rt1015-rt5682.yaml index bf8c8ba25009..a781e7aaaa38 100644 --- a/Documentation/devicetree/bindings/sound/mt8192-mt6359-rt1015-rt5682.yaml +++ b/Documentation/devicetree/bindings/sound/mt8192-mt6359-rt1015-rt5682.yaml @@ -23,6 +23,10 @@ properties: $ref: "/schemas/types.yaml#/definitions/phandle" description: The phandle of MT8192 ASoC platform. + mediatek,hdmi-codec: + $ref: "/schemas/types.yaml#/definitions/phandle" + description: The phandle of HDMI codec. + additionalProperties: false required: @@ -35,6 +39,7 @@ examples: sound: mt8192-sound { compatible = "mediatek,mt8192_mt6359_rt1015_rt5682"; mediatek,platform = <&afe>; + mediatek,hdmi-codec = <&anx_bridge_dp>; pinctrl-names = "aud_clk_mosi_off", "aud_clk_mosi_on"; pinctrl-0 = <&aud_clk_mosi_off>; -- cgit v1.2.3 From 5581304004659ddc8d0d45561c1f2abfe080b4d4 Mon Sep 17 00:00:00 2001 From: AngeloGioacchino Del Regno Date: Tue, 19 Jan 2021 18:44:18 +0100 Subject: regulator: qcom-labibb: Document soft start properties Document properties to configure soft start and discharge resistor for LAB and IBB respectively. Signed-off-by: AngeloGioacchino Del Regno Reviewed-by: Bjorn Andersson Link: https://lore.kernel.org/r/20210119174421.226541-5-angelogioacchino.delregno@somainline.org Signed-off-by: Mark Brown --- .../devicetree/bindings/regulator/qcom-labibb-regulator.yaml | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/regulator/qcom-labibb-regulator.yaml b/Documentation/devicetree/bindings/regulator/qcom-labibb-regulator.yaml index 53853ec20fe2..7a507692f1ba 100644 --- a/Documentation/devicetree/bindings/regulator/qcom-labibb-regulator.yaml +++ b/Documentation/devicetree/bindings/regulator/qcom-labibb-regulator.yaml @@ -22,6 +22,11 @@ properties: type: object properties: + qcom,soft-start-us: + $ref: /schemas/types.yaml#/definitions/uint32 + description: Regulator soft start time in microseconds. + enum: [200, 400, 600, 800] + default: 200 interrupts: maxItems: 1 @@ -35,6 +40,11 @@ properties: type: object properties: + qcom,discharge-resistor-kohms: + $ref: /schemas/types.yaml#/definitions/uint32 + description: Discharge resistor value in KiloOhms. + enum: [300, 64, 32, 16] + default: 300 interrupts: maxItems: 1 -- cgit v1.2.3 From 9499200484669fe33c20c735a3d5a29a0dc0e9d4 Mon Sep 17 00:00:00 2001 From: AngeloGioacchino Del Regno Date: Tue, 19 Jan 2021 18:44:20 +0100 Subject: regulator: qcom-labibb: Document SCP/OCP interrupts Short-Circuit Protection (SCP) and Over-Current Protection (OCP) are now implemented in the driver: document the interrupts. This also fixes wrong documentation about the SCP interrupt for LAB. Signed-off-by: AngeloGioacchino Del Regno Reviewed-by: Bjorn Andersson Link: https://lore.kernel.org/r/20210119174421.226541-7-angelogioacchino.delregno@somainline.org Signed-off-by: Mark Brown --- .../bindings/regulator/qcom-labibb-regulator.yaml | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/regulator/qcom-labibb-regulator.yaml b/Documentation/devicetree/bindings/regulator/qcom-labibb-regulator.yaml index 7a507692f1ba..cf784bd1f5e5 100644 --- a/Documentation/devicetree/bindings/regulator/qcom-labibb-regulator.yaml +++ b/Documentation/devicetree/bindings/regulator/qcom-labibb-regulator.yaml @@ -29,9 +29,10 @@ properties: default: 200 interrupts: - maxItems: 1 + minItems: 1 + maxItems: 2 description: - Short-circuit interrupt for lab. + Short-circuit and over-current interrupts for lab. required: - interrupts @@ -47,9 +48,10 @@ properties: default: 300 interrupts: - maxItems: 1 + minItems: 1 + maxItems: 2 description: - Short-circuit interrupt for lab. + Short-circuit and over-current interrupts for ibb. required: - interrupts @@ -67,13 +69,15 @@ examples: compatible = "qcom,pmi8998-lab-ibb"; lab { - interrupts = <0x3 0x0 IRQ_TYPE_EDGE_RISING>; - interrupt-names = "sc-err"; + interrupts = <0x3 0xde 0x1 IRQ_TYPE_EDGE_RISING>, + <0x3 0xde 0x0 IRQ_TYPE_LEVEL_LOW>; + interrupt-names = "sc-err", "ocp"; }; ibb { - interrupts = <0x3 0x2 IRQ_TYPE_EDGE_RISING>; - interrupt-names = "sc-err"; + interrupts = <0x3 0xdc 0x2 IRQ_TYPE_EDGE_RISING>, + <0x3 0xdc 0x0 IRQ_TYPE_LEVEL_LOW>; + interrupt-names = "sc-err", "ocp"; }; }; -- cgit v1.2.3 From 61fbeb5dcb3debb88d9f2eeed7e599b1ed7e3344 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Wed, 20 Jan 2021 17:25:52 +0100 Subject: ASoC: remove sirf prima/atlas drivers The CSR SiRF prima2/atlas platforms are getting removed, so this driver is no longer needed. Signed-off-by: Arnd Bergmann Acked-by: Barry Song Link: https://lore.kernel.org/r/20210120162553.21666-2-arnd@kernel.org Signed-off-by: Mark Brown --- .../devicetree/bindings/sound/sirf-audio-codec.txt | 17 - .../devicetree/bindings/sound/sirf-usp.txt | 27 - sound/soc/Kconfig | 1 - sound/soc/Makefile | 1 - sound/soc/codecs/Makefile | 2 - sound/soc/codecs/sirf-audio-codec.c | 575 --------------------- sound/soc/sirf/Kconfig | 21 - sound/soc/sirf/Makefile | 8 - sound/soc/sirf/sirf-audio-port.c | 86 --- sound/soc/sirf/sirf-audio.c | 160 ------ sound/soc/sirf/sirf-usp.c | 435 ---------------- sound/soc/sirf/sirf-usp.h | 292 ----------- 12 files changed, 1625 deletions(-) delete mode 100644 Documentation/devicetree/bindings/sound/sirf-audio-codec.txt delete mode 100644 Documentation/devicetree/bindings/sound/sirf-usp.txt delete mode 100644 sound/soc/codecs/sirf-audio-codec.c delete mode 100644 sound/soc/sirf/Kconfig delete mode 100644 sound/soc/sirf/Makefile delete mode 100644 sound/soc/sirf/sirf-audio-port.c delete mode 100644 sound/soc/sirf/sirf-audio.c delete mode 100644 sound/soc/sirf/sirf-usp.c delete mode 100644 sound/soc/sirf/sirf-usp.h (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/sound/sirf-audio-codec.txt b/Documentation/devicetree/bindings/sound/sirf-audio-codec.txt deleted file mode 100644 index 062f5ec36f9b..000000000000 --- a/Documentation/devicetree/bindings/sound/sirf-audio-codec.txt +++ /dev/null @@ -1,17 +0,0 @@ -SiRF internal audio CODEC - -Required properties: - - - compatible : "sirf,atlas6-audio-codec" or "sirf,prima2-audio-codec" - - - reg : the register address of the device. - - - clocks: the clock of SiRF internal audio codec - -Example: - -audiocodec: audiocodec@b0040000 { - compatible = "sirf,atlas6-audio-codec"; - reg = <0xb0040000 0x10000>; - clocks = <&clks 27>; -}; diff --git a/Documentation/devicetree/bindings/sound/sirf-usp.txt b/Documentation/devicetree/bindings/sound/sirf-usp.txt deleted file mode 100644 index 02f85b32d359..000000000000 --- a/Documentation/devicetree/bindings/sound/sirf-usp.txt +++ /dev/null @@ -1,27 +0,0 @@ -* SiRF SoC USP module - -Required properties: -- compatible: "sirf,prima2-usp-pcm" -- reg: Base address and size entries: -- dmas: List of DMA controller phandle and DMA request line ordered pairs. -- dma-names: Identifier string for each DMA request line in the dmas property. - These strings correspond 1:1 with the ordered pairs in dmas. - - One of the DMA channels will be responsible for transmission (should be - named "tx") and one for reception (should be named "rx"). - -- clocks: USP controller clock source -- pinctrl-names: Must contain a "default" entry. -- pinctrl-NNN: One property must exist for each entry in pinctrl-names. - -Example: -usp0: usp@b0080000 { - compatible = "sirf,prima2-usp-pcm"; - reg = <0xb0080000 0x10000>; - clocks = <&clks 28>; - dmas = <&dmac1 1>, <&dmac1 2>; - dma-names = "rx", "tx"; - pinctrl-names = "default"; - pinctrl-0 = <&usp0_only_utfs_pins_a>; -}; - diff --git a/sound/soc/Kconfig b/sound/soc/Kconfig index 47da9ce17693..547b26ca714f 100644 --- a/sound/soc/Kconfig +++ b/sound/soc/Kconfig @@ -62,7 +62,6 @@ source "sound/soc/qcom/Kconfig" source "sound/soc/rockchip/Kconfig" source "sound/soc/samsung/Kconfig" source "sound/soc/sh/Kconfig" -source "sound/soc/sirf/Kconfig" source "sound/soc/sof/Kconfig" source "sound/soc/spear/Kconfig" source "sound/soc/sprd/Kconfig" diff --git a/sound/soc/Makefile b/sound/soc/Makefile index 508dbaa1814e..74508b0f9c47 100644 --- a/sound/soc/Makefile +++ b/sound/soc/Makefile @@ -45,7 +45,6 @@ obj-$(CONFIG_SND_SOC) += qcom/ obj-$(CONFIG_SND_SOC) += rockchip/ obj-$(CONFIG_SND_SOC) += samsung/ obj-$(CONFIG_SND_SOC) += sh/ -obj-$(CONFIG_SND_SOC) += sirf/ obj-$(CONFIG_SND_SOC) += sof/ obj-$(CONFIG_SND_SOC) += spear/ obj-$(CONFIG_SND_SOC) += sprd/ diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile index d277f0366e09..c30762fc9b87 100644 --- a/sound/soc/codecs/Makefile +++ b/sound/soc/codecs/Makefile @@ -201,7 +201,6 @@ snd-soc-sigmadsp-objs := sigmadsp.o snd-soc-sigmadsp-i2c-objs := sigmadsp-i2c.o snd-soc-sigmadsp-regmap-objs := sigmadsp-regmap.o snd-soc-si476x-objs := si476x.o -snd-soc-sirf-audio-codec-objs := sirf-audio-codec.o snd-soc-spdif-tx-objs := spdif_transmitter.o snd-soc-spdif-rx-objs := spdif_receiver.o snd-soc-ssm2305-objs := ssm2305.o @@ -516,7 +515,6 @@ obj-$(CONFIG_SND_SOC_SIGMADSP_I2C) += snd-soc-sigmadsp-i2c.o obj-$(CONFIG_SND_SOC_SIGMADSP_REGMAP) += snd-soc-sigmadsp-regmap.o obj-$(CONFIG_SND_SOC_SI476X) += snd-soc-si476x.o obj-$(CONFIG_SND_SOC_SPDIF) += snd-soc-spdif-rx.o snd-soc-spdif-tx.o -obj-$(CONFIG_SND_SOC_SIRF_AUDIO_CODEC) += sirf-audio-codec.o obj-$(CONFIG_SND_SOC_SSM2305) += snd-soc-ssm2305.o obj-$(CONFIG_SND_SOC_SSM2518) += snd-soc-ssm2518.o obj-$(CONFIG_SND_SOC_SSM2602) += snd-soc-ssm2602.o diff --git a/sound/soc/codecs/sirf-audio-codec.c b/sound/soc/codecs/sirf-audio-codec.c deleted file mode 100644 index a061d78473ac..000000000000 --- a/sound/soc/codecs/sirf-audio-codec.c +++ /dev/null @@ -1,575 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * SiRF audio codec driver - * - * Copyright (c) 2011 Cambridge Silicon Radio Limited, a CSR plc group company. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "sirf-audio-codec.h" - -struct sirf_audio_codec { - struct clk *clk; - struct regmap *regmap; - u32 reg_ctrl0, reg_ctrl1; -}; - -static const char * const input_mode_mux[] = {"Single-ended", - "Differential"}; - -static const struct soc_enum input_mode_mux_enum = - SOC_ENUM_SINGLE(AUDIO_IC_CODEC_CTRL1, 4, 2, input_mode_mux); - -static const struct snd_kcontrol_new sirf_audio_codec_input_mode_control = - SOC_DAPM_ENUM("Route", input_mode_mux_enum); - -static const DECLARE_TLV_DB_SCALE(playback_vol_tlv, -12400, 100, 0); -static const DECLARE_TLV_DB_SCALE(capture_vol_tlv_prima2, 500, 100, 0); -static const DECLARE_TLV_DB_RANGE(capture_vol_tlv_atlas6, - 0, 7, TLV_DB_SCALE_ITEM(-100, 100, 0), - 0x22, 0x3F, TLV_DB_SCALE_ITEM(700, 100, 0), -); - -static struct snd_kcontrol_new volume_controls_atlas6[] = { - SOC_DOUBLE_TLV("Playback Volume", AUDIO_IC_CODEC_CTRL0, 21, 14, - 0x7F, 0, playback_vol_tlv), - SOC_DOUBLE_TLV("Capture Volume", AUDIO_IC_CODEC_CTRL1, 16, 10, - 0x3F, 0, capture_vol_tlv_atlas6), -}; - -static struct snd_kcontrol_new volume_controls_prima2[] = { - SOC_DOUBLE_TLV("Speaker Volume", AUDIO_IC_CODEC_CTRL0, 21, 14, - 0x7F, 0, playback_vol_tlv), - SOC_DOUBLE_TLV("Capture Volume", AUDIO_IC_CODEC_CTRL1, 15, 10, - 0x1F, 0, capture_vol_tlv_prima2), -}; - -static struct snd_kcontrol_new left_input_path_controls[] = { - SOC_DAPM_SINGLE("Line Left Switch", AUDIO_IC_CODEC_CTRL1, 6, 1, 0), - SOC_DAPM_SINGLE("Mic Left Switch", AUDIO_IC_CODEC_CTRL1, 3, 1, 0), -}; - -static struct snd_kcontrol_new right_input_path_controls[] = { - SOC_DAPM_SINGLE("Line Right Switch", AUDIO_IC_CODEC_CTRL1, 5, 1, 0), - SOC_DAPM_SINGLE("Mic Right Switch", AUDIO_IC_CODEC_CTRL1, 2, 1, 0), -}; - -static struct snd_kcontrol_new left_dac_to_hp_left_amp_switch_control = - SOC_DAPM_SINGLE("Switch", AUDIO_IC_CODEC_CTRL0, 9, 1, 0); - -static struct snd_kcontrol_new left_dac_to_hp_right_amp_switch_control = - SOC_DAPM_SINGLE("Switch", AUDIO_IC_CODEC_CTRL0, 8, 1, 0); - -static struct snd_kcontrol_new right_dac_to_hp_left_amp_switch_control = - SOC_DAPM_SINGLE("Switch", AUDIO_IC_CODEC_CTRL0, 7, 1, 0); - -static struct snd_kcontrol_new right_dac_to_hp_right_amp_switch_control = - SOC_DAPM_SINGLE("Switch", AUDIO_IC_CODEC_CTRL0, 6, 1, 0); - -static struct snd_kcontrol_new left_dac_to_speaker_lineout_switch_control = - SOC_DAPM_SINGLE("Switch", AUDIO_IC_CODEC_CTRL0, 11, 1, 0); - -static struct snd_kcontrol_new right_dac_to_speaker_lineout_switch_control = - SOC_DAPM_SINGLE("Switch", AUDIO_IC_CODEC_CTRL0, 10, 1, 0); - -/* After enable adc, Delay 200ms to avoid pop noise */ -static int adc_enable_delay_event(struct snd_soc_dapm_widget *w, - struct snd_kcontrol *kcontrol, int event) -{ - switch (event) { - case SND_SOC_DAPM_POST_PMU: - msleep(200); - break; - default: - break; - } - - return 0; -} - -static void enable_and_reset_codec(struct regmap *regmap, - u32 codec_enable_bits, u32 codec_reset_bits) -{ - regmap_update_bits(regmap, AUDIO_IC_CODEC_CTRL1, - codec_enable_bits | codec_reset_bits, - codec_enable_bits); - msleep(20); - regmap_update_bits(regmap, AUDIO_IC_CODEC_CTRL1, - codec_reset_bits, codec_reset_bits); -} - -static int atlas6_codec_enable_and_reset_event(struct snd_soc_dapm_widget *w, - struct snd_kcontrol *kcontrol, int event) -{ -#define ATLAS6_CODEC_ENABLE_BITS (1 << 29) -#define ATLAS6_CODEC_RESET_BITS (1 << 28) - struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); - struct sirf_audio_codec *sirf_audio_codec = snd_soc_component_get_drvdata(component); - switch (event) { - case SND_SOC_DAPM_PRE_PMU: - enable_and_reset_codec(sirf_audio_codec->regmap, - ATLAS6_CODEC_ENABLE_BITS, ATLAS6_CODEC_RESET_BITS); - break; - case SND_SOC_DAPM_POST_PMD: - regmap_update_bits(sirf_audio_codec->regmap, - AUDIO_IC_CODEC_CTRL1, ATLAS6_CODEC_ENABLE_BITS, 0); - break; - default: - break; - } - - return 0; -} - -static int prima2_codec_enable_and_reset_event(struct snd_soc_dapm_widget *w, - struct snd_kcontrol *kcontrol, int event) -{ -#define PRIMA2_CODEC_ENABLE_BITS (1 << 27) -#define PRIMA2_CODEC_RESET_BITS (1 << 26) - struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); - struct sirf_audio_codec *sirf_audio_codec = snd_soc_component_get_drvdata(component); - switch (event) { - case SND_SOC_DAPM_POST_PMU: - enable_and_reset_codec(sirf_audio_codec->regmap, - PRIMA2_CODEC_ENABLE_BITS, PRIMA2_CODEC_RESET_BITS); - break; - case SND_SOC_DAPM_POST_PMD: - regmap_update_bits(sirf_audio_codec->regmap, - AUDIO_IC_CODEC_CTRL1, PRIMA2_CODEC_ENABLE_BITS, 0); - break; - default: - break; - } - - return 0; -} - -static const struct snd_soc_dapm_widget atlas6_output_driver_dapm_widgets[] = { - SND_SOC_DAPM_OUT_DRV("HP Left Driver", AUDIO_IC_CODEC_CTRL1, - 25, 0, NULL, 0), - SND_SOC_DAPM_OUT_DRV("HP Right Driver", AUDIO_IC_CODEC_CTRL1, - 26, 0, NULL, 0), - SND_SOC_DAPM_OUT_DRV("Speaker Driver", AUDIO_IC_CODEC_CTRL1, - 27, 0, NULL, 0), -}; - -static const struct snd_soc_dapm_widget prima2_output_driver_dapm_widgets[] = { - SND_SOC_DAPM_OUT_DRV("HP Left Driver", AUDIO_IC_CODEC_CTRL1, - 23, 0, NULL, 0), - SND_SOC_DAPM_OUT_DRV("HP Right Driver", AUDIO_IC_CODEC_CTRL1, - 24, 0, NULL, 0), - SND_SOC_DAPM_OUT_DRV("Speaker Driver", AUDIO_IC_CODEC_CTRL1, - 25, 0, NULL, 0), -}; - -static const struct snd_soc_dapm_widget atlas6_codec_clock_dapm_widget = - SND_SOC_DAPM_SUPPLY("codecclk", SND_SOC_NOPM, 0, 0, - atlas6_codec_enable_and_reset_event, - SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD); - -static const struct snd_soc_dapm_widget prima2_codec_clock_dapm_widget = - SND_SOC_DAPM_SUPPLY("codecclk", SND_SOC_NOPM, 0, 0, - prima2_codec_enable_and_reset_event, - SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD); - -static const struct snd_soc_dapm_widget sirf_audio_codec_dapm_widgets[] = { - SND_SOC_DAPM_DAC("DAC left", NULL, AUDIO_IC_CODEC_CTRL0, 1, 0), - SND_SOC_DAPM_DAC("DAC right", NULL, AUDIO_IC_CODEC_CTRL0, 0, 0), - SND_SOC_DAPM_SWITCH("Left dac to hp left amp", SND_SOC_NOPM, 0, 0, - &left_dac_to_hp_left_amp_switch_control), - SND_SOC_DAPM_SWITCH("Left dac to hp right amp", SND_SOC_NOPM, 0, 0, - &left_dac_to_hp_right_amp_switch_control), - SND_SOC_DAPM_SWITCH("Right dac to hp left amp", SND_SOC_NOPM, 0, 0, - &right_dac_to_hp_left_amp_switch_control), - SND_SOC_DAPM_SWITCH("Right dac to hp right amp", SND_SOC_NOPM, 0, 0, - &right_dac_to_hp_right_amp_switch_control), - SND_SOC_DAPM_OUT_DRV("HP amp left driver", AUDIO_IC_CODEC_CTRL0, 3, 0, - NULL, 0), - SND_SOC_DAPM_OUT_DRV("HP amp right driver", AUDIO_IC_CODEC_CTRL0, 3, 0, - NULL, 0), - - SND_SOC_DAPM_SWITCH("Left dac to speaker lineout", SND_SOC_NOPM, 0, 0, - &left_dac_to_speaker_lineout_switch_control), - SND_SOC_DAPM_SWITCH("Right dac to speaker lineout", SND_SOC_NOPM, 0, 0, - &right_dac_to_speaker_lineout_switch_control), - SND_SOC_DAPM_OUT_DRV("Speaker amp driver", AUDIO_IC_CODEC_CTRL0, 4, 0, - NULL, 0), - - SND_SOC_DAPM_OUTPUT("HPOUTL"), - SND_SOC_DAPM_OUTPUT("HPOUTR"), - SND_SOC_DAPM_OUTPUT("SPKOUT"), - - SND_SOC_DAPM_ADC_E("ADC left", NULL, AUDIO_IC_CODEC_CTRL1, 8, 0, - adc_enable_delay_event, SND_SOC_DAPM_POST_PMU), - SND_SOC_DAPM_ADC_E("ADC right", NULL, AUDIO_IC_CODEC_CTRL1, 7, 0, - adc_enable_delay_event, SND_SOC_DAPM_POST_PMU), - SND_SOC_DAPM_MIXER("Left PGA mixer", AUDIO_IC_CODEC_CTRL1, 1, 0, - &left_input_path_controls[0], - ARRAY_SIZE(left_input_path_controls)), - SND_SOC_DAPM_MIXER("Right PGA mixer", AUDIO_IC_CODEC_CTRL1, 0, 0, - &right_input_path_controls[0], - ARRAY_SIZE(right_input_path_controls)), - - SND_SOC_DAPM_MUX("Mic input mode mux", SND_SOC_NOPM, 0, 0, - &sirf_audio_codec_input_mode_control), - SND_SOC_DAPM_MICBIAS("Mic Bias", AUDIO_IC_CODEC_PWR, 3, 0), - SND_SOC_DAPM_INPUT("MICIN1"), - SND_SOC_DAPM_INPUT("MICIN2"), - SND_SOC_DAPM_INPUT("LINEIN1"), - SND_SOC_DAPM_INPUT("LINEIN2"), - - SND_SOC_DAPM_SUPPLY("HSL Phase Opposite", AUDIO_IC_CODEC_CTRL0, - 30, 0, NULL, 0), -}; - -static const struct snd_soc_dapm_route sirf_audio_codec_map[] = { - {"SPKOUT", NULL, "Speaker Driver"}, - {"Speaker Driver", NULL, "Speaker amp driver"}, - {"Speaker amp driver", NULL, "Left dac to speaker lineout"}, - {"Speaker amp driver", NULL, "Right dac to speaker lineout"}, - {"Left dac to speaker lineout", "Switch", "DAC left"}, - {"Right dac to speaker lineout", "Switch", "DAC right"}, - {"HPOUTL", NULL, "HP Left Driver"}, - {"HPOUTR", NULL, "HP Right Driver"}, - {"HP Left Driver", NULL, "HP amp left driver"}, - {"HP Right Driver", NULL, "HP amp right driver"}, - {"HP amp left driver", NULL, "Right dac to hp left amp"}, - {"HP amp right driver", NULL , "Right dac to hp right amp"}, - {"HP amp left driver", NULL, "Left dac to hp left amp"}, - {"HP amp right driver", NULL , "Right dac to hp right amp"}, - {"Right dac to hp left amp", "Switch", "DAC left"}, - {"Right dac to hp right amp", "Switch", "DAC right"}, - {"Left dac to hp left amp", "Switch", "DAC left"}, - {"Left dac to hp right amp", "Switch", "DAC right"}, - {"DAC left", NULL, "codecclk"}, - {"DAC right", NULL, "codecclk"}, - {"DAC left", NULL, "Playback"}, - {"DAC right", NULL, "Playback"}, - {"DAC left", NULL, "HSL Phase Opposite"}, - {"DAC right", NULL, "HSL Phase Opposite"}, - - {"Capture", NULL, "ADC left"}, - {"Capture", NULL, "ADC right"}, - {"ADC left", NULL, "codecclk"}, - {"ADC right", NULL, "codecclk"}, - {"ADC left", NULL, "Left PGA mixer"}, - {"ADC right", NULL, "Right PGA mixer"}, - {"Left PGA mixer", "Line Left Switch", "LINEIN2"}, - {"Right PGA mixer", "Line Right Switch", "LINEIN1"}, - {"Left PGA mixer", "Mic Left Switch", "MICIN2"}, - {"Right PGA mixer", "Mic Right Switch", "Mic input mode mux"}, - {"Mic input mode mux", "Single-ended", "MICIN1"}, - {"Mic input mode mux", "Differential", "MICIN1"}, -}; - -static void sirf_audio_codec_tx_enable(struct sirf_audio_codec *sirf_audio_codec) -{ - regmap_update_bits(sirf_audio_codec->regmap, AUDIO_PORT_IC_TXFIFO_OP, - AUDIO_FIFO_RESET, AUDIO_FIFO_RESET); - regmap_update_bits(sirf_audio_codec->regmap, AUDIO_PORT_IC_TXFIFO_OP, - AUDIO_FIFO_RESET, ~AUDIO_FIFO_RESET); - regmap_write(sirf_audio_codec->regmap, AUDIO_PORT_IC_TXFIFO_INT_MSK, 0); - regmap_write(sirf_audio_codec->regmap, AUDIO_PORT_IC_TXFIFO_OP, 0); - regmap_update_bits(sirf_audio_codec->regmap, AUDIO_PORT_IC_TXFIFO_OP, - AUDIO_FIFO_START, AUDIO_FIFO_START); - regmap_update_bits(sirf_audio_codec->regmap, - AUDIO_PORT_IC_CODEC_TX_CTRL, IC_TX_ENABLE, IC_TX_ENABLE); -} - -static void sirf_audio_codec_tx_disable(struct sirf_audio_codec *sirf_audio_codec) -{ - regmap_write(sirf_audio_codec->regmap, AUDIO_PORT_IC_TXFIFO_OP, 0); - regmap_update_bits(sirf_audio_codec->regmap, - AUDIO_PORT_IC_CODEC_TX_CTRL, IC_TX_ENABLE, ~IC_TX_ENABLE); -} - -static void sirf_audio_codec_rx_enable(struct sirf_audio_codec *sirf_audio_codec, - int channels) -{ - regmap_update_bits(sirf_audio_codec->regmap, AUDIO_PORT_IC_RXFIFO_OP, - AUDIO_FIFO_RESET, AUDIO_FIFO_RESET); - regmap_update_bits(sirf_audio_codec->regmap, AUDIO_PORT_IC_RXFIFO_OP, - AUDIO_FIFO_RESET, ~AUDIO_FIFO_RESET); - regmap_write(sirf_audio_codec->regmap, - AUDIO_PORT_IC_RXFIFO_INT_MSK, 0); - regmap_write(sirf_audio_codec->regmap, AUDIO_PORT_IC_RXFIFO_OP, 0); - regmap_update_bits(sirf_audio_codec->regmap, AUDIO_PORT_IC_RXFIFO_OP, - AUDIO_FIFO_START, AUDIO_FIFO_START); - if (channels == 1) - regmap_update_bits(sirf_audio_codec->regmap, - AUDIO_PORT_IC_CODEC_RX_CTRL, - IC_RX_ENABLE_MONO, IC_RX_ENABLE_MONO); - else - regmap_update_bits(sirf_audio_codec->regmap, - AUDIO_PORT_IC_CODEC_RX_CTRL, - IC_RX_ENABLE_STEREO, IC_RX_ENABLE_STEREO); -} - -static void sirf_audio_codec_rx_disable(struct sirf_audio_codec *sirf_audio_codec) -{ - regmap_update_bits(sirf_audio_codec->regmap, - AUDIO_PORT_IC_CODEC_RX_CTRL, - IC_RX_ENABLE_STEREO, ~IC_RX_ENABLE_STEREO); -} - -static int sirf_audio_codec_trigger(struct snd_pcm_substream *substream, - int cmd, - struct snd_soc_dai *dai) -{ - struct snd_soc_component *component = dai->component; - struct sirf_audio_codec *sirf_audio_codec = snd_soc_component_get_drvdata(component); - int playback = substream->stream == SNDRV_PCM_STREAM_PLAYBACK; - - /* - * This is a workaround, When stop playback, - * need disable HP amp, avoid the current noise. - */ - switch (cmd) { - case SNDRV_PCM_TRIGGER_STOP: - case SNDRV_PCM_TRIGGER_SUSPEND: - case SNDRV_PCM_TRIGGER_PAUSE_PUSH: - if (playback) { - snd_soc_component_update_bits(component, AUDIO_IC_CODEC_CTRL0, - IC_HSLEN | IC_HSREN, 0); - sirf_audio_codec_tx_disable(sirf_audio_codec); - } else - sirf_audio_codec_rx_disable(sirf_audio_codec); - break; - case SNDRV_PCM_TRIGGER_START: - case SNDRV_PCM_TRIGGER_RESUME: - case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: - if (playback) { - sirf_audio_codec_tx_enable(sirf_audio_codec); - snd_soc_component_update_bits(component, AUDIO_IC_CODEC_CTRL0, - IC_HSLEN | IC_HSREN, IC_HSLEN | IC_HSREN); - } else - sirf_audio_codec_rx_enable(sirf_audio_codec, - substream->runtime->channels); - break; - default: - return -EINVAL; - } - - return 0; -} - -static const struct snd_soc_dai_ops sirf_audio_codec_dai_ops = { - .trigger = sirf_audio_codec_trigger, -}; - -static struct snd_soc_dai_driver sirf_audio_codec_dai = { - .name = "sirf-audio-codec", - .playback = { - .stream_name = "Playback", - .channels_min = 2, - .channels_max = 2, - .rates = SNDRV_PCM_RATE_48000, - .formats = SNDRV_PCM_FMTBIT_S16_LE, - }, - .capture = { - .stream_name = "Capture", - .channels_min = 1, - .channels_max = 2, - .rates = SNDRV_PCM_RATE_48000, - .formats = SNDRV_PCM_FMTBIT_S16_LE, - }, - .ops = &sirf_audio_codec_dai_ops, -}; - -static int sirf_audio_codec_probe(struct snd_soc_component *component) -{ - struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component); - - pm_runtime_enable(component->dev); - - if (of_device_is_compatible(component->dev->of_node, "sirf,prima2-audio-codec")) { - snd_soc_dapm_new_controls(dapm, - prima2_output_driver_dapm_widgets, - ARRAY_SIZE(prima2_output_driver_dapm_widgets)); - snd_soc_dapm_new_controls(dapm, - &prima2_codec_clock_dapm_widget, 1); - return snd_soc_add_component_controls(component, - volume_controls_prima2, - ARRAY_SIZE(volume_controls_prima2)); - } - if (of_device_is_compatible(component->dev->of_node, "sirf,atlas6-audio-codec")) { - snd_soc_dapm_new_controls(dapm, - atlas6_output_driver_dapm_widgets, - ARRAY_SIZE(atlas6_output_driver_dapm_widgets)); - snd_soc_dapm_new_controls(dapm, - &atlas6_codec_clock_dapm_widget, 1); - return snd_soc_add_component_controls(component, - volume_controls_atlas6, - ARRAY_SIZE(volume_controls_atlas6)); - } - - return -EINVAL; -} - -static void sirf_audio_codec_remove(struct snd_soc_component *component) -{ - pm_runtime_disable(component->dev); -} - -static const struct snd_soc_component_driver soc_codec_device_sirf_audio_codec = { - .probe = sirf_audio_codec_probe, - .remove = sirf_audio_codec_remove, - .dapm_widgets = sirf_audio_codec_dapm_widgets, - .num_dapm_widgets = ARRAY_SIZE(sirf_audio_codec_dapm_widgets), - .dapm_routes = sirf_audio_codec_map, - .num_dapm_routes = ARRAY_SIZE(sirf_audio_codec_map), - .use_pmdown_time = 1, - .endianness = 1, - .non_legacy_dai_naming = 1, -}; - -static const struct of_device_id sirf_audio_codec_of_match[] = { - { .compatible = "sirf,prima2-audio-codec" }, - { .compatible = "sirf,atlas6-audio-codec" }, - {} -}; -MODULE_DEVICE_TABLE(of, sirf_audio_codec_of_match); - -static const struct regmap_config sirf_audio_codec_regmap_config = { - .reg_bits = 32, - .reg_stride = 4, - .val_bits = 32, - .max_register = AUDIO_PORT_IC_RXFIFO_INT_MSK, - .cache_type = REGCACHE_NONE, -}; - -static int sirf_audio_codec_driver_probe(struct platform_device *pdev) -{ - int ret; - struct sirf_audio_codec *sirf_audio_codec; - void __iomem *base; - - sirf_audio_codec = devm_kzalloc(&pdev->dev, - sizeof(struct sirf_audio_codec), GFP_KERNEL); - if (!sirf_audio_codec) - return -ENOMEM; - - platform_set_drvdata(pdev, sirf_audio_codec); - - base = devm_platform_ioremap_resource(pdev, 0); - if (IS_ERR(base)) - return PTR_ERR(base); - - sirf_audio_codec->regmap = devm_regmap_init_mmio(&pdev->dev, base, - &sirf_audio_codec_regmap_config); - if (IS_ERR(sirf_audio_codec->regmap)) - return PTR_ERR(sirf_audio_codec->regmap); - - sirf_audio_codec->clk = devm_clk_get(&pdev->dev, NULL); - if (IS_ERR(sirf_audio_codec->clk)) { - dev_err(&pdev->dev, "Get clock failed.\n"); - return PTR_ERR(sirf_audio_codec->clk); - } - - ret = clk_prepare_enable(sirf_audio_codec->clk); - if (ret) { - dev_err(&pdev->dev, "Enable clock failed.\n"); - return ret; - } - - ret = devm_snd_soc_register_component(&(pdev->dev), - &soc_codec_device_sirf_audio_codec, - &sirf_audio_codec_dai, 1); - if (ret) { - dev_err(&pdev->dev, "Register Audio Codec dai failed.\n"); - goto err_clk_put; - } - - /* - * Always open charge pump, if not, when the charge pump closed the - * adc will not stable - */ - regmap_update_bits(sirf_audio_codec->regmap, AUDIO_IC_CODEC_CTRL0, - IC_CPFREQ, IC_CPFREQ); - - if (of_device_is_compatible(pdev->dev.of_node, "sirf,atlas6-audio-codec")) - regmap_update_bits(sirf_audio_codec->regmap, - AUDIO_IC_CODEC_CTRL0, IC_CPEN, IC_CPEN); - return 0; - -err_clk_put: - clk_disable_unprepare(sirf_audio_codec->clk); - return ret; -} - -static int sirf_audio_codec_driver_remove(struct platform_device *pdev) -{ - struct sirf_audio_codec *sirf_audio_codec = platform_get_drvdata(pdev); - - clk_disable_unprepare(sirf_audio_codec->clk); - - return 0; -} - -#ifdef CONFIG_PM_SLEEP -static int sirf_audio_codec_suspend(struct device *dev) -{ - struct sirf_audio_codec *sirf_audio_codec = dev_get_drvdata(dev); - - regmap_read(sirf_audio_codec->regmap, AUDIO_IC_CODEC_CTRL0, - &sirf_audio_codec->reg_ctrl0); - regmap_read(sirf_audio_codec->regmap, AUDIO_IC_CODEC_CTRL1, - &sirf_audio_codec->reg_ctrl1); - clk_disable_unprepare(sirf_audio_codec->clk); - - return 0; -} - -static int sirf_audio_codec_resume(struct device *dev) -{ - struct sirf_audio_codec *sirf_audio_codec = dev_get_drvdata(dev); - int ret; - - ret = clk_prepare_enable(sirf_audio_codec->clk); - if (ret) - return ret; - - regmap_write(sirf_audio_codec->regmap, AUDIO_IC_CODEC_CTRL0, - sirf_audio_codec->reg_ctrl0); - regmap_write(sirf_audio_codec->regmap, AUDIO_IC_CODEC_CTRL1, - sirf_audio_codec->reg_ctrl1); - - return 0; -} -#endif - -static const struct dev_pm_ops sirf_audio_codec_pm_ops = { - SET_SYSTEM_SLEEP_PM_OPS(sirf_audio_codec_suspend, sirf_audio_codec_resume) -}; - -static struct platform_driver sirf_audio_codec_driver = { - .driver = { - .name = "sirf-audio-codec", - .of_match_table = sirf_audio_codec_of_match, - .pm = &sirf_audio_codec_pm_ops, - }, - .probe = sirf_audio_codec_driver_probe, - .remove = sirf_audio_codec_driver_remove, -}; - -module_platform_driver(sirf_audio_codec_driver); - -MODULE_DESCRIPTION("SiRF audio codec driver"); -MODULE_AUTHOR("RongJun Ying "); -MODULE_LICENSE("GPL v2"); diff --git a/sound/soc/sirf/Kconfig b/sound/soc/sirf/Kconfig deleted file mode 100644 index 094a1c89c59d..000000000000 --- a/sound/soc/sirf/Kconfig +++ /dev/null @@ -1,21 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0-only -config SND_SOC_SIRF - tristate "SoC Audio for the SiRF SoC chips" - depends on ARCH_SIRF || COMPILE_TEST - select SND_SOC_GENERIC_DMAENGINE_PCM - -config SND_SOC_SIRF_AUDIO - tristate "SoC Audio support for SiRF internal audio codec" - depends on SND_SOC_SIRF - select SND_SOC_SIRF_AUDIO_CODEC - select SND_SOC_SIRF_AUDIO_PORT - -config SND_SOC_SIRF_AUDIO_PORT - select REGMAP_MMIO - tristate - -config SND_SOC_SIRF_USP - tristate "SoC Audio (I2S protocol) for SiRF SoC USP interface" - depends on SND_SOC_SIRF - select REGMAP_MMIO - tristate diff --git a/sound/soc/sirf/Makefile b/sound/soc/sirf/Makefile deleted file mode 100644 index 16ed11965ff9..000000000000 --- a/sound/soc/sirf/Makefile +++ /dev/null @@ -1,8 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0 -snd-soc-sirf-audio-objs := sirf-audio.o -snd-soc-sirf-audio-port-objs := sirf-audio-port.o -snd-soc-sirf-usp-objs := sirf-usp.o - -obj-$(CONFIG_SND_SOC_SIRF_AUDIO) += snd-soc-sirf-audio.o -obj-$(CONFIG_SND_SOC_SIRF_AUDIO_PORT) += snd-soc-sirf-audio-port.o -obj-$(CONFIG_SND_SOC_SIRF_USP) += snd-soc-sirf-usp.o diff --git a/sound/soc/sirf/sirf-audio-port.c b/sound/soc/sirf/sirf-audio-port.c deleted file mode 100644 index 8be2f0bc477b..000000000000 --- a/sound/soc/sirf/sirf-audio-port.c +++ /dev/null @@ -1,86 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * SiRF Audio port driver - * - * Copyright (c) 2011 Cambridge Silicon Radio Limited, a CSR plc group company. - */ -#include -#include -#include - -struct sirf_audio_port { - struct regmap *regmap; - struct snd_dmaengine_dai_dma_data playback_dma_data; - struct snd_dmaengine_dai_dma_data capture_dma_data; -}; - - -static int sirf_audio_port_dai_probe(struct snd_soc_dai *dai) -{ - struct sirf_audio_port *port = snd_soc_dai_get_drvdata(dai); - - snd_soc_dai_init_dma_data(dai, &port->playback_dma_data, - &port->capture_dma_data); - return 0; -} - -static struct snd_soc_dai_driver sirf_audio_port_dai = { - .probe = sirf_audio_port_dai_probe, - .name = "sirf-audio-port", - .id = 0, - .playback = { - .channels_min = 2, - .channels_max = 2, - .rates = SNDRV_PCM_RATE_48000, - .formats = SNDRV_PCM_FMTBIT_S16_LE, - }, - .capture = { - .channels_min = 1, - .channels_max = 2, - .rates = SNDRV_PCM_RATE_48000, - .formats = SNDRV_PCM_FMTBIT_S16_LE, - }, -}; - -static const struct snd_soc_component_driver sirf_audio_port_component = { - .name = "sirf-audio-port", -}; - -static int sirf_audio_port_probe(struct platform_device *pdev) -{ - int ret; - struct sirf_audio_port *port; - - port = devm_kzalloc(&pdev->dev, - sizeof(struct sirf_audio_port), GFP_KERNEL); - if (!port) - return -ENOMEM; - - ret = devm_snd_soc_register_component(&pdev->dev, - &sirf_audio_port_component, &sirf_audio_port_dai, 1); - if (ret) - return ret; - - platform_set_drvdata(pdev, port); - return devm_snd_dmaengine_pcm_register(&pdev->dev, NULL, 0); -} - -static const struct of_device_id sirf_audio_port_of_match[] = { - { .compatible = "sirf,audio-port", }, - {} -}; -MODULE_DEVICE_TABLE(of, sirf_audio_port_of_match); - -static struct platform_driver sirf_audio_port_driver = { - .driver = { - .name = "sirf-audio-port", - .of_match_table = sirf_audio_port_of_match, - }, - .probe = sirf_audio_port_probe, -}; - -module_platform_driver(sirf_audio_port_driver); - -MODULE_DESCRIPTION("SiRF Audio Port driver"); -MODULE_AUTHOR("RongJun Ying "); -MODULE_LICENSE("GPL v2"); diff --git a/sound/soc/sirf/sirf-audio.c b/sound/soc/sirf/sirf-audio.c deleted file mode 100644 index c923b6772b22..000000000000 --- a/sound/soc/sirf/sirf-audio.c +++ /dev/null @@ -1,160 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * SiRF audio card driver - * - * Copyright (c) 2011 Cambridge Silicon Radio Limited, a CSR plc group company. - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -struct sirf_audio_card { - unsigned int gpio_hp_pa; - unsigned int gpio_spk_pa; -}; - -static int sirf_audio_hp_event(struct snd_soc_dapm_widget *w, - struct snd_kcontrol *ctrl, int event) -{ - struct snd_soc_dapm_context *dapm = w->dapm; - struct snd_soc_card *card = dapm->card; - struct sirf_audio_card *sirf_audio_card = snd_soc_card_get_drvdata(card); - int on = !SND_SOC_DAPM_EVENT_OFF(event); - - if (gpio_is_valid(sirf_audio_card->gpio_hp_pa)) - gpio_set_value(sirf_audio_card->gpio_hp_pa, on); - return 0; -} - -static int sirf_audio_spk_event(struct snd_soc_dapm_widget *w, - struct snd_kcontrol *ctrl, int event) -{ - struct snd_soc_dapm_context *dapm = w->dapm; - struct snd_soc_card *card = dapm->card; - struct sirf_audio_card *sirf_audio_card = snd_soc_card_get_drvdata(card); - int on = !SND_SOC_DAPM_EVENT_OFF(event); - - if (gpio_is_valid(sirf_audio_card->gpio_spk_pa)) - gpio_set_value(sirf_audio_card->gpio_spk_pa, on); - - return 0; -} -static const struct snd_soc_dapm_widget sirf_audio_dapm_widgets[] = { - SND_SOC_DAPM_HP("Hp", sirf_audio_hp_event), - SND_SOC_DAPM_SPK("Ext Spk", sirf_audio_spk_event), - SND_SOC_DAPM_MIC("Ext Mic", NULL), -}; - -static const struct snd_soc_dapm_route intercon[] = { - {"Hp", NULL, "HPOUTL"}, - {"Hp", NULL, "HPOUTR"}, - {"Ext Spk", NULL, "SPKOUT"}, - {"MICIN1", NULL, "Mic Bias"}, - {"Mic Bias", NULL, "Ext Mic"}, -}; - -/* Digital audio interface glue - connects codec <--> CPU */ -SND_SOC_DAILINK_DEFS(sirf, - DAILINK_COMP_ARRAY(COMP_EMPTY()), - DAILINK_COMP_ARRAY(COMP_CODEC(NULL, "sirf-audio-codec")), - DAILINK_COMP_ARRAY(COMP_EMPTY())); - -static struct snd_soc_dai_link sirf_audio_dai_link[] = { - { - .name = "SiRF audio card", - .stream_name = "SiRF audio HiFi", - SND_SOC_DAILINK_REG(sirf), - }, -}; - -/* Audio machine driver */ -static struct snd_soc_card snd_soc_sirf_audio_card = { - .name = "SiRF audio card", - .owner = THIS_MODULE, - .dai_link = sirf_audio_dai_link, - .num_links = ARRAY_SIZE(sirf_audio_dai_link), - .dapm_widgets = sirf_audio_dapm_widgets, - .num_dapm_widgets = ARRAY_SIZE(sirf_audio_dapm_widgets), - .dapm_routes = intercon, - .num_dapm_routes = ARRAY_SIZE(intercon), -}; - -static int sirf_audio_probe(struct platform_device *pdev) -{ - struct snd_soc_card *card = &snd_soc_sirf_audio_card; - struct sirf_audio_card *sirf_audio_card; - int ret; - - sirf_audio_card = devm_kzalloc(&pdev->dev, sizeof(struct sirf_audio_card), - GFP_KERNEL); - if (sirf_audio_card == NULL) - return -ENOMEM; - - sirf_audio_dai_link[0].cpus->of_node = - of_parse_phandle(pdev->dev.of_node, "sirf,audio-platform", 0); - sirf_audio_dai_link[0].platforms->of_node = - of_parse_phandle(pdev->dev.of_node, "sirf,audio-platform", 0); - sirf_audio_dai_link[0].codecs->of_node = - of_parse_phandle(pdev->dev.of_node, "sirf,audio-codec", 0); - sirf_audio_card->gpio_spk_pa = of_get_named_gpio(pdev->dev.of_node, - "spk-pa-gpios", 0); - sirf_audio_card->gpio_hp_pa = of_get_named_gpio(pdev->dev.of_node, - "hp-pa-gpios", 0); - if (gpio_is_valid(sirf_audio_card->gpio_spk_pa)) { - ret = devm_gpio_request_one(&pdev->dev, - sirf_audio_card->gpio_spk_pa, - GPIOF_OUT_INIT_LOW, "SPA_PA_SD"); - if (ret) { - dev_err(&pdev->dev, - "Failed to request GPIO_%d for reset: %d\n", - sirf_audio_card->gpio_spk_pa, ret); - return ret; - } - } - if (gpio_is_valid(sirf_audio_card->gpio_hp_pa)) { - ret = devm_gpio_request_one(&pdev->dev, - sirf_audio_card->gpio_hp_pa, - GPIOF_OUT_INIT_LOW, "HP_PA_SD"); - if (ret) { - dev_err(&pdev->dev, - "Failed to request GPIO_%d for reset: %d\n", - sirf_audio_card->gpio_hp_pa, ret); - return ret; - } - } - - card->dev = &pdev->dev; - snd_soc_card_set_drvdata(card, sirf_audio_card); - - ret = devm_snd_soc_register_card(&pdev->dev, card); - if (ret) - dev_err(&pdev->dev, "snd_soc_register_card() failed:%d\n", ret); - - return ret; -} - -static const struct of_device_id sirf_audio_of_match[] = { - {.compatible = "sirf,sirf-audio-card", }, - { }, -}; -MODULE_DEVICE_TABLE(of, sirf_audio_of_match); - -static struct platform_driver sirf_audio_driver = { - .driver = { - .name = "sirf-audio-card", - .pm = &snd_soc_pm_ops, - .of_match_table = sirf_audio_of_match, - }, - .probe = sirf_audio_probe, -}; -module_platform_driver(sirf_audio_driver); - -MODULE_AUTHOR("RongJun Ying "); -MODULE_DESCRIPTION("ALSA SoC SIRF audio card driver"); -MODULE_LICENSE("GPL v2"); diff --git a/sound/soc/sirf/sirf-usp.c b/sound/soc/sirf/sirf-usp.c deleted file mode 100644 index 2af0c6f14ee6..000000000000 --- a/sound/soc/sirf/sirf-usp.c +++ /dev/null @@ -1,435 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * SiRF USP in I2S/DSP mode - * - * Copyright (c) 2011 Cambridge Silicon Radio Limited, a CSR plc group company. - */ -#include -#include -#include -#include -#include -#include -#include -#include - -#include "sirf-usp.h" - -struct sirf_usp { - struct regmap *regmap; - struct clk *clk; - u32 mode1_reg; - u32 mode2_reg; - int daifmt_format; - struct snd_dmaengine_dai_dma_data playback_dma_data; - struct snd_dmaengine_dai_dma_data capture_dma_data; -}; - -static void sirf_usp_tx_enable(struct sirf_usp *usp) -{ - regmap_update_bits(usp->regmap, USP_TX_FIFO_OP, - USP_TX_FIFO_RESET, USP_TX_FIFO_RESET); - regmap_write(usp->regmap, USP_TX_FIFO_OP, 0); - - regmap_update_bits(usp->regmap, USP_TX_FIFO_OP, - USP_TX_FIFO_START, USP_TX_FIFO_START); - - regmap_update_bits(usp->regmap, USP_TX_RX_ENABLE, - USP_TX_ENA, USP_TX_ENA); -} - -static void sirf_usp_tx_disable(struct sirf_usp *usp) -{ - regmap_update_bits(usp->regmap, USP_TX_RX_ENABLE, - USP_TX_ENA, ~USP_TX_ENA); - /* FIFO stop */ - regmap_write(usp->regmap, USP_TX_FIFO_OP, 0); -} - -static void sirf_usp_rx_enable(struct sirf_usp *usp) -{ - regmap_update_bits(usp->regmap, USP_RX_FIFO_OP, - USP_RX_FIFO_RESET, USP_RX_FIFO_RESET); - regmap_write(usp->regmap, USP_RX_FIFO_OP, 0); - - regmap_update_bits(usp->regmap, USP_RX_FIFO_OP, - USP_RX_FIFO_START, USP_RX_FIFO_START); - - regmap_update_bits(usp->regmap, USP_TX_RX_ENABLE, - USP_RX_ENA, USP_RX_ENA); -} - -static void sirf_usp_rx_disable(struct sirf_usp *usp) -{ - regmap_update_bits(usp->regmap, USP_TX_RX_ENABLE, - USP_RX_ENA, ~USP_RX_ENA); - /* FIFO stop */ - regmap_write(usp->regmap, USP_RX_FIFO_OP, 0); -} - -static int sirf_usp_pcm_dai_probe(struct snd_soc_dai *dai) -{ - struct sirf_usp *usp = snd_soc_dai_get_drvdata(dai); - - snd_soc_dai_init_dma_data(dai, &usp->playback_dma_data, - &usp->capture_dma_data); - return 0; -} - -static int sirf_usp_pcm_set_dai_fmt(struct snd_soc_dai *dai, - unsigned int fmt) -{ - struct sirf_usp *usp = snd_soc_dai_get_drvdata(dai); - - /* set master/slave audio interface */ - switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { - case SND_SOC_DAIFMT_CBM_CFM: - break; - default: - dev_err(dai->dev, "Only CBM and CFM supported\n"); - return -EINVAL; - } - - switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { - case SND_SOC_DAIFMT_I2S: - case SND_SOC_DAIFMT_DSP_A: - usp->daifmt_format = (fmt & SND_SOC_DAIFMT_FORMAT_MASK); - break; - default: - dev_err(dai->dev, "Only I2S and DSP_A format supported\n"); - return -EINVAL; - } - - switch (fmt & SND_SOC_DAIFMT_INV_MASK) { - case SND_SOC_DAIFMT_NB_NF: - break; - case SND_SOC_DAIFMT_IB_NF: - usp->daifmt_format |= (fmt & SND_SOC_DAIFMT_INV_MASK); - break; - default: - return -EINVAL; - } - - return 0; -} - -static void sirf_usp_i2s_init(struct sirf_usp *usp) -{ - /* Configure RISC mode */ - regmap_update_bits(usp->regmap, USP_RISC_DSP_MODE, - USP_RISC_DSP_SEL, ~USP_RISC_DSP_SEL); - - /* - * Configure DMA IO Length register - * Set no limit, USP can receive data continuously until it is diabled - */ - regmap_write(usp->regmap, USP_TX_DMA_IO_LEN, 0); - regmap_write(usp->regmap, USP_RX_DMA_IO_LEN, 0); - - /* Configure Mode2 register */ - regmap_write(usp->regmap, USP_MODE2, (1 << USP_RXD_DELAY_LEN_OFFSET) | - (0 << USP_TXD_DELAY_LEN_OFFSET) | - USP_TFS_CLK_SLAVE_MODE | USP_RFS_CLK_SLAVE_MODE); - - /* Configure Mode1 register */ - regmap_write(usp->regmap, USP_MODE1, - USP_SYNC_MODE | USP_EN | USP_TXD_ACT_EDGE_FALLING | - USP_RFS_ACT_LEVEL_LOGIC1 | USP_TFS_ACT_LEVEL_LOGIC1 | - USP_TX_UFLOW_REPEAT_ZERO | USP_CLOCK_MODE_SLAVE); - - /* Configure RX DMA IO Control register */ - regmap_write(usp->regmap, USP_RX_DMA_IO_CTRL, 0); - - /* Congiure RX FIFO Control register */ - regmap_write(usp->regmap, USP_RX_FIFO_CTRL, - (USP_RX_FIFO_THRESHOLD << USP_RX_FIFO_THD_OFFSET) | - (USP_TX_RX_FIFO_WIDTH_DWORD << USP_RX_FIFO_WIDTH_OFFSET)); - - /* Congiure RX FIFO Level Check register */ - regmap_write(usp->regmap, USP_RX_FIFO_LEVEL_CHK, - RX_FIFO_SC(0x04) | RX_FIFO_LC(0x0E) | RX_FIFO_HC(0x1B)); - - /* Configure TX DMA IO Control register*/ - regmap_write(usp->regmap, USP_TX_DMA_IO_CTRL, 0); - - /* Configure TX FIFO Control register */ - regmap_write(usp->regmap, USP_TX_FIFO_CTRL, - (USP_TX_FIFO_THRESHOLD << USP_TX_FIFO_THD_OFFSET) | - (USP_TX_RX_FIFO_WIDTH_DWORD << USP_TX_FIFO_WIDTH_OFFSET)); - /* Congiure TX FIFO Level Check register */ - regmap_write(usp->regmap, USP_TX_FIFO_LEVEL_CHK, - TX_FIFO_SC(0x1B) | TX_FIFO_LC(0x0E) | TX_FIFO_HC(0x04)); -} - -static int sirf_usp_pcm_hw_params(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *params, struct snd_soc_dai *dai) -{ - struct sirf_usp *usp = snd_soc_dai_get_drvdata(dai); - u32 data_len, frame_len, shifter_len; - - switch (params_format(params)) { - case SNDRV_PCM_FORMAT_S16_LE: - data_len = 16; - frame_len = 16; - break; - case SNDRV_PCM_FORMAT_S24_LE: - data_len = 24; - frame_len = 32; - break; - case SNDRV_PCM_FORMAT_S24_3LE: - data_len = 24; - frame_len = 24; - break; - default: - dev_err(dai->dev, "Format unsupported\n"); - return -EINVAL; - } - - shifter_len = data_len; - - switch (usp->daifmt_format & SND_SOC_DAIFMT_FORMAT_MASK) { - case SND_SOC_DAIFMT_I2S: - regmap_update_bits(usp->regmap, USP_RX_FRAME_CTRL, - USP_I2S_SYNC_CHG, USP_I2S_SYNC_CHG); - break; - case SND_SOC_DAIFMT_DSP_A: - regmap_update_bits(usp->regmap, USP_RX_FRAME_CTRL, - USP_I2S_SYNC_CHG, 0); - frame_len = data_len * params_channels(params); - data_len = frame_len; - break; - default: - dev_err(dai->dev, "Only support I2S and DSP_A mode\n"); - return -EINVAL; - } - - switch (usp->daifmt_format & SND_SOC_DAIFMT_INV_MASK) { - case SND_SOC_DAIFMT_NB_NF: - break; - case SND_SOC_DAIFMT_IB_NF: - regmap_update_bits(usp->regmap, USP_MODE1, - USP_RXD_ACT_EDGE_FALLING | USP_TXD_ACT_EDGE_FALLING, - USP_RXD_ACT_EDGE_FALLING); - break; - default: - return -EINVAL; - } - - if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) - regmap_update_bits(usp->regmap, USP_TX_FRAME_CTRL, - USP_TXC_DATA_LEN_MASK | USP_TXC_FRAME_LEN_MASK - | USP_TXC_SHIFTER_LEN_MASK | USP_TXC_SLAVE_CLK_SAMPLE, - ((data_len - 1) << USP_TXC_DATA_LEN_OFFSET) - | ((frame_len - 1) << USP_TXC_FRAME_LEN_OFFSET) - | ((shifter_len - 1) << USP_TXC_SHIFTER_LEN_OFFSET) - | USP_TXC_SLAVE_CLK_SAMPLE); - else - regmap_update_bits(usp->regmap, USP_RX_FRAME_CTRL, - USP_RXC_DATA_LEN_MASK | USP_RXC_FRAME_LEN_MASK - | USP_RXC_SHIFTER_LEN_MASK | USP_SINGLE_SYNC_MODE, - ((data_len - 1) << USP_RXC_DATA_LEN_OFFSET) - | ((frame_len - 1) << USP_RXC_FRAME_LEN_OFFSET) - | ((shifter_len - 1) << USP_RXC_SHIFTER_LEN_OFFSET) - | USP_SINGLE_SYNC_MODE); - - return 0; -} - -static int sirf_usp_pcm_trigger(struct snd_pcm_substream *substream, int cmd, - struct snd_soc_dai *dai) -{ - struct sirf_usp *usp = snd_soc_dai_get_drvdata(dai); - - switch (cmd) { - case SNDRV_PCM_TRIGGER_START: - case SNDRV_PCM_TRIGGER_RESUME: - case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: - if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) - sirf_usp_tx_enable(usp); - else - sirf_usp_rx_enable(usp); - break; - case SNDRV_PCM_TRIGGER_STOP: - case SNDRV_PCM_TRIGGER_SUSPEND: - case SNDRV_PCM_TRIGGER_PAUSE_PUSH: - if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) - sirf_usp_tx_disable(usp); - else - sirf_usp_rx_disable(usp); - break; - } - - return 0; -} - -static const struct snd_soc_dai_ops sirf_usp_pcm_dai_ops = { - .trigger = sirf_usp_pcm_trigger, - .set_fmt = sirf_usp_pcm_set_dai_fmt, - .hw_params = sirf_usp_pcm_hw_params, -}; - -static struct snd_soc_dai_driver sirf_usp_pcm_dai = { - .probe = sirf_usp_pcm_dai_probe, - .name = "sirf-usp-pcm", - .id = 0, - .playback = { - .stream_name = "SiRF USP PCM Playback", - .channels_min = 1, - .channels_max = 2, - .rates = SNDRV_PCM_RATE_8000_192000, - .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE | - SNDRV_PCM_FMTBIT_S24_3LE, - }, - .capture = { - .stream_name = "SiRF USP PCM Capture", - .channels_min = 1, - .channels_max = 2, - .rates = SNDRV_PCM_RATE_8000_192000, - .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE | - SNDRV_PCM_FMTBIT_S24_3LE, - }, - .ops = &sirf_usp_pcm_dai_ops, -}; - -static int sirf_usp_pcm_runtime_suspend(struct device *dev) -{ - struct sirf_usp *usp = dev_get_drvdata(dev); - - clk_disable_unprepare(usp->clk); - return 0; -} - -static int sirf_usp_pcm_runtime_resume(struct device *dev) -{ - struct sirf_usp *usp = dev_get_drvdata(dev); - int ret; - - ret = clk_prepare_enable(usp->clk); - if (ret) { - dev_err(dev, "clk_enable failed: %d\n", ret); - return ret; - } - sirf_usp_i2s_init(usp); - return 0; -} - -#ifdef CONFIG_PM_SLEEP -static int sirf_usp_pcm_suspend(struct device *dev) -{ - struct sirf_usp *usp = dev_get_drvdata(dev); - - if (!pm_runtime_status_suspended(dev)) { - regmap_read(usp->regmap, USP_MODE1, &usp->mode1_reg); - regmap_read(usp->regmap, USP_MODE2, &usp->mode2_reg); - sirf_usp_pcm_runtime_suspend(dev); - } - return 0; -} - -static int sirf_usp_pcm_resume(struct device *dev) -{ - struct sirf_usp *usp = dev_get_drvdata(dev); - int ret; - - if (!pm_runtime_status_suspended(dev)) { - ret = sirf_usp_pcm_runtime_resume(dev); - if (ret) - return ret; - regmap_write(usp->regmap, USP_MODE1, usp->mode1_reg); - regmap_write(usp->regmap, USP_MODE2, usp->mode2_reg); - } - return 0; -} -#endif - -static const struct snd_soc_component_driver sirf_usp_component = { - .name = "sirf-usp", -}; - -static const struct regmap_config sirf_usp_regmap_config = { - .reg_bits = 32, - .reg_stride = 4, - .val_bits = 32, - .max_register = USP_RX_FIFO_DATA, - .cache_type = REGCACHE_NONE, -}; - -static int sirf_usp_pcm_probe(struct platform_device *pdev) -{ - int ret; - struct sirf_usp *usp; - void __iomem *base; - - usp = devm_kzalloc(&pdev->dev, sizeof(struct sirf_usp), - GFP_KERNEL); - if (!usp) - return -ENOMEM; - - platform_set_drvdata(pdev, usp); - - base = devm_platform_ioremap_resource(pdev, 0); - if (IS_ERR(base)) - return PTR_ERR(base); - usp->regmap = devm_regmap_init_mmio(&pdev->dev, base, - &sirf_usp_regmap_config); - if (IS_ERR(usp->regmap)) - return PTR_ERR(usp->regmap); - - usp->clk = devm_clk_get(&pdev->dev, NULL); - if (IS_ERR(usp->clk)) { - dev_err(&pdev->dev, "Get clock failed.\n"); - return PTR_ERR(usp->clk); - } - - pm_runtime_enable(&pdev->dev); - if (!pm_runtime_enabled(&pdev->dev)) { - ret = sirf_usp_pcm_runtime_resume(&pdev->dev); - if (ret) - return ret; - } - - ret = devm_snd_soc_register_component(&pdev->dev, &sirf_usp_component, - &sirf_usp_pcm_dai, 1); - if (ret) { - dev_err(&pdev->dev, "Register Audio SoC dai failed.\n"); - return ret; - } - return devm_snd_dmaengine_pcm_register(&pdev->dev, NULL, 0); -} - -static int sirf_usp_pcm_remove(struct platform_device *pdev) -{ - if (!pm_runtime_enabled(&pdev->dev)) - sirf_usp_pcm_runtime_suspend(&pdev->dev); - else - pm_runtime_disable(&pdev->dev); - return 0; -} - -static const struct of_device_id sirf_usp_pcm_of_match[] = { - { .compatible = "sirf,prima2-usp-pcm", }, - {} -}; -MODULE_DEVICE_TABLE(of, sirf_usp_pcm_of_match); - -static const struct dev_pm_ops sirf_usp_pcm_pm_ops = { - SET_RUNTIME_PM_OPS(sirf_usp_pcm_runtime_suspend, - sirf_usp_pcm_runtime_resume, NULL) - SET_SYSTEM_SLEEP_PM_OPS(sirf_usp_pcm_suspend, sirf_usp_pcm_resume) -}; - -static struct platform_driver sirf_usp_pcm_driver = { - .driver = { - .name = "sirf-usp-pcm", - .of_match_table = sirf_usp_pcm_of_match, - .pm = &sirf_usp_pcm_pm_ops, - }, - .probe = sirf_usp_pcm_probe, - .remove = sirf_usp_pcm_remove, -}; - -module_platform_driver(sirf_usp_pcm_driver); - -MODULE_DESCRIPTION("SiRF SoC USP PCM bus driver"); -MODULE_AUTHOR("RongJun Ying "); -MODULE_LICENSE("GPL v2"); diff --git a/sound/soc/sirf/sirf-usp.h b/sound/soc/sirf/sirf-usp.h deleted file mode 100644 index 08993b5992c4..000000000000 --- a/sound/soc/sirf/sirf-usp.h +++ /dev/null @@ -1,292 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-or-later */ -/* - * arch/arm/mach-prima2/include/mach/sirfsoc_usp.h - * - * Copyright (c) 2011 Cambridge Silicon Radio Limited, a CSR plc group company. - */ - -#ifndef _SIRF_USP_H -#define _SIRF_USP_H - -/* USP Registers */ -#define USP_MODE1 0x00 -#define USP_MODE2 0x04 -#define USP_TX_FRAME_CTRL 0x08 -#define USP_RX_FRAME_CTRL 0x0C -#define USP_TX_RX_ENABLE 0x10 -#define USP_INT_ENABLE 0x14 -#define USP_INT_STATUS 0x18 -#define USP_PIN_IO_DATA 0x1C -#define USP_RISC_DSP_MODE 0x20 -#define USP_AYSNC_PARAM_REG 0x24 -#define USP_IRDA_X_MODE_DIV 0x28 -#define USP_SM_CFG 0x2C -#define USP_TX_DMA_IO_CTRL 0x100 -#define USP_TX_DMA_IO_LEN 0x104 -#define USP_TX_FIFO_CTRL 0x108 -#define USP_TX_FIFO_LEVEL_CHK 0x10C -#define USP_TX_FIFO_OP 0x110 -#define USP_TX_FIFO_STATUS 0x114 -#define USP_TX_FIFO_DATA 0x118 -#define USP_RX_DMA_IO_CTRL 0x120 -#define USP_RX_DMA_IO_LEN 0x124 -#define USP_RX_FIFO_CTRL 0x128 -#define USP_RX_FIFO_LEVEL_CHK 0x12C -#define USP_RX_FIFO_OP 0x130 -#define USP_RX_FIFO_STATUS 0x134 -#define USP_RX_FIFO_DATA 0x138 - -/* USP MODE register-1 */ -#define USP_SYNC_MODE 0x00000001 -#define USP_CLOCK_MODE_SLAVE 0x00000002 -#define USP_LOOP_BACK_EN 0x00000004 -#define USP_HPSIR_EN 0x00000008 -#define USP_ENDIAN_CTRL_LSBF 0x00000010 -#define USP_EN 0x00000020 -#define USP_RXD_ACT_EDGE_FALLING 0x00000040 -#define USP_TXD_ACT_EDGE_FALLING 0x00000080 -#define USP_RFS_ACT_LEVEL_LOGIC1 0x00000100 -#define USP_TFS_ACT_LEVEL_LOGIC1 0x00000200 -#define USP_SCLK_IDLE_MODE_TOGGLE 0x00000400 -#define USP_SCLK_IDLE_LEVEL_LOGIC1 0x00000800 -#define USP_SCLK_PIN_MODE_IO 0x00001000 -#define USP_RFS_PIN_MODE_IO 0x00002000 -#define USP_TFS_PIN_MODE_IO 0x00004000 -#define USP_RXD_PIN_MODE_IO 0x00008000 -#define USP_TXD_PIN_MODE_IO 0x00010000 -#define USP_SCLK_IO_MODE_INPUT 0x00020000 -#define USP_RFS_IO_MODE_INPUT 0x00040000 -#define USP_TFS_IO_MODE_INPUT 0x00080000 -#define USP_RXD_IO_MODE_INPUT 0x00100000 -#define USP_TXD_IO_MODE_INPUT 0x00200000 -#define USP_IRDA_WIDTH_DIV_MASK 0x3FC00000 -#define USP_IRDA_WIDTH_DIV_OFFSET 0 -#define USP_IRDA_IDLE_LEVEL_HIGH 0x40000000 -#define USP_TX_UFLOW_REPEAT_ZERO 0x80000000 -#define USP_TX_ENDIAN_MODE 0x00000020 -#define USP_RX_ENDIAN_MODE 0x00000020 - -/* USP Mode Register-2 */ -#define USP_RXD_DELAY_LEN_MASK 0x000000FF -#define USP_RXD_DELAY_LEN_OFFSET 0 - -#define USP_TXD_DELAY_LEN_MASK 0x0000FF00 -#define USP_TXD_DELAY_LEN_OFFSET 8 - -#define USP_ENA_CTRL_MODE 0x00010000 -#define USP_FRAME_CTRL_MODE 0x00020000 -#define USP_TFS_SOURCE_MODE 0x00040000 -#define USP_TFS_MS_MODE 0x00080000 -#define USP_CLK_DIVISOR_MASK 0x7FE00000 -#define USP_CLK_DIVISOR_OFFSET 21 - -#define USP_TFS_CLK_SLAVE_MODE (1<<20) -#define USP_RFS_CLK_SLAVE_MODE (1<<19) - -#define USP_IRDA_DATA_WIDTH 0x80000000 - -/* USP Transmit Frame Control Register */ - -#define USP_TXC_DATA_LEN_MASK 0x000000FF -#define USP_TXC_DATA_LEN_OFFSET 0 - -#define USP_TXC_SYNC_LEN_MASK 0x0000FF00 -#define USP_TXC_SYNC_LEN_OFFSET 8 - -#define USP_TXC_FRAME_LEN_MASK 0x00FF0000 -#define USP_TXC_FRAME_LEN_OFFSET 16 - -#define USP_TXC_SHIFTER_LEN_MASK 0x1F000000 -#define USP_TXC_SHIFTER_LEN_OFFSET 24 - -#define USP_TXC_SLAVE_CLK_SAMPLE 0x20000000 - -#define USP_TXC_CLK_DIVISOR_MASK 0xC0000000 -#define USP_TXC_CLK_DIVISOR_OFFSET 30 - -/* USP Receive Frame Control Register */ - -#define USP_RXC_DATA_LEN_MASK 0x000000FF -#define USP_RXC_DATA_LEN_OFFSET 0 - -#define USP_RXC_FRAME_LEN_MASK 0x0000FF00 -#define USP_RXC_FRAME_LEN_OFFSET 8 - -#define USP_RXC_SHIFTER_LEN_MASK 0x001F0000 -#define USP_RXC_SHIFTER_LEN_OFFSET 16 - -#define USP_START_EDGE_MODE 0x00800000 -#define USP_I2S_SYNC_CHG 0x00200000 - -#define USP_RXC_CLK_DIVISOR_MASK 0x0F000000 -#define USP_RXC_CLK_DIVISOR_OFFSET 24 -#define USP_SINGLE_SYNC_MODE 0x00400000 - -/* Tx - RX Enable Register */ - -#define USP_RX_ENA 0x00000001 -#define USP_TX_ENA 0x00000002 - -/* USP Interrupt Enable and status Register */ -#define USP_RX_DONE_INT 0x00000001 -#define USP_TX_DONE_INT 0x00000002 -#define USP_RX_OFLOW_INT 0x00000004 -#define USP_TX_UFLOW_INT 0x00000008 -#define USP_RX_IO_DMA_INT 0x00000010 -#define USP_TX_IO_DMA_INT 0x00000020 -#define USP_RXFIFO_FULL_INT 0x00000040 -#define USP_TXFIFO_EMPTY_INT 0x00000080 -#define USP_RXFIFO_THD_INT 0x00000100 -#define USP_TXFIFO_THD_INT 0x00000200 -#define USP_UART_FRM_ERR_INT 0x00000400 -#define USP_RX_TIMEOUT_INT 0x00000800 -#define USP_TX_ALLOUT_INT 0x00001000 -#define USP_RXD_BREAK_INT 0x00008000 - -/* All possible TX interruots */ -#define USP_TX_INTERRUPT (USP_TX_DONE_INT|USP_TX_UFLOW_INT|\ - USP_TX_IO_DMA_INT|\ - USP_TXFIFO_EMPTY_INT|\ - USP_TXFIFO_THD_INT) -/* All possible RX interruots */ -#define USP_RX_INTERRUPT (USP_RX_DONE_INT|USP_RX_OFLOW_INT|\ - USP_RX_IO_DMA_INT|\ - USP_RXFIFO_FULL_INT|\ - USP_RXFIFO_THD_INT|\ - USP_RX_TIMEOUT_INT) - -#define USP_INT_ALL 0x1FFF - -/* USP Pin I/O Data Register */ - -#define USP_RFS_PIN_VALUE_MASK 0x00000001 -#define USP_TFS_PIN_VALUE_MASK 0x00000002 -#define USP_RXD_PIN_VALUE_MASK 0x00000004 -#define USP_TXD_PIN_VALUE_MASK 0x00000008 -#define USP_SCLK_PIN_VALUE_MASK 0x00000010 - -/* USP RISC/DSP Mode Register */ -#define USP_RISC_DSP_SEL 0x00000001 - -/* USP ASYNC PARAMETER Register*/ - -#define USP_ASYNC_TIMEOUT_MASK 0x0000FFFF -#define USP_ASYNC_TIMEOUT_OFFSET 0 -#define USP_ASYNC_TIMEOUT(x) (((x)&USP_ASYNC_TIMEOUT_MASK) \ - < Date: Wed, 20 Jan 2021 17:25:53 +0100 Subject: ASoC: remove zte zx drivers The zte zx platform is getting removed, so this driver is no longer needed. Cc: Jun Nie Cc: Shawn Guo Signed-off-by: Arnd Bergmann Link: https://lore.kernel.org/r/20210120162553.21666-3-arnd@kernel.org Signed-off-by: Mark Brown --- .../devicetree/bindings/sound/zte,tdm.txt | 30 -- .../devicetree/bindings/sound/zte,zx-aud96p22.txt | 24 -- .../devicetree/bindings/sound/zte,zx-i2s.txt | 45 -- .../devicetree/bindings/sound/zte,zx-spdif.txt | 27 -- sound/soc/Kconfig | 1 - sound/soc/Makefile | 1 - sound/soc/codecs/Makefile | 2 - sound/soc/codecs/zx_aud96p22.c | 401 ------------------ sound/soc/zte/Kconfig | 26 -- sound/soc/zte/Makefile | 4 - sound/soc/zte/zx-i2s.c | 452 -------------------- sound/soc/zte/zx-spdif.c | 363 ---------------- sound/soc/zte/zx-tdm.c | 458 --------------------- 13 files changed, 1834 deletions(-) delete mode 100644 Documentation/devicetree/bindings/sound/zte,tdm.txt delete mode 100644 Documentation/devicetree/bindings/sound/zte,zx-aud96p22.txt delete mode 100644 Documentation/devicetree/bindings/sound/zte,zx-i2s.txt delete mode 100644 Documentation/devicetree/bindings/sound/zte,zx-spdif.txt delete mode 100644 sound/soc/codecs/zx_aud96p22.c delete mode 100644 sound/soc/zte/Kconfig delete mode 100644 sound/soc/zte/Makefile delete mode 100644 sound/soc/zte/zx-i2s.c delete mode 100644 sound/soc/zte/zx-spdif.c delete mode 100644 sound/soc/zte/zx-tdm.c (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/sound/zte,tdm.txt b/Documentation/devicetree/bindings/sound/zte,tdm.txt deleted file mode 100644 index 2a07ca655264..000000000000 --- a/Documentation/devicetree/bindings/sound/zte,tdm.txt +++ /dev/null @@ -1,30 +0,0 @@ -ZTE TDM DAI driver - -Required properties: - -- compatible : should be one of the following. - * zte,zx296718-tdm -- reg : physical base address of the controller and length of memory mapped - region. -- clocks : Pairs of phandle and specifier referencing the controller's clocks. -- clock-names: "wclk" for the wclk. - "pclk" for the pclk. --#clock-cells: should be 1. -- zte,tdm-dma-sysctrl : Reference to the sysctrl controller controlling - the dma. includes: - phandle of sysctrl. - register offset in sysctrl for control dma. - mask of the register that be written to sysctrl. - -Example: - - tdm: tdm@1487000 { - compatible = "zte,zx296718-tdm"; - reg = <0x01487000 0x1000>; - clocks = <&audiocrm AUDIO_TDM_WCLK>, <&audiocrm AUDIO_TDM_PCLK>; - clock-names = "wclk", "pclk"; - #clock-cells = <1>; - pinctrl-names = "default"; - pinctrl-0 = <&tdm_global_pin>; - zte,tdm-dma-sysctrl = <&sysctrl 0x10c 4>; - }; diff --git a/Documentation/devicetree/bindings/sound/zte,zx-aud96p22.txt b/Documentation/devicetree/bindings/sound/zte,zx-aud96p22.txt deleted file mode 100644 index 41bb1040eb71..000000000000 --- a/Documentation/devicetree/bindings/sound/zte,zx-aud96p22.txt +++ /dev/null @@ -1,24 +0,0 @@ -ZTE ZX AUD96P22 Audio Codec - -Required properties: - - compatible: Must be "zte,zx-aud96p22" - - #sound-dai-cells: Should be 0 - - reg: I2C bus slave address of AUD96P22 - -Example: - - i2c0: i2c@1486000 { - compatible = "zte,zx296718-i2c"; - reg = <0x01486000 0x1000>; - interrupts = ; - #address-cells = <1>; - #size-cells = <0>; - clocks = <&audiocrm AUDIO_I2C0_WCLK>; - clock-frequency = <1600000>; - - aud96p22: codec@22 { - compatible = "zte,zx-aud96p22"; - #sound-dai-cells = <0>; - reg = <0x22>; - }; - }; diff --git a/Documentation/devicetree/bindings/sound/zte,zx-i2s.txt b/Documentation/devicetree/bindings/sound/zte,zx-i2s.txt deleted file mode 100644 index 3927251464f0..000000000000 --- a/Documentation/devicetree/bindings/sound/zte,zx-i2s.txt +++ /dev/null @@ -1,45 +0,0 @@ -ZTE ZX296702 I2S controller - -Required properties: - - compatible : Must be one of: - "zte,zx296718-i2s", "zte,zx296702-i2s" - "zte,zx296702-i2s" - - reg : Must contain I2S core's registers location and length - - clocks : Pairs of phandle and specifier referencing the controller's clocks. - - clock-names: "wclk" for the wclk, "pclk" for the pclk to the I2S interface. - - dmas: Pairs of phandle and specifier for the DMA channel that is used by - the core. The core expects two dma channels for transmit. - - dma-names : Must be "tx" and "rx" - -For more details on the 'dma', 'dma-names', 'clock' and 'clock-names' properties -please check: - * resource-names.txt - * clock/clock-bindings.txt - * dma/dma.txt - -Example: - i2s0: i2s@b005000 { - #sound-dai-cells = <0>; - compatible = "zte,zx296718-i2s", "zte,zx296702-i2s"; - reg = <0x0b005000 0x1000>; - clocks = <&audiocrm AUDIO_I2S0_WCLK>, <&audiocrm AUDIO_I2S0_PCLK>; - clock-names = "wclk", "pclk"; - interrupts = ; - dmas = <&dma 5>, <&dma 6>; - dma-names = "tx", "rx"; - }; - - sound { - compatible = "simple-audio-card"; - simple-audio-card,name = "zx296702_snd"; - simple-audio-card,format = "left_j"; - simple-audio-card,bitclock-master = <&sndcodec>; - simple-audio-card,frame-master = <&sndcodec>; - sndcpu: simple-audio-card,cpu { - sound-dai = <&i2s0>; - }; - - sndcodec: simple-audio-card,codec { - sound-dai = <&acodec>; - }; - }; diff --git a/Documentation/devicetree/bindings/sound/zte,zx-spdif.txt b/Documentation/devicetree/bindings/sound/zte,zx-spdif.txt deleted file mode 100644 index 09231d7586b2..000000000000 --- a/Documentation/devicetree/bindings/sound/zte,zx-spdif.txt +++ /dev/null @@ -1,27 +0,0 @@ -ZTE ZX296702 SPDIF controller - -Required properties: - - compatible : Must be "zte,zx296702-spdif" - - reg : Must contain SPDIF core's registers location and length - - clocks : Pairs of phandle and specifier referencing the controller's clocks. - - clock-names: "tx" for the clock to the SPDIF interface. - - dmas: Pairs of phandle and specifier for the DMA channel that is used by - the core. The core expects one dma channel for transmit. - - dma-names : Must be "tx" - -For more details on the 'dma', 'dma-names', 'clock' and 'clock-names' properties -please check: - * resource-names.txt - * clock/clock-bindings.txt - * dma/dma.txt - -Example: - spdif0: spdif0@b004000 { - compatible = "zte,zx296702-spdif"; - reg = <0x0b004000 0x1000>; - clocks = <&lsp0clk ZX296702_SPDIF0_DIV>; - clock-names = "tx"; - interrupts = ; - dmas = <&dma 4>; - dma-names = "tx"; - }; diff --git a/sound/soc/Kconfig b/sound/soc/Kconfig index 547b26ca714f..ba79d5f4e299 100644 --- a/sound/soc/Kconfig +++ b/sound/soc/Kconfig @@ -74,7 +74,6 @@ source "sound/soc/uniphier/Kconfig" source "sound/soc/ux500/Kconfig" source "sound/soc/xilinx/Kconfig" source "sound/soc/xtensa/Kconfig" -source "sound/soc/zte/Kconfig" # Supported codecs source "sound/soc/codecs/Kconfig" diff --git a/sound/soc/Makefile b/sound/soc/Makefile index 74508b0f9c47..eee370492eee 100644 --- a/sound/soc/Makefile +++ b/sound/soc/Makefile @@ -57,4 +57,3 @@ obj-$(CONFIG_SND_SOC) += uniphier/ obj-$(CONFIG_SND_SOC) += ux500/ obj-$(CONFIG_SND_SOC) += xilinx/ obj-$(CONFIG_SND_SOC) += xtensa/ -obj-$(CONFIG_SND_SOC) += zte/ diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile index c30762fc9b87..628b0c9b3e2a 100644 --- a/sound/soc/codecs/Makefile +++ b/sound/soc/codecs/Makefile @@ -301,7 +301,6 @@ snd-soc-wm9713-objs := wm9713.o snd-soc-wm-hubs-objs := wm_hubs.o snd-soc-wsa881x-objs := wsa881x.o snd-soc-zl38060-objs := zl38060.o -snd-soc-zx-aud96p22-objs := zx_aud96p22.o # Amp snd-soc-max9877-objs := max9877.o snd-soc-max98504-objs := max98504.o @@ -616,7 +615,6 @@ obj-$(CONFIG_SND_SOC_WM_ADSP) += snd-soc-wm-adsp.o obj-$(CONFIG_SND_SOC_WM_HUBS) += snd-soc-wm-hubs.o obj-$(CONFIG_SND_SOC_WSA881X) += snd-soc-wsa881x.o obj-$(CONFIG_SND_SOC_ZL38060) += snd-soc-zl38060.o -obj-$(CONFIG_SND_SOC_ZX_AUD96P22) += snd-soc-zx-aud96p22.o # Amp obj-$(CONFIG_SND_SOC_MAX9877) += snd-soc-max9877.o diff --git a/sound/soc/codecs/zx_aud96p22.c b/sound/soc/codecs/zx_aud96p22.c deleted file mode 100644 index 16d44efb132d..000000000000 --- a/sound/soc/codecs/zx_aud96p22.c +++ /dev/null @@ -1,401 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Copyright (C) 2017 Sanechips Technology Co., Ltd. - * Copyright 2017 Linaro Ltd. - * - * Author: Baoyou Xie - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define AUD96P22_RESET 0x00 -#define RST_DAC_DPZ BIT(0) -#define RST_ADC_DPZ BIT(1) -#define AUD96P22_I2S1_CONFIG_0 0x03 -#define I2S1_MS_MODE BIT(3) -#define I2S1_MODE_MASK 0x7 -#define I2S1_MODE_RIGHT_J 0x0 -#define I2S1_MODE_I2S 0x1 -#define I2S1_MODE_LEFT_J 0x2 -#define AUD96P22_PD_0 0x15 -#define AUD96P22_PD_1 0x16 -#define AUD96P22_PD_3 0x18 -#define AUD96P22_PD_4 0x19 -#define AUD96P22_MUTE_0 0x1d -#define AUD96P22_MUTE_2 0x1f -#define AUD96P22_MUTE_4 0x21 -#define AUD96P22_RECVOL_0 0x24 -#define AUD96P22_RECVOL_1 0x25 -#define AUD96P22_PGA1VOL_0 0x26 -#define AUD96P22_PGA1VOL_1 0x27 -#define AUD96P22_LMVOL_0 0x34 -#define AUD96P22_LMVOL_1 0x35 -#define AUD96P22_HS1VOL_0 0x38 -#define AUD96P22_HS1VOL_1 0x39 -#define AUD96P22_PGA1SEL_0 0x47 -#define AUD96P22_PGA1SEL_1 0x48 -#define AUD96P22_LDR1SEL_0 0x59 -#define AUD96P22_LDR1SEL_1 0x60 -#define AUD96P22_LDR2SEL_0 0x5d -#define AUD96P22_REG_MAX 0xfb - -struct aud96p22_priv { - struct regmap *regmap; -}; - -static int aud96p22_adc_event(struct snd_soc_dapm_widget *w, - struct snd_kcontrol *kcontrol, int event) -{ - struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); - struct aud96p22_priv *priv = snd_soc_component_get_drvdata(component); - struct regmap *regmap = priv->regmap; - - if (event != SND_SOC_DAPM_POST_PMU) - return -EINVAL; - - /* Assert/de-assert the bit to reset ADC data path */ - regmap_update_bits(regmap, AUD96P22_RESET, RST_ADC_DPZ, 0); - regmap_update_bits(regmap, AUD96P22_RESET, RST_ADC_DPZ, RST_ADC_DPZ); - - return 0; -} - -static int aud96p22_dac_event(struct snd_soc_dapm_widget *w, - struct snd_kcontrol *kcontrol, int event) -{ - struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); - struct aud96p22_priv *priv = snd_soc_component_get_drvdata(component); - struct regmap *regmap = priv->regmap; - - if (event != SND_SOC_DAPM_POST_PMU) - return -EINVAL; - - /* Assert/de-assert the bit to reset DAC data path */ - regmap_update_bits(regmap, AUD96P22_RESET, RST_DAC_DPZ, 0); - regmap_update_bits(regmap, AUD96P22_RESET, RST_DAC_DPZ, RST_DAC_DPZ); - - return 0; -} - -static const DECLARE_TLV_DB_SCALE(lm_tlv, -11550, 50, 0); -static const DECLARE_TLV_DB_SCALE(hs_tlv, -3900, 300, 0); -static const DECLARE_TLV_DB_SCALE(rec_tlv, -9550, 50, 0); -static const DECLARE_TLV_DB_SCALE(pga_tlv, -1800, 100, 0); - -static const struct snd_kcontrol_new aud96p22_snd_controls[] = { - /* Volume control */ - SOC_DOUBLE_R_TLV("Master Playback Volume", AUD96P22_LMVOL_0, - AUD96P22_LMVOL_1, 0, 0xff, 0, lm_tlv), - SOC_DOUBLE_R_TLV("Headphone Volume", AUD96P22_HS1VOL_0, - AUD96P22_HS1VOL_1, 0, 0xf, 0, hs_tlv), - SOC_DOUBLE_R_TLV("Master Capture Volume", AUD96P22_RECVOL_0, - AUD96P22_RECVOL_1, 0, 0xff, 0, rec_tlv), - SOC_DOUBLE_R_TLV("Analogue Capture Volume", AUD96P22_PGA1VOL_0, - AUD96P22_PGA1VOL_1, 0, 0x37, 0, pga_tlv), - - /* Mute control */ - SOC_DOUBLE("Master Playback Switch", AUD96P22_MUTE_2, 0, 1, 1, 1), - SOC_DOUBLE("Headphone Switch", AUD96P22_MUTE_2, 4, 5, 1, 1), - SOC_DOUBLE("Line Out Switch", AUD96P22_MUTE_4, 0, 1, 1, 1), - SOC_DOUBLE("Speaker Switch", AUD96P22_MUTE_4, 2, 3, 1, 1), - SOC_DOUBLE("Master Capture Switch", AUD96P22_MUTE_0, 0, 1, 1, 1), - SOC_DOUBLE("Analogue Capture Switch", AUD96P22_MUTE_0, 2, 3, 1, 1), -}; - -/* Input mux kcontrols */ -static const unsigned int ain_mux_values[] = { - 0, 1, 3, 4, 5, -}; - -static const char * const ainl_mux_texts[] = { - "AINL1 differential", - "AINL1 single-ended", - "AINL3 single-ended", - "AINL2 differential", - "AINL2 single-ended", -}; - -static const char * const ainr_mux_texts[] = { - "AINR1 differential", - "AINR1 single-ended", - "AINR3 single-ended", - "AINR2 differential", - "AINR2 single-ended", -}; - -static SOC_VALUE_ENUM_SINGLE_DECL(ainl_mux_enum, AUD96P22_PGA1SEL_0, - 0, 0x7, ainl_mux_texts, ain_mux_values); -static SOC_VALUE_ENUM_SINGLE_DECL(ainr_mux_enum, AUD96P22_PGA1SEL_1, - 0, 0x7, ainr_mux_texts, ain_mux_values); - -static const struct snd_kcontrol_new ainl_mux_kcontrol = - SOC_DAPM_ENUM("AINL Mux", ainl_mux_enum); -static const struct snd_kcontrol_new ainr_mux_kcontrol = - SOC_DAPM_ENUM("AINR Mux", ainr_mux_enum); - -/* Output mixer kcontrols */ -static const struct snd_kcontrol_new ld1_left_kcontrols[] = { - SOC_DAPM_SINGLE("DACL LD1L Switch", AUD96P22_LDR1SEL_0, 0, 1, 0), - SOC_DAPM_SINGLE("AINL LD1L Switch", AUD96P22_LDR1SEL_0, 1, 1, 0), - SOC_DAPM_SINGLE("AINR LD1L Switch", AUD96P22_LDR1SEL_0, 2, 1, 0), -}; - -static const struct snd_kcontrol_new ld1_right_kcontrols[] = { - SOC_DAPM_SINGLE("DACR LD1R Switch", AUD96P22_LDR1SEL_1, 8, 1, 0), - SOC_DAPM_SINGLE("AINR LD1R Switch", AUD96P22_LDR1SEL_1, 9, 1, 0), - SOC_DAPM_SINGLE("AINL LD1R Switch", AUD96P22_LDR1SEL_1, 10, 1, 0), -}; - -static const struct snd_kcontrol_new ld2_kcontrols[] = { - SOC_DAPM_SINGLE("DACL LD2 Switch", AUD96P22_LDR2SEL_0, 0, 1, 0), - SOC_DAPM_SINGLE("AINL LD2 Switch", AUD96P22_LDR2SEL_0, 1, 1, 0), - SOC_DAPM_SINGLE("DACR LD2 Switch", AUD96P22_LDR2SEL_0, 2, 1, 0), -}; - -static const struct snd_soc_dapm_widget aud96p22_dapm_widgets[] = { - /* Overall power bit */ - SND_SOC_DAPM_SUPPLY("POWER", AUD96P22_PD_0, 0, 0, NULL, 0), - - /* Input pins */ - SND_SOC_DAPM_INPUT("AINL1P"), - SND_SOC_DAPM_INPUT("AINL2P"), - SND_SOC_DAPM_INPUT("AINL3"), - SND_SOC_DAPM_INPUT("AINL1N"), - SND_SOC_DAPM_INPUT("AINL2N"), - SND_SOC_DAPM_INPUT("AINR2N"), - SND_SOC_DAPM_INPUT("AINR1N"), - SND_SOC_DAPM_INPUT("AINR3"), - SND_SOC_DAPM_INPUT("AINR2P"), - SND_SOC_DAPM_INPUT("AINR1P"), - - /* Input muxes */ - SND_SOC_DAPM_MUX("AINLMUX", AUD96P22_PD_1, 2, 0, &ainl_mux_kcontrol), - SND_SOC_DAPM_MUX("AINRMUX", AUD96P22_PD_1, 3, 0, &ainr_mux_kcontrol), - - /* ADCs */ - SND_SOC_DAPM_ADC_E("ADCL", "Capture Left", AUD96P22_PD_1, 0, 0, - aud96p22_adc_event, SND_SOC_DAPM_POST_PMU), - SND_SOC_DAPM_ADC_E("ADCR", "Capture Right", AUD96P22_PD_1, 1, 0, - aud96p22_adc_event, SND_SOC_DAPM_POST_PMU), - - /* DACs */ - SND_SOC_DAPM_DAC_E("DACL", "Playback Left", AUD96P22_PD_3, 0, 0, - aud96p22_dac_event, SND_SOC_DAPM_POST_PMU), - SND_SOC_DAPM_DAC_E("DACR", "Playback Right", AUD96P22_PD_3, 1, 0, - aud96p22_dac_event, SND_SOC_DAPM_POST_PMU), - - /* Output mixers */ - SND_SOC_DAPM_MIXER("LD1L", AUD96P22_PD_3, 6, 0, ld1_left_kcontrols, - ARRAY_SIZE(ld1_left_kcontrols)), - SND_SOC_DAPM_MIXER("LD1R", AUD96P22_PD_3, 7, 0, ld1_right_kcontrols, - ARRAY_SIZE(ld1_right_kcontrols)), - SND_SOC_DAPM_MIXER("LD2", AUD96P22_PD_4, 2, 0, ld2_kcontrols, - ARRAY_SIZE(ld2_kcontrols)), - - /* Headset power switch */ - SND_SOC_DAPM_SUPPLY("HS1L", AUD96P22_PD_3, 4, 0, NULL, 0), - SND_SOC_DAPM_SUPPLY("HS1R", AUD96P22_PD_3, 5, 0, NULL, 0), - - /* Output pins */ - SND_SOC_DAPM_OUTPUT("HSOUTL"), - SND_SOC_DAPM_OUTPUT("LINEOUTL"), - SND_SOC_DAPM_OUTPUT("LINEOUTMP"), - SND_SOC_DAPM_OUTPUT("LINEOUTMN"), - SND_SOC_DAPM_OUTPUT("LINEOUTR"), - SND_SOC_DAPM_OUTPUT("HSOUTR"), -}; - -static const struct snd_soc_dapm_route aud96p22_dapm_routes[] = { - { "AINLMUX", "AINL1 differential", "AINL1N" }, - { "AINLMUX", "AINL1 single-ended", "AINL1P" }, - { "AINLMUX", "AINL3 single-ended", "AINL3" }, - { "AINLMUX", "AINL2 differential", "AINL2N" }, - { "AINLMUX", "AINL2 single-ended", "AINL2P" }, - - { "AINRMUX", "AINR1 differential", "AINR1N" }, - { "AINRMUX", "AINR1 single-ended", "AINR1P" }, - { "AINRMUX", "AINR3 single-ended", "AINR3" }, - { "AINRMUX", "AINR2 differential", "AINR2N" }, - { "AINRMUX", "AINR2 single-ended", "AINR2P" }, - - { "ADCL", NULL, "AINLMUX" }, - { "ADCR", NULL, "AINRMUX" }, - - { "ADCL", NULL, "POWER" }, - { "ADCR", NULL, "POWER" }, - { "DACL", NULL, "POWER" }, - { "DACR", NULL, "POWER" }, - - { "LD1L", "DACL LD1L Switch", "DACL" }, - { "LD1L", "AINL LD1L Switch", "AINLMUX" }, - { "LD1L", "AINR LD1L Switch", "AINRMUX" }, - - { "LD1R", "DACR LD1R Switch", "DACR" }, - { "LD1R", "AINR LD1R Switch", "AINRMUX" }, - { "LD1R", "AINL LD1R Switch", "AINLMUX" }, - - { "LD2", "DACL LD2 Switch", "DACL" }, - { "LD2", "AINL LD2 Switch", "AINLMUX" }, - { "LD2", "DACR LD2 Switch", "DACR" }, - - { "HSOUTL", NULL, "LD1L" }, - { "HSOUTR", NULL, "LD1R" }, - { "HSOUTL", NULL, "HS1L" }, - { "HSOUTR", NULL, "HS1R" }, - - { "LINEOUTL", NULL, "LD1L" }, - { "LINEOUTR", NULL, "LD1R" }, - - { "LINEOUTMP", NULL, "LD2" }, - { "LINEOUTMN", NULL, "LD2" }, -}; - -static const struct snd_soc_component_driver aud96p22_driver = { - .controls = aud96p22_snd_controls, - .num_controls = ARRAY_SIZE(aud96p22_snd_controls), - .dapm_widgets = aud96p22_dapm_widgets, - .num_dapm_widgets = ARRAY_SIZE(aud96p22_dapm_widgets), - .dapm_routes = aud96p22_dapm_routes, - .num_dapm_routes = ARRAY_SIZE(aud96p22_dapm_routes), - .idle_bias_on = 1, - .use_pmdown_time = 1, - .endianness = 1, - .non_legacy_dai_naming = 1, -}; - -static int aud96p22_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) -{ - struct aud96p22_priv *priv = snd_soc_component_get_drvdata(dai->component); - struct regmap *regmap = priv->regmap; - unsigned int val; - - /* Master/slave mode */ - switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { - case SND_SOC_DAIFMT_CBS_CFS: - val = 0; - break; - case SND_SOC_DAIFMT_CBM_CFM: - val = I2S1_MS_MODE; - break; - default: - return -EINVAL; - } - - regmap_update_bits(regmap, AUD96P22_I2S1_CONFIG_0, I2S1_MS_MODE, val); - - /* Audio format */ - switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { - case SND_SOC_DAIFMT_RIGHT_J: - val = I2S1_MODE_RIGHT_J; - break; - case SND_SOC_DAIFMT_I2S: - val = I2S1_MODE_I2S; - break; - case SND_SOC_DAIFMT_LEFT_J: - val = I2S1_MODE_LEFT_J; - break; - default: - return -EINVAL; - } - - regmap_update_bits(regmap, AUD96P22_I2S1_CONFIG_0, I2S1_MODE_MASK, val); - - return 0; -} - -static const struct snd_soc_dai_ops aud96p22_dai_ops = { - .set_fmt = aud96p22_set_fmt, -}; - -#define AUD96P22_RATES SNDRV_PCM_RATE_8000_192000 -#define AUD96P22_FORMATS (\ - SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S18_3LE | \ - SNDRV_PCM_FMTBIT_S20_3LE | SNDRV_PCM_FMTBIT_S24_LE) - -static struct snd_soc_dai_driver aud96p22_dai = { - .name = "aud96p22-dai", - .playback = { - .stream_name = "Playback", - .channels_min = 1, - .channels_max = 2, - .rates = AUD96P22_RATES, - .formats = AUD96P22_FORMATS, - }, - .capture = { - .stream_name = "Capture", - .channels_min = 1, - .channels_max = 2, - .rates = AUD96P22_RATES, - .formats = AUD96P22_FORMATS, - }, - .ops = &aud96p22_dai_ops, -}; - -static const struct regmap_config aud96p22_regmap = { - .reg_bits = 8, - .val_bits = 8, - .max_register = AUD96P22_REG_MAX, - .cache_type = REGCACHE_RBTREE, -}; - -static int aud96p22_i2c_probe(struct i2c_client *i2c, - const struct i2c_device_id *id) -{ - struct device *dev = &i2c->dev; - struct aud96p22_priv *priv; - int ret; - - priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); - if (priv == NULL) - return -ENOMEM; - - priv->regmap = devm_regmap_init_i2c(i2c, &aud96p22_regmap); - if (IS_ERR(priv->regmap)) { - ret = PTR_ERR(priv->regmap); - dev_err(dev, "failed to init i2c regmap: %d\n", ret); - return ret; - } - - i2c_set_clientdata(i2c, priv); - - ret = devm_snd_soc_register_component(dev, &aud96p22_driver, &aud96p22_dai, 1); - if (ret) { - dev_err(dev, "failed to register component: %d\n", ret); - return ret; - } - - return 0; -} - -static int aud96p22_i2c_remove(struct i2c_client *i2c) -{ - return 0; -} - -static const struct of_device_id aud96p22_dt_ids[] = { - { .compatible = "zte,zx-aud96p22", }, - { } -}; -MODULE_DEVICE_TABLE(of, aud96p22_dt_ids); - -static struct i2c_driver aud96p22_i2c_driver = { - .driver = { - .name = "zx_aud96p22", - .of_match_table = aud96p22_dt_ids, - }, - .probe = aud96p22_i2c_probe, - .remove = aud96p22_i2c_remove, -}; -module_i2c_driver(aud96p22_i2c_driver); - -MODULE_DESCRIPTION("ZTE ASoC AUD96P22 CODEC driver"); -MODULE_AUTHOR("Baoyou Xie "); -MODULE_LICENSE("GPL v2"); diff --git a/sound/soc/zte/Kconfig b/sound/soc/zte/Kconfig deleted file mode 100644 index a23d4f13ca19..000000000000 --- a/sound/soc/zte/Kconfig +++ /dev/null @@ -1,26 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0-only -config ZX_SPDIF - tristate "ZTE ZX SPDIF Driver Support" - depends on ARCH_ZX || COMPILE_TEST - depends on COMMON_CLK - select SND_SOC_GENERIC_DMAENGINE_PCM - help - Say Y or M if you want to add support for codecs attached to the - ZTE ZX SPDIF interface - -config ZX_I2S - tristate "ZTE ZX I2S Driver Support" - depends on ARCH_ZX || COMPILE_TEST - depends on COMMON_CLK - select SND_SOC_GENERIC_DMAENGINE_PCM - help - Say Y or M if you want to add support for codecs attached to the - ZTE ZX I2S interface - -config ZX_TDM - tristate "ZTE ZX TDM Driver Support" - depends on COMMON_CLK - select SND_SOC_GENERIC_DMAENGINE_PCM - help - Say Y or M if you want to add support for codecs attached to the - ZTE ZX TDM interface diff --git a/sound/soc/zte/Makefile b/sound/soc/zte/Makefile deleted file mode 100644 index 2f7cdefa42df..000000000000 --- a/sound/soc/zte/Makefile +++ /dev/null @@ -1,4 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0-only -obj-$(CONFIG_ZX_SPDIF) += zx-spdif.o -obj-$(CONFIG_ZX_I2S) += zx-i2s.o -obj-$(CONFIG_ZX_TDM) += zx-tdm.o diff --git a/sound/soc/zte/zx-i2s.c b/sound/soc/zte/zx-i2s.c deleted file mode 100644 index 1c1a44e08a67..000000000000 --- a/sound/soc/zte/zx-i2s.c +++ /dev/null @@ -1,452 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Copyright (C) 2015 Linaro - * - * Author: Jun Nie - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#define ZX_I2S_PROCESS_CTRL 0x04 -#define ZX_I2S_TIMING_CTRL 0x08 -#define ZX_I2S_FIFO_CTRL 0x0C -#define ZX_I2S_FIFO_STATUS 0x10 -#define ZX_I2S_INT_EN 0x14 -#define ZX_I2S_INT_STATUS 0x18 -#define ZX_I2S_DATA 0x1C -#define ZX_I2S_FRAME_CNTR 0x20 - -#define I2S_DEAGULT_FIFO_THRES (0x10) -#define I2S_MAX_FIFO_THRES (0x20) - -#define ZX_I2S_PROCESS_TX_EN (1 << 0) -#define ZX_I2S_PROCESS_TX_DIS (0 << 0) -#define ZX_I2S_PROCESS_RX_EN (1 << 1) -#define ZX_I2S_PROCESS_RX_DIS (0 << 1) -#define ZX_I2S_PROCESS_I2S_EN (1 << 2) -#define ZX_I2S_PROCESS_I2S_DIS (0 << 2) - -#define ZX_I2S_TIMING_MAST (1 << 0) -#define ZX_I2S_TIMING_SLAVE (0 << 0) -#define ZX_I2S_TIMING_MS_MASK (1 << 0) -#define ZX_I2S_TIMING_LOOP (1 << 1) -#define ZX_I2S_TIMING_NOR (0 << 1) -#define ZX_I2S_TIMING_LOOP_MASK (1 << 1) -#define ZX_I2S_TIMING_PTNR (1 << 2) -#define ZX_I2S_TIMING_NTPR (0 << 2) -#define ZX_I2S_TIMING_PHASE_MASK (1 << 2) -#define ZX_I2S_TIMING_TDM (1 << 3) -#define ZX_I2S_TIMING_I2S (0 << 3) -#define ZX_I2S_TIMING_TIMING_MASK (1 << 3) -#define ZX_I2S_TIMING_LONG_SYNC (1 << 4) -#define ZX_I2S_TIMING_SHORT_SYNC (0 << 4) -#define ZX_I2S_TIMING_SYNC_MASK (1 << 4) -#define ZX_I2S_TIMING_TEAK_EN (1 << 5) -#define ZX_I2S_TIMING_TEAK_DIS (0 << 5) -#define ZX_I2S_TIMING_TEAK_MASK (1 << 5) -#define ZX_I2S_TIMING_STD_I2S (0 << 6) -#define ZX_I2S_TIMING_MSB_JUSTIF (1 << 6) -#define ZX_I2S_TIMING_LSB_JUSTIF (2 << 6) -#define ZX_I2S_TIMING_ALIGN_MASK (3 << 6) -#define ZX_I2S_TIMING_CHN_MASK (7 << 8) -#define ZX_I2S_TIMING_CHN(x) ((x - 1) << 8) -#define ZX_I2S_TIMING_LANE_MASK (3 << 11) -#define ZX_I2S_TIMING_LANE(x) ((x - 1) << 11) -#define ZX_I2S_TIMING_TSCFG_MASK (7 << 13) -#define ZX_I2S_TIMING_TSCFG(x) (x << 13) -#define ZX_I2S_TIMING_TS_WIDTH_MASK (0x1f << 16) -#define ZX_I2S_TIMING_TS_WIDTH(x) ((x - 1) << 16) -#define ZX_I2S_TIMING_DATA_SIZE_MASK (0x1f << 21) -#define ZX_I2S_TIMING_DATA_SIZE(x) ((x - 1) << 21) -#define ZX_I2S_TIMING_CFG_ERR_MASK (1 << 31) - -#define ZX_I2S_FIFO_CTRL_TX_RST (1 << 0) -#define ZX_I2S_FIFO_CTRL_TX_RST_MASK (1 << 0) -#define ZX_I2S_FIFO_CTRL_RX_RST (1 << 1) -#define ZX_I2S_FIFO_CTRL_RX_RST_MASK (1 << 1) -#define ZX_I2S_FIFO_CTRL_TX_DMA_EN (1 << 4) -#define ZX_I2S_FIFO_CTRL_TX_DMA_DIS (0 << 4) -#define ZX_I2S_FIFO_CTRL_TX_DMA_MASK (1 << 4) -#define ZX_I2S_FIFO_CTRL_RX_DMA_EN (1 << 5) -#define ZX_I2S_FIFO_CTRL_RX_DMA_DIS (0 << 5) -#define ZX_I2S_FIFO_CTRL_RX_DMA_MASK (1 << 5) -#define ZX_I2S_FIFO_CTRL_TX_THRES_MASK (0x1F << 8) -#define ZX_I2S_FIFO_CTRL_RX_THRES_MASK (0x1F << 16) - -#define CLK_RAT (32 * 4) - -struct zx_i2s_info { - struct snd_dmaengine_dai_dma_data dma_playback; - struct snd_dmaengine_dai_dma_data dma_capture; - struct clk *dai_wclk; - struct clk *dai_pclk; - void __iomem *reg_base; - int master; - resource_size_t mapbase; -}; - -static void zx_i2s_tx_en(void __iomem *base, bool on) -{ - unsigned long val; - - val = readl_relaxed(base + ZX_I2S_PROCESS_CTRL); - if (on) - val |= ZX_I2S_PROCESS_TX_EN | ZX_I2S_PROCESS_I2S_EN; - else - val &= ~(ZX_I2S_PROCESS_TX_EN | ZX_I2S_PROCESS_I2S_EN); - writel_relaxed(val, base + ZX_I2S_PROCESS_CTRL); -} - -static void zx_i2s_rx_en(void __iomem *base, bool on) -{ - unsigned long val; - - val = readl_relaxed(base + ZX_I2S_PROCESS_CTRL); - if (on) - val |= ZX_I2S_PROCESS_RX_EN | ZX_I2S_PROCESS_I2S_EN; - else - val &= ~(ZX_I2S_PROCESS_RX_EN | ZX_I2S_PROCESS_I2S_EN); - writel_relaxed(val, base + ZX_I2S_PROCESS_CTRL); -} - -static void zx_i2s_tx_dma_en(void __iomem *base, bool on) -{ - unsigned long val; - - val = readl_relaxed(base + ZX_I2S_FIFO_CTRL); - val |= ZX_I2S_FIFO_CTRL_TX_RST | (I2S_DEAGULT_FIFO_THRES << 8); - if (on) - val |= ZX_I2S_FIFO_CTRL_TX_DMA_EN; - else - val &= ~ZX_I2S_FIFO_CTRL_TX_DMA_EN; - writel_relaxed(val, base + ZX_I2S_FIFO_CTRL); -} - -static void zx_i2s_rx_dma_en(void __iomem *base, bool on) -{ - unsigned long val; - - val = readl_relaxed(base + ZX_I2S_FIFO_CTRL); - val |= ZX_I2S_FIFO_CTRL_RX_RST | (I2S_DEAGULT_FIFO_THRES << 16); - if (on) - val |= ZX_I2S_FIFO_CTRL_RX_DMA_EN; - else - val &= ~ZX_I2S_FIFO_CTRL_RX_DMA_EN; - writel_relaxed(val, base + ZX_I2S_FIFO_CTRL); -} - -#define ZX_I2S_RATES \ - (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 | SNDRV_PCM_RATE_16000 | \ - SNDRV_PCM_RATE_22050 | SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | \ - SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000| \ - SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_192000) - -#define ZX_I2S_FMTBIT \ - (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE | \ - SNDRV_PCM_FMTBIT_S32_LE) - -static int zx_i2s_dai_probe(struct snd_soc_dai *dai) -{ - struct zx_i2s_info *zx_i2s = dev_get_drvdata(dai->dev); - - snd_soc_dai_set_drvdata(dai, zx_i2s); - zx_i2s->dma_playback.addr = zx_i2s->mapbase + ZX_I2S_DATA; - zx_i2s->dma_playback.maxburst = 16; - zx_i2s->dma_capture.addr = zx_i2s->mapbase + ZX_I2S_DATA; - zx_i2s->dma_capture.maxburst = 16; - snd_soc_dai_init_dma_data(dai, &zx_i2s->dma_playback, - &zx_i2s->dma_capture); - return 0; -} - -static int zx_i2s_set_fmt(struct snd_soc_dai *cpu_dai, unsigned int fmt) -{ - struct zx_i2s_info *i2s = snd_soc_dai_get_drvdata(cpu_dai); - unsigned long val; - - val = readl_relaxed(i2s->reg_base + ZX_I2S_TIMING_CTRL); - val &= ~(ZX_I2S_TIMING_TIMING_MASK | ZX_I2S_TIMING_ALIGN_MASK | - ZX_I2S_TIMING_TEAK_MASK | ZX_I2S_TIMING_SYNC_MASK | - ZX_I2S_TIMING_MS_MASK); - - switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { - case SND_SOC_DAIFMT_I2S: - val |= (ZX_I2S_TIMING_I2S | ZX_I2S_TIMING_STD_I2S); - break; - case SND_SOC_DAIFMT_LEFT_J: - val |= (ZX_I2S_TIMING_I2S | ZX_I2S_TIMING_MSB_JUSTIF); - break; - case SND_SOC_DAIFMT_RIGHT_J: - val |= (ZX_I2S_TIMING_I2S | ZX_I2S_TIMING_LSB_JUSTIF); - break; - default: - dev_err(cpu_dai->dev, "Unknown i2s timing\n"); - return -EINVAL; - } - - switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { - case SND_SOC_DAIFMT_CBM_CFM: - /* Codec is master, and I2S is slave. */ - i2s->master = 0; - val |= ZX_I2S_TIMING_SLAVE; - break; - case SND_SOC_DAIFMT_CBS_CFS: - /* Codec is slave, and I2S is master. */ - i2s->master = 1; - val |= ZX_I2S_TIMING_MAST; - break; - default: - dev_err(cpu_dai->dev, "Unknown master/slave format\n"); - return -EINVAL; - } - - writel_relaxed(val, i2s->reg_base + ZX_I2S_TIMING_CTRL); - return 0; -} - -static int zx_i2s_hw_params(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *params, - struct snd_soc_dai *socdai) -{ - struct zx_i2s_info *i2s = snd_soc_dai_get_drvdata(socdai); - struct snd_dmaengine_dai_dma_data *dma_data; - unsigned int lane, ch_num, len, ret = 0; - unsigned int ts_width = 32; - unsigned long val; - unsigned long chn_cfg; - - dma_data = snd_soc_dai_get_dma_data(socdai, substream); - dma_data->addr_width = ts_width >> 3; - - val = readl_relaxed(i2s->reg_base + ZX_I2S_TIMING_CTRL); - val &= ~(ZX_I2S_TIMING_TS_WIDTH_MASK | ZX_I2S_TIMING_DATA_SIZE_MASK | - ZX_I2S_TIMING_LANE_MASK | ZX_I2S_TIMING_CHN_MASK | - ZX_I2S_TIMING_TSCFG_MASK); - - switch (params_format(params)) { - case SNDRV_PCM_FORMAT_S16_LE: - len = 16; - break; - case SNDRV_PCM_FORMAT_S24_LE: - len = 24; - break; - case SNDRV_PCM_FORMAT_S32_LE: - len = 32; - break; - default: - dev_err(socdai->dev, "Unknown data format\n"); - return -EINVAL; - } - val |= ZX_I2S_TIMING_TS_WIDTH(ts_width) | ZX_I2S_TIMING_DATA_SIZE(len); - - ch_num = params_channels(params); - switch (ch_num) { - case 1: - lane = 1; - chn_cfg = 2; - break; - case 2: - case 4: - case 6: - case 8: - lane = ch_num / 2; - chn_cfg = 3; - break; - default: - dev_err(socdai->dev, "Not support channel num %d\n", ch_num); - return -EINVAL; - } - val |= ZX_I2S_TIMING_LANE(lane); - val |= ZX_I2S_TIMING_TSCFG(chn_cfg); - val |= ZX_I2S_TIMING_CHN(ch_num); - writel_relaxed(val, i2s->reg_base + ZX_I2S_TIMING_CTRL); - - if (i2s->master) - ret = clk_set_rate(i2s->dai_wclk, - params_rate(params) * ch_num * CLK_RAT); - - return ret; -} - -static int zx_i2s_trigger(struct snd_pcm_substream *substream, int cmd, - struct snd_soc_dai *dai) -{ - struct zx_i2s_info *zx_i2s = dev_get_drvdata(dai->dev); - int capture = (substream->stream == SNDRV_PCM_STREAM_CAPTURE); - int ret = 0; - - switch (cmd) { - case SNDRV_PCM_TRIGGER_START: - if (capture) - zx_i2s_rx_dma_en(zx_i2s->reg_base, true); - else - zx_i2s_tx_dma_en(zx_i2s->reg_base, true); - fallthrough; - case SNDRV_PCM_TRIGGER_RESUME: - case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: - if (capture) - zx_i2s_rx_en(zx_i2s->reg_base, true); - else - zx_i2s_tx_en(zx_i2s->reg_base, true); - break; - - case SNDRV_PCM_TRIGGER_STOP: - if (capture) - zx_i2s_rx_dma_en(zx_i2s->reg_base, false); - else - zx_i2s_tx_dma_en(zx_i2s->reg_base, false); - fallthrough; - case SNDRV_PCM_TRIGGER_SUSPEND: - case SNDRV_PCM_TRIGGER_PAUSE_PUSH: - if (capture) - zx_i2s_rx_en(zx_i2s->reg_base, false); - else - zx_i2s_tx_en(zx_i2s->reg_base, false); - break; - - default: - ret = -EINVAL; - break; - } - - return ret; -} - -static int zx_i2s_startup(struct snd_pcm_substream *substream, - struct snd_soc_dai *dai) -{ - struct zx_i2s_info *zx_i2s = dev_get_drvdata(dai->dev); - int ret; - - ret = clk_prepare_enable(zx_i2s->dai_wclk); - if (ret) - return ret; - - ret = clk_prepare_enable(zx_i2s->dai_pclk); - if (ret) { - clk_disable_unprepare(zx_i2s->dai_wclk); - return ret; - } - - return ret; -} - -static void zx_i2s_shutdown(struct snd_pcm_substream *substream, - struct snd_soc_dai *dai) -{ - struct zx_i2s_info *zx_i2s = dev_get_drvdata(dai->dev); - - clk_disable_unprepare(zx_i2s->dai_wclk); - clk_disable_unprepare(zx_i2s->dai_pclk); -} - -static const struct snd_soc_dai_ops zx_i2s_dai_ops = { - .trigger = zx_i2s_trigger, - .hw_params = zx_i2s_hw_params, - .set_fmt = zx_i2s_set_fmt, - .startup = zx_i2s_startup, - .shutdown = zx_i2s_shutdown, -}; - -static const struct snd_soc_component_driver zx_i2s_component = { - .name = "zx-i2s", -}; - -static struct snd_soc_dai_driver zx_i2s_dai = { - .name = "zx-i2s-dai", - .id = 0, - .probe = zx_i2s_dai_probe, - .playback = { - .channels_min = 1, - .channels_max = 8, - .rates = ZX_I2S_RATES, - .formats = ZX_I2S_FMTBIT, - }, - .capture = { - .channels_min = 1, - .channels_max = 2, - .rates = ZX_I2S_RATES, - .formats = ZX_I2S_FMTBIT, - }, - .ops = &zx_i2s_dai_ops, -}; - -static int zx_i2s_probe(struct platform_device *pdev) -{ - struct resource *res; - struct zx_i2s_info *zx_i2s; - int ret; - - zx_i2s = devm_kzalloc(&pdev->dev, sizeof(*zx_i2s), GFP_KERNEL); - if (!zx_i2s) - return -ENOMEM; - - zx_i2s->dai_wclk = devm_clk_get(&pdev->dev, "wclk"); - if (IS_ERR(zx_i2s->dai_wclk)) { - dev_err(&pdev->dev, "Fail to get wclk\n"); - return PTR_ERR(zx_i2s->dai_wclk); - } - - zx_i2s->dai_pclk = devm_clk_get(&pdev->dev, "pclk"); - if (IS_ERR(zx_i2s->dai_pclk)) { - dev_err(&pdev->dev, "Fail to get pclk\n"); - return PTR_ERR(zx_i2s->dai_pclk); - } - - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - zx_i2s->mapbase = res->start; - zx_i2s->reg_base = devm_ioremap_resource(&pdev->dev, res); - if (IS_ERR(zx_i2s->reg_base)) { - dev_err(&pdev->dev, "ioremap failed!\n"); - return PTR_ERR(zx_i2s->reg_base); - } - - writel_relaxed(0, zx_i2s->reg_base + ZX_I2S_FIFO_CTRL); - platform_set_drvdata(pdev, zx_i2s); - - ret = devm_snd_soc_register_component(&pdev->dev, &zx_i2s_component, - &zx_i2s_dai, 1); - if (ret) { - dev_err(&pdev->dev, "Register DAI failed: %d\n", ret); - return ret; - } - - ret = devm_snd_dmaengine_pcm_register(&pdev->dev, NULL, 0); - if (ret) - dev_err(&pdev->dev, "Register platform PCM failed: %d\n", ret); - - return ret; -} - -static const struct of_device_id zx_i2s_dt_ids[] = { - { .compatible = "zte,zx296702-i2s", }, - {} -}; -MODULE_DEVICE_TABLE(of, zx_i2s_dt_ids); - -static struct platform_driver i2s_driver = { - .probe = zx_i2s_probe, - .driver = { - .name = "zx-i2s", - .of_match_table = zx_i2s_dt_ids, - }, -}; - -module_platform_driver(i2s_driver); - -MODULE_AUTHOR("Jun Nie "); -MODULE_DESCRIPTION("ZTE I2S SoC DAI"); -MODULE_LICENSE("GPL"); diff --git a/sound/soc/zte/zx-spdif.c b/sound/soc/zte/zx-spdif.c deleted file mode 100644 index b4168bd532b7..000000000000 --- a/sound/soc/zte/zx-spdif.c +++ /dev/null @@ -1,363 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Copyright (C) 2015 Linaro - * - * Author: Jun Nie - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define ZX_CTRL 0x04 -#define ZX_FIFOCTRL 0x08 -#define ZX_INT_STATUS 0x10 -#define ZX_INT_MASK 0x14 -#define ZX_DATA 0x18 -#define ZX_VALID_BIT 0x1c -#define ZX_CH_STA_1 0x20 -#define ZX_CH_STA_2 0x24 -#define ZX_CH_STA_3 0x28 -#define ZX_CH_STA_4 0x2c -#define ZX_CH_STA_5 0x30 -#define ZX_CH_STA_6 0x34 - -#define ZX_CTRL_MODA_16 (0 << 6) -#define ZX_CTRL_MODA_18 BIT(6) -#define ZX_CTRL_MODA_20 (2 << 6) -#define ZX_CTRL_MODA_24 (3 << 6) -#define ZX_CTRL_MODA_MASK (3 << 6) - -#define ZX_CTRL_ENB BIT(4) -#define ZX_CTRL_DNB (0 << 4) -#define ZX_CTRL_ENB_MASK BIT(4) - -#define ZX_CTRL_TX_OPEN BIT(0) -#define ZX_CTRL_TX_CLOSE (0 << 0) -#define ZX_CTRL_TX_MASK BIT(0) - -#define ZX_CTRL_OPEN (ZX_CTRL_TX_OPEN | ZX_CTRL_ENB) -#define ZX_CTRL_CLOSE (ZX_CTRL_TX_CLOSE | ZX_CTRL_DNB) - -#define ZX_CTRL_DOUBLE_TRACK (0 << 8) -#define ZX_CTRL_LEFT_TRACK BIT(8) -#define ZX_CTRL_RIGHT_TRACK (2 << 8) -#define ZX_CTRL_TRACK_MASK (3 << 8) - -#define ZX_FIFOCTRL_TXTH_MASK (0x1f << 8) -#define ZX_FIFOCTRL_TXTH(x) (x << 8) -#define ZX_FIFOCTRL_TX_DMA_EN BIT(2) -#define ZX_FIFOCTRL_TX_DMA_DIS (0 << 2) -#define ZX_FIFOCTRL_TX_DMA_EN_MASK BIT(2) -#define ZX_FIFOCTRL_TX_FIFO_RST BIT(0) -#define ZX_FIFOCTRL_TX_FIFO_RST_MASK BIT(0) - -#define ZX_VALID_DOUBLE_TRACK (0 << 0) -#define ZX_VALID_LEFT_TRACK BIT(1) -#define ZX_VALID_RIGHT_TRACK (2 << 0) -#define ZX_VALID_TRACK_MASK (3 << 0) - -#define ZX_SPDIF_CLK_RAT (2 * 32) - -struct zx_spdif_info { - struct snd_dmaengine_dai_dma_data dma_data; - struct clk *dai_clk; - void __iomem *reg_base; - resource_size_t mapbase; -}; - -static int zx_spdif_dai_probe(struct snd_soc_dai *dai) -{ - struct zx_spdif_info *zx_spdif = dev_get_drvdata(dai->dev); - - snd_soc_dai_set_drvdata(dai, zx_spdif); - zx_spdif->dma_data.addr = zx_spdif->mapbase + ZX_DATA; - zx_spdif->dma_data.maxburst = 8; - snd_soc_dai_init_dma_data(dai, &zx_spdif->dma_data, NULL); - return 0; -} - -static int zx_spdif_chanstats(void __iomem *base, unsigned int rate) -{ - u32 cstas1; - - switch (rate) { - case 22050: - cstas1 = IEC958_AES3_CON_FS_22050; - break; - case 24000: - cstas1 = IEC958_AES3_CON_FS_24000; - break; - case 32000: - cstas1 = IEC958_AES3_CON_FS_32000; - break; - case 44100: - cstas1 = IEC958_AES3_CON_FS_44100; - break; - case 48000: - cstas1 = IEC958_AES3_CON_FS_48000; - break; - case 88200: - cstas1 = IEC958_AES3_CON_FS_88200; - break; - case 96000: - cstas1 = IEC958_AES3_CON_FS_96000; - break; - case 176400: - cstas1 = IEC958_AES3_CON_FS_176400; - break; - case 192000: - cstas1 = IEC958_AES3_CON_FS_192000; - break; - default: - return -EINVAL; - } - cstas1 = cstas1 << 24; - cstas1 |= IEC958_AES0_CON_NOT_COPYRIGHT; - - writel_relaxed(cstas1, base + ZX_CH_STA_1); - return 0; -} - -static int zx_spdif_hw_params(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *params, - struct snd_soc_dai *socdai) -{ - struct zx_spdif_info *zx_spdif = dev_get_drvdata(socdai->dev); - struct zx_spdif_info *spdif = snd_soc_dai_get_drvdata(socdai); - struct snd_dmaengine_dai_dma_data *dma_data = - snd_soc_dai_get_dma_data(socdai, substream); - u32 val, ch_num, rate; - int ret; - - dma_data->addr_width = params_width(params) >> 3; - - val = readl_relaxed(zx_spdif->reg_base + ZX_CTRL); - val &= ~ZX_CTRL_MODA_MASK; - switch (params_format(params)) { - case SNDRV_PCM_FORMAT_S16_LE: - val |= ZX_CTRL_MODA_16; - break; - - case SNDRV_PCM_FORMAT_S18_3LE: - val |= ZX_CTRL_MODA_18; - break; - - case SNDRV_PCM_FORMAT_S20_3LE: - val |= ZX_CTRL_MODA_20; - break; - - case SNDRV_PCM_FORMAT_S24_LE: - val |= ZX_CTRL_MODA_24; - break; - default: - dev_err(socdai->dev, "Format not support!\n"); - return -EINVAL; - } - - ch_num = params_channels(params); - if (ch_num == 2) - val |= ZX_CTRL_DOUBLE_TRACK; - else - val |= ZX_CTRL_LEFT_TRACK; - writel_relaxed(val, zx_spdif->reg_base + ZX_CTRL); - - val = readl_relaxed(zx_spdif->reg_base + ZX_VALID_BIT); - val &= ~ZX_VALID_TRACK_MASK; - if (ch_num == 2) - val |= ZX_VALID_DOUBLE_TRACK; - else - val |= ZX_VALID_RIGHT_TRACK; - writel_relaxed(val, zx_spdif->reg_base + ZX_VALID_BIT); - - rate = params_rate(params); - ret = zx_spdif_chanstats(zx_spdif->reg_base, rate); - if (ret) - return ret; - return clk_set_rate(spdif->dai_clk, rate * ch_num * ZX_SPDIF_CLK_RAT); -} - -static void zx_spdif_cfg_tx(void __iomem *base, int on) -{ - u32 val; - - val = readl_relaxed(base + ZX_CTRL); - val &= ~(ZX_CTRL_ENB_MASK | ZX_CTRL_TX_MASK); - val |= on ? ZX_CTRL_OPEN : ZX_CTRL_CLOSE; - writel_relaxed(val, base + ZX_CTRL); - - val = readl_relaxed(base + ZX_FIFOCTRL); - val &= ~ZX_FIFOCTRL_TX_DMA_EN_MASK; - if (on) - val |= ZX_FIFOCTRL_TX_DMA_EN; - writel_relaxed(val, base + ZX_FIFOCTRL); -} - -static int zx_spdif_trigger(struct snd_pcm_substream *substream, int cmd, - struct snd_soc_dai *dai) -{ - u32 val; - struct zx_spdif_info *zx_spdif = dev_get_drvdata(dai->dev); - int ret = 0; - - switch (cmd) { - case SNDRV_PCM_TRIGGER_START: - val = readl_relaxed(zx_spdif->reg_base + ZX_FIFOCTRL); - val |= ZX_FIFOCTRL_TX_FIFO_RST; - writel_relaxed(val, zx_spdif->reg_base + ZX_FIFOCTRL); - fallthrough; - case SNDRV_PCM_TRIGGER_RESUME: - case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: - zx_spdif_cfg_tx(zx_spdif->reg_base, true); - break; - - case SNDRV_PCM_TRIGGER_STOP: - case SNDRV_PCM_TRIGGER_SUSPEND: - case SNDRV_PCM_TRIGGER_PAUSE_PUSH: - zx_spdif_cfg_tx(zx_spdif->reg_base, false); - break; - - default: - ret = -EINVAL; - break; - } - - return ret; -} - -static int zx_spdif_startup(struct snd_pcm_substream *substream, - struct snd_soc_dai *dai) -{ - struct zx_spdif_info *zx_spdif = dev_get_drvdata(dai->dev); - - return clk_prepare_enable(zx_spdif->dai_clk); -} - -static void zx_spdif_shutdown(struct snd_pcm_substream *substream, - struct snd_soc_dai *dai) -{ - struct zx_spdif_info *zx_spdif = dev_get_drvdata(dai->dev); - - clk_disable_unprepare(zx_spdif->dai_clk); -} - -#define ZX_RATES \ - (SNDRV_PCM_RATE_22050 | SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | \ - SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000 |\ - SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_192000) - -#define ZX_FORMAT \ - (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S18_3LE \ - | SNDRV_PCM_FMTBIT_S20_3LE | SNDRV_PCM_FMTBIT_S24_LE) - -static const struct snd_soc_dai_ops zx_spdif_dai_ops = { - .trigger = zx_spdif_trigger, - .startup = zx_spdif_startup, - .shutdown = zx_spdif_shutdown, - .hw_params = zx_spdif_hw_params, -}; - -static struct snd_soc_dai_driver zx_spdif_dai = { - .name = "spdif", - .id = 0, - .probe = zx_spdif_dai_probe, - .playback = { - .channels_min = 1, - .channels_max = 2, - .rates = ZX_RATES, - .formats = ZX_FORMAT, - }, - .ops = &zx_spdif_dai_ops, -}; - -static const struct snd_soc_component_driver zx_spdif_component = { - .name = "spdif", -}; - -static void zx_spdif_dev_init(void __iomem *base) -{ - u32 val; - - writel_relaxed(0, base + ZX_CTRL); - writel_relaxed(0, base + ZX_INT_MASK); - writel_relaxed(0xf, base + ZX_INT_STATUS); - writel_relaxed(0x1, base + ZX_FIFOCTRL); - - val = readl_relaxed(base + ZX_FIFOCTRL); - val &= ~(ZX_FIFOCTRL_TXTH_MASK | ZX_FIFOCTRL_TX_FIFO_RST_MASK); - val |= ZX_FIFOCTRL_TXTH(8); - writel_relaxed(val, base + ZX_FIFOCTRL); -} - -static int zx_spdif_probe(struct platform_device *pdev) -{ - struct resource *res; - struct zx_spdif_info *zx_spdif; - int ret; - - zx_spdif = devm_kzalloc(&pdev->dev, sizeof(*zx_spdif), GFP_KERNEL); - if (!zx_spdif) - return -ENOMEM; - - zx_spdif->dai_clk = devm_clk_get(&pdev->dev, "tx"); - if (IS_ERR(zx_spdif->dai_clk)) { - dev_err(&pdev->dev, "Fail to get clk\n"); - return PTR_ERR(zx_spdif->dai_clk); - } - - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - zx_spdif->mapbase = res->start; - zx_spdif->reg_base = devm_ioremap_resource(&pdev->dev, res); - if (IS_ERR(zx_spdif->reg_base)) { - return PTR_ERR(zx_spdif->reg_base); - } - - zx_spdif_dev_init(zx_spdif->reg_base); - platform_set_drvdata(pdev, zx_spdif); - - ret = devm_snd_soc_register_component(&pdev->dev, &zx_spdif_component, - &zx_spdif_dai, 1); - if (ret) { - dev_err(&pdev->dev, "Register DAI failed: %d\n", ret); - return ret; - } - - ret = devm_snd_dmaengine_pcm_register(&pdev->dev, NULL, 0); - if (ret) - dev_err(&pdev->dev, "Register platform PCM failed: %d\n", ret); - - return ret; -} - -static const struct of_device_id zx_spdif_dt_ids[] = { - { .compatible = "zte,zx296702-spdif", }, - {} -}; -MODULE_DEVICE_TABLE(of, zx_spdif_dt_ids); - -static struct platform_driver spdif_driver = { - .probe = zx_spdif_probe, - .driver = { - .name = "zx-spdif", - .of_match_table = zx_spdif_dt_ids, - }, -}; - -module_platform_driver(spdif_driver); - -MODULE_AUTHOR("Jun Nie "); -MODULE_DESCRIPTION("ZTE SPDIF SoC DAI"); -MODULE_LICENSE("GPL"); diff --git a/sound/soc/zte/zx-tdm.c b/sound/soc/zte/zx-tdm.c deleted file mode 100644 index 4f787185d630..000000000000 --- a/sound/soc/zte/zx-tdm.c +++ /dev/null @@ -1,458 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * ZTE's TDM driver - * - * Copyright (C) 2017 ZTE Ltd - * - * Author: Baoyou Xie - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -#define REG_TIMING_CTRL 0x04 -#define REG_TX_FIFO_CTRL 0x0C -#define REG_RX_FIFO_CTRL 0x10 -#define REG_INT_EN 0x1C -#define REG_INT_STATUS 0x20 -#define REG_DATABUF 0x24 -#define REG_TS_MASK0 0x44 -#define REG_PROCESS_CTRL 0x54 - -#define FIFO_CTRL_TX_RST BIT(0) -#define FIFO_CTRL_RX_RST BIT(0) -#define DEAGULT_FIFO_THRES GENMASK(4, 2) - -#define FIFO_CTRL_TX_DMA_EN BIT(1) -#define FIFO_CTRL_RX_DMA_EN BIT(1) - -#define TX_FIFO_RST_MASK BIT(0) -#define RX_FIFO_RST_MASK BIT(0) - -#define FIFOCTRL_TX_FIFO_RST BIT(0) -#define FIFOCTRL_RX_FIFO_RST BIT(0) - -#define TXTH_MASK GENMASK(5, 2) -#define RXTH_MASK GENMASK(5, 2) - -#define FIFOCTRL_THRESHOLD(x) ((x) << 2) - -#define TIMING_MS_MASK BIT(1) -/* - * 00: 8 clk cycles every timeslot - * 01: 16 clk cycles every timeslot - * 10: 32 clk cycles every timeslot - */ -#define TIMING_SYNC_WIDTH_MASK GENMASK(6, 5) -#define TIMING_WIDTH_SHIFT 5 -#define TIMING_DEFAULT_WIDTH 0 -#define TIMING_TS_WIDTH(x) ((x) << TIMING_WIDTH_SHIFT) -#define TIMING_WIDTH_FACTOR 8 - -#define TIMING_MASTER_MODE BIT(21) -#define TIMING_LSB_FIRST BIT(20) -#define TIMING_TS_NUM(x) (((x) - 1) << 7) -#define TIMING_CLK_SEL_MASK GENMASK(2, 0) -#define TIMING_CLK_SEL_DEF BIT(2) - -#define PROCESS_TX_EN BIT(0) -#define PROCESS_RX_EN BIT(1) -#define PROCESS_TDM_EN BIT(2) -#define PROCESS_DISABLE_ALL 0 - -#define INT_DISABLE_ALL 0 -#define INT_STATUS_MASK GENMASK(6, 0) - -struct zx_tdm_info { - struct snd_dmaengine_dai_dma_data dma_playback; - struct snd_dmaengine_dai_dma_data dma_capture; - resource_size_t phy_addr; - void __iomem *regbase; - struct clk *dai_wclk; - struct clk *dai_pclk; - int master; - struct device *dev; -}; - -static inline u32 zx_tdm_readl(struct zx_tdm_info *tdm, u16 reg) -{ - return readl_relaxed(tdm->regbase + reg); -} - -static inline void zx_tdm_writel(struct zx_tdm_info *tdm, u16 reg, u32 val) -{ - writel_relaxed(val, tdm->regbase + reg); -} - -static void zx_tdm_tx_en(struct zx_tdm_info *tdm, bool on) -{ - unsigned long val; - - val = zx_tdm_readl(tdm, REG_PROCESS_CTRL); - if (on) - val |= PROCESS_TX_EN | PROCESS_TDM_EN; - else - val &= ~(PROCESS_TX_EN | PROCESS_TDM_EN); - zx_tdm_writel(tdm, REG_PROCESS_CTRL, val); -} - -static void zx_tdm_rx_en(struct zx_tdm_info *tdm, bool on) -{ - unsigned long val; - - val = zx_tdm_readl(tdm, REG_PROCESS_CTRL); - if (on) - val |= PROCESS_RX_EN | PROCESS_TDM_EN; - else - val &= ~(PROCESS_RX_EN | PROCESS_TDM_EN); - zx_tdm_writel(tdm, REG_PROCESS_CTRL, val); -} - -static void zx_tdm_tx_dma_en(struct zx_tdm_info *tdm, bool on) -{ - unsigned long val; - - val = zx_tdm_readl(tdm, REG_TX_FIFO_CTRL); - val |= FIFO_CTRL_TX_RST | DEAGULT_FIFO_THRES; - if (on) - val |= FIFO_CTRL_TX_DMA_EN; - else - val &= ~FIFO_CTRL_TX_DMA_EN; - zx_tdm_writel(tdm, REG_TX_FIFO_CTRL, val); -} - -static void zx_tdm_rx_dma_en(struct zx_tdm_info *tdm, bool on) -{ - unsigned long val; - - val = zx_tdm_readl(tdm, REG_RX_FIFO_CTRL); - val |= FIFO_CTRL_RX_RST | DEAGULT_FIFO_THRES; - if (on) - val |= FIFO_CTRL_RX_DMA_EN; - else - val &= ~FIFO_CTRL_RX_DMA_EN; - zx_tdm_writel(tdm, REG_RX_FIFO_CTRL, val); -} - -#define ZX_TDM_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000) - -#define ZX_TDM_FMTBIT \ - (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_MU_LAW | \ - SNDRV_PCM_FMTBIT_A_LAW) - -static int zx_tdm_dai_probe(struct snd_soc_dai *dai) -{ - struct zx_tdm_info *zx_tdm = dev_get_drvdata(dai->dev); - - snd_soc_dai_set_drvdata(dai, zx_tdm); - zx_tdm->dma_playback.addr = zx_tdm->phy_addr + REG_DATABUF; - zx_tdm->dma_playback.maxburst = 16; - zx_tdm->dma_capture.addr = zx_tdm->phy_addr + REG_DATABUF; - zx_tdm->dma_capture.maxburst = 16; - snd_soc_dai_init_dma_data(dai, &zx_tdm->dma_playback, - &zx_tdm->dma_capture); - return 0; -} - -static int zx_tdm_set_fmt(struct snd_soc_dai *cpu_dai, unsigned int fmt) -{ - struct zx_tdm_info *tdm = snd_soc_dai_get_drvdata(cpu_dai); - unsigned long val; - - val = zx_tdm_readl(tdm, REG_TIMING_CTRL); - val &= ~(TIMING_SYNC_WIDTH_MASK | TIMING_MS_MASK); - val |= TIMING_DEFAULT_WIDTH << TIMING_WIDTH_SHIFT; - - switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { - case SND_SOC_DAIFMT_CBM_CFM: - tdm->master = 1; - val |= TIMING_MASTER_MODE; - break; - case SND_SOC_DAIFMT_CBS_CFS: - tdm->master = 0; - val &= ~TIMING_MASTER_MODE; - break; - default: - dev_err(cpu_dai->dev, "Unknown master/slave format\n"); - return -EINVAL; - } - - - zx_tdm_writel(tdm, REG_TIMING_CTRL, val); - - return 0; -} - -static int zx_tdm_hw_params(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *params, - struct snd_soc_dai *socdai) -{ - struct zx_tdm_info *tdm = snd_soc_dai_get_drvdata(socdai); - struct snd_dmaengine_dai_dma_data *dma_data; - unsigned int ts_width = TIMING_DEFAULT_WIDTH; - unsigned int ch_num = 32; - unsigned int mask = 0; - unsigned int ret = 0; - unsigned long val; - - dma_data = snd_soc_dai_get_dma_data(socdai, substream); - dma_data->addr_width = ch_num >> 3; - - switch (params_format(params)) { - case SNDRV_PCM_FORMAT_MU_LAW: - case SNDRV_PCM_FORMAT_A_LAW: - case SNDRV_PCM_FORMAT_S16_LE: - ts_width = 1; - break; - default: - dev_err(socdai->dev, "Unknown data format\n"); - return -EINVAL; - } - - val = zx_tdm_readl(tdm, REG_TIMING_CTRL); - val |= TIMING_TS_WIDTH(ts_width) | TIMING_TS_NUM(1); - zx_tdm_writel(tdm, REG_TIMING_CTRL, val); - zx_tdm_writel(tdm, REG_TS_MASK0, mask); - - if (tdm->master) - ret = clk_set_rate(tdm->dai_wclk, - params_rate(params) * TIMING_WIDTH_FACTOR * ch_num); - - return ret; -} - -static int zx_tdm_trigger(struct snd_pcm_substream *substream, int cmd, - struct snd_soc_dai *dai) -{ - int capture = (substream->stream == SNDRV_PCM_STREAM_CAPTURE); - struct zx_tdm_info *zx_tdm = dev_get_drvdata(dai->dev); - unsigned int val; - int ret = 0; - - switch (cmd) { - case SNDRV_PCM_TRIGGER_START: - if (capture) { - val = zx_tdm_readl(zx_tdm, REG_RX_FIFO_CTRL); - val |= FIFOCTRL_RX_FIFO_RST; - zx_tdm_writel(zx_tdm, REG_RX_FIFO_CTRL, val); - - zx_tdm_rx_dma_en(zx_tdm, true); - } else { - val = zx_tdm_readl(zx_tdm, REG_TX_FIFO_CTRL); - val |= FIFOCTRL_TX_FIFO_RST; - zx_tdm_writel(zx_tdm, REG_TX_FIFO_CTRL, val); - - zx_tdm_tx_dma_en(zx_tdm, true); - } - break; - case SNDRV_PCM_TRIGGER_RESUME: - case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: - if (capture) - zx_tdm_rx_en(zx_tdm, true); - else - zx_tdm_tx_en(zx_tdm, true); - break; - case SNDRV_PCM_TRIGGER_STOP: - if (capture) - zx_tdm_rx_dma_en(zx_tdm, false); - else - zx_tdm_tx_dma_en(zx_tdm, false); - break; - case SNDRV_PCM_TRIGGER_SUSPEND: - case SNDRV_PCM_TRIGGER_PAUSE_PUSH: - if (capture) - zx_tdm_rx_en(zx_tdm, false); - else - zx_tdm_tx_en(zx_tdm, false); - break; - default: - ret = -EINVAL; - break; - } - - return ret; -} - -static int zx_tdm_startup(struct snd_pcm_substream *substream, - struct snd_soc_dai *dai) -{ - struct zx_tdm_info *zx_tdm = dev_get_drvdata(dai->dev); - int ret; - - ret = clk_prepare_enable(zx_tdm->dai_wclk); - if (ret) - return ret; - - ret = clk_prepare_enable(zx_tdm->dai_pclk); - if (ret) { - clk_disable_unprepare(zx_tdm->dai_wclk); - return ret; - } - - return 0; -} - -static void zx_tdm_shutdown(struct snd_pcm_substream *substream, - struct snd_soc_dai *dai) -{ - struct zx_tdm_info *zx_tdm = dev_get_drvdata(dai->dev); - - clk_disable_unprepare(zx_tdm->dai_pclk); - clk_disable_unprepare(zx_tdm->dai_wclk); -} - -static const struct snd_soc_dai_ops zx_tdm_dai_ops = { - .trigger = zx_tdm_trigger, - .hw_params = zx_tdm_hw_params, - .set_fmt = zx_tdm_set_fmt, - .startup = zx_tdm_startup, - .shutdown = zx_tdm_shutdown, -}; - -static const struct snd_soc_component_driver zx_tdm_component = { - .name = "zx-tdm", -}; - -static void zx_tdm_init_state(struct zx_tdm_info *tdm) -{ - unsigned int val; - - zx_tdm_writel(tdm, REG_PROCESS_CTRL, PROCESS_DISABLE_ALL); - - val = zx_tdm_readl(tdm, REG_TIMING_CTRL); - val |= TIMING_LSB_FIRST; - val &= ~TIMING_CLK_SEL_MASK; - val |= TIMING_CLK_SEL_DEF; - zx_tdm_writel(tdm, REG_TIMING_CTRL, val); - - zx_tdm_writel(tdm, REG_INT_EN, INT_DISABLE_ALL); - /* - * write INT_STATUS register to clear it. - */ - zx_tdm_writel(tdm, REG_INT_STATUS, INT_STATUS_MASK); - zx_tdm_writel(tdm, REG_RX_FIFO_CTRL, FIFOCTRL_RX_FIFO_RST); - zx_tdm_writel(tdm, REG_TX_FIFO_CTRL, FIFOCTRL_TX_FIFO_RST); - - val = zx_tdm_readl(tdm, REG_RX_FIFO_CTRL); - val &= ~(RXTH_MASK | RX_FIFO_RST_MASK); - val |= FIFOCTRL_THRESHOLD(8); - zx_tdm_writel(tdm, REG_RX_FIFO_CTRL, val); - - val = zx_tdm_readl(tdm, REG_TX_FIFO_CTRL); - val &= ~(TXTH_MASK | TX_FIFO_RST_MASK); - val |= FIFOCTRL_THRESHOLD(8); - zx_tdm_writel(tdm, REG_TX_FIFO_CTRL, val); -} - -static struct snd_soc_dai_driver zx_tdm_dai = { - .name = "zx-tdm-dai", - .id = 0, - .probe = zx_tdm_dai_probe, - .playback = { - .channels_min = 1, - .channels_max = 4, - .rates = ZX_TDM_RATES, - .formats = ZX_TDM_FMTBIT, - }, - .capture = { - .channels_min = 1, - .channels_max = 4, - .rates = ZX_TDM_RATES, - .formats = ZX_TDM_FMTBIT, - }, - .ops = &zx_tdm_dai_ops, -}; - -static int zx_tdm_probe(struct platform_device *pdev) -{ - struct of_phandle_args out_args; - unsigned int dma_reg_offset; - struct zx_tdm_info *zx_tdm; - unsigned int dma_mask; - struct resource *res; - struct regmap *regmap_sysctrl; - int ret; - - zx_tdm = devm_kzalloc(&pdev->dev, sizeof(*zx_tdm), GFP_KERNEL); - if (!zx_tdm) - return -ENOMEM; - - zx_tdm->dev = &pdev->dev; - - zx_tdm->dai_wclk = devm_clk_get(&pdev->dev, "wclk"); - if (IS_ERR(zx_tdm->dai_wclk)) { - dev_err(&pdev->dev, "Fail to get wclk\n"); - return PTR_ERR(zx_tdm->dai_wclk); - } - - zx_tdm->dai_pclk = devm_clk_get(&pdev->dev, "pclk"); - if (IS_ERR(zx_tdm->dai_pclk)) { - dev_err(&pdev->dev, "Fail to get pclk\n"); - return PTR_ERR(zx_tdm->dai_pclk); - } - - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - zx_tdm->phy_addr = res->start; - zx_tdm->regbase = devm_ioremap_resource(&pdev->dev, res); - if (IS_ERR(zx_tdm->regbase)) - return PTR_ERR(zx_tdm->regbase); - - ret = of_parse_phandle_with_fixed_args(pdev->dev.of_node, - "zte,tdm-dma-sysctrl", 2, 0, &out_args); - if (ret) { - dev_err(&pdev->dev, "Fail to get zte,tdm-dma-sysctrl\n"); - return ret; - } - - dma_reg_offset = out_args.args[0]; - dma_mask = out_args.args[1]; - regmap_sysctrl = syscon_node_to_regmap(out_args.np); - if (IS_ERR(regmap_sysctrl)) { - of_node_put(out_args.np); - return PTR_ERR(regmap_sysctrl); - } - - regmap_update_bits(regmap_sysctrl, dma_reg_offset, dma_mask, dma_mask); - of_node_put(out_args.np); - - zx_tdm_init_state(zx_tdm); - platform_set_drvdata(pdev, zx_tdm); - - ret = devm_snd_soc_register_component(&pdev->dev, &zx_tdm_component, - &zx_tdm_dai, 1); - if (ret) { - dev_err(&pdev->dev, "Register DAI failed: %d\n", ret); - return ret; - } - - ret = devm_snd_dmaengine_pcm_register(&pdev->dev, NULL, 0); - if (ret) - dev_err(&pdev->dev, "Register platform PCM failed: %d\n", ret); - - return ret; -} - -static const struct of_device_id zx_tdm_dt_ids[] = { - { .compatible = "zte,zx296718-tdm", }, - {} -}; -MODULE_DEVICE_TABLE(of, zx_tdm_dt_ids); - -static struct platform_driver tdm_driver = { - .probe = zx_tdm_probe, - .driver = { - .name = "zx-tdm", - .of_match_table = zx_tdm_dt_ids, - }, -}; -module_platform_driver(tdm_driver); - -MODULE_AUTHOR("Baoyou Xie "); -MODULE_DESCRIPTION("ZTE TDM DAI driver"); -MODULE_LICENSE("GPL v2"); -- cgit v1.2.3 From d2e04b9dd617ceaebf4f0ce6a3daf039bc08895e Mon Sep 17 00:00:00 2001 From: Lukas Bulwahn Date: Mon, 18 Jan 2021 09:00:04 +0100 Subject: docs, bpf: Add minimal markup to address doc warning Commit 91c960b00566 ("bpf: Rename BPF_XADD and prepare to encode other atomics in .imm") modified the BPF documentation, but missed some ReST markup. Hence, make htmldocs warns on Documentation/networking/filter.rst:1053: WARNING: Inline emphasis start-string without end-string. Add some minimal markup to address this warning. Fixes: 91c960b00566 ("bpf: Rename BPF_XADD and prepare to encode other atomics in .imm") Signed-off-by: Lukas Bulwahn Signed-off-by: Daniel Borkmann Acked-by: Brendan Jackman Link: https://lore.kernel.org/bpf/20210118080004.6367-1-lukas.bulwahn@gmail.com Signed-off-by: Alexei Starovoitov --- Documentation/networking/filter.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'Documentation') diff --git a/Documentation/networking/filter.rst b/Documentation/networking/filter.rst index f6d8f90e9a56..45f6fde1776c 100644 --- a/Documentation/networking/filter.rst +++ b/Documentation/networking/filter.rst @@ -1048,12 +1048,12 @@ Unlike classic BPF instruction set, eBPF has generic load/store operations:: Where size is one of: BPF_B or BPF_H or BPF_W or BPF_DW. It also includes atomic operations, which use the immediate field for extra -encoding. +encoding:: .imm = BPF_ADD, .code = BPF_ATOMIC | BPF_W | BPF_STX: lock xadd *(u32 *)(dst_reg + off16) += src_reg .imm = BPF_ADD, .code = BPF_ATOMIC | BPF_DW | BPF_STX: lock xadd *(u64 *)(dst_reg + off16) += src_reg -The basic atomic operations supported are: +The basic atomic operations supported are:: BPF_ADD BPF_AND -- cgit v1.2.3 From 6939f4ef16d48f2093f337162cfc041d0e30ed25 Mon Sep 17 00:00:00 2001 From: Qais Yousef Date: Tue, 19 Jan 2021 12:22:36 +0000 Subject: trace: bpf: Allow bpf to attach to bare tracepoints Some subsystems only have bare tracepoints (a tracepoint with no associated trace event) to avoid the problem of trace events being an ABI that can't be changed. >From bpf presepective, bare tracepoints are what it calls RAW_TRACEPOINT(). Since bpf assumed there's 1:1 mapping, it relied on hooking to DEFINE_EVENT() macro to create bpf mapping of the tracepoints. Since bare tracepoints use DECLARE_TRACE() to create the tracepoint, bpf had no knowledge about their existence. By teaching bpf_probe.h to parse DECLARE_TRACE() in a similar fashion to DEFINE_EVENT(), bpf can find and attach to the new raw tracepoints. Enabling that comes with the contract that changes to raw tracepoints don't constitute a regression if they break existing bpf programs. We need the ability to continue to morph and modify these raw tracepoints without worrying about any ABI. Update Documentation/bpf/bpf_design_QA.rst to document this contract. Signed-off-by: Qais Yousef Signed-off-by: Alexei Starovoitov Acked-by: Yonghong Song Link: https://lore.kernel.org/bpf/20210119122237.2426878-2-qais.yousef@arm.com --- Documentation/bpf/bpf_design_QA.rst | 6 ++++++ include/trace/bpf_probe.h | 12 ++++++++++-- 2 files changed, 16 insertions(+), 2 deletions(-) (limited to 'Documentation') diff --git a/Documentation/bpf/bpf_design_QA.rst b/Documentation/bpf/bpf_design_QA.rst index 2df7b067ab93..0e15f9b05c9d 100644 --- a/Documentation/bpf/bpf_design_QA.rst +++ b/Documentation/bpf/bpf_design_QA.rst @@ -208,6 +208,12 @@ data structures and compile with kernel internal headers. Both of these kernel internals are subject to change and can break with newer kernels such that the program needs to be adapted accordingly. +Q: Are tracepoints part of the stable ABI? +------------------------------------------ +A: NO. Tracepoints are tied to internal implementation details hence they are +subject to change and can break with newer kernels. BPF programs need to change +accordingly when this happens. + Q: How much stack space a BPF program uses? ------------------------------------------- A: Currently all program types are limited to 512 bytes of stack diff --git a/include/trace/bpf_probe.h b/include/trace/bpf_probe.h index cd74bffed5c6..a23be89119aa 100644 --- a/include/trace/bpf_probe.h +++ b/include/trace/bpf_probe.h @@ -55,8 +55,7 @@ /* tracepoints with more than 12 arguments will hit build error */ #define CAST_TO_U64(...) CONCATENATE(__CAST, COUNT_ARGS(__VA_ARGS__))(__VA_ARGS__) -#undef DECLARE_EVENT_CLASS -#define DECLARE_EVENT_CLASS(call, proto, args, tstruct, assign, print) \ +#define __BPF_DECLARE_TRACE(call, proto, args) \ static notrace void \ __bpf_trace_##call(void *__data, proto) \ { \ @@ -64,6 +63,10 @@ __bpf_trace_##call(void *__data, proto) \ CONCATENATE(bpf_trace_run, COUNT_ARGS(args))(prog, CAST_TO_U64(args)); \ } +#undef DECLARE_EVENT_CLASS +#define DECLARE_EVENT_CLASS(call, proto, args, tstruct, assign, print) \ + __BPF_DECLARE_TRACE(call, PARAMS(proto), PARAMS(args)) + /* * This part is compiled out, it is only here as a build time check * to make sure that if the tracepoint handling changes, the @@ -111,6 +114,11 @@ __DEFINE_EVENT(template, call, PARAMS(proto), PARAMS(args), size) #define DEFINE_EVENT_PRINT(template, name, proto, args, print) \ DEFINE_EVENT(template, name, PARAMS(proto), PARAMS(args)) +#undef DECLARE_TRACE +#define DECLARE_TRACE(call, proto, args) \ + __BPF_DECLARE_TRACE(call, PARAMS(proto), PARAMS(args)) \ + __DEFINE_EVENT(call, call, PARAMS(proto), PARAMS(args), 0) + #include TRACE_INCLUDE(TRACE_INCLUDE_FILE) #undef DEFINE_EVENT_WRITABLE -- cgit v1.2.3 From 53fe5418fe3f286ddb28fc0f0862923a9c94d671 Mon Sep 17 00:00:00 2001 From: Brendan Jackman Date: Wed, 20 Jan 2021 13:39:45 +0000 Subject: docs: bpf: Fixup atomics markup This fixes up the markup to fix a warning, be more consistent with use of monospace, and use the correct .rst syntax for (* instead of _). Signed-off-by: Brendan Jackman Signed-off-by: Alexei Starovoitov Reviewed-by: Lukas Bulwahn Link: https://lore.kernel.org/bpf/20210120133946.2107897-2-jackmanb@google.com --- Documentation/networking/filter.rst | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) (limited to 'Documentation') diff --git a/Documentation/networking/filter.rst b/Documentation/networking/filter.rst index 45f6fde1776c..4c2bb4c6364d 100644 --- a/Documentation/networking/filter.rst +++ b/Documentation/networking/filter.rst @@ -1066,12 +1066,12 @@ memory location addresed by ``dst_reg + off`` is atomically modified, with immediate, then these operations also overwrite ``src_reg`` with the value that was in memory before it was modified. -The more special operations are: +The more special operations are:: BPF_XCHG This atomically exchanges ``src_reg`` with the value addressed by ``dst_reg + -off``. +off``. :: BPF_CMPXCHG @@ -1081,18 +1081,19 @@ before is loaded back to ``R0``. Note that 1 and 2 byte atomic operations are not supported. -Except ``BPF_ADD`` _without_ ``BPF_FETCH`` (for legacy reasons), all 4 byte +Except ``BPF_ADD`` *without* ``BPF_FETCH`` (for legacy reasons), all 4 byte atomic operations require alu32 mode. Clang enables this mode by default in architecture v3 (``-mcpu=v3``). For older versions it can be enabled with ``-Xclang -target-feature -Xclang +alu32``. -You may encounter BPF_XADD - this is a legacy name for BPF_ATOMIC, referring to -the exclusive-add operation encoded when the immediate field is zero. +You may encounter ``BPF_XADD`` - this is a legacy name for ``BPF_ATOMIC``, +referring to the exclusive-add operation encoded when the immediate field is +zero. -eBPF has one 16-byte instruction: BPF_LD | BPF_DW | BPF_IMM which consists +eBPF has one 16-byte instruction: ``BPF_LD | BPF_DW | BPF_IMM`` which consists of two consecutive ``struct bpf_insn`` 8-byte blocks and interpreted as single instruction that loads 64-bit immediate value into a dst_reg. -Classic BPF has similar instruction: BPF_LD | BPF_W | BPF_IMM which loads +Classic BPF has similar instruction: ``BPF_LD | BPF_W | BPF_IMM`` which loads 32-bit immediate value into a register. eBPF verifier -- cgit v1.2.3 From b452ee005a9135ed89fc8c9dff14e042770eb4f1 Mon Sep 17 00:00:00 2001 From: Brendan Jackman Date: Wed, 20 Jan 2021 13:39:46 +0000 Subject: docs: bpf: Clarify -mcpu=v3 requirement for atomic ops Alexei pointed out [1] that this wording is pretty confusing. Here's an attempt to be more explicit and clear. [1] https://lore.kernel.org/bpf/CAADnVQJVvwoZsE1K+6qRxzF7+6CvZNzygnoBW9tZNWJELk5c=Q@mail.gmail.com/ Signed-off-by: Brendan Jackman Signed-off-by: Alexei Starovoitov Link: https://lore.kernel.org/bpf/20210120133946.2107897-3-jackmanb@google.com --- Documentation/networking/filter.rst | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'Documentation') diff --git a/Documentation/networking/filter.rst b/Documentation/networking/filter.rst index 4c2bb4c6364d..b3f457802836 100644 --- a/Documentation/networking/filter.rst +++ b/Documentation/networking/filter.rst @@ -1081,9 +1081,10 @@ before is loaded back to ``R0``. Note that 1 and 2 byte atomic operations are not supported. -Except ``BPF_ADD`` *without* ``BPF_FETCH`` (for legacy reasons), all 4 byte -atomic operations require alu32 mode. Clang enables this mode by default in -architecture v3 (``-mcpu=v3``). For older versions it can be enabled with +Clang can generate atomic instructions by default when ``-mcpu=v3`` is +enabled. If a lower version for ``-mcpu`` is set, the only atomic instruction +Clang can generate is ``BPF_ADD`` *without* ``BPF_FETCH``. If you need to enable +the atomics features, while keeping a lower ``-mcpu`` version, you can use ``-Xclang -target-feature -Xclang +alu32``. You may encounter ``BPF_XADD`` - this is a legacy name for ``BPF_ATOMIC``, -- cgit v1.2.3 From 06aea26676a584d0effa72ce6a21b21de7643b30 Mon Sep 17 00:00:00 2001 From: Bean Huo Date: Tue, 19 Jan 2021 17:38:43 +0100 Subject: scsi: ufs: docs: ABI: Add wb_on documentation for new entry wb_on Adds UFS sysfs documentation for new entry wb_on. [mkp: fix doc formatting] Link: https://lore.kernel.org/r/20210119163847.20165-3-huobean@gmail.com Signed-off-by: Bean Huo Signed-off-by: Martin K. Petersen fix format --- Documentation/ABI/testing/sysfs-driver-ufs | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'Documentation') diff --git a/Documentation/ABI/testing/sysfs-driver-ufs b/Documentation/ABI/testing/sysfs-driver-ufs index adc0d0e91607..375a10f159b1 100644 --- a/Documentation/ABI/testing/sysfs-driver-ufs +++ b/Documentation/ABI/testing/sysfs-driver-ufs @@ -1153,3 +1153,14 @@ Description: This entry shows the configured size of WriteBooster buffer. 0400h corresponds to 4GB. The file is read only. + +What: /sys/bus/platform/drivers/ufshcd/*/wb_on +Date: January 2021 +Contact: Bean Huo +Description: This node is used to set or display whether UFS WriteBooster is + enabled. Echo 0 to this file to disable UFS WriteBooster or 1 to + enable it. The WriteBooster is enabled after power-on/reset, + however, it will be disabled/enable while CLK scaling down/up + (if the platform supports UFSHCD_CAP_CLK_SCALING). For a + platform that doesn't support UFSHCD_CAP_CLK_SCALING, we can + disable/enable WriteBooster through this sysfs node. -- cgit v1.2.3 From 484c58d6601c2868e9763e105443ef57d562ee3b Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Wed, 20 Jan 2021 14:20:42 +0100 Subject: pinctrl: remove zte zx driver The zte zx platform is getting removed, so this driver is no longer needed. Cc: Jun Nie Cc: Shawn Guo Signed-off-by: Arnd Bergmann Link: https://lore.kernel.org/r/20210120132045.2127659-3-arnd@kernel.org Signed-off-by: Linus Walleij --- .../devicetree/bindings/pinctrl/pinctrl-zx.txt | 84 -- drivers/pinctrl/Kconfig | 1 - drivers/pinctrl/Makefile | 1 - drivers/pinctrl/zte/Kconfig | 14 - drivers/pinctrl/zte/Makefile | 3 - drivers/pinctrl/zte/pinctrl-zx.c | 445 --------- drivers/pinctrl/zte/pinctrl-zx.h | 102 -- drivers/pinctrl/zte/pinctrl-zx296718.c | 1024 -------------------- 8 files changed, 1674 deletions(-) delete mode 100644 Documentation/devicetree/bindings/pinctrl/pinctrl-zx.txt delete mode 100644 drivers/pinctrl/zte/Kconfig delete mode 100644 drivers/pinctrl/zte/Makefile delete mode 100644 drivers/pinctrl/zte/pinctrl-zx.c delete mode 100644 drivers/pinctrl/zte/pinctrl-zx.h delete mode 100644 drivers/pinctrl/zte/pinctrl-zx296718.c (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/pinctrl/pinctrl-zx.txt b/Documentation/devicetree/bindings/pinctrl/pinctrl-zx.txt deleted file mode 100644 index 39170f372599..000000000000 --- a/Documentation/devicetree/bindings/pinctrl/pinctrl-zx.txt +++ /dev/null @@ -1,84 +0,0 @@ -* ZTE ZX Pin Controller - -The pin controller on ZTE ZX platforms is kinda of hybrid. It consists of -a main controller and an auxiliary one. For example, on ZX296718 SoC, the -main controller is TOP_PMM and the auxiliary one is AON_IOCFG. Both -controllers work together to control pin multiplexing and configuration in -the way illustrated as below. - - - GMII_RXD3 ---+ - | - DVI1_HS ---+----------------------------- GMII_RXD3 (TOP pin) - | - BGPIO16 ---+ ^ - | pinconf - ^ | - | pinmux | - | | - - TOP_PMM (main) AON_IOCFG (aux) - - | | | - | pinmux | | - | pinmux v | - v | pinconf - KEY_ROW2 ---+ v - PORT1_LCD_TE ---+ | - | AGPIO10 ---+------ KEY_ROW2 (AON pin) - I2S0_DOUT3 ---+ | - |-----------------------+ - PWM_OUT3 ---+ - | - VGA_VS1 ---+ - - -For most of pins like GMII_RXD3 in the figure, the pinmux function is -controlled by TOP_PMM block only, and this type of pins are meant by term -'TOP pins'. For pins like KEY_ROW2, the pinmux is controlled by both -TOP_PMM and AON_IOCFG blocks, as the available multiplexing functions for -the pin spread in both controllers. This type of pins are called 'AON pins'. -Though pinmux implementation is quite different, pinconf is same for both -types of pins. Both are controlled by auxiliary controller, i.e. AON_IOCFG -on ZX296718. - -Required properties: -- compatible: should be "zte,zx296718-pmm". -- reg: the register physical address and length. -- zte,auxiliary-controller: phandle to the auxiliary pin controller which - implements pinmux for AON pins and pinconf for all pins. - -The following pin configuration are supported. Please refer to -pinctrl-bindings.txt in this directory for more details of the common -pinctrl bindings used by client devices. - -- bias-pull-up -- bias-pull-down -- drive-strength -- input-enable -- slew-rate - -Examples: - -iocfg: pin-controller@119000 { - compatible = "zte,zx296718-iocfg"; - reg = <0x119000 0x1000>; -}; - -pmm: pin-controller@1462000 { - compatible = "zte,zx296718-pmm"; - reg = <0x1462000 0x1000>; - zte,auxiliary-controller = <&iocfg>; -}; - -&pmm { - vga_pins: vga { - pins = "KEY_COL1", "KEY_COL2", "KEY_ROW1", "KEY_ROW2"; - function = "VGA"; - }; -}; - -&vga { - pinctrl-names = "default"; - pinctrl-0 = <&vga_pins>; -}; diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig index d4b2f2e2ed75..1c1fa681b96d 100644 --- a/drivers/pinctrl/Kconfig +++ b/drivers/pinctrl/Kconfig @@ -417,7 +417,6 @@ source "drivers/pinctrl/ti/Kconfig" source "drivers/pinctrl/uniphier/Kconfig" source "drivers/pinctrl/vt8500/Kconfig" source "drivers/pinctrl/mediatek/Kconfig" -source "drivers/pinctrl/zte/Kconfig" source "drivers/pinctrl/meson/Kconfig" source "drivers/pinctrl/cirrus/Kconfig" source "drivers/pinctrl/visconti/Kconfig" diff --git a/drivers/pinctrl/Makefile b/drivers/pinctrl/Makefile index 5bb9bb6cc3ce..fef92794900d 100644 --- a/drivers/pinctrl/Makefile +++ b/drivers/pinctrl/Makefile @@ -71,6 +71,5 @@ obj-y += ti/ obj-$(CONFIG_PINCTRL_UNIPHIER) += uniphier/ obj-$(CONFIG_ARCH_VT8500) += vt8500/ obj-y += mediatek/ -obj-$(CONFIG_PINCTRL_ZX) += zte/ obj-y += cirrus/ obj-$(CONFIG_PINCTRL_VISCONTI) += visconti/ diff --git a/drivers/pinctrl/zte/Kconfig b/drivers/pinctrl/zte/Kconfig deleted file mode 100644 index 4fdc70511034..000000000000 --- a/drivers/pinctrl/zte/Kconfig +++ /dev/null @@ -1,14 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0-only -config PINCTRL_ZX - bool - select PINMUX - select GENERIC_PINCONF - select GENERIC_PINCTRL_GROUPS - select GENERIC_PINMUX_FUNCTIONS - -config PINCTRL_ZX296718 - bool "ZTE ZX296718 pinctrl driver" - depends on OF && ARCH_ZX - select PINCTRL_ZX - help - Say Y here to enable the ZX296718 pinctrl driver diff --git a/drivers/pinctrl/zte/Makefile b/drivers/pinctrl/zte/Makefile deleted file mode 100644 index 2084c7810f96..000000000000 --- a/drivers/pinctrl/zte/Makefile +++ /dev/null @@ -1,3 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0-only -obj-$(CONFIG_PINCTRL_ZX) += pinctrl-zx.o -obj-$(CONFIG_PINCTRL_ZX296718) += pinctrl-zx296718.o diff --git a/drivers/pinctrl/zte/pinctrl-zx.c b/drivers/pinctrl/zte/pinctrl-zx.c deleted file mode 100644 index 80d00ab8c110..000000000000 --- a/drivers/pinctrl/zte/pinctrl-zx.c +++ /dev/null @@ -1,445 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Copyright (C) 2017 Sanechips Technology Co., Ltd. - * Copyright 2017 Linaro Ltd. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "../core.h" -#include "../pinctrl-utils.h" -#include "../pinmux.h" -#include "pinctrl-zx.h" - -#define ZX_PULL_DOWN BIT(0) -#define ZX_PULL_UP BIT(1) -#define ZX_INPUT_ENABLE BIT(3) -#define ZX_DS_SHIFT 4 -#define ZX_DS_MASK (0x7 << ZX_DS_SHIFT) -#define ZX_DS_VALUE(x) (((x) << ZX_DS_SHIFT) & ZX_DS_MASK) -#define ZX_SLEW BIT(8) - -struct zx_pinctrl { - struct pinctrl_dev *pctldev; - struct device *dev; - void __iomem *base; - void __iomem *aux_base; - spinlock_t lock; - struct zx_pinctrl_soc_info *info; -}; - -static int zx_dt_node_to_map(struct pinctrl_dev *pctldev, - struct device_node *np_config, - struct pinctrl_map **map, u32 *num_maps) -{ - return pinconf_generic_dt_node_to_map(pctldev, np_config, map, - num_maps, PIN_MAP_TYPE_INVALID); -} - -static const struct pinctrl_ops zx_pinctrl_ops = { - .dt_node_to_map = zx_dt_node_to_map, - .dt_free_map = pinctrl_utils_free_map, - .get_groups_count = pinctrl_generic_get_group_count, - .get_group_name = pinctrl_generic_get_group_name, - .get_group_pins = pinctrl_generic_get_group_pins, -}; - -#define NONAON_MVAL 2 - -static int zx_set_mux(struct pinctrl_dev *pctldev, unsigned int func_selector, - unsigned int group_selector) -{ - struct zx_pinctrl *zpctl = pinctrl_dev_get_drvdata(pctldev); - struct zx_pinctrl_soc_info *info = zpctl->info; - const struct pinctrl_pin_desc *pindesc = info->pins + group_selector; - struct zx_pin_data *data = pindesc->drv_data; - struct zx_mux_desc *mux; - u32 mask, offset, bitpos; - struct function_desc *func; - unsigned long flags; - u32 val, mval; - - /* Skip reserved pin */ - if (!data) - return -EINVAL; - - mux = data->muxes; - mask = (1 << data->width) - 1; - offset = data->offset; - bitpos = data->bitpos; - - func = pinmux_generic_get_function(pctldev, func_selector); - if (!func) - return -EINVAL; - - while (mux->name) { - if (strcmp(mux->name, func->name) == 0) - break; - mux++; - } - - /* Found mux value to be written */ - mval = mux->muxval; - - spin_lock_irqsave(&zpctl->lock, flags); - - if (data->aon_pin) { - /* - * It's an AON pin, whose mux register offset and bit position - * can be calculated from pin number. Each register covers 16 - * pins, and each pin occupies 2 bits. - */ - u16 aoffset = pindesc->number / 16 * 4; - u16 abitpos = (pindesc->number % 16) * 2; - - if (mval & AON_MUX_FLAG) { - /* - * This is a mux value that needs to be written into - * AON pinmux register. Write it and then we're done. - */ - val = readl(zpctl->aux_base + aoffset); - val &= ~(0x3 << abitpos); - val |= (mval & 0x3) << abitpos; - writel(val, zpctl->aux_base + aoffset); - } else { - /* - * It's a mux value that needs to be written into TOP - * pinmux register. - */ - val = readl(zpctl->base + offset); - val &= ~(mask << bitpos); - val |= (mval & mask) << bitpos; - writel(val, zpctl->base + offset); - - /* - * In this case, the AON pinmux register needs to be - * set up to select non-AON function. - */ - val = readl(zpctl->aux_base + aoffset); - val &= ~(0x3 << abitpos); - val |= NONAON_MVAL << abitpos; - writel(val, zpctl->aux_base + aoffset); - } - - } else { - /* - * This is a TOP pin, and we only need to set up TOP pinmux - * register and then we're done with it. - */ - val = readl(zpctl->base + offset); - val &= ~(mask << bitpos); - val |= (mval & mask) << bitpos; - writel(val, zpctl->base + offset); - } - - spin_unlock_irqrestore(&zpctl->lock, flags); - - return 0; -} - -static const struct pinmux_ops zx_pinmux_ops = { - .get_functions_count = pinmux_generic_get_function_count, - .get_function_name = pinmux_generic_get_function_name, - .get_function_groups = pinmux_generic_get_function_groups, - .set_mux = zx_set_mux, -}; - -static int zx_pin_config_get(struct pinctrl_dev *pctldev, unsigned int pin, - unsigned long *config) -{ - struct zx_pinctrl *zpctl = pinctrl_dev_get_drvdata(pctldev); - struct zx_pinctrl_soc_info *info = zpctl->info; - const struct pinctrl_pin_desc *pindesc = info->pins + pin; - struct zx_pin_data *data = pindesc->drv_data; - enum pin_config_param param = pinconf_to_config_param(*config); - u32 val; - - /* Skip reserved pin */ - if (!data) - return -EINVAL; - - val = readl(zpctl->aux_base + data->coffset); - val = val >> data->cbitpos; - - switch (param) { - case PIN_CONFIG_BIAS_PULL_DOWN: - val &= ZX_PULL_DOWN; - val = !!val; - if (val == 0) - return -EINVAL; - break; - case PIN_CONFIG_BIAS_PULL_UP: - val &= ZX_PULL_UP; - val = !!val; - if (val == 0) - return -EINVAL; - break; - case PIN_CONFIG_INPUT_ENABLE: - val &= ZX_INPUT_ENABLE; - val = !!val; - if (val == 0) - return -EINVAL; - break; - case PIN_CONFIG_DRIVE_STRENGTH: - val &= ZX_DS_MASK; - val = val >> ZX_DS_SHIFT; - break; - case PIN_CONFIG_SLEW_RATE: - val &= ZX_SLEW; - val = !!val; - break; - default: - return -ENOTSUPP; - } - - *config = pinconf_to_config_packed(param, val); - - return 0; -} - -static int zx_pin_config_set(struct pinctrl_dev *pctldev, unsigned int pin, - unsigned long *configs, unsigned int num_configs) -{ - struct zx_pinctrl *zpctl = pinctrl_dev_get_drvdata(pctldev); - struct zx_pinctrl_soc_info *info = zpctl->info; - const struct pinctrl_pin_desc *pindesc = info->pins + pin; - struct zx_pin_data *data = pindesc->drv_data; - enum pin_config_param param; - u32 val, arg; - int i; - - /* Skip reserved pin */ - if (!data) - return -EINVAL; - - val = readl(zpctl->aux_base + data->coffset); - - for (i = 0; i < num_configs; i++) { - param = pinconf_to_config_param(configs[i]); - arg = pinconf_to_config_argument(configs[i]); - - switch (param) { - case PIN_CONFIG_BIAS_PULL_DOWN: - val |= ZX_PULL_DOWN << data->cbitpos; - break; - case PIN_CONFIG_BIAS_PULL_UP: - val |= ZX_PULL_UP << data->cbitpos; - break; - case PIN_CONFIG_INPUT_ENABLE: - val |= ZX_INPUT_ENABLE << data->cbitpos; - break; - case PIN_CONFIG_DRIVE_STRENGTH: - val &= ~(ZX_DS_MASK << data->cbitpos); - val |= ZX_DS_VALUE(arg) << data->cbitpos; - break; - case PIN_CONFIG_SLEW_RATE: - if (arg) - val |= ZX_SLEW << data->cbitpos; - else - val &= ~ZX_SLEW << data->cbitpos; - break; - default: - return -ENOTSUPP; - } - } - - writel(val, zpctl->aux_base + data->coffset); - return 0; -} - -static const struct pinconf_ops zx_pinconf_ops = { - .pin_config_set = zx_pin_config_set, - .pin_config_get = zx_pin_config_get, - .is_generic = true, -}; - -static int zx_pinctrl_build_state(struct platform_device *pdev) -{ - struct zx_pinctrl *zpctl = platform_get_drvdata(pdev); - struct zx_pinctrl_soc_info *info = zpctl->info; - struct pinctrl_dev *pctldev = zpctl->pctldev; - struct function_desc *functions; - int nfunctions; - struct group_desc *groups; - int ngroups; - int i; - - /* Every single pin composes a group */ - ngroups = info->npins; - groups = devm_kcalloc(&pdev->dev, ngroups, sizeof(*groups), - GFP_KERNEL); - if (!groups) - return -ENOMEM; - - for (i = 0; i < ngroups; i++) { - const struct pinctrl_pin_desc *pindesc = info->pins + i; - struct group_desc *group = groups + i; - - group->name = pindesc->name; - group->pins = (int *) &pindesc->number; - group->num_pins = 1; - radix_tree_insert(&pctldev->pin_group_tree, i, group); - } - - pctldev->num_groups = ngroups; - - /* Build function list from pin mux functions */ - functions = kcalloc(info->npins, sizeof(*functions), GFP_KERNEL); - if (!functions) - return -ENOMEM; - - nfunctions = 0; - for (i = 0; i < info->npins; i++) { - const struct pinctrl_pin_desc *pindesc = info->pins + i; - struct zx_pin_data *data = pindesc->drv_data; - struct zx_mux_desc *mux; - - /* Reserved pins do not have a drv_data at all */ - if (!data) - continue; - - /* Loop over all muxes for the pin */ - mux = data->muxes; - while (mux->name) { - struct function_desc *func = functions; - - /* Search function list for given mux */ - while (func->name) { - if (strcmp(mux->name, func->name) == 0) { - /* Function exists */ - func->num_group_names++; - break; - } - func++; - } - - if (!func->name) { - /* New function */ - func->name = mux->name; - func->num_group_names = 1; - radix_tree_insert(&pctldev->pin_function_tree, - nfunctions++, func); - } - - mux++; - } - } - - pctldev->num_functions = nfunctions; - functions = krealloc(functions, nfunctions * sizeof(*functions), - GFP_KERNEL); - - /* Find pin groups for every single function */ - for (i = 0; i < info->npins; i++) { - const struct pinctrl_pin_desc *pindesc = info->pins + i; - struct zx_pin_data *data = pindesc->drv_data; - struct zx_mux_desc *mux; - - if (!data) - continue; - - mux = data->muxes; - while (mux->name) { - struct function_desc *func; - const char **group; - int j; - - /* Find function for given mux */ - for (j = 0; j < nfunctions; j++) - if (strcmp(functions[j].name, mux->name) == 0) - break; - - func = functions + j; - if (!func->group_names) { - func->group_names = devm_kcalloc(&pdev->dev, - func->num_group_names, - sizeof(*func->group_names), - GFP_KERNEL); - if (!func->group_names) { - kfree(functions); - return -ENOMEM; - } - } - - group = func->group_names; - while (*group) - group++; - *group = pindesc->name; - - mux++; - } - } - - return 0; -} - -int zx_pinctrl_init(struct platform_device *pdev, - struct zx_pinctrl_soc_info *info) -{ - struct pinctrl_desc *pctldesc; - struct zx_pinctrl *zpctl; - struct device_node *np; - int ret; - - zpctl = devm_kzalloc(&pdev->dev, sizeof(*zpctl), GFP_KERNEL); - if (!zpctl) - return -ENOMEM; - - spin_lock_init(&zpctl->lock); - - zpctl->base = devm_platform_ioremap_resource(pdev, 0); - if (IS_ERR(zpctl->base)) - return PTR_ERR(zpctl->base); - - np = of_parse_phandle(pdev->dev.of_node, "zte,auxiliary-controller", 0); - if (!np) { - dev_err(&pdev->dev, "failed to find auxiliary controller\n"); - return -ENODEV; - } - - zpctl->aux_base = of_iomap(np, 0); - of_node_put(np); - if (!zpctl->aux_base) - return -ENOMEM; - - zpctl->dev = &pdev->dev; - zpctl->info = info; - - pctldesc = devm_kzalloc(&pdev->dev, sizeof(*pctldesc), GFP_KERNEL); - if (!pctldesc) - return -ENOMEM; - - pctldesc->name = dev_name(&pdev->dev); - pctldesc->owner = THIS_MODULE; - pctldesc->pins = info->pins; - pctldesc->npins = info->npins; - pctldesc->pctlops = &zx_pinctrl_ops; - pctldesc->pmxops = &zx_pinmux_ops; - pctldesc->confops = &zx_pinconf_ops; - - zpctl->pctldev = devm_pinctrl_register(&pdev->dev, pctldesc, zpctl); - if (IS_ERR(zpctl->pctldev)) { - ret = PTR_ERR(zpctl->pctldev); - dev_err(&pdev->dev, "failed to register pinctrl: %d\n", ret); - return ret; - } - - platform_set_drvdata(pdev, zpctl); - - ret = zx_pinctrl_build_state(pdev); - if (ret) { - dev_err(&pdev->dev, "failed to build state: %d\n", ret); - return ret; - } - - dev_info(&pdev->dev, "initialized pinctrl driver\n"); - return 0; -} diff --git a/drivers/pinctrl/zte/pinctrl-zx.h b/drivers/pinctrl/zte/pinctrl-zx.h deleted file mode 100644 index a0692e2e9012..000000000000 --- a/drivers/pinctrl/zte/pinctrl-zx.h +++ /dev/null @@ -1,102 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ -/* - * Copyright (C) 2017 Sanechips Technology Co., Ltd. - * Copyright 2017 Linaro Ltd. - */ - -#ifndef __PINCTRL_ZX_H -#define __PINCTRL_ZX_H - -/** - * struct zx_mux_desc - hardware mux descriptor - * @name: mux function name - * @muxval: mux register bit value - */ -struct zx_mux_desc { - const char *name; - u8 muxval; -}; - -/** - * struct zx_pin_data - hardware per-pin data - * @aon_pin: whether it's an AON pin - * @offset: register offset within TOP pinmux controller - * @bitpos: bit position within TOP pinmux register - * @width: bit width within TOP pinmux register - * @coffset: pinconf register offset within AON controller - * @cbitpos: pinconf bit position within AON register - * @muxes: available mux function names and corresponding register values - * - * Unlike TOP pinmux and AON pinconf registers which are arranged pretty - * arbitrarily, AON pinmux register bits are well organized per pin id, and - * each pin occupies two bits, so that we can calculate the AON register offset - * and bit position from pin id. Thus, we only need to define TOP pinmux and - * AON pinconf register data for the pin. - */ -struct zx_pin_data { - bool aon_pin; - u16 offset; - u16 bitpos; - u16 width; - u16 coffset; - u16 cbitpos; - struct zx_mux_desc *muxes; -}; - -struct zx_pinctrl_soc_info { - const struct pinctrl_pin_desc *pins; - unsigned int npins; -}; - -#define TOP_PIN(pin, off, bp, wd, coff, cbp, ...) { \ - .number = pin, \ - .name = #pin, \ - .drv_data = &(struct zx_pin_data) { \ - .aon_pin = false, \ - .offset = off, \ - .bitpos = bp, \ - .width = wd, \ - .coffset = coff, \ - .cbitpos = cbp, \ - .muxes = (struct zx_mux_desc[]) { \ - __VA_ARGS__, { } }, \ - }, \ -} - -#define AON_PIN(pin, off, bp, wd, coff, cbp, ...) { \ - .number = pin, \ - .name = #pin, \ - .drv_data = &(struct zx_pin_data) { \ - .aon_pin = true, \ - .offset = off, \ - .bitpos = bp, \ - .width = wd, \ - .coffset = coff, \ - .cbitpos = cbp, \ - .muxes = (struct zx_mux_desc[]) { \ - __VA_ARGS__, { } }, \ - }, \ -} - -#define ZX_RESERVED(pin) PINCTRL_PIN(pin, #pin) - -#define TOP_MUX(_val, _name) { \ - .name = _name, \ - .muxval = _val, \ -} - -/* - * When the flag is set, it's a mux configuration for an AON pin that sits in - * AON register. Otherwise, it's one for AON pin but sitting in TOP register. - */ -#define AON_MUX_FLAG BIT(7) - -#define AON_MUX(_val, _name) { \ - .name = _name, \ - .muxval = _val | AON_MUX_FLAG, \ -} - -int zx_pinctrl_init(struct platform_device *pdev, - struct zx_pinctrl_soc_info *info); - -#endif /* __PINCTRL_ZX_H */ diff --git a/drivers/pinctrl/zte/pinctrl-zx296718.c b/drivers/pinctrl/zte/pinctrl-zx296718.c deleted file mode 100644 index c980aecb6f2f..000000000000 --- a/drivers/pinctrl/zte/pinctrl-zx296718.c +++ /dev/null @@ -1,1024 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Copyright (C) 2017 Sanechips Technology Co., Ltd. - * Copyright 2017 Linaro Ltd. - */ - -#include -#include -#include -#include -#include -#include - -#include "pinctrl-zx.h" - -#define TOP_REG0 0x00 -#define TOP_REG1 0x04 -#define TOP_REG2 0x08 -#define TOP_REG3 0x0c -#define TOP_REG4 0x10 -#define TOP_REG5 0x14 -#define TOP_REG6 0x18 -#define TOP_REG7 0x1c -#define TOP_REG8 0x20 - -/* - * The pin numbering starts from AON pins with reserved ones included, - * so that register data like offset and bit position for AON pins can - * be calculated from pin number. - */ -enum zx296718_pin { - /* aon_pmm_reg_0 */ - I2C3_SCL = 0, - I2C3_SDA = 1, - AON_RESERVED0 = 2, - AON_RESERVED1 = 3, - SEC_EN = 4, - UART0_RXD = 5, - UART0_TXD = 6, - IR_IN = 7, - SPI0_CLK = 8, - SPI0_CS = 9, - SPI0_TXD = 10, - SPI0_RXD = 11, - KEY_COL0 = 12, - KEY_COL1 = 13, - KEY_COL2 = 14, - KEY_ROW0 = 15, - - /* aon_pmm_reg_1 */ - KEY_ROW1 = 16, - KEY_ROW2 = 17, - HDMI_SCL = 18, - HDMI_SDA = 19, - JTAG_TCK = 20, - JTAG_TRSTN = 21, - JTAG_TMS = 22, - JTAG_TDI = 23, - JTAG_TDO = 24, - I2C0_SCL = 25, - I2C0_SDA = 26, - I2C1_SCL = 27, - I2C1_SDA = 28, - AON_RESERVED2 = 29, - AON_RESERVED3 = 30, - AON_RESERVED4 = 31, - - /* aon_pmm_reg_2 */ - SPI1_CLK = 32, - SPI1_CS = 33, - SPI1_TXD = 34, - SPI1_RXD = 35, - AON_RESERVED5 = 36, - AON_RESERVED6 = 37, - AUDIO_DET = 38, - SPDIF_OUT = 39, - HDMI_CEC = 40, - HDMI_HPD = 41, - GMAC_25M_OUT = 42, - BOOT_SEL0 = 43, - BOOT_SEL1 = 44, - BOOT_SEL2 = 45, - DEEP_SLEEP_OUT_N = 46, - AON_RESERVED7 = 47, - - /* top_pmm_reg_0 */ - GMII_GTX_CLK = 48, - GMII_TX_CLK = 49, - GMII_TXD0 = 50, - GMII_TXD1 = 51, - GMII_TXD2 = 52, - GMII_TXD3 = 53, - GMII_TXD4 = 54, - GMII_TXD5 = 55, - GMII_TXD6 = 56, - GMII_TXD7 = 57, - GMII_TX_ER = 58, - GMII_TX_EN = 59, - GMII_RX_CLK = 60, - GMII_RXD0 = 61, - GMII_RXD1 = 62, - GMII_RXD2 = 63, - - /* top_pmm_reg_1 */ - GMII_RXD3 = 64, - GMII_RXD4 = 65, - GMII_RXD5 = 66, - GMII_RXD6 = 67, - GMII_RXD7 = 68, - GMII_RX_ER = 69, - GMII_RX_DV = 70, - GMII_COL = 71, - GMII_CRS = 72, - GMII_MDC = 73, - GMII_MDIO = 74, - SDIO1_CLK = 75, - SDIO1_CMD = 76, - SDIO1_DATA0 = 77, - SDIO1_DATA1 = 78, - SDIO1_DATA2 = 79, - - /* top_pmm_reg_2 */ - SDIO1_DATA3 = 80, - SDIO1_CD = 81, - SDIO1_WP = 82, - USIM1_CD = 83, - USIM1_CLK = 84, - USIM1_RST = 85, - - /* top_pmm_reg_3 */ - USIM1_DATA = 86, - SDIO0_CLK = 87, - SDIO0_CMD = 88, - SDIO0_DATA0 = 89, - SDIO0_DATA1 = 90, - SDIO0_DATA2 = 91, - SDIO0_DATA3 = 92, - SDIO0_CD = 93, - SDIO0_WP = 94, - - /* top_pmm_reg_4 */ - TSI0_DATA0 = 95, - SPINOR_CLK = 96, - TSI2_DATA = 97, - TSI2_CLK = 98, - TSI2_SYNC = 99, - TSI2_VALID = 100, - SPINOR_CS = 101, - SPINOR_DQ0 = 102, - SPINOR_DQ1 = 103, - SPINOR_DQ2 = 104, - SPINOR_DQ3 = 105, - VGA_HS = 106, - VGA_VS = 107, - TSI3_DATA = 108, - - /* top_pmm_reg_5 */ - TSI3_CLK = 109, - TSI3_SYNC = 110, - TSI3_VALID = 111, - I2S1_WS = 112, - I2S1_BCLK = 113, - I2S1_MCLK = 114, - I2S1_DIN0 = 115, - I2S1_DOUT0 = 116, - SPI3_CLK = 117, - SPI3_CS = 118, - SPI3_TXD = 119, - NAND_LDO_MS18_SEL = 120, - - /* top_pmm_reg_6 */ - SPI3_RXD = 121, - I2S0_MCLK = 122, - I2S0_BCLK = 123, - I2S0_WS = 124, - I2S0_DIN0 = 125, - I2S0_DOUT0 = 126, - I2C5_SCL = 127, - I2C5_SDA = 128, - SPI2_CLK = 129, - SPI2_CS = 130, - SPI2_TXD = 131, - - /* top_pmm_reg_7 */ - SPI2_RXD = 132, - NAND_WP_N = 133, - NAND_PAGE_SIZE0 = 134, - NAND_PAGE_SIZE1 = 135, - NAND_ADDR_CYCLE = 136, - NAND_RB0 = 137, - NAND_RB1 = 138, - NAND_RB2 = 139, - NAND_RB3 = 140, - - /* top_pmm_reg_8 */ - GMAC_125M_IN = 141, - GMAC_50M_OUT = 142, - SPINOR_SSCLK_LOOPBACK = 143, - SPINOR_SDIO1CLK_LOOPBACK = 144, -}; - -static const struct pinctrl_pin_desc zx296718_pins[] = { - /* aon_pmm_reg_0 */ - AON_PIN(I2C3_SCL, TOP_REG2, 18, 2, 0x48, 0, - AON_MUX(0x0, "ANMI"), /* anmi */ - AON_MUX(0x1, "AGPIO"), /* agpio29 */ - AON_MUX(0x2, "nonAON"), /* pin0 */ - AON_MUX(0x3, "EXT_INT"), /* int4 */ - TOP_MUX(0x0, "I2C3"), /* scl */ - TOP_MUX(0x1, "SPI2"), /* txd */ - TOP_MUX(0x2, "I2S1")), /* din0 */ - AON_PIN(I2C3_SDA, TOP_REG2, 20, 2, 0x48, 9, - AON_MUX(0x0, "WD"), /* rst_b */ - AON_MUX(0x1, "AGPIO"), /* agpio30 */ - AON_MUX(0x2, "nonAON"), /* pin1 */ - AON_MUX(0x3, "EXT_INT"), /* int5 */ - TOP_MUX(0x0, "I2C3"), /* sda */ - TOP_MUX(0x1, "SPI2"), /* rxd */ - TOP_MUX(0x2, "I2S0")), /* mclk */ - ZX_RESERVED(AON_RESERVED0), - ZX_RESERVED(AON_RESERVED1), - AON_PIN(SEC_EN, TOP_REG3, 5, 1, 0x50, 0, - AON_MUX(0x0, "SEC"), /* en */ - AON_MUX(0x1, "AGPIO"), /* agpio28 */ - AON_MUX(0x2, "nonAON"), /* pin3 */ - AON_MUX(0x3, "EXT_INT"), /* int7 */ - TOP_MUX(0x0, "I2C2"), /* sda */ - TOP_MUX(0x1, "SPI2")), /* cs */ - AON_PIN(UART0_RXD, 0, 0, 0, 0x50, 9, - AON_MUX(0x0, "UART0"), /* rxd */ - AON_MUX(0x1, "AGPIO"), /* agpio20 */ - AON_MUX(0x2, "nonAON")), /* pin34 */ - AON_PIN(UART0_TXD, 0, 0, 0, 0x50, 18, - AON_MUX(0x0, "UART0"), /* txd */ - AON_MUX(0x1, "AGPIO"), /* agpio21 */ - AON_MUX(0x2, "nonAON")), /* pin32 */ - AON_PIN(IR_IN, 0, 0, 0, 0x64, 0, - AON_MUX(0x0, "IR"), /* in */ - AON_MUX(0x1, "AGPIO"), /* agpio0 */ - AON_MUX(0x2, "nonAON")), /* pin27 */ - AON_PIN(SPI0_CLK, TOP_REG3, 16, 1, 0x64, 9, - AON_MUX(0x0, "EXT_INT"), /* int0 */ - AON_MUX(0x1, "AGPIO"), /* agpio23 */ - AON_MUX(0x2, "nonAON"), /* pin5 */ - AON_MUX(0x3, "PCU"), /* test6 */ - TOP_MUX(0x0, "SPI0"), /* clk */ - TOP_MUX(0x1, "ISP")), /* flash_trig */ - AON_PIN(SPI0_CS, TOP_REG3, 17, 1, 0x64, 18, - AON_MUX(0x0, "EXT_INT"), /* int1 */ - AON_MUX(0x1, "AGPIO"), /* agpio24 */ - AON_MUX(0x2, "nonAON"), /* pin6 */ - AON_MUX(0x3, "PCU"), /* test0 */ - TOP_MUX(0x0, "SPI0"), /* cs */ - TOP_MUX(0x1, "ISP")), /* prelight_trig */ - AON_PIN(SPI0_TXD, TOP_REG3, 18, 1, 0x68, 0, - AON_MUX(0x0, "EXT_INT"), /* int2 */ - AON_MUX(0x1, "AGPIO"), /* agpio25 */ - AON_MUX(0x2, "nonAON"), /* pin7 */ - AON_MUX(0x3, "PCU"), /* test1 */ - TOP_MUX(0x0, "SPI0"), /* txd */ - TOP_MUX(0x1, "ISP")), /* shutter_trig */ - AON_PIN(SPI0_RXD, TOP_REG3, 19, 1, 0x68, 9, - AON_MUX(0x0, "EXT_INT"), /* int3 */ - AON_MUX(0x1, "AGPIO"), /* agpio26 */ - AON_MUX(0x2, "nonAON"), /* pin8 */ - AON_MUX(0x3, "PCU"), /* test2 */ - TOP_MUX(0x0, "SPI0"), /* rxd */ - TOP_MUX(0x1, "ISP")), /* shutter_open */ - AON_PIN(KEY_COL0, TOP_REG3, 20, 1, 0x68, 18, - AON_MUX(0x0, "KEY"), /* col0 */ - AON_MUX(0x1, "AGPIO"), /* agpio5 */ - AON_MUX(0x2, "nonAON"), /* pin9 */ - AON_MUX(0x3, "PCU"), /* test3 */ - TOP_MUX(0x0, "UART3"), /* rxd */ - TOP_MUX(0x1, "I2S0")), /* din1 */ - AON_PIN(KEY_COL1, TOP_REG3, 21, 2, 0x6c, 0, - AON_MUX(0x0, "KEY"), /* col1 */ - AON_MUX(0x1, "AGPIO"), /* agpio6 */ - AON_MUX(0x2, "nonAON"), /* pin10 */ - TOP_MUX(0x0, "UART3"), /* txd */ - TOP_MUX(0x1, "I2S0"), /* din2 */ - TOP_MUX(0x2, "VGA")), /* scl */ - AON_PIN(KEY_COL2, TOP_REG3, 23, 2, 0x6c, 9, - AON_MUX(0x0, "KEY"), /* col2 */ - AON_MUX(0x1, "AGPIO"), /* agpio7 */ - AON_MUX(0x2, "nonAON"), /* pin11 */ - TOP_MUX(0x0, "PWM"), /* out1 */ - TOP_MUX(0x1, "I2S0"), /* din3 */ - TOP_MUX(0x2, "VGA")), /* sda */ - AON_PIN(KEY_ROW0, 0, 0, 0, 0x6c, 18, - AON_MUX(0x0, "KEY"), /* row0 */ - AON_MUX(0x1, "AGPIO"), /* agpio8 */ - AON_MUX(0x2, "nonAON"), /* pin33 */ - AON_MUX(0x3, "WD")), /* rst_b */ - - /* aon_pmm_reg_1 */ - AON_PIN(KEY_ROW1, TOP_REG3, 25, 2, 0x70, 0, - AON_MUX(0x0, "KEY"), /* row1 */ - AON_MUX(0x1, "AGPIO"), /* agpio9 */ - AON_MUX(0x2, "nonAON"), /* pin12 */ - TOP_MUX(0x0, "LCD"), /* port0 lcd_te */ - TOP_MUX(0x1, "I2S0"), /* dout2 */ - TOP_MUX(0x2, "PWM"), /* out2 */ - TOP_MUX(0x3, "VGA")), /* hs1 */ - AON_PIN(KEY_ROW2, TOP_REG3, 27, 2, 0x70, 9, - AON_MUX(0x0, "KEY"), /* row2 */ - AON_MUX(0x1, "AGPIO"), /* agpio10 */ - AON_MUX(0x2, "nonAON"), /* pin13 */ - TOP_MUX(0x0, "LCD"), /* port1 lcd_te */ - TOP_MUX(0x1, "I2S0"), /* dout3 */ - TOP_MUX(0x2, "PWM"), /* out3 */ - TOP_MUX(0x3, "VGA")), /* vs1 */ - AON_PIN(HDMI_SCL, TOP_REG3, 29, 1, 0x70, 18, - AON_MUX(0x0, "PCU"), /* test7 */ - AON_MUX(0x1, "AGPIO"), /* agpio3 */ - AON_MUX(0x2, "nonAON"), /* pin14 */ - TOP_MUX(0x0, "HDMI"), /* scl */ - TOP_MUX(0x1, "UART3")), /* rxd */ - AON_PIN(HDMI_SDA, TOP_REG3, 30, 1, 0x74, 0, - AON_MUX(0x0, "PCU"), /* test8 */ - AON_MUX(0x1, "AGPIO"), /* agpio4 */ - AON_MUX(0x2, "nonAON"), /* pin15 */ - TOP_MUX(0x0, "HDMI"), /* sda */ - TOP_MUX(0x1, "UART3")), /* txd */ - AON_PIN(JTAG_TCK, TOP_REG7, 3, 1, 0x78, 18, - AON_MUX(0x0, "JTAG"), /* tck */ - AON_MUX(0x1, "AGPIO"), /* agpio11 */ - AON_MUX(0x2, "nonAON"), /* pin22 */ - AON_MUX(0x3, "EXT_INT"), /* int4 */ - TOP_MUX(0x0, "SPI4"), /* clk */ - TOP_MUX(0x1, "UART1")), /* rxd */ - AON_PIN(JTAG_TRSTN, TOP_REG7, 4, 1, 0xac, 0, - AON_MUX(0x0, "JTAG"), /* trstn */ - AON_MUX(0x1, "AGPIO"), /* agpio12 */ - AON_MUX(0x2, "nonAON"), /* pin23 */ - AON_MUX(0x3, "EXT_INT"), /* int5 */ - TOP_MUX(0x0, "SPI4"), /* cs */ - TOP_MUX(0x1, "UART1")), /* txd */ - AON_PIN(JTAG_TMS, TOP_REG7, 5, 1, 0xac, 9, - AON_MUX(0x0, "JTAG"), /* tms */ - AON_MUX(0x1, "AGPIO"), /* agpio13 */ - AON_MUX(0x2, "nonAON"), /* pin24 */ - AON_MUX(0x3, "EXT_INT"), /* int6 */ - TOP_MUX(0x0, "SPI4"), /* txd */ - TOP_MUX(0x1, "UART2")), /* rxd */ - AON_PIN(JTAG_TDI, TOP_REG7, 6, 1, 0xac, 18, - AON_MUX(0x0, "JTAG"), /* tdi */ - AON_MUX(0x1, "AGPIO"), /* agpio14 */ - AON_MUX(0x2, "nonAON"), /* pin25 */ - AON_MUX(0x3, "EXT_INT"), /* int7 */ - TOP_MUX(0x0, "SPI4"), /* rxd */ - TOP_MUX(0x1, "UART2")), /* txd */ - AON_PIN(JTAG_TDO, 0, 0, 0, 0xb0, 0, - AON_MUX(0x0, "JTAG"), /* tdo */ - AON_MUX(0x1, "AGPIO"), /* agpio15 */ - AON_MUX(0x2, "nonAON")), /* pin26 */ - AON_PIN(I2C0_SCL, 0, 0, 0, 0xb0, 9, - AON_MUX(0x0, "I2C0"), /* scl */ - AON_MUX(0x1, "AGPIO"), /* agpio16 */ - AON_MUX(0x2, "nonAON")), /* pin28 */ - AON_PIN(I2C0_SDA, 0, 0, 0, 0xb0, 18, - AON_MUX(0x0, "I2C0"), /* sda */ - AON_MUX(0x1, "AGPIO"), /* agpio17 */ - AON_MUX(0x2, "nonAON")), /* pin29 */ - AON_PIN(I2C1_SCL, TOP_REG8, 4, 1, 0xb4, 0, - AON_MUX(0x0, "I2C1"), /* scl */ - AON_MUX(0x1, "AGPIO"), /* agpio18 */ - AON_MUX(0x2, "nonAON"), /* pin30 */ - TOP_MUX(0x0, "LCD")), /* port0 lcd_te */ - AON_PIN(I2C1_SDA, TOP_REG8, 5, 1, 0xb4, 9, - AON_MUX(0x0, "I2C1"), /* sda */ - AON_MUX(0x1, "AGPIO"), /* agpio19 */ - AON_MUX(0x2, "nonAON"), /* pin31 */ - TOP_MUX(0x0, "LCD")), /* port1 lcd_te */ - ZX_RESERVED(AON_RESERVED2), - ZX_RESERVED(AON_RESERVED3), - ZX_RESERVED(AON_RESERVED4), - - /* aon_pmm_reg_2 */ - AON_PIN(SPI1_CLK, TOP_REG2, 6, 3, 0x40, 9, - AON_MUX(0x0, "EXT_INT"), /* int0 */ - AON_MUX(0x1, "PCU"), /* test12 */ - AON_MUX(0x2, "nonAON"), /* pin39 */ - TOP_MUX(0x0, "SPI1"), /* clk */ - TOP_MUX(0x1, "PCM"), /* clk */ - TOP_MUX(0x2, "BGPIO"), /* gpio35 */ - TOP_MUX(0x3, "I2C4"), /* scl */ - TOP_MUX(0x4, "I2S1"), /* mclk */ - TOP_MUX(0x5, "ISP")), /* flash_trig */ - AON_PIN(SPI1_CS, TOP_REG2, 9, 3, 0x40, 18, - AON_MUX(0x0, "EXT_INT"), /* int1 */ - AON_MUX(0x1, "PCU"), /* test13 */ - AON_MUX(0x2, "nonAON"), /* pin40 */ - TOP_MUX(0x0, "SPI1"), /* cs */ - TOP_MUX(0x1, "PCM"), /* fs */ - TOP_MUX(0x2, "BGPIO"), /* gpio36 */ - TOP_MUX(0x3, "I2C4"), /* sda */ - TOP_MUX(0x4, "I2S1"), /* bclk */ - TOP_MUX(0x5, "ISP")), /* prelight_trig */ - AON_PIN(SPI1_TXD, TOP_REG2, 12, 3, 0x44, 0, - AON_MUX(0x0, "EXT_INT"), /* int2 */ - AON_MUX(0x1, "PCU"), /* test14 */ - AON_MUX(0x2, "nonAON"), /* pin41 */ - TOP_MUX(0x0, "SPI1"), /* txd */ - TOP_MUX(0x1, "PCM"), /* txd */ - TOP_MUX(0x2, "BGPIO"), /* gpio37 */ - TOP_MUX(0x3, "UART5"), /* rxd */ - TOP_MUX(0x4, "I2S1"), /* ws */ - TOP_MUX(0x5, "ISP")), /* shutter_trig */ - AON_PIN(SPI1_RXD, TOP_REG2, 15, 3, 0x44, 9, - AON_MUX(0x0, "EXT_INT"), /* int3 */ - AON_MUX(0x1, "PCU"), /* test15 */ - AON_MUX(0x2, "nonAON"), /* pin42 */ - TOP_MUX(0x0, "SPI1"), /* rxd */ - TOP_MUX(0x1, "PCM"), /* rxd */ - TOP_MUX(0x2, "BGPIO"), /* gpio38 */ - TOP_MUX(0x3, "UART5"), /* txd */ - TOP_MUX(0x4, "I2S1"), /* dout0 */ - TOP_MUX(0x5, "ISP")), /* shutter_open */ - ZX_RESERVED(AON_RESERVED5), - ZX_RESERVED(AON_RESERVED6), - AON_PIN(AUDIO_DET, TOP_REG3, 3, 2, 0x48, 18, - AON_MUX(0x0, "PCU"), /* test4 */ - AON_MUX(0x1, "AGPIO"), /* agpio27 */ - AON_MUX(0x2, "nonAON"), /* pin2 */ - AON_MUX(0x3, "EXT_INT"), /* int16 */ - TOP_MUX(0x0, "AUDIO"), /* detect */ - TOP_MUX(0x1, "I2C2"), /* scl */ - TOP_MUX(0x2, "SPI2")), /* clk */ - AON_PIN(SPDIF_OUT, TOP_REG3, 14, 2, 0x78, 9, - AON_MUX(0x0, "PCU"), /* test5 */ - AON_MUX(0x1, "AGPIO"), /* agpio22 */ - AON_MUX(0x2, "nonAON"), /* pin4 */ - TOP_MUX(0x0, "SPDIF"), /* out */ - TOP_MUX(0x1, "PWM"), /* out0 */ - TOP_MUX(0x2, "ISP")), /* fl_trig */ - AON_PIN(HDMI_CEC, 0, 0, 0, 0x74, 9, - AON_MUX(0x0, "PCU"), /* test9 */ - AON_MUX(0x1, "AGPIO"), /* agpio1 */ - AON_MUX(0x2, "nonAON")), /* pin16 */ - AON_PIN(HDMI_HPD, 0, 0, 0, 0x74, 18, - AON_MUX(0x0, "PCU"), /* test10 */ - AON_MUX(0x1, "AGPIO"), /* agpio2 */ - AON_MUX(0x2, "nonAON")), /* pin17 */ - AON_PIN(GMAC_25M_OUT, 0, 0, 0, 0x78, 0, - AON_MUX(0x0, "PCU"), /* test11 */ - AON_MUX(0x1, "AGPIO"), /* agpio31 */ - AON_MUX(0x2, "nonAON")), /* pin43 */ - AON_PIN(BOOT_SEL0, 0, 0, 0, 0xc0, 9, - AON_MUX(0x0, "BOOT"), /* sel0 */ - AON_MUX(0x1, "AGPIO"), /* agpio18 */ - AON_MUX(0x2, "nonAON")), /* pin18 */ - AON_PIN(BOOT_SEL1, 0, 0, 0, 0xc0, 18, - AON_MUX(0x0, "BOOT"), /* sel1 */ - AON_MUX(0x1, "AGPIO"), /* agpio19 */ - AON_MUX(0x2, "nonAON")), /* pin19 */ - AON_PIN(BOOT_SEL2, 0, 0, 0, 0xc4, 0, - AON_MUX(0x0, "BOOT"), /* sel2 */ - AON_MUX(0x1, "AGPIO"), /* agpio20 */ - AON_MUX(0x2, "nonAON")), /* pin20 */ - AON_PIN(DEEP_SLEEP_OUT_N, 0, 0, 0, 0xc4, 9, - AON_MUX(0x0, "DEEPSLP"), /* deep sleep out_n */ - AON_MUX(0x1, "AGPIO"), /* agpio21 */ - AON_MUX(0x2, "nonAON")), /* pin21 */ - ZX_RESERVED(AON_RESERVED7), - - /* top_pmm_reg_0 */ - TOP_PIN(GMII_GTX_CLK, TOP_REG0, 0, 2, 0x10, 0, - TOP_MUX(0x0, "GMII"), /* gtx_clk */ - TOP_MUX(0x1, "DVI0"), /* clk */ - TOP_MUX(0x2, "BGPIO")), /* gpio0 */ - TOP_PIN(GMII_TX_CLK, TOP_REG0, 2, 2, 0x10, 9, - TOP_MUX(0x0, "GMII"), /* tx_clk */ - TOP_MUX(0x1, "DVI0"), /* vs */ - TOP_MUX(0x2, "BGPIO")), /* gpio1 */ - TOP_PIN(GMII_TXD0, TOP_REG0, 4, 2, 0x10, 18, - TOP_MUX(0x0, "GMII"), /* txd0 */ - TOP_MUX(0x1, "DVI0"), /* hs */ - TOP_MUX(0x2, "BGPIO")), /* gpio2 */ - TOP_PIN(GMII_TXD1, TOP_REG0, 6, 2, 0x14, 0, - TOP_MUX(0x0, "GMII"), /* txd1 */ - TOP_MUX(0x1, "DVI0"), /* d0 */ - TOP_MUX(0x2, "BGPIO")), /* gpio3 */ - TOP_PIN(GMII_TXD2, TOP_REG0, 8, 2, 0x14, 9, - TOP_MUX(0x0, "GMII"), /* txd2 */ - TOP_MUX(0x1, "DVI0"), /* d1 */ - TOP_MUX(0x2, "BGPIO")), /* gpio4 */ - TOP_PIN(GMII_TXD3, TOP_REG0, 10, 2, 0x14, 18, - TOP_MUX(0x0, "GMII"), /* txd3 */ - TOP_MUX(0x1, "DVI0"), /* d2 */ - TOP_MUX(0x2, "BGPIO")), /* gpio5 */ - TOP_PIN(GMII_TXD4, TOP_REG0, 12, 2, 0x18, 0, - TOP_MUX(0x0, "GMII"), /* txd4 */ - TOP_MUX(0x1, "DVI0"), /* d3 */ - TOP_MUX(0x2, "BGPIO")), /* gpio6 */ - TOP_PIN(GMII_TXD5, TOP_REG0, 14, 2, 0x18, 9, - TOP_MUX(0x0, "GMII"), /* txd5 */ - TOP_MUX(0x1, "DVI0"), /* d4 */ - TOP_MUX(0x2, "BGPIO")), /* gpio7 */ - TOP_PIN(GMII_TXD6, TOP_REG0, 16, 2, 0x18, 18, - TOP_MUX(0x0, "GMII"), /* txd6 */ - TOP_MUX(0x1, "DVI0"), /* d5 */ - TOP_MUX(0x2, "BGPIO")), /* gpio8 */ - TOP_PIN(GMII_TXD7, TOP_REG0, 18, 2, 0x1c, 0, - TOP_MUX(0x0, "GMII"), /* txd7 */ - TOP_MUX(0x1, "DVI0"), /* d6 */ - TOP_MUX(0x2, "BGPIO")), /* gpio9 */ - TOP_PIN(GMII_TX_ER, TOP_REG0, 20, 2, 0x1c, 9, - TOP_MUX(0x0, "GMII"), /* tx_er */ - TOP_MUX(0x1, "DVI0"), /* d7 */ - TOP_MUX(0x2, "BGPIO")), /* gpio10 */ - TOP_PIN(GMII_TX_EN, TOP_REG0, 22, 2, 0x1c, 18, - TOP_MUX(0x0, "GMII"), /* tx_en */ - TOP_MUX(0x1, "DVI0"), /* d8 */ - TOP_MUX(0x3, "BGPIO")), /* gpio11 */ - TOP_PIN(GMII_RX_CLK, TOP_REG0, 24, 2, 0x20, 0, - TOP_MUX(0x0, "GMII"), /* rx_clk */ - TOP_MUX(0x1, "DVI0"), /* d9 */ - TOP_MUX(0x3, "BGPIO")), /* gpio12 */ - TOP_PIN(GMII_RXD0, TOP_REG0, 26, 2, 0x20, 9, - TOP_MUX(0x0, "GMII"), /* rxd0 */ - TOP_MUX(0x1, "DVI0"), /* d10 */ - TOP_MUX(0x3, "BGPIO")), /* gpio13 */ - TOP_PIN(GMII_RXD1, TOP_REG0, 28, 2, 0x20, 18, - TOP_MUX(0x0, "GMII"), /* rxd1 */ - TOP_MUX(0x1, "DVI0"), /* d11 */ - TOP_MUX(0x2, "BGPIO")), /* gpio14 */ - TOP_PIN(GMII_RXD2, TOP_REG0, 30, 2, 0x24, 0, - TOP_MUX(0x0, "GMII"), /* rxd2 */ - TOP_MUX(0x1, "DVI1"), /* clk */ - TOP_MUX(0x2, "BGPIO")), /* gpio15 */ - - /* top_pmm_reg_1 */ - TOP_PIN(GMII_RXD3, TOP_REG1, 0, 2, 0x24, 9, - TOP_MUX(0x0, "GMII"), /* rxd3 */ - TOP_MUX(0x1, "DVI1"), /* hs */ - TOP_MUX(0x2, "BGPIO")), /* gpio16 */ - TOP_PIN(GMII_RXD4, TOP_REG1, 2, 2, 0x24, 18, - TOP_MUX(0x0, "GMII"), /* rxd4 */ - TOP_MUX(0x1, "DVI1"), /* vs */ - TOP_MUX(0x2, "BGPIO")), /* gpio17 */ - TOP_PIN(GMII_RXD5, TOP_REG1, 4, 2, 0x28, 0, - TOP_MUX(0x0, "GMII"), /* rxd5 */ - TOP_MUX(0x1, "DVI1"), /* d0 */ - TOP_MUX(0x2, "BGPIO"), /* gpio18 */ - TOP_MUX(0x3, "TSI0")), /* dat0 */ - TOP_PIN(GMII_RXD6, TOP_REG1, 6, 2, 0x28, 9, - TOP_MUX(0x0, "GMII"), /* rxd6 */ - TOP_MUX(0x1, "DVI1"), /* d1 */ - TOP_MUX(0x2, "BGPIO"), /* gpio19 */ - TOP_MUX(0x3, "TSI0")), /* clk */ - TOP_PIN(GMII_RXD7, TOP_REG1, 8, 2, 0x28, 18, - TOP_MUX(0x0, "GMII"), /* rxd7 */ - TOP_MUX(0x1, "DVI1"), /* d2 */ - TOP_MUX(0x2, "BGPIO"), /* gpio20 */ - TOP_MUX(0x3, "TSI0")), /* sync */ - TOP_PIN(GMII_RX_ER, TOP_REG1, 10, 2, 0x2c, 0, - TOP_MUX(0x0, "GMII"), /* rx_er */ - TOP_MUX(0x1, "DVI1"), /* d3 */ - TOP_MUX(0x2, "BGPIO"), /* gpio21 */ - TOP_MUX(0x3, "TSI0")), /* valid */ - TOP_PIN(GMII_RX_DV, TOP_REG1, 12, 2, 0x2c, 9, - TOP_MUX(0x0, "GMII"), /* rx_dv */ - TOP_MUX(0x1, "DVI1"), /* d4 */ - TOP_MUX(0x2, "BGPIO"), /* gpio22 */ - TOP_MUX(0x3, "TSI1")), /* dat0 */ - TOP_PIN(GMII_COL, TOP_REG1, 14, 2, 0x2c, 18, - TOP_MUX(0x0, "GMII"), /* col */ - TOP_MUX(0x1, "DVI1"), /* d5 */ - TOP_MUX(0x2, "BGPIO"), /* gpio23 */ - TOP_MUX(0x3, "TSI1")), /* clk */ - TOP_PIN(GMII_CRS, TOP_REG1, 16, 2, 0x30, 0, - TOP_MUX(0x0, "GMII"), /* crs */ - TOP_MUX(0x1, "DVI1"), /* d6 */ - TOP_MUX(0x2, "BGPIO"), /* gpio24 */ - TOP_MUX(0x3, "TSI1")), /* sync */ - TOP_PIN(GMII_MDC, TOP_REG1, 18, 2, 0x30, 9, - TOP_MUX(0x0, "GMII"), /* mdc */ - TOP_MUX(0x1, "DVI1"), /* d7 */ - TOP_MUX(0x2, "BGPIO"), /* gpio25 */ - TOP_MUX(0x3, "TSI1")), /* valid */ - TOP_PIN(GMII_MDIO, TOP_REG1, 20, 1, 0x30, 18, - TOP_MUX(0x0, "GMII"), /* mdio */ - TOP_MUX(0x2, "BGPIO")), /* gpio26 */ - TOP_PIN(SDIO1_CLK, TOP_REG1, 21, 2, 0x34, 18, - TOP_MUX(0x0, "SDIO1"), /* clk */ - TOP_MUX(0x1, "USIM0"), /* clk */ - TOP_MUX(0x2, "BGPIO"), /* gpio27 */ - TOP_MUX(0x3, "SPINOR")), /* clk */ - TOP_PIN(SDIO1_CMD, TOP_REG1, 23, 2, 0x38, 0, - TOP_MUX(0x0, "SDIO1"), /* cmd */ - TOP_MUX(0x1, "USIM0"), /* cd */ - TOP_MUX(0x2, "BGPIO"), /* gpio28 */ - TOP_MUX(0x3, "SPINOR")), /* cs */ - TOP_PIN(SDIO1_DATA0, TOP_REG1, 25, 2, 0x38, 9, - TOP_MUX(0x0, "SDIO1"), /* dat0 */ - TOP_MUX(0x1, "USIM0"), /* rst */ - TOP_MUX(0x2, "BGPIO"), /* gpio29 */ - TOP_MUX(0x3, "SPINOR")), /* dq0 */ - TOP_PIN(SDIO1_DATA1, TOP_REG1, 27, 2, 0x38, 18, - TOP_MUX(0x0, "SDIO1"), /* dat1 */ - TOP_MUX(0x1, "USIM0"), /* data */ - TOP_MUX(0x2, "BGPIO"), /* gpio30 */ - TOP_MUX(0x3, "SPINOR")), /* dq1 */ - TOP_PIN(SDIO1_DATA2, TOP_REG1, 29, 2, 0x3c, 0, - TOP_MUX(0x0, "SDIO1"), /* dat2 */ - TOP_MUX(0x1, "BGPIO"), /* gpio31 */ - TOP_MUX(0x2, "SPINOR")), /* dq2 */ - - /* top_pmm_reg_2 */ - TOP_PIN(SDIO1_DATA3, TOP_REG2, 0, 2, 0x3c, 9, - TOP_MUX(0x0, "SDIO1"), /* dat3 */ - TOP_MUX(0x1, "BGPIO"), /* gpio32 */ - TOP_MUX(0x2, "SPINOR")), /* dq3 */ - TOP_PIN(SDIO1_CD, TOP_REG2, 2, 2, 0x3c, 18, - TOP_MUX(0x0, "SDIO1"), /* cd */ - TOP_MUX(0x1, "BGPIO"), /* gpio33 */ - TOP_MUX(0x2, "ISP")), /* fl_trig */ - TOP_PIN(SDIO1_WP, TOP_REG2, 4, 2, 0x40, 0, - TOP_MUX(0x0, "SDIO1"), /* wp */ - TOP_MUX(0x1, "BGPIO"), /* gpio34 */ - TOP_MUX(0x2, "ISP")), /* ref_clk */ - TOP_PIN(USIM1_CD, TOP_REG2, 22, 3, 0x44, 18, - TOP_MUX(0x0, "USIM1"), /* cd */ - TOP_MUX(0x1, "UART4"), /* rxd */ - TOP_MUX(0x2, "BGPIO"), /* gpio39 */ - TOP_MUX(0x3, "SPI3"), /* clk */ - TOP_MUX(0x4, "I2S0"), /* bclk */ - TOP_MUX(0x5, "B_DVI0")), /* d8 */ - TOP_PIN(USIM1_CLK, TOP_REG2, 25, 3, 0x4c, 18, - TOP_MUX(0x0, "USIM1"), /* clk */ - TOP_MUX(0x1, "UART4"), /* txd */ - TOP_MUX(0x2, "BGPIO"), /* gpio40 */ - TOP_MUX(0x3, "SPI3"), /* cs */ - TOP_MUX(0x4, "I2S0"), /* ws */ - TOP_MUX(0x5, "B_DVI0")), /* d9 */ - TOP_PIN(USIM1_RST, TOP_REG2, 28, 3, 0x4c, 0, - TOP_MUX(0x0, "USIM1"), /* rst */ - TOP_MUX(0x1, "UART4"), /* cts */ - TOP_MUX(0x2, "BGPIO"), /* gpio41 */ - TOP_MUX(0x3, "SPI3"), /* txd */ - TOP_MUX(0x4, "I2S0"), /* dout0 */ - TOP_MUX(0x5, "B_DVI0")), /* d10 */ - - /* top_pmm_reg_3 */ - TOP_PIN(USIM1_DATA, TOP_REG3, 0, 3, 0x4c, 9, - TOP_MUX(0x0, "USIM1"), /* dat */ - TOP_MUX(0x1, "UART4"), /* rst */ - TOP_MUX(0x2, "BGPIO"), /* gpio42 */ - TOP_MUX(0x3, "SPI3"), /* rxd */ - TOP_MUX(0x4, "I2S0"), /* din0 */ - TOP_MUX(0x5, "B_DVI0")), /* d11 */ - TOP_PIN(SDIO0_CLK, TOP_REG3, 6, 1, 0x58, 0, - TOP_MUX(0x0, "SDIO0"), /* clk */ - TOP_MUX(0x1, "GPIO")), /* gpio43 */ - TOP_PIN(SDIO0_CMD, TOP_REG3, 7, 1, 0x58, 9, - TOP_MUX(0x0, "SDIO0"), /* cmd */ - TOP_MUX(0x1, "GPIO")), /* gpio44 */ - TOP_PIN(SDIO0_DATA0, TOP_REG3, 8, 1, 0x58, 18, - TOP_MUX(0x0, "SDIO0"), /* dat0 */ - TOP_MUX(0x1, "GPIO")), /* gpio45 */ - TOP_PIN(SDIO0_DATA1, TOP_REG3, 9, 1, 0x5c, 0, - TOP_MUX(0x0, "SDIO0"), /* dat1 */ - TOP_MUX(0x1, "GPIO")), /* gpio46 */ - TOP_PIN(SDIO0_DATA2, TOP_REG3, 10, 1, 0x5c, 9, - TOP_MUX(0x0, "SDIO0"), /* dat2 */ - TOP_MUX(0x1, "GPIO")), /* gpio47 */ - TOP_PIN(SDIO0_DATA3, TOP_REG3, 11, 1, 0x5c, 18, - TOP_MUX(0x0, "SDIO0"), /* dat3 */ - TOP_MUX(0x1, "GPIO")), /* gpio48 */ - TOP_PIN(SDIO0_CD, TOP_REG3, 12, 1, 0x60, 0, - TOP_MUX(0x0, "SDIO0"), /* cd */ - TOP_MUX(0x1, "GPIO")), /* gpio49 */ - TOP_PIN(SDIO0_WP, TOP_REG3, 13, 1, 0x60, 9, - TOP_MUX(0x0, "SDIO0"), /* wp */ - TOP_MUX(0x1, "GPIO")), /* gpio50 */ - - /* top_pmm_reg_4 */ - TOP_PIN(TSI0_DATA0, TOP_REG4, 0, 2, 0x60, 18, - TOP_MUX(0x0, "TSI0"), /* dat0 */ - TOP_MUX(0x1, "LCD"), /* clk */ - TOP_MUX(0x2, "BGPIO")), /* gpio51 */ - TOP_PIN(SPINOR_CLK, TOP_REG4, 2, 2, 0xa8, 18, - TOP_MUX(0x0, "SPINOR"), /* clk */ - TOP_MUX(0x1, "TSI0"), /* dat1 */ - TOP_MUX(0x2, "LCD"), /* dat0 */ - TOP_MUX(0x3, "BGPIO")), /* gpio52 */ - TOP_PIN(TSI2_DATA, TOP_REG4, 4, 2, 0x7c, 0, - TOP_MUX(0x0, "TSI2"), /* dat */ - TOP_MUX(0x1, "TSI0"), /* dat2 */ - TOP_MUX(0x2, "LCD"), /* dat1 */ - TOP_MUX(0x3, "BGPIO")), /* gpio53 */ - TOP_PIN(TSI2_CLK, TOP_REG4, 6, 2, 0x7c, 9, - TOP_MUX(0x0, "TSI2"), /* clk */ - TOP_MUX(0x1, "TSI0"), /* dat3 */ - TOP_MUX(0x2, "LCD"), /* dat2 */ - TOP_MUX(0x3, "BGPIO")), /* gpio54 */ - TOP_PIN(TSI2_SYNC, TOP_REG4, 8, 2, 0x7c, 18, - TOP_MUX(0x0, "TSI2"), /* sync */ - TOP_MUX(0x1, "TSI0"), /* dat4 */ - TOP_MUX(0x2, "LCD"), /* dat3 */ - TOP_MUX(0x3, "BGPIO")), /* gpio55 */ - TOP_PIN(TSI2_VALID, TOP_REG4, 10, 2, 0x80, 0, - TOP_MUX(0x0, "TSI2"), /* valid */ - TOP_MUX(0x1, "TSI0"), /* dat5 */ - TOP_MUX(0x2, "LCD"), /* dat4 */ - TOP_MUX(0x3, "BGPIO")), /* gpio56 */ - TOP_PIN(SPINOR_CS, TOP_REG4, 12, 2, 0x80, 9, - TOP_MUX(0x0, "SPINOR"), /* cs */ - TOP_MUX(0x1, "TSI0"), /* dat6 */ - TOP_MUX(0x2, "LCD"), /* dat5 */ - TOP_MUX(0x3, "BGPIO")), /* gpio57 */ - TOP_PIN(SPINOR_DQ0, TOP_REG4, 14, 2, 0x80, 18, - TOP_MUX(0x0, "SPINOR"), /* dq0 */ - TOP_MUX(0x1, "TSI0"), /* dat7 */ - TOP_MUX(0x2, "LCD"), /* dat6 */ - TOP_MUX(0x3, "BGPIO")), /* gpio58 */ - TOP_PIN(SPINOR_DQ1, TOP_REG4, 16, 2, 0x84, 0, - TOP_MUX(0x0, "SPINOR"), /* dq1 */ - TOP_MUX(0x1, "TSI0"), /* clk */ - TOP_MUX(0x2, "LCD"), /* dat7 */ - TOP_MUX(0x3, "BGPIO")), /* gpio59 */ - TOP_PIN(SPINOR_DQ2, TOP_REG4, 18, 2, 0x84, 9, - TOP_MUX(0x0, "SPINOR"), /* dq2 */ - TOP_MUX(0x1, "TSI0"), /* sync */ - TOP_MUX(0x2, "LCD"), /* dat8 */ - TOP_MUX(0x3, "BGPIO")), /* gpio60 */ - TOP_PIN(SPINOR_DQ3, TOP_REG4, 20, 2, 0x84, 18, - TOP_MUX(0x0, "SPINOR"), /* dq3 */ - TOP_MUX(0x1, "TSI0"), /* valid */ - TOP_MUX(0x2, "LCD"), /* dat9 */ - TOP_MUX(0x3, "BGPIO")), /* gpio61 */ - TOP_PIN(VGA_HS, TOP_REG4, 22, 3, 0x88, 0, - TOP_MUX(0x0, "VGA"), /* hs */ - TOP_MUX(0x1, "TSI1"), /* dat0 */ - TOP_MUX(0x2, "LCD"), /* dat10 */ - TOP_MUX(0x3, "BGPIO"), /* gpio62 */ - TOP_MUX(0x4, "I2S1"), /* din1 */ - TOP_MUX(0x5, "B_DVI0")), /* clk */ - TOP_PIN(VGA_VS, TOP_REG4, 25, 3, 0x88, 9, - TOP_MUX(0x0, "VGA"), /* vs0 */ - TOP_MUX(0x1, "TSI1"), /* dat1 */ - TOP_MUX(0x2, "LCD"), /* dat11 */ - TOP_MUX(0x3, "BGPIO"), /* gpio63 */ - TOP_MUX(0x4, "I2S1"), /* din2 */ - TOP_MUX(0x5, "B_DVI0")), /* vs */ - TOP_PIN(TSI3_DATA, TOP_REG4, 28, 3, 0x88, 18, - TOP_MUX(0x0, "TSI3"), /* dat */ - TOP_MUX(0x1, "TSI1"), /* dat2 */ - TOP_MUX(0x2, "LCD"), /* dat12 */ - TOP_MUX(0x3, "BGPIO"), /* gpio64 */ - TOP_MUX(0x4, "I2S1"), /* din3 */ - TOP_MUX(0x5, "B_DVI0")), /* hs */ - - /* top_pmm_reg_5 */ - TOP_PIN(TSI3_CLK, TOP_REG5, 0, 3, 0x8c, 0, - TOP_MUX(0x0, "TSI3"), /* clk */ - TOP_MUX(0x1, "TSI1"), /* dat3 */ - TOP_MUX(0x2, "LCD"), /* dat13 */ - TOP_MUX(0x3, "BGPIO"), /* gpio65 */ - TOP_MUX(0x4, "I2S1"), /* dout1 */ - TOP_MUX(0x5, "B_DVI0")), /* d0 */ - TOP_PIN(TSI3_SYNC, TOP_REG5, 3, 3, 0x8c, 9, - TOP_MUX(0x0, "TSI3"), /* sync */ - TOP_MUX(0x1, "TSI1"), /* dat4 */ - TOP_MUX(0x2, "LCD"), /* dat14 */ - TOP_MUX(0x3, "BGPIO"), /* gpio66 */ - TOP_MUX(0x4, "I2S1"), /* dout2 */ - TOP_MUX(0x5, "B_DVI0")), /* d1 */ - TOP_PIN(TSI3_VALID, TOP_REG5, 6, 3, 0x8c, 18, - TOP_MUX(0x0, "TSI3"), /* valid */ - TOP_MUX(0x1, "TSI1"), /* dat5 */ - TOP_MUX(0x2, "LCD"), /* dat15 */ - TOP_MUX(0x3, "BGPIO"), /* gpio67 */ - TOP_MUX(0x4, "I2S1"), /* dout3 */ - TOP_MUX(0x5, "B_DVI0")), /* d2 */ - TOP_PIN(I2S1_WS, TOP_REG5, 9, 3, 0x90, 0, - TOP_MUX(0x0, "I2S1"), /* ws */ - TOP_MUX(0x1, "TSI1"), /* dat6 */ - TOP_MUX(0x2, "LCD"), /* dat16 */ - TOP_MUX(0x3, "BGPIO"), /* gpio68 */ - TOP_MUX(0x4, "VGA"), /* scl */ - TOP_MUX(0x5, "B_DVI0")), /* d3 */ - TOP_PIN(I2S1_BCLK, TOP_REG5, 12, 3, 0x90, 9, - TOP_MUX(0x0, "I2S1"), /* bclk */ - TOP_MUX(0x1, "TSI1"), /* dat7 */ - TOP_MUX(0x2, "LCD"), /* dat17 */ - TOP_MUX(0x3, "BGPIO"), /* gpio69 */ - TOP_MUX(0x4, "VGA"), /* sda */ - TOP_MUX(0x5, "B_DVI0")), /* d4 */ - TOP_PIN(I2S1_MCLK, TOP_REG5, 15, 2, 0x90, 18, - TOP_MUX(0x0, "I2S1"), /* mclk */ - TOP_MUX(0x1, "TSI1"), /* clk */ - TOP_MUX(0x2, "LCD"), /* dat18 */ - TOP_MUX(0x3, "BGPIO")), /* gpio70 */ - TOP_PIN(I2S1_DIN0, TOP_REG5, 17, 2, 0x94, 0, - TOP_MUX(0x0, "I2S1"), /* din0 */ - TOP_MUX(0x1, "TSI1"), /* sync */ - TOP_MUX(0x2, "LCD"), /* dat19 */ - TOP_MUX(0x3, "BGPIO")), /* gpio71 */ - TOP_PIN(I2S1_DOUT0, TOP_REG5, 19, 2, 0x94, 9, - TOP_MUX(0x0, "I2S1"), /* dout0 */ - TOP_MUX(0x1, "TSI1"), /* valid */ - TOP_MUX(0x2, "LCD"), /* dat20 */ - TOP_MUX(0x3, "BGPIO")), /* gpio72 */ - TOP_PIN(SPI3_CLK, TOP_REG5, 21, 3, 0x94, 18, - TOP_MUX(0x0, "SPI3"), /* clk */ - TOP_MUX(0x1, "TSO1"), /* clk */ - TOP_MUX(0x2, "LCD"), /* dat21 */ - TOP_MUX(0x3, "BGPIO"), /* gpio73 */ - TOP_MUX(0x4, "UART5"), /* rxd */ - TOP_MUX(0x5, "PCM"), /* fs */ - TOP_MUX(0x6, "I2S0"), /* din1 */ - TOP_MUX(0x7, "B_DVI0")), /* d5 */ - TOP_PIN(SPI3_CS, TOP_REG5, 24, 3, 0x98, 0, - TOP_MUX(0x0, "SPI3"), /* cs */ - TOP_MUX(0x1, "TSO1"), /* dat0 */ - TOP_MUX(0x2, "LCD"), /* dat22 */ - TOP_MUX(0x3, "BGPIO"), /* gpio74 */ - TOP_MUX(0x4, "UART5"), /* txd */ - TOP_MUX(0x5, "PCM"), /* clk */ - TOP_MUX(0x6, "I2S0"), /* din2 */ - TOP_MUX(0x7, "B_DVI0")), /* d6 */ - TOP_PIN(SPI3_TXD, TOP_REG5, 27, 3, 0x98, 9, - TOP_MUX(0x0, "SPI3"), /* txd */ - TOP_MUX(0x1, "TSO1"), /* dat1 */ - TOP_MUX(0x2, "LCD"), /* dat23 */ - TOP_MUX(0x3, "BGPIO"), /* gpio75 */ - TOP_MUX(0x4, "UART5"), /* cts */ - TOP_MUX(0x5, "PCM"), /* txd */ - TOP_MUX(0x6, "I2S0"), /* din3 */ - TOP_MUX(0x7, "B_DVI0")), /* d7 */ - TOP_PIN(NAND_LDO_MS18_SEL, TOP_REG5, 30, 1, 0xe4, 0, - TOP_MUX(0x0, "NAND"), /* ldo_ms18_sel */ - TOP_MUX(0x1, "BGPIO")), /* gpio99 */ - - /* top_pmm_reg_6 */ - TOP_PIN(SPI3_RXD, TOP_REG6, 0, 3, 0x98, 18, - TOP_MUX(0x0, "SPI3"), /* rxd */ - TOP_MUX(0x1, "TSO1"), /* dat2 */ - TOP_MUX(0x2, "LCD"), /* stvu_vsync */ - TOP_MUX(0x3, "BGPIO"), /* gpio76 */ - TOP_MUX(0x4, "UART5"), /* rts */ - TOP_MUX(0x5, "PCM"), /* rxd */ - TOP_MUX(0x6, "I2S0"), /* dout1 */ - TOP_MUX(0x7, "B_DVI1")), /* clk */ - TOP_PIN(I2S0_MCLK, TOP_REG6, 3, 3, 0x9c, 0, - TOP_MUX(0x0, "I2S0"), /* mclk */ - TOP_MUX(0x1, "TSO1"), /* dat3 */ - TOP_MUX(0x2, "LCD"), /* stvd */ - TOP_MUX(0x3, "BGPIO"), /* gpio77 */ - TOP_MUX(0x4, "USIM0"), /* cd */ - TOP_MUX(0x5, "B_DVI1")), /* vs */ - TOP_PIN(I2S0_BCLK, TOP_REG6, 6, 3, 0x9c, 9, - TOP_MUX(0x0, "I2S0"), /* bclk */ - TOP_MUX(0x1, "TSO1"), /* dat4 */ - TOP_MUX(0x2, "LCD"), /* sthl_hsync */ - TOP_MUX(0x3, "BGPIO"), /* gpio78 */ - TOP_MUX(0x4, "USIM0"), /* clk */ - TOP_MUX(0x5, "B_DVI1")), /* hs */ - TOP_PIN(I2S0_WS, TOP_REG6, 9, 3, 0x9c, 18, - TOP_MUX(0x0, "I2S0"), /* ws */ - TOP_MUX(0x1, "TSO1"), /* dat5 */ - TOP_MUX(0x2, "LCD"), /* sthr */ - TOP_MUX(0x3, "BGPIO"), /* gpio79 */ - TOP_MUX(0x4, "USIM0"), /* rst */ - TOP_MUX(0x5, "B_DVI1")), /* d0 */ - TOP_PIN(I2S0_DIN0, TOP_REG6, 12, 3, 0xa0, 0, - TOP_MUX(0x0, "I2S0"), /* din0 */ - TOP_MUX(0x1, "TSO1"), /* dat6 */ - TOP_MUX(0x2, "LCD"), /* oev_dataen */ - TOP_MUX(0x3, "BGPIO"), /* gpio80 */ - TOP_MUX(0x4, "USIM0"), /* dat */ - TOP_MUX(0x5, "B_DVI1")), /* d1 */ - TOP_PIN(I2S0_DOUT0, TOP_REG6, 15, 2, 0xa0, 9, - TOP_MUX(0x0, "I2S0"), /* dout0 */ - TOP_MUX(0x1, "TSO1"), /* dat7 */ - TOP_MUX(0x2, "LCD"), /* ckv */ - TOP_MUX(0x3, "BGPIO")), /* gpio81 */ - TOP_PIN(I2C5_SCL, TOP_REG6, 17, 3, 0xa0, 18, - TOP_MUX(0x0, "I2C5"), /* scl */ - TOP_MUX(0x1, "TSO1"), /* sync */ - TOP_MUX(0x2, "LCD"), /* ld */ - TOP_MUX(0x3, "BGPIO"), /* gpio82 */ - TOP_MUX(0x4, "PWM"), /* out2 */ - TOP_MUX(0x5, "I2S0"), /* dout2 */ - TOP_MUX(0x6, "B_DVI1")), /* d2 */ - TOP_PIN(I2C5_SDA, TOP_REG6, 20, 3, 0xa4, 0, - TOP_MUX(0x0, "I2C5"), /* sda */ - TOP_MUX(0x1, "TSO1"), /* vld */ - TOP_MUX(0x2, "LCD"), /* pol */ - TOP_MUX(0x3, "BGPIO"), /* gpio83 */ - TOP_MUX(0x4, "PWM"), /* out3 */ - TOP_MUX(0x5, "I2S0"), /* dout3 */ - TOP_MUX(0x6, "B_DVI1")), /* d3 */ - TOP_PIN(SPI2_CLK, TOP_REG6, 23, 3, 0xa4, 9, - TOP_MUX(0x0, "SPI2"), /* clk */ - TOP_MUX(0x1, "TSO0"), /* clk */ - TOP_MUX(0x2, "LCD"), /* degsl */ - TOP_MUX(0x3, "BGPIO"), /* gpio84 */ - TOP_MUX(0x4, "I2C4"), /* scl */ - TOP_MUX(0x5, "B_DVI1")), /* d4 */ - TOP_PIN(SPI2_CS, TOP_REG6, 26, 3, 0xa4, 18, - TOP_MUX(0x0, "SPI2"), /* cs */ - TOP_MUX(0x1, "TSO0"), /* data */ - TOP_MUX(0x2, "LCD"), /* rev */ - TOP_MUX(0x3, "BGPIO"), /* gpio85 */ - TOP_MUX(0x4, "I2C4"), /* sda */ - TOP_MUX(0x5, "B_DVI1")), /* d5 */ - TOP_PIN(SPI2_TXD, TOP_REG6, 29, 3, 0xa8, 0, - TOP_MUX(0x0, "SPI2"), /* txd */ - TOP_MUX(0x1, "TSO0"), /* sync */ - TOP_MUX(0x2, "LCD"), /* u_d */ - TOP_MUX(0x3, "BGPIO"), /* gpio86 */ - TOP_MUX(0x4, "I2C4"), /* scl */ - TOP_MUX(0x5, "B_DVI1")), /* d6 */ - - /* top_pmm_reg_7 */ - TOP_PIN(SPI2_RXD, TOP_REG7, 0, 3, 0xa8, 9, - TOP_MUX(0x0, "SPI2"), /* rxd */ - TOP_MUX(0x1, "TSO0"), /* vld */ - TOP_MUX(0x2, "LCD"), /* r_l */ - TOP_MUX(0x3, "BGPIO"), /* gpio87 */ - TOP_MUX(0x4, "I2C3"), /* sda */ - TOP_MUX(0x5, "B_DVI1")), /* d7 */ - TOP_PIN(NAND_WP_N, TOP_REG7, 7, 3, 0x54, 9, - TOP_MUX(0x0, "NAND"), /* wp */ - TOP_MUX(0x1, "PWM"), /* out2 */ - TOP_MUX(0x2, "SPI2"), /* clk */ - TOP_MUX(0x3, "BGPIO"), /* gpio88 */ - TOP_MUX(0x4, "TSI0"), /* dat0 */ - TOP_MUX(0x5, "I2S1")), /* din1 */ - TOP_PIN(NAND_PAGE_SIZE0, TOP_REG7, 10, 3, 0xb8, 0, - TOP_MUX(0x0, "NAND"), /* boot_pagesize0 */ - TOP_MUX(0x1, "PWM"), /* out3 */ - TOP_MUX(0x2, "SPI2"), /* cs */ - TOP_MUX(0x3, "BGPIO"), /* gpio89 */ - TOP_MUX(0x4, "TSI0"), /* clk */ - TOP_MUX(0x5, "I2S1")), /* din2 */ - TOP_PIN(NAND_PAGE_SIZE1, TOP_REG7, 13, 3, 0xb8, 9, - TOP_MUX(0x0, "NAND"), /* boot_pagesize1 */ - TOP_MUX(0x1, "I2C4"), /* scl */ - TOP_MUX(0x2, "SPI2"), /* txd */ - TOP_MUX(0x3, "BGPIO"), /* gpio90 */ - TOP_MUX(0x4, "TSI0"), /* sync */ - TOP_MUX(0x5, "I2S1")), /* din3 */ - TOP_PIN(NAND_ADDR_CYCLE, TOP_REG7, 16, 3, 0xb8, 18, - TOP_MUX(0x0, "NAND"), /* boot_addr_cycles */ - TOP_MUX(0x1, "I2C4"), /* sda */ - TOP_MUX(0x2, "SPI2"), /* rxd */ - TOP_MUX(0x3, "BGPIO"), /* gpio91 */ - TOP_MUX(0x4, "TSI0"), /* valid */ - TOP_MUX(0x5, "I2S1")), /* dout1 */ - TOP_PIN(NAND_RB0, TOP_REG7, 19, 3, 0xbc, 0, - TOP_MUX(0x0, "NAND"), /* rdy_busy0 */ - TOP_MUX(0x1, "I2C2"), /* scl */ - TOP_MUX(0x2, "USIM0"), /* cd */ - TOP_MUX(0x3, "BGPIO"), /* gpio92 */ - TOP_MUX(0x4, "TSI1")), /* data0 */ - TOP_PIN(NAND_RB1, TOP_REG7, 22, 3, 0xbc, 9, - TOP_MUX(0x0, "NAND"), /* rdy_busy1 */ - TOP_MUX(0x1, "I2C2"), /* sda */ - TOP_MUX(0x2, "USIM0"), /* clk */ - TOP_MUX(0x3, "BGPIO"), /* gpio93 */ - TOP_MUX(0x4, "TSI1")), /* clk */ - TOP_PIN(NAND_RB2, TOP_REG7, 25, 3, 0xbc, 18, - TOP_MUX(0x0, "NAND"), /* rdy_busy2 */ - TOP_MUX(0x1, "UART5"), /* rxd */ - TOP_MUX(0x2, "USIM0"), /* rst */ - TOP_MUX(0x3, "BGPIO"), /* gpio94 */ - TOP_MUX(0x4, "TSI1"), /* sync */ - TOP_MUX(0x4, "I2S1")), /* dout2 */ - TOP_PIN(NAND_RB3, TOP_REG7, 28, 3, 0x54, 18, - TOP_MUX(0x0, "NAND"), /* rdy_busy3 */ - TOP_MUX(0x1, "UART5"), /* txd */ - TOP_MUX(0x2, "USIM0"), /* dat */ - TOP_MUX(0x3, "BGPIO"), /* gpio95 */ - TOP_MUX(0x4, "TSI1"), /* valid */ - TOP_MUX(0x4, "I2S1")), /* dout3 */ - - /* top_pmm_reg_8 */ - TOP_PIN(GMAC_125M_IN, TOP_REG8, 0, 2, 0x34, 0, - TOP_MUX(0x0, "GMII"), /* 125m_in */ - TOP_MUX(0x1, "USB2"), /* 0_drvvbus */ - TOP_MUX(0x2, "ISP"), /* ref_clk */ - TOP_MUX(0x3, "BGPIO")), /* gpio96 */ - TOP_PIN(GMAC_50M_OUT, TOP_REG8, 2, 2, 0x34, 9, - TOP_MUX(0x0, "GMII"), /* 50m_out */ - TOP_MUX(0x1, "USB2"), /* 1_drvvbus */ - TOP_MUX(0x2, "BGPIO"), /* gpio97 */ - TOP_MUX(0x3, "USB2")), /* 0_drvvbus */ - TOP_PIN(SPINOR_SSCLK_LOOPBACK, TOP_REG8, 6, 1, 0xc8, 9, - TOP_MUX(0x0, "SPINOR")), /* sdio1_clk_i */ - TOP_PIN(SPINOR_SDIO1CLK_LOOPBACK, TOP_REG8, 7, 1, 0xc8, 18, - TOP_MUX(0x0, "SPINOR")), /* ssclk_i */ -}; - -static struct zx_pinctrl_soc_info zx296718_pinctrl_info = { - .pins = zx296718_pins, - .npins = ARRAY_SIZE(zx296718_pins), -}; - -static int zx296718_pinctrl_probe(struct platform_device *pdev) -{ - return zx_pinctrl_init(pdev, &zx296718_pinctrl_info); -} - -static const struct of_device_id zx296718_pinctrl_match[] = { - { .compatible = "zte,zx296718-pmm", }, - {} -}; -MODULE_DEVICE_TABLE(of, zx296718_pinctrl_match); - -static struct platform_driver zx296718_pinctrl_driver = { - .probe = zx296718_pinctrl_probe, - .driver = { - .name = "zx296718-pinctrl", - .of_match_table = zx296718_pinctrl_match, - }, -}; -builtin_platform_driver(zx296718_pinctrl_driver); - -MODULE_DESCRIPTION("ZTE ZX296718 pinctrl driver"); -MODULE_LICENSE("GPL"); -- cgit v1.2.3 From c41e02c384f50dd514b904dc2fbf1627e11a6313 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Wed, 20 Jan 2021 14:20:43 +0100 Subject: pinctrl: remove sirf atlas/prima drivers The CSR SiRF prima2/atlas platforms are getting removed, so this driver is no longer needed. Cc: Barry Song Signed-off-by: Arnd Bergmann Acked-by: Barry Song Link: https://lore.kernel.org/r/20210120132045.2127659-4-arnd@kernel.org Signed-off-by: Linus Walleij --- .../devicetree/bindings/gpio/gpio-atlas7.txt | 50 - .../devicetree/bindings/pinctrl/pinctrl-atlas7.txt | 109 - drivers/pinctrl/Kconfig | 8 - drivers/pinctrl/Makefile | 1 - drivers/pinctrl/sirf/Makefile | 7 - drivers/pinctrl/sirf/pinctrl-atlas6.c | 1137 ---- drivers/pinctrl/sirf/pinctrl-atlas7.c | 6157 -------------------- drivers/pinctrl/sirf/pinctrl-prima2.c | 1131 ---- drivers/pinctrl/sirf/pinctrl-sirf.c | 894 --- drivers/pinctrl/sirf/pinctrl-sirf.h | 116 - 10 files changed, 9610 deletions(-) delete mode 100644 Documentation/devicetree/bindings/gpio/gpio-atlas7.txt delete mode 100644 Documentation/devicetree/bindings/pinctrl/pinctrl-atlas7.txt delete mode 100644 drivers/pinctrl/sirf/Makefile delete mode 100644 drivers/pinctrl/sirf/pinctrl-atlas6.c delete mode 100644 drivers/pinctrl/sirf/pinctrl-atlas7.c delete mode 100644 drivers/pinctrl/sirf/pinctrl-prima2.c delete mode 100644 drivers/pinctrl/sirf/pinctrl-sirf.c delete mode 100644 drivers/pinctrl/sirf/pinctrl-sirf.h (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/gpio/gpio-atlas7.txt b/Documentation/devicetree/bindings/gpio/gpio-atlas7.txt deleted file mode 100644 index d7e123fc90b5..000000000000 --- a/Documentation/devicetree/bindings/gpio/gpio-atlas7.txt +++ /dev/null @@ -1,50 +0,0 @@ -CSR SiRFatlas7 GPIO controller bindings - -Required properties: -- compatible : "sirf,atlas7-gpio" -- reg : Address range of the pinctrl registers -- interrupts : Interrupts used by every GPIO group -- gpio-banks : How many gpio banks on this controller -- gpio-controller : Indicates this device is a GPIO controller -- interrupt-controller : Marks the device node as an interrupt controller - -The GPIO controller also acts as an interrupt controller. It uses the default -two cells specifier as described in Documentation/devicetree/bindings/ -interrupt-controller/interrupts.txt. - -Example: - - gpio_0: gpio_mediam@17040000 { - compatible = "sirf,atlas7-gpio"; - reg = <0x17040000 0x1000>; - interrupts = <0 13 0>, <0 14 0>; - - #gpio-cells = <2>; - #interrupt-cells = <2>; - - gpio-controller; - interrupt-controller; - - gpio-banks = <2>; - gpio-ranges = <&pinctrl 0 0 0>, - <&pinctrl 32 0 0>; - gpio-ranges-group-names = "lvds_gpio_grp", - "uart_nand_gpio_grp"; - }; - - leds { - compatible = "gpio-leds"; - - led1 { - gpios = <&gpio_1 15 0>; - ... - }; - - led2 { - gpios = <&gpio_2 34 0>; - ... - }; - }; - -Please refer to gpio.txt in this directory for details of the common -gpio properties used by devices. diff --git a/Documentation/devicetree/bindings/pinctrl/pinctrl-atlas7.txt b/Documentation/devicetree/bindings/pinctrl/pinctrl-atlas7.txt deleted file mode 100644 index fbdd1a716a1e..000000000000 --- a/Documentation/devicetree/bindings/pinctrl/pinctrl-atlas7.txt +++ /dev/null @@ -1,109 +0,0 @@ -CSR SiRFatlas7 pinmux controller - -Required properties: -- compatible : "sirf,atlas7-ioc" -- reg : Address range of the pinctrl registers - -For example, pinctrl might have properties like the following: - pinctrl: ioc@18880000 { - compatible = "sirf,atlas7-ioc"; - reg = <0x18880000 0x1000>; - - a_ac97_pmx: ac97@0 { - ac97 { - groups = "audio_ac97_grp"; - function = "audio_ac97"; - }; - }; - - ... - - sd2_pmx: sd2@0 { - sd2 { - groups = "sd2_grp0"; - function = "sd2"; - }; - }; - - ... - - - sample0_cfg: sample0@0 { - sample0 { - pins = "ldd_0", "ldd_1"; - bias-pull-up; - }; - }; - - sample1_cfg: sample1@0 { - sample1 { - pins = "ldd_2", "ldd_3"; - input-schmitt-enable; - }; - }; - - sample2_cfg: sample2@0 { - sample2 { - groups = "uart4_nopause_grp"; - bias-pull-down; - }; - }; - - sample3_cfg: sample3@0 { - sample3 { - pins = "ldd_4", "ldd_5"; - drive-strength = <2>; - }; - }; - }; - -Please refer to pinctrl-bindings.txt in this directory for details of the common -pinctrl bindings used by client devices. - -SiRFatlas7's pinmux nodes act as a container for an arbitrary number of subnodes. -Each of these subnodes represents some desired configuration for a group of pins. - -Required subnode-properties: -- groups : An array of strings. Each string contains the name of a group. -- function: A string containing the name of the function to mux to the - group. - - Valid values for group and function names can be found from looking at the - group and function arrays in driver files: - drivers/pinctrl/pinctrl-sirf.c - -For example, pinctrl might have subnodes like the following: - sd0_pmx: sd0@0 { - sd0 { - groups = "sd0_grp"; - function = "sd0"; - }; - }; - - sd1_pmx0: sd1@0 { - sd1 { - groups = "sd1_grp0"; - function = "sd1_m0"; - }; - }; - - sd1_pmx1: sd1@1 { - sd1 { - groups = "sd1_grp1"; - function = "sd1_m1"; - }; - }; - -For a specific board, if it wants to use sd1, -it can add the following to its board-specific .dts file. -sd1: sd@12340000 { - pinctrl-names = "default"; - pinctrl-0 = <&sd1_pmx0>; -} - -or - -sd1: sd@12340000 { - pinctrl-names = "default"; - pinctrl-0 = <&sd1_pmx1>; -} diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig index 1c1fa681b96d..e176137dbf29 100644 --- a/drivers/pinctrl/Kconfig +++ b/drivers/pinctrl/Kconfig @@ -226,14 +226,6 @@ config PINCTRL_SINGLE help This selects the device tree based generic pinctrl driver. -config PINCTRL_SIRF - bool "CSR SiRFprimaII pin controller driver" - depends on ARCH_SIRF - select PINMUX - select PINCONF - select GENERIC_PINCONF - select GPIOLIB_IRQCHIP - config PINCTRL_SX150X bool "Semtech SX150x I2C GPIO expander pinctrl driver" depends on I2C=y diff --git a/drivers/pinctrl/Makefile b/drivers/pinctrl/Makefile index fef92794900d..f414846abe2d 100644 --- a/drivers/pinctrl/Makefile +++ b/drivers/pinctrl/Makefile @@ -31,7 +31,6 @@ obj-$(CONFIG_PINCTRL_PIC32) += pinctrl-pic32.o obj-$(CONFIG_PINCTRL_PISTACHIO) += pinctrl-pistachio.o obj-$(CONFIG_PINCTRL_ROCKCHIP) += pinctrl-rockchip.o obj-$(CONFIG_PINCTRL_SINGLE) += pinctrl-single.o -obj-$(CONFIG_PINCTRL_SIRF) += sirf/ obj-$(CONFIG_PINCTRL_SX150X) += pinctrl-sx150x.o obj-$(CONFIG_ARCH_TEGRA) += tegra/ obj-$(CONFIG_PINCTRL_U300) += pinctrl-u300.o diff --git a/drivers/pinctrl/sirf/Makefile b/drivers/pinctrl/sirf/Makefile deleted file mode 100644 index 1ab0742075f6..000000000000 --- a/drivers/pinctrl/sirf/Makefile +++ /dev/null @@ -1,7 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0-only -# CSR SiRFsoc pinmux support - -obj-y += pinctrl-sirf.o -obj-y += pinctrl-prima2.o -obj-y += pinctrl-atlas6.o -obj-y += pinctrl-atlas7.o diff --git a/drivers/pinctrl/sirf/pinctrl-atlas6.c b/drivers/pinctrl/sirf/pinctrl-atlas6.c deleted file mode 100644 index ab35d59bfa04..000000000000 --- a/drivers/pinctrl/sirf/pinctrl-atlas6.c +++ /dev/null @@ -1,1137 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * pinctrl pads, groups, functions for CSR SiRFatlasVI - * - * Copyright (c) 2011 - 2014 Cambridge Silicon Radio Limited, a CSR plc group - * company. - */ - -#include -#include - -#include "pinctrl-sirf.h" - -/* - * pad list for the pinmux subsystem - * refer to atlasVI_io_table_v0.93.xls - */ -static const struct pinctrl_pin_desc sirfsoc_pads[] = { - PINCTRL_PIN(0, "gpio0-0"), - PINCTRL_PIN(1, "gpio0-1"), - PINCTRL_PIN(2, "gpio0-2"), - PINCTRL_PIN(3, "gpio0-3"), - PINCTRL_PIN(4, "pwm0"), - PINCTRL_PIN(5, "pwm1"), - PINCTRL_PIN(6, "pwm2"), - PINCTRL_PIN(7, "pwm3"), - PINCTRL_PIN(8, "warm_rst_b"), - PINCTRL_PIN(9, "odo_0"), - PINCTRL_PIN(10, "odo_1"), - PINCTRL_PIN(11, "dr_dir"), - PINCTRL_PIN(12, "rts_0"), - PINCTRL_PIN(13, "scl_1"), - PINCTRL_PIN(14, "ntrst"), - PINCTRL_PIN(15, "sda_1"), - PINCTRL_PIN(16, "x_ldd[16]"), - PINCTRL_PIN(17, "x_ldd[17]"), - PINCTRL_PIN(18, "x_ldd[18]"), - PINCTRL_PIN(19, "x_ldd[19]"), - PINCTRL_PIN(20, "x_ldd[20]"), - PINCTRL_PIN(21, "x_ldd[21]"), - PINCTRL_PIN(22, "x_ldd[22]"), - PINCTRL_PIN(23, "x_ldd[23]"), - PINCTRL_PIN(24, "gps_sgn"), - PINCTRL_PIN(25, "gps_mag"), - PINCTRL_PIN(26, "gps_clk"), - PINCTRL_PIN(27, "sd_cd_b_2"), - PINCTRL_PIN(28, "sd_vcc_on_2"), - PINCTRL_PIN(29, "sd_wp_b_2"), - PINCTRL_PIN(30, "sd_clk_3"), - PINCTRL_PIN(31, "sd_cmd_3"), - - PINCTRL_PIN(32, "x_sd_dat_3[0]"), - PINCTRL_PIN(33, "x_sd_dat_3[1]"), - PINCTRL_PIN(34, "x_sd_dat_3[2]"), - PINCTRL_PIN(35, "x_sd_dat_3[3]"), - PINCTRL_PIN(36, "usb_clk"), - PINCTRL_PIN(37, "usb_dir"), - PINCTRL_PIN(38, "usb_nxt"), - PINCTRL_PIN(39, "usb_stp"), - PINCTRL_PIN(40, "usb_dat[7]"), - PINCTRL_PIN(41, "usb_dat[6]"), - PINCTRL_PIN(42, "x_cko_1"), - PINCTRL_PIN(43, "spi_clk_1"), - PINCTRL_PIN(44, "spi_dout_1"), - PINCTRL_PIN(45, "spi_din_1"), - PINCTRL_PIN(46, "spi_en_1"), - PINCTRL_PIN(47, "x_txd_1"), - PINCTRL_PIN(48, "x_txd_2"), - PINCTRL_PIN(49, "x_rxd_1"), - PINCTRL_PIN(50, "x_rxd_2"), - PINCTRL_PIN(51, "x_usclk_0"), - PINCTRL_PIN(52, "x_utxd_0"), - PINCTRL_PIN(53, "x_urxd_0"), - PINCTRL_PIN(54, "x_utfs_0"), - PINCTRL_PIN(55, "x_urfs_0"), - PINCTRL_PIN(56, "usb_dat5"), - PINCTRL_PIN(57, "usb_dat4"), - PINCTRL_PIN(58, "usb_dat3"), - PINCTRL_PIN(59, "usb_dat2"), - PINCTRL_PIN(60, "usb_dat1"), - PINCTRL_PIN(61, "usb_dat0"), - PINCTRL_PIN(62, "x_ldd[14]"), - PINCTRL_PIN(63, "x_ldd[15]"), - - PINCTRL_PIN(64, "x_gps_gpio"), - PINCTRL_PIN(65, "x_ldd[13]"), - PINCTRL_PIN(66, "x_df_we_b"), - PINCTRL_PIN(67, "x_df_re_b"), - PINCTRL_PIN(68, "x_txd_0"), - PINCTRL_PIN(69, "x_rxd_0"), - PINCTRL_PIN(70, "x_l_lck"), - PINCTRL_PIN(71, "x_l_fck"), - PINCTRL_PIN(72, "x_l_de"), - PINCTRL_PIN(73, "x_ldd[0]"), - PINCTRL_PIN(74, "x_ldd[1]"), - PINCTRL_PIN(75, "x_ldd[2]"), - PINCTRL_PIN(76, "x_ldd[3]"), - PINCTRL_PIN(77, "x_ldd[4]"), - PINCTRL_PIN(78, "x_cko_0"), - PINCTRL_PIN(79, "x_ldd[5]"), - PINCTRL_PIN(80, "x_ldd[6]"), - PINCTRL_PIN(81, "x_ldd[7]"), - PINCTRL_PIN(82, "x_ldd[8]"), - PINCTRL_PIN(83, "x_ldd[9]"), - PINCTRL_PIN(84, "x_ldd[10]"), - PINCTRL_PIN(85, "x_ldd[11]"), - PINCTRL_PIN(86, "x_ldd[12]"), - PINCTRL_PIN(87, "x_vip_vsync"), - PINCTRL_PIN(88, "x_vip_hsync"), - PINCTRL_PIN(89, "x_vip_pxclk"), - PINCTRL_PIN(90, "x_sda_0"), - PINCTRL_PIN(91, "x_scl_0"), - PINCTRL_PIN(92, "x_df_ry_by"), - PINCTRL_PIN(93, "x_df_cs_b[1]"), - PINCTRL_PIN(94, "x_df_cs_b[0]"), - PINCTRL_PIN(95, "x_l_pclk"), - - PINCTRL_PIN(96, "x_df_dqs"), - PINCTRL_PIN(97, "x_df_wp_b"), - PINCTRL_PIN(98, "ac97_sync"), - PINCTRL_PIN(99, "ac97_bit_clk "), - PINCTRL_PIN(100, "ac97_dout"), - PINCTRL_PIN(101, "ac97_din"), - PINCTRL_PIN(102, "x_rtc_io"), - - PINCTRL_PIN(103, "x_usb1_dp"), - PINCTRL_PIN(104, "x_usb1_dn"), -}; - -static const struct sirfsoc_muxmask lcd_16bits_sirfsoc_muxmask[] = { - { - .group = 1, - .mask = BIT(30) | BIT(31), - }, { - .group = 2, - .mask = BIT(1) | BIT(6) | BIT(7) | BIT(8) | BIT(9) | - BIT(10) | BIT(11) | BIT(12) | BIT(13) | BIT(15) | - BIT(16) | BIT(17) | BIT(18) | BIT(19) | - BIT(20) | BIT(21) | BIT(22) | BIT(31), - }, -}; - -static const struct sirfsoc_padmux lcd_16bits_padmux = { - .muxmask_counts = ARRAY_SIZE(lcd_16bits_sirfsoc_muxmask), - .muxmask = lcd_16bits_sirfsoc_muxmask, - .ctrlreg = SIRFSOC_RSC_PIN_MUX, - .funcmask = BIT(4), - .funcval = 0, -}; - -static const unsigned lcd_16bits_pins[] = { 62, 63, 65, 70, 71, 72, 73, 74, 75, - 76, 77, 79, 80, 81, 82, 83, 84, 85, 86, 95 }; - -static const struct sirfsoc_muxmask lcd_18bits_muxmask[] = { - { - .group = 2, - .mask = BIT(1) | BIT(6) | BIT(7) | BIT(8) | BIT(9) | - BIT(10) | BIT(11) | BIT(12) | BIT(13) | BIT(15) | - BIT(16) | BIT(17) | BIT(18) | BIT(19) | - BIT(20) | BIT(21) | BIT(22) | BIT(31), - }, { - .group = 1, - .mask = BIT(30) | BIT(31), - }, { - .group = 0, - .mask = BIT(16) | BIT(17), - }, -}; - -static const struct sirfsoc_padmux lcd_18bits_padmux = { - .muxmask_counts = ARRAY_SIZE(lcd_18bits_muxmask), - .muxmask = lcd_18bits_muxmask, - .ctrlreg = SIRFSOC_RSC_PIN_MUX, - .funcmask = BIT(4) | BIT(15), - .funcval = 0, -}; - -static const unsigned lcd_18bits_pins[] = { 16, 17, 62, 63, 65, 70, 71, 72, 73, - 74, 75, 76, 77, 79, 80, 81, 82, 83, 84, 85, 86, 95 }; - -static const struct sirfsoc_muxmask lcd_24bits_muxmask[] = { - { - .group = 2, - .mask = BIT(1) | BIT(6) | BIT(7) | BIT(8) | BIT(9) | - BIT(10) | BIT(11) | BIT(12) | BIT(13) | BIT(15) | - BIT(16) | BIT(17) | BIT(18) | BIT(19) | - BIT(20) | BIT(21) | BIT(22) | BIT(31), - }, { - .group = 1, - .mask = BIT(30) | BIT(31), - }, { - .group = 0, - .mask = BIT(16) | BIT(17) | BIT(18) | BIT(19) | BIT(20) | - BIT(21) | BIT(22) | BIT(23), - }, -}; - -static const struct sirfsoc_padmux lcd_24bits_padmux = { - .muxmask_counts = ARRAY_SIZE(lcd_24bits_muxmask), - .muxmask = lcd_24bits_muxmask, - .ctrlreg = SIRFSOC_RSC_PIN_MUX, - .funcmask = BIT(4) | BIT(15), - .funcval = 0, -}; - -static const unsigned lcd_24bits_pins[] = { 16, 17, 18, 19, 20, 21, 22, 23, 62, - 63, 65, 70, 71, 72, 73, 74, 75, 76, 77, 79, 80, 81, 82, 83, 84, - 85, 86, 95}; - -static const struct sirfsoc_muxmask lcdrom_muxmask[] = { - { - .group = 2, - .mask = BIT(1) | BIT(6) | BIT(7) | BIT(8) | BIT(9) | BIT(10) | - BIT(11) | BIT(12) | BIT(13) | BIT(15) | BIT(16) | - BIT(17) | BIT(18) | BIT(19) | - BIT(20) | BIT(21) | BIT(22) | BIT(31), - }, { - .group = 1, - .mask = BIT(30) | BIT(31), - }, { - .group = 0, - .mask = BIT(8), - }, -}; - -static const struct sirfsoc_padmux lcdrom_padmux = { - .muxmask_counts = ARRAY_SIZE(lcdrom_muxmask), - .muxmask = lcdrom_muxmask, - .ctrlreg = SIRFSOC_RSC_PIN_MUX, - .funcmask = BIT(4), - .funcval = BIT(4), -}; - -static const unsigned lcdrom_pins[] = { 8, 62, 63, 65, 70, 71, 72, 73, 74, 75, - 76, 77, 79, 80, 81, 82, 83, 84, 85, 86, 95}; - -static const struct sirfsoc_muxmask uart0_muxmask[] = { - { - .group = 0, - .mask = BIT(12), - }, { - .group = 1, - .mask = BIT(23), - }, { - .group = 2, - .mask = BIT(4) | BIT(5), - }, -}; - -static const struct sirfsoc_padmux uart0_padmux = { - .muxmask_counts = ARRAY_SIZE(uart0_muxmask), - .muxmask = uart0_muxmask, - .ctrlreg = SIRFSOC_RSC_PIN_MUX, - .funcmask = BIT(9), - .funcval = BIT(9), -}; - -static const unsigned uart0_pins[] = { 12, 55, 68, 69 }; - -static const struct sirfsoc_muxmask uart0_nostreamctrl_muxmask[] = { - { - .group = 2, - .mask = BIT(4) | BIT(5), - }, -}; - -static const struct sirfsoc_padmux uart0_nostreamctrl_padmux = { - .muxmask_counts = ARRAY_SIZE(uart0_nostreamctrl_muxmask), - .muxmask = uart0_nostreamctrl_muxmask, -}; - -static const unsigned uart0_nostreamctrl_pins[] = { 68, 69 }; - -static const struct sirfsoc_muxmask uart1_muxmask[] = { - { - .group = 1, - .mask = BIT(15) | BIT(17), - }, -}; - -static const struct sirfsoc_padmux uart1_padmux = { - .muxmask_counts = ARRAY_SIZE(uart1_muxmask), - .muxmask = uart1_muxmask, -}; - -static const unsigned uart1_pins[] = { 47, 49 }; - -static const struct sirfsoc_muxmask uart2_muxmask[] = { - { - .group = 0, - .mask = BIT(10) | BIT(14), - }, { - .group = 1, - .mask = BIT(16) | BIT(18), - }, -}; - -static const struct sirfsoc_padmux uart2_padmux = { - .muxmask_counts = ARRAY_SIZE(uart2_muxmask), - .muxmask = uart2_muxmask, - .ctrlreg = SIRFSOC_RSC_PIN_MUX, - .funcmask = BIT(10), - .funcval = BIT(10), -}; - -static const unsigned uart2_pins[] = { 10, 14, 48, 50 }; - -static const struct sirfsoc_muxmask uart2_nostreamctrl_muxmask[] = { - { - .group = 1, - .mask = BIT(16) | BIT(18), - }, -}; - -static const struct sirfsoc_padmux uart2_nostreamctrl_padmux = { - .muxmask_counts = ARRAY_SIZE(uart2_nostreamctrl_muxmask), - .muxmask = uart2_nostreamctrl_muxmask, -}; - -static const unsigned uart2_nostreamctrl_pins[] = { 48, 50 }; - -static const struct sirfsoc_muxmask sdmmc3_muxmask[] = { - { - .group = 0, - .mask = BIT(30) | BIT(31), - }, { - .group = 1, - .mask = BIT(0) | BIT(1) | BIT(2) | BIT(3), - }, -}; - -static const struct sirfsoc_padmux sdmmc3_padmux = { - .muxmask_counts = ARRAY_SIZE(sdmmc3_muxmask), - .muxmask = sdmmc3_muxmask, - .ctrlreg = SIRFSOC_RSC_PIN_MUX, - .funcmask = BIT(7), - .funcval = 0, -}; - -static const unsigned sdmmc3_pins[] = { 30, 31, 32, 33, 34, 35 }; - -static const struct sirfsoc_muxmask spi0_muxmask[] = { - { - .group = 0, - .mask = BIT(30), - }, { - .group = 1, - .mask = BIT(0) | BIT(2) | BIT(3), - }, -}; - -static const struct sirfsoc_padmux spi0_padmux = { - .muxmask_counts = ARRAY_SIZE(spi0_muxmask), - .muxmask = spi0_muxmask, - .ctrlreg = SIRFSOC_RSC_PIN_MUX, - .funcmask = BIT(7), - .funcval = BIT(7), -}; - -static const unsigned spi0_pins[] = { 30, 32, 34, 35 }; - -static const struct sirfsoc_muxmask cko1_muxmask[] = { - { - .group = 1, - .mask = BIT(10), - }, -}; - -static const struct sirfsoc_padmux cko1_padmux = { - .muxmask_counts = ARRAY_SIZE(cko1_muxmask), - .muxmask = cko1_muxmask, - .ctrlreg = SIRFSOC_RSC_PIN_MUX, - .funcmask = BIT(3), - .funcval = 0, -}; - -static const unsigned cko1_pins[] = { 42 }; - -static const struct sirfsoc_muxmask i2s_mclk_muxmask[] = { - { - .group = 1, - .mask = BIT(10), - }, -}; - -static const struct sirfsoc_padmux i2s_mclk_padmux = { - .muxmask_counts = ARRAY_SIZE(i2s_mclk_muxmask), - .muxmask = i2s_mclk_muxmask, - .ctrlreg = SIRFSOC_RSC_PIN_MUX, - .funcmask = BIT(3), - .funcval = BIT(3), -}; - -static const unsigned i2s_mclk_pins[] = { 42 }; - -static const struct sirfsoc_muxmask i2s_ext_clk_input_muxmask[] = { - { - .group = 1, - .mask = BIT(19), - }, -}; - -static const struct sirfsoc_padmux i2s_ext_clk_input_padmux = { - .muxmask_counts = ARRAY_SIZE(i2s_ext_clk_input_muxmask), - .muxmask = i2s_ext_clk_input_muxmask, - .ctrlreg = SIRFSOC_RSC_PIN_MUX, - .funcmask = BIT(2), - .funcval = BIT(2), -}; - -static const unsigned i2s_ext_clk_input_pins[] = { 51 }; - -static const struct sirfsoc_muxmask i2s_muxmask[] = { - { - .group = 3, - .mask = BIT(2) | BIT(3) | BIT(4) | BIT(5), - }, -}; - -static const struct sirfsoc_padmux i2s_padmux = { - .muxmask_counts = ARRAY_SIZE(i2s_muxmask), - .muxmask = i2s_muxmask, - .ctrlreg = SIRFSOC_RSC_PIN_MUX, -}; - -static const unsigned i2s_pins[] = { 98, 99, 100, 101 }; - -static const struct sirfsoc_muxmask i2s_no_din_muxmask[] = { - { - .group = 3, - .mask = BIT(2) | BIT(3) | BIT(4), - }, -}; - -static const struct sirfsoc_padmux i2s_no_din_padmux = { - .muxmask_counts = ARRAY_SIZE(i2s_no_din_muxmask), - .muxmask = i2s_no_din_muxmask, - .ctrlreg = SIRFSOC_RSC_PIN_MUX, -}; - -static const unsigned i2s_no_din_pins[] = { 98, 99, 100 }; - -static const struct sirfsoc_muxmask i2s_6chn_muxmask[] = { - { - .group = 3, - .mask = BIT(2) | BIT(3) | BIT(4) | BIT(5), - }, -}; - -static const struct sirfsoc_padmux i2s_6chn_padmux = { - .muxmask_counts = ARRAY_SIZE(i2s_6chn_muxmask), - .muxmask = i2s_6chn_muxmask, - .ctrlreg = SIRFSOC_RSC_PIN_MUX, - .funcmask = BIT(1) | BIT(9), - .funcval = BIT(1) | BIT(9), -}; - -static const unsigned i2s_6chn_pins[] = { 52, 55, 98, 99, 100, 101 }; - -static const struct sirfsoc_muxmask ac97_muxmask[] = { - { - .group = 3, - .mask = BIT(2) | BIT(3) | BIT(4) | BIT(5), - }, -}; - -static const struct sirfsoc_padmux ac97_padmux = { - .muxmask_counts = ARRAY_SIZE(ac97_muxmask), - .muxmask = ac97_muxmask, -}; - -static const unsigned ac97_pins[] = { 98, 99, 100, 101 }; - -static const struct sirfsoc_muxmask spi1_muxmask[] = { - { - .group = 1, - .mask = BIT(11) | BIT(12) | BIT(13) | BIT(14), - }, -}; - -static const struct sirfsoc_padmux spi1_padmux = { - .muxmask_counts = ARRAY_SIZE(spi1_muxmask), - .muxmask = spi1_muxmask, - .ctrlreg = SIRFSOC_RSC_PIN_MUX, - .funcmask = BIT(16), - .funcval = 0, -}; - -static const unsigned spi1_pins[] = { 43, 44, 45, 46 }; - -static const struct sirfsoc_muxmask sdmmc1_muxmask[] = { - { - .group = 2, - .mask = BIT(2) | BIT(3), - }, -}; - -static const struct sirfsoc_padmux sdmmc1_padmux = { - .muxmask_counts = ARRAY_SIZE(sdmmc1_muxmask), - .muxmask = sdmmc1_muxmask, - .ctrlreg = SIRFSOC_RSC_PIN_MUX, - .funcmask = BIT(5), - .funcval = BIT(5), -}; - -static const unsigned sdmmc1_pins[] = { 66, 67 }; - -static const struct sirfsoc_muxmask gps_muxmask[] = { - { - .group = 0, - .mask = BIT(24) | BIT(25) | BIT(26), - }, -}; - -static const struct sirfsoc_padmux gps_padmux = { - .muxmask_counts = ARRAY_SIZE(gps_muxmask), - .muxmask = gps_muxmask, - .ctrlreg = SIRFSOC_RSC_PIN_MUX, - .funcmask = BIT(13), - .funcval = 0, -}; - -static const unsigned gps_pins[] = { 24, 25, 26 }; - -static const struct sirfsoc_muxmask sdmmc5_muxmask[] = { - { - .group = 0, - .mask = BIT(24) | BIT(25) | BIT(26), - }, -}; - -static const struct sirfsoc_padmux sdmmc5_padmux = { - .muxmask_counts = ARRAY_SIZE(sdmmc5_muxmask), - .muxmask = sdmmc5_muxmask, - .ctrlreg = SIRFSOC_RSC_PIN_MUX, - .funcmask = BIT(13), - .funcval = BIT(13), -}; - -static const unsigned sdmmc5_pins[] = { 24, 25, 26 }; - -static const struct sirfsoc_muxmask usp0_muxmask[] = { - { - .group = 1, - .mask = BIT(19) | BIT(20) | BIT(21) | BIT(22) | BIT(23), - }, -}; - -static const struct sirfsoc_padmux usp0_padmux = { - .muxmask_counts = ARRAY_SIZE(usp0_muxmask), - .muxmask = usp0_muxmask, - .ctrlreg = SIRFSOC_RSC_PIN_MUX, - .funcmask = BIT(1) | BIT(2) | BIT(9), - .funcval = 0, -}; - -static const unsigned usp0_pins[] = { 51, 52, 53, 54, 55 }; - -static const struct sirfsoc_muxmask usp0_only_utfs_muxmask[] = { - { - .group = 1, - .mask = BIT(19) | BIT(20) | BIT(21) | BIT(22), - }, -}; - -static const struct sirfsoc_padmux usp0_only_utfs_padmux = { - .muxmask_counts = ARRAY_SIZE(usp0_only_utfs_muxmask), - .muxmask = usp0_only_utfs_muxmask, - .ctrlreg = SIRFSOC_RSC_PIN_MUX, - .funcmask = BIT(1) | BIT(2) | BIT(6), - .funcval = 0, -}; - -static const unsigned usp0_only_utfs_pins[] = { 51, 52, 53, 54 }; - -static const struct sirfsoc_muxmask usp0_only_urfs_muxmask[] = { - { - .group = 1, - .mask = BIT(19) | BIT(20) | BIT(21) | BIT(23), - }, -}; - -static const struct sirfsoc_padmux usp0_only_urfs_padmux = { - .muxmask_counts = ARRAY_SIZE(usp0_only_urfs_muxmask), - .muxmask = usp0_only_urfs_muxmask, - .ctrlreg = SIRFSOC_RSC_PIN_MUX, - .funcmask = BIT(1) | BIT(2) | BIT(9), - .funcval = 0, -}; - -static const unsigned usp0_only_urfs_pins[] = { 51, 52, 53, 55 }; - -static const struct sirfsoc_muxmask usp0_uart_nostreamctrl_muxmask[] = { - { - .group = 1, - .mask = BIT(20) | BIT(21), - }, -}; - -static const struct sirfsoc_padmux usp0_uart_nostreamctrl_padmux = { - .muxmask_counts = ARRAY_SIZE(usp0_uart_nostreamctrl_muxmask), - .muxmask = usp0_uart_nostreamctrl_muxmask, -}; - -static const unsigned usp0_uart_nostreamctrl_pins[] = { 52, 53 }; -static const struct sirfsoc_muxmask usp1_muxmask[] = { - { - .group = 0, - .mask = BIT(15), - }, { - .group = 1, - .mask = BIT(11) | BIT(12) | BIT(13) | BIT(14), - }, -}; - -static const struct sirfsoc_padmux usp1_padmux = { - .muxmask_counts = ARRAY_SIZE(usp1_muxmask), - .muxmask = usp1_muxmask, - .ctrlreg = SIRFSOC_RSC_PIN_MUX, - .funcmask = BIT(16), - .funcval = BIT(16), -}; - -static const unsigned usp1_pins[] = { 15, 43, 44, 45, 46 }; - -static const struct sirfsoc_muxmask usp1_uart_nostreamctrl_muxmask[] = { - { - .group = 1, - .mask = BIT(12) | BIT(13), - }, -}; - -static const struct sirfsoc_padmux usp1_uart_nostreamctrl_padmux = { - .muxmask_counts = ARRAY_SIZE(usp1_uart_nostreamctrl_muxmask), - .muxmask = usp1_uart_nostreamctrl_muxmask, - .ctrlreg = SIRFSOC_RSC_PIN_MUX, - .funcmask = BIT(16), - .funcval = BIT(16), -}; - -static const unsigned usp1_uart_nostreamctrl_pins[] = { 44, 45 }; - -static const struct sirfsoc_muxmask nand_muxmask[] = { - { - .group = 2, - .mask = BIT(2) | BIT(3) | BIT(28) | BIT(29) | BIT(30), - }, { - .group = 3, - .mask = BIT(0) | BIT(1), - }, -}; - -static const struct sirfsoc_padmux nand_padmux = { - .muxmask_counts = ARRAY_SIZE(nand_muxmask), - .muxmask = nand_muxmask, - .ctrlreg = SIRFSOC_RSC_PIN_MUX, - .funcmask = BIT(5) | BIT(19), - .funcval = 0, -}; - -static const unsigned nand_pins[] = { 66, 67, 92, 93, 94, 96, 97 }; - -static const struct sirfsoc_muxmask sdmmc0_muxmask[] = { - { - .group = 3, - .mask = BIT(1), - }, -}; - -static const struct sirfsoc_padmux sdmmc0_padmux = { - .muxmask_counts = ARRAY_SIZE(sdmmc0_muxmask), - .muxmask = sdmmc0_muxmask, - .ctrlreg = SIRFSOC_RSC_PIN_MUX, - .funcmask = BIT(5) | BIT(19), - .funcval = BIT(19), -}; - -static const unsigned sdmmc0_pins[] = { 97 }; - -static const struct sirfsoc_muxmask sdmmc2_muxmask[] = { - { - .group = 0, - .mask = BIT(27) | BIT(28) | BIT(29), - }, -}; - -static const struct sirfsoc_padmux sdmmc2_padmux = { - .muxmask_counts = ARRAY_SIZE(sdmmc2_muxmask), - .muxmask = sdmmc2_muxmask, - .ctrlreg = SIRFSOC_RSC_PIN_MUX, - .funcmask = BIT(11), - .funcval = 0, -}; - -static const unsigned sdmmc2_pins[] = { 27, 28, 29 }; - -static const struct sirfsoc_muxmask sdmmc2_nowp_muxmask[] = { - { - .group = 0, - .mask = BIT(27) | BIT(28), - }, -}; - -static const struct sirfsoc_padmux sdmmc2_nowp_padmux = { - .muxmask_counts = ARRAY_SIZE(sdmmc2_nowp_muxmask), - .muxmask = sdmmc2_nowp_muxmask, - .ctrlreg = SIRFSOC_RSC_PIN_MUX, - .funcmask = BIT(11), - .funcval = 0, -}; - -static const unsigned sdmmc2_nowp_pins[] = { 27, 28 }; - -static const struct sirfsoc_muxmask cko0_muxmask[] = { - { - .group = 2, - .mask = BIT(14), - }, -}; - -static const struct sirfsoc_padmux cko0_padmux = { - .muxmask_counts = ARRAY_SIZE(cko0_muxmask), - .muxmask = cko0_muxmask, -}; - -static const unsigned cko0_pins[] = { 78 }; - -static const struct sirfsoc_muxmask vip_muxmask[] = { - { - .group = 1, - .mask = BIT(4) | BIT(5) | BIT(6) | BIT(8) | BIT(9) - | BIT(24) | BIT(25) | BIT(26) | BIT(27) | BIT(28) | - BIT(29), - }, -}; - -static const struct sirfsoc_padmux vip_padmux = { - .muxmask_counts = ARRAY_SIZE(vip_muxmask), - .muxmask = vip_muxmask, - .ctrlreg = SIRFSOC_RSC_PIN_MUX, - .funcmask = BIT(18), - .funcval = BIT(18), -}; - -static const unsigned vip_pins[] = { 36, 37, 38, 40, 41, 56, 57, 58, 59, - 60, 61 }; - -static const struct sirfsoc_muxmask vip_noupli_muxmask[] = { - { - .group = 0, - .mask = BIT(16) | BIT(17) | BIT(18) | BIT(19) | BIT(20) - | BIT(21) | BIT(22) | BIT(23), - }, { - .group = 2, - .mask = BIT(23) | BIT(24) | BIT(25), - }, -}; - -static const struct sirfsoc_padmux vip_noupli_padmux = { - .muxmask_counts = ARRAY_SIZE(vip_noupli_muxmask), - .muxmask = vip_noupli_muxmask, - .ctrlreg = SIRFSOC_RSC_PIN_MUX, - .funcmask = BIT(15), - .funcval = BIT(15), -}; - -static const unsigned vip_noupli_pins[] = { 16, 17, 18, 19, 20, 21, 22, 23, - 87, 88, 89 }; - -static const struct sirfsoc_muxmask i2c0_muxmask[] = { - { - .group = 2, - .mask = BIT(26) | BIT(27), - }, -}; - -static const struct sirfsoc_padmux i2c0_padmux = { - .muxmask_counts = ARRAY_SIZE(i2c0_muxmask), - .muxmask = i2c0_muxmask, -}; - -static const unsigned i2c0_pins[] = { 90, 91 }; - -static const struct sirfsoc_muxmask i2c1_muxmask[] = { - { - .group = 0, - .mask = BIT(13) | BIT(15), - }, -}; - -static const struct sirfsoc_padmux i2c1_padmux = { - .muxmask_counts = ARRAY_SIZE(i2c1_muxmask), - .muxmask = i2c1_muxmask, - .ctrlreg = SIRFSOC_RSC_PIN_MUX, - .funcmask = BIT(16), - .funcval = 0, -}; - -static const unsigned i2c1_pins[] = { 13, 15 }; - -static const struct sirfsoc_muxmask pwm0_muxmask[] = { - { - .group = 0, - .mask = BIT(4), - }, -}; - -static const struct sirfsoc_padmux pwm0_padmux = { - .muxmask_counts = ARRAY_SIZE(pwm0_muxmask), - .muxmask = pwm0_muxmask, - .ctrlreg = SIRFSOC_RSC_PIN_MUX, - .funcmask = BIT(12), - .funcval = 0, -}; - -static const unsigned pwm0_pins[] = { 4 }; - -static const struct sirfsoc_muxmask pwm1_muxmask[] = { - { - .group = 0, - .mask = BIT(5), - }, -}; - -static const struct sirfsoc_padmux pwm1_padmux = { - .muxmask_counts = ARRAY_SIZE(pwm1_muxmask), - .muxmask = pwm1_muxmask, -}; - -static const unsigned pwm1_pins[] = { 5 }; - -static const struct sirfsoc_muxmask pwm2_muxmask[] = { - { - .group = 0, - .mask = BIT(6), - }, -}; - -static const struct sirfsoc_padmux pwm2_padmux = { - .muxmask_counts = ARRAY_SIZE(pwm2_muxmask), - .muxmask = pwm2_muxmask, -}; - -static const unsigned pwm2_pins[] = { 6 }; - -static const struct sirfsoc_muxmask pwm3_muxmask[] = { - { - .group = 0, - .mask = BIT(7), - }, -}; - -static const struct sirfsoc_padmux pwm3_padmux = { - .muxmask_counts = ARRAY_SIZE(pwm3_muxmask), - .muxmask = pwm3_muxmask, -}; - -static const unsigned pwm3_pins[] = { 7 }; - -static const struct sirfsoc_muxmask pwm4_muxmask[] = { - { - .group = 2, - .mask = BIT(14), - }, -}; - -static const struct sirfsoc_padmux pwm4_padmux = { - .muxmask_counts = ARRAY_SIZE(pwm4_muxmask), - .muxmask = pwm4_muxmask, -}; - -static const unsigned pwm4_pins[] = { 78 }; - -static const struct sirfsoc_muxmask warm_rst_muxmask[] = { - { - .group = 0, - .mask = BIT(8), - }, -}; - -static const struct sirfsoc_padmux warm_rst_padmux = { - .muxmask_counts = ARRAY_SIZE(warm_rst_muxmask), - .muxmask = warm_rst_muxmask, - .ctrlreg = SIRFSOC_RSC_PIN_MUX, - .funcmask = BIT(4), - .funcval = 0, -}; - -static const unsigned warm_rst_pins[] = { 8 }; - -static const struct sirfsoc_muxmask usb0_upli_drvbus_muxmask[] = { - { - .group = 1, - .mask = BIT(4) | BIT(5) | BIT(6) | BIT(7) | BIT(8) - | BIT(9) | BIT(24) | BIT(25) | BIT(26) | - BIT(27) | BIT(28) | BIT(29), - }, -}; -static const struct sirfsoc_padmux usb0_upli_drvbus_padmux = { - .muxmask_counts = ARRAY_SIZE(usb0_upli_drvbus_muxmask), - .muxmask = usb0_upli_drvbus_muxmask, - .ctrlreg = SIRFSOC_RSC_PIN_MUX, - .funcmask = BIT(18), - .funcval = 0, -}; - -static const unsigned usb0_upli_drvbus_pins[] = { 36, 37, 38, 39, 40, - 41, 56, 57, 58, 59, 60, 61 }; - -static const struct sirfsoc_muxmask usb1_utmi_drvbus_muxmask[] = { - { - .group = 0, - .mask = BIT(28), - }, -}; - -static const struct sirfsoc_padmux usb1_utmi_drvbus_padmux = { - .muxmask_counts = ARRAY_SIZE(usb1_utmi_drvbus_muxmask), - .muxmask = usb1_utmi_drvbus_muxmask, - .ctrlreg = SIRFSOC_RSC_PIN_MUX, - .funcmask = BIT(11), - .funcval = BIT(11), /* refer to PAD_UTMI_DRVVBUS1_ENABLE */ -}; - -static const unsigned usb1_utmi_drvbus_pins[] = { 28 }; - -static const struct sirfsoc_padmux usb1_dp_dn_padmux = { - .muxmask_counts = 0, - .ctrlreg = SIRFSOC_RSC_USB_UART_SHARE, - .funcmask = BIT(2), - .funcval = BIT(2), -}; - -static const unsigned usb1_dp_dn_pins[] = { 103, 104 }; - -static const struct sirfsoc_padmux uart1_route_io_usb1_padmux = { - .muxmask_counts = 0, - .ctrlreg = SIRFSOC_RSC_USB_UART_SHARE, - .funcmask = BIT(2), - .funcval = 0, -}; - -static const unsigned uart1_route_io_usb1_pins[] = { 103, 104 }; - -static const struct sirfsoc_muxmask pulse_count_muxmask[] = { - { - .group = 0, - .mask = BIT(9) | BIT(10) | BIT(11), - }, -}; - -static const struct sirfsoc_padmux pulse_count_padmux = { - .muxmask_counts = ARRAY_SIZE(pulse_count_muxmask), - .muxmask = pulse_count_muxmask, -}; - -static const unsigned pulse_count_pins[] = { 9, 10, 11 }; - -static const struct sirfsoc_pin_group sirfsoc_pin_groups[] = { - SIRFSOC_PIN_GROUP("lcd_16bitsgrp", lcd_16bits_pins), - SIRFSOC_PIN_GROUP("lcd_18bitsgrp", lcd_18bits_pins), - SIRFSOC_PIN_GROUP("lcd_24bitsgrp", lcd_24bits_pins), - SIRFSOC_PIN_GROUP("lcdrom_grp", lcdrom_pins), - SIRFSOC_PIN_GROUP("uart0grp", uart0_pins), - SIRFSOC_PIN_GROUP("uart0_nostreamctrlgrp", uart0_nostreamctrl_pins), - SIRFSOC_PIN_GROUP("uart1grp", uart1_pins), - SIRFSOC_PIN_GROUP("uart2grp", uart2_pins), - SIRFSOC_PIN_GROUP("uart2_nostreamctrlgrp", uart2_nostreamctrl_pins), - SIRFSOC_PIN_GROUP("usp0grp", usp0_pins), - SIRFSOC_PIN_GROUP("usp0_uart_nostreamctrl_grp", - usp0_uart_nostreamctrl_pins), - SIRFSOC_PIN_GROUP("usp0_only_utfs_grp", usp0_only_utfs_pins), - SIRFSOC_PIN_GROUP("usp0_only_urfs_grp", usp0_only_urfs_pins), - SIRFSOC_PIN_GROUP("usp1grp", usp1_pins), - SIRFSOC_PIN_GROUP("usp1_uart_nostreamctrl_grp", - usp1_uart_nostreamctrl_pins), - SIRFSOC_PIN_GROUP("i2c0grp", i2c0_pins), - SIRFSOC_PIN_GROUP("i2c1grp", i2c1_pins), - SIRFSOC_PIN_GROUP("pwm0grp", pwm0_pins), - SIRFSOC_PIN_GROUP("pwm1grp", pwm1_pins), - SIRFSOC_PIN_GROUP("pwm2grp", pwm2_pins), - SIRFSOC_PIN_GROUP("pwm3grp", pwm3_pins), - SIRFSOC_PIN_GROUP("pwm4grp", pwm4_pins), - SIRFSOC_PIN_GROUP("vipgrp", vip_pins), - SIRFSOC_PIN_GROUP("vip_noupligrp", vip_noupli_pins), - SIRFSOC_PIN_GROUP("warm_rstgrp", warm_rst_pins), - SIRFSOC_PIN_GROUP("cko0grp", cko0_pins), - SIRFSOC_PIN_GROUP("cko1grp", cko1_pins), - SIRFSOC_PIN_GROUP("sdmmc0grp", sdmmc0_pins), - SIRFSOC_PIN_GROUP("sdmmc1grp", sdmmc1_pins), - SIRFSOC_PIN_GROUP("sdmmc2grp", sdmmc2_pins), - SIRFSOC_PIN_GROUP("sdmmc2_nowpgrp", sdmmc2_nowp_pins), - SIRFSOC_PIN_GROUP("sdmmc3grp", sdmmc3_pins), - SIRFSOC_PIN_GROUP("sdmmc5grp", sdmmc5_pins), - SIRFSOC_PIN_GROUP("usb0_upli_drvbusgrp", usb0_upli_drvbus_pins), - SIRFSOC_PIN_GROUP("usb1_utmi_drvbusgrp", usb1_utmi_drvbus_pins), - SIRFSOC_PIN_GROUP("usb1_dp_dngrp", usb1_dp_dn_pins), - SIRFSOC_PIN_GROUP("uart1_route_io_usb1grp", uart1_route_io_usb1_pins), - SIRFSOC_PIN_GROUP("pulse_countgrp", pulse_count_pins), - SIRFSOC_PIN_GROUP("i2smclkgrp", i2s_mclk_pins), - SIRFSOC_PIN_GROUP("i2s_ext_clk_inputgrp", i2s_ext_clk_input_pins), - SIRFSOC_PIN_GROUP("i2sgrp", i2s_pins), - SIRFSOC_PIN_GROUP("i2s_no_dingrp", i2s_no_din_pins), - SIRFSOC_PIN_GROUP("i2s_6chngrp", i2s_6chn_pins), - SIRFSOC_PIN_GROUP("ac97grp", ac97_pins), - SIRFSOC_PIN_GROUP("nandgrp", nand_pins), - SIRFSOC_PIN_GROUP("spi0grp", spi0_pins), - SIRFSOC_PIN_GROUP("spi1grp", spi1_pins), - SIRFSOC_PIN_GROUP("gpsgrp", gps_pins), -}; - -static const char * const lcd_16bitsgrp[] = { "lcd_16bitsgrp" }; -static const char * const lcd_18bitsgrp[] = { "lcd_18bitsgrp" }; -static const char * const lcd_24bitsgrp[] = { "lcd_24bitsgrp" }; -static const char * const lcdromgrp[] = { "lcdromgrp" }; -static const char * const uart0grp[] = { "uart0grp" }; -static const char * const uart0_nostreamctrlgrp[] = { "uart0_nostreamctrlgrp" }; -static const char * const uart1grp[] = { "uart1grp" }; -static const char * const uart2grp[] = { "uart2grp" }; -static const char * const uart2_nostreamctrlgrp[] = { "uart2_nostreamctrlgrp" }; -static const char * const usp0_uart_nostreamctrl_grp[] = { - "usp0_uart_nostreamctrl_grp" }; -static const char * const usp0grp[] = { "usp0grp" }; -static const char * const usp0_only_utfs_grp[] = { "usp0_only_utfs_grp" }; -static const char * const usp0_only_urfs_grp[] = { "usp0_only_urfs_grp" }; - -static const char * const usp1grp[] = { "usp1grp" }; -static const char * const usp1_uart_nostreamctrl_grp[] = { - "usp1_uart_nostreamctrl_grp" }; -static const char * const i2c0grp[] = { "i2c0grp" }; -static const char * const i2c1grp[] = { "i2c1grp" }; -static const char * const pwm0grp[] = { "pwm0grp" }; -static const char * const pwm1grp[] = { "pwm1grp" }; -static const char * const pwm2grp[] = { "pwm2grp" }; -static const char * const pwm3grp[] = { "pwm3grp" }; -static const char * const pwm4grp[] = { "pwm4grp" }; -static const char * const vipgrp[] = { "vipgrp" }; -static const char * const vip_noupligrp[] = { "vip_noupligrp" }; -static const char * const warm_rstgrp[] = { "warm_rstgrp" }; -static const char * const cko0grp[] = { "cko0grp" }; -static const char * const cko1grp[] = { "cko1grp" }; -static const char * const sdmmc0grp[] = { "sdmmc0grp" }; -static const char * const sdmmc1grp[] = { "sdmmc1grp" }; -static const char * const sdmmc2grp[] = { "sdmmc2grp" }; -static const char * const sdmmc3grp[] = { "sdmmc3grp" }; -static const char * const sdmmc5grp[] = { "sdmmc5grp" }; -static const char * const sdmmc2_nowpgrp[] = { "sdmmc2_nowpgrp" }; -static const char * const usb0_upli_drvbusgrp[] = { "usb0_upli_drvbusgrp" }; -static const char * const usb1_utmi_drvbusgrp[] = { "usb1_utmi_drvbusgrp" }; -static const char * const usb1_dp_dngrp[] = { "usb1_dp_dngrp" }; -static const char * const - uart1_route_io_usb1grp[] = { "uart1_route_io_usb1grp" }; -static const char * const pulse_countgrp[] = { "pulse_countgrp" }; -static const char * const i2smclkgrp[] = { "i2smclkgrp" }; -static const char * const i2s_ext_clk_inputgrp[] = { "i2s_ext_clk_inputgrp" }; -static const char * const i2sgrp[] = { "i2sgrp" }; -static const char * const i2s_no_dingrp[] = { "i2s_no_dingrp" }; -static const char * const i2s_6chngrp[] = { "i2s_6chngrp" }; -static const char * const ac97grp[] = { "ac97grp" }; -static const char * const nandgrp[] = { "nandgrp" }; -static const char * const spi0grp[] = { "spi0grp" }; -static const char * const spi1grp[] = { "spi1grp" }; -static const char * const gpsgrp[] = { "gpsgrp" }; - -static const struct sirfsoc_pmx_func sirfsoc_pmx_functions[] = { - SIRFSOC_PMX_FUNCTION("lcd_16bits", lcd_16bitsgrp, lcd_16bits_padmux), - SIRFSOC_PMX_FUNCTION("lcd_18bits", lcd_18bitsgrp, lcd_18bits_padmux), - SIRFSOC_PMX_FUNCTION("lcd_24bits", lcd_24bitsgrp, lcd_24bits_padmux), - SIRFSOC_PMX_FUNCTION("lcdrom", lcdromgrp, lcdrom_padmux), - SIRFSOC_PMX_FUNCTION("uart0", uart0grp, uart0_padmux), - SIRFSOC_PMX_FUNCTION("uart0_nostreamctrl", uart0_nostreamctrlgrp, - uart0_nostreamctrl_padmux), - SIRFSOC_PMX_FUNCTION("uart1", uart1grp, uart1_padmux), - SIRFSOC_PMX_FUNCTION("uart2", uart2grp, uart2_padmux), - SIRFSOC_PMX_FUNCTION("uart2_nostreamctrl", - uart2_nostreamctrlgrp, uart2_nostreamctrl_padmux), - SIRFSOC_PMX_FUNCTION("usp0", usp0grp, usp0_padmux), - SIRFSOC_PMX_FUNCTION("usp0_uart_nostreamctrl", - usp0_uart_nostreamctrl_grp, - usp0_uart_nostreamctrl_padmux), - SIRFSOC_PMX_FUNCTION("usp0_only_utfs", usp0_only_utfs_grp, - usp0_only_utfs_padmux), - SIRFSOC_PMX_FUNCTION("usp0_only_urfs", usp0_only_urfs_grp, - usp0_only_urfs_padmux), - SIRFSOC_PMX_FUNCTION("usp1", usp1grp, usp1_padmux), - SIRFSOC_PMX_FUNCTION("usp1_uart_nostreamctrl", - usp1_uart_nostreamctrl_grp, - usp1_uart_nostreamctrl_padmux), - SIRFSOC_PMX_FUNCTION("i2c0", i2c0grp, i2c0_padmux), - SIRFSOC_PMX_FUNCTION("i2c1", i2c1grp, i2c1_padmux), - SIRFSOC_PMX_FUNCTION("pwm0", pwm0grp, pwm0_padmux), - SIRFSOC_PMX_FUNCTION("pwm1", pwm1grp, pwm1_padmux), - SIRFSOC_PMX_FUNCTION("pwm2", pwm2grp, pwm2_padmux), - SIRFSOC_PMX_FUNCTION("pwm3", pwm3grp, pwm3_padmux), - SIRFSOC_PMX_FUNCTION("pwm4", pwm4grp, pwm4_padmux), - SIRFSOC_PMX_FUNCTION("vip", vipgrp, vip_padmux), - SIRFSOC_PMX_FUNCTION("vip_noupli", vip_noupligrp, vip_noupli_padmux), - SIRFSOC_PMX_FUNCTION("warm_rst", warm_rstgrp, warm_rst_padmux), - SIRFSOC_PMX_FUNCTION("cko0", cko0grp, cko0_padmux), - SIRFSOC_PMX_FUNCTION("cko1", cko1grp, cko1_padmux), - SIRFSOC_PMX_FUNCTION("sdmmc0", sdmmc0grp, sdmmc0_padmux), - SIRFSOC_PMX_FUNCTION("sdmmc1", sdmmc1grp, sdmmc1_padmux), - SIRFSOC_PMX_FUNCTION("sdmmc2", sdmmc2grp, sdmmc2_padmux), - SIRFSOC_PMX_FUNCTION("sdmmc3", sdmmc3grp, sdmmc3_padmux), - SIRFSOC_PMX_FUNCTION("sdmmc5", sdmmc5grp, sdmmc5_padmux), - SIRFSOC_PMX_FUNCTION("sdmmc2_nowp", - sdmmc2_nowpgrp, sdmmc2_nowp_padmux), - SIRFSOC_PMX_FUNCTION("usb0_upli_drvbus", - usb0_upli_drvbusgrp, usb0_upli_drvbus_padmux), - SIRFSOC_PMX_FUNCTION("usb1_utmi_drvbus", - usb1_utmi_drvbusgrp, usb1_utmi_drvbus_padmux), - SIRFSOC_PMX_FUNCTION("usb1_dp_dn", usb1_dp_dngrp, usb1_dp_dn_padmux), - SIRFSOC_PMX_FUNCTION("uart1_route_io_usb1", - uart1_route_io_usb1grp, uart1_route_io_usb1_padmux), - SIRFSOC_PMX_FUNCTION("pulse_count", pulse_countgrp, pulse_count_padmux), - SIRFSOC_PMX_FUNCTION("i2s_mclk", i2smclkgrp, i2s_mclk_padmux), - SIRFSOC_PMX_FUNCTION("i2s_ext_clk_input", i2s_ext_clk_inputgrp, - i2s_ext_clk_input_padmux), - SIRFSOC_PMX_FUNCTION("i2s", i2sgrp, i2s_padmux), - SIRFSOC_PMX_FUNCTION("i2s_no_din", i2s_no_dingrp, i2s_no_din_padmux), - SIRFSOC_PMX_FUNCTION("i2s_6chn", i2s_6chngrp, i2s_6chn_padmux), - SIRFSOC_PMX_FUNCTION("ac97", ac97grp, ac97_padmux), - SIRFSOC_PMX_FUNCTION("nand", nandgrp, nand_padmux), - SIRFSOC_PMX_FUNCTION("spi0", spi0grp, spi0_padmux), - SIRFSOC_PMX_FUNCTION("spi1", spi1grp, spi1_padmux), - SIRFSOC_PMX_FUNCTION("gps", gpsgrp, gps_padmux), -}; - -struct sirfsoc_pinctrl_data atlas6_pinctrl_data = { - (struct pinctrl_pin_desc *)sirfsoc_pads, - ARRAY_SIZE(sirfsoc_pads), - (struct sirfsoc_pin_group *)sirfsoc_pin_groups, - ARRAY_SIZE(sirfsoc_pin_groups), - (struct sirfsoc_pmx_func *)sirfsoc_pmx_functions, - ARRAY_SIZE(sirfsoc_pmx_functions), -}; - diff --git a/drivers/pinctrl/sirf/pinctrl-atlas7.c b/drivers/pinctrl/sirf/pinctrl-atlas7.c deleted file mode 100644 index e54a6e3cafd2..000000000000 --- a/drivers/pinctrl/sirf/pinctrl-atlas7.c +++ /dev/null @@ -1,6157 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * pinctrl pads, groups, functions for CSR SiRFatlasVII - * - * Copyright (c) 2011 - 2014 Cambridge Silicon Radio Limited, a CSR plc group - * company. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* Definition of Pad&Mux Properties */ -#define N 0 - -/* The Bank contains input-disable regisgers */ -#define BANK_DS 0 - -/* Clear Register offset */ -#define CLR_REG(r) ((r) + 0x04) - -/* Definition of multiple function select register */ -#define FUNC_CLEAR_MASK 0x7 -#define FUNC_GPIO 0 -#define FUNC_ANALOGUE 0x8 -#define ANA_CLEAR_MASK 0x1 - -/* The Atlas7's Pad Type List */ -enum altas7_pad_type { - PAD_T_4WE_PD = 0, /* ZIO_PAD3V_4WE_PD */ - PAD_T_4WE_PU, /* ZIO_PAD3V_4WE_PD */ - PAD_T_16ST, /* ZIO_PAD3V_SDCLK_PD */ - PAD_T_M31_0204_PD, /* PRDW0204SDGZ_M311311_PD */ - PAD_T_M31_0204_PU, /* PRDW0204SDGZ_M311311_PU */ - PAD_T_M31_0610_PD, /* PRUW0610SDGZ_M311311_PD */ - PAD_T_M31_0610_PU, /* PRUW0610SDGZ_M311311_PU */ - PAD_T_AD, /* PRDWUWHW08SCDG_HZ */ -}; - -/* Raw value of Driver-Strength Bits */ -#define DS3 BIT(3) -#define DS2 BIT(2) -#define DS1 BIT(1) -#define DS0 BIT(0) -#define DSZ 0 - -/* Drive-Strength Intermediate Values */ -#define DS_NULL -1 -#define DS_1BIT_IM_VAL DS0 -#define DS_1BIT_MASK 0x1 -#define DS_2BIT_IM_VAL (DS1 | DS0) -#define DS_2BIT_MASK 0x3 -#define DS_4BIT_IM_VAL (DS3 | DS2 | DS1 | DS0) -#define DS_4BIT_MASK 0xf - -/* The Drive-Strength of 4WE Pad DS1 0 CO */ -#define DS_4WE_3 (DS1 | DS0) /* 1 1 3 */ -#define DS_4WE_2 (DS1) /* 1 0 2 */ -#define DS_4WE_1 (DS0) /* 0 1 1 */ -#define DS_4WE_0 (DSZ) /* 0 0 0 */ - -/* The Drive-Strength of 16st Pad DS3 2 1 0 CO */ -#define DS_16ST_15 (DS3 | DS2 | DS1 | DS0) /* 1 1 1 1 15 */ -#define DS_16ST_14 (DS3 | DS2 | DS0) /* 1 1 0 1 13 */ -#define DS_16ST_13 (DS3 | DS2 | DS1) /* 1 1 1 0 14 */ -#define DS_16ST_12 (DS2 | DS1 | DS0) /* 0 1 1 1 7 */ -#define DS_16ST_11 (DS2 | DS0) /* 0 1 0 1 5 */ -#define DS_16ST_10 (DS3 | DS1 | DS0) /* 1 0 1 1 11 */ -#define DS_16ST_9 (DS3 | DS0) /* 1 0 0 1 9 */ -#define DS_16ST_8 (DS1 | DS0) /* 0 0 1 1 3 */ -#define DS_16ST_7 (DS2 | DS1) /* 0 1 1 0 6 */ -#define DS_16ST_6 (DS3 | DS2) /* 1 1 0 0 12 */ -#define DS_16ST_5 (DS2) /* 0 1 0 0 4 */ -#define DS_16ST_4 (DS3 | DS1) /* 1 0 1 0 10 */ -#define DS_16ST_3 (DS1) /* 0 0 1 0 2 */ -#define DS_16ST_2 (DS0) /* 0 0 0 1 1 */ -#define DS_16ST_1 (DSZ) /* 0 0 0 0 0 */ -#define DS_16ST_0 (DS3) /* 1 0 0 0 8 */ - -/* The Drive-Strength of M31 Pad DS0 CO */ -#define DS_M31_0 (DSZ) /* 0 0 */ -#define DS_M31_1 (DS0) /* 1 1 */ - -/* Raw values of Pull Option Bits */ -#define PUN BIT(1) -#define PD BIT(0) -#define PE BIT(0) -#define PZ 0 - -/* Definition of Pull Types */ -#define PULL_UP 0 -#define HIGH_HYSTERESIS 1 -#define HIGH_Z 2 -#define PULL_DOWN 3 -#define PULL_DISABLE 4 -#define PULL_ENABLE 5 -#define PULL_UNKNOWN -1 - -/* Pull Options for 4WE Pad PUN PD CO */ -#define P4WE_PULL_MASK 0x3 -#define P4WE_PULL_DOWN (PUN | PD) /* 1 1 3 */ -#define P4WE_HIGH_Z (PUN) /* 1 0 2 */ -#define P4WE_HIGH_HYSTERESIS (PD) /* 0 1 1 */ -#define P4WE_PULL_UP (PZ) /* 0 0 0 */ - -/* Pull Options for 16ST Pad PUN PD CO */ -#define P16ST_PULL_MASK 0x3 -#define P16ST_PULL_DOWN (PUN | PD) /* 1 1 3 */ -#define P16ST_HIGH_Z (PUN) /* 1 0 2 */ -#define P16ST_PULL_UP (PZ) /* 0 0 0 */ - -/* Pull Options for M31 Pad PE */ -#define PM31_PULL_MASK 0x1 -#define PM31_PULL_ENABLED (PE) /* 1 */ -#define PM31_PULL_DISABLED (PZ) /* 0 */ - -/* Pull Options for A/D Pad PUN PD CO */ -#define PANGD_PULL_MASK 0x3 -#define PANGD_PULL_DOWN (PUN | PD) /* 1 1 3 */ -#define PANGD_HIGH_Z (PUN) /* 1 0 2 */ -#define PANGD_PULL_UP (PZ) /* 0 0 0 */ - -/* Definition of Input Disable */ -#define DI_MASK 0x1 -#define DI_DISABLE 0x1 -#define DI_ENABLE 0x0 - -/* Definition of Input Disable Value */ -#define DIV_MASK 0x1 -#define DIV_DISABLE 0x1 -#define DIV_ENABLE 0x0 - -/* Number of Function input disable registers */ -#define NUM_OF_IN_DISABLE_REG 0x2 - -/* Offset of Function input disable registers */ -#define IN_DISABLE_0_REG_SET 0x0A00 -#define IN_DISABLE_0_REG_CLR 0x0A04 -#define IN_DISABLE_1_REG_SET 0x0A08 -#define IN_DISABLE_1_REG_CLR 0x0A0C -#define IN_DISABLE_VAL_0_REG_SET 0x0A80 -#define IN_DISABLE_VAL_0_REG_CLR 0x0A84 -#define IN_DISABLE_VAL_1_REG_SET 0x0A88 -#define IN_DISABLE_VAL_1_REG_CLR 0x0A8C - -/* Offset of the SDIO9SEL*/ -#define SYS2PCI_SDIO9SEL 0x14 - -struct dt_params { - const char *property; - int value; -}; - -/** - * struct atlas7_pad_conf - Atlas7 Pad Configuration - * @id: The ID of this Pad. - * @type: The type of this Pad. - * @mux_reg: The mux register offset. - * This register contains the mux. - * @pupd_reg: The pull-up/down register offset. - * @drvstr_reg: The drive-strength register offset. - * @ad_ctrl_reg: The Analogue/Digital Control register. - * - * @mux_bit: The start bit of mux register. - * @pupd_bit: The start bit of pull-up/down register. - * @drvstr_bit: The start bit of drive-strength register. - * @ad_ctrl_bit: The start bit of analogue/digital register. - */ -struct atlas7_pad_config { - const u32 id; - u32 type; - u32 mux_reg; - u32 pupd_reg; - u32 drvstr_reg; - u32 ad_ctrl_reg; - /* bits in register */ - u8 mux_bit; - u8 pupd_bit; - u8 drvstr_bit; - u8 ad_ctrl_bit; -}; - -#define PADCONF(pad, t, mr, pr, dsr, adr, mb, pb, dsb, adb) \ - { \ - .id = pad, \ - .type = t, \ - .mux_reg = mr, \ - .pupd_reg = pr, \ - .drvstr_reg = dsr, \ - .ad_ctrl_reg = adr, \ - .mux_bit = mb, \ - .pupd_bit = pb, \ - .drvstr_bit = dsb, \ - .ad_ctrl_bit = adb, \ - } - -/* - * struct atlas7_pad_status - Atlas7 Pad status - */ -struct atlas7_pad_status { - u8 func; - u8 pull; - u8 dstr; - u8 reserved; -}; - -/** - * struct atlas7_pad_mux - Atlas7 mux - * @bank: The bank of this pad's registers on. - * @pin : The ID of this Pad. - * @func: The mux func on this Pad. - * @dinput_reg: The Input-Disable register offset. - * @dinput_bit: The start bit of Input-Disable register. - * @dinput_val_reg: The Input-Disable-value register offset. - * This register is used to set the value of this pad - * if this pad was disabled. - * @dinput_val_bit: The start bit of Input-Disable Value register. - */ -struct atlas7_pad_mux { - u32 bank; - u32 pin; - u32 func; - u32 dinput_reg; - u32 dinput_bit; - u32 dinput_val_reg; - u32 dinput_val_bit; -}; - -#define MUX(b, pad, f, dr, db, dvr, dvb) \ - { \ - .bank = b, \ - .pin = pad, \ - .func = f, \ - .dinput_reg = dr, \ - .dinput_bit = db, \ - .dinput_val_reg = dvr, \ - .dinput_val_bit = dvb, \ - } - -struct atlas7_grp_mux { - unsigned int group; - unsigned int pad_mux_count; - const struct atlas7_pad_mux *pad_mux_list; -}; - - /** - * struct sirfsoc_pin_group - describes a SiRFprimaII pin group - * @name: the name of this specific pin group - * @pins: an array of discrete physical pins used in this group, taken - * from the driver-local pin enumeration space - * @num_pins: the number of pins in this group array, i.e. the number of - * elements in .pins so we can iterate over that array - */ -struct atlas7_pin_group { - const char *name; - const unsigned int *pins; - const unsigned num_pins; -}; - -#define GROUP(n, p) \ - { \ - .name = n, \ - .pins = p, \ - .num_pins = ARRAY_SIZE(p), \ - } - -struct atlas7_pmx_func { - const char *name; - const char * const *groups; - const unsigned num_groups; - const struct atlas7_grp_mux *grpmux; -}; - -#define FUNCTION(n, g, m) \ - { \ - .name = n, \ - .groups = g, \ - .num_groups = ARRAY_SIZE(g), \ - .grpmux = m, \ - } - -struct atlas7_pinctrl_data { - struct pinctrl_pin_desc *pads; - int pads_cnt; - struct atlas7_pin_group *grps; - int grps_cnt; - struct atlas7_pmx_func *funcs; - int funcs_cnt; - struct atlas7_pad_config *confs; - int confs_cnt; -}; - -/* Platform info of atlas7 pinctrl */ -#define ATLAS7_PINCTRL_REG_BANKS 2 -#define ATLAS7_PINCTRL_BANK_0_PINS 18 -#define ATLAS7_PINCTRL_BANK_1_PINS 141 -#define ATLAS7_PINCTRL_TOTAL_PINS \ - (ATLAS7_PINCTRL_BANK_0_PINS + ATLAS7_PINCTRL_BANK_1_PINS) - -/** - * Atlas7 GPIO Chip - */ - -#define NGPIO_OF_BANK 32 -#define GPIO_TO_BANK(gpio) ((gpio) / NGPIO_OF_BANK) - -/* Registers of GPIO Controllers */ -#define ATLAS7_GPIO_BASE(g, b) ((g)->reg + 0x100 * (b)) -#define ATLAS7_GPIO_CTRL(b, i) ((b)->base + 4 * (i)) -#define ATLAS7_GPIO_INT_STATUS(b) ((b)->base + 0x8C) - -/* Definition bits of GPIO Control Registers */ -#define ATLAS7_GPIO_CTL_INTR_LOW_MASK BIT(0) -#define ATLAS7_GPIO_CTL_INTR_HIGH_MASK BIT(1) -#define ATLAS7_GPIO_CTL_INTR_TYPE_MASK BIT(2) -#define ATLAS7_GPIO_CTL_INTR_EN_MASK BIT(3) -#define ATLAS7_GPIO_CTL_INTR_STATUS_MASK BIT(4) -#define ATLAS7_GPIO_CTL_OUT_EN_MASK BIT(5) -#define ATLAS7_GPIO_CTL_DATAOUT_MASK BIT(6) -#define ATLAS7_GPIO_CTL_DATAIN_MASK BIT(7) - -struct atlas7_gpio_bank { - int id; - int irq; - void __iomem *base; - unsigned int gpio_offset; - unsigned int ngpio; - const unsigned int *gpio_pins; - u32 sleep_data[NGPIO_OF_BANK]; -}; - -struct atlas7_gpio_chip { - const char *name; - void __iomem *reg; - struct clk *clk; - int nbank; - raw_spinlock_t lock; - struct gpio_chip chip; - struct atlas7_gpio_bank banks[]; -}; - -struct atlas7_pmx { - struct device *dev; - struct pinctrl_dev *pctl; - struct pinctrl_desc pctl_desc; - struct atlas7_pinctrl_data *pctl_data; - void __iomem *regs[ATLAS7_PINCTRL_REG_BANKS]; - void __iomem *sys2pci_base; - u32 status_ds[NUM_OF_IN_DISABLE_REG]; - u32 status_dsv[NUM_OF_IN_DISABLE_REG]; - struct atlas7_pad_status sleep_data[ATLAS7_PINCTRL_TOTAL_PINS]; -}; - -/* - * Pad list for the pinmux subsystem - * refer to A7DA IO Summary - CS-314158-DD-4E.xls - */ - -/* Pads in IOC RTC & TOP */ -static const struct pinctrl_pin_desc atlas7_ioc_pads[] = { - /* RTC PADs */ - PINCTRL_PIN(0, "rtc_gpio_0"), - PINCTRL_PIN(1, "rtc_gpio_1"), - PINCTRL_PIN(2, "rtc_gpio_2"), - PINCTRL_PIN(3, "rtc_gpio_3"), - PINCTRL_PIN(4, "low_bat_ind_b"), - PINCTRL_PIN(5, "on_key_b"), - PINCTRL_PIN(6, "ext_on"), - PINCTRL_PIN(7, "mem_on"), - PINCTRL_PIN(8, "core_on"), - PINCTRL_PIN(9, "io_on"), - PINCTRL_PIN(10, "can0_tx"), - PINCTRL_PIN(11, "can0_rx"), - PINCTRL_PIN(12, "spi0_clk"), - PINCTRL_PIN(13, "spi0_cs_b"), - PINCTRL_PIN(14, "spi0_io_0"), - PINCTRL_PIN(15, "spi0_io_1"), - PINCTRL_PIN(16, "spi0_io_2"), - PINCTRL_PIN(17, "spi0_io_3"), - - /* TOP PADs */ - PINCTRL_PIN(18, "spi1_en"), - PINCTRL_PIN(19, "spi1_clk"), - PINCTRL_PIN(20, "spi1_din"), - PINCTRL_PIN(21, "spi1_dout"), - PINCTRL_PIN(22, "trg_spi_clk"), - PINCTRL_PIN(23, "trg_spi_di"), - PINCTRL_PIN(24, "trg_spi_do"), - PINCTRL_PIN(25, "trg_spi_cs_b"), - PINCTRL_PIN(26, "trg_acq_d1"), - PINCTRL_PIN(27, "trg_irq_b"), - PINCTRL_PIN(28, "trg_acq_d0"), - PINCTRL_PIN(29, "trg_acq_clk"), - PINCTRL_PIN(30, "trg_shutdown_b_out"), - PINCTRL_PIN(31, "sdio2_clk"), - PINCTRL_PIN(32, "sdio2_cmd"), - PINCTRL_PIN(33, "sdio2_dat_0"), - PINCTRL_PIN(34, "sdio2_dat_1"), - PINCTRL_PIN(35, "sdio2_dat_2"), - PINCTRL_PIN(36, "sdio2_dat_3"), - PINCTRL_PIN(37, "df_ad_7"), - PINCTRL_PIN(38, "df_ad_6"), - PINCTRL_PIN(39, "df_ad_5"), - PINCTRL_PIN(40, "df_ad_4"), - PINCTRL_PIN(41, "df_ad_3"), - PINCTRL_PIN(42, "df_ad_2"), - PINCTRL_PIN(43, "df_ad_1"), - PINCTRL_PIN(44, "df_ad_0"), - PINCTRL_PIN(45, "df_dqs"), - PINCTRL_PIN(46, "df_cle"), - PINCTRL_PIN(47, "df_ale"), - PINCTRL_PIN(48, "df_we_b"), - PINCTRL_PIN(49, "df_re_b"), - PINCTRL_PIN(50, "df_ry_by"), - PINCTRL_PIN(51, "df_cs_b_1"), - PINCTRL_PIN(52, "df_cs_b_0"), - PINCTRL_PIN(53, "l_pclk"), - PINCTRL_PIN(54, "l_lck"), - PINCTRL_PIN(55, "l_fck"), - PINCTRL_PIN(56, "l_de"), - PINCTRL_PIN(57, "ldd_0"), - PINCTRL_PIN(58, "ldd_1"), - PINCTRL_PIN(59, "ldd_2"), - PINCTRL_PIN(60, "ldd_3"), - PINCTRL_PIN(61, "ldd_4"), - PINCTRL_PIN(62, "ldd_5"), - PINCTRL_PIN(63, "ldd_6"), - PINCTRL_PIN(64, "ldd_7"), - PINCTRL_PIN(65, "ldd_8"), - PINCTRL_PIN(66, "ldd_9"), - PINCTRL_PIN(67, "ldd_10"), - PINCTRL_PIN(68, "ldd_11"), - PINCTRL_PIN(69, "ldd_12"), - PINCTRL_PIN(70, "ldd_13"), - PINCTRL_PIN(71, "ldd_14"), - PINCTRL_PIN(72, "ldd_15"), - PINCTRL_PIN(73, "lcd_gpio_20"), - PINCTRL_PIN(74, "vip_0"), - PINCTRL_PIN(75, "vip_1"), - PINCTRL_PIN(76, "vip_2"), - PINCTRL_PIN(77, "vip_3"), - PINCTRL_PIN(78, "vip_4"), - PINCTRL_PIN(79, "vip_5"), - PINCTRL_PIN(80, "vip_6"), - PINCTRL_PIN(81, "vip_7"), - PINCTRL_PIN(82, "vip_pxclk"), - PINCTRL_PIN(83, "vip_hsync"), - PINCTRL_PIN(84, "vip_vsync"), - PINCTRL_PIN(85, "sdio3_clk"), - PINCTRL_PIN(86, "sdio3_cmd"), - PINCTRL_PIN(87, "sdio3_dat_0"), - PINCTRL_PIN(88, "sdio3_dat_1"), - PINCTRL_PIN(89, "sdio3_dat_2"), - PINCTRL_PIN(90, "sdio3_dat_3"), - PINCTRL_PIN(91, "sdio5_clk"), - PINCTRL_PIN(92, "sdio5_cmd"), - PINCTRL_PIN(93, "sdio5_dat_0"), - PINCTRL_PIN(94, "sdio5_dat_1"), - PINCTRL_PIN(95, "sdio5_dat_2"), - PINCTRL_PIN(96, "sdio5_dat_3"), - PINCTRL_PIN(97, "rgmii_txd_0"), - PINCTRL_PIN(98, "rgmii_txd_1"), - PINCTRL_PIN(99, "rgmii_txd_2"), - PINCTRL_PIN(100, "rgmii_txd_3"), - PINCTRL_PIN(101, "rgmii_txclk"), - PINCTRL_PIN(102, "rgmii_tx_ctl"), - PINCTRL_PIN(103, "rgmii_rxd_0"), - PINCTRL_PIN(104, "rgmii_rxd_1"), - PINCTRL_PIN(105, "rgmii_rxd_2"), - PINCTRL_PIN(106, "rgmii_rxd_3"), - PINCTRL_PIN(107, "rgmii_rx_clk"), - PINCTRL_PIN(108, "rgmii_rxc_ctl"), - PINCTRL_PIN(109, "rgmii_mdio"), - PINCTRL_PIN(110, "rgmii_mdc"), - PINCTRL_PIN(111, "rgmii_intr_n"), - PINCTRL_PIN(112, "i2s_mclk"), - PINCTRL_PIN(113, "i2s_bclk"), - PINCTRL_PIN(114, "i2s_ws"), - PINCTRL_PIN(115, "i2s_dout0"), - PINCTRL_PIN(116, "i2s_dout1"), - PINCTRL_PIN(117, "i2s_dout2"), - PINCTRL_PIN(118, "i2s_din"), - PINCTRL_PIN(119, "gpio_0"), - PINCTRL_PIN(120, "gpio_1"), - PINCTRL_PIN(121, "gpio_2"), - PINCTRL_PIN(122, "gpio_3"), - PINCTRL_PIN(123, "gpio_4"), - PINCTRL_PIN(124, "gpio_5"), - PINCTRL_PIN(125, "gpio_6"), - PINCTRL_PIN(126, "gpio_7"), - PINCTRL_PIN(127, "sda_0"), - PINCTRL_PIN(128, "scl_0"), - PINCTRL_PIN(129, "coex_pio_0"), - PINCTRL_PIN(130, "coex_pio_1"), - PINCTRL_PIN(131, "coex_pio_2"), - PINCTRL_PIN(132, "coex_pio_3"), - PINCTRL_PIN(133, "uart0_tx"), - PINCTRL_PIN(134, "uart0_rx"), - PINCTRL_PIN(135, "uart1_tx"), - PINCTRL_PIN(136, "uart1_rx"), - PINCTRL_PIN(137, "uart3_tx"), - PINCTRL_PIN(138, "uart3_rx"), - PINCTRL_PIN(139, "uart4_tx"), - PINCTRL_PIN(140, "uart4_rx"), - PINCTRL_PIN(141, "usp0_clk"), - PINCTRL_PIN(142, "usp0_tx"), - PINCTRL_PIN(143, "usp0_rx"), - PINCTRL_PIN(144, "usp0_fs"), - PINCTRL_PIN(145, "usp1_clk"), - PINCTRL_PIN(146, "usp1_tx"), - PINCTRL_PIN(147, "usp1_rx"), - PINCTRL_PIN(148, "usp1_fs"), - PINCTRL_PIN(149, "lvds_tx0d4p"), - PINCTRL_PIN(150, "lvds_tx0d4n"), - PINCTRL_PIN(151, "lvds_tx0d3p"), - PINCTRL_PIN(152, "lvds_tx0d3n"), - PINCTRL_PIN(153, "lvds_tx0d2p"), - PINCTRL_PIN(154, "lvds_tx0d2n"), - PINCTRL_PIN(155, "lvds_tx0d1p"), - PINCTRL_PIN(156, "lvds_tx0d1n"), - PINCTRL_PIN(157, "lvds_tx0d0p"), - PINCTRL_PIN(158, "lvds_tx0d0n"), - PINCTRL_PIN(159, "jtag_tdo"), - PINCTRL_PIN(160, "jtag_tms"), - PINCTRL_PIN(161, "jtag_tck"), - PINCTRL_PIN(162, "jtag_tdi"), - PINCTRL_PIN(163, "jtag_trstn"), -}; - -static struct atlas7_pad_config atlas7_ioc_pad_confs[] = { - /* The Configuration of IOC_RTC Pads */ - PADCONF(0, 3, 0x0, 0x100, 0x200, -1, 0, 0, 0, 0), - PADCONF(1, 3, 0x0, 0x100, 0x200, -1, 4, 2, 2, 0), - PADCONF(2, 3, 0x0, 0x100, 0x200, -1, 8, 4, 4, 0), - PADCONF(3, 5, 0x0, 0x100, 0x200, -1, 12, 6, 6, 0), - PADCONF(4, 4, 0x0, 0x100, 0x200, -1, 16, 8, 8, 0), - PADCONF(5, 4, 0x0, 0x100, 0x200, -1, 20, 10, 10, 0), - PADCONF(6, 3, 0x0, 0x100, 0x200, -1, 24, 12, 12, 0), - PADCONF(7, 3, 0x0, 0x100, 0x200, -1, 28, 14, 14, 0), - PADCONF(8, 3, 0x8, 0x100, 0x200, -1, 0, 16, 16, 0), - PADCONF(9, 3, 0x8, 0x100, 0x200, -1, 4, 18, 18, 0), - PADCONF(10, 4, 0x8, 0x100, 0x200, -1, 8, 20, 20, 0), - PADCONF(11, 4, 0x8, 0x100, 0x200, -1, 12, 22, 22, 0), - PADCONF(12, 5, 0x8, 0x100, 0x200, -1, 16, 24, 24, 0), - PADCONF(13, 6, 0x8, 0x100, 0x200, -1, 20, 26, 26, 0), - PADCONF(14, 5, 0x8, 0x100, 0x200, -1, 24, 28, 28, 0), - PADCONF(15, 5, 0x8, 0x100, 0x200, -1, 28, 30, 30, 0), - PADCONF(16, 5, 0x10, 0x108, 0x208, -1, 0, 0, 0, 0), - PADCONF(17, 5, 0x10, 0x108, 0x208, -1, 4, 2, 2, 0), - /* The Configuration of IOC_TOP Pads */ - PADCONF(18, 5, 0x80, 0x180, 0x300, -1, 0, 0, 0, 0), - PADCONF(19, 5, 0x80, 0x180, 0x300, -1, 4, 2, 2, 0), - PADCONF(20, 5, 0x80, 0x180, 0x300, -1, 8, 4, 4, 0), - PADCONF(21, 5, 0x80, 0x180, 0x300, -1, 12, 6, 6, 0), - PADCONF(22, 5, 0x88, 0x188, 0x308, -1, 0, 0, 0, 0), - PADCONF(23, 5, 0x88, 0x188, 0x308, -1, 4, 2, 2, 0), - PADCONF(24, 5, 0x88, 0x188, 0x308, -1, 8, 4, 4, 0), - PADCONF(25, 6, 0x88, 0x188, 0x308, -1, 12, 6, 6, 0), - PADCONF(26, 5, 0x88, 0x188, 0x308, -1, 16, 8, 8, 0), - PADCONF(27, 6, 0x88, 0x188, 0x308, -1, 20, 10, 10, 0), - PADCONF(28, 5, 0x88, 0x188, 0x308, -1, 24, 12, 12, 0), - PADCONF(29, 5, 0x88, 0x188, 0x308, -1, 28, 14, 14, 0), - PADCONF(30, 5, 0x90, 0x188, 0x308, -1, 0, 16, 16, 0), - PADCONF(31, 2, 0x98, 0x190, 0x310, -1, 0, 0, 0, 0), - PADCONF(32, 1, 0x98, 0x190, 0x310, -1, 4, 2, 4, 0), - PADCONF(33, 1, 0x98, 0x190, 0x310, -1, 8, 4, 6, 0), - PADCONF(34, 1, 0x98, 0x190, 0x310, -1, 12, 6, 8, 0), - PADCONF(35, 1, 0x98, 0x190, 0x310, -1, 16, 8, 10, 0), - PADCONF(36, 1, 0x98, 0x190, 0x310, -1, 20, 10, 12, 0), - PADCONF(37, 1, 0xa0, 0x198, 0x318, -1, 0, 0, 0, 0), - PADCONF(38, 1, 0xa0, 0x198, 0x318, -1, 4, 2, 2, 0), - PADCONF(39, 1, 0xa0, 0x198, 0x318, -1, 8, 4, 4, 0), - PADCONF(40, 1, 0xa0, 0x198, 0x318, -1, 12, 6, 6, 0), - PADCONF(41, 1, 0xa0, 0x198, 0x318, -1, 16, 8, 8, 0), - PADCONF(42, 1, 0xa0, 0x198, 0x318, -1, 20, 10, 10, 0), - PADCONF(43, 1, 0xa0, 0x198, 0x318, -1, 24, 12, 12, 0), - PADCONF(44, 1, 0xa0, 0x198, 0x318, -1, 28, 14, 14, 0), - PADCONF(45, 0, 0xa8, 0x198, 0x318, -1, 0, 16, 16, 0), - PADCONF(46, 0, 0xa8, 0x198, 0x318, -1, 4, 18, 18, 0), - PADCONF(47, 1, 0xa8, 0x198, 0x318, -1, 8, 20, 20, 0), - PADCONF(48, 1, 0xa8, 0x198, 0x318, -1, 12, 22, 22, 0), - PADCONF(49, 1, 0xa8, 0x198, 0x318, -1, 16, 24, 24, 0), - PADCONF(50, 1, 0xa8, 0x198, 0x318, -1, 20, 26, 26, 0), - PADCONF(51, 1, 0xa8, 0x198, 0x318, -1, 24, 28, 28, 0), - PADCONF(52, 1, 0xa8, 0x198, 0x318, -1, 28, 30, 30, 0), - PADCONF(53, 0, 0xb0, 0x1a0, 0x320, -1, 0, 0, 0, 0), - PADCONF(54, 0, 0xb0, 0x1a0, 0x320, -1, 4, 2, 2, 0), - PADCONF(55, 0, 0xb0, 0x1a0, 0x320, -1, 8, 4, 4, 0), - PADCONF(56, 0, 0xb0, 0x1a0, 0x320, -1, 12, 6, 6, 0), - PADCONF(57, 0, 0xb0, 0x1a0, 0x320, -1, 16, 8, 8, 0), - PADCONF(58, 0, 0xb0, 0x1a0, 0x320, -1, 20, 10, 10, 0), - PADCONF(59, 0, 0xb0, 0x1a0, 0x320, -1, 24, 12, 12, 0), - PADCONF(60, 0, 0xb0, 0x1a0, 0x320, -1, 28, 14, 14, 0), - PADCONF(61, 0, 0xb8, 0x1a0, 0x320, -1, 0, 16, 16, 0), - PADCONF(62, 0, 0xb8, 0x1a0, 0x320, -1, 4, 18, 18, 0), - PADCONF(63, 0, 0xb8, 0x1a0, 0x320, -1, 8, 20, 20, 0), - PADCONF(64, 0, 0xb8, 0x1a0, 0x320, -1, 12, 22, 22, 0), - PADCONF(65, 0, 0xb8, 0x1a0, 0x320, -1, 16, 24, 24, 0), - PADCONF(66, 0, 0xb8, 0x1a0, 0x320, -1, 20, 26, 26, 0), - PADCONF(67, 0, 0xb8, 0x1a0, 0x320, -1, 24, 28, 28, 0), - PADCONF(68, 0, 0xb8, 0x1a0, 0x320, -1, 28, 30, 30, 0), - PADCONF(69, 0, 0xc0, 0x1a8, 0x328, -1, 0, 0, 0, 0), - PADCONF(70, 0, 0xc0, 0x1a8, 0x328, -1, 4, 2, 2, 0), - PADCONF(71, 0, 0xc0, 0x1a8, 0x328, -1, 8, 4, 4, 0), - PADCONF(72, 0, 0xc0, 0x1a8, 0x328, -1, 12, 6, 6, 0), - PADCONF(73, 0, 0xc0, 0x1a8, 0x328, -1, 16, 8, 8, 0), - PADCONF(74, 0, 0xc8, 0x1b0, 0x330, -1, 0, 0, 0, 0), - PADCONF(75, 0, 0xc8, 0x1b0, 0x330, -1, 4, 2, 2, 0), - PADCONF(76, 0, 0xc8, 0x1b0, 0x330, -1, 8, 4, 4, 0), - PADCONF(77, 0, 0xc8, 0x1b0, 0x330, -1, 12, 6, 6, 0), - PADCONF(78, 0, 0xc8, 0x1b0, 0x330, -1, 16, 8, 8, 0), - PADCONF(79, 0, 0xc8, 0x1b0, 0x330, -1, 20, 10, 10, 0), - PADCONF(80, 0, 0xc8, 0x1b0, 0x330, -1, 24, 12, 12, 0), - PADCONF(81, 0, 0xc8, 0x1b0, 0x330, -1, 28, 14, 14, 0), - PADCONF(82, 0, 0xd0, 0x1b0, 0x330, -1, 0, 16, 16, 0), - PADCONF(83, 0, 0xd0, 0x1b0, 0x330, -1, 4, 18, 18, 0), - PADCONF(84, 0, 0xd0, 0x1b0, 0x330, -1, 8, 20, 20, 0), - PADCONF(85, 2, 0xd8, 0x1b8, 0x338, -1, 0, 0, 0, 0), - PADCONF(86, 1, 0xd8, 0x1b8, 0x338, -1, 4, 4, 4, 0), - PADCONF(87, 1, 0xd8, 0x1b8, 0x338, -1, 8, 6, 6, 0), - PADCONF(88, 1, 0xd8, 0x1b8, 0x338, -1, 12, 8, 8, 0), - PADCONF(89, 1, 0xd8, 0x1b8, 0x338, -1, 16, 10, 10, 0), - PADCONF(90, 1, 0xd8, 0x1b8, 0x338, -1, 20, 12, 12, 0), - PADCONF(91, 2, 0xe0, 0x1c0, 0x340, -1, 0, 0, 0, 0), - PADCONF(92, 1, 0xe0, 0x1c0, 0x340, -1, 4, 4, 4, 0), - PADCONF(93, 1, 0xe0, 0x1c0, 0x340, -1, 8, 6, 6, 0), - PADCONF(94, 1, 0xe0, 0x1c0, 0x340, -1, 12, 8, 8, 0), - PADCONF(95, 1, 0xe0, 0x1c0, 0x340, -1, 16, 10, 10, 0), - PADCONF(96, 1, 0xe0, 0x1c0, 0x340, -1, 20, 12, 12, 0), - PADCONF(97, 0, 0xe8, 0x1c8, 0x348, -1, 0, 0, 0, 0), - PADCONF(98, 0, 0xe8, 0x1c8, 0x348, -1, 4, 2, 2, 0), - PADCONF(99, 0, 0xe8, 0x1c8, 0x348, -1, 8, 4, 4, 0), - PADCONF(100, 0, 0xe8, 0x1c8, 0x348, -1, 12, 6, 6, 0), - PADCONF(101, 2, 0xe8, 0x1c8, 0x348, -1, 16, 8, 8, 0), - PADCONF(102, 0, 0xe8, 0x1c8, 0x348, -1, 20, 12, 12, 0), - PADCONF(103, 0, 0xe8, 0x1c8, 0x348, -1, 24, 14, 14, 0), - PADCONF(104, 0, 0xe8, 0x1c8, 0x348, -1, 28, 16, 16, 0), - PADCONF(105, 0, 0xf0, 0x1c8, 0x348, -1, 0, 18, 18, 0), - PADCONF(106, 0, 0xf0, 0x1c8, 0x348, -1, 4, 20, 20, 0), - PADCONF(107, 0, 0xf0, 0x1c8, 0x348, -1, 8, 22, 22, 0), - PADCONF(108, 0, 0xf0, 0x1c8, 0x348, -1, 12, 24, 24, 0), - PADCONF(109, 1, 0xf0, 0x1c8, 0x348, -1, 16, 26, 26, 0), - PADCONF(110, 0, 0xf0, 0x1c8, 0x348, -1, 20, 28, 28, 0), - PADCONF(111, 1, 0xf0, 0x1c8, 0x348, -1, 24, 30, 30, 0), - PADCONF(112, 5, 0xf8, 0x200, 0x350, -1, 0, 0, 0, 0), - PADCONF(113, 5, 0xf8, 0x200, 0x350, -1, 4, 2, 2, 0), - PADCONF(114, 5, 0xf8, 0x200, 0x350, -1, 8, 4, 4, 0), - PADCONF(115, 5, 0xf8, 0x200, 0x350, -1, 12, 6, 6, 0), - PADCONF(116, 5, 0xf8, 0x200, 0x350, -1, 16, 8, 8, 0), - PADCONF(117, 5, 0xf8, 0x200, 0x350, -1, 20, 10, 10, 0), - PADCONF(118, 5, 0xf8, 0x200, 0x350, -1, 24, 12, 12, 0), - PADCONF(119, 5, 0x100, 0x250, 0x358, -1, 0, 0, 0, 0), - PADCONF(120, 5, 0x100, 0x250, 0x358, -1, 4, 2, 2, 0), - PADCONF(121, 5, 0x100, 0x250, 0x358, -1, 8, 4, 4, 0), - PADCONF(122, 5, 0x100, 0x250, 0x358, -1, 12, 6, 6, 0), - PADCONF(123, 6, 0x100, 0x250, 0x358, -1, 16, 8, 8, 0), - PADCONF(124, 6, 0x100, 0x250, 0x358, -1, 20, 10, 10, 0), - PADCONF(125, 6, 0x100, 0x250, 0x358, -1, 24, 12, 12, 0), - PADCONF(126, 6, 0x100, 0x250, 0x358, -1, 28, 14, 14, 0), - PADCONF(127, 6, 0x108, 0x250, 0x358, -1, 16, 24, 24, 0), - PADCONF(128, 6, 0x108, 0x250, 0x358, -1, 20, 26, 26, 0), - PADCONF(129, 0, 0x110, 0x258, 0x360, -1, 0, 0, 0, 0), - PADCONF(130, 0, 0x110, 0x258, 0x360, -1, 4, 2, 2, 0), - PADCONF(131, 0, 0x110, 0x258, 0x360, -1, 8, 4, 4, 0), - PADCONF(132, 0, 0x110, 0x258, 0x360, -1, 12, 6, 6, 0), - PADCONF(133, 6, 0x118, 0x260, 0x368, -1, 0, 0, 0, 0), - PADCONF(134, 6, 0x118, 0x260, 0x368, -1, 4, 2, 2, 0), - PADCONF(135, 6, 0x118, 0x260, 0x368, -1, 16, 8, 8, 0), - PADCONF(136, 6, 0x118, 0x260, 0x368, -1, 20, 10, 10, 0), - PADCONF(137, 6, 0x118, 0x260, 0x368, -1, 24, 12, 12, 0), - PADCONF(138, 6, 0x118, 0x260, 0x368, -1, 28, 14, 14, 0), - PADCONF(139, 6, 0x120, 0x260, 0x368, -1, 0, 16, 16, 0), - PADCONF(140, 6, 0x120, 0x260, 0x368, -1, 4, 18, 18, 0), - PADCONF(141, 5, 0x128, 0x268, 0x378, -1, 0, 0, 0, 0), - PADCONF(142, 5, 0x128, 0x268, 0x378, -1, 4, 2, 2, 0), - PADCONF(143, 5, 0x128, 0x268, 0x378, -1, 8, 4, 4, 0), - PADCONF(144, 5, 0x128, 0x268, 0x378, -1, 12, 6, 6, 0), - PADCONF(145, 5, 0x128, 0x268, 0x378, -1, 16, 8, 8, 0), - PADCONF(146, 5, 0x128, 0x268, 0x378, -1, 20, 10, 10, 0), - PADCONF(147, 5, 0x128, 0x268, 0x378, -1, 24, 12, 12, 0), - PADCONF(148, 5, 0x128, 0x268, 0x378, -1, 28, 14, 14, 0), - PADCONF(149, 7, 0x130, 0x270, -1, 0x480, 0, 0, 0, 0), - PADCONF(150, 7, 0x130, 0x270, -1, 0x480, 4, 2, 0, 1), - PADCONF(151, 7, 0x130, 0x270, -1, 0x480, 8, 4, 0, 2), - PADCONF(152, 7, 0x130, 0x270, -1, 0x480, 12, 6, 0, 3), - PADCONF(153, 7, 0x130, 0x270, -1, 0x480, 16, 8, 0, 4), - PADCONF(154, 7, 0x130, 0x270, -1, 0x480, 20, 10, 0, 5), - PADCONF(155, 7, 0x130, 0x270, -1, 0x480, 24, 12, 0, 6), - PADCONF(156, 7, 0x130, 0x270, -1, 0x480, 28, 14, 0, 7), - PADCONF(157, 7, 0x138, 0x278, -1, 0x480, 0, 0, 0, 8), - PADCONF(158, 7, 0x138, 0x278, -1, 0x480, 4, 2, 0, 9), - PADCONF(159, 5, 0x140, 0x280, 0x380, -1, 0, 0, 0, 0), - PADCONF(160, 6, 0x140, 0x280, 0x380, -1, 4, 2, 2, 0), - PADCONF(161, 5, 0x140, 0x280, 0x380, -1, 8, 4, 4, 0), - PADCONF(162, 6, 0x140, 0x280, 0x380, -1, 12, 6, 6, 0), - PADCONF(163, 6, 0x140, 0x280, 0x380, -1, 16, 8, 8, 0), -}; - -/* pin list of each pin group */ -static const unsigned int gnss_gpio_pins[] = { 119, 120, 121, 122, 123, 124, - 125, 126, 127, 128, 22, 23, 24, 25, 26, 27, 28, 29, 30, }; -static const unsigned int lcd_vip_gpio_pins[] = { 74, 75, 76, 77, 78, 79, 80, - 81, 82, 83, 84, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, - 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, }; -static const unsigned int sdio_i2s_gpio_pins[] = { 31, 32, 33, 34, 35, 36, - 85, 86, 87, 88, 89, 90, 129, 130, 131, 132, 91, 92, 93, 94, - 95, 96, 112, 113, 114, 115, 116, 117, 118, }; -static const unsigned int sp_rgmii_gpio_pins[] = { 97, 98, 99, 100, 101, 102, - 103, 104, 105, 106, 107, 108, 109, 110, 111, 18, 19, 20, 21, - 141, 142, 143, 144, 145, 146, 147, 148, }; -static const unsigned int lvds_gpio_pins[] = { 157, 158, 155, 156, 153, 154, - 151, 152, 149, 150, }; -static const unsigned int jtag_uart_nand_gpio_pins[] = { 44, 43, 42, 41, 40, - 39, 38, 37, 46, 47, 48, 49, 50, 52, 51, 45, 133, 134, 135, - 136, 137, 138, 139, 140, 159, 160, 161, 162, 163, }; -static const unsigned int rtc_gpio_pins[] = { 0, 1, 2, 3, 4, 10, 11, 12, 13, - 14, 15, 16, 17, 9, }; -static const unsigned int audio_ac97_pins[] = { 113, 118, 115, 114, }; -static const unsigned int audio_digmic_pins0[] = { 51, }; -static const unsigned int audio_digmic_pins1[] = { 122, }; -static const unsigned int audio_digmic_pins2[] = { 161, }; -static const unsigned int audio_func_dbg_pins[] = { 141, 144, 44, 43, 42, 41, - 40, 39, 38, 37, 74, 75, 76, 77, 78, 79, 81, 113, 114, 118, - 115, 49, 50, 142, 143, 80, }; -static const unsigned int audio_i2s_pins[] = { 118, 115, 116, 117, 112, 113, - 114, }; -static const unsigned int audio_i2s_2ch_pins[] = { 118, 115, 112, 113, 114, }; -static const unsigned int audio_i2s_extclk_pins[] = { 112, }; -static const unsigned int audio_spdif_out_pins0[] = { 112, }; -static const unsigned int audio_spdif_out_pins1[] = { 116, }; -static const unsigned int audio_spdif_out_pins2[] = { 142, }; -static const unsigned int audio_uart0_basic_pins[] = { 143, 142, 141, 144, }; -static const unsigned int audio_uart0_urfs_pins0[] = { 117, }; -static const unsigned int audio_uart0_urfs_pins1[] = { 139, }; -static const unsigned int audio_uart0_urfs_pins2[] = { 163, }; -static const unsigned int audio_uart0_urfs_pins3[] = { 162, }; -static const unsigned int audio_uart1_basic_pins[] = { 147, 146, 145, 148, }; -static const unsigned int audio_uart1_urfs_pins0[] = { 117, }; -static const unsigned int audio_uart1_urfs_pins1[] = { 140, }; -static const unsigned int audio_uart1_urfs_pins2[] = { 163, }; -static const unsigned int audio_uart2_urfs_pins0[] = { 139, }; -static const unsigned int audio_uart2_urfs_pins1[] = { 163, }; -static const unsigned int audio_uart2_urfs_pins2[] = { 96, }; -static const unsigned int audio_uart2_urxd_pins0[] = { 20, }; -static const unsigned int audio_uart2_urxd_pins1[] = { 109, }; -static const unsigned int audio_uart2_urxd_pins2[] = { 93, }; -static const unsigned int audio_uart2_usclk_pins0[] = { 19, }; -static const unsigned int audio_uart2_usclk_pins1[] = { 101, }; -static const unsigned int audio_uart2_usclk_pins2[] = { 91, }; -static const unsigned int audio_uart2_utfs_pins0[] = { 18, }; -static const unsigned int audio_uart2_utfs_pins1[] = { 111, }; -static const unsigned int audio_uart2_utfs_pins2[] = { 94, }; -static const unsigned int audio_uart2_utxd_pins0[] = { 21, }; -static const unsigned int audio_uart2_utxd_pins1[] = { 110, }; -static const unsigned int audio_uart2_utxd_pins2[] = { 92, }; -static const unsigned int c_can_trnsvr_en_pins0[] = { 2, }; -static const unsigned int c_can_trnsvr_en_pins1[] = { 0, }; -static const unsigned int c_can_trnsvr_intr_pins[] = { 1, }; -static const unsigned int c_can_trnsvr_stb_n_pins[] = { 3, }; -static const unsigned int c0_can_rxd_trnsv0_pins[] = { 11, }; -static const unsigned int c0_can_rxd_trnsv1_pins[] = { 2, }; -static const unsigned int c0_can_txd_trnsv0_pins[] = { 10, }; -static const unsigned int c0_can_txd_trnsv1_pins[] = { 3, }; -static const unsigned int c1_can_rxd_pins0[] = { 138, }; -static const unsigned int c1_can_rxd_pins1[] = { 147, }; -static const unsigned int c1_can_rxd_pins2[] = { 2, }; -static const unsigned int c1_can_rxd_pins3[] = { 162, }; -static const unsigned int c1_can_txd_pins0[] = { 137, }; -static const unsigned int c1_can_txd_pins1[] = { 146, }; -static const unsigned int c1_can_txd_pins2[] = { 3, }; -static const unsigned int c1_can_txd_pins3[] = { 161, }; -static const unsigned int ca_audio_lpc_pins[] = { 62, 63, 64, 65, 66, 67, 68, - 69, 70, 71, }; -static const unsigned int ca_bt_lpc_pins[] = { 85, 86, 87, 88, 89, 90, }; -static const unsigned int ca_coex_pins[] = { 129, 130, 131, 132, }; -static const unsigned int ca_curator_lpc_pins[] = { 57, 58, 59, 60, }; -static const unsigned int ca_pcm_debug_pins[] = { 91, 93, 94, 92, }; -static const unsigned int ca_pio_pins[] = { 121, 122, 125, 126, 38, 37, 47, - 49, 50, 54, 55, 56, }; -static const unsigned int ca_sdio_debug_pins[] = { 40, 39, 44, 43, 42, 41, }; -static const unsigned int ca_spi_pins[] = { 82, 79, 80, 81, }; -static const unsigned int ca_trb_pins[] = { 91, 93, 94, 95, 96, 78, 74, 75, - 76, 77, }; -static const unsigned int ca_uart_debug_pins[] = { 136, 135, 134, 133, }; -static const unsigned int clkc_pins0[] = { 30, 47, }; -static const unsigned int clkc_pins1[] = { 78, 54, }; -static const unsigned int gn_gnss_i2c_pins[] = { 128, 127, }; -static const unsigned int gn_gnss_uart_nopause_pins[] = { 134, 133, }; -static const unsigned int gn_gnss_uart_pins[] = { 134, 133, 136, 135, }; -static const unsigned int gn_trg_spi_pins0[] = { 22, 25, 23, 24, }; -static const unsigned int gn_trg_spi_pins1[] = { 82, 79, 80, 81, }; -static const unsigned int cvbs_dbg_pins[] = { 54, 53, 82, 74, 75, 76, 77, 78, - 79, 80, 81, 83, 84, 73, 55, 56, }; -static const unsigned int cvbs_dbg_test_pins0[] = { 57, }; -static const unsigned int cvbs_dbg_test_pins1[] = { 58, }; -static const unsigned int cvbs_dbg_test_pins2[] = { 59, }; -static const unsigned int cvbs_dbg_test_pins3[] = { 60, }; -static const unsigned int cvbs_dbg_test_pins4[] = { 61, }; -static const unsigned int cvbs_dbg_test_pins5[] = { 62, }; -static const unsigned int cvbs_dbg_test_pins6[] = { 63, }; -static const unsigned int cvbs_dbg_test_pins7[] = { 64, }; -static const unsigned int cvbs_dbg_test_pins8[] = { 65, }; -static const unsigned int cvbs_dbg_test_pins9[] = { 66, }; -static const unsigned int cvbs_dbg_test_pins10[] = { 67, }; -static const unsigned int cvbs_dbg_test_pins11[] = { 68, }; -static const unsigned int cvbs_dbg_test_pins12[] = { 69, }; -static const unsigned int cvbs_dbg_test_pins13[] = { 70, }; -static const unsigned int cvbs_dbg_test_pins14[] = { 71, }; -static const unsigned int cvbs_dbg_test_pins15[] = { 72, }; -static const unsigned int gn_gnss_power_pins[] = { 123, 124, 121, 122, 125, - 120, }; -static const unsigned int gn_gnss_sw_status_pins[] = { 57, 58, 59, 60, 61, - 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 53, 55, 56, 54, }; -static const unsigned int gn_gnss_eclk_pins[] = { 113, }; -static const unsigned int gn_gnss_irq1_pins0[] = { 112, }; -static const unsigned int gn_gnss_irq2_pins0[] = { 118, }; -static const unsigned int gn_gnss_tm_pins[] = { 115, }; -static const unsigned int gn_gnss_tsync_pins[] = { 114, }; -static const unsigned int gn_io_gnsssys_sw_cfg_pins[] = { 44, 43, 42, 41, 40, - 39, 38, 37, 49, 50, 91, 92, 93, 94, 95, 96, }; -static const unsigned int gn_trg_pins0[] = { 29, 28, 26, 27, }; -static const unsigned int gn_trg_pins1[] = { 77, 76, 74, 75, }; -static const unsigned int gn_trg_shutdown_pins0[] = { 30, }; -static const unsigned int gn_trg_shutdown_pins1[] = { 83, }; -static const unsigned int gn_trg_shutdown_pins2[] = { 117, }; -static const unsigned int gn_trg_shutdown_pins3[] = { 123, }; -static const unsigned int i2c0_pins[] = { 128, 127, }; -static const unsigned int i2c1_pins[] = { 126, 125, }; -static const unsigned int i2s0_pins[] = { 91, 93, 94, 92, }; -static const unsigned int i2s1_basic_pins[] = { 95, 96, }; -static const unsigned int i2s1_rxd0_pins0[] = { 61, }; -static const unsigned int i2s1_rxd0_pins1[] = { 131, }; -static const unsigned int i2s1_rxd0_pins2[] = { 129, }; -static const unsigned int i2s1_rxd0_pins3[] = { 117, }; -static const unsigned int i2s1_rxd0_pins4[] = { 83, }; -static const unsigned int i2s1_rxd1_pins0[] = { 72, }; -static const unsigned int i2s1_rxd1_pins1[] = { 132, }; -static const unsigned int i2s1_rxd1_pins2[] = { 130, }; -static const unsigned int i2s1_rxd1_pins3[] = { 118, }; -static const unsigned int i2s1_rxd1_pins4[] = { 84, }; -static const unsigned int jtag_jt_dbg_nsrst_pins[] = { 125, }; -static const unsigned int jtag_ntrst_pins0[] = { 4, }; -static const unsigned int jtag_ntrst_pins1[] = { 163, }; -static const unsigned int jtag_swdiotms_pins0[] = { 2, }; -static const unsigned int jtag_swdiotms_pins1[] = { 160, }; -static const unsigned int jtag_tck_pins0[] = { 0, }; -static const unsigned int jtag_tck_pins1[] = { 161, }; -static const unsigned int jtag_tdi_pins0[] = { 1, }; -static const unsigned int jtag_tdi_pins1[] = { 162, }; -static const unsigned int jtag_tdo_pins0[] = { 3, }; -static const unsigned int jtag_tdo_pins1[] = { 159, }; -static const unsigned int ks_kas_spi_pins0[] = { 141, 144, 143, 142, }; -static const unsigned int ld_ldd_pins[] = { 57, 58, 59, 60, 61, 62, 63, 64, - 65, 66, 67, 68, 69, 70, 71, 72, 74, 75, 76, 77, 78, 79, 80, - 81, 56, 53, }; -static const unsigned int ld_ldd_16bit_pins[] = { 57, 58, 59, 60, 61, 62, 63, - 64, 65, 66, 67, 68, 69, 70, 71, 72, 56, 53, }; -static const unsigned int ld_ldd_fck_pins[] = { 55, }; -static const unsigned int ld_ldd_lck_pins[] = { 54, }; -static const unsigned int lr_lcdrom_pins[] = { 73, 54, 57, 58, 59, 60, 61, - 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 56, 53, 55, }; -static const unsigned int lvds_analog_pins[] = { 149, 150, 151, 152, 153, 154, - 155, 156, 157, 158, }; -static const unsigned int nd_df_basic_pins[] = { 44, 43, 42, 41, 40, 39, 38, - 37, 47, 46, 52, 45, 49, 50, 48, }; -static const unsigned int nd_df_wp_pins[] = { 124, }; -static const unsigned int nd_df_cs_pins[] = { 51, }; -static const unsigned int ps_pins[] = { 120, 119, 121, }; -static const unsigned int ps_no_dir_pins[] = { 119, }; -static const unsigned int pwc_core_on_pins[] = { 8, }; -static const unsigned int pwc_ext_on_pins[] = { 6, }; -static const unsigned int pwc_gpio3_clk_pins[] = { 3, }; -static const unsigned int pwc_io_on_pins[] = { 9, }; -static const unsigned int pwc_lowbatt_b_pins0[] = { 4, }; -static const unsigned int pwc_mem_on_pins[] = { 7, }; -static const unsigned int pwc_on_key_b_pins0[] = { 5, }; -static const unsigned int pwc_wakeup_src0_pins[] = { 0, }; -static const unsigned int pwc_wakeup_src1_pins[] = { 1, }; -static const unsigned int pwc_wakeup_src2_pins[] = { 2, }; -static const unsigned int pwc_wakeup_src3_pins[] = { 3, }; -static const unsigned int pw_cko0_pins0[] = { 123, }; -static const unsigned int pw_cko0_pins1[] = { 101, }; -static const unsigned int pw_cko0_pins2[] = { 82, }; -static const unsigned int pw_cko0_pins3[] = { 162, }; -static const unsigned int pw_cko1_pins0[] = { 124, }; -static const unsigned int pw_cko1_pins1[] = { 110, }; -static const unsigned int pw_cko1_pins2[] = { 163, }; -static const unsigned int pw_i2s01_clk_pins0[] = { 125, }; -static const unsigned int pw_i2s01_clk_pins1[] = { 117, }; -static const unsigned int pw_i2s01_clk_pins2[] = { 132, }; -static const unsigned int pw_pwm0_pins0[] = { 119, }; -static const unsigned int pw_pwm0_pins1[] = { 159, }; -static const unsigned int pw_pwm1_pins0[] = { 120, }; -static const unsigned int pw_pwm1_pins1[] = { 160, }; -static const unsigned int pw_pwm1_pins2[] = { 131, }; -static const unsigned int pw_pwm2_pins0[] = { 121, }; -static const unsigned int pw_pwm2_pins1[] = { 98, }; -static const unsigned int pw_pwm2_pins2[] = { 161, }; -static const unsigned int pw_pwm3_pins0[] = { 122, }; -static const unsigned int pw_pwm3_pins1[] = { 73, }; -static const unsigned int pw_pwm_cpu_vol_pins0[] = { 121, }; -static const unsigned int pw_pwm_cpu_vol_pins1[] = { 98, }; -static const unsigned int pw_pwm_cpu_vol_pins2[] = { 161, }; -static const unsigned int pw_backlight_pins0[] = { 122, }; -static const unsigned int pw_backlight_pins1[] = { 73, }; -static const unsigned int rg_eth_mac_pins[] = { 108, 103, 104, 105, 106, 107, - 102, 97, 98, 99, 100, 101, }; -static const unsigned int rg_gmac_phy_intr_n_pins[] = { 111, }; -static const unsigned int rg_rgmii_mac_pins[] = { 109, 110, }; -static const unsigned int rg_rgmii_phy_ref_clk_pins0[] = { 111, }; -static const unsigned int rg_rgmii_phy_ref_clk_pins1[] = { 53, }; -static const unsigned int sd0_pins[] = { 46, 47, 44, 43, 42, 41, 40, 39, 38, - 37, }; -static const unsigned int sd0_4bit_pins[] = { 46, 47, 44, 43, 42, 41, }; -static const unsigned int sd1_pins[] = { 48, 49, 44, 43, 42, 41, 40, 39, 38, - 37, }; -static const unsigned int sd1_4bit_pins0[] = { 48, 49, 44, 43, 42, 41, }; -static const unsigned int sd1_4bit_pins1[] = { 48, 49, 40, 39, 38, 37, }; -static const unsigned int sd2_basic_pins[] = { 31, 32, 33, 34, 35, 36, }; -static const unsigned int sd2_cdb_pins0[] = { 124, }; -static const unsigned int sd2_cdb_pins1[] = { 161, }; -static const unsigned int sd2_wpb_pins0[] = { 123, }; -static const unsigned int sd2_wpb_pins1[] = { 163, }; -static const unsigned int sd3_9_pins[] = { 85, 86, 87, 88, 89, 90, }; -static const unsigned int sd5_pins[] = { 91, 92, 93, 94, 95, 96, }; -static const unsigned int sd6_pins0[] = { 79, 78, 74, 75, 76, 77, }; -static const unsigned int sd6_pins1[] = { 101, 99, 100, 110, 109, 111, }; -static const unsigned int sp0_ext_ldo_on_pins[] = { 4, }; -static const unsigned int sp0_qspi_pins[] = { 12, 13, 14, 15, 16, 17, }; -static const unsigned int sp1_spi_pins[] = { 19, 20, 21, 18, }; -static const unsigned int tpiu_trace_pins[] = { 53, 56, 57, 58, 59, 60, 61, - 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, }; -static const unsigned int uart0_pins[] = { 121, 120, 134, 133, }; -static const unsigned int uart0_nopause_pins[] = { 134, 133, }; -static const unsigned int uart1_pins[] = { 136, 135, }; -static const unsigned int uart2_cts_pins0[] = { 132, }; -static const unsigned int uart2_cts_pins1[] = { 162, }; -static const unsigned int uart2_rts_pins0[] = { 131, }; -static const unsigned int uart2_rts_pins1[] = { 161, }; -static const unsigned int uart2_rxd_pins0[] = { 11, }; -static const unsigned int uart2_rxd_pins1[] = { 160, }; -static const unsigned int uart2_rxd_pins2[] = { 130, }; -static const unsigned int uart2_txd_pins0[] = { 10, }; -static const unsigned int uart2_txd_pins1[] = { 159, }; -static const unsigned int uart2_txd_pins2[] = { 129, }; -static const unsigned int uart3_cts_pins0[] = { 125, }; -static const unsigned int uart3_cts_pins1[] = { 111, }; -static const unsigned int uart3_cts_pins2[] = { 140, }; -static const unsigned int uart3_rts_pins0[] = { 126, }; -static const unsigned int uart3_rts_pins1[] = { 109, }; -static const unsigned int uart3_rts_pins2[] = { 139, }; -static const unsigned int uart3_rxd_pins0[] = { 138, }; -static const unsigned int uart3_rxd_pins1[] = { 84, }; -static const unsigned int uart3_rxd_pins2[] = { 162, }; -static const unsigned int uart3_txd_pins0[] = { 137, }; -static const unsigned int uart3_txd_pins1[] = { 83, }; -static const unsigned int uart3_txd_pins2[] = { 161, }; -static const unsigned int uart4_basic_pins[] = { 140, 139, }; -static const unsigned int uart4_cts_pins0[] = { 122, }; -static const unsigned int uart4_cts_pins1[] = { 100, }; -static const unsigned int uart4_cts_pins2[] = { 117, }; -static const unsigned int uart4_rts_pins0[] = { 123, }; -static const unsigned int uart4_rts_pins1[] = { 99, }; -static const unsigned int uart4_rts_pins2[] = { 116, }; -static const unsigned int usb0_drvvbus_pins0[] = { 51, }; -static const unsigned int usb0_drvvbus_pins1[] = { 162, }; -static const unsigned int usb1_drvvbus_pins0[] = { 134, }; -static const unsigned int usb1_drvvbus_pins1[] = { 163, }; -static const unsigned int visbus_dout_pins[] = { 57, 58, 59, 60, 61, 62, 63, - 64, 65, 66, 67, 68, 69, 70, 71, 72, 53, 54, 55, 56, 85, 86, - 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, }; -static const unsigned int vi_vip1_pins[] = { 74, 75, 76, 77, 78, 79, 80, 81, - 82, 83, 84, 103, 104, 105, 106, 107, 102, 97, 98, }; -static const unsigned int vi_vip1_ext_pins[] = { 74, 75, 76, 77, 78, 79, 80, - 81, 82, 83, 84, 108, 103, 104, 105, 106, 107, 102, 97, 98, - 99, 100, }; -static const unsigned int vi_vip1_low8bit_pins[] = { 74, 75, 76, 77, 78, 79, - 80, 81, 82, 83, 84, }; -static const unsigned int vi_vip1_high8bit_pins[] = { 82, 83, 84, 103, 104, - 105, 106, 107, 102, 97, 98, }; - -/* definition of pin group table */ -static struct atlas7_pin_group altas7_pin_groups[] = { - GROUP("gnss_gpio_grp", gnss_gpio_pins), - GROUP("lcd_vip_gpio_grp", lcd_vip_gpio_pins), - GROUP("sdio_i2s_gpio_grp", sdio_i2s_gpio_pins), - GROUP("sp_rgmii_gpio_grp", sp_rgmii_gpio_pins), - GROUP("lvds_gpio_grp", lvds_gpio_pins), - GROUP("jtag_uart_nand_gpio_grp", jtag_uart_nand_gpio_pins), - GROUP("rtc_gpio_grp", rtc_gpio_pins), - GROUP("audio_ac97_grp", audio_ac97_pins), - GROUP("audio_digmic_grp0", audio_digmic_pins0), - GROUP("audio_digmic_grp1", audio_digmic_pins1), - GROUP("audio_digmic_grp2", audio_digmic_pins2), - GROUP("audio_func_dbg_grp", audio_func_dbg_pins), - GROUP("audio_i2s_grp", audio_i2s_pins), - GROUP("audio_i2s_2ch_grp", audio_i2s_2ch_pins), - GROUP("audio_i2s_extclk_grp", audio_i2s_extclk_pins), - GROUP("audio_spdif_out_grp0", audio_spdif_out_pins0), - GROUP("audio_spdif_out_grp1", audio_spdif_out_pins1), - GROUP("audio_spdif_out_grp2", audio_spdif_out_pins2), - GROUP("audio_uart0_basic_grp", audio_uart0_basic_pins), - GROUP("audio_uart0_urfs_grp0", audio_uart0_urfs_pins0), - GROUP("audio_uart0_urfs_grp1", audio_uart0_urfs_pins1), - GROUP("audio_uart0_urfs_grp2", audio_uart0_urfs_pins2), - GROUP("audio_uart0_urfs_grp3", audio_uart0_urfs_pins3), - GROUP("audio_uart1_basic_grp", audio_uart1_basic_pins), - GROUP("audio_uart1_urfs_grp0", audio_uart1_urfs_pins0), - GROUP("audio_uart1_urfs_grp1", audio_uart1_urfs_pins1), - GROUP("audio_uart1_urfs_grp2", audio_uart1_urfs_pins2), - GROUP("audio_uart2_urfs_grp0", audio_uart2_urfs_pins0), - GROUP("audio_uart2_urfs_grp1", audio_uart2_urfs_pins1), - GROUP("audio_uart2_urfs_grp2", audio_uart2_urfs_pins2), - GROUP("audio_uart2_urxd_grp0", audio_uart2_urxd_pins0), - GROUP("audio_uart2_urxd_grp1", audio_uart2_urxd_pins1), - GROUP("audio_uart2_urxd_grp2", audio_uart2_urxd_pins2), - GROUP("audio_uart2_usclk_grp0", audio_uart2_usclk_pins0), - GROUP("audio_uart2_usclk_grp1", audio_uart2_usclk_pins1), - GROUP("audio_uart2_usclk_grp2", audio_uart2_usclk_pins2), - GROUP("audio_uart2_utfs_grp0", audio_uart2_utfs_pins0), - GROUP("audio_uart2_utfs_grp1", audio_uart2_utfs_pins1), - GROUP("audio_uart2_utfs_grp2", audio_uart2_utfs_pins2), - GROUP("audio_uart2_utxd_grp0", audio_uart2_utxd_pins0), - GROUP("audio_uart2_utxd_grp1", audio_uart2_utxd_pins1), - GROUP("audio_uart2_utxd_grp2", audio_uart2_utxd_pins2), - GROUP("c_can_trnsvr_en_grp0", c_can_trnsvr_en_pins0), - GROUP("c_can_trnsvr_en_grp1", c_can_trnsvr_en_pins1), - GROUP("c_can_trnsvr_intr_grp", c_can_trnsvr_intr_pins), - GROUP("c_can_trnsvr_stb_n_grp", c_can_trnsvr_stb_n_pins), - GROUP("c0_can_rxd_trnsv0_grp", c0_can_rxd_trnsv0_pins), - GROUP("c0_can_rxd_trnsv1_grp", c0_can_rxd_trnsv1_pins), - GROUP("c0_can_txd_trnsv0_grp", c0_can_txd_trnsv0_pins), - GROUP("c0_can_txd_trnsv1_grp", c0_can_txd_trnsv1_pins), - GROUP("c1_can_rxd_grp0", c1_can_rxd_pins0), - GROUP("c1_can_rxd_grp1", c1_can_rxd_pins1), - GROUP("c1_can_rxd_grp2", c1_can_rxd_pins2), - GROUP("c1_can_rxd_grp3", c1_can_rxd_pins3), - GROUP("c1_can_txd_grp0", c1_can_txd_pins0), - GROUP("c1_can_txd_grp1", c1_can_txd_pins1), - GROUP("c1_can_txd_grp2", c1_can_txd_pins2), - GROUP("c1_can_txd_grp3", c1_can_txd_pins3), - GROUP("ca_audio_lpc_grp", ca_audio_lpc_pins), - GROUP("ca_bt_lpc_grp", ca_bt_lpc_pins), - GROUP("ca_coex_grp", ca_coex_pins), - GROUP("ca_curator_lpc_grp", ca_curator_lpc_pins), - GROUP("ca_pcm_debug_grp", ca_pcm_debug_pins), - GROUP("ca_pio_grp", ca_pio_pins), - GROUP("ca_sdio_debug_grp", ca_sdio_debug_pins), - GROUP("ca_spi_grp", ca_spi_pins), - GROUP("ca_trb_grp", ca_trb_pins), - GROUP("ca_uart_debug_grp", ca_uart_debug_pins), - GROUP("clkc_grp0", clkc_pins0), - GROUP("clkc_grp1", clkc_pins1), - GROUP("gn_gnss_i2c_grp", gn_gnss_i2c_pins), - GROUP("gn_gnss_uart_nopause_grp", gn_gnss_uart_nopause_pins), - GROUP("gn_gnss_uart_grp", gn_gnss_uart_pins), - GROUP("gn_trg_spi_grp0", gn_trg_spi_pins0), - GROUP("gn_trg_spi_grp1", gn_trg_spi_pins1), - GROUP("cvbs_dbg_grp", cvbs_dbg_pins), - GROUP("cvbs_dbg_test_grp0", cvbs_dbg_test_pins0), - GROUP("cvbs_dbg_test_grp1", cvbs_dbg_test_pins1), - GROUP("cvbs_dbg_test_grp2", cvbs_dbg_test_pins2), - GROUP("cvbs_dbg_test_grp3", cvbs_dbg_test_pins3), - GROUP("cvbs_dbg_test_grp4", cvbs_dbg_test_pins4), - GROUP("cvbs_dbg_test_grp5", cvbs_dbg_test_pins5), - GROUP("cvbs_dbg_test_grp6", cvbs_dbg_test_pins6), - GROUP("cvbs_dbg_test_grp7", cvbs_dbg_test_pins7), - GROUP("cvbs_dbg_test_grp8", cvbs_dbg_test_pins8), - GROUP("cvbs_dbg_test_grp9", cvbs_dbg_test_pins9), - GROUP("cvbs_dbg_test_grp10", cvbs_dbg_test_pins10), - GROUP("cvbs_dbg_test_grp11", cvbs_dbg_test_pins11), - GROUP("cvbs_dbg_test_grp12", cvbs_dbg_test_pins12), - GROUP("cvbs_dbg_test_grp13", cvbs_dbg_test_pins13), - GROUP("cvbs_dbg_test_grp14", cvbs_dbg_test_pins14), - GROUP("cvbs_dbg_test_grp15", cvbs_dbg_test_pins15), - GROUP("gn_gnss_power_grp", gn_gnss_power_pins), - GROUP("gn_gnss_sw_status_grp", gn_gnss_sw_status_pins), - GROUP("gn_gnss_eclk_grp", gn_gnss_eclk_pins), - GROUP("gn_gnss_irq1_grp0", gn_gnss_irq1_pins0), - GROUP("gn_gnss_irq2_grp0", gn_gnss_irq2_pins0), - GROUP("gn_gnss_tm_grp", gn_gnss_tm_pins), - GROUP("gn_gnss_tsync_grp", gn_gnss_tsync_pins), - GROUP("gn_io_gnsssys_sw_cfg_grp", gn_io_gnsssys_sw_cfg_pins), - GROUP("gn_trg_grp0", gn_trg_pins0), - GROUP("gn_trg_grp1", gn_trg_pins1), - GROUP("gn_trg_shutdown_grp0", gn_trg_shutdown_pins0), - GROUP("gn_trg_shutdown_grp1", gn_trg_shutdown_pins1), - GROUP("gn_trg_shutdown_grp2", gn_trg_shutdown_pins2), - GROUP("gn_trg_shutdown_grp3", gn_trg_shutdown_pins3), - GROUP("i2c0_grp", i2c0_pins), - GROUP("i2c1_grp", i2c1_pins), - GROUP("i2s0_grp", i2s0_pins), - GROUP("i2s1_basic_grp", i2s1_basic_pins), - GROUP("i2s1_rxd0_grp0", i2s1_rxd0_pins0), - GROUP("i2s1_rxd0_grp1", i2s1_rxd0_pins1), - GROUP("i2s1_rxd0_grp2", i2s1_rxd0_pins2), - GROUP("i2s1_rxd0_grp3", i2s1_rxd0_pins3), - GROUP("i2s1_rxd0_grp4", i2s1_rxd0_pins4), - GROUP("i2s1_rxd1_grp0", i2s1_rxd1_pins0), - GROUP("i2s1_rxd1_grp1", i2s1_rxd1_pins1), - GROUP("i2s1_rxd1_grp2", i2s1_rxd1_pins2), - GROUP("i2s1_rxd1_grp3", i2s1_rxd1_pins3), - GROUP("i2s1_rxd1_grp4", i2s1_rxd1_pins4), - GROUP("jtag_jt_dbg_nsrst_grp", jtag_jt_dbg_nsrst_pins), - GROUP("jtag_ntrst_grp0", jtag_ntrst_pins0), - GROUP("jtag_ntrst_grp1", jtag_ntrst_pins1), - GROUP("jtag_swdiotms_grp0", jtag_swdiotms_pins0), - GROUP("jtag_swdiotms_grp1", jtag_swdiotms_pins1), - GROUP("jtag_tck_grp0", jtag_tck_pins0), - GROUP("jtag_tck_grp1", jtag_tck_pins1), - GROUP("jtag_tdi_grp0", jtag_tdi_pins0), - GROUP("jtag_tdi_grp1", jtag_tdi_pins1), - GROUP("jtag_tdo_grp0", jtag_tdo_pins0), - GROUP("jtag_tdo_grp1", jtag_tdo_pins1), - GROUP("ks_kas_spi_grp0", ks_kas_spi_pins0), - GROUP("ld_ldd_grp", ld_ldd_pins), - GROUP("ld_ldd_16bit_grp", ld_ldd_16bit_pins), - GROUP("ld_ldd_fck_grp", ld_ldd_fck_pins), - GROUP("ld_ldd_lck_grp", ld_ldd_lck_pins), - GROUP("lr_lcdrom_grp", lr_lcdrom_pins), - GROUP("lvds_analog_grp", lvds_analog_pins), - GROUP("nd_df_basic_grp", nd_df_basic_pins), - GROUP("nd_df_wp_grp", nd_df_wp_pins), - GROUP("nd_df_cs_grp", nd_df_cs_pins), - GROUP("ps_grp", ps_pins), - GROUP("ps_no_dir_grp", ps_no_dir_pins), - GROUP("pwc_core_on_grp", pwc_core_on_pins), - GROUP("pwc_ext_on_grp", pwc_ext_on_pins), - GROUP("pwc_gpio3_clk_grp", pwc_gpio3_clk_pins), - GROUP("pwc_io_on_grp", pwc_io_on_pins), - GROUP("pwc_lowbatt_b_grp0", pwc_lowbatt_b_pins0), - GROUP("pwc_mem_on_grp", pwc_mem_on_pins), - GROUP("pwc_on_key_b_grp0", pwc_on_key_b_pins0), - GROUP("pwc_wakeup_src0_grp", pwc_wakeup_src0_pins), - GROUP("pwc_wakeup_src1_grp", pwc_wakeup_src1_pins), - GROUP("pwc_wakeup_src2_grp", pwc_wakeup_src2_pins), - GROUP("pwc_wakeup_src3_grp", pwc_wakeup_src3_pins), - GROUP("pw_cko0_grp0", pw_cko0_pins0), - GROUP("pw_cko0_grp1", pw_cko0_pins1), - GROUP("pw_cko0_grp2", pw_cko0_pins2), - GROUP("pw_cko0_grp3", pw_cko0_pins3), - GROUP("pw_cko1_grp0", pw_cko1_pins0), - GROUP("pw_cko1_grp1", pw_cko1_pins1), - GROUP("pw_cko1_grp2", pw_cko1_pins2), - GROUP("pw_i2s01_clk_grp0", pw_i2s01_clk_pins0), - GROUP("pw_i2s01_clk_grp1", pw_i2s01_clk_pins1), - GROUP("pw_i2s01_clk_grp2", pw_i2s01_clk_pins2), - GROUP("pw_pwm0_grp0", pw_pwm0_pins0), - GROUP("pw_pwm0_grp1", pw_pwm0_pins1), - GROUP("pw_pwm1_grp0", pw_pwm1_pins0), - GROUP("pw_pwm1_grp1", pw_pwm1_pins1), - GROUP("pw_pwm1_grp2", pw_pwm1_pins2), - GROUP("pw_pwm2_grp0", pw_pwm2_pins0), - GROUP("pw_pwm2_grp1", pw_pwm2_pins1), - GROUP("pw_pwm2_grp2", pw_pwm2_pins2), - GROUP("pw_pwm3_grp0", pw_pwm3_pins0), - GROUP("pw_pwm3_grp1", pw_pwm3_pins1), - GROUP("pw_pwm_cpu_vol_grp0", pw_pwm_cpu_vol_pins0), - GROUP("pw_pwm_cpu_vol_grp1", pw_pwm_cpu_vol_pins1), - GROUP("pw_pwm_cpu_vol_grp2", pw_pwm_cpu_vol_pins2), - GROUP("pw_backlight_grp0", pw_backlight_pins0), - GROUP("pw_backlight_grp1", pw_backlight_pins1), - GROUP("rg_eth_mac_grp", rg_eth_mac_pins), - GROUP("rg_gmac_phy_intr_n_grp", rg_gmac_phy_intr_n_pins), - GROUP("rg_rgmii_mac_grp", rg_rgmii_mac_pins), - GROUP("rg_rgmii_phy_ref_clk_grp0", rg_rgmii_phy_ref_clk_pins0), - GROUP("rg_rgmii_phy_ref_clk_grp1", rg_rgmii_phy_ref_clk_pins1), - GROUP("sd0_grp", sd0_pins), - GROUP("sd0_4bit_grp", sd0_4bit_pins), - GROUP("sd1_grp", sd1_pins), - GROUP("sd1_4bit_grp0", sd1_4bit_pins0), - GROUP("sd1_4bit_grp1", sd1_4bit_pins1), - GROUP("sd2_basic_grp", sd2_basic_pins), - GROUP("sd2_cdb_grp0", sd2_cdb_pins0), - GROUP("sd2_cdb_grp1", sd2_cdb_pins1), - GROUP("sd2_wpb_grp0", sd2_wpb_pins0), - GROUP("sd2_wpb_grp1", sd2_wpb_pins1), - GROUP("sd3_9_grp", sd3_9_pins), - GROUP("sd5_grp", sd5_pins), - GROUP("sd6_grp0", sd6_pins0), - GROUP("sd6_grp1", sd6_pins1), - GROUP("sp0_ext_ldo_on_grp", sp0_ext_ldo_on_pins), - GROUP("sp0_qspi_grp", sp0_qspi_pins), - GROUP("sp1_spi_grp", sp1_spi_pins), - GROUP("tpiu_trace_grp", tpiu_trace_pins), - GROUP("uart0_grp", uart0_pins), - GROUP("uart0_nopause_grp", uart0_nopause_pins), - GROUP("uart1_grp", uart1_pins), - GROUP("uart2_cts_grp0", uart2_cts_pins0), - GROUP("uart2_cts_grp1", uart2_cts_pins1), - GROUP("uart2_rts_grp0", uart2_rts_pins0), - GROUP("uart2_rts_grp1", uart2_rts_pins1), - GROUP("uart2_rxd_grp0", uart2_rxd_pins0), - GROUP("uart2_rxd_grp1", uart2_rxd_pins1), - GROUP("uart2_rxd_grp2", uart2_rxd_pins2), - GROUP("uart2_txd_grp0", uart2_txd_pins0), - GROUP("uart2_txd_grp1", uart2_txd_pins1), - GROUP("uart2_txd_grp2", uart2_txd_pins2), - GROUP("uart3_cts_grp0", uart3_cts_pins0), - GROUP("uart3_cts_grp1", uart3_cts_pins1), - GROUP("uart3_cts_grp2", uart3_cts_pins2), - GROUP("uart3_rts_grp0", uart3_rts_pins0), - GROUP("uart3_rts_grp1", uart3_rts_pins1), - GROUP("uart3_rts_grp2", uart3_rts_pins2), - GROUP("uart3_rxd_grp0", uart3_rxd_pins0), - GROUP("uart3_rxd_grp1", uart3_rxd_pins1), - GROUP("uart3_rxd_grp2", uart3_rxd_pins2), - GROUP("uart3_txd_grp0", uart3_txd_pins0), - GROUP("uart3_txd_grp1", uart3_txd_pins1), - GROUP("uart3_txd_grp2", uart3_txd_pins2), - GROUP("uart4_basic_grp", uart4_basic_pins), - GROUP("uart4_cts_grp0", uart4_cts_pins0), - GROUP("uart4_cts_grp1", uart4_cts_pins1), - GROUP("uart4_cts_grp2", uart4_cts_pins2), - GROUP("uart4_rts_grp0", uart4_rts_pins0), - GROUP("uart4_rts_grp1", uart4_rts_pins1), - GROUP("uart4_rts_grp2", uart4_rts_pins2), - GROUP("usb0_drvvbus_grp0", usb0_drvvbus_pins0), - GROUP("usb0_drvvbus_grp1", usb0_drvvbus_pins1), - GROUP("usb1_drvvbus_grp0", usb1_drvvbus_pins0), - GROUP("usb1_drvvbus_grp1", usb1_drvvbus_pins1), - GROUP("visbus_dout_grp", visbus_dout_pins), - GROUP("vi_vip1_grp", vi_vip1_pins), - GROUP("vi_vip1_ext_grp", vi_vip1_ext_pins), - GROUP("vi_vip1_low8bit_grp", vi_vip1_low8bit_pins), - GROUP("vi_vip1_high8bit_grp", vi_vip1_high8bit_pins), -}; - -/* How many groups that a function can use */ -static const char * const gnss_gpio_grp[] = { "gnss_gpio_grp", }; -static const char * const lcd_vip_gpio_grp[] = { "lcd_vip_gpio_grp", }; -static const char * const sdio_i2s_gpio_grp[] = { "sdio_i2s_gpio_grp", }; -static const char * const sp_rgmii_gpio_grp[] = { "sp_rgmii_gpio_grp", }; -static const char * const lvds_gpio_grp[] = { "lvds_gpio_grp", }; -static const char * const jtag_uart_nand_gpio_grp[] = { - "jtag_uart_nand_gpio_grp", }; -static const char * const rtc_gpio_grp[] = { "rtc_gpio_grp", }; -static const char * const audio_ac97_grp[] = { "audio_ac97_grp", }; -static const char * const audio_digmic_grp0[] = { "audio_digmic_grp0", }; -static const char * const audio_digmic_grp1[] = { "audio_digmic_grp1", }; -static const char * const audio_digmic_grp2[] = { "audio_digmic_grp2", }; -static const char * const audio_func_dbg_grp[] = { "audio_func_dbg_grp", }; -static const char * const audio_i2s_grp[] = { "audio_i2s_grp", }; -static const char * const audio_i2s_2ch_grp[] = { "audio_i2s_2ch_grp", }; -static const char * const audio_i2s_extclk_grp[] = { "audio_i2s_extclk_grp", }; -static const char * const audio_spdif_out_grp0[] = { "audio_spdif_out_grp0", }; -static const char * const audio_spdif_out_grp1[] = { "audio_spdif_out_grp1", }; -static const char * const audio_spdif_out_grp2[] = { "audio_spdif_out_grp2", }; -static const char * const audio_uart0_basic_grp[] = { - "audio_uart0_basic_grp", }; -static const char * const audio_uart0_urfs_grp0[] = { - "audio_uart0_urfs_grp0", }; -static const char * const audio_uart0_urfs_grp1[] = { - "audio_uart0_urfs_grp1", }; -static const char * const audio_uart0_urfs_grp2[] = { - "audio_uart0_urfs_grp2", }; -static const char * const audio_uart0_urfs_grp3[] = { - "audio_uart0_urfs_grp3", }; -static const char * const audio_uart1_basic_grp[] = { - "audio_uart1_basic_grp", }; -static const char * const audio_uart1_urfs_grp0[] = { - "audio_uart1_urfs_grp0", }; -static const char * const audio_uart1_urfs_grp1[] = { - "audio_uart1_urfs_grp1", }; -static const char * const audio_uart1_urfs_grp2[] = { - "audio_uart1_urfs_grp2", }; -static const char * const audio_uart2_urfs_grp0[] = { - "audio_uart2_urfs_grp0", }; -static const char * const audio_uart2_urfs_grp1[] = { - "audio_uart2_urfs_grp1", }; -static const char * const audio_uart2_urfs_grp2[] = { - "audio_uart2_urfs_grp2", }; -static const char * const audio_uart2_urxd_grp0[] = { - "audio_uart2_urxd_grp0", }; -static const char * const audio_uart2_urxd_grp1[] = { - "audio_uart2_urxd_grp1", }; -static const char * const audio_uart2_urxd_grp2[] = { - "audio_uart2_urxd_grp2", }; -static const char * const audio_uart2_usclk_grp0[] = { - "audio_uart2_usclk_grp0", }; -static const char * const audio_uart2_usclk_grp1[] = { - "audio_uart2_usclk_grp1", }; -static const char * const audio_uart2_usclk_grp2[] = { - "audio_uart2_usclk_grp2", }; -static const char * const audio_uart2_utfs_grp0[] = { - "audio_uart2_utfs_grp0", }; -static const char * const audio_uart2_utfs_grp1[] = { - "audio_uart2_utfs_grp1", }; -static const char * const audio_uart2_utfs_grp2[] = { - "audio_uart2_utfs_grp2", }; -static const char * const audio_uart2_utxd_grp0[] = { - "audio_uart2_utxd_grp0", }; -static const char * const audio_uart2_utxd_grp1[] = { - "audio_uart2_utxd_grp1", }; -static const char * const audio_uart2_utxd_grp2[] = { - "audio_uart2_utxd_grp2", }; -static const char * const c_can_trnsvr_en_grp0[] = { "c_can_trnsvr_en_grp0", }; -static const char * const c_can_trnsvr_en_grp1[] = { "c_can_trnsvr_en_grp1", }; -static const char * const c_can_trnsvr_intr_grp[] = { - "c_can_trnsvr_intr_grp", }; -static const char * const c_can_trnsvr_stb_n_grp[] = { - "c_can_trnsvr_stb_n_grp", }; -static const char * const c0_can_rxd_trnsv0_grp[] = { - "c0_can_rxd_trnsv0_grp", }; -static const char * const c0_can_rxd_trnsv1_grp[] = { - "c0_can_rxd_trnsv1_grp", }; -static const char * const c0_can_txd_trnsv0_grp[] = { - "c0_can_txd_trnsv0_grp", }; -static const char * const c0_can_txd_trnsv1_grp[] = { - "c0_can_txd_trnsv1_grp", }; -static const char * const c1_can_rxd_grp0[] = { "c1_can_rxd_grp0", }; -static const char * const c1_can_rxd_grp1[] = { "c1_can_rxd_grp1", }; -static const char * const c1_can_rxd_grp2[] = { "c1_can_rxd_grp2", }; -static const char * const c1_can_rxd_grp3[] = { "c1_can_rxd_grp3", }; -static const char * const c1_can_txd_grp0[] = { "c1_can_txd_grp0", }; -static const char * const c1_can_txd_grp1[] = { "c1_can_txd_grp1", }; -static const char * const c1_can_txd_grp2[] = { "c1_can_txd_grp2", }; -static const char * const c1_can_txd_grp3[] = { "c1_can_txd_grp3", }; -static const char * const ca_audio_lpc_grp[] = { "ca_audio_lpc_grp", }; -static const char * const ca_bt_lpc_grp[] = { "ca_bt_lpc_grp", }; -static const char * const ca_coex_grp[] = { "ca_coex_grp", }; -static const char * const ca_curator_lpc_grp[] = { "ca_curator_lpc_grp", }; -static const char * const ca_pcm_debug_grp[] = { "ca_pcm_debug_grp", }; -static const char * const ca_pio_grp[] = { "ca_pio_grp", }; -static const char * const ca_sdio_debug_grp[] = { "ca_sdio_debug_grp", }; -static const char * const ca_spi_grp[] = { "ca_spi_grp", }; -static const char * const ca_trb_grp[] = { "ca_trb_grp", }; -static const char * const ca_uart_debug_grp[] = { "ca_uart_debug_grp", }; -static const char * const clkc_grp0[] = { "clkc_grp0", }; -static const char * const clkc_grp1[] = { "clkc_grp1", }; -static const char * const gn_gnss_i2c_grp[] = { "gn_gnss_i2c_grp", }; -static const char * const gn_gnss_uart_nopause_grp[] = { - "gn_gnss_uart_nopause_grp", }; -static const char * const gn_gnss_uart_grp[] = { "gn_gnss_uart_grp", }; -static const char * const gn_trg_spi_grp0[] = { "gn_trg_spi_grp0", }; -static const char * const gn_trg_spi_grp1[] = { "gn_trg_spi_grp1", }; -static const char * const cvbs_dbg_grp[] = { "cvbs_dbg_grp", }; -static const char * const cvbs_dbg_test_grp0[] = { "cvbs_dbg_test_grp0", }; -static const char * const cvbs_dbg_test_grp1[] = { "cvbs_dbg_test_grp1", }; -static const char * const cvbs_dbg_test_grp2[] = { "cvbs_dbg_test_grp2", }; -static const char * const cvbs_dbg_test_grp3[] = { "cvbs_dbg_test_grp3", }; -static const char * const cvbs_dbg_test_grp4[] = { "cvbs_dbg_test_grp4", }; -static const char * const cvbs_dbg_test_grp5[] = { "cvbs_dbg_test_grp5", }; -static const char * const cvbs_dbg_test_grp6[] = { "cvbs_dbg_test_grp6", }; -static const char * const cvbs_dbg_test_grp7[] = { "cvbs_dbg_test_grp7", }; -static const char * const cvbs_dbg_test_grp8[] = { "cvbs_dbg_test_grp8", }; -static const char * const cvbs_dbg_test_grp9[] = { "cvbs_dbg_test_grp9", }; -static const char * const cvbs_dbg_test_grp10[] = { "cvbs_dbg_test_grp10", }; -static const char * const cvbs_dbg_test_grp11[] = { "cvbs_dbg_test_grp11", }; -static const char * const cvbs_dbg_test_grp12[] = { "cvbs_dbg_test_grp12", }; -static const char * const cvbs_dbg_test_grp13[] = { "cvbs_dbg_test_grp13", }; -static const char * const cvbs_dbg_test_grp14[] = { "cvbs_dbg_test_grp14", }; -static const char * const cvbs_dbg_test_grp15[] = { "cvbs_dbg_test_grp15", }; -static const char * const gn_gnss_power_grp[] = { "gn_gnss_power_grp", }; -static const char * const gn_gnss_sw_status_grp[] = { - "gn_gnss_sw_status_grp", }; -static const char * const gn_gnss_eclk_grp[] = { "gn_gnss_eclk_grp", }; -static const char * const gn_gnss_irq1_grp0[] = { "gn_gnss_irq1_grp0", }; -static const char * const gn_gnss_irq2_grp0[] = { "gn_gnss_irq2_grp0", }; -static const char * const gn_gnss_tm_grp[] = { "gn_gnss_tm_grp", }; -static const char * const gn_gnss_tsync_grp[] = { "gn_gnss_tsync_grp", }; -static const char * const gn_io_gnsssys_sw_cfg_grp[] = { - "gn_io_gnsssys_sw_cfg_grp", }; -static const char * const gn_trg_grp0[] = { "gn_trg_grp0", }; -static const char * const gn_trg_grp1[] = { "gn_trg_grp1", }; -static const char * const gn_trg_shutdown_grp0[] = { "gn_trg_shutdown_grp0", }; -static const char * const gn_trg_shutdown_grp1[] = { "gn_trg_shutdown_grp1", }; -static const char * const gn_trg_shutdown_grp2[] = { "gn_trg_shutdown_grp2", }; -static const char * const gn_trg_shutdown_grp3[] = { "gn_trg_shutdown_grp3", }; -static const char * const i2c0_grp[] = { "i2c0_grp", }; -static const char * const i2c1_grp[] = { "i2c1_grp", }; -static const char * const i2s0_grp[] = { "i2s0_grp", }; -static const char * const i2s1_basic_grp[] = { "i2s1_basic_grp", }; -static const char * const i2s1_rxd0_grp0[] = { "i2s1_rxd0_grp0", }; -static const char * const i2s1_rxd0_grp1[] = { "i2s1_rxd0_grp1", }; -static const char * const i2s1_rxd0_grp2[] = { "i2s1_rxd0_grp2", }; -static const char * const i2s1_rxd0_grp3[] = { "i2s1_rxd0_grp3", }; -static const char * const i2s1_rxd0_grp4[] = { "i2s1_rxd0_grp4", }; -static const char * const i2s1_rxd1_grp0[] = { "i2s1_rxd1_grp0", }; -static const char * const i2s1_rxd1_grp1[] = { "i2s1_rxd1_grp1", }; -static const char * const i2s1_rxd1_grp2[] = { "i2s1_rxd1_grp2", }; -static const char * const i2s1_rxd1_grp3[] = { "i2s1_rxd1_grp3", }; -static const char * const i2s1_rxd1_grp4[] = { "i2s1_rxd1_grp4", }; -static const char * const jtag_jt_dbg_nsrst_grp[] = { - "jtag_jt_dbg_nsrst_grp", }; -static const char * const jtag_ntrst_grp0[] = { "jtag_ntrst_grp0", }; -static const char * const jtag_ntrst_grp1[] = { "jtag_ntrst_grp1", }; -static const char * const jtag_swdiotms_grp0[] = { "jtag_swdiotms_grp0", }; -static const char * const jtag_swdiotms_grp1[] = { "jtag_swdiotms_grp1", }; -static const char * const jtag_tck_grp0[] = { "jtag_tck_grp0", }; -static const char * const jtag_tck_grp1[] = { "jtag_tck_grp1", }; -static const char * const jtag_tdi_grp0[] = { "jtag_tdi_grp0", }; -static const char * const jtag_tdi_grp1[] = { "jtag_tdi_grp1", }; -static const char * const jtag_tdo_grp0[] = { "jtag_tdo_grp0", }; -static const char * const jtag_tdo_grp1[] = { "jtag_tdo_grp1", }; -static const char * const ks_kas_spi_grp0[] = { "ks_kas_spi_grp0", }; -static const char * const ld_ldd_grp[] = { "ld_ldd_grp", }; -static const char * const ld_ldd_16bit_grp[] = { "ld_ldd_16bit_grp", }; -static const char * const ld_ldd_fck_grp[] = { "ld_ldd_fck_grp", }; -static const char * const ld_ldd_lck_grp[] = { "ld_ldd_lck_grp", }; -static const char * const lr_lcdrom_grp[] = { "lr_lcdrom_grp", }; -static const char * const lvds_analog_grp[] = { "lvds_analog_grp", }; -static const char * const nd_df_basic_grp[] = { "nd_df_basic_grp", }; -static const char * const nd_df_wp_grp[] = { "nd_df_wp_grp", }; -static const char * const nd_df_cs_grp[] = { "nd_df_cs_grp", }; -static const char * const ps_grp[] = { "ps_grp", }; -static const char * const ps_no_dir_grp[] = { "ps_no_dir_grp", }; -static const char * const pwc_core_on_grp[] = { "pwc_core_on_grp", }; -static const char * const pwc_ext_on_grp[] = { "pwc_ext_on_grp", }; -static const char * const pwc_gpio3_clk_grp[] = { "pwc_gpio3_clk_grp", }; -static const char * const pwc_io_on_grp[] = { "pwc_io_on_grp", }; -static const char * const pwc_lowbatt_b_grp0[] = { "pwc_lowbatt_b_grp0", }; -static const char * const pwc_mem_on_grp[] = { "pwc_mem_on_grp", }; -static const char * const pwc_on_key_b_grp0[] = { "pwc_on_key_b_grp0", }; -static const char * const pwc_wakeup_src0_grp[] = { "pwc_wakeup_src0_grp", }; -static const char * const pwc_wakeup_src1_grp[] = { "pwc_wakeup_src1_grp", }; -static const char * const pwc_wakeup_src2_grp[] = { "pwc_wakeup_src2_grp", }; -static const char * const pwc_wakeup_src3_grp[] = { "pwc_wakeup_src3_grp", }; -static const char * const pw_cko0_grp0[] = { "pw_cko0_grp0", }; -static const char * const pw_cko0_grp1[] = { "pw_cko0_grp1", }; -static const char * const pw_cko0_grp2[] = { "pw_cko0_grp2", }; -static const char * const pw_cko0_grp3[] = { "pw_cko0_grp3", }; -static const char * const pw_cko1_grp0[] = { "pw_cko1_grp0", }; -static const char * const pw_cko1_grp1[] = { "pw_cko1_grp1", }; -static const char * const pw_cko1_grp2[] = { "pw_cko1_grp2", }; -static const char * const pw_i2s01_clk_grp0[] = { "pw_i2s01_clk_grp0", }; -static const char * const pw_i2s01_clk_grp1[] = { "pw_i2s01_clk_grp1", }; -static const char * const pw_i2s01_clk_grp2[] = { "pw_i2s01_clk_grp2", }; -static const char * const pw_pwm0_grp0[] = { "pw_pwm0_grp0", }; -static const char * const pw_pwm0_grp1[] = { "pw_pwm0_grp1", }; -static const char * const pw_pwm1_grp0[] = { "pw_pwm1_grp0", }; -static const char * const pw_pwm1_grp1[] = { "pw_pwm1_grp1", }; -static const char * const pw_pwm1_grp2[] = { "pw_pwm1_grp2", }; -static const char * const pw_pwm2_grp0[] = { "pw_pwm2_grp0", }; -static const char * const pw_pwm2_grp1[] = { "pw_pwm2_grp1", }; -static const char * const pw_pwm2_grp2[] = { "pw_pwm2_grp2", }; -static const char * const pw_pwm3_grp0[] = { "pw_pwm3_grp0", }; -static const char * const pw_pwm3_grp1[] = { "pw_pwm3_grp1", }; -static const char * const pw_pwm_cpu_vol_grp0[] = { "pw_pwm_cpu_vol_grp0", }; -static const char * const pw_pwm_cpu_vol_grp1[] = { "pw_pwm_cpu_vol_grp1", }; -static const char * const pw_pwm_cpu_vol_grp2[] = { "pw_pwm_cpu_vol_grp2", }; -static const char * const pw_backlight_grp0[] = { "pw_backlight_grp0", }; -static const char * const pw_backlight_grp1[] = { "pw_backlight_grp1", }; -static const char * const rg_eth_mac_grp[] = { "rg_eth_mac_grp", }; -static const char * const rg_gmac_phy_intr_n_grp[] = { - "rg_gmac_phy_intr_n_grp", }; -static const char * const rg_rgmii_mac_grp[] = { "rg_rgmii_mac_grp", }; -static const char * const rg_rgmii_phy_ref_clk_grp0[] = { - "rg_rgmii_phy_ref_clk_grp0", }; -static const char * const rg_rgmii_phy_ref_clk_grp1[] = { - "rg_rgmii_phy_ref_clk_grp1", }; -static const char * const sd0_grp[] = { "sd0_grp", }; -static const char * const sd0_4bit_grp[] = { "sd0_4bit_grp", }; -static const char * const sd1_grp[] = { "sd1_grp", }; -static const char * const sd1_4bit_grp0[] = { "sd1_4bit_grp0", }; -static const char * const sd1_4bit_grp1[] = { "sd1_4bit_grp1", }; -static const char * const sd2_basic_grp[] = { "sd2_basic_grp", }; -static const char * const sd2_cdb_grp0[] = { "sd2_cdb_grp0", }; -static const char * const sd2_cdb_grp1[] = { "sd2_cdb_grp1", }; -static const char * const sd2_wpb_grp0[] = { "sd2_wpb_grp0", }; -static const char * const sd2_wpb_grp1[] = { "sd2_wpb_grp1", }; -static const char * const sd3_9_grp[] = { "sd3_9_grp", }; -static const char * const sd5_grp[] = { "sd5_grp", }; -static const char * const sd6_grp0[] = { "sd6_grp0", }; -static const char * const sd6_grp1[] = { "sd6_grp1", }; -static const char * const sp0_ext_ldo_on_grp[] = { "sp0_ext_ldo_on_grp", }; -static const char * const sp0_qspi_grp[] = { "sp0_qspi_grp", }; -static const char * const sp1_spi_grp[] = { "sp1_spi_grp", }; -static const char * const tpiu_trace_grp[] = { "tpiu_trace_grp", }; -static const char * const uart0_grp[] = { "uart0_grp", }; -static const char * const uart0_nopause_grp[] = { "uart0_nopause_grp", }; -static const char * const uart1_grp[] = { "uart1_grp", }; -static const char * const uart2_cts_grp0[] = { "uart2_cts_grp0", }; -static const char * const uart2_cts_grp1[] = { "uart2_cts_grp1", }; -static const char * const uart2_rts_grp0[] = { "uart2_rts_grp0", }; -static const char * const uart2_rts_grp1[] = { "uart2_rts_grp1", }; -static const char * const uart2_rxd_grp0[] = { "uart2_rxd_grp0", }; -static const char * const uart2_rxd_grp1[] = { "uart2_rxd_grp1", }; -static const char * const uart2_rxd_grp2[] = { "uart2_rxd_grp2", }; -static const char * const uart2_txd_grp0[] = { "uart2_txd_grp0", }; -static const char * const uart2_txd_grp1[] = { "uart2_txd_grp1", }; -static const char * const uart2_txd_grp2[] = { "uart2_txd_grp2", }; -static const char * const uart3_cts_grp0[] = { "uart3_cts_grp0", }; -static const char * const uart3_cts_grp1[] = { "uart3_cts_grp1", }; -static const char * const uart3_cts_grp2[] = { "uart3_cts_grp2", }; -static const char * const uart3_rts_grp0[] = { "uart3_rts_grp0", }; -static const char * const uart3_rts_grp1[] = { "uart3_rts_grp1", }; -static const char * const uart3_rts_grp2[] = { "uart3_rts_grp2", }; -static const char * const uart3_rxd_grp0[] = { "uart3_rxd_grp0", }; -static const char * const uart3_rxd_grp1[] = { "uart3_rxd_grp1", }; -static const char * const uart3_rxd_grp2[] = { "uart3_rxd_grp2", }; -static const char * const uart3_txd_grp0[] = { "uart3_txd_grp0", }; -static const char * const uart3_txd_grp1[] = { "uart3_txd_grp1", }; -static const char * const uart3_txd_grp2[] = { "uart3_txd_grp2", }; -static const char * const uart4_basic_grp[] = { "uart4_basic_grp", }; -static const char * const uart4_cts_grp0[] = { "uart4_cts_grp0", }; -static const char * const uart4_cts_grp1[] = { "uart4_cts_grp1", }; -static const char * const uart4_cts_grp2[] = { "uart4_cts_grp2", }; -static const char * const uart4_rts_grp0[] = { "uart4_rts_grp0", }; -static const char * const uart4_rts_grp1[] = { "uart4_rts_grp1", }; -static const char * const uart4_rts_grp2[] = { "uart4_rts_grp2", }; -static const char * const usb0_drvvbus_grp0[] = { "usb0_drvvbus_grp0", }; -static const char * const usb0_drvvbus_grp1[] = { "usb0_drvvbus_grp1", }; -static const char * const usb1_drvvbus_grp0[] = { "usb1_drvvbus_grp0", }; -static const char * const usb1_drvvbus_grp1[] = { "usb1_drvvbus_grp1", }; -static const char * const visbus_dout_grp[] = { "visbus_dout_grp", }; -static const char * const vi_vip1_grp[] = { "vi_vip1_grp", }; -static const char * const vi_vip1_ext_grp[] = { "vi_vip1_ext_grp", }; -static const char * const vi_vip1_low8bit_grp[] = { "vi_vip1_low8bit_grp", }; -static const char * const vi_vip1_high8bit_grp[] = { "vi_vip1_high8bit_grp", }; - -static struct atlas7_pad_mux gnss_gpio_grp_pad_mux[] = { - MUX(1, 119, 0, N, N, N, N), - MUX(1, 120, 0, N, N, N, N), - MUX(1, 121, 0, N, N, N, N), - MUX(1, 122, 0, N, N, N, N), - MUX(1, 123, 0, N, N, N, N), - MUX(1, 124, 0, N, N, N, N), - MUX(1, 125, 0, N, N, N, N), - MUX(1, 126, 0, N, N, N, N), - MUX(1, 127, 0, N, N, N, N), - MUX(1, 128, 0, N, N, N, N), - MUX(1, 22, 0, N, N, N, N), - MUX(1, 23, 0, N, N, N, N), - MUX(1, 24, 0, N, N, N, N), - MUX(1, 25, 0, N, N, N, N), - MUX(1, 26, 0, N, N, N, N), - MUX(1, 27, 0, N, N, N, N), - MUX(1, 28, 0, N, N, N, N), - MUX(1, 29, 0, N, N, N, N), - MUX(1, 30, 0, N, N, N, N), -}; - -static struct atlas7_grp_mux gnss_gpio_grp_mux = { - .pad_mux_count = ARRAY_SIZE(gnss_gpio_grp_pad_mux), - .pad_mux_list = gnss_gpio_grp_pad_mux, -}; - -static struct atlas7_pad_mux lcd_vip_gpio_grp_pad_mux[] = { - MUX(1, 74, 0, N, N, N, N), - MUX(1, 75, 0, N, N, N, N), - MUX(1, 76, 0, N, N, N, N), - MUX(1, 77, 0, N, N, N, N), - MUX(1, 78, 0, N, N, N, N), - MUX(1, 79, 0, N, N, N, N), - MUX(1, 80, 0, N, N, N, N), - MUX(1, 81, 0, N, N, N, N), - MUX(1, 82, 0, N, N, N, N), - MUX(1, 83, 0, N, N, N, N), - MUX(1, 84, 0, N, N, N, N), - MUX(1, 53, 0, N, N, N, N), - MUX(1, 54, 0, N, N, N, N), - MUX(1, 55, 0, N, N, N, N), - MUX(1, 56, 0, N, N, N, N), - MUX(1, 57, 0, N, N, N, N), - MUX(1, 58, 0, N, N, N, N), - MUX(1, 59, 0, N, N, N, N), - MUX(1, 60, 0, N, N, N, N), - MUX(1, 61, 0, N, N, N, N), - MUX(1, 62, 0, N, N, N, N), - MUX(1, 63, 0, N, N, N, N), - MUX(1, 64, 0, N, N, N, N), - MUX(1, 65, 0, N, N, N, N), - MUX(1, 66, 0, N, N, N, N), - MUX(1, 67, 0, N, N, N, N), - MUX(1, 68, 0, N, N, N, N), - MUX(1, 69, 0, N, N, N, N), - MUX(1, 70, 0, N, N, N, N), - MUX(1, 71, 0, N, N, N, N), - MUX(1, 72, 0, N, N, N, N), - MUX(1, 73, 0, N, N, N, N), -}; - -static struct atlas7_grp_mux lcd_vip_gpio_grp_mux = { - .pad_mux_count = ARRAY_SIZE(lcd_vip_gpio_grp_pad_mux), - .pad_mux_list = lcd_vip_gpio_grp_pad_mux, -}; - -static struct atlas7_pad_mux sdio_i2s_gpio_grp_pad_mux[] = { - MUX(1, 31, 0, N, N, N, N), - MUX(1, 32, 0, N, N, N, N), - MUX(1, 33, 0, N, N, N, N), - MUX(1, 34, 0, N, N, N, N), - MUX(1, 35, 0, N, N, N, N), - MUX(1, 36, 0, N, N, N, N), - MUX(1, 85, 0, N, N, N, N), - MUX(1, 86, 0, N, N, N, N), - MUX(1, 87, 0, N, N, N, N), - MUX(1, 88, 0, N, N, N, N), - MUX(1, 89, 0, N, N, N, N), - MUX(1, 90, 0, N, N, N, N), - MUX(1, 129, 0, N, N, N, N), - MUX(1, 130, 0, N, N, N, N), - MUX(1, 131, 0, N, N, N, N), - MUX(1, 132, 0, N, N, N, N), - MUX(1, 91, 0, N, N, N, N), - MUX(1, 92, 0, N, N, N, N), - MUX(1, 93, 0, N, N, N, N), - MUX(1, 94, 0, N, N, N, N), - MUX(1, 95, 0, N, N, N, N), - MUX(1, 96, 0, N, N, N, N), - MUX(1, 112, 0, N, N, N, N), - MUX(1, 113, 0, N, N, N, N), - MUX(1, 114, 0, N, N, N, N), - MUX(1, 115, 0, N, N, N, N), - MUX(1, 116, 0, N, N, N, N), - MUX(1, 117, 0, N, N, N, N), - MUX(1, 118, 0, N, N, N, N), -}; - -static struct atlas7_grp_mux sdio_i2s_gpio_grp_mux = { - .pad_mux_count = ARRAY_SIZE(sdio_i2s_gpio_grp_pad_mux), - .pad_mux_list = sdio_i2s_gpio_grp_pad_mux, -}; - -static struct atlas7_pad_mux sp_rgmii_gpio_grp_pad_mux[] = { - MUX(1, 97, 0, N, N, N, N), - MUX(1, 98, 0, N, N, N, N), - MUX(1, 99, 0, N, N, N, N), - MUX(1, 100, 0, N, N, N, N), - MUX(1, 101, 0, N, N, N, N), - MUX(1, 102, 0, N, N, N, N), - MUX(1, 103, 0, N, N, N, N), - MUX(1, 104, 0, N, N, N, N), - MUX(1, 105, 0, N, N, N, N), - MUX(1, 106, 0, N, N, N, N), - MUX(1, 107, 0, N, N, N, N), - MUX(1, 108, 0, N, N, N, N), - MUX(1, 109, 0, N, N, N, N), - MUX(1, 110, 0, N, N, N, N), - MUX(1, 111, 0, N, N, N, N), - MUX(1, 18, 0, N, N, N, N), - MUX(1, 19, 0, N, N, N, N), - MUX(1, 20, 0, N, N, N, N), - MUX(1, 21, 0, N, N, N, N), - MUX(1, 141, 0, N, N, N, N), - MUX(1, 142, 0, N, N, N, N), - MUX(1, 143, 0, N, N, N, N), - MUX(1, 144, 0, N, N, N, N), - MUX(1, 145, 0, N, N, N, N), - MUX(1, 146, 0, N, N, N, N), - MUX(1, 147, 0, N, N, N, N), - MUX(1, 148, 0, N, N, N, N), -}; - -static struct atlas7_grp_mux sp_rgmii_gpio_grp_mux = { - .pad_mux_count = ARRAY_SIZE(sp_rgmii_gpio_grp_pad_mux), - .pad_mux_list = sp_rgmii_gpio_grp_pad_mux, -}; - -static struct atlas7_pad_mux lvds_gpio_grp_pad_mux[] = { - MUX(1, 157, 0, N, N, N, N), - MUX(1, 158, 0, N, N, N, N), - MUX(1, 155, 0, N, N, N, N), - MUX(1, 156, 0, N, N, N, N), - MUX(1, 153, 0, N, N, N, N), - MUX(1, 154, 0, N, N, N, N), - MUX(1, 151, 0, N, N, N, N), - MUX(1, 152, 0, N, N, N, N), - MUX(1, 149, 0, N, N, N, N), - MUX(1, 150, 0, N, N, N, N), -}; - -static struct atlas7_grp_mux lvds_gpio_grp_mux = { - .pad_mux_count = ARRAY_SIZE(lvds_gpio_grp_pad_mux), - .pad_mux_list = lvds_gpio_grp_pad_mux, -}; - -static struct atlas7_pad_mux jtag_uart_nand_gpio_grp_pad_mux[] = { - MUX(1, 44, 0, N, N, N, N), - MUX(1, 43, 0, N, N, N, N), - MUX(1, 42, 0, N, N, N, N), - MUX(1, 41, 0, N, N, N, N), - MUX(1, 40, 0, N, N, N, N), - MUX(1, 39, 0, N, N, N, N), - MUX(1, 38, 0, N, N, N, N), - MUX(1, 37, 0, N, N, N, N), - MUX(1, 46, 0, N, N, N, N), - MUX(1, 47, 0, N, N, N, N), - MUX(1, 48, 0, N, N, N, N), - MUX(1, 49, 0, N, N, N, N), - MUX(1, 50, 0, N, N, N, N), - MUX(1, 52, 0, N, N, N, N), - MUX(1, 51, 0, N, N, N, N), - MUX(1, 45, 0, N, N, N, N), - MUX(1, 133, 0, N, N, N, N), - MUX(1, 134, 0, N, N, N, N), - MUX(1, 135, 0, N, N, N, N), - MUX(1, 136, 0, N, N, N, N), - MUX(1, 137, 0, N, N, N, N), - MUX(1, 138, 0, N, N, N, N), - MUX(1, 139, 0, N, N, N, N), - MUX(1, 140, 0, N, N, N, N), - MUX(1, 159, 0, N, N, N, N), - MUX(1, 160, 0, N, N, N, N), - MUX(1, 161, 0, N, N, N, N), - MUX(1, 162, 0, N, N, N, N), - MUX(1, 163, 0, N, N, N, N), -}; - -static struct atlas7_grp_mux jtag_uart_nand_gpio_grp_mux = { - .pad_mux_count = ARRAY_SIZE(jtag_uart_nand_gpio_grp_pad_mux), - .pad_mux_list = jtag_uart_nand_gpio_grp_pad_mux, -}; - -static struct atlas7_pad_mux rtc_gpio_grp_pad_mux[] = { - MUX(0, 0, 0, N, N, N, N), - MUX(0, 1, 0, N, N, N, N), - MUX(0, 2, 0, N, N, N, N), - MUX(0, 3, 0, N, N, N, N), - MUX(0, 4, 0, N, N, N, N), - MUX(0, 10, 0, N, N, N, N), - MUX(0, 11, 0, N, N, N, N), - MUX(0, 12, 0, N, N, N, N), - MUX(0, 13, 0, N, N, N, N), - MUX(0, 14, 0, N, N, N, N), - MUX(0, 15, 0, N, N, N, N), - MUX(0, 16, 0, N, N, N, N), - MUX(0, 17, 0, N, N, N, N), - MUX(0, 9, 0, N, N, N, N), -}; - -static struct atlas7_grp_mux rtc_gpio_grp_mux = { - .pad_mux_count = ARRAY_SIZE(rtc_gpio_grp_pad_mux), - .pad_mux_list = rtc_gpio_grp_pad_mux, -}; - -static struct atlas7_pad_mux audio_ac97_grp_pad_mux[] = { - MUX(1, 113, 2, N, N, N, N), - MUX(1, 118, 2, N, N, N, N), - MUX(1, 115, 2, N, N, N, N), - MUX(1, 114, 2, N, N, N, N), -}; - -static struct atlas7_grp_mux audio_ac97_grp_mux = { - .pad_mux_count = ARRAY_SIZE(audio_ac97_grp_pad_mux), - .pad_mux_list = audio_ac97_grp_pad_mux, -}; - -static struct atlas7_pad_mux audio_digmic_grp0_pad_mux[] = { - MUX(1, 51, 3, 0xa10, 20, 0xa90, 20), -}; - -static struct atlas7_grp_mux audio_digmic_grp0_mux = { - .pad_mux_count = ARRAY_SIZE(audio_digmic_grp0_pad_mux), - .pad_mux_list = audio_digmic_grp0_pad_mux, -}; - -static struct atlas7_pad_mux audio_digmic_grp1_pad_mux[] = { - MUX(1, 122, 5, 0xa10, 20, 0xa90, 20), -}; - -static struct atlas7_grp_mux audio_digmic_grp1_mux = { - .pad_mux_count = ARRAY_SIZE(audio_digmic_grp1_pad_mux), - .pad_mux_list = audio_digmic_grp1_pad_mux, -}; - -static struct atlas7_pad_mux audio_digmic_grp2_pad_mux[] = { - MUX(1, 161, 7, 0xa10, 20, 0xa90, 20), -}; - -static struct atlas7_grp_mux audio_digmic_grp2_mux = { - .pad_mux_count = ARRAY_SIZE(audio_digmic_grp2_pad_mux), - .pad_mux_list = audio_digmic_grp2_pad_mux, -}; - -static struct atlas7_pad_mux audio_func_dbg_grp_pad_mux[] = { - MUX(1, 141, 4, N, N, N, N), - MUX(1, 144, 4, N, N, N, N), - MUX(1, 44, 6, N, N, N, N), - MUX(1, 43, 6, N, N, N, N), - MUX(1, 42, 6, N, N, N, N), - MUX(1, 41, 6, N, N, N, N), - MUX(1, 40, 6, N, N, N, N), - MUX(1, 39, 6, N, N, N, N), - MUX(1, 38, 6, N, N, N, N), - MUX(1, 37, 6, N, N, N, N), - MUX(1, 74, 6, N, N, N, N), - MUX(1, 75, 6, N, N, N, N), - MUX(1, 76, 6, N, N, N, N), - MUX(1, 77, 6, N, N, N, N), - MUX(1, 78, 6, N, N, N, N), - MUX(1, 79, 6, N, N, N, N), - MUX(1, 81, 6, N, N, N, N), - MUX(1, 113, 6, N, N, N, N), - MUX(1, 114, 6, N, N, N, N), - MUX(1, 118, 6, N, N, N, N), - MUX(1, 115, 6, N, N, N, N), - MUX(1, 49, 6, N, N, N, N), - MUX(1, 50, 6, N, N, N, N), - MUX(1, 142, 4, N, N, N, N), - MUX(1, 143, 4, N, N, N, N), - MUX(1, 80, 6, N, N, N, N), -}; - -static struct atlas7_grp_mux audio_func_dbg_grp_mux = { - .pad_mux_count = ARRAY_SIZE(audio_func_dbg_grp_pad_mux), - .pad_mux_list = audio_func_dbg_grp_pad_mux, -}; - -static struct atlas7_pad_mux audio_i2s_grp_pad_mux[] = { - MUX(1, 118, 1, N, N, N, N), - MUX(1, 115, 1, N, N, N, N), - MUX(1, 116, 1, N, N, N, N), - MUX(1, 117, 1, N, N, N, N), - MUX(1, 112, 1, N, N, N, N), - MUX(1, 113, 1, N, N, N, N), - MUX(1, 114, 1, N, N, N, N), -}; - -static struct atlas7_grp_mux audio_i2s_grp_mux = { - .pad_mux_count = ARRAY_SIZE(audio_i2s_grp_pad_mux), - .pad_mux_list = audio_i2s_grp_pad_mux, -}; - -static struct atlas7_pad_mux audio_i2s_2ch_grp_pad_mux[] = { - MUX(1, 118, 1, N, N, N, N), - MUX(1, 115, 1, N, N, N, N), - MUX(1, 112, 1, N, N, N, N), - MUX(1, 113, 1, N, N, N, N), - MUX(1, 114, 1, N, N, N, N), -}; - -static struct atlas7_grp_mux audio_i2s_2ch_grp_mux = { - .pad_mux_count = ARRAY_SIZE(audio_i2s_2ch_grp_pad_mux), - .pad_mux_list = audio_i2s_2ch_grp_pad_mux, -}; - -static struct atlas7_pad_mux audio_i2s_extclk_grp_pad_mux[] = { - MUX(1, 112, 2, N, N, N, N), -}; - -static struct atlas7_grp_mux audio_i2s_extclk_grp_mux = { - .pad_mux_count = ARRAY_SIZE(audio_i2s_extclk_grp_pad_mux), - .pad_mux_list = audio_i2s_extclk_grp_pad_mux, -}; - -static struct atlas7_pad_mux audio_spdif_out_grp0_pad_mux[] = { - MUX(1, 112, 3, N, N, N, N), -}; - -static struct atlas7_grp_mux audio_spdif_out_grp0_mux = { - .pad_mux_count = ARRAY_SIZE(audio_spdif_out_grp0_pad_mux), - .pad_mux_list = audio_spdif_out_grp0_pad_mux, -}; - -static struct atlas7_pad_mux audio_spdif_out_grp1_pad_mux[] = { - MUX(1, 116, 3, N, N, N, N), -}; - -static struct atlas7_grp_mux audio_spdif_out_grp1_mux = { - .pad_mux_count = ARRAY_SIZE(audio_spdif_out_grp1_pad_mux), - .pad_mux_list = audio_spdif_out_grp1_pad_mux, -}; - -static struct atlas7_pad_mux audio_spdif_out_grp2_pad_mux[] = { - MUX(1, 142, 3, N, N, N, N), -}; - -static struct atlas7_grp_mux audio_spdif_out_grp2_mux = { - .pad_mux_count = ARRAY_SIZE(audio_spdif_out_grp2_pad_mux), - .pad_mux_list = audio_spdif_out_grp2_pad_mux, -}; - -static struct atlas7_pad_mux audio_uart0_basic_grp_pad_mux[] = { - MUX(1, 143, 1, N, N, N, N), - MUX(1, 142, 1, N, N, N, N), - MUX(1, 141, 1, N, N, N, N), - MUX(1, 144, 1, N, N, N, N), -}; - -static struct atlas7_grp_mux audio_uart0_basic_grp_mux = { - .pad_mux_count = ARRAY_SIZE(audio_uart0_basic_grp_pad_mux), - .pad_mux_list = audio_uart0_basic_grp_pad_mux, -}; - -static struct atlas7_pad_mux audio_uart0_urfs_grp0_pad_mux[] = { - MUX(1, 117, 5, 0xa10, 28, 0xa90, 28), -}; - -static struct atlas7_grp_mux audio_uart0_urfs_grp0_mux = { - .pad_mux_count = ARRAY_SIZE(audio_uart0_urfs_grp0_pad_mux), - .pad_mux_list = audio_uart0_urfs_grp0_pad_mux, -}; - -static struct atlas7_pad_mux audio_uart0_urfs_grp1_pad_mux[] = { - MUX(1, 139, 3, 0xa10, 28, 0xa90, 28), -}; - -static struct atlas7_grp_mux audio_uart0_urfs_grp1_mux = { - .pad_mux_count = ARRAY_SIZE(audio_uart0_urfs_grp1_pad_mux), - .pad_mux_list = audio_uart0_urfs_grp1_pad_mux, -}; - -static struct atlas7_pad_mux audio_uart0_urfs_grp2_pad_mux[] = { - MUX(1, 163, 3, 0xa10, 28, 0xa90, 28), -}; - -static struct atlas7_grp_mux audio_uart0_urfs_grp2_mux = { - .pad_mux_count = ARRAY_SIZE(audio_uart0_urfs_grp2_pad_mux), - .pad_mux_list = audio_uart0_urfs_grp2_pad_mux, -}; - -static struct atlas7_pad_mux audio_uart0_urfs_grp3_pad_mux[] = { - MUX(1, 162, 6, 0xa10, 28, 0xa90, 28), -}; - -static struct atlas7_grp_mux audio_uart0_urfs_grp3_mux = { - .pad_mux_count = ARRAY_SIZE(audio_uart0_urfs_grp3_pad_mux), - .pad_mux_list = audio_uart0_urfs_grp3_pad_mux, -}; - -static struct atlas7_pad_mux audio_uart1_basic_grp_pad_mux[] = { - MUX(1, 147, 1, 0xa10, 24, 0xa90, 24), - MUX(1, 146, 1, 0xa10, 25, 0xa90, 25), - MUX(1, 145, 1, 0xa10, 23, 0xa90, 23), - MUX(1, 148, 1, 0xa10, 22, 0xa90, 22), -}; - -static struct atlas7_grp_mux audio_uart1_basic_grp_mux = { - .pad_mux_count = ARRAY_SIZE(audio_uart1_basic_grp_pad_mux), - .pad_mux_list = audio_uart1_basic_grp_pad_mux, -}; - -static struct atlas7_pad_mux audio_uart1_urfs_grp0_pad_mux[] = { - MUX(1, 117, 6, 0xa10, 29, 0xa90, 29), -}; - -static struct atlas7_grp_mux audio_uart1_urfs_grp0_mux = { - .pad_mux_count = ARRAY_SIZE(audio_uart1_urfs_grp0_pad_mux), - .pad_mux_list = audio_uart1_urfs_grp0_pad_mux, -}; - -static struct atlas7_pad_mux audio_uart1_urfs_grp1_pad_mux[] = { - MUX(1, 140, 3, 0xa10, 29, 0xa90, 29), -}; - -static struct atlas7_grp_mux audio_uart1_urfs_grp1_mux = { - .pad_mux_count = ARRAY_SIZE(audio_uart1_urfs_grp1_pad_mux), - .pad_mux_list = audio_uart1_urfs_grp1_pad_mux, -}; - -static struct atlas7_pad_mux audio_uart1_urfs_grp2_pad_mux[] = { - MUX(1, 163, 4, 0xa10, 29, 0xa90, 29), -}; - -static struct atlas7_grp_mux audio_uart1_urfs_grp2_mux = { - .pad_mux_count = ARRAY_SIZE(audio_uart1_urfs_grp2_pad_mux), - .pad_mux_list = audio_uart1_urfs_grp2_pad_mux, -}; - -static struct atlas7_pad_mux audio_uart2_urfs_grp0_pad_mux[] = { - MUX(1, 139, 4, 0xa10, 30, 0xa90, 30), -}; - -static struct atlas7_grp_mux audio_uart2_urfs_grp0_mux = { - .pad_mux_count = ARRAY_SIZE(audio_uart2_urfs_grp0_pad_mux), - .pad_mux_list = audio_uart2_urfs_grp0_pad_mux, -}; - -static struct atlas7_pad_mux audio_uart2_urfs_grp1_pad_mux[] = { - MUX(1, 163, 6, 0xa10, 30, 0xa90, 30), -}; - -static struct atlas7_grp_mux audio_uart2_urfs_grp1_mux = { - .pad_mux_count = ARRAY_SIZE(audio_uart2_urfs_grp1_pad_mux), - .pad_mux_list = audio_uart2_urfs_grp1_pad_mux, -}; - -static struct atlas7_pad_mux audio_uart2_urfs_grp2_pad_mux[] = { - MUX(1, 96, 3, 0xa10, 30, 0xa90, 30), -}; - -static struct atlas7_grp_mux audio_uart2_urfs_grp2_mux = { - .pad_mux_count = ARRAY_SIZE(audio_uart2_urfs_grp2_pad_mux), - .pad_mux_list = audio_uart2_urfs_grp2_pad_mux, -}; - -static struct atlas7_pad_mux audio_uart2_urxd_grp0_pad_mux[] = { - MUX(1, 20, 2, 0xa00, 24, 0xa80, 24), -}; - -static struct atlas7_grp_mux audio_uart2_urxd_grp0_mux = { - .pad_mux_count = ARRAY_SIZE(audio_uart2_urxd_grp0_pad_mux), - .pad_mux_list = audio_uart2_urxd_grp0_pad_mux, -}; - -static struct atlas7_pad_mux audio_uart2_urxd_grp1_pad_mux[] = { - MUX(1, 109, 2, 0xa00, 24, 0xa80, 24), -}; - -static struct atlas7_grp_mux audio_uart2_urxd_grp1_mux = { - .pad_mux_count = ARRAY_SIZE(audio_uart2_urxd_grp1_pad_mux), - .pad_mux_list = audio_uart2_urxd_grp1_pad_mux, -}; - -static struct atlas7_pad_mux audio_uart2_urxd_grp2_pad_mux[] = { - MUX(1, 93, 3, 0xa00, 24, 0xa80, 24), -}; - -static struct atlas7_grp_mux audio_uart2_urxd_grp2_mux = { - .pad_mux_count = ARRAY_SIZE(audio_uart2_urxd_grp2_pad_mux), - .pad_mux_list = audio_uart2_urxd_grp2_pad_mux, -}; - -static struct atlas7_pad_mux audio_uart2_usclk_grp0_pad_mux[] = { - MUX(1, 19, 2, 0xa00, 23, 0xa80, 23), -}; - -static struct atlas7_grp_mux audio_uart2_usclk_grp0_mux = { - .pad_mux_count = ARRAY_SIZE(audio_uart2_usclk_grp0_pad_mux), - .pad_mux_list = audio_uart2_usclk_grp0_pad_mux, -}; - -static struct atlas7_pad_mux audio_uart2_usclk_grp1_pad_mux[] = { - MUX(1, 101, 2, 0xa00, 23, 0xa80, 23), -}; - -static struct atlas7_grp_mux audio_uart2_usclk_grp1_mux = { - .pad_mux_count = ARRAY_SIZE(audio_uart2_usclk_grp1_pad_mux), - .pad_mux_list = audio_uart2_usclk_grp1_pad_mux, -}; - -static struct atlas7_pad_mux audio_uart2_usclk_grp2_pad_mux[] = { - MUX(1, 91, 3, 0xa00, 23, 0xa80, 23), -}; - -static struct atlas7_grp_mux audio_uart2_usclk_grp2_mux = { - .pad_mux_count = ARRAY_SIZE(audio_uart2_usclk_grp2_pad_mux), - .pad_mux_list = audio_uart2_usclk_grp2_pad_mux, -}; - -static struct atlas7_pad_mux audio_uart2_utfs_grp0_pad_mux[] = { - MUX(1, 18, 2, 0xa00, 22, 0xa80, 22), -}; - -static struct atlas7_grp_mux audio_uart2_utfs_grp0_mux = { - .pad_mux_count = ARRAY_SIZE(audio_uart2_utfs_grp0_pad_mux), - .pad_mux_list = audio_uart2_utfs_grp0_pad_mux, -}; - -static struct atlas7_pad_mux audio_uart2_utfs_grp1_pad_mux[] = { - MUX(1, 111, 2, 0xa00, 22, 0xa80, 22), -}; - -static struct atlas7_grp_mux audio_uart2_utfs_grp1_mux = { - .pad_mux_count = ARRAY_SIZE(audio_uart2_utfs_grp1_pad_mux), - .pad_mux_list = audio_uart2_utfs_grp1_pad_mux, -}; - -static struct atlas7_pad_mux audio_uart2_utfs_grp2_pad_mux[] = { - MUX(1, 94, 3, 0xa00, 22, 0xa80, 22), -}; - -static struct atlas7_grp_mux audio_uart2_utfs_grp2_mux = { - .pad_mux_count = ARRAY_SIZE(audio_uart2_utfs_grp2_pad_mux), - .pad_mux_list = audio_uart2_utfs_grp2_pad_mux, -}; - -static struct atlas7_pad_mux audio_uart2_utxd_grp0_pad_mux[] = { - MUX(1, 21, 2, 0xa00, 25, 0xa80, 25), -}; - -static struct atlas7_grp_mux audio_uart2_utxd_grp0_mux = { - .pad_mux_count = ARRAY_SIZE(audio_uart2_utxd_grp0_pad_mux), - .pad_mux_list = audio_uart2_utxd_grp0_pad_mux, -}; - -static struct atlas7_pad_mux audio_uart2_utxd_grp1_pad_mux[] = { - MUX(1, 110, 2, 0xa00, 25, 0xa80, 25), -}; - -static struct atlas7_grp_mux audio_uart2_utxd_grp1_mux = { - .pad_mux_count = ARRAY_SIZE(audio_uart2_utxd_grp1_pad_mux), - .pad_mux_list = audio_uart2_utxd_grp1_pad_mux, -}; - -static struct atlas7_pad_mux audio_uart2_utxd_grp2_pad_mux[] = { - MUX(1, 92, 3, 0xa00, 25, 0xa80, 25), -}; - -static struct atlas7_grp_mux audio_uart2_utxd_grp2_mux = { - .pad_mux_count = ARRAY_SIZE(audio_uart2_utxd_grp2_pad_mux), - .pad_mux_list = audio_uart2_utxd_grp2_pad_mux, -}; - -static struct atlas7_pad_mux c_can_trnsvr_en_grp0_pad_mux[] = { - MUX(0, 2, 6, N, N, N, N), -}; - -static struct atlas7_grp_mux c_can_trnsvr_en_grp0_mux = { - .pad_mux_count = ARRAY_SIZE(c_can_trnsvr_en_grp0_pad_mux), - .pad_mux_list = c_can_trnsvr_en_grp0_pad_mux, -}; - -static struct atlas7_pad_mux c_can_trnsvr_en_grp1_pad_mux[] = { - MUX(0, 0, 2, N, N, N, N), -}; - -static struct atlas7_grp_mux c_can_trnsvr_en_grp1_mux = { - .pad_mux_count = ARRAY_SIZE(c_can_trnsvr_en_grp1_pad_mux), - .pad_mux_list = c_can_trnsvr_en_grp1_pad_mux, -}; - -static struct atlas7_pad_mux c_can_trnsvr_intr_grp_pad_mux[] = { - MUX(0, 1, 2, N, N, N, N), -}; - -static struct atlas7_grp_mux c_can_trnsvr_intr_grp_mux = { - .pad_mux_count = ARRAY_SIZE(c_can_trnsvr_intr_grp_pad_mux), - .pad_mux_list = c_can_trnsvr_intr_grp_pad_mux, -}; - -static struct atlas7_pad_mux c_can_trnsvr_stb_n_grp_pad_mux[] = { - MUX(0, 3, 6, N, N, N, N), -}; - -static struct atlas7_grp_mux c_can_trnsvr_stb_n_grp_mux = { - .pad_mux_count = ARRAY_SIZE(c_can_trnsvr_stb_n_grp_pad_mux), - .pad_mux_list = c_can_trnsvr_stb_n_grp_pad_mux, -}; - -static struct atlas7_pad_mux c0_can_rxd_trnsv0_grp_pad_mux[] = { - MUX(0, 11, 1, 0xa08, 9, 0xa88, 9), -}; - -static struct atlas7_grp_mux c0_can_rxd_trnsv0_grp_mux = { - .pad_mux_count = ARRAY_SIZE(c0_can_rxd_trnsv0_grp_pad_mux), - .pad_mux_list = c0_can_rxd_trnsv0_grp_pad_mux, -}; - -static struct atlas7_pad_mux c0_can_rxd_trnsv1_grp_pad_mux[] = { - MUX(0, 2, 5, 0xa10, 9, 0xa90, 9), -}; - -static struct atlas7_grp_mux c0_can_rxd_trnsv1_grp_mux = { - .pad_mux_count = ARRAY_SIZE(c0_can_rxd_trnsv1_grp_pad_mux), - .pad_mux_list = c0_can_rxd_trnsv1_grp_pad_mux, -}; - -static struct atlas7_pad_mux c0_can_txd_trnsv0_grp_pad_mux[] = { - MUX(0, 10, 1, N, N, N, N), -}; - -static struct atlas7_grp_mux c0_can_txd_trnsv0_grp_mux = { - .pad_mux_count = ARRAY_SIZE(c0_can_txd_trnsv0_grp_pad_mux), - .pad_mux_list = c0_can_txd_trnsv0_grp_pad_mux, -}; - -static struct atlas7_pad_mux c0_can_txd_trnsv1_grp_pad_mux[] = { - MUX(0, 3, 5, N, N, N, N), -}; - -static struct atlas7_grp_mux c0_can_txd_trnsv1_grp_mux = { - .pad_mux_count = ARRAY_SIZE(c0_can_txd_trnsv1_grp_pad_mux), - .pad_mux_list = c0_can_txd_trnsv1_grp_pad_mux, -}; - -static struct atlas7_pad_mux c1_can_rxd_grp0_pad_mux[] = { - MUX(1, 138, 2, 0xa00, 4, 0xa80, 4), -}; - -static struct atlas7_grp_mux c1_can_rxd_grp0_mux = { - .pad_mux_count = ARRAY_SIZE(c1_can_rxd_grp0_pad_mux), - .pad_mux_list = c1_can_rxd_grp0_pad_mux, -}; - -static struct atlas7_pad_mux c1_can_rxd_grp1_pad_mux[] = { - MUX(1, 147, 2, 0xa00, 4, 0xa80, 4), -}; - -static struct atlas7_grp_mux c1_can_rxd_grp1_mux = { - .pad_mux_count = ARRAY_SIZE(c1_can_rxd_grp1_pad_mux), - .pad_mux_list = c1_can_rxd_grp1_pad_mux, -}; - -static struct atlas7_pad_mux c1_can_rxd_grp2_pad_mux[] = { - MUX(0, 2, 2, 0xa00, 4, 0xa80, 4), -}; - -static struct atlas7_grp_mux c1_can_rxd_grp2_mux = { - .pad_mux_count = ARRAY_SIZE(c1_can_rxd_grp2_pad_mux), - .pad_mux_list = c1_can_rxd_grp2_pad_mux, -}; - -static struct atlas7_pad_mux c1_can_rxd_grp3_pad_mux[] = { - MUX(1, 162, 4, 0xa00, 4, 0xa80, 4), -}; - -static struct atlas7_grp_mux c1_can_rxd_grp3_mux = { - .pad_mux_count = ARRAY_SIZE(c1_can_rxd_grp3_pad_mux), - .pad_mux_list = c1_can_rxd_grp3_pad_mux, -}; - -static struct atlas7_pad_mux c1_can_txd_grp0_pad_mux[] = { - MUX(1, 137, 2, N, N, N, N), -}; - -static struct atlas7_grp_mux c1_can_txd_grp0_mux = { - .pad_mux_count = ARRAY_SIZE(c1_can_txd_grp0_pad_mux), - .pad_mux_list = c1_can_txd_grp0_pad_mux, -}; - -static struct atlas7_pad_mux c1_can_txd_grp1_pad_mux[] = { - MUX(1, 146, 2, N, N, N, N), -}; - -static struct atlas7_grp_mux c1_can_txd_grp1_mux = { - .pad_mux_count = ARRAY_SIZE(c1_can_txd_grp1_pad_mux), - .pad_mux_list = c1_can_txd_grp1_pad_mux, -}; - -static struct atlas7_pad_mux c1_can_txd_grp2_pad_mux[] = { - MUX(0, 3, 2, N, N, N, N), -}; - -static struct atlas7_grp_mux c1_can_txd_grp2_mux = { - .pad_mux_count = ARRAY_SIZE(c1_can_txd_grp2_pad_mux), - .pad_mux_list = c1_can_txd_grp2_pad_mux, -}; - -static struct atlas7_pad_mux c1_can_txd_grp3_pad_mux[] = { - MUX(1, 161, 4, N, N, N, N), -}; - -static struct atlas7_grp_mux c1_can_txd_grp3_mux = { - .pad_mux_count = ARRAY_SIZE(c1_can_txd_grp3_pad_mux), - .pad_mux_list = c1_can_txd_grp3_pad_mux, -}; - -static struct atlas7_pad_mux ca_audio_lpc_grp_pad_mux[] = { - MUX(1, 62, 4, N, N, N, N), - MUX(1, 63, 4, N, N, N, N), - MUX(1, 64, 4, N, N, N, N), - MUX(1, 65, 4, N, N, N, N), - MUX(1, 66, 4, N, N, N, N), - MUX(1, 67, 4, N, N, N, N), - MUX(1, 68, 4, N, N, N, N), - MUX(1, 69, 4, N, N, N, N), - MUX(1, 70, 4, N, N, N, N), - MUX(1, 71, 4, N, N, N, N), -}; - -static struct atlas7_grp_mux ca_audio_lpc_grp_mux = { - .pad_mux_count = ARRAY_SIZE(ca_audio_lpc_grp_pad_mux), - .pad_mux_list = ca_audio_lpc_grp_pad_mux, -}; - -static struct atlas7_pad_mux ca_bt_lpc_grp_pad_mux[] = { - MUX(1, 85, 5, N, N, N, N), - MUX(1, 86, 5, N, N, N, N), - MUX(1, 87, 5, N, N, N, N), - MUX(1, 88, 5, N, N, N, N), - MUX(1, 89, 5, N, N, N, N), - MUX(1, 90, 5, N, N, N, N), -}; - -static struct atlas7_grp_mux ca_bt_lpc_grp_mux = { - .pad_mux_count = ARRAY_SIZE(ca_bt_lpc_grp_pad_mux), - .pad_mux_list = ca_bt_lpc_grp_pad_mux, -}; - -static struct atlas7_pad_mux ca_coex_grp_pad_mux[] = { - MUX(1, 129, 1, N, N, N, N), - MUX(1, 130, 1, N, N, N, N), - MUX(1, 131, 1, N, N, N, N), - MUX(1, 132, 1, N, N, N, N), -}; - -static struct atlas7_grp_mux ca_coex_grp_mux = { - .pad_mux_count = ARRAY_SIZE(ca_coex_grp_pad_mux), - .pad_mux_list = ca_coex_grp_pad_mux, -}; - -static struct atlas7_pad_mux ca_curator_lpc_grp_pad_mux[] = { - MUX(1, 57, 4, N, N, N, N), - MUX(1, 58, 4, N, N, N, N), - MUX(1, 59, 4, N, N, N, N), - MUX(1, 60, 4, N, N, N, N), -}; - -static struct atlas7_grp_mux ca_curator_lpc_grp_mux = { - .pad_mux_count = ARRAY_SIZE(ca_curator_lpc_grp_pad_mux), - .pad_mux_list = ca_curator_lpc_grp_pad_mux, -}; - -static struct atlas7_pad_mux ca_pcm_debug_grp_pad_mux[] = { - MUX(1, 91, 5, N, N, N, N), - MUX(1, 93, 5, N, N, N, N), - MUX(1, 94, 5, N, N, N, N), - MUX(1, 92, 5, N, N, N, N), -}; - -static struct atlas7_grp_mux ca_pcm_debug_grp_mux = { - .pad_mux_count = ARRAY_SIZE(ca_pcm_debug_grp_pad_mux), - .pad_mux_list = ca_pcm_debug_grp_pad_mux, -}; - -static struct atlas7_pad_mux ca_pio_grp_pad_mux[] = { - MUX(1, 121, 2, N, N, N, N), - MUX(1, 122, 2, N, N, N, N), - MUX(1, 125, 6, N, N, N, N), - MUX(1, 126, 6, N, N, N, N), - MUX(1, 38, 5, N, N, N, N), - MUX(1, 37, 5, N, N, N, N), - MUX(1, 47, 5, N, N, N, N), - MUX(1, 49, 5, N, N, N, N), - MUX(1, 50, 5, N, N, N, N), - MUX(1, 54, 4, N, N, N, N), - MUX(1, 55, 4, N, N, N, N), - MUX(1, 56, 4, N, N, N, N), -}; - -static struct atlas7_grp_mux ca_pio_grp_mux = { - .pad_mux_count = ARRAY_SIZE(ca_pio_grp_pad_mux), - .pad_mux_list = ca_pio_grp_pad_mux, -}; - -static struct atlas7_pad_mux ca_sdio_debug_grp_pad_mux[] = { - MUX(1, 40, 5, N, N, N, N), - MUX(1, 39, 5, N, N, N, N), - MUX(1, 44, 5, N, N, N, N), - MUX(1, 43, 5, N, N, N, N), - MUX(1, 42, 5, N, N, N, N), - MUX(1, 41, 5, N, N, N, N), -}; - -static struct atlas7_grp_mux ca_sdio_debug_grp_mux = { - .pad_mux_count = ARRAY_SIZE(ca_sdio_debug_grp_pad_mux), - .pad_mux_list = ca_sdio_debug_grp_pad_mux, -}; - -static struct atlas7_pad_mux ca_spi_grp_pad_mux[] = { - MUX(1, 82, 5, N, N, N, N), - MUX(1, 79, 5, 0xa08, 6, 0xa88, 6), - MUX(1, 80, 5, N, N, N, N), - MUX(1, 81, 5, N, N, N, N), -}; - -static struct atlas7_grp_mux ca_spi_grp_mux = { - .pad_mux_count = ARRAY_SIZE(ca_spi_grp_pad_mux), - .pad_mux_list = ca_spi_grp_pad_mux, -}; - -static struct atlas7_pad_mux ca_trb_grp_pad_mux[] = { - MUX(1, 91, 4, N, N, N, N), - MUX(1, 93, 4, N, N, N, N), - MUX(1, 94, 4, N, N, N, N), - MUX(1, 95, 4, N, N, N, N), - MUX(1, 96, 4, N, N, N, N), - MUX(1, 78, 5, N, N, N, N), - MUX(1, 74, 5, N, N, N, N), - MUX(1, 75, 5, N, N, N, N), - MUX(1, 76, 5, N, N, N, N), - MUX(1, 77, 5, N, N, N, N), -}; - -static struct atlas7_grp_mux ca_trb_grp_mux = { - .pad_mux_count = ARRAY_SIZE(ca_trb_grp_pad_mux), - .pad_mux_list = ca_trb_grp_pad_mux, -}; - -static struct atlas7_pad_mux ca_uart_debug_grp_pad_mux[] = { - MUX(1, 136, 3, N, N, N, N), - MUX(1, 135, 3, N, N, N, N), - MUX(1, 134, 3, N, N, N, N), - MUX(1, 133, 3, N, N, N, N), -}; - -static struct atlas7_grp_mux ca_uart_debug_grp_mux = { - .pad_mux_count = ARRAY_SIZE(ca_uart_debug_grp_pad_mux), - .pad_mux_list = ca_uart_debug_grp_pad_mux, -}; - -static struct atlas7_pad_mux clkc_grp0_pad_mux[] = { - MUX(1, 30, 2, 0xa08, 14, 0xa88, 14), - MUX(1, 47, 6, N, N, N, N), -}; - -static struct atlas7_grp_mux clkc_grp0_mux = { - .pad_mux_count = ARRAY_SIZE(clkc_grp0_pad_mux), - .pad_mux_list = clkc_grp0_pad_mux, -}; - -static struct atlas7_pad_mux clkc_grp1_pad_mux[] = { - MUX(1, 78, 3, 0xa08, 14, 0xa88, 14), - MUX(1, 54, 5, N, N, N, N), -}; - -static struct atlas7_grp_mux clkc_grp1_mux = { - .pad_mux_count = ARRAY_SIZE(clkc_grp1_pad_mux), - .pad_mux_list = clkc_grp1_pad_mux, -}; - -static struct atlas7_pad_mux gn_gnss_i2c_grp_pad_mux[] = { - MUX(1, 128, 2, N, N, N, N), - MUX(1, 127, 2, N, N, N, N), -}; - -static struct atlas7_grp_mux gn_gnss_i2c_grp_mux = { - .pad_mux_count = ARRAY_SIZE(gn_gnss_i2c_grp_pad_mux), - .pad_mux_list = gn_gnss_i2c_grp_pad_mux, -}; - -static struct atlas7_pad_mux gn_gnss_uart_nopause_grp_pad_mux[] = { - MUX(1, 134, 4, N, N, N, N), - MUX(1, 133, 4, N, N, N, N), -}; - -static struct atlas7_grp_mux gn_gnss_uart_nopause_grp_mux = { - .pad_mux_count = ARRAY_SIZE(gn_gnss_uart_nopause_grp_pad_mux), - .pad_mux_list = gn_gnss_uart_nopause_grp_pad_mux, -}; - -static struct atlas7_pad_mux gn_gnss_uart_grp_pad_mux[] = { - MUX(1, 134, 4, N, N, N, N), - MUX(1, 133, 4, N, N, N, N), - MUX(1, 136, 4, N, N, N, N), - MUX(1, 135, 4, N, N, N, N), -}; - -static struct atlas7_grp_mux gn_gnss_uart_grp_mux = { - .pad_mux_count = ARRAY_SIZE(gn_gnss_uart_grp_pad_mux), - .pad_mux_list = gn_gnss_uart_grp_pad_mux, -}; - -static struct atlas7_pad_mux gn_trg_spi_grp0_pad_mux[] = { - MUX(1, 22, 1, N, N, N, N), - MUX(1, 25, 1, N, N, N, N), - MUX(1, 23, 1, 0xa00, 10, 0xa80, 10), - MUX(1, 24, 1, N, N, N, N), -}; - -static struct atlas7_grp_mux gn_trg_spi_grp0_mux = { - .pad_mux_count = ARRAY_SIZE(gn_trg_spi_grp0_pad_mux), - .pad_mux_list = gn_trg_spi_grp0_pad_mux, -}; - -static struct atlas7_pad_mux gn_trg_spi_grp1_pad_mux[] = { - MUX(1, 82, 3, N, N, N, N), - MUX(1, 79, 3, N, N, N, N), - MUX(1, 80, 3, 0xa00, 10, 0xa80, 10), - MUX(1, 81, 3, N, N, N, N), -}; - -static struct atlas7_grp_mux gn_trg_spi_grp1_mux = { - .pad_mux_count = ARRAY_SIZE(gn_trg_spi_grp1_pad_mux), - .pad_mux_list = gn_trg_spi_grp1_pad_mux, -}; - -static struct atlas7_pad_mux cvbs_dbg_grp_pad_mux[] = { - MUX(1, 54, 3, N, N, N, N), - MUX(1, 53, 3, N, N, N, N), - MUX(1, 82, 7, N, N, N, N), - MUX(1, 74, 7, N, N, N, N), - MUX(1, 75, 7, N, N, N, N), - MUX(1, 76, 7, N, N, N, N), - MUX(1, 77, 7, N, N, N, N), - MUX(1, 78, 7, N, N, N, N), - MUX(1, 79, 7, N, N, N, N), - MUX(1, 80, 7, N, N, N, N), - MUX(1, 81, 7, N, N, N, N), - MUX(1, 83, 7, N, N, N, N), - MUX(1, 84, 7, N, N, N, N), - MUX(1, 73, 3, N, N, N, N), - MUX(1, 55, 3, N, N, N, N), - MUX(1, 56, 3, N, N, N, N), -}; - -static struct atlas7_grp_mux cvbs_dbg_grp_mux = { - .pad_mux_count = ARRAY_SIZE(cvbs_dbg_grp_pad_mux), - .pad_mux_list = cvbs_dbg_grp_pad_mux, -}; - -static struct atlas7_pad_mux cvbs_dbg_test_grp0_pad_mux[] = { - MUX(1, 57, 3, N, N, N, N), -}; - -static struct atlas7_grp_mux cvbs_dbg_test_grp0_mux = { - .pad_mux_count = ARRAY_SIZE(cvbs_dbg_test_grp0_pad_mux), - .pad_mux_list = cvbs_dbg_test_grp0_pad_mux, -}; - -static struct atlas7_pad_mux cvbs_dbg_test_grp1_pad_mux[] = { - MUX(1, 58, 3, N, N, N, N), -}; - -static struct atlas7_grp_mux cvbs_dbg_test_grp1_mux = { - .pad_mux_count = ARRAY_SIZE(cvbs_dbg_test_grp1_pad_mux), - .pad_mux_list = cvbs_dbg_test_grp1_pad_mux, -}; - -static struct atlas7_pad_mux cvbs_dbg_test_grp2_pad_mux[] = { - MUX(1, 59, 3, N, N, N, N), -}; - -static struct atlas7_grp_mux cvbs_dbg_test_grp2_mux = { - .pad_mux_count = ARRAY_SIZE(cvbs_dbg_test_grp2_pad_mux), - .pad_mux_list = cvbs_dbg_test_grp2_pad_mux, -}; - -static struct atlas7_pad_mux cvbs_dbg_test_grp3_pad_mux[] = { - MUX(1, 60, 3, N, N, N, N), -}; - -static struct atlas7_grp_mux cvbs_dbg_test_grp3_mux = { - .pad_mux_count = ARRAY_SIZE(cvbs_dbg_test_grp3_pad_mux), - .pad_mux_list = cvbs_dbg_test_grp3_pad_mux, -}; - -static struct atlas7_pad_mux cvbs_dbg_test_grp4_pad_mux[] = { - MUX(1, 61, 3, N, N, N, N), -}; - -static struct atlas7_grp_mux cvbs_dbg_test_grp4_mux = { - .pad_mux_count = ARRAY_SIZE(cvbs_dbg_test_grp4_pad_mux), - .pad_mux_list = cvbs_dbg_test_grp4_pad_mux, -}; - -static struct atlas7_pad_mux cvbs_dbg_test_grp5_pad_mux[] = { - MUX(1, 62, 3, N, N, N, N), -}; - -static struct atlas7_grp_mux cvbs_dbg_test_grp5_mux = { - .pad_mux_count = ARRAY_SIZE(cvbs_dbg_test_grp5_pad_mux), - .pad_mux_list = cvbs_dbg_test_grp5_pad_mux, -}; - -static struct atlas7_pad_mux cvbs_dbg_test_grp6_pad_mux[] = { - MUX(1, 63, 3, N, N, N, N), -}; - -static struct atlas7_grp_mux cvbs_dbg_test_grp6_mux = { - .pad_mux_count = ARRAY_SIZE(cvbs_dbg_test_grp6_pad_mux), - .pad_mux_list = cvbs_dbg_test_grp6_pad_mux, -}; - -static struct atlas7_pad_mux cvbs_dbg_test_grp7_pad_mux[] = { - MUX(1, 64, 3, N, N, N, N), -}; - -static struct atlas7_grp_mux cvbs_dbg_test_grp7_mux = { - .pad_mux_count = ARRAY_SIZE(cvbs_dbg_test_grp7_pad_mux), - .pad_mux_list = cvbs_dbg_test_grp7_pad_mux, -}; - -static struct atlas7_pad_mux cvbs_dbg_test_grp8_pad_mux[] = { - MUX(1, 65, 3, N, N, N, N), -}; - -static struct atlas7_grp_mux cvbs_dbg_test_grp8_mux = { - .pad_mux_count = ARRAY_SIZE(cvbs_dbg_test_grp8_pad_mux), - .pad_mux_list = cvbs_dbg_test_grp8_pad_mux, -}; - -static struct atlas7_pad_mux cvbs_dbg_test_grp9_pad_mux[] = { - MUX(1, 66, 3, N, N, N, N), -}; - -static struct atlas7_grp_mux cvbs_dbg_test_grp9_mux = { - .pad_mux_count = ARRAY_SIZE(cvbs_dbg_test_grp9_pad_mux), - .pad_mux_list = cvbs_dbg_test_grp9_pad_mux, -}; - -static struct atlas7_pad_mux cvbs_dbg_test_grp10_pad_mux[] = { - MUX(1, 67, 3, N, N, N, N), -}; - -static struct atlas7_grp_mux cvbs_dbg_test_grp10_mux = { - .pad_mux_count = ARRAY_SIZE(cvbs_dbg_test_grp10_pad_mux), - .pad_mux_list = cvbs_dbg_test_grp10_pad_mux, -}; - -static struct atlas7_pad_mux cvbs_dbg_test_grp11_pad_mux[] = { - MUX(1, 68, 3, N, N, N, N), -}; - -static struct atlas7_grp_mux cvbs_dbg_test_grp11_mux = { - .pad_mux_count = ARRAY_SIZE(cvbs_dbg_test_grp11_pad_mux), - .pad_mux_list = cvbs_dbg_test_grp11_pad_mux, -}; - -static struct atlas7_pad_mux cvbs_dbg_test_grp12_pad_mux[] = { - MUX(1, 69, 3, N, N, N, N), -}; - -static struct atlas7_grp_mux cvbs_dbg_test_grp12_mux = { - .pad_mux_count = ARRAY_SIZE(cvbs_dbg_test_grp12_pad_mux), - .pad_mux_list = cvbs_dbg_test_grp12_pad_mux, -}; - -static struct atlas7_pad_mux cvbs_dbg_test_grp13_pad_mux[] = { - MUX(1, 70, 3, N, N, N, N), -}; - -static struct atlas7_grp_mux cvbs_dbg_test_grp13_mux = { - .pad_mux_count = ARRAY_SIZE(cvbs_dbg_test_grp13_pad_mux), - .pad_mux_list = cvbs_dbg_test_grp13_pad_mux, -}; - -static struct atlas7_pad_mux cvbs_dbg_test_grp14_pad_mux[] = { - MUX(1, 71, 3, N, N, N, N), -}; - -static struct atlas7_grp_mux cvbs_dbg_test_grp14_mux = { - .pad_mux_count = ARRAY_SIZE(cvbs_dbg_test_grp14_pad_mux), - .pad_mux_list = cvbs_dbg_test_grp14_pad_mux, -}; - -static struct atlas7_pad_mux cvbs_dbg_test_grp15_pad_mux[] = { - MUX(1, 72, 3, N, N, N, N), -}; - -static struct atlas7_grp_mux cvbs_dbg_test_grp15_mux = { - .pad_mux_count = ARRAY_SIZE(cvbs_dbg_test_grp15_pad_mux), - .pad_mux_list = cvbs_dbg_test_grp15_pad_mux, -}; - -static struct atlas7_pad_mux gn_gnss_power_grp_pad_mux[] = { - MUX(1, 123, 7, N, N, N, N), - MUX(1, 124, 7, N, N, N, N), - MUX(1, 121, 7, N, N, N, N), - MUX(1, 122, 7, N, N, N, N), - MUX(1, 125, 7, N, N, N, N), - MUX(1, 120, 7, N, N, N, N), -}; - -static struct atlas7_grp_mux gn_gnss_power_grp_mux = { - .pad_mux_count = ARRAY_SIZE(gn_gnss_power_grp_pad_mux), - .pad_mux_list = gn_gnss_power_grp_pad_mux, -}; - -static struct atlas7_pad_mux gn_gnss_sw_status_grp_pad_mux[] = { - MUX(1, 57, 7, N, N, N, N), - MUX(1, 58, 7, N, N, N, N), - MUX(1, 59, 7, N, N, N, N), - MUX(1, 60, 7, N, N, N, N), - MUX(1, 61, 7, N, N, N, N), - MUX(1, 62, 7, N, N, N, N), - MUX(1, 63, 7, N, N, N, N), - MUX(1, 64, 7, N, N, N, N), - MUX(1, 65, 7, N, N, N, N), - MUX(1, 66, 7, N, N, N, N), - MUX(1, 67, 7, N, N, N, N), - MUX(1, 68, 7, N, N, N, N), - MUX(1, 69, 7, N, N, N, N), - MUX(1, 70, 7, N, N, N, N), - MUX(1, 71, 7, N, N, N, N), - MUX(1, 72, 7, N, N, N, N), - MUX(1, 53, 7, N, N, N, N), - MUX(1, 55, 7, N, N, N, N), - MUX(1, 56, 7, 0xa08, 12, 0xa88, 12), - MUX(1, 54, 7, N, N, N, N), -}; - -static struct atlas7_grp_mux gn_gnss_sw_status_grp_mux = { - .pad_mux_count = ARRAY_SIZE(gn_gnss_sw_status_grp_pad_mux), - .pad_mux_list = gn_gnss_sw_status_grp_pad_mux, -}; - -static struct atlas7_pad_mux gn_gnss_eclk_grp_pad_mux[] = { - MUX(1, 113, 4, N, N, N, N), -}; - -static struct atlas7_grp_mux gn_gnss_eclk_grp_mux = { - .pad_mux_count = ARRAY_SIZE(gn_gnss_eclk_grp_pad_mux), - .pad_mux_list = gn_gnss_eclk_grp_pad_mux, -}; - -static struct atlas7_pad_mux gn_gnss_irq1_grp0_pad_mux[] = { - MUX(1, 112, 4, 0xa08, 10, 0xa88, 10), -}; - -static struct atlas7_grp_mux gn_gnss_irq1_grp0_mux = { - .pad_mux_count = ARRAY_SIZE(gn_gnss_irq1_grp0_pad_mux), - .pad_mux_list = gn_gnss_irq1_grp0_pad_mux, -}; - -static struct atlas7_pad_mux gn_gnss_irq2_grp0_pad_mux[] = { - MUX(1, 118, 4, 0xa08, 11, 0xa88, 11), -}; - -static struct atlas7_grp_mux gn_gnss_irq2_grp0_mux = { - .pad_mux_count = ARRAY_SIZE(gn_gnss_irq2_grp0_pad_mux), - .pad_mux_list = gn_gnss_irq2_grp0_pad_mux, -}; - -static struct atlas7_pad_mux gn_gnss_tm_grp_pad_mux[] = { - MUX(1, 115, 4, N, N, N, N), -}; - -static struct atlas7_grp_mux gn_gnss_tm_grp_mux = { - .pad_mux_count = ARRAY_SIZE(gn_gnss_tm_grp_pad_mux), - .pad_mux_list = gn_gnss_tm_grp_pad_mux, -}; - -static struct atlas7_pad_mux gn_gnss_tsync_grp_pad_mux[] = { - MUX(1, 114, 4, N, N, N, N), -}; - -static struct atlas7_grp_mux gn_gnss_tsync_grp_mux = { - .pad_mux_count = ARRAY_SIZE(gn_gnss_tsync_grp_pad_mux), - .pad_mux_list = gn_gnss_tsync_grp_pad_mux, -}; - -static struct atlas7_pad_mux gn_io_gnsssys_sw_cfg_grp_pad_mux[] = { - MUX(1, 44, 7, N, N, N, N), - MUX(1, 43, 7, N, N, N, N), - MUX(1, 42, 7, N, N, N, N), - MUX(1, 41, 7, N, N, N, N), - MUX(1, 40, 7, N, N, N, N), - MUX(1, 39, 7, N, N, N, N), - MUX(1, 38, 7, N, N, N, N), - MUX(1, 37, 7, N, N, N, N), - MUX(1, 49, 7, N, N, N, N), - MUX(1, 50, 7, N, N, N, N), - MUX(1, 91, 7, N, N, N, N), - MUX(1, 92, 7, N, N, N, N), - MUX(1, 93, 7, N, N, N, N), - MUX(1, 94, 7, N, N, N, N), - MUX(1, 95, 7, N, N, N, N), - MUX(1, 96, 7, N, N, N, N), -}; - -static struct atlas7_grp_mux gn_io_gnsssys_sw_cfg_grp_mux = { - .pad_mux_count = ARRAY_SIZE(gn_io_gnsssys_sw_cfg_grp_pad_mux), - .pad_mux_list = gn_io_gnsssys_sw_cfg_grp_pad_mux, -}; - -static struct atlas7_pad_mux gn_trg_grp0_pad_mux[] = { - MUX(1, 29, 1, 0xa00, 6, 0xa80, 6), - MUX(1, 28, 1, 0xa00, 7, 0xa80, 7), - MUX(1, 26, 1, 0xa00, 8, 0xa80, 8), - MUX(1, 27, 1, 0xa00, 9, 0xa80, 9), -}; - -static struct atlas7_grp_mux gn_trg_grp0_mux = { - .pad_mux_count = ARRAY_SIZE(gn_trg_grp0_pad_mux), - .pad_mux_list = gn_trg_grp0_pad_mux, -}; - -static struct atlas7_pad_mux gn_trg_grp1_pad_mux[] = { - MUX(1, 77, 3, 0xa00, 6, 0xa80, 6), - MUX(1, 76, 3, 0xa00, 7, 0xa80, 7), - MUX(1, 74, 3, 0xa00, 8, 0xa80, 8), - MUX(1, 75, 3, 0xa00, 9, 0xa80, 9), -}; - -static struct atlas7_grp_mux gn_trg_grp1_mux = { - .pad_mux_count = ARRAY_SIZE(gn_trg_grp1_pad_mux), - .pad_mux_list = gn_trg_grp1_pad_mux, -}; - -static struct atlas7_pad_mux gn_trg_shutdown_grp0_pad_mux[] = { - MUX(1, 30, 1, N, N, N, N), -}; - -static struct atlas7_grp_mux gn_trg_shutdown_grp0_mux = { - .pad_mux_count = ARRAY_SIZE(gn_trg_shutdown_grp0_pad_mux), - .pad_mux_list = gn_trg_shutdown_grp0_pad_mux, -}; - -static struct atlas7_pad_mux gn_trg_shutdown_grp1_pad_mux[] = { - MUX(1, 83, 3, N, N, N, N), -}; - -static struct atlas7_grp_mux gn_trg_shutdown_grp1_mux = { - .pad_mux_count = ARRAY_SIZE(gn_trg_shutdown_grp1_pad_mux), - .pad_mux_list = gn_trg_shutdown_grp1_pad_mux, -}; - -static struct atlas7_pad_mux gn_trg_shutdown_grp2_pad_mux[] = { - MUX(1, 117, 4, N, N, N, N), -}; - -static struct atlas7_grp_mux gn_trg_shutdown_grp2_mux = { - .pad_mux_count = ARRAY_SIZE(gn_trg_shutdown_grp2_pad_mux), - .pad_mux_list = gn_trg_shutdown_grp2_pad_mux, -}; - -static struct atlas7_pad_mux gn_trg_shutdown_grp3_pad_mux[] = { - MUX(1, 123, 5, N, N, N, N), -}; - -static struct atlas7_grp_mux gn_trg_shutdown_grp3_mux = { - .pad_mux_count = ARRAY_SIZE(gn_trg_shutdown_grp3_pad_mux), - .pad_mux_list = gn_trg_shutdown_grp3_pad_mux, -}; - -static struct atlas7_pad_mux i2c0_grp_pad_mux[] = { - MUX(1, 128, 1, N, N, N, N), - MUX(1, 127, 1, N, N, N, N), -}; - -static struct atlas7_grp_mux i2c0_grp_mux = { - .pad_mux_count = ARRAY_SIZE(i2c0_grp_pad_mux), - .pad_mux_list = i2c0_grp_pad_mux, -}; - -static struct atlas7_pad_mux i2c1_grp_pad_mux[] = { - MUX(1, 126, 4, N, N, N, N), - MUX(1, 125, 4, N, N, N, N), -}; - -static struct atlas7_grp_mux i2c1_grp_mux = { - .pad_mux_count = ARRAY_SIZE(i2c1_grp_pad_mux), - .pad_mux_list = i2c1_grp_pad_mux, -}; - -static struct atlas7_pad_mux i2s0_grp_pad_mux[] = { - MUX(1, 91, 2, 0xa10, 12, 0xa90, 12), - MUX(1, 93, 2, 0xa10, 13, 0xa90, 13), - MUX(1, 94, 2, 0xa10, 14, 0xa90, 14), - MUX(1, 92, 2, 0xa10, 15, 0xa90, 15), -}; - -static struct atlas7_grp_mux i2s0_grp_mux = { - .pad_mux_count = ARRAY_SIZE(i2s0_grp_pad_mux), - .pad_mux_list = i2s0_grp_pad_mux, -}; - -static struct atlas7_pad_mux i2s1_basic_grp_pad_mux[] = { - MUX(1, 95, 2, 0xa10, 16, 0xa90, 16), - MUX(1, 96, 2, 0xa10, 19, 0xa90, 19), -}; - -static struct atlas7_grp_mux i2s1_basic_grp_mux = { - .pad_mux_count = ARRAY_SIZE(i2s1_basic_grp_pad_mux), - .pad_mux_list = i2s1_basic_grp_pad_mux, -}; - -static struct atlas7_pad_mux i2s1_rxd0_grp0_pad_mux[] = { - MUX(1, 61, 4, 0xa10, 17, 0xa90, 17), -}; - -static struct atlas7_grp_mux i2s1_rxd0_grp0_mux = { - .pad_mux_count = ARRAY_SIZE(i2s1_rxd0_grp0_pad_mux), - .pad_mux_list = i2s1_rxd0_grp0_pad_mux, -}; - -static struct atlas7_pad_mux i2s1_rxd0_grp1_pad_mux[] = { - MUX(1, 131, 4, 0xa10, 17, 0xa90, 17), -}; - -static struct atlas7_grp_mux i2s1_rxd0_grp1_mux = { - .pad_mux_count = ARRAY_SIZE(i2s1_rxd0_grp1_pad_mux), - .pad_mux_list = i2s1_rxd0_grp1_pad_mux, -}; - -static struct atlas7_pad_mux i2s1_rxd0_grp2_pad_mux[] = { - MUX(1, 129, 2, 0xa10, 17, 0xa90, 17), -}; - -static struct atlas7_grp_mux i2s1_rxd0_grp2_mux = { - .pad_mux_count = ARRAY_SIZE(i2s1_rxd0_grp2_pad_mux), - .pad_mux_list = i2s1_rxd0_grp2_pad_mux, -}; - -static struct atlas7_pad_mux i2s1_rxd0_grp3_pad_mux[] = { - MUX(1, 117, 7, 0xa10, 17, 0xa90, 17), -}; - -static struct atlas7_grp_mux i2s1_rxd0_grp3_mux = { - .pad_mux_count = ARRAY_SIZE(i2s1_rxd0_grp3_pad_mux), - .pad_mux_list = i2s1_rxd0_grp3_pad_mux, -}; - -static struct atlas7_pad_mux i2s1_rxd0_grp4_pad_mux[] = { - MUX(1, 83, 4, 0xa10, 17, 0xa90, 17), -}; - -static struct atlas7_grp_mux i2s1_rxd0_grp4_mux = { - .pad_mux_count = ARRAY_SIZE(i2s1_rxd0_grp4_pad_mux), - .pad_mux_list = i2s1_rxd0_grp4_pad_mux, -}; - -static struct atlas7_pad_mux i2s1_rxd1_grp0_pad_mux[] = { - MUX(1, 72, 4, 0xa10, 18, 0xa90, 18), -}; - -static struct atlas7_grp_mux i2s1_rxd1_grp0_mux = { - .pad_mux_count = ARRAY_SIZE(i2s1_rxd1_grp0_pad_mux), - .pad_mux_list = i2s1_rxd1_grp0_pad_mux, -}; - -static struct atlas7_pad_mux i2s1_rxd1_grp1_pad_mux[] = { - MUX(1, 132, 4, 0xa10, 18, 0xa90, 18), -}; - -static struct atlas7_grp_mux i2s1_rxd1_grp1_mux = { - .pad_mux_count = ARRAY_SIZE(i2s1_rxd1_grp1_pad_mux), - .pad_mux_list = i2s1_rxd1_grp1_pad_mux, -}; - -static struct atlas7_pad_mux i2s1_rxd1_grp2_pad_mux[] = { - MUX(1, 130, 2, 0xa10, 18, 0xa90, 18), -}; - -static struct atlas7_grp_mux i2s1_rxd1_grp2_mux = { - .pad_mux_count = ARRAY_SIZE(i2s1_rxd1_grp2_pad_mux), - .pad_mux_list = i2s1_rxd1_grp2_pad_mux, -}; - -static struct atlas7_pad_mux i2s1_rxd1_grp3_pad_mux[] = { - MUX(1, 118, 7, 0xa10, 18, 0xa90, 18), -}; - -static struct atlas7_grp_mux i2s1_rxd1_grp3_mux = { - .pad_mux_count = ARRAY_SIZE(i2s1_rxd1_grp3_pad_mux), - .pad_mux_list = i2s1_rxd1_grp3_pad_mux, -}; - -static struct atlas7_pad_mux i2s1_rxd1_grp4_pad_mux[] = { - MUX(1, 84, 4, 0xa10, 18, 0xa90, 18), -}; - -static struct atlas7_grp_mux i2s1_rxd1_grp4_mux = { - .pad_mux_count = ARRAY_SIZE(i2s1_rxd1_grp4_pad_mux), - .pad_mux_list = i2s1_rxd1_grp4_pad_mux, -}; - -static struct atlas7_pad_mux jtag_jt_dbg_nsrst_grp_pad_mux[] = { - MUX(1, 125, 5, 0xa08, 2, 0xa88, 2), -}; - -static struct atlas7_grp_mux jtag_jt_dbg_nsrst_grp_mux = { - .pad_mux_count = ARRAY_SIZE(jtag_jt_dbg_nsrst_grp_pad_mux), - .pad_mux_list = jtag_jt_dbg_nsrst_grp_pad_mux, -}; - -static struct atlas7_pad_mux jtag_ntrst_grp0_pad_mux[] = { - MUX(0, 4, 3, 0xa08, 3, 0xa88, 3), -}; - -static struct atlas7_grp_mux jtag_ntrst_grp0_mux = { - .pad_mux_count = ARRAY_SIZE(jtag_ntrst_grp0_pad_mux), - .pad_mux_list = jtag_ntrst_grp0_pad_mux, -}; - -static struct atlas7_pad_mux jtag_ntrst_grp1_pad_mux[] = { - MUX(1, 163, 1, 0xa08, 3, 0xa88, 3), -}; - -static struct atlas7_grp_mux jtag_ntrst_grp1_mux = { - .pad_mux_count = ARRAY_SIZE(jtag_ntrst_grp1_pad_mux), - .pad_mux_list = jtag_ntrst_grp1_pad_mux, -}; - -static struct atlas7_pad_mux jtag_swdiotms_grp0_pad_mux[] = { - MUX(0, 2, 3, 0xa10, 10, 0xa90, 10), -}; - -static struct atlas7_grp_mux jtag_swdiotms_grp0_mux = { - .pad_mux_count = ARRAY_SIZE(jtag_swdiotms_grp0_pad_mux), - .pad_mux_list = jtag_swdiotms_grp0_pad_mux, -}; - -static struct atlas7_pad_mux jtag_swdiotms_grp1_pad_mux[] = { - MUX(1, 160, 1, 0xa10, 10, 0xa90, 10), -}; - -static struct atlas7_grp_mux jtag_swdiotms_grp1_mux = { - .pad_mux_count = ARRAY_SIZE(jtag_swdiotms_grp1_pad_mux), - .pad_mux_list = jtag_swdiotms_grp1_pad_mux, -}; - -static struct atlas7_pad_mux jtag_tck_grp0_pad_mux[] = { - MUX(0, 0, 3, 0xa10, 11, 0xa90, 11), -}; - -static struct atlas7_grp_mux jtag_tck_grp0_mux = { - .pad_mux_count = ARRAY_SIZE(jtag_tck_grp0_pad_mux), - .pad_mux_list = jtag_tck_grp0_pad_mux, -}; - -static struct atlas7_pad_mux jtag_tck_grp1_pad_mux[] = { - MUX(1, 161, 1, 0xa10, 11, 0xa90, 11), -}; - -static struct atlas7_grp_mux jtag_tck_grp1_mux = { - .pad_mux_count = ARRAY_SIZE(jtag_tck_grp1_pad_mux), - .pad_mux_list = jtag_tck_grp1_pad_mux, -}; - -static struct atlas7_pad_mux jtag_tdi_grp0_pad_mux[] = { - MUX(0, 1, 3, 0xa10, 31, 0xa90, 31), -}; - -static struct atlas7_grp_mux jtag_tdi_grp0_mux = { - .pad_mux_count = ARRAY_SIZE(jtag_tdi_grp0_pad_mux), - .pad_mux_list = jtag_tdi_grp0_pad_mux, -}; - -static struct atlas7_pad_mux jtag_tdi_grp1_pad_mux[] = { - MUX(1, 162, 1, 0xa10, 31, 0xa90, 31), -}; - -static struct atlas7_grp_mux jtag_tdi_grp1_mux = { - .pad_mux_count = ARRAY_SIZE(jtag_tdi_grp1_pad_mux), - .pad_mux_list = jtag_tdi_grp1_pad_mux, -}; - -static struct atlas7_pad_mux jtag_tdo_grp0_pad_mux[] = { - MUX(0, 3, 3, N, N, N, N), -}; - -static struct atlas7_grp_mux jtag_tdo_grp0_mux = { - .pad_mux_count = ARRAY_SIZE(jtag_tdo_grp0_pad_mux), - .pad_mux_list = jtag_tdo_grp0_pad_mux, -}; - -static struct atlas7_pad_mux jtag_tdo_grp1_pad_mux[] = { - MUX(1, 159, 1, N, N, N, N), -}; - -static struct atlas7_grp_mux jtag_tdo_grp1_mux = { - .pad_mux_count = ARRAY_SIZE(jtag_tdo_grp1_pad_mux), - .pad_mux_list = jtag_tdo_grp1_pad_mux, -}; - -static struct atlas7_pad_mux ks_kas_spi_grp0_pad_mux[] = { - MUX(1, 141, 2, N, N, N, N), - MUX(1, 144, 2, 0xa08, 8, 0xa88, 8), - MUX(1, 143, 2, N, N, N, N), - MUX(1, 142, 2, N, N, N, N), -}; - -static struct atlas7_grp_mux ks_kas_spi_grp0_mux = { - .pad_mux_count = ARRAY_SIZE(ks_kas_spi_grp0_pad_mux), - .pad_mux_list = ks_kas_spi_grp0_pad_mux, -}; - -static struct atlas7_pad_mux ld_ldd_grp_pad_mux[] = { - MUX(1, 57, 1, N, N, N, N), - MUX(1, 58, 1, N, N, N, N), - MUX(1, 59, 1, N, N, N, N), - MUX(1, 60, 1, N, N, N, N), - MUX(1, 61, 1, N, N, N, N), - MUX(1, 62, 1, N, N, N, N), - MUX(1, 63, 1, N, N, N, N), - MUX(1, 64, 1, N, N, N, N), - MUX(1, 65, 1, N, N, N, N), - MUX(1, 66, 1, N, N, N, N), - MUX(1, 67, 1, N, N, N, N), - MUX(1, 68, 1, N, N, N, N), - MUX(1, 69, 1, N, N, N, N), - MUX(1, 70, 1, N, N, N, N), - MUX(1, 71, 1, N, N, N, N), - MUX(1, 72, 1, N, N, N, N), - MUX(1, 74, 2, N, N, N, N), - MUX(1, 75, 2, N, N, N, N), - MUX(1, 76, 2, N, N, N, N), - MUX(1, 77, 2, N, N, N, N), - MUX(1, 78, 2, N, N, N, N), - MUX(1, 79, 2, N, N, N, N), - MUX(1, 80, 2, N, N, N, N), - MUX(1, 81, 2, N, N, N, N), - MUX(1, 56, 1, N, N, N, N), - MUX(1, 53, 1, N, N, N, N), -}; - -static struct atlas7_grp_mux ld_ldd_grp_mux = { - .pad_mux_count = ARRAY_SIZE(ld_ldd_grp_pad_mux), - .pad_mux_list = ld_ldd_grp_pad_mux, -}; - -static struct atlas7_pad_mux ld_ldd_16bit_grp_pad_mux[] = { - MUX(1, 57, 1, N, N, N, N), - MUX(1, 58, 1, N, N, N, N), - MUX(1, 59, 1, N, N, N, N), - MUX(1, 60, 1, N, N, N, N), - MUX(1, 61, 1, N, N, N, N), - MUX(1, 62, 1, N, N, N, N), - MUX(1, 63, 1, N, N, N, N), - MUX(1, 64, 1, N, N, N, N), - MUX(1, 65, 1, N, N, N, N), - MUX(1, 66, 1, N, N, N, N), - MUX(1, 67, 1, N, N, N, N), - MUX(1, 68, 1, N, N, N, N), - MUX(1, 69, 1, N, N, N, N), - MUX(1, 70, 1, N, N, N, N), - MUX(1, 71, 1, N, N, N, N), - MUX(1, 72, 1, N, N, N, N), - MUX(1, 56, 1, N, N, N, N), - MUX(1, 53, 1, N, N, N, N), -}; - -static struct atlas7_grp_mux ld_ldd_16bit_grp_mux = { - .pad_mux_count = ARRAY_SIZE(ld_ldd_16bit_grp_pad_mux), - .pad_mux_list = ld_ldd_16bit_grp_pad_mux, -}; - -static struct atlas7_pad_mux ld_ldd_fck_grp_pad_mux[] = { - MUX(1, 55, 1, N, N, N, N), -}; - -static struct atlas7_grp_mux ld_ldd_fck_grp_mux = { - .pad_mux_count = ARRAY_SIZE(ld_ldd_fck_grp_pad_mux), - .pad_mux_list = ld_ldd_fck_grp_pad_mux, -}; - -static struct atlas7_pad_mux ld_ldd_lck_grp_pad_mux[] = { - MUX(1, 54, 1, N, N, N, N), -}; - -static struct atlas7_grp_mux ld_ldd_lck_grp_mux = { - .pad_mux_count = ARRAY_SIZE(ld_ldd_lck_grp_pad_mux), - .pad_mux_list = ld_ldd_lck_grp_pad_mux, -}; - -static struct atlas7_pad_mux lr_lcdrom_grp_pad_mux[] = { - MUX(1, 73, 2, N, N, N, N), - MUX(1, 54, 2, N, N, N, N), - MUX(1, 57, 2, N, N, N, N), - MUX(1, 58, 2, N, N, N, N), - MUX(1, 59, 2, N, N, N, N), - MUX(1, 60, 2, N, N, N, N), - MUX(1, 61, 2, N, N, N, N), - MUX(1, 62, 2, N, N, N, N), - MUX(1, 63, 2, N, N, N, N), - MUX(1, 64, 2, N, N, N, N), - MUX(1, 65, 2, N, N, N, N), - MUX(1, 66, 2, N, N, N, N), - MUX(1, 67, 2, N, N, N, N), - MUX(1, 68, 2, N, N, N, N), - MUX(1, 69, 2, N, N, N, N), - MUX(1, 70, 2, N, N, N, N), - MUX(1, 71, 2, N, N, N, N), - MUX(1, 72, 2, N, N, N, N), - MUX(1, 56, 2, N, N, N, N), - MUX(1, 53, 2, N, N, N, N), - MUX(1, 55, 2, N, N, N, N), -}; - -static struct atlas7_grp_mux lr_lcdrom_grp_mux = { - .pad_mux_count = ARRAY_SIZE(lr_lcdrom_grp_pad_mux), - .pad_mux_list = lr_lcdrom_grp_pad_mux, -}; - -static struct atlas7_pad_mux lvds_analog_grp_pad_mux[] = { - MUX(1, 149, 8, N, N, N, N), - MUX(1, 150, 8, N, N, N, N), - MUX(1, 151, 8, N, N, N, N), - MUX(1, 152, 8, N, N, N, N), - MUX(1, 153, 8, N, N, N, N), - MUX(1, 154, 8, N, N, N, N), - MUX(1, 155, 8, N, N, N, N), - MUX(1, 156, 8, N, N, N, N), - MUX(1, 157, 8, N, N, N, N), - MUX(1, 158, 8, N, N, N, N), -}; - -static struct atlas7_grp_mux lvds_analog_grp_mux = { - .pad_mux_count = ARRAY_SIZE(lvds_analog_grp_pad_mux), - .pad_mux_list = lvds_analog_grp_pad_mux, -}; - -static struct atlas7_pad_mux nd_df_basic_grp_pad_mux[] = { - MUX(1, 44, 1, N, N, N, N), - MUX(1, 43, 1, N, N, N, N), - MUX(1, 42, 1, N, N, N, N), - MUX(1, 41, 1, N, N, N, N), - MUX(1, 40, 1, N, N, N, N), - MUX(1, 39, 1, N, N, N, N), - MUX(1, 38, 1, N, N, N, N), - MUX(1, 37, 1, N, N, N, N), - MUX(1, 47, 1, N, N, N, N), - MUX(1, 46, 1, N, N, N, N), - MUX(1, 52, 1, N, N, N, N), - MUX(1, 45, 1, N, N, N, N), - MUX(1, 49, 1, N, N, N, N), - MUX(1, 50, 1, N, N, N, N), - MUX(1, 48, 1, N, N, N, N), -}; - -static struct atlas7_grp_mux nd_df_basic_grp_mux = { - .pad_mux_count = ARRAY_SIZE(nd_df_basic_grp_pad_mux), - .pad_mux_list = nd_df_basic_grp_pad_mux, -}; - -static struct atlas7_pad_mux nd_df_wp_grp_pad_mux[] = { - MUX(1, 124, 4, N, N, N, N), -}; - -static struct atlas7_grp_mux nd_df_wp_grp_mux = { - .pad_mux_count = ARRAY_SIZE(nd_df_wp_grp_pad_mux), - .pad_mux_list = nd_df_wp_grp_pad_mux, -}; - -static struct atlas7_pad_mux nd_df_cs_grp_pad_mux[] = { - MUX(1, 51, 1, N, N, N, N), -}; - -static struct atlas7_grp_mux nd_df_cs_grp_mux = { - .pad_mux_count = ARRAY_SIZE(nd_df_cs_grp_pad_mux), - .pad_mux_list = nd_df_cs_grp_pad_mux, -}; - -static struct atlas7_pad_mux ps_grp_pad_mux[] = { - MUX(1, 120, 2, N, N, N, N), - MUX(1, 119, 2, N, N, N, N), - MUX(1, 121, 5, N, N, N, N), -}; - -static struct atlas7_grp_mux ps_grp_mux = { - .pad_mux_count = ARRAY_SIZE(ps_grp_pad_mux), - .pad_mux_list = ps_grp_pad_mux, -}; - -static struct atlas7_pad_mux ps_no_dir_grp_pad_mux[] = { - MUX(1, 119, 2, N, N, N, N), -}; - -static struct atlas7_grp_mux ps_no_dir_grp_mux = { - .pad_mux_count = ARRAY_SIZE(ps_no_dir_grp_pad_mux), - .pad_mux_list = ps_no_dir_grp_pad_mux, -}; - -static struct atlas7_pad_mux pwc_core_on_grp_pad_mux[] = { - MUX(0, 8, 1, N, N, N, N), -}; - -static struct atlas7_grp_mux pwc_core_on_grp_mux = { - .pad_mux_count = ARRAY_SIZE(pwc_core_on_grp_pad_mux), - .pad_mux_list = pwc_core_on_grp_pad_mux, -}; - -static struct atlas7_pad_mux pwc_ext_on_grp_pad_mux[] = { - MUX(0, 6, 1, N, N, N, N), -}; - -static struct atlas7_grp_mux pwc_ext_on_grp_mux = { - .pad_mux_count = ARRAY_SIZE(pwc_ext_on_grp_pad_mux), - .pad_mux_list = pwc_ext_on_grp_pad_mux, -}; - -static struct atlas7_pad_mux pwc_gpio3_clk_grp_pad_mux[] = { - MUX(0, 3, 4, N, N, N, N), -}; - -static struct atlas7_grp_mux pwc_gpio3_clk_grp_mux = { - .pad_mux_count = ARRAY_SIZE(pwc_gpio3_clk_grp_pad_mux), - .pad_mux_list = pwc_gpio3_clk_grp_pad_mux, -}; - -static struct atlas7_pad_mux pwc_io_on_grp_pad_mux[] = { - MUX(0, 9, 1, N, N, N, N), -}; - -static struct atlas7_grp_mux pwc_io_on_grp_mux = { - .pad_mux_count = ARRAY_SIZE(pwc_io_on_grp_pad_mux), - .pad_mux_list = pwc_io_on_grp_pad_mux, -}; - -static struct atlas7_pad_mux pwc_lowbatt_b_grp0_pad_mux[] = { - MUX(0, 4, 1, 0xa08, 4, 0xa88, 4), -}; - -static struct atlas7_grp_mux pwc_lowbatt_b_grp0_mux = { - .pad_mux_count = ARRAY_SIZE(pwc_lowbatt_b_grp0_pad_mux), - .pad_mux_list = pwc_lowbatt_b_grp0_pad_mux, -}; - -static struct atlas7_pad_mux pwc_mem_on_grp_pad_mux[] = { - MUX(0, 7, 1, N, N, N, N), -}; - -static struct atlas7_grp_mux pwc_mem_on_grp_mux = { - .pad_mux_count = ARRAY_SIZE(pwc_mem_on_grp_pad_mux), - .pad_mux_list = pwc_mem_on_grp_pad_mux, -}; - -static struct atlas7_pad_mux pwc_on_key_b_grp0_pad_mux[] = { - MUX(0, 5, 1, 0xa08, 5, 0xa88, 5), -}; - -static struct atlas7_grp_mux pwc_on_key_b_grp0_mux = { - .pad_mux_count = ARRAY_SIZE(pwc_on_key_b_grp0_pad_mux), - .pad_mux_list = pwc_on_key_b_grp0_pad_mux, -}; - -static struct atlas7_pad_mux pwc_wakeup_src0_grp_pad_mux[] = { - MUX(0, 0, 1, N, N, N, N), -}; - -static struct atlas7_grp_mux pwc_wakeup_src0_grp_mux = { - .pad_mux_count = ARRAY_SIZE(pwc_wakeup_src0_grp_pad_mux), - .pad_mux_list = pwc_wakeup_src0_grp_pad_mux, -}; - -static struct atlas7_pad_mux pwc_wakeup_src1_grp_pad_mux[] = { - MUX(0, 1, 1, N, N, N, N), -}; - -static struct atlas7_grp_mux pwc_wakeup_src1_grp_mux = { - .pad_mux_count = ARRAY_SIZE(pwc_wakeup_src1_grp_pad_mux), - .pad_mux_list = pwc_wakeup_src1_grp_pad_mux, -}; - -static struct atlas7_pad_mux pwc_wakeup_src2_grp_pad_mux[] = { - MUX(0, 2, 1, N, N, N, N), -}; - -static struct atlas7_grp_mux pwc_wakeup_src2_grp_mux = { - .pad_mux_count = ARRAY_SIZE(pwc_wakeup_src2_grp_pad_mux), - .pad_mux_list = pwc_wakeup_src2_grp_pad_mux, -}; - -static struct atlas7_pad_mux pwc_wakeup_src3_grp_pad_mux[] = { - MUX(0, 3, 1, N, N, N, N), -}; - -static struct atlas7_grp_mux pwc_wakeup_src3_grp_mux = { - .pad_mux_count = ARRAY_SIZE(pwc_wakeup_src3_grp_pad_mux), - .pad_mux_list = pwc_wakeup_src3_grp_pad_mux, -}; - -static struct atlas7_pad_mux pw_cko0_grp0_pad_mux[] = { - MUX(1, 123, 3, N, N, N, N), -}; - -static struct atlas7_grp_mux pw_cko0_grp0_mux = { - .pad_mux_count = ARRAY_SIZE(pw_cko0_grp0_pad_mux), - .pad_mux_list = pw_cko0_grp0_pad_mux, -}; - -static struct atlas7_pad_mux pw_cko0_grp1_pad_mux[] = { - MUX(1, 101, 4, N, N, N, N), -}; - -static struct atlas7_grp_mux pw_cko0_grp1_mux = { - .pad_mux_count = ARRAY_SIZE(pw_cko0_grp1_pad_mux), - .pad_mux_list = pw_cko0_grp1_pad_mux, -}; - -static struct atlas7_pad_mux pw_cko0_grp2_pad_mux[] = { - MUX(1, 82, 2, N, N, N, N), -}; - -static struct atlas7_grp_mux pw_cko0_grp2_mux = { - .pad_mux_count = ARRAY_SIZE(pw_cko0_grp2_pad_mux), - .pad_mux_list = pw_cko0_grp2_pad_mux, -}; - -static struct atlas7_pad_mux pw_cko0_grp3_pad_mux[] = { - MUX(1, 162, 5, N, N, N, N), -}; - -static struct atlas7_grp_mux pw_cko0_grp3_mux = { - .pad_mux_count = ARRAY_SIZE(pw_cko0_grp3_pad_mux), - .pad_mux_list = pw_cko0_grp3_pad_mux, -}; - -static struct atlas7_pad_mux pw_cko1_grp0_pad_mux[] = { - MUX(1, 124, 3, N, N, N, N), -}; - -static struct atlas7_grp_mux pw_cko1_grp0_mux = { - .pad_mux_count = ARRAY_SIZE(pw_cko1_grp0_pad_mux), - .pad_mux_list = pw_cko1_grp0_pad_mux, -}; - -static struct atlas7_pad_mux pw_cko1_grp1_pad_mux[] = { - MUX(1, 110, 4, N, N, N, N), -}; - -static struct atlas7_grp_mux pw_cko1_grp1_mux = { - .pad_mux_count = ARRAY_SIZE(pw_cko1_grp1_pad_mux), - .pad_mux_list = pw_cko1_grp1_pad_mux, -}; - -static struct atlas7_pad_mux pw_cko1_grp2_pad_mux[] = { - MUX(1, 163, 5, N, N, N, N), -}; - -static struct atlas7_grp_mux pw_cko1_grp2_mux = { - .pad_mux_count = ARRAY_SIZE(pw_cko1_grp2_pad_mux), - .pad_mux_list = pw_cko1_grp2_pad_mux, -}; - -static struct atlas7_pad_mux pw_i2s01_clk_grp0_pad_mux[] = { - MUX(1, 125, 3, N, N, N, N), -}; - -static struct atlas7_grp_mux pw_i2s01_clk_grp0_mux = { - .pad_mux_count = ARRAY_SIZE(pw_i2s01_clk_grp0_pad_mux), - .pad_mux_list = pw_i2s01_clk_grp0_pad_mux, -}; - -static struct atlas7_pad_mux pw_i2s01_clk_grp1_pad_mux[] = { - MUX(1, 117, 3, N, N, N, N), -}; - -static struct atlas7_grp_mux pw_i2s01_clk_grp1_mux = { - .pad_mux_count = ARRAY_SIZE(pw_i2s01_clk_grp1_pad_mux), - .pad_mux_list = pw_i2s01_clk_grp1_pad_mux, -}; - -static struct atlas7_pad_mux pw_i2s01_clk_grp2_pad_mux[] = { - MUX(1, 132, 2, N, N, N, N), -}; - -static struct atlas7_grp_mux pw_i2s01_clk_grp2_mux = { - .pad_mux_count = ARRAY_SIZE(pw_i2s01_clk_grp2_pad_mux), - .pad_mux_list = pw_i2s01_clk_grp2_pad_mux, -}; - -static struct atlas7_pad_mux pw_pwm0_grp0_pad_mux[] = { - MUX(1, 119, 3, N, N, N, N), -}; - -static struct atlas7_grp_mux pw_pwm0_grp0_mux = { - .pad_mux_count = ARRAY_SIZE(pw_pwm0_grp0_pad_mux), - .pad_mux_list = pw_pwm0_grp0_pad_mux, -}; - -static struct atlas7_pad_mux pw_pwm0_grp1_pad_mux[] = { - MUX(1, 159, 5, N, N, N, N), -}; - -static struct atlas7_grp_mux pw_pwm0_grp1_mux = { - .pad_mux_count = ARRAY_SIZE(pw_pwm0_grp1_pad_mux), - .pad_mux_list = pw_pwm0_grp1_pad_mux, -}; - -static struct atlas7_pad_mux pw_pwm1_grp0_pad_mux[] = { - MUX(1, 120, 3, N, N, N, N), -}; - -static struct atlas7_grp_mux pw_pwm1_grp0_mux = { - .pad_mux_count = ARRAY_SIZE(pw_pwm1_grp0_pad_mux), - .pad_mux_list = pw_pwm1_grp0_pad_mux, -}; - -static struct atlas7_pad_mux pw_pwm1_grp1_pad_mux[] = { - MUX(1, 160, 5, N, N, N, N), -}; - -static struct atlas7_grp_mux pw_pwm1_grp1_mux = { - .pad_mux_count = ARRAY_SIZE(pw_pwm1_grp1_pad_mux), - .pad_mux_list = pw_pwm1_grp1_pad_mux, -}; - -static struct atlas7_pad_mux pw_pwm1_grp2_pad_mux[] = { - MUX(1, 131, 2, N, N, N, N), -}; - -static struct atlas7_grp_mux pw_pwm1_grp2_mux = { - .pad_mux_count = ARRAY_SIZE(pw_pwm1_grp2_pad_mux), - .pad_mux_list = pw_pwm1_grp2_pad_mux, -}; - -static struct atlas7_pad_mux pw_pwm2_grp0_pad_mux[] = { - MUX(1, 121, 3, N, N, N, N), -}; - -static struct atlas7_grp_mux pw_pwm2_grp0_mux = { - .pad_mux_count = ARRAY_SIZE(pw_pwm2_grp0_pad_mux), - .pad_mux_list = pw_pwm2_grp0_pad_mux, -}; - -static struct atlas7_pad_mux pw_pwm2_grp1_pad_mux[] = { - MUX(1, 98, 3, N, N, N, N), -}; - -static struct atlas7_grp_mux pw_pwm2_grp1_mux = { - .pad_mux_count = ARRAY_SIZE(pw_pwm2_grp1_pad_mux), - .pad_mux_list = pw_pwm2_grp1_pad_mux, -}; - -static struct atlas7_pad_mux pw_pwm2_grp2_pad_mux[] = { - MUX(1, 161, 5, N, N, N, N), -}; - -static struct atlas7_grp_mux pw_pwm2_grp2_mux = { - .pad_mux_count = ARRAY_SIZE(pw_pwm2_grp2_pad_mux), - .pad_mux_list = pw_pwm2_grp2_pad_mux, -}; - -static struct atlas7_pad_mux pw_pwm3_grp0_pad_mux[] = { - MUX(1, 122, 3, N, N, N, N), -}; - -static struct atlas7_grp_mux pw_pwm3_grp0_mux = { - .pad_mux_count = ARRAY_SIZE(pw_pwm3_grp0_pad_mux), - .pad_mux_list = pw_pwm3_grp0_pad_mux, -}; - -static struct atlas7_pad_mux pw_pwm3_grp1_pad_mux[] = { - MUX(1, 73, 4, N, N, N, N), -}; - -static struct atlas7_grp_mux pw_pwm3_grp1_mux = { - .pad_mux_count = ARRAY_SIZE(pw_pwm3_grp1_pad_mux), - .pad_mux_list = pw_pwm3_grp1_pad_mux, -}; - -static struct atlas7_pad_mux pw_pwm_cpu_vol_grp0_pad_mux[] = { - MUX(1, 121, 3, N, N, N, N), -}; - -static struct atlas7_grp_mux pw_pwm_cpu_vol_grp0_mux = { - .pad_mux_count = ARRAY_SIZE(pw_pwm_cpu_vol_grp0_pad_mux), - .pad_mux_list = pw_pwm_cpu_vol_grp0_pad_mux, -}; - -static struct atlas7_pad_mux pw_pwm_cpu_vol_grp1_pad_mux[] = { - MUX(1, 98, 3, N, N, N, N), -}; - -static struct atlas7_grp_mux pw_pwm_cpu_vol_grp1_mux = { - .pad_mux_count = ARRAY_SIZE(pw_pwm_cpu_vol_grp1_pad_mux), - .pad_mux_list = pw_pwm_cpu_vol_grp1_pad_mux, -}; - -static struct atlas7_pad_mux pw_pwm_cpu_vol_grp2_pad_mux[] = { - MUX(1, 161, 5, N, N, N, N), -}; - -static struct atlas7_grp_mux pw_pwm_cpu_vol_grp2_mux = { - .pad_mux_count = ARRAY_SIZE(pw_pwm_cpu_vol_grp2_pad_mux), - .pad_mux_list = pw_pwm_cpu_vol_grp2_pad_mux, -}; - -static struct atlas7_pad_mux pw_backlight_grp0_pad_mux[] = { - MUX(1, 122, 3, N, N, N, N), -}; - -static struct atlas7_grp_mux pw_backlight_grp0_mux = { - .pad_mux_count = ARRAY_SIZE(pw_backlight_grp0_pad_mux), - .pad_mux_list = pw_backlight_grp0_pad_mux, -}; - -static struct atlas7_pad_mux pw_backlight_grp1_pad_mux[] = { - MUX(1, 73, 4, N, N, N, N), -}; - -static struct atlas7_grp_mux pw_backlight_grp1_mux = { - .pad_mux_count = ARRAY_SIZE(pw_backlight_grp1_pad_mux), - .pad_mux_list = pw_backlight_grp1_pad_mux, -}; - -static struct atlas7_pad_mux rg_eth_mac_grp_pad_mux[] = { - MUX(1, 108, 1, N, N, N, N), - MUX(1, 103, 1, N, N, N, N), - MUX(1, 104, 1, N, N, N, N), - MUX(1, 105, 1, N, N, N, N), - MUX(1, 106, 1, N, N, N, N), - MUX(1, 107, 1, N, N, N, N), - MUX(1, 102, 1, N, N, N, N), - MUX(1, 97, 1, N, N, N, N), - MUX(1, 98, 1, N, N, N, N), - MUX(1, 99, 1, N, N, N, N), - MUX(1, 100, 1, N, N, N, N), - MUX(1, 101, 1, N, N, N, N), -}; - -static struct atlas7_grp_mux rg_eth_mac_grp_mux = { - .pad_mux_count = ARRAY_SIZE(rg_eth_mac_grp_pad_mux), - .pad_mux_list = rg_eth_mac_grp_pad_mux, -}; - -static struct atlas7_pad_mux rg_gmac_phy_intr_n_grp_pad_mux[] = { - MUX(1, 111, 1, 0xa08, 13, 0xa88, 13), -}; - -static struct atlas7_grp_mux rg_gmac_phy_intr_n_grp_mux = { - .pad_mux_count = ARRAY_SIZE(rg_gmac_phy_intr_n_grp_pad_mux), - .pad_mux_list = rg_gmac_phy_intr_n_grp_pad_mux, -}; - -static struct atlas7_pad_mux rg_rgmii_mac_grp_pad_mux[] = { - MUX(1, 109, 1, N, N, N, N), - MUX(1, 110, 1, N, N, N, N), -}; - -static struct atlas7_grp_mux rg_rgmii_mac_grp_mux = { - .pad_mux_count = ARRAY_SIZE(rg_rgmii_mac_grp_pad_mux), - .pad_mux_list = rg_rgmii_mac_grp_pad_mux, -}; - -static struct atlas7_pad_mux rg_rgmii_phy_ref_clk_grp0_pad_mux[] = { - MUX(1, 111, 5, N, N, N, N), -}; - -static struct atlas7_grp_mux rg_rgmii_phy_ref_clk_grp0_mux = { - .pad_mux_count = ARRAY_SIZE(rg_rgmii_phy_ref_clk_grp0_pad_mux), - .pad_mux_list = rg_rgmii_phy_ref_clk_grp0_pad_mux, -}; - -static struct atlas7_pad_mux rg_rgmii_phy_ref_clk_grp1_pad_mux[] = { - MUX(1, 53, 4, N, N, N, N), -}; - -static struct atlas7_grp_mux rg_rgmii_phy_ref_clk_grp1_mux = { - .pad_mux_count = ARRAY_SIZE(rg_rgmii_phy_ref_clk_grp1_pad_mux), - .pad_mux_list = rg_rgmii_phy_ref_clk_grp1_pad_mux, -}; - -static struct atlas7_pad_mux sd0_grp_pad_mux[] = { - MUX(1, 46, 2, N, N, N, N), - MUX(1, 47, 2, N, N, N, N), - MUX(1, 44, 2, N, N, N, N), - MUX(1, 43, 2, N, N, N, N), - MUX(1, 42, 2, N, N, N, N), - MUX(1, 41, 2, N, N, N, N), - MUX(1, 40, 2, N, N, N, N), - MUX(1, 39, 2, N, N, N, N), - MUX(1, 38, 2, N, N, N, N), - MUX(1, 37, 2, N, N, N, N), -}; - -static struct atlas7_grp_mux sd0_grp_mux = { - .pad_mux_count = ARRAY_SIZE(sd0_grp_pad_mux), - .pad_mux_list = sd0_grp_pad_mux, -}; - -static struct atlas7_pad_mux sd0_4bit_grp_pad_mux[] = { - MUX(1, 46, 2, N, N, N, N), - MUX(1, 47, 2, N, N, N, N), - MUX(1, 44, 2, N, N, N, N), - MUX(1, 43, 2, N, N, N, N), - MUX(1, 42, 2, N, N, N, N), - MUX(1, 41, 2, N, N, N, N), -}; - -static struct atlas7_grp_mux sd0_4bit_grp_mux = { - .pad_mux_count = ARRAY_SIZE(sd0_4bit_grp_pad_mux), - .pad_mux_list = sd0_4bit_grp_pad_mux, -}; - -static struct atlas7_pad_mux sd1_grp_pad_mux[] = { - MUX(1, 48, 3, N, N, N, N), - MUX(1, 49, 3, N, N, N, N), - MUX(1, 44, 3, 0xa00, 0, 0xa80, 0), - MUX(1, 43, 3, 0xa00, 1, 0xa80, 1), - MUX(1, 42, 3, 0xa00, 2, 0xa80, 2), - MUX(1, 41, 3, 0xa00, 3, 0xa80, 3), - MUX(1, 40, 3, N, N, N, N), - MUX(1, 39, 3, N, N, N, N), - MUX(1, 38, 3, N, N, N, N), - MUX(1, 37, 3, N, N, N, N), -}; - -static struct atlas7_grp_mux sd1_grp_mux = { - .pad_mux_count = ARRAY_SIZE(sd1_grp_pad_mux), - .pad_mux_list = sd1_grp_pad_mux, -}; - -static struct atlas7_pad_mux sd1_4bit_grp0_pad_mux[] = { - MUX(1, 48, 3, N, N, N, N), - MUX(1, 49, 3, N, N, N, N), - MUX(1, 44, 3, 0xa00, 0, 0xa80, 0), - MUX(1, 43, 3, 0xa00, 1, 0xa80, 1), - MUX(1, 42, 3, 0xa00, 2, 0xa80, 2), - MUX(1, 41, 3, 0xa00, 3, 0xa80, 3), -}; - -static struct atlas7_grp_mux sd1_4bit_grp0_mux = { - .pad_mux_count = ARRAY_SIZE(sd1_4bit_grp0_pad_mux), - .pad_mux_list = sd1_4bit_grp0_pad_mux, -}; - -static struct atlas7_pad_mux sd1_4bit_grp1_pad_mux[] = { - MUX(1, 48, 3, N, N, N, N), - MUX(1, 49, 3, N, N, N, N), - MUX(1, 40, 4, 0xa00, 0, 0xa80, 0), - MUX(1, 39, 4, 0xa00, 1, 0xa80, 1), - MUX(1, 38, 4, 0xa00, 2, 0xa80, 2), - MUX(1, 37, 4, 0xa00, 3, 0xa80, 3), -}; - -static struct atlas7_grp_mux sd1_4bit_grp1_mux = { - .pad_mux_count = ARRAY_SIZE(sd1_4bit_grp1_pad_mux), - .pad_mux_list = sd1_4bit_grp1_pad_mux, -}; - -static struct atlas7_pad_mux sd2_basic_grp_pad_mux[] = { - MUX(1, 31, 1, N, N, N, N), - MUX(1, 32, 1, N, N, N, N), - MUX(1, 33, 1, N, N, N, N), - MUX(1, 34, 1, N, N, N, N), - MUX(1, 35, 1, N, N, N, N), - MUX(1, 36, 1, N, N, N, N), -}; - -static struct atlas7_grp_mux sd2_basic_grp_mux = { - .pad_mux_count = ARRAY_SIZE(sd2_basic_grp_pad_mux), - .pad_mux_list = sd2_basic_grp_pad_mux, -}; - -static struct atlas7_pad_mux sd2_cdb_grp0_pad_mux[] = { - MUX(1, 124, 2, 0xa08, 7, 0xa88, 7), -}; - -static struct atlas7_grp_mux sd2_cdb_grp0_mux = { - .pad_mux_count = ARRAY_SIZE(sd2_cdb_grp0_pad_mux), - .pad_mux_list = sd2_cdb_grp0_pad_mux, -}; - -static struct atlas7_pad_mux sd2_cdb_grp1_pad_mux[] = { - MUX(1, 161, 6, 0xa08, 7, 0xa88, 7), -}; - -static struct atlas7_grp_mux sd2_cdb_grp1_mux = { - .pad_mux_count = ARRAY_SIZE(sd2_cdb_grp1_pad_mux), - .pad_mux_list = sd2_cdb_grp1_pad_mux, -}; - -static struct atlas7_pad_mux sd2_wpb_grp0_pad_mux[] = { - MUX(1, 123, 2, 0xa10, 6, 0xa90, 6), -}; - -static struct atlas7_grp_mux sd2_wpb_grp0_mux = { - .pad_mux_count = ARRAY_SIZE(sd2_wpb_grp0_pad_mux), - .pad_mux_list = sd2_wpb_grp0_pad_mux, -}; - -static struct atlas7_pad_mux sd2_wpb_grp1_pad_mux[] = { - MUX(1, 163, 7, 0xa10, 6, 0xa90, 6), -}; - -static struct atlas7_grp_mux sd2_wpb_grp1_mux = { - .pad_mux_count = ARRAY_SIZE(sd2_wpb_grp1_pad_mux), - .pad_mux_list = sd2_wpb_grp1_pad_mux, -}; - -static struct atlas7_pad_mux sd3_9_grp_pad_mux[] = { - MUX(1, 85, 1, N, N, N, N), - MUX(1, 86, 1, N, N, N, N), - MUX(1, 87, 1, N, N, N, N), - MUX(1, 88, 1, N, N, N, N), - MUX(1, 89, 1, N, N, N, N), - MUX(1, 90, 1, N, N, N, N), -}; - -static struct atlas7_grp_mux sd3_9_grp_mux = { - .pad_mux_count = ARRAY_SIZE(sd3_9_grp_pad_mux), - .pad_mux_list = sd3_9_grp_pad_mux, -}; - -static struct atlas7_pad_mux sd5_grp_pad_mux[] = { - MUX(1, 91, 1, N, N, N, N), - MUX(1, 92, 1, N, N, N, N), - MUX(1, 93, 1, N, N, N, N), - MUX(1, 94, 1, N, N, N, N), - MUX(1, 95, 1, N, N, N, N), - MUX(1, 96, 1, N, N, N, N), -}; - -static struct atlas7_grp_mux sd5_grp_mux = { - .pad_mux_count = ARRAY_SIZE(sd5_grp_pad_mux), - .pad_mux_list = sd5_grp_pad_mux, -}; - -static struct atlas7_pad_mux sd6_grp0_pad_mux[] = { - MUX(1, 79, 4, 0xa00, 27, 0xa80, 27), - MUX(1, 78, 4, 0xa00, 26, 0xa80, 26), - MUX(1, 74, 4, 0xa00, 28, 0xa80, 28), - MUX(1, 75, 4, 0xa00, 29, 0xa80, 29), - MUX(1, 76, 4, 0xa00, 30, 0xa80, 30), - MUX(1, 77, 4, 0xa00, 31, 0xa80, 31), -}; - -static struct atlas7_grp_mux sd6_grp0_mux = { - .pad_mux_count = ARRAY_SIZE(sd6_grp0_pad_mux), - .pad_mux_list = sd6_grp0_pad_mux, -}; - -static struct atlas7_pad_mux sd6_grp1_pad_mux[] = { - MUX(1, 101, 3, 0xa00, 27, 0xa80, 27), - MUX(1, 99, 3, 0xa00, 26, 0xa80, 26), - MUX(1, 100, 3, 0xa00, 28, 0xa80, 28), - MUX(1, 110, 3, 0xa00, 29, 0xa80, 29), - MUX(1, 109, 3, 0xa00, 30, 0xa80, 30), - MUX(1, 111, 3, 0xa00, 31, 0xa80, 31), -}; - -static struct atlas7_grp_mux sd6_grp1_mux = { - .pad_mux_count = ARRAY_SIZE(sd6_grp1_pad_mux), - .pad_mux_list = sd6_grp1_pad_mux, -}; - -static struct atlas7_pad_mux sp0_ext_ldo_on_grp_pad_mux[] = { - MUX(0, 4, 2, N, N, N, N), -}; - -static struct atlas7_grp_mux sp0_ext_ldo_on_grp_mux = { - .pad_mux_count = ARRAY_SIZE(sp0_ext_ldo_on_grp_pad_mux), - .pad_mux_list = sp0_ext_ldo_on_grp_pad_mux, -}; - -static struct atlas7_pad_mux sp0_qspi_grp_pad_mux[] = { - MUX(0, 12, 1, N, N, N, N), - MUX(0, 13, 1, N, N, N, N), - MUX(0, 14, 1, N, N, N, N), - MUX(0, 15, 1, N, N, N, N), - MUX(0, 16, 1, N, N, N, N), - MUX(0, 17, 1, N, N, N, N), -}; - -static struct atlas7_grp_mux sp0_qspi_grp_mux = { - .pad_mux_count = ARRAY_SIZE(sp0_qspi_grp_pad_mux), - .pad_mux_list = sp0_qspi_grp_pad_mux, -}; - -static struct atlas7_pad_mux sp1_spi_grp_pad_mux[] = { - MUX(1, 19, 1, N, N, N, N), - MUX(1, 20, 1, N, N, N, N), - MUX(1, 21, 1, N, N, N, N), - MUX(1, 18, 1, N, N, N, N), -}; - -static struct atlas7_grp_mux sp1_spi_grp_mux = { - .pad_mux_count = ARRAY_SIZE(sp1_spi_grp_pad_mux), - .pad_mux_list = sp1_spi_grp_pad_mux, -}; - -static struct atlas7_pad_mux tpiu_trace_grp_pad_mux[] = { - MUX(1, 53, 5, N, N, N, N), - MUX(1, 56, 5, N, N, N, N), - MUX(1, 57, 5, N, N, N, N), - MUX(1, 58, 5, N, N, N, N), - MUX(1, 59, 5, N, N, N, N), - MUX(1, 60, 5, N, N, N, N), - MUX(1, 61, 5, N, N, N, N), - MUX(1, 62, 5, N, N, N, N), - MUX(1, 63, 5, N, N, N, N), - MUX(1, 64, 5, N, N, N, N), - MUX(1, 65, 5, N, N, N, N), - MUX(1, 66, 5, N, N, N, N), - MUX(1, 67, 5, N, N, N, N), - MUX(1, 68, 5, N, N, N, N), - MUX(1, 69, 5, N, N, N, N), - MUX(1, 70, 5, N, N, N, N), - MUX(1, 71, 5, N, N, N, N), - MUX(1, 72, 5, N, N, N, N), -}; - -static struct atlas7_grp_mux tpiu_trace_grp_mux = { - .pad_mux_count = ARRAY_SIZE(tpiu_trace_grp_pad_mux), - .pad_mux_list = tpiu_trace_grp_pad_mux, -}; - -static struct atlas7_pad_mux uart0_grp_pad_mux[] = { - MUX(1, 121, 4, N, N, N, N), - MUX(1, 120, 4, N, N, N, N), - MUX(1, 134, 1, N, N, N, N), - MUX(1, 133, 1, N, N, N, N), -}; - -static struct atlas7_grp_mux uart0_grp_mux = { - .pad_mux_count = ARRAY_SIZE(uart0_grp_pad_mux), - .pad_mux_list = uart0_grp_pad_mux, -}; - -static struct atlas7_pad_mux uart0_nopause_grp_pad_mux[] = { - MUX(1, 134, 1, N, N, N, N), - MUX(1, 133, 1, N, N, N, N), -}; - -static struct atlas7_grp_mux uart0_nopause_grp_mux = { - .pad_mux_count = ARRAY_SIZE(uart0_nopause_grp_pad_mux), - .pad_mux_list = uart0_nopause_grp_pad_mux, -}; - -static struct atlas7_pad_mux uart1_grp_pad_mux[] = { - MUX(1, 136, 1, N, N, N, N), - MUX(1, 135, 1, N, N, N, N), -}; - -static struct atlas7_grp_mux uart1_grp_mux = { - .pad_mux_count = ARRAY_SIZE(uart1_grp_pad_mux), - .pad_mux_list = uart1_grp_pad_mux, -}; - -static struct atlas7_pad_mux uart2_cts_grp0_pad_mux[] = { - MUX(1, 132, 3, 0xa10, 2, 0xa90, 2), -}; - -static struct atlas7_grp_mux uart2_cts_grp0_mux = { - .pad_mux_count = ARRAY_SIZE(uart2_cts_grp0_pad_mux), - .pad_mux_list = uart2_cts_grp0_pad_mux, -}; - -static struct atlas7_pad_mux uart2_cts_grp1_pad_mux[] = { - MUX(1, 162, 2, 0xa10, 2, 0xa90, 2), -}; - -static struct atlas7_grp_mux uart2_cts_grp1_mux = { - .pad_mux_count = ARRAY_SIZE(uart2_cts_grp1_pad_mux), - .pad_mux_list = uart2_cts_grp1_pad_mux, -}; - -static struct atlas7_pad_mux uart2_rts_grp0_pad_mux[] = { - MUX(1, 131, 3, N, N, N, N), -}; - -static struct atlas7_grp_mux uart2_rts_grp0_mux = { - .pad_mux_count = ARRAY_SIZE(uart2_rts_grp0_pad_mux), - .pad_mux_list = uart2_rts_grp0_pad_mux, -}; - -static struct atlas7_pad_mux uart2_rts_grp1_pad_mux[] = { - MUX(1, 161, 2, N, N, N, N), -}; - -static struct atlas7_grp_mux uart2_rts_grp1_mux = { - .pad_mux_count = ARRAY_SIZE(uart2_rts_grp1_pad_mux), - .pad_mux_list = uart2_rts_grp1_pad_mux, -}; - -static struct atlas7_pad_mux uart2_rxd_grp0_pad_mux[] = { - MUX(0, 11, 2, 0xa10, 5, 0xa90, 5), -}; - -static struct atlas7_grp_mux uart2_rxd_grp0_mux = { - .pad_mux_count = ARRAY_SIZE(uart2_rxd_grp0_pad_mux), - .pad_mux_list = uart2_rxd_grp0_pad_mux, -}; - -static struct atlas7_pad_mux uart2_rxd_grp1_pad_mux[] = { - MUX(1, 160, 2, 0xa10, 5, 0xa90, 5), -}; - -static struct atlas7_grp_mux uart2_rxd_grp1_mux = { - .pad_mux_count = ARRAY_SIZE(uart2_rxd_grp1_pad_mux), - .pad_mux_list = uart2_rxd_grp1_pad_mux, -}; - -static struct atlas7_pad_mux uart2_rxd_grp2_pad_mux[] = { - MUX(1, 130, 3, 0xa10, 5, 0xa90, 5), -}; - -static struct atlas7_grp_mux uart2_rxd_grp2_mux = { - .pad_mux_count = ARRAY_SIZE(uart2_rxd_grp2_pad_mux), - .pad_mux_list = uart2_rxd_grp2_pad_mux, -}; - -static struct atlas7_pad_mux uart2_txd_grp0_pad_mux[] = { - MUX(0, 10, 2, N, N, N, N), -}; - -static struct atlas7_grp_mux uart2_txd_grp0_mux = { - .pad_mux_count = ARRAY_SIZE(uart2_txd_grp0_pad_mux), - .pad_mux_list = uart2_txd_grp0_pad_mux, -}; - -static struct atlas7_pad_mux uart2_txd_grp1_pad_mux[] = { - MUX(1, 159, 2, N, N, N, N), -}; - -static struct atlas7_grp_mux uart2_txd_grp1_mux = { - .pad_mux_count = ARRAY_SIZE(uart2_txd_grp1_pad_mux), - .pad_mux_list = uart2_txd_grp1_pad_mux, -}; - -static struct atlas7_pad_mux uart2_txd_grp2_pad_mux[] = { - MUX(1, 129, 3, N, N, N, N), -}; - -static struct atlas7_grp_mux uart2_txd_grp2_mux = { - .pad_mux_count = ARRAY_SIZE(uart2_txd_grp2_pad_mux), - .pad_mux_list = uart2_txd_grp2_pad_mux, -}; - -static struct atlas7_pad_mux uart3_cts_grp0_pad_mux[] = { - MUX(1, 125, 2, 0xa08, 0, 0xa88, 0), -}; - -static struct atlas7_grp_mux uart3_cts_grp0_mux = { - .pad_mux_count = ARRAY_SIZE(uart3_cts_grp0_pad_mux), - .pad_mux_list = uart3_cts_grp0_pad_mux, -}; - -static struct atlas7_pad_mux uart3_cts_grp1_pad_mux[] = { - MUX(1, 111, 4, 0xa08, 0, 0xa88, 0), -}; - -static struct atlas7_grp_mux uart3_cts_grp1_mux = { - .pad_mux_count = ARRAY_SIZE(uart3_cts_grp1_pad_mux), - .pad_mux_list = uart3_cts_grp1_pad_mux, -}; - -static struct atlas7_pad_mux uart3_cts_grp2_pad_mux[] = { - MUX(1, 140, 2, 0xa08, 0, 0xa88, 0), -}; - -static struct atlas7_grp_mux uart3_cts_grp2_mux = { - .pad_mux_count = ARRAY_SIZE(uart3_cts_grp2_pad_mux), - .pad_mux_list = uart3_cts_grp2_pad_mux, -}; - -static struct atlas7_pad_mux uart3_rts_grp0_pad_mux[] = { - MUX(1, 126, 2, N, N, N, N), -}; - -static struct atlas7_grp_mux uart3_rts_grp0_mux = { - .pad_mux_count = ARRAY_SIZE(uart3_rts_grp0_pad_mux), - .pad_mux_list = uart3_rts_grp0_pad_mux, -}; - -static struct atlas7_pad_mux uart3_rts_grp1_pad_mux[] = { - MUX(1, 109, 4, N, N, N, N), -}; - -static struct atlas7_grp_mux uart3_rts_grp1_mux = { - .pad_mux_count = ARRAY_SIZE(uart3_rts_grp1_pad_mux), - .pad_mux_list = uart3_rts_grp1_pad_mux, -}; - -static struct atlas7_pad_mux uart3_rts_grp2_pad_mux[] = { - MUX(1, 139, 2, N, N, N, N), -}; - -static struct atlas7_grp_mux uart3_rts_grp2_mux = { - .pad_mux_count = ARRAY_SIZE(uart3_rts_grp2_pad_mux), - .pad_mux_list = uart3_rts_grp2_pad_mux, -}; - -static struct atlas7_pad_mux uart3_rxd_grp0_pad_mux[] = { - MUX(1, 138, 1, 0xa00, 5, 0xa80, 5), -}; - -static struct atlas7_grp_mux uart3_rxd_grp0_mux = { - .pad_mux_count = ARRAY_SIZE(uart3_rxd_grp0_pad_mux), - .pad_mux_list = uart3_rxd_grp0_pad_mux, -}; - -static struct atlas7_pad_mux uart3_rxd_grp1_pad_mux[] = { - MUX(1, 84, 2, 0xa00, 5, 0xa80, 5), -}; - -static struct atlas7_grp_mux uart3_rxd_grp1_mux = { - .pad_mux_count = ARRAY_SIZE(uart3_rxd_grp1_pad_mux), - .pad_mux_list = uart3_rxd_grp1_pad_mux, -}; - -static struct atlas7_pad_mux uart3_rxd_grp2_pad_mux[] = { - MUX(1, 162, 3, 0xa00, 5, 0xa80, 5), -}; - -static struct atlas7_grp_mux uart3_rxd_grp2_mux = { - .pad_mux_count = ARRAY_SIZE(uart3_rxd_grp2_pad_mux), - .pad_mux_list = uart3_rxd_grp2_pad_mux, -}; - -static struct atlas7_pad_mux uart3_txd_grp0_pad_mux[] = { - MUX(1, 137, 1, N, N, N, N), -}; - -static struct atlas7_grp_mux uart3_txd_grp0_mux = { - .pad_mux_count = ARRAY_SIZE(uart3_txd_grp0_pad_mux), - .pad_mux_list = uart3_txd_grp0_pad_mux, -}; - -static struct atlas7_pad_mux uart3_txd_grp1_pad_mux[] = { - MUX(1, 83, 2, N, N, N, N), -}; - -static struct atlas7_grp_mux uart3_txd_grp1_mux = { - .pad_mux_count = ARRAY_SIZE(uart3_txd_grp1_pad_mux), - .pad_mux_list = uart3_txd_grp1_pad_mux, -}; - -static struct atlas7_pad_mux uart3_txd_grp2_pad_mux[] = { - MUX(1, 161, 3, N, N, N, N), -}; - -static struct atlas7_grp_mux uart3_txd_grp2_mux = { - .pad_mux_count = ARRAY_SIZE(uart3_txd_grp2_pad_mux), - .pad_mux_list = uart3_txd_grp2_pad_mux, -}; - -static struct atlas7_pad_mux uart4_basic_grp_pad_mux[] = { - MUX(1, 140, 1, N, N, N, N), - MUX(1, 139, 1, N, N, N, N), -}; - -static struct atlas7_grp_mux uart4_basic_grp_mux = { - .pad_mux_count = ARRAY_SIZE(uart4_basic_grp_pad_mux), - .pad_mux_list = uart4_basic_grp_pad_mux, -}; - -static struct atlas7_pad_mux uart4_cts_grp0_pad_mux[] = { - MUX(1, 122, 4, 0xa08, 1, 0xa88, 1), -}; - -static struct atlas7_grp_mux uart4_cts_grp0_mux = { - .pad_mux_count = ARRAY_SIZE(uart4_cts_grp0_pad_mux), - .pad_mux_list = uart4_cts_grp0_pad_mux, -}; - -static struct atlas7_pad_mux uart4_cts_grp1_pad_mux[] = { - MUX(1, 100, 4, 0xa08, 1, 0xa88, 1), -}; - -static struct atlas7_grp_mux uart4_cts_grp1_mux = { - .pad_mux_count = ARRAY_SIZE(uart4_cts_grp1_pad_mux), - .pad_mux_list = uart4_cts_grp1_pad_mux, -}; - -static struct atlas7_pad_mux uart4_cts_grp2_pad_mux[] = { - MUX(1, 117, 2, 0xa08, 1, 0xa88, 1), -}; - -static struct atlas7_grp_mux uart4_cts_grp2_mux = { - .pad_mux_count = ARRAY_SIZE(uart4_cts_grp2_pad_mux), - .pad_mux_list = uart4_cts_grp2_pad_mux, -}; - -static struct atlas7_pad_mux uart4_rts_grp0_pad_mux[] = { - MUX(1, 123, 4, N, N, N, N), -}; - -static struct atlas7_grp_mux uart4_rts_grp0_mux = { - .pad_mux_count = ARRAY_SIZE(uart4_rts_grp0_pad_mux), - .pad_mux_list = uart4_rts_grp0_pad_mux, -}; - -static struct atlas7_pad_mux uart4_rts_grp1_pad_mux[] = { - MUX(1, 99, 4, N, N, N, N), -}; - -static struct atlas7_grp_mux uart4_rts_grp1_mux = { - .pad_mux_count = ARRAY_SIZE(uart4_rts_grp1_pad_mux), - .pad_mux_list = uart4_rts_grp1_pad_mux, -}; - -static struct atlas7_pad_mux uart4_rts_grp2_pad_mux[] = { - MUX(1, 116, 2, N, N, N, N), -}; - -static struct atlas7_grp_mux uart4_rts_grp2_mux = { - .pad_mux_count = ARRAY_SIZE(uart4_rts_grp2_pad_mux), - .pad_mux_list = uart4_rts_grp2_pad_mux, -}; - -static struct atlas7_pad_mux usb0_drvvbus_grp0_pad_mux[] = { - MUX(1, 51, 2, N, N, N, N), -}; - -static struct atlas7_grp_mux usb0_drvvbus_grp0_mux = { - .pad_mux_count = ARRAY_SIZE(usb0_drvvbus_grp0_pad_mux), - .pad_mux_list = usb0_drvvbus_grp0_pad_mux, -}; - -static struct atlas7_pad_mux usb0_drvvbus_grp1_pad_mux[] = { - MUX(1, 162, 7, N, N, N, N), -}; - -static struct atlas7_grp_mux usb0_drvvbus_grp1_mux = { - .pad_mux_count = ARRAY_SIZE(usb0_drvvbus_grp1_pad_mux), - .pad_mux_list = usb0_drvvbus_grp1_pad_mux, -}; - -static struct atlas7_pad_mux usb1_drvvbus_grp0_pad_mux[] = { - MUX(1, 134, 2, N, N, N, N), -}; - -static struct atlas7_grp_mux usb1_drvvbus_grp0_mux = { - .pad_mux_count = ARRAY_SIZE(usb1_drvvbus_grp0_pad_mux), - .pad_mux_list = usb1_drvvbus_grp0_pad_mux, -}; - -static struct atlas7_pad_mux usb1_drvvbus_grp1_pad_mux[] = { - MUX(1, 163, 2, N, N, N, N), -}; - -static struct atlas7_grp_mux usb1_drvvbus_grp1_mux = { - .pad_mux_count = ARRAY_SIZE(usb1_drvvbus_grp1_pad_mux), - .pad_mux_list = usb1_drvvbus_grp1_pad_mux, -}; - -static struct atlas7_pad_mux visbus_dout_grp_pad_mux[] = { - MUX(1, 57, 6, N, N, N, N), - MUX(1, 58, 6, N, N, N, N), - MUX(1, 59, 6, N, N, N, N), - MUX(1, 60, 6, N, N, N, N), - MUX(1, 61, 6, N, N, N, N), - MUX(1, 62, 6, N, N, N, N), - MUX(1, 63, 6, N, N, N, N), - MUX(1, 64, 6, N, N, N, N), - MUX(1, 65, 6, N, N, N, N), - MUX(1, 66, 6, N, N, N, N), - MUX(1, 67, 6, N, N, N, N), - MUX(1, 68, 6, N, N, N, N), - MUX(1, 69, 6, N, N, N, N), - MUX(1, 70, 6, N, N, N, N), - MUX(1, 71, 6, N, N, N, N), - MUX(1, 72, 6, N, N, N, N), - MUX(1, 53, 6, N, N, N, N), - MUX(1, 54, 6, N, N, N, N), - MUX(1, 55, 6, N, N, N, N), - MUX(1, 56, 6, N, N, N, N), - MUX(1, 85, 6, N, N, N, N), - MUX(1, 86, 6, N, N, N, N), - MUX(1, 87, 6, N, N, N, N), - MUX(1, 88, 6, N, N, N, N), - MUX(1, 89, 6, N, N, N, N), - MUX(1, 90, 6, N, N, N, N), - MUX(1, 91, 6, N, N, N, N), - MUX(1, 92, 6, N, N, N, N), - MUX(1, 93, 6, N, N, N, N), - MUX(1, 94, 6, N, N, N, N), - MUX(1, 95, 6, N, N, N, N), - MUX(1, 96, 6, N, N, N, N), -}; - -static struct atlas7_grp_mux visbus_dout_grp_mux = { - .pad_mux_count = ARRAY_SIZE(visbus_dout_grp_pad_mux), - .pad_mux_list = visbus_dout_grp_pad_mux, -}; - -static struct atlas7_pad_mux vi_vip1_grp_pad_mux[] = { - MUX(1, 74, 1, N, N, N, N), - MUX(1, 75, 1, N, N, N, N), - MUX(1, 76, 1, N, N, N, N), - MUX(1, 77, 1, N, N, N, N), - MUX(1, 78, 1, N, N, N, N), - MUX(1, 79, 1, N, N, N, N), - MUX(1, 80, 1, N, N, N, N), - MUX(1, 81, 1, N, N, N, N), - MUX(1, 82, 1, N, N, N, N), - MUX(1, 83, 1, N, N, N, N), - MUX(1, 84, 1, N, N, N, N), - MUX(1, 103, 2, N, N, N, N), - MUX(1, 104, 2, N, N, N, N), - MUX(1, 105, 2, N, N, N, N), - MUX(1, 106, 2, N, N, N, N), - MUX(1, 107, 2, N, N, N, N), - MUX(1, 102, 2, N, N, N, N), - MUX(1, 97, 2, N, N, N, N), - MUX(1, 98, 2, N, N, N, N), -}; - -static struct atlas7_grp_mux vi_vip1_grp_mux = { - .pad_mux_count = ARRAY_SIZE(vi_vip1_grp_pad_mux), - .pad_mux_list = vi_vip1_grp_pad_mux, -}; - -static struct atlas7_pad_mux vi_vip1_ext_grp_pad_mux[] = { - MUX(1, 74, 1, N, N, N, N), - MUX(1, 75, 1, N, N, N, N), - MUX(1, 76, 1, N, N, N, N), - MUX(1, 77, 1, N, N, N, N), - MUX(1, 78, 1, N, N, N, N), - MUX(1, 79, 1, N, N, N, N), - MUX(1, 80, 1, N, N, N, N), - MUX(1, 81, 1, N, N, N, N), - MUX(1, 82, 1, N, N, N, N), - MUX(1, 83, 1, N, N, N, N), - MUX(1, 84, 1, N, N, N, N), - MUX(1, 108, 2, N, N, N, N), - MUX(1, 103, 2, N, N, N, N), - MUX(1, 104, 2, N, N, N, N), - MUX(1, 105, 2, N, N, N, N), - MUX(1, 106, 2, N, N, N, N), - MUX(1, 107, 2, N, N, N, N), - MUX(1, 102, 2, N, N, N, N), - MUX(1, 97, 2, N, N, N, N), - MUX(1, 98, 2, N, N, N, N), - MUX(1, 99, 2, N, N, N, N), - MUX(1, 100, 2, N, N, N, N), -}; - -static struct atlas7_grp_mux vi_vip1_ext_grp_mux = { - .pad_mux_count = ARRAY_SIZE(vi_vip1_ext_grp_pad_mux), - .pad_mux_list = vi_vip1_ext_grp_pad_mux, -}; - -static struct atlas7_pad_mux vi_vip1_low8bit_grp_pad_mux[] = { - MUX(1, 74, 1, N, N, N, N), - MUX(1, 75, 1, N, N, N, N), - MUX(1, 76, 1, N, N, N, N), - MUX(1, 77, 1, N, N, N, N), - MUX(1, 78, 1, N, N, N, N), - MUX(1, 79, 1, N, N, N, N), - MUX(1, 80, 1, N, N, N, N), - MUX(1, 81, 1, N, N, N, N), - MUX(1, 82, 1, N, N, N, N), - MUX(1, 83, 1, N, N, N, N), - MUX(1, 84, 1, N, N, N, N), -}; - -static struct atlas7_grp_mux vi_vip1_low8bit_grp_mux = { - .pad_mux_count = ARRAY_SIZE(vi_vip1_low8bit_grp_pad_mux), - .pad_mux_list = vi_vip1_low8bit_grp_pad_mux, -}; - -static struct atlas7_pad_mux vi_vip1_high8bit_grp_pad_mux[] = { - MUX(1, 82, 1, N, N, N, N), - MUX(1, 83, 1, N, N, N, N), - MUX(1, 84, 1, N, N, N, N), - MUX(1, 103, 2, N, N, N, N), - MUX(1, 104, 2, N, N, N, N), - MUX(1, 105, 2, N, N, N, N), - MUX(1, 106, 2, N, N, N, N), - MUX(1, 107, 2, N, N, N, N), - MUX(1, 102, 2, N, N, N, N), - MUX(1, 97, 2, N, N, N, N), - MUX(1, 98, 2, N, N, N, N), -}; - -static struct atlas7_grp_mux vi_vip1_high8bit_grp_mux = { - .pad_mux_count = ARRAY_SIZE(vi_vip1_high8bit_grp_pad_mux), - .pad_mux_list = vi_vip1_high8bit_grp_pad_mux, -}; - -static struct atlas7_pmx_func atlas7_pmx_functions[] = { - FUNCTION("gnss_gpio", gnss_gpio_grp, &gnss_gpio_grp_mux), - FUNCTION("lcd_vip_gpio", lcd_vip_gpio_grp, &lcd_vip_gpio_grp_mux), - FUNCTION("sdio_i2s_gpio", sdio_i2s_gpio_grp, &sdio_i2s_gpio_grp_mux), - FUNCTION("sp_rgmii_gpio", sp_rgmii_gpio_grp, &sp_rgmii_gpio_grp_mux), - FUNCTION("lvds_gpio", lvds_gpio_grp, &lvds_gpio_grp_mux), - FUNCTION("jtag_uart_nand_gpio", - jtag_uart_nand_gpio_grp, - &jtag_uart_nand_gpio_grp_mux), - FUNCTION("rtc_gpio", rtc_gpio_grp, &rtc_gpio_grp_mux), - FUNCTION("audio_ac97", audio_ac97_grp, &audio_ac97_grp_mux), - FUNCTION("audio_digmic_m0", - audio_digmic_grp0, - &audio_digmic_grp0_mux), - FUNCTION("audio_digmic_m1", - audio_digmic_grp1, - &audio_digmic_grp1_mux), - FUNCTION("audio_digmic_m2", - audio_digmic_grp2, - &audio_digmic_grp2_mux), - FUNCTION("audio_func_dbg", - audio_func_dbg_grp, - &audio_func_dbg_grp_mux), - FUNCTION("audio_i2s", audio_i2s_grp, &audio_i2s_grp_mux), - FUNCTION("audio_i2s_2ch", audio_i2s_2ch_grp, &audio_i2s_2ch_grp_mux), - FUNCTION("audio_i2s_extclk", - audio_i2s_extclk_grp, - &audio_i2s_extclk_grp_mux), - FUNCTION("audio_spdif_out_m0", - audio_spdif_out_grp0, - &audio_spdif_out_grp0_mux), - FUNCTION("audio_spdif_out_m1", - audio_spdif_out_grp1, - &audio_spdif_out_grp1_mux), - FUNCTION("audio_spdif_out_m2", - audio_spdif_out_grp2, - &audio_spdif_out_grp2_mux), - FUNCTION("audio_uart0_basic", - audio_uart0_basic_grp, - &audio_uart0_basic_grp_mux), - FUNCTION("audio_uart0_urfs_m0", - audio_uart0_urfs_grp0, - &audio_uart0_urfs_grp0_mux), - FUNCTION("audio_uart0_urfs_m1", - audio_uart0_urfs_grp1, - &audio_uart0_urfs_grp1_mux), - FUNCTION("audio_uart0_urfs_m2", - audio_uart0_urfs_grp2, - &audio_uart0_urfs_grp2_mux), - FUNCTION("audio_uart0_urfs_m3", - audio_uart0_urfs_grp3, - &audio_uart0_urfs_grp3_mux), - FUNCTION("audio_uart1_basic", - audio_uart1_basic_grp, - &audio_uart1_basic_grp_mux), - FUNCTION("audio_uart1_urfs_m0", - audio_uart1_urfs_grp0, - &audio_uart1_urfs_grp0_mux), - FUNCTION("audio_uart1_urfs_m1", - audio_uart1_urfs_grp1, - &audio_uart1_urfs_grp1_mux), - FUNCTION("audio_uart1_urfs_m2", - audio_uart1_urfs_grp2, - &audio_uart1_urfs_grp2_mux), - FUNCTION("audio_uart2_urfs_m0", - audio_uart2_urfs_grp0, - &audio_uart2_urfs_grp0_mux), - FUNCTION("audio_uart2_urfs_m1", - audio_uart2_urfs_grp1, - &audio_uart2_urfs_grp1_mux), - FUNCTION("audio_uart2_urfs_m2", - audio_uart2_urfs_grp2, - &audio_uart2_urfs_grp2_mux), - FUNCTION("audio_uart2_urxd_m0", - audio_uart2_urxd_grp0, - &audio_uart2_urxd_grp0_mux), - FUNCTION("audio_uart2_urxd_m1", - audio_uart2_urxd_grp1, - &audio_uart2_urxd_grp1_mux), - FUNCTION("audio_uart2_urxd_m2", - audio_uart2_urxd_grp2, - &audio_uart2_urxd_grp2_mux), - FUNCTION("audio_uart2_usclk_m0", - audio_uart2_usclk_grp0, - &audio_uart2_usclk_grp0_mux), - FUNCTION("audio_uart2_usclk_m1", - audio_uart2_usclk_grp1, - &audio_uart2_usclk_grp1_mux), - FUNCTION("audio_uart2_usclk_m2", - audio_uart2_usclk_grp2, - &audio_uart2_usclk_grp2_mux), - FUNCTION("audio_uart2_utfs_m0", - audio_uart2_utfs_grp0, - &audio_uart2_utfs_grp0_mux), - FUNCTION("audio_uart2_utfs_m1", - audio_uart2_utfs_grp1, - &audio_uart2_utfs_grp1_mux), - FUNCTION("audio_uart2_utfs_m2", - audio_uart2_utfs_grp2, - &audio_uart2_utfs_grp2_mux), - FUNCTION("audio_uart2_utxd_m0", - audio_uart2_utxd_grp0, - &audio_uart2_utxd_grp0_mux), - FUNCTION("audio_uart2_utxd_m1", - audio_uart2_utxd_grp1, - &audio_uart2_utxd_grp1_mux), - FUNCTION("audio_uart2_utxd_m2", - audio_uart2_utxd_grp2, - &audio_uart2_utxd_grp2_mux), - FUNCTION("c_can_trnsvr_en_m0", - c_can_trnsvr_en_grp0, - &c_can_trnsvr_en_grp0_mux), - FUNCTION("c_can_trnsvr_en_m1", - c_can_trnsvr_en_grp1, - &c_can_trnsvr_en_grp1_mux), - FUNCTION("c_can_trnsvr_intr", - c_can_trnsvr_intr_grp, - &c_can_trnsvr_intr_grp_mux), - FUNCTION("c_can_trnsvr_stb_n", - c_can_trnsvr_stb_n_grp, - &c_can_trnsvr_stb_n_grp_mux), - FUNCTION("c0_can_rxd_trnsv0", - c0_can_rxd_trnsv0_grp, - &c0_can_rxd_trnsv0_grp_mux), - FUNCTION("c0_can_rxd_trnsv1", - c0_can_rxd_trnsv1_grp, - &c0_can_rxd_trnsv1_grp_mux), - FUNCTION("c0_can_txd_trnsv0", - c0_can_txd_trnsv0_grp, - &c0_can_txd_trnsv0_grp_mux), - FUNCTION("c0_can_txd_trnsv1", - c0_can_txd_trnsv1_grp, - &c0_can_txd_trnsv1_grp_mux), - FUNCTION("c1_can_rxd_m0", c1_can_rxd_grp0, &c1_can_rxd_grp0_mux), - FUNCTION("c1_can_rxd_m1", c1_can_rxd_grp1, &c1_can_rxd_grp1_mux), - FUNCTION("c1_can_rxd_m2", c1_can_rxd_grp2, &c1_can_rxd_grp2_mux), - FUNCTION("c1_can_rxd_m3", c1_can_rxd_grp3, &c1_can_rxd_grp3_mux), - FUNCTION("c1_can_txd_m0", c1_can_txd_grp0, &c1_can_txd_grp0_mux), - FUNCTION("c1_can_txd_m1", c1_can_txd_grp1, &c1_can_txd_grp1_mux), - FUNCTION("c1_can_txd_m2", c1_can_txd_grp2, &c1_can_txd_grp2_mux), - FUNCTION("c1_can_txd_m3", c1_can_txd_grp3, &c1_can_txd_grp3_mux), - FUNCTION("ca_audio_lpc", ca_audio_lpc_grp, &ca_audio_lpc_grp_mux), - FUNCTION("ca_bt_lpc", ca_bt_lpc_grp, &ca_bt_lpc_grp_mux), - FUNCTION("ca_coex", ca_coex_grp, &ca_coex_grp_mux), - FUNCTION("ca_curator_lpc", - ca_curator_lpc_grp, - &ca_curator_lpc_grp_mux), - FUNCTION("ca_pcm_debug", ca_pcm_debug_grp, &ca_pcm_debug_grp_mux), - FUNCTION("ca_pio", ca_pio_grp, &ca_pio_grp_mux), - FUNCTION("ca_sdio_debug", ca_sdio_debug_grp, &ca_sdio_debug_grp_mux), - FUNCTION("ca_spi", ca_spi_grp, &ca_spi_grp_mux), - FUNCTION("ca_trb", ca_trb_grp, &ca_trb_grp_mux), - FUNCTION("ca_uart_debug", ca_uart_debug_grp, &ca_uart_debug_grp_mux), - FUNCTION("clkc_m0", clkc_grp0, &clkc_grp0_mux), - FUNCTION("clkc_m1", clkc_grp1, &clkc_grp1_mux), - FUNCTION("gn_gnss_i2c", gn_gnss_i2c_grp, &gn_gnss_i2c_grp_mux), - FUNCTION("gn_gnss_uart_nopause", - gn_gnss_uart_nopause_grp, - &gn_gnss_uart_nopause_grp_mux), - FUNCTION("gn_gnss_uart", gn_gnss_uart_grp, &gn_gnss_uart_grp_mux), - FUNCTION("gn_trg_spi_m0", gn_trg_spi_grp0, &gn_trg_spi_grp0_mux), - FUNCTION("gn_trg_spi_m1", gn_trg_spi_grp1, &gn_trg_spi_grp1_mux), - FUNCTION("cvbs_dbg", cvbs_dbg_grp, &cvbs_dbg_grp_mux), - FUNCTION("cvbs_dbg_test_m0", - cvbs_dbg_test_grp0, - &cvbs_dbg_test_grp0_mux), - FUNCTION("cvbs_dbg_test_m1", - cvbs_dbg_test_grp1, - &cvbs_dbg_test_grp1_mux), - FUNCTION("cvbs_dbg_test_m2", - cvbs_dbg_test_grp2, - &cvbs_dbg_test_grp2_mux), - FUNCTION("cvbs_dbg_test_m3", - cvbs_dbg_test_grp3, - &cvbs_dbg_test_grp3_mux), - FUNCTION("cvbs_dbg_test_m4", - cvbs_dbg_test_grp4, - &cvbs_dbg_test_grp4_mux), - FUNCTION("cvbs_dbg_test_m5", - cvbs_dbg_test_grp5, - &cvbs_dbg_test_grp5_mux), - FUNCTION("cvbs_dbg_test_m6", - cvbs_dbg_test_grp6, - &cvbs_dbg_test_grp6_mux), - FUNCTION("cvbs_dbg_test_m7", - cvbs_dbg_test_grp7, - &cvbs_dbg_test_grp7_mux), - FUNCTION("cvbs_dbg_test_m8", - cvbs_dbg_test_grp8, - &cvbs_dbg_test_grp8_mux), - FUNCTION("cvbs_dbg_test_m9", - cvbs_dbg_test_grp9, - &cvbs_dbg_test_grp9_mux), - FUNCTION("cvbs_dbg_test_m10", - cvbs_dbg_test_grp10, - &cvbs_dbg_test_grp10_mux), - FUNCTION("cvbs_dbg_test_m11", - cvbs_dbg_test_grp11, - &cvbs_dbg_test_grp11_mux), - FUNCTION("cvbs_dbg_test_m12", - cvbs_dbg_test_grp12, - &cvbs_dbg_test_grp12_mux), - FUNCTION("cvbs_dbg_test_m13", - cvbs_dbg_test_grp13, - &cvbs_dbg_test_grp13_mux), - FUNCTION("cvbs_dbg_test_m14", - cvbs_dbg_test_grp14, - &cvbs_dbg_test_grp14_mux), - FUNCTION("cvbs_dbg_test_m15", - cvbs_dbg_test_grp15, - &cvbs_dbg_test_grp15_mux), - FUNCTION("gn_gnss_power", gn_gnss_power_grp, &gn_gnss_power_grp_mux), - FUNCTION("gn_gnss_sw_status", - gn_gnss_sw_status_grp, - &gn_gnss_sw_status_grp_mux), - FUNCTION("gn_gnss_eclk", gn_gnss_eclk_grp, &gn_gnss_eclk_grp_mux), - FUNCTION("gn_gnss_irq1_m0", - gn_gnss_irq1_grp0, - &gn_gnss_irq1_grp0_mux), - FUNCTION("gn_gnss_irq2_m0", - gn_gnss_irq2_grp0, - &gn_gnss_irq2_grp0_mux), - FUNCTION("gn_gnss_tm", gn_gnss_tm_grp, &gn_gnss_tm_grp_mux), - FUNCTION("gn_gnss_tsync", gn_gnss_tsync_grp, &gn_gnss_tsync_grp_mux), - FUNCTION("gn_io_gnsssys_sw_cfg", - gn_io_gnsssys_sw_cfg_grp, - &gn_io_gnsssys_sw_cfg_grp_mux), - FUNCTION("gn_trg_m0", gn_trg_grp0, &gn_trg_grp0_mux), - FUNCTION("gn_trg_m1", gn_trg_grp1, &gn_trg_grp1_mux), - FUNCTION("gn_trg_shutdown_m0", - gn_trg_shutdown_grp0, - &gn_trg_shutdown_grp0_mux), - FUNCTION("gn_trg_shutdown_m1", - gn_trg_shutdown_grp1, - &gn_trg_shutdown_grp1_mux), - FUNCTION("gn_trg_shutdown_m2", - gn_trg_shutdown_grp2, - &gn_trg_shutdown_grp2_mux), - FUNCTION("gn_trg_shutdown_m3", - gn_trg_shutdown_grp3, - &gn_trg_shutdown_grp3_mux), - FUNCTION("i2c0", i2c0_grp, &i2c0_grp_mux), - FUNCTION("i2c1", i2c1_grp, &i2c1_grp_mux), - FUNCTION("i2s0", i2s0_grp, &i2s0_grp_mux), - FUNCTION("i2s1_basic", i2s1_basic_grp, &i2s1_basic_grp_mux), - FUNCTION("i2s1_rxd0_m0", i2s1_rxd0_grp0, &i2s1_rxd0_grp0_mux), - FUNCTION("i2s1_rxd0_m1", i2s1_rxd0_grp1, &i2s1_rxd0_grp1_mux), - FUNCTION("i2s1_rxd0_m2", i2s1_rxd0_grp2, &i2s1_rxd0_grp2_mux), - FUNCTION("i2s1_rxd0_m3", i2s1_rxd0_grp3, &i2s1_rxd0_grp3_mux), - FUNCTION("i2s1_rxd0_m4", i2s1_rxd0_grp4, &i2s1_rxd0_grp4_mux), - FUNCTION("i2s1_rxd1_m0", i2s1_rxd1_grp0, &i2s1_rxd1_grp0_mux), - FUNCTION("i2s1_rxd1_m1", i2s1_rxd1_grp1, &i2s1_rxd1_grp1_mux), - FUNCTION("i2s1_rxd1_m2", i2s1_rxd1_grp2, &i2s1_rxd1_grp2_mux), - FUNCTION("i2s1_rxd1_m3", i2s1_rxd1_grp3, &i2s1_rxd1_grp3_mux), - FUNCTION("i2s1_rxd1_m4", i2s1_rxd1_grp4, &i2s1_rxd1_grp4_mux), - FUNCTION("jtag_jt_dbg_nsrst", - jtag_jt_dbg_nsrst_grp, - &jtag_jt_dbg_nsrst_grp_mux), - FUNCTION("jtag_ntrst_m0", jtag_ntrst_grp0, &jtag_ntrst_grp0_mux), - FUNCTION("jtag_ntrst_m1", jtag_ntrst_grp1, &jtag_ntrst_grp1_mux), - FUNCTION("jtag_swdiotms_m0", - jtag_swdiotms_grp0, - &jtag_swdiotms_grp0_mux), - FUNCTION("jtag_swdiotms_m1", - jtag_swdiotms_grp1, - &jtag_swdiotms_grp1_mux), - FUNCTION("jtag_tck_m0", jtag_tck_grp0, &jtag_tck_grp0_mux), - FUNCTION("jtag_tck_m1", jtag_tck_grp1, &jtag_tck_grp1_mux), - FUNCTION("jtag_tdi_m0", jtag_tdi_grp0, &jtag_tdi_grp0_mux), - FUNCTION("jtag_tdi_m1", jtag_tdi_grp1, &jtag_tdi_grp1_mux), - FUNCTION("jtag_tdo_m0", jtag_tdo_grp0, &jtag_tdo_grp0_mux), - FUNCTION("jtag_tdo_m1", jtag_tdo_grp1, &jtag_tdo_grp1_mux), - FUNCTION("ks_kas_spi_m0", ks_kas_spi_grp0, &ks_kas_spi_grp0_mux), - FUNCTION("ld_ldd", ld_ldd_grp, &ld_ldd_grp_mux), - FUNCTION("ld_ldd_16bit", ld_ldd_16bit_grp, &ld_ldd_16bit_grp_mux), - FUNCTION("ld_ldd_fck", ld_ldd_fck_grp, &ld_ldd_fck_grp_mux), - FUNCTION("ld_ldd_lck", ld_ldd_lck_grp, &ld_ldd_lck_grp_mux), - FUNCTION("lr_lcdrom", lr_lcdrom_grp, &lr_lcdrom_grp_mux), - FUNCTION("lvds_analog", lvds_analog_grp, &lvds_analog_grp_mux), - FUNCTION("nd_df_basic", nd_df_basic_grp, &nd_df_basic_grp_mux), - FUNCTION("nd_df_wp", nd_df_wp_grp, &nd_df_wp_grp_mux), - FUNCTION("nd_df_cs", nd_df_cs_grp, &nd_df_cs_grp_mux), - FUNCTION("ps", ps_grp, &ps_grp_mux), - FUNCTION("ps_no_dir", ps_no_dir_grp, &ps_no_dir_grp_mux), - FUNCTION("pwc_core_on", pwc_core_on_grp, &pwc_core_on_grp_mux), - FUNCTION("pwc_ext_on", pwc_ext_on_grp, &pwc_ext_on_grp_mux), - FUNCTION("pwc_gpio3_clk", pwc_gpio3_clk_grp, &pwc_gpio3_clk_grp_mux), - FUNCTION("pwc_io_on", pwc_io_on_grp, &pwc_io_on_grp_mux), - FUNCTION("pwc_lowbatt_b_m0", - pwc_lowbatt_b_grp0, - &pwc_lowbatt_b_grp0_mux), - FUNCTION("pwc_mem_on", pwc_mem_on_grp, &pwc_mem_on_grp_mux), - FUNCTION("pwc_on_key_b_m0", - pwc_on_key_b_grp0, - &pwc_on_key_b_grp0_mux), - FUNCTION("pwc_wakeup_src0", - pwc_wakeup_src0_grp, - &pwc_wakeup_src0_grp_mux), - FUNCTION("pwc_wakeup_src1", - pwc_wakeup_src1_grp, - &pwc_wakeup_src1_grp_mux), - FUNCTION("pwc_wakeup_src2", - pwc_wakeup_src2_grp, - &pwc_wakeup_src2_grp_mux), - FUNCTION("pwc_wakeup_src3", - pwc_wakeup_src3_grp, - &pwc_wakeup_src3_grp_mux), - FUNCTION("pw_cko0_m0", pw_cko0_grp0, &pw_cko0_grp0_mux), - FUNCTION("pw_cko0_m1", pw_cko0_grp1, &pw_cko0_grp1_mux), - FUNCTION("pw_cko0_m2", pw_cko0_grp2, &pw_cko0_grp2_mux), - FUNCTION("pw_cko0_m3", pw_cko0_grp3, &pw_cko0_grp3_mux), - FUNCTION("pw_cko1_m0", pw_cko1_grp0, &pw_cko1_grp0_mux), - FUNCTION("pw_cko1_m1", pw_cko1_grp1, &pw_cko1_grp1_mux), - FUNCTION("pw_cko1_m2", pw_cko1_grp2, &pw_cko1_grp2_mux), - FUNCTION("pw_i2s01_clk_m0", - pw_i2s01_clk_grp0, - &pw_i2s01_clk_grp0_mux), - FUNCTION("pw_i2s01_clk_m1", - pw_i2s01_clk_grp1, - &pw_i2s01_clk_grp1_mux), - FUNCTION("pw_i2s01_clk_m2", - pw_i2s01_clk_grp2, - &pw_i2s01_clk_grp2_mux), - FUNCTION("pw_pwm0_m0", pw_pwm0_grp0, &pw_pwm0_grp0_mux), - FUNCTION("pw_pwm0_m1", pw_pwm0_grp1, &pw_pwm0_grp1_mux), - FUNCTION("pw_pwm1_m0", pw_pwm1_grp0, &pw_pwm1_grp0_mux), - FUNCTION("pw_pwm1_m1", pw_pwm1_grp1, &pw_pwm1_grp1_mux), - FUNCTION("pw_pwm1_m2", pw_pwm1_grp2, &pw_pwm1_grp2_mux), - FUNCTION("pw_pwm2_m0", pw_pwm2_grp0, &pw_pwm2_grp0_mux), - FUNCTION("pw_pwm2_m1", pw_pwm2_grp1, &pw_pwm2_grp1_mux), - FUNCTION("pw_pwm2_m2", pw_pwm2_grp2, &pw_pwm2_grp2_mux), - FUNCTION("pw_pwm3_m0", pw_pwm3_grp0, &pw_pwm3_grp0_mux), - FUNCTION("pw_pwm3_m1", pw_pwm3_grp1, &pw_pwm3_grp1_mux), - FUNCTION("pw_pwm_cpu_vol_m0", - pw_pwm_cpu_vol_grp0, - &pw_pwm_cpu_vol_grp0_mux), - FUNCTION("pw_pwm_cpu_vol_m1", - pw_pwm_cpu_vol_grp1, - &pw_pwm_cpu_vol_grp1_mux), - FUNCTION("pw_pwm_cpu_vol_m2", - pw_pwm_cpu_vol_grp2, - &pw_pwm_cpu_vol_grp2_mux), - FUNCTION("pw_backlight_m0", - pw_backlight_grp0, - &pw_backlight_grp0_mux), - FUNCTION("pw_backlight_m1", - pw_backlight_grp1, - &pw_backlight_grp1_mux), - FUNCTION("rg_eth_mac", rg_eth_mac_grp, &rg_eth_mac_grp_mux), - FUNCTION("rg_gmac_phy_intr_n", - rg_gmac_phy_intr_n_grp, - &rg_gmac_phy_intr_n_grp_mux), - FUNCTION("rg_rgmii_mac", rg_rgmii_mac_grp, &rg_rgmii_mac_grp_mux), - FUNCTION("rg_rgmii_phy_ref_clk_m0", - rg_rgmii_phy_ref_clk_grp0, - &rg_rgmii_phy_ref_clk_grp0_mux), - FUNCTION("rg_rgmii_phy_ref_clk_m1", - rg_rgmii_phy_ref_clk_grp1, - &rg_rgmii_phy_ref_clk_grp1_mux), - FUNCTION("sd0", sd0_grp, &sd0_grp_mux), - FUNCTION("sd0_4bit", sd0_4bit_grp, &sd0_4bit_grp_mux), - FUNCTION("sd1", sd1_grp, &sd1_grp_mux), - FUNCTION("sd1_4bit_m0", sd1_4bit_grp0, &sd1_4bit_grp0_mux), - FUNCTION("sd1_4bit_m1", sd1_4bit_grp1, &sd1_4bit_grp1_mux), - FUNCTION("sd2_basic", sd2_basic_grp, &sd2_basic_grp_mux), - FUNCTION("sd2_cdb_m0", sd2_cdb_grp0, &sd2_cdb_grp0_mux), - FUNCTION("sd2_cdb_m1", sd2_cdb_grp1, &sd2_cdb_grp1_mux), - FUNCTION("sd2_wpb_m0", sd2_wpb_grp0, &sd2_wpb_grp0_mux), - FUNCTION("sd2_wpb_m1", sd2_wpb_grp1, &sd2_wpb_grp1_mux), - FUNCTION("sd3", sd3_9_grp, &sd3_9_grp_mux), - FUNCTION("sd5", sd5_grp, &sd5_grp_mux), - FUNCTION("sd6_m0", sd6_grp0, &sd6_grp0_mux), - FUNCTION("sd6_m1", sd6_grp1, &sd6_grp1_mux), - FUNCTION("sd9", sd3_9_grp, &sd3_9_grp_mux), - FUNCTION("sp0_ext_ldo_on", - sp0_ext_ldo_on_grp, - &sp0_ext_ldo_on_grp_mux), - FUNCTION("sp0_qspi", sp0_qspi_grp, &sp0_qspi_grp_mux), - FUNCTION("sp1_spi", sp1_spi_grp, &sp1_spi_grp_mux), - FUNCTION("tpiu_trace", tpiu_trace_grp, &tpiu_trace_grp_mux), - FUNCTION("uart0", uart0_grp, &uart0_grp_mux), - FUNCTION("uart0_nopause", uart0_nopause_grp, &uart0_nopause_grp_mux), - FUNCTION("uart1", uart1_grp, &uart1_grp_mux), - FUNCTION("uart2_cts_m0", uart2_cts_grp0, &uart2_cts_grp0_mux), - FUNCTION("uart2_cts_m1", uart2_cts_grp1, &uart2_cts_grp1_mux), - FUNCTION("uart2_rts_m0", uart2_rts_grp0, &uart2_rts_grp0_mux), - FUNCTION("uart2_rts_m1", uart2_rts_grp1, &uart2_rts_grp1_mux), - FUNCTION("uart2_rxd_m0", uart2_rxd_grp0, &uart2_rxd_grp0_mux), - FUNCTION("uart2_rxd_m1", uart2_rxd_grp1, &uart2_rxd_grp1_mux), - FUNCTION("uart2_rxd_m2", uart2_rxd_grp2, &uart2_rxd_grp2_mux), - FUNCTION("uart2_txd_m0", uart2_txd_grp0, &uart2_txd_grp0_mux), - FUNCTION("uart2_txd_m1", uart2_txd_grp1, &uart2_txd_grp1_mux), - FUNCTION("uart2_txd_m2", uart2_txd_grp2, &uart2_txd_grp2_mux), - FUNCTION("uart3_cts_m0", uart3_cts_grp0, &uart3_cts_grp0_mux), - FUNCTION("uart3_cts_m1", uart3_cts_grp1, &uart3_cts_grp1_mux), - FUNCTION("uart3_cts_m2", uart3_cts_grp2, &uart3_cts_grp2_mux), - FUNCTION("uart3_rts_m0", uart3_rts_grp0, &uart3_rts_grp0_mux), - FUNCTION("uart3_rts_m1", uart3_rts_grp1, &uart3_rts_grp1_mux), - FUNCTION("uart3_rts_m2", uart3_rts_grp2, &uart3_rts_grp2_mux), - FUNCTION("uart3_rxd_m0", uart3_rxd_grp0, &uart3_rxd_grp0_mux), - FUNCTION("uart3_rxd_m1", uart3_rxd_grp1, &uart3_rxd_grp1_mux), - FUNCTION("uart3_rxd_m2", uart3_rxd_grp2, &uart3_rxd_grp2_mux), - FUNCTION("uart3_txd_m0", uart3_txd_grp0, &uart3_txd_grp0_mux), - FUNCTION("uart3_txd_m1", uart3_txd_grp1, &uart3_txd_grp1_mux), - FUNCTION("uart3_txd_m2", uart3_txd_grp2, &uart3_txd_grp2_mux), - FUNCTION("uart4_basic", uart4_basic_grp, &uart4_basic_grp_mux), - FUNCTION("uart4_cts_m0", uart4_cts_grp0, &uart4_cts_grp0_mux), - FUNCTION("uart4_cts_m1", uart4_cts_grp1, &uart4_cts_grp1_mux), - FUNCTION("uart4_cts_m2", uart4_cts_grp2, &uart4_cts_grp2_mux), - FUNCTION("uart4_rts_m0", uart4_rts_grp0, &uart4_rts_grp0_mux), - FUNCTION("uart4_rts_m1", uart4_rts_grp1, &uart4_rts_grp1_mux), - FUNCTION("uart4_rts_m2", uart4_rts_grp2, &uart4_rts_grp2_mux), - FUNCTION("usb0_drvvbus_m0", - usb0_drvvbus_grp0, - &usb0_drvvbus_grp0_mux), - FUNCTION("usb0_drvvbus_m1", - usb0_drvvbus_grp1, - &usb0_drvvbus_grp1_mux), - FUNCTION("usb1_drvvbus_m0", - usb1_drvvbus_grp0, - &usb1_drvvbus_grp0_mux), - FUNCTION("usb1_drvvbus_m1", - usb1_drvvbus_grp1, - &usb1_drvvbus_grp1_mux), - FUNCTION("visbus_dout", visbus_dout_grp, &visbus_dout_grp_mux), - FUNCTION("vi_vip1", vi_vip1_grp, &vi_vip1_grp_mux), - FUNCTION("vi_vip1_ext", vi_vip1_ext_grp, &vi_vip1_ext_grp_mux), - FUNCTION("vi_vip1_low8bit", - vi_vip1_low8bit_grp, - &vi_vip1_low8bit_grp_mux), - FUNCTION("vi_vip1_high8bit", - vi_vip1_high8bit_grp, - &vi_vip1_high8bit_grp_mux), -}; - -static struct atlas7_pinctrl_data atlas7_ioc_data = { - .pads = (struct pinctrl_pin_desc *)atlas7_ioc_pads, - .pads_cnt = ARRAY_SIZE(atlas7_ioc_pads), - .grps = (struct atlas7_pin_group *)altas7_pin_groups, - .grps_cnt = ARRAY_SIZE(altas7_pin_groups), - .funcs = (struct atlas7_pmx_func *)atlas7_pmx_functions, - .funcs_cnt = ARRAY_SIZE(atlas7_pmx_functions), - .confs = (struct atlas7_pad_config *)atlas7_ioc_pad_confs, - .confs_cnt = ARRAY_SIZE(atlas7_ioc_pad_confs), -}; - -/* Simple map data structure */ -struct map_data { - u8 idx; - u8 data; -}; - -/** - * struct atlas7_pull_info - Atlas7 Pad pull info - * @pad_type: The type of this Pad. - * @mask: The mas value of this pin's pull bits. - * @v2s: The map of pull register value to pull status. - * @s2v: The map of pull status to pull register value. - */ -struct atlas7_pull_info { - u8 pad_type; - u8 mask; - const struct map_data *v2s; - const struct map_data *s2v; -}; - -/* Pull Register value map to status */ -static const struct map_data p4we_pull_v2s[] = { - { P4WE_PULL_UP, PULL_UP }, - { P4WE_HIGH_HYSTERESIS, HIGH_HYSTERESIS }, - { P4WE_HIGH_Z, HIGH_Z }, - { P4WE_PULL_DOWN, PULL_DOWN }, -}; - -static const struct map_data p16st_pull_v2s[] = { - { P16ST_PULL_UP, PULL_UP }, - { PD, PULL_UNKNOWN }, - { P16ST_HIGH_Z, HIGH_Z }, - { P16ST_PULL_DOWN, PULL_DOWN }, -}; - -static const struct map_data pm31_pull_v2s[] = { - { PM31_PULL_DISABLED, PULL_DOWN }, - { PM31_PULL_ENABLED, PULL_UP }, -}; - -static const struct map_data pangd_pull_v2s[] = { - { PANGD_PULL_UP, PULL_UP }, - { PD, PULL_UNKNOWN }, - { PANGD_HIGH_Z, HIGH_Z }, - { PANGD_PULL_DOWN, PULL_DOWN }, -}; - -/* Pull status map to register value */ -static const struct map_data p4we_pull_s2v[] = { - { PULL_UP, P4WE_PULL_UP }, - { HIGH_HYSTERESIS, P4WE_HIGH_HYSTERESIS }, - { HIGH_Z, P4WE_HIGH_Z }, - { PULL_DOWN, P4WE_PULL_DOWN }, - { PULL_DISABLE, -1 }, - { PULL_ENABLE, -1 }, -}; - -static const struct map_data p16st_pull_s2v[] = { - { PULL_UP, P16ST_PULL_UP }, - { HIGH_HYSTERESIS, -1 }, - { HIGH_Z, P16ST_HIGH_Z }, - { PULL_DOWN, P16ST_PULL_DOWN }, - { PULL_DISABLE, -1 }, - { PULL_ENABLE, -1 }, -}; - -static const struct map_data pm31_pull_s2v[] = { - { PULL_UP, PM31_PULL_ENABLED }, - { HIGH_HYSTERESIS, -1 }, - { HIGH_Z, -1 }, - { PULL_DOWN, PM31_PULL_DISABLED }, - { PULL_DISABLE, -1 }, - { PULL_ENABLE, -1 }, -}; - -static const struct map_data pangd_pull_s2v[] = { - { PULL_UP, PANGD_PULL_UP }, - { HIGH_HYSTERESIS, -1 }, - { HIGH_Z, PANGD_HIGH_Z }, - { PULL_DOWN, PANGD_PULL_DOWN }, - { PULL_DISABLE, -1 }, - { PULL_ENABLE, -1 }, -}; - -static const struct atlas7_pull_info atlas7_pull_map[] = { - { PAD_T_4WE_PD, P4WE_PULL_MASK, p4we_pull_v2s, p4we_pull_s2v }, - { PAD_T_4WE_PU, P4WE_PULL_MASK, p4we_pull_v2s, p4we_pull_s2v }, - { PAD_T_16ST, P16ST_PULL_MASK, p16st_pull_v2s, p16st_pull_s2v }, - { PAD_T_M31_0204_PD, PM31_PULL_MASK, pm31_pull_v2s, pm31_pull_s2v }, - { PAD_T_M31_0204_PU, PM31_PULL_MASK, pm31_pull_v2s, pm31_pull_s2v }, - { PAD_T_M31_0610_PD, PM31_PULL_MASK, pm31_pull_v2s, pm31_pull_s2v }, - { PAD_T_M31_0610_PU, PM31_PULL_MASK, pm31_pull_v2s, pm31_pull_s2v }, - { PAD_T_AD, PANGD_PULL_MASK, pangd_pull_v2s, pangd_pull_s2v }, -}; - -/** - * struct atlas7_ds_ma_info - Atlas7 Pad DriveStrength & currents info - * @ma: The Drive Strength in current value . - * @ds_16st: The correspond raw value of 16st pad. - * @ds_4we: The correspond raw value of 4we pad. - * @ds_0204m31: The correspond raw value of 0204m31 pad. - * @ds_0610m31: The correspond raw value of 0610m31 pad. - */ -struct atlas7_ds_ma_info { - u32 ma; - u32 ds_16st; - u32 ds_4we; - u32 ds_0204m31; - u32 ds_0610m31; -}; - -static const struct atlas7_ds_ma_info atlas7_ma2ds_map[] = { - { 2, DS_16ST_0, DS_4WE_0, DS_M31_0, DS_NULL }, - { 4, DS_16ST_1, DS_NULL, DS_M31_1, DS_NULL }, - { 6, DS_16ST_2, DS_NULL, DS_NULL, DS_M31_0 }, - { 8, DS_16ST_3, DS_4WE_1, DS_NULL, DS_NULL }, - { 10, DS_16ST_4, DS_NULL, DS_NULL, DS_M31_1 }, - { 12, DS_16ST_5, DS_NULL, DS_NULL, DS_NULL }, - { 14, DS_16ST_6, DS_NULL, DS_NULL, DS_NULL }, - { 16, DS_16ST_7, DS_4WE_2, DS_NULL, DS_NULL }, - { 18, DS_16ST_8, DS_NULL, DS_NULL, DS_NULL }, - { 20, DS_16ST_9, DS_NULL, DS_NULL, DS_NULL }, - { 22, DS_16ST_10, DS_NULL, DS_NULL, DS_NULL }, - { 24, DS_16ST_11, DS_NULL, DS_NULL, DS_NULL }, - { 26, DS_16ST_12, DS_NULL, DS_NULL, DS_NULL }, - { 28, DS_16ST_13, DS_4WE_3, DS_NULL, DS_NULL }, - { 30, DS_16ST_14, DS_NULL, DS_NULL, DS_NULL }, - { 32, DS_16ST_15, DS_NULL, DS_NULL, DS_NULL }, -}; - -/** - * struct atlas7_ds_info - Atlas7 Pad DriveStrength info - * @type: The type of this Pad. - * @mask: The mask value of this pin's pull bits. - * @imval: The immediate value of drives trength register. - * @reserved: Reserved space - */ -struct atlas7_ds_info { - u8 type; - u8 mask; - u8 imval; - u8 reserved; -}; - -static const struct atlas7_ds_info atlas7_ds_map[] = { - { PAD_T_4WE_PD, DS_2BIT_MASK, DS_2BIT_IM_VAL }, - { PAD_T_4WE_PU, DS_2BIT_MASK, DS_2BIT_IM_VAL }, - { PAD_T_16ST, DS_4BIT_MASK, DS_4BIT_IM_VAL }, - { PAD_T_M31_0204_PD, DS_1BIT_MASK, DS_1BIT_IM_VAL }, - { PAD_T_M31_0204_PU, DS_1BIT_MASK, DS_1BIT_IM_VAL }, - { PAD_T_M31_0610_PD, DS_1BIT_MASK, DS_1BIT_IM_VAL }, - { PAD_T_M31_0610_PU, DS_1BIT_MASK, DS_1BIT_IM_VAL }, - { PAD_T_AD, DS_NULL, DS_NULL }, -}; - -static inline u32 atlas7_pin_to_bank(u32 pin) -{ - return (pin >= ATLAS7_PINCTRL_BANK_0_PINS) ? 1 : 0; -} - -static int atlas7_pmx_get_funcs_count(struct pinctrl_dev *pctldev) -{ - struct atlas7_pmx *pmx = pinctrl_dev_get_drvdata(pctldev); - - return pmx->pctl_data->funcs_cnt; -} - -static const char *atlas7_pmx_get_func_name(struct pinctrl_dev *pctldev, - u32 selector) -{ - struct atlas7_pmx *pmx = pinctrl_dev_get_drvdata(pctldev); - - return pmx->pctl_data->funcs[selector].name; -} - -static int atlas7_pmx_get_func_groups(struct pinctrl_dev *pctldev, - u32 selector, const char * const **groups, - u32 * const num_groups) -{ - struct atlas7_pmx *pmx = pinctrl_dev_get_drvdata(pctldev); - - *groups = pmx->pctl_data->funcs[selector].groups; - *num_groups = pmx->pctl_data->funcs[selector].num_groups; - - return 0; -} - -static void __atlas7_pmx_pin_input_disable_set(struct atlas7_pmx *pmx, - const struct atlas7_pad_mux *mux) -{ - /* Set Input Disable to avoid input glitches - * - * All Input-Disable Control registers are located on IOCRTC. - * So the regs bank is always 0. - * - */ - if (mux->dinput_reg && mux->dinput_val_reg) { - writel(DI_MASK << mux->dinput_bit, - pmx->regs[BANK_DS] + CLR_REG(mux->dinput_reg)); - writel(DI_DISABLE << mux->dinput_bit, - pmx->regs[BANK_DS] + mux->dinput_reg); - - - writel(DIV_MASK << mux->dinput_val_bit, - pmx->regs[BANK_DS] + CLR_REG(mux->dinput_val_reg)); - writel(DIV_DISABLE << mux->dinput_val_bit, - pmx->regs[BANK_DS] + mux->dinput_val_reg); - } -} - -static void __atlas7_pmx_pin_input_disable_clr(struct atlas7_pmx *pmx, - const struct atlas7_pad_mux *mux) -{ - /* Clear Input Disable to avoid input glitches */ - if (mux->dinput_reg && mux->dinput_val_reg) { - writel(DI_MASK << mux->dinput_bit, - pmx->regs[BANK_DS] + CLR_REG(mux->dinput_reg)); - writel(DI_ENABLE << mux->dinput_bit, - pmx->regs[BANK_DS] + mux->dinput_reg); - - writel(DIV_MASK << mux->dinput_val_bit, - pmx->regs[BANK_DS] + CLR_REG(mux->dinput_val_reg)); - writel(DIV_ENABLE << mux->dinput_val_bit, - pmx->regs[BANK_DS] + mux->dinput_val_reg); - } -} - -static int __atlas7_pmx_pin_ad_sel(struct atlas7_pmx *pmx, - struct atlas7_pad_config *conf, - u32 bank, u32 ad_sel) -{ - unsigned long regv; - - /* Write to clear register to clear A/D selector */ - writel(ANA_CLEAR_MASK << conf->ad_ctrl_bit, - pmx->regs[bank] + CLR_REG(conf->ad_ctrl_reg)); - - /* Set target pad A/D selector */ - regv = readl(pmx->regs[bank] + conf->ad_ctrl_reg); - regv &= ~(ANA_CLEAR_MASK << conf->ad_ctrl_bit); - writel(regv | (ad_sel << conf->ad_ctrl_bit), - pmx->regs[bank] + conf->ad_ctrl_reg); - - regv = readl(pmx->regs[bank] + conf->ad_ctrl_reg); - pr_debug("bank:%d reg:0x%04x val:0x%08lx\n", - bank, conf->ad_ctrl_reg, regv); - return 0; -} - -static int __atlas7_pmx_pin_analog_enable(struct atlas7_pmx *pmx, - struct atlas7_pad_config *conf, u32 bank) -{ - /* Only PAD_T_AD pins can change between Analogue&Digital */ - if (conf->type != PAD_T_AD) - return -EINVAL; - - return __atlas7_pmx_pin_ad_sel(pmx, conf, bank, 0); -} - -static int __atlas7_pmx_pin_digital_enable(struct atlas7_pmx *pmx, - struct atlas7_pad_config *conf, u32 bank) -{ - /* Other type pads are always digital */ - if (conf->type != PAD_T_AD) - return 0; - - return __atlas7_pmx_pin_ad_sel(pmx, conf, bank, 1); -} - -static int __atlas7_pmx_pin_enable(struct atlas7_pmx *pmx, - u32 pin, u32 func) -{ - struct atlas7_pad_config *conf; - u32 bank; - int ret; - unsigned long regv; - - pr_debug("PMX DUMP ### pin#%d func:%d #### START >>>\n", - pin, func); - - /* Get this Pad's descriptor from PINCTRL */ - conf = &pmx->pctl_data->confs[pin]; - bank = atlas7_pin_to_bank(pin); - - /* Just enable the analog function of this pad */ - if (FUNC_ANALOGUE == func) { - ret = __atlas7_pmx_pin_analog_enable(pmx, conf, bank); - if (ret) - dev_err(pmx->dev, - "Convert pad#%d to analog failed, ret=%d\n", - pin, ret); - return ret; - } - - /* Set Pads from analog to digital */ - ret = __atlas7_pmx_pin_digital_enable(pmx, conf, bank); - if (ret) { - dev_err(pmx->dev, - "Convert pad#%d to digital failed, ret=%d\n", - pin, ret); - return ret; - } - - /* Write to clear register to clear current function */ - writel(FUNC_CLEAR_MASK << conf->mux_bit, - pmx->regs[bank] + CLR_REG(conf->mux_reg)); - - /* Set target pad mux function */ - regv = readl(pmx->regs[bank] + conf->mux_reg); - regv &= ~(FUNC_CLEAR_MASK << conf->mux_bit); - writel(regv | (func << conf->mux_bit), - pmx->regs[bank] + conf->mux_reg); - - regv = readl(pmx->regs[bank] + conf->mux_reg); - pr_debug("bank:%d reg:0x%04x val:0x%08lx\n", - bank, conf->mux_reg, regv); - - return 0; -} - -static int atlas7_pmx_set_mux(struct pinctrl_dev *pctldev, - u32 func_selector, u32 group_selector) -{ - int idx, ret; - struct atlas7_pmx *pmx = pinctrl_dev_get_drvdata(pctldev); - struct atlas7_pmx_func *pmx_func; - struct atlas7_pin_group *pin_grp; - const struct atlas7_grp_mux *grp_mux; - const struct atlas7_pad_mux *mux; - - pmx_func = &pmx->pctl_data->funcs[func_selector]; - pin_grp = &pmx->pctl_data->grps[group_selector]; - - pr_debug("PMX DUMP ### Function:[%s] Group:[%s] #### START >>>\n", - pmx_func->name, pin_grp->name); - - /* the sd3 and sd9 pin select by SYS2PCI_SDIO9SEL register */ - if (pin_grp->pins == (unsigned int *)&sd3_9_pins) { - if (!strcmp(pmx_func->name, "sd9")) - writel(1, pmx->sys2pci_base + SYS2PCI_SDIO9SEL); - else - writel(0, pmx->sys2pci_base + SYS2PCI_SDIO9SEL); - } - - grp_mux = pmx_func->grpmux; - - for (idx = 0; idx < grp_mux->pad_mux_count; idx++) { - mux = &grp_mux->pad_mux_list[idx]; - __atlas7_pmx_pin_input_disable_set(pmx, mux); - ret = __atlas7_pmx_pin_enable(pmx, mux->pin, mux->func); - if (ret) { - dev_err(pmx->dev, - "FUNC:%s GRP:%s PIN#%d.%d failed, ret=%d\n", - pmx_func->name, pin_grp->name, - mux->pin, mux->func, ret); - BUG_ON(1); - } - __atlas7_pmx_pin_input_disable_clr(pmx, mux); - } - pr_debug("PMX DUMP ### Function:[%s] Group:[%s] #### END <<<\n", - pmx_func->name, pin_grp->name); - - return 0; -} - -static u32 convert_current_to_drive_strength(u32 type, u32 ma) -{ - int idx; - - for (idx = 0; idx < ARRAY_SIZE(atlas7_ma2ds_map); idx++) { - if (atlas7_ma2ds_map[idx].ma != ma) - continue; - - if (type == PAD_T_4WE_PD || type == PAD_T_4WE_PU) - return atlas7_ma2ds_map[idx].ds_4we; - else if (type == PAD_T_16ST) - return atlas7_ma2ds_map[idx].ds_16st; - else if (type == PAD_T_M31_0204_PD || type == PAD_T_M31_0204_PU) - return atlas7_ma2ds_map[idx].ds_0204m31; - else if (type == PAD_T_M31_0610_PD || type == PAD_T_M31_0610_PU) - return atlas7_ma2ds_map[idx].ds_0610m31; - } - - return DS_NULL; -} - -static int altas7_pinctrl_set_pull_sel(struct pinctrl_dev *pctldev, - u32 pin, u32 sel) -{ - struct atlas7_pmx *pmx = pinctrl_dev_get_drvdata(pctldev); - struct atlas7_pad_config *conf = &pmx->pctl_data->confs[pin]; - const struct atlas7_pull_info *pull_info; - u32 bank; - unsigned long regv; - void __iomem *pull_sel_reg; - - bank = atlas7_pin_to_bank(pin); - pull_info = &atlas7_pull_map[conf->type]; - pull_sel_reg = pmx->regs[bank] + conf->pupd_reg; - - /* Retrieve correspond register value from table by sel */ - regv = pull_info->s2v[sel].data & pull_info->mask; - - /* Clear & Set new value to pull register */ - writel(pull_info->mask << conf->pupd_bit, CLR_REG(pull_sel_reg)); - writel(regv << conf->pupd_bit, pull_sel_reg); - - pr_debug("PIN_CFG ### SET PIN#%d PULL SELECTOR:%d == OK ####\n", - pin, sel); - return 0; -} - -static int __altas7_pinctrl_set_drive_strength_sel(struct pinctrl_dev *pctldev, - u32 pin, u32 sel) -{ - struct atlas7_pmx *pmx = pinctrl_dev_get_drvdata(pctldev); - struct atlas7_pad_config *conf = &pmx->pctl_data->confs[pin]; - const struct atlas7_ds_info *ds_info; - u32 bank; - void __iomem *ds_sel_reg; - - ds_info = &atlas7_ds_map[conf->type]; - if (sel & (~(ds_info->mask))) - goto unsupport; - - bank = atlas7_pin_to_bank(pin); - ds_sel_reg = pmx->regs[bank] + conf->drvstr_reg; - - writel(ds_info->imval << conf->drvstr_bit, CLR_REG(ds_sel_reg)); - writel(sel << conf->drvstr_bit, ds_sel_reg); - - return 0; - -unsupport: - pr_err("Pad#%d type[%d] doesn't support ds code[%d]!\n", - pin, conf->type, sel); - return -ENOTSUPP; -} - -static int altas7_pinctrl_set_drive_strength_sel(struct pinctrl_dev *pctldev, - u32 pin, u32 ma) -{ - struct atlas7_pmx *pmx = pinctrl_dev_get_drvdata(pctldev); - struct atlas7_pad_config *conf = &pmx->pctl_data->confs[pin]; - u32 type = conf->type; - u32 sel; - int ret; - - sel = convert_current_to_drive_strength(conf->type, ma); - if (DS_NULL == sel) { - pr_err("Pad#%d type[%d] doesn't support ds current[%d]!\n", - pin, type, ma); - return -ENOTSUPP; - } - - ret = __altas7_pinctrl_set_drive_strength_sel(pctldev, - pin, sel); - pr_debug("PIN_CFG ### SET PIN#%d DS:%d MA:%d == %s ####\n", - pin, sel, ma, ret?"FAILED":"OK"); - return ret; -} - -static int atlas7_pmx_gpio_request_enable(struct pinctrl_dev *pctldev, - struct pinctrl_gpio_range *range, u32 pin) -{ - struct atlas7_pmx *pmx = pinctrl_dev_get_drvdata(pctldev); - u32 idx; - - dev_dbg(pmx->dev, - "atlas7_pmx_gpio_request_enable: pin=%d\n", pin); - for (idx = 0; idx < range->npins; idx++) { - if (pin == range->pins[idx]) - break; - } - - if (idx >= range->npins) { - dev_err(pmx->dev, - "The pin#%d could not be requested as GPIO!!\n", - pin); - return -EPERM; - } - - __atlas7_pmx_pin_enable(pmx, pin, FUNC_GPIO); - - return 0; -} - -static const struct pinmux_ops atlas7_pinmux_ops = { - .get_functions_count = atlas7_pmx_get_funcs_count, - .get_function_name = atlas7_pmx_get_func_name, - .get_function_groups = atlas7_pmx_get_func_groups, - .set_mux = atlas7_pmx_set_mux, - .gpio_request_enable = atlas7_pmx_gpio_request_enable, -}; - -static int atlas7_pinctrl_get_groups_count(struct pinctrl_dev *pctldev) -{ - struct atlas7_pmx *pmx = pinctrl_dev_get_drvdata(pctldev); - - return pmx->pctl_data->grps_cnt; -} - -static const char *atlas7_pinctrl_get_group_name(struct pinctrl_dev *pctldev, - u32 group) -{ - struct atlas7_pmx *pmx = pinctrl_dev_get_drvdata(pctldev); - - return pmx->pctl_data->grps[group].name; -} - -static int atlas7_pinctrl_get_group_pins(struct pinctrl_dev *pctldev, - u32 group, const u32 **pins, u32 *num_pins) -{ - struct atlas7_pmx *pmx = pinctrl_dev_get_drvdata(pctldev); - - *num_pins = pmx->pctl_data->grps[group].num_pins; - *pins = pmx->pctl_data->grps[group].pins; - - return 0; -} - -static int atlas7_pinctrl_dt_node_to_map(struct pinctrl_dev *pctldev, - struct device_node *np_config, - struct pinctrl_map **map, - u32 *num_maps) -{ - return pinconf_generic_dt_node_to_map(pctldev, np_config, map, - num_maps, PIN_MAP_TYPE_INVALID); -} - -static void atlas7_pinctrl_dt_free_map(struct pinctrl_dev *pctldev, - struct pinctrl_map *map, u32 num_maps) -{ - kfree(map); -} - -static const struct pinctrl_ops atlas7_pinctrl_ops = { - .get_groups_count = atlas7_pinctrl_get_groups_count, - .get_group_name = atlas7_pinctrl_get_group_name, - .get_group_pins = atlas7_pinctrl_get_group_pins, - .dt_node_to_map = atlas7_pinctrl_dt_node_to_map, - .dt_free_map = atlas7_pinctrl_dt_free_map, -}; - -static int atlas7_pin_config_set(struct pinctrl_dev *pctldev, - unsigned pin, unsigned long *configs, - unsigned num_configs) -{ - u16 param; - u32 arg; - int idx, err; - - for (idx = 0; idx < num_configs; idx++) { - param = pinconf_to_config_param(configs[idx]); - arg = pinconf_to_config_argument(configs[idx]); - - pr_debug("PMX CFG###### ATLAS7 PIN#%d [%s] CONFIG PARAM:%d ARG:%d >>>>>\n", - pin, atlas7_ioc_pads[pin].name, param, arg); - switch (param) { - case PIN_CONFIG_BIAS_PULL_UP: - err = altas7_pinctrl_set_pull_sel(pctldev, - pin, PULL_UP); - if (err) - return err; - break; - - case PIN_CONFIG_BIAS_PULL_DOWN: - err = altas7_pinctrl_set_pull_sel(pctldev, - pin, PULL_DOWN); - if (err) - return err; - break; - - case PIN_CONFIG_INPUT_SCHMITT_ENABLE: - err = altas7_pinctrl_set_pull_sel(pctldev, - pin, HIGH_HYSTERESIS); - if (err) - return err; - break; - case PIN_CONFIG_BIAS_HIGH_IMPEDANCE: - err = altas7_pinctrl_set_pull_sel(pctldev, - pin, HIGH_Z); - if (err) - return err; - break; - - case PIN_CONFIG_DRIVE_STRENGTH: - err = altas7_pinctrl_set_drive_strength_sel(pctldev, - pin, arg); - if (err) - return err; - break; - default: - return -ENOTSUPP; - } - pr_debug("PMX CFG###### ATLAS7 PIN#%d [%s] CONFIG PARAM:%d ARG:%d <<<<\n", - pin, atlas7_ioc_pads[pin].name, param, arg); - } - - return 0; -} - -static int atlas7_pin_config_group_set(struct pinctrl_dev *pctldev, - unsigned group, unsigned long *configs, - unsigned num_configs) -{ - const unsigned *pins; - unsigned npins; - int i, ret; - - ret = atlas7_pinctrl_get_group_pins(pctldev, group, &pins, &npins); - if (ret) - return ret; - for (i = 0; i < npins; i++) { - if (atlas7_pin_config_set(pctldev, pins[i], - configs, num_configs)) - return -ENOTSUPP; - } - return 0; -} - -static const struct pinconf_ops atlas7_pinconf_ops = { - .pin_config_set = atlas7_pin_config_set, - .pin_config_group_set = atlas7_pin_config_group_set, - .is_generic = true, -}; - -static int atlas7_pinmux_probe(struct platform_device *pdev) -{ - int ret, idx; - struct atlas7_pmx *pmx; - struct device_node *np = pdev->dev.of_node; - u32 banks = ATLAS7_PINCTRL_REG_BANKS; - struct device_node *sys2pci_np; - struct resource res; - - /* Create state holders etc for this driver */ - pmx = devm_kzalloc(&pdev->dev, sizeof(*pmx), GFP_KERNEL); - if (!pmx) - return -ENOMEM; - - /* The sd3 and sd9 shared all pins, and the function select by - * SYS2PCI_SDIO9SEL register - */ - sys2pci_np = of_find_node_by_name(NULL, "sys2pci"); - if (!sys2pci_np) - return -EINVAL; - - ret = of_address_to_resource(sys2pci_np, 0, &res); - of_node_put(sys2pci_np); - if (ret) - return ret; - - pmx->sys2pci_base = devm_ioremap_resource(&pdev->dev, &res); - if (IS_ERR(pmx->sys2pci_base)) - return -ENOMEM; - - pmx->dev = &pdev->dev; - - pmx->pctl_data = &atlas7_ioc_data; - pmx->pctl_desc.name = "pinctrl-atlas7"; - pmx->pctl_desc.pins = pmx->pctl_data->pads; - pmx->pctl_desc.npins = pmx->pctl_data->pads_cnt; - pmx->pctl_desc.pctlops = &atlas7_pinctrl_ops; - pmx->pctl_desc.pmxops = &atlas7_pinmux_ops; - pmx->pctl_desc.confops = &atlas7_pinconf_ops; - - for (idx = 0; idx < banks; idx++) { - pmx->regs[idx] = of_iomap(np, idx); - if (!pmx->regs[idx]) { - dev_err(&pdev->dev, - "can't map ioc bank#%d registers\n", idx); - ret = -ENOMEM; - goto unmap_io; - } - } - - /* Now register the pin controller and all pins it handles */ - pmx->pctl = pinctrl_register(&pmx->pctl_desc, &pdev->dev, pmx); - if (IS_ERR(pmx->pctl)) { - dev_err(&pdev->dev, "could not register atlas7 pinmux driver\n"); - ret = PTR_ERR(pmx->pctl); - goto unmap_io; - } - - platform_set_drvdata(pdev, pmx); - - dev_info(&pdev->dev, "initialized atlas7 pinmux driver\n"); - - return 0; - -unmap_io: - for (idx = 0; idx < banks; idx++) { - if (!pmx->regs[idx]) - break; - iounmap(pmx->regs[idx]); - } - - return ret; -} - -#ifdef CONFIG_PM_SLEEP -static int atlas7_pinmux_suspend_noirq(struct device *dev) -{ - struct atlas7_pmx *pmx = dev_get_drvdata(dev); - struct atlas7_pad_status *status; - struct atlas7_pad_config *conf; - const struct atlas7_ds_info *ds_info; - const struct atlas7_pull_info *pull_info; - int idx; - u32 bank; - unsigned long regv; - - for (idx = 0; idx < pmx->pctl_desc.npins; idx++) { - /* Get this Pad's descriptor from PINCTRL */ - conf = &pmx->pctl_data->confs[idx]; - bank = atlas7_pin_to_bank(idx); - status = &pmx->sleep_data[idx]; - - /* Save Function selector */ - regv = readl(pmx->regs[bank] + conf->mux_reg); - status->func = (regv >> conf->mux_bit) & FUNC_CLEAR_MASK; - - /* Check if Pad is in Analogue selector */ - if (conf->ad_ctrl_reg == -1) - goto save_ds_sel; - - regv = readl(pmx->regs[bank] + conf->ad_ctrl_reg); - if (!(regv & (conf->ad_ctrl_bit << ANA_CLEAR_MASK))) - status->func = FUNC_ANALOGUE; - -save_ds_sel: - if (conf->drvstr_reg == -1) - goto save_pull_sel; - - /* Save Drive Strength selector */ - ds_info = &atlas7_ds_map[conf->type]; - regv = readl(pmx->regs[bank] + conf->drvstr_reg); - status->dstr = (regv >> conf->drvstr_bit) & ds_info->mask; - -save_pull_sel: - /* Save Pull selector */ - pull_info = &atlas7_pull_map[conf->type]; - regv = readl(pmx->regs[bank] + conf->pupd_reg); - regv = (regv >> conf->pupd_bit) & pull_info->mask; - status->pull = pull_info->v2s[regv].data; - } - - /* - * Save disable input selector, this selector is not for Pin, - * but for Mux function. - */ - for (idx = 0; idx < NUM_OF_IN_DISABLE_REG; idx++) { - pmx->status_ds[idx] = readl(pmx->regs[BANK_DS] + - IN_DISABLE_0_REG_SET + 0x8 * idx); - pmx->status_dsv[idx] = readl(pmx->regs[BANK_DS] + - IN_DISABLE_VAL_0_REG_SET + 0x8 * idx); - } - - return 0; -} - -static int atlas7_pinmux_resume_noirq(struct device *dev) -{ - struct atlas7_pmx *pmx = dev_get_drvdata(dev); - struct atlas7_pad_status *status; - int idx; - - for (idx = 0; idx < pmx->pctl_desc.npins; idx++) { - /* Get this Pad's descriptor from PINCTRL */ - status = &pmx->sleep_data[idx]; - - /* Restore Function selector */ - __atlas7_pmx_pin_enable(pmx, idx, (u32)status->func & 0xff); - - if (FUNC_ANALOGUE == status->func) - goto restore_pull_sel; - - /* Restore Drive Strength selector */ - __altas7_pinctrl_set_drive_strength_sel(pmx->pctl, idx, - (u32)status->dstr & 0xff); - -restore_pull_sel: - /* Restore Pull selector */ - altas7_pinctrl_set_pull_sel(pmx->pctl, idx, - (u32)status->pull & 0xff); - } - - /* - * Restore disable input selector, this selector is not for Pin, - * but for Mux function - */ - for (idx = 0; idx < NUM_OF_IN_DISABLE_REG; idx++) { - writel(~0, pmx->regs[BANK_DS] + - IN_DISABLE_0_REG_CLR + 0x8 * idx); - writel(pmx->status_ds[idx], pmx->regs[BANK_DS] + - IN_DISABLE_0_REG_SET + 0x8 * idx); - writel(~0, pmx->regs[BANK_DS] + - IN_DISABLE_VAL_0_REG_CLR + 0x8 * idx); - writel(pmx->status_dsv[idx], pmx->regs[BANK_DS] + - IN_DISABLE_VAL_0_REG_SET + 0x8 * idx); - } - - return 0; -} - -static const struct dev_pm_ops atlas7_pinmux_pm_ops = { - .suspend_noirq = atlas7_pinmux_suspend_noirq, - .resume_noirq = atlas7_pinmux_resume_noirq, - .freeze_noirq = atlas7_pinmux_suspend_noirq, - .restore_noirq = atlas7_pinmux_resume_noirq, -}; -#endif - -static const struct of_device_id atlas7_pinmux_ids[] = { - { .compatible = "sirf,atlas7-ioc",}, - {}, -}; - -static struct platform_driver atlas7_pinmux_driver = { - .driver = { - .name = "atlas7-ioc", - .of_match_table = atlas7_pinmux_ids, -#ifdef CONFIG_PM_SLEEP - .pm = &atlas7_pinmux_pm_ops, -#endif - }, - .probe = atlas7_pinmux_probe, -}; - -static int __init atlas7_pinmux_init(void) -{ - return platform_driver_register(&atlas7_pinmux_driver); -} -arch_initcall(atlas7_pinmux_init); - - -/* - * The Following is GPIO Code - */ -static inline struct -atlas7_gpio_bank *atlas7_gpio_to_bank(struct atlas7_gpio_chip *a7gc, u32 gpio) -{ - return &a7gc->banks[GPIO_TO_BANK(gpio)]; -} - -static int __atlas7_gpio_to_pin(struct atlas7_gpio_chip *a7gc, u32 gpio) -{ - struct atlas7_gpio_bank *bank; - u32 ofs; - - bank = atlas7_gpio_to_bank(a7gc, gpio); - ofs = gpio - bank->gpio_offset; - if (ofs >= bank->ngpio) - return -ENODEV; - - return bank->gpio_pins[ofs]; -} - -static void atlas7_gpio_irq_ack(struct irq_data *d) -{ - struct gpio_chip *gc = irq_data_get_irq_chip_data(d); - struct atlas7_gpio_chip *a7gc = gpiochip_get_data(gc); - struct atlas7_gpio_bank *bank; - void __iomem *ctrl_reg; - u32 val, pin_in_bank; - unsigned long flags; - - bank = atlas7_gpio_to_bank(a7gc, d->hwirq); - pin_in_bank = d->hwirq - bank->gpio_offset; - ctrl_reg = ATLAS7_GPIO_CTRL(bank, pin_in_bank); - - raw_spin_lock_irqsave(&a7gc->lock, flags); - - val = readl(ctrl_reg); - /* clear interrupt status */ - writel(val, ctrl_reg); - - raw_spin_unlock_irqrestore(&a7gc->lock, flags); -} - -static void __atlas7_gpio_irq_mask(struct atlas7_gpio_chip *a7gc, int idx) -{ - struct atlas7_gpio_bank *bank; - void __iomem *ctrl_reg; - u32 val, pin_in_bank; - - bank = atlas7_gpio_to_bank(a7gc, idx); - pin_in_bank = idx - bank->gpio_offset; - ctrl_reg = ATLAS7_GPIO_CTRL(bank, pin_in_bank); - - val = readl(ctrl_reg); - val &= ~(ATLAS7_GPIO_CTL_INTR_EN_MASK | - ATLAS7_GPIO_CTL_INTR_STATUS_MASK); - writel(val, ctrl_reg); -} - -static void atlas7_gpio_irq_mask(struct irq_data *d) -{ - struct gpio_chip *gc = irq_data_get_irq_chip_data(d); - struct atlas7_gpio_chip *a7gc = gpiochip_get_data(gc); - unsigned long flags; - - raw_spin_lock_irqsave(&a7gc->lock, flags); - - __atlas7_gpio_irq_mask(a7gc, d->hwirq); - - raw_spin_unlock_irqrestore(&a7gc->lock, flags); -} - -static void atlas7_gpio_irq_unmask(struct irq_data *d) -{ - struct gpio_chip *gc = irq_data_get_irq_chip_data(d); - struct atlas7_gpio_chip *a7gc = gpiochip_get_data(gc); - struct atlas7_gpio_bank *bank; - void __iomem *ctrl_reg; - u32 val, pin_in_bank; - unsigned long flags; - - bank = atlas7_gpio_to_bank(a7gc, d->hwirq); - pin_in_bank = d->hwirq - bank->gpio_offset; - ctrl_reg = ATLAS7_GPIO_CTRL(bank, pin_in_bank); - - raw_spin_lock_irqsave(&a7gc->lock, flags); - - val = readl(ctrl_reg); - val &= ~ATLAS7_GPIO_CTL_INTR_STATUS_MASK; - val |= ATLAS7_GPIO_CTL_INTR_EN_MASK; - writel(val, ctrl_reg); - - raw_spin_unlock_irqrestore(&a7gc->lock, flags); -} - -static int atlas7_gpio_irq_type(struct irq_data *d, - unsigned int type) -{ - struct gpio_chip *gc = irq_data_get_irq_chip_data(d); - struct atlas7_gpio_chip *a7gc = gpiochip_get_data(gc); - struct atlas7_gpio_bank *bank; - void __iomem *ctrl_reg; - u32 val, pin_in_bank; - unsigned long flags; - - bank = atlas7_gpio_to_bank(a7gc, d->hwirq); - pin_in_bank = d->hwirq - bank->gpio_offset; - ctrl_reg = ATLAS7_GPIO_CTRL(bank, pin_in_bank); - - raw_spin_lock_irqsave(&a7gc->lock, flags); - - val = readl(ctrl_reg); - val &= ~(ATLAS7_GPIO_CTL_INTR_STATUS_MASK | - ATLAS7_GPIO_CTL_INTR_EN_MASK); - - switch (type) { - case IRQ_TYPE_NONE: - break; - - case IRQ_TYPE_EDGE_RISING: - val |= ATLAS7_GPIO_CTL_INTR_HIGH_MASK | - ATLAS7_GPIO_CTL_INTR_TYPE_MASK; - val &= ~ATLAS7_GPIO_CTL_INTR_LOW_MASK; - break; - - case IRQ_TYPE_EDGE_FALLING: - val &= ~ATLAS7_GPIO_CTL_INTR_HIGH_MASK; - val |= ATLAS7_GPIO_CTL_INTR_LOW_MASK | - ATLAS7_GPIO_CTL_INTR_TYPE_MASK; - break; - - case IRQ_TYPE_EDGE_BOTH: - val |= ATLAS7_GPIO_CTL_INTR_HIGH_MASK | - ATLAS7_GPIO_CTL_INTR_LOW_MASK | - ATLAS7_GPIO_CTL_INTR_TYPE_MASK; - break; - - case IRQ_TYPE_LEVEL_LOW: - val &= ~(ATLAS7_GPIO_CTL_INTR_HIGH_MASK | - ATLAS7_GPIO_CTL_INTR_TYPE_MASK); - val |= ATLAS7_GPIO_CTL_INTR_LOW_MASK; - break; - - case IRQ_TYPE_LEVEL_HIGH: - val |= ATLAS7_GPIO_CTL_INTR_HIGH_MASK; - val &= ~(ATLAS7_GPIO_CTL_INTR_LOW_MASK | - ATLAS7_GPIO_CTL_INTR_TYPE_MASK); - break; - } - - writel(val, ctrl_reg); - - raw_spin_unlock_irqrestore(&a7gc->lock, flags); - - return 0; -} - -static struct irq_chip atlas7_gpio_irq_chip = { - .name = "atlas7-gpio-irq", - .irq_ack = atlas7_gpio_irq_ack, - .irq_mask = atlas7_gpio_irq_mask, - .irq_unmask = atlas7_gpio_irq_unmask, - .irq_set_type = atlas7_gpio_irq_type, -}; - -static void atlas7_gpio_handle_irq(struct irq_desc *desc) -{ - struct gpio_chip *gc = irq_desc_get_handler_data(desc); - struct atlas7_gpio_chip *a7gc = gpiochip_get_data(gc); - struct atlas7_gpio_bank *bank = NULL; - u32 status, ctrl; - int pin_in_bank = 0, idx; - struct irq_chip *chip = irq_desc_get_chip(desc); - unsigned int irq = irq_desc_get_irq(desc); - - for (idx = 0; idx < a7gc->nbank; idx++) { - bank = &a7gc->banks[idx]; - if (bank->irq == irq) - break; - } - BUG_ON(idx == a7gc->nbank); - - chained_irq_enter(chip, desc); - - status = readl(ATLAS7_GPIO_INT_STATUS(bank)); - if (!status) { - pr_warn("%s: gpio [%s] status %#x no interrupt is flagged\n", - __func__, gc->label, status); - handle_bad_irq(desc); - return; - } - - while (status) { - ctrl = readl(ATLAS7_GPIO_CTRL(bank, pin_in_bank)); - - /* - * Here we must check whether the corresponding GPIO's - * interrupt has been enabled, otherwise just skip it - */ - if ((status & 0x1) && (ctrl & ATLAS7_GPIO_CTL_INTR_EN_MASK)) { - pr_debug("%s: chip[%s] gpio:%d happens\n", - __func__, gc->label, - bank->gpio_offset + pin_in_bank); - generic_handle_irq( - irq_find_mapping(gc->irq.domain, - bank->gpio_offset + pin_in_bank)); - } - - if (++pin_in_bank >= bank->ngpio) - break; - - status = status >> 1; - } - - chained_irq_exit(chip, desc); -} - -static void __atlas7_gpio_set_input(struct atlas7_gpio_chip *a7gc, - unsigned int gpio) -{ - struct atlas7_gpio_bank *bank; - void __iomem *ctrl_reg; - u32 val, pin_in_bank; - - bank = atlas7_gpio_to_bank(a7gc, gpio); - pin_in_bank = gpio - bank->gpio_offset; - ctrl_reg = ATLAS7_GPIO_CTRL(bank, pin_in_bank); - - val = readl(ctrl_reg); - val &= ~ATLAS7_GPIO_CTL_OUT_EN_MASK; - writel(val, ctrl_reg); -} - -static int atlas7_gpio_request(struct gpio_chip *chip, - unsigned int gpio) -{ - struct atlas7_gpio_chip *a7gc = gpiochip_get_data(chip); - int ret; - unsigned long flags; - - ret = __atlas7_gpio_to_pin(a7gc, gpio); - if (ret < 0) - return ret; - - if (pinctrl_gpio_request(chip->base + gpio)) - return -ENODEV; - - raw_spin_lock_irqsave(&a7gc->lock, flags); - - /* - * default status: - * set direction as input and mask irq - */ - __atlas7_gpio_set_input(a7gc, gpio); - __atlas7_gpio_irq_mask(a7gc, gpio); - - raw_spin_unlock_irqrestore(&a7gc->lock, flags); - - return 0; -} - -static void atlas7_gpio_free(struct gpio_chip *chip, - unsigned int gpio) -{ - struct atlas7_gpio_chip *a7gc = gpiochip_get_data(chip); - unsigned long flags; - - raw_spin_lock_irqsave(&a7gc->lock, flags); - - __atlas7_gpio_irq_mask(a7gc, gpio); - __atlas7_gpio_set_input(a7gc, gpio); - - raw_spin_unlock_irqrestore(&a7gc->lock, flags); - - pinctrl_gpio_free(chip->base + gpio); -} - -static int atlas7_gpio_direction_input(struct gpio_chip *chip, - unsigned int gpio) -{ - struct atlas7_gpio_chip *a7gc = gpiochip_get_data(chip); - unsigned long flags; - - raw_spin_lock_irqsave(&a7gc->lock, flags); - - __atlas7_gpio_set_input(a7gc, gpio); - - raw_spin_unlock_irqrestore(&a7gc->lock, flags); - - return 0; -} - -static void __atlas7_gpio_set_output(struct atlas7_gpio_chip *a7gc, - unsigned int gpio, int value) -{ - struct atlas7_gpio_bank *bank; - void __iomem *ctrl_reg; - u32 out_ctrl, pin_in_bank; - - bank = atlas7_gpio_to_bank(a7gc, gpio); - pin_in_bank = gpio - bank->gpio_offset; - ctrl_reg = ATLAS7_GPIO_CTRL(bank, pin_in_bank); - - out_ctrl = readl(ctrl_reg); - if (value) - out_ctrl |= ATLAS7_GPIO_CTL_DATAOUT_MASK; - else - out_ctrl &= ~ATLAS7_GPIO_CTL_DATAOUT_MASK; - - out_ctrl &= ~ATLAS7_GPIO_CTL_INTR_EN_MASK; - out_ctrl |= ATLAS7_GPIO_CTL_OUT_EN_MASK; - writel(out_ctrl, ctrl_reg); -} - -static int atlas7_gpio_direction_output(struct gpio_chip *chip, - unsigned int gpio, int value) -{ - struct atlas7_gpio_chip *a7gc = gpiochip_get_data(chip); - unsigned long flags; - - raw_spin_lock_irqsave(&a7gc->lock, flags); - - __atlas7_gpio_set_output(a7gc, gpio, value); - - raw_spin_unlock_irqrestore(&a7gc->lock, flags); - - return 0; -} - -static int atlas7_gpio_get_value(struct gpio_chip *chip, - unsigned int gpio) -{ - struct atlas7_gpio_chip *a7gc = gpiochip_get_data(chip); - struct atlas7_gpio_bank *bank; - u32 val, pin_in_bank; - unsigned long flags; - - bank = atlas7_gpio_to_bank(a7gc, gpio); - pin_in_bank = gpio - bank->gpio_offset; - - raw_spin_lock_irqsave(&a7gc->lock, flags); - - val = readl(ATLAS7_GPIO_CTRL(bank, pin_in_bank)); - - raw_spin_unlock_irqrestore(&a7gc->lock, flags); - - return !!(val & ATLAS7_GPIO_CTL_DATAIN_MASK); -} - -static void atlas7_gpio_set_value(struct gpio_chip *chip, - unsigned int gpio, int value) -{ - struct atlas7_gpio_chip *a7gc = gpiochip_get_data(chip); - struct atlas7_gpio_bank *bank; - void __iomem *ctrl_reg; - u32 ctrl, pin_in_bank; - unsigned long flags; - - bank = atlas7_gpio_to_bank(a7gc, gpio); - pin_in_bank = gpio - bank->gpio_offset; - ctrl_reg = ATLAS7_GPIO_CTRL(bank, pin_in_bank); - - raw_spin_lock_irqsave(&a7gc->lock, flags); - - ctrl = readl(ctrl_reg); - if (value) - ctrl |= ATLAS7_GPIO_CTL_DATAOUT_MASK; - else - ctrl &= ~ATLAS7_GPIO_CTL_DATAOUT_MASK; - writel(ctrl, ctrl_reg); - - raw_spin_unlock_irqrestore(&a7gc->lock, flags); -} - -static const struct of_device_id atlas7_gpio_ids[] = { - { .compatible = "sirf,atlas7-gpio", }, - {}, -}; - -static int atlas7_gpio_probe(struct platform_device *pdev) -{ - struct device_node *np = pdev->dev.of_node; - struct atlas7_gpio_chip *a7gc; - struct gpio_chip *chip; - u32 nbank; - int ret, idx; - struct gpio_irq_chip *girq; - - ret = of_property_read_u32(np, "gpio-banks", &nbank); - if (ret) { - dev_err(&pdev->dev, - "Could not find GPIO bank info,ret=%d!\n", - ret); - return ret; - } - - /* retrieve gpio descriptor data */ - a7gc = devm_kzalloc(&pdev->dev, struct_size(a7gc, banks, nbank), - GFP_KERNEL); - if (!a7gc) - return -ENOMEM; - - /* Get Gpio clk */ - a7gc->clk = of_clk_get(np, 0); - if (!IS_ERR(a7gc->clk)) { - ret = clk_prepare_enable(a7gc->clk); - if (ret) { - dev_err(&pdev->dev, - "Could not enable clock!\n"); - return ret; - } - } - - /* Get Gpio Registers */ - a7gc->reg = of_iomap(np, 0); - if (!a7gc->reg) { - dev_err(&pdev->dev, "Could not map GPIO Registers!\n"); - return -ENOMEM; - } - - a7gc->nbank = nbank; - raw_spin_lock_init(&a7gc->lock); - - /* Setup GPIO Chip */ - chip = &a7gc->chip; - chip->request = atlas7_gpio_request; - chip->free = atlas7_gpio_free; - chip->direction_input = atlas7_gpio_direction_input; - chip->get = atlas7_gpio_get_value; - chip->direction_output = atlas7_gpio_direction_output; - chip->set = atlas7_gpio_set_value; - chip->base = -1; - /* Each chip can support 32 pins at one bank */ - chip->ngpio = NGPIO_OF_BANK * nbank; - chip->label = kstrdup(np->name, GFP_KERNEL); - chip->of_node = np; - chip->of_gpio_n_cells = 2; - chip->parent = &pdev->dev; - - girq = &chip->irq; - girq->chip = &atlas7_gpio_irq_chip; - girq->parent_handler = atlas7_gpio_handle_irq; - girq->num_parents = nbank; - girq->parents = devm_kcalloc(&pdev->dev, nbank, - sizeof(*girq->parents), - GFP_KERNEL); - if (!girq->parents) - return -ENOMEM; - for (idx = 0; idx < nbank; idx++) { - struct atlas7_gpio_bank *bank; - - bank = &a7gc->banks[idx]; - /* Set ctrl registers' base of this bank */ - bank->base = ATLAS7_GPIO_BASE(a7gc, idx); - bank->gpio_offset = idx * NGPIO_OF_BANK; - - /* Get interrupt number from DTS */ - ret = of_irq_get(np, idx); - if (ret <= 0) { - dev_err(&pdev->dev, - "Unable to find IRQ number. ret=%d\n", ret); - if (!ret) - ret = -ENXIO; - goto failed; - } - bank->irq = ret; - girq->parents[idx] = ret; - } - girq->default_type = IRQ_TYPE_NONE; - girq->handler = handle_level_irq; - - /* Add gpio chip to system */ - ret = gpiochip_add_data(chip, a7gc); - if (ret) { - dev_err(&pdev->dev, - "%pOF: error in probe function with status %d\n", - np, ret); - goto failed; - } - - platform_set_drvdata(pdev, a7gc); - dev_info(&pdev->dev, "add to system.\n"); - return 0; -failed: - return ret; -} - -#ifdef CONFIG_PM_SLEEP -static int atlas7_gpio_suspend_noirq(struct device *dev) -{ - struct atlas7_gpio_chip *a7gc = dev_get_drvdata(dev); - struct atlas7_gpio_bank *bank; - void __iomem *ctrl_reg; - u32 idx, pin; - - for (idx = 0; idx < a7gc->nbank; idx++) { - bank = &a7gc->banks[idx]; - for (pin = 0; pin < bank->ngpio; pin++) { - ctrl_reg = ATLAS7_GPIO_CTRL(bank, pin); - bank->sleep_data[pin] = readl(ctrl_reg); - } - } - - return 0; -} - -static int atlas7_gpio_resume_noirq(struct device *dev) -{ - struct atlas7_gpio_chip *a7gc = dev_get_drvdata(dev); - struct atlas7_gpio_bank *bank; - void __iomem *ctrl_reg; - u32 idx, pin; - - for (idx = 0; idx < a7gc->nbank; idx++) { - bank = &a7gc->banks[idx]; - for (pin = 0; pin < bank->ngpio; pin++) { - ctrl_reg = ATLAS7_GPIO_CTRL(bank, pin); - writel(bank->sleep_data[pin], ctrl_reg); - } - } - - return 0; -} - -static const struct dev_pm_ops atlas7_gpio_pm_ops = { - .suspend_noirq = atlas7_gpio_suspend_noirq, - .resume_noirq = atlas7_gpio_resume_noirq, - .freeze_noirq = atlas7_gpio_suspend_noirq, - .restore_noirq = atlas7_gpio_resume_noirq, -}; -#endif - -static struct platform_driver atlas7_gpio_driver = { - .driver = { - .name = "atlas7-gpio", - .of_match_table = atlas7_gpio_ids, -#ifdef CONFIG_PM_SLEEP - .pm = &atlas7_gpio_pm_ops, -#endif - }, - .probe = atlas7_gpio_probe, -}; - -static int __init atlas7_gpio_init(void) -{ - return platform_driver_register(&atlas7_gpio_driver); -} -subsys_initcall(atlas7_gpio_init); diff --git a/drivers/pinctrl/sirf/pinctrl-prima2.c b/drivers/pinctrl/sirf/pinctrl-prima2.c deleted file mode 100644 index 49da2a7eba1f..000000000000 --- a/drivers/pinctrl/sirf/pinctrl-prima2.c +++ /dev/null @@ -1,1131 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * pinctrl pads, groups, functions for CSR SiRFprimaII - * - * Copyright (c) 2011 - 2014 Cambridge Silicon Radio Limited, a CSR plc group - * company. - */ - -#include -#include - -#include "pinctrl-sirf.h" - -/* - * pad list for the pinmux subsystem - * refer to CS-131858-DC-6A.xls - */ -static const struct pinctrl_pin_desc sirfsoc_pads[] = { - PINCTRL_PIN(0, "gpio0-0"), - PINCTRL_PIN(1, "gpio0-1"), - PINCTRL_PIN(2, "gpio0-2"), - PINCTRL_PIN(3, "gpio0-3"), - PINCTRL_PIN(4, "pwm0"), - PINCTRL_PIN(5, "pwm1"), - PINCTRL_PIN(6, "pwm2"), - PINCTRL_PIN(7, "pwm3"), - PINCTRL_PIN(8, "warm_rst_b"), - PINCTRL_PIN(9, "odo_0"), - PINCTRL_PIN(10, "odo_1"), - PINCTRL_PIN(11, "dr_dir"), - PINCTRL_PIN(12, "viprom_fa"), - PINCTRL_PIN(13, "scl_1"), - PINCTRL_PIN(14, "ntrst"), - PINCTRL_PIN(15, "sda_1"), - PINCTRL_PIN(16, "x_ldd[16]"), - PINCTRL_PIN(17, "x_ldd[17]"), - PINCTRL_PIN(18, "x_ldd[18]"), - PINCTRL_PIN(19, "x_ldd[19]"), - PINCTRL_PIN(20, "x_ldd[20]"), - PINCTRL_PIN(21, "x_ldd[21]"), - PINCTRL_PIN(22, "x_ldd[22]"), - PINCTRL_PIN(23, "x_ldd[23], lcdrom_frdy"), - PINCTRL_PIN(24, "gps_sgn"), - PINCTRL_PIN(25, "gps_mag"), - PINCTRL_PIN(26, "gps_clk"), - PINCTRL_PIN(27, "sd_cd_b_1"), - PINCTRL_PIN(28, "sd_vcc_on_1"), - PINCTRL_PIN(29, "sd_wp_b_1"), - PINCTRL_PIN(30, "sd_clk_3"), - PINCTRL_PIN(31, "sd_cmd_3"), - - PINCTRL_PIN(32, "x_sd_dat_3[0]"), - PINCTRL_PIN(33, "x_sd_dat_3[1]"), - PINCTRL_PIN(34, "x_sd_dat_3[2]"), - PINCTRL_PIN(35, "x_sd_dat_3[3]"), - PINCTRL_PIN(36, "x_sd_clk_4"), - PINCTRL_PIN(37, "x_sd_cmd_4"), - PINCTRL_PIN(38, "x_sd_dat_4[0]"), - PINCTRL_PIN(39, "x_sd_dat_4[1]"), - PINCTRL_PIN(40, "x_sd_dat_4[2]"), - PINCTRL_PIN(41, "x_sd_dat_4[3]"), - PINCTRL_PIN(42, "x_cko_1"), - PINCTRL_PIN(43, "x_ac97_bit_clk"), - PINCTRL_PIN(44, "x_ac97_dout"), - PINCTRL_PIN(45, "x_ac97_din"), - PINCTRL_PIN(46, "x_ac97_sync"), - PINCTRL_PIN(47, "x_txd_1"), - PINCTRL_PIN(48, "x_txd_2"), - PINCTRL_PIN(49, "x_rxd_1"), - PINCTRL_PIN(50, "x_rxd_2"), - PINCTRL_PIN(51, "x_usclk_0"), - PINCTRL_PIN(52, "x_utxd_0"), - PINCTRL_PIN(53, "x_urxd_0"), - PINCTRL_PIN(54, "x_utfs_0"), - PINCTRL_PIN(55, "x_urfs_0"), - PINCTRL_PIN(56, "x_usclk_1"), - PINCTRL_PIN(57, "x_utxd_1"), - PINCTRL_PIN(58, "x_urxd_1"), - PINCTRL_PIN(59, "x_utfs_1"), - PINCTRL_PIN(60, "x_urfs_1"), - PINCTRL_PIN(61, "x_usclk_2"), - PINCTRL_PIN(62, "x_utxd_2"), - PINCTRL_PIN(63, "x_urxd_2"), - - PINCTRL_PIN(64, "x_utfs_2"), - PINCTRL_PIN(65, "x_urfs_2"), - PINCTRL_PIN(66, "x_df_we_b"), - PINCTRL_PIN(67, "x_df_re_b"), - PINCTRL_PIN(68, "x_txd_0"), - PINCTRL_PIN(69, "x_rxd_0"), - PINCTRL_PIN(78, "x_cko_0"), - PINCTRL_PIN(79, "x_vip_pxd[7]"), - PINCTRL_PIN(80, "x_vip_pxd[6]"), - PINCTRL_PIN(81, "x_vip_pxd[5]"), - PINCTRL_PIN(82, "x_vip_pxd[4]"), - PINCTRL_PIN(83, "x_vip_pxd[3]"), - PINCTRL_PIN(84, "x_vip_pxd[2]"), - PINCTRL_PIN(85, "x_vip_pxd[1]"), - PINCTRL_PIN(86, "x_vip_pxd[0]"), - PINCTRL_PIN(87, "x_vip_vsync"), - PINCTRL_PIN(88, "x_vip_hsync"), - PINCTRL_PIN(89, "x_vip_pxclk"), - PINCTRL_PIN(90, "x_sda_0"), - PINCTRL_PIN(91, "x_scl_0"), - PINCTRL_PIN(92, "x_df_ry_by"), - PINCTRL_PIN(93, "x_df_cs_b[1]"), - PINCTRL_PIN(94, "x_df_cs_b[0]"), - PINCTRL_PIN(95, "x_l_pclk"), - - PINCTRL_PIN(96, "x_l_lck"), - PINCTRL_PIN(97, "x_l_fck"), - PINCTRL_PIN(98, "x_l_de"), - PINCTRL_PIN(99, "x_ldd[0]"), - PINCTRL_PIN(100, "x_ldd[1]"), - PINCTRL_PIN(101, "x_ldd[2]"), - PINCTRL_PIN(102, "x_ldd[3]"), - PINCTRL_PIN(103, "x_ldd[4]"), - PINCTRL_PIN(104, "x_ldd[5]"), - PINCTRL_PIN(105, "x_ldd[6]"), - PINCTRL_PIN(106, "x_ldd[7]"), - PINCTRL_PIN(107, "x_ldd[8]"), - PINCTRL_PIN(108, "x_ldd[9]"), - PINCTRL_PIN(109, "x_ldd[10]"), - PINCTRL_PIN(110, "x_ldd[11]"), - PINCTRL_PIN(111, "x_ldd[12]"), - PINCTRL_PIN(112, "x_ldd[13]"), - PINCTRL_PIN(113, "x_ldd[14]"), - PINCTRL_PIN(114, "x_ldd[15]"), - - PINCTRL_PIN(115, "x_usb1_dp"), - PINCTRL_PIN(116, "x_usb1_dn"), -}; - -static const struct sirfsoc_muxmask lcd_16bits_sirfsoc_muxmask[] = { - { - .group = 3, - .mask = BIT(0) | BIT(1) | BIT(2) | BIT(3) | BIT(4) | BIT(5) | - BIT(6) | BIT(7) | BIT(8) | BIT(9) | BIT(10) | BIT(11) | - BIT(12) | BIT(13) | BIT(14) | BIT(15) | BIT(16) | - BIT(17) | BIT(18), - }, { - .group = 2, - .mask = BIT(31), - }, -}; - -static const struct sirfsoc_padmux lcd_16bits_padmux = { - .muxmask_counts = ARRAY_SIZE(lcd_16bits_sirfsoc_muxmask), - .muxmask = lcd_16bits_sirfsoc_muxmask, - .ctrlreg = SIRFSOC_RSC_PIN_MUX, - .funcmask = BIT(4), - .funcval = 0, -}; - -static const unsigned lcd_16bits_pins[] = { 95, 96, 97, 98, 99, 100, 101, 102, - 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114 }; - -static const struct sirfsoc_muxmask lcd_18bits_muxmask[] = { - { - .group = 3, - .mask = BIT(0) | BIT(1) | BIT(2) | BIT(3) | BIT(4) | BIT(5) | - BIT(6) | BIT(7) | BIT(8) | BIT(9) | BIT(10) | BIT(11) | - BIT(12) | BIT(13) | BIT(14) | BIT(15) | BIT(16) | - BIT(17) | BIT(18), - }, { - .group = 2, - .mask = BIT(31), - }, { - .group = 0, - .mask = BIT(16) | BIT(17), - }, -}; - -static const struct sirfsoc_padmux lcd_18bits_padmux = { - .muxmask_counts = ARRAY_SIZE(lcd_18bits_muxmask), - .muxmask = lcd_18bits_muxmask, - .ctrlreg = SIRFSOC_RSC_PIN_MUX, - .funcmask = BIT(4), - .funcval = 0, -}; - -static const unsigned lcd_18bits_pins[] = { 16, 17, 95, 96, 97, 98, 99, 100, - 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114}; - -static const struct sirfsoc_muxmask lcd_24bits_muxmask[] = { - { - .group = 3, - .mask = BIT(0) | BIT(1) | BIT(2) | BIT(3) | BIT(4) | BIT(5) | - BIT(6) | BIT(7) | BIT(8) | BIT(9) | BIT(10) | BIT(11) | - BIT(12) | BIT(13) | BIT(14) | BIT(15) | BIT(16) | - BIT(17) | BIT(18), - }, { - .group = 2, - .mask = BIT(31), - }, { - .group = 0, - .mask = BIT(16) | BIT(17) | BIT(18) | BIT(19) | BIT(20) | - BIT(21) | BIT(22) | BIT(23), - }, -}; - -static const struct sirfsoc_padmux lcd_24bits_padmux = { - .muxmask_counts = ARRAY_SIZE(lcd_24bits_muxmask), - .muxmask = lcd_24bits_muxmask, - .ctrlreg = SIRFSOC_RSC_PIN_MUX, - .funcmask = BIT(4), - .funcval = 0, -}; - -static const unsigned lcd_24bits_pins[] = { 16, 17, 18, 19, 20, 21, 22, 23, - 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, - 110, 111, 112, 113, 114 }; - -static const struct sirfsoc_muxmask lcdrom_muxmask[] = { - { - .group = 3, - .mask = BIT(0) | BIT(1) | BIT(2) | BIT(3) | BIT(4) | BIT(5) | - BIT(6) | BIT(7) | BIT(8) | BIT(9) | BIT(10) | BIT(11) | - BIT(12) | BIT(13) | BIT(14) | BIT(15) | BIT(16) | - BIT(17) | BIT(18), - }, { - .group = 2, - .mask = BIT(31), - }, { - .group = 0, - .mask = BIT(23), - }, -}; - -static const struct sirfsoc_padmux lcdrom_padmux = { - .muxmask_counts = ARRAY_SIZE(lcdrom_muxmask), - .muxmask = lcdrom_muxmask, - .ctrlreg = SIRFSOC_RSC_PIN_MUX, - .funcmask = BIT(4), - .funcval = BIT(4), -}; - -static const unsigned lcdrom_pins[] = { 23, 95, 96, 97, 98, 99, 100, 101, 102, - 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114 }; - -static const struct sirfsoc_muxmask uart0_muxmask[] = { - { - .group = 2, - .mask = BIT(4) | BIT(5), - }, { - .group = 1, - .mask = BIT(23) | BIT(28), - }, -}; - -static const struct sirfsoc_padmux uart0_padmux = { - .muxmask_counts = ARRAY_SIZE(uart0_muxmask), - .muxmask = uart0_muxmask, - .ctrlreg = SIRFSOC_RSC_PIN_MUX, - .funcmask = BIT(9), - .funcval = BIT(9), -}; - -static const unsigned uart0_pins[] = { 55, 60, 68, 69 }; - -static const struct sirfsoc_muxmask uart0_nostreamctrl_muxmask[] = { - { - .group = 2, - .mask = BIT(4) | BIT(5), - }, -}; - -static const struct sirfsoc_padmux uart0_nostreamctrl_padmux = { - .muxmask_counts = ARRAY_SIZE(uart0_nostreamctrl_muxmask), - .muxmask = uart0_nostreamctrl_muxmask, -}; - -static const unsigned uart0_nostreamctrl_pins[] = { 68, 69 }; - -static const struct sirfsoc_muxmask uart1_muxmask[] = { - { - .group = 1, - .mask = BIT(15) | BIT(17), - }, -}; - -static const struct sirfsoc_padmux uart1_padmux = { - .muxmask_counts = ARRAY_SIZE(uart1_muxmask), - .muxmask = uart1_muxmask, -}; - -static const unsigned uart1_pins[] = { 47, 49 }; - -static const struct sirfsoc_muxmask uart2_muxmask[] = { - { - .group = 1, - .mask = BIT(16) | BIT(18) | BIT(24) | BIT(27), - }, -}; - -static const struct sirfsoc_padmux uart2_padmux = { - .muxmask_counts = ARRAY_SIZE(uart2_muxmask), - .muxmask = uart2_muxmask, - .ctrlreg = SIRFSOC_RSC_PIN_MUX, - .funcmask = BIT(10), - .funcval = BIT(10), -}; - -static const unsigned uart2_pins[] = { 48, 50, 56, 59 }; - -static const struct sirfsoc_muxmask uart2_nostreamctrl_muxmask[] = { - { - .group = 1, - .mask = BIT(16) | BIT(18), - }, -}; - -static const struct sirfsoc_padmux uart2_nostreamctrl_padmux = { - .muxmask_counts = ARRAY_SIZE(uart2_nostreamctrl_muxmask), - .muxmask = uart2_nostreamctrl_muxmask, -}; - -static const unsigned uart2_nostreamctrl_pins[] = { 48, 50 }; - -static const struct sirfsoc_muxmask sdmmc3_muxmask[] = { - { - .group = 0, - .mask = BIT(30) | BIT(31), - }, { - .group = 1, - .mask = BIT(0) | BIT(1) | BIT(2) | BIT(3), - }, -}; - -static const struct sirfsoc_padmux sdmmc3_padmux = { - .muxmask_counts = ARRAY_SIZE(sdmmc3_muxmask), - .muxmask = sdmmc3_muxmask, - .ctrlreg = SIRFSOC_RSC_PIN_MUX, - .funcmask = BIT(7), - .funcval = 0, -}; - -static const unsigned sdmmc3_pins[] = { 30, 31, 32, 33, 34, 35 }; - -static const struct sirfsoc_muxmask spi0_muxmask[] = { - { - .group = 1, - .mask = BIT(0) | BIT(1) | BIT(2) | BIT(3), - }, -}; - -static const struct sirfsoc_padmux spi0_padmux = { - .muxmask_counts = ARRAY_SIZE(spi0_muxmask), - .muxmask = spi0_muxmask, - .ctrlreg = SIRFSOC_RSC_PIN_MUX, - .funcmask = BIT(7), - .funcval = BIT(7), -}; - -static const unsigned spi0_pins[] = { 32, 33, 34, 35 }; - -static const struct sirfsoc_muxmask sdmmc4_muxmask[] = { - { - .group = 1, - .mask = BIT(4) | BIT(5) | BIT(6) | BIT(7) | BIT(8) | BIT(9), - }, -}; - -static const struct sirfsoc_padmux sdmmc4_padmux = { - .muxmask_counts = ARRAY_SIZE(sdmmc4_muxmask), - .muxmask = sdmmc4_muxmask, -}; - -static const unsigned sdmmc4_pins[] = { 36, 37, 38, 39, 40, 41 }; - -static const struct sirfsoc_muxmask cko1_muxmask[] = { - { - .group = 1, - .mask = BIT(10), - }, -}; - -static const struct sirfsoc_padmux cko1_padmux = { - .muxmask_counts = ARRAY_SIZE(cko1_muxmask), - .muxmask = cko1_muxmask, - .ctrlreg = SIRFSOC_RSC_PIN_MUX, - .funcmask = BIT(3), - .funcval = 0, -}; - -static const unsigned cko1_pins[] = { 42 }; - -static const struct sirfsoc_muxmask i2s_mclk_muxmask[] = { - { - .group = 1, - .mask = BIT(10), - }, -}; - -static const struct sirfsoc_padmux i2s_mclk_padmux = { - .muxmask_counts = ARRAY_SIZE(i2s_mclk_muxmask), - .muxmask = i2s_mclk_muxmask, - .ctrlreg = SIRFSOC_RSC_PIN_MUX, - .funcmask = BIT(3), - .funcval = BIT(3), -}; - -static const unsigned i2s_mclk_pins[] = { 42 }; - -static const struct sirfsoc_muxmask i2s_ext_clk_input_muxmask[] = { - { - .group = 1, - .mask = BIT(19), - }, -}; - -static const struct sirfsoc_padmux i2s_ext_clk_input_padmux = { - .muxmask_counts = ARRAY_SIZE(i2s_ext_clk_input_muxmask), - .muxmask = i2s_ext_clk_input_muxmask, - .ctrlreg = SIRFSOC_RSC_PIN_MUX, - .funcmask = BIT(2), - .funcval = BIT(2), -}; - -static const unsigned i2s_ext_clk_input_pins[] = { 51 }; - -static const struct sirfsoc_muxmask i2s_muxmask[] = { - { - .group = 1, - .mask = BIT(11) | BIT(12) | BIT(13) | BIT(14), - }, -}; - -static const struct sirfsoc_padmux i2s_padmux = { - .muxmask_counts = ARRAY_SIZE(i2s_muxmask), - .muxmask = i2s_muxmask, - .ctrlreg = SIRFSOC_RSC_PIN_MUX, -}; - -static const unsigned i2s_pins[] = { 43, 44, 45, 46 }; - -static const struct sirfsoc_muxmask i2s_no_din_muxmask[] = { - { - .group = 1, - .mask = BIT(11) | BIT(12) | BIT(14), - }, -}; - -static const struct sirfsoc_padmux i2s_no_din_padmux = { - .muxmask_counts = ARRAY_SIZE(i2s_no_din_muxmask), - .muxmask = i2s_no_din_muxmask, - .ctrlreg = SIRFSOC_RSC_PIN_MUX, -}; - -static const unsigned i2s_no_din_pins[] = { 43, 44, 46 }; - -static const struct sirfsoc_muxmask i2s_6chn_muxmask[] = { - { - .group = 1, - .mask = BIT(11) | BIT(12) | BIT(13) | BIT(14) - | BIT(23) | BIT(28), - }, -}; - -static const struct sirfsoc_padmux i2s_6chn_padmux = { - .muxmask_counts = ARRAY_SIZE(i2s_6chn_muxmask), - .muxmask = i2s_6chn_muxmask, - .ctrlreg = SIRFSOC_RSC_PIN_MUX, - .funcmask = BIT(1) | BIT(9), - .funcval = BIT(1) | BIT(9), -}; - -static const unsigned i2s_6chn_pins[] = { 43, 44, 45, 46, 55, 60 }; - -static const struct sirfsoc_muxmask ac97_muxmask[] = { - { - .group = 1, - .mask = BIT(11) | BIT(12) | BIT(13) | BIT(14), - }, -}; - -static const struct sirfsoc_padmux ac97_padmux = { - .muxmask_counts = ARRAY_SIZE(ac97_muxmask), - .muxmask = ac97_muxmask, - .ctrlreg = SIRFSOC_RSC_PIN_MUX, - .funcmask = BIT(8), - .funcval = 0, -}; - -static const unsigned ac97_pins[] = { 43, 44, 45, 46 }; - -static const struct sirfsoc_muxmask spi1_muxmask[] = { - { - .group = 1, - .mask = BIT(11) | BIT(12) | BIT(13) | BIT(14), - }, -}; - -static const struct sirfsoc_padmux spi1_padmux = { - .muxmask_counts = ARRAY_SIZE(spi1_muxmask), - .muxmask = spi1_muxmask, - .ctrlreg = SIRFSOC_RSC_PIN_MUX, - .funcmask = BIT(8), - .funcval = BIT(8), -}; - -static const unsigned spi1_pins[] = { 43, 44, 45, 46 }; - -static const struct sirfsoc_muxmask sdmmc1_muxmask[] = { - { - .group = 0, - .mask = BIT(27) | BIT(28) | BIT(29), - }, -}; - -static const struct sirfsoc_padmux sdmmc1_padmux = { - .muxmask_counts = ARRAY_SIZE(sdmmc1_muxmask), - .muxmask = sdmmc1_muxmask, -}; - -static const unsigned sdmmc1_pins[] = { 27, 28, 29 }; - -static const struct sirfsoc_muxmask gps_muxmask[] = { - { - .group = 0, - .mask = BIT(24) | BIT(25) | BIT(26), - }, -}; - -static const struct sirfsoc_padmux gps_padmux = { - .muxmask_counts = ARRAY_SIZE(gps_muxmask), - .muxmask = gps_muxmask, - .ctrlreg = SIRFSOC_RSC_PIN_MUX, - .funcmask = BIT(12) | BIT(13) | BIT(14), - .funcval = BIT(12), -}; - -static const unsigned gps_pins[] = { 24, 25, 26 }; - -static const struct sirfsoc_muxmask sdmmc5_muxmask[] = { - { - .group = 0, - .mask = BIT(24) | BIT(25) | BIT(26), - }, -}; - -static const struct sirfsoc_padmux sdmmc5_padmux = { - .muxmask_counts = ARRAY_SIZE(sdmmc5_muxmask), - .muxmask = sdmmc5_muxmask, - .ctrlreg = SIRFSOC_RSC_PIN_MUX, - .funcmask = BIT(13) | BIT(14), - .funcval = BIT(13) | BIT(14), -}; - -static const unsigned sdmmc5_pins[] = { 24, 25, 26 }; - -static const struct sirfsoc_muxmask usp0_muxmask[] = { - { - .group = 1, - .mask = BIT(19) | BIT(20) | BIT(21) | BIT(22) | BIT(23), - }, -}; - -static const struct sirfsoc_padmux usp0_padmux = { - .muxmask_counts = ARRAY_SIZE(usp0_muxmask), - .muxmask = usp0_muxmask, - .ctrlreg = SIRFSOC_RSC_PIN_MUX, - .funcmask = BIT(1) | BIT(2) | BIT(6) | BIT(9), - .funcval = 0, -}; - -static const unsigned usp0_pins[] = { 51, 52, 53, 54, 55 }; - -static const struct sirfsoc_muxmask usp0_only_utfs_muxmask[] = { - { - .group = 1, - .mask = BIT(19) | BIT(20) | BIT(21) | BIT(22), - }, -}; - -static const struct sirfsoc_padmux usp0_only_utfs_padmux = { - .muxmask_counts = ARRAY_SIZE(usp0_only_utfs_muxmask), - .muxmask = usp0_only_utfs_muxmask, - .ctrlreg = SIRFSOC_RSC_PIN_MUX, - .funcmask = BIT(1) | BIT(2) | BIT(6), - .funcval = 0, -}; - -static const unsigned usp0_only_utfs_pins[] = { 51, 52, 53, 54 }; - -static const struct sirfsoc_muxmask usp0_only_urfs_muxmask[] = { - { - .group = 1, - .mask = BIT(19) | BIT(20) | BIT(21) | BIT(23), - }, -}; - -static const struct sirfsoc_padmux usp0_only_urfs_padmux = { - .muxmask_counts = ARRAY_SIZE(usp0_only_urfs_muxmask), - .muxmask = usp0_only_urfs_muxmask, - .ctrlreg = SIRFSOC_RSC_PIN_MUX, - .funcmask = BIT(1) | BIT(2) | BIT(9), - .funcval = 0, -}; - -static const unsigned usp0_only_urfs_pins[] = { 51, 52, 53, 55 }; - -static const struct sirfsoc_muxmask usp0_uart_nostreamctrl_muxmask[] = { - { - .group = 1, - .mask = BIT(20) | BIT(21), - }, -}; - -static const struct sirfsoc_padmux usp0_uart_nostreamctrl_padmux = { - .muxmask_counts = ARRAY_SIZE(usp0_uart_nostreamctrl_muxmask), - .muxmask = usp0_uart_nostreamctrl_muxmask, -}; - -static const unsigned usp0_uart_nostreamctrl_pins[] = { 52, 53 }; - -static const struct sirfsoc_muxmask usp1_muxmask[] = { - { - .group = 1, - .mask = BIT(24) | BIT(25) | BIT(26) | BIT(27) | BIT(28), - }, -}; - -static const struct sirfsoc_padmux usp1_padmux = { - .muxmask_counts = ARRAY_SIZE(usp1_muxmask), - .muxmask = usp1_muxmask, - .ctrlreg = SIRFSOC_RSC_PIN_MUX, - .funcmask = BIT(1) | BIT(9) | BIT(10) | BIT(11), - .funcval = 0, -}; - -static const unsigned usp1_pins[] = { 56, 57, 58, 59, 60 }; - -static const struct sirfsoc_muxmask usp1_uart_nostreamctrl_muxmask[] = { - { - .group = 1, - .mask = BIT(25) | BIT(26), - }, -}; - -static const struct sirfsoc_padmux usp1_uart_nostreamctrl_padmux = { - .muxmask_counts = ARRAY_SIZE(usp1_uart_nostreamctrl_muxmask), - .muxmask = usp1_uart_nostreamctrl_muxmask, -}; - -static const unsigned usp1_uart_nostreamctrl_pins[] = { 57, 58 }; - -static const struct sirfsoc_muxmask usp2_muxmask[] = { - { - .group = 1, - .mask = BIT(29) | BIT(30) | BIT(31), - }, { - .group = 2, - .mask = BIT(0) | BIT(1), - }, -}; - -static const struct sirfsoc_padmux usp2_padmux = { - .muxmask_counts = ARRAY_SIZE(usp2_muxmask), - .muxmask = usp2_muxmask, - .ctrlreg = SIRFSOC_RSC_PIN_MUX, - .funcmask = BIT(13) | BIT(14), - .funcval = 0, -}; - -static const unsigned usp2_pins[] = { 61, 62, 63, 64, 65 }; - -static const struct sirfsoc_muxmask usp2_uart_nostreamctrl_muxmask[] = { - { - .group = 1, - .mask = BIT(30) | BIT(31), - }, -}; - -static const struct sirfsoc_padmux usp2_uart_nostreamctrl_padmux = { - .muxmask_counts = ARRAY_SIZE(usp2_uart_nostreamctrl_muxmask), - .muxmask = usp2_uart_nostreamctrl_muxmask, -}; - -static const unsigned usp2_uart_nostreamctrl_pins[] = { 62, 63 }; - -static const struct sirfsoc_muxmask nand_muxmask[] = { - { - .group = 2, - .mask = BIT(2) | BIT(3) | BIT(28) | BIT(29) | BIT(30), - }, -}; - -static const struct sirfsoc_padmux nand_padmux = { - .muxmask_counts = ARRAY_SIZE(nand_muxmask), - .muxmask = nand_muxmask, - .ctrlreg = SIRFSOC_RSC_PIN_MUX, - .funcmask = BIT(5), - .funcval = 0, -}; - -static const unsigned nand_pins[] = { 64, 65, 92, 93, 94 }; - -static const struct sirfsoc_padmux sdmmc0_padmux = { - .muxmask_counts = 0, - .ctrlreg = SIRFSOC_RSC_PIN_MUX, - .funcmask = BIT(5), - .funcval = 0, -}; - -static const unsigned sdmmc0_pins[] = { }; - -static const struct sirfsoc_muxmask sdmmc2_muxmask[] = { - { - .group = 2, - .mask = BIT(2) | BIT(3), - }, -}; - -static const struct sirfsoc_padmux sdmmc2_padmux = { - .muxmask_counts = ARRAY_SIZE(sdmmc2_muxmask), - .muxmask = sdmmc2_muxmask, - .ctrlreg = SIRFSOC_RSC_PIN_MUX, - .funcmask = BIT(5), - .funcval = BIT(5), -}; - -static const unsigned sdmmc2_pins[] = { 66, 67 }; - -static const struct sirfsoc_muxmask cko0_muxmask[] = { - { - .group = 2, - .mask = BIT(14), - }, -}; - -static const struct sirfsoc_padmux cko0_padmux = { - .muxmask_counts = ARRAY_SIZE(cko0_muxmask), - .muxmask = cko0_muxmask, -}; - -static const unsigned cko0_pins[] = { 78 }; - -static const struct sirfsoc_muxmask vip_muxmask[] = { - { - .group = 2, - .mask = BIT(15) | BIT(16) | BIT(17) | BIT(18) | BIT(19) - | BIT(20) | BIT(21) | BIT(22) | BIT(23) | BIT(24) | - BIT(25), - }, -}; - -static const struct sirfsoc_padmux vip_padmux = { - .muxmask_counts = ARRAY_SIZE(vip_muxmask), - .muxmask = vip_muxmask, - .ctrlreg = SIRFSOC_RSC_PIN_MUX, - .funcmask = BIT(0), - .funcval = 0, -}; - -static const unsigned vip_pins[] = { 79, 80, 81, 82, 83, 84, 85, 86, 87, - 88, 89 }; - -static const struct sirfsoc_muxmask i2c0_muxmask[] = { - { - .group = 2, - .mask = BIT(26) | BIT(27), - }, -}; - -static const struct sirfsoc_padmux i2c0_padmux = { - .muxmask_counts = ARRAY_SIZE(i2c0_muxmask), - .muxmask = i2c0_muxmask, -}; - -static const unsigned i2c0_pins[] = { 90, 91 }; - -static const struct sirfsoc_muxmask i2c1_muxmask[] = { - { - .group = 0, - .mask = BIT(13) | BIT(15), - }, -}; - -static const struct sirfsoc_padmux i2c1_padmux = { - .muxmask_counts = ARRAY_SIZE(i2c1_muxmask), - .muxmask = i2c1_muxmask, -}; - -static const unsigned i2c1_pins[] = { 13, 15 }; - -static const struct sirfsoc_muxmask viprom_muxmask[] = { - { - .group = 2, - .mask = BIT(15) | BIT(16) | BIT(17) | BIT(18) | BIT(19) - | BIT(20) | BIT(21) | BIT(22) | BIT(23) | BIT(24) | - BIT(25), - }, { - .group = 0, - .mask = BIT(12), - }, -}; - -static const struct sirfsoc_padmux viprom_padmux = { - .muxmask_counts = ARRAY_SIZE(viprom_muxmask), - .muxmask = viprom_muxmask, - .ctrlreg = SIRFSOC_RSC_PIN_MUX, - .funcmask = BIT(0), - .funcval = BIT(0), -}; - -static const unsigned viprom_pins[] = { 12, 79, 80, 81, 82, 83, 84, 85, 86, - 87, 88, 89 }; - -static const struct sirfsoc_muxmask pwm0_muxmask[] = { - { - .group = 0, - .mask = BIT(4), - }, -}; - -static const struct sirfsoc_padmux pwm0_padmux = { - .muxmask_counts = ARRAY_SIZE(pwm0_muxmask), - .muxmask = pwm0_muxmask, - .ctrlreg = SIRFSOC_RSC_PIN_MUX, - .funcmask = BIT(12), - .funcval = 0, -}; - -static const unsigned pwm0_pins[] = { 4 }; - -static const struct sirfsoc_muxmask pwm1_muxmask[] = { - { - .group = 0, - .mask = BIT(5), - }, -}; - -static const struct sirfsoc_padmux pwm1_padmux = { - .muxmask_counts = ARRAY_SIZE(pwm1_muxmask), - .muxmask = pwm1_muxmask, -}; - -static const unsigned pwm1_pins[] = { 5 }; - -static const struct sirfsoc_muxmask pwm2_muxmask[] = { - { - .group = 0, - .mask = BIT(6), - }, -}; - -static const struct sirfsoc_padmux pwm2_padmux = { - .muxmask_counts = ARRAY_SIZE(pwm2_muxmask), - .muxmask = pwm2_muxmask, -}; - -static const unsigned pwm2_pins[] = { 6 }; - -static const struct sirfsoc_muxmask pwm3_muxmask[] = { - { - .group = 0, - .mask = BIT(7), - }, -}; - -static const struct sirfsoc_padmux pwm3_padmux = { - .muxmask_counts = ARRAY_SIZE(pwm3_muxmask), - .muxmask = pwm3_muxmask, -}; - -static const unsigned pwm3_pins[] = { 7 }; - -static const struct sirfsoc_muxmask warm_rst_muxmask[] = { - { - .group = 0, - .mask = BIT(8), - }, -}; - -static const struct sirfsoc_padmux warm_rst_padmux = { - .muxmask_counts = ARRAY_SIZE(warm_rst_muxmask), - .muxmask = warm_rst_muxmask, -}; - -static const unsigned warm_rst_pins[] = { 8 }; - -static const struct sirfsoc_muxmask usb0_utmi_drvbus_muxmask[] = { - { - .group = 1, - .mask = BIT(22), - }, -}; -static const struct sirfsoc_padmux usb0_utmi_drvbus_padmux = { - .muxmask_counts = ARRAY_SIZE(usb0_utmi_drvbus_muxmask), - .muxmask = usb0_utmi_drvbus_muxmask, - .ctrlreg = SIRFSOC_RSC_PIN_MUX, - .funcmask = BIT(6), - .funcval = BIT(6), /* refer to PAD_UTMI_DRVVBUS0_ENABLE */ -}; - -static const unsigned usb0_utmi_drvbus_pins[] = { 54 }; - -static const struct sirfsoc_muxmask usb1_utmi_drvbus_muxmask[] = { - { - .group = 1, - .mask = BIT(27), - }, -}; - -static const struct sirfsoc_padmux usb1_utmi_drvbus_padmux = { - .muxmask_counts = ARRAY_SIZE(usb1_utmi_drvbus_muxmask), - .muxmask = usb1_utmi_drvbus_muxmask, - .ctrlreg = SIRFSOC_RSC_PIN_MUX, - .funcmask = BIT(11), - .funcval = BIT(11), /* refer to PAD_UTMI_DRVVBUS1_ENABLE */ -}; - -static const unsigned usb1_utmi_drvbus_pins[] = { 59 }; - -static const struct sirfsoc_padmux usb1_dp_dn_padmux = { - .muxmask_counts = 0, - .ctrlreg = SIRFSOC_RSC_USB_UART_SHARE, - .funcmask = BIT(2), - .funcval = BIT(2), -}; - -static const unsigned usb1_dp_dn_pins[] = { 115, 116 }; - -static const struct sirfsoc_padmux uart1_route_io_usb1_padmux = { - .muxmask_counts = 0, - .ctrlreg = SIRFSOC_RSC_USB_UART_SHARE, - .funcmask = BIT(2), - .funcval = 0, -}; - -static const unsigned uart1_route_io_usb1_pins[] = { 115, 116 }; - -static const struct sirfsoc_muxmask pulse_count_muxmask[] = { - { - .group = 0, - .mask = BIT(9) | BIT(10) | BIT(11), - }, -}; - -static const struct sirfsoc_padmux pulse_count_padmux = { - .muxmask_counts = ARRAY_SIZE(pulse_count_muxmask), - .muxmask = pulse_count_muxmask, -}; - -static const unsigned pulse_count_pins[] = { 9, 10, 11 }; - -static const struct sirfsoc_pin_group sirfsoc_pin_groups[] = { - SIRFSOC_PIN_GROUP("lcd_16bitsgrp", lcd_16bits_pins), - SIRFSOC_PIN_GROUP("lcd_18bitsgrp", lcd_18bits_pins), - SIRFSOC_PIN_GROUP("lcd_24bitsgrp", lcd_24bits_pins), - SIRFSOC_PIN_GROUP("lcdrom_grp", lcdrom_pins), - SIRFSOC_PIN_GROUP("uart0grp", uart0_pins), - SIRFSOC_PIN_GROUP("uart0_nostreamctrlgrp", uart0_nostreamctrl_pins), - SIRFSOC_PIN_GROUP("uart1grp", uart1_pins), - SIRFSOC_PIN_GROUP("uart2grp", uart2_pins), - SIRFSOC_PIN_GROUP("uart2_nostreamctrlgrp", uart2_nostreamctrl_pins), - SIRFSOC_PIN_GROUP("usp0grp", usp0_pins), - SIRFSOC_PIN_GROUP("usp0_uart_nostreamctrl_grp", - usp0_uart_nostreamctrl_pins), - SIRFSOC_PIN_GROUP("usp0_only_utfs_grp", usp0_only_utfs_pins), - SIRFSOC_PIN_GROUP("usp0_only_urfs_grp", usp0_only_urfs_pins), - SIRFSOC_PIN_GROUP("usp1grp", usp1_pins), - SIRFSOC_PIN_GROUP("usp1_uart_nostreamctrl_grp", - usp1_uart_nostreamctrl_pins), - SIRFSOC_PIN_GROUP("usp2grp", usp2_pins), - SIRFSOC_PIN_GROUP("usp2_uart_nostreamctrl_grp", - usp2_uart_nostreamctrl_pins), - SIRFSOC_PIN_GROUP("i2c0grp", i2c0_pins), - SIRFSOC_PIN_GROUP("i2c1grp", i2c1_pins), - SIRFSOC_PIN_GROUP("pwm0grp", pwm0_pins), - SIRFSOC_PIN_GROUP("pwm1grp", pwm1_pins), - SIRFSOC_PIN_GROUP("pwm2grp", pwm2_pins), - SIRFSOC_PIN_GROUP("pwm3grp", pwm3_pins), - SIRFSOC_PIN_GROUP("vipgrp", vip_pins), - SIRFSOC_PIN_GROUP("vipromgrp", viprom_pins), - SIRFSOC_PIN_GROUP("warm_rstgrp", warm_rst_pins), - SIRFSOC_PIN_GROUP("cko0grp", cko0_pins), - SIRFSOC_PIN_GROUP("cko1grp", cko1_pins), - SIRFSOC_PIN_GROUP("sdmmc0grp", sdmmc0_pins), - SIRFSOC_PIN_GROUP("sdmmc1grp", sdmmc1_pins), - SIRFSOC_PIN_GROUP("sdmmc2grp", sdmmc2_pins), - SIRFSOC_PIN_GROUP("sdmmc3grp", sdmmc3_pins), - SIRFSOC_PIN_GROUP("sdmmc4grp", sdmmc4_pins), - SIRFSOC_PIN_GROUP("sdmmc5grp", sdmmc5_pins), - SIRFSOC_PIN_GROUP("usb0_utmi_drvbusgrp", usb0_utmi_drvbus_pins), - SIRFSOC_PIN_GROUP("usb1_utmi_drvbusgrp", usb1_utmi_drvbus_pins), - SIRFSOC_PIN_GROUP("usb1_dp_dngrp", usb1_dp_dn_pins), - SIRFSOC_PIN_GROUP("uart1_route_io_usb1grp", uart1_route_io_usb1_pins), - SIRFSOC_PIN_GROUP("pulse_countgrp", pulse_count_pins), - SIRFSOC_PIN_GROUP("i2smclkgrp", i2s_mclk_pins), - SIRFSOC_PIN_GROUP("i2s_ext_clk_inputgrp", i2s_ext_clk_input_pins), - SIRFSOC_PIN_GROUP("i2sgrp", i2s_pins), - SIRFSOC_PIN_GROUP("i2s_no_dingrp", i2s_no_din_pins), - SIRFSOC_PIN_GROUP("i2s_6chngrp", i2s_6chn_pins), - SIRFSOC_PIN_GROUP("ac97grp", ac97_pins), - SIRFSOC_PIN_GROUP("nandgrp", nand_pins), - SIRFSOC_PIN_GROUP("spi0grp", spi0_pins), - SIRFSOC_PIN_GROUP("spi1grp", spi1_pins), - SIRFSOC_PIN_GROUP("gpsgrp", gps_pins), -}; - -static const char * const lcd_16bitsgrp[] = { "lcd_16bitsgrp" }; -static const char * const lcd_18bitsgrp[] = { "lcd_18bitsgrp" }; -static const char * const lcd_24bitsgrp[] = { "lcd_24bitsgrp" }; -static const char * const lcdromgrp[] = { "lcdromgrp" }; -static const char * const uart0grp[] = { "uart0grp" }; -static const char * const uart0_nostreamctrlgrp[] = { "uart0_nostreamctrlgrp" }; -static const char * const uart1grp[] = { "uart1grp" }; -static const char * const uart2grp[] = { "uart2grp" }; -static const char * const uart2_nostreamctrlgrp[] = { "uart2_nostreamctrlgrp" }; -static const char * const usp0grp[] = { "usp0grp" }; -static const char * const usp0_uart_nostreamctrl_grp[] = { - "usp0_uart_nostreamctrl_grp" -}; -static const char * const usp0_only_utfs_grp[] = { "usp0_only_utfs_grp" }; -static const char * const usp0_only_urfs_grp[] = { "usp0_only_urfs_grp" }; -static const char * const usp1grp[] = { "usp1grp" }; -static const char * const usp1_uart_nostreamctrl_grp[] = { - "usp1_uart_nostreamctrl_grp" -}; -static const char * const usp2grp[] = { "usp2grp" }; -static const char * const usp2_uart_nostreamctrl_grp[] = { - "usp2_uart_nostreamctrl_grp" -}; -static const char * const i2c0grp[] = { "i2c0grp" }; -static const char * const i2c1grp[] = { "i2c1grp" }; -static const char * const pwm0grp[] = { "pwm0grp" }; -static const char * const pwm1grp[] = { "pwm1grp" }; -static const char * const pwm2grp[] = { "pwm2grp" }; -static const char * const pwm3grp[] = { "pwm3grp" }; -static const char * const vipgrp[] = { "vipgrp" }; -static const char * const vipromgrp[] = { "vipromgrp" }; -static const char * const warm_rstgrp[] = { "warm_rstgrp" }; -static const char * const cko0grp[] = { "cko0grp" }; -static const char * const cko1grp[] = { "cko1grp" }; -static const char * const sdmmc0grp[] = { "sdmmc0grp" }; -static const char * const sdmmc1grp[] = { "sdmmc1grp" }; -static const char * const sdmmc2grp[] = { "sdmmc2grp" }; -static const char * const sdmmc3grp[] = { "sdmmc3grp" }; -static const char * const sdmmc4grp[] = { "sdmmc4grp" }; -static const char * const sdmmc5grp[] = { "sdmmc5grp" }; -static const char * const usb0_utmi_drvbusgrp[] = { "usb0_utmi_drvbusgrp" }; -static const char * const usb1_utmi_drvbusgrp[] = { "usb1_utmi_drvbusgrp" }; -static const char * const usb1_dp_dngrp[] = { "usb1_dp_dngrp" }; -static const char * const - uart1_route_io_usb1grp[] = { "uart1_route_io_usb1grp" }; -static const char * const pulse_countgrp[] = { "pulse_countgrp" }; -static const char * const i2smclkgrp[] = { "i2smclkgrp" }; -static const char * const i2s_ext_clk_inputgrp[] = { "i2s_ext_clk_inputgrp" }; -static const char * const i2sgrp[] = { "i2sgrp" }; -static const char * const i2s_no_dingrp[] = { "i2s_no_dingrp" }; -static const char * const i2s_6chngrp[] = { "i2s_6chngrp" }; -static const char * const ac97grp[] = { "ac97grp" }; -static const char * const nandgrp[] = { "nandgrp" }; -static const char * const spi0grp[] = { "spi0grp" }; -static const char * const spi1grp[] = { "spi1grp" }; -static const char * const gpsgrp[] = { "gpsgrp" }; - -static const struct sirfsoc_pmx_func sirfsoc_pmx_functions[] = { - SIRFSOC_PMX_FUNCTION("lcd_16bits", lcd_16bitsgrp, lcd_16bits_padmux), - SIRFSOC_PMX_FUNCTION("lcd_18bits", lcd_18bitsgrp, lcd_18bits_padmux), - SIRFSOC_PMX_FUNCTION("lcd_24bits", lcd_24bitsgrp, lcd_24bits_padmux), - SIRFSOC_PMX_FUNCTION("lcdrom", lcdromgrp, lcdrom_padmux), - SIRFSOC_PMX_FUNCTION("uart0", uart0grp, uart0_padmux), - SIRFSOC_PMX_FUNCTION("uart0_nostreamctrl", - uart0_nostreamctrlgrp, uart0_nostreamctrl_padmux), - SIRFSOC_PMX_FUNCTION("uart1", uart1grp, uart1_padmux), - SIRFSOC_PMX_FUNCTION("uart2", uart2grp, uart2_padmux), - SIRFSOC_PMX_FUNCTION("uart2_nostreamctrl", - uart2_nostreamctrlgrp, uart2_nostreamctrl_padmux), - SIRFSOC_PMX_FUNCTION("usp0", usp0grp, usp0_padmux), - SIRFSOC_PMX_FUNCTION("usp0_uart_nostreamctrl", - usp0_uart_nostreamctrl_grp, usp0_uart_nostreamctrl_padmux), - SIRFSOC_PMX_FUNCTION("usp0_only_utfs", - usp0_only_utfs_grp, usp0_only_utfs_padmux), - SIRFSOC_PMX_FUNCTION("usp0_only_urfs", - usp0_only_urfs_grp, usp0_only_urfs_padmux), - SIRFSOC_PMX_FUNCTION("usp1", usp1grp, usp1_padmux), - SIRFSOC_PMX_FUNCTION("usp1_uart_nostreamctrl", - usp1_uart_nostreamctrl_grp, usp1_uart_nostreamctrl_padmux), - SIRFSOC_PMX_FUNCTION("usp2", usp2grp, usp2_padmux), - SIRFSOC_PMX_FUNCTION("usp2_uart_nostreamctrl", - usp2_uart_nostreamctrl_grp, usp2_uart_nostreamctrl_padmux), - SIRFSOC_PMX_FUNCTION("i2c0", i2c0grp, i2c0_padmux), - SIRFSOC_PMX_FUNCTION("i2c1", i2c1grp, i2c1_padmux), - SIRFSOC_PMX_FUNCTION("pwm0", pwm0grp, pwm0_padmux), - SIRFSOC_PMX_FUNCTION("pwm1", pwm1grp, pwm1_padmux), - SIRFSOC_PMX_FUNCTION("pwm2", pwm2grp, pwm2_padmux), - SIRFSOC_PMX_FUNCTION("pwm3", pwm3grp, pwm3_padmux), - SIRFSOC_PMX_FUNCTION("vip", vipgrp, vip_padmux), - SIRFSOC_PMX_FUNCTION("viprom", vipromgrp, viprom_padmux), - SIRFSOC_PMX_FUNCTION("warm_rst", warm_rstgrp, warm_rst_padmux), - SIRFSOC_PMX_FUNCTION("cko0", cko0grp, cko0_padmux), - SIRFSOC_PMX_FUNCTION("cko1", cko1grp, cko1_padmux), - SIRFSOC_PMX_FUNCTION("sdmmc0", sdmmc0grp, sdmmc0_padmux), - SIRFSOC_PMX_FUNCTION("sdmmc1", sdmmc1grp, sdmmc1_padmux), - SIRFSOC_PMX_FUNCTION("sdmmc2", sdmmc2grp, sdmmc2_padmux), - SIRFSOC_PMX_FUNCTION("sdmmc3", sdmmc3grp, sdmmc3_padmux), - SIRFSOC_PMX_FUNCTION("sdmmc4", sdmmc4grp, sdmmc4_padmux), - SIRFSOC_PMX_FUNCTION("sdmmc5", sdmmc5grp, sdmmc5_padmux), - SIRFSOC_PMX_FUNCTION("usb0_utmi_drvbus", - usb0_utmi_drvbusgrp, usb0_utmi_drvbus_padmux), - SIRFSOC_PMX_FUNCTION("usb1_utmi_drvbus", - usb1_utmi_drvbusgrp, usb1_utmi_drvbus_padmux), - SIRFSOC_PMX_FUNCTION("usb1_dp_dn", usb1_dp_dngrp, usb1_dp_dn_padmux), - SIRFSOC_PMX_FUNCTION("uart1_route_io_usb1", - uart1_route_io_usb1grp, uart1_route_io_usb1_padmux), - SIRFSOC_PMX_FUNCTION("pulse_count", pulse_countgrp, pulse_count_padmux), - SIRFSOC_PMX_FUNCTION("i2s_mclk", i2smclkgrp, i2s_mclk_padmux), - SIRFSOC_PMX_FUNCTION("i2s_ext_clk_input", i2s_ext_clk_inputgrp, - i2s_ext_clk_input_padmux), - SIRFSOC_PMX_FUNCTION("i2s", i2sgrp, i2s_padmux), - SIRFSOC_PMX_FUNCTION("i2s_no_din", i2s_no_dingrp, i2s_no_din_padmux), - SIRFSOC_PMX_FUNCTION("i2s_6chn", i2s_6chngrp, i2s_6chn_padmux), - SIRFSOC_PMX_FUNCTION("ac97", ac97grp, ac97_padmux), - SIRFSOC_PMX_FUNCTION("nand", nandgrp, nand_padmux), - SIRFSOC_PMX_FUNCTION("spi0", spi0grp, spi0_padmux), - SIRFSOC_PMX_FUNCTION("spi1", spi1grp, spi1_padmux), - SIRFSOC_PMX_FUNCTION("gps", gpsgrp, gps_padmux), -}; - -struct sirfsoc_pinctrl_data prima2_pinctrl_data = { - (struct pinctrl_pin_desc *)sirfsoc_pads, - ARRAY_SIZE(sirfsoc_pads), - (struct sirfsoc_pin_group *)sirfsoc_pin_groups, - ARRAY_SIZE(sirfsoc_pin_groups), - (struct sirfsoc_pmx_func *)sirfsoc_pmx_functions, - ARRAY_SIZE(sirfsoc_pmx_functions), -}; - diff --git a/drivers/pinctrl/sirf/pinctrl-sirf.c b/drivers/pinctrl/sirf/pinctrl-sirf.c deleted file mode 100644 index 63a287d5795f..000000000000 --- a/drivers/pinctrl/sirf/pinctrl-sirf.c +++ /dev/null @@ -1,894 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * pinmux driver for CSR SiRFprimaII - * - * Authors: - * Rongjun Ying - * Yuping Luo - * Barry Song - * - * Copyright (c) 2011 - 2014 Cambridge Silicon Radio Limited, a CSR plc group - * company. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "pinctrl-sirf.h" - -#define DRIVER_NAME "pinmux-sirf" - -struct sirfsoc_gpio_bank { - int id; - int parent_irq; - spinlock_t lock; -}; - -struct sirfsoc_gpio_chip { - struct of_mm_gpio_chip chip; - struct sirfsoc_gpio_bank sgpio_bank[SIRFSOC_GPIO_NO_OF_BANKS]; - spinlock_t lock; -}; - -static struct sirfsoc_pin_group *sirfsoc_pin_groups; -static int sirfsoc_pingrp_cnt; - -static int sirfsoc_get_groups_count(struct pinctrl_dev *pctldev) -{ - return sirfsoc_pingrp_cnt; -} - -static const char *sirfsoc_get_group_name(struct pinctrl_dev *pctldev, - unsigned selector) -{ - return sirfsoc_pin_groups[selector].name; -} - -static int sirfsoc_get_group_pins(struct pinctrl_dev *pctldev, - unsigned selector, - const unsigned **pins, - unsigned *num_pins) -{ - *pins = sirfsoc_pin_groups[selector].pins; - *num_pins = sirfsoc_pin_groups[selector].num_pins; - return 0; -} - -static void sirfsoc_pin_dbg_show(struct pinctrl_dev *pctldev, - struct seq_file *s, unsigned offset) -{ - seq_printf(s, " " DRIVER_NAME); -} - -static int sirfsoc_dt_node_to_map(struct pinctrl_dev *pctldev, - struct device_node *np_config, - struct pinctrl_map **map, unsigned *num_maps) -{ - struct sirfsoc_pmx *spmx = pinctrl_dev_get_drvdata(pctldev); - struct device_node *np; - struct property *prop; - const char *function, *group; - int ret, index = 0, count = 0; - - /* calculate number of maps required */ - for_each_child_of_node(np_config, np) { - ret = of_property_read_string(np, "sirf,function", &function); - if (ret < 0) { - of_node_put(np); - return ret; - } - - ret = of_property_count_strings(np, "sirf,pins"); - if (ret < 0) { - of_node_put(np); - return ret; - } - - count += ret; - } - - if (!count) { - dev_err(spmx->dev, "No child nodes passed via DT\n"); - return -ENODEV; - } - - *map = kcalloc(count, sizeof(**map), GFP_KERNEL); - if (!*map) - return -ENOMEM; - - for_each_child_of_node(np_config, np) { - of_property_read_string(np, "sirf,function", &function); - of_property_for_each_string(np, "sirf,pins", prop, group) { - (*map)[index].type = PIN_MAP_TYPE_MUX_GROUP; - (*map)[index].data.mux.group = group; - (*map)[index].data.mux.function = function; - index++; - } - } - - *num_maps = count; - - return 0; -} - -static void sirfsoc_dt_free_map(struct pinctrl_dev *pctldev, - struct pinctrl_map *map, unsigned num_maps) -{ - kfree(map); -} - -static const struct pinctrl_ops sirfsoc_pctrl_ops = { - .get_groups_count = sirfsoc_get_groups_count, - .get_group_name = sirfsoc_get_group_name, - .get_group_pins = sirfsoc_get_group_pins, - .pin_dbg_show = sirfsoc_pin_dbg_show, - .dt_node_to_map = sirfsoc_dt_node_to_map, - .dt_free_map = sirfsoc_dt_free_map, -}; - -static struct sirfsoc_pmx_func *sirfsoc_pmx_functions; -static int sirfsoc_pmxfunc_cnt; - -static void sirfsoc_pinmux_endisable(struct sirfsoc_pmx *spmx, - unsigned selector, bool enable) -{ - int i; - const struct sirfsoc_padmux *mux = - sirfsoc_pmx_functions[selector].padmux; - const struct sirfsoc_muxmask *mask = mux->muxmask; - - for (i = 0; i < mux->muxmask_counts; i++) { - u32 muxval; - muxval = readl(spmx->gpio_virtbase + - SIRFSOC_GPIO_PAD_EN(mask[i].group)); - if (enable) - muxval = muxval & ~mask[i].mask; - else - muxval = muxval | mask[i].mask; - writel(muxval, spmx->gpio_virtbase + - SIRFSOC_GPIO_PAD_EN(mask[i].group)); - } - - if (mux->funcmask && enable) { - u32 func_en_val; - - func_en_val = - readl(spmx->rsc_virtbase + mux->ctrlreg); - func_en_val = - (func_en_val & ~mux->funcmask) | (mux->funcval); - writel(func_en_val, spmx->rsc_virtbase + mux->ctrlreg); - } -} - -static int sirfsoc_pinmux_set_mux(struct pinctrl_dev *pmxdev, - unsigned selector, - unsigned group) -{ - struct sirfsoc_pmx *spmx; - - spmx = pinctrl_dev_get_drvdata(pmxdev); - sirfsoc_pinmux_endisable(spmx, selector, true); - - return 0; -} - -static int sirfsoc_pinmux_get_funcs_count(struct pinctrl_dev *pmxdev) -{ - return sirfsoc_pmxfunc_cnt; -} - -static const char *sirfsoc_pinmux_get_func_name(struct pinctrl_dev *pctldev, - unsigned selector) -{ - return sirfsoc_pmx_functions[selector].name; -} - -static int sirfsoc_pinmux_get_groups(struct pinctrl_dev *pctldev, - unsigned selector, - const char * const **groups, - unsigned * const num_groups) -{ - *groups = sirfsoc_pmx_functions[selector].groups; - *num_groups = sirfsoc_pmx_functions[selector].num_groups; - return 0; -} - -static int sirfsoc_pinmux_request_gpio(struct pinctrl_dev *pmxdev, - struct pinctrl_gpio_range *range, unsigned offset) -{ - struct sirfsoc_pmx *spmx; - - int group = range->id; - - u32 muxval; - - spmx = pinctrl_dev_get_drvdata(pmxdev); - - muxval = readl(spmx->gpio_virtbase + - SIRFSOC_GPIO_PAD_EN(group)); - muxval = muxval | (1 << (offset - range->pin_base)); - writel(muxval, spmx->gpio_virtbase + - SIRFSOC_GPIO_PAD_EN(group)); - - return 0; -} - -static const struct pinmux_ops sirfsoc_pinmux_ops = { - .set_mux = sirfsoc_pinmux_set_mux, - .get_functions_count = sirfsoc_pinmux_get_funcs_count, - .get_function_name = sirfsoc_pinmux_get_func_name, - .get_function_groups = sirfsoc_pinmux_get_groups, - .gpio_request_enable = sirfsoc_pinmux_request_gpio, -}; - -static struct pinctrl_desc sirfsoc_pinmux_desc = { - .name = DRIVER_NAME, - .pctlops = &sirfsoc_pctrl_ops, - .pmxops = &sirfsoc_pinmux_ops, - .owner = THIS_MODULE, -}; - -static void __iomem *sirfsoc_rsc_of_iomap(void) -{ - const struct of_device_id rsc_ids[] = { - { .compatible = "sirf,prima2-rsc" }, - {} - }; - struct device_node *np; - - np = of_find_matching_node(NULL, rsc_ids); - if (!np) - panic("unable to find compatible rsc node in dtb\n"); - - return of_iomap(np, 0); -} - -static int sirfsoc_gpio_of_xlate(struct gpio_chip *gc, - const struct of_phandle_args *gpiospec, - u32 *flags) -{ - if (gpiospec->args[0] > SIRFSOC_GPIO_NO_OF_BANKS * SIRFSOC_GPIO_BANK_SIZE) - return -EINVAL; - - if (flags) - *flags = gpiospec->args[1]; - - return gpiospec->args[0]; -} - -static const struct of_device_id pinmux_ids[] = { - { .compatible = "sirf,prima2-pinctrl", .data = &prima2_pinctrl_data, }, - { .compatible = "sirf,atlas6-pinctrl", .data = &atlas6_pinctrl_data, }, - {} -}; - -static int sirfsoc_pinmux_probe(struct platform_device *pdev) -{ - int ret; - struct sirfsoc_pmx *spmx; - struct device_node *np = pdev->dev.of_node; - const struct sirfsoc_pinctrl_data *pdata; - - /* Create state holders etc for this driver */ - spmx = devm_kzalloc(&pdev->dev, sizeof(*spmx), GFP_KERNEL); - if (!spmx) - return -ENOMEM; - - spmx->dev = &pdev->dev; - - platform_set_drvdata(pdev, spmx); - - spmx->gpio_virtbase = of_iomap(np, 0); - if (!spmx->gpio_virtbase) { - dev_err(&pdev->dev, "can't map gpio registers\n"); - return -ENOMEM; - } - - spmx->rsc_virtbase = sirfsoc_rsc_of_iomap(); - if (!spmx->rsc_virtbase) { - ret = -ENOMEM; - dev_err(&pdev->dev, "can't map rsc registers\n"); - goto out_no_rsc_remap; - } - - pdata = of_match_node(pinmux_ids, np)->data; - sirfsoc_pin_groups = pdata->grps; - sirfsoc_pingrp_cnt = pdata->grps_cnt; - sirfsoc_pmx_functions = pdata->funcs; - sirfsoc_pmxfunc_cnt = pdata->funcs_cnt; - sirfsoc_pinmux_desc.pins = pdata->pads; - sirfsoc_pinmux_desc.npins = pdata->pads_cnt; - - - /* Now register the pin controller and all pins it handles */ - spmx->pmx = pinctrl_register(&sirfsoc_pinmux_desc, &pdev->dev, spmx); - if (IS_ERR(spmx->pmx)) { - dev_err(&pdev->dev, "could not register SIRFSOC pinmux driver\n"); - ret = PTR_ERR(spmx->pmx); - goto out_no_pmx; - } - - dev_info(&pdev->dev, "initialized SIRFSOC pinmux driver\n"); - - return 0; - -out_no_pmx: - iounmap(spmx->rsc_virtbase); -out_no_rsc_remap: - iounmap(spmx->gpio_virtbase); - return ret; -} - -#ifdef CONFIG_PM_SLEEP -static int sirfsoc_pinmux_suspend_noirq(struct device *dev) -{ - int i, j; - struct sirfsoc_pmx *spmx = dev_get_drvdata(dev); - - for (i = 0; i < SIRFSOC_GPIO_NO_OF_BANKS; i++) { - for (j = 0; j < SIRFSOC_GPIO_BANK_SIZE; j++) { - spmx->gpio_regs[i][j] = readl(spmx->gpio_virtbase + - SIRFSOC_GPIO_CTRL(i, j)); - } - spmx->ints_regs[i] = readl(spmx->gpio_virtbase + - SIRFSOC_GPIO_INT_STATUS(i)); - spmx->paden_regs[i] = readl(spmx->gpio_virtbase + - SIRFSOC_GPIO_PAD_EN(i)); - } - spmx->dspen_regs = readl(spmx->gpio_virtbase + SIRFSOC_GPIO_DSP_EN0); - - for (i = 0; i < 3; i++) - spmx->rsc_regs[i] = readl(spmx->rsc_virtbase + 4 * i); - - return 0; -} - -static int sirfsoc_pinmux_resume_noirq(struct device *dev) -{ - int i, j; - struct sirfsoc_pmx *spmx = dev_get_drvdata(dev); - - for (i = 0; i < SIRFSOC_GPIO_NO_OF_BANKS; i++) { - for (j = 0; j < SIRFSOC_GPIO_BANK_SIZE; j++) { - writel(spmx->gpio_regs[i][j], spmx->gpio_virtbase + - SIRFSOC_GPIO_CTRL(i, j)); - } - writel(spmx->ints_regs[i], spmx->gpio_virtbase + - SIRFSOC_GPIO_INT_STATUS(i)); - writel(spmx->paden_regs[i], spmx->gpio_virtbase + - SIRFSOC_GPIO_PAD_EN(i)); - } - writel(spmx->dspen_regs, spmx->gpio_virtbase + SIRFSOC_GPIO_DSP_EN0); - - for (i = 0; i < 3; i++) - writel(spmx->rsc_regs[i], spmx->rsc_virtbase + 4 * i); - - return 0; -} - -static const struct dev_pm_ops sirfsoc_pinmux_pm_ops = { - .suspend_noirq = sirfsoc_pinmux_suspend_noirq, - .resume_noirq = sirfsoc_pinmux_resume_noirq, - .freeze_noirq = sirfsoc_pinmux_suspend_noirq, - .restore_noirq = sirfsoc_pinmux_resume_noirq, -}; -#endif - -static struct platform_driver sirfsoc_pinmux_driver = { - .driver = { - .name = DRIVER_NAME, - .of_match_table = pinmux_ids, -#ifdef CONFIG_PM_SLEEP - .pm = &sirfsoc_pinmux_pm_ops, -#endif - }, - .probe = sirfsoc_pinmux_probe, -}; - -static int __init sirfsoc_pinmux_init(void) -{ - return platform_driver_register(&sirfsoc_pinmux_driver); -} -arch_initcall(sirfsoc_pinmux_init); - -static inline struct sirfsoc_gpio_bank * -sirfsoc_gpio_to_bank(struct sirfsoc_gpio_chip *sgpio, unsigned int offset) -{ - return &sgpio->sgpio_bank[offset / SIRFSOC_GPIO_BANK_SIZE]; -} - -static inline int sirfsoc_gpio_to_bankoff(unsigned int offset) -{ - return offset % SIRFSOC_GPIO_BANK_SIZE; -} - -static void sirfsoc_gpio_irq_ack(struct irq_data *d) -{ - struct gpio_chip *gc = irq_data_get_irq_chip_data(d); - struct sirfsoc_gpio_chip *sgpio = gpiochip_get_data(gc); - struct sirfsoc_gpio_bank *bank = sirfsoc_gpio_to_bank(sgpio, d->hwirq); - int idx = sirfsoc_gpio_to_bankoff(d->hwirq); - u32 val, offset; - unsigned long flags; - - offset = SIRFSOC_GPIO_CTRL(bank->id, idx); - - spin_lock_irqsave(&sgpio->lock, flags); - - val = readl(sgpio->chip.regs + offset); - - writel(val, sgpio->chip.regs + offset); - - spin_unlock_irqrestore(&sgpio->lock, flags); -} - -static void __sirfsoc_gpio_irq_mask(struct sirfsoc_gpio_chip *sgpio, - struct sirfsoc_gpio_bank *bank, - int idx) -{ - u32 val, offset; - unsigned long flags; - - offset = SIRFSOC_GPIO_CTRL(bank->id, idx); - - spin_lock_irqsave(&sgpio->lock, flags); - - val = readl(sgpio->chip.regs + offset); - val &= ~SIRFSOC_GPIO_CTL_INTR_EN_MASK; - val &= ~SIRFSOC_GPIO_CTL_INTR_STS_MASK; - writel(val, sgpio->chip.regs + offset); - - spin_unlock_irqrestore(&sgpio->lock, flags); -} - -static void sirfsoc_gpio_irq_mask(struct irq_data *d) -{ - struct gpio_chip *gc = irq_data_get_irq_chip_data(d); - struct sirfsoc_gpio_chip *sgpio = gpiochip_get_data(gc); - struct sirfsoc_gpio_bank *bank = sirfsoc_gpio_to_bank(sgpio, d->hwirq); - - __sirfsoc_gpio_irq_mask(sgpio, bank, d->hwirq % SIRFSOC_GPIO_BANK_SIZE); -} - -static void sirfsoc_gpio_irq_unmask(struct irq_data *d) -{ - struct gpio_chip *gc = irq_data_get_irq_chip_data(d); - struct sirfsoc_gpio_chip *sgpio = gpiochip_get_data(gc); - struct sirfsoc_gpio_bank *bank = sirfsoc_gpio_to_bank(sgpio, d->hwirq); - int idx = sirfsoc_gpio_to_bankoff(d->hwirq); - u32 val, offset; - unsigned long flags; - - offset = SIRFSOC_GPIO_CTRL(bank->id, idx); - - spin_lock_irqsave(&sgpio->lock, flags); - - val = readl(sgpio->chip.regs + offset); - val &= ~SIRFSOC_GPIO_CTL_INTR_STS_MASK; - val |= SIRFSOC_GPIO_CTL_INTR_EN_MASK; - writel(val, sgpio->chip.regs + offset); - - spin_unlock_irqrestore(&sgpio->lock, flags); -} - -static int sirfsoc_gpio_irq_type(struct irq_data *d, unsigned type) -{ - struct gpio_chip *gc = irq_data_get_irq_chip_data(d); - struct sirfsoc_gpio_chip *sgpio = gpiochip_get_data(gc); - struct sirfsoc_gpio_bank *bank = sirfsoc_gpio_to_bank(sgpio, d->hwirq); - int idx = sirfsoc_gpio_to_bankoff(d->hwirq); - u32 val, offset; - unsigned long flags; - - offset = SIRFSOC_GPIO_CTRL(bank->id, idx); - - spin_lock_irqsave(&sgpio->lock, flags); - - val = readl(sgpio->chip.regs + offset); - val &= ~(SIRFSOC_GPIO_CTL_INTR_STS_MASK | SIRFSOC_GPIO_CTL_OUT_EN_MASK); - - switch (type) { - case IRQ_TYPE_NONE: - break; - case IRQ_TYPE_EDGE_RISING: - val |= SIRFSOC_GPIO_CTL_INTR_HIGH_MASK | - SIRFSOC_GPIO_CTL_INTR_TYPE_MASK; - val &= ~SIRFSOC_GPIO_CTL_INTR_LOW_MASK; - break; - case IRQ_TYPE_EDGE_FALLING: - val &= ~SIRFSOC_GPIO_CTL_INTR_HIGH_MASK; - val |= SIRFSOC_GPIO_CTL_INTR_LOW_MASK | - SIRFSOC_GPIO_CTL_INTR_TYPE_MASK; - break; - case IRQ_TYPE_EDGE_BOTH: - val |= SIRFSOC_GPIO_CTL_INTR_HIGH_MASK | - SIRFSOC_GPIO_CTL_INTR_LOW_MASK | - SIRFSOC_GPIO_CTL_INTR_TYPE_MASK; - break; - case IRQ_TYPE_LEVEL_LOW: - val &= ~(SIRFSOC_GPIO_CTL_INTR_HIGH_MASK | - SIRFSOC_GPIO_CTL_INTR_TYPE_MASK); - val |= SIRFSOC_GPIO_CTL_INTR_LOW_MASK; - break; - case IRQ_TYPE_LEVEL_HIGH: - val |= SIRFSOC_GPIO_CTL_INTR_HIGH_MASK; - val &= ~(SIRFSOC_GPIO_CTL_INTR_LOW_MASK | - SIRFSOC_GPIO_CTL_INTR_TYPE_MASK); - break; - } - - writel(val, sgpio->chip.regs + offset); - - spin_unlock_irqrestore(&sgpio->lock, flags); - - return 0; -} - -static struct irq_chip sirfsoc_irq_chip = { - .name = "sirf-gpio-irq", - .irq_ack = sirfsoc_gpio_irq_ack, - .irq_mask = sirfsoc_gpio_irq_mask, - .irq_unmask = sirfsoc_gpio_irq_unmask, - .irq_set_type = sirfsoc_gpio_irq_type, -}; - -static void sirfsoc_gpio_handle_irq(struct irq_desc *desc) -{ - unsigned int irq = irq_desc_get_irq(desc); - struct gpio_chip *gc = irq_desc_get_handler_data(desc); - struct sirfsoc_gpio_chip *sgpio = gpiochip_get_data(gc); - struct sirfsoc_gpio_bank *bank; - u32 status, ctrl; - int idx = 0; - struct irq_chip *chip = irq_desc_get_chip(desc); - int i; - - for (i = 0; i < SIRFSOC_GPIO_NO_OF_BANKS; i++) { - bank = &sgpio->sgpio_bank[i]; - if (bank->parent_irq == irq) - break; - } - BUG_ON(i == SIRFSOC_GPIO_NO_OF_BANKS); - - chained_irq_enter(chip, desc); - - status = readl(sgpio->chip.regs + SIRFSOC_GPIO_INT_STATUS(bank->id)); - if (!status) { - printk(KERN_WARNING - "%s: gpio id %d status %#x no interrupt is flagged\n", - __func__, bank->id, status); - handle_bad_irq(desc); - return; - } - - while (status) { - ctrl = readl(sgpio->chip.regs + SIRFSOC_GPIO_CTRL(bank->id, idx)); - - /* - * Here we must check whether the corresponding GPIO's interrupt - * has been enabled, otherwise just skip it - */ - if ((status & 0x1) && (ctrl & SIRFSOC_GPIO_CTL_INTR_EN_MASK)) { - pr_debug("%s: gpio id %d idx %d happens\n", - __func__, bank->id, idx); - generic_handle_irq(irq_find_mapping(gc->irq.domain, idx + - bank->id * SIRFSOC_GPIO_BANK_SIZE)); - } - - idx++; - status = status >> 1; - } - - chained_irq_exit(chip, desc); -} - -static inline void sirfsoc_gpio_set_input(struct sirfsoc_gpio_chip *sgpio, - unsigned ctrl_offset) -{ - u32 val; - - val = readl(sgpio->chip.regs + ctrl_offset); - val &= ~SIRFSOC_GPIO_CTL_OUT_EN_MASK; - writel(val, sgpio->chip.regs + ctrl_offset); -} - -static int sirfsoc_gpio_request(struct gpio_chip *chip, unsigned offset) -{ - struct sirfsoc_gpio_chip *sgpio = gpiochip_get_data(chip); - struct sirfsoc_gpio_bank *bank = sirfsoc_gpio_to_bank(sgpio, offset); - unsigned long flags; - - if (pinctrl_gpio_request(chip->base + offset)) - return -ENODEV; - - spin_lock_irqsave(&bank->lock, flags); - - /* - * default status: - * set direction as input and mask irq - */ - sirfsoc_gpio_set_input(sgpio, SIRFSOC_GPIO_CTRL(bank->id, offset)); - __sirfsoc_gpio_irq_mask(sgpio, bank, offset); - - spin_unlock_irqrestore(&bank->lock, flags); - - return 0; -} - -static void sirfsoc_gpio_free(struct gpio_chip *chip, unsigned offset) -{ - struct sirfsoc_gpio_chip *sgpio = gpiochip_get_data(chip); - struct sirfsoc_gpio_bank *bank = sirfsoc_gpio_to_bank(sgpio, offset); - unsigned long flags; - - spin_lock_irqsave(&bank->lock, flags); - - __sirfsoc_gpio_irq_mask(sgpio, bank, offset); - sirfsoc_gpio_set_input(sgpio, SIRFSOC_GPIO_CTRL(bank->id, offset)); - - spin_unlock_irqrestore(&bank->lock, flags); - - pinctrl_gpio_free(chip->base + offset); -} - -static int sirfsoc_gpio_direction_input(struct gpio_chip *chip, unsigned gpio) -{ - struct sirfsoc_gpio_chip *sgpio = gpiochip_get_data(chip); - struct sirfsoc_gpio_bank *bank = sirfsoc_gpio_to_bank(sgpio, gpio); - int idx = sirfsoc_gpio_to_bankoff(gpio); - unsigned long flags; - unsigned offset; - - offset = SIRFSOC_GPIO_CTRL(bank->id, idx); - - spin_lock_irqsave(&bank->lock, flags); - - sirfsoc_gpio_set_input(sgpio, offset); - - spin_unlock_irqrestore(&bank->lock, flags); - - return 0; -} - -static inline void sirfsoc_gpio_set_output(struct sirfsoc_gpio_chip *sgpio, - struct sirfsoc_gpio_bank *bank, - unsigned offset, - int value) -{ - u32 out_ctrl; - unsigned long flags; - - spin_lock_irqsave(&bank->lock, flags); - - out_ctrl = readl(sgpio->chip.regs + offset); - if (value) - out_ctrl |= SIRFSOC_GPIO_CTL_DATAOUT_MASK; - else - out_ctrl &= ~SIRFSOC_GPIO_CTL_DATAOUT_MASK; - - out_ctrl &= ~SIRFSOC_GPIO_CTL_INTR_EN_MASK; - out_ctrl |= SIRFSOC_GPIO_CTL_OUT_EN_MASK; - writel(out_ctrl, sgpio->chip.regs + offset); - - spin_unlock_irqrestore(&bank->lock, flags); -} - -static int sirfsoc_gpio_direction_output(struct gpio_chip *chip, - unsigned gpio, int value) -{ - struct sirfsoc_gpio_chip *sgpio = gpiochip_get_data(chip); - struct sirfsoc_gpio_bank *bank = sirfsoc_gpio_to_bank(sgpio, gpio); - int idx = sirfsoc_gpio_to_bankoff(gpio); - u32 offset; - unsigned long flags; - - offset = SIRFSOC_GPIO_CTRL(bank->id, idx); - - spin_lock_irqsave(&sgpio->lock, flags); - - sirfsoc_gpio_set_output(sgpio, bank, offset, value); - - spin_unlock_irqrestore(&sgpio->lock, flags); - - return 0; -} - -static int sirfsoc_gpio_get_value(struct gpio_chip *chip, unsigned offset) -{ - struct sirfsoc_gpio_chip *sgpio = gpiochip_get_data(chip); - struct sirfsoc_gpio_bank *bank = sirfsoc_gpio_to_bank(sgpio, offset); - u32 val; - unsigned long flags; - - spin_lock_irqsave(&bank->lock, flags); - - val = readl(sgpio->chip.regs + SIRFSOC_GPIO_CTRL(bank->id, offset)); - - spin_unlock_irqrestore(&bank->lock, flags); - - return !!(val & SIRFSOC_GPIO_CTL_DATAIN_MASK); -} - -static void sirfsoc_gpio_set_value(struct gpio_chip *chip, unsigned offset, - int value) -{ - struct sirfsoc_gpio_chip *sgpio = gpiochip_get_data(chip); - struct sirfsoc_gpio_bank *bank = sirfsoc_gpio_to_bank(sgpio, offset); - u32 ctrl; - unsigned long flags; - - spin_lock_irqsave(&bank->lock, flags); - - ctrl = readl(sgpio->chip.regs + SIRFSOC_GPIO_CTRL(bank->id, offset)); - if (value) - ctrl |= SIRFSOC_GPIO_CTL_DATAOUT_MASK; - else - ctrl &= ~SIRFSOC_GPIO_CTL_DATAOUT_MASK; - writel(ctrl, sgpio->chip.regs + SIRFSOC_GPIO_CTRL(bank->id, offset)); - - spin_unlock_irqrestore(&bank->lock, flags); -} - -static void sirfsoc_gpio_set_pullup(struct sirfsoc_gpio_chip *sgpio, - const u32 *pullups) -{ - int i, n; - const unsigned long *p = (const unsigned long *)pullups; - - for (i = 0; i < SIRFSOC_GPIO_NO_OF_BANKS; i++) { - for_each_set_bit(n, p + i, BITS_PER_LONG) { - u32 offset = SIRFSOC_GPIO_CTRL(i, n); - u32 val = readl(sgpio->chip.regs + offset); - val |= SIRFSOC_GPIO_CTL_PULL_MASK; - val |= SIRFSOC_GPIO_CTL_PULL_HIGH; - writel(val, sgpio->chip.regs + offset); - } - } -} - -static void sirfsoc_gpio_set_pulldown(struct sirfsoc_gpio_chip *sgpio, - const u32 *pulldowns) -{ - int i, n; - const unsigned long *p = (const unsigned long *)pulldowns; - - for (i = 0; i < SIRFSOC_GPIO_NO_OF_BANKS; i++) { - for_each_set_bit(n, p + i, BITS_PER_LONG) { - u32 offset = SIRFSOC_GPIO_CTRL(i, n); - u32 val = readl(sgpio->chip.regs + offset); - val |= SIRFSOC_GPIO_CTL_PULL_MASK; - val &= ~SIRFSOC_GPIO_CTL_PULL_HIGH; - writel(val, sgpio->chip.regs + offset); - } - } -} - -static int sirfsoc_gpio_probe(struct device_node *np) -{ - int i, err = 0; - struct sirfsoc_gpio_chip *sgpio; - struct sirfsoc_gpio_bank *bank; - void __iomem *regs; - struct platform_device *pdev; - struct gpio_irq_chip *girq; - - u32 pullups[SIRFSOC_GPIO_NO_OF_BANKS], pulldowns[SIRFSOC_GPIO_NO_OF_BANKS]; - - pdev = of_find_device_by_node(np); - if (!pdev) - return -ENODEV; - - sgpio = devm_kzalloc(&pdev->dev, sizeof(*sgpio), GFP_KERNEL); - if (!sgpio) { - err = -ENOMEM; - goto out_put_device; - } - spin_lock_init(&sgpio->lock); - - regs = of_iomap(np, 0); - if (!regs) { - err = -ENOMEM; - goto out_put_device; - } - - sgpio->chip.gc.request = sirfsoc_gpio_request; - sgpio->chip.gc.free = sirfsoc_gpio_free; - sgpio->chip.gc.direction_input = sirfsoc_gpio_direction_input; - sgpio->chip.gc.get = sirfsoc_gpio_get_value; - sgpio->chip.gc.direction_output = sirfsoc_gpio_direction_output; - sgpio->chip.gc.set = sirfsoc_gpio_set_value; - sgpio->chip.gc.base = 0; - sgpio->chip.gc.ngpio = SIRFSOC_GPIO_BANK_SIZE * SIRFSOC_GPIO_NO_OF_BANKS; - sgpio->chip.gc.label = kasprintf(GFP_KERNEL, "%pOF", np); - sgpio->chip.gc.of_node = np; - sgpio->chip.gc.of_xlate = sirfsoc_gpio_of_xlate; - sgpio->chip.gc.of_gpio_n_cells = 2; - sgpio->chip.gc.parent = &pdev->dev; - sgpio->chip.regs = regs; - - girq = &sgpio->chip.gc.irq; - girq->chip = &sirfsoc_irq_chip; - girq->parent_handler = sirfsoc_gpio_handle_irq; - girq->num_parents = SIRFSOC_GPIO_NO_OF_BANKS; - girq->parents = devm_kcalloc(&pdev->dev, SIRFSOC_GPIO_NO_OF_BANKS, - sizeof(*girq->parents), - GFP_KERNEL); - if (!girq->parents) { - err = -ENOMEM; - goto out_put_device; - } - for (i = 0; i < SIRFSOC_GPIO_NO_OF_BANKS; i++) { - bank = &sgpio->sgpio_bank[i]; - spin_lock_init(&bank->lock); - bank->parent_irq = platform_get_irq(pdev, i); - if (bank->parent_irq < 0) { - err = bank->parent_irq; - goto out; - } - girq->parents[i] = bank->parent_irq; - } - girq->default_type = IRQ_TYPE_NONE; - girq->handler = handle_level_irq; - - err = gpiochip_add_data(&sgpio->chip.gc, sgpio); - if (err) { - dev_err(&pdev->dev, "%pOF: error in probe function with status %d\n", - np, err); - goto out; - } - - err = gpiochip_add_pin_range(&sgpio->chip.gc, dev_name(&pdev->dev), - 0, 0, SIRFSOC_GPIO_BANK_SIZE * SIRFSOC_GPIO_NO_OF_BANKS); - if (err) { - dev_err(&pdev->dev, - "could not add gpiochip pin range\n"); - goto out_no_range; - } - - if (!of_property_read_u32_array(np, "sirf,pullups", pullups, - SIRFSOC_GPIO_NO_OF_BANKS)) - sirfsoc_gpio_set_pullup(sgpio, pullups); - - if (!of_property_read_u32_array(np, "sirf,pulldowns", pulldowns, - SIRFSOC_GPIO_NO_OF_BANKS)) - sirfsoc_gpio_set_pulldown(sgpio, pulldowns); - - return 0; - -out_no_range: - gpiochip_remove(&sgpio->chip.gc); -out: - iounmap(regs); -out_put_device: - put_device(&pdev->dev); - return err; -} - -static int __init sirfsoc_gpio_init(void) -{ - - struct device_node *np; - - np = of_find_matching_node(NULL, pinmux_ids); - - if (!np) - return -ENODEV; - - return sirfsoc_gpio_probe(np); -} -subsys_initcall(sirfsoc_gpio_init); diff --git a/drivers/pinctrl/sirf/pinctrl-sirf.h b/drivers/pinctrl/sirf/pinctrl-sirf.h deleted file mode 100644 index d7125b8773cc..000000000000 --- a/drivers/pinctrl/sirf/pinctrl-sirf.h +++ /dev/null @@ -1,116 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-or-later */ -/* - * pinmux driver shared headfile for CSR SiRFsoc - * - * Copyright (c) 2011 Cambridge Silicon Radio Limited, a CSR plc group company. - */ - -#ifndef __PINMUX_SIRF_H__ -#define __PINMUX_SIRF_H__ - -#define SIRFSOC_NUM_PADS 622 -#define SIRFSOC_RSC_USB_UART_SHARE 0 -#define SIRFSOC_RSC_PIN_MUX 0x4 - -#define SIRFSOC_GPIO_PAD_EN(g) ((g)*0x100 + 0x84) -#define SIRFSOC_GPIO_PAD_EN_CLR(g) ((g)*0x100 + 0x90) -#define SIRFSOC_GPIO_CTRL(g, i) ((g)*0x100 + (i)*4) -#define SIRFSOC_GPIO_DSP_EN0 (0x80) -#define SIRFSOC_GPIO_INT_STATUS(g) ((g)*0x100 + 0x8C) - -#define SIRFSOC_GPIO_CTL_INTR_LOW_MASK 0x1 -#define SIRFSOC_GPIO_CTL_INTR_HIGH_MASK 0x2 -#define SIRFSOC_GPIO_CTL_INTR_TYPE_MASK 0x4 -#define SIRFSOC_GPIO_CTL_INTR_EN_MASK 0x8 -#define SIRFSOC_GPIO_CTL_INTR_STS_MASK 0x10 -#define SIRFSOC_GPIO_CTL_OUT_EN_MASK 0x20 -#define SIRFSOC_GPIO_CTL_DATAOUT_MASK 0x40 -#define SIRFSOC_GPIO_CTL_DATAIN_MASK 0x80 -#define SIRFSOC_GPIO_CTL_PULL_MASK 0x100 -#define SIRFSOC_GPIO_CTL_PULL_HIGH 0x200 -#define SIRFSOC_GPIO_CTL_DSP_INT 0x400 - -#define SIRFSOC_GPIO_NO_OF_BANKS 5 -#define SIRFSOC_GPIO_BANK_SIZE 32 -#define SIRFSOC_GPIO_NUM(bank, index) (((bank)*(32)) + (index)) - -/** - * @dev: a pointer back to containing device - * @virtbase: the offset to the controller in virtual memory - */ -struct sirfsoc_pmx { - struct device *dev; - struct pinctrl_dev *pmx; - void __iomem *gpio_virtbase; - void __iomem *rsc_virtbase; - u32 gpio_regs[SIRFSOC_GPIO_NO_OF_BANKS][SIRFSOC_GPIO_BANK_SIZE]; - u32 ints_regs[SIRFSOC_GPIO_NO_OF_BANKS]; - u32 paden_regs[SIRFSOC_GPIO_NO_OF_BANKS]; - u32 dspen_regs; - u32 rsc_regs[3]; -}; - -/* SIRFSOC_GPIO_PAD_EN set */ -struct sirfsoc_muxmask { - unsigned long group; - unsigned long mask; -}; - -struct sirfsoc_padmux { - unsigned long muxmask_counts; - const struct sirfsoc_muxmask *muxmask; - /* RSC_PIN_MUX set */ - unsigned long ctrlreg; - unsigned long funcmask; - unsigned long funcval; -}; - - /** - * struct sirfsoc_pin_group - describes a SiRFprimaII pin group - * @name: the name of this specific pin group - * @pins: an array of discrete physical pins used in this group, taken - * from the driver-local pin enumeration space - * @num_pins: the number of pins in this group array, i.e. the number of - * elements in .pins so we can iterate over that array - */ -struct sirfsoc_pin_group { - const char *name; - const unsigned int *pins; - const unsigned num_pins; -}; - -#define SIRFSOC_PIN_GROUP(n, p) \ - { \ - .name = n, \ - .pins = p, \ - .num_pins = ARRAY_SIZE(p), \ - } - -struct sirfsoc_pmx_func { - const char *name; - const char * const *groups; - const unsigned num_groups; - const struct sirfsoc_padmux *padmux; -}; - -#define SIRFSOC_PMX_FUNCTION(n, g, m) \ - { \ - .name = n, \ - .groups = g, \ - .num_groups = ARRAY_SIZE(g), \ - .padmux = &m, \ - } - -struct sirfsoc_pinctrl_data { - struct pinctrl_pin_desc *pads; - int pads_cnt; - struct sirfsoc_pin_group *grps; - int grps_cnt; - struct sirfsoc_pmx_func *funcs; - int funcs_cnt; -}; - -extern struct sirfsoc_pinctrl_data prima2_pinctrl_data; -extern struct sirfsoc_pinctrl_data atlas6_pinctrl_data; - -#endif -- cgit v1.2.3 From 5817364a90c944cbe72c657e53495d41868013f4 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Wed, 20 Jan 2021 14:20:44 +0100 Subject: pinctrl: remove coh901 driver The ST-Ericsson U300 platform is getting removed, so this driver is no longer needed. Cc: Linus Walleij Signed-off-by: Arnd Bergmann Link: https://lore.kernel.org/r/20210120132045.2127659-5-arnd@kernel.org Signed-off-by: Linus Walleij --- .../bindings/gpio/gpio-stericsson-coh901.txt | 7 - drivers/pinctrl/Kconfig | 10 - drivers/pinctrl/Makefile | 1 - drivers/pinctrl/pinctrl-coh901.c | 774 --------------------- drivers/pinctrl/pinctrl-coh901.h | 6 - 5 files changed, 798 deletions(-) delete mode 100644 Documentation/devicetree/bindings/gpio/gpio-stericsson-coh901.txt delete mode 100644 drivers/pinctrl/pinctrl-coh901.c delete mode 100644 drivers/pinctrl/pinctrl-coh901.h (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/gpio/gpio-stericsson-coh901.txt b/Documentation/devicetree/bindings/gpio/gpio-stericsson-coh901.txt deleted file mode 100644 index fd665b44d767..000000000000 --- a/Documentation/devicetree/bindings/gpio/gpio-stericsson-coh901.txt +++ /dev/null @@ -1,7 +0,0 @@ -ST-Ericsson COH 901 571/3 GPIO controller - -Required properties: -- compatible: Compatible property value should be "stericsson,gpio-coh901" -- reg: Physical base address of the controller and length of memory mapped - region. -- interrupts: the 0...n interrupts assigned to the different GPIO ports/banks. diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig index e176137dbf29..9ddbf14d9536 100644 --- a/drivers/pinctrl/Kconfig +++ b/drivers/pinctrl/Kconfig @@ -277,16 +277,6 @@ config PINCTRL_U300 select PINMUX select GENERIC_PINCONF -config PINCTRL_COH901 - bool "ST-Ericsson U300 COH 901 335/571 GPIO" - depends on GPIOLIB && ARCH_U300 && PINCTRL_U300 - select GPIOLIB_IRQCHIP - help - Say yes here to support GPIO interface on ST-Ericsson U300. - The names of the two IP block variants supported are - COH 901 335 and COH 901 571/3. They contain 3, 5 or 7 - ports of 8 GPIO pins each. - config PINCTRL_MAX77620 tristate "MAX77620/MAX20024 Pincontrol support" depends on MFD_MAX77620 && OF diff --git a/drivers/pinctrl/Makefile b/drivers/pinctrl/Makefile index f414846abe2d..10643440b467 100644 --- a/drivers/pinctrl/Makefile +++ b/drivers/pinctrl/Makefile @@ -34,7 +34,6 @@ obj-$(CONFIG_PINCTRL_SINGLE) += pinctrl-single.o obj-$(CONFIG_PINCTRL_SX150X) += pinctrl-sx150x.o obj-$(CONFIG_ARCH_TEGRA) += tegra/ obj-$(CONFIG_PINCTRL_U300) += pinctrl-u300.o -obj-$(CONFIG_PINCTRL_COH901) += pinctrl-coh901.o obj-$(CONFIG_PINCTRL_XWAY) += pinctrl-xway.o obj-$(CONFIG_PINCTRL_LANTIQ) += pinctrl-lantiq.o obj-$(CONFIG_PINCTRL_LPC18XX) += pinctrl-lpc18xx.o diff --git a/drivers/pinctrl/pinctrl-coh901.c b/drivers/pinctrl/pinctrl-coh901.c deleted file mode 100644 index 2905348ff430..000000000000 --- a/drivers/pinctrl/pinctrl-coh901.c +++ /dev/null @@ -1,774 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * U300 GPIO module. - * - * Copyright (C) 2007-2012 ST-Ericsson AB - * COH 901 571/3 - Used in DB3210 (U365 2.0) and DB3350 (U335 1.0) - * Author: Linus Walleij - * Author: Jonas Aaberg - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "pinctrl-coh901.h" - -#define U300_GPIO_PORT_STRIDE (0x30) -/* - * Control Register 32bit (R/W) - * bit 15-9 (mask 0x0000FE00) contains the number of cores. 8*cores - * gives the number of GPIO pins. - * bit 8-2 (mask 0x000001FC) contains the core version ID. - */ -#define U300_GPIO_CR (0x00) -#define U300_GPIO_CR_SYNC_SEL_ENABLE (0x00000002UL) -#define U300_GPIO_CR_BLOCK_CLKRQ_ENABLE (0x00000001UL) -#define U300_GPIO_PXPDIR (0x04) -#define U300_GPIO_PXPDOR (0x08) -#define U300_GPIO_PXPCR (0x0C) -#define U300_GPIO_PXPCR_ALL_PINS_MODE_MASK (0x0000FFFFUL) -#define U300_GPIO_PXPCR_PIN_MODE_MASK (0x00000003UL) -#define U300_GPIO_PXPCR_PIN_MODE_SHIFT (0x00000002UL) -#define U300_GPIO_PXPCR_PIN_MODE_INPUT (0x00000000UL) -#define U300_GPIO_PXPCR_PIN_MODE_OUTPUT_PUSH_PULL (0x00000001UL) -#define U300_GPIO_PXPCR_PIN_MODE_OUTPUT_OPEN_DRAIN (0x00000002UL) -#define U300_GPIO_PXPCR_PIN_MODE_OUTPUT_OPEN_SOURCE (0x00000003UL) -#define U300_GPIO_PXPER (0x10) -#define U300_GPIO_PXPER_ALL_PULL_UP_DISABLE_MASK (0x000000FFUL) -#define U300_GPIO_PXPER_PULL_UP_DISABLE (0x00000001UL) -#define U300_GPIO_PXIEV (0x14) -#define U300_GPIO_PXIEN (0x18) -#define U300_GPIO_PXIFR (0x1C) -#define U300_GPIO_PXICR (0x20) -#define U300_GPIO_PXICR_ALL_IRQ_CONFIG_MASK (0x000000FFUL) -#define U300_GPIO_PXICR_IRQ_CONFIG_MASK (0x00000001UL) -#define U300_GPIO_PXICR_IRQ_CONFIG_FALLING_EDGE (0x00000000UL) -#define U300_GPIO_PXICR_IRQ_CONFIG_RISING_EDGE (0x00000001UL) - -/* 8 bits per port, no version has more than 7 ports */ -#define U300_GPIO_NUM_PORTS 7 -#define U300_GPIO_PINS_PER_PORT 8 -#define U300_GPIO_MAX (U300_GPIO_PINS_PER_PORT * U300_GPIO_NUM_PORTS) - -struct u300_gpio_port { - struct u300_gpio *gpio; - char name[8]; - int irq; - int number; - u8 toggle_edge_mode; -}; - -struct u300_gpio { - struct gpio_chip chip; - struct u300_gpio_port ports[U300_GPIO_NUM_PORTS]; - struct clk *clk; - void __iomem *base; - struct device *dev; - u32 stride; - /* Register offsets */ - u32 pcr; - u32 dor; - u32 dir; - u32 per; - u32 icr; - u32 ien; - u32 iev; -}; - -/* - * Macro to expand to read a specific register found in the "gpio" - * struct. It requires the struct u300_gpio *gpio variable to exist in - * its context. It calculates the port offset from the given pin - * offset, muliplies by the port stride and adds the register offset - * so it provides a pointer to the desired register. - */ -#define U300_PIN_REG(pin, reg) \ - (gpio->base + (pin >> 3) * gpio->stride + gpio->reg) - -/* - * Provides a bitmask for a specific gpio pin inside an 8-bit GPIO - * register. - */ -#define U300_PIN_BIT(pin) \ - (1 << (pin & 0x07)) - -struct u300_gpio_confdata { - u16 bias_mode; - bool output; - int outval; -}; - -#define U300_FLOATING_INPUT { \ - .bias_mode = PIN_CONFIG_BIAS_HIGH_IMPEDANCE, \ - .output = false, \ -} - -#define U300_PULL_UP_INPUT { \ - .bias_mode = PIN_CONFIG_BIAS_PULL_UP, \ - .output = false, \ -} - -#define U300_OUTPUT_LOW { \ - .output = true, \ - .outval = 0, \ -} - -#define U300_OUTPUT_HIGH { \ - .output = true, \ - .outval = 1, \ -} - -/* Initial configuration */ -static const struct u300_gpio_confdata __initconst -bs335_gpio_config[U300_GPIO_NUM_PORTS][U300_GPIO_PINS_PER_PORT] = { - /* Port 0, pins 0-7 */ - { - U300_FLOATING_INPUT, - U300_OUTPUT_HIGH, - U300_FLOATING_INPUT, - U300_OUTPUT_LOW, - U300_OUTPUT_LOW, - U300_OUTPUT_LOW, - U300_OUTPUT_LOW, - U300_OUTPUT_LOW, - }, - /* Port 1, pins 0-7 */ - { - U300_OUTPUT_LOW, - U300_OUTPUT_LOW, - U300_OUTPUT_LOW, - U300_PULL_UP_INPUT, - U300_FLOATING_INPUT, - U300_OUTPUT_HIGH, - U300_OUTPUT_LOW, - U300_OUTPUT_LOW, - }, - /* Port 2, pins 0-7 */ - { - U300_FLOATING_INPUT, - U300_FLOATING_INPUT, - U300_FLOATING_INPUT, - U300_FLOATING_INPUT, - U300_OUTPUT_LOW, - U300_PULL_UP_INPUT, - U300_OUTPUT_LOW, - U300_PULL_UP_INPUT, - }, - /* Port 3, pins 0-7 */ - { - U300_PULL_UP_INPUT, - U300_OUTPUT_LOW, - U300_FLOATING_INPUT, - U300_FLOATING_INPUT, - U300_FLOATING_INPUT, - U300_FLOATING_INPUT, - U300_FLOATING_INPUT, - U300_FLOATING_INPUT, - }, - /* Port 4, pins 0-7 */ - { - U300_FLOATING_INPUT, - U300_FLOATING_INPUT, - U300_FLOATING_INPUT, - U300_FLOATING_INPUT, - U300_FLOATING_INPUT, - U300_FLOATING_INPUT, - U300_FLOATING_INPUT, - U300_FLOATING_INPUT, - }, - /* Port 5, pins 0-7 */ - { - U300_FLOATING_INPUT, - U300_FLOATING_INPUT, - U300_FLOATING_INPUT, - U300_FLOATING_INPUT, - U300_FLOATING_INPUT, - U300_FLOATING_INPUT, - U300_FLOATING_INPUT, - U300_FLOATING_INPUT, - }, - /* Port 6, pind 0-7 */ - { - U300_FLOATING_INPUT, - U300_FLOATING_INPUT, - U300_FLOATING_INPUT, - U300_FLOATING_INPUT, - U300_FLOATING_INPUT, - U300_FLOATING_INPUT, - U300_FLOATING_INPUT, - U300_FLOATING_INPUT, - } -}; - -static int u300_gpio_get(struct gpio_chip *chip, unsigned offset) -{ - struct u300_gpio *gpio = gpiochip_get_data(chip); - - return !!(readl(U300_PIN_REG(offset, dir)) & U300_PIN_BIT(offset)); -} - -static void u300_gpio_set(struct gpio_chip *chip, unsigned offset, int value) -{ - struct u300_gpio *gpio = gpiochip_get_data(chip); - unsigned long flags; - u32 val; - - local_irq_save(flags); - - val = readl(U300_PIN_REG(offset, dor)); - if (value) - writel(val | U300_PIN_BIT(offset), U300_PIN_REG(offset, dor)); - else - writel(val & ~U300_PIN_BIT(offset), U300_PIN_REG(offset, dor)); - - local_irq_restore(flags); -} - -static int u300_gpio_direction_input(struct gpio_chip *chip, unsigned offset) -{ - struct u300_gpio *gpio = gpiochip_get_data(chip); - unsigned long flags; - u32 val; - - local_irq_save(flags); - val = readl(U300_PIN_REG(offset, pcr)); - /* Mask out this pin, note 2 bits per setting */ - val &= ~(U300_GPIO_PXPCR_PIN_MODE_MASK << ((offset & 0x07) << 1)); - writel(val, U300_PIN_REG(offset, pcr)); - local_irq_restore(flags); - return 0; -} - -static int u300_gpio_direction_output(struct gpio_chip *chip, unsigned offset, - int value) -{ - struct u300_gpio *gpio = gpiochip_get_data(chip); - unsigned long flags; - u32 oldmode; - u32 val; - - local_irq_save(flags); - val = readl(U300_PIN_REG(offset, pcr)); - /* - * Drive mode must be set by the special mode set function, set - * push/pull mode by default if no mode has been selected. - */ - oldmode = val & (U300_GPIO_PXPCR_PIN_MODE_MASK << - ((offset & 0x07) << 1)); - /* mode = 0 means input, else some mode is already set */ - if (oldmode == 0) { - val &= ~(U300_GPIO_PXPCR_PIN_MODE_MASK << - ((offset & 0x07) << 1)); - val |= (U300_GPIO_PXPCR_PIN_MODE_OUTPUT_PUSH_PULL - << ((offset & 0x07) << 1)); - writel(val, U300_PIN_REG(offset, pcr)); - } - u300_gpio_set(chip, offset, value); - local_irq_restore(flags); - return 0; -} - -/* Returning -EINVAL means "supported but not available" */ -int u300_gpio_config_get(struct gpio_chip *chip, - unsigned offset, - unsigned long *config) -{ - struct u300_gpio *gpio = gpiochip_get_data(chip); - enum pin_config_param param = (enum pin_config_param) *config; - bool biasmode; - u32 drmode; - - /* One bit per pin, clamp to bool range */ - biasmode = !!(readl(U300_PIN_REG(offset, per)) & U300_PIN_BIT(offset)); - - /* Mask out the two bits for this pin and shift to bits 0,1 */ - drmode = readl(U300_PIN_REG(offset, pcr)); - drmode &= (U300_GPIO_PXPCR_PIN_MODE_MASK << ((offset & 0x07) << 1)); - drmode >>= ((offset & 0x07) << 1); - - switch (param) { - case PIN_CONFIG_BIAS_HIGH_IMPEDANCE: - *config = 0; - if (biasmode) - return 0; - else - return -EINVAL; - break; - case PIN_CONFIG_BIAS_PULL_UP: - *config = 0; - if (!biasmode) - return 0; - else - return -EINVAL; - break; - case PIN_CONFIG_DRIVE_PUSH_PULL: - *config = 0; - if (drmode == U300_GPIO_PXPCR_PIN_MODE_OUTPUT_PUSH_PULL) - return 0; - else - return -EINVAL; - break; - case PIN_CONFIG_DRIVE_OPEN_DRAIN: - *config = 0; - if (drmode == U300_GPIO_PXPCR_PIN_MODE_OUTPUT_OPEN_DRAIN) - return 0; - else - return -EINVAL; - break; - case PIN_CONFIG_DRIVE_OPEN_SOURCE: - *config = 0; - if (drmode == U300_GPIO_PXPCR_PIN_MODE_OUTPUT_OPEN_SOURCE) - return 0; - else - return -EINVAL; - break; - default: - break; - } - return -ENOTSUPP; -} - -int u300_gpio_config_set(struct gpio_chip *chip, unsigned offset, - enum pin_config_param param) -{ - struct u300_gpio *gpio = gpiochip_get_data(chip); - unsigned long flags; - u32 val; - - local_irq_save(flags); - switch (param) { - case PIN_CONFIG_BIAS_DISABLE: - case PIN_CONFIG_BIAS_HIGH_IMPEDANCE: - val = readl(U300_PIN_REG(offset, per)); - writel(val | U300_PIN_BIT(offset), U300_PIN_REG(offset, per)); - break; - case PIN_CONFIG_BIAS_PULL_UP: - val = readl(U300_PIN_REG(offset, per)); - writel(val & ~U300_PIN_BIT(offset), U300_PIN_REG(offset, per)); - break; - case PIN_CONFIG_DRIVE_PUSH_PULL: - val = readl(U300_PIN_REG(offset, pcr)); - val &= ~(U300_GPIO_PXPCR_PIN_MODE_MASK - << ((offset & 0x07) << 1)); - val |= (U300_GPIO_PXPCR_PIN_MODE_OUTPUT_PUSH_PULL - << ((offset & 0x07) << 1)); - writel(val, U300_PIN_REG(offset, pcr)); - break; - case PIN_CONFIG_DRIVE_OPEN_DRAIN: - val = readl(U300_PIN_REG(offset, pcr)); - val &= ~(U300_GPIO_PXPCR_PIN_MODE_MASK - << ((offset & 0x07) << 1)); - val |= (U300_GPIO_PXPCR_PIN_MODE_OUTPUT_OPEN_DRAIN - << ((offset & 0x07) << 1)); - writel(val, U300_PIN_REG(offset, pcr)); - break; - case PIN_CONFIG_DRIVE_OPEN_SOURCE: - val = readl(U300_PIN_REG(offset, pcr)); - val &= ~(U300_GPIO_PXPCR_PIN_MODE_MASK - << ((offset & 0x07) << 1)); - val |= (U300_GPIO_PXPCR_PIN_MODE_OUTPUT_OPEN_SOURCE - << ((offset & 0x07) << 1)); - writel(val, U300_PIN_REG(offset, pcr)); - break; - default: - local_irq_restore(flags); - dev_err(gpio->dev, "illegal configuration requested\n"); - return -EINVAL; - } - local_irq_restore(flags); - return 0; -} - -static const struct gpio_chip u300_gpio_chip = { - .label = "u300-gpio-chip", - .owner = THIS_MODULE, - .request = gpiochip_generic_request, - .free = gpiochip_generic_free, - .get = u300_gpio_get, - .set = u300_gpio_set, - .direction_input = u300_gpio_direction_input, - .direction_output = u300_gpio_direction_output, -}; - -static void u300_toggle_trigger(struct u300_gpio *gpio, unsigned offset) -{ - u32 val; - - val = readl(U300_PIN_REG(offset, icr)); - /* Set mode depending on state */ - if (u300_gpio_get(&gpio->chip, offset)) { - /* High now, let's trigger on falling edge next then */ - writel(val & ~U300_PIN_BIT(offset), U300_PIN_REG(offset, icr)); - dev_dbg(gpio->dev, "next IRQ on falling edge on pin %d\n", - offset); - } else { - /* Low now, let's trigger on rising edge next then */ - writel(val | U300_PIN_BIT(offset), U300_PIN_REG(offset, icr)); - dev_dbg(gpio->dev, "next IRQ on rising edge on pin %d\n", - offset); - } -} - -static int u300_gpio_irq_type(struct irq_data *d, unsigned trigger) -{ - struct gpio_chip *chip = irq_data_get_irq_chip_data(d); - struct u300_gpio *gpio = gpiochip_get_data(chip); - struct u300_gpio_port *port = &gpio->ports[d->hwirq >> 3]; - int offset = d->hwirq; - u32 val; - - if ((trigger & IRQF_TRIGGER_RISING) && - (trigger & IRQF_TRIGGER_FALLING)) { - /* - * The GPIO block can only trigger on falling OR rising edges, - * not both. So we need to toggle the mode whenever the pin - * goes from one state to the other with a special state flag - */ - dev_dbg(gpio->dev, - "trigger on both rising and falling edge on pin %d\n", - offset); - port->toggle_edge_mode |= U300_PIN_BIT(offset); - u300_toggle_trigger(gpio, offset); - } else if (trigger & IRQF_TRIGGER_RISING) { - dev_dbg(gpio->dev, "trigger on rising edge on pin %d\n", - offset); - val = readl(U300_PIN_REG(offset, icr)); - writel(val | U300_PIN_BIT(offset), U300_PIN_REG(offset, icr)); - port->toggle_edge_mode &= ~U300_PIN_BIT(offset); - } else if (trigger & IRQF_TRIGGER_FALLING) { - dev_dbg(gpio->dev, "trigger on falling edge on pin %d\n", - offset); - val = readl(U300_PIN_REG(offset, icr)); - writel(val & ~U300_PIN_BIT(offset), U300_PIN_REG(offset, icr)); - port->toggle_edge_mode &= ~U300_PIN_BIT(offset); - } - - return 0; -} - -static void u300_gpio_irq_enable(struct irq_data *d) -{ - struct gpio_chip *chip = irq_data_get_irq_chip_data(d); - struct u300_gpio *gpio = gpiochip_get_data(chip); - struct u300_gpio_port *port = &gpio->ports[d->hwirq >> 3]; - int offset = d->hwirq; - u32 val; - unsigned long flags; - - dev_dbg(gpio->dev, "enable IRQ for hwirq %lu on port %s, offset %d\n", - d->hwirq, port->name, offset); - local_irq_save(flags); - val = readl(U300_PIN_REG(offset, ien)); - writel(val | U300_PIN_BIT(offset), U300_PIN_REG(offset, ien)); - local_irq_restore(flags); -} - -static void u300_gpio_irq_disable(struct irq_data *d) -{ - struct gpio_chip *chip = irq_data_get_irq_chip_data(d); - struct u300_gpio *gpio = gpiochip_get_data(chip); - int offset = d->hwirq; - u32 val; - unsigned long flags; - - local_irq_save(flags); - val = readl(U300_PIN_REG(offset, ien)); - writel(val & ~U300_PIN_BIT(offset), U300_PIN_REG(offset, ien)); - local_irq_restore(flags); -} - -static struct irq_chip u300_gpio_irqchip = { - .name = "u300-gpio-irqchip", - .irq_enable = u300_gpio_irq_enable, - .irq_disable = u300_gpio_irq_disable, - .irq_set_type = u300_gpio_irq_type, -}; - -static void u300_gpio_irq_handler(struct irq_desc *desc) -{ - unsigned int irq = irq_desc_get_irq(desc); - struct irq_chip *parent_chip = irq_desc_get_chip(desc); - struct gpio_chip *chip = irq_desc_get_handler_data(desc); - struct u300_gpio *gpio = gpiochip_get_data(chip); - struct u300_gpio_port *port = &gpio->ports[irq - chip->base]; - int pinoffset = port->number << 3; /* get the right stride */ - unsigned long val; - - chained_irq_enter(parent_chip, desc); - - /* Read event register */ - val = readl(U300_PIN_REG(pinoffset, iev)); - /* Mask relevant bits */ - val &= 0xFFU; /* 8 bits per port */ - /* ACK IRQ (clear event) */ - writel(val, U300_PIN_REG(pinoffset, iev)); - - /* Call IRQ handler */ - if (val != 0) { - int irqoffset; - - for_each_set_bit(irqoffset, &val, U300_GPIO_PINS_PER_PORT) { - int offset = pinoffset + irqoffset; - int pin_irq = irq_find_mapping(chip->irq.domain, offset); - - dev_dbg(gpio->dev, "GPIO IRQ %d on pin %d\n", - pin_irq, offset); - generic_handle_irq(pin_irq); - /* - * Triggering IRQ on both rising and falling edge - * needs mockery - */ - if (port->toggle_edge_mode & U300_PIN_BIT(offset)) - u300_toggle_trigger(gpio, offset); - } - } - - chained_irq_exit(parent_chip, desc); -} - -static void __init u300_gpio_init_pin(struct u300_gpio *gpio, - int offset, - const struct u300_gpio_confdata *conf) -{ - /* Set mode: input or output */ - if (conf->output) { - u300_gpio_direction_output(&gpio->chip, offset, conf->outval); - - /* Deactivate bias mode for output */ - u300_gpio_config_set(&gpio->chip, offset, - PIN_CONFIG_BIAS_HIGH_IMPEDANCE); - - /* Set drive mode for output */ - u300_gpio_config_set(&gpio->chip, offset, - PIN_CONFIG_DRIVE_PUSH_PULL); - - dev_dbg(gpio->dev, "set up pin %d as output, value: %d\n", - offset, conf->outval); - } else { - u300_gpio_direction_input(&gpio->chip, offset); - - /* Always set output low on input pins */ - u300_gpio_set(&gpio->chip, offset, 0); - - /* Set bias mode for input */ - u300_gpio_config_set(&gpio->chip, offset, conf->bias_mode); - - dev_dbg(gpio->dev, "set up pin %d as input, bias: %04x\n", - offset, conf->bias_mode); - } -} - -static void __init u300_gpio_init_coh901571(struct u300_gpio *gpio) -{ - int i, j; - - /* Write default config and values to all pins */ - for (i = 0; i < U300_GPIO_NUM_PORTS; i++) { - for (j = 0; j < 8; j++) { - const struct u300_gpio_confdata *conf; - int offset = (i*8) + j; - - conf = &bs335_gpio_config[i][j]; - u300_gpio_init_pin(gpio, offset, conf); - } - } -} - -/* - * Here we map a GPIO in the local gpio_chip pin space to a pin in - * the local pinctrl pin space. The pin controller used is - * pinctrl-u300. - */ -struct coh901_pinpair { - unsigned int offset; - unsigned int pin_base; -}; - -#define COH901_PINRANGE(a, b) { .offset = a, .pin_base = b } - -static struct coh901_pinpair coh901_pintable[] = { - COH901_PINRANGE(10, 426), - COH901_PINRANGE(11, 180), - COH901_PINRANGE(12, 165), /* MS/MMC card insertion */ - COH901_PINRANGE(13, 179), - COH901_PINRANGE(14, 178), - COH901_PINRANGE(16, 194), - COH901_PINRANGE(17, 193), - COH901_PINRANGE(18, 192), - COH901_PINRANGE(19, 191), - COH901_PINRANGE(20, 186), - COH901_PINRANGE(21, 185), - COH901_PINRANGE(22, 184), - COH901_PINRANGE(23, 183), - COH901_PINRANGE(24, 182), - COH901_PINRANGE(25, 181), -}; - -static int __init u300_gpio_probe(struct platform_device *pdev) -{ - struct u300_gpio *gpio; - struct gpio_irq_chip *girq; - int err = 0; - int portno; - u32 val; - u32 ifr; - int i; - - gpio = devm_kzalloc(&pdev->dev, sizeof(struct u300_gpio), GFP_KERNEL); - if (gpio == NULL) - return -ENOMEM; - - gpio->chip = u300_gpio_chip; - gpio->chip.ngpio = U300_GPIO_NUM_PORTS * U300_GPIO_PINS_PER_PORT; - gpio->chip.parent = &pdev->dev; - gpio->chip.base = 0; - gpio->dev = &pdev->dev; - - gpio->base = devm_platform_ioremap_resource(pdev, 0); - if (IS_ERR(gpio->base)) - return PTR_ERR(gpio->base); - - gpio->clk = devm_clk_get(gpio->dev, NULL); - if (IS_ERR(gpio->clk)) { - err = PTR_ERR(gpio->clk); - dev_err(gpio->dev, "could not get GPIO clock\n"); - return err; - } - - err = clk_prepare_enable(gpio->clk); - if (err) { - dev_err(gpio->dev, "could not enable GPIO clock\n"); - return err; - } - - dev_info(gpio->dev, - "initializing GPIO Controller COH 901 571/3\n"); - gpio->stride = U300_GPIO_PORT_STRIDE; - gpio->pcr = U300_GPIO_PXPCR; - gpio->dor = U300_GPIO_PXPDOR; - gpio->dir = U300_GPIO_PXPDIR; - gpio->per = U300_GPIO_PXPER; - gpio->icr = U300_GPIO_PXICR; - gpio->ien = U300_GPIO_PXIEN; - gpio->iev = U300_GPIO_PXIEV; - ifr = U300_GPIO_PXIFR; - - val = readl(gpio->base + U300_GPIO_CR); - dev_info(gpio->dev, "COH901571/3 block version: %d, " \ - "number of cores: %d totalling %d pins\n", - ((val & 0x000001FC) >> 2), - ((val & 0x0000FE00) >> 9), - ((val & 0x0000FE00) >> 9) * 8); - writel(U300_GPIO_CR_BLOCK_CLKRQ_ENABLE, - gpio->base + U300_GPIO_CR); - u300_gpio_init_coh901571(gpio); - - girq = &gpio->chip.irq; - girq->chip = &u300_gpio_irqchip; - girq->parent_handler = u300_gpio_irq_handler; - girq->num_parents = U300_GPIO_NUM_PORTS; - girq->parents = devm_kcalloc(gpio->dev, U300_GPIO_NUM_PORTS, - sizeof(*girq->parents), - GFP_KERNEL); - if (!girq->parents) { - err = -ENOMEM; - goto err_dis_clk; - } - for (portno = 0 ; portno < U300_GPIO_NUM_PORTS; portno++) { - struct u300_gpio_port *port = &gpio->ports[portno]; - - snprintf(port->name, 8, "gpio%d", portno); - port->number = portno; - port->gpio = gpio; - - port->irq = platform_get_irq(pdev, portno); - girq->parents[portno] = port->irq; - - /* Turns off irq force (test register) for this port */ - writel(0x0, gpio->base + portno * gpio->stride + ifr); - } - girq->default_type = IRQ_TYPE_EDGE_FALLING; - girq->handler = handle_simple_irq; -#ifdef CONFIG_OF_GPIO - gpio->chip.of_node = pdev->dev.of_node; -#endif - err = gpiochip_add_data(&gpio->chip, gpio); - if (err) { - dev_err(gpio->dev, "unable to add gpiochip: %d\n", err); - goto err_dis_clk; - } - - /* - * Add pinctrl pin ranges, the pin controller must be registered - * at this point - */ - for (i = 0; i < ARRAY_SIZE(coh901_pintable); i++) { - struct coh901_pinpair *p = &coh901_pintable[i]; - - err = gpiochip_add_pin_range(&gpio->chip, "pinctrl-u300", - p->offset, p->pin_base, 1); - if (err) - goto err_no_range; - } - - platform_set_drvdata(pdev, gpio); - - return 0; - -err_no_range: - gpiochip_remove(&gpio->chip); -err_dis_clk: - clk_disable_unprepare(gpio->clk); - dev_err(&pdev->dev, "module ERROR:%d\n", err); - return err; -} - -static int __exit u300_gpio_remove(struct platform_device *pdev) -{ - struct u300_gpio *gpio = platform_get_drvdata(pdev); - - /* Turn off the GPIO block */ - writel(0x00000000U, gpio->base + U300_GPIO_CR); - - gpiochip_remove(&gpio->chip); - clk_disable_unprepare(gpio->clk); - return 0; -} - -static const struct of_device_id u300_gpio_match[] = { - { .compatible = "stericsson,gpio-coh901" }, - {}, -}; - -static struct platform_driver u300_gpio_driver = { - .driver = { - .name = "u300-gpio", - .of_match_table = u300_gpio_match, - }, - .remove = __exit_p(u300_gpio_remove), -}; - -static int __init u300_gpio_init(void) -{ - return platform_driver_probe(&u300_gpio_driver, u300_gpio_probe); -} - -static void __exit u300_gpio_exit(void) -{ - platform_driver_unregister(&u300_gpio_driver); -} - -arch_initcall(u300_gpio_init); -module_exit(u300_gpio_exit); - -MODULE_AUTHOR("Linus Walleij "); -MODULE_DESCRIPTION("ST-Ericsson AB COH 901 335/COH 901 571/3 GPIO driver"); -MODULE_LICENSE("GPL"); diff --git a/drivers/pinctrl/pinctrl-coh901.h b/drivers/pinctrl/pinctrl-coh901.h deleted file mode 100644 index ba2678665168..000000000000 --- a/drivers/pinctrl/pinctrl-coh901.h +++ /dev/null @@ -1,6 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -int u300_gpio_config_get(struct gpio_chip *chip, - unsigned offset, - unsigned long *config); -int u300_gpio_config_set(struct gpio_chip *chip, unsigned offset, - enum pin_config_param param); -- cgit v1.2.3 From 139bc8a6146d92822c866cf2fd410159c56b3648 Mon Sep 17 00:00:00 2001 From: Marc Zyngier Date: Thu, 21 Jan 2021 12:08:15 +0000 Subject: KVM: Forbid the use of tagged userspace addresses for memslots The use of a tagged address could be pretty confusing for the whole memslot infrastructure as well as the MMU notifiers. Forbid it altogether, as it never quite worked the first place. Cc: stable@vger.kernel.org Reported-by: Rick Edgecombe Reviewed-by: Catalin Marinas Signed-off-by: Marc Zyngier --- Documentation/virt/kvm/api.rst | 3 +++ virt/kvm/kvm_main.c | 1 + 2 files changed, 4 insertions(+) (limited to 'Documentation') diff --git a/Documentation/virt/kvm/api.rst b/Documentation/virt/kvm/api.rst index 4e5316ed10e9..c347b7083abf 100644 --- a/Documentation/virt/kvm/api.rst +++ b/Documentation/virt/kvm/api.rst @@ -1269,6 +1269,9 @@ field userspace_addr, which must point at user addressable memory for the entire memory slot size. Any object may back this memory, including anonymous memory, ordinary files, and hugetlbfs. +On architectures that support a form of address tagging, userspace_addr must +be an untagged address. + It is recommended that the lower 21 bits of guest_phys_addr and userspace_addr be identical. This allows large pages in the guest to be backed by large pages in the host. diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c index 2541a17ff1c4..a9abaf5f8e53 100644 --- a/virt/kvm/kvm_main.c +++ b/virt/kvm/kvm_main.c @@ -1290,6 +1290,7 @@ int __kvm_set_memory_region(struct kvm *kvm, return -EINVAL; /* We can read the guest memory with __xxx_user() later on. */ if ((mem->userspace_addr & (PAGE_SIZE - 1)) || + (mem->userspace_addr != untagged_addr(mem->userspace_addr)) || !access_ok((void __user *)(unsigned long)mem->userspace_addr, mem->memory_size)) return -EINVAL; -- cgit v1.2.3 From 8fe62e0c0e2efa5437f3ee81b65d69e70a45ecd2 Mon Sep 17 00:00:00 2001 From: Gabriel Krisman Bertazi Date: Tue, 24 Nov 2020 15:28:02 -0500 Subject: watch_queue: Drop references to /dev/watch_queue The merged API doesn't use a watch_queue device, but instead relies on pipes, so let the documentation reflect that. Fixes: f7e47677e39a ("watch_queue: Add a key/keyring notification facility") Signed-off-by: Gabriel Krisman Bertazi Signed-off-by: David Howells Acked-by: Jarkko Sakkinen Reviewed-by: Ben Boeckel --- Documentation/security/keys/core.rst | 4 ++-- samples/Kconfig | 2 +- samples/watch_queue/watch_test.c | 2 +- security/keys/Kconfig | 8 ++++---- 4 files changed, 8 insertions(+), 8 deletions(-) (limited to 'Documentation') diff --git a/Documentation/security/keys/core.rst b/Documentation/security/keys/core.rst index aa0081685ee1..b3ed5c581034 100644 --- a/Documentation/security/keys/core.rst +++ b/Documentation/security/keys/core.rst @@ -1040,8 +1040,8 @@ The keyctl syscall functions are: "key" is the ID of the key to be watched. - "queue_fd" is a file descriptor referring to an open "/dev/watch_queue" - which manages the buffer into which notifications will be delivered. + "queue_fd" is a file descriptor referring to an open pipe which + manages the buffer into which notifications will be delivered. "filter" is either NULL to remove a watch or a filter specification to indicate what events are required from the key. diff --git a/samples/Kconfig b/samples/Kconfig index 0ed6e4d71d87..e76cdfc50e25 100644 --- a/samples/Kconfig +++ b/samples/Kconfig @@ -210,7 +210,7 @@ config SAMPLE_WATCHDOG depends on CC_CAN_LINK config SAMPLE_WATCH_QUEUE - bool "Build example /dev/watch_queue notification consumer" + bool "Build example watch_queue notification API consumer" depends on CC_CAN_LINK && HEADERS_INSTALL help Build example userspace program to use the new mount_notify(), diff --git a/samples/watch_queue/watch_test.c b/samples/watch_queue/watch_test.c index 46e618a897fe..8c6cb57d5cfc 100644 --- a/samples/watch_queue/watch_test.c +++ b/samples/watch_queue/watch_test.c @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GPL-2.0 -/* Use /dev/watch_queue to watch for notifications. +/* Use watch_queue API to watch for notifications. * * Copyright (C) 2020 Red Hat, Inc. All Rights Reserved. * Written by David Howells (dhowells@redhat.com) diff --git a/security/keys/Kconfig b/security/keys/Kconfig index 83bc23409164..c161642a8484 100644 --- a/security/keys/Kconfig +++ b/security/keys/Kconfig @@ -119,7 +119,7 @@ config KEY_NOTIFICATIONS bool "Provide key/keyring change notifications" depends on KEYS && WATCH_QUEUE help - This option provides support for getting change notifications on keys - and keyrings on which the caller has View permission. This makes use - of the /dev/watch_queue misc device to handle the notification - buffer and provides KEYCTL_WATCH_KEY to enable/disable watches. + This option provides support for getting change notifications + on keys and keyrings on which the caller has View permission. + This makes use of pipes to handle the notification buffer and + provides KEYCTL_WATCH_KEY to enable/disable watches. -- cgit v1.2.3 From 181997b4940880b6ebc317b34dca38a17f107318 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Wed, 20 Jan 2021 17:14:00 +0100 Subject: spi: remove sirf prima/atlas driver The CSR SiRF prima2/atlas platforms are getting removed, so this driver is no longer needed. Cc: Barry Song Signed-off-by: Arnd Bergmann Acked-by: Barry Song Link: https://lore.kernel.org/r/20210120161658.3820610-1-arnd@kernel.org Signed-off-by: Mark Brown --- Documentation/devicetree/bindings/spi/spi-sirf.txt | 42 - drivers/spi/Kconfig | 7 - drivers/spi/Makefile | 1 - drivers/spi/spi-sirf.c | 1236 -------------------- 4 files changed, 1286 deletions(-) delete mode 100644 Documentation/devicetree/bindings/spi/spi-sirf.txt delete mode 100644 drivers/spi/spi-sirf.c (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/spi/spi-sirf.txt b/Documentation/devicetree/bindings/spi/spi-sirf.txt deleted file mode 100644 index ddd78ff68fae..000000000000 --- a/Documentation/devicetree/bindings/spi/spi-sirf.txt +++ /dev/null @@ -1,42 +0,0 @@ -* CSR SiRFprimaII Serial Peripheral Interface - -Required properties: -- compatible : Should be "sirf,prima2-spi", "sirf,prima2-usp" - or "sirf,atlas7-usp" -- reg : Offset and length of the register set for the device -- interrupts : Should contain SPI interrupt -- resets: phandle to the reset controller asserting this device in - reset - See ../reset/reset.txt for details. -- dmas : Must contain an entry for each entry in clock-names. - See ../dma/dma.txt for details. -- dma-names : Must include the following entries: - - rx - - tx -- clocks : Must contain an entry for each entry in clock-names. - See ../clocks/clock-bindings.txt for details. - -- #address-cells: Number of cells required to define a chip select - address on the SPI bus. Should be set to 1. -- #size-cells: Should be zero. - -Optional properties: -- spi-max-frequency: Specifies maximum SPI clock frequency, - Units - Hz. Definition as per - Documentation/devicetree/bindings/spi/spi-bus.txt -- cs-gpios: should specify GPIOs used for chipselects. - -Example: - -spi0: spi@b00d0000 { - compatible = "sirf,prima2-spi"; - reg = <0xb00d0000 0x10000>; - interrupts = <15>; - dmas = <&dmac1 9>, - <&dmac1 4>; - dma-names = "rx", "tx"; - #address-cells = <1>; - #size-cells = <0>; - clocks = <&clks 19>; - resets = <&rstc 26>; -}; diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig index 46ac0f467ea4..5aab7c6cc439 100644 --- a/drivers/spi/Kconfig +++ b/drivers/spi/Kconfig @@ -744,13 +744,6 @@ config SPI_SIFIVE help This exposes the SPI controller IP from SiFive. -config SPI_SIRF - tristate "CSR SiRFprimaII SPI controller" - depends on SIRF_DMA - select SPI_BITBANG - help - SPI driver for CSR SiRFprimaII SoCs - config SPI_SLAVE_MT27XX tristate "MediaTek SPI slave device" depends on ARCH_MEDIATEK || COMPILE_TEST diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile index ae1475c72979..f5e27e048d2c 100644 --- a/drivers/spi/Makefile +++ b/drivers/spi/Makefile @@ -104,7 +104,6 @@ obj-$(CONFIG_SPI_SH_HSPI) += spi-sh-hspi.o obj-$(CONFIG_SPI_SH_MSIOF) += spi-sh-msiof.o obj-$(CONFIG_SPI_SH_SCI) += spi-sh-sci.o obj-$(CONFIG_SPI_SIFIVE) += spi-sifive.o -obj-$(CONFIG_SPI_SIRF) += spi-sirf.o obj-$(CONFIG_SPI_SLAVE_MT27XX) += spi-slave-mt27xx.o obj-$(CONFIG_SPI_SPRD) += spi-sprd.o obj-$(CONFIG_SPI_SPRD_ADI) += spi-sprd-adi.o diff --git a/drivers/spi/spi-sirf.c b/drivers/spi/spi-sirf.c deleted file mode 100644 index 8419e6722e17..000000000000 --- a/drivers/spi/spi-sirf.c +++ /dev/null @@ -1,1236 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * SPI bus driver for CSR SiRFprimaII - * - * Copyright (c) 2011 Cambridge Silicon Radio Limited, a CSR plc group company. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define DRIVER_NAME "sirfsoc_spi" -/* SPI CTRL register defines */ -#define SIRFSOC_SPI_SLV_MODE BIT(16) -#define SIRFSOC_SPI_CMD_MODE BIT(17) -#define SIRFSOC_SPI_CS_IO_OUT BIT(18) -#define SIRFSOC_SPI_CS_IO_MODE BIT(19) -#define SIRFSOC_SPI_CLK_IDLE_STAT BIT(20) -#define SIRFSOC_SPI_CS_IDLE_STAT BIT(21) -#define SIRFSOC_SPI_TRAN_MSB BIT(22) -#define SIRFSOC_SPI_DRV_POS_EDGE BIT(23) -#define SIRFSOC_SPI_CS_HOLD_TIME BIT(24) -#define SIRFSOC_SPI_CLK_SAMPLE_MODE BIT(25) -#define SIRFSOC_SPI_TRAN_DAT_FORMAT_8 (0 << 26) -#define SIRFSOC_SPI_TRAN_DAT_FORMAT_12 (1 << 26) -#define SIRFSOC_SPI_TRAN_DAT_FORMAT_16 (2 << 26) -#define SIRFSOC_SPI_TRAN_DAT_FORMAT_32 (3 << 26) -#define SIRFSOC_SPI_CMD_BYTE_NUM(x) ((x & 3) << 28) -#define SIRFSOC_SPI_ENA_AUTO_CLR BIT(30) -#define SIRFSOC_SPI_MUL_DAT_MODE BIT(31) - -/* Interrupt Enable */ -#define SIRFSOC_SPI_RX_DONE_INT_EN BIT(0) -#define SIRFSOC_SPI_TX_DONE_INT_EN BIT(1) -#define SIRFSOC_SPI_RX_OFLOW_INT_EN BIT(2) -#define SIRFSOC_SPI_TX_UFLOW_INT_EN BIT(3) -#define SIRFSOC_SPI_RX_IO_DMA_INT_EN BIT(4) -#define SIRFSOC_SPI_TX_IO_DMA_INT_EN BIT(5) -#define SIRFSOC_SPI_RXFIFO_FULL_INT_EN BIT(6) -#define SIRFSOC_SPI_TXFIFO_EMPTY_INT_EN BIT(7) -#define SIRFSOC_SPI_RXFIFO_THD_INT_EN BIT(8) -#define SIRFSOC_SPI_TXFIFO_THD_INT_EN BIT(9) -#define SIRFSOC_SPI_FRM_END_INT_EN BIT(10) - -/* Interrupt status */ -#define SIRFSOC_SPI_RX_DONE BIT(0) -#define SIRFSOC_SPI_TX_DONE BIT(1) -#define SIRFSOC_SPI_RX_OFLOW BIT(2) -#define SIRFSOC_SPI_TX_UFLOW BIT(3) -#define SIRFSOC_SPI_RX_IO_DMA BIT(4) -#define SIRFSOC_SPI_RX_FIFO_FULL BIT(6) -#define SIRFSOC_SPI_TXFIFO_EMPTY BIT(7) -#define SIRFSOC_SPI_RXFIFO_THD_REACH BIT(8) -#define SIRFSOC_SPI_TXFIFO_THD_REACH BIT(9) -#define SIRFSOC_SPI_FRM_END BIT(10) - -/* TX RX enable */ -#define SIRFSOC_SPI_RX_EN BIT(0) -#define SIRFSOC_SPI_TX_EN BIT(1) -#define SIRFSOC_SPI_CMD_TX_EN BIT(2) - -#define SIRFSOC_SPI_IO_MODE_SEL BIT(0) -#define SIRFSOC_SPI_RX_DMA_FLUSH BIT(2) - -/* FIFO OPs */ -#define SIRFSOC_SPI_FIFO_RESET BIT(0) -#define SIRFSOC_SPI_FIFO_START BIT(1) - -/* FIFO CTRL */ -#define SIRFSOC_SPI_FIFO_WIDTH_BYTE (0 << 0) -#define SIRFSOC_SPI_FIFO_WIDTH_WORD (1 << 0) -#define SIRFSOC_SPI_FIFO_WIDTH_DWORD (2 << 0) -/* USP related */ -#define SIRFSOC_USP_SYNC_MODE BIT(0) -#define SIRFSOC_USP_SLV_MODE BIT(1) -#define SIRFSOC_USP_LSB BIT(4) -#define SIRFSOC_USP_EN BIT(5) -#define SIRFSOC_USP_RXD_FALLING_EDGE BIT(6) -#define SIRFSOC_USP_TXD_FALLING_EDGE BIT(7) -#define SIRFSOC_USP_CS_HIGH_VALID BIT(9) -#define SIRFSOC_USP_SCLK_IDLE_STAT BIT(11) -#define SIRFSOC_USP_TFS_IO_MODE BIT(14) -#define SIRFSOC_USP_TFS_IO_INPUT BIT(19) - -#define SIRFSOC_USP_RXD_DELAY_LEN_MASK 0xFF -#define SIRFSOC_USP_TXD_DELAY_LEN_MASK 0xFF -#define SIRFSOC_USP_RXD_DELAY_OFFSET 0 -#define SIRFSOC_USP_TXD_DELAY_OFFSET 8 -#define SIRFSOC_USP_RXD_DELAY_LEN 1 -#define SIRFSOC_USP_TXD_DELAY_LEN 1 -#define SIRFSOC_USP_CLK_DIVISOR_OFFSET 21 -#define SIRFSOC_USP_CLK_DIVISOR_MASK 0x3FF -#define SIRFSOC_USP_CLK_10_11_MASK 0x3 -#define SIRFSOC_USP_CLK_10_11_OFFSET 30 -#define SIRFSOC_USP_CLK_12_15_MASK 0xF -#define SIRFSOC_USP_CLK_12_15_OFFSET 24 - -#define SIRFSOC_USP_TX_DATA_OFFSET 0 -#define SIRFSOC_USP_TX_SYNC_OFFSET 8 -#define SIRFSOC_USP_TX_FRAME_OFFSET 16 -#define SIRFSOC_USP_TX_SHIFTER_OFFSET 24 - -#define SIRFSOC_USP_TX_DATA_MASK 0xFF -#define SIRFSOC_USP_TX_SYNC_MASK 0xFF -#define SIRFSOC_USP_TX_FRAME_MASK 0xFF -#define SIRFSOC_USP_TX_SHIFTER_MASK 0x1F - -#define SIRFSOC_USP_RX_DATA_OFFSET 0 -#define SIRFSOC_USP_RX_FRAME_OFFSET 8 -#define SIRFSOC_USP_RX_SHIFTER_OFFSET 16 - -#define SIRFSOC_USP_RX_DATA_MASK 0xFF -#define SIRFSOC_USP_RX_FRAME_MASK 0xFF -#define SIRFSOC_USP_RX_SHIFTER_MASK 0x1F -#define SIRFSOC_USP_CS_HIGH_VALUE BIT(1) - -#define SIRFSOC_SPI_FIFO_SC_OFFSET 0 -#define SIRFSOC_SPI_FIFO_LC_OFFSET 10 -#define SIRFSOC_SPI_FIFO_HC_OFFSET 20 - -#define SIRFSOC_SPI_FIFO_FULL_MASK(s) (1 << ((s)->fifo_full_offset)) -#define SIRFSOC_SPI_FIFO_EMPTY_MASK(s) (1 << ((s)->fifo_full_offset + 1)) -#define SIRFSOC_SPI_FIFO_THD_MASK(s) ((s)->fifo_size - 1) -#define SIRFSOC_SPI_FIFO_THD_OFFSET 2 -#define SIRFSOC_SPI_FIFO_LEVEL_CHK_MASK(s, val) \ - ((val) & (s)->fifo_level_chk_mask) - -enum sirf_spi_type { - SIRF_REAL_SPI, - SIRF_USP_SPI_P2, - SIRF_USP_SPI_A7, -}; - -/* - * only if the rx/tx buffer and transfer size are 4-bytes aligned, we use dma - * due to the limitation of dma controller - */ - -#define ALIGNED(x) (!((u32)x & 0x3)) -#define IS_DMA_VALID(x) (x && ALIGNED(x->tx_buf) && ALIGNED(x->rx_buf) && \ - ALIGNED(x->len) && (x->len < 2 * PAGE_SIZE)) - -#define SIRFSOC_MAX_CMD_BYTES 4 -#define SIRFSOC_SPI_DEFAULT_FRQ 1000000 - -struct sirf_spi_register { - /*SPI and USP-SPI common*/ - u32 tx_rx_en; - u32 int_en; - u32 int_st; - u32 tx_dma_io_ctrl; - u32 tx_dma_io_len; - u32 txfifo_ctrl; - u32 txfifo_level_chk; - u32 txfifo_op; - u32 txfifo_st; - u32 txfifo_data; - u32 rx_dma_io_ctrl; - u32 rx_dma_io_len; - u32 rxfifo_ctrl; - u32 rxfifo_level_chk; - u32 rxfifo_op; - u32 rxfifo_st; - u32 rxfifo_data; - /*SPI self*/ - u32 spi_ctrl; - u32 spi_cmd; - u32 spi_dummy_delay_ctrl; - /*USP-SPI self*/ - u32 usp_mode1; - u32 usp_mode2; - u32 usp_tx_frame_ctrl; - u32 usp_rx_frame_ctrl; - u32 usp_pin_io_data; - u32 usp_risc_dsp_mode; - u32 usp_async_param_reg; - u32 usp_irda_x_mode_div; - u32 usp_sm_cfg; - u32 usp_int_en_clr; -}; - -static const struct sirf_spi_register real_spi_register = { - .tx_rx_en = 0x8, - .int_en = 0xc, - .int_st = 0x10, - .tx_dma_io_ctrl = 0x100, - .tx_dma_io_len = 0x104, - .txfifo_ctrl = 0x108, - .txfifo_level_chk = 0x10c, - .txfifo_op = 0x110, - .txfifo_st = 0x114, - .txfifo_data = 0x118, - .rx_dma_io_ctrl = 0x120, - .rx_dma_io_len = 0x124, - .rxfifo_ctrl = 0x128, - .rxfifo_level_chk = 0x12c, - .rxfifo_op = 0x130, - .rxfifo_st = 0x134, - .rxfifo_data = 0x138, - .spi_ctrl = 0x0, - .spi_cmd = 0x4, - .spi_dummy_delay_ctrl = 0x144, -}; - -static const struct sirf_spi_register usp_spi_register = { - .tx_rx_en = 0x10, - .int_en = 0x14, - .int_st = 0x18, - .tx_dma_io_ctrl = 0x100, - .tx_dma_io_len = 0x104, - .txfifo_ctrl = 0x108, - .txfifo_level_chk = 0x10c, - .txfifo_op = 0x110, - .txfifo_st = 0x114, - .txfifo_data = 0x118, - .rx_dma_io_ctrl = 0x120, - .rx_dma_io_len = 0x124, - .rxfifo_ctrl = 0x128, - .rxfifo_level_chk = 0x12c, - .rxfifo_op = 0x130, - .rxfifo_st = 0x134, - .rxfifo_data = 0x138, - .usp_mode1 = 0x0, - .usp_mode2 = 0x4, - .usp_tx_frame_ctrl = 0x8, - .usp_rx_frame_ctrl = 0xc, - .usp_pin_io_data = 0x1c, - .usp_risc_dsp_mode = 0x20, - .usp_async_param_reg = 0x24, - .usp_irda_x_mode_div = 0x28, - .usp_sm_cfg = 0x2c, - .usp_int_en_clr = 0x140, -}; - -struct sirfsoc_spi { - struct spi_bitbang bitbang; - struct completion rx_done; - struct completion tx_done; - - void __iomem *base; - u32 ctrl_freq; /* SPI controller clock speed */ - struct clk *clk; - - /* rx & tx bufs from the spi_transfer */ - const void *tx; - void *rx; - - /* place received word into rx buffer */ - void (*rx_word) (struct sirfsoc_spi *); - /* get word from tx buffer for sending */ - void (*tx_word) (struct sirfsoc_spi *); - - /* number of words left to be tranmitted/received */ - unsigned int left_tx_word; - unsigned int left_rx_word; - - /* rx & tx DMA channels */ - struct dma_chan *rx_chan; - struct dma_chan *tx_chan; - dma_addr_t src_start; - dma_addr_t dst_start; - int word_width; /* in bytes */ - - /* - * if tx size is not more than 4 and rx size is NULL, use - * command model - */ - bool tx_by_cmd; - bool hw_cs; - enum sirf_spi_type type; - const struct sirf_spi_register *regs; - unsigned int fifo_size; - /* fifo empty offset is (fifo full offset + 1)*/ - unsigned int fifo_full_offset; - /* fifo_level_chk_mask is (fifo_size/4 - 1) */ - unsigned int fifo_level_chk_mask; - unsigned int dat_max_frm_len; -}; - -struct sirf_spi_comp_data { - const struct sirf_spi_register *regs; - enum sirf_spi_type type; - unsigned int dat_max_frm_len; - unsigned int fifo_size; - void (*hwinit)(struct sirfsoc_spi *sspi); -}; - -static void sirfsoc_usp_hwinit(struct sirfsoc_spi *sspi) -{ - /* reset USP and let USP can operate */ - writel(readl(sspi->base + sspi->regs->usp_mode1) & - ~SIRFSOC_USP_EN, sspi->base + sspi->regs->usp_mode1); - writel(readl(sspi->base + sspi->regs->usp_mode1) | - SIRFSOC_USP_EN, sspi->base + sspi->regs->usp_mode1); -} - -static void spi_sirfsoc_rx_word_u8(struct sirfsoc_spi *sspi) -{ - u32 data; - u8 *rx = sspi->rx; - - data = readl(sspi->base + sspi->regs->rxfifo_data); - - if (rx) { - *rx++ = (u8) data; - sspi->rx = rx; - } - - sspi->left_rx_word--; -} - -static void spi_sirfsoc_tx_word_u8(struct sirfsoc_spi *sspi) -{ - u32 data = 0; - const u8 *tx = sspi->tx; - - if (tx) { - data = *tx++; - sspi->tx = tx; - } - writel(data, sspi->base + sspi->regs->txfifo_data); - sspi->left_tx_word--; -} - -static void spi_sirfsoc_rx_word_u16(struct sirfsoc_spi *sspi) -{ - u32 data; - u16 *rx = sspi->rx; - - data = readl(sspi->base + sspi->regs->rxfifo_data); - - if (rx) { - *rx++ = (u16) data; - sspi->rx = rx; - } - - sspi->left_rx_word--; -} - -static void spi_sirfsoc_tx_word_u16(struct sirfsoc_spi *sspi) -{ - u32 data = 0; - const u16 *tx = sspi->tx; - - if (tx) { - data = *tx++; - sspi->tx = tx; - } - - writel(data, sspi->base + sspi->regs->txfifo_data); - sspi->left_tx_word--; -} - -static void spi_sirfsoc_rx_word_u32(struct sirfsoc_spi *sspi) -{ - u32 data; - u32 *rx = sspi->rx; - - data = readl(sspi->base + sspi->regs->rxfifo_data); - - if (rx) { - *rx++ = (u32) data; - sspi->rx = rx; - } - - sspi->left_rx_word--; - -} - -static void spi_sirfsoc_tx_word_u32(struct sirfsoc_spi *sspi) -{ - u32 data = 0; - const u32 *tx = sspi->tx; - - if (tx) { - data = *tx++; - sspi->tx = tx; - } - - writel(data, sspi->base + sspi->regs->txfifo_data); - sspi->left_tx_word--; -} - -static irqreturn_t spi_sirfsoc_irq(int irq, void *dev_id) -{ - struct sirfsoc_spi *sspi = dev_id; - u32 spi_stat; - - spi_stat = readl(sspi->base + sspi->regs->int_st); - if (sspi->tx_by_cmd && sspi->type == SIRF_REAL_SPI - && (spi_stat & SIRFSOC_SPI_FRM_END)) { - complete(&sspi->tx_done); - writel(0x0, sspi->base + sspi->regs->int_en); - writel(readl(sspi->base + sspi->regs->int_st), - sspi->base + sspi->regs->int_st); - return IRQ_HANDLED; - } - /* Error Conditions */ - if (spi_stat & SIRFSOC_SPI_RX_OFLOW || - spi_stat & SIRFSOC_SPI_TX_UFLOW) { - complete(&sspi->tx_done); - complete(&sspi->rx_done); - switch (sspi->type) { - case SIRF_REAL_SPI: - case SIRF_USP_SPI_P2: - writel(0x0, sspi->base + sspi->regs->int_en); - break; - case SIRF_USP_SPI_A7: - writel(~0UL, sspi->base + sspi->regs->usp_int_en_clr); - break; - } - writel(readl(sspi->base + sspi->regs->int_st), - sspi->base + sspi->regs->int_st); - return IRQ_HANDLED; - } - if (spi_stat & SIRFSOC_SPI_TXFIFO_EMPTY) - complete(&sspi->tx_done); - while (!(readl(sspi->base + sspi->regs->int_st) & - SIRFSOC_SPI_RX_IO_DMA)) - cpu_relax(); - complete(&sspi->rx_done); - switch (sspi->type) { - case SIRF_REAL_SPI: - case SIRF_USP_SPI_P2: - writel(0x0, sspi->base + sspi->regs->int_en); - break; - case SIRF_USP_SPI_A7: - writel(~0UL, sspi->base + sspi->regs->usp_int_en_clr); - break; - } - writel(readl(sspi->base + sspi->regs->int_st), - sspi->base + sspi->regs->int_st); - - return IRQ_HANDLED; -} - -static void spi_sirfsoc_dma_fini_callback(void *data) -{ - struct completion *dma_complete = data; - - complete(dma_complete); -} - -static void spi_sirfsoc_cmd_transfer(struct spi_device *spi, - struct spi_transfer *t) -{ - struct sirfsoc_spi *sspi; - int timeout = t->len * 10; - u32 cmd; - - sspi = spi_master_get_devdata(spi->master); - writel(SIRFSOC_SPI_FIFO_RESET, sspi->base + sspi->regs->txfifo_op); - writel(SIRFSOC_SPI_FIFO_START, sspi->base + sspi->regs->txfifo_op); - memcpy(&cmd, sspi->tx, t->len); - if (sspi->word_width == 1 && !(spi->mode & SPI_LSB_FIRST)) - cmd = cpu_to_be32(cmd) >> - ((SIRFSOC_MAX_CMD_BYTES - t->len) * 8); - if (sspi->word_width == 2 && t->len == 4 && - (!(spi->mode & SPI_LSB_FIRST))) - cmd = ((cmd & 0xffff) << 16) | (cmd >> 16); - writel(cmd, sspi->base + sspi->regs->spi_cmd); - writel(SIRFSOC_SPI_FRM_END_INT_EN, - sspi->base + sspi->regs->int_en); - writel(SIRFSOC_SPI_CMD_TX_EN, - sspi->base + sspi->regs->tx_rx_en); - if (wait_for_completion_timeout(&sspi->tx_done, timeout) == 0) { - dev_err(&spi->dev, "cmd transfer timeout\n"); - return; - } - sspi->left_rx_word -= t->len; -} - -static void spi_sirfsoc_dma_transfer(struct spi_device *spi, - struct spi_transfer *t) -{ - struct sirfsoc_spi *sspi; - struct dma_async_tx_descriptor *rx_desc, *tx_desc; - int timeout = t->len * 10; - - sspi = spi_master_get_devdata(spi->master); - writel(SIRFSOC_SPI_FIFO_RESET, sspi->base + sspi->regs->rxfifo_op); - writel(SIRFSOC_SPI_FIFO_RESET, sspi->base + sspi->regs->txfifo_op); - switch (sspi->type) { - case SIRF_REAL_SPI: - writel(SIRFSOC_SPI_FIFO_START, - sspi->base + sspi->regs->rxfifo_op); - writel(SIRFSOC_SPI_FIFO_START, - sspi->base + sspi->regs->txfifo_op); - writel(0, sspi->base + sspi->regs->int_en); - break; - case SIRF_USP_SPI_P2: - writel(0x0, sspi->base + sspi->regs->rxfifo_op); - writel(0x0, sspi->base + sspi->regs->txfifo_op); - writel(0, sspi->base + sspi->regs->int_en); - break; - case SIRF_USP_SPI_A7: - writel(0x0, sspi->base + sspi->regs->rxfifo_op); - writel(0x0, sspi->base + sspi->regs->txfifo_op); - writel(~0UL, sspi->base + sspi->regs->usp_int_en_clr); - break; - } - writel(readl(sspi->base + sspi->regs->int_st), - sspi->base + sspi->regs->int_st); - if (sspi->left_tx_word < sspi->dat_max_frm_len) { - switch (sspi->type) { - case SIRF_REAL_SPI: - writel(readl(sspi->base + sspi->regs->spi_ctrl) | - SIRFSOC_SPI_ENA_AUTO_CLR | - SIRFSOC_SPI_MUL_DAT_MODE, - sspi->base + sspi->regs->spi_ctrl); - writel(sspi->left_tx_word - 1, - sspi->base + sspi->regs->tx_dma_io_len); - writel(sspi->left_tx_word - 1, - sspi->base + sspi->regs->rx_dma_io_len); - break; - case SIRF_USP_SPI_P2: - case SIRF_USP_SPI_A7: - /*USP simulate SPI, tx/rx_dma_io_len indicates bytes*/ - writel(sspi->left_tx_word * sspi->word_width, - sspi->base + sspi->regs->tx_dma_io_len); - writel(sspi->left_tx_word * sspi->word_width, - sspi->base + sspi->regs->rx_dma_io_len); - break; - } - } else { - if (sspi->type == SIRF_REAL_SPI) - writel(readl(sspi->base + sspi->regs->spi_ctrl), - sspi->base + sspi->regs->spi_ctrl); - writel(0, sspi->base + sspi->regs->tx_dma_io_len); - writel(0, sspi->base + sspi->regs->rx_dma_io_len); - } - sspi->dst_start = dma_map_single(&spi->dev, sspi->rx, t->len, - (t->tx_buf != t->rx_buf) ? - DMA_FROM_DEVICE : DMA_BIDIRECTIONAL); - rx_desc = dmaengine_prep_slave_single(sspi->rx_chan, - sspi->dst_start, t->len, DMA_DEV_TO_MEM, - DMA_PREP_INTERRUPT | DMA_CTRL_ACK); - rx_desc->callback = spi_sirfsoc_dma_fini_callback; - rx_desc->callback_param = &sspi->rx_done; - - sspi->src_start = dma_map_single(&spi->dev, (void *)sspi->tx, t->len, - (t->tx_buf != t->rx_buf) ? - DMA_TO_DEVICE : DMA_BIDIRECTIONAL); - tx_desc = dmaengine_prep_slave_single(sspi->tx_chan, - sspi->src_start, t->len, DMA_MEM_TO_DEV, - DMA_PREP_INTERRUPT | DMA_CTRL_ACK); - tx_desc->callback = spi_sirfsoc_dma_fini_callback; - tx_desc->callback_param = &sspi->tx_done; - - dmaengine_submit(tx_desc); - dmaengine_submit(rx_desc); - dma_async_issue_pending(sspi->tx_chan); - dma_async_issue_pending(sspi->rx_chan); - writel(SIRFSOC_SPI_RX_EN | SIRFSOC_SPI_TX_EN, - sspi->base + sspi->regs->tx_rx_en); - if (sspi->type == SIRF_USP_SPI_P2 || - sspi->type == SIRF_USP_SPI_A7) { - writel(SIRFSOC_SPI_FIFO_START, - sspi->base + sspi->regs->rxfifo_op); - writel(SIRFSOC_SPI_FIFO_START, - sspi->base + sspi->regs->txfifo_op); - } - if (wait_for_completion_timeout(&sspi->rx_done, timeout) == 0) { - dev_err(&spi->dev, "transfer timeout\n"); - dmaengine_terminate_all(sspi->rx_chan); - } else - sspi->left_rx_word = 0; - /* - * we only wait tx-done event if transferring by DMA. for PIO, - * we get rx data by writing tx data, so if rx is done, tx has - * done earlier - */ - if (wait_for_completion_timeout(&sspi->tx_done, timeout) == 0) { - dev_err(&spi->dev, "transfer timeout\n"); - if (sspi->type == SIRF_USP_SPI_P2 || - sspi->type == SIRF_USP_SPI_A7) - writel(0, sspi->base + sspi->regs->tx_rx_en); - dmaengine_terminate_all(sspi->tx_chan); - } - dma_unmap_single(&spi->dev, sspi->src_start, t->len, DMA_TO_DEVICE); - dma_unmap_single(&spi->dev, sspi->dst_start, t->len, DMA_FROM_DEVICE); - /* TX, RX FIFO stop */ - writel(0, sspi->base + sspi->regs->rxfifo_op); - writel(0, sspi->base + sspi->regs->txfifo_op); - if (sspi->left_tx_word >= sspi->dat_max_frm_len) - writel(0, sspi->base + sspi->regs->tx_rx_en); - if (sspi->type == SIRF_USP_SPI_P2 || - sspi->type == SIRF_USP_SPI_A7) - writel(0, sspi->base + sspi->regs->tx_rx_en); -} - -static void spi_sirfsoc_pio_transfer(struct spi_device *spi, - struct spi_transfer *t) -{ - struct sirfsoc_spi *sspi; - int timeout = t->len * 10; - unsigned int data_units; - - sspi = spi_master_get_devdata(spi->master); - do { - writel(SIRFSOC_SPI_FIFO_RESET, - sspi->base + sspi->regs->rxfifo_op); - writel(SIRFSOC_SPI_FIFO_RESET, - sspi->base + sspi->regs->txfifo_op); - switch (sspi->type) { - case SIRF_USP_SPI_P2: - writel(0x0, sspi->base + sspi->regs->rxfifo_op); - writel(0x0, sspi->base + sspi->regs->txfifo_op); - writel(0, sspi->base + sspi->regs->int_en); - writel(readl(sspi->base + sspi->regs->int_st), - sspi->base + sspi->regs->int_st); - writel(min((sspi->left_tx_word * sspi->word_width), - sspi->fifo_size), - sspi->base + sspi->regs->tx_dma_io_len); - writel(min((sspi->left_rx_word * sspi->word_width), - sspi->fifo_size), - sspi->base + sspi->regs->rx_dma_io_len); - break; - case SIRF_USP_SPI_A7: - writel(0x0, sspi->base + sspi->regs->rxfifo_op); - writel(0x0, sspi->base + sspi->regs->txfifo_op); - writel(~0UL, sspi->base + sspi->regs->usp_int_en_clr); - writel(readl(sspi->base + sspi->regs->int_st), - sspi->base + sspi->regs->int_st); - writel(min((sspi->left_tx_word * sspi->word_width), - sspi->fifo_size), - sspi->base + sspi->regs->tx_dma_io_len); - writel(min((sspi->left_rx_word * sspi->word_width), - sspi->fifo_size), - sspi->base + sspi->regs->rx_dma_io_len); - break; - case SIRF_REAL_SPI: - writel(SIRFSOC_SPI_FIFO_START, - sspi->base + sspi->regs->rxfifo_op); - writel(SIRFSOC_SPI_FIFO_START, - sspi->base + sspi->regs->txfifo_op); - writel(0, sspi->base + sspi->regs->int_en); - writel(readl(sspi->base + sspi->regs->int_st), - sspi->base + sspi->regs->int_st); - writel(readl(sspi->base + sspi->regs->spi_ctrl) | - SIRFSOC_SPI_MUL_DAT_MODE | - SIRFSOC_SPI_ENA_AUTO_CLR, - sspi->base + sspi->regs->spi_ctrl); - data_units = sspi->fifo_size / sspi->word_width; - writel(min(sspi->left_tx_word, data_units) - 1, - sspi->base + sspi->regs->tx_dma_io_len); - writel(min(sspi->left_rx_word, data_units) - 1, - sspi->base + sspi->regs->rx_dma_io_len); - break; - } - while (!((readl(sspi->base + sspi->regs->txfifo_st) - & SIRFSOC_SPI_FIFO_FULL_MASK(sspi))) && - sspi->left_tx_word) - sspi->tx_word(sspi); - writel(SIRFSOC_SPI_TXFIFO_EMPTY_INT_EN | - SIRFSOC_SPI_TX_UFLOW_INT_EN | - SIRFSOC_SPI_RX_OFLOW_INT_EN | - SIRFSOC_SPI_RX_IO_DMA_INT_EN, - sspi->base + sspi->regs->int_en); - writel(SIRFSOC_SPI_RX_EN | SIRFSOC_SPI_TX_EN, - sspi->base + sspi->regs->tx_rx_en); - if (sspi->type == SIRF_USP_SPI_P2 || - sspi->type == SIRF_USP_SPI_A7) { - writel(SIRFSOC_SPI_FIFO_START, - sspi->base + sspi->regs->rxfifo_op); - writel(SIRFSOC_SPI_FIFO_START, - sspi->base + sspi->regs->txfifo_op); - } - if (!wait_for_completion_timeout(&sspi->tx_done, timeout) || - !wait_for_completion_timeout(&sspi->rx_done, timeout)) { - dev_err(&spi->dev, "transfer timeout\n"); - if (sspi->type == SIRF_USP_SPI_P2 || - sspi->type == SIRF_USP_SPI_A7) - writel(0, sspi->base + sspi->regs->tx_rx_en); - break; - } - while (!((readl(sspi->base + sspi->regs->rxfifo_st) - & SIRFSOC_SPI_FIFO_EMPTY_MASK(sspi))) && - sspi->left_rx_word) - sspi->rx_word(sspi); - if (sspi->type == SIRF_USP_SPI_P2 || - sspi->type == SIRF_USP_SPI_A7) - writel(0, sspi->base + sspi->regs->tx_rx_en); - writel(0, sspi->base + sspi->regs->rxfifo_op); - writel(0, sspi->base + sspi->regs->txfifo_op); - } while (sspi->left_tx_word != 0 || sspi->left_rx_word != 0); -} - -static int spi_sirfsoc_transfer(struct spi_device *spi, struct spi_transfer *t) -{ - struct sirfsoc_spi *sspi; - - sspi = spi_master_get_devdata(spi->master); - sspi->tx = t->tx_buf; - sspi->rx = t->rx_buf; - sspi->left_tx_word = sspi->left_rx_word = t->len / sspi->word_width; - reinit_completion(&sspi->rx_done); - reinit_completion(&sspi->tx_done); - /* - * in the transfer, if transfer data using command register with rx_buf - * null, just fill command data into command register and wait for its - * completion. - */ - if (sspi->type == SIRF_REAL_SPI && sspi->tx_by_cmd) - spi_sirfsoc_cmd_transfer(spi, t); - else if (IS_DMA_VALID(t)) - spi_sirfsoc_dma_transfer(spi, t); - else - spi_sirfsoc_pio_transfer(spi, t); - - return t->len - sspi->left_rx_word * sspi->word_width; -} - -static void spi_sirfsoc_chipselect(struct spi_device *spi, int value) -{ - struct sirfsoc_spi *sspi = spi_master_get_devdata(spi->master); - - if (sspi->hw_cs) { - u32 regval; - - switch (sspi->type) { - case SIRF_REAL_SPI: - regval = readl(sspi->base + sspi->regs->spi_ctrl); - switch (value) { - case BITBANG_CS_ACTIVE: - if (spi->mode & SPI_CS_HIGH) - regval |= SIRFSOC_SPI_CS_IO_OUT; - else - regval &= ~SIRFSOC_SPI_CS_IO_OUT; - break; - case BITBANG_CS_INACTIVE: - if (spi->mode & SPI_CS_HIGH) - regval &= ~SIRFSOC_SPI_CS_IO_OUT; - else - regval |= SIRFSOC_SPI_CS_IO_OUT; - break; - } - writel(regval, sspi->base + sspi->regs->spi_ctrl); - break; - case SIRF_USP_SPI_P2: - case SIRF_USP_SPI_A7: - regval = readl(sspi->base + - sspi->regs->usp_pin_io_data); - switch (value) { - case BITBANG_CS_ACTIVE: - if (spi->mode & SPI_CS_HIGH) - regval |= SIRFSOC_USP_CS_HIGH_VALUE; - else - regval &= ~(SIRFSOC_USP_CS_HIGH_VALUE); - break; - case BITBANG_CS_INACTIVE: - if (spi->mode & SPI_CS_HIGH) - regval &= ~(SIRFSOC_USP_CS_HIGH_VALUE); - else - regval |= SIRFSOC_USP_CS_HIGH_VALUE; - break; - } - writel(regval, - sspi->base + sspi->regs->usp_pin_io_data); - break; - } - } else { - switch (value) { - case BITBANG_CS_ACTIVE: - gpio_direction_output(spi->cs_gpio, - spi->mode & SPI_CS_HIGH ? 1 : 0); - break; - case BITBANG_CS_INACTIVE: - gpio_direction_output(spi->cs_gpio, - spi->mode & SPI_CS_HIGH ? 0 : 1); - break; - } - } -} - -static int spi_sirfsoc_config_mode(struct spi_device *spi) -{ - struct sirfsoc_spi *sspi; - u32 regval, usp_mode1; - - sspi = spi_master_get_devdata(spi->master); - regval = readl(sspi->base + sspi->regs->spi_ctrl); - usp_mode1 = readl(sspi->base + sspi->regs->usp_mode1); - if (!(spi->mode & SPI_CS_HIGH)) { - regval |= SIRFSOC_SPI_CS_IDLE_STAT; - usp_mode1 &= ~SIRFSOC_USP_CS_HIGH_VALID; - } else { - regval &= ~SIRFSOC_SPI_CS_IDLE_STAT; - usp_mode1 |= SIRFSOC_USP_CS_HIGH_VALID; - } - if (!(spi->mode & SPI_LSB_FIRST)) { - regval |= SIRFSOC_SPI_TRAN_MSB; - usp_mode1 &= ~SIRFSOC_USP_LSB; - } else { - regval &= ~SIRFSOC_SPI_TRAN_MSB; - usp_mode1 |= SIRFSOC_USP_LSB; - } - if (spi->mode & SPI_CPOL) { - regval |= SIRFSOC_SPI_CLK_IDLE_STAT; - usp_mode1 |= SIRFSOC_USP_SCLK_IDLE_STAT; - } else { - regval &= ~SIRFSOC_SPI_CLK_IDLE_STAT; - usp_mode1 &= ~SIRFSOC_USP_SCLK_IDLE_STAT; - } - /* - * Data should be driven at least 1/2 cycle before the fetch edge - * to make sure that data gets stable at the fetch edge. - */ - if (((spi->mode & SPI_CPOL) && (spi->mode & SPI_CPHA)) || - (!(spi->mode & SPI_CPOL) && !(spi->mode & SPI_CPHA))) { - regval &= ~SIRFSOC_SPI_DRV_POS_EDGE; - usp_mode1 |= (SIRFSOC_USP_TXD_FALLING_EDGE | - SIRFSOC_USP_RXD_FALLING_EDGE); - } else { - regval |= SIRFSOC_SPI_DRV_POS_EDGE; - usp_mode1 &= ~(SIRFSOC_USP_RXD_FALLING_EDGE | - SIRFSOC_USP_TXD_FALLING_EDGE); - } - writel((SIRFSOC_SPI_FIFO_LEVEL_CHK_MASK(sspi, sspi->fifo_size - 2) << - SIRFSOC_SPI_FIFO_SC_OFFSET) | - (SIRFSOC_SPI_FIFO_LEVEL_CHK_MASK(sspi, sspi->fifo_size / 2) << - SIRFSOC_SPI_FIFO_LC_OFFSET) | - (SIRFSOC_SPI_FIFO_LEVEL_CHK_MASK(sspi, 2) << - SIRFSOC_SPI_FIFO_HC_OFFSET), - sspi->base + sspi->regs->txfifo_level_chk); - writel((SIRFSOC_SPI_FIFO_LEVEL_CHK_MASK(sspi, 2) << - SIRFSOC_SPI_FIFO_SC_OFFSET) | - (SIRFSOC_SPI_FIFO_LEVEL_CHK_MASK(sspi, sspi->fifo_size / 2) << - SIRFSOC_SPI_FIFO_LC_OFFSET) | - (SIRFSOC_SPI_FIFO_LEVEL_CHK_MASK(sspi, sspi->fifo_size - 2) << - SIRFSOC_SPI_FIFO_HC_OFFSET), - sspi->base + sspi->regs->rxfifo_level_chk); - /* - * it should never set to hardware cs mode because in hardware cs mode, - * cs signal can't controlled by driver. - */ - switch (sspi->type) { - case SIRF_REAL_SPI: - regval |= SIRFSOC_SPI_CS_IO_MODE; - writel(regval, sspi->base + sspi->regs->spi_ctrl); - break; - case SIRF_USP_SPI_P2: - case SIRF_USP_SPI_A7: - usp_mode1 |= SIRFSOC_USP_SYNC_MODE; - usp_mode1 |= SIRFSOC_USP_TFS_IO_MODE; - usp_mode1 &= ~SIRFSOC_USP_TFS_IO_INPUT; - writel(usp_mode1, sspi->base + sspi->regs->usp_mode1); - break; - } - - return 0; -} - -static int -spi_sirfsoc_setup_transfer(struct spi_device *spi, struct spi_transfer *t) -{ - struct sirfsoc_spi *sspi; - u8 bits_per_word = 0; - int hz = 0; - u32 regval, txfifo_ctrl, rxfifo_ctrl, tx_frm_ctl, rx_frm_ctl, usp_mode2; - - sspi = spi_master_get_devdata(spi->master); - - bits_per_word = (t) ? t->bits_per_word : spi->bits_per_word; - hz = t && t->speed_hz ? t->speed_hz : spi->max_speed_hz; - - usp_mode2 = regval = (sspi->ctrl_freq / (2 * hz)) - 1; - if (regval > 0xFFFF || regval < 0) { - dev_err(&spi->dev, "Speed %d not supported\n", hz); - return -EINVAL; - } - switch (bits_per_word) { - case 8: - regval |= SIRFSOC_SPI_TRAN_DAT_FORMAT_8; - sspi->rx_word = spi_sirfsoc_rx_word_u8; - sspi->tx_word = spi_sirfsoc_tx_word_u8; - break; - case 12: - case 16: - regval |= (bits_per_word == 12) ? - SIRFSOC_SPI_TRAN_DAT_FORMAT_12 : - SIRFSOC_SPI_TRAN_DAT_FORMAT_16; - sspi->rx_word = spi_sirfsoc_rx_word_u16; - sspi->tx_word = spi_sirfsoc_tx_word_u16; - break; - case 32: - regval |= SIRFSOC_SPI_TRAN_DAT_FORMAT_32; - sspi->rx_word = spi_sirfsoc_rx_word_u32; - sspi->tx_word = spi_sirfsoc_tx_word_u32; - break; - default: - dev_err(&spi->dev, "bpw %d not supported\n", bits_per_word); - return -EINVAL; - } - sspi->word_width = DIV_ROUND_UP(bits_per_word, 8); - txfifo_ctrl = (((sspi->fifo_size / 2) & - SIRFSOC_SPI_FIFO_THD_MASK(sspi)) - << SIRFSOC_SPI_FIFO_THD_OFFSET) | - (sspi->word_width >> 1); - rxfifo_ctrl = (((sspi->fifo_size / 2) & - SIRFSOC_SPI_FIFO_THD_MASK(sspi)) - << SIRFSOC_SPI_FIFO_THD_OFFSET) | - (sspi->word_width >> 1); - writel(txfifo_ctrl, sspi->base + sspi->regs->txfifo_ctrl); - writel(rxfifo_ctrl, sspi->base + sspi->regs->rxfifo_ctrl); - if (sspi->type == SIRF_USP_SPI_P2 || - sspi->type == SIRF_USP_SPI_A7) { - tx_frm_ctl = 0; - tx_frm_ctl |= ((bits_per_word - 1) & SIRFSOC_USP_TX_DATA_MASK) - << SIRFSOC_USP_TX_DATA_OFFSET; - tx_frm_ctl |= ((bits_per_word + 1 + SIRFSOC_USP_TXD_DELAY_LEN - - 1) & SIRFSOC_USP_TX_SYNC_MASK) << - SIRFSOC_USP_TX_SYNC_OFFSET; - tx_frm_ctl |= ((bits_per_word + 1 + SIRFSOC_USP_TXD_DELAY_LEN - + 2 - 1) & SIRFSOC_USP_TX_FRAME_MASK) << - SIRFSOC_USP_TX_FRAME_OFFSET; - tx_frm_ctl |= ((bits_per_word - 1) & - SIRFSOC_USP_TX_SHIFTER_MASK) << - SIRFSOC_USP_TX_SHIFTER_OFFSET; - rx_frm_ctl = 0; - rx_frm_ctl |= ((bits_per_word - 1) & SIRFSOC_USP_RX_DATA_MASK) - << SIRFSOC_USP_RX_DATA_OFFSET; - rx_frm_ctl |= ((bits_per_word + 1 + SIRFSOC_USP_RXD_DELAY_LEN - + 2 - 1) & SIRFSOC_USP_RX_FRAME_MASK) << - SIRFSOC_USP_RX_FRAME_OFFSET; - rx_frm_ctl |= ((bits_per_word - 1) - & SIRFSOC_USP_RX_SHIFTER_MASK) << - SIRFSOC_USP_RX_SHIFTER_OFFSET; - writel(tx_frm_ctl | (((usp_mode2 >> 10) & - SIRFSOC_USP_CLK_10_11_MASK) << - SIRFSOC_USP_CLK_10_11_OFFSET), - sspi->base + sspi->regs->usp_tx_frame_ctrl); - writel(rx_frm_ctl | (((usp_mode2 >> 12) & - SIRFSOC_USP_CLK_12_15_MASK) << - SIRFSOC_USP_CLK_12_15_OFFSET), - sspi->base + sspi->regs->usp_rx_frame_ctrl); - writel(readl(sspi->base + sspi->regs->usp_mode2) | - ((usp_mode2 & SIRFSOC_USP_CLK_DIVISOR_MASK) << - SIRFSOC_USP_CLK_DIVISOR_OFFSET) | - (SIRFSOC_USP_RXD_DELAY_LEN << - SIRFSOC_USP_RXD_DELAY_OFFSET) | - (SIRFSOC_USP_TXD_DELAY_LEN << - SIRFSOC_USP_TXD_DELAY_OFFSET), - sspi->base + sspi->regs->usp_mode2); - } - if (sspi->type == SIRF_REAL_SPI) - writel(regval, sspi->base + sspi->regs->spi_ctrl); - spi_sirfsoc_config_mode(spi); - if (sspi->type == SIRF_REAL_SPI) { - if (t && t->tx_buf && !t->rx_buf && - (t->len <= SIRFSOC_MAX_CMD_BYTES)) { - sspi->tx_by_cmd = true; - writel(readl(sspi->base + sspi->regs->spi_ctrl) | - (SIRFSOC_SPI_CMD_BYTE_NUM((t->len - 1)) | - SIRFSOC_SPI_CMD_MODE), - sspi->base + sspi->regs->spi_ctrl); - } else { - sspi->tx_by_cmd = false; - writel(readl(sspi->base + sspi->regs->spi_ctrl) & - ~SIRFSOC_SPI_CMD_MODE, - sspi->base + sspi->regs->spi_ctrl); - } - } - if (IS_DMA_VALID(t)) { - /* Enable DMA mode for RX, TX */ - writel(0, sspi->base + sspi->regs->tx_dma_io_ctrl); - writel(SIRFSOC_SPI_RX_DMA_FLUSH, - sspi->base + sspi->regs->rx_dma_io_ctrl); - } else { - /* Enable IO mode for RX, TX */ - writel(SIRFSOC_SPI_IO_MODE_SEL, - sspi->base + sspi->regs->tx_dma_io_ctrl); - writel(SIRFSOC_SPI_IO_MODE_SEL, - sspi->base + sspi->regs->rx_dma_io_ctrl); - } - return 0; -} - -static int spi_sirfsoc_setup(struct spi_device *spi) -{ - struct sirfsoc_spi *sspi; - int ret = 0; - - sspi = spi_master_get_devdata(spi->master); - if (spi->cs_gpio == -ENOENT) - sspi->hw_cs = true; - else { - sspi->hw_cs = false; - if (!spi_get_ctldata(spi)) { - void *cs = kmalloc(sizeof(int), GFP_KERNEL); - if (!cs) { - ret = -ENOMEM; - goto exit; - } - ret = gpio_is_valid(spi->cs_gpio); - if (!ret) { - dev_err(&spi->dev, "no valid gpio\n"); - ret = -ENOENT; - goto exit; - } - ret = gpio_request(spi->cs_gpio, DRIVER_NAME); - if (ret) { - dev_err(&spi->dev, "failed to request gpio\n"); - goto exit; - } - spi_set_ctldata(spi, cs); - } - } - spi_sirfsoc_config_mode(spi); - spi_sirfsoc_chipselect(spi, BITBANG_CS_INACTIVE); -exit: - return ret; -} - -static void spi_sirfsoc_cleanup(struct spi_device *spi) -{ - if (spi_get_ctldata(spi)) { - gpio_free(spi->cs_gpio); - kfree(spi_get_ctldata(spi)); - } -} - -static const struct sirf_spi_comp_data sirf_real_spi = { - .regs = &real_spi_register, - .type = SIRF_REAL_SPI, - .dat_max_frm_len = 64 * 1024, - .fifo_size = 256, -}; - -static const struct sirf_spi_comp_data sirf_usp_spi_p2 = { - .regs = &usp_spi_register, - .type = SIRF_USP_SPI_P2, - .dat_max_frm_len = 1024 * 1024, - .fifo_size = 128, - .hwinit = sirfsoc_usp_hwinit, -}; - -static const struct sirf_spi_comp_data sirf_usp_spi_a7 = { - .regs = &usp_spi_register, - .type = SIRF_USP_SPI_A7, - .dat_max_frm_len = 1024 * 1024, - .fifo_size = 512, - .hwinit = sirfsoc_usp_hwinit, -}; - -static const struct of_device_id spi_sirfsoc_of_match[] = { - { .compatible = "sirf,prima2-spi", .data = &sirf_real_spi}, - { .compatible = "sirf,prima2-usp-spi", .data = &sirf_usp_spi_p2}, - { .compatible = "sirf,atlas7-usp-spi", .data = &sirf_usp_spi_a7}, - {} -}; -MODULE_DEVICE_TABLE(of, spi_sirfsoc_of_match); - -static int spi_sirfsoc_probe(struct platform_device *pdev) -{ - struct sirfsoc_spi *sspi; - struct spi_master *master; - const struct sirf_spi_comp_data *spi_comp_data; - int irq; - int ret; - const struct of_device_id *match; - - ret = device_reset(&pdev->dev); - if (ret) { - dev_err(&pdev->dev, "SPI reset failed!\n"); - return ret; - } - - master = spi_alloc_master(&pdev->dev, sizeof(*sspi)); - if (!master) { - dev_err(&pdev->dev, "Unable to allocate SPI master\n"); - return -ENOMEM; - } - match = of_match_node(spi_sirfsoc_of_match, pdev->dev.of_node); - platform_set_drvdata(pdev, master); - sspi = spi_master_get_devdata(master); - sspi->fifo_full_offset = ilog2(sspi->fifo_size); - spi_comp_data = match->data; - sspi->regs = spi_comp_data->regs; - sspi->type = spi_comp_data->type; - sspi->fifo_level_chk_mask = (sspi->fifo_size / 4) - 1; - sspi->dat_max_frm_len = spi_comp_data->dat_max_frm_len; - sspi->fifo_size = spi_comp_data->fifo_size; - sspi->base = devm_platform_ioremap_resource(pdev, 0); - if (IS_ERR(sspi->base)) { - ret = PTR_ERR(sspi->base); - goto free_master; - } - irq = platform_get_irq(pdev, 0); - if (irq < 0) { - ret = -ENXIO; - goto free_master; - } - ret = devm_request_irq(&pdev->dev, irq, spi_sirfsoc_irq, 0, - DRIVER_NAME, sspi); - if (ret) - goto free_master; - - sspi->bitbang.master = master; - sspi->bitbang.chipselect = spi_sirfsoc_chipselect; - sspi->bitbang.setup_transfer = spi_sirfsoc_setup_transfer; - sspi->bitbang.txrx_bufs = spi_sirfsoc_transfer; - sspi->bitbang.master->setup = spi_sirfsoc_setup; - sspi->bitbang.master->cleanup = spi_sirfsoc_cleanup; - master->bus_num = pdev->id; - master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_LSB_FIRST | SPI_CS_HIGH; - master->bits_per_word_mask = SPI_BPW_MASK(8) | SPI_BPW_MASK(12) | - SPI_BPW_MASK(16) | SPI_BPW_MASK(32); - master->max_speed_hz = SIRFSOC_SPI_DEFAULT_FRQ; - master->flags = SPI_MASTER_MUST_RX | SPI_MASTER_MUST_TX; - sspi->bitbang.master->dev.of_node = pdev->dev.of_node; - - /* request DMA channels */ - sspi->rx_chan = dma_request_chan(&pdev->dev, "rx"); - if (IS_ERR(sspi->rx_chan)) { - dev_err(&pdev->dev, "can not allocate rx dma channel\n"); - ret = PTR_ERR(sspi->rx_chan); - goto free_master; - } - sspi->tx_chan = dma_request_chan(&pdev->dev, "tx"); - if (IS_ERR(sspi->tx_chan)) { - dev_err(&pdev->dev, "can not allocate tx dma channel\n"); - ret = PTR_ERR(sspi->tx_chan); - goto free_rx_dma; - } - - sspi->clk = clk_get(&pdev->dev, NULL); - if (IS_ERR(sspi->clk)) { - ret = PTR_ERR(sspi->clk); - goto free_tx_dma; - } - clk_prepare_enable(sspi->clk); - if (spi_comp_data->hwinit) - spi_comp_data->hwinit(sspi); - sspi->ctrl_freq = clk_get_rate(sspi->clk); - - init_completion(&sspi->rx_done); - init_completion(&sspi->tx_done); - - ret = spi_bitbang_start(&sspi->bitbang); - if (ret) - goto free_clk; - dev_info(&pdev->dev, "registered, bus number = %d\n", master->bus_num); - - return 0; -free_clk: - clk_disable_unprepare(sspi->clk); - clk_put(sspi->clk); -free_tx_dma: - dma_release_channel(sspi->tx_chan); -free_rx_dma: - dma_release_channel(sspi->rx_chan); -free_master: - spi_master_put(master); - - return ret; -} - -static int spi_sirfsoc_remove(struct platform_device *pdev) -{ - struct spi_master *master; - struct sirfsoc_spi *sspi; - - master = platform_get_drvdata(pdev); - sspi = spi_master_get_devdata(master); - spi_bitbang_stop(&sspi->bitbang); - clk_disable_unprepare(sspi->clk); - clk_put(sspi->clk); - dma_release_channel(sspi->rx_chan); - dma_release_channel(sspi->tx_chan); - spi_master_put(master); - return 0; -} - -#ifdef CONFIG_PM_SLEEP -static int spi_sirfsoc_suspend(struct device *dev) -{ - struct spi_master *master = dev_get_drvdata(dev); - struct sirfsoc_spi *sspi = spi_master_get_devdata(master); - int ret; - - ret = spi_master_suspend(master); - if (ret) - return ret; - - clk_disable(sspi->clk); - return 0; -} - -static int spi_sirfsoc_resume(struct device *dev) -{ - struct spi_master *master = dev_get_drvdata(dev); - struct sirfsoc_spi *sspi = spi_master_get_devdata(master); - - clk_enable(sspi->clk); - writel(SIRFSOC_SPI_FIFO_RESET, sspi->base + sspi->regs->txfifo_op); - writel(SIRFSOC_SPI_FIFO_RESET, sspi->base + sspi->regs->rxfifo_op); - writel(SIRFSOC_SPI_FIFO_START, sspi->base + sspi->regs->txfifo_op); - writel(SIRFSOC_SPI_FIFO_START, sspi->base + sspi->regs->rxfifo_op); - return 0; -} -#endif - -static SIMPLE_DEV_PM_OPS(spi_sirfsoc_pm_ops, spi_sirfsoc_suspend, - spi_sirfsoc_resume); - -static struct platform_driver spi_sirfsoc_driver = { - .driver = { - .name = DRIVER_NAME, - .pm = &spi_sirfsoc_pm_ops, - .of_match_table = spi_sirfsoc_of_match, - }, - .probe = spi_sirfsoc_probe, - .remove = spi_sirfsoc_remove, -}; -module_platform_driver(spi_sirfsoc_driver); -MODULE_DESCRIPTION("SiRF SoC SPI master driver"); -MODULE_AUTHOR("Zhiwu Song "); -MODULE_AUTHOR("Barry Song "); -MODULE_AUTHOR("Qipan Li "); -MODULE_LICENSE("GPL v2"); -- cgit v1.2.3 From 71ca776a8885aff469f2aa45382518513ecce883 Mon Sep 17 00:00:00 2001 From: Bjorn Andersson Date: Wed, 20 Jan 2021 14:49:00 -0800 Subject: regulator: qcom-rpmh: Add pmc8180 and pmc8180c Add RPMH regulator compatibles for two of the PMIC variants used on the SC8180x platform. Signed-off-by: Bjorn Andersson Link: https://lore.kernel.org/r/20210120224901.1611232-1-bjorn.andersson@linaro.org Signed-off-by: Mark Brown --- Documentation/devicetree/bindings/regulator/qcom,rpmh-regulator.txt | 2 ++ 1 file changed, 2 insertions(+) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/regulator/qcom,rpmh-regulator.txt b/Documentation/devicetree/bindings/regulator/qcom,rpmh-regulator.txt index 7d462b899473..ce1e04354006 100644 --- a/Documentation/devicetree/bindings/regulator/qcom,rpmh-regulator.txt +++ b/Documentation/devicetree/bindings/regulator/qcom,rpmh-regulator.txt @@ -50,6 +50,8 @@ First Level Nodes - PMIC "qcom,pm8350-rpmh-regulators" "qcom,pm8350c-rpmh-regulators" "qcom,pm8998-rpmh-regulators" + "qcom,pmc8180-rpmh-regulators" + "qcom,pmc8180c-rpmh-regulators" "qcom,pmi8998-rpmh-regulators" "qcom,pm6150-rpmh-regulators" "qcom,pm6150l-rpmh-regulators" -- cgit v1.2.3 From 7ebc7dc87103652c552ecd973b9e7bf24ee7c7c2 Mon Sep 17 00:00:00 2001 From: Kir Kolyshkin Date: Tue, 19 Jan 2021 16:18:15 -0800 Subject: docs/scheduler/sched-bwc: formatting fix Since commit d6a3b247627a3 these three lines are merged into one by the RST processor, making it hard to read. Use bullet points to separate the entries, like it's done in other similar places. Signed-off-by: Kir Kolyshkin Acked-by: Tejun Heo Link: https://lore.kernel.org/r/20210120001824.385168-2-kolyshkin@gmail.com Signed-off-by: Jonathan Corbet --- Documentation/scheduler/sched-bwc.rst | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'Documentation') diff --git a/Documentation/scheduler/sched-bwc.rst b/Documentation/scheduler/sched-bwc.rst index 9801d6b284b1..4af4ee1f3600 100644 --- a/Documentation/scheduler/sched-bwc.rst +++ b/Documentation/scheduler/sched-bwc.rst @@ -25,9 +25,10 @@ Management ---------- Quota and period are managed within the cpu subsystem via cgroupfs. -cpu.cfs_quota_us: the total available run-time within a period (in microseconds) -cpu.cfs_period_us: the length of a period (in microseconds) -cpu.stat: exports throttling statistics [explained further below] +- cpu.cfs_quota_us: the total available run-time within a period (in + microseconds) +- cpu.cfs_period_us: the length of a period (in microseconds) +- cpu.stat: exports throttling statistics [explained further below] The default values are:: -- cgit v1.2.3 From f1779d13edf3157d8636b45bd756f9439ebe7d85 Mon Sep 17 00:00:00 2001 From: Kir Kolyshkin Date: Tue, 19 Jan 2021 16:18:16 -0800 Subject: docs/scheduler/sched-design-CFS: formatting fix Fix the rendering of the paragraph. Before the fix, the first line is rendered in bold (I'm not quite sure why) and is also separated from the rest of the paragraph, which is rendered with an indent. Signed-off-by: Kir Kolyshkin Acked-by: Tejun Heo Link: https://lore.kernel.org/r/20210120001824.385168-3-kolyshkin@gmail.com Signed-off-by: Jonathan Corbet --- Documentation/scheduler/sched-design-CFS.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'Documentation') diff --git a/Documentation/scheduler/sched-design-CFS.rst b/Documentation/scheduler/sched-design-CFS.rst index a96c72651877..59b2d1fb4dc4 100644 --- a/Documentation/scheduler/sched-design-CFS.rst +++ b/Documentation/scheduler/sched-design-CFS.rst @@ -34,9 +34,9 @@ In CFS the virtual runtime is expressed and tracked via the per-task p->se.vruntime (nanosec-unit) value. This way, it's possible to accurately timestamp and measure the "expected CPU time" a task should have gotten. -[ small detail: on "ideal" hardware, at any time all tasks would have the same - p->se.vruntime value --- i.e., tasks would execute simultaneously and no task - would ever get "out of balance" from the "ideal" share of CPU time. ] + Small detail: on "ideal" hardware, at any time all tasks would have the same + p->se.vruntime value --- i.e., tasks would execute simultaneously and no task + would ever get "out of balance" from the "ideal" share of CPU time. CFS's task picking logic is based on this p->se.vruntime value and it is thus very simple: it always tries to run the task with the smallest p->se.vruntime -- cgit v1.2.3 From 6c57c12d0f74a1f76dee5b6f7b93a321d57dfd7a Mon Sep 17 00:00:00 2001 From: Kir Kolyshkin Date: Tue, 19 Jan 2021 16:18:17 -0800 Subject: docs/scheduler/sched-bwc: fix note rendering Signed-off-by: Kir Kolyshkin Acked-by: Tejun Heo Link: https://lore.kernel.org/r/20210120001824.385168-4-kolyshkin@gmail.com Signed-off-by: Jonathan Corbet --- Documentation/scheduler/sched-bwc.rst | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'Documentation') diff --git a/Documentation/scheduler/sched-bwc.rst b/Documentation/scheduler/sched-bwc.rst index 4af4ee1f3600..a44860d33ffc 100644 --- a/Documentation/scheduler/sched-bwc.rst +++ b/Documentation/scheduler/sched-bwc.rst @@ -2,8 +2,9 @@ CFS Bandwidth Control ===================== -[ This document only discusses CPU bandwidth control for SCHED_NORMAL. - The SCHED_RT case is covered in Documentation/scheduler/sched-rt-group.rst ] +.. note:: + This document only discusses CPU bandwidth control for SCHED_NORMAL. + The SCHED_RT case is covered in Documentation/scheduler/sched-rt-group.rst CFS bandwidth control is a CONFIG_FAIR_GROUP_SCHED extension which allows the specification of the maximum CPU bandwidth available to a group or hierarchy. -- cgit v1.2.3 From e5ba9ea634501b6820f263a405ae465fee28abb8 Mon Sep 17 00:00:00 2001 From: Kir Kolyshkin Date: Tue, 19 Jan 2021 16:18:19 -0800 Subject: docs/scheduler/sched-bwc: note/link cgroup v2 Signed-off-by: Kir Kolyshkin Acked-by: Tejun Heo Link: https://lore.kernel.org/r/20210120001824.385168-6-kolyshkin@gmail.com Signed-off-by: Jonathan Corbet --- Documentation/admin-guide/cgroup-v2.rst | 4 ++++ Documentation/scheduler/sched-bwc.rst | 5 +++++ 2 files changed, 9 insertions(+) (limited to 'Documentation') diff --git a/Documentation/admin-guide/cgroup-v2.rst b/Documentation/admin-guide/cgroup-v2.rst index e0f6ff7cfa93..b55362454886 100644 --- a/Documentation/admin-guide/cgroup-v2.rst +++ b/Documentation/admin-guide/cgroup-v2.rst @@ -1,3 +1,5 @@ +.. _cgroup-v2: + ================ Control Group v2 ================ @@ -954,6 +956,8 @@ All cgroup core files are prefixed with "cgroup." Controllers =========== +.. _cgroup-v2-cpu: + CPU --- diff --git a/Documentation/scheduler/sched-bwc.rst b/Documentation/scheduler/sched-bwc.rst index a44860d33ffc..845eee659199 100644 --- a/Documentation/scheduler/sched-bwc.rst +++ b/Documentation/scheduler/sched-bwc.rst @@ -26,6 +26,11 @@ Management ---------- Quota and period are managed within the cpu subsystem via cgroupfs. +.. note:: + The cgroupfs files described in this section are only applicable + to cgroup v1. For cgroup v2, see + :ref:`Documentation/admin-guide/cgroupv2.rst `. + - cpu.cfs_quota_us: the total available run-time within a period (in microseconds) - cpu.cfs_period_us: the length of a period (in microseconds) -- cgit v1.2.3 From f6aed68e8a2a646c78801f6c545f9c4db2f4e610 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Wed, 13 Jan 2021 11:59:17 +0100 Subject: hwmon: (ina2) update ti,ina2xx.yaml reference in documentation Changeset 94f1ab944565 ("dt-bindings: hwmon: convert TI INA2xx bindings to dt-schema") renamed: Documentation/devicetree/bindings/hwmon/ina2xx.txt to: Documentation/devicetree/bindings/hwmon/ti,ina2xx.yaml. Update its cross-reference accordingly. Signed-off-by: Mauro Carvalho Chehab Link: https://lore.kernel.org/r/886bd248721b146d844d46e26ddd4cd277f51446.1610535350.git.mchehab+huawei@kernel.org Signed-off-by: Guenter Roeck --- Documentation/hwmon/ina2xx.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Documentation') diff --git a/Documentation/hwmon/ina2xx.rst b/Documentation/hwmon/ina2xx.rst index f78a5cd44c4c..27d2e39bc8ac 100644 --- a/Documentation/hwmon/ina2xx.rst +++ b/Documentation/hwmon/ina2xx.rst @@ -74,7 +74,7 @@ bus supply voltage. The shunt value in micro-ohms can be set via platform data or device tree at compile-time or via the shunt_resistor attribute in sysfs at run-time. Please -refer to the Documentation/devicetree/bindings/hwmon/ina2xx.txt for bindings +refer to the Documentation/devicetree/bindings/hwmon/ti,ina2xx.yaml for bindings if the device tree is used. Additionally ina226 supports update_interval attribute as described in -- cgit v1.2.3 From d41b3365bda7845b28c5a06eef19be0b353cf128 Mon Sep 17 00:00:00 2001 From: George Cherian Date: Tue, 19 Jan 2021 15:31:20 +0530 Subject: docs: octeontx2: Add Documentation for NIX health reporters Add devlink health reporter documentation for NIX block. Signed-off-by: George Cherian Signed-off-by: Jakub Kicinski --- .../device_drivers/ethernet/marvell/octeontx2.rst | 70 ++++++++++++++++++++++ 1 file changed, 70 insertions(+) (limited to 'Documentation') diff --git a/Documentation/networking/device_drivers/ethernet/marvell/octeontx2.rst b/Documentation/networking/device_drivers/ethernet/marvell/octeontx2.rst index 61e850460e18..dd5cd69467be 100644 --- a/Documentation/networking/device_drivers/ethernet/marvell/octeontx2.rst +++ b/Documentation/networking/device_drivers/ethernet/marvell/octeontx2.rst @@ -217,3 +217,73 @@ For example:: NPA_AF_ERR: NPA Error Interrupt Reg : 4096 AQ Doorbell Error + + +NIX Reporters +------------- +The NIX reporters are responsible for reporting and recovering the following group of errors: + +1. GENERAL events + + - Receive mirror/multicast packet drop due to insufficient buffer. + - SMQ Flush operation. + +2. ERROR events + + - Memory Fault due to WQE read/write from multicast/mirror buffer. + - Receive multicast/mirror replication list error. + - Receive packet on an unmapped PF. + - Fault due to NIX_AQ_INST_S read or NIX_AQ_RES_S write. + - AQ Doorbell Error. + +3. RAS events + + - RAS Error Reporting for NIX Receive Multicast/Mirror Entry Structure. + - RAS Error Reporting for WQE/Packet Data read from Multicast/Mirror Buffer.. + - RAS Error Reporting for NIX_AQ_INST_S/NIX_AQ_RES_S. + +4. RVU events + + - Error due to unmapped slot. + +Sample Output:: + + ~# ./devlink health + pci/0002:01:00.0: + reporter hw_npa_intr + state healthy error 0 recover 0 grace_period 0 auto_recover true auto_dump true + reporter hw_npa_gen + state healthy error 0 recover 0 grace_period 0 auto_recover true auto_dump true + reporter hw_npa_err + state healthy error 0 recover 0 grace_period 0 auto_recover true auto_dump true + reporter hw_npa_ras + state healthy error 0 recover 0 grace_period 0 auto_recover true auto_dump true + reporter hw_nix_intr + state healthy error 1121 recover 1121 last_dump_date 2021-01-19 last_dump_time 05:42:26 grace_period 0 auto_recover true auto_dump true + reporter hw_nix_gen + state healthy error 949 recover 949 last_dump_date 2021-01-19 last_dump_time 05:42:43 grace_period 0 auto_recover true auto_dump true + reporter hw_nix_err + state healthy error 1147 recover 1147 last_dump_date 2021-01-19 last_dump_time 05:42:59 grace_period 0 auto_recover true auto_dump true + reporter hw_nix_ras + state healthy error 409 recover 409 last_dump_date 2021-01-19 last_dump_time 05:43:16 grace_period 0 auto_recover true auto_dump true + +Each reporter dumps the + + - Error Type + - Error Register value + - Reason in words + +For example:: + + ~# devlink health dump show pci/0002:01:00.0 reporter hw_nix_intr + NIX_AF_RVU: + NIX RVU Interrupt Reg : 1 + Unmap Slot Error + ~# devlink health dump show pci/0002:01:00.0 reporter hw_nix_gen + NIX_AF_GENERAL: + NIX General Interrupt Reg : 1 + Rx multicast pkt drop + ~# devlink health dump show pci/0002:01:00.0 reporter hw_nix_err + NIX_AF_ERR: + NIX Error Interrupt Reg : 64 + Rx on unmapped PF_FUNC -- cgit v1.2.3 From 00e772c4929257b11b51d47e4645f67826ded0fc Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Wed, 20 Jan 2021 14:30:07 +0100 Subject: irqchip: Remove sigma tango driver The tango platform is getting removed, so the driver is no longer needed. Cc: Marc Gonzalez Cc: Mans Rullgard Signed-off-by: Arnd Bergmann Acked-by: Mans Rullgard Signed-off-by: Marc Zyngier Link: https://lore.kernel.org/r/20210120133008.2421897-2-arnd@kernel.org --- .../interrupt-controller/sigma,smp8642-intc.txt | 48 ----- drivers/irqchip/Kconfig | 5 - drivers/irqchip/Makefile | 1 - drivers/irqchip/irq-tango.c | 227 --------------------- 4 files changed, 281 deletions(-) delete mode 100644 Documentation/devicetree/bindings/interrupt-controller/sigma,smp8642-intc.txt delete mode 100644 drivers/irqchip/irq-tango.c (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/interrupt-controller/sigma,smp8642-intc.txt b/Documentation/devicetree/bindings/interrupt-controller/sigma,smp8642-intc.txt deleted file mode 100644 index 355c18a3a4d3..000000000000 --- a/Documentation/devicetree/bindings/interrupt-controller/sigma,smp8642-intc.txt +++ /dev/null @@ -1,48 +0,0 @@ -Sigma Designs SMP86xx/SMP87xx secondary interrupt controller - -Required properties: -- compatible: should be "sigma,smp8642-intc" -- reg: physical address of MMIO region -- ranges: address space mapping of child nodes -- interrupt-controller: boolean -- #address-cells: should be <1> -- #size-cells: should be <1> - -One child node per control block with properties: -- reg: address of registers for this control block -- interrupt-controller: boolean -- #interrupt-cells: should be <2>, interrupt index and flags per interrupts.txt -- interrupts: interrupt spec of primary interrupt controller - -Example: - -interrupt-controller@6e000 { - compatible = "sigma,smp8642-intc"; - reg = <0x6e000 0x400>; - ranges = <0x0 0x6e000 0x400>; - interrupt-parent = <&gic>; - interrupt-controller; - #address-cells = <1>; - #size-cells = <1>; - - irq0: interrupt-controller@0 { - reg = <0x000 0x100>; - interrupt-controller; - #interrupt-cells = <2>; - interrupts = ; - }; - - irq1: interrupt-controller@100 { - reg = <0x100 0x100>; - interrupt-controller; - #interrupt-cells = <2>; - interrupts = ; - }; - - irq2: interrupt-controller@300 { - reg = <0x300 0x100>; - interrupt-controller; - #interrupt-cells = <2>; - interrupts = ; - }; -}; diff --git a/drivers/irqchip/Kconfig b/drivers/irqchip/Kconfig index 94920a51c628..f95d114c63ed 100644 --- a/drivers/irqchip/Kconfig +++ b/drivers/irqchip/Kconfig @@ -260,11 +260,6 @@ config ST_IRQCHIP help Enables SysCfg Controlled IRQs on STi based platforms. -config TANGO_IRQ - bool - select IRQ_DOMAIN - select GENERIC_IRQ_CHIP - config TB10X_IRQC bool select IRQ_DOMAIN diff --git a/drivers/irqchip/Makefile b/drivers/irqchip/Makefile index 0ac93bfaec61..084e11774071 100644 --- a/drivers/irqchip/Makefile +++ b/drivers/irqchip/Makefile @@ -55,7 +55,6 @@ obj-$(CONFIG_VERSATILE_FPGA_IRQ) += irq-versatile-fpga.o obj-$(CONFIG_ARCH_NSPIRE) += irq-zevio.o obj-$(CONFIG_ARCH_VT8500) += irq-vt8500.o obj-$(CONFIG_ST_IRQCHIP) += irq-st.o -obj-$(CONFIG_TANGO_IRQ) += irq-tango.o obj-$(CONFIG_TB10X_IRQC) += irq-tb10x.o obj-$(CONFIG_TS4800_IRQ) += irq-ts4800.o obj-$(CONFIG_XTENSA) += irq-xtensa-pic.o diff --git a/drivers/irqchip/irq-tango.c b/drivers/irqchip/irq-tango.c deleted file mode 100644 index 34290f09b853..000000000000 --- a/drivers/irqchip/irq-tango.c +++ /dev/null @@ -1,227 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * Copyright (C) 2014 Mans Rullgard - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define IRQ0_CTL_BASE 0x0000 -#define IRQ1_CTL_BASE 0x0100 -#define EDGE_CTL_BASE 0x0200 -#define IRQ2_CTL_BASE 0x0300 - -#define IRQ_CTL_HI 0x18 -#define EDGE_CTL_HI 0x20 - -#define IRQ_STATUS 0x00 -#define IRQ_RAWSTAT 0x04 -#define IRQ_EN_SET 0x08 -#define IRQ_EN_CLR 0x0c -#define IRQ_SOFT_SET 0x10 -#define IRQ_SOFT_CLR 0x14 - -#define EDGE_STATUS 0x00 -#define EDGE_RAWSTAT 0x04 -#define EDGE_CFG_RISE 0x08 -#define EDGE_CFG_FALL 0x0c -#define EDGE_CFG_RISE_SET 0x10 -#define EDGE_CFG_RISE_CLR 0x14 -#define EDGE_CFG_FALL_SET 0x18 -#define EDGE_CFG_FALL_CLR 0x1c - -struct tangox_irq_chip { - void __iomem *base; - unsigned long ctl; -}; - -static inline u32 intc_readl(struct tangox_irq_chip *chip, int reg) -{ - return readl_relaxed(chip->base + reg); -} - -static inline void intc_writel(struct tangox_irq_chip *chip, int reg, u32 val) -{ - writel_relaxed(val, chip->base + reg); -} - -static void tangox_dispatch_irqs(struct irq_domain *dom, unsigned int status, - int base) -{ - unsigned int hwirq; - unsigned int virq; - - while (status) { - hwirq = __ffs(status); - virq = irq_find_mapping(dom, base + hwirq); - if (virq) - generic_handle_irq(virq); - status &= ~BIT(hwirq); - } -} - -static void tangox_irq_handler(struct irq_desc *desc) -{ - struct irq_domain *dom = irq_desc_get_handler_data(desc); - struct irq_chip *host_chip = irq_desc_get_chip(desc); - struct tangox_irq_chip *chip = dom->host_data; - unsigned int status_lo, status_hi; - - chained_irq_enter(host_chip, desc); - - status_lo = intc_readl(chip, chip->ctl + IRQ_STATUS); - status_hi = intc_readl(chip, chip->ctl + IRQ_CTL_HI + IRQ_STATUS); - - tangox_dispatch_irqs(dom, status_lo, 0); - tangox_dispatch_irqs(dom, status_hi, 32); - - chained_irq_exit(host_chip, desc); -} - -static int tangox_irq_set_type(struct irq_data *d, unsigned int flow_type) -{ - struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d); - struct tangox_irq_chip *chip = gc->domain->host_data; - struct irq_chip_regs *regs = &gc->chip_types[0].regs; - - switch (flow_type & IRQ_TYPE_SENSE_MASK) { - case IRQ_TYPE_EDGE_RISING: - intc_writel(chip, regs->type + EDGE_CFG_RISE_SET, d->mask); - intc_writel(chip, regs->type + EDGE_CFG_FALL_CLR, d->mask); - break; - - case IRQ_TYPE_EDGE_FALLING: - intc_writel(chip, regs->type + EDGE_CFG_RISE_CLR, d->mask); - intc_writel(chip, regs->type + EDGE_CFG_FALL_SET, d->mask); - break; - - case IRQ_TYPE_LEVEL_HIGH: - intc_writel(chip, regs->type + EDGE_CFG_RISE_CLR, d->mask); - intc_writel(chip, regs->type + EDGE_CFG_FALL_CLR, d->mask); - break; - - case IRQ_TYPE_LEVEL_LOW: - intc_writel(chip, regs->type + EDGE_CFG_RISE_SET, d->mask); - intc_writel(chip, regs->type + EDGE_CFG_FALL_SET, d->mask); - break; - - default: - pr_err("Invalid trigger mode %x for IRQ %d\n", - flow_type, d->irq); - return -EINVAL; - } - - return irq_setup_alt_chip(d, flow_type); -} - -static void __init tangox_irq_init_chip(struct irq_chip_generic *gc, - unsigned long ctl_offs, - unsigned long edge_offs) -{ - struct tangox_irq_chip *chip = gc->domain->host_data; - struct irq_chip_type *ct = gc->chip_types; - unsigned long ctl_base = chip->ctl + ctl_offs; - unsigned long edge_base = EDGE_CTL_BASE + edge_offs; - int i; - - gc->reg_base = chip->base; - gc->unused = 0; - - for (i = 0; i < 2; i++) { - ct[i].chip.irq_ack = irq_gc_ack_set_bit; - ct[i].chip.irq_mask = irq_gc_mask_disable_reg; - ct[i].chip.irq_mask_ack = irq_gc_mask_disable_and_ack_set; - ct[i].chip.irq_unmask = irq_gc_unmask_enable_reg; - ct[i].chip.irq_set_type = tangox_irq_set_type; - ct[i].chip.name = gc->domain->name; - - ct[i].regs.enable = ctl_base + IRQ_EN_SET; - ct[i].regs.disable = ctl_base + IRQ_EN_CLR; - ct[i].regs.ack = edge_base + EDGE_RAWSTAT; - ct[i].regs.type = edge_base; - } - - ct[0].type = IRQ_TYPE_LEVEL_MASK; - ct[0].handler = handle_level_irq; - - ct[1].type = IRQ_TYPE_EDGE_BOTH; - ct[1].handler = handle_edge_irq; - - intc_writel(chip, ct->regs.disable, 0xffffffff); - intc_writel(chip, ct->regs.ack, 0xffffffff); -} - -static void __init tangox_irq_domain_init(struct irq_domain *dom) -{ - struct irq_chip_generic *gc; - int i; - - for (i = 0; i < 2; i++) { - gc = irq_get_domain_generic_chip(dom, i * 32); - tangox_irq_init_chip(gc, i * IRQ_CTL_HI, i * EDGE_CTL_HI); - } -} - -static int __init tangox_irq_init(void __iomem *base, struct resource *baseres, - struct device_node *node) -{ - struct tangox_irq_chip *chip; - struct irq_domain *dom; - struct resource res; - int irq; - int err; - - irq = irq_of_parse_and_map(node, 0); - if (!irq) - panic("%pOFn: failed to get IRQ", node); - - err = of_address_to_resource(node, 0, &res); - if (err) - panic("%pOFn: failed to get address", node); - - chip = kzalloc(sizeof(*chip), GFP_KERNEL); - chip->ctl = res.start - baseres->start; - chip->base = base; - - dom = irq_domain_add_linear(node, 64, &irq_generic_chip_ops, chip); - if (!dom) - panic("%pOFn: failed to create irqdomain", node); - - err = irq_alloc_domain_generic_chips(dom, 32, 2, node->name, - handle_level_irq, 0, 0, 0); - if (err) - panic("%pOFn: failed to allocate irqchip", node); - - tangox_irq_domain_init(dom); - - irq_set_chained_handler_and_data(irq, tangox_irq_handler, dom); - - return 0; -} - -static int __init tangox_of_irq_init(struct device_node *node, - struct device_node *parent) -{ - struct device_node *c; - struct resource res; - void __iomem *base; - - base = of_iomap(node, 0); - if (!base) - panic("%pOFn: of_iomap failed", node); - - of_address_to_resource(node, 0, &res); - - for_each_child_of_node(node, c) - tangox_irq_init(base, &res, c); - - return 0; -} -IRQCHIP_DECLARE(tangox_intc, "sigma,smp8642-intc", tangox_of_irq_init); -- cgit v1.2.3 From ad6b47cdef760410311f41876b21eb0c6fda4717 Mon Sep 17 00:00:00 2001 From: Samuel Holland Date: Sun, 17 Jan 2021 23:50:31 -0600 Subject: dt-bindings: irq: sun6i-r: Split the binding from sun7i-nmi The R_INTC in the A31 and newer sun8i/sun50i SoCs has additional functionality compared to the sun7i/sun9i NMI controller. Among other things, it multiplexes access to up to 128 interrupts corresponding to (and in parallel to) the first 128 GIC SPIs. This means the NMI is no longer the lowest-numbered hwirq at this irqchip, since it is SPI 32 or 96 (depending on SoC). hwirq 0 now corresponds to SPI 0, usually UART0. To allow access to all multiplexed IRQs, the R_INTC requires a new binding where the interrupt number matches the GIC interrupt number. Otherwise, interrupts with hwirq numbers below the NMI would not be representable in the device tree. For simplicity, copy the three-cell GIC binding; this disambiguates interrupt 0 in the old binding (the NMI) from interrupt 0 in the new binding (SPI 0) by the number of cells. Because the H6 R_INTC has a different mapping from multiplexed IRQs to top-level register bits, it is no longer compatible with the A31 R_INTC. Acked-by: Maxime Ripard Reviewed-by: Rob Herring Signed-off-by: Samuel Holland Signed-off-by: Marc Zyngier Link: https://lore.kernel.org/r/20210118055040.21910-2-samuel@sholland.org --- .../allwinner,sun6i-a31-r-intc.yaml | 66 ++++++++++++++++++++++ .../allwinner,sun7i-a20-sc-nmi.yaml | 10 ---- 2 files changed, 66 insertions(+), 10 deletions(-) create mode 100644 Documentation/devicetree/bindings/interrupt-controller/allwinner,sun6i-a31-r-intc.yaml (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/interrupt-controller/allwinner,sun6i-a31-r-intc.yaml b/Documentation/devicetree/bindings/interrupt-controller/allwinner,sun6i-a31-r-intc.yaml new file mode 100644 index 000000000000..50e607e607c8 --- /dev/null +++ b/Documentation/devicetree/bindings/interrupt-controller/allwinner,sun6i-a31-r-intc.yaml @@ -0,0 +1,66 @@ +# SPDX-License-Identifier: GPL-2.0 +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/interrupt-controller/allwinner,sun6i-a31-r-intc.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Allwinner A31 NMI/Wakeup Interrupt Controller Device Tree Bindings + +maintainers: + - Chen-Yu Tsai + - Maxime Ripard + +allOf: + - $ref: /schemas/interrupt-controller.yaml# + +properties: + "#interrupt-cells": + const: 3 + description: + The first cell is GIC_SPI (0), the second cell is the IRQ number, and + the third cell is the trigger type as defined in interrupt.txt in this + directory. + + compatible: + oneOf: + - const: allwinner,sun6i-a31-r-intc + - items: + - enum: + - allwinner,sun8i-a83t-r-intc + - allwinner,sun50i-a64-r-intc + - const: allwinner,sun6i-a31-r-intc + - const: allwinner,sun50i-h6-r-intc + + reg: + maxItems: 1 + + interrupts: + maxItems: 1 + description: + The GIC interrupt labeled as "External NMI". + + interrupt-controller: true + +required: + - "#interrupt-cells" + - compatible + - reg + - interrupts + - interrupt-controller + +additionalProperties: false + +examples: + - | + #include + + r_intc: interrupt-controller@1f00c00 { + compatible = "allwinner,sun50i-a64-r-intc", + "allwinner,sun6i-a31-r-intc"; + interrupt-controller; + #interrupt-cells = <3>; + reg = <0x01f00c00 0x400>; + interrupts = ; + }; + +... diff --git a/Documentation/devicetree/bindings/interrupt-controller/allwinner,sun7i-a20-sc-nmi.yaml b/Documentation/devicetree/bindings/interrupt-controller/allwinner,sun7i-a20-sc-nmi.yaml index 8acca0ae3129..f34ecc8c7093 100644 --- a/Documentation/devicetree/bindings/interrupt-controller/allwinner,sun7i-a20-sc-nmi.yaml +++ b/Documentation/devicetree/bindings/interrupt-controller/allwinner,sun7i-a20-sc-nmi.yaml @@ -22,23 +22,13 @@ properties: compatible: oneOf: - - const: allwinner,sun6i-a31-r-intc - const: allwinner,sun6i-a31-sc-nmi deprecated: true - const: allwinner,sun7i-a20-sc-nmi - - items: - - const: allwinner,sun8i-a83t-r-intc - - const: allwinner,sun6i-a31-r-intc - const: allwinner,sun9i-a80-nmi - - items: - - const: allwinner,sun50i-a64-r-intc - - const: allwinner,sun6i-a31-r-intc - items: - const: allwinner,sun50i-a100-nmi - const: allwinner,sun9i-a80-nmi - - items: - - const: allwinner,sun50i-h6-r-intc - - const: allwinner,sun6i-a31-r-intc reg: maxItems: 1 -- cgit v1.2.3 From 6436eb4417094ea3308b33d8392fc02a1068dc78 Mon Sep 17 00:00:00 2001 From: Samuel Holland Date: Sun, 17 Jan 2021 23:50:32 -0600 Subject: dt-bindings: irq: sun6i-r: Add a compatible for the H3 The Allwinner H3 SoC contains an R_INTC that is, as far as we know, compatible with the R_INTC present in other sun8i SoCs starting with the A31. Since the R_INTC hardware is undocumented, introduce a new compatible for the R_INTC variant in this SoC, in case there turns out to be some difference. Acked-by: Maxime Ripard Acked-by: Rob Herring Signed-off-by: Samuel Holland Signed-off-by: Marc Zyngier Link: https://lore.kernel.org/r/20210118055040.21910-3-samuel@sholland.org --- .../bindings/interrupt-controller/allwinner,sun6i-a31-r-intc.yaml | 1 + 1 file changed, 1 insertion(+) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/interrupt-controller/allwinner,sun6i-a31-r-intc.yaml b/Documentation/devicetree/bindings/interrupt-controller/allwinner,sun6i-a31-r-intc.yaml index 50e607e607c8..4db24b8a9ffe 100644 --- a/Documentation/devicetree/bindings/interrupt-controller/allwinner,sun6i-a31-r-intc.yaml +++ b/Documentation/devicetree/bindings/interrupt-controller/allwinner,sun6i-a31-r-intc.yaml @@ -27,6 +27,7 @@ properties: - items: - enum: - allwinner,sun8i-a83t-r-intc + - allwinner,sun8i-h3-r-intc - allwinner,sun50i-a64-r-intc - const: allwinner,sun6i-a31-r-intc - const: allwinner,sun50i-h6-r-intc -- cgit v1.2.3 From a21e7bb3d6d954f1db819b5423b885eb2122bffb Mon Sep 17 00:00:00 2001 From: Kir Kolyshkin Date: Tue, 19 Jan 2021 16:18:20 -0800 Subject: docs/admin-guide: cgroup-v2: typos and spaces - fix a typo (mempry -> memory) in a file name; - add space before "(" where appropriate. Signed-off-by: Kir Kolyshkin Acked-by: Tejun Heo Link: https://lore.kernel.org/r/20210120001824.385168-7-kolyshkin@gmail.com Signed-off-by: Jonathan Corbet --- Documentation/admin-guide/cgroup-v2.rst | 34 ++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) (limited to 'Documentation') diff --git a/Documentation/admin-guide/cgroup-v2.rst b/Documentation/admin-guide/cgroup-v2.rst index b55362454886..073f976d44ea 100644 --- a/Documentation/admin-guide/cgroup-v2.rst +++ b/Documentation/admin-guide/cgroup-v2.rst @@ -1263,9 +1263,9 @@ PAGE_SIZE multiple when read back. can show up in the middle. Don't rely on items remaining in a fixed position; use the keys to look up specific values! - If the entry has no per-node counter(or not show in the - mempry.numa_stat). We use 'npn'(non-per-node) as the tag - to indicate that it will not show in the mempry.numa_stat. + If the entry has no per-node counter (or not show in the + memory.numa_stat). We use 'npn' (non-per-node) as the tag + to indicate that it will not show in the memory.numa_stat. anon Amount of memory used in anonymous mappings such as @@ -1281,11 +1281,11 @@ PAGE_SIZE multiple when read back. pagetables Amount of memory allocated for page tables. - percpu(npn) + percpu (npn) Amount of memory used for storing per-cpu kernel data structures. - sock(npn) + sock (npn) Amount of memory used in network transmission buffers shmem @@ -1333,7 +1333,7 @@ PAGE_SIZE multiple when read back. Part of "slab" that cannot be reclaimed on memory pressure. - slab(npn) + slab (npn) Amount of memory used for storing in-kernel data structures. @@ -1361,39 +1361,39 @@ PAGE_SIZE multiple when read back. workingset_nodereclaim Number of times a shadow node has been reclaimed - pgfault(npn) + pgfault (npn) Total number of page faults incurred - pgmajfault(npn) + pgmajfault (npn) Number of major page faults incurred - pgrefill(npn) + pgrefill (npn) Amount of scanned pages (in an active LRU list) - pgscan(npn) + pgscan (npn) Amount of scanned pages (in an inactive LRU list) - pgsteal(npn) + pgsteal (npn) Amount of reclaimed pages - pgactivate(npn) + pgactivate (npn) Amount of pages moved to the active LRU list - pgdeactivate(npn) + pgdeactivate (npn) Amount of pages moved to the inactive LRU list - pglazyfree(npn) + pglazyfree (npn) Amount of pages postponed to be freed under memory pressure - pglazyfreed(npn) + pglazyfreed (npn) Amount of reclaimed lazyfree pages - thp_fault_alloc(npn) + thp_fault_alloc (npn) Number of transparent hugepages which were allocated to satisfy a page fault. This counter is not present when CONFIG_TRANSPARENT_HUGEPAGE is not set. - thp_collapse_alloc(npn) + thp_collapse_alloc (npn) Number of transparent hugepages which were allocated to allow collapsing an existing range of pages. This counter is not present when CONFIG_TRANSPARENT_HUGEPAGE is not set. -- cgit v1.2.3 From 0d17d017fd090b3ec434373adb800cfc0cb6e7f6 Mon Sep 17 00:00:00 2001 From: Kir Kolyshkin Date: Tue, 19 Jan 2021 16:18:21 -0800 Subject: docs/admin-guide: cgroup-v2: fix cgroup.type rendering Due to an extra vertical whitespace, this was not recognised as a definition list entry, and thus was not rendered like the rest of cgroupfs files. Signed-off-by: Kir Kolyshkin Acked-by: Tejun Heo Link: https://lore.kernel.org/r/20210120001824.385168-8-kolyshkin@gmail.com Signed-off-by: Jonathan Corbet --- Documentation/admin-guide/cgroup-v2.rst | 1 - 1 file changed, 1 deletion(-) (limited to 'Documentation') diff --git a/Documentation/admin-guide/cgroup-v2.rst b/Documentation/admin-guide/cgroup-v2.rst index 073f976d44ea..c1b6ffc286cf 100644 --- a/Documentation/admin-guide/cgroup-v2.rst +++ b/Documentation/admin-guide/cgroup-v2.rst @@ -788,7 +788,6 @@ Core Interface Files All cgroup core files are prefixed with "cgroup." cgroup.type - A read-write single value file which exists on non-root cgroups. -- cgit v1.2.3 From 8a32d0fee43d9f4bcaacb3234301a8f1fea8925b Mon Sep 17 00:00:00 2001 From: Kir Kolyshkin Date: Tue, 19 Jan 2021 16:18:22 -0800 Subject: doc/admin-guide/cgroup-v2: use tables MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit These two places are rendered like a table in the source (rst) code, but they are seen as plain text by formatters, and thus are joined together into a single line, e.g.: > “root” - a partition root “member” - a non-root member of a partition This is definitely not what was intended. To fix, use table formatting, like in other places. Signed-off-by: Kir Kolyshkin Acked-by: Tejun Heo Link: https://lore.kernel.org/r/20210120001824.385168-9-kolyshkin@gmail.com Signed-off-by: Jonathan Corbet --- Documentation/admin-guide/cgroup-v2.rst | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) (limited to 'Documentation') diff --git a/Documentation/admin-guide/cgroup-v2.rst b/Documentation/admin-guide/cgroup-v2.rst index c1b6ffc286cf..6f59f13f28d0 100644 --- a/Documentation/admin-guide/cgroup-v2.rst +++ b/Documentation/admin-guide/cgroup-v2.rst @@ -2003,10 +2003,12 @@ Cpuset Interface Files cpuset-enabled cgroups. This flag is owned by the parent cgroup and is not delegatable. - It accepts only the following input values when written to. + It accepts only the following input values when written to. - "root" - a partition root - "member" - a non-root member of a partition + ======== ================================ + "root" a partition root + "member" a non-root member of a partition + ======== ================================ When set to be a partition root, the current cgroup is the root of a new partition or scheduling domain that comprises @@ -2047,9 +2049,11 @@ Cpuset Interface Files root to change. On read, the "cpuset.sched.partition" file can show the following values. - "member" Non-root member of a partition - "root" Partition root - "root invalid" Invalid partition root + ============== ============================== + "member" Non-root member of a partition + "root" Partition root + "root invalid" Invalid partition root + ============== ============================== It is a partition root if the first 2 partition root conditions above are true and at least one CPU from "cpuset.cpus" is -- cgit v1.2.3 From 7361ec680c32d43053fc8a5570b182ff3cda8b1b Mon Sep 17 00:00:00 2001 From: Kir Kolyshkin Date: Tue, 19 Jan 2021 16:18:23 -0800 Subject: docs/admin-guide/cgroup-v2: nit Improper Capitalization. Signed-off-by: Kir Kolyshkin Acked-by: Tejun Heo Link: https://lore.kernel.org/r/20210120001824.385168-10-kolyshkin@gmail.com Signed-off-by: Jonathan Corbet --- Documentation/admin-guide/cgroup-v2.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Documentation') diff --git a/Documentation/admin-guide/cgroup-v2.rst b/Documentation/admin-guide/cgroup-v2.rst index 6f59f13f28d0..136902cd0e98 100644 --- a/Documentation/admin-guide/cgroup-v2.rst +++ b/Documentation/admin-guide/cgroup-v2.rst @@ -2226,7 +2226,7 @@ Without cgroup namespace, the "/proc/$PID/cgroup" file shows the complete path of the cgroup of a process. In a container setup where a set of cgroups and namespaces are intended to isolate processes the "/proc/$PID/cgroup" file may leak potential system level information -to the isolated processes. For Example:: +to the isolated processes. For example:: # cat /proc/self/cgroup 0::/batchjobs/container_id1 -- cgit v1.2.3 From ffcc972a88aa23c5aa728a96f8362a01b7480510 Mon Sep 17 00:00:00 2001 From: Kir Kolyshkin Date: Tue, 19 Jan 2021 16:18:24 -0800 Subject: docs/admin-guide/cgroup-v2: fix mount opt rendering Due to an extra empty line between the option and its description it is rendered not like in other places. Remove the empty lines to fix. Signed-off-by: Kir Kolyshkin Acked-by: Tejun Heo Link: https://lore.kernel.org/r/20210120001824.385168-11-kolyshkin@gmail.com Signed-off-by: Jonathan Corbet --- Documentation/admin-guide/cgroup-v2.rst | 3 --- 1 file changed, 3 deletions(-) (limited to 'Documentation') diff --git a/Documentation/admin-guide/cgroup-v2.rst b/Documentation/admin-guide/cgroup-v2.rst index 136902cd0e98..14a7523c46a4 100644 --- a/Documentation/admin-guide/cgroup-v2.rst +++ b/Documentation/admin-guide/cgroup-v2.rst @@ -174,7 +174,6 @@ disabling controllers in v1 and make them always available in v2. cgroup v2 currently supports the following mount options. nsdelegate - Consider cgroup namespaces as delegation boundaries. This option is system wide and can only be set on mount or modified through remount from the init namespace. The mount option is @@ -182,7 +181,6 @@ cgroup v2 currently supports the following mount options. Delegation section for details. memory_localevents - Only populate memory.events with data for the current cgroup, and not any subtrees. This is legacy behaviour, the default behaviour without this option is to include subtree counts. @@ -191,7 +189,6 @@ cgroup v2 currently supports the following mount options. option is ignored on non-init namespace mounts. memory_recursiveprot - Recursively apply memory.min and memory.low protection to entire subtrees, without requiring explicit downward propagation into leaf cgroups. This allows protecting entire -- cgit v1.2.3 From 1008bfd8e3510f5d7ca1216677e2daec4b9d2add Mon Sep 17 00:00:00 2001 From: Yanteng Si Date: Tue, 19 Jan 2021 11:03:20 +0800 Subject: docs: iio: Correct a typo There are two EP9312, one of them should be 9315 Signed-off-by: Yanteng Si Link: https://lore.kernel.org/r/20210119030320.2860870-1-siyanteng@loongson.cn Signed-off-by: Jonathan Corbet --- Documentation/iio/ep93xx_adc.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Documentation') diff --git a/Documentation/iio/ep93xx_adc.rst b/Documentation/iio/ep93xx_adc.rst index 4fd8dea3f6b8..0af0e9040457 100644 --- a/Documentation/iio/ep93xx_adc.rst +++ b/Documentation/iio/ep93xx_adc.rst @@ -13,7 +13,7 @@ touchscreen/ADC module. ==================== Numbering scheme for channels 0..4 is defined in EP9301 and EP9302 datasheets. -EP9307, EP9312 and EP9312 have 3 channels more (total 8), but the numbering is +EP9307, EP9312 and EP9315 have 3 channels more (total 8), but the numbering is not defined. So the last three are numbered randomly, let's say. Assuming ep93xx_adc is IIO device0, you'd find the following entries under -- cgit v1.2.3 From 047a4aba71e90c4d4f4d9c25b3591130db75315d Mon Sep 17 00:00:00 2001 From: Alex Shi Date: Thu, 21 Jan 2021 10:41:13 +0800 Subject: docs/zh_CN: remove cn_index tag in mips It's a unused tag with a incorrect big name but just for mips arch. So remove it. Signed-off-by: Alex Shi Cc: Yanteng Si Cc: Jonathan Corbet Cc: linux-doc@vger.kernel.org Link: https://lore.kernel.org/r/20210121024113.16344-1-alex.shi@linux.alibaba.com Signed-off-by: Jonathan Corbet --- Documentation/translations/zh_CN/mips/index.rst | 3 --- 1 file changed, 3 deletions(-) (limited to 'Documentation') diff --git a/Documentation/translations/zh_CN/mips/index.rst b/Documentation/translations/zh_CN/mips/index.rst index 27a2eae8484a..b85033f9d67c 100644 --- a/Documentation/translations/zh_CN/mips/index.rst +++ b/Documentation/translations/zh_CN/mips/index.rst @@ -5,9 +5,6 @@ :Original: :doc:`../../../mips/index` :Translator: Yanteng Si -.. _cn_index: - - =========================== MIPS特性文档 =========================== -- cgit v1.2.3 From f7775c20847c7c46ffdd1b03a9238bc791b7efaa Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Sun, 17 Jan 2021 13:33:51 -0800 Subject: AFS: Documentation: fix a few typos in afs.rst Fix typos (punctuation, grammar, spelling) in afs.rst. Signed-off-by: Randy Dunlap Cc: David Howells Cc: linux-afs@lists.infradead.org Cc: Jonathan Corbet Cc: linux-doc@vger.kernel.org Link: https://lore.kernel.org/r/20210117213351.1075-1-rdunlap@infradead.org Signed-off-by: Jonathan Corbet --- Documentation/filesystems/afs.rst | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'Documentation') diff --git a/Documentation/filesystems/afs.rst b/Documentation/filesystems/afs.rst index 0abb155ac666..ca062a7f8ee2 100644 --- a/Documentation/filesystems/afs.rst +++ b/Documentation/filesystems/afs.rst @@ -109,7 +109,7 @@ Mountpoints AFS has a concept of mountpoints. In AFS terms, these are specially formatted symbolic links (of the same form as the "device name" passed to mount). kAFS presents these to the user as directories that have a follow-link capability -(ie: symbolic link semantics). If anyone attempts to access them, they will +(i.e.: symbolic link semantics). If anyone attempts to access them, they will automatically cause the target volume to be mounted (if possible) on that site. Automatically mounted filesystems will be automatically unmounted approximately @@ -144,7 +144,7 @@ looks up a cell of the same name, for example:: Proc Filesystem =============== -The AFS modules creates a "/proc/fs/afs/" directory and populates it: +The AFS module creates a "/proc/fs/afs/" directory and populates it: (*) A "cells" file that lists cells currently known to the afs module and their usage counts:: @@ -201,7 +201,7 @@ And then run as:: ./klog Assuming it's successful, this adds a key of type RxRPC, named for the service -and cell, eg: "afs@". This can be viewed with the keyctl program or +and cell, e.g.: "afs@". This can be viewed with the keyctl program or by cat'ing /proc/keys:: [root@andromeda ~]# keyctl show @@ -211,7 +211,7 @@ by cat'ing /proc/keys:: 111416553 --als--v 0 0 \_ rxrpc: afs@CAMBRIDGE.REDHAT.COM Currently the username, realm, password and proposed ticket lifetime are -compiled in to the program. +compiled into the program. It is not required to acquire a key before using AFS facilities, but if one is not acquired then all operations will be governed by the anonymous user parts -- cgit v1.2.3 From fdca7cb995aea31072f65cbef8a758b87358f5ac Mon Sep 17 00:00:00 2001 From: Andre Przywara Date: Mon, 18 Jan 2021 02:08:30 +0000 Subject: dt-bindings: pinctrl: Add Allwinner H616 compatible strings A new SoC, a new compatible string. Also we were too miserly with just allowing seven interrupt banks. Signed-off-by: Andre Przywara Acked-by: Maxime Ripard Link: https://lore.kernel.org/r/20210118020848.11721-4-andre.przywara@arm.com Signed-off-by: Linus Walleij --- .../bindings/pinctrl/allwinner,sun4i-a10-pinctrl.yaml | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/pinctrl/allwinner,sun4i-a10-pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/allwinner,sun4i-a10-pinctrl.yaml index 5240487dfe50..cce63c3cc463 100644 --- a/Documentation/devicetree/bindings/pinctrl/allwinner,sun4i-a10-pinctrl.yaml +++ b/Documentation/devicetree/bindings/pinctrl/allwinner,sun4i-a10-pinctrl.yaml @@ -53,6 +53,8 @@ properties: - allwinner,sun50i-h5-pinctrl - allwinner,sun50i-h6-pinctrl - allwinner,sun50i-h6-r-pinctrl + - allwinner,sun50i-h616-pinctrl + - allwinner,sun50i-h616-r-pinctrl - allwinner,suniv-f1c100s-pinctrl - nextthing,gr8-pinctrl @@ -61,7 +63,7 @@ properties: interrupts: minItems: 1 - maxItems: 7 + maxItems: 8 description: One interrupt per external interrupt bank supported on the controller, sorted by bank number ascending order. @@ -91,7 +93,7 @@ properties: bank found in the controller $ref: /schemas/types.yaml#/definitions/uint32-array minItems: 1 - maxItems: 5 + maxItems: 8 patternProperties: # It's pretty scary, but the basic idea is that: @@ -145,6 +147,17 @@ allOf: # boards are defining it at the moment so it would generate a lot of # warnings. + - if: + properties: + compatible: + enum: + - allwinner,sun50i-h616-pinctrl + + then: + properties: + interrupts: + minItems: 8 + - if: properties: compatible: -- cgit v1.2.3 From 27bb36ed7775683a957f57c1c368d319c85f2e4f Mon Sep 17 00:00:00 2001 From: Alex Elder Date: Wed, 20 Jan 2021 15:26:04 -0600 Subject: dt-bindings: net: remove modem-remoteproc property The IPA driver uses the remoteproc SSR notifier now, rather than the temporary IPA notification system used initially. As a result it no longer needs a property identifying the modem subsystem DT node. Use GIC_SPI rather than 0 in the example interrupt definition. Signed-off-by: Alex Elder Signed-off-by: Jakub Kicinski --- Documentation/devicetree/bindings/net/qcom,ipa.yaml | 15 +++------------ 1 file changed, 3 insertions(+), 12 deletions(-) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/net/qcom,ipa.yaml b/Documentation/devicetree/bindings/net/qcom,ipa.yaml index 8a2d12644675..8f86084bf12e 100644 --- a/Documentation/devicetree/bindings/net/qcom,ipa.yaml +++ b/Documentation/devicetree/bindings/net/qcom,ipa.yaml @@ -113,13 +113,6 @@ properties: performing early IPA initialization, including loading and validating firwmare used by the GSI. - modem-remoteproc: - $ref: /schemas/types.yaml#/definitions/phandle - description: - This defines the phandle to the remoteproc node representing - the modem subsystem. This is requied so the IPA driver can - receive and act on notifications of modem up/down events. - memory-region: maxItems: 1 description: @@ -135,7 +128,6 @@ required: - interrupts - interconnects - qcom,smem-states - - modem-remoteproc oneOf: - required: @@ -147,7 +139,7 @@ additionalProperties: false examples: - | - #include + #include #include #include @@ -168,7 +160,6 @@ examples: compatible = "qcom,sdm845-ipa"; modem-init; - modem-remoteproc = <&mss_pil>; iommus = <&apps_smmu 0x720 0x3>; reg = <0x1e40000 0x7000>, @@ -178,8 +169,8 @@ examples: "ipa-shared", "gsi"; - interrupts-extended = <&intc 0 311 IRQ_TYPE_EDGE_RISING>, - <&intc 0 432 IRQ_TYPE_LEVEL_HIGH>, + interrupts-extended = <&intc GIC_SPI 311 IRQ_TYPE_EDGE_RISING>, + <&intc GIC_SPI 432 IRQ_TYPE_LEVEL_HIGH>, <&ipa_smp2p_in 0 IRQ_TYPE_EDGE_RISING>, <&ipa_smp2p_in 1 IRQ_TYPE_EDGE_RISING>; interrupt-names = "ipa", -- cgit v1.2.3 From da6336e2484a382b8d080fd9ede1114b5c98b7b0 Mon Sep 17 00:00:00 2001 From: Devajith V S Date: Sun, 13 Dec 2020 22:54:35 +0530 Subject: dt-bindings: iio: accel: kxcjk1013: Document regulator supplies kxcjk1013 devices have VDD and VDDIO power lines. Need to make sure the regulators are enabled before any communication with kxcjk1013. Document support for vdd/vddio-supply to implement this. Signed-off-by: Devajith V S Reviewed-by: Rob Herring Link: https://lore.kernel.org/r/20201213172437.2779-1-devajithvs@gmail.com Signed-off-by: Jonathan Cameron --- Documentation/devicetree/bindings/iio/accel/kionix,kxcjk1013.yaml | 3 +++ 1 file changed, 3 insertions(+) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/iio/accel/kionix,kxcjk1013.yaml b/Documentation/devicetree/bindings/iio/accel/kionix,kxcjk1013.yaml index 5667d09dfe6a..fbb714431e3d 100644 --- a/Documentation/devicetree/bindings/iio/accel/kionix,kxcjk1013.yaml +++ b/Documentation/devicetree/bindings/iio/accel/kionix,kxcjk1013.yaml @@ -20,6 +20,9 @@ properties: reg: maxItems: 1 + vdd-supply: true + vddio-supply: true + mount-matrix: description: an optional 3x3 mounting rotation matrix. -- cgit v1.2.3 From fe28b2aa52a92401d58ef6fc7283127030c2947b Mon Sep 17 00:00:00 2001 From: Stephan Gerhold Date: Fri, 11 Dec 2020 19:38:14 +0100 Subject: dt-bindings: iio: gyroscope: bmg160: Document regulator supplies BMG160 needs VDD and VDDIO regulators that might need to be explicitly enabled. Document support for vdd/vddio-supply to implement this. Signed-off-by: Stephan Gerhold Reviewed-by: Linus Walleij Reviewed-by: Rob Herring Link: https://lore.kernel.org/r/20201211183815.51269-1-stephan@gerhold.net Signed-off-by: Jonathan Cameron --- Documentation/devicetree/bindings/iio/gyroscope/bosch,bmg160.yaml | 3 +++ 1 file changed, 3 insertions(+) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/iio/gyroscope/bosch,bmg160.yaml b/Documentation/devicetree/bindings/iio/gyroscope/bosch,bmg160.yaml index 0466483be6bb..b6bbc312a7cf 100644 --- a/Documentation/devicetree/bindings/iio/gyroscope/bosch,bmg160.yaml +++ b/Documentation/devicetree/bindings/iio/gyroscope/bosch,bmg160.yaml @@ -19,6 +19,9 @@ properties: reg: maxItems: 1 + vdd-supply: true + vddio-supply: true + interrupts: minItems: 1 description: -- cgit v1.2.3 From 3cc718bc798f6dcba43fecafe2be81f0d612c56d Mon Sep 17 00:00:00 2001 From: Ye Xiang Date: Tue, 15 Dec 2020 13:44:44 +0800 Subject: iio:Documentation: Add documentation for hinge sensor channels Add channel description for hinge sensor, including channel label attribute and raw data description. Signed-off-by: Ye Xiang Link: https://lore.kernel.org/r/20201215054444.9324-4-xiang.ye@intel.com Signed-off-by: Jonathan Cameron --- Documentation/ABI/testing/sysfs-bus-iio | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'Documentation') diff --git a/Documentation/ABI/testing/sysfs-bus-iio b/Documentation/ABI/testing/sysfs-bus-iio index 35289d47d6cb..d957f5da5c04 100644 --- a/Documentation/ABI/testing/sysfs-bus-iio +++ b/Documentation/ABI/testing/sysfs-bus-iio @@ -198,6 +198,7 @@ Description: Units after application of scale and offset are m/s^2. What: /sys/bus/iio/devices/iio:deviceX/in_angl_raw +What: /sys/bus/iio/devices/iio:deviceX/in_anglY_raw KernelVersion: 4.17 Contact: linux-iio@vger.kernel.org Description: @@ -1812,3 +1813,13 @@ Contact: linux-iio@vger.kernel.org Description: Unscaled light intensity according to CIE 1931/DIN 5033 color space. Units after application of scale are nano nanowatts per square meter. + +What: /sys/bus/iio/devices/iio:deviceX/in_anglY_label +KernelVersion: 5.12 +Contact: linux-iio@vger.kernel.org +Description: + Optional symbolic label for channel Y. + For Intel hid hinge sensor, the label values are: + hinge, keyboard, screen. It means the three channels + each correspond respectively to hinge angle, keyboard angle, + and screen angle. -- cgit v1.2.3 From 111a10d4991409fc84b0d9c510d8d497da5cf21c Mon Sep 17 00:00:00 2001 From: Stephan Gerhold Date: Sat, 9 Jan 2021 16:23:26 +0100 Subject: dt-bindings: iio: magnetometer: bmc150: Document regulator supplies BMC150 needs VDD and VDDIO regulators that might need to be explicitly enabled. Document support for vdd/vddio-supply to implement this. Reviewed-by: Linus Walleij Reviewed-by: Rob Herring Signed-off-by: Stephan Gerhold Link: https://lore.kernel.org/r/20210109152327.512538-1-stephan@gerhold.net Signed-off-by: Jonathan Cameron --- .../devicetree/bindings/iio/magnetometer/bosch,bmc150_magn.yaml | 3 +++ 1 file changed, 3 insertions(+) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/iio/magnetometer/bosch,bmc150_magn.yaml b/Documentation/devicetree/bindings/iio/magnetometer/bosch,bmc150_magn.yaml index cdef7aeba708..2867ab6bf9b0 100644 --- a/Documentation/devicetree/bindings/iio/magnetometer/bosch,bmc150_magn.yaml +++ b/Documentation/devicetree/bindings/iio/magnetometer/bosch,bmc150_magn.yaml @@ -30,6 +30,9 @@ properties: reg: maxItems: 1 + vdd-supply: true + vddio-supply: true + interrupts: maxItems: 1 -- cgit v1.2.3 From e904cc899293fe3502cff2bb4049fc75a5fd3ecb Mon Sep 17 00:00:00 2001 From: Cristian Pop Date: Fri, 15 Jan 2021 13:21:03 +0200 Subject: dt-bindings: iio: dac: AD5766 yaml documentation This adds device tree bindings for the AD5766 DAC. Signed-off-by: Cristian Pop Reviewed-by: Rob Herring Link: https://lore.kernel.org/r/20210115112105.58652-1-cristian.pop@analog.com Signed-off-by: Jonathan Cameron --- .../devicetree/bindings/iio/dac/adi,ad5766.yaml | 63 ++++++++++++++++++++++ 1 file changed, 63 insertions(+) create mode 100644 Documentation/devicetree/bindings/iio/dac/adi,ad5766.yaml (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/iio/dac/adi,ad5766.yaml b/Documentation/devicetree/bindings/iio/dac/adi,ad5766.yaml new file mode 100644 index 000000000000..d5c54813ce87 --- /dev/null +++ b/Documentation/devicetree/bindings/iio/dac/adi,ad5766.yaml @@ -0,0 +1,63 @@ +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) +# Copyright 2020 Analog Devices Inc. +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/iio/dac/adi,ad5766.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Analog Devices AD5766 DAC device driver + +maintainers: + - Cristian Pop + +description: | + Bindings for the Analog Devices AD5766 current DAC device. Datasheet can be + found here: + https://www.analog.com/media/en/technical-documentation/data-sheets/ad5766-5767.pdf + +properties: + compatible: + enum: + - adi,ad5766 + - adi,ad5767 + + output-range-microvolts: + description: Select converter output range. + + reg: + maxItems: 1 + + spi-max-frequency: + maximum: 1000000 + + spi-cpol: true + + reset-gpios: + description: GPIO spec for the RESET pin. As the line is active low, it + should be marked GPIO_ACTIVE_LOW. + maxItems: 1 + +required: + - compatible + - output-range-microvolts + - reg + - spi-max-frequency + - spi-cpol + +additionalProperties: false + +examples: + - | + spi { + #address-cells = <1>; + #size-cells = <0>; + + ad5766@0 { + compatible = "adi,ad5766"; + output-range-microvolts = <(-5000) 5000>; + reg = <0>; + spi-cpol; + spi-max-frequency = <1000000>; + reset-gpios = <&gpio 22 0>; + }; + }; -- cgit v1.2.3 From b1a1fd93e11adb71a1d28a739bc58816e90fe1e5 Mon Sep 17 00:00:00 2001 From: Cristian Pop Date: Fri, 15 Jan 2021 13:21:04 +0200 Subject: Documentation/ABI/testing: Add documentation for AD5766 new ABI New interface is proposed for dither functionality. This future allows composing an external signals to the selected output channel. The dither signal can be turned on/off, scaled, inverted, or it can be selected from different sources. Signed-off-by: Cristian Pop Link: https://lore.kernel.org/r/20210115112105.58652-2-cristian.pop@analog.com Signed-off-by: Jonathan Cameron --- Documentation/ABI/testing/sysfs-bus-iio-dac-ad5766 | 31 ++++++++++++++++++++++ 1 file changed, 31 insertions(+) create mode 100644 Documentation/ABI/testing/sysfs-bus-iio-dac-ad5766 (limited to 'Documentation') diff --git a/Documentation/ABI/testing/sysfs-bus-iio-dac-ad5766 b/Documentation/ABI/testing/sysfs-bus-iio-dac-ad5766 new file mode 100644 index 000000000000..7fbcba15bf1e --- /dev/null +++ b/Documentation/ABI/testing/sysfs-bus-iio-dac-ad5766 @@ -0,0 +1,31 @@ +What: /sys/bus/iio/devices/iio:deviceX/in_voltageY_dither_enable +KernelVersion: 5.12 +Contact: linux-iio@vger.kernel.org +Description: + Dither enable. Write 1 to enable dither or 0 to disable it. + +What: /sys/bus/iio/devices/iio:deviceX/in_voltageY_dither_invert +KernelVersion: 5.12 +Contact: linux-iio@vger.kernel.org +Description: + Inverts the dither applied to the selected DAC channel. Dither is not + inverted by default. Write "1" to invert dither. + +What: /sys/bus/iio/devices/iio:deviceX/in_voltageY_dither_scale_available +KernelVersion: 5.12 +Contact: linux-iio@vger.kernel.org +Description: + Returns possible scalings available for the current channel. + +What: /sys/bus/iio/devices/iio:deviceX/in_voltageY_dither_scale +KernelVersion: 5.12 +Contact: linux-iio@vger.kernel.org +Description: + Scales the dither before it is applied to the selected channel. + +What: /sys/bus/iio/devices/iio:deviceX/in_voltageY_dither_source +KernelVersion: 5.12 +Contact: linux-iio@vger.kernel.org +Description: + Selects dither source applied to the selected channel. Write "0" to + select N0 source, write "1" to select N1 source. -- cgit v1.2.3 From d1004b707d8b4c05f20bed7506b99d58495d9046 Mon Sep 17 00:00:00 2001 From: Alexandre Belloni Date: Sun, 10 Jan 2021 00:11:43 +0100 Subject: dt-bindings: trivial-devices: reorder memsic devices Reorder memsic compatible strings alphabetically Signed-off-by: Alexandre Belloni Acked-by: Rob Herring Link: https://lore.kernel.org/r/20210109231148.1168104-2-alexandre.belloni@bootlin.com Signed-off-by: Jonathan Cameron --- Documentation/devicetree/bindings/trivial-devices.yaml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/trivial-devices.yaml b/Documentation/devicetree/bindings/trivial-devices.yaml index bdc2dc318178..e9b64be4b91e 100644 --- a/Documentation/devicetree/bindings/trivial-devices.yaml +++ b/Documentation/devicetree/bindings/trivial-devices.yaml @@ -148,10 +148,6 @@ properties: - maxim,max31730 # mCube 3-axis 8-bit digital accelerometer - mcube,mc3230 - # MEMSIC magnetometer - - memsic,mmc35240 - # MEMSIC 2-axis 8-bit digital accelerometer - - memsic,mxc6225 # Measurement Specialities I2C temperature and humidity sensor - meas,htu21 # Measurement Specialities I2C pressure and temperature sensor @@ -166,6 +162,10 @@ properties: - meas,ms8607-temppressure # Measurement Specialties temperature sensor - meas,tsys01 + # MEMSIC magnetometer + - memsic,mmc35240 + # MEMSIC 2-axis 8-bit digital accelerometer + - memsic,mxc6225 # Microchip differential I2C ADC, 1 Channel, 18 bit - microchip,mcp3421 # Microchip differential I2C ADC, 2 Channel, 18 bit -- cgit v1.2.3 From 649ef114a0a05541f9241442fa6b9c9bef457bb4 Mon Sep 17 00:00:00 2001 From: Alexandre Belloni Date: Sun, 10 Jan 2021 00:11:48 +0100 Subject: iio:pressure:ms5637: add ms5803 support The ms5803 is very similar to the ms5805 but has less resolution options and has the 128bit PROM layout. Signed-off-by: Alexandre Belloni Acked-by: Rob Herring Link: https://lore.kernel.org/r/20210109231148.1168104-7-alexandre.belloni@bootlin.com Signed-off-by: Jonathan Cameron --- Documentation/devicetree/bindings/trivial-devices.yaml | 2 ++ drivers/iio/pressure/ms5637.c | 8 ++++++++ 2 files changed, 10 insertions(+) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/trivial-devices.yaml b/Documentation/devicetree/bindings/trivial-devices.yaml index e9b64be4b91e..a327130d1faa 100644 --- a/Documentation/devicetree/bindings/trivial-devices.yaml +++ b/Documentation/devicetree/bindings/trivial-devices.yaml @@ -153,6 +153,8 @@ properties: # Measurement Specialities I2C pressure and temperature sensor - meas,ms5637 # Measurement Specialities I2C pressure and temperature sensor + - meas,ms5803 + # Measurement Specialities I2C pressure and temperature sensor - meas,ms5805 # Measurement Specialities I2C pressure and temperature sensor - meas,ms5837 diff --git a/drivers/iio/pressure/ms5637.c b/drivers/iio/pressure/ms5637.c index 0a6034342714..81f683321b23 100644 --- a/drivers/iio/pressure/ms5637.c +++ b/drivers/iio/pressure/ms5637.c @@ -200,8 +200,15 @@ static const struct ms_tp_hw_data ms5637_hw_data = { .max_res_index = 5 }; +static const struct ms_tp_hw_data ms5803_hw_data = { + .prom_len = 8, + .max_res_index = 4 +}; + static const struct ms_tp_data ms5637_data = { .name = "ms5637", .hw = &ms5637_hw_data }; +static const struct ms_tp_data ms5803_data = { .name = "ms5803", .hw = &ms5803_hw_data }; + static const struct ms_tp_data ms5805_data = { .name = "ms5805", .hw = &ms5637_hw_data }; static const struct ms_tp_data ms5837_data = { .name = "ms5837", .hw = &ms5637_hw_data }; @@ -222,6 +229,7 @@ MODULE_DEVICE_TABLE(i2c, ms5637_id); static const struct of_device_id ms5637_of_match[] = { { .compatible = "meas,ms5637", .data = &ms5637_data }, + { .compatible = "meas,ms5803", .data = &ms5803_data }, { .compatible = "meas,ms5805", .data = &ms5805_data }, { .compatible = "meas,ms5837", .data = &ms5837_data }, { .compatible = "meas,ms8607-temppressure", .data = &ms8607_data }, -- cgit v1.2.3 From 2cea84ddae1cc3af3969bfeae015aa303bf6e08d Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Wed, 20 Jan 2021 14:28:32 +0100 Subject: i2c: remove sirf bus driver The CSR SiRF prima2/atlas platforms are getting removed, so this driver is no longer needed. Signed-off-by: Arnd Bergmann Acked-by: Barry Song Signed-off-by: Wolfram Sang --- Documentation/devicetree/bindings/i2c/i2c-sirf.txt | 19 - drivers/i2c/busses/Kconfig | 10 - drivers/i2c/busses/Makefile | 1 - drivers/i2c/busses/i2c-sirf.c | 475 --------------------- 4 files changed, 505 deletions(-) delete mode 100644 Documentation/devicetree/bindings/i2c/i2c-sirf.txt delete mode 100644 drivers/i2c/busses/i2c-sirf.c (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/i2c/i2c-sirf.txt b/Documentation/devicetree/bindings/i2c/i2c-sirf.txt deleted file mode 100644 index 2701eefb00f7..000000000000 --- a/Documentation/devicetree/bindings/i2c/i2c-sirf.txt +++ /dev/null @@ -1,19 +0,0 @@ -I2C for SiRFprimaII platforms - -Required properties : -- compatible : Must be "sirf,prima2-i2c" -- reg: physical base address of the controller and length of memory mapped - region. -- interrupts: interrupt number to the cpu. - -Optional properties: -- clock-frequency : Constains desired I2C/HS-I2C bus clock frequency in Hz. - The absence of the property indicates the default frequency 100 kHz. - -Examples : - -i2c0: i2c@b00e0000 { - compatible = "sirf,prima2-i2c"; - reg = <0xb00e0000 0x10000>; - interrupts = <24>; -}; diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig index fd919f9339d6..ce2efb56df54 100644 --- a/drivers/i2c/busses/Kconfig +++ b/drivers/i2c/busses/Kconfig @@ -993,16 +993,6 @@ config I2C_SIMTEC This driver can also be built as a module. If so, the module will be called i2c-simtec. -config I2C_SIRF - tristate "CSR SiRFprimaII I2C interface" - depends on ARCH_SIRF || COMPILE_TEST - help - If you say yes to this option, support will be included for the - CSR SiRFprimaII I2C interface. - - This driver can also be built as a module. If so, the module - will be called i2c-sirf. - config I2C_SPRD tristate "Spreadtrum I2C interface" depends on I2C=y && (ARCH_SPRD || COMPILE_TEST) diff --git a/drivers/i2c/busses/Makefile b/drivers/i2c/busses/Makefile index 894ff95885b8..1c30bba977ef 100644 --- a/drivers/i2c/busses/Makefile +++ b/drivers/i2c/busses/Makefile @@ -98,7 +98,6 @@ obj-$(CONFIG_I2C_S3C2410) += i2c-s3c2410.o obj-$(CONFIG_I2C_SH7760) += i2c-sh7760.o obj-$(CONFIG_I2C_SH_MOBILE) += i2c-sh_mobile.o obj-$(CONFIG_I2C_SIMTEC) += i2c-simtec.o -obj-$(CONFIG_I2C_SIRF) += i2c-sirf.o obj-$(CONFIG_I2C_SPRD) += i2c-sprd.o obj-$(CONFIG_I2C_ST) += i2c-st.o obj-$(CONFIG_I2C_STM32F4) += i2c-stm32f4.o diff --git a/drivers/i2c/busses/i2c-sirf.c b/drivers/i2c/busses/i2c-sirf.c deleted file mode 100644 index 30db8fafe078..000000000000 --- a/drivers/i2c/busses/i2c-sirf.c +++ /dev/null @@ -1,475 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * I2C bus driver for CSR SiRFprimaII - * - * Copyright (c) 2011 Cambridge Silicon Radio Limited, a CSR plc group company. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define SIRFSOC_I2C_CLK_CTRL 0x00 -#define SIRFSOC_I2C_STATUS 0x0C -#define SIRFSOC_I2C_CTRL 0x10 -#define SIRFSOC_I2C_IO_CTRL 0x14 -#define SIRFSOC_I2C_SDA_DELAY 0x18 -#define SIRFSOC_I2C_CMD_START 0x1C -#define SIRFSOC_I2C_CMD_BUF 0x30 -#define SIRFSOC_I2C_DATA_BUF 0x80 - -#define SIRFSOC_I2C_CMD_BUF_MAX 16 -#define SIRFSOC_I2C_DATA_BUF_MAX 16 - -#define SIRFSOC_I2C_CMD(x) (SIRFSOC_I2C_CMD_BUF + (x)*0x04) -#define SIRFSOC_I2C_DATA_MASK(x) (0xFF<<(((x)&3)*8)) -#define SIRFSOC_I2C_DATA_SHIFT(x) (((x)&3)*8) - -#define SIRFSOC_I2C_DIV_MASK (0xFFFF) - -/* I2C status flags */ -#define SIRFSOC_I2C_STAT_BUSY BIT(0) -#define SIRFSOC_I2C_STAT_TIP BIT(1) -#define SIRFSOC_I2C_STAT_NACK BIT(2) -#define SIRFSOC_I2C_STAT_TR_INT BIT(4) -#define SIRFSOC_I2C_STAT_STOP BIT(6) -#define SIRFSOC_I2C_STAT_CMD_DONE BIT(8) -#define SIRFSOC_I2C_STAT_ERR BIT(9) -#define SIRFSOC_I2C_CMD_INDEX (0x1F<<16) - -/* I2C control flags */ -#define SIRFSOC_I2C_RESET BIT(0) -#define SIRFSOC_I2C_CORE_EN BIT(1) -#define SIRFSOC_I2C_MASTER_MODE BIT(2) -#define SIRFSOC_I2C_CMD_DONE_EN BIT(11) -#define SIRFSOC_I2C_ERR_INT_EN BIT(12) - -#define SIRFSOC_I2C_SDA_DELAY_MASK (0xFF) -#define SIRFSOC_I2C_SCLF_FILTER (3<<8) - -#define SIRFSOC_I2C_START_CMD BIT(0) - -#define SIRFSOC_I2C_CMD_RP(x) ((x)&0x7) -#define SIRFSOC_I2C_NACK BIT(3) -#define SIRFSOC_I2C_WRITE BIT(4) -#define SIRFSOC_I2C_READ BIT(5) -#define SIRFSOC_I2C_STOP BIT(6) -#define SIRFSOC_I2C_START BIT(7) - -#define SIRFSOC_I2C_ERR_NOACK 1 -#define SIRFSOC_I2C_ERR_TIMEOUT 2 - -struct sirfsoc_i2c { - void __iomem *base; - struct clk *clk; - u32 cmd_ptr; /* Current position in CMD buffer */ - u8 *buf; /* Buffer passed by user */ - u32 msg_len; /* Message length */ - u32 finished_len; /* number of bytes read/written */ - u32 read_cmd_len; /* number of read cmd sent */ - int msg_read; /* 1 indicates a read message */ - int err_status; /* 1 indicates an error on bus */ - - u32 sda_delay; /* For suspend/resume */ - u32 clk_div; - int last; /* Last message in transfer, STOP cmd can be sent */ - - struct completion done; /* indicates completion of message transfer */ - struct i2c_adapter adapter; -}; - -static void i2c_sirfsoc_read_data(struct sirfsoc_i2c *siic) -{ - u32 data = 0; - int i; - - for (i = 0; i < siic->read_cmd_len; i++) { - if (!(i & 0x3)) - data = readl(siic->base + SIRFSOC_I2C_DATA_BUF + i); - siic->buf[siic->finished_len++] = - (u8)((data & SIRFSOC_I2C_DATA_MASK(i)) >> - SIRFSOC_I2C_DATA_SHIFT(i)); - } -} - -static void i2c_sirfsoc_queue_cmd(struct sirfsoc_i2c *siic) -{ - u32 regval; - int i = 0; - - if (siic->msg_read) { - while (((siic->finished_len + i) < siic->msg_len) - && (siic->cmd_ptr < SIRFSOC_I2C_CMD_BUF_MAX)) { - regval = SIRFSOC_I2C_READ | SIRFSOC_I2C_CMD_RP(0); - if (((siic->finished_len + i) == - (siic->msg_len - 1)) && siic->last) - regval |= SIRFSOC_I2C_STOP | SIRFSOC_I2C_NACK; - writel(regval, - siic->base + SIRFSOC_I2C_CMD(siic->cmd_ptr++)); - i++; - } - - siic->read_cmd_len = i; - } else { - while ((siic->cmd_ptr < SIRFSOC_I2C_CMD_BUF_MAX - 1) - && (siic->finished_len < siic->msg_len)) { - regval = SIRFSOC_I2C_WRITE | SIRFSOC_I2C_CMD_RP(0); - if ((siic->finished_len == (siic->msg_len - 1)) - && siic->last) - regval |= SIRFSOC_I2C_STOP; - writel(regval, - siic->base + SIRFSOC_I2C_CMD(siic->cmd_ptr++)); - writel(siic->buf[siic->finished_len++], - siic->base + SIRFSOC_I2C_CMD(siic->cmd_ptr++)); - } - } - siic->cmd_ptr = 0; - - /* Trigger the transfer */ - writel(SIRFSOC_I2C_START_CMD, siic->base + SIRFSOC_I2C_CMD_START); -} - -static irqreturn_t i2c_sirfsoc_irq(int irq, void *dev_id) -{ - struct sirfsoc_i2c *siic = (struct sirfsoc_i2c *)dev_id; - u32 i2c_stat = readl(siic->base + SIRFSOC_I2C_STATUS); - - if (i2c_stat & SIRFSOC_I2C_STAT_ERR) { - /* Error conditions */ - siic->err_status = SIRFSOC_I2C_ERR_NOACK; - writel(SIRFSOC_I2C_STAT_ERR, siic->base + SIRFSOC_I2C_STATUS); - - if (i2c_stat & SIRFSOC_I2C_STAT_NACK) - dev_dbg(&siic->adapter.dev, "ACK not received\n"); - else - dev_err(&siic->adapter.dev, "I2C error\n"); - - /* - * Due to hardware ANOMALY, we need to reset I2C earlier after - * we get NOACK while accessing non-existing clients, otherwise - * we will get errors even we access existing clients later - */ - writel(readl(siic->base + SIRFSOC_I2C_CTRL) | SIRFSOC_I2C_RESET, - siic->base + SIRFSOC_I2C_CTRL); - while (readl(siic->base + SIRFSOC_I2C_CTRL) & SIRFSOC_I2C_RESET) - cpu_relax(); - - complete(&siic->done); - } else if (i2c_stat & SIRFSOC_I2C_STAT_CMD_DONE) { - /* CMD buffer execution complete */ - if (siic->msg_read) - i2c_sirfsoc_read_data(siic); - if (siic->finished_len == siic->msg_len) - complete(&siic->done); - else /* Fill a new CMD buffer for left data */ - i2c_sirfsoc_queue_cmd(siic); - - writel(SIRFSOC_I2C_STAT_CMD_DONE, siic->base + SIRFSOC_I2C_STATUS); - } - - return IRQ_HANDLED; -} - -static void i2c_sirfsoc_set_address(struct sirfsoc_i2c *siic, - struct i2c_msg *msg) -{ - unsigned char addr; - u32 regval = SIRFSOC_I2C_START | SIRFSOC_I2C_CMD_RP(0) | SIRFSOC_I2C_WRITE; - - /* no data and last message -> add STOP */ - if (siic->last && (msg->len == 0)) - regval |= SIRFSOC_I2C_STOP; - - writel(regval, siic->base + SIRFSOC_I2C_CMD(siic->cmd_ptr++)); - - addr = i2c_8bit_addr_from_msg(msg); - - /* Reverse direction bit */ - if (msg->flags & I2C_M_REV_DIR_ADDR) - addr ^= 1; - - writel(addr, siic->base + SIRFSOC_I2C_CMD(siic->cmd_ptr++)); -} - -static int i2c_sirfsoc_xfer_msg(struct sirfsoc_i2c *siic, struct i2c_msg *msg) -{ - u32 regval = readl(siic->base + SIRFSOC_I2C_CTRL); - /* timeout waiting for the xfer to finish or fail */ - int timeout = msecs_to_jiffies((msg->len + 1) * 50); - - i2c_sirfsoc_set_address(siic, msg); - - writel(regval | SIRFSOC_I2C_CMD_DONE_EN | SIRFSOC_I2C_ERR_INT_EN, - siic->base + SIRFSOC_I2C_CTRL); - i2c_sirfsoc_queue_cmd(siic); - - if (wait_for_completion_timeout(&siic->done, timeout) == 0) { - siic->err_status = SIRFSOC_I2C_ERR_TIMEOUT; - dev_err(&siic->adapter.dev, "Transfer timeout\n"); - } - - writel(regval & ~(SIRFSOC_I2C_CMD_DONE_EN | SIRFSOC_I2C_ERR_INT_EN), - siic->base + SIRFSOC_I2C_CTRL); - writel(0, siic->base + SIRFSOC_I2C_CMD_START); - - /* i2c control doesn't response, reset it */ - if (siic->err_status == SIRFSOC_I2C_ERR_TIMEOUT) { - writel(readl(siic->base + SIRFSOC_I2C_CTRL) | SIRFSOC_I2C_RESET, - siic->base + SIRFSOC_I2C_CTRL); - while (readl(siic->base + SIRFSOC_I2C_CTRL) & SIRFSOC_I2C_RESET) - cpu_relax(); - } - return siic->err_status ? -EAGAIN : 0; -} - -static u32 i2c_sirfsoc_func(struct i2c_adapter *adap) -{ - return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL; -} - -static int i2c_sirfsoc_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, - int num) -{ - struct sirfsoc_i2c *siic = adap->algo_data; - int i, ret; - - clk_enable(siic->clk); - - for (i = 0; i < num; i++) { - siic->buf = msgs[i].buf; - siic->msg_len = msgs[i].len; - siic->msg_read = !!(msgs[i].flags & I2C_M_RD); - siic->err_status = 0; - siic->cmd_ptr = 0; - siic->finished_len = 0; - siic->last = (i == (num - 1)); - - ret = i2c_sirfsoc_xfer_msg(siic, &msgs[i]); - if (ret) { - clk_disable(siic->clk); - return ret; - } - } - - clk_disable(siic->clk); - return num; -} - -/* I2C algorithms associated with this master controller driver */ -static const struct i2c_algorithm i2c_sirfsoc_algo = { - .master_xfer = i2c_sirfsoc_xfer, - .functionality = i2c_sirfsoc_func, -}; - -static int i2c_sirfsoc_probe(struct platform_device *pdev) -{ - struct sirfsoc_i2c *siic; - struct i2c_adapter *adap; - struct clk *clk; - int bitrate; - int ctrl_speed; - int irq; - - int err; - u32 regval; - - clk = clk_get(&pdev->dev, NULL); - if (IS_ERR(clk)) { - err = PTR_ERR(clk); - dev_err(&pdev->dev, "Clock get failed\n"); - goto err_get_clk; - } - - err = clk_prepare(clk); - if (err) { - dev_err(&pdev->dev, "Clock prepare failed\n"); - goto err_clk_prep; - } - - err = clk_enable(clk); - if (err) { - dev_err(&pdev->dev, "Clock enable failed\n"); - goto err_clk_en; - } - - ctrl_speed = clk_get_rate(clk); - - siic = devm_kzalloc(&pdev->dev, sizeof(*siic), GFP_KERNEL); - if (!siic) { - err = -ENOMEM; - goto out; - } - adap = &siic->adapter; - adap->class = I2C_CLASS_DEPRECATED; - - siic->base = devm_platform_ioremap_resource(pdev, 0); - if (IS_ERR(siic->base)) { - err = PTR_ERR(siic->base); - goto out; - } - - irq = platform_get_irq(pdev, 0); - if (irq < 0) { - err = irq; - goto out; - } - err = devm_request_irq(&pdev->dev, irq, i2c_sirfsoc_irq, 0, - dev_name(&pdev->dev), siic); - if (err) - goto out; - - adap->algo = &i2c_sirfsoc_algo; - adap->algo_data = siic; - adap->retries = 3; - - adap->dev.of_node = pdev->dev.of_node; - adap->dev.parent = &pdev->dev; - adap->nr = pdev->id; - - strlcpy(adap->name, "sirfsoc-i2c", sizeof(adap->name)); - - platform_set_drvdata(pdev, adap); - init_completion(&siic->done); - - /* Controller initialisation */ - - writel(SIRFSOC_I2C_RESET, siic->base + SIRFSOC_I2C_CTRL); - while (readl(siic->base + SIRFSOC_I2C_CTRL) & SIRFSOC_I2C_RESET) - cpu_relax(); - writel(SIRFSOC_I2C_CORE_EN | SIRFSOC_I2C_MASTER_MODE, - siic->base + SIRFSOC_I2C_CTRL); - - siic->clk = clk; - - err = of_property_read_u32(pdev->dev.of_node, - "clock-frequency", &bitrate); - if (err < 0) - bitrate = I2C_MAX_STANDARD_MODE_FREQ; - - /* - * Due to some hardware design issues, we need to tune the formula. - * Since i2c is open drain interface that allows the slave to - * stall the transaction by holding the SCL line at '0', the RTL - * implementation is waiting for SCL feedback from the pin after - * setting it to High-Z ('1'). This wait adds to the high-time - * interval counter few cycles of the input synchronization - * (depending on the SCL_FILTER_REG field), and also the time it - * takes for the board pull-up resistor to rise the SCL line. - * For slow SCL settings these additions are negligible, - * but they start to affect the speed when clock is set to faster - * frequencies. - * Through the actual tests, use the different user_div value(which - * in the divider formula 'Fio / (Fi2c * user_div)') to adapt - * the different ranges of i2c bus clock frequency, to make the SCL - * more accurate. - */ - if (bitrate <= 30000) - regval = ctrl_speed / (bitrate * 5); - else if (bitrate > 30000 && bitrate <= 280000) - regval = (2 * ctrl_speed) / (bitrate * 11); - else - regval = ctrl_speed / (bitrate * 6); - - writel(regval, siic->base + SIRFSOC_I2C_CLK_CTRL); - if (regval > 0xFF) - writel(0xFF, siic->base + SIRFSOC_I2C_SDA_DELAY); - else - writel(regval, siic->base + SIRFSOC_I2C_SDA_DELAY); - - err = i2c_add_numbered_adapter(adap); - if (err < 0) - goto out; - - clk_disable(clk); - - dev_info(&pdev->dev, " I2C adapter ready to operate\n"); - - return 0; - -out: - clk_disable(clk); -err_clk_en: - clk_unprepare(clk); -err_clk_prep: - clk_put(clk); -err_get_clk: - return err; -} - -static int i2c_sirfsoc_remove(struct platform_device *pdev) -{ - struct i2c_adapter *adapter = platform_get_drvdata(pdev); - struct sirfsoc_i2c *siic = adapter->algo_data; - - writel(SIRFSOC_I2C_RESET, siic->base + SIRFSOC_I2C_CTRL); - i2c_del_adapter(adapter); - clk_unprepare(siic->clk); - clk_put(siic->clk); - return 0; -} - -#ifdef CONFIG_PM -static int i2c_sirfsoc_suspend(struct device *dev) -{ - struct i2c_adapter *adapter = dev_get_drvdata(dev); - struct sirfsoc_i2c *siic = adapter->algo_data; - - clk_enable(siic->clk); - siic->sda_delay = readl(siic->base + SIRFSOC_I2C_SDA_DELAY); - siic->clk_div = readl(siic->base + SIRFSOC_I2C_CLK_CTRL); - clk_disable(siic->clk); - return 0; -} - -static int i2c_sirfsoc_resume(struct device *dev) -{ - struct i2c_adapter *adapter = dev_get_drvdata(dev); - struct sirfsoc_i2c *siic = adapter->algo_data; - - clk_enable(siic->clk); - writel(SIRFSOC_I2C_RESET, siic->base + SIRFSOC_I2C_CTRL); - while (readl(siic->base + SIRFSOC_I2C_CTRL) & SIRFSOC_I2C_RESET) - cpu_relax(); - writel(SIRFSOC_I2C_CORE_EN | SIRFSOC_I2C_MASTER_MODE, - siic->base + SIRFSOC_I2C_CTRL); - writel(siic->clk_div, siic->base + SIRFSOC_I2C_CLK_CTRL); - writel(siic->sda_delay, siic->base + SIRFSOC_I2C_SDA_DELAY); - clk_disable(siic->clk); - return 0; -} - -static const struct dev_pm_ops i2c_sirfsoc_pm_ops = { - .suspend = i2c_sirfsoc_suspend, - .resume = i2c_sirfsoc_resume, -}; -#endif - -static const struct of_device_id sirfsoc_i2c_of_match[] = { - { .compatible = "sirf,prima2-i2c", }, - {}, -}; -MODULE_DEVICE_TABLE(of, sirfsoc_i2c_of_match); - -static struct platform_driver i2c_sirfsoc_driver = { - .driver = { - .name = "sirfsoc_i2c", -#ifdef CONFIG_PM - .pm = &i2c_sirfsoc_pm_ops, -#endif - .of_match_table = sirfsoc_i2c_of_match, - }, - .probe = i2c_sirfsoc_probe, - .remove = i2c_sirfsoc_remove, -}; -module_platform_driver(i2c_sirfsoc_driver); - -MODULE_DESCRIPTION("SiRF SoC I2C master controller driver"); -MODULE_AUTHOR("Zhiwu Song "); -MODULE_AUTHOR("Xiangzhen Ye "); -MODULE_LICENSE("GPL v2"); -- cgit v1.2.3 From 1059b2bcc683ab29c25d542af4902bfdb3f91b40 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Wed, 20 Jan 2021 14:28:33 +0100 Subject: i2c: remove u300 bus driver The ST-Ericsson U300 platform is getting removed, so this driver is no longer needed. Signed-off-by: Arnd Bergmann Reviewed-by: Linus Walleij Signed-off-by: Wolfram Sang --- .../devicetree/bindings/i2c/i2c-stu300.txt | 15 - drivers/i2c/busses/Kconfig | 13 - drivers/i2c/busses/Makefile | 1 - drivers/i2c/busses/i2c-stu300.c | 1008 -------------------- 4 files changed, 1037 deletions(-) delete mode 100644 Documentation/devicetree/bindings/i2c/i2c-stu300.txt delete mode 100644 drivers/i2c/busses/i2c-stu300.c (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/i2c/i2c-stu300.txt b/Documentation/devicetree/bindings/i2c/i2c-stu300.txt deleted file mode 100644 index bd81a482634f..000000000000 --- a/Documentation/devicetree/bindings/i2c/i2c-stu300.txt +++ /dev/null @@ -1,15 +0,0 @@ -ST Microelectronics DDC I2C - -Required properties : -- compatible : Must be "st,ddci2c" -- reg: physical base address of the controller and length of memory mapped - region. -- interrupts: interrupt number to the cpu. -- #address-cells = <1>; -- #size-cells = <0>; - -Optional properties: -- Child nodes conforming to i2c bus binding - -Examples : - diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig index ce2efb56df54..4fe74259d44c 100644 --- a/drivers/i2c/busses/Kconfig +++ b/drivers/i2c/busses/Kconfig @@ -1032,19 +1032,6 @@ config I2C_STM32F7 This driver can also be built as module. If so, the module will be called i2c-stm32f7. -config I2C_STU300 - tristate "ST Microelectronics DDC I2C interface" - depends on MACH_U300 || COMPILE_TEST - default y if MACH_U300 - help - If you say yes to this option, support will be included for the - I2C interface from ST Microelectronics simply called "DDC I2C" - supporting both I2C and DDC, used in e.g. the U300 series - mobile platforms. - - This driver can also be built as a module. If so, the module - will be called i2c-stu300. - config I2C_SUN6I_P2WI tristate "Allwinner sun6i internal P2WI controller" depends on RESET_CONTROLLER diff --git a/drivers/i2c/busses/Makefile b/drivers/i2c/busses/Makefile index 1c30bba977ef..572d5fcc6016 100644 --- a/drivers/i2c/busses/Makefile +++ b/drivers/i2c/busses/Makefile @@ -103,7 +103,6 @@ obj-$(CONFIG_I2C_ST) += i2c-st.o obj-$(CONFIG_I2C_STM32F4) += i2c-stm32f4.o i2c-stm32f7-drv-objs := i2c-stm32f7.o i2c-stm32.o obj-$(CONFIG_I2C_STM32F7) += i2c-stm32f7-drv.o -obj-$(CONFIG_I2C_STU300) += i2c-stu300.o obj-$(CONFIG_I2C_SUN6I_P2WI) += i2c-sun6i-p2wi.o obj-$(CONFIG_I2C_SYNQUACER) += i2c-synquacer.o obj-$(CONFIG_I2C_TEGRA) += i2c-tegra.o diff --git a/drivers/i2c/busses/i2c-stu300.c b/drivers/i2c/busses/i2c-stu300.c deleted file mode 100644 index 64d739baf480..000000000000 --- a/drivers/i2c/busses/i2c-stu300.c +++ /dev/null @@ -1,1008 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Copyright (C) 2007-2012 ST-Ericsson AB - * ST DDC I2C master mode driver, used in e.g. U300 series platforms. - * Author: Linus Walleij - * Author: Jonas Aaberg - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* the name of this kernel module */ -#define NAME "stu300" - -/* CR (Control Register) 8bit (R/W) */ -#define I2C_CR (0x00000000) -#define I2C_CR_RESET_VALUE (0x00) -#define I2C_CR_RESET_UMASK (0x00) -#define I2C_CR_DDC1_ENABLE (0x80) -#define I2C_CR_TRANS_ENABLE (0x40) -#define I2C_CR_PERIPHERAL_ENABLE (0x20) -#define I2C_CR_DDC2B_ENABLE (0x10) -#define I2C_CR_START_ENABLE (0x08) -#define I2C_CR_ACK_ENABLE (0x04) -#define I2C_CR_STOP_ENABLE (0x02) -#define I2C_CR_INTERRUPT_ENABLE (0x01) -/* SR1 (Status Register 1) 8bit (R/-) */ -#define I2C_SR1 (0x00000004) -#define I2C_SR1_RESET_VALUE (0x00) -#define I2C_SR1_RESET_UMASK (0x00) -#define I2C_SR1_EVF_IND (0x80) -#define I2C_SR1_ADD10_IND (0x40) -#define I2C_SR1_TRA_IND (0x20) -#define I2C_SR1_BUSY_IND (0x10) -#define I2C_SR1_BTF_IND (0x08) -#define I2C_SR1_ADSL_IND (0x04) -#define I2C_SR1_MSL_IND (0x02) -#define I2C_SR1_SB_IND (0x01) -/* SR2 (Status Register 2) 8bit (R/-) */ -#define I2C_SR2 (0x00000008) -#define I2C_SR2_RESET_VALUE (0x00) -#define I2C_SR2_RESET_UMASK (0x40) -#define I2C_SR2_MASK (0xBF) -#define I2C_SR2_SCLFAL_IND (0x80) -#define I2C_SR2_ENDAD_IND (0x20) -#define I2C_SR2_AF_IND (0x10) -#define I2C_SR2_STOPF_IND (0x08) -#define I2C_SR2_ARLO_IND (0x04) -#define I2C_SR2_BERR_IND (0x02) -#define I2C_SR2_DDC2BF_IND (0x01) -/* CCR (Clock Control Register) 8bit (R/W) */ -#define I2C_CCR (0x0000000C) -#define I2C_CCR_RESET_VALUE (0x00) -#define I2C_CCR_RESET_UMASK (0x00) -#define I2C_CCR_MASK (0xFF) -#define I2C_CCR_FMSM (0x80) -#define I2C_CCR_CC_MASK (0x7F) -/* OAR1 (Own Address Register 1) 8bit (R/W) */ -#define I2C_OAR1 (0x00000010) -#define I2C_OAR1_RESET_VALUE (0x00) -#define I2C_OAR1_RESET_UMASK (0x00) -#define I2C_OAR1_ADD_MASK (0xFF) -/* OAR2 (Own Address Register 2) 8bit (R/W) */ -#define I2C_OAR2 (0x00000014) -#define I2C_OAR2_RESET_VALUE (0x40) -#define I2C_OAR2_RESET_UMASK (0x19) -#define I2C_OAR2_MASK (0xE6) -#define I2C_OAR2_FR_25_10MHZ (0x00) -#define I2C_OAR2_FR_10_1667MHZ (0x20) -#define I2C_OAR2_FR_1667_2667MHZ (0x40) -#define I2C_OAR2_FR_2667_40MHZ (0x60) -#define I2C_OAR2_FR_40_5333MHZ (0x80) -#define I2C_OAR2_FR_5333_66MHZ (0xA0) -#define I2C_OAR2_FR_66_80MHZ (0xC0) -#define I2C_OAR2_FR_80_100MHZ (0xE0) -#define I2C_OAR2_FR_MASK (0xE0) -#define I2C_OAR2_ADD_MASK (0x06) -/* DR (Data Register) 8bit (R/W) */ -#define I2C_DR (0x00000018) -#define I2C_DR_RESET_VALUE (0x00) -#define I2C_DR_RESET_UMASK (0xFF) -#define I2C_DR_D_MASK (0xFF) -/* ECCR (Extended Clock Control Register) 8bit (R/W) */ -#define I2C_ECCR (0x0000001C) -#define I2C_ECCR_RESET_VALUE (0x00) -#define I2C_ECCR_RESET_UMASK (0xE0) -#define I2C_ECCR_MASK (0x1F) -#define I2C_ECCR_CC_MASK (0x1F) - -/* - * These events are more or less responses to commands - * sent into the hardware, presumably reflecting the state - * of an internal state machine. - */ -enum stu300_event { - STU300_EVENT_NONE = 0, - STU300_EVENT_1, - STU300_EVENT_2, - STU300_EVENT_3, - STU300_EVENT_4, - STU300_EVENT_5, - STU300_EVENT_6, - STU300_EVENT_7, - STU300_EVENT_8, - STU300_EVENT_9 -}; - -enum stu300_error { - STU300_ERROR_NONE = 0, - STU300_ERROR_ACKNOWLEDGE_FAILURE, - STU300_ERROR_BUS_ERROR, - STU300_ERROR_ARBITRATION_LOST, - STU300_ERROR_UNKNOWN -}; - -/* timeout waiting for the controller to respond */ -#define STU300_TIMEOUT (msecs_to_jiffies(1000)) - -/* - * The number of address send athemps tried before giving up. - * If the first one fails it seems like 5 to 8 attempts are required. - */ -#define NUM_ADDR_RESEND_ATTEMPTS 12 - -/* I2C clock speed, in Hz 0-400kHz*/ -static unsigned int scl_frequency = I2C_MAX_STANDARD_MODE_FREQ; -module_param(scl_frequency, uint, 0644); - -/** - * struct stu300_dev - the stu300 driver state holder - * @pdev: parent platform device - * @adapter: corresponding I2C adapter - * @clk: hardware block clock - * @irq: assigned interrupt line - * @cmd_issue_lock: this locks the following cmd_ variables - * @cmd_complete: acknowledge completion for an I2C command - * @cmd_event: expected event coming in as a response to a command - * @cmd_err: error code as response to a command - * @speed: current bus speed in Hz - * @msg_index: index of current message - * @msg_len: length of current message - */ - -struct stu300_dev { - struct platform_device *pdev; - struct i2c_adapter adapter; - void __iomem *virtbase; - struct clk *clk; - int irq; - spinlock_t cmd_issue_lock; - struct completion cmd_complete; - enum stu300_event cmd_event; - enum stu300_error cmd_err; - unsigned int speed; - int msg_index; - int msg_len; -}; - -/* Local forward function declarations */ -static int stu300_init_hw(struct stu300_dev *dev); - -/* - * The block needs writes in both MSW and LSW in order - * for all data lines to reach their destination. - */ -static inline void stu300_wr8(u32 value, void __iomem *address) -{ - writel((value << 16) | value, address); -} - -/* - * This merely masks off the duplicates which appear - * in bytes 1-3. You _MUST_ use 32-bit bus access on this - * device, else it will not work. - */ -static inline u32 stu300_r8(void __iomem *address) -{ - return readl(address) & 0x000000FFU; -} - -static void stu300_irq_enable(struct stu300_dev *dev) -{ - u32 val; - val = stu300_r8(dev->virtbase + I2C_CR); - val |= I2C_CR_INTERRUPT_ENABLE; - /* Twice paranoia (possible HW glitch) */ - stu300_wr8(val, dev->virtbase + I2C_CR); - stu300_wr8(val, dev->virtbase + I2C_CR); -} - -static void stu300_irq_disable(struct stu300_dev *dev) -{ - u32 val; - val = stu300_r8(dev->virtbase + I2C_CR); - val &= ~I2C_CR_INTERRUPT_ENABLE; - /* Twice paranoia (possible HW glitch) */ - stu300_wr8(val, dev->virtbase + I2C_CR); - stu300_wr8(val, dev->virtbase + I2C_CR); -} - - -/* - * Tells whether a certain event or events occurred in - * response to a command. The events represent states in - * the internal state machine of the hardware. The events - * are not very well described in the hardware - * documentation and can only be treated as abstract state - * machine states. - * - * @ret 0 = event has not occurred or unknown error, any - * other value means the correct event occurred or an error. - */ - -static int stu300_event_occurred(struct stu300_dev *dev, - enum stu300_event mr_event) { - u32 status1; - u32 status2; - - /* What event happened? */ - status1 = stu300_r8(dev->virtbase + I2C_SR1); - - if (!(status1 & I2C_SR1_EVF_IND)) - /* No event at all */ - return 0; - - status2 = stu300_r8(dev->virtbase + I2C_SR2); - - /* Block any multiple interrupts */ - stu300_irq_disable(dev); - - /* Check for errors first */ - if (status2 & I2C_SR2_AF_IND) { - dev->cmd_err = STU300_ERROR_ACKNOWLEDGE_FAILURE; - return 1; - } else if (status2 & I2C_SR2_BERR_IND) { - dev->cmd_err = STU300_ERROR_BUS_ERROR; - return 1; - } else if (status2 & I2C_SR2_ARLO_IND) { - dev->cmd_err = STU300_ERROR_ARBITRATION_LOST; - return 1; - } - - switch (mr_event) { - case STU300_EVENT_1: - if (status1 & I2C_SR1_ADSL_IND) - return 1; - break; - case STU300_EVENT_2: - case STU300_EVENT_3: - case STU300_EVENT_7: - case STU300_EVENT_8: - if (status1 & I2C_SR1_BTF_IND) { - return 1; - } - break; - case STU300_EVENT_4: - if (status2 & I2C_SR2_STOPF_IND) - return 1; - break; - case STU300_EVENT_5: - if (status1 & I2C_SR1_SB_IND) - /* Clear start bit */ - return 1; - break; - case STU300_EVENT_6: - if (status2 & I2C_SR2_ENDAD_IND) { - /* First check for any errors */ - return 1; - } - break; - case STU300_EVENT_9: - if (status1 & I2C_SR1_ADD10_IND) - return 1; - break; - default: - break; - } - /* If we get here, we're on thin ice. - * Here we are in a status where we have - * gotten a response that does not match - * what we requested. - */ - dev->cmd_err = STU300_ERROR_UNKNOWN; - dev_err(&dev->pdev->dev, - "Unhandled interrupt! %d sr1: 0x%x sr2: 0x%x\n", - mr_event, status1, status2); - return 0; -} - -static irqreturn_t stu300_irh(int irq, void *data) -{ - struct stu300_dev *dev = data; - int res; - - /* Just make sure that the block is clocked */ - clk_enable(dev->clk); - - /* See if this was what we were waiting for */ - spin_lock(&dev->cmd_issue_lock); - - res = stu300_event_occurred(dev, dev->cmd_event); - if (res || dev->cmd_err != STU300_ERROR_NONE) - complete(&dev->cmd_complete); - - spin_unlock(&dev->cmd_issue_lock); - - clk_disable(dev->clk); - - return IRQ_HANDLED; -} - -/* - * Sends a command and then waits for the bits masked by *flagmask* - * to go high or low by IRQ awaiting. - */ -static int stu300_start_and_await_event(struct stu300_dev *dev, - u8 cr_value, - enum stu300_event mr_event) -{ - int ret; - - /* Lock command issue, fill in an event we wait for */ - spin_lock_irq(&dev->cmd_issue_lock); - init_completion(&dev->cmd_complete); - dev->cmd_err = STU300_ERROR_NONE; - dev->cmd_event = mr_event; - spin_unlock_irq(&dev->cmd_issue_lock); - - /* Turn on interrupt, send command and wait. */ - cr_value |= I2C_CR_INTERRUPT_ENABLE; - stu300_wr8(cr_value, dev->virtbase + I2C_CR); - ret = wait_for_completion_interruptible_timeout(&dev->cmd_complete, - STU300_TIMEOUT); - if (ret < 0) { - dev_err(&dev->pdev->dev, - "wait_for_completion_interruptible_timeout() " - "returned %d waiting for event %04x\n", ret, mr_event); - return ret; - } - - if (ret == 0) { - dev_err(&dev->pdev->dev, "controller timed out " - "waiting for event %d, reinit hardware\n", mr_event); - (void) stu300_init_hw(dev); - return -ETIMEDOUT; - } - - if (dev->cmd_err != STU300_ERROR_NONE) { - dev_err(&dev->pdev->dev, "controller (start) " - "error %d waiting for event %d, reinit hardware\n", - dev->cmd_err, mr_event); - (void) stu300_init_hw(dev); - return -EIO; - } - - return 0; -} - -/* - * This waits for a flag to be set, if it is not set on entry, an interrupt is - * configured to wait for the flag using a completion. - */ -static int stu300_await_event(struct stu300_dev *dev, - enum stu300_event mr_event) -{ - int ret; - - /* Is it already here? */ - spin_lock_irq(&dev->cmd_issue_lock); - dev->cmd_err = STU300_ERROR_NONE; - dev->cmd_event = mr_event; - - init_completion(&dev->cmd_complete); - - /* Turn on the I2C interrupt for current operation */ - stu300_irq_enable(dev); - - /* Unlock the command block and wait for the event to occur */ - spin_unlock_irq(&dev->cmd_issue_lock); - - ret = wait_for_completion_interruptible_timeout(&dev->cmd_complete, - STU300_TIMEOUT); - if (ret < 0) { - dev_err(&dev->pdev->dev, - "wait_for_completion_interruptible_timeout()" - "returned %d waiting for event %04x\n", ret, mr_event); - return ret; - } - - if (ret == 0) { - if (mr_event != STU300_EVENT_6) { - dev_err(&dev->pdev->dev, "controller " - "timed out waiting for event %d, reinit " - "hardware\n", mr_event); - (void) stu300_init_hw(dev); - } - return -ETIMEDOUT; - } - - if (dev->cmd_err != STU300_ERROR_NONE) { - if (mr_event != STU300_EVENT_6) { - dev_err(&dev->pdev->dev, "controller " - "error (await_event) %d waiting for event %d, " - "reinit hardware\n", dev->cmd_err, mr_event); - (void) stu300_init_hw(dev); - } - return -EIO; - } - - return 0; -} - -/* - * Waits for the busy bit to go low by repeated polling. - */ -#define BUSY_RELEASE_ATTEMPTS 10 -static int stu300_wait_while_busy(struct stu300_dev *dev) -{ - unsigned long timeout; - int i; - - for (i = 0; i < BUSY_RELEASE_ATTEMPTS; i++) { - timeout = jiffies + STU300_TIMEOUT; - - while (!time_after(jiffies, timeout)) { - /* Is not busy? */ - if ((stu300_r8(dev->virtbase + I2C_SR1) & - I2C_SR1_BUSY_IND) == 0) - return 0; - msleep(1); - } - - dev_err(&dev->pdev->dev, "transaction timed out " - "waiting for device to be free (not busy). " - "Attempt: %d\n", i+1); - - dev_err(&dev->pdev->dev, "base address = " - "0x%p, reinit hardware\n", dev->virtbase); - - (void) stu300_init_hw(dev); - } - - dev_err(&dev->pdev->dev, "giving up after %d attempts " - "to reset the bus.\n", BUSY_RELEASE_ATTEMPTS); - - return -ETIMEDOUT; -} - -struct stu300_clkset { - unsigned long rate; - u32 setting; -}; - -static const struct stu300_clkset stu300_clktable[] = { - { 0, 0xFFU }, - { 2500000, I2C_OAR2_FR_25_10MHZ }, - { 10000000, I2C_OAR2_FR_10_1667MHZ }, - { 16670000, I2C_OAR2_FR_1667_2667MHZ }, - { 26670000, I2C_OAR2_FR_2667_40MHZ }, - { 40000000, I2C_OAR2_FR_40_5333MHZ }, - { 53330000, I2C_OAR2_FR_5333_66MHZ }, - { 66000000, I2C_OAR2_FR_66_80MHZ }, - { 80000000, I2C_OAR2_FR_80_100MHZ }, - { 100000000, 0xFFU }, -}; - - -static int stu300_set_clk(struct stu300_dev *dev, unsigned long clkrate) -{ - - u32 val; - int i = 0; - - /* Locate the appropriate clock setting */ - while (i < ARRAY_SIZE(stu300_clktable) - 1 && - stu300_clktable[i].rate < clkrate) - i++; - - if (stu300_clktable[i].setting == 0xFFU) { - dev_err(&dev->pdev->dev, "too %s clock rate requested " - "(%lu Hz).\n", i ? "high" : "low", clkrate); - return -EINVAL; - } - - stu300_wr8(stu300_clktable[i].setting, - dev->virtbase + I2C_OAR2); - - dev_dbg(&dev->pdev->dev, "Clock rate %lu Hz, I2C bus speed %d Hz " - "virtbase %p\n", clkrate, dev->speed, dev->virtbase); - - if (dev->speed > I2C_MAX_STANDARD_MODE_FREQ) - /* Fast Mode I2C */ - val = ((clkrate/dev->speed) - 9)/3 + 1; - else - /* Standard Mode I2C */ - val = ((clkrate/dev->speed) - 7)/2 + 1; - - /* According to spec the divider must be > 2 */ - if (val < 0x002) { - dev_err(&dev->pdev->dev, "too low clock rate (%lu Hz).\n", - clkrate); - return -EINVAL; - } - - /* We have 12 bits clock divider only! */ - if (val & 0xFFFFF000U) { - dev_err(&dev->pdev->dev, "too high clock rate (%lu Hz).\n", - clkrate); - return -EINVAL; - } - - if (dev->speed > I2C_MAX_STANDARD_MODE_FREQ) { - /* CC6..CC0 */ - stu300_wr8((val & I2C_CCR_CC_MASK) | I2C_CCR_FMSM, - dev->virtbase + I2C_CCR); - dev_dbg(&dev->pdev->dev, "set clock divider to 0x%08x, " - "Fast Mode I2C\n", val); - } else { - /* CC6..CC0 */ - stu300_wr8((val & I2C_CCR_CC_MASK), - dev->virtbase + I2C_CCR); - dev_dbg(&dev->pdev->dev, "set clock divider to " - "0x%08x, Standard Mode I2C\n", val); - } - - /* CC11..CC7 */ - stu300_wr8(((val >> 7) & 0x1F), - dev->virtbase + I2C_ECCR); - - return 0; -} - - -static int stu300_init_hw(struct stu300_dev *dev) -{ - u32 dummy; - unsigned long clkrate; - int ret; - - /* Disable controller */ - stu300_wr8(0x00, dev->virtbase + I2C_CR); - /* - * Set own address to some default value (0x00). - * We do not support slave mode anyway. - */ - stu300_wr8(0x00, dev->virtbase + I2C_OAR1); - /* - * The I2C controller only operates properly in 26 MHz but we - * program this driver as if we didn't know. This will also set the two - * high bits of the own address to zero as well. - * There is no known hardware issue with running in 13 MHz - * However, speeds over 200 kHz are not used. - */ - clkrate = clk_get_rate(dev->clk); - ret = stu300_set_clk(dev, clkrate); - - if (ret) - return ret; - /* - * Enable block, do it TWICE (hardware glitch) - * Setting bit 7 can enable DDC mode. (Not used currently.) - */ - stu300_wr8(I2C_CR_PERIPHERAL_ENABLE, - dev->virtbase + I2C_CR); - stu300_wr8(I2C_CR_PERIPHERAL_ENABLE, - dev->virtbase + I2C_CR); - /* Make a dummy read of the status register SR1 & SR2 */ - dummy = stu300_r8(dev->virtbase + I2C_SR2); - dummy = stu300_r8(dev->virtbase + I2C_SR1); - - return 0; -} - - - -/* Send slave address. */ -static int stu300_send_address(struct stu300_dev *dev, - struct i2c_msg *msg, int resend) -{ - u32 val; - int ret; - - if (msg->flags & I2C_M_TEN) { - /* This is probably how 10 bit addresses look */ - val = (0xf0 | (((u32) msg->addr & 0x300) >> 7)) & - I2C_DR_D_MASK; - if (msg->flags & I2C_M_RD) - /* This is the direction bit */ - val |= 0x01; - } else { - val = i2c_8bit_addr_from_msg(msg); - } - - if (resend) { - if (msg->flags & I2C_M_RD) - dev_dbg(&dev->pdev->dev, "read resend\n"); - else - dev_dbg(&dev->pdev->dev, "write resend\n"); - } - - stu300_wr8(val, dev->virtbase + I2C_DR); - - /* For 10bit addressing, await 10bit request (EVENT 9) */ - if (msg->flags & I2C_M_TEN) { - ret = stu300_await_event(dev, STU300_EVENT_9); - /* - * The slave device wants a 10bit address, send the rest - * of the bits (the LSBits) - */ - val = msg->addr & I2C_DR_D_MASK; - /* This clears "event 9" */ - stu300_wr8(val, dev->virtbase + I2C_DR); - if (ret != 0) - return ret; - } - /* FIXME: Why no else here? two events for 10bit? - * Await event 6 (normal) or event 9 (10bit) - */ - - if (resend) - dev_dbg(&dev->pdev->dev, "await event 6\n"); - ret = stu300_await_event(dev, STU300_EVENT_6); - - /* - * Clear any pending EVENT 6 no matter what happened during - * await_event. - */ - val = stu300_r8(dev->virtbase + I2C_CR); - val |= I2C_CR_PERIPHERAL_ENABLE; - stu300_wr8(val, dev->virtbase + I2C_CR); - - return ret; -} - -static int stu300_xfer_msg(struct i2c_adapter *adap, - struct i2c_msg *msg, int stop) -{ - u32 cr; - u32 val; - u32 i; - int ret; - int attempts = 0; - struct stu300_dev *dev = i2c_get_adapdata(adap); - - clk_enable(dev->clk); - - /* Remove this if (0) to trace each and every message. */ - if (0) { - dev_dbg(&dev->pdev->dev, "I2C message to: 0x%04x, len: %d, " - "flags: 0x%04x, stop: %d\n", - msg->addr, msg->len, msg->flags, stop); - } - - /* - * For some reason, sending the address sometimes fails when running - * on the 13 MHz clock. No interrupt arrives. This is a work around, - * which tries to restart and send the address up to 10 times before - * really giving up. Usually 5 to 8 attempts are enough. - */ - do { - if (attempts) - dev_dbg(&dev->pdev->dev, "wait while busy\n"); - /* Check that the bus is free, or wait until some timeout */ - ret = stu300_wait_while_busy(dev); - if (ret != 0) - goto exit_disable; - - if (attempts) - dev_dbg(&dev->pdev->dev, "re-int hw\n"); - /* - * According to ST, there is no problem if the clock is - * changed between 13 and 26 MHz during a transfer. - */ - ret = stu300_init_hw(dev); - if (ret) - goto exit_disable; - - /* Send a start condition */ - cr = I2C_CR_PERIPHERAL_ENABLE; - /* Setting the START bit puts the block in master mode */ - if (!(msg->flags & I2C_M_NOSTART)) - cr |= I2C_CR_START_ENABLE; - if ((msg->flags & I2C_M_RD) && (msg->len > 1)) - /* On read more than 1 byte, we need ack. */ - cr |= I2C_CR_ACK_ENABLE; - /* Check that it gets through */ - if (!(msg->flags & I2C_M_NOSTART)) { - if (attempts) - dev_dbg(&dev->pdev->dev, "send start event\n"); - ret = stu300_start_and_await_event(dev, cr, - STU300_EVENT_5); - } - - if (attempts) - dev_dbg(&dev->pdev->dev, "send address\n"); - - if (ret == 0) - /* Send address */ - ret = stu300_send_address(dev, msg, attempts != 0); - - if (ret != 0) { - attempts++; - dev_dbg(&dev->pdev->dev, "failed sending address, " - "retrying. Attempt: %d msg_index: %d/%d\n", - attempts, dev->msg_index, dev->msg_len); - } - - } while (ret != 0 && attempts < NUM_ADDR_RESEND_ATTEMPTS); - - if (attempts < NUM_ADDR_RESEND_ATTEMPTS && attempts > 0) { - dev_dbg(&dev->pdev->dev, "managed to get address " - "through after %d attempts\n", attempts); - } else if (attempts == NUM_ADDR_RESEND_ATTEMPTS) { - dev_dbg(&dev->pdev->dev, "I give up, tried %d times " - "to resend address.\n", - NUM_ADDR_RESEND_ATTEMPTS); - goto exit_disable; - } - - - if (msg->flags & I2C_M_RD) { - /* READ: we read the actual bytes one at a time */ - for (i = 0; i < msg->len; i++) { - if (i == msg->len-1) { - /* - * Disable ACK and set STOP condition before - * reading last byte - */ - val = I2C_CR_PERIPHERAL_ENABLE; - - if (stop) - val |= I2C_CR_STOP_ENABLE; - - stu300_wr8(val, - dev->virtbase + I2C_CR); - } - /* Wait for this byte... */ - ret = stu300_await_event(dev, STU300_EVENT_7); - if (ret != 0) - goto exit_disable; - /* This clears event 7 */ - msg->buf[i] = (u8) stu300_r8(dev->virtbase + I2C_DR); - } - } else { - /* WRITE: we send the actual bytes one at a time */ - for (i = 0; i < msg->len; i++) { - /* Write the byte */ - stu300_wr8(msg->buf[i], - dev->virtbase + I2C_DR); - /* Check status */ - ret = stu300_await_event(dev, STU300_EVENT_8); - /* Next write to DR will clear event 8 */ - if (ret != 0) { - dev_err(&dev->pdev->dev, "error awaiting " - "event 8 (%d)\n", ret); - goto exit_disable; - } - } - /* Check NAK */ - if (!(msg->flags & I2C_M_IGNORE_NAK)) { - if (stu300_r8(dev->virtbase + I2C_SR2) & - I2C_SR2_AF_IND) { - dev_err(&dev->pdev->dev, "I2C payload " - "send returned NAK!\n"); - ret = -EIO; - goto exit_disable; - } - } - if (stop) { - /* Send stop condition */ - val = I2C_CR_PERIPHERAL_ENABLE; - val |= I2C_CR_STOP_ENABLE; - stu300_wr8(val, dev->virtbase + I2C_CR); - } - } - - /* Check that the bus is free, or wait until some timeout occurs */ - ret = stu300_wait_while_busy(dev); - if (ret != 0) { - dev_err(&dev->pdev->dev, "timeout waiting for transfer " - "to commence.\n"); - goto exit_disable; - } - - /* Dummy read status registers */ - val = stu300_r8(dev->virtbase + I2C_SR2); - val = stu300_r8(dev->virtbase + I2C_SR1); - ret = 0; - - exit_disable: - /* Disable controller */ - stu300_wr8(0x00, dev->virtbase + I2C_CR); - clk_disable(dev->clk); - return ret; -} - -static int stu300_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, - int num) -{ - int ret = -1; - int i; - - struct stu300_dev *dev = i2c_get_adapdata(adap); - dev->msg_len = num; - - for (i = 0; i < num; i++) { - /* - * Another driver appears to send stop for each message, - * here we only do that for the last message. Possibly some - * peripherals require this behaviour, then their drivers - * have to send single messages in order to get "stop" for - * each message. - */ - dev->msg_index = i; - - ret = stu300_xfer_msg(adap, &msgs[i], (i == (num - 1))); - - if (ret != 0) { - num = ret; - break; - } - } - - return num; -} - -static int stu300_xfer_todo(struct i2c_adapter *adap, struct i2c_msg *msgs, int num) -{ - /* TODO: implement polling for this case if need be. */ - WARN(1, "%s: atomic transfers not implemented\n", dev_name(&adap->dev)); - return -EOPNOTSUPP; -} - -static u32 stu300_func(struct i2c_adapter *adap) -{ - /* This is the simplest thing you can think of... */ - return I2C_FUNC_I2C | I2C_FUNC_10BIT_ADDR; -} - -static const struct i2c_algorithm stu300_algo = { - .master_xfer = stu300_xfer, - .master_xfer_atomic = stu300_xfer_todo, - .functionality = stu300_func, -}; - -static const struct i2c_adapter_quirks stu300_quirks = { - .flags = I2C_AQ_NO_ZERO_LEN, -}; - -static int stu300_probe(struct platform_device *pdev) -{ - struct stu300_dev *dev; - struct i2c_adapter *adap; - int bus_nr; - int ret = 0; - - dev = devm_kzalloc(&pdev->dev, sizeof(struct stu300_dev), GFP_KERNEL); - if (!dev) - return -ENOMEM; - - bus_nr = pdev->id; - dev->clk = devm_clk_get(&pdev->dev, NULL); - if (IS_ERR(dev->clk)) { - dev_err(&pdev->dev, "could not retrieve i2c bus clock\n"); - return PTR_ERR(dev->clk); - } - - dev->pdev = pdev; - dev->virtbase = devm_platform_ioremap_resource(pdev, 0); - dev_dbg(&pdev->dev, "initialize bus device I2C%d on virtual " - "base %p\n", bus_nr, dev->virtbase); - if (IS_ERR(dev->virtbase)) - return PTR_ERR(dev->virtbase); - - dev->irq = platform_get_irq(pdev, 0); - ret = devm_request_irq(&pdev->dev, dev->irq, stu300_irh, 0, NAME, dev); - if (ret < 0) - return ret; - - dev->speed = scl_frequency; - - clk_prepare_enable(dev->clk); - ret = stu300_init_hw(dev); - clk_disable(dev->clk); - if (ret != 0) { - dev_err(&dev->pdev->dev, "error initializing hardware.\n"); - return -EIO; - } - - /* IRQ event handling initialization */ - spin_lock_init(&dev->cmd_issue_lock); - dev->cmd_event = STU300_EVENT_NONE; - dev->cmd_err = STU300_ERROR_NONE; - - adap = &dev->adapter; - adap->owner = THIS_MODULE; - /* DDC class but actually often used for more generic I2C */ - adap->class = I2C_CLASS_DEPRECATED; - strlcpy(adap->name, "ST Microelectronics DDC I2C adapter", - sizeof(adap->name)); - adap->nr = bus_nr; - adap->algo = &stu300_algo; - adap->dev.parent = &pdev->dev; - adap->dev.of_node = pdev->dev.of_node; - adap->quirks = &stu300_quirks; - - i2c_set_adapdata(adap, dev); - - /* i2c device drivers may be active on return from add_adapter() */ - ret = i2c_add_numbered_adapter(adap); - if (ret) - return ret; - - platform_set_drvdata(pdev, dev); - dev_info(&pdev->dev, "ST DDC I2C @ %p, irq %d\n", - dev->virtbase, dev->irq); - - return 0; -} - -#ifdef CONFIG_PM_SLEEP -static int stu300_suspend(struct device *device) -{ - struct stu300_dev *dev = dev_get_drvdata(device); - - /* Turn off everything */ - stu300_wr8(0x00, dev->virtbase + I2C_CR); - return 0; -} - -static int stu300_resume(struct device *device) -{ - int ret = 0; - struct stu300_dev *dev = dev_get_drvdata(device); - - clk_enable(dev->clk); - ret = stu300_init_hw(dev); - clk_disable(dev->clk); - - if (ret != 0) - dev_err(device, "error re-initializing hardware.\n"); - return ret; -} - -static SIMPLE_DEV_PM_OPS(stu300_pm, stu300_suspend, stu300_resume); -#define STU300_I2C_PM (&stu300_pm) -#else -#define STU300_I2C_PM NULL -#endif - -static int stu300_remove(struct platform_device *pdev) -{ - struct stu300_dev *dev = platform_get_drvdata(pdev); - - i2c_del_adapter(&dev->adapter); - /* Turn off everything */ - stu300_wr8(0x00, dev->virtbase + I2C_CR); - return 0; -} - -static const struct of_device_id stu300_dt_match[] = { - { .compatible = "st,ddci2c" }, - {}, -}; -MODULE_DEVICE_TABLE(of, stu300_dt_match); - -static struct platform_driver stu300_i2c_driver = { - .driver = { - .name = NAME, - .pm = STU300_I2C_PM, - .of_match_table = stu300_dt_match, - }, - .probe = stu300_probe, - .remove = stu300_remove, - -}; - -static int __init stu300_init(void) -{ - return platform_driver_register(&stu300_i2c_driver); -} - -static void __exit stu300_exit(void) -{ - platform_driver_unregister(&stu300_i2c_driver); -} - -/* - * The systems using this bus often have very basic devices such - * as regulators on the I2C bus, so this needs to be loaded early. - * Therefore it is registered in the subsys_initcall(). - */ -subsys_initcall(stu300_init); -module_exit(stu300_exit); - -MODULE_AUTHOR("Linus Walleij "); -MODULE_DESCRIPTION("ST Micro DDC I2C adapter (" NAME ")"); -MODULE_LICENSE("GPL"); -MODULE_ALIAS("platform:" NAME); -- cgit v1.2.3 From 9cde12ba07ce71cdc420b9eb8dbd5b19f0bbc730 Mon Sep 17 00:00:00 2001 From: Bjorn Andersson Date: Wed, 20 Jan 2021 17:40:04 -0800 Subject: dt-bindings: arm-smmu-qcom: Add Qualcomm SC8180X compatible Add compatible for the ARM SMMU found in the Qualcomm SC8180x platform. Signed-off-by: Bjorn Andersson Link: https://lore.kernel.org/r/20210121014005.1612382-1-bjorn.andersson@linaro.org Signed-off-by: Will Deacon --- Documentation/devicetree/bindings/iommu/arm,smmu.yaml | 1 + 1 file changed, 1 insertion(+) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/iommu/arm,smmu.yaml b/Documentation/devicetree/bindings/iommu/arm,smmu.yaml index 3b63f2ae24db..c50198e17d52 100644 --- a/Documentation/devicetree/bindings/iommu/arm,smmu.yaml +++ b/Documentation/devicetree/bindings/iommu/arm,smmu.yaml @@ -34,6 +34,7 @@ properties: items: - enum: - qcom,sc7180-smmu-500 + - qcom,sc8180x-smmu-500 - qcom,sdm845-smmu-500 - qcom,sm8150-smmu-500 - qcom,sm8250-smmu-500 -- cgit v1.2.3 From 70b5b6a6daeac0ce8ae57bfec7e1dcf295b42336 Mon Sep 17 00:00:00 2001 From: Vinod Koul Date: Fri, 15 Jan 2021 14:33:21 +0530 Subject: dt-bindings: arm-smmu: Add sm8350 compatible string Add compatible string for sm8350 iommu to documentation. Signed-off-by: Vinod Koul Link: https://lore.kernel.org/r/20210115090322.2287538-1-vkoul@kernel.org Signed-off-by: Will Deacon --- Documentation/devicetree/bindings/iommu/arm,smmu.yaml | 1 + 1 file changed, 1 insertion(+) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/iommu/arm,smmu.yaml b/Documentation/devicetree/bindings/iommu/arm,smmu.yaml index c50198e17d52..6ba161dea4d8 100644 --- a/Documentation/devicetree/bindings/iommu/arm,smmu.yaml +++ b/Documentation/devicetree/bindings/iommu/arm,smmu.yaml @@ -38,6 +38,7 @@ properties: - qcom,sdm845-smmu-500 - qcom,sm8150-smmu-500 - qcom,sm8250-smmu-500 + - qcom,sm8350-smmu-500 - const: arm,mmu-500 - description: Qcom Adreno GPUs implementing "arm,smmu-v2" items: -- cgit v1.2.3 From cd4919105c8f36378afba4cf0e9c869d523b4d6d Mon Sep 17 00:00:00 2001 From: Drew Fustini Date: Tue, 19 Jan 2021 21:03:44 -0800 Subject: pinctrl: clarify #pinctrl-cells for pinctrl-single,pins Document that #pinctrl-cells can be 1 or 2 for pinctrl-single,pins Fixes: 27c90e5e48d0 ("ARM: dts: am33xx-l4: change #pinctrl-cells from 1 to 2") Reported-by: Emmanuel Vadot Link: https://lore.kernel.org/linux-gpio/20210115190201.9273b637a7f967e7e55bc740@bidouilliste.com/ Cc: Tony Lindgren Signed-off-by: Drew Fustini Reviewed-by: Tony Lindgren Link: https://lore.kernel.org/r/20210120050342.320704-1-drew@beagleboard.org Signed-off-by: Linus Walleij --- Documentation/devicetree/bindings/pinctrl/pinctrl-single.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/pinctrl/pinctrl-single.txt b/Documentation/devicetree/bindings/pinctrl/pinctrl-single.txt index f903eb4471f8..bb9999119314 100644 --- a/Documentation/devicetree/bindings/pinctrl/pinctrl-single.txt +++ b/Documentation/devicetree/bindings/pinctrl/pinctrl-single.txt @@ -8,7 +8,7 @@ Required properties: - reg : offset and length of the register set for the mux registers - #pinctrl-cells : number of cells in addition to the index, set to 1 - for pinctrl-single,pins and 2 for pinctrl-single,bits + or 2 for pinctrl-single,pins and set to 2 for pinctrl-single,bits - pinctrl-single,register-width : pinmux register access width in bits -- cgit v1.2.3 From 731e97e0769805cdebfd7d2b19a7d3f6abcace09 Mon Sep 17 00:00:00 2001 From: Flavio Suligoi Date: Fri, 8 Jan 2021 16:24:47 +0100 Subject: Documentation: ACPI: add new rule for gpio-line-names The gpio-line-names lists must respect some rules. This patch adds a new rule in documentation, to avoid the use of duplicate names in the same gpiochip. Signed-off-by: Flavio Suligoi Reviewed-by: Andy Shevchenko Signed-off-by: Rafael J. Wysocki --- Documentation/firmware-guide/acpi/gpio-properties.rst | 1 + 1 file changed, 1 insertion(+) (limited to 'Documentation') diff --git a/Documentation/firmware-guide/acpi/gpio-properties.rst b/Documentation/firmware-guide/acpi/gpio-properties.rst index b36aa3e743d8..4e264c16ddff 100644 --- a/Documentation/firmware-guide/acpi/gpio-properties.rst +++ b/Documentation/firmware-guide/acpi/gpio-properties.rst @@ -146,6 +146,7 @@ following rules (see also the examples): other words, it is not mandatory to fill all the GPIO lines - empty names are allowed (two quotation marks ``""`` correspond to an empty name) + - names inside one GPIO controller/expander must be unique Example of a GPIO controller of 16 lines, with an incomplete list with two empty names:: -- cgit v1.2.3 From 0e43e08c13a1b77b2274a2122d3f51dfe00cda09 Mon Sep 17 00:00:00 2001 From: Manivannan Sadhasivam Date: Mon, 18 Jan 2021 10:39:59 +0530 Subject: dt-bindings: usb: qcom,dwc3: Add binding for SDX55 Add devicetree binding for SDX55 USB controller based on Qcom designware IP. Acked-by: Felipe Balbi Cc: Rob Herring Cc: devicetree@vger.kernel.org Cc: linux-usb@vger.kernel.org Signed-off-by: Manivannan Sadhasivam Link: https://lore.kernel.org/r/20210118051005.55958-2-manivannan.sadhasivam@linaro.org Signed-off-by: Bjorn Andersson --- Documentation/devicetree/bindings/usb/qcom,dwc3.yaml | 1 + 1 file changed, 1 insertion(+) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/usb/qcom,dwc3.yaml b/Documentation/devicetree/bindings/usb/qcom,dwc3.yaml index 2cf525d21e05..fd93b941f07a 100644 --- a/Documentation/devicetree/bindings/usb/qcom,dwc3.yaml +++ b/Documentation/devicetree/bindings/usb/qcom,dwc3.yaml @@ -17,6 +17,7 @@ properties: - qcom,msm8998-dwc3 - qcom,sc7180-dwc3 - qcom,sdm845-dwc3 + - qcom,sdx55-dwc3 - const: qcom,dwc3 reg: -- cgit v1.2.3 From 54211b6125030364604d91bcfb83b5efa0a240a8 Mon Sep 17 00:00:00 2001 From: Manivannan Sadhasivam Date: Mon, 18 Jan 2021 10:40:02 +0530 Subject: dt-bindings: watchdog: Add binding for Qcom SDX55 Add devicetree binding for watchdog present in Qcom SDX55 platform. Cc: Wim Van Sebroeck Cc: Guenter Roeck Cc: Rob Herring Cc: linux-watchdog@vger.kernel.org Cc: devicetree@vger.kernel.org Signed-off-by: Manivannan Sadhasivam Link: https://lore.kernel.org/r/20210118051005.55958-5-manivannan.sadhasivam@linaro.org Signed-off-by: Bjorn Andersson --- Documentation/devicetree/bindings/watchdog/qcom-wdt.yaml | 1 + 1 file changed, 1 insertion(+) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/watchdog/qcom-wdt.yaml b/Documentation/devicetree/bindings/watchdog/qcom-wdt.yaml index 8e3760a3822b..b8e4118945a0 100644 --- a/Documentation/devicetree/bindings/watchdog/qcom-wdt.yaml +++ b/Documentation/devicetree/bindings/watchdog/qcom-wdt.yaml @@ -18,6 +18,7 @@ properties: - qcom,apss-wdt-qcs404 - qcom,apss-wdt-sc7180 - qcom,apss-wdt-sdm845 + - qcom,apss-wdt-sdx55 - qcom,apss-wdt-sm8150 - qcom,kpss-timer - qcom,kpss-wdt -- cgit v1.2.3 From 90d010b8634b89a97ca3b7aa6a88fd566fc77717 Mon Sep 17 00:00:00 2001 From: Parav Pandit Date: Fri, 11 Dec 2020 22:12:17 -0800 Subject: net/mlx5: SF, Add auxiliary device support Introduce API to add and delete an auxiliary device for an SF. Each SF has its own dedicated window in the PCI BAR 2. SF device is similar to PCI PF and VF that supports multiple class of devices such as net, rdma and vdpa. SF device will be added or removed in subsequent patch during SF devlink port function state change command. A subfunction device exposes user supplied subfunction number which will be further used by systemd/udev to have deterministic name for its netdevice and rdma device. An mlx5 subfunction auxiliary device example: $ devlink dev eswitch set pci/0000:06:00.0 mode switchdev $ devlink port show pci/0000:06:00.0/65535: type eth netdev ens2f0np0 flavour physical port 0 splittable false $ devlink port add pci/0000:06:00.0 flavour pcisf pfnum 0 sfnum 88 pci/0000:08:00.0/32768: type eth netdev eth6 flavour pcisf controller 0 pfnum 0 sfnum 88 external false splittable false function: hw_addr 00:00:00:00:00:00 state inactive opstate detached $ devlink port show ens2f0npf0sf88 pci/0000:06:00.0/32768: type eth netdev ens2f0npf0sf88 flavour pcisf controller 0 pfnum 0 sfnum 88 external false splittable false function: hw_addr 00:00:00:00:88:88 state inactive opstate detached $ devlink port function set ens2f0npf0sf88 hw_addr 00:00:00:00:88:88 state active On activation, $ ls -l /sys/bus/auxiliary/devices/ mlx5_core.sf.4 -> ../../../devices/pci0000:00/0000:00:03.0/0000:06:00.0/mlx5_core.sf.4 $ cat /sys/bus/auxiliary/devices/mlx5_core.sf.4/sfnum 88 Signed-off-by: Parav Pandit Reviewed-by: Vu Pham Signed-off-by: Saeed Mahameed --- .../device_drivers/ethernet/mellanox/mlx5.rst | 5 + drivers/net/ethernet/mellanox/mlx5/core/Makefile | 2 +- drivers/net/ethernet/mellanox/mlx5/core/main.c | 4 + .../net/ethernet/mellanox/mlx5/core/sf/dev/dev.c | 265 +++++++++++++++++++++ .../net/ethernet/mellanox/mlx5/core/sf/dev/dev.h | 35 +++ include/linux/mlx5/driver.h | 2 + 6 files changed, 312 insertions(+), 1 deletion(-) create mode 100644 drivers/net/ethernet/mellanox/mlx5/core/sf/dev/dev.c create mode 100644 drivers/net/ethernet/mellanox/mlx5/core/sf/dev/dev.h (limited to 'Documentation') diff --git a/Documentation/networking/device_drivers/ethernet/mellanox/mlx5.rst b/Documentation/networking/device_drivers/ethernet/mellanox/mlx5.rst index e9b65035cd47..a5eb22793bb9 100644 --- a/Documentation/networking/device_drivers/ethernet/mellanox/mlx5.rst +++ b/Documentation/networking/device_drivers/ethernet/mellanox/mlx5.rst @@ -97,6 +97,11 @@ Enabling the driver and kconfig options | Provides low-level InfiniBand/RDMA and `RoCE `_ support. +**CONFIG_MLX5_SF=(y/n)** + +| Build support for subfunction. +| Subfunctons are more light weight than PCI SRIOV VFs. Choosing this option +| will enable support for creating subfunction devices. **External options** ( Choose if the corresponding mlx5 feature is required ) diff --git a/drivers/net/ethernet/mellanox/mlx5/core/Makefile b/drivers/net/ethernet/mellanox/mlx5/core/Makefile index 22ef2ebbee96..f5b2e9101348 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/Makefile +++ b/drivers/net/ethernet/mellanox/mlx5/core/Makefile @@ -89,4 +89,4 @@ mlx5_core-$(CONFIG_MLX5_SW_STEERING) += steering/dr_domain.o steering/dr_table.o # # SF device # -mlx5_core-$(CONFIG_MLX5_SF) += sf/vhca_event.o +mlx5_core-$(CONFIG_MLX5_SF) += sf/vhca_event.o sf/dev/dev.o diff --git a/drivers/net/ethernet/mellanox/mlx5/core/main.c b/drivers/net/ethernet/mellanox/mlx5/core/main.c index b16f57befe52..26b5502712a6 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/main.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/main.c @@ -74,6 +74,7 @@ #include "lib/hv_vhca.h" #include "diag/rsc_dump.h" #include "sf/vhca_event.h" +#include "sf/dev/dev.h" MODULE_AUTHOR("Eli Cohen "); MODULE_DESCRIPTION("Mellanox 5th generation network adapters (ConnectX series) core driver"); @@ -1155,6 +1156,8 @@ static int mlx5_load(struct mlx5_core_dev *dev) goto err_sriov; } + mlx5_sf_dev_table_create(dev); + return 0; err_sriov: @@ -1186,6 +1189,7 @@ err_irq_table: static void mlx5_unload(struct mlx5_core_dev *dev) { + mlx5_sf_dev_table_destroy(dev); mlx5_sriov_detach(dev); mlx5_ec_cleanup(dev); mlx5_vhca_event_stop(dev); diff --git a/drivers/net/ethernet/mellanox/mlx5/core/sf/dev/dev.c b/drivers/net/ethernet/mellanox/mlx5/core/sf/dev/dev.c new file mode 100644 index 000000000000..4a8eeb7c853e --- /dev/null +++ b/drivers/net/ethernet/mellanox/mlx5/core/sf/dev/dev.c @@ -0,0 +1,265 @@ +// SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB +/* Copyright (c) 2020 Mellanox Technologies Ltd */ + +#include +#include +#include "mlx5_core.h" +#include "dev.h" +#include "sf/vhca_event.h" +#include "sf/sf.h" +#include "sf/mlx5_ifc_vhca_event.h" +#include "ecpf.h" + +struct mlx5_sf_dev_table { + struct xarray devices; + unsigned int max_sfs; + phys_addr_t base_address; + u64 sf_bar_length; + struct notifier_block nb; + struct mlx5_core_dev *dev; +}; + +static bool mlx5_sf_dev_supported(const struct mlx5_core_dev *dev) +{ + return MLX5_CAP_GEN(dev, sf) && mlx5_vhca_event_supported(dev); +} + +static ssize_t sfnum_show(struct device *dev, struct device_attribute *attr, char *buf) +{ + struct auxiliary_device *adev = container_of(dev, struct auxiliary_device, dev); + struct mlx5_sf_dev *sf_dev = container_of(adev, struct mlx5_sf_dev, adev); + + return scnprintf(buf, PAGE_SIZE, "%u\n", sf_dev->sfnum); +} +static DEVICE_ATTR_RO(sfnum); + +static struct attribute *sf_device_attrs[] = { + &dev_attr_sfnum.attr, + NULL, +}; + +static const struct attribute_group sf_attr_group = { + .attrs = sf_device_attrs, +}; + +static const struct attribute_group *sf_attr_groups[2] = { + &sf_attr_group, + NULL +}; + +static void mlx5_sf_dev_release(struct device *device) +{ + struct auxiliary_device *adev = container_of(device, struct auxiliary_device, dev); + struct mlx5_sf_dev *sf_dev = container_of(adev, struct mlx5_sf_dev, adev); + + mlx5_adev_idx_free(adev->id); + kfree(sf_dev); +} + +static void mlx5_sf_dev_remove(struct mlx5_sf_dev *sf_dev) +{ + auxiliary_device_delete(&sf_dev->adev); + auxiliary_device_uninit(&sf_dev->adev); +} + +static void mlx5_sf_dev_add(struct mlx5_core_dev *dev, u16 sf_index, u32 sfnum) +{ + struct mlx5_sf_dev_table *table = dev->priv.sf_dev_table; + struct mlx5_sf_dev *sf_dev; + struct pci_dev *pdev; + int err; + int id; + + id = mlx5_adev_idx_alloc(); + if (id < 0) { + err = id; + goto add_err; + } + + sf_dev = kzalloc(sizeof(*sf_dev), GFP_KERNEL); + if (!sf_dev) { + mlx5_adev_idx_free(id); + err = -ENOMEM; + goto add_err; + } + pdev = dev->pdev; + sf_dev->adev.id = id; + sf_dev->adev.name = MLX5_SF_DEV_ID_NAME; + sf_dev->adev.dev.release = mlx5_sf_dev_release; + sf_dev->adev.dev.parent = &pdev->dev; + sf_dev->adev.dev.groups = sf_attr_groups; + sf_dev->sfnum = sfnum; + sf_dev->parent_mdev = dev; + + if (!table->max_sfs) { + mlx5_adev_idx_free(id); + kfree(sf_dev); + err = -EOPNOTSUPP; + goto add_err; + } + sf_dev->bar_base_addr = table->base_address + (sf_index * table->sf_bar_length); + + err = auxiliary_device_init(&sf_dev->adev); + if (err) { + mlx5_adev_idx_free(id); + kfree(sf_dev); + goto add_err; + } + + err = auxiliary_device_add(&sf_dev->adev); + if (err) { + put_device(&sf_dev->adev.dev); + goto add_err; + } + + err = xa_insert(&table->devices, sf_index, sf_dev, GFP_KERNEL); + if (err) + goto xa_err; + return; + +xa_err: + mlx5_sf_dev_remove(sf_dev); +add_err: + mlx5_core_err(dev, "SF DEV: fail device add for index=%d sfnum=%d err=%d\n", + sf_index, sfnum, err); +} + +static void mlx5_sf_dev_del(struct mlx5_core_dev *dev, struct mlx5_sf_dev *sf_dev, u16 sf_index) +{ + struct mlx5_sf_dev_table *table = dev->priv.sf_dev_table; + + xa_erase(&table->devices, sf_index); + mlx5_sf_dev_remove(sf_dev); +} + +static int +mlx5_sf_dev_state_change_handler(struct notifier_block *nb, unsigned long event_code, void *data) +{ + struct mlx5_sf_dev_table *table = container_of(nb, struct mlx5_sf_dev_table, nb); + const struct mlx5_vhca_state_event *event = data; + struct mlx5_sf_dev *sf_dev; + u16 sf_index; + + sf_index = event->function_id - MLX5_CAP_GEN(table->dev, sf_base_id); + sf_dev = xa_load(&table->devices, sf_index); + switch (event->new_vhca_state) { + case MLX5_VHCA_STATE_ALLOCATED: + if (sf_dev) + mlx5_sf_dev_del(table->dev, sf_dev, sf_index); + break; + case MLX5_VHCA_STATE_TEARDOWN_REQUEST: + if (sf_dev) + mlx5_sf_dev_del(table->dev, sf_dev, sf_index); + else + mlx5_core_err(table->dev, + "SF DEV: teardown state for invalid dev index=%d fn_id=0x%x\n", + sf_index, event->sw_function_id); + break; + case MLX5_VHCA_STATE_ACTIVE: + if (!sf_dev) + mlx5_sf_dev_add(table->dev, sf_index, event->sw_function_id); + break; + default: + break; + } + return 0; +} + +static int mlx5_sf_dev_vhca_arm_all(struct mlx5_sf_dev_table *table) +{ + struct mlx5_core_dev *dev = table->dev; + u16 max_functions; + u16 function_id; + int err = 0; + bool ecpu; + int i; + + max_functions = mlx5_sf_max_functions(dev); + function_id = MLX5_CAP_GEN(dev, sf_base_id); + ecpu = mlx5_read_embedded_cpu(dev); + /* Arm the vhca context as the vhca event notifier */ + for (i = 0; i < max_functions; i++) { + err = mlx5_vhca_event_arm(dev, function_id, ecpu); + if (err) + return err; + + function_id++; + } + return 0; +} + +void mlx5_sf_dev_table_create(struct mlx5_core_dev *dev) +{ + struct mlx5_sf_dev_table *table; + unsigned int max_sfs; + int err; + + if (!mlx5_sf_dev_supported(dev) || !mlx5_vhca_event_supported(dev)) + return; + + table = kzalloc(sizeof(*table), GFP_KERNEL); + if (!table) { + err = -ENOMEM; + goto table_err; + } + + table->nb.notifier_call = mlx5_sf_dev_state_change_handler; + table->dev = dev; + if (MLX5_CAP_GEN(dev, max_num_sf)) + max_sfs = MLX5_CAP_GEN(dev, max_num_sf); + else + max_sfs = 1 << MLX5_CAP_GEN(dev, log_max_sf); + table->sf_bar_length = 1 << (MLX5_CAP_GEN(dev, log_min_sf_size) + 12); + table->base_address = pci_resource_start(dev->pdev, 2); + table->max_sfs = max_sfs; + xa_init(&table->devices); + dev->priv.sf_dev_table = table; + + err = mlx5_vhca_event_notifier_register(dev, &table->nb); + if (err) + goto vhca_err; + err = mlx5_sf_dev_vhca_arm_all(table); + if (err) + goto arm_err; + mlx5_core_dbg(dev, "SF DEV: max sf devices=%d\n", max_sfs); + return; + +arm_err: + mlx5_vhca_event_notifier_unregister(dev, &table->nb); +vhca_err: + table->max_sfs = 0; + kfree(table); + dev->priv.sf_dev_table = NULL; +table_err: + mlx5_core_err(dev, "SF DEV table create err = %d\n", err); +} + +static void mlx5_sf_dev_destroy_all(struct mlx5_sf_dev_table *table) +{ + struct mlx5_sf_dev *sf_dev; + unsigned long index; + + xa_for_each(&table->devices, index, sf_dev) { + xa_erase(&table->devices, index); + mlx5_sf_dev_remove(sf_dev); + } +} + +void mlx5_sf_dev_table_destroy(struct mlx5_core_dev *dev) +{ + struct mlx5_sf_dev_table *table = dev->priv.sf_dev_table; + + if (!table) + return; + + mlx5_vhca_event_notifier_unregister(dev, &table->nb); + + /* Now that event handler is not running, it is safe to destroy + * the sf device without race. + */ + mlx5_sf_dev_destroy_all(table); + + WARN_ON(!xa_empty(&table->devices)); + kfree(table); + dev->priv.sf_dev_table = NULL; +} diff --git a/drivers/net/ethernet/mellanox/mlx5/core/sf/dev/dev.h b/drivers/net/ethernet/mellanox/mlx5/core/sf/dev/dev.h new file mode 100644 index 000000000000..a6fb7289ba2c --- /dev/null +++ b/drivers/net/ethernet/mellanox/mlx5/core/sf/dev/dev.h @@ -0,0 +1,35 @@ +/* SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB */ +/* Copyright (c) 2020 Mellanox Technologies Ltd */ + +#ifndef __MLX5_SF_DEV_H__ +#define __MLX5_SF_DEV_H__ + +#ifdef CONFIG_MLX5_SF + +#include + +#define MLX5_SF_DEV_ID_NAME "sf" + +struct mlx5_sf_dev { + struct auxiliary_device adev; + struct mlx5_core_dev *parent_mdev; + phys_addr_t bar_base_addr; + u32 sfnum; +}; + +void mlx5_sf_dev_table_create(struct mlx5_core_dev *dev); +void mlx5_sf_dev_table_destroy(struct mlx5_core_dev *dev); + +#else + +static inline void mlx5_sf_dev_table_create(struct mlx5_core_dev *dev) +{ +} + +static inline void mlx5_sf_dev_table_destroy(struct mlx5_core_dev *dev) +{ +} + +#endif + +#endif diff --git a/include/linux/mlx5/driver.h b/include/linux/mlx5/driver.h index ffba0786051e..08e5fbe97df0 100644 --- a/include/linux/mlx5/driver.h +++ b/include/linux/mlx5/driver.h @@ -508,6 +508,7 @@ struct mlx5_fw_reset; struct mlx5_eq_table; struct mlx5_irq_table; struct mlx5_vhca_state_notifier; +struct mlx5_sf_dev_table; struct mlx5_rate_limit { u32 rate; @@ -606,6 +607,7 @@ struct mlx5_priv { struct mlx5_uars_page *uar; #ifdef CONFIG_MLX5_SF struct mlx5_vhca_state_notifier *vhca_state_notifier; + struct mlx5_sf_dev_table *sf_dev_table; #endif }; -- cgit v1.2.3 From c736111cf8d519d46ac62af36378aed472faaa12 Mon Sep 17 00:00:00 2001 From: Parav Pandit Date: Fri, 11 Dec 2020 22:12:23 -0800 Subject: devlink: Add devlink port documentation Added documentation for devlink port and port function related commands. Signed-off-by: Parav Pandit Reviewed-by: Jiri Pirko Reviewed-by: Jacob Keller Signed-off-by: Saeed Mahameed --- Documentation/networking/devlink/devlink-port.rst | 118 ++++++++++++++++++++++ Documentation/networking/devlink/index.rst | 1 + 2 files changed, 119 insertions(+) create mode 100644 Documentation/networking/devlink/devlink-port.rst (limited to 'Documentation') diff --git a/Documentation/networking/devlink/devlink-port.rst b/Documentation/networking/devlink/devlink-port.rst new file mode 100644 index 000000000000..c564b557e757 --- /dev/null +++ b/Documentation/networking/devlink/devlink-port.rst @@ -0,0 +1,118 @@ +.. SPDX-License-Identifier: GPL-2.0 + +.. _devlink_port: + +============ +Devlink Port +============ + +``devlink-port`` is a port that exists on the device. It has a logically +separate ingress/egress point of the device. A devlink port can be any one +of many flavours. A devlink port flavour along with port attributes +describe what a port represents. + +A device driver that intends to publish a devlink port sets the +devlink port attributes and registers the devlink port. + +Devlink port flavours are described below. + +.. list-table:: List of devlink port flavours + :widths: 33 90 + + * - Flavour + - Description + * - ``DEVLINK_PORT_FLAVOUR_PHYSICAL`` + - Any kind of physical port. This can be an eswitch physical port or any + other physical port on the device. + * - ``DEVLINK_PORT_FLAVOUR_DSA`` + - This indicates a DSA interconnect port. + * - ``DEVLINK_PORT_FLAVOUR_CPU`` + - This indicates a CPU port applicable only to DSA. + * - ``DEVLINK_PORT_FLAVOUR_PCI_PF`` + - This indicates an eswitch port representing a port of PCI + physical function (PF). + * - ``DEVLINK_PORT_FLAVOUR_PCI_VF`` + - This indicates an eswitch port representing a port of PCI + virtual function (VF). + * - ``DEVLINK_PORT_FLAVOUR_VIRTUAL`` + - This indicates a virtual port for the PCI virtual function. + +Devlink port can have a different type based on the link layer described below. + +.. list-table:: List of devlink port types + :widths: 23 90 + + * - Type + - Description + * - ``DEVLINK_PORT_TYPE_ETH`` + - Driver should set this port type when a link layer of the port is + Ethernet. + * - ``DEVLINK_PORT_TYPE_IB`` + - Driver should set this port type when a link layer of the port is + InfiniBand. + * - ``DEVLINK_PORT_TYPE_AUTO`` + - This type is indicated by the user when driver should detect the port + type automatically. + +PCI controllers +--------------- +In most cases a PCI device has only one controller. A controller consists of +potentially multiple physical and virtual functions. A function consists +of one or more ports. This port is represented by the devlink eswitch port. + +A PCI device connected to multiple CPUs or multiple PCI root complexes or a +SmartNIC, however, may have multiple controllers. For a device with multiple +controllers, each controller is distinguished by a unique controller number. +An eswitch is on the PCI device which supports ports of multiple controllers. + +An example view of a system with two controllers:: + + --------------------------------------------------------- + | | + | --------- --------- ------- ------- | + ----------- | | vf(s) | | sf(s) | |vf(s)| |sf(s)| | + | server | | ------- ----/---- ---/----- ------- ---/--- ---/--- | + | pci rc |=== | pf0 |______/________/ | pf1 |___/_______/ | + | connect | | ------- ------- | + ----------- | | controller_num=1 (no eswitch) | + ------|-------------------------------------------------- + (internal wire) + | + --------------------------------------------------------- + | devlink eswitch ports and reps | + | ----------------------------------------------------- | + | |ctrl-0 | ctrl-0 | ctrl-0 | ctrl-0 | ctrl-0 |ctrl-0 | | + | |pf0 | pf0vfN | pf0sfN | pf1 | pf1vfN |pf1sfN | | + | ----------------------------------------------------- | + | |ctrl-1 | ctrl-1 | ctrl-1 | ctrl-1 | ctrl-1 |ctrl-1 | | + | |pf0 | pf0vfN | pf0sfN | pf1 | pf1vfN |pf1sfN | | + | ----------------------------------------------------- | + | | + | | + ----------- | --------- --------- ------- ------- | + | smartNIC| | | vf(s) | | sf(s) | |vf(s)| |sf(s)| | + | pci rc |==| ------- ----/---- ---/----- ------- ---/--- ---/--- | + | connect | | | pf0 |______/________/ | pf1 |___/_______/ | + ----------- | ------- ------- | + | | + | local controller_num=0 (eswitch) | + --------------------------------------------------------- + +In the above example, the external controller (identified by controller number = 1) +doesn't have the eswitch. Local controller (identified by controller number = 0) +has the eswitch. The Devlink instance on the local controller has eswitch +devlink ports for both the controllers. + +Function configuration +====================== + +A user can configure the function attribute before enumerating the PCI +function. Usually it means, user should configure function attribute +before a bus specific device for the function is created. However, when +SRIOV is enabled, virtual function devices are created on the PCI bus. +Hence, function attribute should be configured before binding virtual +function device to the driver. + +A user may set the hardware address of the function using +'devlink port function set hw_addr' command. For Ethernet port function +this means a MAC address. diff --git a/Documentation/networking/devlink/index.rst b/Documentation/networking/devlink/index.rst index d82874760ae2..aab79667f97b 100644 --- a/Documentation/networking/devlink/index.rst +++ b/Documentation/networking/devlink/index.rst @@ -18,6 +18,7 @@ general. devlink-info devlink-flash devlink-params + devlink-port devlink-region devlink-resource devlink-reload -- cgit v1.2.3 From 6474ce7ecd80c5071861ba96c864f03d84319e73 Mon Sep 17 00:00:00 2001 From: Parav Pandit Date: Fri, 11 Dec 2020 22:12:24 -0800 Subject: devlink: Extend devlink port documentation for subfunctions Add devlink port documentation for subfunction management. Signed-off-by: Parav Pandit Signed-off-by: Saeed Mahameed --- Documentation/driver-api/auxiliary_bus.rst | 2 + Documentation/networking/devlink/devlink-port.rst | 87 ++++++++++++++++++++++- 2 files changed, 86 insertions(+), 3 deletions(-) (limited to 'Documentation') diff --git a/Documentation/driver-api/auxiliary_bus.rst b/Documentation/driver-api/auxiliary_bus.rst index 2312506b0674..fff96c7ba7a8 100644 --- a/Documentation/driver-api/auxiliary_bus.rst +++ b/Documentation/driver-api/auxiliary_bus.rst @@ -1,5 +1,7 @@ .. SPDX-License-Identifier: GPL-2.0-only +.. _auxiliary_bus: + ============= Auxiliary Bus ============= diff --git a/Documentation/networking/devlink/devlink-port.rst b/Documentation/networking/devlink/devlink-port.rst index c564b557e757..e99b41599465 100644 --- a/Documentation/networking/devlink/devlink-port.rst +++ b/Documentation/networking/devlink/devlink-port.rst @@ -34,6 +34,9 @@ Devlink port flavours are described below. * - ``DEVLINK_PORT_FLAVOUR_PCI_VF`` - This indicates an eswitch port representing a port of PCI virtual function (VF). + * - ``DEVLINK_PORT_FLAVOUR_PCI_SF`` + - This indicates an eswitch port representing a port of PCI + subfunction (SF). * - ``DEVLINK_PORT_FLAVOUR_VIRTUAL`` - This indicates a virtual port for the PCI virtual function. @@ -57,8 +60,9 @@ Devlink port can have a different type based on the link layer described below. PCI controllers --------------- In most cases a PCI device has only one controller. A controller consists of -potentially multiple physical and virtual functions. A function consists -of one or more ports. This port is represented by the devlink eswitch port. +potentially multiple physical, virtual functions and subfunctions. A function +consists of one or more ports. This port is represented by the devlink eswitch +port. A PCI device connected to multiple CPUs or multiple PCI root complexes or a SmartNIC, however, may have multiple controllers. For a device with multiple @@ -111,8 +115,85 @@ function. Usually it means, user should configure function attribute before a bus specific device for the function is created. However, when SRIOV is enabled, virtual function devices are created on the PCI bus. Hence, function attribute should be configured before binding virtual -function device to the driver. +function device to the driver. For subfunctions, this means user should +configure port function attribute before activating the port function. A user may set the hardware address of the function using 'devlink port function set hw_addr' command. For Ethernet port function this means a MAC address. + +Subfunction +============ + +Subfunction is a lightweight function that has a parent PCI function on which +it is deployed. Subfunction is created and deployed in unit of 1. Unlike +SRIOV VFs, a subfunction doesn't require its own PCI virtual function. +A subfunction communicates with the hardware through the parent PCI function. + +To use a subfunction, 3 steps setup sequence is followed. +(1) create - create a subfunction; +(2) configure - configure subfunction attributes; +(3) deploy - deploy the subfunction; + +Subfunction management is done using devlink port user interface. +User performs setup on the subfunction management device. + +(1) Create +---------- +A subfunction is created using a devlink port interface. A user adds the +subfunction by adding a devlink port of subfunction flavour. The devlink +kernel code calls down to subfunction management driver (devlink ops) and asks +it to create a subfunction devlink port. Driver then instantiates the +subfunction port and any associated objects such as health reporters and +representor netdevice. + +(2) Configure +------------- +A subfunction devlink port is created but it is not active yet. That means the +entities are created on devlink side, the e-switch port representor is created, +but the subfunction device itself it not created. A user might use e-switch port +representor to do settings, putting it into bridge, adding TC rules, etc. A user +might as well configure the hardware address (such as MAC address) of the +subfunction while subfunction is inactive. + +(3) Deploy +---------- +Once a subfunction is configured, user must activate it to use it. Upon +activation, subfunction management driver asks the subfunction management +device to instantiate the subfunction device on particular PCI function. +A subfunction device is created on the :ref:`Documentation/driver-api/auxiliary_bus.rst `. +At this point a matching subfunction driver binds to the subfunction's auxiliary device. + +Terms and Definitions +===================== + +.. list-table:: Terms and Definitions + :widths: 22 90 + + * - Term + - Definitions + * - ``PCI device`` + - A physical PCI device having one or more PCI bus consists of one or + more PCI controllers. + * - ``PCI controller`` + - A controller consists of potentially multiple physical functions, + virtual functions and subfunctions. + * - ``Port function`` + - An object to manage the function of a port. + * - ``Subfunction`` + - A lightweight function that has parent PCI function on which it is + deployed. + * - ``Subfunction device`` + - A bus device of the subfunction, usually on a auxiliary bus. + * - ``Subfunction driver`` + - A device driver for the subfunction auxiliary device. + * - ``Subfunction management device`` + - A PCI physical function that supports subfunction management. + * - ``Subfunction management driver`` + - A device driver for PCI physical function that supports + subfunction management using devlink port interface. + * - ``Subfunction host driver`` + - A device driver for PCI physical function that hosts subfunction + devices. In most cases it is same as subfunction management driver. When + subfunction is used on external controller, subfunction management and + host drivers are different. -- cgit v1.2.3 From 142d93d12dc187f6a32aae2048da0c8230636b86 Mon Sep 17 00:00:00 2001 From: Parav Pandit Date: Fri, 11 Dec 2020 22:12:25 -0800 Subject: net/mlx5: Add devlink subfunction port documentation Add documentation for subfunction management using devlink port. Signed-off-by: Parav Pandit Signed-off-by: Saeed Mahameed --- .../device_drivers/ethernet/mellanox/mlx5.rst | 210 +++++++++++++++++++++ 1 file changed, 210 insertions(+) (limited to 'Documentation') diff --git a/Documentation/networking/device_drivers/ethernet/mellanox/mlx5.rst b/Documentation/networking/device_drivers/ethernet/mellanox/mlx5.rst index a5eb22793bb9..a1b32fcd0d76 100644 --- a/Documentation/networking/device_drivers/ethernet/mellanox/mlx5.rst +++ b/Documentation/networking/device_drivers/ethernet/mellanox/mlx5.rst @@ -12,6 +12,8 @@ Contents - `Enabling the driver and kconfig options`_ - `Devlink info`_ - `Devlink parameters`_ +- `mlx5 subfunction`_ +- `mlx5 port function`_ - `Devlink health reporters`_ - `mlx5 tracepoints`_ @@ -181,6 +183,214 @@ User command examples: values: cmode driverinit value true +mlx5 subfunction +================ +mlx5 supports subfunction management using devlink port (see :ref:`Documentation/networking/devlink/devlink-port.rst `) interface. + +A Subfunction has its own function capabilities and its own resources. This +means a subfunction has its own dedicated queues (txq, rxq, cq, eq). These +queues are neither shared nor stolen from the parent PCI function. + +When a subfunction is RDMA capable, it has its own QP1, GID table and rdma +resources neither shared nor stolen from the parent PCI function. + +A subfunction has a dedicated window in PCI BAR space that is not shared +with ther other subfunctions or the parent PCI function. This ensures that all +devices (netdev, rdma, vdpa etc.) of the subfunction accesses only assigned +PCI BAR space. + +A Subfunction supports eswitch representation through which it supports tc +offloads. The user configures eswitch to send/receive packets from/to +the subfunction port. + +Subfunctions share PCI level resources such as PCI MSI-X IRQs with +other subfunctions and/or with its parent PCI function. + +Example mlx5 software, system and device view:: + + _______ + | admin | + | user |---------- + |_______| | + | | + ____|____ __|______ _________________ + | | | | | | + | devlink | | tc tool | | user | + | tool | |_________| | applications | + |_________| | |_________________| + | | | | + | | | | Userspace + +---------|-------------|-------------------|----------|--------------------+ + | | +----------+ +----------+ Kernel + | | | netdev | | rdma dev | + | | +----------+ +----------+ + (devlink port add/del | ^ ^ + port function set) | | | + | | +---------------| + _____|___ | | _______|_______ + | | | | | mlx5 class | + | devlink | +------------+ | | drivers | + | kernel | | rep netdev | | |(mlx5_core,ib) | + |_________| +------------+ | |_______________| + | | | ^ + (devlink ops) | | (probe/remove) + _________|________ | | ____|________ + | subfunction | | +---------------+ | subfunction | + | management driver|----- | subfunction |---| driver | + | (mlx5_core) | | auxiliary dev | | (mlx5_core) | + |__________________| +---------------+ |_____________| + | ^ + (sf add/del, vhca events) | + | (device add/del) + _____|____ ____|________ + | | | subfunction | + | PCI NIC |---- activate/deactive events---->| host driver | + |__________| | (mlx5_core) | + |_____________| + +Subfunction is created using devlink port interface. + +- Change device to switchdev mode:: + + $ devlink dev eswitch set pci/0000:06:00.0 mode switchdev + +- Add a devlink port of subfunction flaovur:: + + $ devlink port add pci/0000:06:00.0 flavour pcisf pfnum 0 sfnum 88 + pci/0000:06:00.0/32768: type eth netdev eth6 flavour pcisf controller 0 pfnum 0 sfnum 88 external false splittable false + function: + hw_addr 00:00:00:00:00:00 state inactive opstate detached + +- Show a devlink port of the subfunction:: + + $ devlink port show pci/0000:06:00.0/32768 + pci/0000:06:00.0/32768: type eth netdev enp6s0pf0sf88 flavour pcisf pfnum 0 sfnum 88 + function: + hw_addr 00:00:00:00:00:00 state inactive opstate detached + +- Delete a devlink port of subfunction after use:: + + $ devlink port del pci/0000:06:00.0/32768 + +mlx5 function attributes +======================== +The mlx5 driver provides a mechanism to setup PCI VF/SF function attributes in +a unified way for SmartNIC and non-SmartNIC. + +This is supported only when the eswitch mode is set to switchdev. Port function +configuration of the PCI VF/SF is supported through devlink eswitch port. + +Port function attributes should be set before PCI VF/SF is enumerated by the +driver. + +MAC address setup +----------------- +mlx5 driver provides mechanism to setup the MAC address of the PCI VF/SF. + +The configured MAC address of the PCI VF/SF will be used by netdevice and rdma +device created for the PCI VF/SF. + +- Get the MAC address of the VF identified by its unique devlink port index:: + + $ devlink port show pci/0000:06:00.0/2 + pci/0000:06:00.0/2: type eth netdev enp6s0pf0vf1 flavour pcivf pfnum 0 vfnum 1 + function: + hw_addr 00:00:00:00:00:00 + +- Set the MAC address of the VF identified by its unique devlink port index:: + + $ devlink port function set pci/0000:06:00.0/2 hw_addr 00:11:22:33:44:55 + + $ devlink port show pci/0000:06:00.0/2 + pci/0000:06:00.0/2: type eth netdev enp6s0pf0vf1 flavour pcivf pfnum 0 vfnum 1 + function: + hw_addr 00:11:22:33:44:55 + +- Get the MAC address of the SF identified by its unique devlink port index:: + + $ devlink port show pci/0000:06:00.0/32768 + pci/0000:06:00.0/32768: type eth netdev enp6s0pf0sf88 flavour pcisf pfnum 0 sfnum 88 + function: + hw_addr 00:00:00:00:00:00 + +- Set the MAC address of the VF identified by its unique devlink port index:: + + $ devlink port function set pci/0000:06:00.0/32768 hw_addr 00:00:00:00:88:88 + + $ devlink port show pci/0000:06:00.0/32768 + pci/0000:06:00.0/32768: type eth netdev enp6s0pf0sf88 flavour pcivf pfnum 0 sfnum 88 + function: + hw_addr 00:00:00:00:88:88 + +SF state setup +-------------- +To use the SF, the user must active the SF using the SF function state +attribute. + +- Get the state of the SF identified by its unique devlink port index:: + + $ devlink port show ens2f0npf0sf88 + pci/0000:06:00.0/32768: type eth netdev ens2f0npf0sf88 flavour pcisf controller 0 pfnum 0 sfnum 88 external false splittable false + function: + hw_addr 00:00:00:00:88:88 state inactive opstate detached + +- Activate the function and verify its state is active:: + + $ devlink port function set ens2f0npf0sf88 state active + + $ devlink port show ens2f0npf0sf88 + pci/0000:06:00.0/32768: type eth netdev ens2f0npf0sf88 flavour pcisf controller 0 pfnum 0 sfnum 88 external false splittable false + function: + hw_addr 00:00:00:00:88:88 state active opstate detached + +Upon function activation, the PF driver instance gets the event from the device +that a particular SF was activated. It's the cue to put the device on bus, probe +it and instantiate the devlink instance and class specific auxiliary devices +for it. + +- Show the auxiliary device and port of the subfunction:: + + $ devlink dev show + devlink dev show auxiliary/mlx5_core.sf.4 + + $ devlink port show auxiliary/mlx5_core.sf.4/1 + auxiliary/mlx5_core.sf.4/1: type eth netdev p0sf88 flavour virtual port 0 splittable false + + $ rdma link show mlx5_0/1 + link mlx5_0/1 state ACTIVE physical_state LINK_UP netdev p0sf88 + + $ rdma dev show + 8: rocep6s0f1: node_type ca fw 16.29.0550 node_guid 248a:0703:00b3:d113 sys_image_guid 248a:0703:00b3:d112 + 13: mlx5_0: node_type ca fw 16.29.0550 node_guid 0000:00ff:fe00:8888 sys_image_guid 248a:0703:00b3:d112 + +- Subfunction auxiliary device and class device hierarchy:: + + mlx5_core.sf.4 + (subfunction auxiliary device) + /\ + / \ + / \ + / \ + / \ + mlx5_core.eth.4 mlx5_core.rdma.4 + (sf eth aux dev) (sf rdma aux dev) + | | + | | + p0sf88 mlx5_0 + (sf netdev) (sf rdma device) + +Additionally, the SF port also gets the event when the driver attaches to the +auxiliary device of the subfunction. This results in changing the operational +state of the function. This provides visiblity to the user to decide when is it +safe to delete the SF port for graceful termination of the subfunction. + +- Show the SF port operational state:: + + $ devlink port show ens2f0npf0sf88 + pci/0000:06:00.0/32768: type eth netdev ens2f0npf0sf88 flavour pcisf controller 0 pfnum 0 sfnum 88 external false splittable false + function: + hw_addr 00:00:00:00:88:88 state active opstate attached + Devlink health reporters ======================== -- cgit v1.2.3 From 41f42b6e693dc9822f83bc832de508600b00535f Mon Sep 17 00:00:00 2001 From: Rob Herring Date: Mon, 4 Jan 2021 17:58:07 +0100 Subject: media: dt-bindings: Convert video-interfaces.txt properties to schemas Convert video-interfaces.txt to DT schema. As it contains a mixture of device level and endpoint properties, split it up into 2 schemas. Binding schemas will need to reference both the graph.yaml and video-interfaces.yaml schemas. The exact schema depends on how many ports and endpoints for the binding. A single port with a single endpoint looks similar to this: port: $ref: /schemas/graph.yaml#/$defs/port-base properties: endpoint: $ref: video-interfaces.yaml# unevaluatedProperties: false properties: bus-width: enum: [ 8, 10, 12, 16 ] pclk-sample: true hsync-active: true vsync-active: true required: - bus-width additionalProperties: false Acked-by: Sakari Ailus Acked-by: Jacopo Mondi Acked-by: Guennadi Liakhovetski Acked-by: Hans Verkuil Reviewed-by: Laurent Pinchart Signed-off-by: Rob Herring Signed-off-by: Mauro Carvalho Chehab --- .../bindings/media/video-interface-devices.yaml | 406 +++++++++++++ .../devicetree/bindings/media/video-interfaces.txt | 640 +-------------------- .../bindings/media/video-interfaces.yaml | 344 +++++++++++ 3 files changed, 751 insertions(+), 639 deletions(-) create mode 100644 Documentation/devicetree/bindings/media/video-interface-devices.yaml create mode 100644 Documentation/devicetree/bindings/media/video-interfaces.yaml (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/media/video-interface-devices.yaml b/Documentation/devicetree/bindings/media/video-interface-devices.yaml new file mode 100644 index 000000000000..4527f56a5a6e --- /dev/null +++ b/Documentation/devicetree/bindings/media/video-interface-devices.yaml @@ -0,0 +1,406 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/media/video-interface-devices.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Common bindings for video receiver and transmitter devices + +maintainers: + - Jacopo Mondi + - Sakari Ailus + +properties: + flash-leds: + $ref: /schemas/types.yaml#/definitions/phandle-array + description: + An array of phandles, each referring to a flash LED, a sub-node of the LED + driver device node. + + lens-focus: + $ref: /schemas/types.yaml#/definitions/phandle + description: + A phandle to the node of the focus lens controller. + + rotation: + $ref: /schemas/types.yaml#/definitions/uint32 + enum: [ 0, 90, 180, 270 ] + description: | + The camera rotation is expressed as the angular difference in degrees + between two reference systems, one relative to the camera module, and one + defined on the external world scene to be captured when projected on the + image sensor pixel array. + + A camera sensor has a 2-dimensional reference system 'Rc' defined by its + pixel array read-out order. The origin is set to the first pixel being + read out, the X-axis points along the column read-out direction towards + the last columns, and the Y-axis along the row read-out direction towards + the last row. + + A typical example for a sensor with a 2592x1944 pixel array matrix + observed from the front is: + + 2591 X-axis 0 + <------------------------+ 0 + .......... ... ..........! + .......... ... ..........! Y-axis + ... ! + .......... ... ..........! + .......... ... ..........! 1943 + V + + The external world scene reference system 'Rs' is a 2-dimensional + reference system on the focal plane of the camera module. The origin is + placed on the top-left corner of the visible scene, the X-axis points + towards the right, and the Y-axis points towards the bottom of the scene. + The top, bottom, left and right directions are intentionally not defined + and depend on the environment in which the camera is used. + + A typical example of a (very common) picture of a shark swimming from left + to right, as seen from the camera, is: + + 0 X-axis + 0 +-------------------------------------> + ! + ! + ! + ! |\____)\___ + ! ) _____ __`< + ! |/ )/ + ! + ! + ! + V + Y-axis + + with the reference system 'Rs' placed on the camera focal plane: + + ¸.·˙! + ¸.·˙ ! + _ ¸.·˙ ! + +-/ \-+¸.·˙ ! + | (o) | ! Camera focal plane + +-----+˙·.¸ ! + ˙·.¸ ! + ˙·.¸ ! + ˙·.¸! + + When projected on the sensor's pixel array, the image and the associated + reference system 'Rs' are typically (but not always) inverted, due to the + camera module's lens optical inversion effect. + + Assuming the above represented scene of the swimming shark, the lens + inversion projects the scene and its reference system onto the sensor + pixel array, seen from the front of the camera sensor, as follows: + + Y-axis + ^ + ! + ! + ! + ! |\_____)\__ + ! ) ____ ___.< + ! |/ )/ + ! + ! + ! + 0 +-------------------------------------> + 0 X-axis + + Note the shark being upside-down. + + The resulting projected reference system is named 'Rp'. + + The camera rotation property is then defined as the angular difference in + the counter-clockwise direction between the camera reference system 'Rc' + and the projected scene reference system 'Rp'. It is expressed in degrees + as a number in the range [0, 360[. + + Examples + + 0 degrees camera rotation: + + + Y-Rp + ^ + Y-Rc ! + ^ ! + ! ! + ! ! + ! ! + ! ! + ! ! + ! ! + ! ! + ! 0 +-------------------------------------> + ! 0 X-Rp + 0 +-------------------------------------> + 0 X-Rc + + + X-Rc 0 + <------------------------------------+ 0 + X-Rp 0 ! + <------------------------------------+ 0 ! + ! ! + ! ! + ! ! + ! ! + ! ! + ! ! + ! ! + ! V + ! Y-Rc + V + Y-Rp + + 90 degrees camera rotation: + + 0 Y-Rc + 0 +--------------------> + ! Y-Rp + ! ^ + ! ! + ! ! + ! ! + ! ! + ! ! + ! ! + ! ! + ! ! + ! ! + ! 0 +-------------------------------------> + ! 0 X-Rp + ! + ! + ! + ! + V + X-Rc + + 180 degrees camera rotation: + + 0 + <------------------------------------+ 0 + X-Rc ! + Y-Rp ! + ^ ! + ! ! + ! ! + ! ! + ! ! + ! ! + ! ! + ! V + ! Y-Rc + 0 +-------------------------------------> + 0 X-Rp + + 270 degrees camera rotation: + + 0 Y-Rc + 0 +--------------------> + ! 0 + ! <-----------------------------------+ 0 + ! X-Rp ! + ! ! + ! ! + ! ! + ! ! + ! ! + ! ! + ! ! + ! ! + ! V + ! Y-Rp + ! + ! + ! + ! + V + X-Rc + + + Example one - Webcam + + A camera module installed on the user facing part of a laptop screen + casing used for video calls. The captured images are meant to be displayed + in landscape mode (width > height) on the laptop screen. + + The camera is typically mounted upside-down to compensate the lens optical + inversion effect: + + Y-Rp + Y-Rc ^ + ^ ! + ! ! + ! ! |\_____)\__ + ! ! ) ____ ___.< + ! ! |/ )/ + ! ! + ! ! + ! ! + ! 0 +-------------------------------------> + ! 0 X-Rp + 0 +-------------------------------------> + 0 X-Rc + + The two reference systems are aligned, the resulting camera rotation is + 0 degrees, no rotation correction needs to be applied to the resulting + image once captured to memory buffers to correctly display it to users: + + +--------------------------------------+ + ! ! + ! ! + ! ! + ! |\____)\___ ! + ! ) _____ __`< ! + ! |/ )/ ! + ! ! + ! ! + ! ! + +--------------------------------------+ + + If the camera sensor is not mounted upside-down to compensate for the lens + optical inversion, the two reference systems will not be aligned, with + 'Rp' being rotated 180 degrees relatively to 'Rc': + + + X-Rc 0 + <------------------------------------+ 0 + ! + Y-Rp ! + ^ ! + ! ! + ! |\_____)\__ ! + ! ) ____ ___.< ! + ! |/ )/ ! + ! ! + ! ! + ! V + ! Y-Rc + 0 +-------------------------------------> + 0 X-Rp + + The image once captured to memory will then be rotated by 180 degrees: + + +--------------------------------------+ + ! ! + ! ! + ! ! + ! __/(_____/| ! + ! >.___ ____ ( ! + ! \( \| ! + ! ! + ! ! + ! ! + +--------------------------------------+ + + A software rotation correction of 180 degrees should be applied to + correctly display the image: + + +--------------------------------------+ + ! ! + ! ! + ! ! + ! |\____)\___ ! + ! ) _____ __`< ! + ! |/ )/ ! + ! ! + ! ! + ! ! + +--------------------------------------+ + + Example two - Phone camera + + A camera installed on the back side of a mobile device facing away from + the user. The captured images are meant to be displayed in portrait mode + (height > width) to match the device screen orientation and the device + usage orientation used when taking the picture. + + The camera sensor is typically mounted with its pixel array longer side + aligned to the device longer side, upside-down mounted to compensate for + the lens optical inversion effect: + + 0 Y-Rc + 0 +--------------------> + ! Y-Rp + ! ^ + ! ! + ! ! + ! ! + ! ! |\_____)\__ + ! ! ) ____ ___.< + ! ! |/ )/ + ! ! + ! ! + ! ! + ! 0 +-------------------------------------> + ! 0 X-Rp + ! + ! + ! + ! + V + X-Rc + + The two reference systems are not aligned and the 'Rp' reference system is + rotated by 90 degrees in the counter-clockwise direction relatively to the + 'Rc' reference system. + + The image once captured to memory will be rotated: + + +-------------------------------------+ + | _ _ | + | \ / | + | | | | + | | | | + | | > | + | < | | + | | | | + | . | + | V | + +-------------------------------------+ + + A correction of 90 degrees in counter-clockwise direction has to be + applied to correctly display the image in portrait mode on the device + screen: + + +--------------------+ + | | + | | + | | + | | + | | + | | + | |\____)\___ | + | ) _____ __`< | + | |/ )/ | + | | + | | + | | + | | + | | + +--------------------+ + + orientation: + description: + The orientation of a device (typically an image sensor or a flash LED) + describing its mounting position relative to the usage orientation of the + system where the device is installed on. + $ref: /schemas/types.yaml#/definitions/uint32 + enum: + # Front. The device is mounted on the front facing side of the system. For + # mobile devices such as smartphones, tablets and laptops the front side + # is the user facing side. + - 0 + # Back. The device is mounted on the back side of the system, which is + # defined as the opposite side of the front facing one. + - 1 + # External. The device is not attached directly to the system but is + # attached in a way that allows it to move freely. + - 2 + +additionalProperties: true + +... diff --git a/Documentation/devicetree/bindings/media/video-interfaces.txt b/Documentation/devicetree/bindings/media/video-interfaces.txt index 3920f25a9123..8fcf5f52bf5b 100644 --- a/Documentation/devicetree/bindings/media/video-interfaces.txt +++ b/Documentation/devicetree/bindings/media/video-interfaces.txt @@ -1,639 +1 @@ -Common bindings for video receiver and transmitter interfaces - -General concept ---------------- - -Video data pipelines usually consist of external devices, e.g. camera sensors, -controlled over an I2C, SPI or UART bus, and SoC internal IP blocks, including -video DMA engines and video data processors. - -SoC internal blocks are described by DT nodes, placed similarly to other SoC -blocks. External devices are represented as child nodes of their respective -bus controller nodes, e.g. I2C. - -Data interfaces on all video devices are described by their child 'port' nodes. -Configuration of a port depends on other devices participating in the data -transfer and is described by 'endpoint' subnodes. - -device { - ... - ports { - #address-cells = <1>; - #size-cells = <0>; - - port@0 { - ... - endpoint@0 { ... }; - endpoint@1 { ... }; - }; - port@1 { ... }; - }; -}; - -If a port can be configured to work with more than one remote device on the same -bus, an 'endpoint' child node must be provided for each of them. If more than -one port is present in a device node or there is more than one endpoint at a -port, or port node needs to be associated with a selected hardware interface, -a common scheme using '#address-cells', '#size-cells' and 'reg' properties is -used. - -All 'port' nodes can be grouped under optional 'ports' node, which allows to -specify #address-cells, #size-cells properties independently for the 'port' -and 'endpoint' nodes and any child device nodes a device might have. - -Two 'endpoint' nodes are linked with each other through their 'remote-endpoint' -phandles. An endpoint subnode of a device contains all properties needed for -configuration of this device for data exchange with other device. In most -cases properties at the peer 'endpoint' nodes will be identical, however they -might need to be different when there is any signal modifications on the bus -between two devices, e.g. there are logic signal inverters on the lines. - -It is allowed for multiple endpoints at a port to be active simultaneously, -where supported by a device. For example, in case where a data interface of -a device is partitioned into multiple data busses, e.g. 16-bit input port -divided into two separate ITU-R BT.656 8-bit busses. In such case bus-width -and data-shift properties can be used to assign physical data lines to each -endpoint node (logical bus). - -Documenting bindings for devices --------------------------------- - -All required and optional bindings the device supports shall be explicitly -documented in device DT binding documentation. This also includes port and -endpoint nodes for the device, including unit-addresses and reg properties where -relevant. - -Please also see Documentation/devicetree/bindings/graph.txt . - -Required properties -------------------- - -If there is more than one 'port' or more than one 'endpoint' node or 'reg' -property is present in port and/or endpoint nodes the following properties -are required in a relevant parent node: - - - #address-cells : number of cells required to define port/endpoint - identifier, should be 1. - - #size-cells : should be zero. - - -Optional properties -------------------- - -- flash-leds: An array of phandles, each referring to a flash LED, a sub-node - of the LED driver device node. - -- lens-focus: A phandle to the node of the focus lens controller. - -- rotation: The camera rotation is expressed as the angular difference in - degrees between two reference systems, one relative to the camera module, and - one defined on the external world scene to be captured when projected on the - image sensor pixel array. - - A camera sensor has a 2-dimensional reference system 'Rc' defined by - its pixel array read-out order. The origin is set to the first pixel - being read out, the X-axis points along the column read-out direction - towards the last columns, and the Y-axis along the row read-out - direction towards the last row. - - A typical example for a sensor with a 2592x1944 pixel array matrix - observed from the front is: - - 2591 X-axis 0 - <------------------------+ 0 - .......... ... ..........! - .......... ... ..........! Y-axis - ... ! - .......... ... ..........! - .......... ... ..........! 1943 - V - - The external world scene reference system 'Rs' is a 2-dimensional - reference system on the focal plane of the camera module. The origin is - placed on the top-left corner of the visible scene, the X-axis points - towards the right, and the Y-axis points towards the bottom of the - scene. The top, bottom, left and right directions are intentionally not - defined and depend on the environment in which the camera is used. - - A typical example of a (very common) picture of a shark swimming from - left to right, as seen from the camera, is: - - 0 X-axis - 0 +-------------------------------------> - ! - ! - ! - ! |\____)\___ - ! ) _____ __`< - ! |/ )/ - ! - ! - ! - V - Y-axis - - with the reference system 'Rs' placed on the camera focal plane: - - ¸.·˙! - ¸.·˙ ! - _ ¸.·˙ ! - +-/ \-+¸.·˙ ! - | (o) | ! Camera focal plane - +-----+˙·.¸ ! - ˙·.¸ ! - ˙·.¸ ! - ˙·.¸! - - When projected on the sensor's pixel array, the image and the associated - reference system 'Rs' are typically (but not always) inverted, due to - the camera module's lens optical inversion effect. - - Assuming the above represented scene of the swimming shark, the lens - inversion projects the scene and its reference system onto the sensor - pixel array, seen from the front of the camera sensor, as follows: - - Y-axis - ^ - ! - ! - ! - ! |\_____)\__ - ! ) ____ ___.< - ! |/ )/ - ! - ! - ! - 0 +-------------------------------------> - 0 X-axis - - Note the shark being upside-down. - - The resulting projected reference system is named 'Rp'. - - The camera rotation property is then defined as the angular difference - in the counter-clockwise direction between the camera reference system - 'Rc' and the projected scene reference system 'Rp'. It is expressed in - degrees as a number in the range [0, 360[. - - Examples - - 0 degrees camera rotation: - - - Y-Rp - ^ - Y-Rc ! - ^ ! - ! ! - ! ! - ! ! - ! ! - ! ! - ! ! - ! ! - ! 0 +-------------------------------------> - ! 0 X-Rp - 0 +-------------------------------------> - 0 X-Rc - - - X-Rc 0 - <------------------------------------+ 0 - X-Rp 0 ! - <------------------------------------+ 0 ! - ! ! - ! ! - ! ! - ! ! - ! ! - ! ! - ! ! - ! V - ! Y-Rc - V - Y-Rp - - 90 degrees camera rotation: - - 0 Y-Rc - 0 +--------------------> - ! Y-Rp - ! ^ - ! ! - ! ! - ! ! - ! ! - ! ! - ! ! - ! ! - ! ! - ! ! - ! 0 +-------------------------------------> - ! 0 X-Rp - ! - ! - ! - ! - V - X-Rc - - 180 degrees camera rotation: - - 0 - <------------------------------------+ 0 - X-Rc ! - Y-Rp ! - ^ ! - ! ! - ! ! - ! ! - ! ! - ! ! - ! ! - ! V - ! Y-Rc - 0 +-------------------------------------> - 0 X-Rp - - 270 degrees camera rotation: - - 0 Y-Rc - 0 +--------------------> - ! 0 - ! <-----------------------------------+ 0 - ! X-Rp ! - ! ! - ! ! - ! ! - ! ! - ! ! - ! ! - ! ! - ! ! - ! V - ! Y-Rp - ! - ! - ! - ! - V - X-Rc - - - Example one - Webcam - - A camera module installed on the user facing part of a laptop screen - casing used for video calls. The captured images are meant to be - displayed in landscape mode (width > height) on the laptop screen. - - The camera is typically mounted upside-down to compensate the lens - optical inversion effect: - - Y-Rp - Y-Rc ^ - ^ ! - ! ! - ! ! |\_____)\__ - ! ! ) ____ ___.< - ! ! |/ )/ - ! ! - ! ! - ! ! - ! 0 +-------------------------------------> - ! 0 X-Rp - 0 +-------------------------------------> - 0 X-Rc - - The two reference systems are aligned, the resulting camera rotation is - 0 degrees, no rotation correction needs to be applied to the resulting - image once captured to memory buffers to correctly display it to users: - - +--------------------------------------+ - ! ! - ! ! - ! ! - ! |\____)\___ ! - ! ) _____ __`< ! - ! |/ )/ ! - ! ! - ! ! - ! ! - +--------------------------------------+ - - If the camera sensor is not mounted upside-down to compensate for the - lens optical inversion, the two reference systems will not be aligned, - with 'Rp' being rotated 180 degrees relatively to 'Rc': - - - X-Rc 0 - <------------------------------------+ 0 - ! - Y-Rp ! - ^ ! - ! ! - ! |\_____)\__ ! - ! ) ____ ___.< ! - ! |/ )/ ! - ! ! - ! ! - ! V - ! Y-Rc - 0 +-------------------------------------> - 0 X-Rp - - The image once captured to memory will then be rotated by 180 degrees: - - +--------------------------------------+ - ! ! - ! ! - ! ! - ! __/(_____/| ! - ! >.___ ____ ( ! - ! \( \| ! - ! ! - ! ! - ! ! - +--------------------------------------+ - - A software rotation correction of 180 degrees should be applied to - correctly display the image: - - +--------------------------------------+ - ! ! - ! ! - ! ! - ! |\____)\___ ! - ! ) _____ __`< ! - ! |/ )/ ! - ! ! - ! ! - ! ! - +--------------------------------------+ - - Example two - Phone camera - - A camera installed on the back side of a mobile device facing away from - the user. The captured images are meant to be displayed in portrait mode - (height > width) to match the device screen orientation and the device - usage orientation used when taking the picture. - - The camera sensor is typically mounted with its pixel array longer side - aligned to the device longer side, upside-down mounted to compensate for - the lens optical inversion effect: - - 0 Y-Rc - 0 +--------------------> - ! Y-Rp - ! ^ - ! ! - ! ! - ! ! - ! ! |\_____)\__ - ! ! ) ____ ___.< - ! ! |/ )/ - ! ! - ! ! - ! ! - ! 0 +-------------------------------------> - ! 0 X-Rp - ! - ! - ! - ! - V - X-Rc - - The two reference systems are not aligned and the 'Rp' reference - system is rotated by 90 degrees in the counter-clockwise direction - relatively to the 'Rc' reference system. - - The image once captured to memory will be rotated: - - +-------------------------------------+ - | _ _ | - | \ / | - | | | | - | | | | - | | > | - | < | | - | | | | - | . | - | V | - +-------------------------------------+ - - A correction of 90 degrees in counter-clockwise direction has to be - applied to correctly display the image in portrait mode on the device - screen: - - +--------------------+ - | | - | | - | | - | | - | | - | | - | |\____)\___ | - | ) _____ __`< | - | |/ )/ | - | | - | | - | | - | | - | | - +--------------------+ - -- orientation: The orientation of a device (typically an image sensor or a flash - LED) describing its mounting position relative to the usage orientation of the - system where the device is installed on. - Possible values are: - 0 - Front. The device is mounted on the front facing side of the system. - For mobile devices such as smartphones, tablets and laptops the front side is - the user facing side. - 1 - Back. The device is mounted on the back side of the system, which is - defined as the opposite side of the front facing one. - 2 - External. The device is not attached directly to the system but is - attached in a way that allows it to move freely. - -Optional endpoint properties ----------------------------- - -- remote-endpoint: phandle to an 'endpoint' subnode of a remote device node. -- slave-mode: a boolean property indicating that the link is run in slave mode. - The default when this property is not specified is master mode. In the slave - mode horizontal and vertical synchronization signals are provided to the - slave device (data source) by the master device (data sink). In the master - mode the data source device is also the source of the synchronization signals. -- bus-type: data bus type. Possible values are: - 1 - MIPI CSI-2 C-PHY - 2 - MIPI CSI1 - 3 - CCP2 - 4 - MIPI CSI-2 D-PHY - 5 - Parallel - 6 - Bt.656 -- bus-width: number of data lines actively used, valid for the parallel busses. -- data-shift: on the parallel data busses, if bus-width is used to specify the - number of data lines, data-shift can be used to specify which data lines are - used, e.g. "bus-width=<8>; data-shift=<2>;" means, that lines 9:2 are used. -- hsync-active: active state of the HSYNC signal, 0/1 for LOW/HIGH respectively. -- vsync-active: active state of the VSYNC signal, 0/1 for LOW/HIGH respectively. - Note, that if HSYNC and VSYNC polarities are not specified, embedded - synchronization may be required, where supported. -- data-active: similar to HSYNC and VSYNC, specifies data line polarity. -- data-enable-active: similar to HSYNC and VSYNC, specifies the data enable - signal polarity. -- field-even-active: field signal level during the even field data transmission. -- pclk-sample: sample data on rising (1) or falling (0) edge of the pixel clock - signal. -- sync-on-green-active: active state of Sync-on-green (SoG) signal, 0/1 for - LOW/HIGH respectively. -- data-lanes: an array of physical data lane indexes. Position of an entry - determines the logical lane number, while the value of an entry indicates - physical lane, e.g. for 2-lane MIPI CSI-2 bus we could have - "data-lanes = <1 2>;", assuming the clock lane is on hardware lane 0. - If the hardware does not support lane reordering, monotonically - incremented values shall be used from 0 or 1 onwards, depending on - whether or not there is also a clock lane. This property is valid for - serial busses only (e.g. MIPI CSI-2). -- clock-lanes: an array of physical clock lane indexes. Position of an entry - determines the logical lane number, while the value of an entry indicates - physical lane, e.g. for a MIPI CSI-2 bus we could have "clock-lanes = <0>;", - which places the clock lane on hardware lane 0. This property is valid for - serial busses only (e.g. MIPI CSI-2). Note that for the MIPI CSI-2 bus this - array contains only one entry. -- clock-noncontinuous: a boolean property to allow MIPI CSI-2 non-continuous - clock mode. -- link-frequencies: Allowed data bus frequencies. For MIPI CSI-2, for - instance, this is the actual frequency of the bus, not bits per clock per - lane value. An array of 64-bit unsigned integers. -- lane-polarities: an array of polarities of the lanes starting from the clock - lane and followed by the data lanes in the same order as in data-lanes. - Valid values are 0 (normal) and 1 (inverted). The length of the array - should be the combined length of data-lanes and clock-lanes properties. - If the lane-polarities property is omitted, the value must be interpreted - as 0 (normal). This property is valid for serial busses only. -- strobe: Whether the clock signal is used as clock (0) or strobe (1). Used - with CCP2, for instance. - -Example -------- - -The example snippet below describes two data pipelines. ov772x and imx074 are -camera sensors with a parallel and serial (MIPI CSI-2) video bus respectively. -Both sensors are on the I2C control bus corresponding to the i2c0 controller -node. ov772x sensor is linked directly to the ceu0 video host interface. -imx074 is linked to ceu0 through the MIPI CSI-2 receiver (csi2). ceu0 has a -(single) DMA engine writing captured data to memory. ceu0 node has a single -'port' node which may indicate that at any time only one of the following data -pipelines can be active: ov772x -> ceu0 or imx074 -> csi2 -> ceu0. - - ceu0: ceu@fe910000 { - compatible = "renesas,sh-mobile-ceu"; - reg = <0xfe910000 0xa0>; - interrupts = <0x880>; - - mclk: master_clock { - compatible = "renesas,ceu-clock"; - #clock-cells = <1>; - clock-frequency = <50000000>; /* Max clock frequency */ - clock-output-names = "mclk"; - }; - - port { - #address-cells = <1>; - #size-cells = <0>; - - /* Parallel bus endpoint */ - ceu0_1: endpoint@1 { - reg = <1>; /* Local endpoint # */ - remote = <&ov772x_1_1>; /* Remote phandle */ - bus-width = <8>; /* Used data lines */ - data-shift = <2>; /* Lines 9:2 are used */ - - /* If hsync-active/vsync-active are missing, - embedded BT.656 sync is used */ - hsync-active = <0>; /* Active low */ - vsync-active = <0>; /* Active low */ - data-active = <1>; /* Active high */ - pclk-sample = <1>; /* Rising */ - }; - - /* MIPI CSI-2 bus endpoint */ - ceu0_0: endpoint@0 { - reg = <0>; - remote = <&csi2_2>; - }; - }; - }; - - i2c0: i2c@fff20000 { - ... - ov772x_1: camera@21 { - compatible = "ovti,ov772x"; - reg = <0x21>; - vddio-supply = <®ulator1>; - vddcore-supply = <®ulator2>; - - clock-frequency = <20000000>; - clocks = <&mclk 0>; - clock-names = "xclk"; - - port { - /* With 1 endpoint per port no need for addresses. */ - ov772x_1_1: endpoint { - bus-width = <8>; - remote-endpoint = <&ceu0_1>; - hsync-active = <1>; - vsync-active = <0>; /* Who came up with an - inverter here ?... */ - data-active = <1>; - pclk-sample = <1>; - }; - }; - }; - - imx074: camera@1a { - compatible = "sony,imx074"; - reg = <0x1a>; - vddio-supply = <®ulator1>; - vddcore-supply = <®ulator2>; - - clock-frequency = <30000000>; /* Shared clock with ov772x_1 */ - clocks = <&mclk 0>; - clock-names = "sysclk"; /* Assuming this is the - name in the datasheet */ - port { - imx074_1: endpoint { - clock-lanes = <0>; - data-lanes = <1 2>; - remote-endpoint = <&csi2_1>; - }; - }; - }; - }; - - csi2: csi2@ffc90000 { - compatible = "renesas,sh-mobile-csi2"; - reg = <0xffc90000 0x1000>; - interrupts = <0x17a0>; - #address-cells = <1>; - #size-cells = <0>; - - port@1 { - compatible = "renesas,csi2c"; /* One of CSI2I and CSI2C. */ - reg = <1>; /* CSI-2 PHY #1 of 2: PHY_S, - PHY_M has port address 0, - is unused. */ - csi2_1: endpoint { - clock-lanes = <0>; - data-lanes = <2 1>; - remote-endpoint = <&imx074_1>; - }; - }; - port@2 { - reg = <2>; /* port 2: link to the CEU */ - - csi2_2: endpoint { - remote-endpoint = <&ceu0_0>; - }; - }; - }; +This file has moved to video-interfaces.yaml and video-interface-devices.yaml. diff --git a/Documentation/devicetree/bindings/media/video-interfaces.yaml b/Documentation/devicetree/bindings/media/video-interfaces.yaml new file mode 100644 index 000000000000..0a7a73fd59f2 --- /dev/null +++ b/Documentation/devicetree/bindings/media/video-interfaces.yaml @@ -0,0 +1,344 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/media/video-interfaces.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Common bindings for video receiver and transmitter interface endpoints + +maintainers: + - Sakari Ailus + - Laurent Pinchart + +description: | + Video data pipelines usually consist of external devices, e.g. camera sensors, + controlled over an I2C, SPI or UART bus, and SoC internal IP blocks, including + video DMA engines and video data processors. + + SoC internal blocks are described by DT nodes, placed similarly to other SoC + blocks. External devices are represented as child nodes of their respective + bus controller nodes, e.g. I2C. + + Data interfaces on all video devices are described by their child 'port' nodes. + Configuration of a port depends on other devices participating in the data + transfer and is described by 'endpoint' subnodes. + + device { + ... + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + ... + endpoint@0 { ... }; + endpoint@1 { ... }; + }; + port@1 { ... }; + }; + }; + + If a port can be configured to work with more than one remote device on the same + bus, an 'endpoint' child node must be provided for each of them. If more than + one port is present in a device node or there is more than one endpoint at a + port, or port node needs to be associated with a selected hardware interface, + a common scheme using '#address-cells', '#size-cells' and 'reg' properties is + used. + + All 'port' nodes can be grouped under optional 'ports' node, which allows to + specify #address-cells, #size-cells properties independently for the 'port' + and 'endpoint' nodes and any child device nodes a device might have. + + Two 'endpoint' nodes are linked with each other through their 'remote-endpoint' + phandles. An endpoint subnode of a device contains all properties needed for + configuration of this device for data exchange with other device. In most + cases properties at the peer 'endpoint' nodes will be identical, however they + might need to be different when there is any signal modifications on the bus + between two devices, e.g. there are logic signal inverters on the lines. + + It is allowed for multiple endpoints at a port to be active simultaneously, + where supported by a device. For example, in case where a data interface of + a device is partitioned into multiple data busses, e.g. 16-bit input port + divided into two separate ITU-R BT.656 8-bit busses. In such case bus-width + and data-shift properties can be used to assign physical data lines to each + endpoint node (logical bus). + + Documenting bindings for devices + -------------------------------- + + All required and optional bindings the device supports shall be explicitly + documented in device DT binding documentation. This also includes port and + endpoint nodes for the device, including unit-addresses and reg properties + where relevant. + +allOf: + - $ref: /schemas/graph.yaml#/$defs/endpoint-base + +properties: + slave-mode: + type: boolean + description: + Indicates that the link is run in slave mode. The default when this + property is not specified is master mode. In the slave mode horizontal and + vertical synchronization signals are provided to the slave device (data + source) by the master device (data sink). In the master mode the data + source device is also the source of the synchronization signals. + + bus-type: + $ref: /schemas/types.yaml#/definitions/uint32 + enum: + - 1 # MIPI CSI-2 C-PHY + - 2 # MIPI CSI1 + - 3 # CCP2 + - 4 # MIPI CSI-2 D-PHY + - 5 # Parallel + - 6 # BT.656 + description: + Data bus type. + + bus-width: + $ref: /schemas/types.yaml#/definitions/uint32 + maximum: 64 + description: + Number of data lines actively used, valid for the parallel busses. + + data-shift: + $ref: /schemas/types.yaml#/definitions/uint32 + maximum: 64 + description: + On the parallel data busses, if bus-width is used to specify the number of + data lines, data-shift can be used to specify which data lines are used, + e.g. "bus-width=<8>; data-shift=<2>;" means, that lines 9:2 are used. + + hsync-active: + $ref: /schemas/types.yaml#/definitions/uint32 + enum: [ 0, 1 ] + description: + Active state of the HSYNC signal, 0/1 for LOW/HIGH respectively. + + vsync-active: + $ref: /schemas/types.yaml#/definitions/uint32 + enum: [ 0, 1 ] + description: + Active state of the VSYNC signal, 0/1 for LOW/HIGH respectively. Note, + that if HSYNC and VSYNC polarities are not specified, embedded + synchronization may be required, where supported. + + data-active: + $ref: /schemas/types.yaml#/definitions/uint32 + enum: [ 0, 1 ] + description: + Similar to HSYNC and VSYNC, specifies data line polarity. + + data-enable-active: + $ref: /schemas/types.yaml#/definitions/uint32 + enum: [ 0, 1 ] + description: + Similar to HSYNC and VSYNC, specifies the data enable signal polarity. + + field-even-active: + $ref: /schemas/types.yaml#/definitions/uint32 + enum: [ 0, 1 ] + description: + Field signal level during the even field data transmission. + + pclk-sample: + $ref: /schemas/types.yaml#/definitions/uint32 + enum: [ 0, 1 ] + description: + Sample data on rising (1) or falling (0) edge of the pixel clock signal. + + sync-on-green-active: + $ref: /schemas/types.yaml#/definitions/uint32 + enum: [ 0, 1 ] + description: + Active state of Sync-on-green (SoG) signal, 0/1 for LOW/HIGH respectively. + + data-lanes: + $ref: /schemas/types.yaml#/definitions/uint32-array + minItems: 1 + maxItems: 8 + items: + # Assume up to 9 physical lane indices + maximum: 8 + description: + An array of physical data lane indexes. Position of an entry determines + the logical lane number, while the value of an entry indicates physical + lane, e.g. for 2-lane MIPI CSI-2 bus we could have "data-lanes = <1 2>;", + assuming the clock lane is on hardware lane 0. If the hardware does not + support lane reordering, monotonically incremented values shall be used + from 0 or 1 onwards, depending on whether or not there is also a clock + lane. This property is valid for serial busses only (e.g. MIPI CSI-2). + + clock-lanes: + $ref: /schemas/types.yaml#/definitions/uint32 + # Assume up to 9 physical lane indices + maximum: 8 + description: + Physical clock lane index. Position of an entry determines the logical + lane number, while the value of an entry indicates physical lane, e.g. for + a MIPI CSI-2 bus we could have "clock-lanes = <0>;", which places the + clock lane on hardware lane 0. This property is valid for serial busses + only (e.g. MIPI CSI-2). + + clock-noncontinuous: + type: boolean + description: + Allow MIPI CSI-2 non-continuous clock mode. + + link-frequencies: + $ref: /schemas/types.yaml#/definitions/uint64-array + description: + Allowed data bus frequencies. For MIPI CSI-2, for instance, this is the + actual frequency of the bus, not bits per clock per lane value. An array + of 64-bit unsigned integers. + + lane-polarities: + $ref: /schemas/types.yaml#/definitions/uint32-array + minItems: 1 + maxItems: 9 + items: + enum: [ 0, 1 ] + description: + An array of polarities of the lanes starting from the clock lane and + followed by the data lanes in the same order as in data-lanes. Valid + values are 0 (normal) and 1 (inverted). The length of the array should be + the combined length of data-lanes and clock-lanes properties. If the + lane-polarities property is omitted, the value must be interpreted as 0 + (normal). This property is valid for serial busses only. + + strobe: + $ref: /schemas/types.yaml#/definitions/uint32 + enum: [ 0, 1 ] + description: + Whether the clock signal is used as clock (0) or strobe (1). Used with + CCP2, for instance. + +additionalProperties: true + +examples: + # The example snippet below describes two data pipelines. ov772x and imx074 + # are camera sensors with a parallel and serial (MIPI CSI-2) video bus + # respectively. Both sensors are on the I2C control bus corresponding to the + # i2c0 controller node. ov772x sensor is linked directly to the ceu0 video + # host interface. imx074 is linked to ceu0 through the MIPI CSI-2 receiver + # (csi2). ceu0 has a (single) DMA engine writing captured data to memory. + # ceu0 node has a single 'port' node which may indicate that at any time + # only one of the following data pipelines can be active: + # ov772x -> ceu0 or imx074 -> csi2 -> ceu0. + - | + ceu@fe910000 { + compatible = "renesas,sh-mobile-ceu"; + reg = <0xfe910000 0xa0>; + interrupts = <0x880>; + + mclk: master_clock { + compatible = "renesas,ceu-clock"; + #clock-cells = <1>; + clock-frequency = <50000000>; /* Max clock frequency */ + clock-output-names = "mclk"; + }; + + port { + #address-cells = <1>; + #size-cells = <0>; + + /* Parallel bus endpoint */ + ceu0_1: endpoint@1 { + reg = <1>; /* Local endpoint # */ + remote-endpoint = <&ov772x_1_1>; /* Remote phandle */ + bus-width = <8>; /* Used data lines */ + data-shift = <2>; /* Lines 9:2 are used */ + + /* If hsync-active/vsync-active are missing, + embedded BT.656 sync is used */ + hsync-active = <0>; /* Active low */ + vsync-active = <0>; /* Active low */ + data-active = <1>; /* Active high */ + pclk-sample = <1>; /* Rising */ + }; + + /* MIPI CSI-2 bus endpoint */ + ceu0_0: endpoint@0 { + reg = <0>; + remote-endpoint = <&csi2_2>; + }; + }; + }; + + i2c { + #address-cells = <1>; + #size-cells = <0>; + + camera@21 { + compatible = "ovti,ov772x"; + reg = <0x21>; + vddio-supply = <®ulator1>; + vddcore-supply = <®ulator2>; + + clock-frequency = <20000000>; + clocks = <&mclk 0>; + clock-names = "xclk"; + + port { + /* With 1 endpoint per port no need for addresses. */ + ov772x_1_1: endpoint { + bus-width = <8>; + remote-endpoint = <&ceu0_1>; + hsync-active = <1>; + vsync-active = <0>; /* Who came up with an + inverter here ?... */ + data-active = <1>; + pclk-sample = <1>; + }; + }; + }; + + camera@1a { + compatible = "sony,imx074"; + reg = <0x1a>; + vddio-supply = <®ulator1>; + vddcore-supply = <®ulator2>; + + clock-frequency = <30000000>; /* Shared clock with ov772x_1 */ + clocks = <&mclk 0>; + clock-names = "sysclk"; /* Assuming this is the + name in the datasheet */ + port { + imx074_1: endpoint { + clock-lanes = <0>; + data-lanes = <1 2>; + remote-endpoint = <&csi2_1>; + }; + }; + }; + }; + + csi2: csi2@ffc90000 { + compatible = "renesas,sh-mobile-csi2"; + reg = <0xffc90000 0x1000>; + interrupts = <0x17a0>; + #address-cells = <1>; + #size-cells = <0>; + + port@1 { + compatible = "renesas,csi2c"; /* One of CSI2I and CSI2C. */ + reg = <1>; /* CSI-2 PHY #1 of 2: PHY_S, + PHY_M has port address 0, + is unused. */ + csi2_1: endpoint { + clock-lanes = <0>; + data-lanes = <2 1>; + remote-endpoint = <&imx074_1>; + }; + }; + port@2 { + reg = <2>; /* port 2: link to the CEU */ + + csi2_2: endpoint { + remote-endpoint = <&ceu0_0>; + }; + }; + }; + +... -- cgit v1.2.3 From 066a94e28a23e04c0e9cb293f9ead56d409d7e41 Mon Sep 17 00:00:00 2001 From: Rob Herring Date: Mon, 4 Jan 2021 17:58:08 +0100 Subject: media: dt-bindings: media: Use graph and video-interfaces schemas Now that we have graph and video-interfaces schemas, rework the media related schemas to use them. Cc: Jacopo Mondi Signed-off-by: Rob Herring Reviewed-by: Laurent Pinchart Acked-by: Maxime Ripard Acked-by: Sakari Ailus Signed-off-by: Mauro Carvalho Chehab --- .../bindings/media/allwinner,sun4i-a10-csi.yaml | 11 +- .../bindings/media/allwinner,sun6i-a31-csi.yaml | 12 +-- .../devicetree/bindings/media/i2c/adv7180.yaml | 36 ++----- .../devicetree/bindings/media/i2c/adv7604.yaml | 37 ++----- .../bindings/media/i2c/aptina,mt9v111.yaml | 4 +- .../bindings/media/i2c/imi,rdacm2x-gmsl.yaml | 30 +----- .../devicetree/bindings/media/i2c/imx219.yaml | 21 ++-- .../bindings/media/i2c/maxim,max9286.yaml | 101 ++++-------------- .../devicetree/bindings/media/i2c/mipi-ccs.yaml | 17 ++-- .../devicetree/bindings/media/i2c/ov5647.yaml | 76 ++++++++++++++ .../devicetree/bindings/media/i2c/ov8856.yaml | 22 ++-- .../bindings/media/i2c/ovti,ov02a10.yaml | 29 +++--- .../devicetree/bindings/media/i2c/ovti,ov2680.yaml | 6 +- .../devicetree/bindings/media/i2c/ovti,ov772x.yaml | 9 +- .../devicetree/bindings/media/i2c/sony,imx214.yaml | 25 ++--- .../devicetree/bindings/media/i2c/sony,imx274.yaml | 3 +- .../bindings/media/marvell,mmp2-ccic.yaml | 15 +-- .../devicetree/bindings/media/nxp,imx7-csi.yaml | 5 +- .../bindings/media/nxp,imx7-mipi-csi2.yaml | 32 ++---- .../devicetree/bindings/media/renesas,ceu.yaml | 17 +--- .../devicetree/bindings/media/renesas,csi2.yaml | 54 ++-------- .../devicetree/bindings/media/renesas,vin.yaml | 113 +++------------------ .../devicetree/bindings/media/rockchip-isp1.yaml | 40 +------- .../devicetree/bindings/media/st,stm32-dcmi.yaml | 18 +--- .../devicetree/bindings/media/ti,cal.yaml | 55 +++------- .../bindings/media/xilinx/xlnx,csi2rxss.yaml | 39 ++----- 26 files changed, 244 insertions(+), 583 deletions(-) create mode 100644 Documentation/devicetree/bindings/media/i2c/ov5647.yaml (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/media/allwinner,sun4i-a10-csi.yaml b/Documentation/devicetree/bindings/media/allwinner,sun4i-a10-csi.yaml index 09318830db47..6ced94064215 100644 --- a/Documentation/devicetree/bindings/media/allwinner,sun4i-a10-csi.yaml +++ b/Documentation/devicetree/bindings/media/allwinner,sun4i-a10-csi.yaml @@ -67,14 +67,14 @@ properties: interconnect-names: const: dma-mem - # See ./video-interfaces.txt for details port: - type: object + $ref: /schemas/graph.yaml#/$defs/port-base additionalProperties: false properties: endpoint: - type: object + $ref: video-interfaces.yaml# + unevaluatedProperties: false properties: bus-width: @@ -83,7 +83,6 @@ properties: data-active: true hsync-active: true pclk-sample: true - remote-endpoint: true vsync-active: true required: @@ -91,12 +90,8 @@ properties: - data-active - hsync-active - pclk-sample - - remote-endpoint - vsync-active - required: - - endpoint - required: - compatible - reg diff --git a/Documentation/devicetree/bindings/media/allwinner,sun6i-a31-csi.yaml b/Documentation/devicetree/bindings/media/allwinner,sun6i-a31-csi.yaml index 1fd9b5532a21..8b568072a069 100644 --- a/Documentation/devicetree/bindings/media/allwinner,sun6i-a31-csi.yaml +++ b/Documentation/devicetree/bindings/media/allwinner,sun6i-a31-csi.yaml @@ -40,17 +40,15 @@ properties: resets: maxItems: 1 - # See ./video-interfaces.txt for details port: - type: object + $ref: /schemas/graph.yaml#/$defs/port-base properties: endpoint: - type: object + $ref: video-interfaces.yaml# + unevaluatedProperties: false properties: - remote-endpoint: true - bus-width: enum: [ 8, 10, 12, 16 ] @@ -60,10 +58,6 @@ properties: required: - bus-width - - remote-endpoint - - required: - - endpoint additionalProperties: false diff --git a/Documentation/devicetree/bindings/media/i2c/adv7180.yaml b/Documentation/devicetree/bindings/media/i2c/adv7180.yaml index d8c54f9d9506..bcfd93739b4f 100644 --- a/Documentation/devicetree/bindings/media/i2c/adv7180.yaml +++ b/Documentation/devicetree/bindings/media/i2c/adv7180.yaml @@ -36,17 +36,9 @@ properties: maxItems: 1 port: - type: object - description: - A node containing a single endpoint as doucmented in - Documentation/devicetree/bindings/media/video-interfaces.txt - - ports: - type: object - description: - A node containing input and output port nodes with endpoint definitions - as documented in - Documentation/devicetree/bindings/media/video-interfaces.txt + $ref: /schemas/graph.yaml#/properties/port + + ports: true additionalProperties: false @@ -80,25 +72,20 @@ allOf: then: properties: ports: + $ref: /schemas/graph.yaml#/properties/ports properties: - '#address-cells': - const: 1 - '#size-cells': - const: 0 port@3: - type: object + $ref: /schemas/graph.yaml#/properties/port description: Output port patternProperties: "^port@[0-2]$": - type: object + $ref: /schemas/graph.yaml#/properties/port description: Input port required: - port@3 - additionalProperties: false - required: - ports @@ -110,25 +97,20 @@ allOf: then: properties: ports: + $ref: /schemas/graph.yaml#/properties/ports properties: - '#address-cells': - const: 1 - '#size-cells': - const: 0 port@6: - type: object + $ref: /schemas/graph.yaml#/properties/port description: Output port patternProperties: "^port@[0-5]$": - type: object + $ref: /schemas/graph.yaml#/properties/port description: Input port required: - port@6 - additionalProperties: false - required: - ports diff --git a/Documentation/devicetree/bindings/media/i2c/adv7604.yaml b/Documentation/devicetree/bindings/media/i2c/adv7604.yaml index 407baddfaa1d..df634b0c1f8c 100644 --- a/Documentation/devicetree/bindings/media/i2c/adv7604.yaml +++ b/Documentation/devicetree/bindings/media/i2c/adv7604.yaml @@ -64,16 +64,12 @@ properties: description: Select which input is selected after reset. - ports: - type: object - description: - A node containing input and output port nodes with endpoint definitions - as documented in - Documentation/devicetree/bindings/media/video-interfaces.txt + ports: true required: - compatible - reg + - ports additionalProperties: false @@ -86,26 +82,19 @@ allOf: then: properties: ports: + $ref: /schemas/graph.yaml#/properties/ports properties: - '#address-cells': - const: 1 - '#size-cells': - const: 0 port@0: - type: object + $ref: /schemas/graph.yaml#/properties/port description: Input port + port@1: - type: object + $ref: /schemas/graph.yaml#/properties/port description: Output port required: - port@1 - additionalProperties: false - - required: - - ports - - if: properties: compatible: @@ -114,28 +103,20 @@ allOf: then: properties: ports: + $ref: /schemas/graph.yaml#/properties/ports properties: - '#address-cells': - const: 1 - '#size-cells': - const: 0 port@2: - type: object + $ref: /schemas/graph.yaml#/properties/port description: Output port patternProperties: "^port@[0-1]$": - type: object + $ref: /schemas/graph.yaml#/properties/port description: Input port required: - port@2 - additionalProperties: false - - required: - - ports - examples: - | #include diff --git a/Documentation/devicetree/bindings/media/i2c/aptina,mt9v111.yaml b/Documentation/devicetree/bindings/media/i2c/aptina,mt9v111.yaml index ff9546e95d05..e53b8d65f381 100644 --- a/Documentation/devicetree/bindings/media/i2c/aptina,mt9v111.yaml +++ b/Documentation/devicetree/bindings/media/i2c/aptina,mt9v111.yaml @@ -41,9 +41,9 @@ properties: maxItems: 1 port: - type: object + $ref: /schemas/graph.yaml#/properties/port description: | - Output video port. See ../video-interfaces.txt. + Output video port. required: - compatible diff --git a/Documentation/devicetree/bindings/media/i2c/imi,rdacm2x-gmsl.yaml b/Documentation/devicetree/bindings/media/i2c/imi,rdacm2x-gmsl.yaml index 3dc06c628e64..e57575c44930 100644 --- a/Documentation/devicetree/bindings/media/i2c/imi,rdacm2x-gmsl.yaml +++ b/Documentation/devicetree/bindings/media/i2c/imi,rdacm2x-gmsl.yaml @@ -86,33 +86,9 @@ properties: maxItems: 3 port: - type: object - additionalProperties: false - description: -| - Connection to the remote GMSL endpoint are modelled using the OF graph - bindings in accordance with the video interface bindings defined in - Documentation/devicetree/bindings/media/video-interfaces.txt. - - The device node contains a single "port" child node with a single - "endpoint" sub-device. - - properties: - endpoint: - type: object - additionalProperties: false - - properties: - remote-endpoint: - description: -| - phandle to the remote GMSL endpoint sub-node in the remote node - port. - maxItems: 1 - - required: - - remote-endpoint - - required: - - endpoint + $ref: /schemas/graph.yaml#/properties/port + description: + Connection to the remote GMSL endpoint. required: - compatible diff --git a/Documentation/devicetree/bindings/media/i2c/imx219.yaml b/Documentation/devicetree/bindings/media/i2c/imx219.yaml index dfc4d29a4f04..012c0565d8ae 100644 --- a/Documentation/devicetree/bindings/media/i2c/imx219.yaml +++ b/Documentation/devicetree/bindings/media/i2c/imx219.yaml @@ -44,12 +44,15 @@ properties: Reference to the GPIO connected to the xclr pin, if any. Must be released (set high) after all supplies are applied. - # See ../video-interfaces.txt for more details port: - type: object + $ref: /schemas/graph.yaml#/$defs/port-base + additionalProperties: false + properties: endpoint: - type: object + $ref: /schemas/media/video-interfaces.yaml# + unevaluatedProperties: false + properties: data-lanes: description: |- @@ -60,16 +63,8 @@ properties: - const: 1 - const: 2 - clock-noncontinuous: - type: boolean - description: |- - MIPI CSI-2 clock is non-continuous if this property is present, - otherwise it's continuous. - - link-frequencies: - $ref: /schemas/types.yaml#/definitions/uint64-array - description: - Allowed data bus frequencies. + clock-noncontinuous: true + link-frequencies: true required: - link-frequencies diff --git a/Documentation/devicetree/bindings/media/i2c/maxim,max9286.yaml b/Documentation/devicetree/bindings/media/i2c/maxim,max9286.yaml index 68ee8c7d9e79..bf4fa56ffcc7 100644 --- a/Documentation/devicetree/bindings/media/i2c/maxim,max9286.yaml +++ b/Documentation/devicetree/bindings/media/i2c/maxim,max9286.yaml @@ -51,81 +51,41 @@ properties: const: 2 ports: - type: object - description: | - The connections to the MAX9286 GMSL and its endpoint nodes are modelled - using the OF graph bindings in accordance with the video interface - bindings defined in - Documentation/devicetree/bindings/media/video-interfaces.txt. - - The following table lists the port number corresponding to each device - port. - - Port Description - ---------------------------------------- - Port 0 GMSL Input 0 - Port 1 GMSL Input 1 - Port 2 GMSL Input 2 - Port 3 GMSL Input 3 - Port 4 CSI-2 Output + $ref: /schemas/graph.yaml#/properties/ports properties: - '#address-cells': - const: 1 - - '#size-cells': - const: 0 - - port@[0-3]: - type: object - properties: - reg: - enum: [ 0, 1, 2, 3 ] - - endpoint: - type: object - - properties: - remote-endpoint: - description: | - phandle to the remote GMSL source endpoint subnode in the - remote node port. + port@0: + $ref: /schemas/graph.yaml#/properties/port + description: GMSL Input 0 - required: - - remote-endpoint + port@1: + $ref: /schemas/graph.yaml#/properties/port + description: GMSL Input 1 - required: - - reg - - endpoint + port@2: + $ref: /schemas/graph.yaml#/properties/port + description: GMSL Input 2 - additionalProperties: false + port@3: + $ref: /schemas/graph.yaml#/properties/port + description: GMSL Input 3 port@4: - type: object - properties: - reg: - const: 4 + $ref: /schemas/graph.yaml#/$defs/port-base + unevaluatedProperties: false + description: CSI-2 Output + properties: endpoint: - type: object + $ref: /schemas/media/video-interfaces.yaml# + unevaluatedProperties: false properties: - remote-endpoint: - description: phandle to the remote CSI-2 sink endpoint. - - data-lanes: - description: array of physical CSI-2 data lane indexes. + data-lanes: true required: - - remote-endpoint - data-lanes - required: - - reg - - endpoint - - additionalProperties: false - required: - port@4 @@ -183,25 +143,8 @@ properties: requirements of the currently connected remote device. port: - type: object - - properties: - endpoint: - type: object - - properties: - remote-endpoint: - description: phandle to the MAX9286 sink endpoint. - - required: - - remote-endpoint - - additionalProperties: false - - required: - - endpoint - - additionalProperties: false + $ref: /schemas/graph.yaml#/properties/port + description: Connection to the MAX9286 sink. required: - compatible diff --git a/Documentation/devicetree/bindings/media/i2c/mipi-ccs.yaml b/Documentation/devicetree/bindings/media/i2c/mipi-ccs.yaml index bb3528315f20..701f4e0d138f 100644 --- a/Documentation/devicetree/bindings/media/i2c/mipi-ccs.yaml +++ b/Documentation/devicetree/bindings/media/i2c/mipi-ccs.yaml @@ -71,19 +71,18 @@ properties: enum: [ 0, 180 ] port: - type: object + $ref: /schemas/graph.yaml#/$defs/port-base + additionalProperties: false + properties: endpoint: - type: object + $ref: /schemas/media/video-interfaces.yaml# + unevaluatedProperties: false + properties: - link-frequencies: - $ref: /schemas/types.yaml#/definitions/uint64-array - description: List of allowed data link frequencies. - data-lanes: - minItems: 1 - maxItems: 8 + link-frequencies: true + data-lanes: true bus-type: - description: The type of the data bus. oneOf: - const: 1 # CSI-2 C-PHY - const: 3 # CCP2 diff --git a/Documentation/devicetree/bindings/media/i2c/ov5647.yaml b/Documentation/devicetree/bindings/media/i2c/ov5647.yaml new file mode 100644 index 000000000000..3b1ea9da437a --- /dev/null +++ b/Documentation/devicetree/bindings/media/i2c/ov5647.yaml @@ -0,0 +1,76 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/media/i2c/ov5647.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Omnivision OV5647 raw image sensor + +maintainers: + - Dave Stevenson + - Jacopo Mondi + +description: |- + The OV5647 is a raw image sensor with MIPI CSI-2 and CCP2 image data + interfaces and CCI (I2C compatible) control bus. + +properties: + compatible: + const: ovti,ov5647 + + reg: + description: I2C device address. + maxItems: 1 + + clocks: + description: Reference to the xclk clock. + maxItems: 1 + + pwdn-gpios: + description: Reference to the GPIO connected to the pwdn pin. Active high. + maxItems: 1 + + port: + $ref: /schemas/graph.yaml#/$defs/port-base + + properties: + endpoint: + $ref: /schemas/media/video-interfaces.yaml# + unevaluatedProperties: false + + properties: + clock-noncontinuous: true + + additionalProperties: false + +required: + - compatible + - reg + - clocks + - port + +additionalProperties: false + +examples: + - | + #include + + i2c { + #address-cells = <1>; + #size-cells = <0>; + + ov5647: camera@36 { + compatible = "ovti,ov5647"; + reg = <0x36>; + clocks = <&camera_clk>; + pwdn-gpios = <&pioE 29 GPIO_ACTIVE_HIGH>; + + port { + camera_out: endpoint { + remote-endpoint = <&csi1_ep1>; + }; + }; + }; + }; + +... diff --git a/Documentation/devicetree/bindings/media/i2c/ov8856.yaml b/Documentation/devicetree/bindings/media/i2c/ov8856.yaml index cde85553fd01..baf92aaaf049 100644 --- a/Documentation/devicetree/bindings/media/i2c/ov8856.yaml +++ b/Documentation/devicetree/bindings/media/i2c/ov8856.yaml @@ -57,16 +57,13 @@ properties: active low. port: - type: object + $ref: /schemas/graph.yaml#/$defs/port-base additionalProperties: false - description: - A node containing an output port node with an endpoint definition - as documented in - Documentation/devicetree/bindings/media/video-interfaces.txt properties: endpoint: - type: object + $ref: /schemas/media/video-interfaces.yaml# + unevaluatedProperties: false properties: data-lanes: @@ -79,18 +76,14 @@ properties: - const: 4 link-frequencies: - $ref: /schemas/types.yaml#/definitions/uint64-array - description: - Allowed data bus frequencies. 360000000, 180000000 Hz or both - are supported by the driver. - + description: Frequencies listed are driver, not h/w limitations. + maxItems: 2 + items: + enum: [ 360000000, 180000000 ] required: - link-frequencies - required: - - endpoint - required: - compatible - reg @@ -139,4 +132,3 @@ examples: }; }; ... - diff --git a/Documentation/devicetree/bindings/media/i2c/ovti,ov02a10.yaml b/Documentation/devicetree/bindings/media/i2c/ovti,ov02a10.yaml index 1c3879ec4122..63a040944f3d 100644 --- a/Documentation/devicetree/bindings/media/i2c/ovti,ov02a10.yaml +++ b/Documentation/devicetree/bindings/media/i2c/ovti,ov02a10.yaml @@ -17,6 +17,9 @@ description: |- @ 1600x1200 (UXGA) resolution transferred over a 1-lane MIPI interface. The sensor output is available via CSI-2 serial data output. +allOf: + - $ref: /schemas/media/video-interface-devices.yaml# + properties: compatible: const: ovti,ov02a10 @@ -66,42 +69,34 @@ properties: maxItems: 1 rotation: - description: - Definition of the sensor's placement. - allOf: - - $ref: "/schemas/types.yaml#/definitions/uint32" - - enum: - - 0 # Sensor Mounted Upright - - 180 # Sensor Mounted Upside Down - default: 0 - - # See ../video-interfaces.txt for details + enum: + - 0 # Sensor Mounted Upright + - 180 # Sensor Mounted Upside Down + default: 0 + port: - type: object + $ref: /schemas/graph.yaml#/$defs/port-base additionalProperties: false description: Output port node, single endpoint describing the CSI-2 transmitter. properties: endpoint: - type: object - additionalProperties: false + $ref: /schemas/media/video-interfaces.yaml# + unevaluatedProperties: false properties: link-frequencies: true ovti,mipi-clock-voltage: - allOf: - - $ref: "/schemas/types.yaml#/definitions/uint32" + $ref: "/schemas/types.yaml#/definitions/uint32" description: Definition of MIPI clock voltage unit. This entry corresponds to the link speed defined by the 'link-frequencies' property. If present, the value shall be in the range of 0-4. default: 4 - remote-endpoint: true required: - link-frequencies - - remote-endpoint required: - endpoint diff --git a/Documentation/devicetree/bindings/media/i2c/ovti,ov2680.yaml b/Documentation/devicetree/bindings/media/i2c/ovti,ov2680.yaml index 43bf749807e1..cf456f8d9ddc 100644 --- a/Documentation/devicetree/bindings/media/i2c/ovti,ov2680.yaml +++ b/Documentation/devicetree/bindings/media/i2c/ovti,ov2680.yaml @@ -50,11 +50,9 @@ properties: Definition of the regulator used as digital power supply. port: - type: object + $ref: /schemas/graph.yaml#/properties/port description: - A node containing an output port node with an endpoint definition - as documented in - Documentation/devicetree/bindings/media/video-interfaces.txt + A node containing an output port node. required: - compatible diff --git a/Documentation/devicetree/bindings/media/i2c/ovti,ov772x.yaml b/Documentation/devicetree/bindings/media/i2c/ovti,ov772x.yaml index 6866c2cdac50..44529425ce3a 100644 --- a/Documentation/devicetree/bindings/media/i2c/ovti,ov772x.yaml +++ b/Documentation/devicetree/bindings/media/i2c/ovti,ov772x.yaml @@ -37,13 +37,14 @@ properties: maxItems: 1 port: - type: object + $ref: /schemas/graph.yaml#/$defs/port-base description: | - Video output port. See ../video-interfaces.txt. + Video output port. properties: endpoint: - type: object + $ref: /schemas/media/video-interfaces.yaml# + unevaluatedProperties: false properties: bus-type: @@ -91,8 +92,6 @@ properties: required: - bus-type - unevaluatedProperties: false - additionalProperties: false required: diff --git a/Documentation/devicetree/bindings/media/i2c/sony,imx214.yaml b/Documentation/devicetree/bindings/media/i2c/sony,imx214.yaml index eb12526a462f..c9760f895b3e 100644 --- a/Documentation/devicetree/bindings/media/i2c/sony,imx214.yaml +++ b/Documentation/devicetree/bindings/media/i2c/sony,imx214.yaml @@ -15,6 +15,9 @@ description: | interface. Image data is sent through MIPI CSI-2, through 2 or 4 lanes at a maximum throughput of 1.2Gbps/lane. +allOf: + - $ref: ../video-interface-devices.yaml# + properties: compatible: const: sony,imx214 @@ -44,25 +47,21 @@ properties: vddd-supply: description: Chip digital core regulator (1.12V). - flash-leds: - description: See ../video-interfaces.txt - - lens-focus: - description: See ../video-interfaces.txt + flash-leds: true + lens-focus: true port: - type: object + $ref: /schemas/graph.yaml#/$defs/port-base description: | - Video output port. See ../video-interfaces.txt. + Video output port. properties: endpoint: - type: object + $ref: /schemas/media/video-interfaces.yaml# + unevaluatedProperties: false properties: data-lanes: - $ref: /schemas/types.yaml#/definitions/uint32-array - description: See ../video-interfaces.txt anyOf: - items: - const: 1 @@ -73,16 +72,12 @@ properties: - const: 3 - const: 4 - link-frequencies: - $ref: /schemas/types.yaml#/definitions/uint64-array - description: See ../video-interfaces.txt + link-frequencies: true required: - data-lanes - link-frequencies - unevaluatedProperties: false - additionalProperties: false required: diff --git a/Documentation/devicetree/bindings/media/i2c/sony,imx274.yaml b/Documentation/devicetree/bindings/media/i2c/sony,imx274.yaml index a66acb20d59b..4271fc3cc623 100644 --- a/Documentation/devicetree/bindings/media/i2c/sony,imx274.yaml +++ b/Documentation/devicetree/bindings/media/i2c/sony,imx274.yaml @@ -41,8 +41,7 @@ properties: description: Sensor digital IO 1.2 V supply. port: - type: object - description: Output video port. See ../video-interfaces.txt. + $ref: /schemas/graph.yaml#/properties/port required: - compatible diff --git a/Documentation/devicetree/bindings/media/marvell,mmp2-ccic.yaml b/Documentation/devicetree/bindings/media/marvell,mmp2-ccic.yaml index 49bff738aca5..9e85c70d1a1f 100644 --- a/Documentation/devicetree/bindings/media/marvell,mmp2-ccic.yaml +++ b/Documentation/devicetree/bindings/media/marvell,mmp2-ccic.yaml @@ -24,29 +24,20 @@ properties: maxItems: 1 port: - type: object + $ref: /schemas/graph.yaml#/$defs/port-base additionalProperties: false properties: endpoint: - type: object - additionalProperties: false + $ref: video-interfaces.yaml# + unevaluatedProperties: false - # Properties described in - # Documentation/devicetree/bindings/media/video-interfaces.txt properties: - remote-endpoint: true hsync-active: true vsync-active: true pclk-sample: true bus-type: true - required: - - remote-endpoint - - required: - - endpoint - clocks: minItems: 1 maxItems: 3 diff --git a/Documentation/devicetree/bindings/media/nxp,imx7-csi.yaml b/Documentation/devicetree/bindings/media/nxp,imx7-csi.yaml index 4e81a47e60ac..d91575b8ebb9 100644 --- a/Documentation/devicetree/bindings/media/nxp,imx7-csi.yaml +++ b/Documentation/devicetree/bindings/media/nxp,imx7-csi.yaml @@ -33,10 +33,7 @@ properties: - const: mclk port: - type: object - description: - A node containing input port nodes with endpoint definitions as documented - in Documentation/devicetree/bindings/media/video-interfaces.txt + $ref: /schemas/graph.yaml#/properties/port required: - compatible diff --git a/Documentation/devicetree/bindings/media/nxp,imx7-mipi-csi2.yaml b/Documentation/devicetree/bindings/media/nxp,imx7-mipi-csi2.yaml index 0668332959e7..be47a7b62ca9 100644 --- a/Documentation/devicetree/bindings/media/nxp,imx7-mipi-csi2.yaml +++ b/Documentation/devicetree/bindings/media/nxp,imx7-mipi-csi2.yaml @@ -58,35 +58,22 @@ properties: Differential receiver (HS-RX) settle time ports: - type: object - description: - A node containing input and output port nodes with endpoint definitions - as documented in - Documentation/devicetree/bindings/media/video-interfaces.txt + $ref: /schemas/graph.yaml#/properties/ports properties: - '#address-cells': - const: 1 - - '#size-cells': - const: 0 - port@0: - type: object + $ref: /schemas/graph.yaml#/$defs/port-base + unevaluatedProperties: false description: Input port node, single endpoint describing the CSI-2 transmitter. properties: - reg: - const: 0 - endpoint: - type: object + $ref: video-interfaces.yaml# + unevaluatedProperties: false properties: data-lanes: - $ref: /schemas/types.yaml#/definitions/uint32-array - description: See ../video-interfaces.txt oneOf: - items: - const: 1 @@ -94,18 +81,11 @@ properties: - const: 1 - const: 2 - remote-endpoint: true - required: - data-lanes - - remote-endpoint - - additionalProperties: false - - additionalProperties: false port@1: - type: object + $ref: /schemas/graph.yaml#/properties/port description: Output port node diff --git a/Documentation/devicetree/bindings/media/renesas,ceu.yaml b/Documentation/devicetree/bindings/media/renesas,ceu.yaml index c7e1e4fe67e6..50e0740af15a 100644 --- a/Documentation/devicetree/bindings/media/renesas,ceu.yaml +++ b/Documentation/devicetree/bindings/media/renesas,ceu.yaml @@ -34,18 +34,15 @@ properties: maxItems: 1 port: - type: object - additionalProperties: false + $ref: /schemas/graph.yaml#/$defs/port-base + unevaluatedProperties: false properties: endpoint: - type: object - additionalProperties: false + $ref: video-interfaces.yaml# + unevaluatedProperties: false - # Properties described in - # Documentation/devicetree/bindings/media/video-interfaces.txt properties: - remote-endpoint: true hsync-active: true vsync-active: true field-even-active: false @@ -53,12 +50,6 @@ properties: enum: [8, 16] default: 8 - required: - - remote-endpoint - - required: - - endpoint - required: - compatible - reg diff --git a/Documentation/devicetree/bindings/media/renesas,csi2.yaml b/Documentation/devicetree/bindings/media/renesas,csi2.yaml index 533c2f181db7..20396f1be999 100644 --- a/Documentation/devicetree/bindings/media/renesas,csi2.yaml +++ b/Documentation/devicetree/bindings/media/renesas,csi2.yaml @@ -46,24 +46,19 @@ properties: maxItems: 1 ports: - type: object - description: - A node containing input and output port nodes with endpoint definitions - as documented in - Documentation/devicetree/bindings/media/video-interfaces.txt + $ref: /schemas/graph.yaml#/properties/ports properties: port@0: - type: object + $ref: /schemas/graph.yaml#/$defs/port-base + unevaluatedProperties: false description: Input port node, single endpoint describing the CSI-2 transmitter. properties: - reg: - const: 0 - endpoint: - type: object + $ref: video-interfaces.yaml# + unevaluatedProperties: false properties: clock-lanes: @@ -72,50 +67,19 @@ properties: data-lanes: maxItems: 1 - remote-endpoint: true - required: - clock-lanes - data-lanes - - remote-endpoint - - additionalProperties: false - - additionalProperties: false port@1: - type: object + $ref: /schemas/graph.yaml#/properties/port description: Output port node, multiple endpoints describing all the R-Car VIN modules connected the CSI-2 receiver. - properties: - '#address-cells': - const: 1 - - '#size-cells': - const: 0 - - reg: - const: 1 - - patternProperties: - "^endpoint@[0-9a-f]$": - type: object - - properties: - reg: - maxItems: 1 - - remote-endpoint: true - - required: - - reg - - remote-endpoint - - additionalProperties: false - - additionalProperties: false + required: + - port@0 + - port@1 required: - compatible diff --git a/Documentation/devicetree/bindings/media/renesas,vin.yaml b/Documentation/devicetree/bindings/media/renesas,vin.yaml index ad2fe660364b..fe7c4cbfe4ba 100644 --- a/Documentation/devicetree/bindings/media/renesas,vin.yaml +++ b/Documentation/devicetree/bindings/media/renesas,vin.yaml @@ -69,15 +69,15 @@ properties: #The per-board settings for Gen2 and RZ/G1 platforms: port: - type: object + $ref: /schemas/graph.yaml#/$defs/port-base + unevaluatedProperties: false description: - A node containing a parallel input with a single endpoint definitions as - documented in - Documentation/devicetree/bindings/media/video-interfaces.txt + A node containing a parallel input properties: endpoint: - type: object + $ref: video-interfaces.yaml# + unevaluatedProperties: false properties: hsync-active: @@ -106,15 +106,6 @@ properties: data-active: true - remote-endpoint: true - - required: - - remote-endpoint - - additionalProperties: false - - additionalProperties: false - #The per-board settings for Gen3 and RZ/G2 platforms: renesas,id: description: VIN channel number @@ -123,23 +114,18 @@ properties: maximum: 15 ports: - type: object - description: - A node containing input nodes with endpoint definitions as documented in - Documentation/devicetree/bindings/media/video-interfaces.txt + $ref: /schemas/graph.yaml#/properties/ports properties: port@0: - type: object + $ref: /schemas/graph.yaml#/properties/port description: Input port node, single endpoint describing a parallel input source. properties: - reg: - const: 0 - endpoint: - type: object + $ref: video-interfaces.yaml# + unevaluatedProperties: false properties: hsync-active: @@ -168,98 +154,29 @@ properties: data-active: true - remote-endpoint: true - - required: - - remote-endpoint - - additionalProperties: false - - required: - - endpoint - - additionalProperties: false - port@1: - type: object + $ref: /schemas/graph.yaml#/properties/port description: Input port node, multiple endpoints describing all the R-Car CSI-2 modules connected the VIN. properties: - '#address-cells': - const: 1 - - '#size-cells': - const: 0 - - reg: - const: 1 - endpoint@0: - type: object + $ref: /schemas/graph.yaml#/properties/endpoint description: Endpoint connected to CSI20. - properties: - reg: - const: 0 - - remote-endpoint: true - - required: - - reg - - remote-endpoint - - additionalProperties: false - endpoint@1: - type: object + $ref: /schemas/graph.yaml#/properties/endpoint description: Endpoint connected to CSI21. - properties: - reg: - const: 1 - - remote-endpoint: true - - required: - - reg - - remote-endpoint - - additionalProperties: false - endpoint@2: - type: object + $ref: /schemas/graph.yaml#/properties/endpoint description: Endpoint connected to CSI40. - properties: - reg: - const: 2 - - remote-endpoint: true - - required: - - reg - - remote-endpoint - - additionalProperties: false - endpoint@3: - type: object + $ref: /schemas/graph.yaml#/properties/endpoint description: Endpoint connected to CSI41. - properties: - reg: - const: 3 - - remote-endpoint: true - - required: - - reg - - remote-endpoint - - additionalProperties: false - anyOf: - required: - endpoint@0 @@ -270,8 +187,6 @@ properties: - required: - endpoint@3 - additionalProperties: false - required: - compatible - reg diff --git a/Documentation/devicetree/bindings/media/rockchip-isp1.yaml b/Documentation/devicetree/bindings/media/rockchip-isp1.yaml index 2004c054ed1a..a6b1eff879ed 100644 --- a/Documentation/devicetree/bindings/media/rockchip-isp1.yaml +++ b/Documentation/devicetree/bindings/media/rockchip-isp1.yaml @@ -56,56 +56,26 @@ properties: power-domains: maxItems: 1 - # See ./video-interfaces.txt for details ports: - type: object - additionalProperties: false + $ref: /schemas/graph.yaml#/properties/ports properties: - "#address-cells": - const: 1 - - "#size-cells": - const: 0 - port@0: - type: object + $ref: /schemas/graph.yaml#/$defs/port-base + unevaluatedProperties: false description: connection point for sensors at MIPI-DPHY RX0 - additionalProperties: false properties: - "#address-cells": - const: 1 - - "#size-cells": - const: 0 - - reg: - const: 0 - - patternProperties: endpoint: - type: object - additionalProperties: false + $ref: video-interfaces.yaml# + unevaluatedProperties: false properties: - reg: - maxItems: 1 - data-lanes: minItems: 1 maxItems: 4 - remote-endpoint: true - - required: - - reg - - "#address-cells" - - "#size-cells" - required: - - "#address-cells" - - "#size-cells" - port@0 required: diff --git a/Documentation/devicetree/bindings/media/st,stm32-dcmi.yaml b/Documentation/devicetree/bindings/media/st,stm32-dcmi.yaml index c18574bb3e81..41e1d0cd80e5 100644 --- a/Documentation/devicetree/bindings/media/st,stm32-dcmi.yaml +++ b/Documentation/devicetree/bindings/media/st,stm32-dcmi.yaml @@ -37,16 +37,15 @@ properties: maxItems: 1 port: - type: object + $ref: /schemas/graph.yaml#/$defs/port-base + unevaluatedProperties: false description: - DCMI supports a single port node with parallel bus. It should contain - one 'port' child node with child 'endpoint' node. Please refer to the - bindings defined in - Documentation/devicetree/bindings/media/video-interfaces.txt. + DCMI supports a single port node with parallel bus. properties: endpoint: - type: object + $ref: video-interfaces.yaml# + unevaluatedProperties: false properties: bus-type: @@ -57,8 +56,6 @@ properties: enum: [8, 10, 12, 14] default: 8 - remote-endpoint: true - allOf: - if: properties: @@ -73,14 +70,9 @@ properties: enum: [8] required: - - remote-endpoint - bus-type - pclk-sample - unevaluatedProperties: false - - additionalProperties: false - required: - compatible - reg diff --git a/Documentation/devicetree/bindings/media/ti,cal.yaml b/Documentation/devicetree/bindings/media/ti,cal.yaml index 5e066629287d..65177cd69514 100644 --- a/Documentation/devicetree/bindings/media/ti,cal.yaml +++ b/Documentation/devicetree/bindings/media/ti,cal.yaml @@ -15,10 +15,7 @@ description: |- processing capability to connect CSI2 image-sensor modules to the DRA72x device. - CAL supports 2 camera port nodes on MIPI bus. Each CSI2 camera port nodes - should contain a 'port' child node with child 'endpoint' node. Please - refer to the bindings defined in - Documentation/devicetree/bindings/media/video-interfaces.txt. + CAL supports 2 camera port nodes on MIPI bus. properties: compatible: @@ -67,31 +64,19 @@ properties: Documentation/devicetree/bindings/power/power_domain.txt maxItems: 1 - # See ./video-interfaces.txt for details ports: - type: object - additionalProperties: false + $ref: /schemas/graph.yaml#/properties/ports properties: - "#address-cells": - const: 1 - - "#size-cells": - const: 0 - port@0: - type: object - additionalProperties: false + $ref: /schemas/graph.yaml#/$defs/port-base + unevaluatedProperties: false + description: CSI2 Port #0 properties: - reg: - const: 0 - description: CSI2 Port #0 - - patternProperties: endpoint: - type: object - additionalProperties: false + $ref: video-interfaces.yaml# + unevaluatedProperties: false properties: clock-lanes: @@ -101,24 +86,15 @@ properties: minItems: 1 maxItems: 4 - remote-endpoint: true - - required: - - reg - port@1: - type: object - additionalProperties: false + $ref: /schemas/graph.yaml#/$defs/port-base + unevaluatedProperties: false + description: CSI2 Port #1 properties: - reg: - const: 1 - description: CSI2 Port #1 - - patternProperties: endpoint: - type: object - additionalProperties: false + $ref: video-interfaces.yaml# + unevaluatedProperties: false properties: clock-lanes: @@ -128,14 +104,7 @@ properties: minItems: 1 maxItems: 4 - remote-endpoint: true - - required: - - reg - required: - - "#address-cells" - - "#size-cells" - port@0 required: diff --git a/Documentation/devicetree/bindings/media/xilinx/xlnx,csi2rxss.yaml b/Documentation/devicetree/bindings/media/xilinx/xlnx,csi2rxss.yaml index 2961a5b6872f..7d77823dbb7a 100644 --- a/Documentation/devicetree/bindings/media/xilinx/xlnx,csi2rxss.yaml +++ b/Documentation/devicetree/bindings/media/xilinx/xlnx,csi2rxss.yaml @@ -97,24 +97,21 @@ properties: maxItems: 1 ports: - type: object + $ref: /schemas/graph.yaml#/properties/ports properties: port@0: - type: object + $ref: /schemas/graph.yaml#/$defs/port-base description: | Input / sink port node, single endpoint describing the CSI-2 transmitter. properties: - reg: - const: 0 - endpoint: - type: object + $ref: /schemas/media/video-interfaces.yaml# + unevaluatedProperties: false properties: - data-lanes: description: | This is required only in the sink port 0 endpoint which @@ -130,41 +127,17 @@ properties: - const: 3 - const: 4 - remote-endpoint: true - required: - data-lanes - - remote-endpoint - - additionalProperties: false - additionalProperties: false + unevaluatedProperties: false port@1: - type: object + $ref: /schemas/graph.yaml#/properties/port description: | Output / source port node, endpoint describing modules connected the CSI-2 receiver. - properties: - - reg: - const: 1 - - endpoint: - type: object - - properties: - - remote-endpoint: true - - required: - - remote-endpoint - - additionalProperties: false - - additionalProperties: false - required: - compatible - reg -- cgit v1.2.3 From 628add78b07ad05ad005f1909dfc3c91e195ac23 Mon Sep 17 00:00:00 2001 From: Tiezhu Yang Date: Fri, 22 Jan 2021 09:39:44 +0800 Subject: bpf, docs: Update build procedure for manually compiling LLVM and Clang The current LLVM and Clang build procedure in samples/bpf/README.rst is out of date. See below that the links are not accessible any more. $ git clone http://llvm.org/git/llvm.git Cloning into 'llvm'... fatal: unable to access 'http://llvm.org/git/llvm.git/': Maximum (20) redirects followed $ git clone --depth 1 http://llvm.org/git/clang.git Cloning into 'clang'... fatal: unable to access 'http://llvm.org/git/clang.git/': Maximum (20) redirects followed The LLVM community has adopted new ways to build the compiler. There are different ways to build LLVM and Clang, the Clang Getting Started page [1] has one way. As Yonghong said, it is better to copy the build procedure in Documentation/bpf/bpf_devel_QA.rst to keep consistent. I verified the procedure and it is proved to be feasible, so we should update README.rst to reflect the reality. At the same time, update the related comment in Makefile. Additionally, as Fangrui said, the dir llvm-project/llvm/build/install is not used, BUILD_SHARED_LIBS=OFF is the default option [2], so also change Documentation/bpf/bpf_devel_QA.rst together. At last, we recommend that developers who want the fastest incremental builds use the Ninja build system [1], you can find it in your system's package manager, usually the package is ninja or ninja-build [3], so add ninja to build dependencies suggested by Nathan. [1] https://clang.llvm.org/get_started.html [2] https://www.llvm.org/docs/CMake.html [3] https://github.com/ninja-build/ninja/wiki/Pre-built-Ninja-packages Signed-off-by: Tiezhu Yang Signed-off-by: Daniel Borkmann Reviewed-by: Nathan Chancellor Acked-by: Yonghong Song Cc: Fangrui Song Link: https://lore.kernel.org/bpf/1611279584-26047-1-git-send-email-yangtiezhu@loongson.cn --- Documentation/bpf/bpf_devel_QA.rst | 11 +++++++---- samples/bpf/Makefile | 2 +- samples/bpf/README.rst | 22 ++++++++++++++-------- 3 files changed, 22 insertions(+), 13 deletions(-) (limited to 'Documentation') diff --git a/Documentation/bpf/bpf_devel_QA.rst b/Documentation/bpf/bpf_devel_QA.rst index 5b613d2a5f1a..2ed89abbf9a4 100644 --- a/Documentation/bpf/bpf_devel_QA.rst +++ b/Documentation/bpf/bpf_devel_QA.rst @@ -501,16 +501,19 @@ All LLVM releases can be found at: http://releases.llvm.org/ Q: Got it, so how do I build LLVM manually anyway? -------------------------------------------------- -A: You need cmake and gcc-c++ as build requisites for LLVM. Once you have -that set up, proceed with building the latest LLVM and clang version +A: We recommend that developers who want the fastest incremental builds +use the Ninja build system, you can find it in your system's package +manager, usually the package is ninja or ninja-build. + +You need ninja, cmake and gcc-c++ as build requisites for LLVM. Once you +have that set up, proceed with building the latest LLVM and clang version from the git repositories:: $ git clone https://github.com/llvm/llvm-project.git - $ mkdir -p llvm-project/llvm/build/install + $ mkdir -p llvm-project/llvm/build $ cd llvm-project/llvm/build $ cmake .. -G "Ninja" -DLLVM_TARGETS_TO_BUILD="BPF;X86" \ -DLLVM_ENABLE_PROJECTS="clang" \ - -DBUILD_SHARED_LIBS=OFF \ -DCMAKE_BUILD_TYPE=Release \ -DLLVM_BUILD_RUNTIME=OFF $ ninja diff --git a/samples/bpf/Makefile b/samples/bpf/Makefile index 26fc96ca619e..d06144613ca2 100644 --- a/samples/bpf/Makefile +++ b/samples/bpf/Makefile @@ -208,7 +208,7 @@ TPROGLDLIBS_xdpsock += -pthread -lcap TPROGLDLIBS_xsk_fwd += -pthread # Allows pointing LLC/CLANG to a LLVM backend with bpf support, redefine on cmdline: -# make M=samples/bpf/ LLC=~/git/llvm/build/bin/llc CLANG=~/git/llvm/build/bin/clang +# make M=samples/bpf LLC=~/git/llvm-project/llvm/build/bin/llc CLANG=~/git/llvm-project/llvm/build/bin/clang LLC ?= llc CLANG ?= clang OPT ?= opt diff --git a/samples/bpf/README.rst b/samples/bpf/README.rst index dd34b2d26f1c..60c6494adb1b 100644 --- a/samples/bpf/README.rst +++ b/samples/bpf/README.rst @@ -62,20 +62,26 @@ To generate a smaller llc binary one can use:: -DLLVM_TARGETS_TO_BUILD="BPF" +We recommend that developers who want the fastest incremental builds +use the Ninja build system, you can find it in your system's package +manager, usually the package is ninja or ninja-build. + Quick sniplet for manually compiling LLVM and clang -(build dependencies are cmake and gcc-c++):: +(build dependencies are ninja, cmake and gcc-c++):: - $ git clone http://llvm.org/git/llvm.git - $ cd llvm/tools - $ git clone --depth 1 http://llvm.org/git/clang.git - $ cd ..; mkdir build; cd build - $ cmake .. -DLLVM_TARGETS_TO_BUILD="BPF;X86" - $ make -j $(getconf _NPROCESSORS_ONLN) + $ git clone https://github.com/llvm/llvm-project.git + $ mkdir -p llvm-project/llvm/build + $ cd llvm-project/llvm/build + $ cmake .. -G "Ninja" -DLLVM_TARGETS_TO_BUILD="BPF;X86" \ + -DLLVM_ENABLE_PROJECTS="clang" \ + -DCMAKE_BUILD_TYPE=Release \ + -DLLVM_BUILD_RUNTIME=OFF + $ ninja It is also possible to point make to the newly compiled 'llc' or 'clang' command via redefining LLC or CLANG on the make command line:: - make M=samples/bpf LLC=~/git/llvm/build/bin/llc CLANG=~/git/llvm/build/bin/clang + make M=samples/bpf LLC=~/git/llvm-project/llvm/build/bin/llc CLANG=~/git/llvm-project/llvm/build/bin/clang Cross compiling samples ----------------------- -- cgit v1.2.3 From ca649ccae45d64b3b8e22a9fee9af7d796494e42 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Thu, 21 Jan 2021 11:06:15 +0100 Subject: dt-bindings: net: renesas,etheravb: Add r8a779a0 support Document the compatible value for the RAVB block in the Renesas R-Car V3U (R8A779A0) SoC. This variant has no stream buffer, so we only need to add the new compatible and add it to the TX delay block. Reviewed-by: Geert Uytterhoeven Acked-by: Rob Herring Signed-off-by: Wolfram Sang Link: https://lore.kernel.org/r/20210121100619.5653-2-wsa+renesas@sang-engineering.com Signed-off-by: Jakub Kicinski --- Documentation/devicetree/bindings/net/renesas,etheravb.yaml | 2 ++ 1 file changed, 2 insertions(+) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/net/renesas,etheravb.yaml b/Documentation/devicetree/bindings/net/renesas,etheravb.yaml index de9dd574a2f9..91ba96d43c6c 100644 --- a/Documentation/devicetree/bindings/net/renesas,etheravb.yaml +++ b/Documentation/devicetree/bindings/net/renesas,etheravb.yaml @@ -40,6 +40,7 @@ properties: - renesas,etheravb-r8a77980 # R-Car V3H - renesas,etheravb-r8a77990 # R-Car E3 - renesas,etheravb-r8a77995 # R-Car D3 + - renesas,etheravb-r8a779a0 # R-Car V3U - const: renesas,etheravb-rcar-gen3 # R-Car Gen3 and RZ/G2 reg: true @@ -170,6 +171,7 @@ allOf: - renesas,etheravb-r8a77965 - renesas,etheravb-r8a77970 - renesas,etheravb-r8a77980 + - renesas,etheravb-r8a779a0 then: required: - tx-internal-delay-ps -- cgit v1.2.3 From 0653c358d2dc7904c5553c5a9f2cbadc236e3f60 Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Wed, 13 Jan 2021 10:04:26 +0100 Subject: scsi: Drop gdth driver The gdth driver refers to a SCSI parallel, PCI-only HBA RAID adapter which was manufactured by the now-defunct ICP Vortex company, later acquired by Adaptec and superseded by the aacraid series of controllers. The driver itself would require a major overhaul before any modifications can be attempted, but seeing that it's unlikely to have any users left it should rather be removed completely. Link: https://lore.kernel.org/r/20210113090500.129644-2-hare@suse.de Cautiously-Acked-by: Christoph Hellwig Signed-off-by: Hannes Reinecke Signed-off-by: Martin K. Petersen --- Documentation/kbuild/makefiles.rst | 4 +- Documentation/process/magic-number.rst | 2 - Documentation/scsi/scsi-parameters.rst | 3 - Documentation/userspace-api/ioctl/ioctl-number.rst | 1 - drivers/scsi/Kconfig | 14 - drivers/scsi/Makefile | 2 - drivers/scsi/gdth.c | 4322 -------------------- drivers/scsi/gdth.h | 981 ----- drivers/scsi/gdth_ioctl.h | 251 -- drivers/scsi/gdth_proc.c | 586 --- drivers/scsi/gdth_proc.h | 18 - 11 files changed, 1 insertion(+), 6183 deletions(-) delete mode 100644 drivers/scsi/gdth.c delete mode 100644 drivers/scsi/gdth.h delete mode 100644 drivers/scsi/gdth_ioctl.h delete mode 100644 drivers/scsi/gdth_proc.c delete mode 100644 drivers/scsi/gdth_proc.h (limited to 'Documentation') diff --git a/Documentation/kbuild/makefiles.rst b/Documentation/kbuild/makefiles.rst index d36768cf1250..fa988b43d0a3 100644 --- a/Documentation/kbuild/makefiles.rst +++ b/Documentation/kbuild/makefiles.rst @@ -461,10 +461,8 @@ more details, with real examples. # drivers/scsi/Makefile CFLAGS_aha152x.o = -DAHA152X_STAT -DAUTOCONF - CFLAGS_gdth.o = # -DDEBUG_GDTH=2 -D__SERIAL__ -D__COM2__ \ - -DGDTH_STATISTICS - These two lines specify compilation flags for aha152x.o and gdth.o. + This line specify compilation flags for aha152x.o. $(AFLAGS_$@) is a similar feature for source files in assembly languages. diff --git a/Documentation/process/magic-number.rst b/Documentation/process/magic-number.rst index e02ff5ffb653..8d078239e2ae 100644 --- a/Documentation/process/magic-number.rst +++ b/Documentation/process/magic-number.rst @@ -99,7 +99,6 @@ USB_SERIAL_PORT_MAGIC 0x7301 usb_serial_port ``drivers/usb/se CG_MAGIC 0x00090255 ufs_cylinder_group ``include/linux/ufs_fs.h`` RPORT_MAGIC 0x00525001 r_port ``drivers/char/rocket_int.h`` LSEMAGIC 0x05091998 lse ``drivers/fc4/fc.c`` -GDTIOCTL_MAGIC 0x06030f07 gdth_iowr_str ``drivers/scsi/gdth_ioctl.h`` RIEBL_MAGIC 0x09051990 ``drivers/net/atarilance.c`` NBD_REQUEST_MAGIC 0x12560953 nbd_request ``include/linux/nbd.h`` RED_MAGIC2 0x170fc2a5 (any) ``mm/slab.c`` @@ -143,7 +142,6 @@ PWC_MAGIC 0x89DC10AB pwc_device ``drivers/usb/me NBD_REPLY_MAGIC 0x96744668 nbd_reply ``include/linux/nbd.h`` ENI155_MAGIC 0xa54b872d midway_eprom ``drivers/atm/eni.h`` CODA_MAGIC 0xC0DAC0DA coda_file_info ``fs/coda/coda_fs_i.h`` -DPMEM_MAGIC 0xc0ffee11 gdt_pci_sram ``drivers/scsi/gdth.h`` YAM_MAGIC 0xF10A7654 yam_port ``drivers/net/hamradio/yam.c`` CCB_MAGIC 0xf2691ad2 ccb ``drivers/scsi/ncr53c8xx.c`` QUEUE_MAGIC_FREE 0xf7e1c9a3 queue_entry ``drivers/scsi/arm/queue.c`` diff --git a/Documentation/scsi/scsi-parameters.rst b/Documentation/scsi/scsi-parameters.rst index e5f68b431f5c..8f4127261662 100644 --- a/Documentation/scsi/scsi-parameters.rst +++ b/Documentation/scsi/scsi-parameters.rst @@ -38,9 +38,6 @@ parameters may be changed at runtime by the command See drivers/scsi/BusLogic.c, comment before function BusLogic_ParseDriverOptions(). - gdth= [HW,SCSI] - See header of drivers/scsi/gdth.c. - gvp11= [HW,SCSI] ips= [HW,SCSI] Adaptec / IBM ServeRAID controller diff --git a/Documentation/userspace-api/ioctl/ioctl-number.rst b/Documentation/userspace-api/ioctl/ioctl-number.rst index a4c75a28c839..6e7ca07c830e 100644 --- a/Documentation/userspace-api/ioctl/ioctl-number.rst +++ b/Documentation/userspace-api/ioctl/ioctl-number.rst @@ -157,7 +157,6 @@ Code Seq# Include File Comments 'I' all linux/isdn.h conflict! 'I' 00-0F drivers/isdn/divert/isdn_divert.h conflict! 'I' 40-4F linux/mISDNif.h conflict! -'J' 00-1F drivers/scsi/gdth_ioctl.h 'K' all linux/kd.h 'L' 00-1F linux/loop.h conflict! 'L' 10-1F drivers/scsi/mpt3sas/mpt3sas_ctl.h conflict! diff --git a/drivers/scsi/Kconfig b/drivers/scsi/Kconfig index 701b61ec76ee..322d582a22d2 100644 --- a/drivers/scsi/Kconfig +++ b/drivers/scsi/Kconfig @@ -669,20 +669,6 @@ config SCSI_FDOMAIN_ISA To compile this driver as a module, choose M here: the module will be called fdomain_isa. -config SCSI_GDTH - tristate "Intel/ICP (former GDT SCSI Disk Array) RAID Controller support" - depends on PCI && SCSI - help - Formerly called GDT SCSI Disk Array Controller Support. - - This is a driver for RAID/SCSI Disk Array Controllers (EISA/ISA/PCI) - manufactured by Intel Corporation/ICP vortex GmbH. It is documented - in the kernel source in and - . - - To compile this driver as a module, choose M here: the - module will be called gdth. - config SCSI_ISCI tristate "Intel(R) C600 Series Chipset SAS Controller" depends on PCI && SCSI diff --git a/drivers/scsi/Makefile b/drivers/scsi/Makefile index c00e3dd57990..bc3882f5cc69 100644 --- a/drivers/scsi/Makefile +++ b/drivers/scsi/Makefile @@ -16,7 +16,6 @@ CFLAGS_aha152x.o = -DAHA152X_STAT -DAUTOCONF -CFLAGS_gdth.o = # -DDEBUG_GDTH=2 -D__SERIAL__ -D__COM2__ -DGDTH_STATISTICS obj-$(CONFIG_PCMCIA) += pcmcia/ @@ -103,7 +102,6 @@ obj-$(CONFIG_SCSI_MPT3SAS) += mpt3sas/ obj-$(CONFIG_SCSI_UFSHCD) += ufs/ obj-$(CONFIG_SCSI_ACARD) += atp870u.o obj-$(CONFIG_SCSI_SUNESP) += esp_scsi.o sun_esp.o -obj-$(CONFIG_SCSI_GDTH) += gdth.o obj-$(CONFIG_SCSI_INITIO) += initio.o obj-$(CONFIG_SCSI_INIA100) += a100u2w.o obj-$(CONFIG_SCSI_QLOGICPTI) += qlogicpti.o diff --git a/drivers/scsi/gdth.c b/drivers/scsi/gdth.c deleted file mode 100644 index 5d801388680b..000000000000 --- a/drivers/scsi/gdth.c +++ /dev/null @@ -1,4322 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/************************************************************************ - * Linux driver for * - * ICP vortex GmbH: GDT PCI Disk Array Controllers * - * Intel Corporation: Storage RAID Controllers * - * * - * gdth.c * - * Copyright (C) 1995-06 ICP vortex GmbH, Achim Leubner * - * Copyright (C) 2002-04 Intel Corporation * - * Copyright (C) 2003-06 Adaptec Inc. * - * * - * * - * Additions/Fixes: * - * Boji Tony Kannanthanam * - * Johannes Dinner * - * * - * * - * Linux kernel 2.6.x supported * - * * - ************************************************************************/ - -/* All GDT Disk Array Controllers are fully supported by this driver. - * This includes the PCI SCSI Disk Array Controllers and the - * PCI Fibre Channel Disk Array Controllers. See gdth.h for a complete - * list of all controller types. - * - * After the optional list of IRQ values, other possible - * command line options are: - * disable:Y disable driver - * disable:N enable driver - * reserve_mode:0 reserve no drives for the raw service - * reserve_mode:1 reserve all not init., removable drives - * reserve_mode:2 reserve all not init. drives - * reserve_list:h,b,t,l,h,b,t,l,... reserve particular drive(s) with - * h- controller no., b- channel no., - * t- target ID, l- LUN - * reverse_scan:Y reverse scan order for PCI controllers - * reverse_scan:N scan PCI controllers like BIOS - * max_ids:x x - target ID count per channel (1..MAXID) - * rescan:Y rescan all channels/IDs - * rescan:N use all devices found until now - * hdr_channel:x x - number of virtual bus for host drives - * shared_access:Y disable driver reserve/release protocol to - * access a shared resource from several nodes, - * appropriate controller firmware required - * shared_access:N enable driver reserve/release protocol - * force_dma32:Y use only 32 bit DMA mode - * force_dma32:N use 64 bit DMA mode, if supported - * - * The default values are: "gdth=disable:N,reserve_mode:1,reverse_scan:N, - * max_ids:127,rescan:N,hdr_channel:0, - * shared_access:Y,force_dma32:N". - * Here is another example: "gdth=reserve_list:0,1,2,0,0,1,3,0,rescan:Y". - * - * When loading the gdth driver as a module, the same options are available. - * You can set the IRQs with "IRQ=...". However, the syntax to specify the - * options changes slightly. You must replace all ',' between options - * with ' ' and all ':' with '=' and you must use - * '1' in place of 'Y' and '0' in place of 'N'. - * - * Default: "modprobe gdth disable=0 reserve_mode=1 reverse_scan=0 - * max_ids=127 rescan=0 hdr_channel=0 shared_access=0 - * force_dma32=0" - * The other example: "modprobe gdth reserve_list=0,1,2,0,0,1,3,0 rescan=1". - */ - -/* The meaning of the Scsi_Pointer members in this driver is as follows: - * ptr: Chaining - * this_residual: unused - * buffer: unused - * dma_handle: unused - * buffers_residual: unused - * Status: unused - * Message: unused - * have_data_in: unused - * sent_command: unused - * phase: unused - */ - -/* statistics */ -#define GDTH_STATISTICS - -#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 "scsi.h" -#include -#include "gdth.h" - -static DEFINE_MUTEX(gdth_mutex); -static void gdth_delay(int milliseconds); -static void gdth_eval_mapping(u32 size, u32 *cyls, int *heads, int *secs); -static irqreturn_t gdth_interrupt(int irq, void *dev_id); -static irqreturn_t __gdth_interrupt(gdth_ha_str *ha, - int gdth_from_wait, int* pIndex); -static int gdth_sync_event(gdth_ha_str *ha, int service, u8 index, - struct scsi_cmnd *scp); -static int gdth_async_event(gdth_ha_str *ha); -static void gdth_log_event(gdth_evt_data *dvr, char *buffer); - -static void gdth_putq(gdth_ha_str *ha, struct scsi_cmnd *scp, u8 priority); -static void gdth_next(gdth_ha_str *ha); -static int gdth_fill_raw_cmd(gdth_ha_str *ha, struct scsi_cmnd *scp, u8 b); -static int gdth_special_cmd(gdth_ha_str *ha, struct scsi_cmnd *scp); -static gdth_evt_str *gdth_store_event(gdth_ha_str *ha, u16 source, - u16 idx, gdth_evt_data *evt); -static int gdth_read_event(gdth_ha_str *ha, int handle, gdth_evt_str *estr); -static void gdth_readapp_event(gdth_ha_str *ha, u8 application, - gdth_evt_str *estr); -static void gdth_clear_events(void); - -static void gdth_copy_internal_data(gdth_ha_str *ha, struct scsi_cmnd *scp, - char *buffer, u16 count); -static int gdth_internal_cache_cmd(gdth_ha_str *ha, struct scsi_cmnd *scp); -static int gdth_fill_cache_cmd(gdth_ha_str *ha, struct scsi_cmnd *scp, - u16 hdrive); - -static void gdth_enable_int(gdth_ha_str *ha); -static int gdth_test_busy(gdth_ha_str *ha); -static int gdth_get_cmd_index(gdth_ha_str *ha); -static void gdth_release_event(gdth_ha_str *ha); -static int gdth_wait(gdth_ha_str *ha, int index,u32 time); -static int gdth_internal_cmd(gdth_ha_str *ha, u8 service, u16 opcode, - u32 p1, u64 p2,u64 p3); -static int gdth_search_drives(gdth_ha_str *ha); -static int gdth_analyse_hdrive(gdth_ha_str *ha, u16 hdrive); - -static const char *gdth_ctr_name(gdth_ha_str *ha); - -static int gdth_open(struct inode *inode, struct file *filep); -static int gdth_close(struct inode *inode, struct file *filep); -static long gdth_unlocked_ioctl(struct file *filep, unsigned int cmd, - unsigned long arg); - -static void gdth_flush(gdth_ha_str *ha); -static int gdth_queuecommand(struct Scsi_Host *h, struct scsi_cmnd *cmd); -static int __gdth_queuecommand(gdth_ha_str *ha, struct scsi_cmnd *scp, - struct gdth_cmndinfo *cmndinfo); -static void gdth_scsi_done(struct scsi_cmnd *scp); - -#ifdef DEBUG_GDTH -static u8 DebugState = DEBUG_GDTH; -#define TRACE(a) {if (DebugState==1) {printk a;}} -#define TRACE2(a) {if (DebugState==1 || DebugState==2) {printk a;}} -#define TRACE3(a) {if (DebugState!=0) {printk a;}} -#else /* !DEBUG */ -#define TRACE(a) -#define TRACE2(a) -#define TRACE3(a) -#endif - -#ifdef GDTH_STATISTICS -static u32 max_rq=0, max_index=0, max_sg=0; -static u32 act_ints=0, act_ios=0, act_stats=0, act_rq=0; -static struct timer_list gdth_timer; -#endif - -#define PTR2USHORT(a) (u16)(unsigned long)(a) -#define GDTOFFSOF(a,b) (size_t)&(((a*)0)->b) -#define INDEX_OK(i,t) ((i)(a)->virt_bus ? (b-1):(b)) - -static u8 gdth_polling; /* polling if TRUE */ -static int gdth_ctr_count = 0; /* controller count */ -static LIST_HEAD(gdth_instances); /* controller list */ -static u8 gdth_write_through = FALSE; /* write through */ -static gdth_evt_str ebuffer[MAX_EVENTS]; /* event buffer */ -static int elastidx; -static int eoldidx; -static int major; - -#define DIN 1 /* IN data direction */ -#define DOU 2 /* OUT data direction */ -#define DNO DIN /* no data transfer */ -#define DUN DIN /* unknown data direction */ -static u8 gdth_direction_tab[0x100] = { - DNO,DNO,DIN,DIN,DOU,DIN,DIN,DOU,DIN,DUN,DOU,DOU,DUN,DUN,DUN,DIN, - DNO,DIN,DIN,DOU,DIN,DOU,DNO,DNO,DOU,DNO,DIN,DNO,DIN,DOU,DNO,DUN, - DIN,DUN,DIN,DUN,DOU,DIN,DUN,DUN,DIN,DIN,DOU,DNO,DUN,DIN,DOU,DOU, - DOU,DOU,DOU,DNO,DIN,DNO,DNO,DIN,DOU,DOU,DOU,DOU,DIN,DOU,DIN,DOU, - DOU,DOU,DIN,DIN,DIN,DNO,DUN,DNO,DNO,DNO,DUN,DNO,DOU,DIN,DUN,DUN, - DUN,DUN,DUN,DUN,DUN,DOU,DUN,DUN,DUN,DUN,DIN,DUN,DUN,DUN,DUN,DUN, - DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN, - DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN, - DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DIN,DUN,DOU,DUN,DUN,DUN,DUN,DUN, - DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DIN,DUN, - DUN,DUN,DUN,DUN,DUN,DNO,DNO,DUN,DIN,DNO,DOU,DUN,DNO,DUN,DOU,DOU, - DOU,DOU,DOU,DNO,DUN,DIN,DOU,DIN,DIN,DUN,DUN,DUN,DUN,DUN,DUN,DUN, - DUN,DUN,DOU,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN, - DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN, - DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DOU,DUN,DUN,DUN,DUN,DUN, - DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN -}; - -/* LILO and modprobe/insmod parameters */ -/* disable driver flag */ -static int disable __initdata = 0; -/* reserve flag */ -static int reserve_mode = 1; -/* reserve list */ -static int reserve_list[MAX_RES_ARGS] = -{0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, - 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, - 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff}; -/* scan order for PCI controllers */ -static int reverse_scan = 0; -/* virtual channel for the host drives */ -static int hdr_channel = 0; -/* max. IDs per channel */ -static int max_ids = MAXID; -/* rescan all IDs */ -static int rescan = 0; -/* shared access */ -static int shared_access = 1; -/* 64 bit DMA mode, support for drives > 2 TB, if force_dma32 = 0 */ -static int force_dma32 = 0; - -/* parameters for modprobe/insmod */ -module_param(disable, int, 0); -module_param(reserve_mode, int, 0); -module_param_array(reserve_list, int, NULL, 0); -module_param(reverse_scan, int, 0); -module_param(hdr_channel, int, 0); -module_param(max_ids, int, 0); -module_param(rescan, int, 0); -module_param(shared_access, int, 0); -module_param(force_dma32, int, 0); -MODULE_AUTHOR("Achim Leubner"); -MODULE_LICENSE("GPL"); - -/* ioctl interface */ -static const struct file_operations gdth_fops = { - .unlocked_ioctl = gdth_unlocked_ioctl, - .open = gdth_open, - .release = gdth_close, - .llseek = noop_llseek, -}; - -#include "gdth_proc.h" -#include "gdth_proc.c" - -static gdth_ha_str *gdth_find_ha(int hanum) -{ - gdth_ha_str *ha; - - list_for_each_entry(ha, &gdth_instances, list) - if (hanum == ha->hanum) - return ha; - - return NULL; -} - -static struct gdth_cmndinfo *gdth_get_cmndinfo(gdth_ha_str *ha) -{ - struct gdth_cmndinfo *priv = NULL; - unsigned long flags; - int i; - - spin_lock_irqsave(&ha->smp_lock, flags); - - for (i=0; icmndinfo[i].index == 0) { - priv = &ha->cmndinfo[i]; - memset(priv, 0, sizeof(*priv)); - priv->index = i+1; - break; - } - } - - spin_unlock_irqrestore(&ha->smp_lock, flags); - - return priv; -} - -static void gdth_put_cmndinfo(struct gdth_cmndinfo *priv) -{ - BUG_ON(!priv); - priv->index = 0; -} - -static void gdth_delay(int milliseconds) -{ - if (milliseconds == 0) { - udelay(1); - } else { - mdelay(milliseconds); - } -} - -static void gdth_scsi_done(struct scsi_cmnd *scp) -{ - struct gdth_cmndinfo *cmndinfo = gdth_cmnd_priv(scp); - int internal_command = cmndinfo->internal_command; - - TRACE2(("gdth_scsi_done()\n")); - - gdth_put_cmndinfo(cmndinfo); - scp->host_scribble = NULL; - - if (internal_command) - complete((struct completion *)scp->request); - else - scp->scsi_done(scp); -} - -static int __gdth_execute(struct scsi_device *sdev, gdth_cmd_str *gdtcmd, - char *cmnd, int timeout, u32 *info) -{ - gdth_ha_str *ha = shost_priv(sdev->host); - struct scsi_cmnd *scp; - struct gdth_cmndinfo cmndinfo; - DECLARE_COMPLETION_ONSTACK(wait); - int rval; - - scp = kzalloc(sizeof(*scp), GFP_KERNEL); - if (!scp) - return -ENOMEM; - - scp->sense_buffer = kzalloc(SCSI_SENSE_BUFFERSIZE, GFP_KERNEL); - if (!scp->sense_buffer) { - kfree(scp); - return -ENOMEM; - } - - scp->device = sdev; - memset(&cmndinfo, 0, sizeof(cmndinfo)); - - /* use request field to save the ptr. to completion struct. */ - scp->request = (struct request *)&wait; - scp->cmd_len = 12; - scp->cmnd = cmnd; - cmndinfo.priority = IOCTL_PRI; - cmndinfo.internal_cmd_str = gdtcmd; - cmndinfo.internal_command = 1; - - TRACE(("__gdth_execute() cmd 0x%x\n", scp->cmnd[0])); - __gdth_queuecommand(ha, scp, &cmndinfo); - - wait_for_completion(&wait); - - rval = cmndinfo.status; - if (info) - *info = cmndinfo.info; - kfree(scp->sense_buffer); - kfree(scp); - return rval; -} - -int gdth_execute(struct Scsi_Host *shost, gdth_cmd_str *gdtcmd, char *cmnd, - int timeout, u32 *info) -{ - struct scsi_device *sdev = scsi_get_host_dev(shost); - int rval = __gdth_execute(sdev, gdtcmd, cmnd, timeout, info); - - scsi_free_host_dev(sdev); - return rval; -} - -static void gdth_eval_mapping(u32 size, u32 *cyls, int *heads, int *secs) -{ - *cyls = size /HEADS/SECS; - if (*cyls <= MAXCYLS) { - *heads = HEADS; - *secs = SECS; - } else { /* too high for 64*32 */ - *cyls = size /MEDHEADS/MEDSECS; - if (*cyls <= MAXCYLS) { - *heads = MEDHEADS; - *secs = MEDSECS; - } else { /* too high for 127*63 */ - *cyls = size /BIGHEADS/BIGSECS; - *heads = BIGHEADS; - *secs = BIGSECS; - } - } -} - -static bool gdth_search_vortex(u16 device) -{ - if (device <= PCI_DEVICE_ID_VORTEX_GDT6555) - return true; - if (device >= PCI_DEVICE_ID_VORTEX_GDT6x17RP && - device <= PCI_DEVICE_ID_VORTEX_GDTMAXRP) - return true; - if (device == PCI_DEVICE_ID_VORTEX_GDTNEWRX || - device == PCI_DEVICE_ID_VORTEX_GDTNEWRX2) - return true; - return false; -} - -static int gdth_pci_probe_one(gdth_pci_str *pcistr, gdth_ha_str **ha_out); -static int gdth_pci_init_one(struct pci_dev *pdev, - const struct pci_device_id *ent); -static void gdth_pci_remove_one(struct pci_dev *pdev); -static void gdth_remove_one(gdth_ha_str *ha); - -/* Vortex only makes RAID controllers. - * We do not really want to specify all 550 ids here, so wildcard match. - */ -static const struct pci_device_id gdthtable[] = { - { PCI_VDEVICE(VORTEX, PCI_ANY_ID) }, - { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_SRC) }, - { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_SRC_XSCALE) }, - { } /* terminate list */ -}; -MODULE_DEVICE_TABLE(pci, gdthtable); - -static struct pci_driver gdth_pci_driver = { - .name = "gdth", - .id_table = gdthtable, - .probe = gdth_pci_init_one, - .remove = gdth_pci_remove_one, -}; - -static void gdth_pci_remove_one(struct pci_dev *pdev) -{ - gdth_ha_str *ha = pci_get_drvdata(pdev); - - list_del(&ha->list); - gdth_remove_one(ha); - - pci_disable_device(pdev); -} - -static int gdth_pci_init_one(struct pci_dev *pdev, - const struct pci_device_id *ent) -{ - u16 vendor = pdev->vendor; - u16 device = pdev->device; - unsigned long base0, base1, base2; - int rc; - gdth_pci_str gdth_pcistr; - gdth_ha_str *ha = NULL; - - TRACE(("gdth_search_dev() cnt %d vendor %x device %x\n", - gdth_ctr_count, vendor, device)); - - memset(&gdth_pcistr, 0, sizeof(gdth_pcistr)); - - if (vendor == PCI_VENDOR_ID_VORTEX && !gdth_search_vortex(device)) - return -ENODEV; - - rc = pci_enable_device(pdev); - if (rc) - return rc; - - if (gdth_ctr_count >= MAXHA) - return -EBUSY; - - /* GDT PCI controller found, resources are already in pdev */ - gdth_pcistr.pdev = pdev; - base0 = pci_resource_flags(pdev, 0); - base1 = pci_resource_flags(pdev, 1); - base2 = pci_resource_flags(pdev, 2); - if (device <= PCI_DEVICE_ID_VORTEX_GDT6000B || /* GDT6000/B */ - device >= PCI_DEVICE_ID_VORTEX_GDT6x17RP) { /* MPR */ - if (!(base0 & IORESOURCE_MEM)) - return -ENODEV; - gdth_pcistr.dpmem = pci_resource_start(pdev, 0); - } else { /* GDT6110, GDT6120, .. */ - if (!(base0 & IORESOURCE_MEM) || - !(base2 & IORESOURCE_MEM) || - !(base1 & IORESOURCE_IO)) - return -ENODEV; - gdth_pcistr.dpmem = pci_resource_start(pdev, 2); - gdth_pcistr.io = pci_resource_start(pdev, 1); - } - TRACE2(("Controller found at %d/%d, irq %d, dpmem 0x%lx\n", - gdth_pcistr.pdev->bus->number, - PCI_SLOT(gdth_pcistr.pdev->devfn), - gdth_pcistr.irq, - gdth_pcistr.dpmem)); - - rc = gdth_pci_probe_one(&gdth_pcistr, &ha); - if (rc) - return rc; - - return 0; -} - -static int gdth_init_pci(struct pci_dev *pdev, gdth_pci_str *pcistr, - gdth_ha_str *ha) -{ - register gdt6_dpram_str __iomem *dp6_ptr; - register gdt6c_dpram_str __iomem *dp6c_ptr; - register gdt6m_dpram_str __iomem *dp6m_ptr; - u32 retries; - u8 prot_ver; - u16 command; - int i, found = FALSE; - - TRACE(("gdth_init_pci()\n")); - - if (pdev->vendor == PCI_VENDOR_ID_INTEL) - ha->oem_id = OEM_ID_INTEL; - else - ha->oem_id = OEM_ID_ICP; - ha->brd_phys = (pdev->bus->number << 8) | (pdev->devfn & 0xf8); - ha->stype = (u32)pdev->device; - ha->irq = pdev->irq; - ha->pdev = pdev; - - if (ha->pdev->device <= PCI_DEVICE_ID_VORTEX_GDT6000B) { /* GDT6000/B */ - TRACE2(("init_pci() dpmem %lx irq %d\n",pcistr->dpmem,ha->irq)); - ha->brd = ioremap(pcistr->dpmem, sizeof(gdt6_dpram_str)); - if (ha->brd == NULL) { - printk("GDT-PCI: Initialization error (DPMEM remap error)\n"); - return 0; - } - /* check and reset interface area */ - dp6_ptr = ha->brd; - writel(DPMEM_MAGIC, &dp6_ptr->u); - if (readl(&dp6_ptr->u) != DPMEM_MAGIC) { - printk("GDT-PCI: Cannot access DPMEM at 0x%lx (shadowed?)\n", - pcistr->dpmem); - found = FALSE; - for (i = 0xC8000; i < 0xE8000; i += 0x4000) { - iounmap(ha->brd); - ha->brd = ioremap(i, sizeof(u16)); - if (ha->brd == NULL) { - printk("GDT-PCI: Initialization error (DPMEM remap error)\n"); - return 0; - } - if (readw(ha->brd) != 0xffff) { - TRACE2(("init_pci_old() address 0x%x busy\n", i)); - continue; - } - iounmap(ha->brd); - pci_write_config_dword(pdev, PCI_BASE_ADDRESS_0, i); - ha->brd = ioremap(i, sizeof(gdt6_dpram_str)); - if (ha->brd == NULL) { - printk("GDT-PCI: Initialization error (DPMEM remap error)\n"); - return 0; - } - dp6_ptr = ha->brd; - writel(DPMEM_MAGIC, &dp6_ptr->u); - if (readl(&dp6_ptr->u) == DPMEM_MAGIC) { - printk("GDT-PCI: Use free address at 0x%x\n", i); - found = TRUE; - break; - } - } - if (!found) { - printk("GDT-PCI: No free address found!\n"); - iounmap(ha->brd); - return 0; - } - } - memset_io(&dp6_ptr->u, 0, sizeof(dp6_ptr->u)); - if (readl(&dp6_ptr->u) != 0) { - printk("GDT-PCI: Initialization error (DPMEM write error)\n"); - iounmap(ha->brd); - return 0; - } - - /* disable board interrupts, deinit services */ - writeb(0xff, &dp6_ptr->io.irqdel); - writeb(0x00, &dp6_ptr->io.irqen); - writeb(0x00, &dp6_ptr->u.ic.S_Status); - writeb(0x00, &dp6_ptr->u.ic.Cmd_Index); - - writel(pcistr->dpmem, &dp6_ptr->u.ic.S_Info[0]); - writeb(0xff, &dp6_ptr->u.ic.S_Cmd_Indx); - writeb(0, &dp6_ptr->io.event); - retries = INIT_RETRIES; - gdth_delay(20); - while (readb(&dp6_ptr->u.ic.S_Status) != 0xff) { - if (--retries == 0) { - printk("GDT-PCI: Initialization error (DEINIT failed)\n"); - iounmap(ha->brd); - return 0; - } - gdth_delay(1); - } - prot_ver = (u8)readl(&dp6_ptr->u.ic.S_Info[0]); - writeb(0, &dp6_ptr->u.ic.S_Status); - writeb(0xff, &dp6_ptr->io.irqdel); - if (prot_ver != PROTOCOL_VERSION) { - printk("GDT-PCI: Illegal protocol version\n"); - iounmap(ha->brd); - return 0; - } - - ha->type = GDT_PCI; - ha->ic_all_size = sizeof(dp6_ptr->u); - - /* special command to controller BIOS */ - writel(0x00, &dp6_ptr->u.ic.S_Info[0]); - writel(0x00, &dp6_ptr->u.ic.S_Info[1]); - writel(0x00, &dp6_ptr->u.ic.S_Info[2]); - writel(0x00, &dp6_ptr->u.ic.S_Info[3]); - writeb(0xfe, &dp6_ptr->u.ic.S_Cmd_Indx); - writeb(0, &dp6_ptr->io.event); - retries = INIT_RETRIES; - gdth_delay(20); - while (readb(&dp6_ptr->u.ic.S_Status) != 0xfe) { - if (--retries == 0) { - printk("GDT-PCI: Initialization error\n"); - iounmap(ha->brd); - return 0; - } - gdth_delay(1); - } - writeb(0, &dp6_ptr->u.ic.S_Status); - writeb(0xff, &dp6_ptr->io.irqdel); - - ha->dma64_support = 0; - - } else if (ha->pdev->device <= PCI_DEVICE_ID_VORTEX_GDT6555) { /* GDT6110, ... */ - ha->plx = (gdt6c_plx_regs *)pcistr->io; - TRACE2(("init_pci_new() dpmem %lx irq %d\n", - pcistr->dpmem,ha->irq)); - ha->brd = ioremap(pcistr->dpmem, sizeof(gdt6c_dpram_str)); - if (ha->brd == NULL) { - printk("GDT-PCI: Initialization error (DPMEM remap error)\n"); - iounmap(ha->brd); - return 0; - } - /* check and reset interface area */ - dp6c_ptr = ha->brd; - writel(DPMEM_MAGIC, &dp6c_ptr->u); - if (readl(&dp6c_ptr->u) != DPMEM_MAGIC) { - printk("GDT-PCI: Cannot access DPMEM at 0x%lx (shadowed?)\n", - pcistr->dpmem); - found = FALSE; - for (i = 0xC8000; i < 0xE8000; i += 0x4000) { - iounmap(ha->brd); - ha->brd = ioremap(i, sizeof(u16)); - if (ha->brd == NULL) { - printk("GDT-PCI: Initialization error (DPMEM remap error)\n"); - return 0; - } - if (readw(ha->brd) != 0xffff) { - TRACE2(("init_pci_plx() address 0x%x busy\n", i)); - continue; - } - iounmap(ha->brd); - pci_write_config_dword(pdev, PCI_BASE_ADDRESS_2, i); - ha->brd = ioremap(i, sizeof(gdt6c_dpram_str)); - if (ha->brd == NULL) { - printk("GDT-PCI: Initialization error (DPMEM remap error)\n"); - return 0; - } - dp6c_ptr = ha->brd; - writel(DPMEM_MAGIC, &dp6c_ptr->u); - if (readl(&dp6c_ptr->u) == DPMEM_MAGIC) { - printk("GDT-PCI: Use free address at 0x%x\n", i); - found = TRUE; - break; - } - } - if (!found) { - printk("GDT-PCI: No free address found!\n"); - iounmap(ha->brd); - return 0; - } - } - memset_io(&dp6c_ptr->u, 0, sizeof(dp6c_ptr->u)); - if (readl(&dp6c_ptr->u) != 0) { - printk("GDT-PCI: Initialization error (DPMEM write error)\n"); - iounmap(ha->brd); - return 0; - } - - /* disable board interrupts, deinit services */ - outb(0x00,PTR2USHORT(&ha->plx->control1)); - outb(0xff,PTR2USHORT(&ha->plx->edoor_reg)); - - writeb(0x00, &dp6c_ptr->u.ic.S_Status); - writeb(0x00, &dp6c_ptr->u.ic.Cmd_Index); - - writel(pcistr->dpmem, &dp6c_ptr->u.ic.S_Info[0]); - writeb(0xff, &dp6c_ptr->u.ic.S_Cmd_Indx); - - outb(1,PTR2USHORT(&ha->plx->ldoor_reg)); - - retries = INIT_RETRIES; - gdth_delay(20); - while (readb(&dp6c_ptr->u.ic.S_Status) != 0xff) { - if (--retries == 0) { - printk("GDT-PCI: Initialization error (DEINIT failed)\n"); - iounmap(ha->brd); - return 0; - } - gdth_delay(1); - } - prot_ver = (u8)readl(&dp6c_ptr->u.ic.S_Info[0]); - writeb(0, &dp6c_ptr->u.ic.Status); - if (prot_ver != PROTOCOL_VERSION) { - printk("GDT-PCI: Illegal protocol version\n"); - iounmap(ha->brd); - return 0; - } - - ha->type = GDT_PCINEW; - ha->ic_all_size = sizeof(dp6c_ptr->u); - - /* special command to controller BIOS */ - writel(0x00, &dp6c_ptr->u.ic.S_Info[0]); - writel(0x00, &dp6c_ptr->u.ic.S_Info[1]); - writel(0x00, &dp6c_ptr->u.ic.S_Info[2]); - writel(0x00, &dp6c_ptr->u.ic.S_Info[3]); - writeb(0xfe, &dp6c_ptr->u.ic.S_Cmd_Indx); - - outb(1,PTR2USHORT(&ha->plx->ldoor_reg)); - - retries = INIT_RETRIES; - gdth_delay(20); - while (readb(&dp6c_ptr->u.ic.S_Status) != 0xfe) { - if (--retries == 0) { - printk("GDT-PCI: Initialization error\n"); - iounmap(ha->brd); - return 0; - } - gdth_delay(1); - } - writeb(0, &dp6c_ptr->u.ic.S_Status); - - ha->dma64_support = 0; - - } else { /* MPR */ - TRACE2(("init_pci_mpr() dpmem %lx irq %d\n",pcistr->dpmem,ha->irq)); - ha->brd = ioremap(pcistr->dpmem, sizeof(gdt6m_dpram_str)); - if (ha->brd == NULL) { - printk("GDT-PCI: Initialization error (DPMEM remap error)\n"); - return 0; - } - - /* manipulate config. space to enable DPMEM, start RP controller */ - pci_read_config_word(pdev, PCI_COMMAND, &command); - command |= 6; - pci_write_config_word(pdev, PCI_COMMAND, command); - gdth_delay(1); - - dp6m_ptr = ha->brd; - - /* Ensure that it is safe to access the non HW portions of DPMEM. - * Aditional check needed for Xscale based RAID controllers */ - while( ((int)readb(&dp6m_ptr->i960r.sema0_reg) ) & 3 ) - gdth_delay(1); - - /* check and reset interface area */ - writel(DPMEM_MAGIC, &dp6m_ptr->u); - if (readl(&dp6m_ptr->u) != DPMEM_MAGIC) { - printk("GDT-PCI: Cannot access DPMEM at 0x%lx (shadowed?)\n", - pcistr->dpmem); - found = FALSE; - for (i = 0xC8000; i < 0xE8000; i += 0x4000) { - iounmap(ha->brd); - ha->brd = ioremap(i, sizeof(u16)); - if (ha->brd == NULL) { - printk("GDT-PCI: Initialization error (DPMEM remap error)\n"); - return 0; - } - if (readw(ha->brd) != 0xffff) { - TRACE2(("init_pci_mpr() address 0x%x busy\n", i)); - continue; - } - iounmap(ha->brd); - pci_write_config_dword(pdev, PCI_BASE_ADDRESS_0, i); - ha->brd = ioremap(i, sizeof(gdt6m_dpram_str)); - if (ha->brd == NULL) { - printk("GDT-PCI: Initialization error (DPMEM remap error)\n"); - return 0; - } - dp6m_ptr = ha->brd; - writel(DPMEM_MAGIC, &dp6m_ptr->u); - if (readl(&dp6m_ptr->u) == DPMEM_MAGIC) { - printk("GDT-PCI: Use free address at 0x%x\n", i); - found = TRUE; - break; - } - } - if (!found) { - printk("GDT-PCI: No free address found!\n"); - iounmap(ha->brd); - return 0; - } - } - memset_io(&dp6m_ptr->u, 0, sizeof(dp6m_ptr->u)); - - /* disable board interrupts, deinit services */ - writeb(readb(&dp6m_ptr->i960r.edoor_en_reg) | 4, - &dp6m_ptr->i960r.edoor_en_reg); - writeb(0xff, &dp6m_ptr->i960r.edoor_reg); - writeb(0x00, &dp6m_ptr->u.ic.S_Status); - writeb(0x00, &dp6m_ptr->u.ic.Cmd_Index); - - writel(pcistr->dpmem, &dp6m_ptr->u.ic.S_Info[0]); - writeb(0xff, &dp6m_ptr->u.ic.S_Cmd_Indx); - writeb(1, &dp6m_ptr->i960r.ldoor_reg); - retries = INIT_RETRIES; - gdth_delay(20); - while (readb(&dp6m_ptr->u.ic.S_Status) != 0xff) { - if (--retries == 0) { - printk("GDT-PCI: Initialization error (DEINIT failed)\n"); - iounmap(ha->brd); - return 0; - } - gdth_delay(1); - } - prot_ver = (u8)readl(&dp6m_ptr->u.ic.S_Info[0]); - writeb(0, &dp6m_ptr->u.ic.S_Status); - if (prot_ver != PROTOCOL_VERSION) { - printk("GDT-PCI: Illegal protocol version\n"); - iounmap(ha->brd); - return 0; - } - - ha->type = GDT_PCIMPR; - ha->ic_all_size = sizeof(dp6m_ptr->u); - - /* special command to controller BIOS */ - writel(0x00, &dp6m_ptr->u.ic.S_Info[0]); - writel(0x00, &dp6m_ptr->u.ic.S_Info[1]); - writel(0x00, &dp6m_ptr->u.ic.S_Info[2]); - writel(0x00, &dp6m_ptr->u.ic.S_Info[3]); - writeb(0xfe, &dp6m_ptr->u.ic.S_Cmd_Indx); - writeb(1, &dp6m_ptr->i960r.ldoor_reg); - retries = INIT_RETRIES; - gdth_delay(20); - while (readb(&dp6m_ptr->u.ic.S_Status) != 0xfe) { - if (--retries == 0) { - printk("GDT-PCI: Initialization error\n"); - iounmap(ha->brd); - return 0; - } - gdth_delay(1); - } - writeb(0, &dp6m_ptr->u.ic.S_Status); - - /* read FW version to detect 64-bit DMA support */ - writeb(0xfd, &dp6m_ptr->u.ic.S_Cmd_Indx); - writeb(1, &dp6m_ptr->i960r.ldoor_reg); - retries = INIT_RETRIES; - gdth_delay(20); - while (readb(&dp6m_ptr->u.ic.S_Status) != 0xfd) { - if (--retries == 0) { - printk("GDT-PCI: Initialization error (DEINIT failed)\n"); - iounmap(ha->brd); - return 0; - } - gdth_delay(1); - } - prot_ver = (u8)(readl(&dp6m_ptr->u.ic.S_Info[0]) >> 16); - writeb(0, &dp6m_ptr->u.ic.S_Status); - if (prot_ver < 0x2b) /* FW < x.43: no 64-bit DMA support */ - ha->dma64_support = 0; - else - ha->dma64_support = 1; - } - - return 1; -} - -/* controller protocol functions */ - -static void gdth_enable_int(gdth_ha_str *ha) -{ - unsigned long flags; - gdt6_dpram_str __iomem *dp6_ptr; - gdt6m_dpram_str __iomem *dp6m_ptr; - - TRACE(("gdth_enable_int() hanum %d\n",ha->hanum)); - spin_lock_irqsave(&ha->smp_lock, flags); - - if (ha->type == GDT_PCI) { - dp6_ptr = ha->brd; - writeb(1, &dp6_ptr->io.irqdel); - writeb(0, &dp6_ptr->u.ic.Cmd_Index); - writeb(1, &dp6_ptr->io.irqen); - } else if (ha->type == GDT_PCINEW) { - outb(0xff, PTR2USHORT(&ha->plx->edoor_reg)); - outb(0x03, PTR2USHORT(&ha->plx->control1)); - } else if (ha->type == GDT_PCIMPR) { - dp6m_ptr = ha->brd; - writeb(0xff, &dp6m_ptr->i960r.edoor_reg); - writeb(readb(&dp6m_ptr->i960r.edoor_en_reg) & ~4, - &dp6m_ptr->i960r.edoor_en_reg); - } - spin_unlock_irqrestore(&ha->smp_lock, flags); -} - -/* return IStatus if interrupt was from this card else 0 */ -static u8 gdth_get_status(gdth_ha_str *ha) -{ - u8 IStatus = 0; - - TRACE(("gdth_get_status() irq %d ctr_count %d\n", ha->irq, gdth_ctr_count)); - - if (ha->type == GDT_PCI) - IStatus = - readb(&((gdt6_dpram_str __iomem *)ha->brd)->u.ic.Cmd_Index); - else if (ha->type == GDT_PCINEW) - IStatus = inb(PTR2USHORT(&ha->plx->edoor_reg)); - else if (ha->type == GDT_PCIMPR) - IStatus = - readb(&((gdt6m_dpram_str __iomem *)ha->brd)->i960r.edoor_reg); - - return IStatus; -} - -static int gdth_test_busy(gdth_ha_str *ha) -{ - register int gdtsema0 = 0; - - TRACE(("gdth_test_busy() hanum %d\n", ha->hanum)); - - if (ha->type == GDT_PCI) - gdtsema0 = (int)readb(&((gdt6_dpram_str __iomem *)ha->brd)->u.ic.Sema0); - else if (ha->type == GDT_PCINEW) - gdtsema0 = (int)inb(PTR2USHORT(&ha->plx->sema0_reg)); - else if (ha->type == GDT_PCIMPR) - gdtsema0 = - (int)readb(&((gdt6m_dpram_str __iomem *)ha->brd)->i960r.sema0_reg); - - return (gdtsema0 & 1); -} - - -static int gdth_get_cmd_index(gdth_ha_str *ha) -{ - int i; - - TRACE(("gdth_get_cmd_index() hanum %d\n", ha->hanum)); - - for (i=0; icmd_tab[i].cmnd == UNUSED_CMND) { - ha->cmd_tab[i].cmnd = ha->pccb->RequestBuffer; - ha->cmd_tab[i].service = ha->pccb->Service; - ha->pccb->CommandIndex = (u32)i+2; - return (i+2); - } - } - return 0; -} - - -static void gdth_set_sema0(gdth_ha_str *ha) -{ - TRACE(("gdth_set_sema0() hanum %d\n", ha->hanum)); - - if (ha->type == GDT_PCI) { - writeb(1, &((gdt6_dpram_str __iomem *)ha->brd)->u.ic.Sema0); - } else if (ha->type == GDT_PCINEW) { - outb(1, PTR2USHORT(&ha->plx->sema0_reg)); - } else if (ha->type == GDT_PCIMPR) { - writeb(1, &((gdt6m_dpram_str __iomem *)ha->brd)->i960r.sema0_reg); - } -} - - -static void gdth_copy_command(gdth_ha_str *ha) -{ - register gdth_cmd_str *cmd_ptr; - register gdt6m_dpram_str __iomem *dp6m_ptr; - register gdt6c_dpram_str __iomem *dp6c_ptr; - gdt6_dpram_str __iomem *dp6_ptr; - u16 cp_count,dp_offset,cmd_no; - - TRACE(("gdth_copy_command() hanum %d\n", ha->hanum)); - - cp_count = ha->cmd_len; - dp_offset= ha->cmd_offs_dpmem; - cmd_no = ha->cmd_cnt; - cmd_ptr = ha->pccb; - - ++ha->cmd_cnt; - - /* set cpcount dword aligned */ - if (cp_count & 3) - cp_count += (4 - (cp_count & 3)); - - ha->cmd_offs_dpmem += cp_count; - - /* set offset and service, copy command to DPMEM */ - if (ha->type == GDT_PCI) { - dp6_ptr = ha->brd; - writew(dp_offset + DPMEM_COMMAND_OFFSET, - &dp6_ptr->u.ic.comm_queue[cmd_no].offset); - writew((u16)cmd_ptr->Service, - &dp6_ptr->u.ic.comm_queue[cmd_no].serv_id); - memcpy_toio(&dp6_ptr->u.ic.gdt_dpr_cmd[dp_offset],cmd_ptr,cp_count); - } else if (ha->type == GDT_PCINEW) { - dp6c_ptr = ha->brd; - writew(dp_offset + DPMEM_COMMAND_OFFSET, - &dp6c_ptr->u.ic.comm_queue[cmd_no].offset); - writew((u16)cmd_ptr->Service, - &dp6c_ptr->u.ic.comm_queue[cmd_no].serv_id); - memcpy_toio(&dp6c_ptr->u.ic.gdt_dpr_cmd[dp_offset],cmd_ptr,cp_count); - } else if (ha->type == GDT_PCIMPR) { - dp6m_ptr = ha->brd; - writew(dp_offset + DPMEM_COMMAND_OFFSET, - &dp6m_ptr->u.ic.comm_queue[cmd_no].offset); - writew((u16)cmd_ptr->Service, - &dp6m_ptr->u.ic.comm_queue[cmd_no].serv_id); - memcpy_toio(&dp6m_ptr->u.ic.gdt_dpr_cmd[dp_offset],cmd_ptr,cp_count); - } -} - - -static void gdth_release_event(gdth_ha_str *ha) -{ - TRACE(("gdth_release_event() hanum %d\n", ha->hanum)); - -#ifdef GDTH_STATISTICS - { - u32 i,j; - for (i=0,j=0; jcmd_tab[j].cmnd != UNUSED_CMND) - ++i; - } - if (max_index < i) { - max_index = i; - TRACE3(("GDT: max_index = %d\n",(u16)i)); - } - } -#endif - - if (ha->pccb->OpCode == GDT_INIT) - ha->pccb->Service |= 0x80; - - if (ha->type == GDT_PCI) { - writeb(0, &((gdt6_dpram_str __iomem *)ha->brd)->io.event); - } else if (ha->type == GDT_PCINEW) { - outb(1, PTR2USHORT(&ha->plx->ldoor_reg)); - } else if (ha->type == GDT_PCIMPR) { - writeb(1, &((gdt6m_dpram_str __iomem *)ha->brd)->i960r.ldoor_reg); - } -} - -static int gdth_wait(gdth_ha_str *ha, int index, u32 time) -{ - int answer_found = FALSE; - int wait_index = 0; - - TRACE(("gdth_wait() hanum %d index %d time %d\n", ha->hanum, index, time)); - - if (index == 0) - return 1; /* no wait required */ - - do { - __gdth_interrupt(ha, true, &wait_index); - if (wait_index == index) { - answer_found = TRUE; - break; - } - gdth_delay(1); - } while (--time); - - while (gdth_test_busy(ha)) - gdth_delay(0); - - return (answer_found); -} - - -static int gdth_internal_cmd(gdth_ha_str *ha, u8 service, u16 opcode, - u32 p1, u64 p2, u64 p3) -{ - register gdth_cmd_str *cmd_ptr; - int retries,index; - - TRACE2(("gdth_internal_cmd() service %d opcode %d\n",service,opcode)); - - cmd_ptr = ha->pccb; - memset((char*)cmd_ptr,0,sizeof(gdth_cmd_str)); - - /* make command */ - for (retries = INIT_RETRIES;;) { - cmd_ptr->Service = service; - cmd_ptr->RequestBuffer = INTERNAL_CMND; - if (!(index=gdth_get_cmd_index(ha))) { - TRACE(("GDT: No free command index found\n")); - return 0; - } - gdth_set_sema0(ha); - cmd_ptr->OpCode = opcode; - cmd_ptr->BoardNode = LOCALBOARD; - if (service == CACHESERVICE) { - if (opcode == GDT_IOCTL) { - cmd_ptr->u.ioctl.subfunc = p1; - cmd_ptr->u.ioctl.channel = (u32)p2; - cmd_ptr->u.ioctl.param_size = (u16)p3; - cmd_ptr->u.ioctl.p_param = ha->scratch_phys; - } else { - if (ha->cache_feat & GDT_64BIT) { - cmd_ptr->u.cache64.DeviceNo = (u16)p1; - cmd_ptr->u.cache64.BlockNo = p2; - } else { - cmd_ptr->u.cache.DeviceNo = (u16)p1; - cmd_ptr->u.cache.BlockNo = (u32)p2; - } - } - } else if (service == SCSIRAWSERVICE) { - if (ha->raw_feat & GDT_64BIT) { - cmd_ptr->u.raw64.direction = p1; - cmd_ptr->u.raw64.bus = (u8)p2; - cmd_ptr->u.raw64.target = (u8)p3; - cmd_ptr->u.raw64.lun = (u8)(p3 >> 8); - } else { - cmd_ptr->u.raw.direction = p1; - cmd_ptr->u.raw.bus = (u8)p2; - cmd_ptr->u.raw.target = (u8)p3; - cmd_ptr->u.raw.lun = (u8)(p3 >> 8); - } - } else if (service == SCREENSERVICE) { - if (opcode == GDT_REALTIME) { - *(u32 *)&cmd_ptr->u.screen.su.data[0] = p1; - *(u32 *)&cmd_ptr->u.screen.su.data[4] = (u32)p2; - *(u32 *)&cmd_ptr->u.screen.su.data[8] = (u32)p3; - } - } - ha->cmd_len = sizeof(gdth_cmd_str); - ha->cmd_offs_dpmem = 0; - ha->cmd_cnt = 0; - gdth_copy_command(ha); - gdth_release_event(ha); - gdth_delay(20); - if (!gdth_wait(ha, index, INIT_TIMEOUT)) { - printk("GDT: Initialization error (timeout service %d)\n",service); - return 0; - } - if (ha->status != S_BSY || --retries == 0) - break; - gdth_delay(1); - } - - return (ha->status != S_OK ? 0:1); -} - - -/* search for devices */ - -static int gdth_search_drives(gdth_ha_str *ha) -{ - u16 cdev_cnt, i; - int ok; - u32 bus_no, drv_cnt, drv_no, j; - gdth_getch_str *chn; - gdth_drlist_str *drl; - gdth_iochan_str *ioc; - gdth_raw_iochan_str *iocr; - gdth_arcdl_str *alst; - gdth_alist_str *alst2; - gdth_oem_str_ioctl *oemstr; - - TRACE(("gdth_search_drives() hanum %d\n", ha->hanum)); - ok = 0; - - /* initialize controller services, at first: screen service */ - ha->screen_feat = 0; - if (!force_dma32) { - ok = gdth_internal_cmd(ha, SCREENSERVICE, GDT_X_INIT_SCR, 0, 0, 0); - if (ok) - ha->screen_feat = GDT_64BIT; - } - if (force_dma32 || (!ok && ha->status == (u16)S_NOFUNC)) - ok = gdth_internal_cmd(ha, SCREENSERVICE, GDT_INIT, 0, 0, 0); - if (!ok) { - printk("GDT-HA %d: Initialization error screen service (code %d)\n", - ha->hanum, ha->status); - return 0; - } - TRACE2(("gdth_search_drives(): SCREENSERVICE initialized\n")); - - /* unfreeze all IOs */ - gdth_internal_cmd(ha, CACHESERVICE, GDT_UNFREEZE_IO, 0, 0, 0); - - /* initialize cache service */ - ha->cache_feat = 0; - if (!force_dma32) { - ok = gdth_internal_cmd(ha, CACHESERVICE, GDT_X_INIT_HOST, LINUX_OS, - 0, 0); - if (ok) - ha->cache_feat = GDT_64BIT; - } - if (force_dma32 || (!ok && ha->status == (u16)S_NOFUNC)) - ok = gdth_internal_cmd(ha, CACHESERVICE, GDT_INIT, LINUX_OS, 0, 0); - if (!ok) { - printk("GDT-HA %d: Initialization error cache service (code %d)\n", - ha->hanum, ha->status); - return 0; - } - TRACE2(("gdth_search_drives(): CACHESERVICE initialized\n")); - cdev_cnt = (u16)ha->info; - ha->fw_vers = ha->service; - - /* detect number of buses - try new IOCTL */ - iocr = (gdth_raw_iochan_str *)ha->pscratch; - iocr->hdr.version = 0xffffffff; - iocr->hdr.list_entries = MAXBUS; - iocr->hdr.first_chan = 0; - iocr->hdr.last_chan = MAXBUS-1; - iocr->hdr.list_offset = GDTOFFSOF(gdth_raw_iochan_str, list[0]); - if (gdth_internal_cmd(ha, CACHESERVICE, GDT_IOCTL, IOCHAN_RAW_DESC, - INVALID_CHANNEL,sizeof(gdth_raw_iochan_str))) { - TRACE2(("IOCHAN_RAW_DESC supported!\n")); - ha->bus_cnt = iocr->hdr.chan_count; - for (bus_no = 0; bus_no < ha->bus_cnt; ++bus_no) { - if (iocr->list[bus_no].proc_id < MAXID) - ha->bus_id[bus_no] = iocr->list[bus_no].proc_id; - else - ha->bus_id[bus_no] = 0xff; - } - } else { - /* old method */ - chn = (gdth_getch_str *)ha->pscratch; - for (bus_no = 0; bus_no < MAXBUS; ++bus_no) { - chn->channel_no = bus_no; - if (!gdth_internal_cmd(ha, CACHESERVICE, GDT_IOCTL, - SCSI_CHAN_CNT | L_CTRL_PATTERN, - IO_CHANNEL | INVALID_CHANNEL, - sizeof(gdth_getch_str))) { - if (bus_no == 0) { - printk("GDT-HA %d: Error detecting channel count (0x%x)\n", - ha->hanum, ha->status); - return 0; - } - break; - } - if (chn->siop_id < MAXID) - ha->bus_id[bus_no] = chn->siop_id; - else - ha->bus_id[bus_no] = 0xff; - } - ha->bus_cnt = (u8)bus_no; - } - TRACE2(("gdth_search_drives() %d channels\n",ha->bus_cnt)); - - /* read cache configuration */ - if (!gdth_internal_cmd(ha, CACHESERVICE, GDT_IOCTL, CACHE_INFO, - INVALID_CHANNEL,sizeof(gdth_cinfo_str))) { - printk("GDT-HA %d: Initialization error cache service (code %d)\n", - ha->hanum, ha->status); - return 0; - } - ha->cpar = ((gdth_cinfo_str *)ha->pscratch)->cpar; - TRACE2(("gdth_search_drives() cinfo: vs %x sta %d str %d dw %d b %d\n", - ha->cpar.version,ha->cpar.state,ha->cpar.strategy, - ha->cpar.write_back,ha->cpar.block_size)); - - /* read board info and features */ - ha->more_proc = FALSE; - if (gdth_internal_cmd(ha, CACHESERVICE, GDT_IOCTL, BOARD_INFO, - INVALID_CHANNEL,sizeof(gdth_binfo_str))) { - memcpy(&ha->binfo, (gdth_binfo_str *)ha->pscratch, - sizeof(gdth_binfo_str)); - if (gdth_internal_cmd(ha, CACHESERVICE, GDT_IOCTL, BOARD_FEATURES, - INVALID_CHANNEL,sizeof(gdth_bfeat_str))) { - TRACE2(("BOARD_INFO/BOARD_FEATURES supported\n")); - ha->bfeat = *(gdth_bfeat_str *)ha->pscratch; - ha->more_proc = TRUE; - } - } else { - TRACE2(("BOARD_INFO requires firmware >= 1.10/2.08\n")); - strcpy(ha->binfo.type_string, gdth_ctr_name(ha)); - } - TRACE2(("Controller name: %s\n",ha->binfo.type_string)); - - /* read more informations */ - if (ha->more_proc) { - /* physical drives, channel addresses */ - ioc = (gdth_iochan_str *)ha->pscratch; - ioc->hdr.version = 0xffffffff; - ioc->hdr.list_entries = MAXBUS; - ioc->hdr.first_chan = 0; - ioc->hdr.last_chan = MAXBUS-1; - ioc->hdr.list_offset = GDTOFFSOF(gdth_iochan_str, list[0]); - if (gdth_internal_cmd(ha, CACHESERVICE, GDT_IOCTL, IOCHAN_DESC, - INVALID_CHANNEL,sizeof(gdth_iochan_str))) { - for (bus_no = 0; bus_no < ha->bus_cnt; ++bus_no) { - ha->raw[bus_no].address = ioc->list[bus_no].address; - ha->raw[bus_no].local_no = ioc->list[bus_no].local_no; - } - } else { - for (bus_no = 0; bus_no < ha->bus_cnt; ++bus_no) { - ha->raw[bus_no].address = IO_CHANNEL; - ha->raw[bus_no].local_no = bus_no; - } - } - for (bus_no = 0; bus_no < ha->bus_cnt; ++bus_no) { - chn = (gdth_getch_str *)ha->pscratch; - chn->channel_no = ha->raw[bus_no].local_no; - if (gdth_internal_cmd(ha, CACHESERVICE, GDT_IOCTL, - SCSI_CHAN_CNT | L_CTRL_PATTERN, - ha->raw[bus_no].address | INVALID_CHANNEL, - sizeof(gdth_getch_str))) { - ha->raw[bus_no].pdev_cnt = chn->drive_cnt; - TRACE2(("Channel %d: %d phys. drives\n", - bus_no,chn->drive_cnt)); - } - if (ha->raw[bus_no].pdev_cnt > 0) { - drl = (gdth_drlist_str *)ha->pscratch; - drl->sc_no = ha->raw[bus_no].local_no; - drl->sc_cnt = ha->raw[bus_no].pdev_cnt; - if (gdth_internal_cmd(ha, CACHESERVICE, GDT_IOCTL, - SCSI_DR_LIST | L_CTRL_PATTERN, - ha->raw[bus_no].address | INVALID_CHANNEL, - sizeof(gdth_drlist_str))) { - for (j = 0; j < ha->raw[bus_no].pdev_cnt; ++j) - ha->raw[bus_no].id_list[j] = drl->sc_list[j]; - } else { - ha->raw[bus_no].pdev_cnt = 0; - } - } - } - - /* logical drives */ - if (gdth_internal_cmd(ha, CACHESERVICE, GDT_IOCTL, CACHE_DRV_CNT, - INVALID_CHANNEL,sizeof(u32))) { - drv_cnt = *(u32 *)ha->pscratch; - if (gdth_internal_cmd(ha, CACHESERVICE, GDT_IOCTL, CACHE_DRV_LIST, - INVALID_CHANNEL,drv_cnt * sizeof(u32))) { - for (j = 0; j < drv_cnt; ++j) { - drv_no = ((u32 *)ha->pscratch)[j]; - if (drv_no < MAX_LDRIVES) { - ha->hdr[drv_no].is_logdrv = TRUE; - TRACE2(("Drive %d is log. drive\n",drv_no)); - } - } - } - alst = (gdth_arcdl_str *)ha->pscratch; - alst->entries_avail = MAX_LDRIVES; - alst->first_entry = 0; - alst->list_offset = GDTOFFSOF(gdth_arcdl_str, list[0]); - if (gdth_internal_cmd(ha, CACHESERVICE, GDT_IOCTL, - ARRAY_DRV_LIST2 | LA_CTRL_PATTERN, - INVALID_CHANNEL, sizeof(gdth_arcdl_str) + - (alst->entries_avail-1) * sizeof(gdth_alist_str))) { - for (j = 0; j < alst->entries_init; ++j) { - ha->hdr[j].is_arraydrv = alst->list[j].is_arrayd; - ha->hdr[j].is_master = alst->list[j].is_master; - ha->hdr[j].is_parity = alst->list[j].is_parity; - ha->hdr[j].is_hotfix = alst->list[j].is_hotfix; - ha->hdr[j].master_no = alst->list[j].cd_handle; - } - } else if (gdth_internal_cmd(ha, CACHESERVICE, GDT_IOCTL, - ARRAY_DRV_LIST | LA_CTRL_PATTERN, - 0, 35 * sizeof(gdth_alist_str))) { - for (j = 0; j < 35; ++j) { - alst2 = &((gdth_alist_str *)ha->pscratch)[j]; - ha->hdr[j].is_arraydrv = alst2->is_arrayd; - ha->hdr[j].is_master = alst2->is_master; - ha->hdr[j].is_parity = alst2->is_parity; - ha->hdr[j].is_hotfix = alst2->is_hotfix; - ha->hdr[j].master_no = alst2->cd_handle; - } - } - } - } - - /* initialize raw service */ - ha->raw_feat = 0; - if (!force_dma32) { - ok = gdth_internal_cmd(ha, SCSIRAWSERVICE, GDT_X_INIT_RAW, 0, 0, 0); - if (ok) - ha->raw_feat = GDT_64BIT; - } - if (force_dma32 || (!ok && ha->status == (u16)S_NOFUNC)) - ok = gdth_internal_cmd(ha, SCSIRAWSERVICE, GDT_INIT, 0, 0, 0); - if (!ok) { - printk("GDT-HA %d: Initialization error raw service (code %d)\n", - ha->hanum, ha->status); - return 0; - } - TRACE2(("gdth_search_drives(): RAWSERVICE initialized\n")); - - /* set/get features raw service (scatter/gather) */ - if (gdth_internal_cmd(ha, SCSIRAWSERVICE, GDT_SET_FEAT, SCATTER_GATHER, - 0, 0)) { - TRACE2(("gdth_search_drives(): set features RAWSERVICE OK\n")); - if (gdth_internal_cmd(ha, SCSIRAWSERVICE, GDT_GET_FEAT, 0, 0, 0)) { - TRACE2(("gdth_search_dr(): get feat RAWSERVICE %d\n", - ha->info)); - ha->raw_feat |= (u16)ha->info; - } - } - - /* set/get features cache service (equal to raw service) */ - if (gdth_internal_cmd(ha, CACHESERVICE, GDT_SET_FEAT, 0, - SCATTER_GATHER,0)) { - TRACE2(("gdth_search_drives(): set features CACHESERVICE OK\n")); - if (gdth_internal_cmd(ha, CACHESERVICE, GDT_GET_FEAT, 0, 0, 0)) { - TRACE2(("gdth_search_dr(): get feat CACHESERV. %d\n", - ha->info)); - ha->cache_feat |= (u16)ha->info; - } - } - - /* reserve drives for raw service */ - if (reserve_mode != 0) { - gdth_internal_cmd(ha, SCSIRAWSERVICE, GDT_RESERVE_ALL, - reserve_mode == 1 ? 1 : 3, 0, 0); - TRACE2(("gdth_search_drives(): RESERVE_ALL code %d\n", - ha->status)); - } - for (i = 0; i < MAX_RES_ARGS; i += 4) { - if (reserve_list[i] == ha->hanum && reserve_list[i+1] < ha->bus_cnt && - reserve_list[i+2] < ha->tid_cnt && reserve_list[i+3] < MAXLUN) { - TRACE2(("gdth_search_drives(): reserve ha %d bus %d id %d lun %d\n", - reserve_list[i], reserve_list[i+1], - reserve_list[i+2], reserve_list[i+3])); - if (!gdth_internal_cmd(ha, SCSIRAWSERVICE, GDT_RESERVE, 0, - reserve_list[i+1], reserve_list[i+2] | - (reserve_list[i+3] << 8))) { - printk("GDT-HA %d: Error raw service (RESERVE, code %d)\n", - ha->hanum, ha->status); - } - } - } - - /* Determine OEM string using IOCTL */ - oemstr = (gdth_oem_str_ioctl *)ha->pscratch; - oemstr->params.ctl_version = 0x01; - oemstr->params.buffer_size = sizeof(oemstr->text); - if (gdth_internal_cmd(ha, CACHESERVICE, GDT_IOCTL, - CACHE_READ_OEM_STRING_RECORD,INVALID_CHANNEL, - sizeof(gdth_oem_str_ioctl))) { - TRACE2(("gdth_search_drives(): CACHE_READ_OEM_STRING_RECORD OK\n")); - printk("GDT-HA %d: Vendor: %s Name: %s\n", - ha->hanum, oemstr->text.oem_company_name, ha->binfo.type_string); - /* Save the Host Drive inquiry data */ - strlcpy(ha->oem_name,oemstr->text.scsi_host_drive_inquiry_vendor_id, - sizeof(ha->oem_name)); - } else { - /* Old method, based on PCI ID */ - TRACE2(("gdth_search_drives(): CACHE_READ_OEM_STRING_RECORD failed\n")); - printk("GDT-HA %d: Name: %s\n", - ha->hanum, ha->binfo.type_string); - if (ha->oem_id == OEM_ID_INTEL) - strlcpy(ha->oem_name,"Intel ", sizeof(ha->oem_name)); - else - strlcpy(ha->oem_name,"ICP ", sizeof(ha->oem_name)); - } - - /* scanning for host drives */ - for (i = 0; i < cdev_cnt; ++i) - gdth_analyse_hdrive(ha, i); - - TRACE(("gdth_search_drives() OK\n")); - return 1; -} - -static int gdth_analyse_hdrive(gdth_ha_str *ha, u16 hdrive) -{ - u32 drv_cyls; - int drv_hds, drv_secs; - - TRACE(("gdth_analyse_hdrive() hanum %d drive %d\n", ha->hanum, hdrive)); - if (hdrive >= MAX_HDRIVES) - return 0; - - if (!gdth_internal_cmd(ha, CACHESERVICE, GDT_INFO, hdrive, 0, 0)) - return 0; - ha->hdr[hdrive].present = TRUE; - ha->hdr[hdrive].size = ha->info; - - /* evaluate mapping (sectors per head, heads per cylinder) */ - ha->hdr[hdrive].size &= ~SECS32; - if (ha->info2 == 0) { - gdth_eval_mapping(ha->hdr[hdrive].size,&drv_cyls,&drv_hds,&drv_secs); - } else { - drv_hds = ha->info2 & 0xff; - drv_secs = (ha->info2 >> 8) & 0xff; - drv_cyls = (u32)ha->hdr[hdrive].size / drv_hds / drv_secs; - } - ha->hdr[hdrive].heads = (u8)drv_hds; - ha->hdr[hdrive].secs = (u8)drv_secs; - /* round size */ - ha->hdr[hdrive].size = drv_cyls * drv_hds * drv_secs; - - if (ha->cache_feat & GDT_64BIT) { - if (gdth_internal_cmd(ha, CACHESERVICE, GDT_X_INFO, hdrive, 0, 0) - && ha->info2 != 0) { - ha->hdr[hdrive].size = ((u64)ha->info2 << 32) | ha->info; - } - } - TRACE2(("gdth_search_dr() cdr. %d size %d hds %d scs %d\n", - hdrive,ha->hdr[hdrive].size,drv_hds,drv_secs)); - - /* get informations about device */ - if (gdth_internal_cmd(ha, CACHESERVICE, GDT_DEVTYPE, hdrive, 0, 0)) { - TRACE2(("gdth_search_dr() cache drive %d devtype %d\n", - hdrive,ha->info)); - ha->hdr[hdrive].devtype = (u16)ha->info; - } - - /* cluster info */ - if (gdth_internal_cmd(ha, CACHESERVICE, GDT_CLUST_INFO, hdrive, 0, 0)) { - TRACE2(("gdth_search_dr() cache drive %d cluster info %d\n", - hdrive,ha->info)); - if (!shared_access) - ha->hdr[hdrive].cluster_type = (u8)ha->info; - } - - /* R/W attributes */ - if (gdth_internal_cmd(ha, CACHESERVICE, GDT_RW_ATTRIBS, hdrive, 0, 0)) { - TRACE2(("gdth_search_dr() cache drive %d r/w attrib. %d\n", - hdrive,ha->info)); - ha->hdr[hdrive].rw_attribs = (u8)ha->info; - } - - return 1; -} - - -/* command queueing/sending functions */ - -static void gdth_putq(gdth_ha_str *ha, struct scsi_cmnd *scp, u8 priority) -{ - struct gdth_cmndinfo *cmndinfo = gdth_cmnd_priv(scp); - register struct scsi_cmnd *pscp; - register struct scsi_cmnd *nscp; - unsigned long flags; - - TRACE(("gdth_putq() priority %d\n",priority)); - spin_lock_irqsave(&ha->smp_lock, flags); - - if (!cmndinfo->internal_command) - cmndinfo->priority = priority; - - if (ha->req_first==NULL) { - ha->req_first = scp; /* queue was empty */ - scp->SCp.ptr = NULL; - } else { /* queue not empty */ - pscp = ha->req_first; - nscp = (struct scsi_cmnd *)pscp->SCp.ptr; - /* priority: 0-highest,..,0xff-lowest */ - while (nscp && gdth_cmnd_priv(nscp)->priority <= priority) { - pscp = nscp; - nscp = (struct scsi_cmnd *)pscp->SCp.ptr; - } - pscp->SCp.ptr = (char *)scp; - scp->SCp.ptr = (char *)nscp; - } - spin_unlock_irqrestore(&ha->smp_lock, flags); - -#ifdef GDTH_STATISTICS - flags = 0; - for (nscp=ha->req_first; nscp; nscp=(struct scsi_cmnd*)nscp->SCp.ptr) - ++flags; - if (max_rq < flags) { - max_rq = flags; - TRACE3(("GDT: max_rq = %d\n",(u16)max_rq)); - } -#endif -} - -static void gdth_next(gdth_ha_str *ha) -{ - register struct scsi_cmnd *pscp; - register struct scsi_cmnd *nscp; - u8 b, t, l, firsttime; - u8 this_cmd, next_cmd; - unsigned long flags = 0; - int cmd_index; - - TRACE(("gdth_next() hanum %d\n", ha->hanum)); - if (!gdth_polling) - spin_lock_irqsave(&ha->smp_lock, flags); - - ha->cmd_cnt = ha->cmd_offs_dpmem = 0; - this_cmd = firsttime = TRUE; - next_cmd = gdth_polling ? FALSE:TRUE; - cmd_index = 0; - - for (nscp = pscp = ha->req_first; nscp; nscp = (struct scsi_cmnd *)nscp->SCp.ptr) { - struct gdth_cmndinfo *nscp_cmndinfo = gdth_cmnd_priv(nscp); - if (nscp != pscp && nscp != (struct scsi_cmnd *)pscp->SCp.ptr) - pscp = (struct scsi_cmnd *)pscp->SCp.ptr; - if (!nscp_cmndinfo->internal_command) { - b = nscp->device->channel; - t = nscp->device->id; - l = nscp->device->lun; - if (nscp_cmndinfo->priority >= DEFAULT_PRI) { - if ((b != ha->virt_bus && ha->raw[BUS_L2P(ha,b)].lock) || - (b == ha->virt_bus && t < MAX_HDRIVES && ha->hdr[t].lock)) - continue; - } - } else - b = t = l = 0; - - if (firsttime) { - if (gdth_test_busy(ha)) { /* controller busy ? */ - TRACE(("gdth_next() controller %d busy !\n", ha->hanum)); - if (!gdth_polling) { - spin_unlock_irqrestore(&ha->smp_lock, flags); - return; - } - while (gdth_test_busy(ha)) - gdth_delay(1); - } - firsttime = FALSE; - } - - if (!nscp_cmndinfo->internal_command) { - if (nscp_cmndinfo->phase == -1) { - nscp_cmndinfo->phase = CACHESERVICE; /* default: cache svc. */ - if (nscp->cmnd[0] == TEST_UNIT_READY) { - TRACE2(("TEST_UNIT_READY Bus %d Id %d LUN %d\n", - b, t, l)); - /* TEST_UNIT_READY -> set scan mode */ - if ((ha->scan_mode & 0x0f) == 0) { - if (b == 0 && t == 0 && l == 0) { - ha->scan_mode |= 1; - TRACE2(("Scan mode: 0x%x\n", ha->scan_mode)); - } - } else if ((ha->scan_mode & 0x0f) == 1) { - if (b == 0 && ((t == 0 && l == 1) || - (t == 1 && l == 0))) { - nscp_cmndinfo->OpCode = GDT_SCAN_START; - nscp_cmndinfo->phase = ((ha->scan_mode & 0x10 ? 1:0) << 8) - | SCSIRAWSERVICE; - ha->scan_mode = 0x12; - TRACE2(("Scan mode: 0x%x (SCAN_START)\n", - ha->scan_mode)); - } else { - ha->scan_mode &= 0x10; - TRACE2(("Scan mode: 0x%x\n", ha->scan_mode)); - } - } else if (ha->scan_mode == 0x12) { - if (b == ha->bus_cnt && t == ha->tid_cnt-1) { - nscp_cmndinfo->phase = SCSIRAWSERVICE; - nscp_cmndinfo->OpCode = GDT_SCAN_END; - ha->scan_mode &= 0x10; - TRACE2(("Scan mode: 0x%x (SCAN_END)\n", - ha->scan_mode)); - } - } - } - if (b == ha->virt_bus && nscp->cmnd[0] != INQUIRY && - nscp->cmnd[0] != READ_CAPACITY && nscp->cmnd[0] != MODE_SENSE && - (ha->hdr[t].cluster_type & CLUSTER_DRIVE)) { - /* always GDT_CLUST_INFO! */ - nscp_cmndinfo->OpCode = GDT_CLUST_INFO; - } - } - } - - if (nscp_cmndinfo->OpCode != -1) { - if ((nscp_cmndinfo->phase & 0xff) == CACHESERVICE) { - if (!(cmd_index=gdth_fill_cache_cmd(ha, nscp, t))) - this_cmd = FALSE; - next_cmd = FALSE; - } else if ((nscp_cmndinfo->phase & 0xff) == SCSIRAWSERVICE) { - if (!(cmd_index=gdth_fill_raw_cmd(ha, nscp, BUS_L2P(ha, b)))) - this_cmd = FALSE; - next_cmd = FALSE; - } else { - memset((char*)nscp->sense_buffer,0,16); - nscp->sense_buffer[0] = 0x70; - nscp->sense_buffer[2] = NOT_READY; - nscp->result = (DID_OK << 16) | (CHECK_CONDITION << 1); - if (!nscp_cmndinfo->wait_for_completion) - nscp_cmndinfo->wait_for_completion++; - else - gdth_scsi_done(nscp); - } - } else if (gdth_cmnd_priv(nscp)->internal_command) { - if (!(cmd_index=gdth_special_cmd(ha, nscp))) - this_cmd = FALSE; - next_cmd = FALSE; - } else if (b != ha->virt_bus) { - if (ha->raw[BUS_L2P(ha,b)].io_cnt[t] >= GDTH_MAX_RAW || - !(cmd_index=gdth_fill_raw_cmd(ha, nscp, BUS_L2P(ha, b)))) - this_cmd = FALSE; - else - ha->raw[BUS_L2P(ha,b)].io_cnt[t]++; - } else if (t >= MAX_HDRIVES || !ha->hdr[t].present || l != 0) { - TRACE2(("Command 0x%x to bus %d id %d lun %d -> IGNORE\n", - nscp->cmnd[0], b, t, l)); - nscp->result = DID_BAD_TARGET << 16; - if (!nscp_cmndinfo->wait_for_completion) - nscp_cmndinfo->wait_for_completion++; - else - gdth_scsi_done(nscp); - } else { - switch (nscp->cmnd[0]) { - case TEST_UNIT_READY: - case INQUIRY: - case REQUEST_SENSE: - case READ_CAPACITY: - case VERIFY: - case START_STOP: - case MODE_SENSE: - case SERVICE_ACTION_IN_16: - TRACE(("cache cmd %x/%x/%x/%x/%x/%x\n",nscp->cmnd[0], - nscp->cmnd[1],nscp->cmnd[2],nscp->cmnd[3], - nscp->cmnd[4],nscp->cmnd[5])); - if (ha->hdr[t].media_changed && nscp->cmnd[0] != INQUIRY) { - /* return UNIT_ATTENTION */ - TRACE2(("cmd 0x%x target %d: UNIT_ATTENTION\n", - nscp->cmnd[0], t)); - ha->hdr[t].media_changed = FALSE; - memset((char*)nscp->sense_buffer,0,16); - nscp->sense_buffer[0] = 0x70; - nscp->sense_buffer[2] = UNIT_ATTENTION; - nscp->result = (DID_OK << 16) | (CHECK_CONDITION << 1); - if (!nscp_cmndinfo->wait_for_completion) - nscp_cmndinfo->wait_for_completion++; - else - gdth_scsi_done(nscp); - } else if (gdth_internal_cache_cmd(ha, nscp)) - gdth_scsi_done(nscp); - break; - - case ALLOW_MEDIUM_REMOVAL: - TRACE(("cache cmd %x/%x/%x/%x/%x/%x\n",nscp->cmnd[0], - nscp->cmnd[1],nscp->cmnd[2],nscp->cmnd[3], - nscp->cmnd[4],nscp->cmnd[5])); - if ( (nscp->cmnd[4]&1) && !(ha->hdr[t].devtype&1) ) { - TRACE(("Prevent r. nonremov. drive->do nothing\n")); - nscp->result = DID_OK << 16; - nscp->sense_buffer[0] = 0; - if (!nscp_cmndinfo->wait_for_completion) - nscp_cmndinfo->wait_for_completion++; - else - gdth_scsi_done(nscp); - } else { - nscp->cmnd[3] = (ha->hdr[t].devtype&1) ? 1:0; - TRACE(("Prevent/allow r. %d rem. drive %d\n", - nscp->cmnd[4],nscp->cmnd[3])); - if (!(cmd_index=gdth_fill_cache_cmd(ha, nscp, t))) - this_cmd = FALSE; - } - break; - - case RESERVE: - case RELEASE: - TRACE2(("cache cmd %s\n",nscp->cmnd[0] == RESERVE ? - "RESERVE" : "RELEASE")); - if (!(cmd_index=gdth_fill_cache_cmd(ha, nscp, t))) - this_cmd = FALSE; - break; - - case READ_6: - case WRITE_6: - case READ_10: - case WRITE_10: - case READ_16: - case WRITE_16: - if (ha->hdr[t].media_changed) { - /* return UNIT_ATTENTION */ - TRACE2(("cmd 0x%x target %d: UNIT_ATTENTION\n", - nscp->cmnd[0], t)); - ha->hdr[t].media_changed = FALSE; - memset((char*)nscp->sense_buffer,0,16); - nscp->sense_buffer[0] = 0x70; - nscp->sense_buffer[2] = UNIT_ATTENTION; - nscp->result = (DID_OK << 16) | (CHECK_CONDITION << 1); - if (!nscp_cmndinfo->wait_for_completion) - nscp_cmndinfo->wait_for_completion++; - else - gdth_scsi_done(nscp); - } else if (!(cmd_index=gdth_fill_cache_cmd(ha, nscp, t))) - this_cmd = FALSE; - break; - - default: - TRACE2(("cache cmd %x/%x/%x/%x/%x/%x unknown\n",nscp->cmnd[0], - nscp->cmnd[1],nscp->cmnd[2],nscp->cmnd[3], - nscp->cmnd[4],nscp->cmnd[5])); - printk("GDT-HA %d: Unknown SCSI command 0x%x to cache service !\n", - ha->hanum, nscp->cmnd[0]); - nscp->result = DID_ABORT << 16; - if (!nscp_cmndinfo->wait_for_completion) - nscp_cmndinfo->wait_for_completion++; - else - gdth_scsi_done(nscp); - break; - } - } - - if (!this_cmd) - break; - if (nscp == ha->req_first) - ha->req_first = pscp = (struct scsi_cmnd *)nscp->SCp.ptr; - else - pscp->SCp.ptr = nscp->SCp.ptr; - if (!next_cmd) - break; - } - - if (ha->cmd_cnt > 0) { - gdth_release_event(ha); - } - - if (!gdth_polling) - spin_unlock_irqrestore(&ha->smp_lock, flags); - - if (gdth_polling && ha->cmd_cnt > 0) { - if (!gdth_wait(ha, cmd_index, POLL_TIMEOUT)) - printk("GDT-HA %d: Command %d timed out !\n", - ha->hanum, cmd_index); - } -} - -/* - * gdth_copy_internal_data() - copy to/from a buffer onto a scsi_cmnd's - * buffers, kmap_atomic() as needed. - */ -static void gdth_copy_internal_data(gdth_ha_str *ha, struct scsi_cmnd *scp, - char *buffer, u16 count) -{ - u16 cpcount,i, max_sg = scsi_sg_count(scp); - u16 cpsum,cpnow; - struct scatterlist *sl; - char *address; - - cpcount = min_t(u16, count, scsi_bufflen(scp)); - - if (cpcount) { - cpsum=0; - scsi_for_each_sg(scp, sl, max_sg, i) { - unsigned long flags; - cpnow = (u16)sl->length; - TRACE(("copy_internal() now %d sum %d count %d %d\n", - cpnow, cpsum, cpcount, scsi_bufflen(scp))); - if (cpsum+cpnow > cpcount) - cpnow = cpcount - cpsum; - cpsum += cpnow; - if (!sg_page(sl)) { - printk("GDT-HA %d: invalid sc/gt element in gdth_copy_internal_data()\n", - ha->hanum); - return; - } - local_irq_save(flags); - address = kmap_atomic(sg_page(sl)) + sl->offset; - memcpy(address, buffer, cpnow); - flush_dcache_page(sg_page(sl)); - kunmap_atomic(address); - local_irq_restore(flags); - if (cpsum == cpcount) - break; - buffer += cpnow; - } - } else if (count) { - printk("GDT-HA %d: SCSI command with no buffers but data transfer expected!\n", - ha->hanum); - WARN_ON(1); - } -} - -static int gdth_internal_cache_cmd(gdth_ha_str *ha, struct scsi_cmnd *scp) -{ - u8 t; - gdth_inq_data inq; - gdth_rdcap_data rdc; - gdth_sense_data sd; - gdth_modep_data mpd; - struct gdth_cmndinfo *cmndinfo = gdth_cmnd_priv(scp); - - t = scp->device->id; - TRACE(("gdth_internal_cache_cmd() cmd 0x%x hdrive %d\n", - scp->cmnd[0],t)); - - scp->result = DID_OK << 16; - scp->sense_buffer[0] = 0; - - switch (scp->cmnd[0]) { - case TEST_UNIT_READY: - case VERIFY: - case START_STOP: - TRACE2(("Test/Verify/Start hdrive %d\n",t)); - break; - - case INQUIRY: - TRACE2(("Inquiry hdrive %d devtype %d\n", - t,ha->hdr[t].devtype)); - inq.type_qual = (ha->hdr[t].devtype&4) ? TYPE_ROM:TYPE_DISK; - /* you can here set all disks to removable, if you want to do - a flush using the ALLOW_MEDIUM_REMOVAL command */ - inq.modif_rmb = 0x00; - if ((ha->hdr[t].devtype & 1) || - (ha->hdr[t].cluster_type & CLUSTER_DRIVE)) - inq.modif_rmb = 0x80; - inq.version = 2; - inq.resp_aenc = 2; - inq.add_length= 32; - strcpy(inq.vendor,ha->oem_name); - snprintf(inq.product, sizeof(inq.product), "Host Drive #%02d",t); - strcpy(inq.revision," "); - gdth_copy_internal_data(ha, scp, (char*)&inq, sizeof(gdth_inq_data)); - break; - - case REQUEST_SENSE: - TRACE2(("Request sense hdrive %d\n",t)); - sd.errorcode = 0x70; - sd.segno = 0x00; - sd.key = NO_SENSE; - sd.info = 0; - sd.add_length= 0; - gdth_copy_internal_data(ha, scp, (char*)&sd, sizeof(gdth_sense_data)); - break; - - case MODE_SENSE: - TRACE2(("Mode sense hdrive %d\n",t)); - memset((char*)&mpd,0,sizeof(gdth_modep_data)); - mpd.hd.data_length = sizeof(gdth_modep_data); - mpd.hd.dev_par = (ha->hdr[t].devtype&2) ? 0x80:0; - mpd.hd.bd_length = sizeof(mpd.bd); - mpd.bd.block_length[0] = (SECTOR_SIZE & 0x00ff0000) >> 16; - mpd.bd.block_length[1] = (SECTOR_SIZE & 0x0000ff00) >> 8; - mpd.bd.block_length[2] = (SECTOR_SIZE & 0x000000ff); - gdth_copy_internal_data(ha, scp, (char*)&mpd, sizeof(gdth_modep_data)); - break; - - case READ_CAPACITY: - TRACE2(("Read capacity hdrive %d\n",t)); - if (ha->hdr[t].size > (u64)0xffffffff) - rdc.last_block_no = 0xffffffff; - else - rdc.last_block_no = cpu_to_be32(ha->hdr[t].size-1); - rdc.block_length = cpu_to_be32(SECTOR_SIZE); - gdth_copy_internal_data(ha, scp, (char*)&rdc, sizeof(gdth_rdcap_data)); - break; - - case SERVICE_ACTION_IN_16: - if ((scp->cmnd[1] & 0x1f) == SAI_READ_CAPACITY_16 && - (ha->cache_feat & GDT_64BIT)) { - gdth_rdcap16_data rdc16; - - TRACE2(("Read capacity (16) hdrive %d\n",t)); - rdc16.last_block_no = cpu_to_be64(ha->hdr[t].size-1); - rdc16.block_length = cpu_to_be32(SECTOR_SIZE); - gdth_copy_internal_data(ha, scp, (char*)&rdc16, - sizeof(gdth_rdcap16_data)); - } else { - scp->result = DID_ABORT << 16; - } - break; - - default: - TRACE2(("Internal cache cmd 0x%x unknown\n",scp->cmnd[0])); - break; - } - - if (!cmndinfo->wait_for_completion) - cmndinfo->wait_for_completion++; - else - return 1; - - return 0; -} - -static int gdth_fill_cache_cmd(gdth_ha_str *ha, struct scsi_cmnd *scp, - u16 hdrive) -{ - register gdth_cmd_str *cmdp; - struct gdth_cmndinfo *cmndinfo = gdth_cmnd_priv(scp); - u32 cnt, blockcnt; - u64 no, blockno; - int i, cmd_index, read_write, sgcnt, mode64; - - cmdp = ha->pccb; - TRACE(("gdth_fill_cache_cmd() cmd 0x%x cmdsize %d hdrive %d\n", - scp->cmnd[0],scp->cmd_len,hdrive)); - - mode64 = (ha->cache_feat & GDT_64BIT) ? TRUE : FALSE; - /* test for READ_16, WRITE_16 if !mode64 ? --- - not required, should not occur due to error return on - READ_CAPACITY_16 */ - - cmdp->Service = CACHESERVICE; - cmdp->RequestBuffer = scp; - /* search free command index */ - if (!(cmd_index=gdth_get_cmd_index(ha))) { - TRACE(("GDT: No free command index found\n")); - return 0; - } - /* if it's the first command, set command semaphore */ - if (ha->cmd_cnt == 0) - gdth_set_sema0(ha); - - /* fill command */ - read_write = 0; - if (cmndinfo->OpCode != -1) - cmdp->OpCode = cmndinfo->OpCode; /* special cache cmd. */ - else if (scp->cmnd[0] == RESERVE) - cmdp->OpCode = GDT_RESERVE_DRV; - else if (scp->cmnd[0] == RELEASE) - cmdp->OpCode = GDT_RELEASE_DRV; - else if (scp->cmnd[0] == ALLOW_MEDIUM_REMOVAL) { - if (scp->cmnd[4] & 1) /* prevent ? */ - cmdp->OpCode = GDT_MOUNT; - else if (scp->cmnd[3] & 1) /* removable drive ? */ - cmdp->OpCode = GDT_UNMOUNT; - else - cmdp->OpCode = GDT_FLUSH; - } else if (scp->cmnd[0] == WRITE_6 || scp->cmnd[0] == WRITE_10 || - scp->cmnd[0] == WRITE_12 || scp->cmnd[0] == WRITE_16 - ) { - read_write = 1; - if (gdth_write_through || ((ha->hdr[hdrive].rw_attribs & 1) && - (ha->cache_feat & GDT_WR_THROUGH))) - cmdp->OpCode = GDT_WRITE_THR; - else - cmdp->OpCode = GDT_WRITE; - } else { - read_write = 2; - cmdp->OpCode = GDT_READ; - } - - cmdp->BoardNode = LOCALBOARD; - if (mode64) { - cmdp->u.cache64.DeviceNo = hdrive; - cmdp->u.cache64.BlockNo = 1; - cmdp->u.cache64.sg_canz = 0; - } else { - cmdp->u.cache.DeviceNo = hdrive; - cmdp->u.cache.BlockNo = 1; - cmdp->u.cache.sg_canz = 0; - } - - if (read_write) { - if (scp->cmd_len == 16) { - memcpy(&no, &scp->cmnd[2], sizeof(u64)); - blockno = be64_to_cpu(no); - memcpy(&cnt, &scp->cmnd[10], sizeof(u32)); - blockcnt = be32_to_cpu(cnt); - } else if (scp->cmd_len == 10) { - memcpy(&no, &scp->cmnd[2], sizeof(u32)); - blockno = be32_to_cpu(no); - memcpy(&cnt, &scp->cmnd[7], sizeof(u16)); - blockcnt = be16_to_cpu(cnt); - } else { - memcpy(&no, &scp->cmnd[0], sizeof(u32)); - blockno = be32_to_cpu(no) & 0x001fffffUL; - blockcnt= scp->cmnd[4]==0 ? 0x100 : scp->cmnd[4]; - } - if (mode64) { - cmdp->u.cache64.BlockNo = blockno; - cmdp->u.cache64.BlockCnt = blockcnt; - } else { - cmdp->u.cache.BlockNo = (u32)blockno; - cmdp->u.cache.BlockCnt = blockcnt; - } - - if (scsi_bufflen(scp)) { - cmndinfo->dma_dir = (read_write == 1 ? - DMA_TO_DEVICE : DMA_FROM_DEVICE); - sgcnt = dma_map_sg(&ha->pdev->dev, scsi_sglist(scp), - scsi_sg_count(scp), cmndinfo->dma_dir); - if (mode64) { - struct scatterlist *sl; - - cmdp->u.cache64.DestAddr= (u64)-1; - cmdp->u.cache64.sg_canz = sgcnt; - scsi_for_each_sg(scp, sl, sgcnt, i) { - cmdp->u.cache64.sg_lst[i].sg_ptr = sg_dma_address(sl); - cmdp->u.cache64.sg_lst[i].sg_len = sg_dma_len(sl); - } - } else { - struct scatterlist *sl; - - cmdp->u.cache.DestAddr= 0xffffffff; - cmdp->u.cache.sg_canz = sgcnt; - scsi_for_each_sg(scp, sl, sgcnt, i) { - cmdp->u.cache.sg_lst[i].sg_ptr = sg_dma_address(sl); - cmdp->u.cache.sg_lst[i].sg_len = sg_dma_len(sl); - } - } - -#ifdef GDTH_STATISTICS - if (max_sg < (u32)sgcnt) { - max_sg = (u32)sgcnt; - TRACE3(("GDT: max_sg = %d\n",max_sg)); - } -#endif - - } - } - /* evaluate command size, check space */ - if (mode64) { - TRACE(("cache cmd: addr. %x sganz %x sgptr0 %x sglen0 %x\n", - cmdp->u.cache64.DestAddr,cmdp->u.cache64.sg_canz, - cmdp->u.cache64.sg_lst[0].sg_ptr, - cmdp->u.cache64.sg_lst[0].sg_len)); - TRACE(("cache cmd: cmd %d blockno. %d, blockcnt %d\n", - cmdp->OpCode,cmdp->u.cache64.BlockNo,cmdp->u.cache64.BlockCnt)); - ha->cmd_len = GDTOFFSOF(gdth_cmd_str,u.cache64.sg_lst) + - (u16)cmdp->u.cache64.sg_canz * sizeof(gdth_sg64_str); - } else { - TRACE(("cache cmd: addr. %x sganz %x sgptr0 %x sglen0 %x\n", - cmdp->u.cache.DestAddr,cmdp->u.cache.sg_canz, - cmdp->u.cache.sg_lst[0].sg_ptr, - cmdp->u.cache.sg_lst[0].sg_len)); - TRACE(("cache cmd: cmd %d blockno. %d, blockcnt %d\n", - cmdp->OpCode,cmdp->u.cache.BlockNo,cmdp->u.cache.BlockCnt)); - ha->cmd_len = GDTOFFSOF(gdth_cmd_str,u.cache.sg_lst) + - (u16)cmdp->u.cache.sg_canz * sizeof(gdth_sg_str); - } - if (ha->cmd_len & 3) - ha->cmd_len += (4 - (ha->cmd_len & 3)); - - if (ha->cmd_cnt > 0) { - if ((ha->cmd_offs_dpmem + ha->cmd_len + DPMEM_COMMAND_OFFSET) > - ha->ic_all_size) { - TRACE2(("gdth_fill_cache() DPMEM overflow\n")); - ha->cmd_tab[cmd_index-2].cmnd = UNUSED_CMND; - return 0; - } - } - - /* copy command */ - gdth_copy_command(ha); - return cmd_index; -} - -static int gdth_fill_raw_cmd(gdth_ha_str *ha, struct scsi_cmnd *scp, u8 b) -{ - register gdth_cmd_str *cmdp; - u16 i; - dma_addr_t sense_paddr; - int cmd_index, sgcnt, mode64; - u8 t,l; - struct gdth_cmndinfo *cmndinfo; - - t = scp->device->id; - l = scp->device->lun; - cmdp = ha->pccb; - TRACE(("gdth_fill_raw_cmd() cmd 0x%x bus %d ID %d LUN %d\n", - scp->cmnd[0],b,t,l)); - - mode64 = (ha->raw_feat & GDT_64BIT) ? TRUE : FALSE; - - cmdp->Service = SCSIRAWSERVICE; - cmdp->RequestBuffer = scp; - /* search free command index */ - if (!(cmd_index=gdth_get_cmd_index(ha))) { - TRACE(("GDT: No free command index found\n")); - return 0; - } - /* if it's the first command, set command semaphore */ - if (ha->cmd_cnt == 0) - gdth_set_sema0(ha); - - cmndinfo = gdth_cmnd_priv(scp); - /* fill command */ - if (cmndinfo->OpCode != -1) { - cmdp->OpCode = cmndinfo->OpCode; /* special raw cmd. */ - cmdp->BoardNode = LOCALBOARD; - if (mode64) { - cmdp->u.raw64.direction = (cmndinfo->phase >> 8); - TRACE2(("special raw cmd 0x%x param 0x%x\n", - cmdp->OpCode, cmdp->u.raw64.direction)); - /* evaluate command size */ - ha->cmd_len = GDTOFFSOF(gdth_cmd_str,u.raw64.sg_lst); - } else { - cmdp->u.raw.direction = (cmndinfo->phase >> 8); - TRACE2(("special raw cmd 0x%x param 0x%x\n", - cmdp->OpCode, cmdp->u.raw.direction)); - /* evaluate command size */ - ha->cmd_len = GDTOFFSOF(gdth_cmd_str,u.raw.sg_lst); - } - - } else { - sense_paddr = dma_map_single(&ha->pdev->dev, scp->sense_buffer, 16, - DMA_FROM_DEVICE); - - cmndinfo->sense_paddr = sense_paddr; - cmdp->OpCode = GDT_WRITE; /* always */ - cmdp->BoardNode = LOCALBOARD; - if (mode64) { - cmdp->u.raw64.reserved = 0; - cmdp->u.raw64.mdisc_time = 0; - cmdp->u.raw64.mcon_time = 0; - cmdp->u.raw64.clen = scp->cmd_len; - cmdp->u.raw64.target = t; - cmdp->u.raw64.lun = l; - cmdp->u.raw64.bus = b; - cmdp->u.raw64.priority = 0; - cmdp->u.raw64.sdlen = scsi_bufflen(scp); - cmdp->u.raw64.sense_len = 16; - cmdp->u.raw64.sense_data = sense_paddr; - cmdp->u.raw64.direction = - gdth_direction_tab[scp->cmnd[0]]==DOU ? GDTH_DATA_OUT:GDTH_DATA_IN; - memcpy(cmdp->u.raw64.cmd,scp->cmnd,16); - cmdp->u.raw64.sg_ranz = 0; - } else { - cmdp->u.raw.reserved = 0; - cmdp->u.raw.mdisc_time = 0; - cmdp->u.raw.mcon_time = 0; - cmdp->u.raw.clen = scp->cmd_len; - cmdp->u.raw.target = t; - cmdp->u.raw.lun = l; - cmdp->u.raw.bus = b; - cmdp->u.raw.priority = 0; - cmdp->u.raw.link_p = 0; - cmdp->u.raw.sdlen = scsi_bufflen(scp); - cmdp->u.raw.sense_len = 16; - cmdp->u.raw.sense_data = sense_paddr; - cmdp->u.raw.direction = - gdth_direction_tab[scp->cmnd[0]]==DOU ? GDTH_DATA_OUT:GDTH_DATA_IN; - memcpy(cmdp->u.raw.cmd,scp->cmnd,12); - cmdp->u.raw.sg_ranz = 0; - } - - if (scsi_bufflen(scp)) { - cmndinfo->dma_dir = DMA_BIDIRECTIONAL; - sgcnt = dma_map_sg(&ha->pdev->dev, scsi_sglist(scp), - scsi_sg_count(scp), cmndinfo->dma_dir); - if (mode64) { - struct scatterlist *sl; - - cmdp->u.raw64.sdata = (u64)-1; - cmdp->u.raw64.sg_ranz = sgcnt; - scsi_for_each_sg(scp, sl, sgcnt, i) { - cmdp->u.raw64.sg_lst[i].sg_ptr = sg_dma_address(sl); - cmdp->u.raw64.sg_lst[i].sg_len = sg_dma_len(sl); - } - } else { - struct scatterlist *sl; - - cmdp->u.raw.sdata = 0xffffffff; - cmdp->u.raw.sg_ranz = sgcnt; - scsi_for_each_sg(scp, sl, sgcnt, i) { - cmdp->u.raw.sg_lst[i].sg_ptr = sg_dma_address(sl); - cmdp->u.raw.sg_lst[i].sg_len = sg_dma_len(sl); - } - } - -#ifdef GDTH_STATISTICS - if (max_sg < sgcnt) { - max_sg = sgcnt; - TRACE3(("GDT: max_sg = %d\n",sgcnt)); - } -#endif - - } - if (mode64) { - TRACE(("raw cmd: addr. %x sganz %x sgptr0 %x sglen0 %x\n", - cmdp->u.raw64.sdata,cmdp->u.raw64.sg_ranz, - cmdp->u.raw64.sg_lst[0].sg_ptr, - cmdp->u.raw64.sg_lst[0].sg_len)); - /* evaluate command size */ - ha->cmd_len = GDTOFFSOF(gdth_cmd_str,u.raw64.sg_lst) + - (u16)cmdp->u.raw64.sg_ranz * sizeof(gdth_sg64_str); - } else { - TRACE(("raw cmd: addr. %x sganz %x sgptr0 %x sglen0 %x\n", - cmdp->u.raw.sdata,cmdp->u.raw.sg_ranz, - cmdp->u.raw.sg_lst[0].sg_ptr, - cmdp->u.raw.sg_lst[0].sg_len)); - /* evaluate command size */ - ha->cmd_len = GDTOFFSOF(gdth_cmd_str,u.raw.sg_lst) + - (u16)cmdp->u.raw.sg_ranz * sizeof(gdth_sg_str); - } - } - /* check space */ - if (ha->cmd_len & 3) - ha->cmd_len += (4 - (ha->cmd_len & 3)); - - if (ha->cmd_cnt > 0) { - if ((ha->cmd_offs_dpmem + ha->cmd_len + DPMEM_COMMAND_OFFSET) > - ha->ic_all_size) { - TRACE2(("gdth_fill_raw() DPMEM overflow\n")); - ha->cmd_tab[cmd_index-2].cmnd = UNUSED_CMND; - return 0; - } - } - - /* copy command */ - gdth_copy_command(ha); - return cmd_index; -} - -static int gdth_special_cmd(gdth_ha_str *ha, struct scsi_cmnd *scp) -{ - register gdth_cmd_str *cmdp; - struct gdth_cmndinfo *cmndinfo = gdth_cmnd_priv(scp); - int cmd_index; - - cmdp= ha->pccb; - TRACE2(("gdth_special_cmd(): ")); - - *cmdp = *cmndinfo->internal_cmd_str; - cmdp->RequestBuffer = scp; - - /* search free command index */ - if (!(cmd_index=gdth_get_cmd_index(ha))) { - TRACE(("GDT: No free command index found\n")); - return 0; - } - - /* if it's the first command, set command semaphore */ - if (ha->cmd_cnt == 0) - gdth_set_sema0(ha); - - /* evaluate command size, check space */ - if (cmdp->OpCode == GDT_IOCTL) { - TRACE2(("IOCTL\n")); - ha->cmd_len = - GDTOFFSOF(gdth_cmd_str,u.ioctl.p_param) + sizeof(u64); - } else if (cmdp->Service == CACHESERVICE) { - TRACE2(("cache command %d\n",cmdp->OpCode)); - if (ha->cache_feat & GDT_64BIT) - ha->cmd_len = - GDTOFFSOF(gdth_cmd_str,u.cache64.sg_lst) + sizeof(gdth_sg64_str); - else - ha->cmd_len = - GDTOFFSOF(gdth_cmd_str,u.cache.sg_lst) + sizeof(gdth_sg_str); - } else if (cmdp->Service == SCSIRAWSERVICE) { - TRACE2(("raw command %d\n",cmdp->OpCode)); - if (ha->raw_feat & GDT_64BIT) - ha->cmd_len = - GDTOFFSOF(gdth_cmd_str,u.raw64.sg_lst) + sizeof(gdth_sg64_str); - else - ha->cmd_len = - GDTOFFSOF(gdth_cmd_str,u.raw.sg_lst) + sizeof(gdth_sg_str); - } - - if (ha->cmd_len & 3) - ha->cmd_len += (4 - (ha->cmd_len & 3)); - - if (ha->cmd_cnt > 0) { - if ((ha->cmd_offs_dpmem + ha->cmd_len + DPMEM_COMMAND_OFFSET) > - ha->ic_all_size) { - TRACE2(("gdth_special_cmd() DPMEM overflow\n")); - ha->cmd_tab[cmd_index-2].cmnd = UNUSED_CMND; - return 0; - } - } - - /* copy command */ - gdth_copy_command(ha); - return cmd_index; -} - - -/* Controller event handling functions */ -static gdth_evt_str *gdth_store_event(gdth_ha_str *ha, u16 source, - u16 idx, gdth_evt_data *evt) -{ - gdth_evt_str *e; - - /* no GDTH_LOCK_HA() ! */ - TRACE2(("gdth_store_event() source %d idx %d\n", source, idx)); - if (source == 0) /* no source -> no event */ - return NULL; - - if (ebuffer[elastidx].event_source == source && - ebuffer[elastidx].event_idx == idx && - ((evt->size != 0 && ebuffer[elastidx].event_data.size != 0 && - !memcmp((char *)&ebuffer[elastidx].event_data.eu, - (char *)&evt->eu, evt->size)) || - (evt->size == 0 && ebuffer[elastidx].event_data.size == 0 && - !strcmp((char *)&ebuffer[elastidx].event_data.event_string, - (char *)&evt->event_string)))) { - e = &ebuffer[elastidx]; - e->last_stamp = (u32)ktime_get_real_seconds(); - ++e->same_count; - } else { - if (ebuffer[elastidx].event_source != 0) { /* entry not free ? */ - ++elastidx; - if (elastidx == MAX_EVENTS) - elastidx = 0; - if (elastidx == eoldidx) { /* reached mark ? */ - ++eoldidx; - if (eoldidx == MAX_EVENTS) - eoldidx = 0; - } - } - e = &ebuffer[elastidx]; - e->event_source = source; - e->event_idx = idx; - e->first_stamp = e->last_stamp = (u32)ktime_get_real_seconds(); - e->same_count = 1; - e->event_data = *evt; - e->application = 0; - } - return e; -} - -static int gdth_read_event(gdth_ha_str *ha, int handle, gdth_evt_str *estr) -{ - gdth_evt_str *e; - int eindex; - unsigned long flags; - - TRACE2(("gdth_read_event() handle %d\n", handle)); - spin_lock_irqsave(&ha->smp_lock, flags); - if (handle == -1) - eindex = eoldidx; - else - eindex = handle; - estr->event_source = 0; - - if (eindex < 0 || eindex >= MAX_EVENTS) { - spin_unlock_irqrestore(&ha->smp_lock, flags); - return eindex; - } - e = &ebuffer[eindex]; - if (e->event_source != 0) { - if (eindex != elastidx) { - if (++eindex == MAX_EVENTS) - eindex = 0; - } else { - eindex = -1; - } - memcpy(estr, e, sizeof(gdth_evt_str)); - } - spin_unlock_irqrestore(&ha->smp_lock, flags); - return eindex; -} - -static void gdth_readapp_event(gdth_ha_str *ha, - u8 application, gdth_evt_str *estr) -{ - gdth_evt_str *e; - int eindex; - unsigned long flags; - u8 found = FALSE; - - TRACE2(("gdth_readapp_event() app. %d\n", application)); - spin_lock_irqsave(&ha->smp_lock, flags); - eindex = eoldidx; - for (;;) { - e = &ebuffer[eindex]; - if (e->event_source == 0) - break; - if ((e->application & application) == 0) { - e->application |= application; - found = TRUE; - break; - } - if (eindex == elastidx) - break; - if (++eindex == MAX_EVENTS) - eindex = 0; - } - if (found) - memcpy(estr, e, sizeof(gdth_evt_str)); - else - estr->event_source = 0; - spin_unlock_irqrestore(&ha->smp_lock, flags); -} - -static void gdth_clear_events(void) -{ - TRACE(("gdth_clear_events()")); - - eoldidx = elastidx = 0; - ebuffer[0].event_source = 0; -} - - -/* SCSI interface functions */ - -static irqreturn_t __gdth_interrupt(gdth_ha_str *ha, - int gdth_from_wait, int* pIndex) -{ - gdt6m_dpram_str __iomem *dp6m_ptr = NULL; - gdt6_dpram_str __iomem *dp6_ptr; - struct scsi_cmnd *scp; - int rval, i; - u8 IStatus; - u16 Service; - unsigned long flags = 0; - - TRACE(("gdth_interrupt() IRQ %d\n", ha->irq)); - - /* if polling and not from gdth_wait() -> return */ - if (gdth_polling) { - if (!gdth_from_wait) { - return IRQ_HANDLED; - } - } - - if (!gdth_polling) - spin_lock_irqsave(&ha->smp_lock, flags); - - /* search controller */ - IStatus = gdth_get_status(ha); - if (IStatus == 0) { - /* spurious interrupt */ - if (!gdth_polling) - spin_unlock_irqrestore(&ha->smp_lock, flags); - return IRQ_HANDLED; - } - -#ifdef GDTH_STATISTICS - ++act_ints; -#endif - - if (ha->type == GDT_PCI) { - dp6_ptr = ha->brd; - if (IStatus & 0x80) { /* error flag */ - IStatus &= ~0x80; - ha->status = readw(&dp6_ptr->u.ic.Status); - TRACE2(("gdth_interrupt() error %d/%d\n",IStatus,ha->status)); - } else /* no error */ - ha->status = S_OK; - ha->info = readl(&dp6_ptr->u.ic.Info[0]); - ha->service = readw(&dp6_ptr->u.ic.Service); - ha->info2 = readl(&dp6_ptr->u.ic.Info[1]); - - writeb(0xff, &dp6_ptr->io.irqdel); /* acknowledge interrupt */ - writeb(0, &dp6_ptr->u.ic.Cmd_Index);/* reset command index */ - writeb(0, &dp6_ptr->io.Sema1); /* reset status semaphore */ - } else if (ha->type == GDT_PCINEW) { - if (IStatus & 0x80) { /* error flag */ - IStatus &= ~0x80; - ha->status = inw(PTR2USHORT(&ha->plx->status)); - TRACE2(("gdth_interrupt() error %d/%d\n",IStatus,ha->status)); - } else - ha->status = S_OK; - ha->info = inl(PTR2USHORT(&ha->plx->info[0])); - ha->service = inw(PTR2USHORT(&ha->plx->service)); - ha->info2 = inl(PTR2USHORT(&ha->plx->info[1])); - - outb(0xff, PTR2USHORT(&ha->plx->edoor_reg)); - outb(0x00, PTR2USHORT(&ha->plx->sema1_reg)); - } else if (ha->type == GDT_PCIMPR) { - dp6m_ptr = ha->brd; - if (IStatus & 0x80) { /* error flag */ - IStatus &= ~0x80; - ha->status = readw(&dp6m_ptr->i960r.status); - TRACE2(("gdth_interrupt() error %d/%d\n",IStatus,ha->status)); - } else /* no error */ - ha->status = S_OK; - - ha->info = readl(&dp6m_ptr->i960r.info[0]); - ha->service = readw(&dp6m_ptr->i960r.service); - ha->info2 = readl(&dp6m_ptr->i960r.info[1]); - - /* event string */ - if (IStatus == ASYNCINDEX) { - if (ha->service != SCREENSERVICE && - (ha->fw_vers & 0xff) >= 0x1a) { - ha->dvr.severity = readb - (&((gdt6m_dpram_str __iomem *)ha->brd)->i960r.severity); - for (i = 0; i < 256; ++i) { - ha->dvr.event_string[i] = readb - (&((gdt6m_dpram_str __iomem *)ha->brd)->i960r.evt_str[i]); - if (ha->dvr.event_string[i] == 0) - break; - } - } - } - writeb(0xff, &dp6m_ptr->i960r.edoor_reg); - writeb(0, &dp6m_ptr->i960r.sema1_reg); - } else { - TRACE2(("gdth_interrupt() unknown controller type\n")); - if (!gdth_polling) - spin_unlock_irqrestore(&ha->smp_lock, flags); - return IRQ_HANDLED; - } - - TRACE(("gdth_interrupt() index %d stat %d info %d\n", - IStatus,ha->status,ha->info)); - - if (gdth_from_wait) { - *pIndex = (int)IStatus; - } - - if (IStatus == ASYNCINDEX) { - TRACE2(("gdth_interrupt() async. event\n")); - gdth_async_event(ha); - if (!gdth_polling) - spin_unlock_irqrestore(&ha->smp_lock, flags); - gdth_next(ha); - return IRQ_HANDLED; - } - - if (IStatus == SPEZINDEX) { - TRACE2(("Service unknown or not initialized !\n")); - ha->dvr.size = sizeof(ha->dvr.eu.driver); - ha->dvr.eu.driver.ionode = ha->hanum; - gdth_store_event(ha, ES_DRIVER, 4, &ha->dvr); - if (!gdth_polling) - spin_unlock_irqrestore(&ha->smp_lock, flags); - return IRQ_HANDLED; - } - scp = ha->cmd_tab[IStatus-2].cmnd; - Service = ha->cmd_tab[IStatus-2].service; - ha->cmd_tab[IStatus-2].cmnd = UNUSED_CMND; - if (scp == UNUSED_CMND) { - TRACE2(("gdth_interrupt() index to unused command (%d)\n",IStatus)); - ha->dvr.size = sizeof(ha->dvr.eu.driver); - ha->dvr.eu.driver.ionode = ha->hanum; - ha->dvr.eu.driver.index = IStatus; - gdth_store_event(ha, ES_DRIVER, 1, &ha->dvr); - if (!gdth_polling) - spin_unlock_irqrestore(&ha->smp_lock, flags); - return IRQ_HANDLED; - } - if (scp == INTERNAL_CMND) { - TRACE(("gdth_interrupt() answer to internal command\n")); - if (!gdth_polling) - spin_unlock_irqrestore(&ha->smp_lock, flags); - return IRQ_HANDLED; - } - - TRACE(("gdth_interrupt() sync. status\n")); - rval = gdth_sync_event(ha,Service,IStatus,scp); - if (!gdth_polling) - spin_unlock_irqrestore(&ha->smp_lock, flags); - if (rval == 2) { - gdth_putq(ha, scp, gdth_cmnd_priv(scp)->priority); - } else if (rval == 1) { - gdth_scsi_done(scp); - } - - gdth_next(ha); - return IRQ_HANDLED; -} - -static irqreturn_t gdth_interrupt(int irq, void *dev_id) -{ - gdth_ha_str *ha = dev_id; - - return __gdth_interrupt(ha, false, NULL); -} - -static int gdth_sync_event(gdth_ha_str *ha, int service, u8 index, - struct scsi_cmnd *scp) -{ - gdth_msg_str *msg; - gdth_cmd_str *cmdp; - u8 b, t; - struct gdth_cmndinfo *cmndinfo = gdth_cmnd_priv(scp); - - cmdp = ha->pccb; - TRACE(("gdth_sync_event() serv %d status %d\n", - service,ha->status)); - - if (service == SCREENSERVICE) { - msg = ha->pmsg; - TRACE(("len: %d, answer: %d, ext: %d, alen: %d\n", - msg->msg_len,msg->msg_answer,msg->msg_ext,msg->msg_alen)); - if (msg->msg_len > MSGLEN+1) - msg->msg_len = MSGLEN+1; - if (msg->msg_len) - if (!(msg->msg_answer && msg->msg_ext)) { - msg->msg_text[msg->msg_len] = '\0'; - printk("%s",msg->msg_text); - } - - if (msg->msg_ext && !msg->msg_answer) { - while (gdth_test_busy(ha)) - gdth_delay(0); - cmdp->Service = SCREENSERVICE; - cmdp->RequestBuffer = SCREEN_CMND; - gdth_get_cmd_index(ha); - gdth_set_sema0(ha); - cmdp->OpCode = GDT_READ; - cmdp->BoardNode = LOCALBOARD; - cmdp->u.screen.reserved = 0; - cmdp->u.screen.su.msg.msg_handle= msg->msg_handle; - cmdp->u.screen.su.msg.msg_addr = ha->msg_phys; - ha->cmd_offs_dpmem = 0; - ha->cmd_len = GDTOFFSOF(gdth_cmd_str,u.screen.su.msg.msg_addr) - + sizeof(u64); - ha->cmd_cnt = 0; - gdth_copy_command(ha); - gdth_release_event(ha); - return 0; - } - - if (msg->msg_answer && msg->msg_alen) { - /* default answers (getchar() not possible) */ - if (msg->msg_alen == 1) { - msg->msg_alen = 0; - msg->msg_len = 1; - msg->msg_text[0] = 0; - } else { - msg->msg_alen -= 2; - msg->msg_len = 2; - msg->msg_text[0] = 1; - msg->msg_text[1] = 0; - } - msg->msg_ext = 0; - msg->msg_answer = 0; - while (gdth_test_busy(ha)) - gdth_delay(0); - cmdp->Service = SCREENSERVICE; - cmdp->RequestBuffer = SCREEN_CMND; - gdth_get_cmd_index(ha); - gdth_set_sema0(ha); - cmdp->OpCode = GDT_WRITE; - cmdp->BoardNode = LOCALBOARD; - cmdp->u.screen.reserved = 0; - cmdp->u.screen.su.msg.msg_handle= msg->msg_handle; - cmdp->u.screen.su.msg.msg_addr = ha->msg_phys; - ha->cmd_offs_dpmem = 0; - ha->cmd_len = GDTOFFSOF(gdth_cmd_str,u.screen.su.msg.msg_addr) - + sizeof(u64); - ha->cmd_cnt = 0; - gdth_copy_command(ha); - gdth_release_event(ha); - return 0; - } - printk("\n"); - - } else { - b = scp->device->channel; - t = scp->device->id; - if (cmndinfo->OpCode == -1 && b != ha->virt_bus) { - ha->raw[BUS_L2P(ha,b)].io_cnt[t]--; - } - /* cache or raw service */ - if (ha->status == S_BSY) { - TRACE2(("Controller busy -> retry !\n")); - if (cmndinfo->OpCode == GDT_MOUNT) - cmndinfo->OpCode = GDT_CLUST_INFO; - /* retry */ - return 2; - } - if (scsi_bufflen(scp)) - dma_unmap_sg(&ha->pdev->dev, scsi_sglist(scp), scsi_sg_count(scp), - cmndinfo->dma_dir); - - if (cmndinfo->sense_paddr) - dma_unmap_page(&ha->pdev->dev, cmndinfo->sense_paddr, 16, - DMA_FROM_DEVICE); - - if (ha->status == S_OK) { - cmndinfo->status = S_OK; - cmndinfo->info = ha->info; - if (cmndinfo->OpCode != -1) { - TRACE2(("gdth_sync_event(): special cmd 0x%x OK\n", - cmndinfo->OpCode)); - /* special commands GDT_CLUST_INFO/GDT_MOUNT ? */ - if (cmndinfo->OpCode == GDT_CLUST_INFO) { - ha->hdr[t].cluster_type = (u8)ha->info; - if (!(ha->hdr[t].cluster_type & - CLUSTER_MOUNTED)) { - /* NOT MOUNTED -> MOUNT */ - cmndinfo->OpCode = GDT_MOUNT; - if (ha->hdr[t].cluster_type & - CLUSTER_RESERVED) { - /* cluster drive RESERVED (on the other node) */ - cmndinfo->phase = -2; /* reservation conflict */ - } - } else { - cmndinfo->OpCode = -1; - } - } else { - if (cmndinfo->OpCode == GDT_MOUNT) { - ha->hdr[t].cluster_type |= CLUSTER_MOUNTED; - ha->hdr[t].media_changed = TRUE; - } else if (cmndinfo->OpCode == GDT_UNMOUNT) { - ha->hdr[t].cluster_type &= ~CLUSTER_MOUNTED; - ha->hdr[t].media_changed = TRUE; - } - cmndinfo->OpCode = -1; - } - /* retry */ - cmndinfo->priority = HIGH_PRI; - return 2; - } else { - /* RESERVE/RELEASE ? */ - if (scp->cmnd[0] == RESERVE) { - ha->hdr[t].cluster_type |= CLUSTER_RESERVED; - } else if (scp->cmnd[0] == RELEASE) { - ha->hdr[t].cluster_type &= ~CLUSTER_RESERVED; - } - scp->result = DID_OK << 16; - scp->sense_buffer[0] = 0; - } - } else { - cmndinfo->status = ha->status; - cmndinfo->info = ha->info; - - if (cmndinfo->OpCode != -1) { - TRACE2(("gdth_sync_event(): special cmd 0x%x error 0x%x\n", - cmndinfo->OpCode, ha->status)); - if (cmndinfo->OpCode == GDT_SCAN_START || - cmndinfo->OpCode == GDT_SCAN_END) { - cmndinfo->OpCode = -1; - /* retry */ - cmndinfo->priority = HIGH_PRI; - return 2; - } - memset((char*)scp->sense_buffer,0,16); - scp->sense_buffer[0] = 0x70; - scp->sense_buffer[2] = NOT_READY; - scp->result = (DID_OK << 16) | (CHECK_CONDITION << 1); - } else if (service == CACHESERVICE) { - if (ha->status == S_CACHE_UNKNOWN && - (ha->hdr[t].cluster_type & - CLUSTER_RESERVE_STATE) == CLUSTER_RESERVE_STATE) { - /* bus reset -> force GDT_CLUST_INFO */ - ha->hdr[t].cluster_type &= ~CLUSTER_RESERVED; - } - memset((char*)scp->sense_buffer,0,16); - if (ha->status == (u16)S_CACHE_RESERV) { - scp->result = (DID_OK << 16) | (RESERVATION_CONFLICT << 1); - } else { - scp->sense_buffer[0] = 0x70; - scp->sense_buffer[2] = NOT_READY; - scp->result = (DID_OK << 16) | (CHECK_CONDITION << 1); - } - if (!cmndinfo->internal_command) { - ha->dvr.size = sizeof(ha->dvr.eu.sync); - ha->dvr.eu.sync.ionode = ha->hanum; - ha->dvr.eu.sync.service = service; - ha->dvr.eu.sync.status = ha->status; - ha->dvr.eu.sync.info = ha->info; - ha->dvr.eu.sync.hostdrive = t; - if (ha->status >= 0x8000) - gdth_store_event(ha, ES_SYNC, 0, &ha->dvr); - else - gdth_store_event(ha, ES_SYNC, service, &ha->dvr); - } - } else { - /* sense buffer filled from controller firmware (DMA) */ - if (ha->status != S_RAW_SCSI || ha->info >= 0x100) { - scp->result = DID_BAD_TARGET << 16; - } else { - scp->result = (DID_OK << 16) | ha->info; - } - } - } - if (!cmndinfo->wait_for_completion) - cmndinfo->wait_for_completion++; - else - return 1; - } - - return 0; -} - -static char *async_cache_tab[] = { -/* 0*/ "\011\000\002\002\002\004\002\006\004" - "GDT HA %u, service %u, async. status %u/%lu unknown", -/* 1*/ "\011\000\002\002\002\004\002\006\004" - "GDT HA %u, service %u, async. status %u/%lu unknown", -/* 2*/ "\005\000\002\006\004" - "GDT HA %u, Host Drive %lu not ready", -/* 3*/ "\005\000\002\006\004" - "GDT HA %u, Host Drive %lu: REASSIGN not successful and/or data error on reassigned blocks. Drive may crash in the future and should be replaced", -/* 4*/ "\005\000\002\006\004" - "GDT HA %u, mirror update on Host Drive %lu failed", -/* 5*/ "\005\000\002\006\004" - "GDT HA %u, Mirror Drive %lu failed", -/* 6*/ "\005\000\002\006\004" - "GDT HA %u, Mirror Drive %lu: REASSIGN not successful and/or data error on reassigned blocks. Drive may crash in the future and should be replaced", -/* 7*/ "\005\000\002\006\004" - "GDT HA %u, Host Drive %lu write protected", -/* 8*/ "\005\000\002\006\004" - "GDT HA %u, media changed in Host Drive %lu", -/* 9*/ "\005\000\002\006\004" - "GDT HA %u, Host Drive %lu is offline", -/*10*/ "\005\000\002\006\004" - "GDT HA %u, media change of Mirror Drive %lu", -/*11*/ "\005\000\002\006\004" - "GDT HA %u, Mirror Drive %lu is write protected", -/*12*/ "\005\000\002\006\004" - "GDT HA %u, general error on Host Drive %lu. Please check the devices of this drive!", -/*13*/ "\007\000\002\006\002\010\002" - "GDT HA %u, Array Drive %u: Cache Drive %u failed", -/*14*/ "\005\000\002\006\002" - "GDT HA %u, Array Drive %u: FAIL state entered", -/*15*/ "\005\000\002\006\002" - "GDT HA %u, Array Drive %u: error", -/*16*/ "\007\000\002\006\002\010\002" - "GDT HA %u, Array Drive %u: failed drive replaced by Cache Drive %u", -/*17*/ "\005\000\002\006\002" - "GDT HA %u, Array Drive %u: parity build failed", -/*18*/ "\005\000\002\006\002" - "GDT HA %u, Array Drive %u: drive rebuild failed", -/*19*/ "\005\000\002\010\002" - "GDT HA %u, Test of Hot Fix %u failed", -/*20*/ "\005\000\002\006\002" - "GDT HA %u, Array Drive %u: drive build finished successfully", -/*21*/ "\005\000\002\006\002" - "GDT HA %u, Array Drive %u: drive rebuild finished successfully", -/*22*/ "\007\000\002\006\002\010\002" - "GDT HA %u, Array Drive %u: Hot Fix %u activated", -/*23*/ "\005\000\002\006\002" - "GDT HA %u, Host Drive %u: processing of i/o aborted due to serious drive error", -/*24*/ "\005\000\002\010\002" - "GDT HA %u, mirror update on Cache Drive %u completed", -/*25*/ "\005\000\002\010\002" - "GDT HA %u, mirror update on Cache Drive %lu failed", -/*26*/ "\005\000\002\006\002" - "GDT HA %u, Array Drive %u: drive rebuild started", -/*27*/ "\005\000\002\012\001" - "GDT HA %u, Fault bus %u: SHELF OK detected", -/*28*/ "\005\000\002\012\001" - "GDT HA %u, Fault bus %u: SHELF not OK detected", -/*29*/ "\007\000\002\012\001\013\001" - "GDT HA %u, Fault bus %u, ID %u: Auto Hot Plug started", -/*30*/ "\007\000\002\012\001\013\001" - "GDT HA %u, Fault bus %u, ID %u: new disk detected", -/*31*/ "\007\000\002\012\001\013\001" - "GDT HA %u, Fault bus %u, ID %u: old disk detected", -/*32*/ "\007\000\002\012\001\013\001" - "GDT HA %u, Fault bus %u, ID %u: plugging an active disk is invalid", -/*33*/ "\007\000\002\012\001\013\001" - "GDT HA %u, Fault bus %u, ID %u: invalid device detected", -/*34*/ "\011\000\002\012\001\013\001\006\004" - "GDT HA %u, Fault bus %u, ID %u: insufficient disk capacity (%lu MB required)", -/*35*/ "\007\000\002\012\001\013\001" - "GDT HA %u, Fault bus %u, ID %u: disk write protected", -/*36*/ "\007\000\002\012\001\013\001" - "GDT HA %u, Fault bus %u, ID %u: disk not available", -/*37*/ "\007\000\002\012\001\006\004" - "GDT HA %u, Fault bus %u: swap detected (%lu)", -/*38*/ "\007\000\002\012\001\013\001" - "GDT HA %u, Fault bus %u, ID %u: Auto Hot Plug finished successfully", -/*39*/ "\007\000\002\012\001\013\001" - "GDT HA %u, Fault bus %u, ID %u: Auto Hot Plug aborted due to user Hot Plug", -/*40*/ "\007\000\002\012\001\013\001" - "GDT HA %u, Fault bus %u, ID %u: Auto Hot Plug aborted", -/*41*/ "\007\000\002\012\001\013\001" - "GDT HA %u, Fault bus %u, ID %u: Auto Hot Plug for Hot Fix started", -/*42*/ "\005\000\002\006\002" - "GDT HA %u, Array Drive %u: drive build started", -/*43*/ "\003\000\002" - "GDT HA %u, DRAM parity error detected", -/*44*/ "\005\000\002\006\002" - "GDT HA %u, Mirror Drive %u: update started", -/*45*/ "\007\000\002\006\002\010\002" - "GDT HA %u, Mirror Drive %u: Hot Fix %u activated", -/*46*/ "\005\000\002\006\002" - "GDT HA %u, Array Drive %u: no matching Pool Hot Fix Drive available", -/*47*/ "\005\000\002\006\002" - "GDT HA %u, Array Drive %u: Pool Hot Fix Drive available", -/*48*/ "\005\000\002\006\002" - "GDT HA %u, Mirror Drive %u: no matching Pool Hot Fix Drive available", -/*49*/ "\005\000\002\006\002" - "GDT HA %u, Mirror Drive %u: Pool Hot Fix Drive available", -/*50*/ "\007\000\002\012\001\013\001" - "GDT HA %u, SCSI bus %u, ID %u: IGNORE_WIDE_RESIDUE message received", -/*51*/ "\005\000\002\006\002" - "GDT HA %u, Array Drive %u: expand started", -/*52*/ "\005\000\002\006\002" - "GDT HA %u, Array Drive %u: expand finished successfully", -/*53*/ "\005\000\002\006\002" - "GDT HA %u, Array Drive %u: expand failed", -/*54*/ "\003\000\002" - "GDT HA %u, CPU temperature critical", -/*55*/ "\003\000\002" - "GDT HA %u, CPU temperature OK", -/*56*/ "\005\000\002\006\004" - "GDT HA %u, Host drive %lu created", -/*57*/ "\005\000\002\006\002" - "GDT HA %u, Array Drive %u: expand restarted", -/*58*/ "\005\000\002\006\002" - "GDT HA %u, Array Drive %u: expand stopped", -/*59*/ "\005\000\002\010\002" - "GDT HA %u, Mirror Drive %u: drive build quited", -/*60*/ "\005\000\002\006\002" - "GDT HA %u, Array Drive %u: parity build quited", -/*61*/ "\005\000\002\006\002" - "GDT HA %u, Array Drive %u: drive rebuild quited", -/*62*/ "\005\000\002\006\002" - "GDT HA %u, Array Drive %u: parity verify started", -/*63*/ "\005\000\002\006\002" - "GDT HA %u, Array Drive %u: parity verify done", -/*64*/ "\005\000\002\006\002" - "GDT HA %u, Array Drive %u: parity verify failed", -/*65*/ "\005\000\002\006\002" - "GDT HA %u, Array Drive %u: parity error detected", -/*66*/ "\005\000\002\006\002" - "GDT HA %u, Array Drive %u: parity verify quited", -/*67*/ "\005\000\002\006\002" - "GDT HA %u, Host Drive %u reserved", -/*68*/ "\005\000\002\006\002" - "GDT HA %u, Host Drive %u mounted and released", -/*69*/ "\005\000\002\006\002" - "GDT HA %u, Host Drive %u released", -/*70*/ "\003\000\002" - "GDT HA %u, DRAM error detected and corrected with ECC", -/*71*/ "\003\000\002" - "GDT HA %u, Uncorrectable DRAM error detected with ECC", -/*72*/ "\011\000\002\012\001\013\001\014\001" - "GDT HA %u, SCSI bus %u, ID %u, LUN %u: reassigning block", -/*73*/ "\005\000\002\006\002" - "GDT HA %u, Host drive %u resetted locally", -/*74*/ "\005\000\002\006\002" - "GDT HA %u, Host drive %u resetted remotely", -/*75*/ "\003\000\002" - "GDT HA %u, async. status 75 unknown", -}; - - -static int gdth_async_event(gdth_ha_str *ha) -{ - gdth_cmd_str *cmdp; - - cmdp= ha->pccb; - TRACE2(("gdth_async_event() ha %d serv %d\n", - ha->hanum, ha->service)); - - if (ha->service == SCREENSERVICE) { - if (ha->status == MSG_REQUEST) { - while (gdth_test_busy(ha)) - gdth_delay(0); - cmdp->Service = SCREENSERVICE; - cmdp->RequestBuffer = SCREEN_CMND; - gdth_set_sema0(ha); - cmdp->OpCode = GDT_READ; - cmdp->BoardNode = LOCALBOARD; - cmdp->u.screen.reserved = 0; - cmdp->u.screen.su.msg.msg_handle= MSG_INV_HANDLE; - cmdp->u.screen.su.msg.msg_addr = ha->msg_phys; - ha->cmd_offs_dpmem = 0; - ha->cmd_len = GDTOFFSOF(gdth_cmd_str,u.screen.su.msg.msg_addr) - + sizeof(u64); - ha->cmd_cnt = 0; - gdth_copy_command(ha); - printk("[PCI %d/%d] ",(u16)(ha->brd_phys>>8), - (u16)((ha->brd_phys>>3)&0x1f)); - gdth_release_event(ha); - } - - } else { - if (ha->type == GDT_PCIMPR && - (ha->fw_vers & 0xff) >= 0x1a) { - ha->dvr.size = 0; - ha->dvr.eu.async.ionode = ha->hanum; - ha->dvr.eu.async.status = ha->status; - /* severity and event_string already set! */ - } else { - ha->dvr.size = sizeof(ha->dvr.eu.async); - ha->dvr.eu.async.ionode = ha->hanum; - ha->dvr.eu.async.service = ha->service; - ha->dvr.eu.async.status = ha->status; - ha->dvr.eu.async.info = ha->info; - *(u32 *)ha->dvr.eu.async.scsi_coord = ha->info2; - } - gdth_store_event( ha, ES_ASYNC, ha->service, &ha->dvr ); - gdth_log_event( &ha->dvr, NULL ); - - /* new host drive from expand? */ - if (ha->service == CACHESERVICE && ha->status == 56) { - TRACE2(("gdth_async_event(): new host drive %d created\n", - (u16)ha->info)); - /* gdth_analyse_hdrive(hanum, (u16)ha->info); */ - } - } - return 1; -} - -static void gdth_log_event(gdth_evt_data *dvr, char *buffer) -{ - gdth_stackframe stack; - char *f = NULL; - int i,j; - - TRACE2(("gdth_log_event()\n")); - if (dvr->size == 0) { - if (buffer == NULL) { - printk("Adapter %d: %s\n",dvr->eu.async.ionode,dvr->event_string); - } else { - sprintf(buffer,"Adapter %d: %s\n", - dvr->eu.async.ionode,dvr->event_string); - } - } else if (dvr->eu.async.service == CACHESERVICE && - INDEX_OK(dvr->eu.async.status, async_cache_tab)) { - TRACE2(("GDT: Async. event cache service, event no.: %d\n", - dvr->eu.async.status)); - - f = async_cache_tab[dvr->eu.async.status]; - - /* i: parameter to push, j: stack element to fill */ - for (j=0,i=1; i < f[0]; i+=2) { - switch (f[i+1]) { - case 4: - stack.b[j++] = *(u32*)&dvr->eu.stream[(int)f[i]]; - break; - case 2: - stack.b[j++] = *(u16*)&dvr->eu.stream[(int)f[i]]; - break; - case 1: - stack.b[j++] = *(u8*)&dvr->eu.stream[(int)f[i]]; - break; - default: - break; - } - } - - if (buffer == NULL) { - printk(&f[(int)f[0]],stack); - printk("\n"); - } else { - sprintf(buffer,&f[(int)f[0]],stack); - } - - } else { - if (buffer == NULL) { - printk("GDT HA %u, Unknown async. event service %d event no. %d\n", - dvr->eu.async.ionode,dvr->eu.async.service,dvr->eu.async.status); - } else { - sprintf(buffer,"GDT HA %u, Unknown async. event service %d event no. %d", - dvr->eu.async.ionode,dvr->eu.async.service,dvr->eu.async.status); - } - } -} - -#ifdef GDTH_STATISTICS -static u8 gdth_timer_running; - -static void gdth_timeout(struct timer_list *unused) -{ - u32 i; - struct scsi_cmnd *nscp; - gdth_ha_str *ha; - unsigned long flags; - - if(unlikely(list_empty(&gdth_instances))) { - gdth_timer_running = 0; - return; - } - - ha = list_first_entry(&gdth_instances, gdth_ha_str, list); - spin_lock_irqsave(&ha->smp_lock, flags); - - for (act_stats=0,i=0; icmd_tab[i].cmnd != UNUSED_CMND) - ++act_stats; - - for (act_rq=0, - nscp=ha->req_first; nscp; nscp=(struct scsi_cmnd*)nscp->SCp.ptr) - ++act_rq; - - TRACE2(("gdth_to(): ints %d, ios %d, act_stats %d, act_rq %d\n", - act_ints, act_ios, act_stats, act_rq)); - act_ints = act_ios = 0; - - gdth_timer.expires = jiffies + 30 * HZ; - add_timer(&gdth_timer); - spin_unlock_irqrestore(&ha->smp_lock, flags); -} - -static void gdth_timer_init(void) -{ - if (gdth_timer_running) - return; - gdth_timer_running = 1; - TRACE2(("gdth_detect(): Initializing timer !\n")); - gdth_timer.expires = jiffies + HZ; - add_timer(&gdth_timer); -} -#else -static inline void gdth_timer_init(void) -{ -} -#endif - - -static const char *gdth_ctr_name(gdth_ha_str *ha) -{ - TRACE2(("gdth_ctr_name()\n")); - - if (ha->type == GDT_PCI) { - switch (ha->pdev->device) { - case PCI_DEVICE_ID_VORTEX_GDT60x0: - return("GDT6000/6020/6050"); - case PCI_DEVICE_ID_VORTEX_GDT6000B: - return("GDT6000B/6010"); - } - } - /* new controllers (GDT_PCINEW, GDT_PCIMPR, ..) use board_info IOCTL! */ - - return(""); -} - -static const char *gdth_info(struct Scsi_Host *shp) -{ - gdth_ha_str *ha = shost_priv(shp); - - TRACE2(("gdth_info()\n")); - return ((const char *)ha->binfo.type_string); -} - -static enum blk_eh_timer_return gdth_timed_out(struct scsi_cmnd *scp) -{ - gdth_ha_str *ha = shost_priv(scp->device->host); - struct gdth_cmndinfo *cmndinfo = gdth_cmnd_priv(scp); - u8 b, t; - unsigned long flags; - enum blk_eh_timer_return retval = BLK_EH_DONE; - - TRACE(("%s() cmd 0x%x\n", scp->cmnd[0], __func__)); - b = scp->device->channel; - t = scp->device->id; - - /* - * We don't really honor the command timeout, but we try to - * honor 6 times of the actual command timeout! So reset the - * timer if this is less than 6th timeout on this command! - */ - if (++cmndinfo->timeout_count < 6) - retval = BLK_EH_RESET_TIMER; - - /* Reset the timeout if it is locked IO */ - spin_lock_irqsave(&ha->smp_lock, flags); - if ((b != ha->virt_bus && ha->raw[BUS_L2P(ha, b)].lock) || - (b == ha->virt_bus && t < MAX_HDRIVES && ha->hdr[t].lock)) { - TRACE2(("%s(): locked IO, reset timeout\n", __func__)); - retval = BLK_EH_RESET_TIMER; - } - spin_unlock_irqrestore(&ha->smp_lock, flags); - - return retval; -} - - -static int gdth_eh_bus_reset(struct scsi_cmnd *scp) -{ - gdth_ha_str *ha = shost_priv(scp->device->host); - int i; - unsigned long flags; - struct scsi_cmnd *cmnd; - u8 b; - - TRACE2(("gdth_eh_bus_reset()\n")); - - b = scp->device->channel; - - /* clear command tab */ - spin_lock_irqsave(&ha->smp_lock, flags); - for (i = 0; i < GDTH_MAXCMDS; ++i) { - cmnd = ha->cmd_tab[i].cmnd; - if (!SPECIAL_SCP(cmnd) && cmnd->device->channel == b) - ha->cmd_tab[i].cmnd = UNUSED_CMND; - } - spin_unlock_irqrestore(&ha->smp_lock, flags); - - if (b == ha->virt_bus) { - /* host drives */ - for (i = 0; i < MAX_HDRIVES; ++i) { - if (ha->hdr[i].present) { - spin_lock_irqsave(&ha->smp_lock, flags); - gdth_polling = TRUE; - while (gdth_test_busy(ha)) - gdth_delay(0); - if (gdth_internal_cmd(ha, CACHESERVICE, - GDT_CLUST_RESET, i, 0, 0)) - ha->hdr[i].cluster_type &= ~CLUSTER_RESERVED; - gdth_polling = FALSE; - spin_unlock_irqrestore(&ha->smp_lock, flags); - } - } - } else { - /* raw devices */ - spin_lock_irqsave(&ha->smp_lock, flags); - for (i = 0; i < MAXID; ++i) - ha->raw[BUS_L2P(ha,b)].io_cnt[i] = 0; - gdth_polling = TRUE; - while (gdth_test_busy(ha)) - gdth_delay(0); - gdth_internal_cmd(ha, SCSIRAWSERVICE, GDT_RESET_BUS, - BUS_L2P(ha,b), 0, 0); - gdth_polling = FALSE; - spin_unlock_irqrestore(&ha->smp_lock, flags); - } - return SUCCESS; -} - -static int gdth_bios_param(struct scsi_device *sdev,struct block_device *bdev,sector_t cap,int *ip) -{ - u8 b, t; - gdth_ha_str *ha = shost_priv(sdev->host); - struct scsi_device *sd; - unsigned capacity; - - sd = sdev; - capacity = cap; - b = sd->channel; - t = sd->id; - TRACE2(("gdth_bios_param() ha %d bus %d target %d\n", ha->hanum, b, t)); - - if (b != ha->virt_bus || ha->hdr[t].heads == 0) { - /* raw device or host drive without mapping information */ - TRACE2(("Evaluate mapping\n")); - gdth_eval_mapping(capacity,&ip[2],&ip[0],&ip[1]); - } else { - ip[0] = ha->hdr[t].heads; - ip[1] = ha->hdr[t].secs; - ip[2] = capacity / ip[0] / ip[1]; - } - - TRACE2(("gdth_bios_param(): %d heads, %d secs, %d cyls\n", - ip[0],ip[1],ip[2])); - return 0; -} - - -static int gdth_queuecommand_lck(struct scsi_cmnd *scp, - void (*done)(struct scsi_cmnd *)) -{ - gdth_ha_str *ha = shost_priv(scp->device->host); - struct gdth_cmndinfo *cmndinfo; - - TRACE(("gdth_queuecommand() cmd 0x%x\n", scp->cmnd[0])); - - cmndinfo = gdth_get_cmndinfo(ha); - BUG_ON(!cmndinfo); - - scp->scsi_done = done; - cmndinfo->timeout_count = 0; - cmndinfo->priority = DEFAULT_PRI; - - return __gdth_queuecommand(ha, scp, cmndinfo); -} - -static DEF_SCSI_QCMD(gdth_queuecommand) - -static int __gdth_queuecommand(gdth_ha_str *ha, struct scsi_cmnd *scp, - struct gdth_cmndinfo *cmndinfo) -{ - scp->host_scribble = (unsigned char *)cmndinfo; - cmndinfo->wait_for_completion = 1; - cmndinfo->phase = -1; - cmndinfo->OpCode = -1; - -#ifdef GDTH_STATISTICS - ++act_ios; -#endif - - gdth_putq(ha, scp, cmndinfo->priority); - gdth_next(ha); - return 0; -} - - -static int gdth_open(struct inode *inode, struct file *filep) -{ - gdth_ha_str *ha; - - mutex_lock(&gdth_mutex); - list_for_each_entry(ha, &gdth_instances, list) { - if (!ha->sdev) - ha->sdev = scsi_get_host_dev(ha->shost); - } - mutex_unlock(&gdth_mutex); - - TRACE(("gdth_open()\n")); - return 0; -} - -static int gdth_close(struct inode *inode, struct file *filep) -{ - TRACE(("gdth_close()\n")); - return 0; -} - -static int ioc_event(void __user *arg) -{ - gdth_ioctl_event evt; - gdth_ha_str *ha; - unsigned long flags; - - if (copy_from_user(&evt, arg, sizeof(gdth_ioctl_event))) - return -EFAULT; - ha = gdth_find_ha(evt.ionode); - if (!ha) - return -EFAULT; - - if (evt.erase == 0xff) { - if (evt.event.event_source == ES_TEST) - evt.event.event_data.size=sizeof(evt.event.event_data.eu.test); - else if (evt.event.event_source == ES_DRIVER) - evt.event.event_data.size=sizeof(evt.event.event_data.eu.driver); - else if (evt.event.event_source == ES_SYNC) - evt.event.event_data.size=sizeof(evt.event.event_data.eu.sync); - else - evt.event.event_data.size=sizeof(evt.event.event_data.eu.async); - spin_lock_irqsave(&ha->smp_lock, flags); - gdth_store_event(ha, evt.event.event_source, evt.event.event_idx, - &evt.event.event_data); - spin_unlock_irqrestore(&ha->smp_lock, flags); - } else if (evt.erase == 0xfe) { - gdth_clear_events(); - } else if (evt.erase == 0) { - evt.handle = gdth_read_event(ha, evt.handle, &evt.event); - } else { - gdth_readapp_event(ha, evt.erase, &evt.event); - } - if (copy_to_user(arg, &evt, sizeof(gdth_ioctl_event))) - return -EFAULT; - return 0; -} - -static int ioc_lockdrv(void __user *arg) -{ - gdth_ioctl_lockdrv ldrv; - u8 i, j; - unsigned long flags; - gdth_ha_str *ha; - - if (copy_from_user(&ldrv, arg, sizeof(gdth_ioctl_lockdrv))) - return -EFAULT; - ha = gdth_find_ha(ldrv.ionode); - if (!ha) - return -EFAULT; - - for (i = 0; i < ldrv.drive_cnt && i < MAX_HDRIVES; ++i) { - j = ldrv.drives[i]; - if (j >= MAX_HDRIVES || !ha->hdr[j].present) - continue; - if (ldrv.lock) { - spin_lock_irqsave(&ha->smp_lock, flags); - ha->hdr[j].lock = 1; - spin_unlock_irqrestore(&ha->smp_lock, flags); - gdth_wait_completion(ha, ha->bus_cnt, j); - } else { - spin_lock_irqsave(&ha->smp_lock, flags); - ha->hdr[j].lock = 0; - spin_unlock_irqrestore(&ha->smp_lock, flags); - gdth_next(ha); - } - } - return 0; -} - -static int ioc_resetdrv(void __user *arg, char *cmnd) -{ - gdth_ioctl_reset res; - gdth_cmd_str cmd; - gdth_ha_str *ha; - int rval; - - if (copy_from_user(&res, arg, sizeof(gdth_ioctl_reset)) || - res.number >= MAX_HDRIVES) - return -EFAULT; - ha = gdth_find_ha(res.ionode); - if (!ha) - return -EFAULT; - - if (!ha->hdr[res.number].present) - return 0; - memset(&cmd, 0, sizeof(gdth_cmd_str)); - cmd.Service = CACHESERVICE; - cmd.OpCode = GDT_CLUST_RESET; - if (ha->cache_feat & GDT_64BIT) - cmd.u.cache64.DeviceNo = res.number; - else - cmd.u.cache.DeviceNo = res.number; - - rval = __gdth_execute(ha->sdev, &cmd, cmnd, 30, NULL); - if (rval < 0) - return rval; - res.status = rval; - - if (copy_to_user(arg, &res, sizeof(gdth_ioctl_reset))) - return -EFAULT; - return 0; -} - -static void gdth_ioc_cacheservice(gdth_ha_str *ha, gdth_ioctl_general *gen, - u64 paddr) -{ - if (ha->cache_feat & GDT_64BIT) { - /* copy elements from 32-bit IOCTL structure */ - gen->command.u.cache64.BlockCnt = gen->command.u.cache.BlockCnt; - gen->command.u.cache64.BlockNo = gen->command.u.cache.BlockNo; - gen->command.u.cache64.DeviceNo = gen->command.u.cache.DeviceNo; - - if (ha->cache_feat & SCATTER_GATHER) { - gen->command.u.cache64.DestAddr = (u64)-1; - gen->command.u.cache64.sg_canz = 1; - gen->command.u.cache64.sg_lst[0].sg_ptr = paddr; - gen->command.u.cache64.sg_lst[0].sg_len = gen->data_len; - gen->command.u.cache64.sg_lst[1].sg_len = 0; - } else { - gen->command.u.cache64.DestAddr = paddr; - gen->command.u.cache64.sg_canz = 0; - } - } else { - if (ha->cache_feat & SCATTER_GATHER) { - gen->command.u.cache.DestAddr = 0xffffffff; - gen->command.u.cache.sg_canz = 1; - gen->command.u.cache.sg_lst[0].sg_ptr = (u32)paddr; - gen->command.u.cache.sg_lst[0].sg_len = gen->data_len; - gen->command.u.cache.sg_lst[1].sg_len = 0; - } else { - gen->command.u.cache.DestAddr = paddr; - gen->command.u.cache.sg_canz = 0; - } - } -} - -static void gdth_ioc_scsiraw(gdth_ha_str *ha, gdth_ioctl_general *gen, - u64 paddr) -{ - if (ha->raw_feat & GDT_64BIT) { - /* copy elements from 32-bit IOCTL structure */ - char cmd[16]; - - gen->command.u.raw64.sense_len = gen->command.u.raw.sense_len; - gen->command.u.raw64.bus = gen->command.u.raw.bus; - gen->command.u.raw64.lun = gen->command.u.raw.lun; - gen->command.u.raw64.target = gen->command.u.raw.target; - memcpy(cmd, gen->command.u.raw.cmd, 16); - memcpy(gen->command.u.raw64.cmd, cmd, 16); - gen->command.u.raw64.clen = gen->command.u.raw.clen; - gen->command.u.raw64.sdlen = gen->command.u.raw.sdlen; - gen->command.u.raw64.direction = gen->command.u.raw.direction; - - /* addresses */ - if (ha->raw_feat & SCATTER_GATHER) { - gen->command.u.raw64.sdata = (u64)-1; - gen->command.u.raw64.sg_ranz = 1; - gen->command.u.raw64.sg_lst[0].sg_ptr = paddr; - gen->command.u.raw64.sg_lst[0].sg_len = gen->data_len; - gen->command.u.raw64.sg_lst[1].sg_len = 0; - } else { - gen->command.u.raw64.sdata = paddr; - gen->command.u.raw64.sg_ranz = 0; - } - - gen->command.u.raw64.sense_data = paddr + gen->data_len; - } else { - if (ha->raw_feat & SCATTER_GATHER) { - gen->command.u.raw.sdata = 0xffffffff; - gen->command.u.raw.sg_ranz = 1; - gen->command.u.raw.sg_lst[0].sg_ptr = (u32)paddr; - gen->command.u.raw.sg_lst[0].sg_len = gen->data_len; - gen->command.u.raw.sg_lst[1].sg_len = 0; - } else { - gen->command.u.raw.sdata = paddr; - gen->command.u.raw.sg_ranz = 0; - } - - gen->command.u.raw.sense_data = (u32)paddr + gen->data_len; - } -} - -static int ioc_general(void __user *arg, char *cmnd) -{ - gdth_ioctl_general gen; - gdth_ha_str *ha; - char *buf = NULL; - dma_addr_t paddr; - int rval; - - if (copy_from_user(&gen, arg, sizeof(gdth_ioctl_general))) - return -EFAULT; - ha = gdth_find_ha(gen.ionode); - if (!ha) - return -EFAULT; - - if (gen.data_len > INT_MAX) - return -EINVAL; - if (gen.sense_len > INT_MAX) - return -EINVAL; - if (gen.data_len + gen.sense_len > INT_MAX) - return -EINVAL; - - if (gen.data_len + gen.sense_len > 0) { - buf = dma_alloc_coherent(&ha->pdev->dev, - gen.data_len + gen.sense_len, &paddr, - GFP_KERNEL); - if (!buf) - return -EFAULT; - - rval = -EFAULT; - if (copy_from_user(buf, arg + sizeof(gdth_ioctl_general), - gen.data_len + gen.sense_len)) - goto out_free_buf; - - if (gen.command.OpCode == GDT_IOCTL) - gen.command.u.ioctl.p_param = paddr; - else if (gen.command.Service == CACHESERVICE) - gdth_ioc_cacheservice(ha, &gen, paddr); - else if (gen.command.Service == SCSIRAWSERVICE) - gdth_ioc_scsiraw(ha, &gen, paddr); - else - goto out_free_buf; - } - - rval = __gdth_execute(ha->sdev, &gen.command, cmnd, gen.timeout, - &gen.info); - if (rval < 0) - goto out_free_buf; - gen.status = rval; - - rval = -EFAULT; - if (copy_to_user(arg + sizeof(gdth_ioctl_general), buf, - gen.data_len + gen.sense_len)) - goto out_free_buf; - if (copy_to_user(arg, &gen, - sizeof(gdth_ioctl_general) - sizeof(gdth_cmd_str))) - goto out_free_buf; - - rval = 0; -out_free_buf: - if (buf) - dma_free_coherent(&ha->pdev->dev, gen.data_len + gen.sense_len, - buf, paddr); - return rval; -} - -static int ioc_hdrlist(void __user *arg, char *cmnd) -{ - gdth_ioctl_rescan *rsc; - gdth_cmd_str *cmd; - gdth_ha_str *ha; - u8 i; - int rc = -ENOMEM; - u32 cluster_type = 0; - - rsc = kmalloc(sizeof(*rsc), GFP_KERNEL); - cmd = kmalloc(sizeof(*cmd), GFP_KERNEL); - if (!rsc || !cmd) - goto free_fail; - - if (copy_from_user(rsc, arg, sizeof(gdth_ioctl_rescan)) || - (NULL == (ha = gdth_find_ha(rsc->ionode)))) { - rc = -EFAULT; - goto free_fail; - } - memset(cmd, 0, sizeof(gdth_cmd_str)); - - for (i = 0; i < MAX_HDRIVES; ++i) { - if (!ha->hdr[i].present) { - rsc->hdr_list[i].bus = 0xff; - continue; - } - rsc->hdr_list[i].bus = ha->virt_bus; - rsc->hdr_list[i].target = i; - rsc->hdr_list[i].lun = 0; - rsc->hdr_list[i].cluster_type = ha->hdr[i].cluster_type; - if (ha->hdr[i].cluster_type & CLUSTER_DRIVE) { - cmd->Service = CACHESERVICE; - cmd->OpCode = GDT_CLUST_INFO; - if (ha->cache_feat & GDT_64BIT) - cmd->u.cache64.DeviceNo = i; - else - cmd->u.cache.DeviceNo = i; - if (__gdth_execute(ha->sdev, cmd, cmnd, 30, &cluster_type) == S_OK) - rsc->hdr_list[i].cluster_type = cluster_type; - } - } - - if (copy_to_user(arg, rsc, sizeof(gdth_ioctl_rescan))) - rc = -EFAULT; - else - rc = 0; - -free_fail: - kfree(rsc); - kfree(cmd); - return rc; -} - -static int ioc_rescan(void __user *arg, char *cmnd) -{ - gdth_ioctl_rescan *rsc; - gdth_cmd_str *cmd; - u16 i, status, hdr_cnt; - u32 info; - int cyls, hds, secs; - int rc = -ENOMEM; - unsigned long flags; - gdth_ha_str *ha; - - rsc = kmalloc(sizeof(*rsc), GFP_KERNEL); - cmd = kmalloc(sizeof(*cmd), GFP_KERNEL); - if (!cmd || !rsc) - goto free_fail; - - if (copy_from_user(rsc, arg, sizeof(gdth_ioctl_rescan)) || - (NULL == (ha = gdth_find_ha(rsc->ionode)))) { - rc = -EFAULT; - goto free_fail; - } - memset(cmd, 0, sizeof(gdth_cmd_str)); - - if (rsc->flag == 0) { - /* old method: re-init. cache service */ - cmd->Service = CACHESERVICE; - if (ha->cache_feat & GDT_64BIT) { - cmd->OpCode = GDT_X_INIT_HOST; - cmd->u.cache64.DeviceNo = LINUX_OS; - } else { - cmd->OpCode = GDT_INIT; - cmd->u.cache.DeviceNo = LINUX_OS; - } - - status = __gdth_execute(ha->sdev, cmd, cmnd, 30, &info); - i = 0; - hdr_cnt = (status == S_OK ? (u16)info : 0); - } else { - i = rsc->hdr_no; - hdr_cnt = i + 1; - } - - for (; i < hdr_cnt && i < MAX_HDRIVES; ++i) { - cmd->Service = CACHESERVICE; - cmd->OpCode = GDT_INFO; - if (ha->cache_feat & GDT_64BIT) - cmd->u.cache64.DeviceNo = i; - else - cmd->u.cache.DeviceNo = i; - - status = __gdth_execute(ha->sdev, cmd, cmnd, 30, &info); - - spin_lock_irqsave(&ha->smp_lock, flags); - rsc->hdr_list[i].bus = ha->virt_bus; - rsc->hdr_list[i].target = i; - rsc->hdr_list[i].lun = 0; - if (status != S_OK) { - ha->hdr[i].present = FALSE; - } else { - ha->hdr[i].present = TRUE; - ha->hdr[i].size = info; - /* evaluate mapping */ - ha->hdr[i].size &= ~SECS32; - gdth_eval_mapping(ha->hdr[i].size,&cyls,&hds,&secs); - ha->hdr[i].heads = hds; - ha->hdr[i].secs = secs; - /* round size */ - ha->hdr[i].size = cyls * hds * secs; - } - spin_unlock_irqrestore(&ha->smp_lock, flags); - if (status != S_OK) - continue; - - /* extended info, if GDT_64BIT, for drives > 2 TB */ - /* but we need ha->info2, not yet stored in scp->SCp */ - - /* devtype, cluster info, R/W attribs */ - cmd->Service = CACHESERVICE; - cmd->OpCode = GDT_DEVTYPE; - if (ha->cache_feat & GDT_64BIT) - cmd->u.cache64.DeviceNo = i; - else - cmd->u.cache.DeviceNo = i; - - status = __gdth_execute(ha->sdev, cmd, cmnd, 30, &info); - - spin_lock_irqsave(&ha->smp_lock, flags); - ha->hdr[i].devtype = (status == S_OK ? (u16)info : 0); - spin_unlock_irqrestore(&ha->smp_lock, flags); - - cmd->Service = CACHESERVICE; - cmd->OpCode = GDT_CLUST_INFO; - if (ha->cache_feat & GDT_64BIT) - cmd->u.cache64.DeviceNo = i; - else - cmd->u.cache.DeviceNo = i; - - status = __gdth_execute(ha->sdev, cmd, cmnd, 30, &info); - - spin_lock_irqsave(&ha->smp_lock, flags); - ha->hdr[i].cluster_type = - ((status == S_OK && !shared_access) ? (u16)info : 0); - spin_unlock_irqrestore(&ha->smp_lock, flags); - rsc->hdr_list[i].cluster_type = ha->hdr[i].cluster_type; - - cmd->Service = CACHESERVICE; - cmd->OpCode = GDT_RW_ATTRIBS; - if (ha->cache_feat & GDT_64BIT) - cmd->u.cache64.DeviceNo = i; - else - cmd->u.cache.DeviceNo = i; - - status = __gdth_execute(ha->sdev, cmd, cmnd, 30, &info); - - spin_lock_irqsave(&ha->smp_lock, flags); - ha->hdr[i].rw_attribs = (status == S_OK ? (u16)info : 0); - spin_unlock_irqrestore(&ha->smp_lock, flags); - } - - if (copy_to_user(arg, rsc, sizeof(gdth_ioctl_rescan))) - rc = -EFAULT; - else - rc = 0; - -free_fail: - kfree(rsc); - kfree(cmd); - return rc; -} - -static int gdth_ioctl(struct file *filep, unsigned int cmd, unsigned long arg) -{ - gdth_ha_str *ha; - struct scsi_cmnd *scp; - unsigned long flags; - char cmnd[MAX_COMMAND_SIZE]; - void __user *argp = (void __user *)arg; - - memset(cmnd, 0xff, 12); - - TRACE(("gdth_ioctl() cmd 0x%x\n", cmd)); - - switch (cmd) { - case GDTIOCTL_CTRCNT: - { - int cnt = gdth_ctr_count; - if (put_user(cnt, (int __user *)argp)) - return -EFAULT; - break; - } - - case GDTIOCTL_DRVERS: - { - int ver = (GDTH_VERSION<<8) | GDTH_SUBVERSION; - if (put_user(ver, (int __user *)argp)) - return -EFAULT; - break; - } - - case GDTIOCTL_OSVERS: - { - gdth_ioctl_osvers osv; - - osv.version = (u8)(LINUX_VERSION_CODE >> 16); - osv.subversion = (u8)(LINUX_VERSION_CODE >> 8); - osv.revision = (u16)(LINUX_VERSION_CODE & 0xff); - if (copy_to_user(argp, &osv, sizeof(gdth_ioctl_osvers))) - return -EFAULT; - break; - } - - case GDTIOCTL_CTRTYPE: - { - gdth_ioctl_ctrtype ctrt; - - if (copy_from_user(&ctrt, argp, sizeof(gdth_ioctl_ctrtype)) || - (NULL == (ha = gdth_find_ha(ctrt.ionode)))) - return -EFAULT; - - if (ha->type != GDT_PCIMPR) { - ctrt.type = (u8)((ha->stype<<4) + 6); - } else { - ctrt.type = (ha->oem_id == OEM_ID_INTEL ? 0xfd : 0xfe); - if (ha->stype >= 0x300) - ctrt.ext_type = 0x6000 | ha->pdev->subsystem_device; - else - ctrt.ext_type = 0x6000 | ha->stype; - } - ctrt.device_id = ha->pdev->device; - ctrt.sub_device_id = ha->pdev->subsystem_device; - ctrt.info = ha->brd_phys; - ctrt.oem_id = ha->oem_id; - if (copy_to_user(argp, &ctrt, sizeof(gdth_ioctl_ctrtype))) - return -EFAULT; - break; - } - - case GDTIOCTL_GENERAL: - return ioc_general(argp, cmnd); - - case GDTIOCTL_EVENT: - return ioc_event(argp); - - case GDTIOCTL_LOCKDRV: - return ioc_lockdrv(argp); - - case GDTIOCTL_LOCKCHN: - { - gdth_ioctl_lockchn lchn; - u8 i, j; - - if (copy_from_user(&lchn, argp, sizeof(gdth_ioctl_lockchn)) || - (NULL == (ha = gdth_find_ha(lchn.ionode)))) - return -EFAULT; - - i = lchn.channel; - if (i < ha->bus_cnt) { - if (lchn.lock) { - spin_lock_irqsave(&ha->smp_lock, flags); - ha->raw[i].lock = 1; - spin_unlock_irqrestore(&ha->smp_lock, flags); - for (j = 0; j < ha->tid_cnt; ++j) - gdth_wait_completion(ha, i, j); - } else { - spin_lock_irqsave(&ha->smp_lock, flags); - ha->raw[i].lock = 0; - spin_unlock_irqrestore(&ha->smp_lock, flags); - for (j = 0; j < ha->tid_cnt; ++j) - gdth_next(ha); - } - } - break; - } - - case GDTIOCTL_RESCAN: - return ioc_rescan(argp, cmnd); - - case GDTIOCTL_HDRLIST: - return ioc_hdrlist(argp, cmnd); - - case GDTIOCTL_RESET_BUS: - { - gdth_ioctl_reset res; - int rval; - - if (copy_from_user(&res, argp, sizeof(gdth_ioctl_reset)) || - (NULL == (ha = gdth_find_ha(res.ionode)))) - return -EFAULT; - - scp = kzalloc(sizeof(*scp), GFP_KERNEL); - if (!scp) - return -ENOMEM; - scp->device = ha->sdev; - scp->cmd_len = 12; - scp->device->channel = res.number; - rval = gdth_eh_bus_reset(scp); - res.status = (rval == SUCCESS ? S_OK : S_GENERR); - kfree(scp); - - if (copy_to_user(argp, &res, sizeof(gdth_ioctl_reset))) - return -EFAULT; - break; - } - - case GDTIOCTL_RESET_DRV: - return ioc_resetdrv(argp, cmnd); - - default: - break; - } - return 0; -} - -static long gdth_unlocked_ioctl(struct file *file, unsigned int cmd, - unsigned long arg) -{ - int ret; - - mutex_lock(&gdth_mutex); - ret = gdth_ioctl(file, cmd, arg); - mutex_unlock(&gdth_mutex); - - return ret; -} - -/* flush routine */ -static void gdth_flush(gdth_ha_str *ha) -{ - int i; - gdth_cmd_str gdtcmd; - char cmnd[MAX_COMMAND_SIZE]; - memset(cmnd, 0xff, MAX_COMMAND_SIZE); - - TRACE2(("gdth_flush() hanum %d\n", ha->hanum)); - - for (i = 0; i < MAX_HDRIVES; ++i) { - if (ha->hdr[i].present) { - gdtcmd.BoardNode = LOCALBOARD; - gdtcmd.Service = CACHESERVICE; - gdtcmd.OpCode = GDT_FLUSH; - if (ha->cache_feat & GDT_64BIT) { - gdtcmd.u.cache64.DeviceNo = i; - gdtcmd.u.cache64.BlockNo = 1; - gdtcmd.u.cache64.sg_canz = 0; - } else { - gdtcmd.u.cache.DeviceNo = i; - gdtcmd.u.cache.BlockNo = 1; - gdtcmd.u.cache.sg_canz = 0; - } - TRACE2(("gdth_flush(): flush ha %d drive %d\n", ha->hanum, i)); - - gdth_execute(ha->shost, &gdtcmd, cmnd, 30, NULL); - } - } -} - -/* configure lun */ -static int gdth_slave_configure(struct scsi_device *sdev) -{ - sdev->skip_ms_page_3f = 1; - sdev->skip_ms_page_8 = 1; - return 0; -} - -static struct scsi_host_template gdth_template = { - .name = "GDT SCSI Disk Array Controller", - .info = gdth_info, - .queuecommand = gdth_queuecommand, - .eh_bus_reset_handler = gdth_eh_bus_reset, - .slave_configure = gdth_slave_configure, - .bios_param = gdth_bios_param, - .show_info = gdth_show_info, - .write_info = gdth_set_info, - .eh_timed_out = gdth_timed_out, - .proc_name = "gdth", - .can_queue = GDTH_MAXCMDS, - .this_id = -1, - .sg_tablesize = GDTH_MAXSG, - .cmd_per_lun = GDTH_MAXC_P_L, - .unchecked_isa_dma = 1, - .no_write_same = 1, -}; - -static int gdth_pci_probe_one(gdth_pci_str *pcistr, gdth_ha_str **ha_out) -{ - struct Scsi_Host *shp; - gdth_ha_str *ha; - dma_addr_t scratch_dma_handle = 0; - int error, i; - struct pci_dev *pdev = pcistr->pdev; - - *ha_out = NULL; - - shp = scsi_host_alloc(&gdth_template, sizeof(gdth_ha_str)); - if (!shp) - return -ENOMEM; - ha = shost_priv(shp); - - error = -ENODEV; - if (!gdth_init_pci(pdev, pcistr, ha)) - goto out_host_put; - - /* controller found and initialized */ - printk("Configuring GDT-PCI HA at %d/%d IRQ %u\n", - pdev->bus->number, - PCI_SLOT(pdev->devfn), - ha->irq); - - error = request_irq(ha->irq, gdth_interrupt, - IRQF_SHARED, "gdth", ha); - if (error) { - printk("GDT-PCI: Unable to allocate IRQ\n"); - goto out_host_put; - } - - shp->unchecked_isa_dma = 0; - shp->irq = ha->irq; - shp->dma_channel = 0xff; - - ha->hanum = gdth_ctr_count++; - ha->shost = shp; - - ha->pccb = &ha->cmdext; - ha->ccb_phys = 0L; - - error = -ENOMEM; - - ha->pscratch = dma_alloc_coherent(&ha->pdev->dev, GDTH_SCRATCH, - &scratch_dma_handle, GFP_KERNEL); - if (!ha->pscratch) - goto out_free_irq; - ha->scratch_phys = scratch_dma_handle; - - ha->pmsg = dma_alloc_coherent(&ha->pdev->dev, sizeof(gdth_msg_str), - &scratch_dma_handle, GFP_KERNEL); - if (!ha->pmsg) - goto out_free_pscratch; - ha->msg_phys = scratch_dma_handle; - - ha->scratch_busy = FALSE; - ha->req_first = NULL; - ha->tid_cnt = pdev->device >= 0x200 ? MAXID : MAX_HDRIVES; - if (max_ids > 0 && max_ids < ha->tid_cnt) - ha->tid_cnt = max_ids; - for (i = 0; i < GDTH_MAXCMDS; ++i) - ha->cmd_tab[i].cmnd = UNUSED_CMND; - ha->scan_mode = rescan ? 0x10 : 0; - - error = -ENODEV; - if (!gdth_search_drives(ha)) { - printk("GDT-PCI %d: Error during device scan\n", ha->hanum); - goto out_free_pmsg; - } - - if (hdr_channel < 0 || hdr_channel > ha->bus_cnt) - hdr_channel = ha->bus_cnt; - ha->virt_bus = hdr_channel; - - /* 64-bit DMA only supported from FW >= x.43 */ - if (!(ha->cache_feat & ha->raw_feat & ha->screen_feat & GDT_64BIT) || - !ha->dma64_support) { - if (dma_set_mask(&pdev->dev, DMA_BIT_MASK(32))) { - printk(KERN_WARNING "GDT-PCI %d: " - "Unable to set 32-bit DMA\n", ha->hanum); - goto out_free_pmsg; - } - } else { - shp->max_cmd_len = 16; - if (!dma_set_mask(&pdev->dev, DMA_BIT_MASK(64))) { - printk("GDT-PCI %d: 64-bit DMA enabled\n", ha->hanum); - } else if (dma_set_mask(&pdev->dev, DMA_BIT_MASK(32))) { - printk(KERN_WARNING "GDT-PCI %d: " - "Unable to set 64/32-bit DMA\n", ha->hanum); - goto out_free_pmsg; - } - } - - shp->max_id = ha->tid_cnt; - shp->max_lun = MAXLUN; - shp->max_channel = ha->bus_cnt; - - spin_lock_init(&ha->smp_lock); - gdth_enable_int(ha); - - error = scsi_add_host(shp, &pdev->dev); - if (error) - goto out_free_pmsg; - list_add_tail(&ha->list, &gdth_instances); - - pci_set_drvdata(ha->pdev, ha); - gdth_timer_init(); - - scsi_scan_host(shp); - - *ha_out = ha; - - return 0; - - out_free_pmsg: - dma_free_coherent(&ha->pdev->dev, sizeof(gdth_msg_str), - ha->pmsg, ha->msg_phys); - out_free_pscratch: - dma_free_coherent(&ha->pdev->dev, GDTH_SCRATCH, - ha->pscratch, ha->scratch_phys); - out_free_irq: - free_irq(ha->irq, ha); - gdth_ctr_count--; - out_host_put: - scsi_host_put(shp); - return error; -} - -static void gdth_remove_one(gdth_ha_str *ha) -{ - struct Scsi_Host *shp = ha->shost; - - TRACE2(("gdth_remove_one()\n")); - - scsi_remove_host(shp); - - gdth_flush(ha); - - if (ha->sdev) { - scsi_free_host_dev(ha->sdev); - ha->sdev = NULL; - } - - if (shp->irq) - free_irq(shp->irq,ha); - - if (ha->pscratch) - dma_free_coherent(&ha->pdev->dev, GDTH_SCRATCH, - ha->pscratch, ha->scratch_phys); - if (ha->pmsg) - dma_free_coherent(&ha->pdev->dev, sizeof(gdth_msg_str), - ha->pmsg, ha->msg_phys); - if (ha->ccb_phys) - dma_unmap_single(&ha->pdev->dev, ha->ccb_phys, - sizeof(gdth_cmd_str), DMA_BIDIRECTIONAL); - - scsi_host_put(shp); -} - -static int gdth_halt(struct notifier_block *nb, unsigned long event, void *buf) -{ - gdth_ha_str *ha; - - TRACE2(("gdth_halt() event %d\n", (int)event)); - if (event != SYS_RESTART && event != SYS_HALT && event != SYS_POWER_OFF) - return NOTIFY_DONE; - - list_for_each_entry(ha, &gdth_instances, list) - gdth_flush(ha); - - return NOTIFY_OK; -} - -static struct notifier_block gdth_notifier = { - gdth_halt, NULL, 0 -}; - -static int __init gdth_init(void) -{ - if (disable) { - printk("GDT-HA: Controller driver disabled from" - " command line !\n"); - return 0; - } - - printk("GDT-HA: Storage RAID Controller Driver. Version: %s\n", - GDTH_VERSION_STR); - - /* initializations */ - gdth_polling = TRUE; - gdth_clear_events(); - timer_setup(&gdth_timer, gdth_timeout, 0); - - /* scanning for PCI controllers */ - if (pci_register_driver(&gdth_pci_driver)) { - gdth_ha_str *ha; - - list_for_each_entry(ha, &gdth_instances, list) - gdth_remove_one(ha); - return -ENODEV; - } - - TRACE2(("gdth_detect() %d controller detected\n", gdth_ctr_count)); - - major = register_chrdev(0,"gdth", &gdth_fops); - register_reboot_notifier(&gdth_notifier); - gdth_polling = FALSE; - return 0; -} - -static void __exit gdth_exit(void) -{ - gdth_ha_str *ha; - - unregister_chrdev(major, "gdth"); - unregister_reboot_notifier(&gdth_notifier); - -#ifdef GDTH_STATISTICS - del_timer_sync(&gdth_timer); -#endif - - pci_unregister_driver(&gdth_pci_driver); - - list_for_each_entry(ha, &gdth_instances, list) - gdth_remove_one(ha); -} - -module_init(gdth_init); -module_exit(gdth_exit); - -#ifndef MODULE -static void __init internal_setup(char *str,int *ints) -{ - int i; - char *cur_str, *argv; - - TRACE2(("internal_setup() str %s ints[0] %d\n", - str ? str:"NULL", ints ? ints[0]:0)); - - /* analyse string */ - argv = str; - while (argv && (cur_str = strchr(argv, ':'))) { - int val = 0, c = *++cur_str; - - if (c == 'n' || c == 'N') - val = 0; - else if (c == 'y' || c == 'Y') - val = 1; - else - val = (int)simple_strtoul(cur_str, NULL, 0); - - if (!strncmp(argv, "disable:", 8)) - disable = val; - else if (!strncmp(argv, "reserve_mode:", 13)) - reserve_mode = val; - else if (!strncmp(argv, "reverse_scan:", 13)) - reverse_scan = val; - else if (!strncmp(argv, "hdr_channel:", 12)) - hdr_channel = val; - else if (!strncmp(argv, "max_ids:", 8)) - max_ids = val; - else if (!strncmp(argv, "rescan:", 7)) - rescan = val; - else if (!strncmp(argv, "shared_access:", 14)) - shared_access = val; - else if (!strncmp(argv, "reserve_list:", 13)) { - reserve_list[0] = val; - for (i = 1; i < MAX_RES_ARGS; i++) { - cur_str = strchr(cur_str, ','); - if (!cur_str) - break; - if (!isdigit((int)*++cur_str)) { - --cur_str; - break; - } - reserve_list[i] = - (int)simple_strtoul(cur_str, NULL, 0); - } - if (!cur_str) - break; - argv = ++cur_str; - continue; - } - - if ((argv = strchr(argv, ','))) - ++argv; - } -} - -static int __init option_setup(char *str) -{ - int ints[MAXHA]; - char *cur = str; - int i = 1; - - TRACE2(("option_setup() str %s\n", str ? str:"NULL")); - - while (cur && isdigit(*cur) && i < MAXHA) { - ints[i++] = simple_strtoul(cur, NULL, 0); - if ((cur = strchr(cur, ',')) != NULL) cur++; - } - - ints[0] = i - 1; - internal_setup(cur, ints); - return 1; -} - -__setup("gdth=", option_setup); -#endif diff --git a/drivers/scsi/gdth.h b/drivers/scsi/gdth.h deleted file mode 100644 index 5a13d406d40e..000000000000 --- a/drivers/scsi/gdth.h +++ /dev/null @@ -1,981 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -#ifndef _GDTH_H -#define _GDTH_H - -/* - * Header file for the GDT Disk Array/Storage RAID controllers driver for Linux - * - * gdth.h Copyright (C) 1995-06 ICP vortex, Achim Leubner - * See gdth.c for further informations and - * below for supported controller types - * - * - * - * $Id: gdth.h,v 1.58 2006/01/11 16:14:09 achim Exp $ - */ - -#include - -#ifndef TRUE -#define TRUE 1 -#endif -#ifndef FALSE -#define FALSE 0 -#endif - -/* defines, macros */ - -/* driver version */ -#define GDTH_VERSION_STR "3.05" -#define GDTH_VERSION 3 -#define GDTH_SUBVERSION 5 - -/* protocol version */ -#define PROTOCOL_VERSION 1 - -/* OEM IDs */ -#define OEM_ID_ICP 0x941c -#define OEM_ID_INTEL 0x8000 - -/* controller classes */ -#define GDT_PCI 0x03 /* PCI controller */ -#define GDT_PCINEW 0x04 /* new PCI controller */ -#define GDT_PCIMPR 0x05 /* PCI MPR controller */ - -#ifndef PCI_DEVICE_ID_VORTEX_GDT60x0 -/* GDT_PCI */ -#define PCI_DEVICE_ID_VORTEX_GDT60x0 0 /* GDT6000/6020/6050 */ -#define PCI_DEVICE_ID_VORTEX_GDT6000B 1 /* GDT6000B/6010 */ -/* GDT_PCINEW */ -#define PCI_DEVICE_ID_VORTEX_GDT6x10 2 /* GDT6110/6510 */ -#define PCI_DEVICE_ID_VORTEX_GDT6x20 3 /* GDT6120/6520 */ -#define PCI_DEVICE_ID_VORTEX_GDT6530 4 /* GDT6530 */ -#define PCI_DEVICE_ID_VORTEX_GDT6550 5 /* GDT6550 */ -/* GDT_PCINEW, wide/ultra SCSI controllers */ -#define PCI_DEVICE_ID_VORTEX_GDT6x17 6 /* GDT6117/6517 */ -#define PCI_DEVICE_ID_VORTEX_GDT6x27 7 /* GDT6127/6527 */ -#define PCI_DEVICE_ID_VORTEX_GDT6537 8 /* GDT6537 */ -#define PCI_DEVICE_ID_VORTEX_GDT6557 9 /* GDT6557/6557-ECC */ -/* GDT_PCINEW, wide SCSI controllers */ -#define PCI_DEVICE_ID_VORTEX_GDT6x15 10 /* GDT6115/6515 */ -#define PCI_DEVICE_ID_VORTEX_GDT6x25 11 /* GDT6125/6525 */ -#define PCI_DEVICE_ID_VORTEX_GDT6535 12 /* GDT6535 */ -#define PCI_DEVICE_ID_VORTEX_GDT6555 13 /* GDT6555/6555-ECC */ -#endif - -#ifndef PCI_DEVICE_ID_VORTEX_GDT6x17RP -/* GDT_MPR, RP series, wide/ultra SCSI */ -#define PCI_DEVICE_ID_VORTEX_GDT6x17RP 0x100 /* GDT6117RP/GDT6517RP */ -#define PCI_DEVICE_ID_VORTEX_GDT6x27RP 0x101 /* GDT6127RP/GDT6527RP */ -#define PCI_DEVICE_ID_VORTEX_GDT6537RP 0x102 /* GDT6537RP */ -#define PCI_DEVICE_ID_VORTEX_GDT6557RP 0x103 /* GDT6557RP */ -/* GDT_MPR, RP series, narrow/ultra SCSI */ -#define PCI_DEVICE_ID_VORTEX_GDT6x11RP 0x104 /* GDT6111RP/GDT6511RP */ -#define PCI_DEVICE_ID_VORTEX_GDT6x21RP 0x105 /* GDT6121RP/GDT6521RP */ -#endif -#ifndef PCI_DEVICE_ID_VORTEX_GDT6x17RD -/* GDT_MPR, RD series, wide/ultra SCSI */ -#define PCI_DEVICE_ID_VORTEX_GDT6x17RD 0x110 /* GDT6117RD/GDT6517RD */ -#define PCI_DEVICE_ID_VORTEX_GDT6x27RD 0x111 /* GDT6127RD/GDT6527RD */ -#define PCI_DEVICE_ID_VORTEX_GDT6537RD 0x112 /* GDT6537RD */ -#define PCI_DEVICE_ID_VORTEX_GDT6557RD 0x113 /* GDT6557RD */ -/* GDT_MPR, RD series, narrow/ultra SCSI */ -#define PCI_DEVICE_ID_VORTEX_GDT6x11RD 0x114 /* GDT6111RD/GDT6511RD */ -#define PCI_DEVICE_ID_VORTEX_GDT6x21RD 0x115 /* GDT6121RD/GDT6521RD */ -/* GDT_MPR, RD series, wide/ultra2 SCSI */ -#define PCI_DEVICE_ID_VORTEX_GDT6x18RD 0x118 /* GDT6118RD/GDT6518RD/ - GDT6618RD */ -#define PCI_DEVICE_ID_VORTEX_GDT6x28RD 0x119 /* GDT6128RD/GDT6528RD/ - GDT6628RD */ -#define PCI_DEVICE_ID_VORTEX_GDT6x38RD 0x11A /* GDT6538RD/GDT6638RD */ -#define PCI_DEVICE_ID_VORTEX_GDT6x58RD 0x11B /* GDT6558RD/GDT6658RD */ -/* GDT_MPR, RN series (64-bit PCI), wide/ultra2 SCSI */ -#define PCI_DEVICE_ID_VORTEX_GDT7x18RN 0x168 /* GDT7118RN/GDT7518RN/ - GDT7618RN */ -#define PCI_DEVICE_ID_VORTEX_GDT7x28RN 0x169 /* GDT7128RN/GDT7528RN/ - GDT7628RN */ -#define PCI_DEVICE_ID_VORTEX_GDT7x38RN 0x16A /* GDT7538RN/GDT7638RN */ -#define PCI_DEVICE_ID_VORTEX_GDT7x58RN 0x16B /* GDT7558RN/GDT7658RN */ -#endif - -#ifndef PCI_DEVICE_ID_VORTEX_GDT6x19RD -/* GDT_MPR, RD series, Fibre Channel */ -#define PCI_DEVICE_ID_VORTEX_GDT6x19RD 0x210 /* GDT6519RD/GDT6619RD */ -#define PCI_DEVICE_ID_VORTEX_GDT6x29RD 0x211 /* GDT6529RD/GDT6629RD */ -/* GDT_MPR, RN series (64-bit PCI), Fibre Channel */ -#define PCI_DEVICE_ID_VORTEX_GDT7x19RN 0x260 /* GDT7519RN/GDT7619RN */ -#define PCI_DEVICE_ID_VORTEX_GDT7x29RN 0x261 /* GDT7529RN/GDT7629RN */ -#endif - -#ifndef PCI_DEVICE_ID_VORTEX_GDTMAXRP -/* GDT_MPR, last device ID */ -#define PCI_DEVICE_ID_VORTEX_GDTMAXRP 0x2ff -#endif - -#ifndef PCI_DEVICE_ID_VORTEX_GDTNEWRX -/* new GDT Rx Controller */ -#define PCI_DEVICE_ID_VORTEX_GDTNEWRX 0x300 -#endif - -#ifndef PCI_DEVICE_ID_VORTEX_GDTNEWRX2 -/* new(2) GDT Rx Controller */ -#define PCI_DEVICE_ID_VORTEX_GDTNEWRX2 0x301 -#endif - -#ifndef PCI_DEVICE_ID_INTEL_SRC -/* Intel Storage RAID Controller */ -#define PCI_DEVICE_ID_INTEL_SRC 0x600 -#endif - -#ifndef PCI_DEVICE_ID_INTEL_SRC_XSCALE -/* Intel Storage RAID Controller */ -#define PCI_DEVICE_ID_INTEL_SRC_XSCALE 0x601 -#endif - -/* limits */ -#define GDTH_SCRATCH PAGE_SIZE /* 4KB scratch buffer */ -#define GDTH_MAXCMDS 120 -#define GDTH_MAXC_P_L 16 /* max. cmds per lun */ -#define GDTH_MAX_RAW 2 /* max. cmds per raw device */ -#define MAXOFFSETS 128 -#define MAXHA 16 -#define MAXID 127 -#define MAXLUN 8 -#define MAXBUS 6 -#define MAX_EVENTS 100 /* event buffer count */ -#define MAX_RES_ARGS 40 /* device reservation, - must be a multiple of 4 */ -#define MAXCYLS 1024 -#define HEADS 64 -#define SECS 32 /* mapping 64*32 */ -#define MEDHEADS 127 -#define MEDSECS 63 /* mapping 127*63 */ -#define BIGHEADS 255 -#define BIGSECS 63 /* mapping 255*63 */ - -/* special command ptr. */ -#define UNUSED_CMND ((struct scsi_cmnd *)-1) -#define INTERNAL_CMND ((struct scsi_cmnd *)-2) -#define SCREEN_CMND ((struct scsi_cmnd *)-3) -#define SPECIAL_SCP(p) (p==UNUSED_CMND || p==INTERNAL_CMND || p==SCREEN_CMND) - -/* controller services */ -#define SCSIRAWSERVICE 3 -#define CACHESERVICE 9 -#define SCREENSERVICE 11 - -/* screenservice defines */ -#define MSG_INV_HANDLE -1 /* special message handle */ -#define MSGLEN 16 /* size of message text */ -#define MSG_SIZE 34 /* size of message structure */ -#define MSG_REQUEST 0 /* async. event: message */ - -/* DPMEM constants */ -#define DPMEM_MAGIC 0xC0FFEE11 -#define IC_HEADER_BYTES 48 -#define IC_QUEUE_BYTES 4 -#define DPMEM_COMMAND_OFFSET IC_HEADER_BYTES+IC_QUEUE_BYTES*MAXOFFSETS - -/* cluster_type constants */ -#define CLUSTER_DRIVE 1 -#define CLUSTER_MOUNTED 2 -#define CLUSTER_RESERVED 4 -#define CLUSTER_RESERVE_STATE (CLUSTER_DRIVE|CLUSTER_MOUNTED|CLUSTER_RESERVED) - -/* commands for all services, cache service */ -#define GDT_INIT 0 /* service initialization */ -#define GDT_READ 1 /* read command */ -#define GDT_WRITE 2 /* write command */ -#define GDT_INFO 3 /* information about devices */ -#define GDT_FLUSH 4 /* flush dirty cache buffers */ -#define GDT_IOCTL 5 /* ioctl command */ -#define GDT_DEVTYPE 9 /* additional information */ -#define GDT_MOUNT 10 /* mount cache device */ -#define GDT_UNMOUNT 11 /* unmount cache device */ -#define GDT_SET_FEAT 12 /* set feat. (scatter/gather) */ -#define GDT_GET_FEAT 13 /* get features */ -#define GDT_WRITE_THR 16 /* write through */ -#define GDT_READ_THR 17 /* read through */ -#define GDT_EXT_INFO 18 /* extended info */ -#define GDT_RESET 19 /* controller reset */ -#define GDT_RESERVE_DRV 20 /* reserve host drive */ -#define GDT_RELEASE_DRV 21 /* release host drive */ -#define GDT_CLUST_INFO 22 /* cluster info */ -#define GDT_RW_ATTRIBS 23 /* R/W attribs (write thru,..)*/ -#define GDT_CLUST_RESET 24 /* releases the cluster drives*/ -#define GDT_FREEZE_IO 25 /* freezes all IOs */ -#define GDT_UNFREEZE_IO 26 /* unfreezes all IOs */ -#define GDT_X_INIT_HOST 29 /* ext. init: 64 bit support */ -#define GDT_X_INFO 30 /* ext. info for drives>2TB */ - -/* raw service commands */ -#define GDT_RESERVE 14 /* reserve dev. to raw serv. */ -#define GDT_RELEASE 15 /* release device */ -#define GDT_RESERVE_ALL 16 /* reserve all devices */ -#define GDT_RELEASE_ALL 17 /* release all devices */ -#define GDT_RESET_BUS 18 /* reset bus */ -#define GDT_SCAN_START 19 /* start device scan */ -#define GDT_SCAN_END 20 /* stop device scan */ -#define GDT_X_INIT_RAW 21 /* ext. init: 64 bit support */ - -/* screen service commands */ -#define GDT_REALTIME 3 /* realtime clock to screens. */ -#define GDT_X_INIT_SCR 4 /* ext. init: 64 bit support */ - -/* IOCTL command defines */ -#define SCSI_DR_INFO 0x00 /* SCSI drive info */ -#define SCSI_CHAN_CNT 0x05 /* SCSI channel count */ -#define SCSI_DR_LIST 0x06 /* SCSI drive list */ -#define SCSI_DEF_CNT 0x15 /* grown/primary defects */ -#define DSK_STATISTICS 0x4b /* SCSI disk statistics */ -#define IOCHAN_DESC 0x5d /* description of IO channel */ -#define IOCHAN_RAW_DESC 0x5e /* description of raw IO chn. */ -#define L_CTRL_PATTERN 0x20000000L /* SCSI IOCTL mask */ -#define ARRAY_INFO 0x12 /* array drive info */ -#define ARRAY_DRV_LIST 0x0f /* array drive list */ -#define ARRAY_DRV_LIST2 0x34 /* array drive list (new) */ -#define LA_CTRL_PATTERN 0x10000000L /* array IOCTL mask */ -#define CACHE_DRV_CNT 0x01 /* cache drive count */ -#define CACHE_DRV_LIST 0x02 /* cache drive list */ -#define CACHE_INFO 0x04 /* cache info */ -#define CACHE_CONFIG 0x05 /* cache configuration */ -#define CACHE_DRV_INFO 0x07 /* cache drive info */ -#define BOARD_FEATURES 0x15 /* controller features */ -#define BOARD_INFO 0x28 /* controller info */ -#define SET_PERF_MODES 0x82 /* set mode (coalescing,..) */ -#define GET_PERF_MODES 0x83 /* get mode */ -#define CACHE_READ_OEM_STRING_RECORD 0x84 /* read OEM string record */ -#define HOST_GET 0x10001L /* get host drive list */ -#define IO_CHANNEL 0x00020000L /* default IO channel */ -#define INVALID_CHANNEL 0x0000ffffL /* invalid channel */ - -/* service errors */ -#define S_OK 1 /* no error */ -#define S_GENERR 6 /* general error */ -#define S_BSY 7 /* controller busy */ -#define S_CACHE_UNKNOWN 12 /* cache serv.: drive unknown */ -#define S_RAW_SCSI 12 /* raw serv.: target error */ -#define S_RAW_ILL 0xff /* raw serv.: illegal */ -#define S_NOFUNC -2 /* unknown function */ -#define S_CACHE_RESERV -24 /* cache: reserv. conflict */ - -/* timeout values */ -#define INIT_RETRIES 100000 /* 100000 * 1ms = 100s */ -#define INIT_TIMEOUT 100000 /* 100000 * 1ms = 100s */ -#define POLL_TIMEOUT 10000 /* 10000 * 1ms = 10s */ - -/* priorities */ -#define DEFAULT_PRI 0x20 -#define IOCTL_PRI 0x10 -#define HIGH_PRI 0x08 - -/* data directions */ -#define GDTH_DATA_IN 0x01000000L /* data from target */ -#define GDTH_DATA_OUT 0x00000000L /* data to target */ - -/* other defines */ -#define LINUX_OS 8 /* used for cache optim. */ -#define SECS32 0x1f /* round capacity */ -#define BIOS_ID_OFFS 0x10 /* offset contr-ID in ISABIOS */ -#define LOCALBOARD 0 /* board node always 0 */ -#define ASYNCINDEX 0 /* cmd index async. event */ -#define SPEZINDEX 1 /* cmd index unknown service */ -#define COALINDEX (GDTH_MAXCMDS + 2) - -/* features */ -#define SCATTER_GATHER 1 /* s/g feature */ -#define GDT_WR_THROUGH 0x100 /* WRITE_THROUGH supported */ -#define GDT_64BIT 0x200 /* 64bit / drv>2TB support */ - -#include "gdth_ioctl.h" - -/* screenservice message */ -typedef struct { - u32 msg_handle; /* message handle */ - u32 msg_len; /* size of message */ - u32 msg_alen; /* answer length */ - u8 msg_answer; /* answer flag */ - u8 msg_ext; /* more messages */ - u8 msg_reserved[2]; - char msg_text[MSGLEN+2]; /* the message text */ -} __attribute__((packed)) gdth_msg_str; - - -/* IOCTL data structures */ - -/* Status coalescing buffer for returning multiple requests per interrupt */ -typedef struct { - u32 status; - u32 ext_status; - u32 info0; - u32 info1; -} __attribute__((packed)) gdth_coal_status; - -/* performance mode data structure */ -typedef struct { - u32 version; /* The version of this IOCTL structure. */ - u32 st_mode; /* 0=dis., 1=st_buf_addr1 valid, 2=both */ - u32 st_buff_addr1; /* physical address of status buffer 1 */ - u32 st_buff_u_addr1; /* reserved for 64 bit addressing */ - u32 st_buff_indx1; /* reserved command idx. for this buffer */ - u32 st_buff_addr2; /* physical address of status buffer 1 */ - u32 st_buff_u_addr2; /* reserved for 64 bit addressing */ - u32 st_buff_indx2; /* reserved command idx. for this buffer */ - u32 st_buff_size; /* size of each buffer in bytes */ - u32 cmd_mode; /* 0 = mode disabled, 1 = cmd_buff_addr1 */ - u32 cmd_buff_addr1; /* physical address of cmd buffer 1 */ - u32 cmd_buff_u_addr1; /* reserved for 64 bit addressing */ - u32 cmd_buff_indx1; /* cmd buf addr1 unique identifier */ - u32 cmd_buff_addr2; /* physical address of cmd buffer 1 */ - u32 cmd_buff_u_addr2; /* reserved for 64 bit addressing */ - u32 cmd_buff_indx2; /* cmd buf addr1 unique identifier */ - u32 cmd_buff_size; /* size of each cmd buffer in bytes */ - u32 reserved1; - u32 reserved2; -} __attribute__((packed)) gdth_perf_modes; - -/* SCSI drive info */ -typedef struct { - u8 vendor[8]; /* vendor string */ - u8 product[16]; /* product string */ - u8 revision[4]; /* revision */ - u32 sy_rate; /* current rate for sync. tr. */ - u32 sy_max_rate; /* max. rate for sync. tr. */ - u32 no_ldrive; /* belongs to this log. drv.*/ - u32 blkcnt; /* number of blocks */ - u16 blksize; /* size of block in bytes */ - u8 available; /* flag: access is available */ - u8 init; /* medium is initialized */ - u8 devtype; /* SCSI devicetype */ - u8 rm_medium; /* medium is removable */ - u8 wp_medium; /* medium is write protected */ - u8 ansi; /* SCSI I/II or III? */ - u8 protocol; /* same as ansi */ - u8 sync; /* flag: sync. transfer enab. */ - u8 disc; /* flag: disconnect enabled */ - u8 queueing; /* flag: command queing enab. */ - u8 cached; /* flag: caching enabled */ - u8 target_id; /* target ID of device */ - u8 lun; /* LUN id of device */ - u8 orphan; /* flag: drive fragment */ - u32 last_error; /* sense key or drive state */ - u32 last_result; /* result of last command */ - u32 check_errors; /* err. in last surface check */ - u8 percent; /* progress for surface check */ - u8 last_check; /* IOCTRL operation */ - u8 res[2]; - u32 flags; /* from 1.19/2.19: raw reserv.*/ - u8 multi_bus; /* multi bus dev? (fibre ch.) */ - u8 mb_status; /* status: available? */ - u8 res2[2]; - u8 mb_alt_status; /* status on second bus */ - u8 mb_alt_bid; /* number of second bus */ - u8 mb_alt_tid; /* target id on second bus */ - u8 res3; - u8 fc_flag; /* from 1.22/2.22: info valid?*/ - u8 res4; - u16 fc_frame_size; /* frame size (bytes) */ - char wwn[8]; /* world wide name */ -} __attribute__((packed)) gdth_diskinfo_str; - -/* get SCSI channel count */ -typedef struct { - u32 channel_no; /* number of channel */ - u32 drive_cnt; /* drive count */ - u8 siop_id; /* SCSI processor ID */ - u8 siop_state; /* SCSI processor state */ -} __attribute__((packed)) gdth_getch_str; - -/* get SCSI drive numbers */ -typedef struct { - u32 sc_no; /* SCSI channel */ - u32 sc_cnt; /* sc_list[] elements */ - u32 sc_list[MAXID]; /* minor device numbers */ -} __attribute__((packed)) gdth_drlist_str; - -/* get grown/primary defect count */ -typedef struct { - u8 sddc_type; /* 0x08: grown, 0x10: prim. */ - u8 sddc_format; /* list entry format */ - u8 sddc_len; /* list entry length */ - u8 sddc_res; - u32 sddc_cnt; /* entry count */ -} __attribute__((packed)) gdth_defcnt_str; - -/* disk statistics */ -typedef struct { - u32 bid; /* SCSI channel */ - u32 first; /* first SCSI disk */ - u32 entries; /* number of elements */ - u32 count; /* (R) number of init. el. */ - u32 mon_time; /* time stamp */ - struct { - u8 tid; /* target ID */ - u8 lun; /* LUN */ - u8 res[2]; - u32 blk_size; /* block size in bytes */ - u32 rd_count; /* bytes read */ - u32 wr_count; /* bytes written */ - u32 rd_blk_count; /* blocks read */ - u32 wr_blk_count; /* blocks written */ - u32 retries; /* retries */ - u32 reassigns; /* reassigns */ - } __attribute__((packed)) list[1]; -} __attribute__((packed)) gdth_dskstat_str; - -/* IO channel header */ -typedef struct { - u32 version; /* version (-1UL: newest) */ - u8 list_entries; /* list entry count */ - u8 first_chan; /* first channel number */ - u8 last_chan; /* last channel number */ - u8 chan_count; /* (R) channel count */ - u32 list_offset; /* offset of list[0] */ -} __attribute__((packed)) gdth_iochan_header; - -/* get IO channel description */ -typedef struct { - gdth_iochan_header hdr; - struct { - u32 address; /* channel address */ - u8 type; /* type (SCSI, FCAL) */ - u8 local_no; /* local number */ - u16 features; /* channel features */ - } __attribute__((packed)) list[MAXBUS]; -} __attribute__((packed)) gdth_iochan_str; - -/* get raw IO channel description */ -typedef struct { - gdth_iochan_header hdr; - struct { - u8 proc_id; /* processor id */ - u8 proc_defect; /* defect ? */ - u8 reserved[2]; - } __attribute__((packed)) list[MAXBUS]; -} __attribute__((packed)) gdth_raw_iochan_str; - -/* array drive component */ -typedef struct { - u32 al_controller; /* controller ID */ - u8 al_cache_drive; /* cache drive number */ - u8 al_status; /* cache drive state */ - u8 al_res[2]; -} __attribute__((packed)) gdth_arraycomp_str; - -/* array drive information */ -typedef struct { - u8 ai_type; /* array type (RAID0,4,5) */ - u8 ai_cache_drive_cnt; /* active cachedrives */ - u8 ai_state; /* array drive state */ - u8 ai_master_cd; /* master cachedrive */ - u32 ai_master_controller; /* ID of master controller */ - u32 ai_size; /* user capacity [sectors] */ - u32 ai_striping_size; /* striping size [sectors] */ - u32 ai_secsize; /* sector size [bytes] */ - u32 ai_err_info; /* failed cache drive */ - u8 ai_name[8]; /* name of the array drive */ - u8 ai_controller_cnt; /* number of controllers */ - u8 ai_removable; /* flag: removable */ - u8 ai_write_protected; /* flag: write protected */ - u8 ai_devtype; /* type: always direct access */ - gdth_arraycomp_str ai_drives[35]; /* drive components: */ - u8 ai_drive_entries; /* number of drive components */ - u8 ai_protected; /* protection flag */ - u8 ai_verify_state; /* state of a parity verify */ - u8 ai_ext_state; /* extended array drive state */ - u8 ai_expand_state; /* array expand state (>=2.18)*/ - u8 ai_reserved[3]; -} __attribute__((packed)) gdth_arrayinf_str; - -/* get array drive list */ -typedef struct { - u32 controller_no; /* controller no. */ - u8 cd_handle; /* master cachedrive */ - u8 is_arrayd; /* Flag: is array drive? */ - u8 is_master; /* Flag: is array master? */ - u8 is_parity; /* Flag: is parity drive? */ - u8 is_hotfix; /* Flag: is hotfix drive? */ - u8 res[3]; -} __attribute__((packed)) gdth_alist_str; - -typedef struct { - u32 entries_avail; /* allocated entries */ - u32 entries_init; /* returned entries */ - u32 first_entry; /* first entry number */ - u32 list_offset; /* offset of following list */ - gdth_alist_str list[1]; /* list */ -} __attribute__((packed)) gdth_arcdl_str; - -/* cache info/config IOCTL */ -typedef struct { - u32 version; /* firmware version */ - u16 state; /* cache state (on/off) */ - u16 strategy; /* cache strategy */ - u16 write_back; /* write back state (on/off) */ - u16 block_size; /* cache block size */ -} __attribute__((packed)) gdth_cpar_str; - -typedef struct { - u32 csize; /* cache size */ - u32 read_cnt; /* read/write counter */ - u32 write_cnt; - u32 tr_hits; /* hits */ - u32 sec_hits; - u32 sec_miss; /* misses */ -} __attribute__((packed)) gdth_cstat_str; - -typedef struct { - gdth_cpar_str cpar; - gdth_cstat_str cstat; -} __attribute__((packed)) gdth_cinfo_str; - -/* cache drive info */ -typedef struct { - u8 cd_name[8]; /* cache drive name */ - u32 cd_devtype; /* SCSI devicetype */ - u32 cd_ldcnt; /* number of log. drives */ - u32 cd_last_error; /* last error */ - u8 cd_initialized; /* drive is initialized */ - u8 cd_removable; /* media is removable */ - u8 cd_write_protected; /* write protected */ - u8 cd_flags; /* Pool Hot Fix? */ - u32 ld_blkcnt; /* number of blocks */ - u32 ld_blksize; /* blocksize */ - u32 ld_dcnt; /* number of disks */ - u32 ld_slave; /* log. drive index */ - u32 ld_dtype; /* type of logical drive */ - u32 ld_last_error; /* last error */ - u8 ld_name[8]; /* log. drive name */ - u8 ld_error; /* error */ -} __attribute__((packed)) gdth_cdrinfo_str; - -/* OEM string */ -typedef struct { - u32 ctl_version; - u32 file_major_version; - u32 file_minor_version; - u32 buffer_size; - u32 cpy_count; - u32 ext_error; - u32 oem_id; - u32 board_id; -} __attribute__((packed)) gdth_oem_str_params; - -typedef struct { - u8 product_0_1_name[16]; - u8 product_4_5_name[16]; - u8 product_cluster_name[16]; - u8 product_reserved[16]; - u8 scsi_cluster_target_vendor_id[16]; - u8 cluster_raid_fw_name[16]; - u8 oem_brand_name[16]; - u8 oem_raid_type[16]; - u8 bios_type[13]; - u8 bios_title[50]; - u8 oem_company_name[37]; - u32 pci_id_1; - u32 pci_id_2; - u8 validation_status[80]; - u8 reserved_1[4]; - u8 scsi_host_drive_inquiry_vendor_id[16]; - u8 library_file_template[16]; - u8 reserved_2[16]; - u8 tool_name_1[32]; - u8 tool_name_2[32]; - u8 tool_name_3[32]; - u8 oem_contact_1[84]; - u8 oem_contact_2[84]; - u8 oem_contact_3[84]; -} __attribute__((packed)) gdth_oem_str; - -typedef struct { - gdth_oem_str_params params; - gdth_oem_str text; -} __attribute__((packed)) gdth_oem_str_ioctl; - -/* board features */ -typedef struct { - u8 chaining; /* Chaining supported */ - u8 striping; /* Striping (RAID-0) supp. */ - u8 mirroring; /* Mirroring (RAID-1) supp. */ - u8 raid; /* RAID-4/5/10 supported */ -} __attribute__((packed)) gdth_bfeat_str; - -/* board info IOCTL */ -typedef struct { - u32 ser_no; /* serial no. */ - u8 oem_id[2]; /* OEM ID */ - u16 ep_flags; /* eprom flags */ - u32 proc_id; /* processor ID */ - u32 memsize; /* memory size (bytes) */ - u8 mem_banks; /* memory banks */ - u8 chan_type; /* channel type */ - u8 chan_count; /* channel count */ - u8 rdongle_pres; /* dongle present? */ - u32 epr_fw_ver; /* (eprom) firmware version */ - u32 upd_fw_ver; /* (update) firmware version */ - u32 upd_revision; /* update revision */ - char type_string[16]; /* controller name */ - char raid_string[16]; /* RAID firmware name */ - u8 update_pres; /* update present? */ - u8 xor_pres; /* XOR engine present? */ - u8 prom_type; /* ROM type (eprom/flash) */ - u8 prom_count; /* number of ROM devices */ - u32 dup_pres; /* duplexing module present? */ - u32 chan_pres; /* number of expansion chn. */ - u32 mem_pres; /* memory expansion inst. ? */ - u8 ft_bus_system; /* fault bus supported? */ - u8 subtype_valid; /* board_subtype valid? */ - u8 board_subtype; /* subtype/hardware level */ - u8 ramparity_pres; /* RAM parity check hardware? */ -} __attribute__((packed)) gdth_binfo_str; - -/* get host drive info */ -typedef struct { - char name[8]; /* host drive name */ - u32 size; /* size (sectors) */ - u8 host_drive; /* host drive number */ - u8 log_drive; /* log. drive (master) */ - u8 reserved; - u8 rw_attribs; /* r/w attribs */ - u32 start_sec; /* start sector */ -} __attribute__((packed)) gdth_hentry_str; - -typedef struct { - u32 entries; /* entry count */ - u32 offset; /* offset of entries */ - u8 secs_p_head; /* sectors/head */ - u8 heads_p_cyl; /* heads/cylinder */ - u8 reserved; - u8 clust_drvtype; /* cluster drive type */ - u32 location; /* controller number */ - gdth_hentry_str entry[MAX_HDRIVES]; /* entries */ -} __attribute__((packed)) gdth_hget_str; - - -/* DPRAM structures */ - -/* interface area ISA/PCI */ -typedef struct { - u8 S_Cmd_Indx; /* special command */ - u8 volatile S_Status; /* status special command */ - u16 reserved1; - u32 S_Info[4]; /* add. info special command */ - u8 volatile Sema0; /* command semaphore */ - u8 reserved2[3]; - u8 Cmd_Index; /* command number */ - u8 reserved3[3]; - u16 volatile Status; /* command status */ - u16 Service; /* service(for async.events) */ - u32 Info[2]; /* additional info */ - struct { - u16 offset; /* command offs. in the DPRAM*/ - u16 serv_id; /* service */ - } __attribute__((packed)) comm_queue[MAXOFFSETS]; /* command queue */ - u32 bios_reserved[2]; - u8 gdt_dpr_cmd[1]; /* commands */ -} __attribute__((packed)) gdt_dpr_if; - -/* SRAM structure PCI controllers */ -typedef struct { - u32 magic; /* controller ID from BIOS */ - u16 need_deinit; /* switch betw. BIOS/driver */ - u8 switch_support; /* see need_deinit */ - u8 padding[9]; - u8 os_used[16]; /* OS code per service */ - u8 unused[28]; - u8 fw_magic; /* contr. ID from firmware */ -} __attribute__((packed)) gdt_pci_sram; - -/* DPRAM ISA controllers */ -typedef struct { - union { - struct { - u8 bios_used[0x3c00-32]; /* 15KB - 32Bytes BIOS */ - u16 need_deinit; /* switch betw. BIOS/driver */ - u8 switch_support; /* see need_deinit */ - u8 padding[9]; - u8 os_used[16]; /* OS code per service */ - } __attribute__((packed)) dp_sram; - u8 bios_area[0x4000]; /* 16KB reserved for BIOS */ - } bu; - union { - gdt_dpr_if ic; /* interface area */ - u8 if_area[0x3000]; /* 12KB for interface */ - } u; - struct { - u8 memlock; /* write protection DPRAM */ - u8 event; /* release event */ - u8 irqen; /* board interrupts enable */ - u8 irqdel; /* acknowledge board int. */ - u8 volatile Sema1; /* status semaphore */ - u8 rq; /* IRQ/DRQ configuration */ - } __attribute__((packed)) io; -} __attribute__((packed)) gdt2_dpram_str; - -/* DPRAM PCI controllers */ -typedef struct { - union { - gdt_dpr_if ic; /* interface area */ - u8 if_area[0xff0-sizeof(gdt_pci_sram)]; - } u; - gdt_pci_sram gdt6sr; /* SRAM structure */ - struct { - u8 unused0[1]; - u8 volatile Sema1; /* command semaphore */ - u8 unused1[3]; - u8 irqen; /* board interrupts enable */ - u8 unused2[2]; - u8 event; /* release event */ - u8 unused3[3]; - u8 irqdel; /* acknowledge board int. */ - u8 unused4[3]; - } __attribute__((packed)) io; -} __attribute__((packed)) gdt6_dpram_str; - -/* PLX register structure (new PCI controllers) */ -typedef struct { - u8 cfg_reg; /* DPRAM cfg.(2:below 1MB,0:anywhere)*/ - u8 unused1[0x3f]; - u8 volatile sema0_reg; /* command semaphore */ - u8 volatile sema1_reg; /* status semaphore */ - u8 unused2[2]; - u16 volatile status; /* command status */ - u16 service; /* service */ - u32 info[2]; /* additional info */ - u8 unused3[0x10]; - u8 ldoor_reg; /* PCI to local doorbell */ - u8 unused4[3]; - u8 volatile edoor_reg; /* local to PCI doorbell */ - u8 unused5[3]; - u8 control0; /* control0 register(unused) */ - u8 control1; /* board interrupts enable */ - u8 unused6[0x16]; -} __attribute__((packed)) gdt6c_plx_regs; - -/* DPRAM new PCI controllers */ -typedef struct { - union { - gdt_dpr_if ic; /* interface area */ - u8 if_area[0x4000-sizeof(gdt_pci_sram)]; - } u; - gdt_pci_sram gdt6sr; /* SRAM structure */ -} __attribute__((packed)) gdt6c_dpram_str; - -/* i960 register structure (PCI MPR controllers) */ -typedef struct { - u8 unused1[16]; - u8 volatile sema0_reg; /* command semaphore */ - u8 unused2; - u8 volatile sema1_reg; /* status semaphore */ - u8 unused3; - u16 volatile status; /* command status */ - u16 service; /* service */ - u32 info[2]; /* additional info */ - u8 ldoor_reg; /* PCI to local doorbell */ - u8 unused4[11]; - u8 volatile edoor_reg; /* local to PCI doorbell */ - u8 unused5[7]; - u8 edoor_en_reg; /* board interrupts enable */ - u8 unused6[27]; - u32 unused7[939]; - u32 severity; - char evt_str[256]; /* event string */ -} __attribute__((packed)) gdt6m_i960_regs; - -/* DPRAM PCI MPR controllers */ -typedef struct { - gdt6m_i960_regs i960r; /* 4KB i960 registers */ - union { - gdt_dpr_if ic; /* interface area */ - u8 if_area[0x3000-sizeof(gdt_pci_sram)]; - } u; - gdt_pci_sram gdt6sr; /* SRAM structure */ -} __attribute__((packed)) gdt6m_dpram_str; - - -/* PCI resources */ -typedef struct { - struct pci_dev *pdev; - unsigned long dpmem; /* DPRAM address */ - unsigned long io; /* IO address */ -} gdth_pci_str; - - -/* controller information structure */ -typedef struct { - struct Scsi_Host *shost; - struct list_head list; - u16 hanum; - u16 oem_id; /* OEM */ - u16 type; /* controller class */ - u32 stype; /* subtype (PCI: device ID) */ - u16 fw_vers; /* firmware version */ - u16 cache_feat; /* feat. cache serv. (s/g,..)*/ - u16 raw_feat; /* feat. raw service (s/g,..)*/ - u16 screen_feat; /* feat. raw service (s/g,..)*/ - void __iomem *brd; /* DPRAM address */ - u32 brd_phys; /* slot number/BIOS address */ - gdt6c_plx_regs *plx; /* PLX regs (new PCI contr.) */ - gdth_cmd_str cmdext; - gdth_cmd_str *pccb; /* address command structure */ - u32 ccb_phys; /* phys. address */ -#ifdef INT_COAL - gdth_coal_status *coal_stat; /* buffer for coalescing int.*/ - u64 coal_stat_phys; /* phys. address */ -#endif - char *pscratch; /* scratch (DMA) buffer */ - u64 scratch_phys; /* phys. address */ - u8 scratch_busy; /* in use? */ - u8 dma64_support; /* 64-bit DMA supported? */ - gdth_msg_str *pmsg; /* message buffer */ - u64 msg_phys; /* phys. address */ - u8 scan_mode; /* current scan mode */ - u8 irq; /* IRQ */ - u8 drq; /* DRQ (ISA controllers) */ - u16 status; /* command status */ - u16 service; /* service/firmware ver./.. */ - u32 info; - u32 info2; /* additional info */ - struct scsi_cmnd *req_first; /* top of request queue */ - struct { - u8 present; /* Flag: host drive present? */ - u8 is_logdrv; /* Flag: log. drive (master)? */ - u8 is_arraydrv; /* Flag: array drive? */ - u8 is_master; /* Flag: array drive master? */ - u8 is_parity; /* Flag: parity drive? */ - u8 is_hotfix; /* Flag: hotfix drive? */ - u8 master_no; /* number of master drive */ - u8 lock; /* drive locked? (hot plug) */ - u8 heads; /* mapping */ - u8 secs; - u16 devtype; /* further information */ - u64 size; /* capacity */ - u8 ldr_no; /* log. drive no. */ - u8 rw_attribs; /* r/w attributes */ - u8 cluster_type; /* cluster properties */ - u8 media_changed; /* Flag:MOUNT/UNMOUNT occurred */ - u32 start_sec; /* start sector */ - } hdr[MAX_LDRIVES]; /* host drives */ - struct { - u8 lock; /* channel locked? (hot plug) */ - u8 pdev_cnt; /* physical device count */ - u8 local_no; /* local channel number */ - u8 io_cnt[MAXID]; /* current IO count */ - u32 address; /* channel address */ - u32 id_list[MAXID]; /* IDs of the phys. devices */ - } raw[MAXBUS]; /* SCSI channels */ - struct { - struct scsi_cmnd *cmnd; /* pending request */ - u16 service; /* service */ - } cmd_tab[GDTH_MAXCMDS]; /* table of pend. requests */ - struct gdth_cmndinfo { /* per-command private info */ - int index; - int internal_command; /* don't call scsi_done */ - gdth_cmd_str *internal_cmd_str; /* crier for internal messages*/ - dma_addr_t sense_paddr; /* sense dma-addr */ - u8 priority; - int timeout_count; /* # of timeout calls */ - volatile int wait_for_completion; - u16 status; - u32 info; - enum dma_data_direction dma_dir; - int phase; /* ???? */ - int OpCode; - } cmndinfo[GDTH_MAXCMDS]; /* index==0 is free */ - u8 bus_cnt; /* SCSI bus count */ - u8 tid_cnt; /* Target ID count */ - u8 bus_id[MAXBUS]; /* IOP IDs */ - u8 virt_bus; /* number of virtual bus */ - u8 more_proc; /* more /proc info supported */ - u16 cmd_cnt; /* command count in DPRAM */ - u16 cmd_len; /* length of actual command */ - u16 cmd_offs_dpmem; /* actual offset in DPRAM */ - u16 ic_all_size; /* sizeof DPRAM interf. area */ - gdth_cpar_str cpar; /* controller cache par. */ - gdth_bfeat_str bfeat; /* controller features */ - gdth_binfo_str binfo; /* controller info */ - gdth_evt_data dvr; /* event structure */ - spinlock_t smp_lock; - struct pci_dev *pdev; - char oem_name[8]; -#ifdef GDTH_DMA_STATISTICS - unsigned long dma32_cnt, dma64_cnt; /* statistics: DMA buffer */ -#endif - struct scsi_device *sdev; -} gdth_ha_str; - -static inline struct gdth_cmndinfo *gdth_cmnd_priv(struct scsi_cmnd* cmd) -{ - return (struct gdth_cmndinfo *)cmd->host_scribble; -} - -/* INQUIRY data format */ -typedef struct { - u8 type_qual; - u8 modif_rmb; - u8 version; - u8 resp_aenc; - u8 add_length; - u8 reserved1; - u8 reserved2; - u8 misc; - u8 vendor[8]; - u8 product[16]; - u8 revision[4]; -} __attribute__((packed)) gdth_inq_data; - -/* READ_CAPACITY data format */ -typedef struct { - u32 last_block_no; - u32 block_length; -} __attribute__((packed)) gdth_rdcap_data; - -/* READ_CAPACITY (16) data format */ -typedef struct { - u64 last_block_no; - u32 block_length; -} __attribute__((packed)) gdth_rdcap16_data; - -/* REQUEST_SENSE data format */ -typedef struct { - u8 errorcode; - u8 segno; - u8 key; - u32 info; - u8 add_length; - u32 cmd_info; - u8 adsc; - u8 adsq; - u8 fruc; - u8 key_spec[3]; -} __attribute__((packed)) gdth_sense_data; - -/* MODE_SENSE data format */ -typedef struct { - struct { - u8 data_length; - u8 med_type; - u8 dev_par; - u8 bd_length; - } __attribute__((packed)) hd; - struct { - u8 dens_code; - u8 block_count[3]; - u8 reserved; - u8 block_length[3]; - } __attribute__((packed)) bd; -} __attribute__((packed)) gdth_modep_data; - -/* stack frame */ -typedef struct { - unsigned long b[10]; /* 32/64 bit compiler ! */ -} __attribute__((packed)) gdth_stackframe; - - -/* function prototyping */ - -int gdth_show_info(struct seq_file *, struct Scsi_Host *); -int gdth_set_info(struct Scsi_Host *, char *, int); - -#endif diff --git a/drivers/scsi/gdth_ioctl.h b/drivers/scsi/gdth_ioctl.h deleted file mode 100644 index ee4c9bf1022a..000000000000 --- a/drivers/scsi/gdth_ioctl.h +++ /dev/null @@ -1,251 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -#ifndef _GDTH_IOCTL_H -#define _GDTH_IOCTL_H - -/* gdth_ioctl.h - * $Id: gdth_ioctl.h,v 1.14 2004/02/19 15:43:15 achim Exp $ - */ - -/* IOCTLs */ -#define GDTIOCTL_MASK ('J'<<8) -#define GDTIOCTL_GENERAL (GDTIOCTL_MASK | 0) /* general IOCTL */ -#define GDTIOCTL_DRVERS (GDTIOCTL_MASK | 1) /* get driver version */ -#define GDTIOCTL_CTRTYPE (GDTIOCTL_MASK | 2) /* get controller type */ -#define GDTIOCTL_OSVERS (GDTIOCTL_MASK | 3) /* get OS version */ -#define GDTIOCTL_HDRLIST (GDTIOCTL_MASK | 4) /* get host drive list */ -#define GDTIOCTL_CTRCNT (GDTIOCTL_MASK | 5) /* get controller count */ -#define GDTIOCTL_LOCKDRV (GDTIOCTL_MASK | 6) /* lock host drive */ -#define GDTIOCTL_LOCKCHN (GDTIOCTL_MASK | 7) /* lock channel */ -#define GDTIOCTL_EVENT (GDTIOCTL_MASK | 8) /* read controller events */ -#define GDTIOCTL_SCSI (GDTIOCTL_MASK | 9) /* SCSI command */ -#define GDTIOCTL_RESET_BUS (GDTIOCTL_MASK |10) /* reset SCSI bus */ -#define GDTIOCTL_RESCAN (GDTIOCTL_MASK |11) /* rescan host drives */ -#define GDTIOCTL_RESET_DRV (GDTIOCTL_MASK |12) /* reset (remote) drv. res. */ - -#define GDTIOCTL_MAGIC 0xaffe0004 -#define EVENT_SIZE 294 -#define GDTH_MAXSG 32 /* max. s/g elements */ - -#define MAX_LDRIVES 255 /* max. log. drive count */ -#define MAX_HDRIVES MAX_LDRIVES /* max. host drive count */ - -/* scatter/gather element */ -typedef struct { - u32 sg_ptr; /* address */ - u32 sg_len; /* length */ -} __attribute__((packed)) gdth_sg_str; - -/* scatter/gather element - 64bit addresses */ -typedef struct { - u64 sg_ptr; /* address */ - u32 sg_len; /* length */ -} __attribute__((packed)) gdth_sg64_str; - -/* command structure */ -typedef struct { - u32 BoardNode; /* board node (always 0) */ - u32 CommandIndex; /* command number */ - u16 OpCode; /* the command (READ,..) */ - union { - struct { - u16 DeviceNo; /* number of cache drive */ - u32 BlockNo; /* block number */ - u32 BlockCnt; /* block count */ - u32 DestAddr; /* dest. addr. (if s/g: -1) */ - u32 sg_canz; /* s/g element count */ - gdth_sg_str sg_lst[GDTH_MAXSG]; /* s/g list */ - } __attribute__((packed)) cache; /* cache service cmd. str. */ - struct { - u16 DeviceNo; /* number of cache drive */ - u64 BlockNo; /* block number */ - u32 BlockCnt; /* block count */ - u64 DestAddr; /* dest. addr. (if s/g: -1) */ - u32 sg_canz; /* s/g element count */ - gdth_sg64_str sg_lst[GDTH_MAXSG]; /* s/g list */ - } __attribute__((packed)) cache64; /* cache service cmd. str. */ - struct { - u16 param_size; /* size of p_param buffer */ - u32 subfunc; /* IOCTL function */ - u32 channel; /* device */ - u64 p_param; /* buffer */ - } __attribute__((packed)) ioctl; /* IOCTL command structure */ - struct { - u16 reserved; - union { - struct { - u32 msg_handle; /* message handle */ - u64 msg_addr; /* message buffer address */ - } __attribute__((packed)) msg; - u8 data[12]; /* buffer for rtc data, ... */ - } su; - } __attribute__((packed)) screen; /* screen service cmd. str. */ - struct { - u16 reserved; - u32 direction; /* data direction */ - u32 mdisc_time; /* disc. time (0: no timeout)*/ - u32 mcon_time; /* connect time(0: no to.) */ - u32 sdata; /* dest. addr. (if s/g: -1) */ - u32 sdlen; /* data length (bytes) */ - u32 clen; /* SCSI cmd. length(6,10,12) */ - u8 cmd[12]; /* SCSI command */ - u8 target; /* target ID */ - u8 lun; /* LUN */ - u8 bus; /* SCSI bus number */ - u8 priority; /* only 0 used */ - u32 sense_len; /* sense data length */ - u32 sense_data; /* sense data addr. */ - u32 link_p; /* linked cmds (not supp.) */ - u32 sg_ranz; /* s/g element count */ - gdth_sg_str sg_lst[GDTH_MAXSG]; /* s/g list */ - } __attribute__((packed)) raw; /* raw service cmd. struct. */ - struct { - u16 reserved; - u32 direction; /* data direction */ - u32 mdisc_time; /* disc. time (0: no timeout)*/ - u32 mcon_time; /* connect time(0: no to.) */ - u64 sdata; /* dest. addr. (if s/g: -1) */ - u32 sdlen; /* data length (bytes) */ - u32 clen; /* SCSI cmd. length(6,..,16) */ - u8 cmd[16]; /* SCSI command */ - u8 target; /* target ID */ - u8 lun; /* LUN */ - u8 bus; /* SCSI bus number */ - u8 priority; /* only 0 used */ - u32 sense_len; /* sense data length */ - u64 sense_data; /* sense data addr. */ - u32 sg_ranz; /* s/g element count */ - gdth_sg64_str sg_lst[GDTH_MAXSG]; /* s/g list */ - } __attribute__((packed)) raw64; /* raw service cmd. struct. */ - } u; - /* additional variables */ - u8 Service; /* controller service */ - u8 reserved; - u16 Status; /* command result */ - u32 Info; /* additional information */ - void *RequestBuffer; /* request buffer */ -} __attribute__((packed)) gdth_cmd_str; - -/* controller event structure */ -#define ES_ASYNC 1 -#define ES_DRIVER 2 -#define ES_TEST 3 -#define ES_SYNC 4 -typedef struct { - u16 size; /* size of structure */ - union { - char stream[16]; - struct { - u16 ionode; - u16 service; - u32 index; - } __attribute__((packed)) driver; - struct { - u16 ionode; - u16 service; - u16 status; - u32 info; - u8 scsi_coord[3]; - } __attribute__((packed)) async; - struct { - u16 ionode; - u16 service; - u16 status; - u32 info; - u16 hostdrive; - u8 scsi_coord[3]; - u8 sense_key; - } __attribute__((packed)) sync; - struct { - u32 l1, l2, l3, l4; - } __attribute__((packed)) test; - } eu; - u32 severity; - u8 event_string[256]; -} __attribute__((packed)) gdth_evt_data; - -typedef struct { - u32 first_stamp; - u32 last_stamp; - u16 same_count; - u16 event_source; - u16 event_idx; - u8 application; - u8 reserved; - gdth_evt_data event_data; -} __attribute__((packed)) gdth_evt_str; - -/* GDTIOCTL_GENERAL */ -typedef struct { - u16 ionode; /* controller number */ - u16 timeout; /* timeout */ - u32 info; /* error info */ - u16 status; /* status */ - unsigned long data_len; /* data buffer size */ - unsigned long sense_len; /* sense buffer size */ - gdth_cmd_str command; /* command */ -} gdth_ioctl_general; - -/* GDTIOCTL_LOCKDRV */ -typedef struct { - u16 ionode; /* controller number */ - u8 lock; /* lock/unlock */ - u8 drive_cnt; /* drive count */ - u16 drives[MAX_HDRIVES]; /* drives */ -} gdth_ioctl_lockdrv; - -/* GDTIOCTL_LOCKCHN */ -typedef struct { - u16 ionode; /* controller number */ - u8 lock; /* lock/unlock */ - u8 channel; /* channel */ -} gdth_ioctl_lockchn; - -/* GDTIOCTL_OSVERS */ -typedef struct { - u8 version; /* OS version */ - u8 subversion; /* OS subversion */ - u16 revision; /* revision */ -} gdth_ioctl_osvers; - -/* GDTIOCTL_CTRTYPE */ -typedef struct { - u16 ionode; /* controller number */ - u8 type; /* controller type */ - u16 info; /* slot etc. */ - u16 oem_id; /* OEM ID */ - u16 bios_ver; /* not used */ - u16 access; /* not used */ - u16 ext_type; /* extended type */ - u16 device_id; /* device ID */ - u16 sub_device_id; /* sub device ID */ -} gdth_ioctl_ctrtype; - -/* GDTIOCTL_EVENT */ -typedef struct { - u16 ionode; - int erase; /* erase event? */ - int handle; /* event handle */ - gdth_evt_str event; -} gdth_ioctl_event; - -/* GDTIOCTL_RESCAN/GDTIOCTL_HDRLIST */ -typedef struct { - u16 ionode; /* controller number */ - u8 flag; /* add/remove */ - u16 hdr_no; /* drive no. */ - struct { - u8 bus; /* SCSI bus */ - u8 target; /* target ID */ - u8 lun; /* LUN */ - u8 cluster_type; /* cluster properties */ - } hdr_list[MAX_HDRIVES]; /* index is host drive number */ -} gdth_ioctl_rescan; - -/* GDTIOCTL_RESET_BUS/GDTIOCTL_RESET_DRV */ -typedef struct { - u16 ionode; /* controller number */ - u16 number; /* bus/host drive number */ - u16 status; /* status */ -} gdth_ioctl_reset; - -#endif diff --git a/drivers/scsi/gdth_proc.c b/drivers/scsi/gdth_proc.c deleted file mode 100644 index c764312f9ba0..000000000000 --- a/drivers/scsi/gdth_proc.c +++ /dev/null @@ -1,586 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* gdth_proc.c - * $Id: gdth_proc.c,v 1.43 2006/01/11 16:15:00 achim Exp $ - */ - -#include -#include - -int gdth_set_info(struct Scsi_Host *host, char *buffer, int length) -{ - gdth_ha_str *ha = shost_priv(host); - int ret_val = -EINVAL; - - TRACE2(("gdth_set_info() ha %d\n",ha->hanum,)); - - if (length >= 4) { - if (strncmp(buffer,"gdth",4) == 0) { - buffer += 5; - length -= 5; - ret_val = gdth_set_asc_info(host, buffer, length, ha); - } - } - - return ret_val; -} - -static int gdth_set_asc_info(struct Scsi_Host *host, char *buffer, - int length, gdth_ha_str *ha) -{ - int orig_length, drive, wb_mode; - int i, found; - gdth_cmd_str gdtcmd; - gdth_cpar_str *pcpar; - - char cmnd[MAX_COMMAND_SIZE]; - memset(cmnd, 0xff, 12); - memset(&gdtcmd, 0, sizeof(gdth_cmd_str)); - - TRACE2(("gdth_set_asc_info() ha %d\n",ha->hanum)); - orig_length = length + 5; - drive = -1; - wb_mode = 0; - found = FALSE; - - if (length >= 5 && strncmp(buffer,"flush",5)==0) { - buffer += 6; - length -= 6; - if (length && *buffer>='0' && *buffer<='9') { - drive = (int)(*buffer-'0'); - ++buffer; --length; - if (length && *buffer>='0' && *buffer<='9') { - drive = drive*10 + (int)(*buffer-'0'); - ++buffer; --length; - } - printk("GDT: Flushing host drive %d .. ",drive); - } else { - printk("GDT: Flushing all host drives .. "); - } - for (i = 0; i < MAX_HDRIVES; ++i) { - if (ha->hdr[i].present) { - if (drive != -1 && i != drive) - continue; - found = TRUE; - gdtcmd.Service = CACHESERVICE; - gdtcmd.OpCode = GDT_FLUSH; - if (ha->cache_feat & GDT_64BIT) { - gdtcmd.u.cache64.DeviceNo = i; - gdtcmd.u.cache64.BlockNo = 1; - } else { - gdtcmd.u.cache.DeviceNo = i; - gdtcmd.u.cache.BlockNo = 1; - } - - gdth_execute(host, &gdtcmd, cmnd, 30, NULL); - } - } - if (!found) - printk("\nNo host drive found !\n"); - else - printk("Done.\n"); - return(orig_length); - } - - if (length >= 7 && strncmp(buffer,"wbp_off",7)==0) { - buffer += 8; - length -= 8; - printk("GDT: Disabling write back permanently .. "); - wb_mode = 1; - } else if (length >= 6 && strncmp(buffer,"wbp_on",6)==0) { - buffer += 7; - length -= 7; - printk("GDT: Enabling write back permanently .. "); - wb_mode = 2; - } else if (length >= 6 && strncmp(buffer,"wb_off",6)==0) { - buffer += 7; - length -= 7; - printk("GDT: Disabling write back commands .. "); - if (ha->cache_feat & GDT_WR_THROUGH) { - gdth_write_through = TRUE; - printk("Done.\n"); - } else { - printk("Not supported !\n"); - } - return(orig_length); - } else if (length >= 5 && strncmp(buffer,"wb_on",5)==0) { - buffer += 6; - length -= 6; - printk("GDT: Enabling write back commands .. "); - gdth_write_through = FALSE; - printk("Done.\n"); - return(orig_length); - } - - if (wb_mode) { - unsigned long flags; - - BUILD_BUG_ON(sizeof(gdth_cpar_str) > GDTH_SCRATCH); - - spin_lock_irqsave(&ha->smp_lock, flags); - if (ha->scratch_busy) { - spin_unlock_irqrestore(&ha->smp_lock, flags); - return -EBUSY; - } - ha->scratch_busy = TRUE; - spin_unlock_irqrestore(&ha->smp_lock, flags); - - pcpar = (gdth_cpar_str *)ha->pscratch; - memcpy( pcpar, &ha->cpar, sizeof(gdth_cpar_str) ); - gdtcmd.Service = CACHESERVICE; - gdtcmd.OpCode = GDT_IOCTL; - gdtcmd.u.ioctl.p_param = ha->scratch_phys; - gdtcmd.u.ioctl.param_size = sizeof(gdth_cpar_str); - gdtcmd.u.ioctl.subfunc = CACHE_CONFIG; - gdtcmd.u.ioctl.channel = INVALID_CHANNEL; - pcpar->write_back = wb_mode==1 ? 0:1; - - gdth_execute(host, &gdtcmd, cmnd, 30, NULL); - - spin_lock_irqsave(&ha->smp_lock, flags); - ha->scratch_busy = FALSE; - spin_unlock_irqrestore(&ha->smp_lock, flags); - - printk("Done.\n"); - return(orig_length); - } - - printk("GDT: Unknown command: %s Length: %d\n",buffer,length); - return(-EINVAL); -} - -int gdth_show_info(struct seq_file *m, struct Scsi_Host *host) -{ - gdth_ha_str *ha = shost_priv(host); - int hlen; - int id, i, j, k, sec, flag; - int no_mdrv = 0, drv_no, is_mirr; - u32 cnt; - dma_addr_t paddr; - int rc = -ENOMEM; - - gdth_cmd_str *gdtcmd; - gdth_evt_str *estr; - char hrec[277]; - - char *buf; - gdth_dskstat_str *pds; - gdth_diskinfo_str *pdi; - gdth_arrayinf_str *pai; - gdth_defcnt_str *pdef; - gdth_cdrinfo_str *pcdi; - gdth_hget_str *phg; - char cmnd[MAX_COMMAND_SIZE]; - - gdtcmd = kmalloc(sizeof(*gdtcmd), GFP_KERNEL); - estr = kmalloc(sizeof(*estr), GFP_KERNEL); - if (!gdtcmd || !estr) - goto free_fail; - - memset(cmnd, 0xff, 12); - memset(gdtcmd, 0, sizeof(gdth_cmd_str)); - - TRACE2(("gdth_get_info() ha %d\n",ha->hanum)); - - - /* request is i.e. "cat /proc/scsi/gdth/0" */ - /* format: %-15s\t%-10s\t%-15s\t%s */ - /* driver parameters */ - seq_puts(m, "Driver Parameters:\n"); - if (reserve_list[0] == 0xff) - strcpy(hrec, "--"); - else { - hlen = sprintf(hrec, "%d", reserve_list[0]); - for (i = 1; i < MAX_RES_ARGS; i++) { - if (reserve_list[i] == 0xff) - break; - hlen += scnprintf(hrec + hlen, 161 - hlen, ",%d", reserve_list[i]); - } - } - seq_printf(m, - " reserve_mode: \t%d \treserve_list: \t%s\n", - reserve_mode, hrec); - seq_printf(m, - " max_ids: \t%-3d \thdr_channel: \t%d\n", - max_ids, hdr_channel); - - /* controller information */ - seq_puts(m, "\nDisk Array Controller Information:\n"); - seq_printf(m, - " Number: \t%d \tName: \t%s\n", - ha->hanum, ha->binfo.type_string); - - seq_printf(m, - " Driver Ver.: \t%-10s\tFirmware Ver.: \t", - GDTH_VERSION_STR); - if (ha->more_proc) - seq_printf(m, "%d.%02d.%02d-%c%03X\n", - (u8)(ha->binfo.upd_fw_ver>>24), - (u8)(ha->binfo.upd_fw_ver>>16), - (u8)(ha->binfo.upd_fw_ver), - ha->bfeat.raid ? 'R':'N', - ha->binfo.upd_revision); - else - seq_printf(m, "%d.%02d\n", (u8)(ha->cpar.version>>8), - (u8)(ha->cpar.version)); - - if (ha->more_proc) - /* more information: 1. about controller */ - seq_printf(m, - " Serial No.: \t0x%8X\tCache RAM size:\t%d KB\n", - ha->binfo.ser_no, ha->binfo.memsize / 1024); - - if (ha->more_proc) { - size_t size = max_t(size_t, GDTH_SCRATCH, sizeof(gdth_hget_str)); - - /* more information: 2. about physical devices */ - seq_puts(m, "\nPhysical Devices:"); - flag = FALSE; - - buf = dma_alloc_coherent(&ha->pdev->dev, size, &paddr, GFP_KERNEL); - if (!buf) - goto stop_output; - for (i = 0; i < ha->bus_cnt; ++i) { - /* 2.a statistics (and retries/reassigns) */ - TRACE2(("pdr_statistics() chn %d\n",i)); - pds = (gdth_dskstat_str *)(buf + GDTH_SCRATCH/4); - gdtcmd->Service = CACHESERVICE; - gdtcmd->OpCode = GDT_IOCTL; - gdtcmd->u.ioctl.p_param = paddr + GDTH_SCRATCH/4; - gdtcmd->u.ioctl.param_size = 3*GDTH_SCRATCH/4; - gdtcmd->u.ioctl.subfunc = DSK_STATISTICS | L_CTRL_PATTERN; - gdtcmd->u.ioctl.channel = ha->raw[i].address | INVALID_CHANNEL; - pds->bid = ha->raw[i].local_no; - pds->first = 0; - pds->entries = ha->raw[i].pdev_cnt; - cnt = (3*GDTH_SCRATCH/4 - 5 * sizeof(u32)) / - sizeof(pds->list[0]); - if (pds->entries > cnt) - pds->entries = cnt; - - if (gdth_execute(host, gdtcmd, cmnd, 30, NULL) != S_OK) - pds->count = 0; - - /* other IOCTLs must fit into area GDTH_SCRATCH/4 */ - for (j = 0; j < ha->raw[i].pdev_cnt; ++j) { - /* 2.b drive info */ - TRACE2(("scsi_drv_info() chn %d dev %d\n", - i, ha->raw[i].id_list[j])); - pdi = (gdth_diskinfo_str *)buf; - gdtcmd->Service = CACHESERVICE; - gdtcmd->OpCode = GDT_IOCTL; - gdtcmd->u.ioctl.p_param = paddr; - gdtcmd->u.ioctl.param_size = sizeof(gdth_diskinfo_str); - gdtcmd->u.ioctl.subfunc = SCSI_DR_INFO | L_CTRL_PATTERN; - gdtcmd->u.ioctl.channel = - ha->raw[i].address | ha->raw[i].id_list[j]; - - if (gdth_execute(host, gdtcmd, cmnd, 30, NULL) == S_OK) { - strncpy(hrec,pdi->vendor,8); - strncpy(hrec+8,pdi->product,16); - strncpy(hrec+24,pdi->revision,4); - hrec[28] = 0; - seq_printf(m, - "\n Chn/ID/LUN: \t%c/%02d/%d \tName: \t%s\n", - 'A'+i,pdi->target_id,pdi->lun,hrec); - flag = TRUE; - pdi->no_ldrive &= 0xffff; - if (pdi->no_ldrive == 0xffff) - strcpy(hrec,"--"); - else - sprintf(hrec,"%d",pdi->no_ldrive); - seq_printf(m, - " Capacity [MB]:\t%-6d \tTo Log. Drive: \t%s\n", - pdi->blkcnt/(1024*1024/pdi->blksize), - hrec); - } else { - pdi->devtype = 0xff; - } - - if (pdi->devtype == 0) { - /* search retries/reassigns */ - for (k = 0; k < pds->count; ++k) { - if (pds->list[k].tid == pdi->target_id && - pds->list[k].lun == pdi->lun) { - seq_printf(m, - " Retries: \t%-6d \tReassigns: \t%d\n", - pds->list[k].retries, - pds->list[k].reassigns); - break; - } - } - /* 2.c grown defects */ - TRACE2(("scsi_drv_defcnt() chn %d dev %d\n", - i, ha->raw[i].id_list[j])); - pdef = (gdth_defcnt_str *)buf; - gdtcmd->Service = CACHESERVICE; - gdtcmd->OpCode = GDT_IOCTL; - gdtcmd->u.ioctl.p_param = paddr; - gdtcmd->u.ioctl.param_size = sizeof(gdth_defcnt_str); - gdtcmd->u.ioctl.subfunc = SCSI_DEF_CNT | L_CTRL_PATTERN; - gdtcmd->u.ioctl.channel = - ha->raw[i].address | ha->raw[i].id_list[j]; - pdef->sddc_type = 0x08; - - if (gdth_execute(host, gdtcmd, cmnd, 30, NULL) == S_OK) { - seq_printf(m, - " Grown Defects:\t%d\n", - pdef->sddc_cnt); - } - } - } - } - - if (!flag) - seq_puts(m, "\n --\n"); - - /* 3. about logical drives */ - seq_puts(m, "\nLogical Drives:"); - flag = FALSE; - - for (i = 0; i < MAX_LDRIVES; ++i) { - if (!ha->hdr[i].is_logdrv) - continue; - drv_no = i; - j = k = 0; - is_mirr = FALSE; - do { - /* 3.a log. drive info */ - TRACE2(("cache_drv_info() drive no %d\n",drv_no)); - pcdi = (gdth_cdrinfo_str *)buf; - gdtcmd->Service = CACHESERVICE; - gdtcmd->OpCode = GDT_IOCTL; - gdtcmd->u.ioctl.p_param = paddr; - gdtcmd->u.ioctl.param_size = sizeof(gdth_cdrinfo_str); - gdtcmd->u.ioctl.subfunc = CACHE_DRV_INFO; - gdtcmd->u.ioctl.channel = drv_no; - if (gdth_execute(host, gdtcmd, cmnd, 30, NULL) != S_OK) - break; - pcdi->ld_dtype >>= 16; - j++; - if (pcdi->ld_dtype > 2) { - strcpy(hrec, "missing"); - } else if (pcdi->ld_error & 1) { - strcpy(hrec, "fault"); - } else if (pcdi->ld_error & 2) { - strcpy(hrec, "invalid"); - k++; j--; - } else { - strcpy(hrec, "ok"); - } - - if (drv_no == i) { - seq_printf(m, - "\n Number: \t%-2d \tStatus: \t%s\n", - drv_no, hrec); - flag = TRUE; - no_mdrv = pcdi->cd_ldcnt; - if (no_mdrv > 1 || pcdi->ld_slave != -1) { - is_mirr = TRUE; - strcpy(hrec, "RAID-1"); - } else if (pcdi->ld_dtype == 0) { - strcpy(hrec, "Disk"); - } else if (pcdi->ld_dtype == 1) { - strcpy(hrec, "RAID-0"); - } else if (pcdi->ld_dtype == 2) { - strcpy(hrec, "Chain"); - } else { - strcpy(hrec, "???"); - } - seq_printf(m, - " Capacity [MB]:\t%-6d \tType: \t%s\n", - pcdi->ld_blkcnt/(1024*1024/pcdi->ld_blksize), - hrec); - } else { - seq_printf(m, - " Slave Number: \t%-2d \tStatus: \t%s\n", - drv_no & 0x7fff, hrec); - } - drv_no = pcdi->ld_slave; - } while (drv_no != -1); - - if (is_mirr) - seq_printf(m, - " Missing Drv.: \t%-2d \tInvalid Drv.: \t%d\n", - no_mdrv - j - k, k); - - if (!ha->hdr[i].is_arraydrv) - strcpy(hrec, "--"); - else - sprintf(hrec, "%d", ha->hdr[i].master_no); - seq_printf(m, - " To Array Drv.:\t%s\n", hrec); - } - - if (!flag) - seq_puts(m, "\n --\n"); - - /* 4. about array drives */ - seq_puts(m, "\nArray Drives:"); - flag = FALSE; - - for (i = 0; i < MAX_LDRIVES; ++i) { - if (!(ha->hdr[i].is_arraydrv && ha->hdr[i].is_master)) - continue; - /* 4.a array drive info */ - TRACE2(("array_info() drive no %d\n",i)); - pai = (gdth_arrayinf_str *)buf; - gdtcmd->Service = CACHESERVICE; - gdtcmd->OpCode = GDT_IOCTL; - gdtcmd->u.ioctl.p_param = paddr; - gdtcmd->u.ioctl.param_size = sizeof(gdth_arrayinf_str); - gdtcmd->u.ioctl.subfunc = ARRAY_INFO | LA_CTRL_PATTERN; - gdtcmd->u.ioctl.channel = i; - if (gdth_execute(host, gdtcmd, cmnd, 30, NULL) == S_OK) { - if (pai->ai_state == 0) - strcpy(hrec, "idle"); - else if (pai->ai_state == 2) - strcpy(hrec, "build"); - else if (pai->ai_state == 4) - strcpy(hrec, "ready"); - else if (pai->ai_state == 6) - strcpy(hrec, "fail"); - else if (pai->ai_state == 8 || pai->ai_state == 10) - strcpy(hrec, "rebuild"); - else - strcpy(hrec, "error"); - if (pai->ai_ext_state & 0x10) - strcat(hrec, "/expand"); - else if (pai->ai_ext_state & 0x1) - strcat(hrec, "/patch"); - seq_printf(m, - "\n Number: \t%-2d \tStatus: \t%s\n", - i,hrec); - flag = TRUE; - - if (pai->ai_type == 0) - strcpy(hrec, "RAID-0"); - else if (pai->ai_type == 4) - strcpy(hrec, "RAID-4"); - else if (pai->ai_type == 5) - strcpy(hrec, "RAID-5"); - else - strcpy(hrec, "RAID-10"); - seq_printf(m, - " Capacity [MB]:\t%-6d \tType: \t%s\n", - pai->ai_size/(1024*1024/pai->ai_secsize), - hrec); - } - } - - if (!flag) - seq_puts(m, "\n --\n"); - - /* 5. about host drives */ - seq_puts(m, "\nHost Drives:"); - flag = FALSE; - - for (i = 0; i < MAX_LDRIVES; ++i) { - if (!ha->hdr[i].is_logdrv || - (ha->hdr[i].is_arraydrv && !ha->hdr[i].is_master)) - continue; - /* 5.a get host drive list */ - TRACE2(("host_get() drv_no %d\n",i)); - phg = (gdth_hget_str *)buf; - gdtcmd->Service = CACHESERVICE; - gdtcmd->OpCode = GDT_IOCTL; - gdtcmd->u.ioctl.p_param = paddr; - gdtcmd->u.ioctl.param_size = sizeof(gdth_hget_str); - gdtcmd->u.ioctl.subfunc = HOST_GET | LA_CTRL_PATTERN; - gdtcmd->u.ioctl.channel = i; - phg->entries = MAX_HDRIVES; - phg->offset = GDTOFFSOF(gdth_hget_str, entry[0]); - if (gdth_execute(host, gdtcmd, cmnd, 30, NULL) == S_OK) { - ha->hdr[i].ldr_no = i; - ha->hdr[i].rw_attribs = 0; - ha->hdr[i].start_sec = 0; - } else { - for (j = 0; j < phg->entries; ++j) { - k = phg->entry[j].host_drive; - if (k >= MAX_LDRIVES) - continue; - ha->hdr[k].ldr_no = phg->entry[j].log_drive; - ha->hdr[k].rw_attribs = phg->entry[j].rw_attribs; - ha->hdr[k].start_sec = phg->entry[j].start_sec; - } - } - } - dma_free_coherent(&ha->pdev->dev, size, buf, paddr); - - for (i = 0; i < MAX_HDRIVES; ++i) { - if (!(ha->hdr[i].present)) - continue; - - seq_printf(m, - "\n Number: \t%-2d \tArr/Log. Drive:\t%d\n", - i, ha->hdr[i].ldr_no); - flag = TRUE; - - seq_printf(m, - " Capacity [MB]:\t%-6d \tStart Sector: \t%d\n", - (u32)(ha->hdr[i].size/2048), ha->hdr[i].start_sec); - } - - if (!flag) - seq_puts(m, "\n --\n"); - } - - /* controller events */ - seq_puts(m, "\nController Events:\n"); - - for (id = -1;;) { - id = gdth_read_event(ha, id, estr); - if (estr->event_source == 0) - break; - if (estr->event_data.eu.driver.ionode == ha->hanum && - estr->event_source == ES_ASYNC) { - gdth_log_event(&estr->event_data, hrec); - - /* - * Elapsed seconds subtraction with unsigned operands is - * safe from wrap around in year 2106. Executes as: - * operand a + (2's complement operand b) + 1 - */ - - sec = (int)((u32)ktime_get_real_seconds() - estr->first_stamp); - if (sec < 0) sec = 0; - seq_printf(m," date- %02d:%02d:%02d\t%s\n", - sec/3600, sec%3600/60, sec%60, hrec); - } - if (id == -1) - break; - } -stop_output: - rc = 0; -free_fail: - kfree(gdtcmd); - kfree(estr); - return rc; -} - -static void gdth_wait_completion(gdth_ha_str *ha, int busnum, int id) -{ - unsigned long flags; - int i; - struct scsi_cmnd *scp; - struct gdth_cmndinfo *cmndinfo; - u8 b, t; - - spin_lock_irqsave(&ha->smp_lock, flags); - - for (i = 0; i < GDTH_MAXCMDS; ++i) { - scp = ha->cmd_tab[i].cmnd; - cmndinfo = gdth_cmnd_priv(scp); - - b = scp->device->channel; - t = scp->device->id; - if (!SPECIAL_SCP(scp) && t == (u8)id && - b == (u8)busnum) { - cmndinfo->wait_for_completion = 0; - spin_unlock_irqrestore(&ha->smp_lock, flags); - while (!cmndinfo->wait_for_completion) - barrier(); - spin_lock_irqsave(&ha->smp_lock, flags); - } - } - spin_unlock_irqrestore(&ha->smp_lock, flags); -} diff --git a/drivers/scsi/gdth_proc.h b/drivers/scsi/gdth_proc.h deleted file mode 100644 index 4cc5377cb92e..000000000000 --- a/drivers/scsi/gdth_proc.h +++ /dev/null @@ -1,18 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -#ifndef _GDTH_PROC_H -#define _GDTH_PROC_H - -/* gdth_proc.h - * $Id: gdth_proc.h,v 1.16 2004/01/14 13:09:01 achim Exp $ - */ - -int gdth_execute(struct Scsi_Host *shost, gdth_cmd_str *gdtcmd, char *cmnd, - int timeout, u32 *info); - -static int gdth_set_asc_info(struct Scsi_Host *host, char *buffer, - int length, gdth_ha_str *ha); - -static void gdth_wait_completion(gdth_ha_str *ha, int busnum, int id); - -#endif - -- cgit v1.2.3 From 3f901c81dfad6930de5d4e6b582c4fde880cdada Mon Sep 17 00:00:00 2001 From: "Ahmed S. Darwish" Date: Mon, 18 Jan 2021 11:09:37 +0100 Subject: scsi: libsas: docs: Remove notify_ha_event() The ->notify_ha_event() hook has long been removed from the libsas event interface. Remove it from documentation. Link: https://lore.kernel.org/r/20210118100955.1761652-2-a.darwish@linutronix.de Fixes: 042ebd293b86 ("scsi: libsas: kill useless ha_event and do some cleanup") Cc: stable@vger.kernel.org Reviewed-by: John Garry Reviewed-by: Jack Wang Signed-off-by: Ahmed S. Darwish Signed-off-by: Martin K. Petersen --- Documentation/scsi/libsas.rst | 1 - 1 file changed, 1 deletion(-) (limited to 'Documentation') diff --git a/Documentation/scsi/libsas.rst b/Documentation/scsi/libsas.rst index 7216b5d25800..f9b77c7879db 100644 --- a/Documentation/scsi/libsas.rst +++ b/Documentation/scsi/libsas.rst @@ -189,7 +189,6 @@ num_phys The event interface:: /* LLDD calls these to notify the class of an event. */ - void (*notify_ha_event)(struct sas_ha_struct *, enum ha_event); void (*notify_port_event)(struct sas_phy *, enum port_event); void (*notify_phy_event)(struct sas_phy *, enum phy_event); -- cgit v1.2.3 From 121181f3f839c29d8dd9fdc3cc9babbdc74227f8 Mon Sep 17 00:00:00 2001 From: John Garry Date: Mon, 18 Jan 2021 11:09:38 +0100 Subject: scsi: libsas: Remove notifier indirection LLDDs report events to libsas with .notify_port_event and .notify_phy_event callbacks. These callbacks are fixed and so there is no reason why the functions cannot be called directly, so do that. This neatens the code slightly, makes it more obvious, and reduces function pointer usage, which is generally a good thing. Downside is that there are 2x more symbol exports. [a.darwish@linutronix.de: Remove the now unused "sas_ha" local variables] Link: https://lore.kernel.org/r/20210118100955.1761652-3-a.darwish@linutronix.de Reviewed-by: Christoph Hellwig Reviewed-by: Jack Wang Signed-off-by: John Garry Signed-off-by: Ahmed S. Darwish Signed-off-by: Martin K. Petersen --- Documentation/scsi/libsas.rst | 8 ++----- drivers/scsi/aic94xx/aic94xx_scb.c | 20 ++++++++--------- drivers/scsi/hisi_sas/hisi_sas_main.c | 12 ++++------ drivers/scsi/hisi_sas/hisi_sas_v1_hw.c | 3 +-- drivers/scsi/hisi_sas/hisi_sas_v2_hw.c | 3 +-- drivers/scsi/hisi_sas/hisi_sas_v3_hw.c | 3 +-- drivers/scsi/isci/port.c | 7 +++--- drivers/scsi/libsas/sas_event.c | 13 ++++------- drivers/scsi/libsas/sas_init.c | 6 ----- drivers/scsi/libsas/sas_internal.h | 1 - drivers/scsi/mvsas/mv_sas.c | 14 +++++------- drivers/scsi/pm8001/pm8001_hwi.c | 40 ++++++++++++++++------------------ drivers/scsi/pm8001/pm8001_sas.c | 7 ++---- drivers/scsi/pm8001/pm80xx_hwi.c | 35 +++++++++++++---------------- include/scsi/libsas.h | 7 +++--- 15 files changed, 69 insertions(+), 110 deletions(-) (limited to 'Documentation') diff --git a/Documentation/scsi/libsas.rst b/Documentation/scsi/libsas.rst index f9b77c7879db..6722e352444b 100644 --- a/Documentation/scsi/libsas.rst +++ b/Documentation/scsi/libsas.rst @@ -189,12 +189,8 @@ num_phys The event interface:: /* LLDD calls these to notify the class of an event. */ - void (*notify_port_event)(struct sas_phy *, enum port_event); - void (*notify_phy_event)(struct sas_phy *, enum phy_event); - -When sas_register_ha() returns, those are set and can be -called by the LLDD to notify the SAS layer of such events -the SAS layer. + void sas_notify_port_event(struct sas_phy *, enum port_event); + void sas_notify_phy_event(struct sas_phy *, enum phy_event); The port notification:: diff --git a/drivers/scsi/aic94xx/aic94xx_scb.c b/drivers/scsi/aic94xx/aic94xx_scb.c index 13677973da5c..770546177ca4 100644 --- a/drivers/scsi/aic94xx/aic94xx_scb.c +++ b/drivers/scsi/aic94xx/aic94xx_scb.c @@ -68,7 +68,6 @@ static void asd_phy_event_tasklet(struct asd_ascb *ascb, struct done_list_struct *dl) { struct asd_ha_struct *asd_ha = ascb->ha; - struct sas_ha_struct *sas_ha = &asd_ha->sas_ha; int phy_id = dl->status_block[0] & DL_PHY_MASK; struct asd_phy *phy = &asd_ha->phys[phy_id]; @@ -81,7 +80,7 @@ static void asd_phy_event_tasklet(struct asd_ascb *ascb, ASD_DPRINTK("phy%d: device unplugged\n", phy_id); asd_turn_led(asd_ha, phy_id, 0); sas_phy_disconnected(&phy->sas_phy); - sas_ha->notify_phy_event(&phy->sas_phy, PHYE_LOSS_OF_SIGNAL); + sas_notify_phy_event(&phy->sas_phy, PHYE_LOSS_OF_SIGNAL); break; case CURRENT_OOB_DONE: /* hot plugged device */ @@ -89,12 +88,12 @@ static void asd_phy_event_tasklet(struct asd_ascb *ascb, get_lrate_mode(phy, oob_mode); ASD_DPRINTK("phy%d device plugged: lrate:0x%x, proto:0x%x\n", phy_id, phy->sas_phy.linkrate, phy->sas_phy.iproto); - sas_ha->notify_phy_event(&phy->sas_phy, PHYE_OOB_DONE); + sas_notify_phy_event(&phy->sas_phy, PHYE_OOB_DONE); break; case CURRENT_SPINUP_HOLD: /* hot plug SATA, no COMWAKE sent */ asd_turn_led(asd_ha, phy_id, 1); - sas_ha->notify_phy_event(&phy->sas_phy, PHYE_SPINUP_HOLD); + sas_notify_phy_event(&phy->sas_phy, PHYE_SPINUP_HOLD); break; case CURRENT_GTO_TIMEOUT: case CURRENT_OOB_ERROR: @@ -102,7 +101,7 @@ static void asd_phy_event_tasklet(struct asd_ascb *ascb, dl->status_block[1]); asd_turn_led(asd_ha, phy_id, 0); sas_phy_disconnected(&phy->sas_phy); - sas_ha->notify_phy_event(&phy->sas_phy, PHYE_OOB_ERROR); + sas_notify_phy_event(&phy->sas_phy, PHYE_OOB_ERROR); break; } } @@ -222,7 +221,6 @@ static void asd_bytes_dmaed_tasklet(struct asd_ascb *ascb, int edb_el = edb_id + ascb->edb_index; struct asd_dma_tok *edb = ascb->ha->seq.edb_arr[edb_el]; struct asd_phy *phy = &ascb->ha->phys[phy_id]; - struct sas_ha_struct *sas_ha = phy->sas_phy.ha; u16 size = ((dl->status_block[3] & 7) << 8) | dl->status_block[2]; size = min(size, (u16) sizeof(phy->frame_rcvd)); @@ -234,7 +232,7 @@ static void asd_bytes_dmaed_tasklet(struct asd_ascb *ascb, spin_unlock_irqrestore(&phy->sas_phy.frame_rcvd_lock, flags); asd_dump_frame_rcvd(phy, dl); asd_form_port(ascb->ha, phy); - sas_ha->notify_port_event(&phy->sas_phy, PORTE_BYTES_DMAED); + sas_notify_port_event(&phy->sas_phy, PORTE_BYTES_DMAED); } static void asd_link_reset_err_tasklet(struct asd_ascb *ascb, @@ -270,7 +268,7 @@ static void asd_link_reset_err_tasklet(struct asd_ascb *ascb, asd_turn_led(asd_ha, phy_id, 0); sas_phy_disconnected(sas_phy); asd_deform_port(asd_ha, phy); - sas_ha->notify_port_event(sas_phy, PORTE_LINK_RESET_ERR); + sas_notify_port_event(sas_phy, PORTE_LINK_RESET_ERR); if (retries_left == 0) { int num = 1; @@ -315,7 +313,7 @@ static void asd_primitive_rcvd_tasklet(struct asd_ascb *ascb, spin_lock_irqsave(&sas_phy->sas_prim_lock, flags); sas_phy->sas_prim = ffs(cont); spin_unlock_irqrestore(&sas_phy->sas_prim_lock, flags); - sas_ha->notify_port_event(sas_phy,PORTE_BROADCAST_RCVD); + sas_notify_port_event(sas_phy, PORTE_BROADCAST_RCVD); break; case LmUNKNOWNP: @@ -336,7 +334,7 @@ static void asd_primitive_rcvd_tasklet(struct asd_ascb *ascb, /* The sequencer disables all phys on that port. * We have to re-enable the phys ourselves. */ asd_deform_port(asd_ha, phy); - sas_ha->notify_port_event(sas_phy, PORTE_HARD_RESET); + sas_notify_port_event(sas_phy, PORTE_HARD_RESET); break; default: @@ -567,7 +565,7 @@ static void escb_tasklet_complete(struct asd_ascb *ascb, /* the device is gone */ sas_phy_disconnected(sas_phy); asd_deform_port(asd_ha, phy); - sas_ha->notify_port_event(sas_phy, PORTE_TIMER_EVENT); + sas_notify_port_event(sas_phy, PORTE_TIMER_EVENT); break; default: ASD_DPRINTK("%s: phy%d: unknown event:0x%x\n", __func__, diff --git a/drivers/scsi/hisi_sas/hisi_sas_main.c b/drivers/scsi/hisi_sas/hisi_sas_main.c index cf0bfac920a8..76f8fc3fad59 100644 --- a/drivers/scsi/hisi_sas/hisi_sas_main.c +++ b/drivers/scsi/hisi_sas/hisi_sas_main.c @@ -616,7 +616,6 @@ static void hisi_sas_bytes_dmaed(struct hisi_hba *hisi_hba, int phy_no) { struct hisi_sas_phy *phy = &hisi_hba->phy[phy_no]; struct asd_sas_phy *sas_phy = &phy->sas_phy; - struct sas_ha_struct *sas_ha; if (!phy->phy_attached) return; @@ -627,8 +626,7 @@ static void hisi_sas_bytes_dmaed(struct hisi_hba *hisi_hba, int phy_no) return; } - sas_ha = &hisi_hba->sha; - sas_ha->notify_phy_event(sas_phy, PHYE_OOB_DONE); + sas_notify_phy_event(sas_phy, PHYE_OOB_DONE); if (sas_phy->phy) { struct sas_phy *sphy = sas_phy->phy; @@ -656,7 +654,7 @@ static void hisi_sas_bytes_dmaed(struct hisi_hba *hisi_hba, int phy_no) } sas_phy->frame_rcvd_size = phy->frame_rcvd_size; - sas_ha->notify_port_event(sas_phy, PORTE_BYTES_DMAED); + sas_notify_port_event(sas_phy, PORTE_BYTES_DMAED); } static struct hisi_sas_device *hisi_sas_alloc_dev(struct domain_device *device) @@ -1411,7 +1409,6 @@ static void hisi_sas_refresh_port_id(struct hisi_hba *hisi_hba) static void hisi_sas_rescan_topology(struct hisi_hba *hisi_hba, u32 state) { - struct sas_ha_struct *sas_ha = &hisi_hba->sha; struct asd_sas_port *_sas_port = NULL; int phy_no; @@ -1432,7 +1429,7 @@ static void hisi_sas_rescan_topology(struct hisi_hba *hisi_hba, u32 state) _sas_port = sas_port; if (dev_is_expander(dev->dev_type)) - sas_ha->notify_port_event(sas_phy, + sas_notify_port_event(sas_phy, PORTE_BROADCAST_RCVD); } } else { @@ -2194,7 +2191,6 @@ void hisi_sas_phy_down(struct hisi_hba *hisi_hba, int phy_no, int rdy) { struct hisi_sas_phy *phy = &hisi_hba->phy[phy_no]; struct asd_sas_phy *sas_phy = &phy->sas_phy; - struct sas_ha_struct *sas_ha = &hisi_hba->sha; struct device *dev = hisi_hba->dev; if (rdy) { @@ -2210,7 +2206,7 @@ void hisi_sas_phy_down(struct hisi_hba *hisi_hba, int phy_no, int rdy) return; } /* Phy down and not ready */ - sas_ha->notify_phy_event(sas_phy, PHYE_LOSS_OF_SIGNAL); + sas_notify_phy_event(sas_phy, PHYE_LOSS_OF_SIGNAL); sas_phy_disconnected(sas_phy); if (port) { diff --git a/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c index 45e866cb9164..22eecc89d41b 100644 --- a/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c +++ b/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c @@ -1408,7 +1408,6 @@ static irqreturn_t int_bcast_v1_hw(int irq, void *p) struct hisi_sas_phy *phy = p; struct hisi_hba *hisi_hba = phy->hisi_hba; struct asd_sas_phy *sas_phy = &phy->sas_phy; - struct sas_ha_struct *sha = &hisi_hba->sha; struct device *dev = hisi_hba->dev; int phy_no = sas_phy->id; u32 irq_value; @@ -1424,7 +1423,7 @@ static irqreturn_t int_bcast_v1_hw(int irq, void *p) } if (!test_bit(HISI_SAS_RESET_BIT, &hisi_hba->flags)) - sha->notify_port_event(sas_phy, PORTE_BROADCAST_RCVD); + sas_notify_port_event(sas_phy, PORTE_BROADCAST_RCVD); end: hisi_sas_phy_write32(hisi_hba, phy_no, CHL_INT2, diff --git a/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c index 9adfdefef9ca..10ba0680da04 100644 --- a/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c +++ b/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c @@ -2818,14 +2818,13 @@ static void phy_bcast_v2_hw(int phy_no, struct hisi_hba *hisi_hba) { struct hisi_sas_phy *phy = &hisi_hba->phy[phy_no]; struct asd_sas_phy *sas_phy = &phy->sas_phy; - struct sas_ha_struct *sas_ha = &hisi_hba->sha; u32 bcast_status; hisi_sas_phy_write32(hisi_hba, phy_no, SL_RX_BCAST_CHK_MSK, 1); bcast_status = hisi_sas_phy_read32(hisi_hba, phy_no, RX_PRIMS_STATUS); if ((bcast_status & RX_BCAST_CHG_MSK) && !test_bit(HISI_SAS_RESET_BIT, &hisi_hba->flags)) - sas_ha->notify_port_event(sas_phy, PORTE_BROADCAST_RCVD); + sas_notify_port_event(sas_phy, PORTE_BROADCAST_RCVD); hisi_sas_phy_write32(hisi_hba, phy_no, CHL_INT0, CHL_INT0_SL_RX_BCST_ACK_MSK); hisi_sas_phy_write32(hisi_hba, phy_no, SL_RX_BCAST_CHK_MSK, 0); diff --git a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c index 91a7286e8102..fcf427f46423 100644 --- a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c +++ b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c @@ -1595,14 +1595,13 @@ static irqreturn_t phy_bcast_v3_hw(int phy_no, struct hisi_hba *hisi_hba) { struct hisi_sas_phy *phy = &hisi_hba->phy[phy_no]; struct asd_sas_phy *sas_phy = &phy->sas_phy; - struct sas_ha_struct *sas_ha = &hisi_hba->sha; u32 bcast_status; hisi_sas_phy_write32(hisi_hba, phy_no, SL_RX_BCAST_CHK_MSK, 1); bcast_status = hisi_sas_phy_read32(hisi_hba, phy_no, RX_PRIMS_STATUS); if ((bcast_status & RX_BCAST_CHG_MSK) && !test_bit(HISI_SAS_RESET_BIT, &hisi_hba->flags)) - sas_ha->notify_port_event(sas_phy, PORTE_BROADCAST_RCVD); + sas_notify_port_event(sas_phy, PORTE_BROADCAST_RCVD); hisi_sas_phy_write32(hisi_hba, phy_no, CHL_INT0, CHL_INT0_SL_RX_BCST_ACK_MSK); hisi_sas_phy_write32(hisi_hba, phy_no, SL_RX_BCAST_CHK_MSK, 0); diff --git a/drivers/scsi/isci/port.c b/drivers/scsi/isci/port.c index 1df45f028ea7..8d9349738067 100644 --- a/drivers/scsi/isci/port.c +++ b/drivers/scsi/isci/port.c @@ -164,7 +164,7 @@ static void isci_port_bc_change_received(struct isci_host *ihost, "%s: isci_phy = %p, sas_phy = %p\n", __func__, iphy, &iphy->sas_phy); - ihost->sas_ha.notify_port_event(&iphy->sas_phy, PORTE_BROADCAST_RCVD); + sas_notify_port_event(&iphy->sas_phy, PORTE_BROADCAST_RCVD); sci_port_bcn_enable(iport); } @@ -223,8 +223,7 @@ static void isci_port_link_up(struct isci_host *isci_host, /* Notify libsas that we have an address frame, if indeed * we've found an SSP, SMP, or STP target */ if (success) - isci_host->sas_ha.notify_port_event(&iphy->sas_phy, - PORTE_BYTES_DMAED); + sas_notify_port_event(&iphy->sas_phy, PORTE_BYTES_DMAED); } @@ -270,7 +269,7 @@ static void isci_port_link_down(struct isci_host *isci_host, * isci_port_deformed and isci_dev_gone functions. */ sas_phy_disconnected(&isci_phy->sas_phy); - isci_host->sas_ha.notify_phy_event(&isci_phy->sas_phy, + sas_notify_phy_event(&isci_phy->sas_phy, PHYE_LOSS_OF_SIGNAL); dev_dbg(&isci_host->pdev->dev, diff --git a/drivers/scsi/libsas/sas_event.c b/drivers/scsi/libsas/sas_event.c index a1852f6c042b..112a1b76f63b 100644 --- a/drivers/scsi/libsas/sas_event.c +++ b/drivers/scsi/libsas/sas_event.c @@ -109,7 +109,7 @@ void sas_enable_revalidation(struct sas_ha_struct *ha) sas_phy = container_of(port->phy_list.next, struct asd_sas_phy, port_phy_el); - ha->notify_port_event(sas_phy, PORTE_BROADCAST_RCVD); + sas_notify_port_event(sas_phy, PORTE_BROADCAST_RCVD); } mutex_unlock(&ha->disco_mutex); } @@ -131,7 +131,7 @@ static void sas_phy_event_worker(struct work_struct *work) sas_free_event(ev); } -static int sas_notify_port_event(struct asd_sas_phy *phy, enum port_event event) +int sas_notify_port_event(struct asd_sas_phy *phy, enum port_event event) { struct asd_sas_event *ev; struct sas_ha_struct *ha = phy->ha; @@ -151,6 +151,7 @@ static int sas_notify_port_event(struct asd_sas_phy *phy, enum port_event event) return ret; } +EXPORT_SYMBOL_GPL(sas_notify_port_event); int sas_notify_phy_event(struct asd_sas_phy *phy, enum phy_event event) { @@ -172,11 +173,5 @@ int sas_notify_phy_event(struct asd_sas_phy *phy, enum phy_event event) return ret; } +EXPORT_SYMBOL_GPL(sas_notify_phy_event); -int sas_init_events(struct sas_ha_struct *sas_ha) -{ - sas_ha->notify_port_event = sas_notify_port_event; - sas_ha->notify_phy_event = sas_notify_phy_event; - - return 0; -} diff --git a/drivers/scsi/libsas/sas_init.c b/drivers/scsi/libsas/sas_init.c index 21c43b18d5d5..6dc2505d36af 100644 --- a/drivers/scsi/libsas/sas_init.c +++ b/drivers/scsi/libsas/sas_init.c @@ -123,12 +123,6 @@ int sas_register_ha(struct sas_ha_struct *sas_ha) goto Undo_phys; } - error = sas_init_events(sas_ha); - if (error) { - pr_notice("couldn't start event thread:%d\n", error); - goto Undo_ports; - } - error = -ENOMEM; snprintf(name, sizeof(name), "%s_event_q", dev_name(sas_ha->dev)); sas_ha->event_q = create_singlethread_workqueue(name); diff --git a/drivers/scsi/libsas/sas_internal.h b/drivers/scsi/libsas/sas_internal.h index 1f1d01901978..53ea32ed17a7 100644 --- a/drivers/scsi/libsas/sas_internal.h +++ b/drivers/scsi/libsas/sas_internal.h @@ -54,7 +54,6 @@ void sas_free_event(struct asd_sas_event *event); int sas_register_ports(struct sas_ha_struct *sas_ha); void sas_unregister_ports(struct sas_ha_struct *sas_ha); -int sas_init_events(struct sas_ha_struct *sas_ha); void sas_disable_revalidation(struct sas_ha_struct *ha); void sas_enable_revalidation(struct sas_ha_struct *ha); void __sas_drain_work(struct sas_ha_struct *ha); diff --git a/drivers/scsi/mvsas/mv_sas.c b/drivers/scsi/mvsas/mv_sas.c index a920eced92ec..e5e3e95f78b0 100644 --- a/drivers/scsi/mvsas/mv_sas.c +++ b/drivers/scsi/mvsas/mv_sas.c @@ -220,7 +220,7 @@ static void mvs_bytes_dmaed(struct mvs_info *mvi, int i) { struct mvs_phy *phy = &mvi->phy[i]; struct asd_sas_phy *sas_phy = &phy->sas_phy; - struct sas_ha_struct *sas_ha; + if (!phy->phy_attached) return; @@ -229,8 +229,7 @@ static void mvs_bytes_dmaed(struct mvs_info *mvi, int i) return; } - sas_ha = mvi->sas; - sas_ha->notify_phy_event(sas_phy, PHYE_OOB_DONE); + sas_notify_phy_event(sas_phy, PHYE_OOB_DONE); if (sas_phy->phy) { struct sas_phy *sphy = sas_phy->phy; @@ -262,8 +261,7 @@ static void mvs_bytes_dmaed(struct mvs_info *mvi, int i) sas_phy->frame_rcvd_size = phy->frame_rcvd_size; - mvi->sas->notify_port_event(sas_phy, - PORTE_BYTES_DMAED); + sas_notify_port_event(sas_phy, PORTE_BYTES_DMAED); } void mvs_scan_start(struct Scsi_Host *shost) @@ -1880,7 +1878,6 @@ static void mvs_work_queue(struct work_struct *work) struct mvs_info *mvi = mwq->mvi; unsigned long flags; u32 phy_no = (unsigned long) mwq->data; - struct sas_ha_struct *sas_ha = mvi->sas; struct mvs_phy *phy = &mvi->phy[phy_no]; struct asd_sas_phy *sas_phy = &phy->sas_phy; @@ -1895,7 +1892,7 @@ static void mvs_work_queue(struct work_struct *work) if (!(tmp & PHY_READY_MASK)) { sas_phy_disconnected(sas_phy); mvs_phy_disconnected(phy); - sas_ha->notify_phy_event(sas_phy, + sas_notify_phy_event(sas_phy, PHYE_LOSS_OF_SIGNAL); mv_dprintk("phy%d Removed Device\n", phy_no); } else { @@ -1908,8 +1905,7 @@ static void mvs_work_queue(struct work_struct *work) } } else if (mwq->handler & EXP_BRCT_CHG) { phy->phy_event &= ~EXP_BRCT_CHG; - sas_ha->notify_port_event(sas_phy, - PORTE_BROADCAST_RCVD); + sas_notify_port_event(sas_phy, PORTE_BROADCAST_RCVD); mv_dprintk("phy%d Got Broadcast Change\n", phy_no); } list_del(&mwq->entry); diff --git a/drivers/scsi/pm8001/pm8001_hwi.c b/drivers/scsi/pm8001/pm8001_hwi.c index 4bc11533fc91..f2c2c73fc9a5 100644 --- a/drivers/scsi/pm8001/pm8001_hwi.c +++ b/drivers/scsi/pm8001/pm8001_hwi.c @@ -3185,7 +3185,7 @@ void pm8001_bytes_dmaed(struct pm8001_hba_info *pm8001_ha, int i) pm8001_dbg(pm8001_ha, MSG, "phy %d byte dmaded.\n", i); sas_phy->frame_rcvd_size = phy->frame_rcvd_size; - pm8001_ha->sas->notify_port_event(sas_phy, PORTE_BYTES_DMAED); + sas_notify_port_event(sas_phy, PORTE_BYTES_DMAED); } /* Get the link rate speed */ @@ -3299,7 +3299,6 @@ hw_event_sas_phy_up(struct pm8001_hba_info *pm8001_ha, void *piomb) u32 npip_portstate = le32_to_cpu(pPayload->npip_portstate); u8 portstate = (u8)(npip_portstate & 0x0000000F); struct pm8001_port *port = &pm8001_ha->port[port_id]; - struct sas_ha_struct *sas_ha = pm8001_ha->sas; struct pm8001_phy *phy = &pm8001_ha->phy[phy_id]; unsigned long flags; u8 deviceType = pPayload->sas_identify.dev_type; @@ -3343,7 +3342,7 @@ hw_event_sas_phy_up(struct pm8001_hba_info *pm8001_ha, void *piomb) else if (phy->identify.device_type != SAS_PHY_UNUSED) phy->identify.target_port_protocols = SAS_PROTOCOL_SMP; phy->sas_phy.oob_mode = SAS_OOB_MODE; - sas_ha->notify_phy_event(&phy->sas_phy, PHYE_OOB_DONE); + sas_notify_phy_event(&phy->sas_phy, PHYE_OOB_DONE); spin_lock_irqsave(&phy->sas_phy.frame_rcvd_lock, flags); memcpy(phy->frame_rcvd, &pPayload->sas_identify, sizeof(struct sas_identify_frame)-4); @@ -3375,7 +3374,6 @@ hw_event_sata_phy_up(struct pm8001_hba_info *pm8001_ha, void *piomb) u32 npip_portstate = le32_to_cpu(pPayload->npip_portstate); u8 portstate = (u8)(npip_portstate & 0x0000000F); struct pm8001_port *port = &pm8001_ha->port[port_id]; - struct sas_ha_struct *sas_ha = pm8001_ha->sas; struct pm8001_phy *phy = &pm8001_ha->phy[phy_id]; unsigned long flags; pm8001_dbg(pm8001_ha, DEVIO, "HW_EVENT_SATA_PHY_UP port id = %d, phy id = %d\n", @@ -3387,7 +3385,7 @@ hw_event_sata_phy_up(struct pm8001_hba_info *pm8001_ha, void *piomb) phy->phy_type |= PORT_TYPE_SATA; phy->phy_attached = 1; phy->sas_phy.oob_mode = SATA_OOB_MODE; - sas_ha->notify_phy_event(&phy->sas_phy, PHYE_OOB_DONE); + sas_notify_phy_event(&phy->sas_phy, PHYE_OOB_DONE); spin_lock_irqsave(&phy->sas_phy.frame_rcvd_lock, flags); memcpy(phy->frame_rcvd, ((u8 *)&pPayload->sata_fis - 4), sizeof(struct dev_to_host_fis)); @@ -3734,11 +3732,11 @@ static int mpi_hw_event(struct pm8001_hba_info *pm8001_ha, void* piomb) break; case HW_EVENT_SATA_SPINUP_HOLD: pm8001_dbg(pm8001_ha, MSG, "HW_EVENT_SATA_SPINUP_HOLD\n"); - sas_ha->notify_phy_event(&phy->sas_phy, PHYE_SPINUP_HOLD); + sas_notify_phy_event(&phy->sas_phy, PHYE_SPINUP_HOLD); break; case HW_EVENT_PHY_DOWN: pm8001_dbg(pm8001_ha, MSG, "HW_EVENT_PHY_DOWN\n"); - sas_ha->notify_phy_event(&phy->sas_phy, PHYE_LOSS_OF_SIGNAL); + sas_notify_phy_event(&phy->sas_phy, PHYE_LOSS_OF_SIGNAL); phy->phy_attached = 0; phy->phy_state = 0; hw_event_phy_down(pm8001_ha, piomb); @@ -3747,7 +3745,7 @@ static int mpi_hw_event(struct pm8001_hba_info *pm8001_ha, void* piomb) pm8001_dbg(pm8001_ha, MSG, "HW_EVENT_PORT_INVALID\n"); sas_phy_disconnected(sas_phy); phy->phy_attached = 0; - sas_ha->notify_port_event(sas_phy, PORTE_LINK_RESET_ERR); + sas_notify_port_event(sas_phy, PORTE_LINK_RESET_ERR); break; /* the broadcast change primitive received, tell the LIBSAS this event to revalidate the sas domain*/ @@ -3758,20 +3756,20 @@ static int mpi_hw_event(struct pm8001_hba_info *pm8001_ha, void* piomb) spin_lock_irqsave(&sas_phy->sas_prim_lock, flags); sas_phy->sas_prim = HW_EVENT_BROADCAST_CHANGE; spin_unlock_irqrestore(&sas_phy->sas_prim_lock, flags); - sas_ha->notify_port_event(sas_phy, PORTE_BROADCAST_RCVD); + sas_notify_port_event(sas_phy, PORTE_BROADCAST_RCVD); break; case HW_EVENT_PHY_ERROR: pm8001_dbg(pm8001_ha, MSG, "HW_EVENT_PHY_ERROR\n"); sas_phy_disconnected(&phy->sas_phy); phy->phy_attached = 0; - sas_ha->notify_phy_event(&phy->sas_phy, PHYE_OOB_ERROR); + sas_notify_phy_event(&phy->sas_phy, PHYE_OOB_ERROR); break; case HW_EVENT_BROADCAST_EXP: pm8001_dbg(pm8001_ha, MSG, "HW_EVENT_BROADCAST_EXP\n"); spin_lock_irqsave(&sas_phy->sas_prim_lock, flags); sas_phy->sas_prim = HW_EVENT_BROADCAST_EXP; spin_unlock_irqrestore(&sas_phy->sas_prim_lock, flags); - sas_ha->notify_port_event(sas_phy, PORTE_BROADCAST_RCVD); + sas_notify_port_event(sas_phy, PORTE_BROADCAST_RCVD); break; case HW_EVENT_LINK_ERR_INVALID_DWORD: pm8001_dbg(pm8001_ha, MSG, @@ -3780,7 +3778,7 @@ static int mpi_hw_event(struct pm8001_hba_info *pm8001_ha, void* piomb) HW_EVENT_LINK_ERR_INVALID_DWORD, port_id, phy_id, 0, 0); sas_phy_disconnected(sas_phy); phy->phy_attached = 0; - sas_ha->notify_port_event(sas_phy, PORTE_LINK_RESET_ERR); + sas_notify_port_event(sas_phy, PORTE_LINK_RESET_ERR); break; case HW_EVENT_LINK_ERR_DISPARITY_ERROR: pm8001_dbg(pm8001_ha, MSG, @@ -3790,7 +3788,7 @@ static int mpi_hw_event(struct pm8001_hba_info *pm8001_ha, void* piomb) port_id, phy_id, 0, 0); sas_phy_disconnected(sas_phy); phy->phy_attached = 0; - sas_ha->notify_port_event(sas_phy, PORTE_LINK_RESET_ERR); + sas_notify_port_event(sas_phy, PORTE_LINK_RESET_ERR); break; case HW_EVENT_LINK_ERR_CODE_VIOLATION: pm8001_dbg(pm8001_ha, MSG, @@ -3800,7 +3798,7 @@ static int mpi_hw_event(struct pm8001_hba_info *pm8001_ha, void* piomb) port_id, phy_id, 0, 0); sas_phy_disconnected(sas_phy); phy->phy_attached = 0; - sas_ha->notify_port_event(sas_phy, PORTE_LINK_RESET_ERR); + sas_notify_port_event(sas_phy, PORTE_LINK_RESET_ERR); break; case HW_EVENT_LINK_ERR_LOSS_OF_DWORD_SYNCH: pm8001_dbg(pm8001_ha, MSG, @@ -3810,7 +3808,7 @@ static int mpi_hw_event(struct pm8001_hba_info *pm8001_ha, void* piomb) port_id, phy_id, 0, 0); sas_phy_disconnected(sas_phy); phy->phy_attached = 0; - sas_ha->notify_port_event(sas_phy, PORTE_LINK_RESET_ERR); + sas_notify_port_event(sas_phy, PORTE_LINK_RESET_ERR); break; case HW_EVENT_MALFUNCTION: pm8001_dbg(pm8001_ha, MSG, "HW_EVENT_MALFUNCTION\n"); @@ -3820,7 +3818,7 @@ static int mpi_hw_event(struct pm8001_hba_info *pm8001_ha, void* piomb) spin_lock_irqsave(&sas_phy->sas_prim_lock, flags); sas_phy->sas_prim = HW_EVENT_BROADCAST_SES; spin_unlock_irqrestore(&sas_phy->sas_prim_lock, flags); - sas_ha->notify_port_event(sas_phy, PORTE_BROADCAST_RCVD); + sas_notify_port_event(sas_phy, PORTE_BROADCAST_RCVD); break; case HW_EVENT_INBOUND_CRC_ERROR: pm8001_dbg(pm8001_ha, MSG, "HW_EVENT_INBOUND_CRC_ERROR\n"); @@ -3830,13 +3828,13 @@ static int mpi_hw_event(struct pm8001_hba_info *pm8001_ha, void* piomb) break; case HW_EVENT_HARD_RESET_RECEIVED: pm8001_dbg(pm8001_ha, MSG, "HW_EVENT_HARD_RESET_RECEIVED\n"); - sas_ha->notify_port_event(sas_phy, PORTE_HARD_RESET); + sas_notify_port_event(sas_phy, PORTE_HARD_RESET); break; case HW_EVENT_ID_FRAME_TIMEOUT: pm8001_dbg(pm8001_ha, MSG, "HW_EVENT_ID_FRAME_TIMEOUT\n"); sas_phy_disconnected(sas_phy); phy->phy_attached = 0; - sas_ha->notify_port_event(sas_phy, PORTE_LINK_RESET_ERR); + sas_notify_port_event(sas_phy, PORTE_LINK_RESET_ERR); break; case HW_EVENT_LINK_ERR_PHY_RESET_FAILED: pm8001_dbg(pm8001_ha, MSG, @@ -3846,20 +3844,20 @@ static int mpi_hw_event(struct pm8001_hba_info *pm8001_ha, void* piomb) port_id, phy_id, 0, 0); sas_phy_disconnected(sas_phy); phy->phy_attached = 0; - sas_ha->notify_port_event(sas_phy, PORTE_LINK_RESET_ERR); + sas_notify_port_event(sas_phy, PORTE_LINK_RESET_ERR); break; case HW_EVENT_PORT_RESET_TIMER_TMO: pm8001_dbg(pm8001_ha, MSG, "HW_EVENT_PORT_RESET_TIMER_TMO\n"); sas_phy_disconnected(sas_phy); phy->phy_attached = 0; - sas_ha->notify_port_event(sas_phy, PORTE_LINK_RESET_ERR); + sas_notify_port_event(sas_phy, PORTE_LINK_RESET_ERR); break; case HW_EVENT_PORT_RECOVERY_TIMER_TMO: pm8001_dbg(pm8001_ha, MSG, "HW_EVENT_PORT_RECOVERY_TIMER_TMO\n"); sas_phy_disconnected(sas_phy); phy->phy_attached = 0; - sas_ha->notify_port_event(sas_phy, PORTE_LINK_RESET_ERR); + sas_notify_port_event(sas_phy, PORTE_LINK_RESET_ERR); break; case HW_EVENT_PORT_RECOVER: pm8001_dbg(pm8001_ha, MSG, "HW_EVENT_PORT_RECOVER\n"); diff --git a/drivers/scsi/pm8001/pm8001_sas.c b/drivers/scsi/pm8001/pm8001_sas.c index f8d142f9b9ad..6af561a77c76 100644 --- a/drivers/scsi/pm8001/pm8001_sas.c +++ b/drivers/scsi/pm8001/pm8001_sas.c @@ -158,7 +158,6 @@ int pm8001_phy_control(struct asd_sas_phy *sas_phy, enum phy_func func, int rc = 0, phy_id = sas_phy->id; struct pm8001_hba_info *pm8001_ha = NULL; struct sas_phy_linkrates *rates; - struct sas_ha_struct *sas_ha; struct pm8001_phy *phy; DECLARE_COMPLETION_ONSTACK(completion); unsigned long flags; @@ -207,18 +206,16 @@ int pm8001_phy_control(struct asd_sas_phy *sas_phy, enum phy_func func, if (pm8001_ha->chip_id != chip_8001) { if (pm8001_ha->phy[phy_id].phy_state == PHY_STATE_LINK_UP_SPCV) { - sas_ha = pm8001_ha->sas; sas_phy_disconnected(&phy->sas_phy); - sas_ha->notify_phy_event(&phy->sas_phy, + sas_notify_phy_event(&phy->sas_phy, PHYE_LOSS_OF_SIGNAL); phy->phy_attached = 0; } } else { if (pm8001_ha->phy[phy_id].phy_state == PHY_STATE_LINK_UP_SPC) { - sas_ha = pm8001_ha->sas; sas_phy_disconnected(&phy->sas_phy); - sas_ha->notify_phy_event(&phy->sas_phy, + sas_notify_phy_event(&phy->sas_phy, PHYE_LOSS_OF_SIGNAL); phy->phy_attached = 0; } diff --git a/drivers/scsi/pm8001/pm80xx_hwi.c b/drivers/scsi/pm8001/pm80xx_hwi.c index 6fd206abc9fc..2cae479d0383 100644 --- a/drivers/scsi/pm8001/pm80xx_hwi.c +++ b/drivers/scsi/pm8001/pm80xx_hwi.c @@ -3294,7 +3294,6 @@ hw_event_sas_phy_up(struct pm8001_hba_info *pm8001_ha, void *piomb) u8 portstate = (u8)(phyid_npip_portstate & 0x0000000F); struct pm8001_port *port = &pm8001_ha->port[port_id]; - struct sas_ha_struct *sas_ha = pm8001_ha->sas; struct pm8001_phy *phy = &pm8001_ha->phy[phy_id]; unsigned long flags; u8 deviceType = pPayload->sas_identify.dev_type; @@ -3339,7 +3338,7 @@ hw_event_sas_phy_up(struct pm8001_hba_info *pm8001_ha, void *piomb) else if (phy->identify.device_type != SAS_PHY_UNUSED) phy->identify.target_port_protocols = SAS_PROTOCOL_SMP; phy->sas_phy.oob_mode = SAS_OOB_MODE; - sas_ha->notify_phy_event(&phy->sas_phy, PHYE_OOB_DONE); + sas_notify_phy_event(&phy->sas_phy, PHYE_OOB_DONE); spin_lock_irqsave(&phy->sas_phy.frame_rcvd_lock, flags); memcpy(phy->frame_rcvd, &pPayload->sas_identify, sizeof(struct sas_identify_frame)-4); @@ -3373,7 +3372,6 @@ hw_event_sata_phy_up(struct pm8001_hba_info *pm8001_ha, void *piomb) u8 portstate = (u8)(phyid_npip_portstate & 0x0000000F); struct pm8001_port *port = &pm8001_ha->port[port_id]; - struct sas_ha_struct *sas_ha = pm8001_ha->sas; struct pm8001_phy *phy = &pm8001_ha->phy[phy_id]; unsigned long flags; pm8001_dbg(pm8001_ha, DEVIO, @@ -3387,7 +3385,7 @@ hw_event_sata_phy_up(struct pm8001_hba_info *pm8001_ha, void *piomb) phy->phy_type |= PORT_TYPE_SATA; phy->phy_attached = 1; phy->sas_phy.oob_mode = SATA_OOB_MODE; - sas_ha->notify_phy_event(&phy->sas_phy, PHYE_OOB_DONE); + sas_notify_phy_event(&phy->sas_phy, PHYE_OOB_DONE); spin_lock_irqsave(&phy->sas_phy.frame_rcvd_lock, flags); memcpy(phy->frame_rcvd, ((u8 *)&pPayload->sata_fis - 4), sizeof(struct dev_to_host_fis)); @@ -3469,11 +3467,8 @@ hw_event_phy_down(struct pm8001_hba_info *pm8001_ha, void *piomb) break; } - if (port_sata && (portstate != PORT_IN_RESET)) { - struct sas_ha_struct *sas_ha = pm8001_ha->sas; - - sas_ha->notify_phy_event(&phy->sas_phy, PHYE_LOSS_OF_SIGNAL); - } + if (port_sata && (portstate != PORT_IN_RESET)) + sas_notify_phy_event(&phy->sas_phy, PHYE_LOSS_OF_SIGNAL); } static int mpi_phy_start_resp(struct pm8001_hba_info *pm8001_ha, void *piomb) @@ -3571,7 +3566,7 @@ static int mpi_hw_event(struct pm8001_hba_info *pm8001_ha, void *piomb) break; case HW_EVENT_SATA_SPINUP_HOLD: pm8001_dbg(pm8001_ha, MSG, "HW_EVENT_SATA_SPINUP_HOLD\n"); - sas_ha->notify_phy_event(&phy->sas_phy, PHYE_SPINUP_HOLD); + sas_notify_phy_event(&phy->sas_phy, PHYE_SPINUP_HOLD); break; case HW_EVENT_PHY_DOWN: pm8001_dbg(pm8001_ha, MSG, "HW_EVENT_PHY_DOWN\n"); @@ -3587,7 +3582,7 @@ static int mpi_hw_event(struct pm8001_hba_info *pm8001_ha, void *piomb) pm8001_dbg(pm8001_ha, MSG, "HW_EVENT_PORT_INVALID\n"); sas_phy_disconnected(sas_phy); phy->phy_attached = 0; - sas_ha->notify_port_event(sas_phy, PORTE_LINK_RESET_ERR); + sas_notify_port_event(sas_phy, PORTE_LINK_RESET_ERR); break; /* the broadcast change primitive received, tell the LIBSAS this event to revalidate the sas domain*/ @@ -3598,20 +3593,20 @@ static int mpi_hw_event(struct pm8001_hba_info *pm8001_ha, void *piomb) spin_lock_irqsave(&sas_phy->sas_prim_lock, flags); sas_phy->sas_prim = HW_EVENT_BROADCAST_CHANGE; spin_unlock_irqrestore(&sas_phy->sas_prim_lock, flags); - sas_ha->notify_port_event(sas_phy, PORTE_BROADCAST_RCVD); + sas_notify_port_event(sas_phy, PORTE_BROADCAST_RCVD); break; case HW_EVENT_PHY_ERROR: pm8001_dbg(pm8001_ha, MSG, "HW_EVENT_PHY_ERROR\n"); sas_phy_disconnected(&phy->sas_phy); phy->phy_attached = 0; - sas_ha->notify_phy_event(&phy->sas_phy, PHYE_OOB_ERROR); + sas_notify_phy_event(&phy->sas_phy, PHYE_OOB_ERROR); break; case HW_EVENT_BROADCAST_EXP: pm8001_dbg(pm8001_ha, MSG, "HW_EVENT_BROADCAST_EXP\n"); spin_lock_irqsave(&sas_phy->sas_prim_lock, flags); sas_phy->sas_prim = HW_EVENT_BROADCAST_EXP; spin_unlock_irqrestore(&sas_phy->sas_prim_lock, flags); - sas_ha->notify_port_event(sas_phy, PORTE_BROADCAST_RCVD); + sas_notify_port_event(sas_phy, PORTE_BROADCAST_RCVD); break; case HW_EVENT_LINK_ERR_INVALID_DWORD: pm8001_dbg(pm8001_ha, MSG, @@ -3648,7 +3643,7 @@ static int mpi_hw_event(struct pm8001_hba_info *pm8001_ha, void *piomb) spin_lock_irqsave(&sas_phy->sas_prim_lock, flags); sas_phy->sas_prim = HW_EVENT_BROADCAST_SES; spin_unlock_irqrestore(&sas_phy->sas_prim_lock, flags); - sas_ha->notify_port_event(sas_phy, PORTE_BROADCAST_RCVD); + sas_notify_port_event(sas_phy, PORTE_BROADCAST_RCVD); break; case HW_EVENT_INBOUND_CRC_ERROR: pm8001_dbg(pm8001_ha, MSG, "HW_EVENT_INBOUND_CRC_ERROR\n"); @@ -3658,13 +3653,13 @@ static int mpi_hw_event(struct pm8001_hba_info *pm8001_ha, void *piomb) break; case HW_EVENT_HARD_RESET_RECEIVED: pm8001_dbg(pm8001_ha, MSG, "HW_EVENT_HARD_RESET_RECEIVED\n"); - sas_ha->notify_port_event(sas_phy, PORTE_HARD_RESET); + sas_notify_port_event(sas_phy, PORTE_HARD_RESET); break; case HW_EVENT_ID_FRAME_TIMEOUT: pm8001_dbg(pm8001_ha, MSG, "HW_EVENT_ID_FRAME_TIMEOUT\n"); sas_phy_disconnected(sas_phy); phy->phy_attached = 0; - sas_ha->notify_port_event(sas_phy, PORTE_LINK_RESET_ERR); + sas_notify_port_event(sas_phy, PORTE_LINK_RESET_ERR); break; case HW_EVENT_LINK_ERR_PHY_RESET_FAILED: pm8001_dbg(pm8001_ha, MSG, @@ -3674,7 +3669,7 @@ static int mpi_hw_event(struct pm8001_hba_info *pm8001_ha, void *piomb) port_id, phy_id, 0, 0); sas_phy_disconnected(sas_phy); phy->phy_attached = 0; - sas_ha->notify_port_event(sas_phy, PORTE_LINK_RESET_ERR); + sas_notify_port_event(sas_phy, PORTE_LINK_RESET_ERR); break; case HW_EVENT_PORT_RESET_TIMER_TMO: pm8001_dbg(pm8001_ha, MSG, "HW_EVENT_PORT_RESET_TIMER_TMO\n"); @@ -3682,7 +3677,7 @@ static int mpi_hw_event(struct pm8001_hba_info *pm8001_ha, void *piomb) port_id, phy_id, 0, 0); sas_phy_disconnected(sas_phy); phy->phy_attached = 0; - sas_ha->notify_port_event(sas_phy, PORTE_LINK_RESET_ERR); + sas_notify_port_event(sas_phy, PORTE_LINK_RESET_ERR); if (pm8001_ha->phy[phy_id].reset_completion) { pm8001_ha->phy[phy_id].port_reset_status = PORT_RESET_TMO; @@ -3699,7 +3694,7 @@ static int mpi_hw_event(struct pm8001_hba_info *pm8001_ha, void *piomb) for (i = 0; i < pm8001_ha->chip->n_phy; i++) { if (port->wide_port_phymap & (1 << i)) { phy = &pm8001_ha->phy[i]; - sas_ha->notify_phy_event(&phy->sas_phy, + sas_notify_phy_event(&phy->sas_phy, PHYE_LOSS_OF_SIGNAL); port->wide_port_phymap &= ~(1 << i); } diff --git a/include/scsi/libsas.h b/include/scsi/libsas.h index 4e2d61e8fb1e..3387149502e9 100644 --- a/include/scsi/libsas.h +++ b/include/scsi/libsas.h @@ -391,10 +391,6 @@ struct sas_ha_struct { int strict_wide_ports; /* both sas_addr and attached_sas_addr must match * their siblings when forming wide ports */ - /* LLDD calls these to notify the class of an event. */ - int (*notify_port_event)(struct asd_sas_phy *, enum port_event); - int (*notify_phy_event)(struct asd_sas_phy *, enum phy_event); - void *lldd_ha; /* not touched by sas class code */ struct list_head eh_done_q; /* complete via scsi_eh_flush_done_q */ @@ -706,4 +702,7 @@ struct sas_phy *sas_get_local_phy(struct domain_device *dev); int sas_request_addr(struct Scsi_Host *shost, u8 *addr); +int sas_notify_port_event(struct asd_sas_phy *phy, enum port_event event); +int sas_notify_phy_event(struct asd_sas_phy *phy, enum phy_event event); + #endif /* _SASLIB_H_ */ -- cgit v1.2.3 From c2d0f1a65ab9fbabebb463bf36f50ea8f4633386 Mon Sep 17 00:00:00 2001 From: "Ahmed S. Darwish" Date: Mon, 18 Jan 2021 11:09:39 +0100 Subject: scsi: libsas: Introduce a _gfp() variant of event notifiers sas_alloc_event() uses in_interrupt() to decide which allocation should be used. The usage of in_interrupt() in drivers is phased out and Linus clearly requested that code which changes behaviour depending on context should either be separated or the context be conveyed in an argument passed by the caller, which usually knows the context. The in_interrupt() check is also only partially correct, because it fails to choose the correct code path when just preemption or interrupts are disabled. For example, as in the following call chain: mvsas/mv_sas.c: mvs_work_queue() [process context] spin_lock_irqsave(mvs_info::lock, ) -> libsas/sas_event.c: sas_notify_phy_event() -> sas_alloc_event() -> in_interrupt() = false -> invalid GFP_KERNEL allocation -> libsas/sas_event.c: sas_notify_port_event() -> sas_alloc_event() -> in_interrupt() = false -> invalid GFP_KERNEL allocation Introduce sas_alloc_event_gfp(), sas_notify_port_event_gfp(), and sas_notify_phy_event_gfp(), which all behave like the non _gfp() variants but use a caller-passed GFP mask for allocations. For bisectability, all callers will be modified first to pass GFP context, then the non _gfp() libsas API variants will be modified to take a gfp_t by default. Link: https://lore.kernel.org/r/20210118100955.1761652-4-a.darwish@linutronix.de Fixes: 1c393b970e0f ("scsi: libsas: Use dynamic alloced work to avoid sas event lost") Cc: Jason Yan Reviewed-by: John Garry Signed-off-by: Ahmed S. Darwish Signed-off-by: Martin K. Petersen --- Documentation/scsi/libsas.rst | 2 ++ drivers/scsi/libsas/sas_event.c | 65 +++++++++++++++++++++++++++++++------- drivers/scsi/libsas/sas_init.c | 21 +++++++++--- drivers/scsi/libsas/sas_internal.h | 4 +++ include/scsi/libsas.h | 4 +++ 5 files changed, 79 insertions(+), 17 deletions(-) (limited to 'Documentation') diff --git a/Documentation/scsi/libsas.rst b/Documentation/scsi/libsas.rst index 6722e352444b..ea63ab3a9216 100644 --- a/Documentation/scsi/libsas.rst +++ b/Documentation/scsi/libsas.rst @@ -191,6 +191,8 @@ The event interface:: /* LLDD calls these to notify the class of an event. */ void sas_notify_port_event(struct sas_phy *, enum port_event); void sas_notify_phy_event(struct sas_phy *, enum phy_event); + void sas_notify_port_event_gfp(struct sas_phy *, enum port_event, gfp_t); + void sas_notify_phy_event_gfp(struct sas_phy *, enum phy_event, gfp_t); The port notification:: diff --git a/drivers/scsi/libsas/sas_event.c b/drivers/scsi/libsas/sas_event.c index 112a1b76f63b..ba266a17250a 100644 --- a/drivers/scsi/libsas/sas_event.c +++ b/drivers/scsi/libsas/sas_event.c @@ -131,18 +131,15 @@ static void sas_phy_event_worker(struct work_struct *work) sas_free_event(ev); } -int sas_notify_port_event(struct asd_sas_phy *phy, enum port_event event) +static int __sas_notify_port_event(struct asd_sas_phy *phy, + enum port_event event, + struct asd_sas_event *ev) { - struct asd_sas_event *ev; struct sas_ha_struct *ha = phy->ha; int ret; BUG_ON(event >= PORT_NUM_EVENTS); - ev = sas_alloc_event(phy); - if (!ev) - return -ENOMEM; - INIT_SAS_EVENT(ev, sas_port_event_worker, phy, event); ret = sas_queue_event(event, &ev->work, ha); @@ -151,20 +148,41 @@ int sas_notify_port_event(struct asd_sas_phy *phy, enum port_event event) return ret; } -EXPORT_SYMBOL_GPL(sas_notify_port_event); -int sas_notify_phy_event(struct asd_sas_phy *phy, enum phy_event event) +int sas_notify_port_event_gfp(struct asd_sas_phy *phy, enum port_event event, + gfp_t gfp_flags) { struct asd_sas_event *ev; - struct sas_ha_struct *ha = phy->ha; - int ret; - BUG_ON(event >= PHY_NUM_EVENTS); + ev = sas_alloc_event_gfp(phy, gfp_flags); + if (!ev) + return -ENOMEM; + + return __sas_notify_port_event(phy, event, ev); +} +EXPORT_SYMBOL_GPL(sas_notify_port_event_gfp); + +int sas_notify_port_event(struct asd_sas_phy *phy, enum port_event event) +{ + struct asd_sas_event *ev; ev = sas_alloc_event(phy); if (!ev) return -ENOMEM; + return __sas_notify_port_event(phy, event, ev); +} +EXPORT_SYMBOL_GPL(sas_notify_port_event); + +static inline int __sas_notify_phy_event(struct asd_sas_phy *phy, + enum phy_event event, + struct asd_sas_event *ev) +{ + struct sas_ha_struct *ha = phy->ha; + int ret; + + BUG_ON(event >= PHY_NUM_EVENTS); + INIT_SAS_EVENT(ev, sas_phy_event_worker, phy, event); ret = sas_queue_event(event, &ev->work, ha); @@ -173,5 +191,28 @@ int sas_notify_phy_event(struct asd_sas_phy *phy, enum phy_event event) return ret; } -EXPORT_SYMBOL_GPL(sas_notify_phy_event); +int sas_notify_phy_event_gfp(struct asd_sas_phy *phy, enum phy_event event, + gfp_t gfp_flags) +{ + struct asd_sas_event *ev; + + ev = sas_alloc_event_gfp(phy, gfp_flags); + if (!ev) + return -ENOMEM; + + return __sas_notify_phy_event(phy, event, ev); +} +EXPORT_SYMBOL_GPL(sas_notify_phy_event_gfp); + +int sas_notify_phy_event(struct asd_sas_phy *phy, enum phy_event event) +{ + struct asd_sas_event *ev; + + ev = sas_alloc_event(phy); + if (!ev) + return -ENOMEM; + + return __sas_notify_phy_event(phy, event, ev); +} +EXPORT_SYMBOL_GPL(sas_notify_phy_event); diff --git a/drivers/scsi/libsas/sas_init.c b/drivers/scsi/libsas/sas_init.c index 6dc2505d36af..f8ae1f0f17d3 100644 --- a/drivers/scsi/libsas/sas_init.c +++ b/drivers/scsi/libsas/sas_init.c @@ -584,16 +584,15 @@ sas_domain_attach_transport(struct sas_domain_function_template *dft) } EXPORT_SYMBOL_GPL(sas_domain_attach_transport); - -struct asd_sas_event *sas_alloc_event(struct asd_sas_phy *phy) +static struct asd_sas_event *__sas_alloc_event(struct asd_sas_phy *phy, + gfp_t gfp_flags) { struct asd_sas_event *event; - gfp_t flags = in_interrupt() ? GFP_ATOMIC : GFP_KERNEL; struct sas_ha_struct *sas_ha = phy->ha; struct sas_internal *i = to_sas_internal(sas_ha->core.shost->transportt); - event = kmem_cache_zalloc(sas_event_cache, flags); + event = kmem_cache_zalloc(sas_event_cache, gfp_flags); if (!event) return NULL; @@ -604,7 +603,8 @@ struct asd_sas_event *sas_alloc_event(struct asd_sas_phy *phy) if (cmpxchg(&phy->in_shutdown, 0, 1) == 0) { pr_notice("The phy%d bursting events, shut it down.\n", phy->id); - sas_notify_phy_event(phy, PHYE_SHUTDOWN); + sas_notify_phy_event_gfp(phy, PHYE_SHUTDOWN, + gfp_flags); } } else { /* Do not support PHY control, stop allocating events */ @@ -618,6 +618,17 @@ struct asd_sas_event *sas_alloc_event(struct asd_sas_phy *phy) return event; } +struct asd_sas_event *sas_alloc_event(struct asd_sas_phy *phy) +{ + return __sas_alloc_event(phy, in_interrupt() ? GFP_ATOMIC : GFP_KERNEL); +} + +struct asd_sas_event *sas_alloc_event_gfp(struct asd_sas_phy *phy, + gfp_t gfp_flags) +{ + return __sas_alloc_event(phy, gfp_flags); +} + void sas_free_event(struct asd_sas_event *event) { struct asd_sas_phy *phy = event->phy; diff --git a/drivers/scsi/libsas/sas_internal.h b/drivers/scsi/libsas/sas_internal.h index 53ea32ed17a7..52e09c3e2b50 100644 --- a/drivers/scsi/libsas/sas_internal.h +++ b/drivers/scsi/libsas/sas_internal.h @@ -49,6 +49,8 @@ int sas_register_phys(struct sas_ha_struct *sas_ha); void sas_unregister_phys(struct sas_ha_struct *sas_ha); struct asd_sas_event *sas_alloc_event(struct asd_sas_phy *phy); +struct asd_sas_event *sas_alloc_event_gfp(struct asd_sas_phy *phy, + gfp_t gfp_flags); void sas_free_event(struct asd_sas_event *event); int sas_register_ports(struct sas_ha_struct *sas_ha); @@ -77,6 +79,8 @@ int sas_smp_phy_control(struct domain_device *dev, int phy_id, int sas_smp_get_phy_events(struct sas_phy *phy); int sas_notify_phy_event(struct asd_sas_phy *phy, enum phy_event event); +int sas_notify_phy_event_gfp(struct asd_sas_phy *phy, enum phy_event event, + gfp_t flags); void sas_device_set_phy(struct domain_device *dev, struct sas_port *port); struct domain_device *sas_find_dev_by_rphy(struct sas_rphy *rphy); struct domain_device *sas_ex_to_ata(struct domain_device *ex_dev, int phy_id); diff --git a/include/scsi/libsas.h b/include/scsi/libsas.h index 3387149502e9..e6a43163ab5b 100644 --- a/include/scsi/libsas.h +++ b/include/scsi/libsas.h @@ -704,5 +704,9 @@ int sas_request_addr(struct Scsi_Host *shost, u8 *addr); int sas_notify_port_event(struct asd_sas_phy *phy, enum port_event event); int sas_notify_phy_event(struct asd_sas_phy *phy, enum phy_event event); +int sas_notify_port_event_gfp(struct asd_sas_phy *phy, enum port_event event, + gfp_t gfp_flags); +int sas_notify_phy_event_gfp(struct asd_sas_phy *phy, enum phy_event event, + gfp_t gfp_flags); #endif /* _SASLIB_H_ */ -- cgit v1.2.3 From 5d6a75a1edf63ff243d937253ced62d8edea30b5 Mon Sep 17 00:00:00 2001 From: "Ahmed S. Darwish" Date: Mon, 18 Jan 2021 11:09:48 +0100 Subject: scsi: libsas: Add gfp_t flags parameter to event notifications All call-sites of below libsas APIs: - sas_alloc_event() - sas_notify_port_event() - sas_notify_phy_event() have been converted to use the _gfp()-suffixed version. Modify the original APIs above to take a gfp_t flags parameter by default. For bisectability, call-sites will be modified again to use the original libsas APIs (while passing gfp_t). The temporary _gfp()-suffixed versions can then be removed. Link: https://lore.kernel.org/r/20210118100955.1761652-13-a.darwish@linutronix.de Cc: Jason Yan Reviewed-by: John Garry Signed-off-by: Ahmed S. Darwish Signed-off-by: Martin K. Petersen --- Documentation/scsi/libsas.rst | 4 +-- drivers/scsi/libsas/sas_event.c | 62 +++++++++++--------------------------- drivers/scsi/libsas/sas_init.c | 12 +++----- drivers/scsi/libsas/sas_internal.h | 5 +-- include/scsi/libsas.h | 6 ++-- 5 files changed, 31 insertions(+), 58 deletions(-) (limited to 'Documentation') diff --git a/Documentation/scsi/libsas.rst b/Documentation/scsi/libsas.rst index ea63ab3a9216..c65086470a15 100644 --- a/Documentation/scsi/libsas.rst +++ b/Documentation/scsi/libsas.rst @@ -189,8 +189,8 @@ num_phys The event interface:: /* LLDD calls these to notify the class of an event. */ - void sas_notify_port_event(struct sas_phy *, enum port_event); - void sas_notify_phy_event(struct sas_phy *, enum phy_event); + void sas_notify_port_event(struct sas_phy *, enum port_event, gfp_t); + void sas_notify_phy_event(struct sas_phy *, enum phy_event, gfp_t); void sas_notify_port_event_gfp(struct sas_phy *, enum port_event, gfp_t); void sas_notify_phy_event_gfp(struct sas_phy *, enum phy_event, gfp_t); diff --git a/drivers/scsi/libsas/sas_event.c b/drivers/scsi/libsas/sas_event.c index 25f3aaea8142..3d0cc407b33f 100644 --- a/drivers/scsi/libsas/sas_event.c +++ b/drivers/scsi/libsas/sas_event.c @@ -132,15 +132,19 @@ static void sas_phy_event_worker(struct work_struct *work) sas_free_event(ev); } -static int __sas_notify_port_event(struct asd_sas_phy *phy, - enum port_event event, - struct asd_sas_event *ev) +int sas_notify_port_event(struct asd_sas_phy *phy, enum port_event event, + gfp_t gfp_flags) { struct sas_ha_struct *ha = phy->ha; + struct asd_sas_event *ev; int ret; BUG_ON(event >= PORT_NUM_EVENTS); + ev = sas_alloc_event_gfp(phy, gfp_flags); + if (!ev) + return -ENOMEM; + INIT_SAS_EVENT(ev, sas_port_event_worker, phy, event); ret = sas_queue_event(event, &ev->work, ha); @@ -149,41 +153,28 @@ static int __sas_notify_port_event(struct asd_sas_phy *phy, return ret; } +EXPORT_SYMBOL_GPL(sas_notify_port_event); int sas_notify_port_event_gfp(struct asd_sas_phy *phy, enum port_event event, gfp_t gfp_flags) { - struct asd_sas_event *ev; - - ev = sas_alloc_event_gfp(phy, gfp_flags); - if (!ev) - return -ENOMEM; - - return __sas_notify_port_event(phy, event, ev); + return sas_notify_port_event(phy, event, gfp_flags); } EXPORT_SYMBOL_GPL(sas_notify_port_event_gfp); -int sas_notify_port_event(struct asd_sas_phy *phy, enum port_event event) -{ - struct asd_sas_event *ev; - - ev = sas_alloc_event(phy); - if (!ev) - return -ENOMEM; - - return __sas_notify_port_event(phy, event, ev); -} -EXPORT_SYMBOL_GPL(sas_notify_port_event); - -static inline int __sas_notify_phy_event(struct asd_sas_phy *phy, - enum phy_event event, - struct asd_sas_event *ev) +int sas_notify_phy_event(struct asd_sas_phy *phy, enum phy_event event, + gfp_t gfp_flags) { struct sas_ha_struct *ha = phy->ha; + struct asd_sas_event *ev; int ret; BUG_ON(event >= PHY_NUM_EVENTS); + ev = sas_alloc_event_gfp(phy, gfp_flags); + if (!ev) + return -ENOMEM; + INIT_SAS_EVENT(ev, sas_phy_event_worker, phy, event); ret = sas_queue_event(event, &ev->work, ha); @@ -192,28 +183,11 @@ static inline int __sas_notify_phy_event(struct asd_sas_phy *phy, return ret; } +EXPORT_SYMBOL_GPL(sas_notify_phy_event); int sas_notify_phy_event_gfp(struct asd_sas_phy *phy, enum phy_event event, gfp_t gfp_flags) { - struct asd_sas_event *ev; - - ev = sas_alloc_event_gfp(phy, gfp_flags); - if (!ev) - return -ENOMEM; - - return __sas_notify_phy_event(phy, event, ev); + return sas_notify_phy_event(phy, event, gfp_flags); } EXPORT_SYMBOL_GPL(sas_notify_phy_event_gfp); - -int sas_notify_phy_event(struct asd_sas_phy *phy, enum phy_event event) -{ - struct asd_sas_event *ev; - - ev = sas_alloc_event(phy); - if (!ev) - return -ENOMEM; - - return __sas_notify_phy_event(phy, event, ev); -} -EXPORT_SYMBOL_GPL(sas_notify_phy_event); diff --git a/drivers/scsi/libsas/sas_init.c b/drivers/scsi/libsas/sas_init.c index 9ce0cd214eb9..f06b83211e3b 100644 --- a/drivers/scsi/libsas/sas_init.c +++ b/drivers/scsi/libsas/sas_init.c @@ -585,8 +585,8 @@ sas_domain_attach_transport(struct sas_domain_function_template *dft) } EXPORT_SYMBOL_GPL(sas_domain_attach_transport); -static struct asd_sas_event *__sas_alloc_event(struct asd_sas_phy *phy, - gfp_t gfp_flags) +struct asd_sas_event *sas_alloc_event(struct asd_sas_phy *phy, + gfp_t gfp_flags) { struct asd_sas_event *event; struct sas_ha_struct *sas_ha = phy->ha; @@ -619,15 +619,11 @@ static struct asd_sas_event *__sas_alloc_event(struct asd_sas_phy *phy, return event; } -struct asd_sas_event *sas_alloc_event(struct asd_sas_phy *phy) -{ - return __sas_alloc_event(phy, in_interrupt() ? GFP_ATOMIC : GFP_KERNEL); -} - struct asd_sas_event *sas_alloc_event_gfp(struct asd_sas_phy *phy, gfp_t gfp_flags) { - return __sas_alloc_event(phy, gfp_flags); + + return sas_alloc_event(phy, gfp_flags); } void sas_free_event(struct asd_sas_event *event) diff --git a/drivers/scsi/libsas/sas_internal.h b/drivers/scsi/libsas/sas_internal.h index 52e09c3e2b50..294cdcb4ce42 100644 --- a/drivers/scsi/libsas/sas_internal.h +++ b/drivers/scsi/libsas/sas_internal.h @@ -48,7 +48,7 @@ int sas_show_oob_mode(enum sas_oob_mode oob_mode, char *buf); int sas_register_phys(struct sas_ha_struct *sas_ha); void sas_unregister_phys(struct sas_ha_struct *sas_ha); -struct asd_sas_event *sas_alloc_event(struct asd_sas_phy *phy); +struct asd_sas_event *sas_alloc_event(struct asd_sas_phy *phy, gfp_t gfp_flags); struct asd_sas_event *sas_alloc_event_gfp(struct asd_sas_phy *phy, gfp_t gfp_flags); void sas_free_event(struct asd_sas_event *event); @@ -78,7 +78,8 @@ int sas_smp_phy_control(struct domain_device *dev, int phy_id, enum phy_func phy_func, struct sas_phy_linkrates *); int sas_smp_get_phy_events(struct sas_phy *phy); -int sas_notify_phy_event(struct asd_sas_phy *phy, enum phy_event event); +int sas_notify_phy_event(struct asd_sas_phy *phy, enum phy_event event, + gfp_t flags); int sas_notify_phy_event_gfp(struct asd_sas_phy *phy, enum phy_event event, gfp_t flags); void sas_device_set_phy(struct domain_device *dev, struct sas_port *port); diff --git a/include/scsi/libsas.h b/include/scsi/libsas.h index e6a43163ab5b..fda56e151695 100644 --- a/include/scsi/libsas.h +++ b/include/scsi/libsas.h @@ -702,8 +702,10 @@ struct sas_phy *sas_get_local_phy(struct domain_device *dev); int sas_request_addr(struct Scsi_Host *shost, u8 *addr); -int sas_notify_port_event(struct asd_sas_phy *phy, enum port_event event); -int sas_notify_phy_event(struct asd_sas_phy *phy, enum phy_event event); +int sas_notify_port_event(struct asd_sas_phy *phy, enum port_event event, + gfp_t gfp_flags); +int sas_notify_phy_event(struct asd_sas_phy *phy, enum phy_event event, + gfp_t gfp_flags); int sas_notify_port_event_gfp(struct asd_sas_phy *phy, enum port_event event, gfp_t gfp_flags); int sas_notify_phy_event_gfp(struct asd_sas_phy *phy, enum phy_event event, -- cgit v1.2.3 From 65f7cfba6196baf2fc06ac0ab0be764377f3206a Mon Sep 17 00:00:00 2001 From: "Ahmed S. Darwish" Date: Mon, 18 Jan 2021 11:09:55 +0100 Subject: scsi: libsas: Remove temporarily-added _gfp() API variants These variants were added for bisectability. Remove them, as all call sites have now been convertd to use the original API. Link: https://lore.kernel.org/r/20210118100955.1761652-20-a.darwish@linutronix.de Cc: Jason Yan Reviewed-by: John Garry Signed-off-by: Ahmed S. Darwish Signed-off-by: Martin K. Petersen --- Documentation/scsi/libsas.rst | 2 -- drivers/scsi/libsas/sas_event.c | 14 -------------- drivers/scsi/libsas/sas_init.c | 7 ------- drivers/scsi/libsas/sas_internal.h | 4 ---- include/scsi/libsas.h | 4 ---- 5 files changed, 31 deletions(-) (limited to 'Documentation') diff --git a/Documentation/scsi/libsas.rst b/Documentation/scsi/libsas.rst index c65086470a15..6589dfefbc02 100644 --- a/Documentation/scsi/libsas.rst +++ b/Documentation/scsi/libsas.rst @@ -191,8 +191,6 @@ The event interface:: /* LLDD calls these to notify the class of an event. */ void sas_notify_port_event(struct sas_phy *, enum port_event, gfp_t); void sas_notify_phy_event(struct sas_phy *, enum phy_event, gfp_t); - void sas_notify_port_event_gfp(struct sas_phy *, enum port_event, gfp_t); - void sas_notify_phy_event_gfp(struct sas_phy *, enum phy_event, gfp_t); The port notification:: diff --git a/drivers/scsi/libsas/sas_event.c b/drivers/scsi/libsas/sas_event.c index 542831887769..f703115e7a25 100644 --- a/drivers/scsi/libsas/sas_event.c +++ b/drivers/scsi/libsas/sas_event.c @@ -155,13 +155,6 @@ int sas_notify_port_event(struct asd_sas_phy *phy, enum port_event event, } EXPORT_SYMBOL_GPL(sas_notify_port_event); -int sas_notify_port_event_gfp(struct asd_sas_phy *phy, enum port_event event, - gfp_t gfp_flags) -{ - return sas_notify_port_event(phy, event, gfp_flags); -} -EXPORT_SYMBOL_GPL(sas_notify_port_event_gfp); - int sas_notify_phy_event(struct asd_sas_phy *phy, enum phy_event event, gfp_t gfp_flags) { @@ -184,10 +177,3 @@ int sas_notify_phy_event(struct asd_sas_phy *phy, enum phy_event event, return ret; } EXPORT_SYMBOL_GPL(sas_notify_phy_event); - -int sas_notify_phy_event_gfp(struct asd_sas_phy *phy, enum phy_event event, - gfp_t gfp_flags) -{ - return sas_notify_phy_event(phy, event, gfp_flags); -} -EXPORT_SYMBOL_GPL(sas_notify_phy_event_gfp); diff --git a/drivers/scsi/libsas/sas_init.c b/drivers/scsi/libsas/sas_init.c index 62260e84ca2d..2b0f98ca6ec3 100644 --- a/drivers/scsi/libsas/sas_init.c +++ b/drivers/scsi/libsas/sas_init.c @@ -619,13 +619,6 @@ struct asd_sas_event *sas_alloc_event(struct asd_sas_phy *phy, return event; } -struct asd_sas_event *sas_alloc_event_gfp(struct asd_sas_phy *phy, - gfp_t gfp_flags) -{ - - return sas_alloc_event(phy, gfp_flags); -} - void sas_free_event(struct asd_sas_event *event) { struct asd_sas_phy *phy = event->phy; diff --git a/drivers/scsi/libsas/sas_internal.h b/drivers/scsi/libsas/sas_internal.h index 294cdcb4ce42..d7a1fb5c10c6 100644 --- a/drivers/scsi/libsas/sas_internal.h +++ b/drivers/scsi/libsas/sas_internal.h @@ -49,8 +49,6 @@ int sas_register_phys(struct sas_ha_struct *sas_ha); void sas_unregister_phys(struct sas_ha_struct *sas_ha); struct asd_sas_event *sas_alloc_event(struct asd_sas_phy *phy, gfp_t gfp_flags); -struct asd_sas_event *sas_alloc_event_gfp(struct asd_sas_phy *phy, - gfp_t gfp_flags); void sas_free_event(struct asd_sas_event *event); int sas_register_ports(struct sas_ha_struct *sas_ha); @@ -80,8 +78,6 @@ int sas_smp_get_phy_events(struct sas_phy *phy); int sas_notify_phy_event(struct asd_sas_phy *phy, enum phy_event event, gfp_t flags); -int sas_notify_phy_event_gfp(struct asd_sas_phy *phy, enum phy_event event, - gfp_t flags); void sas_device_set_phy(struct domain_device *dev, struct sas_port *port); struct domain_device *sas_find_dev_by_rphy(struct sas_rphy *rphy); struct domain_device *sas_ex_to_ata(struct domain_device *ex_dev, int phy_id); diff --git a/include/scsi/libsas.h b/include/scsi/libsas.h index fda56e151695..9271d7a49b90 100644 --- a/include/scsi/libsas.h +++ b/include/scsi/libsas.h @@ -706,9 +706,5 @@ int sas_notify_port_event(struct asd_sas_phy *phy, enum port_event event, gfp_t gfp_flags); int sas_notify_phy_event(struct asd_sas_phy *phy, enum phy_event event, gfp_t gfp_flags); -int sas_notify_port_event_gfp(struct asd_sas_phy *phy, enum port_event event, - gfp_t gfp_flags); -int sas_notify_phy_event_gfp(struct asd_sas_phy *phy, enum phy_event event, - gfp_t gfp_flags); #endif /* _SASLIB_H_ */ -- cgit v1.2.3 From 321f7ab0d45899fe0313139822d69c2d5adbb760 Mon Sep 17 00:00:00 2001 From: Danielle Ratson Date: Thu, 21 Jan 2021 15:10:23 +0200 Subject: mlxsw: Register physical ports as a devlink resource The switch ASIC has a limited capacity of physical ('flavour physical' in devlink terminology) ports that it can support. While each system is brought up with a different number of ports, this number can be increased via splitting up to the ASIC's limit. Expose physical ports as a devlink resource so that user space will have visibility to the maximum number of ports that can be supported and the current occupancy. In addition, add a "Generic Resources" section in devlink-resource documentation so the different drivers will be aligned by the same resource name when exposing to user space. Signed-off-by: Danielle Ratson Reviewed-by: Jiri Pirko Signed-off-by: Ido Schimmel Signed-off-by: Jakub Kicinski --- .../networking/devlink/devlink-resource.rst | 14 ++++ drivers/net/ethernet/mellanox/mlxsw/core.c | 77 +++++++++++++++++++--- drivers/net/ethernet/mellanox/mlxsw/core.h | 5 ++ drivers/net/ethernet/mellanox/mlxsw/spectrum.h | 2 +- include/net/devlink.h | 2 + net/core/devlink.c | 4 ++ 6 files changed, 93 insertions(+), 11 deletions(-) (limited to 'Documentation') diff --git a/Documentation/networking/devlink/devlink-resource.rst b/Documentation/networking/devlink/devlink-resource.rst index 93e92d2f0752..3d5ae51e65a2 100644 --- a/Documentation/networking/devlink/devlink-resource.rst +++ b/Documentation/networking/devlink/devlink-resource.rst @@ -23,6 +23,20 @@ current size and related sub resources. To access a sub resource, you specify the path of the resource. For example ``/IPv4/fib`` is the id for the ``fib`` sub-resource under the ``IPv4`` resource. +Generic Resources +================= + +Generic resources are used to describe resources that can be shared by multiple +device drivers and their description must be added to the following table: + +.. list-table:: List of Generic Resources + :widths: 10 90 + + * - Name + - Description + * - ``physical_ports`` + - A limited capacity of physical ports that the switch ASIC can support + example usage ------------- diff --git a/drivers/net/ethernet/mellanox/mlxsw/core.c b/drivers/net/ethernet/mellanox/mlxsw/core.c index 685037e052af..52fdc34251ba 100644 --- a/drivers/net/ethernet/mellanox/mlxsw/core.c +++ b/drivers/net/ethernet/mellanox/mlxsw/core.c @@ -84,6 +84,7 @@ struct mlxsw_core { struct mlxsw_thermal *thermal; struct mlxsw_core_port *ports; unsigned int max_ports; + atomic_t active_ports_count; bool fw_flash_in_progress; struct { struct devlink_health_reporter *fw_fatal; @@ -96,8 +97,36 @@ struct mlxsw_core { #define MLXSW_PORT_MAX_PORTS_DEFAULT 0x40 -static int mlxsw_ports_init(struct mlxsw_core *mlxsw_core) +static u64 mlxsw_ports_occ_get(void *priv) { + struct mlxsw_core *mlxsw_core = priv; + + return atomic_read(&mlxsw_core->active_ports_count); +} + +static int mlxsw_core_resources_ports_register(struct mlxsw_core *mlxsw_core) +{ + struct devlink *devlink = priv_to_devlink(mlxsw_core); + struct devlink_resource_size_params ports_num_params; + u32 max_ports; + + max_ports = mlxsw_core->max_ports - 1; + devlink_resource_size_params_init(&ports_num_params, max_ports, + max_ports, 1, + DEVLINK_RESOURCE_UNIT_ENTRY); + + return devlink_resource_register(devlink, + DEVLINK_RESOURCE_GENERIC_NAME_PORTS, + max_ports, MLXSW_CORE_RESOURCE_PORTS, + DEVLINK_RESOURCE_ID_PARENT_TOP, + &ports_num_params); +} + +static int mlxsw_ports_init(struct mlxsw_core *mlxsw_core, bool reload) +{ + struct devlink *devlink = priv_to_devlink(mlxsw_core); + int err; + /* Switch ports are numbered from 1 to queried value */ if (MLXSW_CORE_RES_VALID(mlxsw_core, MAX_SYSTEM_PORT)) mlxsw_core->max_ports = MLXSW_CORE_RES_GET(mlxsw_core, @@ -110,11 +139,30 @@ static int mlxsw_ports_init(struct mlxsw_core *mlxsw_core) if (!mlxsw_core->ports) return -ENOMEM; + if (!reload) { + err = mlxsw_core_resources_ports_register(mlxsw_core); + if (err) + goto err_resources_ports_register; + } + atomic_set(&mlxsw_core->active_ports_count, 0); + devlink_resource_occ_get_register(devlink, MLXSW_CORE_RESOURCE_PORTS, + mlxsw_ports_occ_get, mlxsw_core); + return 0; + +err_resources_ports_register: + kfree(mlxsw_core->ports); + return err; } -static void mlxsw_ports_fini(struct mlxsw_core *mlxsw_core) +static void mlxsw_ports_fini(struct mlxsw_core *mlxsw_core, bool reload) { + struct devlink *devlink = priv_to_devlink(mlxsw_core); + + devlink_resource_occ_get_unregister(devlink, MLXSW_CORE_RESOURCE_PORTS); + if (!reload) + devlink_resources_unregister(priv_to_devlink(mlxsw_core), NULL); + kfree(mlxsw_core->ports); } @@ -1897,7 +1945,7 @@ __mlxsw_core_bus_device_register(const struct mlxsw_bus_info *mlxsw_bus_info, goto err_register_resources; } - err = mlxsw_ports_init(mlxsw_core); + err = mlxsw_ports_init(mlxsw_core, reload); if (err) goto err_ports_init; @@ -1986,7 +2034,7 @@ err_devlink_register: err_emad_init: kfree(mlxsw_core->lag.mapping); err_alloc_lag_mapping: - mlxsw_ports_fini(mlxsw_core); + mlxsw_ports_fini(mlxsw_core, reload); err_ports_init: if (!reload) devlink_resources_unregister(devlink, NULL); @@ -2056,7 +2104,7 @@ void mlxsw_core_bus_device_unregister(struct mlxsw_core *mlxsw_core, devlink_unregister(devlink); mlxsw_emad_fini(mlxsw_core); kfree(mlxsw_core->lag.mapping); - mlxsw_ports_fini(mlxsw_core); + mlxsw_ports_fini(mlxsw_core, reload); if (!reload) devlink_resources_unregister(devlink, NULL); mlxsw_core->bus->fini(mlxsw_core->bus_priv); @@ -2755,16 +2803,25 @@ int mlxsw_core_port_init(struct mlxsw_core *mlxsw_core, u8 local_port, const unsigned char *switch_id, unsigned char switch_id_len) { - return __mlxsw_core_port_init(mlxsw_core, local_port, - DEVLINK_PORT_FLAVOUR_PHYSICAL, - port_number, split, split_port_subnumber, - splittable, lanes, - switch_id, switch_id_len); + int err; + + err = __mlxsw_core_port_init(mlxsw_core, local_port, + DEVLINK_PORT_FLAVOUR_PHYSICAL, + port_number, split, split_port_subnumber, + splittable, lanes, + switch_id, switch_id_len); + if (err) + return err; + + atomic_inc(&mlxsw_core->active_ports_count); + return 0; } EXPORT_SYMBOL(mlxsw_core_port_init); void mlxsw_core_port_fini(struct mlxsw_core *mlxsw_core, u8 local_port) { + atomic_dec(&mlxsw_core->active_ports_count); + __mlxsw_core_port_fini(mlxsw_core, local_port); } EXPORT_SYMBOL(mlxsw_core_port_fini); diff --git a/drivers/net/ethernet/mellanox/mlxsw/core.h b/drivers/net/ethernet/mellanox/mlxsw/core.h index 6b3ccbf6b238..8af7d9d03475 100644 --- a/drivers/net/ethernet/mellanox/mlxsw/core.h +++ b/drivers/net/ethernet/mellanox/mlxsw/core.h @@ -19,6 +19,11 @@ #include "cmd.h" #include "resources.h" +enum mlxsw_core_resource_id { + MLXSW_CORE_RESOURCE_PORTS = 1, + MLXSW_CORE_RESOURCE_MAX, +}; + struct mlxsw_core; struct mlxsw_core_port; struct mlxsw_driver; diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum.h b/drivers/net/ethernet/mellanox/mlxsw/spectrum.h index a6956cfc9cb1..a3769f95a182 100644 --- a/drivers/net/ethernet/mellanox/mlxsw/spectrum.h +++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum.h @@ -52,7 +52,7 @@ #define MLXSW_SP_RESOURCE_NAME_COUNTERS_RIF "rif" enum mlxsw_sp_resource_id { - MLXSW_SP_RESOURCE_KVD = 1, + MLXSW_SP_RESOURCE_KVD = MLXSW_CORE_RESOURCE_MAX, MLXSW_SP_RESOURCE_KVD_LINEAR, MLXSW_SP_RESOURCE_KVD_HASH_SINGLE, MLXSW_SP_RESOURCE_KVD_HASH_DOUBLE, diff --git a/include/net/devlink.h b/include/net/devlink.h index f466819cc477..d12ed2854c34 100644 --- a/include/net/devlink.h +++ b/include/net/devlink.h @@ -380,6 +380,8 @@ struct devlink_resource { #define DEVLINK_RESOURCE_ID_PARENT_TOP 0 +#define DEVLINK_RESOURCE_GENERIC_NAME_PORTS "physical_ports" + #define __DEVLINK_PARAM_MAX_STRING_VALUE 32 enum devlink_param_type { DEVLINK_PARAM_TYPE_U8, diff --git a/net/core/devlink.c b/net/core/devlink.c index 738d4344d679..72ea79879762 100644 --- a/net/core/devlink.c +++ b/net/core/devlink.c @@ -8617,6 +8617,10 @@ EXPORT_SYMBOL_GPL(devlink_dpipe_table_unregister); * @resource_id: resource's id * @parent_resource_id: resource's parent id * @size_params: size parameters + * + * Generic resources should reuse the same names across drivers. + * Please see the generic resources list at: + * Documentation/networking/devlink/devlink-resource.rst */ int devlink_resource_register(struct devlink *devlink, const char *resource_name, -- cgit v1.2.3 From 1cabe74f148f7b99d9f08274a62467f96c870f07 Mon Sep 17 00:00:00 2001 From: Robert Karszniewicz Date: Fri, 22 Jan 2021 19:04:13 +0100 Subject: Documentation/Kbuild: Remove references to gcc-plugin.sh gcc-plugin.sh has been removed in commit 1e860048c53e ("gcc-plugins: simplify GCC plugin-dev capability test"). Signed-off-by: Robert Karszniewicz Reviewed-by: Kees Cook Signed-off-by: Masahiro Yamada --- Documentation/kbuild/gcc-plugins.rst | 6 ------ 1 file changed, 6 deletions(-) (limited to 'Documentation') diff --git a/Documentation/kbuild/gcc-plugins.rst b/Documentation/kbuild/gcc-plugins.rst index 4b1c10f88e30..63379d0150e3 100644 --- a/Documentation/kbuild/gcc-plugins.rst +++ b/Documentation/kbuild/gcc-plugins.rst @@ -47,12 +47,6 @@ Files This is a compatibility header for GCC plugins. It should be always included instead of individual gcc headers. -**$(src)/scripts/gcc-plugin.sh** - - This script checks the availability of the included headers in - gcc-common.h and chooses the proper host compiler to build the plugins - (gcc-4.7 can be built by either gcc or g++). - **$(src)/scripts/gcc-plugins/gcc-generate-gimple-pass.h, $(src)/scripts/gcc-plugins/gcc-generate-ipa-pass.h, $(src)/scripts/gcc-plugins/gcc-generate-simple_ipa-pass.h, -- cgit v1.2.3 From 9d0735519f99948c5b5c22426b682ced7f7af9be Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Wed, 20 Jan 2021 16:41:56 +0100 Subject: rtc: remove sirfsoc driver The CSR SiRF prima2/atlas platforms are getting removed, so this driver is no longer needed. Cc: Barry Song Signed-off-by: Arnd Bergmann Acked-by: Barry Song Signed-off-by: Alexandre Belloni Link: https://lore.kernel.org/r/20210120154158.1860736-2-arnd@kernel.org --- .../devicetree/bindings/rtc/sirf,prima2-sysrtc.txt | 13 - drivers/rtc/Kconfig | 7 - drivers/rtc/Makefile | 1 - drivers/rtc/rtc-sirfsoc.c | 446 --------------------- include/linux/rtc/sirfsoc_rtciobrg.h | 21 - 5 files changed, 488 deletions(-) delete mode 100644 Documentation/devicetree/bindings/rtc/sirf,prima2-sysrtc.txt delete mode 100644 drivers/rtc/rtc-sirfsoc.c delete mode 100644 include/linux/rtc/sirfsoc_rtciobrg.h (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/rtc/sirf,prima2-sysrtc.txt b/Documentation/devicetree/bindings/rtc/sirf,prima2-sysrtc.txt deleted file mode 100644 index 58885b55da21..000000000000 --- a/Documentation/devicetree/bindings/rtc/sirf,prima2-sysrtc.txt +++ /dev/null @@ -1,13 +0,0 @@ -SiRFSoC Real Time Clock - -Required properties: -- compatible: must be "sirf,prima2-sysrtc" -- reg: address range of rtc register set. -- interrupts: rtc alarm interrupts. - -Example: - rtc@2000 { - compatible = "sirf,prima2-sysrtc"; - reg = <0x2000 0x1000>; - interrupts = <52 53 54>; - }; diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig index fe4fdb75a4c5..12907352f697 100644 --- a/drivers/rtc/Kconfig +++ b/drivers/rtc/Kconfig @@ -1793,13 +1793,6 @@ config RTC_DRV_IMX_SC If you say yes here you get support for the NXP i.MX System Controller RTC module. -config RTC_DRV_SIRFSOC - tristate "SiRFSOC RTC" - depends on ARCH_SIRF - help - Say "yes" here to support the real time clock on SiRF SOC chips. - This driver can also be built as a module called rtc-sirfsoc. - config RTC_DRV_ST_LPC tristate "STMicroelectronics LPC RTC" depends on ARCH_STI diff --git a/drivers/rtc/Makefile b/drivers/rtc/Makefile index a020adde4bbd..821643b3b699 100644 --- a/drivers/rtc/Makefile +++ b/drivers/rtc/Makefile @@ -154,7 +154,6 @@ obj-$(CONFIG_RTC_DRV_SA1100) += rtc-sa1100.o obj-$(CONFIG_RTC_DRV_SC27XX) += rtc-sc27xx.o obj-$(CONFIG_RTC_DRV_SD3078) += rtc-sd3078.o obj-$(CONFIG_RTC_DRV_SH) += rtc-sh.o -obj-$(CONFIG_RTC_DRV_SIRFSOC) += rtc-sirfsoc.o obj-$(CONFIG_RTC_DRV_SNVS) += rtc-snvs.o obj-$(CONFIG_RTC_DRV_SPEAR) += rtc-spear.o obj-$(CONFIG_RTC_DRV_STARFIRE) += rtc-starfire.o diff --git a/drivers/rtc/rtc-sirfsoc.c b/drivers/rtc/rtc-sirfsoc.c deleted file mode 100644 index 03a6cca23201..000000000000 --- a/drivers/rtc/rtc-sirfsoc.c +++ /dev/null @@ -1,446 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * SiRFSoC Real Time Clock interface for Linux - * - * Copyright (c) 2013 Cambridge Silicon Radio Limited, a CSR plc group company. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - - -#define RTC_CN 0x00 -#define RTC_ALARM0 0x04 -#define RTC_ALARM1 0x18 -#define RTC_STATUS 0x08 -#define RTC_SW_VALUE 0x40 -#define SIRFSOC_RTC_AL1E (1<<6) -#define SIRFSOC_RTC_AL1 (1<<4) -#define SIRFSOC_RTC_HZE (1<<3) -#define SIRFSOC_RTC_AL0E (1<<2) -#define SIRFSOC_RTC_HZ (1<<1) -#define SIRFSOC_RTC_AL0 (1<<0) -#define RTC_DIV 0x0c -#define RTC_DEEP_CTRL 0x14 -#define RTC_CLOCK_SWITCH 0x1c -#define SIRFSOC_RTC_CLK 0x03 /* others are reserved */ - -/* Refer to RTC DIV switch */ -#define RTC_HZ 16 - -/* This macro is also defined in arch/arm/plat-sirfsoc/cpu.c */ -#define RTC_SHIFT 4 - -#define INTR_SYSRTC_CN 0x48 - -struct sirfsoc_rtc_drv { - struct rtc_device *rtc; - u32 rtc_base; - u32 irq; - unsigned irq_wake; - /* Overflow for every 8 years extra time */ - u32 overflow_rtc; - spinlock_t lock; - struct regmap *regmap; -#ifdef CONFIG_PM - u32 saved_counter; - u32 saved_overflow_rtc; -#endif -}; - -static u32 sirfsoc_rtc_readl(struct sirfsoc_rtc_drv *rtcdrv, u32 offset) -{ - u32 val; - - regmap_read(rtcdrv->regmap, rtcdrv->rtc_base + offset, &val); - return val; -} - -static void sirfsoc_rtc_writel(struct sirfsoc_rtc_drv *rtcdrv, - u32 offset, u32 val) -{ - regmap_write(rtcdrv->regmap, rtcdrv->rtc_base + offset, val); -} - -static int sirfsoc_rtc_read_alarm(struct device *dev, - struct rtc_wkalrm *alrm) -{ - unsigned long rtc_alarm, rtc_count; - struct sirfsoc_rtc_drv *rtcdrv; - - rtcdrv = dev_get_drvdata(dev); - - spin_lock_irq(&rtcdrv->lock); - - rtc_count = sirfsoc_rtc_readl(rtcdrv, RTC_CN); - - rtc_alarm = sirfsoc_rtc_readl(rtcdrv, RTC_ALARM0); - memset(alrm, 0, sizeof(struct rtc_wkalrm)); - - /* - * assume alarm interval not beyond one round counter overflow_rtc: - * 0->0xffffffff - */ - /* if alarm is in next overflow cycle */ - if (rtc_count > rtc_alarm) - rtc_time64_to_tm((rtcdrv->overflow_rtc + 1) - << (BITS_PER_LONG - RTC_SHIFT) - | rtc_alarm >> RTC_SHIFT, &alrm->time); - else - rtc_time64_to_tm(rtcdrv->overflow_rtc - << (BITS_PER_LONG - RTC_SHIFT) - | rtc_alarm >> RTC_SHIFT, &alrm->time); - if (sirfsoc_rtc_readl(rtcdrv, RTC_STATUS) & SIRFSOC_RTC_AL0E) - alrm->enabled = 1; - - spin_unlock_irq(&rtcdrv->lock); - - return 0; -} - -static int sirfsoc_rtc_set_alarm(struct device *dev, - struct rtc_wkalrm *alrm) -{ - unsigned long rtc_status_reg, rtc_alarm; - struct sirfsoc_rtc_drv *rtcdrv; - rtcdrv = dev_get_drvdata(dev); - - if (alrm->enabled) { - rtc_alarm = rtc_tm_to_time64(&alrm->time); - - spin_lock_irq(&rtcdrv->lock); - - rtc_status_reg = sirfsoc_rtc_readl(rtcdrv, RTC_STATUS); - if (rtc_status_reg & SIRFSOC_RTC_AL0E) { - /* - * An ongoing alarm in progress - ingore it and not - * to return EBUSY - */ - dev_info(dev, "An old alarm was set, will be replaced by a new one\n"); - } - - sirfsoc_rtc_writel(rtcdrv, RTC_ALARM0, rtc_alarm << RTC_SHIFT); - rtc_status_reg &= ~0x07; /* mask out the lower status bits */ - /* - * This bit RTC_AL sets it as a wake-up source for Sleep Mode - * Writing 1 into this bit will clear it - */ - rtc_status_reg |= SIRFSOC_RTC_AL0; - /* enable the RTC alarm interrupt */ - rtc_status_reg |= SIRFSOC_RTC_AL0E; - sirfsoc_rtc_writel(rtcdrv, RTC_STATUS, rtc_status_reg); - - spin_unlock_irq(&rtcdrv->lock); - } else { - /* - * if this function was called with enabled=0 - * then it could mean that the application is - * trying to cancel an ongoing alarm - */ - spin_lock_irq(&rtcdrv->lock); - - rtc_status_reg = sirfsoc_rtc_readl(rtcdrv, RTC_STATUS); - if (rtc_status_reg & SIRFSOC_RTC_AL0E) { - /* clear the RTC status register's alarm bit */ - rtc_status_reg &= ~0x07; - /* write 1 into SIRFSOC_RTC_AL0 to force a clear */ - rtc_status_reg |= (SIRFSOC_RTC_AL0); - /* Clear the Alarm enable bit */ - rtc_status_reg &= ~(SIRFSOC_RTC_AL0E); - - sirfsoc_rtc_writel(rtcdrv, RTC_STATUS, - rtc_status_reg); - } - - spin_unlock_irq(&rtcdrv->lock); - } - - return 0; -} - -static int sirfsoc_rtc_read_time(struct device *dev, - struct rtc_time *tm) -{ - unsigned long tmp_rtc = 0; - struct sirfsoc_rtc_drv *rtcdrv; - rtcdrv = dev_get_drvdata(dev); - /* - * This patch is taken from WinCE - Need to validate this for - * correctness. To work around sirfsoc RTC counter double sync logic - * fail, read several times to make sure get stable value. - */ - do { - tmp_rtc = sirfsoc_rtc_readl(rtcdrv, RTC_CN); - cpu_relax(); - } while (tmp_rtc != sirfsoc_rtc_readl(rtcdrv, RTC_CN)); - - rtc_time64_to_tm(rtcdrv->overflow_rtc << (BITS_PER_LONG - RTC_SHIFT) - | tmp_rtc >> RTC_SHIFT, tm); - return 0; -} - -static int sirfsoc_rtc_set_time(struct device *dev, - struct rtc_time *tm) -{ - unsigned long rtc_time; - struct sirfsoc_rtc_drv *rtcdrv; - rtcdrv = dev_get_drvdata(dev); - - rtc_time = rtc_tm_to_time64(tm); - - rtcdrv->overflow_rtc = rtc_time >> (BITS_PER_LONG - RTC_SHIFT); - - sirfsoc_rtc_writel(rtcdrv, RTC_SW_VALUE, rtcdrv->overflow_rtc); - sirfsoc_rtc_writel(rtcdrv, RTC_CN, rtc_time << RTC_SHIFT); - - return 0; -} - -static int sirfsoc_rtc_alarm_irq_enable(struct device *dev, - unsigned int enabled) -{ - unsigned long rtc_status_reg = 0x0; - struct sirfsoc_rtc_drv *rtcdrv; - - rtcdrv = dev_get_drvdata(dev); - - spin_lock_irq(&rtcdrv->lock); - - rtc_status_reg = sirfsoc_rtc_readl(rtcdrv, RTC_STATUS); - if (enabled) - rtc_status_reg |= SIRFSOC_RTC_AL0E; - else - rtc_status_reg &= ~SIRFSOC_RTC_AL0E; - - sirfsoc_rtc_writel(rtcdrv, RTC_STATUS, rtc_status_reg); - - spin_unlock_irq(&rtcdrv->lock); - - return 0; - -} - -static const struct rtc_class_ops sirfsoc_rtc_ops = { - .read_time = sirfsoc_rtc_read_time, - .set_time = sirfsoc_rtc_set_time, - .read_alarm = sirfsoc_rtc_read_alarm, - .set_alarm = sirfsoc_rtc_set_alarm, - .alarm_irq_enable = sirfsoc_rtc_alarm_irq_enable -}; - -static irqreturn_t sirfsoc_rtc_irq_handler(int irq, void *pdata) -{ - struct sirfsoc_rtc_drv *rtcdrv = pdata; - unsigned long rtc_status_reg = 0x0; - unsigned long events = 0x0; - - spin_lock(&rtcdrv->lock); - - rtc_status_reg = sirfsoc_rtc_readl(rtcdrv, RTC_STATUS); - /* this bit will be set ONLY if an alarm was active - * and it expired NOW - * So this is being used as an ASSERT - */ - if (rtc_status_reg & SIRFSOC_RTC_AL0) { - /* - * clear the RTC status register's alarm bit - * mask out the lower status bits - */ - rtc_status_reg &= ~0x07; - /* write 1 into SIRFSOC_RTC_AL0 to ACK the alarm interrupt */ - rtc_status_reg |= (SIRFSOC_RTC_AL0); - /* Clear the Alarm enable bit */ - rtc_status_reg &= ~(SIRFSOC_RTC_AL0E); - } - - sirfsoc_rtc_writel(rtcdrv, RTC_STATUS, rtc_status_reg); - - spin_unlock(&rtcdrv->lock); - - /* this should wake up any apps polling/waiting on the read - * after setting the alarm - */ - events |= RTC_IRQF | RTC_AF; - rtc_update_irq(rtcdrv->rtc, 1, events); - - return IRQ_HANDLED; -} - -static const struct of_device_id sirfsoc_rtc_of_match[] = { - { .compatible = "sirf,prima2-sysrtc"}, - {}, -}; - -static const struct regmap_config sysrtc_regmap_config = { - .reg_bits = 32, - .val_bits = 32, - .fast_io = true, -}; - -MODULE_DEVICE_TABLE(of, sirfsoc_rtc_of_match); - -static int sirfsoc_rtc_probe(struct platform_device *pdev) -{ - int err; - unsigned long rtc_div; - struct sirfsoc_rtc_drv *rtcdrv; - struct device_node *np = pdev->dev.of_node; - - rtcdrv = devm_kzalloc(&pdev->dev, - sizeof(struct sirfsoc_rtc_drv), GFP_KERNEL); - if (rtcdrv == NULL) - return -ENOMEM; - - spin_lock_init(&rtcdrv->lock); - - err = of_property_read_u32(np, "reg", &rtcdrv->rtc_base); - if (err) { - dev_err(&pdev->dev, "unable to find base address of rtc node in dtb\n"); - return err; - } - - platform_set_drvdata(pdev, rtcdrv); - - /* Register rtc alarm as a wakeup source */ - device_init_wakeup(&pdev->dev, 1); - - rtcdrv->regmap = devm_regmap_init_iobg(&pdev->dev, - &sysrtc_regmap_config); - if (IS_ERR(rtcdrv->regmap)) { - err = PTR_ERR(rtcdrv->regmap); - dev_err(&pdev->dev, "Failed to allocate register map: %d\n", - err); - return err; - } - - /* - * Set SYS_RTC counter in RTC_HZ HZ Units - * We are using 32K RTC crystal (32768 / RTC_HZ / 2) -1 - * If 16HZ, therefore RTC_DIV = 1023; - */ - rtc_div = ((32768 / RTC_HZ) / 2) - 1; - sirfsoc_rtc_writel(rtcdrv, RTC_DIV, rtc_div); - - /* 0x3 -> RTC_CLK */ - sirfsoc_rtc_writel(rtcdrv, RTC_CLOCK_SWITCH, SIRFSOC_RTC_CLK); - - /* reset SYS RTC ALARM0 */ - sirfsoc_rtc_writel(rtcdrv, RTC_ALARM0, 0x0); - - /* reset SYS RTC ALARM1 */ - sirfsoc_rtc_writel(rtcdrv, RTC_ALARM1, 0x0); - - /* Restore RTC Overflow From Register After Command Reboot */ - rtcdrv->overflow_rtc = - sirfsoc_rtc_readl(rtcdrv, RTC_SW_VALUE); - - rtcdrv->rtc = devm_rtc_allocate_device(&pdev->dev); - if (IS_ERR(rtcdrv->rtc)) - return PTR_ERR(rtcdrv->rtc); - - rtcdrv->rtc->ops = &sirfsoc_rtc_ops; - rtcdrv->rtc->range_max = (1ULL << 60) - 1; - - rtcdrv->irq = platform_get_irq(pdev, 0); - err = devm_request_irq(&pdev->dev, rtcdrv->irq, sirfsoc_rtc_irq_handler, - IRQF_SHARED, pdev->name, rtcdrv); - if (err) { - dev_err(&pdev->dev, "Unable to register for the SiRF SOC RTC IRQ\n"); - return err; - } - - return devm_rtc_register_device(rtcdrv->rtc); -} - -#ifdef CONFIG_PM_SLEEP -static int sirfsoc_rtc_suspend(struct device *dev) -{ - struct sirfsoc_rtc_drv *rtcdrv = dev_get_drvdata(dev); - rtcdrv->overflow_rtc = - sirfsoc_rtc_readl(rtcdrv, RTC_SW_VALUE); - - rtcdrv->saved_counter = - sirfsoc_rtc_readl(rtcdrv, RTC_CN); - rtcdrv->saved_overflow_rtc = rtcdrv->overflow_rtc; - if (device_may_wakeup(dev) && !enable_irq_wake(rtcdrv->irq)) - rtcdrv->irq_wake = 1; - - return 0; -} - -static int sirfsoc_rtc_resume(struct device *dev) -{ - u32 tmp; - struct sirfsoc_rtc_drv *rtcdrv = dev_get_drvdata(dev); - - /* - * if resume from snapshot and the rtc power is lost, - * restroe the rtc settings - */ - if (SIRFSOC_RTC_CLK != sirfsoc_rtc_readl(rtcdrv, RTC_CLOCK_SWITCH)) { - u32 rtc_div; - /* 0x3 -> RTC_CLK */ - sirfsoc_rtc_writel(rtcdrv, RTC_CLOCK_SWITCH, SIRFSOC_RTC_CLK); - /* - * Set SYS_RTC counter in RTC_HZ HZ Units - * We are using 32K RTC crystal (32768 / RTC_HZ / 2) -1 - * If 16HZ, therefore RTC_DIV = 1023; - */ - rtc_div = ((32768 / RTC_HZ) / 2) - 1; - - sirfsoc_rtc_writel(rtcdrv, RTC_DIV, rtc_div); - - /* reset SYS RTC ALARM0 */ - sirfsoc_rtc_writel(rtcdrv, RTC_ALARM0, 0x0); - - /* reset SYS RTC ALARM1 */ - sirfsoc_rtc_writel(rtcdrv, RTC_ALARM1, 0x0); - } - rtcdrv->overflow_rtc = rtcdrv->saved_overflow_rtc; - - /* - * if current counter is small than previous, - * it means overflow in sleep - */ - tmp = sirfsoc_rtc_readl(rtcdrv, RTC_CN); - if (tmp <= rtcdrv->saved_counter) - rtcdrv->overflow_rtc++; - /* - *PWRC Value Be Changed When Suspend, Restore Overflow - * In Memory To Register - */ - sirfsoc_rtc_writel(rtcdrv, RTC_SW_VALUE, rtcdrv->overflow_rtc); - - if (device_may_wakeup(dev) && rtcdrv->irq_wake) { - disable_irq_wake(rtcdrv->irq); - rtcdrv->irq_wake = 0; - } - - return 0; -} -#endif - -static SIMPLE_DEV_PM_OPS(sirfsoc_rtc_pm_ops, - sirfsoc_rtc_suspend, sirfsoc_rtc_resume); - -static struct platform_driver sirfsoc_rtc_driver = { - .driver = { - .name = "sirfsoc-rtc", - .pm = &sirfsoc_rtc_pm_ops, - .of_match_table = sirfsoc_rtc_of_match, - }, - .probe = sirfsoc_rtc_probe, -}; -module_platform_driver(sirfsoc_rtc_driver); - -MODULE_DESCRIPTION("SiRF SoC rtc driver"); -MODULE_AUTHOR("Xianglong Du "); -MODULE_LICENSE("GPL v2"); -MODULE_ALIAS("platform:sirfsoc-rtc"); diff --git a/include/linux/rtc/sirfsoc_rtciobrg.h b/include/linux/rtc/sirfsoc_rtciobrg.h deleted file mode 100644 index b31f2856733d..000000000000 --- a/include/linux/rtc/sirfsoc_rtciobrg.h +++ /dev/null @@ -1,21 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-or-later */ -/* - * RTC I/O Bridge interfaces for CSR SiRFprimaII - * ARM access the registers of SYSRTC, GPSRTC and PWRC through this module - * - * Copyright (c) 2011 Cambridge Silicon Radio Limited, a CSR plc group company. - */ -#ifndef _SIRFSOC_RTC_IOBRG_H_ -#define _SIRFSOC_RTC_IOBRG_H_ - -struct regmap_config; - -extern void sirfsoc_rtc_iobrg_besyncing(void); - -extern u32 sirfsoc_rtc_iobrg_readl(u32 addr); - -extern void sirfsoc_rtc_iobrg_writel(u32 val, u32 addr); -struct regmap *devm_regmap_init_iobg(struct device *dev, - const struct regmap_config *config); - -#endif -- cgit v1.2.3 From dd2d3b40039d0278f25a21aa3e50955a01a92a62 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Wed, 20 Jan 2021 16:41:57 +0100 Subject: rtc: remove ste coh901 driver The ST-Ericsson U300 platform is getting removed, so this driver is no longer needed. Cc: Linus Walleij Signed-off-by: Arnd Bergmann Reviewed-by: Linus Walleij Signed-off-by: Alexandre Belloni Link: https://lore.kernel.org/r/20210120154158.1860736-3-arnd@kernel.org --- .../bindings/rtc/stericsson,coh901331.txt | 16 -- drivers/rtc/Kconfig | 12 - drivers/rtc/Makefile | 1 - drivers/rtc/rtc-coh901331.c | 290 --------------------- 4 files changed, 319 deletions(-) delete mode 100644 Documentation/devicetree/bindings/rtc/stericsson,coh901331.txt delete mode 100644 drivers/rtc/rtc-coh901331.c (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/rtc/stericsson,coh901331.txt b/Documentation/devicetree/bindings/rtc/stericsson,coh901331.txt deleted file mode 100644 index e615a897b20e..000000000000 --- a/Documentation/devicetree/bindings/rtc/stericsson,coh901331.txt +++ /dev/null @@ -1,16 +0,0 @@ -ST-Ericsson COH 901 331 Real Time Clock - -Required properties: -- compatible: must be "stericsson,coh901331" -- reg: address range of rtc register set. -- interrupts: rtc alarm interrupt. -- clocks: phandle to the rtc clock source - -Example: - rtc: rtc@c0017000 { - compatible = "stericsson,coh901331"; - reg = <0xc0017000 0x1000>; - interrupt-parent = <&vicb>; - interrupts = <10>; - clocks = <&rtc_clk>; - }; diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig index 12907352f697..38a25bbf3fe9 100644 --- a/drivers/rtc/Kconfig +++ b/drivers/rtc/Kconfig @@ -1639,18 +1639,6 @@ config RTC_DRV_PS3 This driver can also be built as a module. If so, the module will be called rtc-ps3. -config RTC_DRV_COH901331 - tristate "ST-Ericsson COH 901 331 RTC" - depends on ARCH_U300 || COMPILE_TEST - help - If you say Y here you will get access to ST-Ericsson - COH 901 331 RTC clock found in some ST-Ericsson Mobile - Platforms. - - This driver can also be built as a module. If so, the module - will be called "rtc-coh901331". - - config RTC_DRV_STMP tristate "Freescale STMP3xxx/i.MX23/i.MX28 RTC" depends on ARCH_MXS || COMPILE_TEST diff --git a/drivers/rtc/Makefile b/drivers/rtc/Makefile index 821643b3b699..9cb0e0e8fd28 100644 --- a/drivers/rtc/Makefile +++ b/drivers/rtc/Makefile @@ -38,7 +38,6 @@ obj-$(CONFIG_RTC_DRV_BQ4802) += rtc-bq4802.o obj-$(CONFIG_RTC_DRV_BRCMSTB) += rtc-brcmstb-waketimer.o obj-$(CONFIG_RTC_DRV_CADENCE) += rtc-cadence.o obj-$(CONFIG_RTC_DRV_CMOS) += rtc-cmos.o -obj-$(CONFIG_RTC_DRV_COH901331) += rtc-coh901331.o obj-$(CONFIG_RTC_DRV_CPCAP) += rtc-cpcap.o obj-$(CONFIG_RTC_DRV_CROS_EC) += rtc-cros-ec.o obj-$(CONFIG_RTC_DRV_DA9052) += rtc-da9052.o diff --git a/drivers/rtc/rtc-coh901331.c b/drivers/rtc/rtc-coh901331.c deleted file mode 100644 index 168ced87d93a..000000000000 --- a/drivers/rtc/rtc-coh901331.c +++ /dev/null @@ -1,290 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* - * Copyright (C) 2007-2009 ST-Ericsson AB - * Real Time Clock interface for ST-Ericsson AB COH 901 331 RTC. - * Author: Linus Walleij - * Based on rtc-pl031.c by Deepak Saxena - * Copyright 2006 (c) MontaVista Software, Inc. - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* - * Registers in the COH 901 331 - */ -/* Alarm value 32bit (R/W) */ -#define COH901331_ALARM 0x00U -/* Used to set current time 32bit (R/W) */ -#define COH901331_SET_TIME 0x04U -/* Indication if current time is valid 32bit (R/-) */ -#define COH901331_VALID 0x08U -/* Read the current time 32bit (R/-) */ -#define COH901331_CUR_TIME 0x0cU -/* Event register for the "alarm" interrupt */ -#define COH901331_IRQ_EVENT 0x10U -/* Mask register for the "alarm" interrupt */ -#define COH901331_IRQ_MASK 0x14U -/* Force register for the "alarm" interrupt */ -#define COH901331_IRQ_FORCE 0x18U - -/* - * Reference to RTC block clock - * Notice that the frequent clk_enable()/clk_disable() on this - * clock is mainly to be able to turn on/off other clocks in the - * hierarchy as needed, the RTC clock is always on anyway. - */ -struct coh901331_port { - struct rtc_device *rtc; - struct clk *clk; - void __iomem *virtbase; - int irq; -#ifdef CONFIG_PM_SLEEP - u32 irqmaskstore; -#endif -}; - -static irqreturn_t coh901331_interrupt(int irq, void *data) -{ - struct coh901331_port *rtap = data; - - clk_enable(rtap->clk); - /* Ack IRQ */ - writel(1, rtap->virtbase + COH901331_IRQ_EVENT); - /* - * Disable the interrupt. This is necessary because - * the RTC lives on a lower-clocked line and will - * not release the IRQ line until after a few (slower) - * clock cycles. The interrupt will be re-enabled when - * a new alarm is set anyway. - */ - writel(0, rtap->virtbase + COH901331_IRQ_MASK); - clk_disable(rtap->clk); - - /* Set alarm flag */ - rtc_update_irq(rtap->rtc, 1, RTC_AF); - - return IRQ_HANDLED; -} - -static int coh901331_read_time(struct device *dev, struct rtc_time *tm) -{ - struct coh901331_port *rtap = dev_get_drvdata(dev); - - clk_enable(rtap->clk); - /* Check if the time is valid */ - if (!readl(rtap->virtbase + COH901331_VALID)) { - clk_disable(rtap->clk); - return -EINVAL; - } - - rtc_time64_to_tm(readl(rtap->virtbase + COH901331_CUR_TIME), tm); - clk_disable(rtap->clk); - return 0; -} - -static int coh901331_set_time(struct device *dev, struct rtc_time *tm) -{ - struct coh901331_port *rtap = dev_get_drvdata(dev); - - clk_enable(rtap->clk); - writel(rtc_tm_to_time64(tm), rtap->virtbase + COH901331_SET_TIME); - clk_disable(rtap->clk); - - return 0; -} - -static int coh901331_read_alarm(struct device *dev, struct rtc_wkalrm *alarm) -{ - struct coh901331_port *rtap = dev_get_drvdata(dev); - - clk_enable(rtap->clk); - rtc_time64_to_tm(readl(rtap->virtbase + COH901331_ALARM), &alarm->time); - alarm->pending = readl(rtap->virtbase + COH901331_IRQ_EVENT) & 1U; - alarm->enabled = readl(rtap->virtbase + COH901331_IRQ_MASK) & 1U; - clk_disable(rtap->clk); - - return 0; -} - -static int coh901331_set_alarm(struct device *dev, struct rtc_wkalrm *alarm) -{ - struct coh901331_port *rtap = dev_get_drvdata(dev); - unsigned long time = rtc_tm_to_time64(&alarm->time); - - clk_enable(rtap->clk); - writel(time, rtap->virtbase + COH901331_ALARM); - writel(alarm->enabled, rtap->virtbase + COH901331_IRQ_MASK); - clk_disable(rtap->clk); - - return 0; -} - -static int coh901331_alarm_irq_enable(struct device *dev, unsigned int enabled) -{ - struct coh901331_port *rtap = dev_get_drvdata(dev); - - clk_enable(rtap->clk); - if (enabled) - writel(1, rtap->virtbase + COH901331_IRQ_MASK); - else - writel(0, rtap->virtbase + COH901331_IRQ_MASK); - clk_disable(rtap->clk); - - return 0; -} - -static const struct rtc_class_ops coh901331_ops = { - .read_time = coh901331_read_time, - .set_time = coh901331_set_time, - .read_alarm = coh901331_read_alarm, - .set_alarm = coh901331_set_alarm, - .alarm_irq_enable = coh901331_alarm_irq_enable, -}; - -static int __exit coh901331_remove(struct platform_device *pdev) -{ - struct coh901331_port *rtap = platform_get_drvdata(pdev); - - if (rtap) - clk_unprepare(rtap->clk); - - return 0; -} - - -static int __init coh901331_probe(struct platform_device *pdev) -{ - int ret; - struct coh901331_port *rtap; - - rtap = devm_kzalloc(&pdev->dev, - sizeof(struct coh901331_port), GFP_KERNEL); - if (!rtap) - return -ENOMEM; - - rtap->virtbase = devm_platform_ioremap_resource(pdev, 0); - if (IS_ERR(rtap->virtbase)) - return PTR_ERR(rtap->virtbase); - - rtap->irq = platform_get_irq(pdev, 0); - if (devm_request_irq(&pdev->dev, rtap->irq, coh901331_interrupt, 0, - "RTC COH 901 331 Alarm", rtap)) - return -EIO; - - rtap->clk = devm_clk_get(&pdev->dev, NULL); - if (IS_ERR(rtap->clk)) { - ret = PTR_ERR(rtap->clk); - dev_err(&pdev->dev, "could not get clock\n"); - return ret; - } - - rtap->rtc = devm_rtc_allocate_device(&pdev->dev); - if (IS_ERR(rtap->rtc)) - return PTR_ERR(rtap->rtc); - - rtap->rtc->ops = &coh901331_ops; - rtap->rtc->range_max = U32_MAX; - - /* We enable/disable the clock only to assure it works */ - ret = clk_prepare_enable(rtap->clk); - if (ret) { - dev_err(&pdev->dev, "could not enable clock\n"); - return ret; - } - clk_disable(rtap->clk); - - platform_set_drvdata(pdev, rtap); - - ret = devm_rtc_register_device(rtap->rtc); - if (ret) - goto out_no_rtc; - - return 0; - - out_no_rtc: - clk_unprepare(rtap->clk); - return ret; -} - -#ifdef CONFIG_PM_SLEEP -static int coh901331_suspend(struct device *dev) -{ - struct coh901331_port *rtap = dev_get_drvdata(dev); - - /* - * If this RTC alarm will be used for waking the system up, - * don't disable it of course. Else we just disable the alarm - * and await suspension. - */ - if (device_may_wakeup(dev)) { - enable_irq_wake(rtap->irq); - } else { - clk_enable(rtap->clk); - rtap->irqmaskstore = readl(rtap->virtbase + COH901331_IRQ_MASK); - writel(0, rtap->virtbase + COH901331_IRQ_MASK); - clk_disable(rtap->clk); - } - clk_unprepare(rtap->clk); - return 0; -} - -static int coh901331_resume(struct device *dev) -{ - int ret; - struct coh901331_port *rtap = dev_get_drvdata(dev); - - ret = clk_prepare(rtap->clk); - if (ret) - return ret; - - if (device_may_wakeup(dev)) { - disable_irq_wake(rtap->irq); - } else { - clk_enable(rtap->clk); - writel(rtap->irqmaskstore, rtap->virtbase + COH901331_IRQ_MASK); - clk_disable(rtap->clk); - } - return 0; -} -#endif - -static SIMPLE_DEV_PM_OPS(coh901331_pm_ops, coh901331_suspend, coh901331_resume); - -static void coh901331_shutdown(struct platform_device *pdev) -{ - struct coh901331_port *rtap = platform_get_drvdata(pdev); - - clk_enable(rtap->clk); - writel(0, rtap->virtbase + COH901331_IRQ_MASK); - clk_disable_unprepare(rtap->clk); -} - -static const struct of_device_id coh901331_dt_match[] = { - { .compatible = "stericsson,coh901331" }, - {}, -}; -MODULE_DEVICE_TABLE(of, coh901331_dt_match); - -static struct platform_driver coh901331_driver = { - .driver = { - .name = "rtc-coh901331", - .pm = &coh901331_pm_ops, - .of_match_table = coh901331_dt_match, - }, - .remove = __exit_p(coh901331_remove), - .shutdown = coh901331_shutdown, -}; - -module_platform_driver_probe(coh901331_driver, coh901331_probe); - -MODULE_AUTHOR("Linus Walleij "); -MODULE_DESCRIPTION("ST-Ericsson AB COH 901 331 RTC Driver"); -MODULE_LICENSE("GPL"); -- cgit v1.2.3 From fc024c5c07aa2463d36e8c85943343741ba356b7 Mon Sep 17 00:00:00 2001 From: Pali Rohár Date: Thu, 21 Jan 2021 16:02:44 +0100 Subject: doc: networking: ip-sysctl: Document conf/all/disable_ipv6 and conf/default/disable_ipv6 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This patch adds documentation for sysctl conf/all/disable_ipv6 and conf/default/disable_ipv6 settings which is currently missing. Signed-off-by: Pali Rohár Link: https://lore.kernel.org/r/20210121150244.20483-1-pali@kernel.org Signed-off-by: Jakub Kicinski --- Documentation/networking/ip-sysctl.rst | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'Documentation') diff --git a/Documentation/networking/ip-sysctl.rst b/Documentation/networking/ip-sysctl.rst index dd2b12a32b73..c7b775da9554 100644 --- a/Documentation/networking/ip-sysctl.rst +++ b/Documentation/networking/ip-sysctl.rst @@ -1807,12 +1807,24 @@ seg6_flowlabel - INTEGER ``conf/default/*``: Change the interface-specific default settings. + These settings would be used during creating new interfaces. + ``conf/all/*``: Change all the interface-specific settings. [XXX: Other special features than forwarding?] +conf/all/disable_ipv6 - BOOLEAN + Changing this value is same as changing ``conf/default/disable_ipv6`` + setting and also all per-interface ``disable_ipv6`` settings to the same + value. + + Reading this value does not have any particular meaning. It does not say + whether IPv6 support is enabled or disabled. Returned value can be 1 + also in the case when some interface has ``disable_ipv6`` set to 0 and + has configured IPv6 addresses. + conf/all/forwarding - BOOLEAN Enable global IPv6 forwarding between all interfaces. -- cgit v1.2.3 From e65ce2a50cf6af216bea6fd80d771fcbb4c0aaa1 Mon Sep 17 00:00:00 2001 From: Christian Brauner Date: Thu, 21 Jan 2021 14:19:27 +0100 Subject: acl: handle idmapped mounts The posix acl permission checking helpers determine whether a caller is privileged over an inode according to the acls associated with the inode. Add helpers that make it possible to handle acls on idmapped mounts. The vfs and the filesystems targeted by this first iteration make use of posix_acl_fix_xattr_from_user() and posix_acl_fix_xattr_to_user() to translate basic posix access and default permissions such as the ACL_USER and ACL_GROUP type according to the initial user namespace (or the superblock's user namespace) to and from the caller's current user namespace. Adapt these two helpers to handle idmapped mounts whereby we either map from or into the mount's user namespace depending on in which direction we're translating. Similarly, cap_convert_nscap() is used by the vfs to translate user namespace and non-user namespace aware filesystem capabilities from the superblock's user namespace to the caller's user namespace. Enable it to handle idmapped mounts by accounting for the mount's user namespace. In addition the fileystems targeted in the first iteration of this patch series make use of the posix_acl_chmod() and, posix_acl_update_mode() helpers. Both helpers perform permission checks on the target inode. Let them handle idmapped mounts. These two helpers are called when posix acls are set by the respective filesystems to handle this case we extend the ->set() method to take an additional user namespace argument to pass the mount's user namespace down. Link: https://lore.kernel.org/r/20210121131959.646623-9-christian.brauner@ubuntu.com Cc: Christoph Hellwig Cc: David Howells Cc: Al Viro Cc: linux-fsdevel@vger.kernel.org Reviewed-by: Christoph Hellwig Signed-off-by: Christian Brauner --- Documentation/filesystems/locking.rst | 7 ++-- Documentation/filesystems/porting.rst | 2 + fs/9p/acl.c | 4 +- fs/9p/xattr.c | 1 + fs/afs/xattr.c | 2 + fs/btrfs/acl.c | 3 +- fs/btrfs/inode.c | 3 +- fs/btrfs/xattr.c | 2 + fs/ceph/acl.c | 3 +- fs/ceph/inode.c | 2 +- fs/ceph/xattr.c | 1 + fs/cifs/xattr.c | 1 + fs/ecryptfs/inode.c | 1 + fs/ext2/acl.c | 3 +- fs/ext2/inode.c | 2 +- fs/ext2/xattr_security.c | 1 + fs/ext2/xattr_trusted.c | 1 + fs/ext2/xattr_user.c | 1 + fs/ext4/acl.c | 3 +- fs/ext4/inode.c | 2 +- fs/ext4/xattr_hurd.c | 1 + fs/ext4/xattr_security.c | 1 + fs/ext4/xattr_trusted.c | 1 + fs/ext4/xattr_user.c | 1 + fs/f2fs/acl.c | 3 +- fs/f2fs/file.c | 7 ++-- fs/f2fs/xattr.c | 2 + fs/fuse/xattr.c | 2 + fs/gfs2/acl.c | 2 +- fs/gfs2/inode.c | 3 +- fs/gfs2/xattr.c | 1 + fs/hfs/attr.c | 1 + fs/hfsplus/xattr.c | 1 + fs/hfsplus/xattr_security.c | 1 + fs/hfsplus/xattr_trusted.c | 1 + fs/hfsplus/xattr_user.c | 1 + fs/jffs2/acl.c | 3 +- fs/jffs2/fs.c | 2 +- fs/jffs2/security.c | 1 + fs/jffs2/xattr_trusted.c | 1 + fs/jffs2/xattr_user.c | 1 + fs/jfs/acl.c | 2 +- fs/jfs/file.c | 2 +- fs/jfs/xattr.c | 2 + fs/kernfs/inode.c | 2 + fs/nfs/nfs4proc.c | 3 ++ fs/nfsd/nfs2acl.c | 6 ++- fs/nfsd/nfs3acl.c | 6 ++- fs/nfsd/nfs4acl.c | 5 ++- fs/ocfs2/acl.c | 3 +- fs/ocfs2/xattr.c | 3 ++ fs/orangefs/acl.c | 3 +- fs/orangefs/inode.c | 2 +- fs/orangefs/xattr.c | 1 + fs/overlayfs/super.c | 3 ++ fs/posix_acl.c | 79 +++++++++++++++++++++++++---------- fs/reiserfs/xattr_acl.c | 5 ++- fs/reiserfs/xattr_security.c | 3 +- fs/reiserfs/xattr_trusted.c | 3 +- fs/reiserfs/xattr_user.c | 3 +- fs/ubifs/xattr.c | 1 + fs/xattr.c | 14 ++++--- fs/xfs/xfs_acl.c | 3 +- fs/xfs/xfs_iops.c | 2 +- fs/xfs/xfs_xattr.c | 7 ++-- include/linux/capability.h | 3 +- include/linux/posix_acl.h | 11 +++-- include/linux/posix_acl_xattr.h | 12 ++++-- include/linux/xattr.h | 3 +- mm/shmem.c | 3 +- net/socket.c | 1 + security/commoncap.c | 45 ++++++++++++++++---- 72 files changed, 238 insertions(+), 85 deletions(-) (limited to 'Documentation') diff --git a/Documentation/filesystems/locking.rst b/Documentation/filesystems/locking.rst index c0f2c7586531..b7dcc86c92a4 100644 --- a/Documentation/filesystems/locking.rst +++ b/Documentation/filesystems/locking.rst @@ -126,9 +126,10 @@ prototypes:: int (*get)(const struct xattr_handler *handler, struct dentry *dentry, struct inode *inode, const char *name, void *buffer, size_t size); - int (*set)(const struct xattr_handler *handler, struct dentry *dentry, - struct inode *inode, const char *name, const void *buffer, - size_t size, int flags); + int (*set)(const struct xattr_handler *handler, + struct user_namespace *mnt_userns, + struct dentry *dentry, struct inode *inode, const char *name, + const void *buffer, size_t size, int flags); locking rules: all may block diff --git a/Documentation/filesystems/porting.rst b/Documentation/filesystems/porting.rst index 867036aa90b8..de1dcec3b5b8 100644 --- a/Documentation/filesystems/porting.rst +++ b/Documentation/filesystems/porting.rst @@ -717,6 +717,8 @@ be removed. Switch while you still can; the old one won't stay. **mandatory** ->setxattr() and xattr_handler.set() get dentry and inode passed separately. +The xattr_handler.set() gets passed the user namespace of the mount the inode +is seen from so filesystems can idmap the i_uid and i_gid accordingly. dentry might be yet to be attached to inode, so do _not_ use its ->d_inode in the instances. Rationale: !@#!@# security_d_instantiate() needs to be called before we attach dentry to inode and !@#!@##!@$!$#!@#$!@$!@$ smack diff --git a/fs/9p/acl.c b/fs/9p/acl.c index d77b28e8d57a..1c14f18a6ec9 100644 --- a/fs/9p/acl.c +++ b/fs/9p/acl.c @@ -239,6 +239,7 @@ static int v9fs_xattr_get_acl(const struct xattr_handler *handler, } static int v9fs_xattr_set_acl(const struct xattr_handler *handler, + struct user_namespace *mnt_userns, struct dentry *dentry, struct inode *inode, const char *name, const void *value, size_t size, int flags) @@ -279,7 +280,8 @@ static int v9fs_xattr_set_acl(const struct xattr_handler *handler, struct iattr iattr = { 0 }; struct posix_acl *old_acl = acl; - retval = posix_acl_update_mode(inode, &iattr.ia_mode, &acl); + retval = posix_acl_update_mode(mnt_userns, inode, + &iattr.ia_mode, &acl); if (retval) goto err_out; if (!acl) { diff --git a/fs/9p/xattr.c b/fs/9p/xattr.c index 87217dd0433e..ee331845e2c7 100644 --- a/fs/9p/xattr.c +++ b/fs/9p/xattr.c @@ -157,6 +157,7 @@ static int v9fs_xattr_handler_get(const struct xattr_handler *handler, } static int v9fs_xattr_handler_set(const struct xattr_handler *handler, + struct user_namespace *mnt_userns, struct dentry *dentry, struct inode *inode, const char *name, const void *value, size_t size, int flags) diff --git a/fs/afs/xattr.c b/fs/afs/xattr.c index 95c573dcda11..c629caae5002 100644 --- a/fs/afs/xattr.c +++ b/fs/afs/xattr.c @@ -120,6 +120,7 @@ static const struct afs_operation_ops afs_store_acl_operation = { * Set a file's AFS3 ACL. */ static int afs_xattr_set_acl(const struct xattr_handler *handler, + struct user_namespace *mnt_userns, struct dentry *dentry, struct inode *inode, const char *name, const void *buffer, size_t size, int flags) @@ -248,6 +249,7 @@ static const struct afs_operation_ops yfs_store_opaque_acl2_operation = { * Set a file's YFS ACL. */ static int afs_xattr_set_yfs(const struct xattr_handler *handler, + struct user_namespace *mnt_userns, struct dentry *dentry, struct inode *inode, const char *name, const void *buffer, size_t size, int flags) diff --git a/fs/btrfs/acl.c b/fs/btrfs/acl.c index a0af1b952c4d..d12a5a8730a8 100644 --- a/fs/btrfs/acl.c +++ b/fs/btrfs/acl.c @@ -113,7 +113,8 @@ int btrfs_set_acl(struct inode *inode, struct posix_acl *acl, int type) umode_t old_mode = inode->i_mode; if (type == ACL_TYPE_ACCESS && acl) { - ret = posix_acl_update_mode(inode, &inode->i_mode, &acl); + ret = posix_acl_update_mode(&init_user_ns, inode, + &inode->i_mode, &acl); if (ret) return ret; } diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index 792191a8705b..6c18fb1a25af 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c @@ -5070,7 +5070,8 @@ static int btrfs_setattr(struct dentry *dentry, struct iattr *attr) err = btrfs_dirty_inode(inode); if (!err && attr->ia_valid & ATTR_MODE) - err = posix_acl_chmod(inode, inode->i_mode); + err = posix_acl_chmod(&init_user_ns, inode, + inode->i_mode); } return err; diff --git a/fs/btrfs/xattr.c b/fs/btrfs/xattr.c index af6246f36a9e..b025102e435f 100644 --- a/fs/btrfs/xattr.c +++ b/fs/btrfs/xattr.c @@ -362,6 +362,7 @@ static int btrfs_xattr_handler_get(const struct xattr_handler *handler, } static int btrfs_xattr_handler_set(const struct xattr_handler *handler, + struct user_namespace *mnt_userns, struct dentry *unused, struct inode *inode, const char *name, const void *buffer, size_t size, int flags) @@ -371,6 +372,7 @@ static int btrfs_xattr_handler_set(const struct xattr_handler *handler, } static int btrfs_xattr_handler_set_prop(const struct xattr_handler *handler, + struct user_namespace *mnt_userns, struct dentry *unused, struct inode *inode, const char *name, const void *value, size_t size, int flags) diff --git a/fs/ceph/acl.c b/fs/ceph/acl.c index e0465741c591..52a01ddbc4ac 100644 --- a/fs/ceph/acl.c +++ b/fs/ceph/acl.c @@ -100,7 +100,8 @@ int ceph_set_acl(struct inode *inode, struct posix_acl *acl, int type) case ACL_TYPE_ACCESS: name = XATTR_NAME_POSIX_ACL_ACCESS; if (acl) { - ret = posix_acl_update_mode(inode, &new_mode, &acl); + ret = posix_acl_update_mode(&init_user_ns, inode, + &new_mode, &acl); if (ret) goto out; } diff --git a/fs/ceph/inode.c b/fs/ceph/inode.c index 285d3baca27e..145e26a4ddbb 100644 --- a/fs/ceph/inode.c +++ b/fs/ceph/inode.c @@ -2262,7 +2262,7 @@ int ceph_setattr(struct dentry *dentry, struct iattr *attr) err = __ceph_setattr(inode, attr); if (err >= 0 && (attr->ia_valid & ATTR_MODE)) - err = posix_acl_chmod(inode, attr->ia_mode); + err = posix_acl_chmod(&init_user_ns, inode, attr->ia_mode); return err; } diff --git a/fs/ceph/xattr.c b/fs/ceph/xattr.c index 24997982de01..02f59bcb4f27 100644 --- a/fs/ceph/xattr.c +++ b/fs/ceph/xattr.c @@ -1238,6 +1238,7 @@ static int ceph_get_xattr_handler(const struct xattr_handler *handler, } static int ceph_set_xattr_handler(const struct xattr_handler *handler, + struct user_namespace *mnt_userns, struct dentry *unused, struct inode *inode, const char *name, const void *value, size_t size, int flags) diff --git a/fs/cifs/xattr.c b/fs/cifs/xattr.c index 6b658a1172ef..41a611e76bb7 100644 --- a/fs/cifs/xattr.c +++ b/fs/cifs/xattr.c @@ -101,6 +101,7 @@ static int cifs_creation_time_set(unsigned int xid, struct cifs_tcon *pTcon, } static int cifs_xattr_set(const struct xattr_handler *handler, + struct user_namespace *mnt_userns, struct dentry *dentry, struct inode *inode, const char *name, const void *value, size_t size, int flags) diff --git a/fs/ecryptfs/inode.c b/fs/ecryptfs/inode.c index d3ea0c57b075..ac6472a82567 100644 --- a/fs/ecryptfs/inode.c +++ b/fs/ecryptfs/inode.c @@ -1133,6 +1133,7 @@ static int ecryptfs_xattr_get(const struct xattr_handler *handler, } static int ecryptfs_xattr_set(const struct xattr_handler *handler, + struct user_namespace *mnt_userns, struct dentry *dentry, struct inode *inode, const char *name, const void *value, size_t size, int flags) diff --git a/fs/ext2/acl.c b/fs/ext2/acl.c index cf4c77f8dd08..9031f7df2d48 100644 --- a/fs/ext2/acl.c +++ b/fs/ext2/acl.c @@ -223,7 +223,8 @@ ext2_set_acl(struct inode *inode, struct posix_acl *acl, int type) umode_t mode = inode->i_mode; if (type == ACL_TYPE_ACCESS && acl) { - error = posix_acl_update_mode(inode, &mode, &acl); + error = posix_acl_update_mode(&init_user_ns, inode, &mode, + &acl); if (error) return error; update_mode = 1; diff --git a/fs/ext2/inode.c b/fs/ext2/inode.c index 06c0cf28c1a0..9de813635d8d 100644 --- a/fs/ext2/inode.c +++ b/fs/ext2/inode.c @@ -1691,7 +1691,7 @@ int ext2_setattr(struct dentry *dentry, struct iattr *iattr) } setattr_copy(&init_user_ns, inode, iattr); if (iattr->ia_valid & ATTR_MODE) - error = posix_acl_chmod(inode, inode->i_mode); + error = posix_acl_chmod(&init_user_ns, inode, inode->i_mode); mark_inode_dirty(inode); return error; diff --git a/fs/ext2/xattr_security.c b/fs/ext2/xattr_security.c index 9a682e440acb..ebade1f52451 100644 --- a/fs/ext2/xattr_security.c +++ b/fs/ext2/xattr_security.c @@ -19,6 +19,7 @@ ext2_xattr_security_get(const struct xattr_handler *handler, static int ext2_xattr_security_set(const struct xattr_handler *handler, + struct user_namespace *mnt_userns, struct dentry *unused, struct inode *inode, const char *name, const void *value, size_t size, int flags) diff --git a/fs/ext2/xattr_trusted.c b/fs/ext2/xattr_trusted.c index 49add1107850..18a87d5dd1ab 100644 --- a/fs/ext2/xattr_trusted.c +++ b/fs/ext2/xattr_trusted.c @@ -26,6 +26,7 @@ ext2_xattr_trusted_get(const struct xattr_handler *handler, static int ext2_xattr_trusted_set(const struct xattr_handler *handler, + struct user_namespace *mnt_userns, struct dentry *unused, struct inode *inode, const char *name, const void *value, size_t size, int flags) diff --git a/fs/ext2/xattr_user.c b/fs/ext2/xattr_user.c index c243a3b4d69d..58092449f8ff 100644 --- a/fs/ext2/xattr_user.c +++ b/fs/ext2/xattr_user.c @@ -30,6 +30,7 @@ ext2_xattr_user_get(const struct xattr_handler *handler, static int ext2_xattr_user_set(const struct xattr_handler *handler, + struct user_namespace *mnt_userns, struct dentry *unused, struct inode *inode, const char *name, const void *value, size_t size, int flags) diff --git a/fs/ext4/acl.c b/fs/ext4/acl.c index 68aaed48315f..7b0fb66bc04d 100644 --- a/fs/ext4/acl.c +++ b/fs/ext4/acl.c @@ -245,7 +245,8 @@ retry: ext4_fc_start_update(inode); if ((type == ACL_TYPE_ACCESS) && acl) { - error = posix_acl_update_mode(inode, &mode, &acl); + error = posix_acl_update_mode(&init_user_ns, inode, &mode, + &acl); if (error) goto out_stop; if (mode != inode->i_mode) diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c index 8edfa3e226e6..24ea5851e90a 100644 --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c @@ -5524,7 +5524,7 @@ out_mmap_sem: ext4_orphan_del(NULL, inode); if (!error && (ia_valid & ATTR_MODE)) - rc = posix_acl_chmod(inode, inode->i_mode); + rc = posix_acl_chmod(&init_user_ns, inode, inode->i_mode); err_out: if (error) diff --git a/fs/ext4/xattr_hurd.c b/fs/ext4/xattr_hurd.c index 8cfa74a56361..c78df5790377 100644 --- a/fs/ext4/xattr_hurd.c +++ b/fs/ext4/xattr_hurd.c @@ -32,6 +32,7 @@ ext4_xattr_hurd_get(const struct xattr_handler *handler, static int ext4_xattr_hurd_set(const struct xattr_handler *handler, + struct user_namespace *mnt_userns, struct dentry *unused, struct inode *inode, const char *name, const void *value, size_t size, int flags) diff --git a/fs/ext4/xattr_security.c b/fs/ext4/xattr_security.c index 197a9d8a15ef..8213f66f7b2d 100644 --- a/fs/ext4/xattr_security.c +++ b/fs/ext4/xattr_security.c @@ -23,6 +23,7 @@ ext4_xattr_security_get(const struct xattr_handler *handler, static int ext4_xattr_security_set(const struct xattr_handler *handler, + struct user_namespace *mnt_userns, struct dentry *unused, struct inode *inode, const char *name, const void *value, size_t size, int flags) diff --git a/fs/ext4/xattr_trusted.c b/fs/ext4/xattr_trusted.c index e9389e5d75c3..7c21ffb26d25 100644 --- a/fs/ext4/xattr_trusted.c +++ b/fs/ext4/xattr_trusted.c @@ -30,6 +30,7 @@ ext4_xattr_trusted_get(const struct xattr_handler *handler, static int ext4_xattr_trusted_set(const struct xattr_handler *handler, + struct user_namespace *mnt_userns, struct dentry *unused, struct inode *inode, const char *name, const void *value, size_t size, int flags) diff --git a/fs/ext4/xattr_user.c b/fs/ext4/xattr_user.c index d4546184b34b..2fe7ff0a479c 100644 --- a/fs/ext4/xattr_user.c +++ b/fs/ext4/xattr_user.c @@ -31,6 +31,7 @@ ext4_xattr_user_get(const struct xattr_handler *handler, static int ext4_xattr_user_set(const struct xattr_handler *handler, + struct user_namespace *mnt_userns, struct dentry *unused, struct inode *inode, const char *name, const void *value, size_t size, int flags) diff --git a/fs/f2fs/acl.c b/fs/f2fs/acl.c index 1e5e9b1136ee..6a95bf28f602 100644 --- a/fs/f2fs/acl.c +++ b/fs/f2fs/acl.c @@ -213,7 +213,8 @@ static int __f2fs_set_acl(struct inode *inode, int type, case ACL_TYPE_ACCESS: name_index = F2FS_XATTR_INDEX_POSIX_ACL_ACCESS; if (acl && !ipage) { - error = posix_acl_update_mode(inode, &mode, &acl); + error = posix_acl_update_mode(&init_user_ns, inode, + &mode, &acl); if (error) return error; set_acl_inode(inode, mode); diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c index 90d7b89176de..6ccdfe0606d9 100644 --- a/fs/f2fs/file.c +++ b/fs/f2fs/file.c @@ -831,8 +831,8 @@ int f2fs_getattr(const struct path *path, struct kstat *stat, } #ifdef CONFIG_F2FS_FS_POSIX_ACL -static void __setattr_copy(struct user_namespace *mnt_userns, struct inode *inode, - const struct iattr *attr) +static void __setattr_copy(struct user_namespace *mnt_userns, + struct inode *inode, const struct iattr *attr) { unsigned int ia_valid = attr->ia_valid; @@ -950,7 +950,8 @@ int f2fs_setattr(struct dentry *dentry, struct iattr *attr) __setattr_copy(&init_user_ns, inode, attr); if (attr->ia_valid & ATTR_MODE) { - err = posix_acl_chmod(inode, f2fs_get_inode_mode(inode)); + err = posix_acl_chmod(&init_user_ns, inode, + f2fs_get_inode_mode(inode)); if (err || is_inode_flag_set(inode, FI_ACL_MODE)) { inode->i_mode = F2FS_I(inode)->i_acl_mode; clear_inode_flag(inode, FI_ACL_MODE); diff --git a/fs/f2fs/xattr.c b/fs/f2fs/xattr.c index d772bf13a814..10081bf74324 100644 --- a/fs/f2fs/xattr.c +++ b/fs/f2fs/xattr.c @@ -64,6 +64,7 @@ static int f2fs_xattr_generic_get(const struct xattr_handler *handler, } static int f2fs_xattr_generic_set(const struct xattr_handler *handler, + struct user_namespace *mnt_userns, struct dentry *unused, struct inode *inode, const char *name, const void *value, size_t size, int flags) @@ -107,6 +108,7 @@ static int f2fs_xattr_advise_get(const struct xattr_handler *handler, } static int f2fs_xattr_advise_set(const struct xattr_handler *handler, + struct user_namespace *mnt_userns, struct dentry *unused, struct inode *inode, const char *name, const void *value, size_t size, int flags) diff --git a/fs/fuse/xattr.c b/fs/fuse/xattr.c index cdea18de94f7..1a7d7ace54e1 100644 --- a/fs/fuse/xattr.c +++ b/fs/fuse/xattr.c @@ -188,6 +188,7 @@ static int fuse_xattr_get(const struct xattr_handler *handler, } static int fuse_xattr_set(const struct xattr_handler *handler, + struct user_namespace *mnt_userns, struct dentry *dentry, struct inode *inode, const char *name, const void *value, size_t size, int flags) @@ -214,6 +215,7 @@ static int no_xattr_get(const struct xattr_handler *handler, } static int no_xattr_set(const struct xattr_handler *handler, + struct user_namespace *mnt_userns, struct dentry *dentry, struct inode *nodee, const char *name, const void *value, size_t size, int flags) diff --git a/fs/gfs2/acl.c b/fs/gfs2/acl.c index 2e939f5fe751..ce88ef29eef0 100644 --- a/fs/gfs2/acl.c +++ b/fs/gfs2/acl.c @@ -130,7 +130,7 @@ int gfs2_set_acl(struct inode *inode, struct posix_acl *acl, int type) mode = inode->i_mode; if (type == ACL_TYPE_ACCESS && acl) { - ret = posix_acl_update_mode(inode, &mode, &acl); + ret = posix_acl_update_mode(&init_user_ns, inode, &mode, &acl); if (ret) goto unlock; } diff --git a/fs/gfs2/inode.c b/fs/gfs2/inode.c index 59c25181d108..728405d15a05 100644 --- a/fs/gfs2/inode.c +++ b/fs/gfs2/inode.c @@ -1993,7 +1993,8 @@ static int gfs2_setattr(struct dentry *dentry, struct iattr *attr) else { error = gfs2_setattr_simple(inode, attr); if (!error && attr->ia_valid & ATTR_MODE) - error = posix_acl_chmod(inode, inode->i_mode); + error = posix_acl_chmod(&init_user_ns, inode, + inode->i_mode); } error: diff --git a/fs/gfs2/xattr.c b/fs/gfs2/xattr.c index 9d7667bc4292..13969a813410 100644 --- a/fs/gfs2/xattr.c +++ b/fs/gfs2/xattr.c @@ -1214,6 +1214,7 @@ int __gfs2_xattr_set(struct inode *inode, const char *name, } static int gfs2_xattr_set(const struct xattr_handler *handler, + struct user_namespace *mnt_userns, struct dentry *unused, struct inode *inode, const char *name, const void *value, size_t size, int flags) diff --git a/fs/hfs/attr.c b/fs/hfs/attr.c index 74fa62643136..2bd54efaf416 100644 --- a/fs/hfs/attr.c +++ b/fs/hfs/attr.c @@ -121,6 +121,7 @@ static int hfs_xattr_get(const struct xattr_handler *handler, } static int hfs_xattr_set(const struct xattr_handler *handler, + struct user_namespace *mnt_userns, struct dentry *unused, struct inode *inode, const char *name, const void *value, size_t size, int flags) diff --git a/fs/hfsplus/xattr.c b/fs/hfsplus/xattr.c index bb0b27d88e50..4d169c5a2673 100644 --- a/fs/hfsplus/xattr.c +++ b/fs/hfsplus/xattr.c @@ -858,6 +858,7 @@ static int hfsplus_osx_getxattr(const struct xattr_handler *handler, } static int hfsplus_osx_setxattr(const struct xattr_handler *handler, + struct user_namespace *mnt_userns, struct dentry *unused, struct inode *inode, const char *name, const void *buffer, size_t size, int flags) diff --git a/fs/hfsplus/xattr_security.c b/fs/hfsplus/xattr_security.c index cfbe6a3bfb1e..c1c7a16cbf21 100644 --- a/fs/hfsplus/xattr_security.c +++ b/fs/hfsplus/xattr_security.c @@ -23,6 +23,7 @@ static int hfsplus_security_getxattr(const struct xattr_handler *handler, } static int hfsplus_security_setxattr(const struct xattr_handler *handler, + struct user_namespace *mnt_userns, struct dentry *unused, struct inode *inode, const char *name, const void *buffer, size_t size, int flags) diff --git a/fs/hfsplus/xattr_trusted.c b/fs/hfsplus/xattr_trusted.c index fbad91e1dada..e150372ec564 100644 --- a/fs/hfsplus/xattr_trusted.c +++ b/fs/hfsplus/xattr_trusted.c @@ -22,6 +22,7 @@ static int hfsplus_trusted_getxattr(const struct xattr_handler *handler, } static int hfsplus_trusted_setxattr(const struct xattr_handler *handler, + struct user_namespace *mnt_userns, struct dentry *unused, struct inode *inode, const char *name, const void *buffer, size_t size, int flags) diff --git a/fs/hfsplus/xattr_user.c b/fs/hfsplus/xattr_user.c index 74d19faf255e..a6b60b153916 100644 --- a/fs/hfsplus/xattr_user.c +++ b/fs/hfsplus/xattr_user.c @@ -22,6 +22,7 @@ static int hfsplus_user_getxattr(const struct xattr_handler *handler, } static int hfsplus_user_setxattr(const struct xattr_handler *handler, + struct user_namespace *mnt_userns, struct dentry *unused, struct inode *inode, const char *name, const void *buffer, size_t size, int flags) diff --git a/fs/jffs2/acl.c b/fs/jffs2/acl.c index 093ffbd82395..5f27ac593479 100644 --- a/fs/jffs2/acl.c +++ b/fs/jffs2/acl.c @@ -236,7 +236,8 @@ int jffs2_set_acl(struct inode *inode, struct posix_acl *acl, int type) if (acl) { umode_t mode; - rc = posix_acl_update_mode(inode, &mode, &acl); + rc = posix_acl_update_mode(&init_user_ns, inode, &mode, + &acl); if (rc) return rc; if (inode->i_mode != mode) { diff --git a/fs/jffs2/fs.c b/fs/jffs2/fs.c index 67993808f4da..ee9f51bab4c6 100644 --- a/fs/jffs2/fs.c +++ b/fs/jffs2/fs.c @@ -201,7 +201,7 @@ int jffs2_setattr(struct dentry *dentry, struct iattr *iattr) rc = jffs2_do_setattr(inode, iattr); if (!rc && (iattr->ia_valid & ATTR_MODE)) - rc = posix_acl_chmod(inode, inode->i_mode); + rc = posix_acl_chmod(&init_user_ns, inode, inode->i_mode); return rc; } diff --git a/fs/jffs2/security.c b/fs/jffs2/security.c index c2332e30f218..aef5522551db 100644 --- a/fs/jffs2/security.c +++ b/fs/jffs2/security.c @@ -57,6 +57,7 @@ static int jffs2_security_getxattr(const struct xattr_handler *handler, } static int jffs2_security_setxattr(const struct xattr_handler *handler, + struct user_namespace *mnt_userns, struct dentry *unused, struct inode *inode, const char *name, const void *buffer, size_t size, int flags) diff --git a/fs/jffs2/xattr_trusted.c b/fs/jffs2/xattr_trusted.c index 5d6030826c52..cc3f24883e7d 100644 --- a/fs/jffs2/xattr_trusted.c +++ b/fs/jffs2/xattr_trusted.c @@ -25,6 +25,7 @@ static int jffs2_trusted_getxattr(const struct xattr_handler *handler, } static int jffs2_trusted_setxattr(const struct xattr_handler *handler, + struct user_namespace *mnt_userns, struct dentry *unused, struct inode *inode, const char *name, const void *buffer, size_t size, int flags) diff --git a/fs/jffs2/xattr_user.c b/fs/jffs2/xattr_user.c index 9d027b4abcf9..fb945977c013 100644 --- a/fs/jffs2/xattr_user.c +++ b/fs/jffs2/xattr_user.c @@ -25,6 +25,7 @@ static int jffs2_user_getxattr(const struct xattr_handler *handler, } static int jffs2_user_setxattr(const struct xattr_handler *handler, + struct user_namespace *mnt_userns, struct dentry *unused, struct inode *inode, const char *name, const void *buffer, size_t size, int flags) diff --git a/fs/jfs/acl.c b/fs/jfs/acl.c index 92cc0ac2d1fc..cf79a34bfada 100644 --- a/fs/jfs/acl.c +++ b/fs/jfs/acl.c @@ -101,7 +101,7 @@ int jfs_set_acl(struct inode *inode, struct posix_acl *acl, int type) tid = txBegin(inode->i_sb, 0); mutex_lock(&JFS_IP(inode)->commit_mutex); if (type == ACL_TYPE_ACCESS && acl) { - rc = posix_acl_update_mode(inode, &mode, &acl); + rc = posix_acl_update_mode(&init_user_ns, inode, &mode, &acl); if (rc) goto end_tx; if (mode != inode->i_mode) diff --git a/fs/jfs/file.c b/fs/jfs/file.c index ff49876e9c9b..61c3b0c1fbf6 100644 --- a/fs/jfs/file.c +++ b/fs/jfs/file.c @@ -122,7 +122,7 @@ int jfs_setattr(struct dentry *dentry, struct iattr *iattr) mark_inode_dirty(inode); if (iattr->ia_valid & ATTR_MODE) - rc = posix_acl_chmod(inode, inode->i_mode); + rc = posix_acl_chmod(&init_user_ns, inode, inode->i_mode); return rc; } diff --git a/fs/jfs/xattr.c b/fs/jfs/xattr.c index db41e7803163..f9273f6901c8 100644 --- a/fs/jfs/xattr.c +++ b/fs/jfs/xattr.c @@ -932,6 +932,7 @@ static int jfs_xattr_get(const struct xattr_handler *handler, } static int jfs_xattr_set(const struct xattr_handler *handler, + struct user_namespace *mnt_userns, struct dentry *unused, struct inode *inode, const char *name, const void *value, size_t size, int flags) @@ -950,6 +951,7 @@ static int jfs_xattr_get_os2(const struct xattr_handler *handler, } static int jfs_xattr_set_os2(const struct xattr_handler *handler, + struct user_namespace *mnt_userns, struct dentry *unused, struct inode *inode, const char *name, const void *value, size_t size, int flags) diff --git a/fs/kernfs/inode.c b/fs/kernfs/inode.c index 86bd4c593b78..7e44052b42e1 100644 --- a/fs/kernfs/inode.c +++ b/fs/kernfs/inode.c @@ -319,6 +319,7 @@ static int kernfs_vfs_xattr_get(const struct xattr_handler *handler, } static int kernfs_vfs_xattr_set(const struct xattr_handler *handler, + struct user_namespace *mnt_userns, struct dentry *unused, struct inode *inode, const char *suffix, const void *value, size_t size, int flags) @@ -385,6 +386,7 @@ static int kernfs_vfs_user_xattr_rm(struct kernfs_node *kn, } static int kernfs_vfs_user_xattr_set(const struct xattr_handler *handler, + struct user_namespace *mnt_userns, struct dentry *unused, struct inode *inode, const char *suffix, const void *value, size_t size, int flags) diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index 2f4679a62712..a07530cf673d 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c @@ -7491,6 +7491,7 @@ nfs4_release_lockowner(struct nfs_server *server, struct nfs4_lock_state *lsp) #define XATTR_NAME_NFSV4_ACL "system.nfs4_acl" static int nfs4_xattr_set_nfs4_acl(const struct xattr_handler *handler, + struct user_namespace *mnt_userns, struct dentry *unused, struct inode *inode, const char *key, const void *buf, size_t buflen, int flags) @@ -7513,6 +7514,7 @@ static bool nfs4_xattr_list_nfs4_acl(struct dentry *dentry) #ifdef CONFIG_NFS_V4_SECURITY_LABEL static int nfs4_xattr_set_nfs4_label(const struct xattr_handler *handler, + struct user_namespace *mnt_userns, struct dentry *unused, struct inode *inode, const char *key, const void *buf, size_t buflen, int flags) @@ -7563,6 +7565,7 @@ nfs4_listxattr_nfs4_label(struct inode *inode, char *list, size_t list_len) #ifdef CONFIG_NFS_V4_2 static int nfs4_xattr_set_nfs4_user(const struct xattr_handler *handler, + struct user_namespace *mnt_userns, struct dentry *unused, struct inode *inode, const char *key, const void *buf, size_t buflen, int flags) diff --git a/fs/nfsd/nfs2acl.c b/fs/nfsd/nfs2acl.c index b0f66604532a..b83f222558e3 100644 --- a/fs/nfsd/nfs2acl.c +++ b/fs/nfsd/nfs2acl.c @@ -113,10 +113,12 @@ static __be32 nfsacld_proc_setacl(struct svc_rqst *rqstp) fh_lock(fh); - error = set_posix_acl(inode, ACL_TYPE_ACCESS, argp->acl_access); + error = set_posix_acl(&init_user_ns, inode, ACL_TYPE_ACCESS, + argp->acl_access); if (error) goto out_drop_lock; - error = set_posix_acl(inode, ACL_TYPE_DEFAULT, argp->acl_default); + error = set_posix_acl(&init_user_ns, inode, ACL_TYPE_DEFAULT, + argp->acl_default); if (error) goto out_drop_lock; diff --git a/fs/nfsd/nfs3acl.c b/fs/nfsd/nfs3acl.c index 7c30876a31a1..f18ec7e8094d 100644 --- a/fs/nfsd/nfs3acl.c +++ b/fs/nfsd/nfs3acl.c @@ -103,10 +103,12 @@ static __be32 nfsd3_proc_setacl(struct svc_rqst *rqstp) fh_lock(fh); - error = set_posix_acl(inode, ACL_TYPE_ACCESS, argp->acl_access); + error = set_posix_acl(&init_user_ns, inode, ACL_TYPE_ACCESS, + argp->acl_access); if (error) goto out_drop_lock; - error = set_posix_acl(inode, ACL_TYPE_DEFAULT, argp->acl_default); + error = set_posix_acl(&init_user_ns, inode, ACL_TYPE_DEFAULT, + argp->acl_default); out_drop_lock: fh_unlock(fh); diff --git a/fs/nfsd/nfs4acl.c b/fs/nfsd/nfs4acl.c index 71292a0d6f09..eaa3a0cf38f1 100644 --- a/fs/nfsd/nfs4acl.c +++ b/fs/nfsd/nfs4acl.c @@ -781,12 +781,13 @@ nfsd4_set_nfs4_acl(struct svc_rqst *rqstp, struct svc_fh *fhp, fh_lock(fhp); - host_error = set_posix_acl(inode, ACL_TYPE_ACCESS, pacl); + host_error = set_posix_acl(&init_user_ns, inode, ACL_TYPE_ACCESS, pacl); if (host_error < 0) goto out_drop_lock; if (S_ISDIR(inode->i_mode)) { - host_error = set_posix_acl(inode, ACL_TYPE_DEFAULT, dpacl); + host_error = set_posix_acl(&init_user_ns, inode, + ACL_TYPE_DEFAULT, dpacl); } out_drop_lock: diff --git a/fs/ocfs2/acl.c b/fs/ocfs2/acl.c index 7b07f5df3a29..990756cee4bd 100644 --- a/fs/ocfs2/acl.c +++ b/fs/ocfs2/acl.c @@ -274,7 +274,8 @@ int ocfs2_iop_set_acl(struct inode *inode, struct posix_acl *acl, int type) if (type == ACL_TYPE_ACCESS && acl) { umode_t mode; - status = posix_acl_update_mode(inode, &mode, &acl); + status = posix_acl_update_mode(&init_user_ns, inode, &mode, + &acl); if (status) goto unlock; diff --git a/fs/ocfs2/xattr.c b/fs/ocfs2/xattr.c index 9ccd19d8f7b1..36ae47a4aef6 100644 --- a/fs/ocfs2/xattr.c +++ b/fs/ocfs2/xattr.c @@ -7249,6 +7249,7 @@ static int ocfs2_xattr_security_get(const struct xattr_handler *handler, } static int ocfs2_xattr_security_set(const struct xattr_handler *handler, + struct user_namespace *mnt_userns, struct dentry *unused, struct inode *inode, const char *name, const void *value, size_t size, int flags) @@ -7321,6 +7322,7 @@ static int ocfs2_xattr_trusted_get(const struct xattr_handler *handler, } static int ocfs2_xattr_trusted_set(const struct xattr_handler *handler, + struct user_namespace *mnt_userns, struct dentry *unused, struct inode *inode, const char *name, const void *value, size_t size, int flags) @@ -7351,6 +7353,7 @@ static int ocfs2_xattr_user_get(const struct xattr_handler *handler, } static int ocfs2_xattr_user_set(const struct xattr_handler *handler, + struct user_namespace *mnt_userns, struct dentry *unused, struct inode *inode, const char *name, const void *value, size_t size, int flags) diff --git a/fs/orangefs/acl.c b/fs/orangefs/acl.c index a25e6c890975..628921952d16 100644 --- a/fs/orangefs/acl.c +++ b/fs/orangefs/acl.c @@ -132,7 +132,8 @@ int orangefs_set_acl(struct inode *inode, struct posix_acl *acl, int type) * and "mode" to the new desired value. It is up to * us to propagate the new mode back to the server... */ - error = posix_acl_update_mode(inode, &iattr.ia_mode, &acl); + error = posix_acl_update_mode(&init_user_ns, inode, + &iattr.ia_mode, &acl); if (error) { gossip_err("%s: posix_acl_update_mode err: %d\n", __func__, diff --git a/fs/orangefs/inode.c b/fs/orangefs/inode.c index 8ac9491ceb9a..563fe9ab8eb2 100644 --- a/fs/orangefs/inode.c +++ b/fs/orangefs/inode.c @@ -861,7 +861,7 @@ again: if (iattr->ia_valid & ATTR_MODE) /* change mod on a file that has ACLs */ - ret = posix_acl_chmod(inode, inode->i_mode); + ret = posix_acl_chmod(&init_user_ns, inode, inode->i_mode); ret = 0; out: diff --git a/fs/orangefs/xattr.c b/fs/orangefs/xattr.c index bdc285aea360..9a5b757fbd2f 100644 --- a/fs/orangefs/xattr.c +++ b/fs/orangefs/xattr.c @@ -526,6 +526,7 @@ out_unlock: } static int orangefs_xattr_set_default(const struct xattr_handler *handler, + struct user_namespace *mnt_userns, struct dentry *unused, struct inode *inode, const char *name, diff --git a/fs/overlayfs/super.c b/fs/overlayfs/super.c index 39b2e9aa0e5b..e24c995c5fd4 100644 --- a/fs/overlayfs/super.c +++ b/fs/overlayfs/super.c @@ -980,6 +980,7 @@ ovl_posix_acl_xattr_get(const struct xattr_handler *handler, static int __maybe_unused ovl_posix_acl_xattr_set(const struct xattr_handler *handler, + struct user_namespace *mnt_userns, struct dentry *dentry, struct inode *inode, const char *name, const void *value, size_t size, int flags) @@ -1044,6 +1045,7 @@ static int ovl_own_xattr_get(const struct xattr_handler *handler, } static int ovl_own_xattr_set(const struct xattr_handler *handler, + struct user_namespace *mnt_userns, struct dentry *dentry, struct inode *inode, const char *name, const void *value, size_t size, int flags) @@ -1059,6 +1061,7 @@ static int ovl_other_xattr_get(const struct xattr_handler *handler, } static int ovl_other_xattr_set(const struct xattr_handler *handler, + struct user_namespace *mnt_userns, struct dentry *dentry, struct inode *inode, const char *name, const void *value, size_t size, int flags) diff --git a/fs/posix_acl.c b/fs/posix_acl.c index 9ce8214bfdac..d31b60f5d40d 100644 --- a/fs/posix_acl.c +++ b/fs/posix_acl.c @@ -558,8 +558,22 @@ __posix_acl_chmod(struct posix_acl **acl, gfp_t gfp, umode_t mode) } EXPORT_SYMBOL(__posix_acl_chmod); +/** + * posix_acl_chmod - chmod a posix acl + * + * @mnt_userns: user namespace of the mount @inode was found from + * @inode: inode to check permissions on + * @mode: the new mode of @inode + * + * If the inode has been found through an idmapped mount the user namespace of + * the vfsmount must be passed through @mnt_userns. This function will then + * take care to map the inode according to @mnt_userns before checking + * permissions. On non-idmapped mounts or if permission checking is to be + * performed on the raw inode simply passs init_user_ns. + */ int -posix_acl_chmod(struct inode *inode, umode_t mode) + posix_acl_chmod(struct user_namespace *mnt_userns, struct inode *inode, + umode_t mode) { struct posix_acl *acl; int ret = 0; @@ -638,9 +652,10 @@ EXPORT_SYMBOL_GPL(posix_acl_create); /** * posix_acl_update_mode - update mode in set_acl - * @inode: target inode - * @mode_p: mode (pointer) for update - * @acl: acl pointer + * @mnt_userns: user namespace of the mount @inode was found from + * @inode: target inode + * @mode_p: mode (pointer) for update + * @acl: acl pointer * * Update the file mode when setting an ACL: compute the new file permission * bits based on the ACL. In addition, if the ACL is equivalent to the new @@ -649,9 +664,16 @@ EXPORT_SYMBOL_GPL(posix_acl_create); * As with chmod, clear the setgid bit if the caller is not in the owning group * or capable of CAP_FSETID (see inode_change_ok). * + * If the inode has been found through an idmapped mount the user namespace of + * the vfsmount must be passed through @mnt_userns. This function will then + * take care to map the inode according to @mnt_userns before checking + * permissions. On non-idmapped mounts or if permission checking is to be + * performed on the raw inode simply passs init_user_ns. + * * Called from set_acl inode operations. */ -int posix_acl_update_mode(struct inode *inode, umode_t *mode_p, +int posix_acl_update_mode(struct user_namespace *mnt_userns, + struct inode *inode, umode_t *mode_p, struct posix_acl **acl) { umode_t mode = inode->i_mode; @@ -662,8 +684,8 @@ int posix_acl_update_mode(struct inode *inode, umode_t *mode_p, return error; if (error == 0) *acl = NULL; - if (!in_group_p(inode->i_gid) && - !capable_wrt_inode_uidgid(&init_user_ns, inode, CAP_FSETID)) + if (!in_group_p(i_gid_into_mnt(mnt_userns, inode)) && + !capable_wrt_inode_uidgid(mnt_userns, inode, CAP_FSETID)) mode &= ~S_ISGID; *mode_p = mode; return 0; @@ -675,7 +697,8 @@ EXPORT_SYMBOL(posix_acl_update_mode); */ static void posix_acl_fix_xattr_userns( struct user_namespace *to, struct user_namespace *from, - void *value, size_t size) + struct user_namespace *mnt_userns, + void *value, size_t size, bool from_user) { struct posix_acl_xattr_header *header = value; struct posix_acl_xattr_entry *entry = (void *)(header + 1), *end; @@ -700,10 +723,18 @@ static void posix_acl_fix_xattr_userns( switch(le16_to_cpu(entry->e_tag)) { case ACL_USER: uid = make_kuid(from, le32_to_cpu(entry->e_id)); + if (from_user) + uid = kuid_from_mnt(mnt_userns, uid); + else + uid = kuid_into_mnt(mnt_userns, uid); entry->e_id = cpu_to_le32(from_kuid(to, uid)); break; case ACL_GROUP: gid = make_kgid(from, le32_to_cpu(entry->e_id)); + if (from_user) + gid = kgid_from_mnt(mnt_userns, gid); + else + gid = kgid_into_mnt(mnt_userns, gid); entry->e_id = cpu_to_le32(from_kgid(to, gid)); break; default: @@ -712,20 +743,24 @@ static void posix_acl_fix_xattr_userns( } } -void posix_acl_fix_xattr_from_user(void *value, size_t size) +void posix_acl_fix_xattr_from_user(struct user_namespace *mnt_userns, + void *value, size_t size) { struct user_namespace *user_ns = current_user_ns(); - if (user_ns == &init_user_ns) + if ((user_ns == &init_user_ns) && (mnt_userns == &init_user_ns)) return; - posix_acl_fix_xattr_userns(&init_user_ns, user_ns, value, size); + posix_acl_fix_xattr_userns(&init_user_ns, user_ns, mnt_userns, value, + size, true); } -void posix_acl_fix_xattr_to_user(void *value, size_t size) +void posix_acl_fix_xattr_to_user(struct user_namespace *mnt_userns, + void *value, size_t size) { struct user_namespace *user_ns = current_user_ns(); - if (user_ns == &init_user_ns) + if ((user_ns == &init_user_ns) && (mnt_userns == &init_user_ns)) return; - posix_acl_fix_xattr_userns(user_ns, &init_user_ns, value, size); + posix_acl_fix_xattr_userns(user_ns, &init_user_ns, mnt_userns, value, + size, false); } /* @@ -865,7 +900,8 @@ posix_acl_xattr_get(const struct xattr_handler *handler, } int -set_posix_acl(struct inode *inode, int type, struct posix_acl *acl) +set_posix_acl(struct user_namespace *mnt_userns, struct inode *inode, + int type, struct posix_acl *acl) { if (!IS_POSIXACL(inode)) return -EOPNOTSUPP; @@ -874,7 +910,7 @@ set_posix_acl(struct inode *inode, int type, struct posix_acl *acl) if (type == ACL_TYPE_DEFAULT && !S_ISDIR(inode->i_mode)) return acl ? -EACCES : 0; - if (!inode_owner_or_capable(&init_user_ns, inode)) + if (!inode_owner_or_capable(mnt_userns, inode)) return -EPERM; if (acl) { @@ -888,9 +924,10 @@ EXPORT_SYMBOL(set_posix_acl); static int posix_acl_xattr_set(const struct xattr_handler *handler, - struct dentry *unused, struct inode *inode, - const char *name, const void *value, - size_t size, int flags) + struct user_namespace *mnt_userns, + struct dentry *unused, struct inode *inode, + const char *name, const void *value, size_t size, + int flags) { struct posix_acl *acl = NULL; int ret; @@ -900,7 +937,7 @@ posix_acl_xattr_set(const struct xattr_handler *handler, if (IS_ERR(acl)) return PTR_ERR(acl); } - ret = set_posix_acl(inode, handler->flags, acl); + ret = set_posix_acl(mnt_userns, inode, handler->flags, acl); posix_acl_release(acl); return ret; } @@ -934,7 +971,7 @@ int simple_set_acl(struct inode *inode, struct posix_acl *acl, int type) int error; if (type == ACL_TYPE_ACCESS) { - error = posix_acl_update_mode(inode, + error = posix_acl_update_mode(&init_user_ns, inode, &inode->i_mode, &acl); if (error) return error; diff --git a/fs/reiserfs/xattr_acl.c b/fs/reiserfs/xattr_acl.c index ccd40df6eb45..4bf976bc7bad 100644 --- a/fs/reiserfs/xattr_acl.c +++ b/fs/reiserfs/xattr_acl.c @@ -40,7 +40,8 @@ reiserfs_set_acl(struct inode *inode, struct posix_acl *acl, int type) reiserfs_write_unlock(inode->i_sb); if (error == 0) { if (type == ACL_TYPE_ACCESS && acl) { - error = posix_acl_update_mode(inode, &mode, &acl); + error = posix_acl_update_mode(&init_user_ns, inode, + &mode, &acl); if (error) goto unlock; update_mode = 1; @@ -399,5 +400,5 @@ int reiserfs_acl_chmod(struct inode *inode) !reiserfs_posixacl(inode->i_sb)) return 0; - return posix_acl_chmod(inode, inode->i_mode); + return posix_acl_chmod(&init_user_ns, inode, inode->i_mode); } diff --git a/fs/reiserfs/xattr_security.c b/fs/reiserfs/xattr_security.c index 20be9a0e5870..8965c8e5e172 100644 --- a/fs/reiserfs/xattr_security.c +++ b/fs/reiserfs/xattr_security.c @@ -21,7 +21,8 @@ security_get(const struct xattr_handler *handler, struct dentry *unused, } static int -security_set(const struct xattr_handler *handler, struct dentry *unused, +security_set(const struct xattr_handler *handler, + struct user_namespace *mnt_userns, struct dentry *unused, struct inode *inode, const char *name, const void *buffer, size_t size, int flags) { diff --git a/fs/reiserfs/xattr_trusted.c b/fs/reiserfs/xattr_trusted.c index 5ed48da3d02b..d853cea2afcd 100644 --- a/fs/reiserfs/xattr_trusted.c +++ b/fs/reiserfs/xattr_trusted.c @@ -20,7 +20,8 @@ trusted_get(const struct xattr_handler *handler, struct dentry *unused, } static int -trusted_set(const struct xattr_handler *handler, struct dentry *unused, +trusted_set(const struct xattr_handler *handler, + struct user_namespace *mnt_userns, struct dentry *unused, struct inode *inode, const char *name, const void *buffer, size_t size, int flags) { diff --git a/fs/reiserfs/xattr_user.c b/fs/reiserfs/xattr_user.c index a573ca45bacc..65d9cd10a5ea 100644 --- a/fs/reiserfs/xattr_user.c +++ b/fs/reiserfs/xattr_user.c @@ -18,7 +18,8 @@ user_get(const struct xattr_handler *handler, struct dentry *unused, } static int -user_set(const struct xattr_handler *handler, struct dentry *unused, +user_set(const struct xattr_handler *handler, struct user_namespace *mnt_userns, + struct dentry *unused, struct inode *inode, const char *name, const void *buffer, size_t size, int flags) { diff --git a/fs/ubifs/xattr.c b/fs/ubifs/xattr.c index a0b9b349efe6..8f4135c22ab6 100644 --- a/fs/ubifs/xattr.c +++ b/fs/ubifs/xattr.c @@ -681,6 +681,7 @@ static int xattr_get(const struct xattr_handler *handler, } static int xattr_set(const struct xattr_handler *handler, + struct user_namespace *mnt_userns, struct dentry *dentry, struct inode *inode, const char *name, const void *value, size_t size, int flags) diff --git a/fs/xattr.c b/fs/xattr.c index c669922e1bde..d777025121e0 100644 --- a/fs/xattr.c +++ b/fs/xattr.c @@ -175,7 +175,8 @@ __vfs_setxattr(struct dentry *dentry, struct inode *inode, const char *name, return -EOPNOTSUPP; if (size == 0) value = ""; /* empty EA, do not remove */ - return handler->set(handler, dentry, inode, name, value, size, flags); + return handler->set(handler, &init_user_ns, dentry, inode, name, value, + size, flags); } EXPORT_SYMBOL(__vfs_setxattr); @@ -281,7 +282,7 @@ vfs_setxattr(struct dentry *dentry, const char *name, const void *value, int error; if (size && strcmp(name, XATTR_NAME_CAPS) == 0) { - error = cap_convert_nscap(dentry, &value, size); + error = cap_convert_nscap(&init_user_ns, dentry, &value, size); if (error < 0) return error; size = error; @@ -450,7 +451,8 @@ __vfs_removexattr(struct dentry *dentry, const char *name) return PTR_ERR(handler); if (!handler->set) return -EOPNOTSUPP; - return handler->set(handler, dentry, inode, name, NULL, 0, XATTR_REPLACE); + return handler->set(handler, &init_user_ns, dentry, inode, name, NULL, + 0, XATTR_REPLACE); } EXPORT_SYMBOL(__vfs_removexattr); @@ -548,7 +550,8 @@ setxattr(struct dentry *d, const char __user *name, const void __user *value, } if ((strcmp(kname, XATTR_NAME_POSIX_ACL_ACCESS) == 0) || (strcmp(kname, XATTR_NAME_POSIX_ACL_DEFAULT) == 0)) - posix_acl_fix_xattr_from_user(kvalue, size); + posix_acl_fix_xattr_from_user(&init_user_ns, kvalue, + size); } error = vfs_setxattr(d, kname, kvalue, size, flags); @@ -642,7 +645,8 @@ getxattr(struct dentry *d, const char __user *name, void __user *value, if (error > 0) { if ((strcmp(kname, XATTR_NAME_POSIX_ACL_ACCESS) == 0) || (strcmp(kname, XATTR_NAME_POSIX_ACL_DEFAULT) == 0)) - posix_acl_fix_xattr_to_user(kvalue, error); + posix_acl_fix_xattr_to_user(&init_user_ns, kvalue, + error); if (size && copy_to_user(value, kvalue, error)) error = -EFAULT; } else if (error == -ERANGE && size >= XATTR_SIZE_MAX) { diff --git a/fs/xfs/xfs_acl.c b/fs/xfs/xfs_acl.c index 779cb73b3d00..368351298bd5 100644 --- a/fs/xfs/xfs_acl.c +++ b/fs/xfs/xfs_acl.c @@ -252,7 +252,8 @@ xfs_set_acl(struct inode *inode, struct posix_acl *acl, int type) return error; if (type == ACL_TYPE_ACCESS) { - error = posix_acl_update_mode(inode, &mode, &acl); + error = posix_acl_update_mode(&init_user_ns, inode, &mode, + &acl); if (error) return error; set_mode = true; diff --git a/fs/xfs/xfs_iops.c b/fs/xfs/xfs_iops.c index 08a478d25122..26d22edef741 100644 --- a/fs/xfs/xfs_iops.c +++ b/fs/xfs/xfs_iops.c @@ -807,7 +807,7 @@ xfs_setattr_nonsize( * Posix ACL code seems to care about this issue either. */ if (mask & ATTR_MODE) { - error = posix_acl_chmod(inode, inode->i_mode); + error = posix_acl_chmod(&init_user_ns, inode, inode->i_mode); if (error) return error; } diff --git a/fs/xfs/xfs_xattr.c b/fs/xfs/xfs_xattr.c index bca48b308c02..12be32f66dc1 100644 --- a/fs/xfs/xfs_xattr.c +++ b/fs/xfs/xfs_xattr.c @@ -38,9 +38,10 @@ xfs_xattr_get(const struct xattr_handler *handler, struct dentry *unused, } static int -xfs_xattr_set(const struct xattr_handler *handler, struct dentry *unused, - struct inode *inode, const char *name, const void *value, - size_t size, int flags) +xfs_xattr_set(const struct xattr_handler *handler, + struct user_namespace *mnt_userns, struct dentry *unused, + struct inode *inode, const char *name, const void *value, + size_t size, int flags) { struct xfs_da_args args = { .dp = XFS_I(inode), diff --git a/include/linux/capability.h b/include/linux/capability.h index 62bfa3ed84d7..da21ef118b04 100644 --- a/include/linux/capability.h +++ b/include/linux/capability.h @@ -273,6 +273,7 @@ static inline bool checkpoint_restore_ns_capable(struct user_namespace *ns) /* audit system wants to get cap info from files as well */ extern int get_vfs_caps_from_disk(const struct dentry *dentry, struct cpu_vfs_cap_data *cpu_caps); -extern int cap_convert_nscap(struct dentry *dentry, const void **ivalue, size_t size); +int cap_convert_nscap(struct user_namespace *mnt_userns, struct dentry *dentry, + const void **ivalue, size_t size); #endif /* !_LINUX_CAPABILITY_H */ diff --git a/include/linux/posix_acl.h b/include/linux/posix_acl.h index 85fb4c0c650a..6dcd8b8f6ab5 100644 --- a/include/linux/posix_acl.h +++ b/include/linux/posix_acl.h @@ -69,13 +69,15 @@ extern int __posix_acl_create(struct posix_acl **, gfp_t, umode_t *); extern int __posix_acl_chmod(struct posix_acl **, gfp_t, umode_t); extern struct posix_acl *get_posix_acl(struct inode *, int); -extern int set_posix_acl(struct inode *, int, struct posix_acl *); +extern int set_posix_acl(struct user_namespace *, struct inode *, int, + struct posix_acl *); #ifdef CONFIG_FS_POSIX_ACL -extern int posix_acl_chmod(struct inode *, umode_t); +int posix_acl_chmod(struct user_namespace *, struct inode *, umode_t); extern int posix_acl_create(struct inode *, umode_t *, struct posix_acl **, struct posix_acl **); -extern int posix_acl_update_mode(struct inode *, umode_t *, struct posix_acl **); +int posix_acl_update_mode(struct user_namespace *, struct inode *, umode_t *, + struct posix_acl **); extern int simple_set_acl(struct inode *, struct posix_acl *, int); extern int simple_acl_create(struct inode *, struct inode *); @@ -95,7 +97,8 @@ static inline void cache_no_acl(struct inode *inode) inode->i_default_acl = NULL; } #else -static inline int posix_acl_chmod(struct inode *inode, umode_t mode) +static inline int posix_acl_chmod(struct user_namespace *mnt_userns, + struct inode *inode, umode_t mode) { return 0; } diff --git a/include/linux/posix_acl_xattr.h b/include/linux/posix_acl_xattr.h index 2387709991b5..060e8d203181 100644 --- a/include/linux/posix_acl_xattr.h +++ b/include/linux/posix_acl_xattr.h @@ -33,13 +33,17 @@ posix_acl_xattr_count(size_t size) } #ifdef CONFIG_FS_POSIX_ACL -void posix_acl_fix_xattr_from_user(void *value, size_t size); -void posix_acl_fix_xattr_to_user(void *value, size_t size); +void posix_acl_fix_xattr_from_user(struct user_namespace *mnt_userns, + void *value, size_t size); +void posix_acl_fix_xattr_to_user(struct user_namespace *mnt_userns, + void *value, size_t size); #else -static inline void posix_acl_fix_xattr_from_user(void *value, size_t size) +static inline void posix_acl_fix_xattr_from_user(struct user_namespace *mnt_userns, + void *value, size_t size) { } -static inline void posix_acl_fix_xattr_to_user(void *value, size_t size) +static inline void posix_acl_fix_xattr_to_user(struct user_namespace *mnt_userns, + void *value, size_t size) { } #endif diff --git a/include/linux/xattr.h b/include/linux/xattr.h index 10b4dc2709f0..260c9bcb0edb 100644 --- a/include/linux/xattr.h +++ b/include/linux/xattr.h @@ -34,7 +34,8 @@ struct xattr_handler { int (*get)(const struct xattr_handler *, struct dentry *dentry, struct inode *inode, const char *name, void *buffer, size_t size); - int (*set)(const struct xattr_handler *, struct dentry *dentry, + int (*set)(const struct xattr_handler *, + struct user_namespace *mnt_userns, struct dentry *dentry, struct inode *inode, const char *name, const void *buffer, size_t size, int flags); }; diff --git a/mm/shmem.c b/mm/shmem.c index 1cb451e131ec..23b8e9c15a42 100644 --- a/mm/shmem.c +++ b/mm/shmem.c @@ -1143,7 +1143,7 @@ static int shmem_setattr(struct dentry *dentry, struct iattr *attr) setattr_copy(&init_user_ns, inode, attr); if (attr->ia_valid & ATTR_MODE) - error = posix_acl_chmod(inode, inode->i_mode); + error = posix_acl_chmod(&init_user_ns, inode, inode->i_mode); return error; } @@ -3273,6 +3273,7 @@ static int shmem_xattr_handler_get(const struct xattr_handler *handler, } static int shmem_xattr_handler_set(const struct xattr_handler *handler, + struct user_namespace *mnt_userns, struct dentry *unused, struct inode *inode, const char *name, const void *value, size_t size, int flags) diff --git a/net/socket.c b/net/socket.c index 33e8b6c4e1d3..c76703c6f480 100644 --- a/net/socket.c +++ b/net/socket.c @@ -334,6 +334,7 @@ static const struct xattr_handler sockfs_xattr_handler = { }; static int sockfs_security_xattr_set(const struct xattr_handler *handler, + struct user_namespace *mnt_userns, struct dentry *dentry, struct inode *inode, const char *suffix, const void *value, size_t size, int flags) diff --git a/security/commoncap.c b/security/commoncap.c index 88ee345f7bfa..c3fd9b86ea9a 100644 --- a/security/commoncap.c +++ b/security/commoncap.c @@ -450,16 +450,33 @@ int cap_inode_getsecurity(struct inode *inode, const char *name, void **buffer, return size; } +/** + * rootid_from_xattr - translate root uid of vfs caps + * + * @value: vfs caps value which may be modified by this function + * @size: size of @ivalue + * @task_ns: user namespace of the caller + * @mnt_userns: user namespace of the mount the inode was found from + * + * If the inode has been found through an idmapped mount the user namespace of + * the vfsmount must be passed through @mnt_userns. This function will then + * take care to map the inode according to @mnt_userns before checking + * permissions. On non-idmapped mounts or if permission checking is to be + * performed on the raw inode simply passs init_user_ns. + */ static kuid_t rootid_from_xattr(const void *value, size_t size, - struct user_namespace *task_ns) + struct user_namespace *task_ns, + struct user_namespace *mnt_userns) { const struct vfs_ns_cap_data *nscap = value; + kuid_t rootkid; uid_t rootid = 0; if (size == XATTR_CAPS_SZ_3) rootid = le32_to_cpu(nscap->rootid); - return make_kuid(task_ns, rootid); + rootkid = make_kuid(task_ns, rootid); + return kuid_from_mnt(mnt_userns, rootkid); } static bool validheader(size_t size, const struct vfs_cap_data *cap) @@ -467,13 +484,27 @@ static bool validheader(size_t size, const struct vfs_cap_data *cap) return is_v2header(size, cap) || is_v3header(size, cap); } -/* +/** + * cap_convert_nscap - check vfs caps + * + * @mnt_userns: user namespace of the mount the inode was found from + * @dentry: used to retrieve inode to check permissions on + * @ivalue: vfs caps value which may be modified by this function + * @size: size of @ivalue + * * User requested a write of security.capability. If needed, update the * xattr to change from v2 to v3, or to fixup the v3 rootid. * + * If the inode has been found through an idmapped mount the user namespace of + * the vfsmount must be passed through @mnt_userns. This function will then + * take care to map the inode according to @mnt_userns before checking + * permissions. On non-idmapped mounts or if permission checking is to be + * performed on the raw inode simply passs init_user_ns. + * * If all is ok, we return the new size, on error return < 0. */ -int cap_convert_nscap(struct dentry *dentry, const void **ivalue, size_t size) +int cap_convert_nscap(struct user_namespace *mnt_userns, struct dentry *dentry, + const void **ivalue, size_t size) { struct vfs_ns_cap_data *nscap; uid_t nsrootid; @@ -489,14 +520,14 @@ int cap_convert_nscap(struct dentry *dentry, const void **ivalue, size_t size) return -EINVAL; if (!validheader(size, cap)) return -EINVAL; - if (!capable_wrt_inode_uidgid(&init_user_ns, inode, CAP_SETFCAP)) + if (!capable_wrt_inode_uidgid(mnt_userns, inode, CAP_SETFCAP)) return -EPERM; - if (size == XATTR_CAPS_SZ_2) + if (size == XATTR_CAPS_SZ_2 && (mnt_userns == &init_user_ns)) if (ns_capable(inode->i_sb->s_user_ns, CAP_SETFCAP)) /* user is privileged, just write the v2 */ return size; - rootid = rootid_from_xattr(*ivalue, size, task_ns); + rootid = rootid_from_xattr(*ivalue, size, task_ns, mnt_userns); if (!uid_valid(rootid)) return -EINVAL; -- cgit v1.2.3 From 549c7297717c32ee53f156cd949e055e601f67bb Mon Sep 17 00:00:00 2001 From: Christian Brauner Date: Thu, 21 Jan 2021 14:19:43 +0100 Subject: fs: make helpers idmap mount aware Extend some inode methods with an additional user namespace argument. A filesystem that is aware of idmapped mounts will receive the user namespace the mount has been marked with. This can be used for additional permission checking and also to enable filesystems to translate between uids and gids if they need to. We have implemented all relevant helpers in earlier patches. As requested we simply extend the exisiting inode method instead of introducing new ones. This is a little more code churn but it's mostly mechanical and doesnt't leave us with additional inode methods. Link: https://lore.kernel.org/r/20210121131959.646623-25-christian.brauner@ubuntu.com Cc: Christoph Hellwig Cc: David Howells Cc: Al Viro Cc: linux-fsdevel@vger.kernel.org Reviewed-by: Christoph Hellwig Signed-off-by: Christian Brauner --- Documentation/filesystems/vfs.rst | 19 ++++++----- arch/powerpc/platforms/cell/spufs/inode.c | 3 +- drivers/android/binderfs.c | 6 ++-- fs/9p/acl.c | 4 +-- fs/9p/v9fs.h | 3 +- fs/9p/v9fs_vfs.h | 3 +- fs/9p/vfs_inode.c | 26 ++++++++------- fs/9p/vfs_inode_dotl.c | 31 +++++++++-------- fs/adfs/adfs.h | 3 +- fs/adfs/inode.c | 3 +- fs/affs/affs.h | 24 +++++++++----- fs/affs/inode.c | 3 +- fs/affs/namei.c | 15 +++++---- fs/afs/dir.c | 34 ++++++++++--------- fs/afs/inode.c | 7 ++-- fs/afs/internal.h | 7 ++-- fs/afs/security.c | 3 +- fs/attr.c | 4 +-- fs/autofs/root.c | 17 ++++++---- fs/bad_inode.c | 36 ++++++++++++-------- fs/bfs/dir.c | 10 +++--- fs/btrfs/acl.c | 3 +- fs/btrfs/ctree.h | 3 +- fs/btrfs/inode.c | 33 +++++++++++-------- fs/ceph/acl.c | 3 +- fs/ceph/dir.c | 23 ++++++------- fs/ceph/inode.c | 10 +++--- fs/ceph/super.h | 12 ++++--- fs/cifs/cifsfs.c | 3 +- fs/cifs/cifsfs.h | 25 ++++++++------ fs/cifs/dir.c | 8 ++--- fs/cifs/inode.c | 16 +++++---- fs/cifs/link.c | 3 +- fs/coda/coda_linux.h | 8 +++-- fs/coda/dir.c | 18 ++++++---- fs/coda/inode.c | 7 ++-- fs/coda/pioctl.c | 6 ++-- fs/configfs/configfs_internal.h | 6 ++-- fs/configfs/dir.c | 3 +- fs/configfs/inode.c | 5 +-- fs/configfs/symlink.c | 3 +- fs/debugfs/inode.c | 9 ++--- fs/ecryptfs/inode.c | 30 ++++++++++------- fs/efivarfs/inode.c | 4 +-- fs/erofs/inode.c | 5 +-- fs/erofs/internal.h | 5 +-- fs/exfat/exfat_fs.h | 8 +++-- fs/exfat/file.c | 8 +++-- fs/exfat/namei.c | 14 ++++---- fs/ext2/acl.c | 3 +- fs/ext2/acl.h | 3 +- fs/ext2/ext2.h | 5 +-- fs/ext2/inode.c | 7 ++-- fs/ext2/namei.c | 22 ++++++++----- fs/ext4/acl.c | 3 +- fs/ext4/acl.h | 3 +- fs/ext4/ext4.h | 9 +++-- fs/ext4/inode.c | 12 ++++--- fs/ext4/namei.c | 19 ++++++----- fs/f2fs/acl.c | 3 +- fs/f2fs/acl.h | 3 +- fs/f2fs/f2fs.h | 7 ++-- fs/f2fs/file.c | 7 ++-- fs/f2fs/namei.c | 21 +++++++----- fs/fat/fat.h | 6 ++-- fs/fat/file.c | 9 ++--- fs/fat/namei_msdos.c | 10 +++--- fs/fat/namei_vfat.c | 13 ++++---- fs/fuse/acl.c | 3 +- fs/fuse/dir.c | 37 ++++++++++++--------- fs/fuse/fuse_i.h | 4 +-- fs/gfs2/acl.c | 3 +- fs/gfs2/acl.h | 3 +- fs/gfs2/file.c | 2 +- fs/gfs2/inode.c | 53 +++++++++++++++++------------ fs/gfs2/inode.h | 3 +- fs/hfs/dir.c | 13 ++++---- fs/hfs/hfs_fs.h | 3 +- fs/hfs/inode.c | 6 ++-- fs/hfsplus/dir.c | 22 +++++++------ fs/hfsplus/hfsplus_fs.h | 5 +-- fs/hfsplus/inode.c | 8 +++-- fs/hostfs/hostfs_kern.c | 23 ++++++++----- fs/hpfs/hpfs_fn.h | 2 +- fs/hpfs/inode.c | 3 +- fs/hpfs/namei.c | 20 ++++++----- fs/hugetlbfs/inode.c | 29 +++++++++------- fs/jffs2/acl.c | 3 +- fs/jffs2/acl.h | 3 +- fs/jffs2/dir.c | 33 +++++++++++-------- fs/jffs2/fs.c | 3 +- fs/jffs2/os-linux.h | 2 +- fs/jfs/acl.c | 3 +- fs/jfs/file.c | 3 +- fs/jfs/jfs_acl.h | 3 +- fs/jfs/jfs_inode.h | 2 +- fs/jfs/namei.c | 21 ++++++------ fs/kernfs/dir.c | 6 ++-- fs/kernfs/inode.c | 9 +++-- fs/kernfs/kernfs-internal.h | 9 +++-- fs/libfs.c | 31 +++++++++-------- fs/minix/file.c | 3 +- fs/minix/inode.c | 4 +-- fs/minix/minix.h | 3 +- fs/minix/namei.c | 24 ++++++++------ fs/namei.c | 55 ++++++++++++++++++------------- fs/nfs/dir.c | 23 ++++++++----- fs/nfs/inode.c | 7 ++-- fs/nfs/internal.h | 14 +++++--- fs/nfs/namespace.c | 13 +++++--- fs/nfs/nfs3_fs.h | 3 +- fs/nfs/nfs3acl.c | 3 +- fs/nilfs2/inode.c | 6 ++-- fs/nilfs2/namei.c | 19 ++++++----- fs/nilfs2/nilfs.h | 6 ++-- fs/ntfs/inode.c | 4 ++- fs/ntfs/inode.h | 3 +- fs/ocfs2/acl.c | 3 +- fs/ocfs2/acl.h | 3 +- fs/ocfs2/dlmfs/dlmfs.c | 9 +++-- fs/ocfs2/file.c | 10 +++--- fs/ocfs2/file.h | 11 ++++--- fs/ocfs2/namei.c | 19 +++++++---- fs/omfs/dir.c | 13 ++++---- fs/omfs/file.c | 3 +- fs/orangefs/acl.c | 3 +- fs/orangefs/inode.c | 10 +++--- fs/orangefs/namei.c | 12 ++++--- fs/orangefs/orangefs-kernel.h | 13 +++++--- fs/overlayfs/dir.c | 21 ++++++------ fs/overlayfs/inode.c | 10 +++--- fs/overlayfs/overlayfs.h | 10 +++--- fs/overlayfs/super.c | 2 +- fs/posix_acl.c | 9 ++--- fs/proc/base.c | 16 +++++---- fs/proc/fd.c | 3 +- fs/proc/fd.h | 3 +- fs/proc/generic.c | 6 ++-- fs/proc/internal.h | 6 ++-- fs/proc/proc_net.c | 3 +- fs/proc/proc_sysctl.c | 9 +++-- fs/proc/root.c | 3 +- fs/ramfs/file-nommu.c | 5 +-- fs/ramfs/inode.c | 16 +++++---- fs/reiserfs/acl.h | 3 +- fs/reiserfs/inode.c | 3 +- fs/reiserfs/namei.c | 19 ++++++----- fs/reiserfs/reiserfs.h | 3 +- fs/reiserfs/xattr.c | 11 ++++--- fs/reiserfs/xattr.h | 3 +- fs/reiserfs/xattr_acl.c | 3 +- fs/stat.c | 8 +++-- fs/sysv/file.c | 3 +- fs/sysv/itree.c | 4 +-- fs/sysv/namei.c | 21 +++++++----- fs/sysv/sysv.h | 3 +- fs/tracefs/inode.c | 4 ++- fs/ubifs/dir.c | 26 ++++++++------- fs/ubifs/file.c | 3 +- fs/ubifs/ubifs.h | 5 +-- fs/udf/file.c | 3 +- fs/udf/namei.c | 24 +++++++------- fs/udf/symlink.c | 5 +-- fs/ufs/inode.c | 3 +- fs/ufs/namei.c | 19 ++++++----- fs/ufs/ufs.h | 3 +- fs/vboxsf/dir.c | 12 ++++--- fs/vboxsf/utils.c | 7 ++-- fs/vboxsf/vfsmod.h | 8 +++-- fs/xfs/xfs_acl.c | 3 +- fs/xfs/xfs_acl.h | 3 +- fs/xfs/xfs_iops.c | 52 ++++++++++++++++------------- fs/zonefs/super.c | 3 +- include/linux/fs.h | 39 ++++++++++++++-------- include/linux/nfs_fs.h | 7 ++-- include/linux/posix_acl.h | 3 +- ipc/mqueue.c | 4 +-- kernel/bpf/inode.c | 7 ++-- mm/shmem.c | 39 ++++++++++++++-------- net/socket.c | 5 +-- security/apparmor/apparmorfs.c | 3 +- security/integrity/evm/evm_secfs.c | 2 +- 182 files changed, 1121 insertions(+), 756 deletions(-) (limited to 'Documentation') diff --git a/Documentation/filesystems/vfs.rst b/Documentation/filesystems/vfs.rst index ca52c82e5bb5..98290ef311ca 100644 --- a/Documentation/filesystems/vfs.rst +++ b/Documentation/filesystems/vfs.rst @@ -415,28 +415,29 @@ As of kernel 2.6.22, the following members are defined: .. code-block:: c struct inode_operations { - int (*create) (struct inode *,struct dentry *, umode_t, bool); + int (*create) (struct user_namespace *, struct inode *,struct dentry *, umode_t, bool); struct dentry * (*lookup) (struct inode *,struct dentry *, unsigned int); int (*link) (struct dentry *,struct inode *,struct dentry *); int (*unlink) (struct inode *,struct dentry *); - int (*symlink) (struct inode *,struct dentry *,const char *); - int (*mkdir) (struct inode *,struct dentry *,umode_t); + int (*symlink) (struct user_namespace *, struct inode *,struct dentry *,const char *); + int (*mkdir) (struct user_namespace *, struct inode *,struct dentry *,umode_t); int (*rmdir) (struct inode *,struct dentry *); - int (*mknod) (struct inode *,struct dentry *,umode_t,dev_t); - int (*rename) (struct inode *, struct dentry *, + int (*mknod) (struct user_namespace *, struct inode *,struct dentry *,umode_t,dev_t); + int (*rename) (struct user_namespace *, struct inode *, struct dentry *, struct inode *, struct dentry *, unsigned int); int (*readlink) (struct dentry *, char __user *,int); const char *(*get_link) (struct dentry *, struct inode *, struct delayed_call *); - int (*permission) (struct inode *, int); + int (*permission) (struct user_namespace *, struct inode *, int); int (*get_acl)(struct inode *, int); - int (*setattr) (struct dentry *, struct iattr *); - int (*getattr) (const struct path *, struct kstat *, u32, unsigned int); + int (*setattr) (struct user_namespace *, struct dentry *, struct iattr *); + int (*getattr) (struct user_namespace *, const struct path *, struct kstat *, u32, unsigned int); ssize_t (*listxattr) (struct dentry *, char *, size_t); void (*update_time)(struct inode *, struct timespec *, int); int (*atomic_open)(struct inode *, struct dentry *, struct file *, unsigned open_flag, umode_t create_mode); - int (*tmpfile) (struct inode *, struct dentry *, umode_t); + int (*tmpfile) (struct user_namespace *, struct inode *, struct dentry *, umode_t); + int (*set_acl)(struct user_namespace *, struct inode *, struct posix_acl *, int); }; Again, all methods are called without any locks being held, unless diff --git a/arch/powerpc/platforms/cell/spufs/inode.c b/arch/powerpc/platforms/cell/spufs/inode.c index 3de526eb2275..b83a3670bd74 100644 --- a/arch/powerpc/platforms/cell/spufs/inode.c +++ b/arch/powerpc/platforms/cell/spufs/inode.c @@ -91,7 +91,8 @@ out: } static int -spufs_setattr(struct dentry *dentry, struct iattr *attr) +spufs_setattr(struct user_namespace *mnt_userns, struct dentry *dentry, + struct iattr *attr) { struct inode *inode = d_inode(dentry); diff --git a/drivers/android/binderfs.c b/drivers/android/binderfs.c index 7b4f154f07e6..e80ba93c62a9 100644 --- a/drivers/android/binderfs.c +++ b/drivers/android/binderfs.c @@ -355,7 +355,8 @@ static inline bool is_binderfs_control_device(const struct dentry *dentry) return info->control_dentry == dentry; } -static int binderfs_rename(struct inode *old_dir, struct dentry *old_dentry, +static int binderfs_rename(struct user_namespace *mnt_userns, + struct inode *old_dir, struct dentry *old_dentry, struct inode *new_dir, struct dentry *new_dentry, unsigned int flags) { @@ -363,7 +364,8 @@ static int binderfs_rename(struct inode *old_dir, struct dentry *old_dentry, is_binderfs_control_device(new_dentry)) return -EPERM; - return simple_rename(old_dir, old_dentry, new_dir, new_dentry, flags); + return simple_rename(&init_user_ns, old_dir, old_dentry, new_dir, + new_dentry, flags); } static int binderfs_unlink(struct inode *dir, struct dentry *dentry) diff --git a/fs/9p/acl.c b/fs/9p/acl.c index 1c14f18a6ec9..bb1b286c49ae 100644 --- a/fs/9p/acl.c +++ b/fs/9p/acl.c @@ -280,7 +280,7 @@ static int v9fs_xattr_set_acl(const struct xattr_handler *handler, struct iattr iattr = { 0 }; struct posix_acl *old_acl = acl; - retval = posix_acl_update_mode(mnt_userns, inode, + retval = posix_acl_update_mode(&init_user_ns, inode, &iattr.ia_mode, &acl); if (retval) goto err_out; @@ -299,7 +299,7 @@ static int v9fs_xattr_set_acl(const struct xattr_handler *handler, * What is the following setxattr update the * mode ? */ - v9fs_vfs_setattr_dotl(dentry, &iattr); + v9fs_vfs_setattr_dotl(&init_user_ns, dentry, &iattr); } break; case ACL_TYPE_DEFAULT: diff --git a/fs/9p/v9fs.h b/fs/9p/v9fs.h index 7b763776306e..4ca56c5dd637 100644 --- a/fs/9p/v9fs.h +++ b/fs/9p/v9fs.h @@ -135,7 +135,8 @@ extern struct dentry *v9fs_vfs_lookup(struct inode *dir, struct dentry *dentry, unsigned int flags); extern int v9fs_vfs_unlink(struct inode *i, struct dentry *d); extern int v9fs_vfs_rmdir(struct inode *i, struct dentry *d); -extern int v9fs_vfs_rename(struct inode *old_dir, struct dentry *old_dentry, +extern int v9fs_vfs_rename(struct user_namespace *mnt_userns, + struct inode *old_dir, struct dentry *old_dentry, struct inode *new_dir, struct dentry *new_dentry, unsigned int flags); extern struct inode *v9fs_inode_from_fid(struct v9fs_session_info *v9ses, diff --git a/fs/9p/v9fs_vfs.h b/fs/9p/v9fs_vfs.h index fd2a2b040250..d44ade76966a 100644 --- a/fs/9p/v9fs_vfs.h +++ b/fs/9p/v9fs_vfs.h @@ -59,7 +59,8 @@ void v9fs_inode2stat(struct inode *inode, struct p9_wstat *stat); int v9fs_uflags2omode(int uflags, int extended); void v9fs_blank_wstat(struct p9_wstat *wstat); -int v9fs_vfs_setattr_dotl(struct dentry *, struct iattr *); +int v9fs_vfs_setattr_dotl(struct user_namespace *, struct dentry *, + struct iattr *); int v9fs_file_fsync_dotl(struct file *filp, loff_t start, loff_t end, int datasync); int v9fs_refresh_inode(struct p9_fid *fid, struct inode *inode); diff --git a/fs/9p/vfs_inode.c b/fs/9p/vfs_inode.c index c21b146c8d91..648eb4c4cf7f 100644 --- a/fs/9p/vfs_inode.c +++ b/fs/9p/vfs_inode.c @@ -676,8 +676,8 @@ error: */ static int -v9fs_vfs_create(struct inode *dir, struct dentry *dentry, umode_t mode, - bool excl) +v9fs_vfs_create(struct user_namespace *mnt_userns, struct inode *dir, + struct dentry *dentry, umode_t mode, bool excl) { struct v9fs_session_info *v9ses = v9fs_inode2v9ses(dir); u32 perm = unixmode2p9mode(v9ses, mode); @@ -702,7 +702,8 @@ v9fs_vfs_create(struct inode *dir, struct dentry *dentry, umode_t mode, * */ -static int v9fs_vfs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode) +static int v9fs_vfs_mkdir(struct user_namespace *mnt_userns, struct inode *dir, + struct dentry *dentry, umode_t mode) { int err; u32 perm; @@ -907,9 +908,9 @@ int v9fs_vfs_rmdir(struct inode *i, struct dentry *d) */ int -v9fs_vfs_rename(struct inode *old_dir, struct dentry *old_dentry, - struct inode *new_dir, struct dentry *new_dentry, - unsigned int flags) +v9fs_vfs_rename(struct user_namespace *mnt_userns, struct inode *old_dir, + struct dentry *old_dentry, struct inode *new_dir, + struct dentry *new_dentry, unsigned int flags) { int retval; struct inode *old_inode; @@ -1016,8 +1017,8 @@ done: */ static int -v9fs_vfs_getattr(const struct path *path, struct kstat *stat, - u32 request_mask, unsigned int flags) +v9fs_vfs_getattr(struct user_namespace *mnt_userns, const struct path *path, + struct kstat *stat, u32 request_mask, unsigned int flags) { struct dentry *dentry = path->dentry; struct v9fs_session_info *v9ses; @@ -1054,7 +1055,8 @@ v9fs_vfs_getattr(const struct path *path, struct kstat *stat, * */ -static int v9fs_vfs_setattr(struct dentry *dentry, struct iattr *iattr) +static int v9fs_vfs_setattr(struct user_namespace *mnt_userns, + struct dentry *dentry, struct iattr *iattr) { int retval, use_dentry = 0; struct v9fs_session_info *v9ses; @@ -1295,7 +1297,8 @@ static int v9fs_vfs_mkspecial(struct inode *dir, struct dentry *dentry, */ static int -v9fs_vfs_symlink(struct inode *dir, struct dentry *dentry, const char *symname) +v9fs_vfs_symlink(struct user_namespace *mnt_userns, struct inode *dir, + struct dentry *dentry, const char *symname) { p9_debug(P9_DEBUG_VFS, " %lu,%pd,%s\n", dir->i_ino, dentry, symname); @@ -1348,7 +1351,8 @@ v9fs_vfs_link(struct dentry *old_dentry, struct inode *dir, */ static int -v9fs_vfs_mknod(struct inode *dir, struct dentry *dentry, umode_t mode, dev_t rdev) +v9fs_vfs_mknod(struct user_namespace *mnt_userns, struct inode *dir, + struct dentry *dentry, umode_t mode, dev_t rdev) { struct v9fs_session_info *v9ses = v9fs_inode2v9ses(dir); int retval; diff --git a/fs/9p/vfs_inode_dotl.c b/fs/9p/vfs_inode_dotl.c index 984f28315d2a..1dc7af046615 100644 --- a/fs/9p/vfs_inode_dotl.c +++ b/fs/9p/vfs_inode_dotl.c @@ -33,8 +33,8 @@ #include "acl.h" static int -v9fs_vfs_mknod_dotl(struct inode *dir, struct dentry *dentry, umode_t omode, - dev_t rdev); +v9fs_vfs_mknod_dotl(struct user_namespace *mnt_userns, struct inode *dir, + struct dentry *dentry, umode_t omode, dev_t rdev); /** * v9fs_get_fsgid_for_create - Helper function to get the gid for creating a @@ -218,10 +218,10 @@ int v9fs_open_to_dotl_flags(int flags) */ static int -v9fs_vfs_create_dotl(struct inode *dir, struct dentry *dentry, umode_t omode, - bool excl) +v9fs_vfs_create_dotl(struct user_namespace *mnt_userns, struct inode *dir, + struct dentry *dentry, umode_t omode, bool excl) { - return v9fs_vfs_mknod_dotl(dir, dentry, omode, 0); + return v9fs_vfs_mknod_dotl(mnt_userns, dir, dentry, omode, 0); } static int @@ -367,8 +367,9 @@ err_clunk_old_fid: * */ -static int v9fs_vfs_mkdir_dotl(struct inode *dir, - struct dentry *dentry, umode_t omode) +static int v9fs_vfs_mkdir_dotl(struct user_namespace *mnt_userns, + struct inode *dir, struct dentry *dentry, + umode_t omode) { int err; struct v9fs_session_info *v9ses; @@ -457,8 +458,9 @@ error: } static int -v9fs_vfs_getattr_dotl(const struct path *path, struct kstat *stat, - u32 request_mask, unsigned int flags) +v9fs_vfs_getattr_dotl(struct user_namespace *mnt_userns, + const struct path *path, struct kstat *stat, + u32 request_mask, unsigned int flags) { struct dentry *dentry = path->dentry; struct v9fs_session_info *v9ses; @@ -540,7 +542,8 @@ static int v9fs_mapped_iattr_valid(int iattr_valid) * */ -int v9fs_vfs_setattr_dotl(struct dentry *dentry, struct iattr *iattr) +int v9fs_vfs_setattr_dotl(struct user_namespace *mnt_userns, + struct dentry *dentry, struct iattr *iattr) { int retval, use_dentry = 0; struct p9_fid *fid = NULL; @@ -684,8 +687,8 @@ v9fs_stat2inode_dotl(struct p9_stat_dotl *stat, struct inode *inode, } static int -v9fs_vfs_symlink_dotl(struct inode *dir, struct dentry *dentry, - const char *symname) +v9fs_vfs_symlink_dotl(struct user_namespace *mnt_userns, struct inode *dir, + struct dentry *dentry, const char *symname) { int err; kgid_t gid; @@ -824,8 +827,8 @@ v9fs_vfs_link_dotl(struct dentry *old_dentry, struct inode *dir, * */ static int -v9fs_vfs_mknod_dotl(struct inode *dir, struct dentry *dentry, umode_t omode, - dev_t rdev) +v9fs_vfs_mknod_dotl(struct user_namespace *mnt_userns, struct inode *dir, + struct dentry *dentry, umode_t omode, dev_t rdev) { int err; kgid_t gid; diff --git a/fs/adfs/adfs.h b/fs/adfs/adfs.h index 699c4fa8b78b..06b7c92343ad 100644 --- a/fs/adfs/adfs.h +++ b/fs/adfs/adfs.h @@ -144,7 +144,8 @@ struct adfs_discmap { /* Inode stuff */ struct inode *adfs_iget(struct super_block *sb, struct object_info *obj); int adfs_write_inode(struct inode *inode, struct writeback_control *wbc); -int adfs_notify_change(struct dentry *dentry, struct iattr *attr); +int adfs_notify_change(struct user_namespace *mnt_userns, struct dentry *dentry, + struct iattr *attr); /* map.c */ int adfs_map_lookup(struct super_block *sb, u32 frag_id, unsigned int offset); diff --git a/fs/adfs/inode.c b/fs/adfs/inode.c index 278dcee6ae22..fb7ee026d101 100644 --- a/fs/adfs/inode.c +++ b/fs/adfs/inode.c @@ -292,7 +292,8 @@ out: * later. */ int -adfs_notify_change(struct dentry *dentry, struct iattr *attr) +adfs_notify_change(struct user_namespace *mnt_userns, struct dentry *dentry, + struct iattr *attr) { struct inode *inode = d_inode(dentry); struct super_block *sb = inode->i_sb; diff --git a/fs/affs/affs.h b/fs/affs/affs.h index a755bef7c4c7..bfa89e131ead 100644 --- a/fs/affs/affs.h +++ b/fs/affs/affs.h @@ -167,27 +167,33 @@ extern const struct export_operations affs_export_ops; extern int affs_hash_name(struct super_block *sb, const u8 *name, unsigned int len); extern struct dentry *affs_lookup(struct inode *dir, struct dentry *dentry, unsigned int); extern int affs_unlink(struct inode *dir, struct dentry *dentry); -extern int affs_create(struct inode *dir, struct dentry *dentry, umode_t mode, bool); -extern int affs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode); +extern int affs_create(struct user_namespace *mnt_userns, struct inode *dir, + struct dentry *dentry, umode_t mode, bool); +extern int affs_mkdir(struct user_namespace *mnt_userns, struct inode *dir, + struct dentry *dentry, umode_t mode); extern int affs_rmdir(struct inode *dir, struct dentry *dentry); extern int affs_link(struct dentry *olddentry, struct inode *dir, struct dentry *dentry); -extern int affs_symlink(struct inode *dir, struct dentry *dentry, - const char *symname); -extern int affs_rename2(struct inode *old_dir, struct dentry *old_dentry, - struct inode *new_dir, struct dentry *new_dentry, - unsigned int flags); +extern int affs_symlink(struct user_namespace *mnt_userns, + struct inode *dir, struct dentry *dentry, + const char *symname); +extern int affs_rename2(struct user_namespace *mnt_userns, + struct inode *old_dir, struct dentry *old_dentry, + struct inode *new_dir, struct dentry *new_dentry, + unsigned int flags); /* inode.c */ extern struct inode *affs_new_inode(struct inode *dir); -extern int affs_notify_change(struct dentry *dentry, struct iattr *attr); +extern int affs_notify_change(struct user_namespace *mnt_userns, + struct dentry *dentry, struct iattr *attr); extern void affs_evict_inode(struct inode *inode); extern struct inode *affs_iget(struct super_block *sb, unsigned long ino); extern int affs_write_inode(struct inode *inode, struct writeback_control *wbc); -extern int affs_add_entry(struct inode *dir, struct inode *inode, struct dentry *dentry, s32 type); +extern int affs_add_entry(struct inode *dir, struct inode *inode, + struct dentry *dentry, s32 type); /* file.c */ diff --git a/fs/affs/inode.c b/fs/affs/inode.c index 767e5bdfb703..2352a75bd9d6 100644 --- a/fs/affs/inode.c +++ b/fs/affs/inode.c @@ -216,7 +216,8 @@ affs_write_inode(struct inode *inode, struct writeback_control *wbc) } int -affs_notify_change(struct dentry *dentry, struct iattr *attr) +affs_notify_change(struct user_namespace *mnt_userns, struct dentry *dentry, + struct iattr *attr) { struct inode *inode = d_inode(dentry); int error; diff --git a/fs/affs/namei.c b/fs/affs/namei.c index 41c5749f4db7..9ad22befce28 100644 --- a/fs/affs/namei.c +++ b/fs/affs/namei.c @@ -242,7 +242,8 @@ affs_unlink(struct inode *dir, struct dentry *dentry) } int -affs_create(struct inode *dir, struct dentry *dentry, umode_t mode, bool excl) +affs_create(struct user_namespace *mnt_userns, struct inode *dir, + struct dentry *dentry, umode_t mode, bool excl) { struct super_block *sb = dir->i_sb; struct inode *inode; @@ -273,7 +274,8 @@ affs_create(struct inode *dir, struct dentry *dentry, umode_t mode, bool excl) } int -affs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode) +affs_mkdir(struct user_namespace *mnt_userns, struct inode *dir, + struct dentry *dentry, umode_t mode) { struct inode *inode; int error; @@ -311,7 +313,8 @@ affs_rmdir(struct inode *dir, struct dentry *dentry) } int -affs_symlink(struct inode *dir, struct dentry *dentry, const char *symname) +affs_symlink(struct user_namespace *mnt_userns, struct inode *dir, + struct dentry *dentry, const char *symname) { struct super_block *sb = dir->i_sb; struct buffer_head *bh; @@ -498,9 +501,9 @@ done: return retval; } -int affs_rename2(struct inode *old_dir, struct dentry *old_dentry, - struct inode *new_dir, struct dentry *new_dentry, - unsigned int flags) +int affs_rename2(struct user_namespace *mnt_userns, struct inode *old_dir, + struct dentry *old_dentry, struct inode *new_dir, + struct dentry *new_dentry, unsigned int flags) { if (flags & ~(RENAME_NOREPLACE | RENAME_EXCHANGE)) diff --git a/fs/afs/dir.c b/fs/afs/dir.c index 7bd659ad959e..714fcca9af99 100644 --- a/fs/afs/dir.c +++ b/fs/afs/dir.c @@ -28,18 +28,19 @@ static int afs_lookup_one_filldir(struct dir_context *ctx, const char *name, int loff_t fpos, u64 ino, unsigned dtype); static int afs_lookup_filldir(struct dir_context *ctx, const char *name, int nlen, loff_t fpos, u64 ino, unsigned dtype); -static int afs_create(struct inode *dir, struct dentry *dentry, umode_t mode, - bool excl); -static int afs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode); +static int afs_create(struct user_namespace *mnt_userns, struct inode *dir, + struct dentry *dentry, umode_t mode, bool excl); +static int afs_mkdir(struct user_namespace *mnt_userns, struct inode *dir, + struct dentry *dentry, umode_t mode); static int afs_rmdir(struct inode *dir, struct dentry *dentry); static int afs_unlink(struct inode *dir, struct dentry *dentry); static int afs_link(struct dentry *from, struct inode *dir, struct dentry *dentry); -static int afs_symlink(struct inode *dir, struct dentry *dentry, - const char *content); -static int afs_rename(struct inode *old_dir, struct dentry *old_dentry, - struct inode *new_dir, struct dentry *new_dentry, - unsigned int flags); +static int afs_symlink(struct user_namespace *mnt_userns, struct inode *dir, + struct dentry *dentry, const char *content); +static int afs_rename(struct user_namespace *mnt_userns, struct inode *old_dir, + struct dentry *old_dentry, struct inode *new_dir, + struct dentry *new_dentry, unsigned int flags); static int afs_dir_releasepage(struct page *page, gfp_t gfp_flags); static void afs_dir_invalidatepage(struct page *page, unsigned int offset, unsigned int length); @@ -1325,7 +1326,8 @@ static const struct afs_operation_ops afs_mkdir_operation = { /* * create a directory on an AFS filesystem */ -static int afs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode) +static int afs_mkdir(struct user_namespace *mnt_userns, struct inode *dir, + struct dentry *dentry, umode_t mode) { struct afs_operation *op; struct afs_vnode *dvnode = AFS_FS_I(dir); @@ -1619,8 +1621,8 @@ static const struct afs_operation_ops afs_create_operation = { /* * create a regular file on an AFS filesystem */ -static int afs_create(struct inode *dir, struct dentry *dentry, umode_t mode, - bool excl) +static int afs_create(struct user_namespace *mnt_userns, struct inode *dir, + struct dentry *dentry, umode_t mode, bool excl) { struct afs_operation *op; struct afs_vnode *dvnode = AFS_FS_I(dir); @@ -1741,8 +1743,8 @@ static const struct afs_operation_ops afs_symlink_operation = { /* * create a symlink in an AFS filesystem */ -static int afs_symlink(struct inode *dir, struct dentry *dentry, - const char *content) +static int afs_symlink(struct user_namespace *mnt_userns, struct inode *dir, + struct dentry *dentry, const char *content) { struct afs_operation *op; struct afs_vnode *dvnode = AFS_FS_I(dir); @@ -1876,9 +1878,9 @@ static const struct afs_operation_ops afs_rename_operation = { /* * rename a file in an AFS filesystem and/or move it between directories */ -static int afs_rename(struct inode *old_dir, struct dentry *old_dentry, - struct inode *new_dir, struct dentry *new_dentry, - unsigned int flags) +static int afs_rename(struct user_namespace *mnt_userns, struct inode *old_dir, + struct dentry *old_dentry, struct inode *new_dir, + struct dentry *new_dentry, unsigned int flags) { struct afs_operation *op; struct afs_vnode *orig_dvnode, *new_dvnode, *vnode; diff --git a/fs/afs/inode.c b/fs/afs/inode.c index 795ee5cb3817..1156b2df28d3 100644 --- a/fs/afs/inode.c +++ b/fs/afs/inode.c @@ -734,8 +734,8 @@ error_unlock: /* * read the attributes of an inode */ -int afs_getattr(const struct path *path, struct kstat *stat, - u32 request_mask, unsigned int query_flags) +int afs_getattr(struct user_namespace *mnt_userns, const struct path *path, + struct kstat *stat, u32 request_mask, unsigned int query_flags) { struct inode *inode = d_inode(path->dentry); struct afs_vnode *vnode = AFS_FS_I(inode); @@ -857,7 +857,8 @@ static const struct afs_operation_ops afs_setattr_operation = { /* * set the attributes of an inode */ -int afs_setattr(struct dentry *dentry, struct iattr *attr) +int afs_setattr(struct user_namespace *mnt_userns, struct dentry *dentry, + struct iattr *attr) { struct afs_operation *op; struct afs_vnode *vnode = AFS_FS_I(d_inode(dentry)); diff --git a/fs/afs/internal.h b/fs/afs/internal.h index 0d150a29e39e..b626e38e9ab5 100644 --- a/fs/afs/internal.h +++ b/fs/afs/internal.h @@ -1149,8 +1149,9 @@ extern struct inode *afs_iget(struct afs_operation *, struct afs_vnode_param *); extern struct inode *afs_root_iget(struct super_block *, struct key *); extern bool afs_check_validity(struct afs_vnode *); extern int afs_validate(struct afs_vnode *, struct key *); -extern int afs_getattr(const struct path *, struct kstat *, u32, unsigned int); -extern int afs_setattr(struct dentry *, struct iattr *); +extern int afs_getattr(struct user_namespace *mnt_userns, const struct path *, + struct kstat *, u32, unsigned int); +extern int afs_setattr(struct user_namespace *mnt_userns, struct dentry *, struct iattr *); extern void afs_evict_inode(struct inode *); extern int afs_drop_inode(struct inode *); @@ -1361,7 +1362,7 @@ extern void afs_zap_permits(struct rcu_head *); extern struct key *afs_request_key(struct afs_cell *); extern struct key *afs_request_key_rcu(struct afs_cell *); extern int afs_check_permit(struct afs_vnode *, struct key *, afs_access_t *); -extern int afs_permission(struct inode *, int); +extern int afs_permission(struct user_namespace *, struct inode *, int); extern void __exit afs_clean_up_permit_cache(void); /* diff --git a/fs/afs/security.c b/fs/afs/security.c index 9cf3102f370c..3c7a8fc4f93f 100644 --- a/fs/afs/security.c +++ b/fs/afs/security.c @@ -396,7 +396,8 @@ int afs_check_permit(struct afs_vnode *vnode, struct key *key, * - AFS ACLs are attached to directories only, and a file is controlled by its * parent directory's ACL */ -int afs_permission(struct inode *inode, int mask) +int afs_permission(struct user_namespace *mnt_userns, struct inode *inode, + int mask) { struct afs_vnode *vnode = AFS_FS_I(inode); afs_access_t access; diff --git a/fs/attr.c b/fs/attr.c index c2d3bc0869d4..41abd0d973d8 100644 --- a/fs/attr.c +++ b/fs/attr.c @@ -395,9 +395,9 @@ int notify_change(struct user_namespace *mnt_userns, struct dentry *dentry, return error; if (inode->i_op->setattr) - error = inode->i_op->setattr(dentry, attr); + error = inode->i_op->setattr(mnt_userns, dentry, attr); else - error = simple_setattr(dentry, attr); + error = simple_setattr(mnt_userns, dentry, attr); if (!error) { fsnotify_change(dentry, ia_valid); diff --git a/fs/autofs/root.c b/fs/autofs/root.c index 5aaa1732bf1e..91fe4548c256 100644 --- a/fs/autofs/root.c +++ b/fs/autofs/root.c @@ -10,10 +10,12 @@ #include "autofs_i.h" -static int autofs_dir_symlink(struct inode *, struct dentry *, const char *); +static int autofs_dir_symlink(struct user_namespace *, struct inode *, + struct dentry *, const char *); static int autofs_dir_unlink(struct inode *, struct dentry *); static int autofs_dir_rmdir(struct inode *, struct dentry *); -static int autofs_dir_mkdir(struct inode *, struct dentry *, umode_t); +static int autofs_dir_mkdir(struct user_namespace *, struct inode *, + struct dentry *, umode_t); static long autofs_root_ioctl(struct file *, unsigned int, unsigned long); #ifdef CONFIG_COMPAT static long autofs_root_compat_ioctl(struct file *, @@ -524,9 +526,9 @@ static struct dentry *autofs_lookup(struct inode *dir, return NULL; } -static int autofs_dir_symlink(struct inode *dir, - struct dentry *dentry, - const char *symname) +static int autofs_dir_symlink(struct user_namespace *mnt_userns, + struct inode *dir, struct dentry *dentry, + const char *symname) { struct autofs_sb_info *sbi = autofs_sbi(dir->i_sb); struct autofs_info *ino = autofs_dentry_ino(dentry); @@ -715,8 +717,9 @@ static int autofs_dir_rmdir(struct inode *dir, struct dentry *dentry) return 0; } -static int autofs_dir_mkdir(struct inode *dir, - struct dentry *dentry, umode_t mode) +static int autofs_dir_mkdir(struct user_namespace *mnt_userns, + struct inode *dir, struct dentry *dentry, + umode_t mode) { struct autofs_sb_info *sbi = autofs_sbi(dir->i_sb); struct autofs_info *ino = autofs_dentry_ino(dentry); diff --git a/fs/bad_inode.c b/fs/bad_inode.c index 54f0ce444272..48e16144c1f7 100644 --- a/fs/bad_inode.c +++ b/fs/bad_inode.c @@ -27,8 +27,9 @@ static const struct file_operations bad_file_ops = .open = bad_file_open, }; -static int bad_inode_create (struct inode *dir, struct dentry *dentry, - umode_t mode, bool excl) +static int bad_inode_create(struct user_namespace *mnt_userns, + struct inode *dir, struct dentry *dentry, + umode_t mode, bool excl) { return -EIO; } @@ -50,14 +51,15 @@ static int bad_inode_unlink(struct inode *dir, struct dentry *dentry) return -EIO; } -static int bad_inode_symlink (struct inode *dir, struct dentry *dentry, - const char *symname) +static int bad_inode_symlink(struct user_namespace *mnt_userns, + struct inode *dir, struct dentry *dentry, + const char *symname) { return -EIO; } -static int bad_inode_mkdir(struct inode *dir, struct dentry *dentry, - umode_t mode) +static int bad_inode_mkdir(struct user_namespace *mnt_userns, struct inode *dir, + struct dentry *dentry, umode_t mode) { return -EIO; } @@ -67,13 +69,14 @@ static int bad_inode_rmdir (struct inode *dir, struct dentry *dentry) return -EIO; } -static int bad_inode_mknod (struct inode *dir, struct dentry *dentry, - umode_t mode, dev_t rdev) +static int bad_inode_mknod(struct user_namespace *mnt_userns, struct inode *dir, + struct dentry *dentry, umode_t mode, dev_t rdev) { return -EIO; } -static int bad_inode_rename2(struct inode *old_dir, struct dentry *old_dentry, +static int bad_inode_rename2(struct user_namespace *mnt_userns, + struct inode *old_dir, struct dentry *old_dentry, struct inode *new_dir, struct dentry *new_dentry, unsigned int flags) { @@ -86,18 +89,21 @@ static int bad_inode_readlink(struct dentry *dentry, char __user *buffer, return -EIO; } -static int bad_inode_permission(struct inode *inode, int mask) +static int bad_inode_permission(struct user_namespace *mnt_userns, + struct inode *inode, int mask) { return -EIO; } -static int bad_inode_getattr(const struct path *path, struct kstat *stat, +static int bad_inode_getattr(struct user_namespace *mnt_userns, + const struct path *path, struct kstat *stat, u32 request_mask, unsigned int query_flags) { return -EIO; } -static int bad_inode_setattr(struct dentry *direntry, struct iattr *attrs) +static int bad_inode_setattr(struct user_namespace *mnt_userns, + struct dentry *direntry, struct iattr *attrs) { return -EIO; } @@ -140,13 +146,15 @@ static int bad_inode_atomic_open(struct inode *inode, struct dentry *dentry, return -EIO; } -static int bad_inode_tmpfile(struct inode *inode, struct dentry *dentry, +static int bad_inode_tmpfile(struct user_namespace *mnt_userns, + struct inode *inode, struct dentry *dentry, umode_t mode) { return -EIO; } -static int bad_inode_set_acl(struct inode *inode, struct posix_acl *acl, +static int bad_inode_set_acl(struct user_namespace *mnt_userns, + struct inode *inode, struct posix_acl *acl, int type) { return -EIO; diff --git a/fs/bfs/dir.c b/fs/bfs/dir.c index be1335a8d25b..34d4f68f786b 100644 --- a/fs/bfs/dir.c +++ b/fs/bfs/dir.c @@ -75,8 +75,8 @@ const struct file_operations bfs_dir_operations = { .llseek = generic_file_llseek, }; -static int bfs_create(struct inode *dir, struct dentry *dentry, umode_t mode, - bool excl) +static int bfs_create(struct user_namespace *mnt_userns, struct inode *dir, + struct dentry *dentry, umode_t mode, bool excl) { int err; struct inode *inode; @@ -199,9 +199,9 @@ out_brelse: return error; } -static int bfs_rename(struct inode *old_dir, struct dentry *old_dentry, - struct inode *new_dir, struct dentry *new_dentry, - unsigned int flags) +static int bfs_rename(struct user_namespace *mnt_userns, struct inode *old_dir, + struct dentry *old_dentry, struct inode *new_dir, + struct dentry *new_dentry, unsigned int flags) { struct inode *old_inode, *new_inode; struct buffer_head *old_bh, *new_bh; diff --git a/fs/btrfs/acl.c b/fs/btrfs/acl.c index d12a5a8730a8..d95eb5c8cb37 100644 --- a/fs/btrfs/acl.c +++ b/fs/btrfs/acl.c @@ -107,7 +107,8 @@ out: return ret; } -int btrfs_set_acl(struct inode *inode, struct posix_acl *acl, int type) +int btrfs_set_acl(struct user_namespace *mnt_userns, struct inode *inode, + struct posix_acl *acl, int type) { int ret; umode_t old_mode = inode->i_mode; diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h index e6e37591f1de..9c0b43853cd2 100644 --- a/fs/btrfs/ctree.h +++ b/fs/btrfs/ctree.h @@ -3625,7 +3625,8 @@ static inline int __btrfs_fs_compat_ro(struct btrfs_fs_info *fs_info, u64 flag) /* acl.c */ #ifdef CONFIG_BTRFS_FS_POSIX_ACL struct posix_acl *btrfs_get_acl(struct inode *inode, int type); -int btrfs_set_acl(struct inode *inode, struct posix_acl *acl, int type); +int btrfs_set_acl(struct user_namespace *mnt_userns, struct inode *inode, + struct posix_acl *acl, int type); int btrfs_init_acl(struct btrfs_trans_handle *trans, struct inode *inode, struct inode *dir); #else diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index a63faed171de..c0b11db98e5e 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c @@ -5045,7 +5045,8 @@ static int btrfs_setsize(struct inode *inode, struct iattr *attr) return ret; } -static int btrfs_setattr(struct dentry *dentry, struct iattr *attr) +static int btrfs_setattr(struct user_namespace *mnt_userns, struct dentry *dentry, + struct iattr *attr) { struct inode *inode = d_inode(dentry); struct btrfs_root *root = BTRFS_I(inode)->root; @@ -6352,8 +6353,8 @@ static int btrfs_add_nondir(struct btrfs_trans_handle *trans, return err; } -static int btrfs_mknod(struct inode *dir, struct dentry *dentry, - umode_t mode, dev_t rdev) +static int btrfs_mknod(struct user_namespace *mnt_userns, struct inode *dir, + struct dentry *dentry, umode_t mode, dev_t rdev) { struct btrfs_fs_info *fs_info = btrfs_sb(dir->i_sb); struct btrfs_trans_handle *trans; @@ -6416,8 +6417,8 @@ out_unlock: return err; } -static int btrfs_create(struct inode *dir, struct dentry *dentry, - umode_t mode, bool excl) +static int btrfs_create(struct user_namespace *mnt_userns, struct inode *dir, + struct dentry *dentry, umode_t mode, bool excl) { struct btrfs_fs_info *fs_info = btrfs_sb(dir->i_sb); struct btrfs_trans_handle *trans; @@ -6561,7 +6562,8 @@ fail: return err; } -static int btrfs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode) +static int btrfs_mkdir(struct user_namespace *mnt_userns, struct inode *dir, + struct dentry *dentry, umode_t mode) { struct btrfs_fs_info *fs_info = btrfs_sb(dir->i_sb); struct inode *inode = NULL; @@ -8816,7 +8818,8 @@ fail: return -ENOMEM; } -static int btrfs_getattr(const struct path *path, struct kstat *stat, +static int btrfs_getattr(struct user_namespace *mnt_userns, + const struct path *path, struct kstat *stat, u32 request_mask, unsigned int flags) { u64 delalloc_bytes; @@ -9333,9 +9336,9 @@ out_notrans: return ret; } -static int btrfs_rename2(struct inode *old_dir, struct dentry *old_dentry, - struct inode *new_dir, struct dentry *new_dentry, - unsigned int flags) +static int btrfs_rename2(struct user_namespace *mnt_userns, struct inode *old_dir, + struct dentry *old_dentry, struct inode *new_dir, + struct dentry *new_dentry, unsigned int flags) { if (flags & ~(RENAME_NOREPLACE | RENAME_EXCHANGE | RENAME_WHITEOUT)) return -EINVAL; @@ -9543,8 +9546,8 @@ out: return ret; } -static int btrfs_symlink(struct inode *dir, struct dentry *dentry, - const char *symname) +static int btrfs_symlink(struct user_namespace *mnt_userns, struct inode *dir, + struct dentry *dentry, const char *symname) { struct btrfs_fs_info *fs_info = btrfs_sb(dir->i_sb); struct btrfs_trans_handle *trans; @@ -9878,7 +9881,8 @@ static int btrfs_set_page_dirty(struct page *page) return __set_page_dirty_nobuffers(page); } -static int btrfs_permission(struct inode *inode, int mask) +static int btrfs_permission(struct user_namespace *mnt_userns, + struct inode *inode, int mask) { struct btrfs_root *root = BTRFS_I(inode)->root; umode_t mode = inode->i_mode; @@ -9893,7 +9897,8 @@ static int btrfs_permission(struct inode *inode, int mask) return generic_permission(&init_user_ns, inode, mask); } -static int btrfs_tmpfile(struct inode *dir, struct dentry *dentry, umode_t mode) +static int btrfs_tmpfile(struct user_namespace *mnt_userns, struct inode *dir, + struct dentry *dentry, umode_t mode) { struct btrfs_fs_info *fs_info = btrfs_sb(dir->i_sb); struct btrfs_trans_handle *trans; diff --git a/fs/ceph/acl.c b/fs/ceph/acl.c index 52a01ddbc4ac..529af59d9fd3 100644 --- a/fs/ceph/acl.c +++ b/fs/ceph/acl.c @@ -82,7 +82,8 @@ retry: return acl; } -int ceph_set_acl(struct inode *inode, struct posix_acl *acl, int type) +int ceph_set_acl(struct user_namespace *mnt_userns, struct inode *inode, + struct posix_acl *acl, int type) { int ret = 0, size = 0; const char *name = NULL; diff --git a/fs/ceph/dir.c b/fs/ceph/dir.c index 858ee7362ff5..83d9358854fb 100644 --- a/fs/ceph/dir.c +++ b/fs/ceph/dir.c @@ -823,8 +823,8 @@ int ceph_handle_notrace_create(struct inode *dir, struct dentry *dentry) return PTR_ERR(result); } -static int ceph_mknod(struct inode *dir, struct dentry *dentry, - umode_t mode, dev_t rdev) +static int ceph_mknod(struct user_namespace *mnt_userns, struct inode *dir, + struct dentry *dentry, umode_t mode, dev_t rdev) { struct ceph_mds_client *mdsc = ceph_sb_to_mdsc(dir->i_sb); struct ceph_mds_request *req; @@ -878,14 +878,14 @@ out: return err; } -static int ceph_create(struct inode *dir, struct dentry *dentry, umode_t mode, - bool excl) +static int ceph_create(struct user_namespace *mnt_userns, struct inode *dir, + struct dentry *dentry, umode_t mode, bool excl) { - return ceph_mknod(dir, dentry, mode, 0); + return ceph_mknod(mnt_userns, dir, dentry, mode, 0); } -static int ceph_symlink(struct inode *dir, struct dentry *dentry, - const char *dest) +static int ceph_symlink(struct user_namespace *mnt_userns, struct inode *dir, + struct dentry *dentry, const char *dest) { struct ceph_mds_client *mdsc = ceph_sb_to_mdsc(dir->i_sb); struct ceph_mds_request *req; @@ -937,7 +937,8 @@ out: return err; } -static int ceph_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode) +static int ceph_mkdir(struct user_namespace *mnt_userns, struct inode *dir, + struct dentry *dentry, umode_t mode) { struct ceph_mds_client *mdsc = ceph_sb_to_mdsc(dir->i_sb); struct ceph_mds_request *req; @@ -1183,9 +1184,9 @@ out: return err; } -static int ceph_rename(struct inode *old_dir, struct dentry *old_dentry, - struct inode *new_dir, struct dentry *new_dentry, - unsigned int flags) +static int ceph_rename(struct user_namespace *mnt_userns, struct inode *old_dir, + struct dentry *old_dentry, struct inode *new_dir, + struct dentry *new_dentry, unsigned int flags) { struct ceph_mds_client *mdsc = ceph_sb_to_mdsc(old_dir->i_sb); struct ceph_mds_request *req; diff --git a/fs/ceph/inode.c b/fs/ceph/inode.c index 179a2bb88538..d6ece56d40e8 100644 --- a/fs/ceph/inode.c +++ b/fs/ceph/inode.c @@ -2238,7 +2238,8 @@ int __ceph_setattr(struct inode *inode, struct iattr *attr) /* * setattr */ -int ceph_setattr(struct dentry *dentry, struct iattr *attr) +int ceph_setattr(struct user_namespace *mnt_userns, struct dentry *dentry, + struct iattr *attr) { struct inode *inode = d_inode(dentry); struct ceph_fs_client *fsc = ceph_inode_to_client(inode); @@ -2321,7 +2322,8 @@ int __ceph_do_getattr(struct inode *inode, struct page *locked_page, * Check inode permissions. We verify we have a valid value for * the AUTH cap, then call the generic handler. */ -int ceph_permission(struct inode *inode, int mask) +int ceph_permission(struct user_namespace *mnt_userns, struct inode *inode, + int mask) { int err; @@ -2368,8 +2370,8 @@ static int statx_to_caps(u32 want, umode_t mode) * Get all the attributes. If we have sufficient caps for the requested attrs, * then we can avoid talking to the MDS at all. */ -int ceph_getattr(const struct path *path, struct kstat *stat, - u32 request_mask, unsigned int flags) +int ceph_getattr(struct user_namespace *mnt_userns, const struct path *path, + struct kstat *stat, u32 request_mask, unsigned int flags) { struct inode *inode = d_inode(path->dentry); struct ceph_inode_info *ci = ceph_inode(inode); diff --git a/fs/ceph/super.h b/fs/ceph/super.h index b62d8fee3b86..1ef0a2a15817 100644 --- a/fs/ceph/super.h +++ b/fs/ceph/super.h @@ -973,10 +973,13 @@ static inline int ceph_do_getattr(struct inode *inode, int mask, bool force) { return __ceph_do_getattr(inode, NULL, mask, force); } -extern int ceph_permission(struct inode *inode, int mask); +extern int ceph_permission(struct user_namespace *mnt_userns, + struct inode *inode, int mask); extern int __ceph_setattr(struct inode *inode, struct iattr *attr); -extern int ceph_setattr(struct dentry *dentry, struct iattr *attr); -extern int ceph_getattr(const struct path *path, struct kstat *stat, +extern int ceph_setattr(struct user_namespace *mnt_userns, + struct dentry *dentry, struct iattr *attr); +extern int ceph_getattr(struct user_namespace *mnt_userns, + const struct path *path, struct kstat *stat, u32 request_mask, unsigned int flags); /* xattr.c */ @@ -1037,7 +1040,8 @@ void ceph_release_acl_sec_ctx(struct ceph_acl_sec_ctx *as_ctx); #ifdef CONFIG_CEPH_FS_POSIX_ACL struct posix_acl *ceph_get_acl(struct inode *, int); -int ceph_set_acl(struct inode *inode, struct posix_acl *acl, int type); +int ceph_set_acl(struct user_namespace *mnt_userns, + struct inode *inode, struct posix_acl *acl, int type); int ceph_pre_init_acls(struct inode *dir, umode_t *mode, struct ceph_acl_sec_ctx *as_ctx); void ceph_init_inode_acls(struct inode *inode, diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c index ce14e6f8adb6..39e51dcf796f 100644 --- a/fs/cifs/cifsfs.c +++ b/fs/cifs/cifsfs.c @@ -305,7 +305,8 @@ static long cifs_fallocate(struct file *file, int mode, loff_t off, loff_t len) return -EOPNOTSUPP; } -static int cifs_permission(struct inode *inode, int mask) +static int cifs_permission(struct user_namespace *mnt_userns, + struct inode *inode, int mask) { struct cifs_sb_info *cifs_sb; diff --git a/fs/cifs/cifsfs.h b/fs/cifs/cifsfs.h index 2307bb0f6147..71e9c6abb2a6 100644 --- a/fs/cifs/cifsfs.h +++ b/fs/cifs/cifsfs.h @@ -62,19 +62,22 @@ extern void cifs_sb_deactive(struct super_block *sb); /* Functions related to inodes */ extern const struct inode_operations cifs_dir_inode_ops; extern struct inode *cifs_root_iget(struct super_block *); -extern int cifs_create(struct inode *, struct dentry *, umode_t, - bool excl); +extern int cifs_create(struct user_namespace *, struct inode *, + struct dentry *, umode_t, bool excl); extern int cifs_atomic_open(struct inode *, struct dentry *, struct file *, unsigned, umode_t); extern struct dentry *cifs_lookup(struct inode *, struct dentry *, unsigned int); extern int cifs_unlink(struct inode *dir, struct dentry *dentry); extern int cifs_hardlink(struct dentry *, struct inode *, struct dentry *); -extern int cifs_mknod(struct inode *, struct dentry *, umode_t, dev_t); -extern int cifs_mkdir(struct inode *, struct dentry *, umode_t); +extern int cifs_mknod(struct user_namespace *, struct inode *, struct dentry *, + umode_t, dev_t); +extern int cifs_mkdir(struct user_namespace *, struct inode *, struct dentry *, + umode_t); extern int cifs_rmdir(struct inode *, struct dentry *); -extern int cifs_rename2(struct inode *, struct dentry *, struct inode *, - struct dentry *, unsigned int); +extern int cifs_rename2(struct user_namespace *, struct inode *, + struct dentry *, struct inode *, struct dentry *, + unsigned int); extern int cifs_revalidate_file_attr(struct file *filp); extern int cifs_revalidate_dentry_attr(struct dentry *); extern int cifs_revalidate_file(struct file *filp); @@ -82,8 +85,10 @@ extern int cifs_revalidate_dentry(struct dentry *); extern int cifs_invalidate_mapping(struct inode *inode); extern int cifs_revalidate_mapping(struct inode *inode); extern int cifs_zap_mapping(struct inode *inode); -extern int cifs_getattr(const struct path *, struct kstat *, u32, unsigned int); -extern int cifs_setattr(struct dentry *, struct iattr *); +extern int cifs_getattr(struct user_namespace *, const struct path *, + struct kstat *, u32, unsigned int); +extern int cifs_setattr(struct user_namespace *, struct dentry *, + struct iattr *); extern int cifs_fiemap(struct inode *, struct fiemap_extent_info *, u64 start, u64 len); @@ -132,8 +137,8 @@ extern struct vfsmount *cifs_dfs_d_automount(struct path *path); /* Functions related to symlinks */ extern const char *cifs_get_link(struct dentry *, struct inode *, struct delayed_call *); -extern int cifs_symlink(struct inode *inode, struct dentry *direntry, - const char *symname); +extern int cifs_symlink(struct user_namespace *mnt_userns, struct inode *inode, + struct dentry *direntry, const char *symname); #ifdef CONFIG_CIFS_XATTR extern const struct xattr_handler *cifs_xattr_handlers[]; diff --git a/fs/cifs/dir.c b/fs/cifs/dir.c index 68900f1629bf..68f4f8536e6a 100644 --- a/fs/cifs/dir.c +++ b/fs/cifs/dir.c @@ -567,8 +567,8 @@ out_free_xid: return rc; } -int cifs_create(struct inode *inode, struct dentry *direntry, umode_t mode, - bool excl) +int cifs_create(struct user_namespace *mnt_userns, struct inode *inode, + struct dentry *direntry, umode_t mode, bool excl) { int rc; unsigned int xid = get_xid(); @@ -611,8 +611,8 @@ out_free_xid: return rc; } -int cifs_mknod(struct inode *inode, struct dentry *direntry, umode_t mode, - dev_t device_number) +int cifs_mknod(struct user_namespace *mnt_userns, struct inode *inode, + struct dentry *direntry, umode_t mode, dev_t device_number) { int rc = -EPERM; unsigned int xid; diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c index 374abce7efaf..3e9c7bb23f26 100644 --- a/fs/cifs/inode.c +++ b/fs/cifs/inode.c @@ -1857,7 +1857,8 @@ posix_mkdir_get_info: goto posix_mkdir_out; } -int cifs_mkdir(struct inode *inode, struct dentry *direntry, umode_t mode) +int cifs_mkdir(struct user_namespace *mnt_userns, struct inode *inode, + struct dentry *direntry, umode_t mode) { int rc = 0; unsigned int xid; @@ -2067,9 +2068,9 @@ do_rename_exit: } int -cifs_rename2(struct inode *source_dir, struct dentry *source_dentry, - struct inode *target_dir, struct dentry *target_dentry, - unsigned int flags) +cifs_rename2(struct user_namespace *mnt_userns, struct inode *source_dir, + struct dentry *source_dentry, struct inode *target_dir, + struct dentry *target_dentry, unsigned int flags) { char *from_name = NULL; char *to_name = NULL; @@ -2370,8 +2371,8 @@ int cifs_revalidate_dentry(struct dentry *dentry) return cifs_revalidate_mapping(inode); } -int cifs_getattr(const struct path *path, struct kstat *stat, - u32 request_mask, unsigned int flags) +int cifs_getattr(struct user_namespace *mnt_userns, const struct path *path, + struct kstat *stat, u32 request_mask, unsigned int flags) { struct dentry *dentry = path->dentry; struct cifs_sb_info *cifs_sb = CIFS_SB(dentry->d_sb); @@ -2923,7 +2924,8 @@ cifs_setattr_exit: } int -cifs_setattr(struct dentry *direntry, struct iattr *attrs) +cifs_setattr(struct user_namespace *mnt_userns, struct dentry *direntry, + struct iattr *attrs) { struct cifs_sb_info *cifs_sb = CIFS_SB(direntry->d_sb); struct cifs_tcon *pTcon = cifs_sb_master_tcon(cifs_sb); diff --git a/fs/cifs/link.c b/fs/cifs/link.c index 94dab4309fbb..7c5878a645d9 100644 --- a/fs/cifs/link.c +++ b/fs/cifs/link.c @@ -661,7 +661,8 @@ cifs_get_link(struct dentry *direntry, struct inode *inode, } int -cifs_symlink(struct inode *inode, struct dentry *direntry, const char *symname) +cifs_symlink(struct user_namespace *mnt_userns, struct inode *inode, + struct dentry *direntry, const char *symname) { int rc = -EOPNOTSUPP; unsigned int xid; diff --git a/fs/coda/coda_linux.h b/fs/coda/coda_linux.h index d5ebd36fb2cc..e7b27754ce78 100644 --- a/fs/coda/coda_linux.h +++ b/fs/coda/coda_linux.h @@ -46,10 +46,12 @@ extern const struct file_operations coda_ioctl_operations; /* operations shared over more than one file */ int coda_open(struct inode *i, struct file *f); int coda_release(struct inode *i, struct file *f); -int coda_permission(struct inode *inode, int mask); +int coda_permission(struct user_namespace *mnt_userns, struct inode *inode, + int mask); int coda_revalidate_inode(struct inode *); -int coda_getattr(const struct path *, struct kstat *, u32, unsigned int); -int coda_setattr(struct dentry *, struct iattr *); +int coda_getattr(struct user_namespace *, const struct path *, struct kstat *, + u32, unsigned int); +int coda_setattr(struct user_namespace *, struct dentry *, struct iattr *); /* this file: heloers */ char *coda_f2s(struct CodaFid *f); diff --git a/fs/coda/dir.c b/fs/coda/dir.c index ca40c2556ba6..d69989c1bac3 100644 --- a/fs/coda/dir.c +++ b/fs/coda/dir.c @@ -73,7 +73,8 @@ static struct dentry *coda_lookup(struct inode *dir, struct dentry *entry, unsig } -int coda_permission(struct inode *inode, int mask) +int coda_permission(struct user_namespace *mnt_userns, struct inode *inode, + int mask) { int error; @@ -132,7 +133,8 @@ static inline void coda_dir_drop_nlink(struct inode *dir) } /* creation routines: create, mknod, mkdir, link, symlink */ -static int coda_create(struct inode *dir, struct dentry *de, umode_t mode, bool excl) +static int coda_create(struct user_namespace *mnt_userns, struct inode *dir, + struct dentry *de, umode_t mode, bool excl) { int error; const char *name=de->d_name.name; @@ -164,7 +166,8 @@ err_out: return error; } -static int coda_mkdir(struct inode *dir, struct dentry *de, umode_t mode) +static int coda_mkdir(struct user_namespace *mnt_userns, struct inode *dir, + struct dentry *de, umode_t mode) { struct inode *inode; struct coda_vattr attrs; @@ -225,7 +228,8 @@ static int coda_link(struct dentry *source_de, struct inode *dir_inode, } -static int coda_symlink(struct inode *dir_inode, struct dentry *de, +static int coda_symlink(struct user_namespace *mnt_userns, + struct inode *dir_inode, struct dentry *de, const char *symname) { const char *name = de->d_name.name; @@ -291,9 +295,9 @@ static int coda_rmdir(struct inode *dir, struct dentry *de) } /* rename */ -static int coda_rename(struct inode *old_dir, struct dentry *old_dentry, - struct inode *new_dir, struct dentry *new_dentry, - unsigned int flags) +static int coda_rename(struct user_namespace *mnt_userns, struct inode *old_dir, + struct dentry *old_dentry, struct inode *new_dir, + struct dentry *new_dentry, unsigned int flags) { const char *old_name = old_dentry->d_name.name; const char *new_name = new_dentry->d_name.name; diff --git a/fs/coda/inode.c b/fs/coda/inode.c index 4d113e191cb8..d9f1bd7153df 100644 --- a/fs/coda/inode.c +++ b/fs/coda/inode.c @@ -251,8 +251,8 @@ static void coda_evict_inode(struct inode *inode) coda_cache_clear_inode(inode); } -int coda_getattr(const struct path *path, struct kstat *stat, - u32 request_mask, unsigned int flags) +int coda_getattr(struct user_namespace *mnt_userns, const struct path *path, + struct kstat *stat, u32 request_mask, unsigned int flags) { int err = coda_revalidate_inode(d_inode(path->dentry)); if (!err) @@ -260,7 +260,8 @@ int coda_getattr(const struct path *path, struct kstat *stat, return err; } -int coda_setattr(struct dentry *de, struct iattr *iattr) +int coda_setattr(struct user_namespace *mnt_userns, struct dentry *de, + struct iattr *iattr) { struct inode *inode = d_inode(de); struct coda_vattr vattr; diff --git a/fs/coda/pioctl.c b/fs/coda/pioctl.c index 3aec27e5eb82..cb9fd59a688c 100644 --- a/fs/coda/pioctl.c +++ b/fs/coda/pioctl.c @@ -24,7 +24,8 @@ #include "coda_linux.h" /* pioctl ops */ -static int coda_ioctl_permission(struct inode *inode, int mask); +static int coda_ioctl_permission(struct user_namespace *mnt_userns, + struct inode *inode, int mask); static long coda_pioctl(struct file *filp, unsigned int cmd, unsigned long user_data); @@ -40,7 +41,8 @@ const struct file_operations coda_ioctl_operations = { }; /* the coda pioctl inode ops */ -static int coda_ioctl_permission(struct inode *inode, int mask) +static int coda_ioctl_permission(struct user_namespace *mnt_userns, + struct inode *inode, int mask) { return (mask & MAY_EXEC) ? -EACCES : 0; } diff --git a/fs/configfs/configfs_internal.h b/fs/configfs/configfs_internal.h index 22dce2d35a4b..9a3aed249692 100644 --- a/fs/configfs/configfs_internal.h +++ b/fs/configfs/configfs_internal.h @@ -79,7 +79,8 @@ extern void configfs_hash_and_remove(struct dentry * dir, const char * name); extern const unsigned char * configfs_get_name(struct configfs_dirent *sd); extern void configfs_drop_dentry(struct configfs_dirent *sd, struct dentry *parent); -extern int configfs_setattr(struct dentry *dentry, struct iattr *iattr); +extern int configfs_setattr(struct user_namespace *mnt_userns, + struct dentry *dentry, struct iattr *iattr); extern struct dentry *configfs_pin_fs(void); extern void configfs_release_fs(void); @@ -92,7 +93,8 @@ extern const struct inode_operations configfs_root_inode_operations; extern const struct inode_operations configfs_symlink_inode_operations; extern const struct dentry_operations configfs_dentry_ops; -extern int configfs_symlink(struct inode *dir, struct dentry *dentry, +extern int configfs_symlink(struct user_namespace *mnt_userns, + struct inode *dir, struct dentry *dentry, const char *symname); extern int configfs_unlink(struct inode *dir, struct dentry *dentry); diff --git a/fs/configfs/dir.c b/fs/configfs/dir.c index b839dd1b459f..b6098e02e20b 100644 --- a/fs/configfs/dir.c +++ b/fs/configfs/dir.c @@ -1268,7 +1268,8 @@ out_root_unlock: } EXPORT_SYMBOL(configfs_depend_item_unlocked); -static int configfs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode) +static int configfs_mkdir(struct user_namespace *mnt_userns, struct inode *dir, + struct dentry *dentry, umode_t mode) { int ret = 0; int module_got = 0; diff --git a/fs/configfs/inode.c b/fs/configfs/inode.c index 8bd6a883c94c..42c348bb2903 100644 --- a/fs/configfs/inode.c +++ b/fs/configfs/inode.c @@ -40,7 +40,8 @@ static const struct inode_operations configfs_inode_operations ={ .setattr = configfs_setattr, }; -int configfs_setattr(struct dentry * dentry, struct iattr * iattr) +int configfs_setattr(struct user_namespace *mnt_userns, struct dentry *dentry, + struct iattr *iattr) { struct inode * inode = d_inode(dentry); struct configfs_dirent * sd = dentry->d_fsdata; @@ -67,7 +68,7 @@ int configfs_setattr(struct dentry * dentry, struct iattr * iattr) } /* attributes were changed atleast once in past */ - error = simple_setattr(dentry, iattr); + error = simple_setattr(mnt_userns, dentry, iattr); if (error) return error; diff --git a/fs/configfs/symlink.c b/fs/configfs/symlink.c index 8ca36394fa30..77c854364e60 100644 --- a/fs/configfs/symlink.c +++ b/fs/configfs/symlink.c @@ -139,7 +139,8 @@ static int get_target(const char *symname, struct path *path, } -int configfs_symlink(struct inode *dir, struct dentry *dentry, const char *symname) +int configfs_symlink(struct user_namespace *mnt_userns, struct inode *dir, + struct dentry *dentry, const char *symname) { int ret; struct path path; diff --git a/fs/debugfs/inode.c b/fs/debugfs/inode.c index 2fcf66473436..c35249497b9b 100644 --- a/fs/debugfs/inode.c +++ b/fs/debugfs/inode.c @@ -42,13 +42,14 @@ static unsigned int debugfs_allow = DEFAULT_DEBUGFS_ALLOW_BITS; * so that we can use the file mode as part of a heuristic to determine whether * to lock down individual files. */ -static int debugfs_setattr(struct dentry *dentry, struct iattr *ia) +static int debugfs_setattr(struct user_namespace *mnt_userns, + struct dentry *dentry, struct iattr *ia) { int ret = security_locked_down(LOCKDOWN_DEBUGFS); if (ret && (ia->ia_valid & (ATTR_MODE | ATTR_UID | ATTR_GID))) return ret; - return simple_setattr(dentry, ia); + return simple_setattr(&init_user_ns, dentry, ia); } static const struct inode_operations debugfs_file_inode_operations = { @@ -775,8 +776,8 @@ struct dentry *debugfs_rename(struct dentry *old_dir, struct dentry *old_dentry, take_dentry_name_snapshot(&old_name, old_dentry); - error = simple_rename(d_inode(old_dir), old_dentry, d_inode(new_dir), - dentry, 0); + error = simple_rename(&init_user_ns, d_inode(old_dir), old_dentry, + d_inode(new_dir), dentry, 0); if (error) { release_dentry_name_snapshot(&old_name); goto exit; diff --git a/fs/ecryptfs/inode.c b/fs/ecryptfs/inode.c index 73e3d47e7b2d..55da9a91f51a 100644 --- a/fs/ecryptfs/inode.c +++ b/fs/ecryptfs/inode.c @@ -257,7 +257,8 @@ out: * Returns zero on success; non-zero on error condition */ static int -ecryptfs_create(struct inode *directory_inode, struct dentry *ecryptfs_dentry, +ecryptfs_create(struct user_namespace *mnt_userns, + struct inode *directory_inode, struct dentry *ecryptfs_dentry, umode_t mode, bool excl) { struct inode *ecryptfs_inode; @@ -463,7 +464,8 @@ static int ecryptfs_unlink(struct inode *dir, struct dentry *dentry) return ecryptfs_do_unlink(dir, dentry, d_inode(dentry)); } -static int ecryptfs_symlink(struct inode *dir, struct dentry *dentry, +static int ecryptfs_symlink(struct user_namespace *mnt_userns, + struct inode *dir, struct dentry *dentry, const char *symname) { int rc; @@ -502,7 +504,8 @@ out_lock: return rc; } -static int ecryptfs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode) +static int ecryptfs_mkdir(struct user_namespace *mnt_userns, struct inode *dir, + struct dentry *dentry, umode_t mode) { int rc; struct dentry *lower_dentry; @@ -559,7 +562,8 @@ static int ecryptfs_rmdir(struct inode *dir, struct dentry *dentry) } static int -ecryptfs_mknod(struct inode *dir, struct dentry *dentry, umode_t mode, dev_t dev) +ecryptfs_mknod(struct user_namespace *mnt_userns, struct inode *dir, + struct dentry *dentry, umode_t mode, dev_t dev) { int rc; struct dentry *lower_dentry; @@ -584,9 +588,9 @@ out: } static int -ecryptfs_rename(struct inode *old_dir, struct dentry *old_dentry, - struct inode *new_dir, struct dentry *new_dentry, - unsigned int flags) +ecryptfs_rename(struct user_namespace *mnt_userns, struct inode *old_dir, + struct dentry *old_dentry, struct inode *new_dir, + struct dentry *new_dentry, unsigned int flags) { int rc; struct dentry *lower_old_dentry; @@ -874,7 +878,8 @@ int ecryptfs_truncate(struct dentry *dentry, loff_t new_length) } static int -ecryptfs_permission(struct inode *inode, int mask) +ecryptfs_permission(struct user_namespace *mnt_userns, struct inode *inode, + int mask) { return inode_permission(&init_user_ns, ecryptfs_inode_to_lower(inode), mask); @@ -892,7 +897,8 @@ ecryptfs_permission(struct inode *inode, int mask) * All other metadata changes will be passed right to the lower filesystem, * and we will just update our inode to look like the lower. */ -static int ecryptfs_setattr(struct dentry *dentry, struct iattr *ia) +static int ecryptfs_setattr(struct user_namespace *mnt_userns, + struct dentry *dentry, struct iattr *ia) { int rc = 0; struct dentry *lower_dentry; @@ -979,7 +985,8 @@ out: return rc; } -static int ecryptfs_getattr_link(const struct path *path, struct kstat *stat, +static int ecryptfs_getattr_link(struct user_namespace *mnt_userns, + const struct path *path, struct kstat *stat, u32 request_mask, unsigned int flags) { struct dentry *dentry = path->dentry; @@ -1004,7 +1011,8 @@ static int ecryptfs_getattr_link(const struct path *path, struct kstat *stat, return rc; } -static int ecryptfs_getattr(const struct path *path, struct kstat *stat, +static int ecryptfs_getattr(struct user_namespace *mnt_userns, + const struct path *path, struct kstat *stat, u32 request_mask, unsigned int flags) { struct dentry *dentry = path->dentry; diff --git a/fs/efivarfs/inode.c b/fs/efivarfs/inode.c index 0297ad95eb5c..14e2947975fd 100644 --- a/fs/efivarfs/inode.c +++ b/fs/efivarfs/inode.c @@ -66,8 +66,8 @@ bool efivarfs_valid_name(const char *str, int len) return uuid_is_valid(s); } -static int efivarfs_create(struct inode *dir, struct dentry *dentry, - umode_t mode, bool excl) +static int efivarfs_create(struct user_namespace *mnt_userns, struct inode *dir, + struct dentry *dentry, umode_t mode, bool excl) { struct inode *inode = NULL; struct efivar_entry *var; diff --git a/fs/erofs/inode.c b/fs/erofs/inode.c index 083818063ac6..119fdce1b520 100644 --- a/fs/erofs/inode.c +++ b/fs/erofs/inode.c @@ -331,8 +331,9 @@ struct inode *erofs_iget(struct super_block *sb, return inode; } -int erofs_getattr(const struct path *path, struct kstat *stat, - u32 request_mask, unsigned int query_flags) +int erofs_getattr(struct user_namespace *mnt_userns, const struct path *path, + struct kstat *stat, u32 request_mask, + unsigned int query_flags) { struct inode *const inode = d_inode(path->dentry); diff --git a/fs/erofs/internal.h b/fs/erofs/internal.h index 67a7ec945686..351dae524a0c 100644 --- a/fs/erofs/internal.h +++ b/fs/erofs/internal.h @@ -373,8 +373,9 @@ extern const struct inode_operations erofs_symlink_iops; extern const struct inode_operations erofs_fast_symlink_iops; struct inode *erofs_iget(struct super_block *sb, erofs_nid_t nid, bool dir); -int erofs_getattr(const struct path *path, struct kstat *stat, - u32 request_mask, unsigned int query_flags); +int erofs_getattr(struct user_namespace *mnt_userns, const struct path *path, + struct kstat *stat, u32 request_mask, + unsigned int query_flags); /* namei.c */ extern const struct inode_operations erofs_dir_iops; diff --git a/fs/exfat/exfat_fs.h b/fs/exfat/exfat_fs.h index b8f0e829ecbd..d905bb9cd2ca 100644 --- a/fs/exfat/exfat_fs.h +++ b/fs/exfat/exfat_fs.h @@ -416,9 +416,11 @@ int exfat_count_used_clusters(struct super_block *sb, unsigned int *ret_count); extern const struct file_operations exfat_file_operations; int __exfat_truncate(struct inode *inode, loff_t new_size); 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_setattr(struct user_namespace *mnt_userns, struct dentry *dentry, + struct iattr *attr); +int exfat_getattr(struct user_namespace *mnt_userns, 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 */ diff --git a/fs/exfat/file.c b/fs/exfat/file.c index e9705b3295d3..3aa6eb4de5e3 100644 --- a/fs/exfat/file.c +++ b/fs/exfat/file.c @@ -267,8 +267,9 @@ write_size: mutex_unlock(&sbi->s_lock); } -int exfat_getattr(const struct path *path, struct kstat *stat, - unsigned int request_mask, unsigned int query_flags) +int exfat_getattr(struct user_namespace *mnt_uerns, const struct path *path, + struct kstat *stat, unsigned int request_mask, + unsigned int query_flags) { struct inode *inode = d_backing_inode(path->dentry); struct exfat_inode_info *ei = EXFAT_I(inode); @@ -282,7 +283,8 @@ int exfat_getattr(const struct path *path, struct kstat *stat, return 0; } -int exfat_setattr(struct dentry *dentry, struct iattr *attr) +int exfat_setattr(struct user_namespace *mnt_userns, struct dentry *dentry, + struct iattr *attr) { struct exfat_sb_info *sbi = EXFAT_SB(dentry->d_sb); struct inode *inode = dentry->d_inode; diff --git a/fs/exfat/namei.c b/fs/exfat/namei.c index 2932b23a3b6c..d9e8ec689c55 100644 --- a/fs/exfat/namei.c +++ b/fs/exfat/namei.c @@ -541,8 +541,8 @@ out: return ret; } -static int exfat_create(struct inode *dir, struct dentry *dentry, umode_t mode, - bool excl) +static int exfat_create(struct user_namespace *mnt_userns, struct inode *dir, + struct dentry *dentry, umode_t mode, bool excl) { struct super_block *sb = dir->i_sb; struct inode *inode; @@ -827,7 +827,8 @@ unlock: return err; } -static int exfat_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode) +static int exfat_mkdir(struct user_namespace *mnt_userns, struct inode *dir, + struct dentry *dentry, umode_t mode) { struct super_block *sb = dir->i_sb; struct inode *inode; @@ -1318,9 +1319,10 @@ out: return ret; } -static int exfat_rename(struct inode *old_dir, struct dentry *old_dentry, - struct inode *new_dir, struct dentry *new_dentry, - unsigned int flags) +static int exfat_rename(struct user_namespace *mnt_userns, + struct inode *old_dir, struct dentry *old_dentry, + struct inode *new_dir, struct dentry *new_dentry, + unsigned int flags) { struct inode *old_inode, *new_inode; struct super_block *sb = old_dir->i_sb; diff --git a/fs/ext2/acl.c b/fs/ext2/acl.c index 9031f7df2d48..b9a9db98e94b 100644 --- a/fs/ext2/acl.c +++ b/fs/ext2/acl.c @@ -216,7 +216,8 @@ __ext2_set_acl(struct inode *inode, struct posix_acl *acl, int type) * inode->i_mutex: down */ int -ext2_set_acl(struct inode *inode, struct posix_acl *acl, int type) +ext2_set_acl(struct user_namespace *mnt_userns, struct inode *inode, + struct posix_acl *acl, int type) { int error; int update_mode = 0; diff --git a/fs/ext2/acl.h b/fs/ext2/acl.h index 0f01c759daac..917db5f6630a 100644 --- a/fs/ext2/acl.h +++ b/fs/ext2/acl.h @@ -56,7 +56,8 @@ static inline int ext2_acl_count(size_t size) /* acl.c */ extern struct posix_acl *ext2_get_acl(struct inode *inode, int type); -extern int ext2_set_acl(struct inode *inode, struct posix_acl *acl, int type); +extern int ext2_set_acl(struct user_namespace *mnt_userns, struct inode *inode, + struct posix_acl *acl, int type); extern int ext2_init_acl (struct inode *, struct inode *); #else diff --git a/fs/ext2/ext2.h b/fs/ext2/ext2.h index 2a4175fbaf5e..3309fb2d327a 100644 --- a/fs/ext2/ext2.h +++ b/fs/ext2/ext2.h @@ -764,8 +764,9 @@ extern struct inode *ext2_iget (struct super_block *, unsigned long); extern int ext2_write_inode (struct inode *, struct writeback_control *); extern void ext2_evict_inode(struct inode *); extern int ext2_get_block(struct inode *, sector_t, struct buffer_head *, int); -extern int ext2_setattr (struct dentry *, struct iattr *); -extern int ext2_getattr (const struct path *, struct kstat *, u32, unsigned int); +extern int ext2_setattr (struct user_namespace *, struct dentry *, struct iattr *); +extern int ext2_getattr (struct user_namespace *, const struct path *, + struct kstat *, u32, unsigned int); extern void ext2_set_inode_flags(struct inode *inode); extern int ext2_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo, u64 start, u64 len); diff --git a/fs/ext2/inode.c b/fs/ext2/inode.c index 3d8acafca8ce..68178b2234bd 100644 --- a/fs/ext2/inode.c +++ b/fs/ext2/inode.c @@ -1638,8 +1638,8 @@ int ext2_write_inode(struct inode *inode, struct writeback_control *wbc) return __ext2_write_inode(inode, wbc->sync_mode == WB_SYNC_ALL); } -int ext2_getattr(const struct path *path, struct kstat *stat, - u32 request_mask, unsigned int query_flags) +int ext2_getattr(struct user_namespace *mnt_userns, const struct path *path, + struct kstat *stat, u32 request_mask, unsigned int query_flags) { struct inode *inode = d_inode(path->dentry); struct ext2_inode_info *ei = EXT2_I(inode); @@ -1664,7 +1664,8 @@ int ext2_getattr(const struct path *path, struct kstat *stat, return 0; } -int ext2_setattr(struct dentry *dentry, struct iattr *iattr) +int ext2_setattr(struct user_namespace *mnt_userns, struct dentry *dentry, + struct iattr *iattr) { struct inode *inode = d_inode(dentry); int error; diff --git a/fs/ext2/namei.c b/fs/ext2/namei.c index ea980f1e2e99..3367384d344d 100644 --- a/fs/ext2/namei.c +++ b/fs/ext2/namei.c @@ -100,7 +100,9 @@ struct dentry *ext2_get_parent(struct dentry *child) * If the create succeeds, we fill in the inode information * with d_instantiate(). */ -static int ext2_create (struct inode * dir, struct dentry * dentry, umode_t mode, bool excl) +static int ext2_create (struct user_namespace * mnt_userns, + struct inode * dir, struct dentry * dentry, + umode_t mode, bool excl) { struct inode *inode; int err; @@ -118,7 +120,8 @@ static int ext2_create (struct inode * dir, struct dentry * dentry, umode_t mode return ext2_add_nondir(dentry, inode); } -static int ext2_tmpfile(struct inode *dir, struct dentry *dentry, umode_t mode) +static int ext2_tmpfile(struct user_namespace *mnt_userns, struct inode *dir, + struct dentry *dentry, umode_t mode) { struct inode *inode = ext2_new_inode(dir, mode, NULL); if (IS_ERR(inode)) @@ -131,7 +134,8 @@ static int ext2_tmpfile(struct inode *dir, struct dentry *dentry, umode_t mode) return 0; } -static int ext2_mknod (struct inode * dir, struct dentry *dentry, umode_t mode, dev_t rdev) +static int ext2_mknod (struct user_namespace * mnt_userns, struct inode * dir, + struct dentry *dentry, umode_t mode, dev_t rdev) { struct inode * inode; int err; @@ -151,8 +155,8 @@ static int ext2_mknod (struct inode * dir, struct dentry *dentry, umode_t mode, return err; } -static int ext2_symlink (struct inode * dir, struct dentry * dentry, - const char * symname) +static int ext2_symlink (struct user_namespace * mnt_userns, struct inode * dir, + struct dentry * dentry, const char * symname) { struct super_block * sb = dir->i_sb; int err = -ENAMETOOLONG; @@ -225,7 +229,8 @@ static int ext2_link (struct dentry * old_dentry, struct inode * dir, return err; } -static int ext2_mkdir(struct inode * dir, struct dentry * dentry, umode_t mode) +static int ext2_mkdir(struct user_namespace * mnt_userns, + struct inode * dir, struct dentry * dentry, umode_t mode) { struct inode * inode; int err; @@ -315,8 +320,9 @@ static int ext2_rmdir (struct inode * dir, struct dentry *dentry) return err; } -static int ext2_rename (struct inode * old_dir, struct dentry * old_dentry, - struct inode * new_dir, struct dentry * new_dentry, +static int ext2_rename (struct user_namespace * mnt_userns, + struct inode * old_dir, struct dentry * old_dentry, + struct inode * new_dir, struct dentry * new_dentry, unsigned int flags) { struct inode * old_inode = d_inode(old_dentry); diff --git a/fs/ext4/acl.c b/fs/ext4/acl.c index 7b0fb66bc04d..059434e0f36c 100644 --- a/fs/ext4/acl.c +++ b/fs/ext4/acl.c @@ -222,7 +222,8 @@ __ext4_set_acl(handle_t *handle, struct inode *inode, int type, } int -ext4_set_acl(struct inode *inode, struct posix_acl *acl, int type) +ext4_set_acl(struct user_namespace *mnt_userns, struct inode *inode, + struct posix_acl *acl, int type) { handle_t *handle; int error, credits, retries = 0; diff --git a/fs/ext4/acl.h b/fs/ext4/acl.h index 9b63f5416a2f..84b8942a57f2 100644 --- a/fs/ext4/acl.h +++ b/fs/ext4/acl.h @@ -56,7 +56,8 @@ static inline int ext4_acl_count(size_t size) /* acl.c */ struct posix_acl *ext4_get_acl(struct inode *inode, int type); -int ext4_set_acl(struct inode *inode, struct posix_acl *acl, int type); +int ext4_set_acl(struct user_namespace *mnt_userns, struct inode *inode, + struct posix_acl *acl, int type); extern int ext4_init_acl(handle_t *, struct inode *, struct inode *); #else /* CONFIG_EXT4_FS_POSIX_ACL */ diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h index 2866d249f3d2..3c750f5e8ebd 100644 --- a/fs/ext4/ext4.h +++ b/fs/ext4/ext4.h @@ -2877,11 +2877,14 @@ extern struct inode *__ext4_iget(struct super_block *sb, unsigned long ino, __ext4_iget((sb), (ino), (flags), __func__, __LINE__) extern int ext4_write_inode(struct inode *, struct writeback_control *); -extern int ext4_setattr(struct dentry *, struct iattr *); -extern int ext4_getattr(const struct path *, struct kstat *, u32, unsigned int); +extern int ext4_setattr(struct user_namespace *, struct dentry *, + struct iattr *); +extern int ext4_getattr(struct user_namespace *, const struct path *, + struct kstat *, u32, unsigned int); extern void ext4_evict_inode(struct inode *); extern void ext4_clear_inode(struct inode *); -extern int ext4_file_getattr(const struct path *, struct kstat *, u32, unsigned int); +extern int ext4_file_getattr(struct user_namespace *, const struct path *, + struct kstat *, u32, unsigned int); extern int ext4_sync_inode(handle_t *, struct inode *); extern void ext4_dirty_inode(struct inode *, int); extern int ext4_change_inode_journal_flag(struct inode *, int); diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c index 3a303d3f8423..ce45535336fa 100644 --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c @@ -5319,7 +5319,8 @@ static void ext4_wait_for_tail_page_commit(struct inode *inode) * * Called with inode->i_mutex down. */ -int ext4_setattr(struct dentry *dentry, struct iattr *attr) +int ext4_setattr(struct user_namespace *mnt_userns, struct dentry *dentry, + struct iattr *attr) { struct inode *inode = d_inode(dentry); int error, rc = 0; @@ -5535,8 +5536,8 @@ err_out: return error; } -int ext4_getattr(const struct path *path, struct kstat *stat, - u32 request_mask, unsigned int query_flags) +int ext4_getattr(struct user_namespace *mnt_userns, const struct path *path, + struct kstat *stat, u32 request_mask, unsigned int query_flags) { struct inode *inode = d_inode(path->dentry); struct ext4_inode *raw_inode; @@ -5575,13 +5576,14 @@ int ext4_getattr(const struct path *path, struct kstat *stat, return 0; } -int ext4_file_getattr(const struct path *path, struct kstat *stat, +int ext4_file_getattr(struct user_namespace *mnt_userns, + const struct path *path, struct kstat *stat, u32 request_mask, unsigned int query_flags) { struct inode *inode = d_inode(path->dentry); u64 delalloc_blocks; - ext4_getattr(path, stat, request_mask, query_flags); + ext4_getattr(&init_user_ns, path, stat, request_mask, query_flags); /* * If there is inline data in the inode, the inode will normally not diff --git a/fs/ext4/namei.c b/fs/ext4/namei.c index cf652ba3e74d..13dff80aedcb 100644 --- a/fs/ext4/namei.c +++ b/fs/ext4/namei.c @@ -2596,8 +2596,8 @@ static int ext4_add_nondir(handle_t *handle, * If the create succeeds, we fill in the inode information * with d_instantiate(). */ -static int ext4_create(struct inode *dir, struct dentry *dentry, umode_t mode, - bool excl) +static int ext4_create(struct user_namespace *mnt_userns, struct inode *dir, + struct dentry *dentry, umode_t mode, bool excl) { handle_t *handle; struct inode *inode; @@ -2631,8 +2631,8 @@ retry: return err; } -static int ext4_mknod(struct inode *dir, struct dentry *dentry, - umode_t mode, dev_t rdev) +static int ext4_mknod(struct user_namespace *mnt_userns, struct inode *dir, + struct dentry *dentry, umode_t mode, dev_t rdev) { handle_t *handle; struct inode *inode; @@ -2665,7 +2665,8 @@ retry: return err; } -static int ext4_tmpfile(struct inode *dir, struct dentry *dentry, umode_t mode) +static int ext4_tmpfile(struct user_namespace *mnt_userns, struct inode *dir, + struct dentry *dentry, umode_t mode) { handle_t *handle; struct inode *inode; @@ -2774,7 +2775,8 @@ out: return err; } -static int ext4_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode) +static int ext4_mkdir(struct user_namespace *mnt_userns, struct inode *dir, + struct dentry *dentry, umode_t mode) { handle_t *handle; struct inode *inode; @@ -3292,7 +3294,7 @@ out_trace: return retval; } -static int ext4_symlink(struct inode *dir, +static int ext4_symlink(struct user_namespace *mnt_userns, struct inode *dir, struct dentry *dentry, const char *symname) { handle_t *handle; @@ -4085,7 +4087,8 @@ end_rename: return retval; } -static int ext4_rename2(struct inode *old_dir, struct dentry *old_dentry, +static int ext4_rename2(struct user_namespace *mnt_userns, + struct inode *old_dir, struct dentry *old_dentry, struct inode *new_dir, struct dentry *new_dentry, unsigned int flags) { diff --git a/fs/f2fs/acl.c b/fs/f2fs/acl.c index 6a95bf28f602..a19e86c9adac 100644 --- a/fs/f2fs/acl.c +++ b/fs/f2fs/acl.c @@ -249,7 +249,8 @@ static int __f2fs_set_acl(struct inode *inode, int type, return error; } -int f2fs_set_acl(struct inode *inode, struct posix_acl *acl, int type) +int f2fs_set_acl(struct user_namespace *mnt_userns, struct inode *inode, + struct posix_acl *acl, int type) { if (unlikely(f2fs_cp_error(F2FS_I_SB(inode)))) return -EIO; diff --git a/fs/f2fs/acl.h b/fs/f2fs/acl.h index 124868c13f80..986fd1bc780b 100644 --- a/fs/f2fs/acl.h +++ b/fs/f2fs/acl.h @@ -34,7 +34,8 @@ struct f2fs_acl_header { #ifdef CONFIG_F2FS_FS_POSIX_ACL extern struct posix_acl *f2fs_get_acl(struct inode *, int); -extern int f2fs_set_acl(struct inode *, struct posix_acl *, int); +extern int f2fs_set_acl(struct user_namespace *, struct inode *, + struct posix_acl *, int); extern int f2fs_init_acl(struct inode *, struct inode *, struct page *, struct page *); #else diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h index bb11759191dc..c9002b1933f0 100644 --- a/fs/f2fs/f2fs.h +++ b/fs/f2fs/f2fs.h @@ -3135,9 +3135,10 @@ void f2fs_truncate_data_blocks(struct dnode_of_data *dn); int f2fs_do_truncate_blocks(struct inode *inode, u64 from, bool lock); int f2fs_truncate_blocks(struct inode *inode, u64 from, bool lock); int f2fs_truncate(struct inode *inode); -int f2fs_getattr(const struct path *path, struct kstat *stat, - u32 request_mask, unsigned int flags); -int f2fs_setattr(struct dentry *dentry, struct iattr *attr); +int f2fs_getattr(struct user_namespace *mnt_userns, const struct path *path, + struct kstat *stat, u32 request_mask, unsigned int flags); +int f2fs_setattr(struct user_namespace *mnt_userns, struct dentry *dentry, + struct iattr *attr); int f2fs_truncate_hole(struct inode *inode, pgoff_t pg_start, pgoff_t pg_end); void f2fs_truncate_data_blocks_range(struct dnode_of_data *dn, int count); int f2fs_precache_extents(struct inode *inode); diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c index 44cd0dbdbb5d..8f1e97e7d242 100644 --- a/fs/f2fs/file.c +++ b/fs/f2fs/file.c @@ -783,8 +783,8 @@ int f2fs_truncate(struct inode *inode) return 0; } -int f2fs_getattr(const struct path *path, struct kstat *stat, - u32 request_mask, unsigned int query_flags) +int f2fs_getattr(struct user_namespace *mnt_userns, const struct path *path, + struct kstat *stat, u32 request_mask, unsigned int query_flags) { struct inode *inode = d_inode(path->dentry); struct f2fs_inode_info *fi = F2FS_I(inode); @@ -859,7 +859,8 @@ static void __setattr_copy(struct user_namespace *mnt_userns, #define __setattr_copy setattr_copy #endif -int f2fs_setattr(struct dentry *dentry, struct iattr *attr) +int f2fs_setattr(struct user_namespace *mnt_userns, struct dentry *dentry, + struct iattr *attr) { struct inode *inode = d_inode(dentry); int err; diff --git a/fs/f2fs/namei.c b/fs/f2fs/namei.c index ad98926bacac..c061a67e43a3 100644 --- a/fs/f2fs/namei.c +++ b/fs/f2fs/namei.c @@ -314,8 +314,8 @@ static void set_compress_inode(struct f2fs_sb_info *sbi, struct inode *inode, } } -static int f2fs_create(struct inode *dir, struct dentry *dentry, umode_t mode, - bool excl) +static int f2fs_create(struct user_namespace *mnt_userns, struct inode *dir, + struct dentry *dentry, umode_t mode, bool excl) { struct f2fs_sb_info *sbi = F2FS_I_SB(dir); struct inode *inode; @@ -637,8 +637,8 @@ static const char *f2fs_get_link(struct dentry *dentry, return link; } -static int f2fs_symlink(struct inode *dir, struct dentry *dentry, - const char *symname) +static int f2fs_symlink(struct user_namespace *mnt_userns, struct inode *dir, + struct dentry *dentry, const char *symname) { struct f2fs_sb_info *sbi = F2FS_I_SB(dir); struct inode *inode; @@ -717,7 +717,8 @@ out_free_encrypted_link: return err; } -static int f2fs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode) +static int f2fs_mkdir(struct user_namespace *mnt_userns, struct inode *dir, + struct dentry *dentry, umode_t mode) { struct f2fs_sb_info *sbi = F2FS_I_SB(dir); struct inode *inode; @@ -770,8 +771,8 @@ static int f2fs_rmdir(struct inode *dir, struct dentry *dentry) return -ENOTEMPTY; } -static int f2fs_mknod(struct inode *dir, struct dentry *dentry, - umode_t mode, dev_t rdev) +static int f2fs_mknod(struct user_namespace *mnt_userns, struct inode *dir, + struct dentry *dentry, umode_t mode, dev_t rdev) { struct f2fs_sb_info *sbi = F2FS_I_SB(dir); struct inode *inode; @@ -874,7 +875,8 @@ out: return err; } -static int f2fs_tmpfile(struct inode *dir, struct dentry *dentry, umode_t mode) +static int f2fs_tmpfile(struct user_namespace *mnt_userns, struct inode *dir, + struct dentry *dentry, umode_t mode) { struct f2fs_sb_info *sbi = F2FS_I_SB(dir); @@ -1247,7 +1249,8 @@ out: return err; } -static int f2fs_rename2(struct inode *old_dir, struct dentry *old_dentry, +static int f2fs_rename2(struct user_namespace *mnt_userns, + struct inode *old_dir, struct dentry *old_dentry, struct inode *new_dir, struct dentry *new_dentry, unsigned int flags) { diff --git a/fs/fat/fat.h b/fs/fat/fat.h index 922a0c6ba46c..02d4d4234956 100644 --- a/fs/fat/fat.h +++ b/fs/fat/fat.h @@ -397,9 +397,11 @@ extern long fat_generic_ioctl(struct file *filp, unsigned int cmd, unsigned long arg); extern const struct file_operations fat_file_operations; extern const struct inode_operations fat_file_inode_operations; -extern int fat_setattr(struct dentry *dentry, struct iattr *attr); +extern int fat_setattr(struct user_namespace *mnt_userns, struct dentry *dentry, + struct iattr *attr); extern void fat_truncate_blocks(struct inode *inode, loff_t offset); -extern int fat_getattr(const struct path *path, struct kstat *stat, +extern int fat_getattr(struct user_namespace *mnt_userns, + const struct path *path, struct kstat *stat, u32 request_mask, unsigned int flags); extern int fat_file_fsync(struct file *file, loff_t start, loff_t end, int datasync); diff --git a/fs/fat/file.c b/fs/fat/file.c index f7e04f533d31..dd73d1b70c55 100644 --- a/fs/fat/file.c +++ b/fs/fat/file.c @@ -95,7 +95,7 @@ static int fat_ioctl_set_attributes(struct file *file, u32 __user *user_attr) goto out_unlock_inode; /* This MUST be done before doing anything irreversible... */ - err = fat_setattr(file->f_path.dentry, &ia); + err = fat_setattr(file_mnt_user_ns(file), file->f_path.dentry, &ia); if (err) goto out_unlock_inode; @@ -394,8 +394,8 @@ void fat_truncate_blocks(struct inode *inode, loff_t offset) fat_flush_inodes(inode->i_sb, inode, NULL); } -int fat_getattr(const struct path *path, struct kstat *stat, - u32 request_mask, unsigned int flags) +int fat_getattr(struct user_namespace *mnt_userns, const struct path *path, + struct kstat *stat, u32 request_mask, unsigned int flags) { struct inode *inode = d_inode(path->dentry); generic_fillattr(&init_user_ns, inode, stat); @@ -466,7 +466,8 @@ static int fat_allow_set_time(struct msdos_sb_info *sbi, struct inode *inode) /* valid file mode bits */ #define FAT_VALID_MODE (S_IFREG | S_IFDIR | S_IRWXUGO) -int fat_setattr(struct dentry *dentry, struct iattr *attr) +int fat_setattr(struct user_namespace *mnt_userns, struct dentry *dentry, + struct iattr *attr) { struct msdos_sb_info *sbi = MSDOS_SB(dentry->d_sb); struct inode *inode = d_inode(dentry); diff --git a/fs/fat/namei_msdos.c b/fs/fat/namei_msdos.c index 9d062886fbc1..a8f3375d9d10 100644 --- a/fs/fat/namei_msdos.c +++ b/fs/fat/namei_msdos.c @@ -261,8 +261,8 @@ static int msdos_add_entry(struct inode *dir, const unsigned char *name, } /***** Create a file */ -static int msdos_create(struct inode *dir, struct dentry *dentry, umode_t mode, - bool excl) +static int msdos_create(struct user_namespace *mnt_userns, struct inode *dir, + struct dentry *dentry, umode_t mode, bool excl) { struct super_block *sb = dir->i_sb; struct inode *inode = NULL; @@ -339,7 +339,8 @@ out: } /***** Make a directory */ -static int msdos_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode) +static int msdos_mkdir(struct user_namespace *mnt_userns, struct inode *dir, + struct dentry *dentry, umode_t mode) { struct super_block *sb = dir->i_sb; struct fat_slot_info sinfo; @@ -593,7 +594,8 @@ error_inode: } /***** Rename, a wrapper for rename_same_dir & rename_diff_dir */ -static int msdos_rename(struct inode *old_dir, struct dentry *old_dentry, +static int msdos_rename(struct user_namespace *mnt_userns, + struct inode *old_dir, struct dentry *old_dentry, struct inode *new_dir, struct dentry *new_dentry, unsigned int flags) { diff --git a/fs/fat/namei_vfat.c b/fs/fat/namei_vfat.c index 0cdd0fb9f742..23936ecf79a5 100644 --- a/fs/fat/namei_vfat.c +++ b/fs/fat/namei_vfat.c @@ -756,8 +756,8 @@ error: return ERR_PTR(err); } -static int vfat_create(struct inode *dir, struct dentry *dentry, umode_t mode, - bool excl) +static int vfat_create(struct user_namespace *mnt_userns, struct inode *dir, + struct dentry *dentry, umode_t mode, bool excl) { struct super_block *sb = dir->i_sb; struct inode *inode; @@ -846,7 +846,8 @@ out: return err; } -static int vfat_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode) +static int vfat_mkdir(struct user_namespace *mnt_userns, struct inode *dir, + struct dentry *dentry, umode_t mode) { struct super_block *sb = dir->i_sb; struct inode *inode; @@ -892,9 +893,9 @@ out: return err; } -static int vfat_rename(struct inode *old_dir, struct dentry *old_dentry, - struct inode *new_dir, struct dentry *new_dentry, - unsigned int flags) +static int vfat_rename(struct user_namespace *mnt_userns, struct inode *old_dir, + struct dentry *old_dentry, struct inode *new_dir, + struct dentry *new_dentry, unsigned int flags) { struct buffer_head *dotdot_bh; struct msdos_dir_entry *dotdot_de; diff --git a/fs/fuse/acl.c b/fs/fuse/acl.c index f529075a2ce8..e9c0f916349d 100644 --- a/fs/fuse/acl.c +++ b/fs/fuse/acl.c @@ -50,7 +50,8 @@ struct posix_acl *fuse_get_acl(struct inode *inode, int type) return acl; } -int fuse_set_acl(struct inode *inode, struct posix_acl *acl, int type) +int fuse_set_acl(struct user_namespace *mnt_userns, struct inode *inode, + struct posix_acl *acl, int type) { struct fuse_conn *fc = get_fuse_conn(inode); const char *name; diff --git a/fs/fuse/dir.c b/fs/fuse/dir.c index d2e318ed9b26..06a18700a845 100644 --- a/fs/fuse/dir.c +++ b/fs/fuse/dir.c @@ -605,7 +605,8 @@ out_err: return err; } -static int fuse_mknod(struct inode *, struct dentry *, umode_t, dev_t); +static int fuse_mknod(struct user_namespace *, struct inode *, struct dentry *, + umode_t, dev_t); static int fuse_atomic_open(struct inode *dir, struct dentry *entry, struct file *file, unsigned flags, umode_t mode) @@ -645,7 +646,7 @@ out_dput: return err; mknod: - err = fuse_mknod(dir, entry, mode, 0); + err = fuse_mknod(&init_user_ns, dir, entry, mode, 0); if (err) goto out_dput; no_open: @@ -715,8 +716,8 @@ static int create_new_entry(struct fuse_mount *fm, struct fuse_args *args, return err; } -static int fuse_mknod(struct inode *dir, struct dentry *entry, umode_t mode, - dev_t rdev) +static int fuse_mknod(struct user_namespace *mnt_userns, struct inode *dir, + struct dentry *entry, umode_t mode, dev_t rdev) { struct fuse_mknod_in inarg; struct fuse_mount *fm = get_fuse_mount(dir); @@ -738,13 +739,14 @@ static int fuse_mknod(struct inode *dir, struct dentry *entry, umode_t mode, return create_new_entry(fm, &args, dir, entry, mode); } -static int fuse_create(struct inode *dir, struct dentry *entry, umode_t mode, - bool excl) +static int fuse_create(struct user_namespace *mnt_userns, struct inode *dir, + struct dentry *entry, umode_t mode, bool excl) { - return fuse_mknod(dir, entry, mode, 0); + return fuse_mknod(&init_user_ns, dir, entry, mode, 0); } -static int fuse_mkdir(struct inode *dir, struct dentry *entry, umode_t mode) +static int fuse_mkdir(struct user_namespace *mnt_userns, struct inode *dir, + struct dentry *entry, umode_t mode) { struct fuse_mkdir_in inarg; struct fuse_mount *fm = get_fuse_mount(dir); @@ -765,8 +767,8 @@ static int fuse_mkdir(struct inode *dir, struct dentry *entry, umode_t mode) return create_new_entry(fm, &args, dir, entry, S_IFDIR); } -static int fuse_symlink(struct inode *dir, struct dentry *entry, - const char *link) +static int fuse_symlink(struct user_namespace *mnt_userns, struct inode *dir, + struct dentry *entry, const char *link) { struct fuse_mount *fm = get_fuse_mount(dir); unsigned len = strlen(link) + 1; @@ -908,9 +910,9 @@ static int fuse_rename_common(struct inode *olddir, struct dentry *oldent, return err; } -static int fuse_rename2(struct inode *olddir, struct dentry *oldent, - struct inode *newdir, struct dentry *newent, - unsigned int flags) +static int fuse_rename2(struct user_namespace *mnt_userns, struct inode *olddir, + struct dentry *oldent, struct inode *newdir, + struct dentry *newent, unsigned int flags) { struct fuse_conn *fc = get_fuse_conn(olddir); int err; @@ -1249,7 +1251,8 @@ static int fuse_perm_getattr(struct inode *inode, int mask) * access request is sent. Execute permission is still checked * locally based on file mode. */ -static int fuse_permission(struct inode *inode, int mask) +static int fuse_permission(struct user_namespace *mnt_userns, + struct inode *inode, int mask) { struct fuse_conn *fc = get_fuse_conn(inode); bool refreshed = false; @@ -1757,7 +1760,8 @@ error: return err; } -static int fuse_setattr(struct dentry *entry, struct iattr *attr) +static int fuse_setattr(struct user_namespace *mnt_userns, struct dentry *entry, + struct iattr *attr) { struct inode *inode = d_inode(entry); struct fuse_conn *fc = get_fuse_conn(inode); @@ -1819,7 +1823,8 @@ static int fuse_setattr(struct dentry *entry, struct iattr *attr) return ret; } -static int fuse_getattr(const struct path *path, struct kstat *stat, +static int fuse_getattr(struct user_namespace *mnt_userns, + const struct path *path, struct kstat *stat, u32 request_mask, unsigned int flags) { struct inode *inode = d_inode(path->dentry); diff --git a/fs/fuse/fuse_i.h b/fs/fuse/fuse_i.h index 7c4b8cb93f9f..68cca8d4db6e 100644 --- a/fs/fuse/fuse_i.h +++ b/fs/fuse/fuse_i.h @@ -1180,8 +1180,8 @@ extern const struct xattr_handler *fuse_no_acl_xattr_handlers[]; struct posix_acl; struct posix_acl *fuse_get_acl(struct inode *inode, int type); -int fuse_set_acl(struct inode *inode, struct posix_acl *acl, int type); - +int fuse_set_acl(struct user_namespace *mnt_userns, struct inode *inode, + struct posix_acl *acl, int type); /* readdir.c */ int fuse_readdir(struct file *file, struct dir_context *ctx); diff --git a/fs/gfs2/acl.c b/fs/gfs2/acl.c index ce88ef29eef0..9165d70ead07 100644 --- a/fs/gfs2/acl.c +++ b/fs/gfs2/acl.c @@ -106,7 +106,8 @@ out: return error; } -int gfs2_set_acl(struct inode *inode, struct posix_acl *acl, int type) +int gfs2_set_acl(struct user_namespace *mnt_userns, struct inode *inode, + struct posix_acl *acl, int type) { struct gfs2_inode *ip = GFS2_I(inode); struct gfs2_holder gh; diff --git a/fs/gfs2/acl.h b/fs/gfs2/acl.h index 61353a1501c5..eccc6a43326c 100644 --- a/fs/gfs2/acl.h +++ b/fs/gfs2/acl.h @@ -13,6 +13,7 @@ extern struct posix_acl *gfs2_get_acl(struct inode *inode, int type); extern int __gfs2_set_acl(struct inode *inode, struct posix_acl *acl, int type); -extern int gfs2_set_acl(struct inode *inode, struct posix_acl *acl, int type); +extern int gfs2_set_acl(struct user_namespace *mnt_userns, struct inode *inode, + struct posix_acl *acl, int type); #endif /* __ACL_DOT_H__ */ diff --git a/fs/gfs2/file.c b/fs/gfs2/file.c index 1d994bdfffaa..8f5523822788 100644 --- a/fs/gfs2/file.c +++ b/fs/gfs2/file.c @@ -256,7 +256,7 @@ static int do_gfs2_set_flags(struct file *filp, u32 reqflags, u32 mask, !capable(CAP_LINUX_IMMUTABLE)) goto out; if (!IS_IMMUTABLE(inode)) { - error = gfs2_permission(inode, MAY_WRITE); + error = gfs2_permission(&init_user_ns, inode, MAY_WRITE); if (error) goto out; } diff --git a/fs/gfs2/inode.c b/fs/gfs2/inode.c index 226b5b1dc1fa..cfac2c1e67fa 100644 --- a/fs/gfs2/inode.c +++ b/fs/gfs2/inode.c @@ -325,7 +325,7 @@ struct inode *gfs2_lookupi(struct inode *dir, const struct qstr *name, } if (!is_root) { - error = gfs2_permission(dir, MAY_EXEC); + error = gfs2_permission(&init_user_ns, dir, MAY_EXEC); if (error) goto out; } @@ -355,7 +355,8 @@ static int create_ok(struct gfs2_inode *dip, const struct qstr *name, { int error; - error = gfs2_permission(&dip->i_inode, MAY_WRITE | MAY_EXEC); + error = gfs2_permission(&init_user_ns, &dip->i_inode, + MAY_WRITE | MAY_EXEC); if (error) return error; @@ -843,8 +844,8 @@ fail: * Returns: errno */ -static int gfs2_create(struct inode *dir, struct dentry *dentry, - umode_t mode, bool excl) +static int gfs2_create(struct user_namespace *mnt_userns, struct inode *dir, + struct dentry *dentry, umode_t mode, bool excl) { return gfs2_create_inode(dir, dentry, NULL, S_IFREG | mode, 0, NULL, 0, excl); } @@ -951,7 +952,7 @@ static int gfs2_link(struct dentry *old_dentry, struct inode *dir, if (inode->i_nlink == 0) goto out_gunlock; - error = gfs2_permission(dir, MAY_WRITE | MAY_EXEC); + error = gfs2_permission(&init_user_ns, dir, MAY_WRITE | MAY_EXEC); if (error) goto out_gunlock; @@ -1068,7 +1069,8 @@ static int gfs2_unlink_ok(struct gfs2_inode *dip, const struct qstr *name, if (IS_APPEND(&dip->i_inode)) return -EPERM; - error = gfs2_permission(&dip->i_inode, MAY_WRITE | MAY_EXEC); + error = gfs2_permission(&init_user_ns, &dip->i_inode, + MAY_WRITE | MAY_EXEC); if (error) return error; @@ -1204,8 +1206,8 @@ out_inodes: * Returns: errno */ -static int gfs2_symlink(struct inode *dir, struct dentry *dentry, - const char *symname) +static int gfs2_symlink(struct user_namespace *mnt_userns, struct inode *dir, + struct dentry *dentry, const char *symname) { unsigned int size; @@ -1225,7 +1227,8 @@ static int gfs2_symlink(struct inode *dir, struct dentry *dentry, * Returns: errno */ -static int gfs2_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode) +static int gfs2_mkdir(struct user_namespace *mnt_userns, struct inode *dir, + struct dentry *dentry, umode_t mode) { unsigned dsize = gfs2_max_stuffed_size(GFS2_I(dir)); return gfs2_create_inode(dir, dentry, NULL, S_IFDIR | mode, 0, NULL, dsize, 0); @@ -1240,8 +1243,8 @@ static int gfs2_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode) * */ -static int gfs2_mknod(struct inode *dir, struct dentry *dentry, umode_t mode, - dev_t dev) +static int gfs2_mknod(struct user_namespace *mnt_userns, struct inode *dir, + struct dentry *dentry, umode_t mode, dev_t dev) { return gfs2_create_inode(dir, dentry, NULL, mode, dev, NULL, 0, 0); } @@ -1490,7 +1493,8 @@ static int gfs2_rename(struct inode *odir, struct dentry *odentry, } } } else { - error = gfs2_permission(ndir, MAY_WRITE | MAY_EXEC); + error = gfs2_permission(&init_user_ns, ndir, + MAY_WRITE | MAY_EXEC); if (error) goto out_gunlock; @@ -1525,7 +1529,8 @@ static int gfs2_rename(struct inode *odir, struct dentry *odentry, /* Check out the dir to be renamed */ if (dir_rename) { - error = gfs2_permission(d_inode(odentry), MAY_WRITE); + error = gfs2_permission(&init_user_ns, d_inode(odentry), + MAY_WRITE); if (error) goto out_gunlock; } @@ -1688,12 +1693,14 @@ static int gfs2_exchange(struct inode *odir, struct dentry *odentry, goto out_gunlock; if (S_ISDIR(old_mode)) { - error = gfs2_permission(odentry->d_inode, MAY_WRITE); + error = gfs2_permission(&init_user_ns, odentry->d_inode, + MAY_WRITE); if (error) goto out_gunlock; } if (S_ISDIR(new_mode)) { - error = gfs2_permission(ndentry->d_inode, MAY_WRITE); + error = gfs2_permission(&init_user_ns, ndentry->d_inode, + MAY_WRITE); if (error) goto out_gunlock; } @@ -1747,9 +1754,9 @@ out: return error; } -static int gfs2_rename2(struct inode *odir, struct dentry *odentry, - struct inode *ndir, struct dentry *ndentry, - unsigned int flags) +static int gfs2_rename2(struct user_namespace *mnt_userns, struct inode *odir, + struct dentry *odentry, struct inode *ndir, + struct dentry *ndentry, unsigned int flags) { flags &= ~RENAME_NOREPLACE; @@ -1833,7 +1840,8 @@ out: * Returns: errno */ -int gfs2_permission(struct inode *inode, int mask) +int gfs2_permission(struct user_namespace *mnt_userns, struct inode *inode, + int mask) { struct gfs2_inode *ip; struct gfs2_holder i_gh; @@ -1963,7 +1971,8 @@ out: * Returns: errno */ -static int gfs2_setattr(struct dentry *dentry, struct iattr *attr) +static int gfs2_setattr(struct user_namespace *mnt_userns, + struct dentry *dentry, struct iattr *attr) { struct inode *inode = d_inode(dentry); struct gfs2_inode *ip = GFS2_I(inode); @@ -2008,6 +2017,7 @@ out: /** * gfs2_getattr - Read out an inode's attributes + * @mnt_userns: user namespace of the mount the inode was found from * @path: Object to query * @stat: The inode's stats * @request_mask: Mask of STATX_xxx flags indicating the caller's interests @@ -2022,7 +2032,8 @@ out: * Returns: errno */ -static int gfs2_getattr(const struct path *path, struct kstat *stat, +static int gfs2_getattr(struct user_namespace *mnt_userns, + const struct path *path, struct kstat *stat, u32 request_mask, unsigned int flags) { struct inode *inode = d_inode(path->dentry); diff --git a/fs/gfs2/inode.h b/fs/gfs2/inode.h index 8073b8d2c7fa..c447bd5b3017 100644 --- a/fs/gfs2/inode.h +++ b/fs/gfs2/inode.h @@ -99,7 +99,8 @@ extern int gfs2_inode_refresh(struct gfs2_inode *ip); extern struct inode *gfs2_lookupi(struct inode *dir, const struct qstr *name, int is_root); -extern int gfs2_permission(struct inode *inode, int mask); +extern int gfs2_permission(struct user_namespace *mnt_userns, + struct inode *inode, int mask); extern int gfs2_setattr_simple(struct inode *inode, struct iattr *attr); extern struct inode *gfs2_lookup_simple(struct inode *dip, const char *name); extern void gfs2_dinode_out(const struct gfs2_inode *ip, void *buf); diff --git a/fs/hfs/dir.c b/fs/hfs/dir.c index 3bf2ae0e467c..527f6e46cbe8 100644 --- a/fs/hfs/dir.c +++ b/fs/hfs/dir.c @@ -189,8 +189,8 @@ static int hfs_dir_release(struct inode *inode, struct file *file) * a directory and return a corresponding inode, given the inode for * the directory and the name (and its length) of the new file. */ -static int hfs_create(struct inode *dir, struct dentry *dentry, umode_t mode, - bool excl) +static int hfs_create(struct user_namespace *mnt_userns, struct inode *dir, + struct dentry *dentry, umode_t mode, bool excl) { struct inode *inode; int res; @@ -219,7 +219,8 @@ static int hfs_create(struct inode *dir, struct dentry *dentry, umode_t mode, * in a directory, given the inode for the parent directory and the * name (and its length) of the new directory. */ -static int hfs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode) +static int hfs_mkdir(struct user_namespace *mnt_userns, struct inode *dir, + struct dentry *dentry, umode_t mode) { struct inode *inode; int res; @@ -279,9 +280,9 @@ static int hfs_remove(struct inode *dir, struct dentry *dentry) * new file/directory. * XXX: how do you handle must_be dir? */ -static int hfs_rename(struct inode *old_dir, struct dentry *old_dentry, - struct inode *new_dir, struct dentry *new_dentry, - unsigned int flags) +static int hfs_rename(struct user_namespace *mnt_userns, struct inode *old_dir, + struct dentry *old_dentry, struct inode *new_dir, + struct dentry *new_dentry, unsigned int flags) { int res; diff --git a/fs/hfs/hfs_fs.h b/fs/hfs/hfs_fs.h index f71c384064c8..b8eb0322a3e5 100644 --- a/fs/hfs/hfs_fs.h +++ b/fs/hfs/hfs_fs.h @@ -204,7 +204,8 @@ extern const struct address_space_operations hfs_btree_aops; extern struct inode *hfs_new_inode(struct inode *, const struct qstr *, umode_t); extern void hfs_inode_write_fork(struct inode *, struct hfs_extent *, __be32 *, __be32 *); extern int hfs_write_inode(struct inode *, struct writeback_control *); -extern int hfs_inode_setattr(struct dentry *, struct iattr *); +extern int hfs_inode_setattr(struct user_namespace *, struct dentry *, + struct iattr *); extern void hfs_inode_read_fork(struct inode *inode, struct hfs_extent *ext, __be32 log_size, __be32 phys_size, u32 clump_size); extern struct inode *hfs_iget(struct super_block *, struct hfs_cat_key *, hfs_cat_rec *); diff --git a/fs/hfs/inode.c b/fs/hfs/inode.c index c646218b72bf..3fc5cb346586 100644 --- a/fs/hfs/inode.c +++ b/fs/hfs/inode.c @@ -602,13 +602,15 @@ static int hfs_file_release(struct inode *inode, struct file *file) * correspond to the same HFS file. */ -int hfs_inode_setattr(struct dentry *dentry, struct iattr * attr) +int hfs_inode_setattr(struct user_namespace *mnt_userns, struct dentry *dentry, + struct iattr *attr) { struct inode *inode = d_inode(dentry); struct hfs_sb_info *hsb = HFS_SB(inode->i_sb); int error; - error = setattr_prepare(&init_user_ns, dentry, attr); /* basic permission checks */ + error = setattr_prepare(&init_user_ns, dentry, + attr); /* basic permission checks */ if (error) return error; diff --git a/fs/hfsplus/dir.c b/fs/hfsplus/dir.c index 29a9dcfbe81f..03e6c046faf4 100644 --- a/fs/hfsplus/dir.c +++ b/fs/hfsplus/dir.c @@ -434,8 +434,8 @@ out: return res; } -static int hfsplus_symlink(struct inode *dir, struct dentry *dentry, - const char *symname) +static int hfsplus_symlink(struct user_namespace *mnt_userns, struct inode *dir, + struct dentry *dentry, const char *symname) { struct hfsplus_sb_info *sbi = HFSPLUS_SB(dir->i_sb); struct inode *inode; @@ -476,8 +476,8 @@ out: return res; } -static int hfsplus_mknod(struct inode *dir, struct dentry *dentry, - umode_t mode, dev_t rdev) +static int hfsplus_mknod(struct user_namespace *mnt_userns, struct inode *dir, + struct dentry *dentry, umode_t mode, dev_t rdev) { struct hfsplus_sb_info *sbi = HFSPLUS_SB(dir->i_sb); struct inode *inode; @@ -517,18 +517,20 @@ out: return res; } -static int hfsplus_create(struct inode *dir, struct dentry *dentry, umode_t mode, - bool excl) +static int hfsplus_create(struct user_namespace *mnt_userns, struct inode *dir, + struct dentry *dentry, umode_t mode, bool excl) { - return hfsplus_mknod(dir, dentry, mode, 0); + return hfsplus_mknod(&init_user_ns, dir, dentry, mode, 0); } -static int hfsplus_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode) +static int hfsplus_mkdir(struct user_namespace *mnt_userns, struct inode *dir, + struct dentry *dentry, umode_t mode) { - return hfsplus_mknod(dir, dentry, mode | S_IFDIR, 0); + return hfsplus_mknod(&init_user_ns, dir, dentry, mode | S_IFDIR, 0); } -static int hfsplus_rename(struct inode *old_dir, struct dentry *old_dentry, +static int hfsplus_rename(struct user_namespace *mnt_userns, + struct inode *old_dir, struct dentry *old_dentry, struct inode *new_dir, struct dentry *new_dentry, unsigned int flags) { diff --git a/fs/hfsplus/hfsplus_fs.h b/fs/hfsplus/hfsplus_fs.h index a92de5199ec3..12b20479ed2b 100644 --- a/fs/hfsplus/hfsplus_fs.h +++ b/fs/hfsplus/hfsplus_fs.h @@ -488,8 +488,9 @@ void hfsplus_inode_write_fork(struct inode *inode, struct hfsplus_fork_raw *fork); int hfsplus_cat_read_inode(struct inode *inode, struct hfs_find_data *fd); int hfsplus_cat_write_inode(struct inode *inode); -int hfsplus_getattr(const struct path *path, struct kstat *stat, - u32 request_mask, unsigned int query_flags); +int hfsplus_getattr(struct user_namespace *mnt_userns, const struct path *path, + struct kstat *stat, u32 request_mask, + unsigned int query_flags); int hfsplus_file_fsync(struct file *file, loff_t start, loff_t end, int datasync); diff --git a/fs/hfsplus/inode.c b/fs/hfsplus/inode.c index 642e067d8fe8..7a937de9b2ad 100644 --- a/fs/hfsplus/inode.c +++ b/fs/hfsplus/inode.c @@ -241,7 +241,8 @@ static int hfsplus_file_release(struct inode *inode, struct file *file) return 0; } -static int hfsplus_setattr(struct dentry *dentry, struct iattr *attr) +static int hfsplus_setattr(struct user_namespace *mnt_userns, + struct dentry *dentry, struct iattr *attr) { struct inode *inode = d_inode(dentry); int error; @@ -270,8 +271,9 @@ static int hfsplus_setattr(struct dentry *dentry, struct iattr *attr) return 0; } -int hfsplus_getattr(const struct path *path, struct kstat *stat, - u32 request_mask, unsigned int query_flags) +int hfsplus_getattr(struct user_namespace *mnt_userns, const struct path *path, + struct kstat *stat, u32 request_mask, + unsigned int query_flags) { struct inode *inode = d_inode(path->dentry); struct hfsplus_inode_info *hip = HFSPLUS_I(inode); diff --git a/fs/hostfs/hostfs_kern.c b/fs/hostfs/hostfs_kern.c index 6970e29a5287..7c918cd816a3 100644 --- a/fs/hostfs/hostfs_kern.c +++ b/fs/hostfs/hostfs_kern.c @@ -555,8 +555,8 @@ static int read_name(struct inode *ino, char *name) return 0; } -static int hostfs_create(struct inode *dir, struct dentry *dentry, umode_t mode, - bool excl) +static int hostfs_create(struct user_namespace *mnt_userns, struct inode *dir, + struct dentry *dentry, umode_t mode, bool excl) { struct inode *inode; char *name; @@ -654,8 +654,8 @@ static int hostfs_unlink(struct inode *ino, struct dentry *dentry) return err; } -static int hostfs_symlink(struct inode *ino, struct dentry *dentry, - const char *to) +static int hostfs_symlink(struct user_namespace *mnt_userns, struct inode *ino, + struct dentry *dentry, const char *to) { char *file; int err; @@ -667,7 +667,8 @@ static int hostfs_symlink(struct inode *ino, struct dentry *dentry, return err; } -static int hostfs_mkdir(struct inode *ino, struct dentry *dentry, umode_t mode) +static int hostfs_mkdir(struct user_namespace *mnt_userns, struct inode *ino, + struct dentry *dentry, umode_t mode) { char *file; int err; @@ -691,7 +692,8 @@ static int hostfs_rmdir(struct inode *ino, struct dentry *dentry) return err; } -static int hostfs_mknod(struct inode *dir, struct dentry *dentry, umode_t mode, dev_t dev) +static int hostfs_mknod(struct user_namespace *mnt_userns, struct inode *dir, + struct dentry *dentry, umode_t mode, dev_t dev) { struct inode *inode; char *name; @@ -729,7 +731,8 @@ static int hostfs_mknod(struct inode *dir, struct dentry *dentry, umode_t mode, return err; } -static int hostfs_rename2(struct inode *old_dir, struct dentry *old_dentry, +static int hostfs_rename2(struct user_namespace *mnt_userns, + struct inode *old_dir, struct dentry *old_dentry, struct inode *new_dir, struct dentry *new_dentry, unsigned int flags) { @@ -757,7 +760,8 @@ static int hostfs_rename2(struct inode *old_dir, struct dentry *old_dentry, return err; } -static int hostfs_permission(struct inode *ino, int desired) +static int hostfs_permission(struct user_namespace *mnt_userns, + struct inode *ino, int desired) { char *name; int r = 0, w = 0, x = 0, err; @@ -783,7 +787,8 @@ static int hostfs_permission(struct inode *ino, int desired) return err; } -static int hostfs_setattr(struct dentry *dentry, struct iattr *attr) +static int hostfs_setattr(struct user_namespace *mnt_userns, + struct dentry *dentry, struct iattr *attr) { struct inode *inode = d_inode(dentry); struct hostfs_iattr attrs; diff --git a/fs/hpfs/hpfs_fn.h b/fs/hpfs/hpfs_fn.h index 1cca83218fb5..167ec6884642 100644 --- a/fs/hpfs/hpfs_fn.h +++ b/fs/hpfs/hpfs_fn.h @@ -280,7 +280,7 @@ void hpfs_init_inode(struct inode *); void hpfs_read_inode(struct inode *); void hpfs_write_inode(struct inode *); void hpfs_write_inode_nolock(struct inode *); -int hpfs_setattr(struct dentry *, struct iattr *); +int hpfs_setattr(struct user_namespace *, struct dentry *, struct iattr *); void hpfs_write_if_changed(struct inode *); void hpfs_evict_inode(struct inode *); diff --git a/fs/hpfs/inode.c b/fs/hpfs/inode.c index 8ba2152a78ba..82208cc28ebd 100644 --- a/fs/hpfs/inode.c +++ b/fs/hpfs/inode.c @@ -257,7 +257,8 @@ void hpfs_write_inode_nolock(struct inode *i) brelse(bh); } -int hpfs_setattr(struct dentry *dentry, struct iattr *attr) +int hpfs_setattr(struct user_namespace *mnt_userns, struct dentry *dentry, + struct iattr *attr) { struct inode *inode = d_inode(dentry); int error = -EINVAL; diff --git a/fs/hpfs/namei.c b/fs/hpfs/namei.c index 1aee39160ac5..d73f8a67168e 100644 --- a/fs/hpfs/namei.c +++ b/fs/hpfs/namei.c @@ -20,7 +20,8 @@ static void hpfs_update_directory_times(struct inode *dir) hpfs_write_inode_nolock(dir); } -static int hpfs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode) +static int hpfs_mkdir(struct user_namespace *mnt_userns, struct inode *dir, + struct dentry *dentry, umode_t mode) { const unsigned char *name = dentry->d_name.name; unsigned len = dentry->d_name.len; @@ -128,7 +129,8 @@ bail: return err; } -static int hpfs_create(struct inode *dir, struct dentry *dentry, umode_t mode, bool excl) +static int hpfs_create(struct user_namespace *mnt_userns, struct inode *dir, + struct dentry *dentry, umode_t mode, bool excl) { const unsigned char *name = dentry->d_name.name; unsigned len = dentry->d_name.len; @@ -215,7 +217,8 @@ bail: return err; } -static int hpfs_mknod(struct inode *dir, struct dentry *dentry, umode_t mode, dev_t rdev) +static int hpfs_mknod(struct user_namespace *mnt_userns, struct inode *dir, + struct dentry *dentry, umode_t mode, dev_t rdev) { const unsigned char *name = dentry->d_name.name; unsigned len = dentry->d_name.len; @@ -289,7 +292,8 @@ bail: return err; } -static int hpfs_symlink(struct inode *dir, struct dentry *dentry, const char *symlink) +static int hpfs_symlink(struct user_namespace *mnt_userns, struct inode *dir, + struct dentry *dentry, const char *symlink) { const unsigned char *name = dentry->d_name.name; unsigned len = dentry->d_name.len; @@ -506,10 +510,10 @@ fail: const struct address_space_operations hpfs_symlink_aops = { .readpage = hpfs_symlink_readpage }; - -static int hpfs_rename(struct inode *old_dir, struct dentry *old_dentry, - struct inode *new_dir, struct dentry *new_dentry, - unsigned int flags) + +static int hpfs_rename(struct user_namespace *mnt_userns, struct inode *old_dir, + struct dentry *old_dentry, struct inode *new_dir, + struct dentry *new_dentry, unsigned int flags) { const unsigned char *old_name = old_dentry->d_name.name; unsigned old_len = old_dentry->d_name.len; diff --git a/fs/hugetlbfs/inode.c b/fs/hugetlbfs/inode.c index 327e572b4e00..c5c32eb59498 100644 --- a/fs/hugetlbfs/inode.c +++ b/fs/hugetlbfs/inode.c @@ -751,7 +751,8 @@ out: return error; } -static int hugetlbfs_setattr(struct dentry *dentry, struct iattr *attr) +static int hugetlbfs_setattr(struct user_namespace *mnt_userns, + struct dentry *dentry, struct iattr *attr) { struct inode *inode = d_inode(dentry); struct hstate *h = hstate_inode(inode); @@ -898,33 +899,39 @@ static int do_hugetlbfs_mknod(struct inode *dir, return error; } -static int hugetlbfs_mknod(struct inode *dir, - struct dentry *dentry, umode_t mode, dev_t dev) +static int hugetlbfs_mknod(struct user_namespace *mnt_userns, struct inode *dir, + struct dentry *dentry, umode_t mode, dev_t dev) { return do_hugetlbfs_mknod(dir, dentry, mode, dev, false); } -static int hugetlbfs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode) +static int hugetlbfs_mkdir(struct user_namespace *mnt_userns, struct inode *dir, + struct dentry *dentry, umode_t mode) { - int retval = hugetlbfs_mknod(dir, dentry, mode | S_IFDIR, 0); + int retval = hugetlbfs_mknod(&init_user_ns, dir, dentry, + mode | S_IFDIR, 0); if (!retval) inc_nlink(dir); return retval; } -static int hugetlbfs_create(struct inode *dir, struct dentry *dentry, umode_t mode, bool excl) +static int hugetlbfs_create(struct user_namespace *mnt_userns, + struct inode *dir, struct dentry *dentry, + umode_t mode, bool excl) { - return hugetlbfs_mknod(dir, dentry, mode | S_IFREG, 0); + return hugetlbfs_mknod(&init_user_ns, dir, dentry, mode | S_IFREG, 0); } -static int hugetlbfs_tmpfile(struct inode *dir, - struct dentry *dentry, umode_t mode) +static int hugetlbfs_tmpfile(struct user_namespace *mnt_userns, + struct inode *dir, struct dentry *dentry, + umode_t mode) { return do_hugetlbfs_mknod(dir, dentry, mode | S_IFREG, 0, true); } -static int hugetlbfs_symlink(struct inode *dir, - struct dentry *dentry, const char *symname) +static int hugetlbfs_symlink(struct user_namespace *mnt_userns, + struct inode *dir, struct dentry *dentry, + const char *symname) { struct inode *inode; int error = -ENOSPC; diff --git a/fs/jffs2/acl.c b/fs/jffs2/acl.c index 5f27ac593479..55a79df70d24 100644 --- a/fs/jffs2/acl.c +++ b/fs/jffs2/acl.c @@ -226,7 +226,8 @@ static int __jffs2_set_acl(struct inode *inode, int xprefix, struct posix_acl *a return rc; } -int jffs2_set_acl(struct inode *inode, struct posix_acl *acl, int type) +int jffs2_set_acl(struct user_namespace *mnt_userns, struct inode *inode, + struct posix_acl *acl, int type) { int rc, xprefix; diff --git a/fs/jffs2/acl.h b/fs/jffs2/acl.h index 12d0271bdde3..62c50da9d493 100644 --- a/fs/jffs2/acl.h +++ b/fs/jffs2/acl.h @@ -28,7 +28,8 @@ struct jffs2_acl_header { #ifdef CONFIG_JFFS2_FS_POSIX_ACL struct posix_acl *jffs2_get_acl(struct inode *inode, int type); -int jffs2_set_acl(struct inode *inode, struct posix_acl *acl, int type); +int jffs2_set_acl(struct user_namespace *mnt_userns, struct inode *inode, + struct posix_acl *acl, int type); extern int jffs2_init_acl_pre(struct inode *, struct inode *, umode_t *); extern int jffs2_init_acl_post(struct inode *); diff --git a/fs/jffs2/dir.c b/fs/jffs2/dir.c index 776493713153..c0aabbcbfd58 100644 --- a/fs/jffs2/dir.c +++ b/fs/jffs2/dir.c @@ -24,18 +24,21 @@ static int jffs2_readdir (struct file *, struct dir_context *); -static int jffs2_create (struct inode *,struct dentry *,umode_t, - bool); +static int jffs2_create (struct user_namespace *, struct inode *, + struct dentry *, umode_t, bool); static struct dentry *jffs2_lookup (struct inode *,struct dentry *, unsigned int); static int jffs2_link (struct dentry *,struct inode *,struct dentry *); static int jffs2_unlink (struct inode *,struct dentry *); -static int jffs2_symlink (struct inode *,struct dentry *,const char *); -static int jffs2_mkdir (struct inode *,struct dentry *,umode_t); +static int jffs2_symlink (struct user_namespace *, struct inode *, + struct dentry *, const char *); +static int jffs2_mkdir (struct user_namespace *, struct inode *,struct dentry *, + umode_t); static int jffs2_rmdir (struct inode *,struct dentry *); -static int jffs2_mknod (struct inode *,struct dentry *,umode_t,dev_t); -static int jffs2_rename (struct inode *, struct dentry *, - struct inode *, struct dentry *, +static int jffs2_mknod (struct user_namespace *, struct inode *,struct dentry *, + umode_t,dev_t); +static int jffs2_rename (struct user_namespace *, struct inode *, + struct dentry *, struct inode *, struct dentry *, unsigned int); const struct file_operations jffs2_dir_operations = @@ -157,8 +160,8 @@ static int jffs2_readdir(struct file *file, struct dir_context *ctx) /***********************************************************************/ -static int jffs2_create(struct inode *dir_i, struct dentry *dentry, - umode_t mode, bool excl) +static int jffs2_create(struct user_namespace *mnt_userns, struct inode *dir_i, + struct dentry *dentry, umode_t mode, bool excl) { struct jffs2_raw_inode *ri; struct jffs2_inode_info *f, *dir_f; @@ -276,7 +279,8 @@ static int jffs2_link (struct dentry *old_dentry, struct inode *dir_i, struct de /***********************************************************************/ -static int jffs2_symlink (struct inode *dir_i, struct dentry *dentry, const char *target) +static int jffs2_symlink (struct user_namespace *mnt_userns, struct inode *dir_i, + struct dentry *dentry, const char *target) { struct jffs2_inode_info *f, *dir_f; struct jffs2_sb_info *c; @@ -438,7 +442,8 @@ static int jffs2_symlink (struct inode *dir_i, struct dentry *dentry, const char } -static int jffs2_mkdir (struct inode *dir_i, struct dentry *dentry, umode_t mode) +static int jffs2_mkdir (struct user_namespace *mnt_userns, struct inode *dir_i, + struct dentry *dentry, umode_t mode) { struct jffs2_inode_info *f, *dir_f; struct jffs2_sb_info *c; @@ -609,7 +614,8 @@ static int jffs2_rmdir (struct inode *dir_i, struct dentry *dentry) return ret; } -static int jffs2_mknod (struct inode *dir_i, struct dentry *dentry, umode_t mode, dev_t rdev) +static int jffs2_mknod (struct user_namespace *mnt_userns, struct inode *dir_i, + struct dentry *dentry, umode_t mode, dev_t rdev) { struct jffs2_inode_info *f, *dir_f; struct jffs2_sb_info *c; @@ -756,7 +762,8 @@ static int jffs2_mknod (struct inode *dir_i, struct dentry *dentry, umode_t mode return ret; } -static int jffs2_rename (struct inode *old_dir_i, struct dentry *old_dentry, +static int jffs2_rename (struct user_namespace *mnt_userns, + struct inode *old_dir_i, struct dentry *old_dentry, struct inode *new_dir_i, struct dentry *new_dentry, unsigned int flags) { diff --git a/fs/jffs2/fs.c b/fs/jffs2/fs.c index ee9f51bab4c6..2ac410477c4f 100644 --- a/fs/jffs2/fs.c +++ b/fs/jffs2/fs.c @@ -190,7 +190,8 @@ int jffs2_do_setattr (struct inode *inode, struct iattr *iattr) return 0; } -int jffs2_setattr(struct dentry *dentry, struct iattr *iattr) +int jffs2_setattr(struct user_namespace *mnt_userns, struct dentry *dentry, + struct iattr *iattr) { struct inode *inode = d_inode(dentry); int rc; diff --git a/fs/jffs2/os-linux.h b/fs/jffs2/os-linux.h index ef1cfa61549e..173eccac691d 100644 --- a/fs/jffs2/os-linux.h +++ b/fs/jffs2/os-linux.h @@ -164,7 +164,7 @@ long jffs2_ioctl(struct file *, unsigned int, unsigned long); extern const struct inode_operations jffs2_symlink_inode_operations; /* fs.c */ -int jffs2_setattr (struct dentry *, struct iattr *); +int jffs2_setattr (struct user_namespace *, struct dentry *, struct iattr *); int jffs2_do_setattr (struct inode *, struct iattr *); struct inode *jffs2_iget(struct super_block *, unsigned long); void jffs2_evict_inode (struct inode *); diff --git a/fs/jfs/acl.c b/fs/jfs/acl.c index cf79a34bfada..43c285c3d2a7 100644 --- a/fs/jfs/acl.c +++ b/fs/jfs/acl.c @@ -91,7 +91,8 @@ out: return rc; } -int jfs_set_acl(struct inode *inode, struct posix_acl *acl, int type) +int jfs_set_acl(struct user_namespace *mnt_userns, struct inode *inode, + struct posix_acl *acl, int type) { int rc; tid_t tid; diff --git a/fs/jfs/file.c b/fs/jfs/file.c index 61c3b0c1fbf6..28b70e7c7dd4 100644 --- a/fs/jfs/file.c +++ b/fs/jfs/file.c @@ -85,7 +85,8 @@ static int jfs_release(struct inode *inode, struct file *file) return 0; } -int jfs_setattr(struct dentry *dentry, struct iattr *iattr) +int jfs_setattr(struct user_namespace *mnt_userns, struct dentry *dentry, + struct iattr *iattr) { struct inode *inode = d_inode(dentry); int rc; diff --git a/fs/jfs/jfs_acl.h b/fs/jfs/jfs_acl.h index 9f8f92dd6f84..7ae389a7a366 100644 --- a/fs/jfs/jfs_acl.h +++ b/fs/jfs/jfs_acl.h @@ -8,7 +8,8 @@ #ifdef CONFIG_JFS_POSIX_ACL struct posix_acl *jfs_get_acl(struct inode *inode, int type); -int jfs_set_acl(struct inode *inode, struct posix_acl *acl, int type); +int jfs_set_acl(struct user_namespace *mnt_userns, struct inode *inode, + struct posix_acl *acl, int type); int jfs_init_acl(tid_t, struct inode *, struct inode *); #else diff --git a/fs/jfs/jfs_inode.h b/fs/jfs/jfs_inode.h index 70a0d12e427e..01daa0cb0ae5 100644 --- a/fs/jfs/jfs_inode.h +++ b/fs/jfs/jfs_inode.h @@ -26,7 +26,7 @@ extern struct dentry *jfs_fh_to_parent(struct super_block *sb, struct fid *fid, int fh_len, int fh_type); extern void jfs_set_inode_flags(struct inode *); extern int jfs_get_block(struct inode *, sector_t, struct buffer_head *, int); -extern int jfs_setattr(struct dentry *, struct iattr *); +extern int jfs_setattr(struct user_namespace *, struct dentry *, struct iattr *); extern const struct address_space_operations jfs_aops; extern const struct inode_operations jfs_dir_inode_operations; diff --git a/fs/jfs/namei.c b/fs/jfs/namei.c index 7a55d14cc1af..9abed0d750e5 100644 --- a/fs/jfs/namei.c +++ b/fs/jfs/namei.c @@ -59,8 +59,8 @@ static inline void free_ea_wmap(struct inode *inode) * RETURN: Errors from subroutines * */ -static int jfs_create(struct inode *dip, struct dentry *dentry, umode_t mode, - bool excl) +static int jfs_create(struct user_namespace *mnt_userns, struct inode *dip, + struct dentry *dentry, umode_t mode, bool excl) { int rc = 0; tid_t tid; /* transaction id */ @@ -192,7 +192,8 @@ static int jfs_create(struct inode *dip, struct dentry *dentry, umode_t mode, * note: * EACCES: user needs search+write permission on the parent directory */ -static int jfs_mkdir(struct inode *dip, struct dentry *dentry, umode_t mode) +static int jfs_mkdir(struct user_namespace *mnt_userns, struct inode *dip, + struct dentry *dentry, umode_t mode) { int rc = 0; tid_t tid; /* transaction id */ @@ -868,8 +869,8 @@ static int jfs_link(struct dentry *old_dentry, * an intermediate result whose length exceeds PATH_MAX [XPG4.2] */ -static int jfs_symlink(struct inode *dip, struct dentry *dentry, - const char *name) +static int jfs_symlink(struct user_namespace *mnt_userns, struct inode *dip, + struct dentry *dentry, const char *name) { int rc; tid_t tid; @@ -1058,9 +1059,9 @@ static int jfs_symlink(struct inode *dip, struct dentry *dentry, * * FUNCTION: rename a file or directory */ -static int jfs_rename(struct inode *old_dir, struct dentry *old_dentry, - struct inode *new_dir, struct dentry *new_dentry, - unsigned int flags) +static int jfs_rename(struct user_namespace *mnt_userns, struct inode *old_dir, + struct dentry *old_dentry, struct inode *new_dir, + struct dentry *new_dentry, unsigned int flags) { struct btstack btstack; ino_t ino; @@ -1344,8 +1345,8 @@ static int jfs_rename(struct inode *old_dir, struct dentry *old_dentry, * * FUNCTION: Create a special file (device) */ -static int jfs_mknod(struct inode *dir, struct dentry *dentry, - umode_t mode, dev_t rdev) +static int jfs_mknod(struct user_namespace *mnt_userns, struct inode *dir, + struct dentry *dentry, umode_t mode, dev_t rdev) { struct jfs_inode_info *jfs_ip; struct btstack btstack; diff --git a/fs/kernfs/dir.c b/fs/kernfs/dir.c index 7a53eed69fef..7e0e62deab53 100644 --- a/fs/kernfs/dir.c +++ b/fs/kernfs/dir.c @@ -1110,7 +1110,8 @@ static struct dentry *kernfs_iop_lookup(struct inode *dir, return ret; } -static int kernfs_iop_mkdir(struct inode *dir, struct dentry *dentry, +static int kernfs_iop_mkdir(struct user_namespace *mnt_userns, + struct inode *dir, struct dentry *dentry, umode_t mode) { struct kernfs_node *parent = dir->i_private; @@ -1147,7 +1148,8 @@ static int kernfs_iop_rmdir(struct inode *dir, struct dentry *dentry) return ret; } -static int kernfs_iop_rename(struct inode *old_dir, struct dentry *old_dentry, +static int kernfs_iop_rename(struct user_namespace *mnt_userns, + struct inode *old_dir, struct dentry *old_dentry, struct inode *new_dir, struct dentry *new_dentry, unsigned int flags) { diff --git a/fs/kernfs/inode.c b/fs/kernfs/inode.c index 032d3d7546d8..d73950fc3d57 100644 --- a/fs/kernfs/inode.c +++ b/fs/kernfs/inode.c @@ -112,7 +112,8 @@ int kernfs_setattr(struct kernfs_node *kn, const struct iattr *iattr) return ret; } -int kernfs_iop_setattr(struct dentry *dentry, struct iattr *iattr) +int kernfs_iop_setattr(struct user_namespace *mnt_userns, struct dentry *dentry, + struct iattr *iattr) { struct inode *inode = d_inode(dentry); struct kernfs_node *kn = inode->i_private; @@ -183,7 +184,8 @@ static void kernfs_refresh_inode(struct kernfs_node *kn, struct inode *inode) set_nlink(inode, kn->dir.subdirs + 2); } -int kernfs_iop_getattr(const struct path *path, struct kstat *stat, +int kernfs_iop_getattr(struct user_namespace *mnt_userns, + const struct path *path, struct kstat *stat, u32 request_mask, unsigned int query_flags) { struct inode *inode = d_inode(path->dentry); @@ -272,7 +274,8 @@ void kernfs_evict_inode(struct inode *inode) kernfs_put(kn); } -int kernfs_iop_permission(struct inode *inode, int mask) +int kernfs_iop_permission(struct user_namespace *mnt_userns, + struct inode *inode, int mask) { struct kernfs_node *kn; diff --git a/fs/kernfs/kernfs-internal.h b/fs/kernfs/kernfs-internal.h index 7ee97ef59184..ccc3b44f6306 100644 --- a/fs/kernfs/kernfs-internal.h +++ b/fs/kernfs/kernfs-internal.h @@ -89,9 +89,12 @@ extern struct kmem_cache *kernfs_node_cache, *kernfs_iattrs_cache; */ extern const struct xattr_handler *kernfs_xattr_handlers[]; void kernfs_evict_inode(struct inode *inode); -int kernfs_iop_permission(struct inode *inode, int mask); -int kernfs_iop_setattr(struct dentry *dentry, struct iattr *iattr); -int kernfs_iop_getattr(const struct path *path, struct kstat *stat, +int kernfs_iop_permission(struct user_namespace *mnt_userns, + struct inode *inode, int mask); +int kernfs_iop_setattr(struct user_namespace *mnt_userns, struct dentry *dentry, + struct iattr *iattr); +int kernfs_iop_getattr(struct user_namespace *mnt_userns, + const struct path *path, struct kstat *stat, u32 request_mask, unsigned int query_flags); ssize_t kernfs_iop_listxattr(struct dentry *dentry, char *buf, size_t size); int __kernfs_setattr(struct kernfs_node *kn, const struct iattr *iattr); diff --git a/fs/libfs.c b/fs/libfs.c index 508e9ea8e6f3..967aefda6ee3 100644 --- a/fs/libfs.c +++ b/fs/libfs.c @@ -27,8 +27,9 @@ #include "internal.h" -int simple_getattr(const struct path *path, struct kstat *stat, - u32 request_mask, unsigned int query_flags) +int simple_getattr(struct user_namespace *mnt_userns, const struct path *path, + struct kstat *stat, u32 request_mask, + unsigned int query_flags) { struct inode *inode = d_inode(path->dentry); generic_fillattr(&init_user_ns, inode, stat); @@ -447,9 +448,9 @@ int simple_rmdir(struct inode *dir, struct dentry *dentry) } EXPORT_SYMBOL(simple_rmdir); -int simple_rename(struct inode *old_dir, struct dentry *old_dentry, - struct inode *new_dir, struct dentry *new_dentry, - unsigned int flags) +int simple_rename(struct user_namespace *mnt_userns, struct inode *old_dir, + struct dentry *old_dentry, struct inode *new_dir, + struct dentry *new_dentry, unsigned int flags) { struct inode *inode = d_inode(old_dentry); int they_are_dirs = d_is_dir(old_dentry); @@ -492,18 +493,19 @@ EXPORT_SYMBOL(simple_rename); * on simple regular filesystems. Anything that needs to change on-disk * or wire state on size changes needs its own setattr method. */ -int simple_setattr(struct dentry *dentry, struct iattr *iattr) +int simple_setattr(struct user_namespace *mnt_userns, struct dentry *dentry, + struct iattr *iattr) { struct inode *inode = d_inode(dentry); int error; - error = setattr_prepare(&init_user_ns, dentry, iattr); + error = setattr_prepare(mnt_userns, dentry, iattr); if (error) return error; if (iattr->ia_valid & ATTR_SIZE) truncate_setsize(inode, iattr->ia_size); - setattr_copy(&init_user_ns, inode, iattr); + setattr_copy(mnt_userns, inode, iattr); mark_inode_dirty(inode); return 0; } @@ -1300,7 +1302,8 @@ static struct dentry *empty_dir_lookup(struct inode *dir, struct dentry *dentry, return ERR_PTR(-ENOENT); } -static int empty_dir_getattr(const struct path *path, struct kstat *stat, +static int empty_dir_getattr(struct user_namespace *mnt_userns, + const struct path *path, struct kstat *stat, u32 request_mask, unsigned int query_flags) { struct inode *inode = d_inode(path->dentry); @@ -1308,7 +1311,8 @@ static int empty_dir_getattr(const struct path *path, struct kstat *stat, return 0; } -static int empty_dir_setattr(struct dentry *dentry, struct iattr *attr) +static int empty_dir_setattr(struct user_namespace *mnt_userns, + struct dentry *dentry, struct iattr *attr) { return -EPERM; } @@ -1318,14 +1322,9 @@ static ssize_t empty_dir_listxattr(struct dentry *dentry, char *list, size_t siz return -EOPNOTSUPP; } -static int empty_dir_permission(struct inode *inode, int mask) -{ - return generic_permission(&init_user_ns, inode, mask); -} - static const struct inode_operations empty_dir_inode_operations = { .lookup = empty_dir_lookup, - .permission = empty_dir_permission, + .permission = generic_permission, .setattr = empty_dir_setattr, .getattr = empty_dir_getattr, .listxattr = empty_dir_listxattr, diff --git a/fs/minix/file.c b/fs/minix/file.c index f07acd268577..6a7bd2d9eec0 100644 --- a/fs/minix/file.c +++ b/fs/minix/file.c @@ -22,7 +22,8 @@ const struct file_operations minix_file_operations = { .splice_read = generic_file_splice_read, }; -static int minix_setattr(struct dentry *dentry, struct iattr *attr) +static int minix_setattr(struct user_namespace *mnt_userns, + struct dentry *dentry, struct iattr *attr) { struct inode *inode = d_inode(dentry); int error; diff --git a/fs/minix/inode.c b/fs/minix/inode.c index 91c81d2fc90d..a532a99bbe81 100644 --- a/fs/minix/inode.c +++ b/fs/minix/inode.c @@ -652,8 +652,8 @@ static int minix_write_inode(struct inode *inode, struct writeback_control *wbc) return err; } -int minix_getattr(const struct path *path, struct kstat *stat, - u32 request_mask, unsigned int flags) +int minix_getattr(struct user_namespace *mnt_userns, const struct path *path, + struct kstat *stat, u32 request_mask, unsigned int flags) { struct super_block *sb = path->dentry->d_sb; struct inode *inode = d_inode(path->dentry); diff --git a/fs/minix/minix.h b/fs/minix/minix.h index 168d45d3de73..202173368025 100644 --- a/fs/minix/minix.h +++ b/fs/minix/minix.h @@ -51,7 +51,8 @@ extern unsigned long minix_count_free_inodes(struct super_block *sb); extern int minix_new_block(struct inode * inode); extern void minix_free_block(struct inode *inode, unsigned long block); extern unsigned long minix_count_free_blocks(struct super_block *sb); -extern int minix_getattr(const struct path *, struct kstat *, u32, unsigned int); +extern int minix_getattr(struct user_namespace *, const struct path *, + struct kstat *, u32, unsigned int); extern int minix_prepare_chunk(struct page *page, loff_t pos, unsigned len); extern void V1_minix_truncate(struct inode *); diff --git a/fs/minix/namei.c b/fs/minix/namei.c index 1a6084d2b02e..937fa5fae2b8 100644 --- a/fs/minix/namei.c +++ b/fs/minix/namei.c @@ -33,7 +33,8 @@ static struct dentry *minix_lookup(struct inode * dir, struct dentry *dentry, un return d_splice_alias(inode, dentry); } -static int minix_mknod(struct inode * dir, struct dentry *dentry, umode_t mode, dev_t rdev) +static int minix_mknod(struct user_namespace *mnt_userns, struct inode *dir, + struct dentry *dentry, umode_t mode, dev_t rdev) { int error; struct inode *inode; @@ -51,7 +52,8 @@ static int minix_mknod(struct inode * dir, struct dentry *dentry, umode_t mode, return error; } -static int minix_tmpfile(struct inode *dir, struct dentry *dentry, umode_t mode) +static int minix_tmpfile(struct user_namespace *mnt_userns, struct inode *dir, + struct dentry *dentry, umode_t mode) { int error; struct inode *inode = minix_new_inode(dir, mode, &error); @@ -63,14 +65,14 @@ static int minix_tmpfile(struct inode *dir, struct dentry *dentry, umode_t mode) return error; } -static int minix_create(struct inode *dir, struct dentry *dentry, umode_t mode, - bool excl) +static int minix_create(struct user_namespace *mnt_userns, struct inode *dir, + struct dentry *dentry, umode_t mode, bool excl) { - return minix_mknod(dir, dentry, mode, 0); + return minix_mknod(mnt_userns, dir, dentry, mode, 0); } -static int minix_symlink(struct inode * dir, struct dentry *dentry, - const char * symname) +static int minix_symlink(struct user_namespace *mnt_userns, struct inode *dir, + struct dentry *dentry, const char *symname) { int err = -ENAMETOOLONG; int i = strlen(symname)+1; @@ -109,7 +111,8 @@ static int minix_link(struct dentry * old_dentry, struct inode * dir, return add_nondir(dentry, inode); } -static int minix_mkdir(struct inode * dir, struct dentry *dentry, umode_t mode) +static int minix_mkdir(struct user_namespace *mnt_userns, struct inode *dir, + struct dentry *dentry, umode_t mode) { struct inode * inode; int err; @@ -181,8 +184,9 @@ static int minix_rmdir(struct inode * dir, struct dentry *dentry) return err; } -static int minix_rename(struct inode * old_dir, struct dentry *old_dentry, - struct inode * new_dir, struct dentry *new_dentry, +static int minix_rename(struct user_namespace *mnt_userns, + struct inode *old_dir, struct dentry *old_dentry, + struct inode *new_dir, struct dentry *new_dentry, unsigned int flags) { struct inode * old_inode = d_inode(old_dentry); diff --git a/fs/namei.c b/fs/namei.c index c8c083daf368..d9ceb75ac169 100644 --- a/fs/namei.c +++ b/fs/namei.c @@ -443,7 +443,7 @@ static inline int do_inode_permission(struct user_namespace *mnt_userns, { if (unlikely(!(inode->i_opflags & IOP_FASTPERM))) { if (likely(inode->i_op->permission)) - return inode->i_op->permission(inode, mask); + return inode->i_op->permission(mnt_userns, inode, mask); /* This gets set once for the inode lifetime */ spin_lock(&inode->i_lock); @@ -2199,11 +2199,13 @@ static int link_path_walk(const char *name, struct nameidata *nd) /* At this point we know we have a real path component. */ for(;;) { + struct user_namespace *mnt_userns; const char *link; u64 hash_len; int type; - err = may_lookup(&init_user_ns, nd); + mnt_userns = mnt_user_ns(nd->path.mnt); + err = may_lookup(mnt_userns, nd); if (err) return err; @@ -2251,7 +2253,7 @@ static int link_path_walk(const char *name, struct nameidata *nd) OK: /* pathname or trailing symlink, done */ if (!depth) { - nd->dir_uid = i_uid_into_mnt(&init_user_ns, nd->inode); + nd->dir_uid = i_uid_into_mnt(mnt_userns, nd->inode); nd->dir_mode = nd->inode->i_mode; nd->flags &= ~LOOKUP_PARENT; return 0; @@ -2904,7 +2906,7 @@ int vfs_create(struct user_namespace *mnt_userns, struct inode *dir, error = security_inode_create(dir, dentry, mode); if (error) return error; - error = dir->i_op->create(dir, dentry, mode, want_excl); + error = dir->i_op->create(mnt_userns, dir, dentry, mode, want_excl); if (!error) fsnotify_create(dir, dentry); return error; @@ -2995,7 +2997,7 @@ static int may_open(struct user_namespace *mnt_userns, const struct path *path, return 0; } -static int handle_truncate(struct file *filp) +static int handle_truncate(struct user_namespace *mnt_userns, struct file *filp) { const struct path *path = &filp->f_path; struct inode *inode = path->dentry->d_inode; @@ -3009,7 +3011,7 @@ static int handle_truncate(struct file *filp) if (!error) error = security_path_truncate(path); if (!error) { - error = do_truncate(&init_user_ns, path->dentry, 0, + error = do_truncate(mnt_userns, path->dentry, 0, ATTR_MTIME|ATTR_CTIME|ATTR_OPEN, filp); } @@ -3118,6 +3120,7 @@ static struct dentry *lookup_open(struct nameidata *nd, struct file *file, const struct open_flags *op, bool got_write) { + struct user_namespace *mnt_userns; struct dentry *dir = nd->path.dentry; struct inode *dir_inode = dir->d_inode; int open_flag = op->open_flag; @@ -3165,13 +3168,14 @@ static struct dentry *lookup_open(struct nameidata *nd, struct file *file, */ if (unlikely(!got_write)) open_flag &= ~O_TRUNC; + mnt_userns = mnt_user_ns(nd->path.mnt); if (open_flag & O_CREAT) { if (open_flag & O_EXCL) open_flag &= ~O_TRUNC; if (!IS_POSIXACL(dir->d_inode)) mode &= ~current_umask(); if (likely(got_write)) - create_error = may_o_create(&init_user_ns, &nd->path, + create_error = may_o_create(mnt_userns, &nd->path, dentry, mode); else create_error = -EROFS; @@ -3207,8 +3211,9 @@ static struct dentry *lookup_open(struct nameidata *nd, struct file *file, error = -EACCES; goto out_dput; } - error = dir_inode->i_op->create(dir_inode, dentry, mode, - open_flag & O_EXCL); + + error = dir_inode->i_op->create(mnt_userns, dir_inode, dentry, + mode, open_flag & O_EXCL); if (error) goto out_dput; } @@ -3316,6 +3321,7 @@ finish_lookup: static int do_open(struct nameidata *nd, struct file *file, const struct open_flags *op) { + struct user_namespace *mnt_userns; int open_flag = op->open_flag; bool do_truncate; int acc_mode; @@ -3328,12 +3334,13 @@ static int do_open(struct nameidata *nd, } if (!(file->f_mode & FMODE_CREATED)) audit_inode(nd->name, nd->path.dentry, 0); + mnt_userns = mnt_user_ns(nd->path.mnt); if (open_flag & O_CREAT) { if ((open_flag & O_EXCL) && !(file->f_mode & FMODE_CREATED)) return -EEXIST; if (d_is_dir(nd->path.dentry)) return -EISDIR; - error = may_create_in_sticky(&init_user_ns, nd, + error = may_create_in_sticky(mnt_userns, nd, d_backing_inode(nd->path.dentry)); if (unlikely(error)) return error; @@ -3353,13 +3360,13 @@ static int do_open(struct nameidata *nd, return error; do_truncate = true; } - error = may_open(&init_user_ns, &nd->path, acc_mode, open_flag); + error = may_open(mnt_userns, &nd->path, acc_mode, open_flag); if (!error && !(file->f_mode & FMODE_OPENED)) error = vfs_open(&nd->path, file); if (!error) error = ima_file_check(file, op->acc_mode); if (!error && do_truncate) - error = handle_truncate(file); + error = handle_truncate(mnt_userns, file); if (unlikely(error > 0)) { WARN_ON(1); error = -EINVAL; @@ -3403,7 +3410,7 @@ struct dentry *vfs_tmpfile(struct user_namespace *mnt_userns, child = d_alloc(dentry, &slash_name); if (unlikely(!child)) goto out_err; - error = dir->i_op->tmpfile(dir, child, mode); + error = dir->i_op->tmpfile(mnt_userns, dir, child, mode); if (error) goto out_err; error = -ENOENT; @@ -3446,7 +3453,7 @@ static int do_tmpfile(struct nameidata *nd, unsigned flags, path.dentry = child; audit_inode(nd->name, child, 0); /* Don't check for other permissions, the inode was just created */ - error = may_open(&init_user_ns, &path, 0, op->open_flag); + error = may_open(mnt_userns, &path, 0, op->open_flag); if (error) goto out2; file->f_path.mnt = path.mnt; @@ -3690,7 +3697,7 @@ int vfs_mknod(struct user_namespace *mnt_userns, struct inode *dir, if (error) return error; - error = dir->i_op->mknod(dir, dentry, mode, dev); + error = dir->i_op->mknod(mnt_userns, dir, dentry, mode, dev); if (!error) fsnotify_create(dir, dentry); return error; @@ -3809,7 +3816,7 @@ int vfs_mkdir(struct user_namespace *mnt_userns, struct inode *dir, if (max_links && dir->i_nlink >= max_links) return -EMLINK; - error = dir->i_op->mkdir(dir, dentry, mode); + error = dir->i_op->mkdir(mnt_userns, dir, dentry, mode); if (!error) fsnotify_mkdir(dir, dentry); return error; @@ -3834,7 +3841,8 @@ retry: if (!error) { struct user_namespace *mnt_userns; mnt_userns = mnt_user_ns(path.mnt); - error = vfs_mkdir(mnt_userns, path.dentry->d_inode, dentry, mode); + error = vfs_mkdir(mnt_userns, path.dentry->d_inode, dentry, + mode); } done_path_create(&path, dentry); if (retry_estale(error, lookup_flags)) { @@ -4087,7 +4095,8 @@ retry_deleg: if (error) goto exit2; mnt_userns = mnt_user_ns(path.mnt); - error = vfs_unlink(mnt_userns, path.dentry->d_inode, dentry, &delegated_inode); + error = vfs_unlink(mnt_userns, path.dentry->d_inode, dentry, + &delegated_inode); exit2: dput(dentry); } @@ -4166,7 +4175,7 @@ int vfs_symlink(struct user_namespace *mnt_userns, struct inode *dir, if (error) return error; - error = dir->i_op->symlink(dir, dentry, oldname); + error = dir->i_op->symlink(mnt_userns, dir, dentry, oldname); if (!error) fsnotify_create(dir, dentry); return error; @@ -4357,13 +4366,13 @@ retry: error = -EXDEV; if (old_path.mnt != new_path.mnt) goto out_dput; - error = may_linkat(&init_user_ns, &old_path); + mnt_userns = mnt_user_ns(new_path.mnt); + error = may_linkat(mnt_userns, &old_path); if (unlikely(error)) goto out_dput; error = security_path_link(old_path.dentry, &new_path, new_dentry); if (error) goto out_dput; - mnt_userns = mnt_user_ns(new_path.mnt); error = vfs_link(old_path.dentry, mnt_userns, new_path.dentry->d_inode, new_dentry, &delegated_inode); out_dput: @@ -4542,8 +4551,8 @@ int vfs_rename(struct renamedata *rd) if (error) goto out; } - error = old_dir->i_op->rename(old_dir, old_dentry, - new_dir, new_dentry, flags); + error = old_dir->i_op->rename(rd->new_mnt_userns, old_dir, old_dentry, + new_dir, new_dentry, flags); if (error) goto out; diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c index 727e01a84503..19a9f434442f 100644 --- a/fs/nfs/dir.c +++ b/fs/nfs/dir.c @@ -2095,8 +2095,8 @@ EXPORT_SYMBOL_GPL(nfs_instantiate); * that the operation succeeded on the server, but an error in the * reply path made it appear to have failed. */ -int nfs_create(struct inode *dir, struct dentry *dentry, - umode_t mode, bool excl) +int nfs_create(struct user_namespace *mnt_userns, struct inode *dir, + struct dentry *dentry, umode_t mode, bool excl) { struct iattr attr; int open_flags = excl ? O_CREAT | O_EXCL : O_CREAT; @@ -2124,7 +2124,8 @@ EXPORT_SYMBOL_GPL(nfs_create); * See comments for nfs_proc_create regarding failed operations. */ int -nfs_mknod(struct inode *dir, struct dentry *dentry, umode_t mode, dev_t rdev) +nfs_mknod(struct user_namespace *mnt_userns, struct inode *dir, + struct dentry *dentry, umode_t mode, dev_t rdev) { struct iattr attr; int status; @@ -2150,7 +2151,8 @@ EXPORT_SYMBOL_GPL(nfs_mknod); /* * See comments for nfs_proc_create regarding failed operations. */ -int nfs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode) +int nfs_mkdir(struct user_namespace *mnt_userns, struct inode *dir, + struct dentry *dentry, umode_t mode) { struct iattr attr; int error; @@ -2295,7 +2297,8 @@ EXPORT_SYMBOL_GPL(nfs_unlink); * now have a new file handle and can instantiate an in-core NFS inode * and move the raw page into its mapping. */ -int nfs_symlink(struct inode *dir, struct dentry *dentry, const char *symname) +int nfs_symlink(struct user_namespace *mnt_userns, struct inode *dir, + struct dentry *dentry, const char *symname) { struct page *page; char *kaddr; @@ -2398,9 +2401,9 @@ EXPORT_SYMBOL_GPL(nfs_link); * If these conditions are met, we can drop the dentries before doing * the rename. */ -int nfs_rename(struct inode *old_dir, struct dentry *old_dentry, - struct inode *new_dir, struct dentry *new_dentry, - unsigned int flags) +int nfs_rename(struct user_namespace *mnt_userns, struct inode *old_dir, + struct dentry *old_dentry, struct inode *new_dir, + struct dentry *new_dentry, unsigned int flags) { struct inode *old_inode = d_inode(old_dentry); struct inode *new_inode = d_inode(new_dentry); @@ -2939,7 +2942,9 @@ static int nfs_execute_ok(struct inode *inode, int mask) return ret; } -int nfs_permission(struct inode *inode, int mask) +int nfs_permission(struct user_namespace *mnt_userns, + struct inode *inode, + int mask) { const struct cred *cred = current_cred(); int res = 0; diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c index cab123ec1664..447e95974386 100644 --- a/fs/nfs/inode.c +++ b/fs/nfs/inode.c @@ -594,7 +594,8 @@ EXPORT_SYMBOL_GPL(nfs_fhget); #define NFS_VALID_ATTRS (ATTR_MODE|ATTR_UID|ATTR_GID|ATTR_SIZE|ATTR_ATIME|ATTR_ATIME_SET|ATTR_MTIME|ATTR_MTIME_SET|ATTR_FILE|ATTR_OPEN) int -nfs_setattr(struct dentry *dentry, struct iattr *attr) +nfs_setattr(struct user_namespace *mnt_userns, struct dentry *dentry, + struct iattr *attr) { struct inode *inode = d_inode(dentry); struct nfs_fattr *fattr; @@ -787,8 +788,8 @@ static bool nfs_need_revalidate_inode(struct inode *inode) return false; } -int nfs_getattr(const struct path *path, struct kstat *stat, - u32 request_mask, unsigned int query_flags) +int nfs_getattr(struct user_namespace *mnt_userns, const struct path *path, + struct kstat *stat, u32 request_mask, unsigned int query_flags) { struct inode *inode = d_inode(path->dentry); struct nfs_server *server = NFS_SERVER(inode); diff --git a/fs/nfs/internal.h b/fs/nfs/internal.h index 62d3189745cd..25fb43b69e5a 100644 --- a/fs/nfs/internal.h +++ b/fs/nfs/internal.h @@ -378,14 +378,18 @@ extern unsigned long nfs_access_cache_count(struct shrinker *shrink, extern unsigned long nfs_access_cache_scan(struct shrinker *shrink, struct shrink_control *sc); struct dentry *nfs_lookup(struct inode *, struct dentry *, unsigned int); -int nfs_create(struct inode *, struct dentry *, umode_t, bool); -int nfs_mkdir(struct inode *, struct dentry *, umode_t); +int nfs_create(struct user_namespace *, struct inode *, struct dentry *, + umode_t, bool); +int nfs_mkdir(struct user_namespace *, struct inode *, struct dentry *, + umode_t); int nfs_rmdir(struct inode *, struct dentry *); int nfs_unlink(struct inode *, struct dentry *); -int nfs_symlink(struct inode *, struct dentry *, const char *); +int nfs_symlink(struct user_namespace *, struct inode *, struct dentry *, + const char *); int nfs_link(struct dentry *, struct inode *, struct dentry *); -int nfs_mknod(struct inode *, struct dentry *, umode_t, dev_t); -int nfs_rename(struct inode *, struct dentry *, +int nfs_mknod(struct user_namespace *, struct inode *, struct dentry *, umode_t, + dev_t); +int nfs_rename(struct user_namespace *, struct inode *, struct dentry *, struct inode *, struct dentry *, unsigned int); /* file.c */ diff --git a/fs/nfs/namespace.c b/fs/nfs/namespace.c index 55fc711e368b..93e60e921f92 100644 --- a/fs/nfs/namespace.c +++ b/fs/nfs/namespace.c @@ -208,20 +208,23 @@ out_fc: } static int -nfs_namespace_getattr(const struct path *path, struct kstat *stat, - u32 request_mask, unsigned int query_flags) +nfs_namespace_getattr(struct user_namespace *mnt_userns, + const struct path *path, struct kstat *stat, + u32 request_mask, unsigned int query_flags) { if (NFS_FH(d_inode(path->dentry))->size != 0) - return nfs_getattr(path, stat, request_mask, query_flags); + return nfs_getattr(mnt_userns, path, stat, request_mask, + query_flags); generic_fillattr(&init_user_ns, d_inode(path->dentry), stat); return 0; } static int -nfs_namespace_setattr(struct dentry *dentry, struct iattr *attr) +nfs_namespace_setattr(struct user_namespace *mnt_userns, struct dentry *dentry, + struct iattr *attr) { if (NFS_FH(d_inode(dentry))->size != 0) - return nfs_setattr(dentry, attr); + return nfs_setattr(mnt_userns, dentry, attr); return -EACCES; } diff --git a/fs/nfs/nfs3_fs.h b/fs/nfs/nfs3_fs.h index 1b950b66b3bb..c8a192802dda 100644 --- a/fs/nfs/nfs3_fs.h +++ b/fs/nfs/nfs3_fs.h @@ -12,7 +12,8 @@ */ #ifdef CONFIG_NFS_V3_ACL extern struct posix_acl *nfs3_get_acl(struct inode *inode, int type); -extern int nfs3_set_acl(struct inode *inode, struct posix_acl *acl, int type); +extern int nfs3_set_acl(struct user_namespace *mnt_userns, struct inode *inode, + struct posix_acl *acl, int type); extern int nfs3_proc_setacls(struct inode *inode, struct posix_acl *acl, struct posix_acl *dfacl); extern ssize_t nfs3_listxattr(struct dentry *, char *, size_t); diff --git a/fs/nfs/nfs3acl.c b/fs/nfs/nfs3acl.c index c6c863382f37..5604e807fc01 100644 --- a/fs/nfs/nfs3acl.c +++ b/fs/nfs/nfs3acl.c @@ -251,7 +251,8 @@ int nfs3_proc_setacls(struct inode *inode, struct posix_acl *acl, } -int nfs3_set_acl(struct inode *inode, struct posix_acl *acl, int type) +int nfs3_set_acl(struct user_namespace *mnt_userns, struct inode *inode, + struct posix_acl *acl, int type) { struct posix_acl *orig = acl, *dfacl = NULL, *alloc; int status; diff --git a/fs/nilfs2/inode.c b/fs/nilfs2/inode.c index 8aad3c48092a..2e8eb263cf0f 100644 --- a/fs/nilfs2/inode.c +++ b/fs/nilfs2/inode.c @@ -805,7 +805,8 @@ void nilfs_evict_inode(struct inode *inode) */ } -int nilfs_setattr(struct dentry *dentry, struct iattr *iattr) +int nilfs_setattr(struct user_namespace *mnt_userns, struct dentry *dentry, + struct iattr *iattr) { struct nilfs_transaction_info ti; struct inode *inode = d_inode(dentry); @@ -843,7 +844,8 @@ out_err: return err; } -int nilfs_permission(struct inode *inode, int mask) +int nilfs_permission(struct user_namespace *mnt_userns, struct inode *inode, + int mask) { struct nilfs_root *root = NILFS_I(inode)->i_root; diff --git a/fs/nilfs2/namei.c b/fs/nilfs2/namei.c index a6ec7961d4f5..ecace5f96a95 100644 --- a/fs/nilfs2/namei.c +++ b/fs/nilfs2/namei.c @@ -72,8 +72,8 @@ nilfs_lookup(struct inode *dir, struct dentry *dentry, unsigned int flags) * If the create succeeds, we fill in the inode information * with d_instantiate(). */ -static int nilfs_create(struct inode *dir, struct dentry *dentry, umode_t mode, - bool excl) +static int nilfs_create(struct user_namespace *mnt_userns, struct inode *dir, + struct dentry *dentry, umode_t mode, bool excl) { struct inode *inode; struct nilfs_transaction_info ti; @@ -100,7 +100,8 @@ static int nilfs_create(struct inode *dir, struct dentry *dentry, umode_t mode, } static int -nilfs_mknod(struct inode *dir, struct dentry *dentry, umode_t mode, dev_t rdev) +nilfs_mknod(struct user_namespace *mnt_userns, struct inode *dir, + struct dentry *dentry, umode_t mode, dev_t rdev) { struct inode *inode; struct nilfs_transaction_info ti; @@ -124,8 +125,8 @@ nilfs_mknod(struct inode *dir, struct dentry *dentry, umode_t mode, dev_t rdev) return err; } -static int nilfs_symlink(struct inode *dir, struct dentry *dentry, - const char *symname) +static int nilfs_symlink(struct user_namespace *mnt_userns, struct inode *dir, + struct dentry *dentry, const char *symname) { struct nilfs_transaction_info ti; struct super_block *sb = dir->i_sb; @@ -201,7 +202,8 @@ static int nilfs_link(struct dentry *old_dentry, struct inode *dir, return err; } -static int nilfs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode) +static int nilfs_mkdir(struct user_namespace *mnt_userns, struct inode *dir, + struct dentry *dentry, umode_t mode) { struct inode *inode; struct nilfs_transaction_info ti; @@ -338,8 +340,9 @@ static int nilfs_rmdir(struct inode *dir, struct dentry *dentry) return err; } -static int nilfs_rename(struct inode *old_dir, struct dentry *old_dentry, - struct inode *new_dir, struct dentry *new_dentry, +static int nilfs_rename(struct user_namespace *mnt_userns, + struct inode *old_dir, struct dentry *old_dentry, + struct inode *new_dir, struct dentry *new_dentry, unsigned int flags) { struct inode *old_inode = d_inode(old_dentry); diff --git a/fs/nilfs2/nilfs.h b/fs/nilfs2/nilfs.h index f8450ee3fd06..c4a45a081ade 100644 --- a/fs/nilfs2/nilfs.h +++ b/fs/nilfs2/nilfs.h @@ -267,9 +267,11 @@ extern struct inode *nilfs_iget_for_gc(struct super_block *sb, extern void nilfs_update_inode(struct inode *, struct buffer_head *, int); extern void nilfs_truncate(struct inode *); extern void nilfs_evict_inode(struct inode *); -extern int nilfs_setattr(struct dentry *, struct iattr *); +extern int nilfs_setattr(struct user_namespace *, struct dentry *, + struct iattr *); extern void nilfs_write_failed(struct address_space *mapping, loff_t to); -int nilfs_permission(struct inode *inode, int mask); +int nilfs_permission(struct user_namespace *mnt_userns, struct inode *inode, + int mask); int nilfs_load_inode_block(struct inode *inode, struct buffer_head **pbh); extern int nilfs_inode_dirty(struct inode *); int nilfs_set_file_dirty(struct inode *inode, unsigned int nr_dirty); diff --git a/fs/ntfs/inode.c b/fs/ntfs/inode.c index 38f4cf1d4497..4435dbbc0b63 100644 --- a/fs/ntfs/inode.c +++ b/fs/ntfs/inode.c @@ -2848,6 +2848,7 @@ void ntfs_truncate_vfs(struct inode *vi) { /** * ntfs_setattr - called from notify_change() when an attribute is being changed + * @mnt_userns: user namespace of the mount the inode was found from * @dentry: dentry whose attributes to change * @attr: structure describing the attributes and the changes * @@ -2860,7 +2861,8 @@ void ntfs_truncate_vfs(struct inode *vi) { * * Called with ->i_mutex held. */ -int ntfs_setattr(struct dentry *dentry, struct iattr *attr) +int ntfs_setattr(struct user_namespace *mnt_userns, struct dentry *dentry, + struct iattr *attr) { struct inode *vi = d_inode(dentry); int err; diff --git a/fs/ntfs/inode.h b/fs/ntfs/inode.h index 363e4e820673..6f78ee00f57f 100644 --- a/fs/ntfs/inode.h +++ b/fs/ntfs/inode.h @@ -289,7 +289,8 @@ extern int ntfs_show_options(struct seq_file *sf, struct dentry *root); extern int ntfs_truncate(struct inode *vi); extern void ntfs_truncate_vfs(struct inode *vi); -extern int ntfs_setattr(struct dentry *dentry, struct iattr *attr); +extern int ntfs_setattr(struct user_namespace *mnt_userns, + struct dentry *dentry, struct iattr *attr); extern int __ntfs_write_inode(struct inode *vi, int sync); diff --git a/fs/ocfs2/acl.c b/fs/ocfs2/acl.c index 990756cee4bd..5259badabb56 100644 --- a/fs/ocfs2/acl.c +++ b/fs/ocfs2/acl.c @@ -262,7 +262,8 @@ static int ocfs2_set_acl(handle_t *handle, return ret; } -int ocfs2_iop_set_acl(struct inode *inode, struct posix_acl *acl, int type) +int ocfs2_iop_set_acl(struct user_namespace *mnt_userns, struct inode *inode, + struct posix_acl *acl, int type) { struct buffer_head *bh = NULL; int status, had_lock; diff --git a/fs/ocfs2/acl.h b/fs/ocfs2/acl.h index 127b13432146..4e86450917b2 100644 --- a/fs/ocfs2/acl.h +++ b/fs/ocfs2/acl.h @@ -19,7 +19,8 @@ struct ocfs2_acl_entry { }; struct posix_acl *ocfs2_iop_get_acl(struct inode *inode, int type); -int ocfs2_iop_set_acl(struct inode *inode, struct posix_acl *acl, int type); +int ocfs2_iop_set_acl(struct user_namespace *mnt_userns, struct inode *inode, + struct posix_acl *acl, int type); extern int ocfs2_acl_chmod(struct inode *, struct buffer_head *); extern int ocfs2_init_acl(handle_t *, struct inode *, struct inode *, struct buffer_head *, struct buffer_head *, diff --git a/fs/ocfs2/dlmfs/dlmfs.c b/fs/ocfs2/dlmfs/dlmfs.c index 9fa66cd1f622..b2870f1a31df 100644 --- a/fs/ocfs2/dlmfs/dlmfs.c +++ b/fs/ocfs2/dlmfs/dlmfs.c @@ -190,7 +190,8 @@ static int dlmfs_file_release(struct inode *inode, * We do ->setattr() just to override size changes. Our size is the size * of the LVB and nothing else. */ -static int dlmfs_file_setattr(struct dentry *dentry, struct iattr *attr) +static int dlmfs_file_setattr(struct user_namespace *mnt_userns, + struct dentry *dentry, struct iattr *attr) { int error; struct inode *inode = d_inode(dentry); @@ -395,7 +396,8 @@ static struct inode *dlmfs_get_inode(struct inode *parent, * File creation. Allocate an inode, and we're done.. */ /* SMP-safe */ -static int dlmfs_mkdir(struct inode * dir, +static int dlmfs_mkdir(struct user_namespace * mnt_userns, + struct inode * dir, struct dentry * dentry, umode_t mode) { @@ -443,7 +445,8 @@ bail: return status; } -static int dlmfs_create(struct inode *dir, +static int dlmfs_create(struct user_namespace *mnt_userns, + struct inode *dir, struct dentry *dentry, umode_t mode, bool excl) diff --git a/fs/ocfs2/file.c b/fs/ocfs2/file.c index a070d4c9b6ed..e3039d973acd 100644 --- a/fs/ocfs2/file.c +++ b/fs/ocfs2/file.c @@ -1112,7 +1112,8 @@ out: return ret; } -int ocfs2_setattr(struct dentry *dentry, struct iattr *attr) +int ocfs2_setattr(struct user_namespace *mnt_userns, struct dentry *dentry, + struct iattr *attr) { int status = 0, size_change; int inode_locked = 0; @@ -1298,8 +1299,8 @@ bail: return status; } -int ocfs2_getattr(const struct path *path, struct kstat *stat, - u32 request_mask, unsigned int flags) +int ocfs2_getattr(struct user_namespace *mnt_userns, const struct path *path, + struct kstat *stat, u32 request_mask, unsigned int flags) { struct inode *inode = d_inode(path->dentry); struct super_block *sb = path->dentry->d_sb; @@ -1330,7 +1331,8 @@ bail: return err; } -int ocfs2_permission(struct inode *inode, int mask) +int ocfs2_permission(struct user_namespace *mnt_userns, struct inode *inode, + int mask) { int ret, had_lock; struct ocfs2_lock_holder oh; diff --git a/fs/ocfs2/file.h b/fs/ocfs2/file.h index 4832cbceba5b..8536cec5f122 100644 --- a/fs/ocfs2/file.h +++ b/fs/ocfs2/file.h @@ -51,10 +51,13 @@ int ocfs2_extend_no_holes(struct inode *inode, struct buffer_head *di_bh, u64 new_i_size, u64 zero_to); int ocfs2_zero_extend(struct inode *inode, struct buffer_head *di_bh, loff_t zero_to); -int ocfs2_setattr(struct dentry *dentry, struct iattr *attr); -int ocfs2_getattr(const struct path *path, struct kstat *stat, - u32 request_mask, unsigned int flags); -int ocfs2_permission(struct inode *inode, int mask); +int ocfs2_setattr(struct user_namespace *mnt_userns, struct dentry *dentry, + struct iattr *attr); +int ocfs2_getattr(struct user_namespace *mnt_userns, const struct path *path, + struct kstat *stat, u32 request_mask, unsigned int flags); +int ocfs2_permission(struct user_namespace *mnt_userns, + struct inode *inode, + int mask); int ocfs2_should_update_atime(struct inode *inode, struct vfsmount *vfsmnt); diff --git a/fs/ocfs2/namei.c b/fs/ocfs2/namei.c index 908b79e1082b..3abdd36da2e2 100644 --- a/fs/ocfs2/namei.c +++ b/fs/ocfs2/namei.c @@ -221,7 +221,8 @@ static void ocfs2_cleanup_add_entry_failure(struct ocfs2_super *osb, iput(inode); } -static int ocfs2_mknod(struct inode *dir, +static int ocfs2_mknod(struct user_namespace *mnt_userns, + struct inode *dir, struct dentry *dentry, umode_t mode, dev_t dev) @@ -645,7 +646,8 @@ static int ocfs2_mknod_locked(struct ocfs2_super *osb, return status; } -static int ocfs2_mkdir(struct inode *dir, +static int ocfs2_mkdir(struct user_namespace *mnt_userns, + struct inode *dir, struct dentry *dentry, umode_t mode) { @@ -653,14 +655,15 @@ static int ocfs2_mkdir(struct inode *dir, trace_ocfs2_mkdir(dir, dentry, dentry->d_name.len, dentry->d_name.name, OCFS2_I(dir)->ip_blkno, mode); - ret = ocfs2_mknod(dir, dentry, mode | S_IFDIR, 0); + ret = ocfs2_mknod(&init_user_ns, dir, dentry, mode | S_IFDIR, 0); if (ret) mlog_errno(ret); return ret; } -static int ocfs2_create(struct inode *dir, +static int ocfs2_create(struct user_namespace *mnt_userns, + struct inode *dir, struct dentry *dentry, umode_t mode, bool excl) @@ -669,7 +672,7 @@ static int ocfs2_create(struct inode *dir, trace_ocfs2_create(dir, dentry, dentry->d_name.len, dentry->d_name.name, (unsigned long long)OCFS2_I(dir)->ip_blkno, mode); - ret = ocfs2_mknod(dir, dentry, mode | S_IFREG, 0); + ret = ocfs2_mknod(&init_user_ns, dir, dentry, mode | S_IFREG, 0); if (ret) mlog_errno(ret); @@ -1195,7 +1198,8 @@ static void ocfs2_double_unlock(struct inode *inode1, struct inode *inode2) ocfs2_inode_unlock(inode2, 1); } -static int ocfs2_rename(struct inode *old_dir, +static int ocfs2_rename(struct user_namespace *mnt_userns, + struct inode *old_dir, struct dentry *old_dentry, struct inode *new_dir, struct dentry *new_dentry, @@ -1784,7 +1788,8 @@ bail: return status; } -static int ocfs2_symlink(struct inode *dir, +static int ocfs2_symlink(struct user_namespace *mnt_userns, + struct inode *dir, struct dentry *dentry, const char *symname) { diff --git a/fs/omfs/dir.c b/fs/omfs/dir.c index a0f45651f3b7..c219f91f44e9 100644 --- a/fs/omfs/dir.c +++ b/fs/omfs/dir.c @@ -279,13 +279,14 @@ out_free_inode: return err; } -static int omfs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode) +static int omfs_mkdir(struct user_namespace *mnt_userns, struct inode *dir, + struct dentry *dentry, umode_t mode) { return omfs_add_node(dir, dentry, mode | S_IFDIR); } -static int omfs_create(struct inode *dir, struct dentry *dentry, umode_t mode, - bool excl) +static int omfs_create(struct user_namespace *mnt_userns, struct inode *dir, + struct dentry *dentry, umode_t mode, bool excl) { return omfs_add_node(dir, dentry, mode | S_IFREG); } @@ -369,9 +370,9 @@ static bool omfs_fill_chain(struct inode *dir, struct dir_context *ctx, return true; } -static int omfs_rename(struct inode *old_dir, struct dentry *old_dentry, - struct inode *new_dir, struct dentry *new_dentry, - unsigned int flags) +static int omfs_rename(struct user_namespace *mnt_userns, struct inode *old_dir, + struct dentry *old_dentry, struct inode *new_dir, + struct dentry *new_dentry, unsigned int flags) { struct inode *new_inode = d_inode(new_dentry); struct inode *old_inode = d_inode(old_dentry); diff --git a/fs/omfs/file.c b/fs/omfs/file.c index 729339cd7902..11e733aab25d 100644 --- a/fs/omfs/file.c +++ b/fs/omfs/file.c @@ -343,7 +343,8 @@ const struct file_operations omfs_file_operations = { .splice_read = generic_file_splice_read, }; -static int omfs_setattr(struct dentry *dentry, struct iattr *attr) +static int omfs_setattr(struct user_namespace *mnt_userns, + struct dentry *dentry, struct iattr *attr) { struct inode *inode = d_inode(dentry); int error; diff --git a/fs/orangefs/acl.c b/fs/orangefs/acl.c index 628921952d16..18852b9ed82b 100644 --- a/fs/orangefs/acl.c +++ b/fs/orangefs/acl.c @@ -116,7 +116,8 @@ out: return error; } -int orangefs_set_acl(struct inode *inode, struct posix_acl *acl, int type) +int orangefs_set_acl(struct user_namespace *mnt_userns, struct inode *inode, + struct posix_acl *acl, int type) { int error; struct iattr iattr; diff --git a/fs/orangefs/inode.c b/fs/orangefs/inode.c index b94032f77e61..5079cfafa8d7 100644 --- a/fs/orangefs/inode.c +++ b/fs/orangefs/inode.c @@ -871,7 +871,8 @@ out: /* * Change attributes of an object referenced by dentry. */ -int orangefs_setattr(struct dentry *dentry, struct iattr *iattr) +int orangefs_setattr(struct user_namespace *mnt_userns, struct dentry *dentry, + struct iattr *iattr) { int ret; gossip_debug(GOSSIP_INODE_DEBUG, "__orangefs_setattr: called on %pd\n", @@ -890,8 +891,8 @@ out: /* * Obtain attributes of an object given a dentry */ -int orangefs_getattr(const struct path *path, struct kstat *stat, - u32 request_mask, unsigned int flags) +int orangefs_getattr(struct user_namespace *mnt_userns, const struct path *path, + struct kstat *stat, u32 request_mask, unsigned int flags) { int ret; struct inode *inode = path->dentry->d_inode; @@ -919,7 +920,8 @@ int orangefs_getattr(const struct path *path, struct kstat *stat, return ret; } -int orangefs_permission(struct inode *inode, int mask) +int orangefs_permission(struct user_namespace *mnt_userns, + struct inode *inode, int mask) { int ret; diff --git a/fs/orangefs/namei.c b/fs/orangefs/namei.c index 3e7cf3d0a494..600e8eee541f 100644 --- a/fs/orangefs/namei.c +++ b/fs/orangefs/namei.c @@ -15,7 +15,8 @@ /* * Get a newly allocated inode to go with a negative dentry. */ -static int orangefs_create(struct inode *dir, +static int orangefs_create(struct user_namespace *mnt_userns, + struct inode *dir, struct dentry *dentry, umode_t mode, bool exclusive) @@ -215,7 +216,8 @@ static int orangefs_unlink(struct inode *dir, struct dentry *dentry) return ret; } -static int orangefs_symlink(struct inode *dir, +static int orangefs_symlink(struct user_namespace *mnt_userns, + struct inode *dir, struct dentry *dentry, const char *symname) { @@ -303,7 +305,8 @@ out: return ret; } -static int orangefs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode) +static int orangefs_mkdir(struct user_namespace *mnt_userns, struct inode *dir, + struct dentry *dentry, umode_t mode) { struct orangefs_inode_s *parent = ORANGEFS_I(dir); struct orangefs_kernel_op_s *new_op; @@ -372,7 +375,8 @@ out: return ret; } -static int orangefs_rename(struct inode *old_dir, +static int orangefs_rename(struct user_namespace *mnt_userns, + struct inode *old_dir, struct dentry *old_dentry, struct inode *new_dir, struct dentry *new_dentry, diff --git a/fs/orangefs/orangefs-kernel.h b/fs/orangefs/orangefs-kernel.h index e12aeb9623d6..0e6b97682e41 100644 --- a/fs/orangefs/orangefs-kernel.h +++ b/fs/orangefs/orangefs-kernel.h @@ -107,7 +107,9 @@ extern int orangefs_init_acl(struct inode *inode, struct inode *dir); extern const struct xattr_handler *orangefs_xattr_handlers[]; extern struct posix_acl *orangefs_get_acl(struct inode *inode, int type); -extern int orangefs_set_acl(struct inode *inode, struct posix_acl *acl, int type); +extern int orangefs_set_acl(struct user_namespace *mnt_userns, + struct inode *inode, struct posix_acl *acl, + int type); /* * orangefs data structures @@ -359,12 +361,13 @@ struct inode *orangefs_new_inode(struct super_block *sb, struct orangefs_object_kref *ref); int __orangefs_setattr(struct inode *, struct iattr *); -int orangefs_setattr(struct dentry *, struct iattr *); +int orangefs_setattr(struct user_namespace *, struct dentry *, struct iattr *); -int orangefs_getattr(const struct path *path, struct kstat *stat, - u32 request_mask, unsigned int flags); +int orangefs_getattr(struct user_namespace *mnt_userns, const struct path *path, + struct kstat *stat, u32 request_mask, unsigned int flags); -int orangefs_permission(struct inode *inode, int mask); +int orangefs_permission(struct user_namespace *mnt_userns, + struct inode *inode, int mask); int orangefs_update_time(struct inode *, struct timespec64 *, int); diff --git a/fs/overlayfs/dir.c b/fs/overlayfs/dir.c index 6904cc2ed7bb..8b3be7342a8c 100644 --- a/fs/overlayfs/dir.c +++ b/fs/overlayfs/dir.c @@ -650,19 +650,20 @@ out: return err; } -static int ovl_create(struct inode *dir, struct dentry *dentry, umode_t mode, - bool excl) +static int ovl_create(struct user_namespace *mnt_userns, struct inode *dir, + struct dentry *dentry, umode_t mode, bool excl) { return ovl_create_object(dentry, (mode & 07777) | S_IFREG, 0, NULL); } -static int ovl_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode) +static int ovl_mkdir(struct user_namespace *mnt_userns, struct inode *dir, + struct dentry *dentry, umode_t mode) { return ovl_create_object(dentry, (mode & 07777) | S_IFDIR, 0, NULL); } -static int ovl_mknod(struct inode *dir, struct dentry *dentry, umode_t mode, - dev_t rdev) +static int ovl_mknod(struct user_namespace *mnt_userns, struct inode *dir, + struct dentry *dentry, umode_t mode, dev_t rdev) { /* Don't allow creation of "whiteout" on overlay */ if (S_ISCHR(mode) && rdev == WHITEOUT_DEV) @@ -671,8 +672,8 @@ static int ovl_mknod(struct inode *dir, struct dentry *dentry, umode_t mode, return ovl_create_object(dentry, mode, rdev, NULL); } -static int ovl_symlink(struct inode *dir, struct dentry *dentry, - const char *link) +static int ovl_symlink(struct user_namespace *mnt_userns, struct inode *dir, + struct dentry *dentry, const char *link) { return ovl_create_object(dentry, S_IFLNK, 0, link); } @@ -1069,9 +1070,9 @@ static int ovl_set_redirect(struct dentry *dentry, bool samedir) return err; } -static int ovl_rename(struct inode *olddir, struct dentry *old, - struct inode *newdir, struct dentry *new, - unsigned int flags) +static int ovl_rename(struct user_namespace *mnt_userns, struct inode *olddir, + struct dentry *old, struct inode *newdir, + struct dentry *new, unsigned int flags) { int err; struct dentry *old_upperdir; diff --git a/fs/overlayfs/inode.c b/fs/overlayfs/inode.c index 023fde466e3a..e78d45dfeaee 100644 --- a/fs/overlayfs/inode.c +++ b/fs/overlayfs/inode.c @@ -14,7 +14,8 @@ #include "overlayfs.h" -int ovl_setattr(struct dentry *dentry, struct iattr *attr) +int ovl_setattr(struct user_namespace *mnt_userns, struct dentry *dentry, + struct iattr *attr) { int err; bool full_copy_up = false; @@ -154,8 +155,8 @@ static int ovl_map_dev_ino(struct dentry *dentry, struct kstat *stat, int fsid) return 0; } -int ovl_getattr(const struct path *path, struct kstat *stat, - u32 request_mask, unsigned int flags) +int ovl_getattr(struct user_namespace *mnt_userns, const struct path *path, + struct kstat *stat, u32 request_mask, unsigned int flags) { struct dentry *dentry = path->dentry; enum ovl_path_type type; @@ -277,7 +278,8 @@ out: return err; } -int ovl_permission(struct inode *inode, int mask) +int ovl_permission(struct user_namespace *mnt_userns, + struct inode *inode, int mask) { struct inode *upperinode = ovl_inode_upper(inode); struct inode *realinode = upperinode ?: ovl_inode_lower(inode); diff --git a/fs/overlayfs/overlayfs.h b/fs/overlayfs/overlayfs.h index 5e9eb46e741a..78b9d93a33c9 100644 --- a/fs/overlayfs/overlayfs.h +++ b/fs/overlayfs/overlayfs.h @@ -444,10 +444,12 @@ int ovl_set_nlink_lower(struct dentry *dentry); unsigned int ovl_get_nlink(struct ovl_fs *ofs, struct dentry *lowerdentry, struct dentry *upperdentry, unsigned int fallback); -int ovl_setattr(struct dentry *dentry, struct iattr *attr); -int ovl_getattr(const struct path *path, struct kstat *stat, - u32 request_mask, unsigned int flags); -int ovl_permission(struct inode *inode, int mask); +int ovl_setattr(struct user_namespace *mnt_userns, struct dentry *dentry, + struct iattr *attr); +int ovl_getattr(struct user_namespace *mnt_userns, const struct path *path, + struct kstat *stat, u32 request_mask, unsigned int flags); +int ovl_permission(struct user_namespace *mnt_userns, struct inode *inode, + int mask); int ovl_xattr_set(struct dentry *dentry, struct inode *inode, const char *name, const void *value, size_t size, int flags); int ovl_xattr_get(struct dentry *dentry, struct inode *inode, const char *name, diff --git a/fs/overlayfs/super.c b/fs/overlayfs/super.c index 8168ab2dda11..c04612b19054 100644 --- a/fs/overlayfs/super.c +++ b/fs/overlayfs/super.c @@ -1023,7 +1023,7 @@ ovl_posix_acl_xattr_set(const struct xattr_handler *handler, !capable_wrt_inode_uidgid(&init_user_ns, inode, CAP_FSETID)) { struct iattr iattr = { .ia_valid = ATTR_KILL_SGID }; - err = ovl_setattr(dentry, &iattr); + err = ovl_setattr(&init_user_ns, dentry, &iattr); if (err) return err; } diff --git a/fs/posix_acl.c b/fs/posix_acl.c index d31b60f5d40d..f3309a7edb49 100644 --- a/fs/posix_acl.c +++ b/fs/posix_acl.c @@ -593,7 +593,7 @@ int ret = __posix_acl_chmod(&acl, GFP_KERNEL, mode); if (ret) return ret; - ret = inode->i_op->set_acl(inode, acl, ACL_TYPE_ACCESS); + ret = inode->i_op->set_acl(mnt_userns, inode, acl, ACL_TYPE_ACCESS); posix_acl_release(acl); return ret; } @@ -918,7 +918,7 @@ set_posix_acl(struct user_namespace *mnt_userns, struct inode *inode, if (ret) return ret; } - return inode->i_op->set_acl(inode, acl, type); + return inode->i_op->set_acl(mnt_userns, inode, acl, type); } EXPORT_SYMBOL(set_posix_acl); @@ -966,12 +966,13 @@ const struct xattr_handler posix_acl_default_xattr_handler = { }; EXPORT_SYMBOL_GPL(posix_acl_default_xattr_handler); -int simple_set_acl(struct inode *inode, struct posix_acl *acl, int type) +int simple_set_acl(struct user_namespace *mnt_userns, struct inode *inode, + struct posix_acl *acl, int type) { int error; if (type == ACL_TYPE_ACCESS) { - error = posix_acl_update_mode(&init_user_ns, inode, + error = posix_acl_update_mode(mnt_userns, inode, &inode->i_mode, &acl); if (error) return error; diff --git a/fs/proc/base.c b/fs/proc/base.c index d45aa68c1f17..56bf14316122 100644 --- a/fs/proc/base.c +++ b/fs/proc/base.c @@ -685,7 +685,8 @@ static int proc_fd_access_allowed(struct inode *inode) return allowed; } -int proc_setattr(struct dentry *dentry, struct iattr *attr) +int proc_setattr(struct user_namespace *mnt_userns, struct dentry *dentry, + struct iattr *attr) { int error; struct inode *inode = d_inode(dentry); @@ -726,7 +727,8 @@ static bool has_pid_permissions(struct proc_fs_info *fs_info, } -static int proc_pid_permission(struct inode *inode, int mask) +static int proc_pid_permission(struct user_namespace *mnt_userns, + struct inode *inode, int mask) { struct proc_fs_info *fs_info = proc_sb_info(inode->i_sb); struct task_struct *task; @@ -1927,8 +1929,8 @@ out_unlock: return NULL; } -int pid_getattr(const struct path *path, struct kstat *stat, - u32 request_mask, unsigned int query_flags) +int pid_getattr(struct user_namespace *mnt_userns, const struct path *path, + struct kstat *stat, u32 request_mask, unsigned int query_flags) { struct inode *inode = d_inode(path->dentry); struct proc_fs_info *fs_info = proc_sb_info(inode->i_sb); @@ -3473,7 +3475,8 @@ int proc_pid_readdir(struct file *file, struct dir_context *ctx) * This function makes sure that the node is always accessible for members of * same thread group. */ -static int proc_tid_comm_permission(struct inode *inode, int mask) +static int proc_tid_comm_permission(struct user_namespace *mnt_userns, + struct inode *inode, int mask) { bool is_same_tgroup; struct task_struct *task; @@ -3798,7 +3801,8 @@ static int proc_task_readdir(struct file *file, struct dir_context *ctx) return 0; } -static int proc_task_getattr(const struct path *path, struct kstat *stat, +static int proc_task_getattr(struct user_namespace *mnt_userns, + const struct path *path, struct kstat *stat, u32 request_mask, unsigned int query_flags) { struct inode *inode = d_inode(path->dentry); diff --git a/fs/proc/fd.c b/fs/proc/fd.c index d6e76461e135..07fc4fad2602 100644 --- a/fs/proc/fd.c +++ b/fs/proc/fd.c @@ -276,7 +276,8 @@ static struct dentry *proc_lookupfd(struct inode *dir, struct dentry *dentry, * /proc/pid/fd needs a special permission handler so that a process can still * access /proc/self/fd after it has executed a setuid(). */ -int proc_fd_permission(struct inode *inode, int mask) +int proc_fd_permission(struct user_namespace *mnt_userns, + struct inode *inode, int mask) { struct task_struct *p; int rv; diff --git a/fs/proc/fd.h b/fs/proc/fd.h index f371a602bf58..c5a921a06a0b 100644 --- a/fs/proc/fd.h +++ b/fs/proc/fd.h @@ -10,7 +10,8 @@ extern const struct inode_operations proc_fd_inode_operations; extern const struct file_operations proc_fdinfo_operations; extern const struct inode_operations proc_fdinfo_inode_operations; -extern int proc_fd_permission(struct inode *inode, int mask); +extern int proc_fd_permission(struct user_namespace *mnt_userns, + struct inode *inode, int mask); static inline unsigned int proc_fd(struct inode *inode) { diff --git a/fs/proc/generic.c b/fs/proc/generic.c index 0db96a761149..bc86aa87cc41 100644 --- a/fs/proc/generic.c +++ b/fs/proc/generic.c @@ -115,7 +115,8 @@ static bool pde_subdir_insert(struct proc_dir_entry *dir, return true; } -static int proc_notify_change(struct dentry *dentry, struct iattr *iattr) +static int proc_notify_change(struct user_namespace *mnt_userns, + struct dentry *dentry, struct iattr *iattr) { struct inode *inode = d_inode(dentry); struct proc_dir_entry *de = PDE(inode); @@ -133,7 +134,8 @@ static int proc_notify_change(struct dentry *dentry, struct iattr *iattr) return 0; } -static int proc_getattr(const struct path *path, struct kstat *stat, +static int proc_getattr(struct user_namespace *mnt_userns, + const struct path *path, struct kstat *stat, u32 request_mask, unsigned int query_flags) { struct inode *inode = d_inode(path->dentry); diff --git a/fs/proc/internal.h b/fs/proc/internal.h index f60b379dcdc7..03415f3fb3a8 100644 --- a/fs/proc/internal.h +++ b/fs/proc/internal.h @@ -162,8 +162,10 @@ extern int proc_pid_statm(struct seq_file *, struct pid_namespace *, * base.c */ extern const struct dentry_operations pid_dentry_operations; -extern int pid_getattr(const struct path *, struct kstat *, u32, unsigned int); -extern int proc_setattr(struct dentry *, struct iattr *); +extern int pid_getattr(struct user_namespace *, const struct path *, + struct kstat *, u32, unsigned int); +extern int proc_setattr(struct user_namespace *, struct dentry *, + struct iattr *); extern void proc_pid_evict_inode(struct proc_inode *); extern struct inode *proc_pid_make_inode(struct super_block *, struct task_struct *, umode_t); extern void pid_update_inode(struct task_struct *, struct inode *); diff --git a/fs/proc/proc_net.c b/fs/proc/proc_net.c index 4aef49ccf571..15c2e55d2ed2 100644 --- a/fs/proc/proc_net.c +++ b/fs/proc/proc_net.c @@ -289,7 +289,8 @@ static struct dentry *proc_tgid_net_lookup(struct inode *dir, return de; } -static int proc_tgid_net_getattr(const struct path *path, struct kstat *stat, +static int proc_tgid_net_getattr(struct user_namespace *mnt_userns, + const struct path *path, struct kstat *stat, u32 request_mask, unsigned int query_flags) { struct inode *inode = d_inode(path->dentry); diff --git a/fs/proc/proc_sysctl.c b/fs/proc/proc_sysctl.c index 87c828348140..2daac06727d0 100644 --- a/fs/proc/proc_sysctl.c +++ b/fs/proc/proc_sysctl.c @@ -785,7 +785,8 @@ out: return 0; } -static int proc_sys_permission(struct inode *inode, int mask) +static int proc_sys_permission(struct user_namespace *mnt_userns, + struct inode *inode, int mask) { /* * sysctl entries that are not writeable, @@ -813,7 +814,8 @@ static int proc_sys_permission(struct inode *inode, int mask) return error; } -static int proc_sys_setattr(struct dentry *dentry, struct iattr *attr) +static int proc_sys_setattr(struct user_namespace *mnt_userns, + struct dentry *dentry, struct iattr *attr) { struct inode *inode = d_inode(dentry); int error; @@ -830,7 +832,8 @@ static int proc_sys_setattr(struct dentry *dentry, struct iattr *attr) return 0; } -static int proc_sys_getattr(const struct path *path, struct kstat *stat, +static int proc_sys_getattr(struct user_namespace *mnt_userns, + const struct path *path, struct kstat *stat, u32 request_mask, unsigned int query_flags) { struct inode *inode = d_inode(path->dentry); diff --git a/fs/proc/root.c b/fs/proc/root.c index 244e4b6f15ef..c7e3b1350ef8 100644 --- a/fs/proc/root.c +++ b/fs/proc/root.c @@ -308,7 +308,8 @@ void __init proc_root_init(void) register_filesystem(&proc_fs_type); } -static int proc_root_getattr(const struct path *path, struct kstat *stat, +static int proc_root_getattr(struct user_namespace *mnt_userns, + const struct path *path, struct kstat *stat, u32 request_mask, unsigned int query_flags) { generic_fillattr(&init_user_ns, d_inode(path->dentry), stat); diff --git a/fs/ramfs/file-nommu.c b/fs/ramfs/file-nommu.c index f0358fe410d3..ba3525ccc27e 100644 --- a/fs/ramfs/file-nommu.c +++ b/fs/ramfs/file-nommu.c @@ -22,7 +22,7 @@ #include #include "internal.h" -static int ramfs_nommu_setattr(struct dentry *, struct iattr *); +static int ramfs_nommu_setattr(struct user_namespace *, struct dentry *, struct iattr *); static unsigned long ramfs_nommu_get_unmapped_area(struct file *file, unsigned long addr, unsigned long len, @@ -158,7 +158,8 @@ static int ramfs_nommu_resize(struct inode *inode, loff_t newsize, loff_t size) * handle a change of attributes * - we're specifically interested in a change of size */ -static int ramfs_nommu_setattr(struct dentry *dentry, struct iattr *ia) +static int ramfs_nommu_setattr(struct user_namespace *mnt_userns, + struct dentry *dentry, struct iattr *ia) { struct inode *inode = d_inode(dentry); unsigned int old_ia_valid = ia->ia_valid; diff --git a/fs/ramfs/inode.c b/fs/ramfs/inode.c index 3fd4326f36b5..3c2658c8fde0 100644 --- a/fs/ramfs/inode.c +++ b/fs/ramfs/inode.c @@ -101,7 +101,8 @@ struct inode *ramfs_get_inode(struct super_block *sb, */ /* SMP-safe */ static int -ramfs_mknod(struct inode *dir, struct dentry *dentry, umode_t mode, dev_t dev) +ramfs_mknod(struct user_namespace *mnt_userns, struct inode *dir, + struct dentry *dentry, umode_t mode, dev_t dev) { struct inode * inode = ramfs_get_inode(dir->i_sb, dir, mode, dev); int error = -ENOSPC; @@ -115,20 +116,23 @@ ramfs_mknod(struct inode *dir, struct dentry *dentry, umode_t mode, dev_t dev) return error; } -static int ramfs_mkdir(struct inode * dir, struct dentry * dentry, umode_t mode) +static int ramfs_mkdir(struct user_namespace *mnt_userns, struct inode *dir, + struct dentry *dentry, umode_t mode) { - int retval = ramfs_mknod(dir, dentry, mode | S_IFDIR, 0); + int retval = ramfs_mknod(&init_user_ns, dir, dentry, mode | S_IFDIR, 0); if (!retval) inc_nlink(dir); return retval; } -static int ramfs_create(struct inode *dir, struct dentry *dentry, umode_t mode, bool excl) +static int ramfs_create(struct user_namespace *mnt_userns, struct inode *dir, + struct dentry *dentry, umode_t mode, bool excl) { - return ramfs_mknod(dir, dentry, mode | S_IFREG, 0); + return ramfs_mknod(&init_user_ns, dir, dentry, mode | S_IFREG, 0); } -static int ramfs_symlink(struct inode * dir, struct dentry *dentry, const char * symname) +static int ramfs_symlink(struct user_namespace *mnt_userns, struct inode *dir, + struct dentry *dentry, const char *symname) { struct inode *inode; int error = -ENOSPC; diff --git a/fs/reiserfs/acl.h b/fs/reiserfs/acl.h index 0c1c847f992f..fd58618da360 100644 --- a/fs/reiserfs/acl.h +++ b/fs/reiserfs/acl.h @@ -49,7 +49,8 @@ static inline int reiserfs_acl_count(size_t size) #ifdef CONFIG_REISERFS_FS_POSIX_ACL struct posix_acl *reiserfs_get_acl(struct inode *inode, int type); -int reiserfs_set_acl(struct inode *inode, struct posix_acl *acl, int type); +int reiserfs_set_acl(struct user_namespace *mnt_userns, struct inode *inode, + struct posix_acl *acl, int type); int reiserfs_acl_chmod(struct inode *inode); int reiserfs_inherit_default_acl(struct reiserfs_transaction_handle *th, struct inode *dir, struct dentry *dentry, diff --git a/fs/reiserfs/inode.c b/fs/reiserfs/inode.c index 944f2b487cf8..780bb90c1804 100644 --- a/fs/reiserfs/inode.c +++ b/fs/reiserfs/inode.c @@ -3282,7 +3282,8 @@ static ssize_t reiserfs_direct_IO(struct kiocb *iocb, struct iov_iter *iter) return ret; } -int reiserfs_setattr(struct dentry *dentry, struct iattr *attr) +int reiserfs_setattr(struct user_namespace *mnt_userns, struct dentry *dentry, + struct iattr *attr) { struct inode *inode = d_inode(dentry); unsigned int ia_valid; diff --git a/fs/reiserfs/namei.c b/fs/reiserfs/namei.c index a67a7d371725..e6eb05e2b2f1 100644 --- a/fs/reiserfs/namei.c +++ b/fs/reiserfs/namei.c @@ -619,8 +619,8 @@ static int new_inode_init(struct inode *inode, struct inode *dir, umode_t mode) return dquot_initialize(inode); } -static int reiserfs_create(struct inode *dir, struct dentry *dentry, umode_t mode, - bool excl) +static int reiserfs_create(struct user_namespace *mnt_userns, struct inode *dir, + struct dentry *dentry, umode_t mode, bool excl) { int retval; struct inode *inode; @@ -698,8 +698,8 @@ out_failed: return retval; } -static int reiserfs_mknod(struct inode *dir, struct dentry *dentry, umode_t mode, - dev_t rdev) +static int reiserfs_mknod(struct user_namespace *mnt_userns, struct inode *dir, + struct dentry *dentry, umode_t mode, dev_t rdev) { int retval; struct inode *inode; @@ -781,7 +781,8 @@ out_failed: return retval; } -static int reiserfs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode) +static int reiserfs_mkdir(struct user_namespace *mnt_userns, struct inode *dir, + struct dentry *dentry, umode_t mode) { int retval; struct inode *inode; @@ -1094,8 +1095,9 @@ out_unlink: return retval; } -static int reiserfs_symlink(struct inode *parent_dir, - struct dentry *dentry, const char *symname) +static int reiserfs_symlink(struct user_namespace *mnt_userns, + struct inode *parent_dir, struct dentry *dentry, + const char *symname) { int retval; struct inode *inode; @@ -1304,7 +1306,8 @@ static void set_ino_in_dir_entry(struct reiserfs_dir_entry *de, * one path. If it holds 2 or more, it can get into endless waiting in * get_empty_nodes or its clones */ -static int reiserfs_rename(struct inode *old_dir, struct dentry *old_dentry, +static int reiserfs_rename(struct user_namespace *mnt_userns, + struct inode *old_dir, struct dentry *old_dentry, struct inode *new_dir, struct dentry *new_dentry, unsigned int flags) { diff --git a/fs/reiserfs/reiserfs.h b/fs/reiserfs/reiserfs.h index f69871516167..0ca2ac62e534 100644 --- a/fs/reiserfs/reiserfs.h +++ b/fs/reiserfs/reiserfs.h @@ -3102,7 +3102,8 @@ static inline void reiserfs_update_sd(struct reiserfs_transaction_handle *th, } void sd_attrs_to_i_attrs(__u16 sd_attrs, struct inode *inode); -int reiserfs_setattr(struct dentry *dentry, struct iattr *attr); +int reiserfs_setattr(struct user_namespace *mnt_userns, struct dentry *dentry, + struct iattr *attr); int __reiserfs_write_begin(struct page *page, unsigned from, unsigned len); diff --git a/fs/reiserfs/xattr.c b/fs/reiserfs/xattr.c index ec440d1957a1..bd073836e141 100644 --- a/fs/reiserfs/xattr.c +++ b/fs/reiserfs/xattr.c @@ -66,14 +66,14 @@ static int xattr_create(struct inode *dir, struct dentry *dentry, int mode) { BUG_ON(!inode_is_locked(dir)); - return dir->i_op->create(dir, dentry, mode, true); + return dir->i_op->create(&init_user_ns, dir, dentry, mode, true); } #endif static int xattr_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode) { BUG_ON(!inode_is_locked(dir)); - return dir->i_op->mkdir(dir, dentry, mode); + return dir->i_op->mkdir(&init_user_ns, dir, dentry, mode); } /* @@ -352,7 +352,7 @@ static int chown_one_xattr(struct dentry *dentry, void *data) * ATTR_MODE is set. */ attrs->ia_valid &= (ATTR_UID|ATTR_GID); - err = reiserfs_setattr(dentry, attrs); + err = reiserfs_setattr(&init_user_ns, dentry, attrs); attrs->ia_valid = ia_valid; return err; @@ -604,7 +604,7 @@ reiserfs_xattr_set_handle(struct reiserfs_transaction_handle *th, inode_lock_nested(d_inode(dentry), I_MUTEX_XATTR); inode_dio_wait(d_inode(dentry)); - err = reiserfs_setattr(dentry, &newattrs); + err = reiserfs_setattr(&init_user_ns, dentry, &newattrs); inode_unlock(d_inode(dentry)); } else update_ctime(inode); @@ -948,7 +948,8 @@ static int xattr_mount_check(struct super_block *s) return 0; } -int reiserfs_permission(struct inode *inode, int mask) +int reiserfs_permission(struct user_namespace *mnt_userns, struct inode *inode, + int mask) { /* * We don't do permission checks on the internal objects. diff --git a/fs/reiserfs/xattr.h b/fs/reiserfs/xattr.h index c764352447ba..9b3b06da568c 100644 --- a/fs/reiserfs/xattr.h +++ b/fs/reiserfs/xattr.h @@ -16,7 +16,8 @@ int reiserfs_xattr_init(struct super_block *sb, int mount_flags); int reiserfs_lookup_privroot(struct super_block *sb); int reiserfs_delete_xattrs(struct inode *inode); int reiserfs_chown_xattrs(struct inode *inode, struct iattr *attrs); -int reiserfs_permission(struct inode *inode, int mask); +int reiserfs_permission(struct user_namespace *mnt_userns, + struct inode *inode, int mask); #ifdef CONFIG_REISERFS_FS_XATTR #define has_xattr_dir(inode) (REISERFS_I(inode)->i_flags & i_has_xattr_dir) diff --git a/fs/reiserfs/xattr_acl.c b/fs/reiserfs/xattr_acl.c index 4bf976bc7bad..a9547144a099 100644 --- a/fs/reiserfs/xattr_acl.c +++ b/fs/reiserfs/xattr_acl.c @@ -18,7 +18,8 @@ static int __reiserfs_set_acl(struct reiserfs_transaction_handle *th, int -reiserfs_set_acl(struct inode *inode, struct posix_acl *acl, int type) +reiserfs_set_acl(struct user_namespace *mnt_userns, struct inode *inode, + struct posix_acl *acl, int type) { int error, error2; struct reiserfs_transaction_handle th; diff --git a/fs/stat.c b/fs/stat.c index 2c471c2fd766..fbc171d038aa 100644 --- a/fs/stat.c +++ b/fs/stat.c @@ -75,6 +75,7 @@ EXPORT_SYMBOL(generic_fillattr); int vfs_getattr_nosec(const struct path *path, struct kstat *stat, u32 request_mask, unsigned int query_flags) { + struct user_namespace *mnt_userns; struct inode *inode = d_backing_inode(path->dentry); memset(stat, 0, sizeof(*stat)); @@ -91,11 +92,12 @@ int vfs_getattr_nosec(const struct path *path, struct kstat *stat, if (IS_DAX(inode)) stat->attributes |= STATX_ATTR_DAX; + mnt_userns = mnt_user_ns(path->mnt); if (inode->i_op->getattr) - return inode->i_op->getattr(path, stat, request_mask, - query_flags); + return inode->i_op->getattr(mnt_userns, path, stat, + request_mask, query_flags); - generic_fillattr(mnt_user_ns(path->mnt), inode, stat); + generic_fillattr(mnt_userns, inode, stat); return 0; } EXPORT_SYMBOL(vfs_getattr_nosec); diff --git a/fs/sysv/file.c b/fs/sysv/file.c index ca7e216b7b9e..90e00124ea07 100644 --- a/fs/sysv/file.c +++ b/fs/sysv/file.c @@ -29,7 +29,8 @@ const struct file_operations sysv_file_operations = { .splice_read = generic_file_splice_read, }; -static int sysv_setattr(struct dentry *dentry, struct iattr *attr) +static int sysv_setattr(struct user_namespace *mnt_userns, + struct dentry *dentry, struct iattr *attr) { struct inode *inode = d_inode(dentry); int error; diff --git a/fs/sysv/itree.c b/fs/sysv/itree.c index 83cffab6955f..8b2e99b7bc9f 100644 --- a/fs/sysv/itree.c +++ b/fs/sysv/itree.c @@ -441,8 +441,8 @@ static unsigned sysv_nblocks(struct super_block *s, loff_t size) return blocks; } -int sysv_getattr(const struct path *path, struct kstat *stat, - u32 request_mask, unsigned int flags) +int sysv_getattr(struct user_namespace *mnt_userns, const struct path *path, + struct kstat *stat, u32 request_mask, unsigned int flags) { struct super_block *s = path->dentry->d_sb; generic_fillattr(&init_user_ns, d_inode(path->dentry), stat); diff --git a/fs/sysv/namei.c b/fs/sysv/namei.c index ea2414b385ec..b2e6abc06a2d 100644 --- a/fs/sysv/namei.c +++ b/fs/sysv/namei.c @@ -41,7 +41,8 @@ static struct dentry *sysv_lookup(struct inode * dir, struct dentry * dentry, un return d_splice_alias(inode, dentry); } -static int sysv_mknod(struct inode * dir, struct dentry * dentry, umode_t mode, dev_t rdev) +static int sysv_mknod(struct user_namespace *mnt_userns, struct inode *dir, + struct dentry *dentry, umode_t mode, dev_t rdev) { struct inode * inode; int err; @@ -60,13 +61,14 @@ static int sysv_mknod(struct inode * dir, struct dentry * dentry, umode_t mode, return err; } -static int sysv_create(struct inode * dir, struct dentry * dentry, umode_t mode, bool excl) +static int sysv_create(struct user_namespace *mnt_userns, struct inode *dir, + struct dentry *dentry, umode_t mode, bool excl) { - return sysv_mknod(dir, dentry, mode, 0); + return sysv_mknod(&init_user_ns, dir, dentry, mode, 0); } -static int sysv_symlink(struct inode * dir, struct dentry * dentry, - const char * symname) +static int sysv_symlink(struct user_namespace *mnt_userns, struct inode *dir, + struct dentry *dentry, const char *symname) { int err = -ENAMETOOLONG; int l = strlen(symname)+1; @@ -108,7 +110,8 @@ static int sysv_link(struct dentry * old_dentry, struct inode * dir, return add_nondir(dentry, inode); } -static int sysv_mkdir(struct inode * dir, struct dentry *dentry, umode_t mode) +static int sysv_mkdir(struct user_namespace *mnt_userns, struct inode *dir, + struct dentry *dentry, umode_t mode) { struct inode * inode; int err; @@ -186,9 +189,9 @@ static int sysv_rmdir(struct inode * dir, struct dentry * dentry) * Anybody can rename anything with this: the permission checks are left to the * higher-level routines. */ -static int sysv_rename(struct inode * old_dir, struct dentry * old_dentry, - struct inode * new_dir, struct dentry * new_dentry, - unsigned int flags) +static int sysv_rename(struct user_namespace *mnt_userns, struct inode *old_dir, + struct dentry *old_dentry, struct inode *new_dir, + struct dentry *new_dentry, unsigned int flags) { struct inode * old_inode = d_inode(old_dentry); struct inode * new_inode = d_inode(new_dentry); diff --git a/fs/sysv/sysv.h b/fs/sysv/sysv.h index 1cff585526b1..99ddf033da4f 100644 --- a/fs/sysv/sysv.h +++ b/fs/sysv/sysv.h @@ -141,7 +141,8 @@ extern struct inode *sysv_iget(struct super_block *, unsigned int); extern int sysv_write_inode(struct inode *, struct writeback_control *wbc); extern int sysv_sync_inode(struct inode *); extern void sysv_set_inode(struct inode *, dev_t); -extern int sysv_getattr(const struct path *, struct kstat *, u32, unsigned int); +extern int sysv_getattr(struct user_namespace *, const struct path *, + struct kstat *, u32, unsigned int); extern int sysv_init_icache(void); extern void sysv_destroy_icache(void); diff --git a/fs/tracefs/inode.c b/fs/tracefs/inode.c index 0ee8c6dfb036..4b83cbded559 100644 --- a/fs/tracefs/inode.c +++ b/fs/tracefs/inode.c @@ -67,7 +67,9 @@ static char *get_dname(struct dentry *dentry) return name; } -static int tracefs_syscall_mkdir(struct inode *inode, struct dentry *dentry, umode_t mode) +static int tracefs_syscall_mkdir(struct user_namespace *mnt_userns, + struct inode *inode, struct dentry *dentry, + umode_t mode) { char *name; int ret; diff --git a/fs/ubifs/dir.c b/fs/ubifs/dir.c index a8881ed61620..d9d8d7794eff 100644 --- a/fs/ubifs/dir.c +++ b/fs/ubifs/dir.c @@ -280,8 +280,8 @@ static int ubifs_prepare_create(struct inode *dir, struct dentry *dentry, return fscrypt_setup_filename(dir, &dentry->d_name, 0, nm); } -static int ubifs_create(struct inode *dir, struct dentry *dentry, umode_t mode, - bool excl) +static int ubifs_create(struct user_namespace *mnt_userns, struct inode *dir, + struct dentry *dentry, umode_t mode, bool excl) { struct inode *inode; struct ubifs_info *c = dir->i_sb->s_fs_info; @@ -441,8 +441,8 @@ out_budg: return err; } -static int ubifs_tmpfile(struct inode *dir, struct dentry *dentry, - umode_t mode) +static int ubifs_tmpfile(struct user_namespace *mnt_userns, struct inode *dir, + struct dentry *dentry, umode_t mode) { return do_tmpfile(dir, dentry, mode, NULL); } @@ -942,7 +942,8 @@ out_fname: return err; } -static int ubifs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode) +static int ubifs_mkdir(struct user_namespace *mnt_userns, struct inode *dir, + struct dentry *dentry, umode_t mode) { struct inode *inode; struct ubifs_inode *dir_ui = ubifs_inode(dir); @@ -1013,8 +1014,8 @@ out_budg: return err; } -static int ubifs_mknod(struct inode *dir, struct dentry *dentry, - umode_t mode, dev_t rdev) +static int ubifs_mknod(struct user_namespace *mnt_userns, struct inode *dir, + struct dentry *dentry, umode_t mode, dev_t rdev) { struct inode *inode; struct ubifs_inode *ui; @@ -1102,8 +1103,8 @@ out_budg: return err; } -static int ubifs_symlink(struct inode *dir, struct dentry *dentry, - const char *symname) +static int ubifs_symlink(struct user_namespace *mnt_userns, struct inode *dir, + struct dentry *dentry, const char *symname) { struct inode *inode; struct ubifs_inode *ui; @@ -1542,7 +1543,8 @@ static int ubifs_xrename(struct inode *old_dir, struct dentry *old_dentry, return err; } -static int ubifs_rename(struct inode *old_dir, struct dentry *old_dentry, +static int ubifs_rename(struct user_namespace *mnt_userns, + struct inode *old_dir, struct dentry *old_dentry, struct inode *new_dir, struct dentry *new_dentry, unsigned int flags) { @@ -1566,8 +1568,8 @@ static int ubifs_rename(struct inode *old_dir, struct dentry *old_dentry, return do_rename(old_dir, old_dentry, new_dir, new_dentry, flags); } -int ubifs_getattr(const struct path *path, struct kstat *stat, - u32 request_mask, unsigned int flags) +int ubifs_getattr(struct user_namespace *mnt_userns, const struct path *path, + struct kstat *stat, u32 request_mask, unsigned int flags) { loff_t size; struct inode *inode = d_inode(path->dentry); diff --git a/fs/ubifs/file.c b/fs/ubifs/file.c index 76ef392b1e41..0e4b4be3aa26 100644 --- a/fs/ubifs/file.c +++ b/fs/ubifs/file.c @@ -1257,7 +1257,8 @@ static int do_setattr(struct ubifs_info *c, struct inode *inode, return err; } -int ubifs_setattr(struct dentry *dentry, struct iattr *attr) +int ubifs_setattr(struct user_namespace *mnt_userns, struct dentry *dentry, + struct iattr *attr) { int err; struct inode *inode = d_inode(dentry); diff --git a/fs/ubifs/ubifs.h b/fs/ubifs/ubifs.h index fc2cdde3b549..7fdfdbda4b8a 100644 --- a/fs/ubifs/ubifs.h +++ b/fs/ubifs/ubifs.h @@ -1989,13 +1989,14 @@ int ubifs_calc_dark(const struct ubifs_info *c, int spc); /* file.c */ int ubifs_fsync(struct file *file, loff_t start, loff_t end, int datasync); -int ubifs_setattr(struct dentry *dentry, struct iattr *attr); +int ubifs_setattr(struct user_namespace *mnt_userns, struct dentry *dentry, + struct iattr *attr); int ubifs_update_time(struct inode *inode, struct timespec64 *time, int flags); /* dir.c */ struct inode *ubifs_new_inode(struct ubifs_info *c, struct inode *dir, umode_t mode); -int ubifs_getattr(const struct path *path, struct kstat *stat, +int ubifs_getattr(struct user_namespace *mnt_userns, const struct path *path, struct kstat *stat, u32 request_mask, unsigned int flags); int ubifs_check_dir_empty(struct inode *dir); diff --git a/fs/udf/file.c b/fs/udf/file.c index 7c7d161315c2..2846dcd92197 100644 --- a/fs/udf/file.c +++ b/fs/udf/file.c @@ -253,7 +253,8 @@ const struct file_operations udf_file_operations = { .llseek = generic_file_llseek, }; -static int udf_setattr(struct dentry *dentry, struct iattr *attr) +static int udf_setattr(struct user_namespace *mnt_userns, struct dentry *dentry, + struct iattr *attr) { struct inode *inode = d_inode(dentry); struct super_block *sb = inode->i_sb; diff --git a/fs/udf/namei.c b/fs/udf/namei.c index e169d8fe35b5..f146b3089f3d 100644 --- a/fs/udf/namei.c +++ b/fs/udf/namei.c @@ -604,8 +604,8 @@ static int udf_add_nondir(struct dentry *dentry, struct inode *inode) return 0; } -static int udf_create(struct inode *dir, struct dentry *dentry, umode_t mode, - bool excl) +static int udf_create(struct user_namespace *mnt_userns, struct inode *dir, + struct dentry *dentry, umode_t mode, bool excl) { struct inode *inode = udf_new_inode(dir, mode); @@ -623,7 +623,8 @@ static int udf_create(struct inode *dir, struct dentry *dentry, umode_t mode, return udf_add_nondir(dentry, inode); } -static int udf_tmpfile(struct inode *dir, struct dentry *dentry, umode_t mode) +static int udf_tmpfile(struct user_namespace *mnt_userns, struct inode *dir, + struct dentry *dentry, umode_t mode) { struct inode *inode = udf_new_inode(dir, mode); @@ -642,8 +643,8 @@ static int udf_tmpfile(struct inode *dir, struct dentry *dentry, umode_t mode) return 0; } -static int udf_mknod(struct inode *dir, struct dentry *dentry, umode_t mode, - dev_t rdev) +static int udf_mknod(struct user_namespace *mnt_userns, struct inode *dir, + struct dentry *dentry, umode_t mode, dev_t rdev) { struct inode *inode; @@ -658,7 +659,8 @@ static int udf_mknod(struct inode *dir, struct dentry *dentry, umode_t mode, return udf_add_nondir(dentry, inode); } -static int udf_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode) +static int udf_mkdir(struct user_namespace *mnt_userns, struct inode *dir, + struct dentry *dentry, umode_t mode) { struct inode *inode; struct udf_fileident_bh fibh; @@ -877,8 +879,8 @@ out: return retval; } -static int udf_symlink(struct inode *dir, struct dentry *dentry, - const char *symname) +static int udf_symlink(struct user_namespace *mnt_userns, struct inode *dir, + struct dentry *dentry, const char *symname) { struct inode *inode = udf_new_inode(dir, S_IFLNK | 0777); struct pathComponent *pc; @@ -1065,9 +1067,9 @@ static int udf_link(struct dentry *old_dentry, struct inode *dir, /* Anybody can rename anything with this: the permission checks are left to the * higher-level routines. */ -static int udf_rename(struct inode *old_dir, struct dentry *old_dentry, - struct inode *new_dir, struct dentry *new_dentry, - unsigned int flags) +static int udf_rename(struct user_namespace *mnt_userns, struct inode *old_dir, + struct dentry *old_dentry, struct inode *new_dir, + struct dentry *new_dentry, unsigned int flags) { struct inode *old_inode = d_inode(old_dentry); struct inode *new_inode = d_inode(new_dentry); diff --git a/fs/udf/symlink.c b/fs/udf/symlink.c index 54a44d1f023c..9b223421a3c5 100644 --- a/fs/udf/symlink.c +++ b/fs/udf/symlink.c @@ -152,8 +152,9 @@ out_unmap: return err; } -static int udf_symlink_getattr(const struct path *path, struct kstat *stat, - u32 request_mask, unsigned int flags) +static int udf_symlink_getattr(struct user_namespace *mnt_userns, + const struct path *path, struct kstat *stat, + u32 request_mask, unsigned int flags) { struct dentry *dentry = path->dentry; struct inode *inode = d_backing_inode(dentry); diff --git a/fs/ufs/inode.c b/fs/ufs/inode.c index 6b51f3b20143..debc282c1bb4 100644 --- a/fs/ufs/inode.c +++ b/fs/ufs/inode.c @@ -1211,7 +1211,8 @@ out: return err; } -int ufs_setattr(struct dentry *dentry, struct iattr *attr) +int ufs_setattr(struct user_namespace *mnt_userns, struct dentry *dentry, + struct iattr *attr) { struct inode *inode = d_inode(dentry); unsigned int ia_valid = attr->ia_valid; diff --git a/fs/ufs/namei.c b/fs/ufs/namei.c index 9ef40f100415..29d5a0e0c8f0 100644 --- a/fs/ufs/namei.c +++ b/fs/ufs/namei.c @@ -69,7 +69,8 @@ static struct dentry *ufs_lookup(struct inode * dir, struct dentry *dentry, unsi * If the create succeeds, we fill in the inode information * with d_instantiate(). */ -static int ufs_create (struct inode * dir, struct dentry * dentry, umode_t mode, +static int ufs_create (struct user_namespace * mnt_userns, + struct inode * dir, struct dentry * dentry, umode_t mode, bool excl) { struct inode *inode; @@ -85,7 +86,8 @@ static int ufs_create (struct inode * dir, struct dentry * dentry, umode_t mode, return ufs_add_nondir(dentry, inode); } -static int ufs_mknod(struct inode *dir, struct dentry *dentry, umode_t mode, dev_t rdev) +static int ufs_mknod(struct user_namespace *mnt_userns, struct inode *dir, + struct dentry *dentry, umode_t mode, dev_t rdev) { struct inode *inode; int err; @@ -104,8 +106,8 @@ static int ufs_mknod(struct inode *dir, struct dentry *dentry, umode_t mode, dev return err; } -static int ufs_symlink (struct inode * dir, struct dentry * dentry, - const char * symname) +static int ufs_symlink (struct user_namespace * mnt_userns, struct inode * dir, + struct dentry * dentry, const char * symname) { struct super_block * sb = dir->i_sb; int err; @@ -164,7 +166,8 @@ static int ufs_link (struct dentry * old_dentry, struct inode * dir, return error; } -static int ufs_mkdir(struct inode * dir, struct dentry * dentry, umode_t mode) +static int ufs_mkdir(struct user_namespace * mnt_userns, struct inode * dir, + struct dentry * dentry, umode_t mode) { struct inode * inode; int err; @@ -240,9 +243,9 @@ static int ufs_rmdir (struct inode * dir, struct dentry *dentry) return err; } -static int ufs_rename(struct inode *old_dir, struct dentry *old_dentry, - struct inode *new_dir, struct dentry *new_dentry, - unsigned int flags) +static int ufs_rename(struct user_namespace *mnt_userns, struct inode *old_dir, + struct dentry *old_dentry, struct inode *new_dir, + struct dentry *new_dentry, unsigned int flags) { struct inode *old_inode = d_inode(old_dentry); struct inode *new_inode = d_inode(new_dentry); diff --git a/fs/ufs/ufs.h b/fs/ufs/ufs.h index b49e0efdf3d7..550f7c5a3636 100644 --- a/fs/ufs/ufs.h +++ b/fs/ufs/ufs.h @@ -123,7 +123,8 @@ extern struct inode *ufs_iget(struct super_block *, unsigned long); extern int ufs_write_inode (struct inode *, struct writeback_control *); extern int ufs_sync_inode (struct inode *); extern void ufs_evict_inode (struct inode *); -extern int ufs_setattr(struct dentry *dentry, struct iattr *attr); +extern int ufs_setattr(struct user_namespace *mnt_userns, struct dentry *dentry, + struct iattr *attr); /* namei.c */ extern const struct file_operations ufs_dir_operations; diff --git a/fs/vboxsf/dir.c b/fs/vboxsf/dir.c index 4d569f14a8d8..7aee0ec63ade 100644 --- a/fs/vboxsf/dir.c +++ b/fs/vboxsf/dir.c @@ -288,13 +288,15 @@ static int vboxsf_dir_create(struct inode *parent, struct dentry *dentry, return 0; } -static int vboxsf_dir_mkfile(struct inode *parent, struct dentry *dentry, +static int vboxsf_dir_mkfile(struct user_namespace *mnt_userns, + struct inode *parent, struct dentry *dentry, umode_t mode, bool excl) { return vboxsf_dir_create(parent, dentry, mode, 0); } -static int vboxsf_dir_mkdir(struct inode *parent, struct dentry *dentry, +static int vboxsf_dir_mkdir(struct user_namespace *mnt_userns, + struct inode *parent, struct dentry *dentry, umode_t mode) { return vboxsf_dir_create(parent, dentry, mode, 1); @@ -332,7 +334,8 @@ static int vboxsf_dir_unlink(struct inode *parent, struct dentry *dentry) return 0; } -static int vboxsf_dir_rename(struct inode *old_parent, +static int vboxsf_dir_rename(struct user_namespace *mnt_userns, + struct inode *old_parent, struct dentry *old_dentry, struct inode *new_parent, struct dentry *new_dentry, @@ -374,7 +377,8 @@ err_put_old_path: return err; } -static int vboxsf_dir_symlink(struct inode *parent, struct dentry *dentry, +static int vboxsf_dir_symlink(struct user_namespace *mnt_userns, + struct inode *parent, struct dentry *dentry, const char *symname) { struct vboxsf_inode *sf_parent_i = VBOXSF_I(parent); diff --git a/fs/vboxsf/utils.c b/fs/vboxsf/utils.c index d2cd1c99f48e..3b847e3fba24 100644 --- a/fs/vboxsf/utils.c +++ b/fs/vboxsf/utils.c @@ -212,8 +212,8 @@ int vboxsf_inode_revalidate(struct dentry *dentry) return 0; } -int vboxsf_getattr(const struct path *path, struct kstat *kstat, - u32 request_mask, unsigned int flags) +int vboxsf_getattr(struct user_namespace *mnt_userns, const struct path *path, + struct kstat *kstat, u32 request_mask, unsigned int flags) { int err; struct dentry *dentry = path->dentry; @@ -237,7 +237,8 @@ int vboxsf_getattr(const struct path *path, struct kstat *kstat, return 0; } -int vboxsf_setattr(struct dentry *dentry, struct iattr *iattr) +int vboxsf_setattr(struct user_namespace *mnt_userns, struct dentry *dentry, + struct iattr *iattr) { struct vboxsf_inode *sf_i = VBOXSF_I(d_inode(dentry)); struct vboxsf_sbi *sbi = VBOXSF_SBI(dentry->d_sb); diff --git a/fs/vboxsf/vfsmod.h b/fs/vboxsf/vfsmod.h index 18f95b00fc33..760524e78c88 100644 --- a/fs/vboxsf/vfsmod.h +++ b/fs/vboxsf/vfsmod.h @@ -90,9 +90,11 @@ int vboxsf_stat(struct vboxsf_sbi *sbi, struct shfl_string *path, struct shfl_fsobjinfo *info); int vboxsf_stat_dentry(struct dentry *dentry, struct shfl_fsobjinfo *info); int vboxsf_inode_revalidate(struct dentry *dentry); -int vboxsf_getattr(const struct path *path, struct kstat *kstat, - u32 request_mask, unsigned int query_flags); -int vboxsf_setattr(struct dentry *dentry, struct iattr *iattr); +int vboxsf_getattr(struct user_namespace *mnt_userns, const struct path *path, + struct kstat *kstat, u32 request_mask, + unsigned int query_flags); +int vboxsf_setattr(struct user_namespace *mnt_userns, struct dentry *dentry, + struct iattr *iattr); struct shfl_string *vboxsf_path_from_dentry(struct vboxsf_sbi *sbi, struct dentry *dentry); int vboxsf_nlscpy(struct vboxsf_sbi *sbi, char *name, size_t name_bound_len, diff --git a/fs/xfs/xfs_acl.c b/fs/xfs/xfs_acl.c index 368351298bd5..332e87153c6c 100644 --- a/fs/xfs/xfs_acl.c +++ b/fs/xfs/xfs_acl.c @@ -238,7 +238,8 @@ xfs_acl_set_mode( } int -xfs_set_acl(struct inode *inode, struct posix_acl *acl, int type) +xfs_set_acl(struct user_namespace *mnt_userns, struct inode *inode, + struct posix_acl *acl, int type) { umode_t mode; bool set_mode = false; diff --git a/fs/xfs/xfs_acl.h b/fs/xfs/xfs_acl.h index c042c0868016..7bdb3a4ed798 100644 --- a/fs/xfs/xfs_acl.h +++ b/fs/xfs/xfs_acl.h @@ -11,7 +11,8 @@ struct posix_acl; #ifdef CONFIG_XFS_POSIX_ACL extern struct posix_acl *xfs_get_acl(struct inode *inode, int type); -extern int xfs_set_acl(struct inode *inode, struct posix_acl *acl, int type); +extern int xfs_set_acl(struct user_namespace *mnt_userns, struct inode *inode, + struct posix_acl *acl, int type); extern int __xfs_set_acl(struct inode *inode, struct posix_acl *acl, int type); void xfs_forget_acl(struct inode *inode, const char *name); #else diff --git a/fs/xfs/xfs_iops.c b/fs/xfs/xfs_iops.c index 26d22edef741..f5dfa128af64 100644 --- a/fs/xfs/xfs_iops.c +++ b/fs/xfs/xfs_iops.c @@ -220,29 +220,32 @@ xfs_generic_create( STATIC int xfs_vn_mknod( - struct inode *dir, - struct dentry *dentry, - umode_t mode, - dev_t rdev) + struct user_namespace *mnt_userns, + struct inode *dir, + struct dentry *dentry, + umode_t mode, + dev_t rdev) { return xfs_generic_create(dir, dentry, mode, rdev, false); } STATIC int xfs_vn_create( - struct inode *dir, - struct dentry *dentry, - umode_t mode, - bool flags) + struct user_namespace *mnt_userns, + struct inode *dir, + struct dentry *dentry, + umode_t mode, + bool flags) { return xfs_generic_create(dir, dentry, mode, 0, false); } STATIC int xfs_vn_mkdir( - struct inode *dir, - struct dentry *dentry, - umode_t mode) + struct user_namespace *mnt_userns, + struct inode *dir, + struct dentry *dentry, + umode_t mode) { return xfs_generic_create(dir, dentry, mode | S_IFDIR, 0, false); } @@ -361,9 +364,10 @@ xfs_vn_unlink( STATIC int xfs_vn_symlink( - struct inode *dir, - struct dentry *dentry, - const char *symname) + struct user_namespace *mnt_userns, + struct inode *dir, + struct dentry *dentry, + const char *symname) { struct inode *inode; struct xfs_inode *cip = NULL; @@ -403,11 +407,12 @@ xfs_vn_symlink( STATIC int xfs_vn_rename( - struct inode *odir, - struct dentry *odentry, - struct inode *ndir, - struct dentry *ndentry, - unsigned int flags) + struct user_namespace *mnt_userns, + struct inode *odir, + struct dentry *odentry, + struct inode *ndir, + struct dentry *ndentry, + unsigned int flags) { struct inode *new_inode = d_inode(ndentry); int omode = 0; @@ -529,6 +534,7 @@ xfs_stat_blksize( STATIC int xfs_vn_getattr( + struct user_namespace *mnt_userns, const struct path *path, struct kstat *stat, u32 request_mask, @@ -1047,6 +1053,7 @@ xfs_vn_setattr_size( STATIC int xfs_vn_setattr( + struct user_namespace *mnt_userns, struct dentry *dentry, struct iattr *iattr) { @@ -1144,9 +1151,10 @@ xfs_vn_fiemap( STATIC int xfs_vn_tmpfile( - struct inode *dir, - struct dentry *dentry, - umode_t mode) + struct user_namespace *mnt_userns, + struct inode *dir, + struct dentry *dentry, + umode_t mode) { return xfs_generic_create(dir, dentry, mode, 0, true); } diff --git a/fs/zonefs/super.c b/fs/zonefs/super.c index 8a1f69677784..76e45d66d4ce 100644 --- a/fs/zonefs/super.c +++ b/fs/zonefs/super.c @@ -480,7 +480,8 @@ unlock: return ret; } -static int zonefs_inode_setattr(struct dentry *dentry, struct iattr *iattr) +static int zonefs_inode_setattr(struct user_namespace *mnt_userns, + struct dentry *dentry, struct iattr *iattr) { struct inode *inode = d_inode(dentry); int ret; diff --git a/include/linux/fs.h b/include/linux/fs.h index f0601cca1930..7762d3d75230 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -1930,22 +1930,28 @@ struct file_operations { struct inode_operations { struct dentry * (*lookup) (struct inode *,struct dentry *, unsigned int); const char * (*get_link) (struct dentry *, struct inode *, struct delayed_call *); - int (*permission) (struct inode *, int); + int (*permission) (struct user_namespace *, struct inode *, int); struct posix_acl * (*get_acl)(struct inode *, int); int (*readlink) (struct dentry *, char __user *,int); - int (*create) (struct inode *,struct dentry *, umode_t, bool); + int (*create) (struct user_namespace *, struct inode *,struct dentry *, + umode_t, bool); int (*link) (struct dentry *,struct inode *,struct dentry *); int (*unlink) (struct inode *,struct dentry *); - int (*symlink) (struct inode *,struct dentry *,const char *); - int (*mkdir) (struct inode *,struct dentry *,umode_t); + int (*symlink) (struct user_namespace *, struct inode *,struct dentry *, + const char *); + int (*mkdir) (struct user_namespace *, struct inode *,struct dentry *, + umode_t); int (*rmdir) (struct inode *,struct dentry *); - int (*mknod) (struct inode *,struct dentry *,umode_t,dev_t); - int (*rename) (struct inode *, struct dentry *, + int (*mknod) (struct user_namespace *, struct inode *,struct dentry *, + umode_t,dev_t); + int (*rename) (struct user_namespace *, struct inode *, struct dentry *, struct inode *, struct dentry *, unsigned int); - int (*setattr) (struct dentry *, struct iattr *); - int (*getattr) (const struct path *, struct kstat *, u32, unsigned int); + int (*setattr) (struct user_namespace *, struct dentry *, + struct iattr *); + int (*getattr) (struct user_namespace *, const struct path *, + struct kstat *, u32, unsigned int); ssize_t (*listxattr) (struct dentry *, char *, size_t); int (*fiemap)(struct inode *, struct fiemap_extent_info *, u64 start, u64 len); @@ -1953,8 +1959,10 @@ struct inode_operations { int (*atomic_open)(struct inode *, struct dentry *, struct file *, unsigned open_flag, umode_t create_mode); - int (*tmpfile) (struct inode *, struct dentry *, umode_t); - int (*set_acl)(struct inode *, struct posix_acl *, int); + int (*tmpfile) (struct user_namespace *, struct inode *, + struct dentry *, umode_t); + int (*set_acl)(struct user_namespace *, struct inode *, + struct posix_acl *, int); } ____cacheline_aligned; static inline ssize_t call_read_iter(struct file *file, struct kiocb *kio, @@ -3227,15 +3235,18 @@ extern int dcache_dir_open(struct inode *, struct file *); extern int dcache_dir_close(struct inode *, struct file *); extern loff_t dcache_dir_lseek(struct file *, loff_t, int); extern int dcache_readdir(struct file *, struct dir_context *); -extern int simple_setattr(struct dentry *, struct iattr *); -extern int simple_getattr(const struct path *, struct kstat *, u32, unsigned int); +extern int simple_setattr(struct user_namespace *, struct dentry *, + struct iattr *); +extern int simple_getattr(struct user_namespace *, const struct path *, + struct kstat *, u32, unsigned int); extern int simple_statfs(struct dentry *, struct kstatfs *); extern int simple_open(struct inode *inode, struct file *file); extern int simple_link(struct dentry *, struct inode *, struct dentry *); extern int simple_unlink(struct inode *, struct dentry *); extern int simple_rmdir(struct inode *, struct dentry *); -extern int simple_rename(struct inode *, struct dentry *, - struct inode *, struct dentry *, unsigned int); +extern int simple_rename(struct user_namespace *, struct inode *, + struct dentry *, struct inode *, struct dentry *, + unsigned int); extern void simple_recursive_removal(struct dentry *, void (*callback)(struct dentry *)); extern int noop_fsync(struct file *, loff_t, loff_t, int); diff --git a/include/linux/nfs_fs.h b/include/linux/nfs_fs.h index 681ed98e4ba8..8c6c4e32fc2f 100644 --- a/include/linux/nfs_fs.h +++ b/include/linux/nfs_fs.h @@ -379,10 +379,11 @@ extern int nfs_refresh_inode(struct inode *, struct nfs_fattr *); extern int nfs_post_op_update_inode(struct inode *inode, struct nfs_fattr *fattr); extern int nfs_post_op_update_inode_force_wcc(struct inode *inode, struct nfs_fattr *fattr); extern int nfs_post_op_update_inode_force_wcc_locked(struct inode *inode, struct nfs_fattr *fattr); -extern int nfs_getattr(const struct path *, struct kstat *, u32, unsigned int); +extern int nfs_getattr(struct user_namespace *, const struct path *, + struct kstat *, u32, unsigned int); extern void nfs_access_add_cache(struct inode *, struct nfs_access_entry *); extern void nfs_access_set_mask(struct nfs_access_entry *, u32); -extern int nfs_permission(struct inode *, int); +extern int nfs_permission(struct user_namespace *, struct inode *, int); extern int nfs_open(struct inode *, struct file *); extern int nfs_attribute_cache_expired(struct inode *inode); extern int nfs_revalidate_inode(struct nfs_server *server, struct inode *inode); @@ -390,7 +391,7 @@ extern int __nfs_revalidate_inode(struct nfs_server *, struct inode *); extern bool nfs_mapping_need_revalidate_inode(struct inode *inode); extern int nfs_revalidate_mapping(struct inode *inode, struct address_space *mapping); extern int nfs_revalidate_mapping_rcu(struct inode *inode); -extern int nfs_setattr(struct dentry *, struct iattr *); +extern int nfs_setattr(struct user_namespace *, struct dentry *, struct iattr *); extern void nfs_setattr_update_inode(struct inode *inode, struct iattr *attr, struct nfs_fattr *); extern void nfs_setsecurity(struct inode *inode, struct nfs_fattr *fattr, struct nfs4_label *label); diff --git a/include/linux/posix_acl.h b/include/linux/posix_acl.h index 6dcd8b8f6ab5..307094ebb88c 100644 --- a/include/linux/posix_acl.h +++ b/include/linux/posix_acl.h @@ -79,7 +79,8 @@ extern int posix_acl_create(struct inode *, umode_t *, struct posix_acl **, int posix_acl_update_mode(struct user_namespace *, struct inode *, umode_t *, struct posix_acl **); -extern int simple_set_acl(struct inode *, struct posix_acl *, int); +extern int simple_set_acl(struct user_namespace *, struct inode *, + struct posix_acl *, int); extern int simple_acl_create(struct inode *, struct inode *); struct posix_acl *get_cached_acl(struct inode *inode, int type); diff --git a/ipc/mqueue.c b/ipc/mqueue.c index fcd56e077733..8031464ed4ae 100644 --- a/ipc/mqueue.c +++ b/ipc/mqueue.c @@ -594,8 +594,8 @@ out_unlock: return error; } -static int mqueue_create(struct inode *dir, struct dentry *dentry, - umode_t mode, bool excl) +static int mqueue_create(struct user_namespace *mnt_userns, struct inode *dir, + struct dentry *dentry, umode_t mode, bool excl) { return mqueue_create_attr(dentry, mode, NULL); } diff --git a/kernel/bpf/inode.c b/kernel/bpf/inode.c index 05b1f51d15e0..1576ff331ee4 100644 --- a/kernel/bpf/inode.c +++ b/kernel/bpf/inode.c @@ -152,7 +152,8 @@ static void bpf_dentry_finalize(struct dentry *dentry, struct inode *inode, dir->i_ctime = dir->i_mtime; } -static int bpf_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode) +static int bpf_mkdir(struct user_namespace *mnt_userns, struct inode *dir, + struct dentry *dentry, umode_t mode) { struct inode *inode; @@ -381,8 +382,8 @@ bpf_lookup(struct inode *dir, struct dentry *dentry, unsigned flags) return simple_lookup(dir, dentry, flags); } -static int bpf_symlink(struct inode *dir, struct dentry *dentry, - const char *target) +static int bpf_symlink(struct user_namespace *mnt_userns, struct inode *dir, + struct dentry *dentry, const char *target) { char *link = kstrdup(target, GFP_USER | __GFP_NOWARN); struct inode *inode; diff --git a/mm/shmem.c b/mm/shmem.c index 339d5530d3a9..facdd1a9c524 100644 --- a/mm/shmem.c +++ b/mm/shmem.c @@ -1060,7 +1060,8 @@ void shmem_truncate_range(struct inode *inode, loff_t lstart, loff_t lend) } EXPORT_SYMBOL_GPL(shmem_truncate_range); -static int shmem_getattr(const struct path *path, struct kstat *stat, +static int shmem_getattr(struct user_namespace *mnt_userns, + const struct path *path, struct kstat *stat, u32 request_mask, unsigned int query_flags) { struct inode *inode = path->dentry->d_inode; @@ -1080,7 +1081,8 @@ static int shmem_getattr(const struct path *path, struct kstat *stat, return 0; } -static int shmem_setattr(struct dentry *dentry, struct iattr *attr) +static int shmem_setattr(struct user_namespace *mnt_userns, + struct dentry *dentry, struct iattr *attr) { struct inode *inode = d_inode(dentry); struct shmem_inode_info *info = SHMEM_I(inode); @@ -2917,7 +2919,8 @@ static int shmem_statfs(struct dentry *dentry, struct kstatfs *buf) * File creation. Allocate an inode, and we're done.. */ static int -shmem_mknod(struct inode *dir, struct dentry *dentry, umode_t mode, dev_t dev) +shmem_mknod(struct user_namespace *mnt_userns, struct inode *dir, + struct dentry *dentry, umode_t mode, dev_t dev) { struct inode *inode; int error = -ENOSPC; @@ -2946,7 +2949,8 @@ out_iput: } static int -shmem_tmpfile(struct inode *dir, struct dentry *dentry, umode_t mode) +shmem_tmpfile(struct user_namespace *mnt_userns, struct inode *dir, + struct dentry *dentry, umode_t mode) { struct inode *inode; int error = -ENOSPC; @@ -2969,20 +2973,22 @@ out_iput: return error; } -static int shmem_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode) +static int shmem_mkdir(struct user_namespace *mnt_userns, struct inode *dir, + struct dentry *dentry, umode_t mode) { int error; - if ((error = shmem_mknod(dir, dentry, mode | S_IFDIR, 0))) + if ((error = shmem_mknod(&init_user_ns, dir, dentry, + mode | S_IFDIR, 0))) return error; inc_nlink(dir); return 0; } -static int shmem_create(struct inode *dir, struct dentry *dentry, umode_t mode, - bool excl) +static int shmem_create(struct user_namespace *mnt_userns, struct inode *dir, + struct dentry *dentry, umode_t mode, bool excl) { - return shmem_mknod(dir, dentry, mode | S_IFREG, 0); + return shmem_mknod(&init_user_ns, dir, dentry, mode | S_IFREG, 0); } /* @@ -3062,7 +3068,8 @@ static int shmem_exchange(struct inode *old_dir, struct dentry *old_dentry, stru return 0; } -static int shmem_whiteout(struct inode *old_dir, struct dentry *old_dentry) +static int shmem_whiteout(struct user_namespace *mnt_userns, + struct inode *old_dir, struct dentry *old_dentry) { struct dentry *whiteout; int error; @@ -3071,7 +3078,7 @@ static int shmem_whiteout(struct inode *old_dir, struct dentry *old_dentry) if (!whiteout) return -ENOMEM; - error = shmem_mknod(old_dir, whiteout, + error = shmem_mknod(&init_user_ns, old_dir, whiteout, S_IFCHR | WHITEOUT_MODE, WHITEOUT_DEV); dput(whiteout); if (error) @@ -3094,7 +3101,10 @@ static int shmem_whiteout(struct inode *old_dir, struct dentry *old_dentry) * it exists so that the VFS layer correctly free's it when it * gets overwritten. */ -static int shmem_rename2(struct inode *old_dir, struct dentry *old_dentry, struct inode *new_dir, struct dentry *new_dentry, unsigned int flags) +static int shmem_rename2(struct user_namespace *mnt_userns, + struct inode *old_dir, struct dentry *old_dentry, + struct inode *new_dir, struct dentry *new_dentry, + unsigned int flags) { struct inode *inode = d_inode(old_dentry); int they_are_dirs = S_ISDIR(inode->i_mode); @@ -3111,7 +3121,7 @@ static int shmem_rename2(struct inode *old_dir, struct dentry *old_dentry, struc if (flags & RENAME_WHITEOUT) { int error; - error = shmem_whiteout(old_dir, old_dentry); + error = shmem_whiteout(&init_user_ns, old_dir, old_dentry); if (error) return error; } @@ -3135,7 +3145,8 @@ static int shmem_rename2(struct inode *old_dir, struct dentry *old_dentry, struc return 0; } -static int shmem_symlink(struct inode *dir, struct dentry *dentry, const char *symname) +static int shmem_symlink(struct user_namespace *mnt_userns, struct inode *dir, + struct dentry *dentry, const char *symname) { int error; int len; diff --git a/net/socket.c b/net/socket.c index c76703c6f480..2826698ff97c 100644 --- a/net/socket.c +++ b/net/socket.c @@ -538,9 +538,10 @@ static ssize_t sockfs_listxattr(struct dentry *dentry, char *buffer, return used; } -static int sockfs_setattr(struct dentry *dentry, struct iattr *iattr) +static int sockfs_setattr(struct user_namespace *mnt_userns, + struct dentry *dentry, struct iattr *iattr) { - int err = simple_setattr(dentry, iattr); + int err = simple_setattr(&init_user_ns, dentry, iattr); if (!err && (iattr->ia_valid & ATTR_UID)) { struct socket *sock = SOCKET_I(d_inode(dentry)); diff --git a/security/apparmor/apparmorfs.c b/security/apparmor/apparmorfs.c index f95c6bfa8b8e..2ee3b3d29f10 100644 --- a/security/apparmor/apparmorfs.c +++ b/security/apparmor/apparmorfs.c @@ -1773,7 +1773,8 @@ fail2: return error; } -static int ns_mkdir_op(struct inode *dir, struct dentry *dentry, umode_t mode) +static int ns_mkdir_op(struct user_namespace *mnt_userns, struct inode *dir, + struct dentry *dentry, umode_t mode) { struct aa_ns *ns, *parent; /* TODO: improve permission check */ diff --git a/security/integrity/evm/evm_secfs.c b/security/integrity/evm/evm_secfs.c index cfc3075769bb..bbc85637e18b 100644 --- a/security/integrity/evm/evm_secfs.c +++ b/security/integrity/evm/evm_secfs.c @@ -219,7 +219,7 @@ static ssize_t evm_write_xattrs(struct file *file, const char __user *buf, newattrs.ia_valid = ATTR_MODE; inode = evm_xattrs->d_inode; inode_lock(inode); - err = simple_setattr(evm_xattrs, &newattrs); + err = simple_setattr(&init_user_ns, evm_xattrs, &newattrs); inode_unlock(inode); if (!err) err = count; -- cgit v1.2.3 From 822be879980d8a2ddcb7268c77c682c0cdd3c086 Mon Sep 17 00:00:00 2001 From: Grzegorz Jaszczyk Date: Sun, 24 Jan 2021 20:51:37 -0800 Subject: dt-bindings: soc: ti: Update TI PRUSS bindings about schemas to include Now after ti,pruss-intc.yaml and ti,pru-rproc.yaml are merged, include them in proper property and extend the examples section. At the occasion extend the allowed property list about dma-ranges. Reviewed-by: Rob Herring Signed-off-by: Grzegorz Jaszczyk Signed-off-by: Santosh Shilimkar --- .../devicetree/bindings/soc/ti/ti,pruss.yaml | 76 ++++++++++++++++++++++ 1 file changed, 76 insertions(+) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/soc/ti/ti,pruss.yaml b/Documentation/devicetree/bindings/soc/ti/ti,pruss.yaml index 037c51b2f972..dbc62821c60b 100644 --- a/Documentation/devicetree/bindings/soc/ti/ti,pruss.yaml +++ b/Documentation/devicetree/bindings/soc/ti/ti,pruss.yaml @@ -81,6 +81,9 @@ properties: ranges: maxItems: 1 + dma-ranges: + maxItems: 1 + power-domains: description: | This property is as per sci-pm-domain.txt. @@ -278,6 +281,9 @@ patternProperties: that is common to all the PRU cores. This should be represented as an interrupt-controller node. + allOf: + - $ref: /schemas/interrupt-controller/ti,pruss-intc.yaml# + type: object mdio@[a-f0-9]+$: @@ -299,6 +305,9 @@ patternProperties: present on K3 SoCs have additional auxiliary PRU cores with slightly different IP integration. + allOf: + - $ref: /schemas/remoteproc/ti,pru-rproc.yaml# + type: object required: @@ -371,6 +380,36 @@ examples: reg = <0x32000 0x58>; }; + pruss_intc: interrupt-controller@20000 { + compatible = "ti,pruss-intc"; + reg = <0x20000 0x2000>; + interrupt-controller; + #interrupt-cells = <3>; + interrupts = <20 21 22 23 24 25 26 27>; + interrupt-names = "host_intr0", "host_intr1", + "host_intr2", "host_intr3", + "host_intr4", "host_intr5", + "host_intr6", "host_intr7"; + }; + + pru0: pru@34000 { + compatible = "ti,am3356-pru"; + reg = <0x34000 0x2000>, + <0x22000 0x400>, + <0x22400 0x100>; + reg-names = "iram", "control", "debug"; + firmware-name = "am335x-pru0-fw"; + }; + + pru1: pru@38000 { + compatible = "ti,am3356-pru"; + reg = <0x38000 0x2000>, + <0x24000 0x400>, + <0x24400 0x100>; + reg-names = "iram", "control", "debug"; + firmware-name = "am335x-pru1-fw"; + }; + pruss_mdio: mdio@32400 { compatible = "ti,davinci_mdio"; reg = <0x32400 0x90>; @@ -425,6 +464,43 @@ examples: reg = <0x32000 0x58>; }; + pruss1_intc: interrupt-controller@20000 { + compatible = "ti,pruss-intc"; + reg = <0x20000 0x2000>; + interrupt-controller; + #interrupt-cells = <3>; + interrupts = , + , + , + , + , + , + ; + interrupt-names = "host_intr0", "host_intr1", + "host_intr2", "host_intr3", + "host_intr4", + "host_intr6", "host_intr7"; + ti,irqs-reserved = /bits/ 8 <0x20>; /* BIT(5) */ + }; + + pru1_0: pru@34000 { + compatible = "ti,am4376-pru"; + reg = <0x34000 0x3000>, + <0x22000 0x400>, + <0x22400 0x100>; + reg-names = "iram", "control", "debug"; + firmware-name = "am437x-pru1_0-fw"; + }; + + pru1_1: pru@38000 { + compatible = "ti,am4376-pru"; + reg = <0x38000 0x3000>, + <0x24000 0x400>, + <0x24400 0x100>; + reg-names = "iram", "control", "debug"; + firmware-name = "am437x-pru1_1-fw"; + }; + pruss1_mdio: mdio@32400 { compatible = "ti,davinci_mdio"; reg = <0x32400 0x90>; -- cgit v1.2.3 From 9b2e0016d04c6542ace0128eb82ecb3b10c97e43 Mon Sep 17 00:00:00 2001 From: Pavel Begunkov Date: Sat, 9 Jan 2021 16:02:58 +0000 Subject: bvec/iter: disallow zero-length segment bvecs zero-length bvec segments are allowed in general, but not handled by bio and down the block layer so filtered out. This inconsistency may be confusing and prevent from optimisations. As zero-length segments are useless and places that were generating them are patched, declare them not allowed. Reviewed-by: Christoph Hellwig Signed-off-by: Pavel Begunkov Reviewed-by: Ming Lei Signed-off-by: Jens Axboe --- Documentation/block/biovecs.rst | 2 ++ Documentation/filesystems/porting.rst | 7 +++++++ lib/iov_iter.c | 2 -- 3 files changed, 9 insertions(+), 2 deletions(-) (limited to 'Documentation') diff --git a/Documentation/block/biovecs.rst b/Documentation/block/biovecs.rst index 36771a131b56..ddb867e0185b 100644 --- a/Documentation/block/biovecs.rst +++ b/Documentation/block/biovecs.rst @@ -40,6 +40,8 @@ normal code doesn't have to deal with bi_bvec_done. There is a lower level advance function - bvec_iter_advance() - which takes a pointer to a biovec, not a bio; this is used by the bio integrity code. +As of 5.12 bvec segments with zero bv_len are not supported. + What's all this get us? ======================= diff --git a/Documentation/filesystems/porting.rst b/Documentation/filesystems/porting.rst index 867036aa90b8..c722d94f29ea 100644 --- a/Documentation/filesystems/porting.rst +++ b/Documentation/filesystems/porting.rst @@ -865,3 +865,10 @@ no matter what. Everything is handled by the caller. clone_private_mount() returns a longterm mount now, so the proper destructor of its result is kern_unmount() or kern_unmount_array(). + +--- + +**mandatory** + +zero-length bvec segments are disallowed, they must be filtered out before +passed on to an iterator. diff --git a/lib/iov_iter.c b/lib/iov_iter.c index a21e6a5792c5..6c597cdfcf5b 100644 --- a/lib/iov_iter.c +++ b/lib/iov_iter.c @@ -72,8 +72,6 @@ __start.bi_bvec_done = skip; \ __start.bi_idx = 0; \ for_each_bvec(__v, i->bvec, __bi, __start) { \ - if (!__v.bv_len) \ - continue; \ (void)(STEP); \ } \ } -- cgit v1.2.3 From c42bca92be928ce7dece5fc04cf68d0e37ee6718 Mon Sep 17 00:00:00 2001 From: Pavel Begunkov Date: Sat, 9 Jan 2021 16:03:03 +0000 Subject: bio: don't copy bvec for direct IO The block layer spends quite a while in blkdev_direct_IO() to copy and initialise bio's bvec. However, if we've already got a bvec in the input iterator it might be reused in some cases, i.e. when new ITER_BVEC_FLAG_FIXED flag is set. Simple tests show considerable performance boost, and it also reduces memory footprint. Suggested-by: Matthew Wilcox Reviewed-by: Christoph Hellwig Signed-off-by: Pavel Begunkov Reviewed-by: Ming Lei Signed-off-by: Jens Axboe --- Documentation/filesystems/porting.rst | 9 +++++ block/bio.c | 67 +++++++++++++++-------------------- include/linux/bio.h | 5 ++- 3 files changed, 42 insertions(+), 39 deletions(-) (limited to 'Documentation') diff --git a/Documentation/filesystems/porting.rst b/Documentation/filesystems/porting.rst index c722d94f29ea..1f8cf8e10b34 100644 --- a/Documentation/filesystems/porting.rst +++ b/Documentation/filesystems/porting.rst @@ -872,3 +872,12 @@ its result is kern_unmount() or kern_unmount_array(). zero-length bvec segments are disallowed, they must be filtered out before passed on to an iterator. + +--- + +**mandatory** + +For bvec based itererators bio_iov_iter_get_pages() now doesn't copy bvecs but +uses the one provided. Anyone issuing kiocb-I/O should ensure that the bvec and +page references stay until I/O has completed, i.e. until ->ki_complete() has +been called or returned with non -EIOCBQUEUED code. diff --git a/block/bio.c b/block/bio.c index 1cd8a2e79048..99040a7e6656 100644 --- a/block/bio.c +++ b/block/bio.c @@ -942,21 +942,17 @@ void bio_release_pages(struct bio *bio, bool mark_dirty) } EXPORT_SYMBOL_GPL(bio_release_pages); -static int __bio_iov_bvec_add_pages(struct bio *bio, struct iov_iter *iter) +static int bio_iov_bvec_set(struct bio *bio, struct iov_iter *iter) { - const struct bio_vec *bv = iter->bvec; - unsigned int len; - size_t size; - - if (WARN_ON_ONCE(iter->iov_offset > bv->bv_len)) - return -EINVAL; - - len = min_t(size_t, bv->bv_len - iter->iov_offset, iter->count); - size = bio_add_page(bio, bv->bv_page, len, - bv->bv_offset + iter->iov_offset); - if (unlikely(size != len)) - return -EINVAL; - iov_iter_advance(iter, size); + WARN_ON_ONCE(BVEC_POOL_IDX(bio) != 0); + + bio->bi_vcnt = iter->nr_segs; + bio->bi_max_vecs = iter->nr_segs; + bio->bi_io_vec = (struct bio_vec *)iter->bvec; + bio->bi_iter.bi_bvec_done = iter->iov_offset; + bio->bi_iter.bi_size = iter->count; + + iov_iter_advance(iter, iter->count); return 0; } @@ -1070,12 +1066,12 @@ static int __bio_iov_append_get_pages(struct bio *bio, struct iov_iter *iter) * This takes either an iterator pointing to user memory, or one pointing to * kernel pages (BVEC iterator). If we're adding user pages, we pin them and * map them into the kernel. On IO completion, the caller should put those - * pages. If we're adding kernel pages, and the caller told us it's safe to - * do so, we just have to add the pages to the bio directly. We don't grab an - * extra reference to those pages (the user should already have that), and we - * don't put the page on IO completion. The caller needs to check if the bio is - * flagged BIO_NO_PAGE_REF on IO completion. If it isn't, then pages should be - * released. + * pages. For bvec based iterators bio_iov_iter_get_pages() uses the provided + * bvecs rather than copying them. Hence anyone issuing kiocb based IO needs + * to ensure the bvecs and pages stay referenced until the submitted I/O is + * completed by a call to ->ki_complete() or returns with an error other than + * -EIOCBQUEUED. The caller needs to check if the bio is flagged BIO_NO_PAGE_REF + * on IO completion. If it isn't, then pages should be released. * * The function tries, but does not guarantee, to pin as many pages as * fit into the bio, or are requested in @iter, whatever is smaller. If @@ -1087,27 +1083,22 @@ static int __bio_iov_append_get_pages(struct bio *bio, struct iov_iter *iter) */ int bio_iov_iter_get_pages(struct bio *bio, struct iov_iter *iter) { - const bool is_bvec = iov_iter_is_bvec(iter); - int ret; - - if (WARN_ON_ONCE(bio->bi_vcnt)) - return -EINVAL; + int ret = 0; - do { - if (bio_op(bio) == REQ_OP_ZONE_APPEND) { - if (WARN_ON_ONCE(is_bvec)) - return -EINVAL; - ret = __bio_iov_append_get_pages(bio, iter); - } else { - if (is_bvec) - ret = __bio_iov_bvec_add_pages(bio, iter); + if (iov_iter_is_bvec(iter)) { + if (WARN_ON_ONCE(bio_op(bio) == REQ_OP_ZONE_APPEND)) + return -EINVAL; + bio_iov_bvec_set(bio, iter); + bio_set_flag(bio, BIO_NO_PAGE_REF); + return 0; + } else { + do { + if (bio_op(bio) == REQ_OP_ZONE_APPEND) + ret = __bio_iov_append_get_pages(bio, iter); else ret = __bio_iov_iter_get_pages(bio, iter); - } - } while (!ret && iov_iter_count(iter) && !bio_full(bio, 0)); - - if (is_bvec) - bio_set_flag(bio, BIO_NO_PAGE_REF); + } while (!ret && iov_iter_count(iter) && !bio_full(bio, 0)); + } /* don't account direct I/O as memory stall */ bio_clear_flag(bio, BIO_WORKINGSET); diff --git a/include/linux/bio.h b/include/linux/bio.h index 9ddb19801a03..676870b2c88d 100644 --- a/include/linux/bio.h +++ b/include/linux/bio.h @@ -444,10 +444,13 @@ static inline void bio_wouldblock_error(struct bio *bio) /* * Calculate number of bvec segments that should be allocated to fit data - * pointed by @iter. + * pointed by @iter. If @iter is backed by bvec it's going to be reused + * instead of allocating a new one. */ static inline int bio_iov_vecs_to_alloc(struct iov_iter *iter, int max_segs) { + if (iov_iter_is_bvec(iter)) + return 0; return iov_iter_npages(iter, max_segs); } -- cgit v1.2.3 From f288988930e93857e0375bdf88bb670c312b82eb Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Thu, 14 Jan 2021 14:13:33 +0100 Subject: dt-bindings: net: btusb: DT fix s/interrupt-name/interrupt-names/ The standard DT property name is "interrupt-names". Fixes: fd913ef7ce619467 ("Bluetooth: btusb: Add out-of-band wakeup support") Signed-off-by: Geert Uytterhoeven Acked-by: Rob Herring Reviewed-by: Brian Norris Acked-by: Rajat Jain Signed-off-by: Marcel Holtmann --- Documentation/devicetree/bindings/net/btusb.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/net/btusb.txt b/Documentation/devicetree/bindings/net/btusb.txt index b1ad6ee68e90..c51dd99dc0d3 100644 --- a/Documentation/devicetree/bindings/net/btusb.txt +++ b/Documentation/devicetree/bindings/net/btusb.txt @@ -38,7 +38,7 @@ Following example uses irq pin number 3 of gpio0 for out of band wake-on-bt: compatible = "usb1286,204e"; reg = <1>; interrupt-parent = <&gpio0>; - interrupt-name = "wakeup"; + interrupt-names = "wakeup"; interrupts = <3 IRQ_TYPE_LEVEL_LOW>; }; }; -- cgit v1.2.3 From 43eb76a2e56b94541293fc8192d6edf1d0ec8965 Mon Sep 17 00:00:00 2001 From: Konrad Dybcio Date: Mon, 18 Jan 2021 17:19:41 +0100 Subject: drivers: soc: qcom: rpmpd: Add msm8994 RPM Power Domains MSM8994 uses similar to MSM8996, legacy-style voltage control, but does not include a VDD_SC_CX line. This setup is also correct for MSM8992. Do note that there exist some boards that use a tertiary PMIC (most likely pm8004), where SMPB on VDDGFX becomes SMPC. I cannot test this configuration though. Signed-off-by: Konrad Dybcio Link: https://lore.kernel.org/r/20210118161943.105733-1-konrad.dybcio@somainline.org Signed-off-by: Bjorn Andersson --- .../devicetree/bindings/power/qcom,rpmpd.yaml | 1 + drivers/soc/qcom/rpmpd.c | 28 ++++++++++++++++++++++ include/dt-bindings/power/qcom-rpmpd.h | 9 +++++++ 3 files changed, 38 insertions(+) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/power/qcom,rpmpd.yaml b/Documentation/devicetree/bindings/power/qcom,rpmpd.yaml index 64825128ee97..1ea21acbbd55 100644 --- a/Documentation/devicetree/bindings/power/qcom,rpmpd.yaml +++ b/Documentation/devicetree/bindings/power/qcom,rpmpd.yaml @@ -19,6 +19,7 @@ properties: - qcom,msm8916-rpmpd - qcom,msm8939-rpmpd - qcom,msm8976-rpmpd + - qcom,msm8994-rpmpd - qcom,msm8996-rpmpd - qcom,msm8998-rpmpd - qcom,qcs404-rpmpd diff --git a/drivers/soc/qcom/rpmpd.c b/drivers/soc/qcom/rpmpd.c index 85d1207b72d7..27733b0e7fca 100644 --- a/drivers/soc/qcom/rpmpd.c +++ b/drivers/soc/qcom/rpmpd.c @@ -21,6 +21,8 @@ * RPMPD_X is X encoded as a little-endian, lower-case, ASCII string */ #define RPMPD_SMPA 0x61706d73 #define RPMPD_LDOA 0x616f646c +#define RPMPD_SMPB 0x62706d73 +#define RPMPD_LDOB 0x626f646c #define RPMPD_RWCX 0x78637772 #define RPMPD_RWMX 0x786d7772 #define RPMPD_RWLC 0x636c7772 @@ -184,6 +186,31 @@ static const struct rpmpd_desc msm8976_desc = { .max_state = RPM_SMD_LEVEL_TURBO_HIGH, }; +/* msm8994 RPM Power domains */ +DEFINE_RPMPD_PAIR(msm8994, vddcx, vddcx_ao, SMPA, CORNER, 1); +DEFINE_RPMPD_PAIR(msm8994, vddmx, vddmx_ao, SMPA, CORNER, 2); +/* Attention! *Some* 8994 boards with pm8004 may use SMPC here! */ +DEFINE_RPMPD_CORNER(msm8994, vddgfx, SMPB, 2); + +DEFINE_RPMPD_VFC(msm8994, vddcx_vfc, SMPA, 1); +DEFINE_RPMPD_VFC(msm8994, vddgfx_vfc, SMPB, 2); + +static struct rpmpd *msm8994_rpmpds[] = { + [MSM8994_VDDCX] = &msm8994_vddcx, + [MSM8994_VDDCX_AO] = &msm8994_vddcx_ao, + [MSM8994_VDDCX_VFC] = &msm8994_vddcx_vfc, + [MSM8994_VDDMX] = &msm8994_vddmx, + [MSM8994_VDDMX_AO] = &msm8994_vddmx_ao, + [MSM8994_VDDGFX] = &msm8994_vddgfx, + [MSM8994_VDDGFX_VFC] = &msm8994_vddgfx_vfc, +}; + +static const struct rpmpd_desc msm8994_desc = { + .rpmpds = msm8994_rpmpds, + .num_pds = ARRAY_SIZE(msm8994_rpmpds), + .max_state = MAX_CORNER_RPMPD_STATE, +}; + /* msm8996 RPM Power domains */ DEFINE_RPMPD_PAIR(msm8996, vddcx, vddcx_ao, SMPA, CORNER, 1); DEFINE_RPMPD_PAIR(msm8996, vddmx, vddmx_ao, SMPA, CORNER, 2); @@ -302,6 +329,7 @@ static const struct of_device_id rpmpd_match_table[] = { { .compatible = "qcom,msm8916-rpmpd", .data = &msm8916_desc }, { .compatible = "qcom,msm8939-rpmpd", .data = &msm8939_desc }, { .compatible = "qcom,msm8976-rpmpd", .data = &msm8976_desc }, + { .compatible = "qcom,msm8994-rpmpd", .data = &msm8994_desc }, { .compatible = "qcom,msm8996-rpmpd", .data = &msm8996_desc }, { .compatible = "qcom,msm8998-rpmpd", .data = &msm8998_desc }, { .compatible = "qcom,qcs404-rpmpd", .data = &qcs404_desc }, diff --git a/include/dt-bindings/power/qcom-rpmpd.h b/include/dt-bindings/power/qcom-rpmpd.h index 7714487ac76b..d711e250cf2c 100644 --- a/include/dt-bindings/power/qcom-rpmpd.h +++ b/include/dt-bindings/power/qcom-rpmpd.h @@ -94,6 +94,15 @@ #define MSM8976_VDDMX_AO 4 #define MSM8976_VDDMX_VFL 5 +/* MSM8994 Power Domain Indexes */ +#define MSM8994_VDDCX 0 +#define MSM8994_VDDCX_AO 1 +#define MSM8994_VDDCX_VFC 2 +#define MSM8994_VDDMX 3 +#define MSM8994_VDDMX_AO 4 +#define MSM8994_VDDGFX 5 +#define MSM8994_VDDGFX_VFC 6 + /* MSM8996 Power Domain Indexes */ #define MSM8996_VDDCX 0 #define MSM8996_VDDCX_AO 1 -- cgit v1.2.3 From 0bc92e7f0d9ab06afacff7e5b0e08b5ce8f3f32f Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Wed, 13 Jan 2021 11:59:21 +0100 Subject: ASoC: audio-graph-card: update audio-graph-card.yaml reference Changeset 97198614f6c3 ("ASoC: audio-graph-card: switch to yaml base Documentation") renamed: Documentation/devicetree/bindings/sound/audio-graph-card.txt to: Documentation/devicetree/bindings/sound/audio-graph-card.yaml. Update its cross-reference accordingly. Signed-off-by: Mauro Carvalho Chehab Link: https://lore.kernel.org/r/8a779e6b9644d19c5d77b382059f6ccf9781434d.1610535350.git.mchehab+huawei@kernel.org Signed-off-by: Rob Herring --- Documentation/devicetree/bindings/display/bridge/sii902x.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/display/bridge/sii902x.txt b/Documentation/devicetree/bindings/display/bridge/sii902x.txt index 02c21b584741..3bc760cc31cb 100644 --- a/Documentation/devicetree/bindings/display/bridge/sii902x.txt +++ b/Documentation/devicetree/bindings/display/bridge/sii902x.txt @@ -40,7 +40,7 @@ Optional properties: 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.yaml - Documentation/devicetree/bindings/sound/audio-graph-card.txt + Documentation/devicetree/bindings/sound/audio-graph-card.yaml Note: In case of the audio-graph-card binding the used port index should be 3. -- cgit v1.2.3 From 601bd38ccd25e831865dd8442e3491fc8ce9604d Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Wed, 13 Jan 2021 11:59:22 +0100 Subject: dt-bindings: display: mediatek: update mediatek,dpi.yaml reference Changeset 9273cf7d3942 ("dt-bindings: display: mediatek: convert the dpi bindings to yaml") renamed: Documentation/devicetree/bindings/display/mediatek/mediatek,dpi.txt to: Documentation/devicetree/bindings/display/mediatek/mediatek,dpi.yaml. Update its cross-reference accordingly. Signed-off-by: Mauro Carvalho Chehab Link: https://lore.kernel.org/r/3bf906f39b797d18800abd387187cce71296e5eb.1610535350.git.mchehab+huawei@kernel.org Signed-off-by: Rob Herring --- Documentation/devicetree/bindings/display/mediatek/mediatek,disp.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,disp.txt b/Documentation/devicetree/bindings/display/mediatek/mediatek,disp.txt index 33977e15bebd..865e1e1b88ac 100644 --- a/Documentation/devicetree/bindings/display/mediatek/mediatek,disp.txt +++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,disp.txt @@ -23,7 +23,7 @@ connected to. For a description of the display interface sink function blocks, see Documentation/devicetree/bindings/display/mediatek/mediatek,dsi.txt and -Documentation/devicetree/bindings/display/mediatek/mediatek,dpi.txt. +Documentation/devicetree/bindings/display/mediatek/mediatek,dpi.yaml. Required properties (all function blocks): - compatible: "mediatek,-disp-", one of -- cgit v1.2.3 From c5dde04b9059c91515d609a41e9c1a148ee4d850 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Wed, 13 Jan 2021 11:59:23 +0100 Subject: dt-bindings: memory: mediatek: update mediatek,smi-larb.yaml references Changeset 27bb0e42855a ("dt-bindings: memory: mediatek: Convert SMI to DT schema") renamed: Documentation/devicetree/bindings/memory-controllers/mediatek,smi-larb.txt to: Documentation/devicetree/bindings/memory-controllers/mediatek,smi-larb.yaml. Update its cross-references accordingly. Signed-off-by: Mauro Carvalho Chehab Link: https://lore.kernel.org/r/c70bd79b311a65babe7374eaf81974563400a943.1610535350.git.mchehab+huawei@kernel.org Signed-off-by: Rob Herring --- Documentation/devicetree/bindings/display/mediatek/mediatek,disp.txt | 2 +- Documentation/devicetree/bindings/media/mediatek-jpeg-decoder.txt | 2 +- Documentation/devicetree/bindings/media/mediatek-jpeg-encoder.txt | 2 +- Documentation/devicetree/bindings/media/mediatek-mdp.txt | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,disp.txt b/Documentation/devicetree/bindings/display/mediatek/mediatek,disp.txt index 865e1e1b88ac..ed76332ec01e 100644 --- a/Documentation/devicetree/bindings/display/mediatek/mediatek,disp.txt +++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,disp.txt @@ -61,7 +61,7 @@ Required properties (DMA function blocks): "mediatek,-disp-wdma" the supported chips are mt2701, mt8167 and mt8173. - larb: Should contain a phandle pointing to the local arbiter device as defined - in Documentation/devicetree/bindings/memory-controllers/mediatek,smi-larb.txt + in Documentation/devicetree/bindings/memory-controllers/mediatek,smi-larb.yaml - iommus: Should point to the respective IOMMU block with master port as argument, see Documentation/devicetree/bindings/iommu/mediatek,iommu.txt for details. diff --git a/Documentation/devicetree/bindings/media/mediatek-jpeg-decoder.txt b/Documentation/devicetree/bindings/media/mediatek-jpeg-decoder.txt index 044b11913c49..cf60c5acc0e4 100644 --- a/Documentation/devicetree/bindings/media/mediatek-jpeg-decoder.txt +++ b/Documentation/devicetree/bindings/media/mediatek-jpeg-decoder.txt @@ -16,7 +16,7 @@ Required properties: - power-domains: a phandle to the power domain, see Documentation/devicetree/bindings/power/power_domain.txt for details. - mediatek,larb: must contain the local arbiters in the current Socs, see - Documentation/devicetree/bindings/memory-controllers/mediatek,smi-larb.txt + Documentation/devicetree/bindings/memory-controllers/mediatek,smi-larb.yaml for details. - iommus: should point to the respective IOMMU block with master port as argument, see Documentation/devicetree/bindings/iommu/mediatek,iommu.txt diff --git a/Documentation/devicetree/bindings/media/mediatek-jpeg-encoder.txt b/Documentation/devicetree/bindings/media/mediatek-jpeg-encoder.txt index 736be7cad385..acfb50375b8a 100644 --- a/Documentation/devicetree/bindings/media/mediatek-jpeg-encoder.txt +++ b/Documentation/devicetree/bindings/media/mediatek-jpeg-encoder.txt @@ -14,7 +14,7 @@ Required properties: - power-domains: a phandle to the power domain, see Documentation/devicetree/bindings/power/power_domain.txt for details. - mediatek,larb: must contain the local arbiters in the current SoCs, see - Documentation/devicetree/bindings/memory-controllers/mediatek,smi-larb.txt + Documentation/devicetree/bindings/memory-controllers/mediatek,smi-larb.yaml for details. - iommus: should point to the respective IOMMU block with master port as argument, see Documentation/devicetree/bindings/iommu/mediatek,iommu.txt diff --git a/Documentation/devicetree/bindings/media/mediatek-mdp.txt b/Documentation/devicetree/bindings/media/mediatek-mdp.txt index 0d03e3ae2be2..f4798d04e925 100644 --- a/Documentation/devicetree/bindings/media/mediatek-mdp.txt +++ b/Documentation/devicetree/bindings/media/mediatek-mdp.txt @@ -28,7 +28,7 @@ Required properties (DMA function blocks, child node): argument, see Documentation/devicetree/bindings/iommu/mediatek,iommu.txt for details. - mediatek,larb: must contain the local arbiters in the current Socs, see - Documentation/devicetree/bindings/memory-controllers/mediatek,smi-larb.txt + Documentation/devicetree/bindings/memory-controllers/mediatek,smi-larb.yaml for details. Example: -- cgit v1.2.3 From 3490e333bda0709a5a2c9b7ab9b0209bb16619d8 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Wed, 13 Jan 2021 11:59:24 +0100 Subject: dt-bindings:iio:adc: update adc.yaml reference Changeset b70d154d6558 ("dt-bindings:iio:adc: convert adc.txt to yaml") renamed: Documentation/devicetree/bindings/iio/adc/adc.txt to: Documentation/devicetree/bindings/iio/adc/adc.yaml. Update its cross-reference accordingly. Signed-off-by: Mauro Carvalho Chehab Acked-by: Jonathan Cameron Link: https://lore.kernel.org/r/8e37dba8ae9099acd649bab8a1cf718caa4f3e6a.1610535350.git.mchehab+huawei@kernel.org Signed-off-by: Rob Herring --- Documentation/devicetree/bindings/iio/adc/adi,ad7192.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/iio/adc/adi,ad7192.yaml b/Documentation/devicetree/bindings/iio/adc/adi,ad7192.yaml index e0cc3b2e8957..22b7ed3723f6 100644 --- a/Documentation/devicetree/bindings/iio/adc/adi,ad7192.yaml +++ b/Documentation/devicetree/bindings/iio/adc/adi,ad7192.yaml @@ -80,7 +80,7 @@ properties: type: boolean bipolar: - description: see Documentation/devicetree/bindings/iio/adc/adc.txt + description: see Documentation/devicetree/bindings/iio/adc/adc.yaml type: boolean required: -- cgit v1.2.3 From d7cbe2773aed0b636d48bb6795637eb486ecba6d Mon Sep 17 00:00:00 2001 From: Nitin Joshi Date: Mon, 25 Jan 2021 11:59:16 +0900 Subject: platform/x86: thinkpad_acpi: set keyboard language This patch is to create sysfs entry for setting keyboard language using ASL method. Some thinkpads models like T580 , T590 , T15 Gen 1 etc. has "=", "(',")" numeric keys, which are not displaying correctly, when keyboard language is other than "english". This patch fixes this issue by setting keyboard language to ECFW. Signed-off-by: Nitin Joshi Reviewed-by: Hans de Goede Link: https://lore.kernel.org/r/20210125025916.180831-1-nitjoshi@gmail.com Signed-off-by: Hans de Goede --- .../admin-guide/laptops/thinkpad-acpi.rst | 24 +++ drivers/platform/x86/thinkpad_acpi.c | 181 +++++++++++++++++++++ 2 files changed, 205 insertions(+) (limited to 'Documentation') diff --git a/Documentation/admin-guide/laptops/thinkpad-acpi.rst b/Documentation/admin-guide/laptops/thinkpad-acpi.rst index 5fe1ade88c17..b1188f05a99a 100644 --- a/Documentation/admin-guide/laptops/thinkpad-acpi.rst +++ b/Documentation/admin-guide/laptops/thinkpad-acpi.rst @@ -51,6 +51,7 @@ detailed description): - UWB enable and disable - LCD Shadow (PrivacyGuard) enable and disable - Lap mode sensor + - Setting keyboard language A compatibility table by model and feature is maintained on the web site, http://ibm-acpi.sf.net/. I appreciate any success or failure @@ -1466,6 +1467,29 @@ Sysfs notes rfkill controller switch "tpacpi_uwb_sw": refer to Documentation/driver-api/rfkill.rst for details. + +Setting keyboard language +------------------- + +sysfs: keyboard_lang + +This feature is used to set keyboard language to ECFW using ASL interface. +Fewer thinkpads models like T580 , T590 , T15 Gen 1 etc.. has "=", "(', +")" numeric keys, which are not displaying correctly, when keyboard language +is other than "english". This is because of default keyboard language in ECFW +is set as "english". Hence using this sysfs, user can set correct keyboard +language to ECFW and then these key's will work correctly . + +Example of command to set keyboard language is mentioned below:: + + echo jp > /sys/devices/platform/thinkpad_acpi/keyboard_lang + +Text corresponding to keyboard layout to be set in sysfs are : jp (Japan), be(Belgian), +cz(Czech), en(English), da(Danish), de(German), es(Spain) , et(Estonian), +fr(French) , fr-ch (French(Switzerland)), pl(Polish), sl(Slovenian), hu +(Hungarian), nl(Dutch), tr(Turkey), it(Italy), sv(Sweden), pt(portugese) + + Adaptive keyboard ----------------- diff --git a/drivers/platform/x86/thinkpad_acpi.c b/drivers/platform/x86/thinkpad_acpi.c index f3e8eca8d86d..81f8ad6bb688 100644 --- a/drivers/platform/x86/thinkpad_acpi.c +++ b/drivers/platform/x86/thinkpad_acpi.c @@ -9983,6 +9983,183 @@ static struct ibm_struct proxsensor_driver_data = { .exit = proxsensor_exit, }; +/************************************************************************* + * Keyboard language interface + */ + +struct keyboard_lang_data { + const char *lang_str; + int lang_code; +}; + +/* + * When adding new entries to keyboard_lang_data, please check that + * the select_lang[] buffer in keyboard_lang_show() is still large enough. + */ +struct keyboard_lang_data keyboard_lang_data[] = { + {"en", 0}, + {"be", 0x080c}, + {"cz", 0x0405}, + {"da", 0x0406}, + {"de", 0x0c07}, + {"es", 0x2c0a}, + {"et", 0x0425}, + {"fr", 0x040c}, + {"fr-ch", 0x100c}, + {"hu", 0x040e}, + {"it", 0x0410}, + {"jp", 0x0411}, + {"nl", 0x0413}, + {"nn", 0x0414}, + {"pl", 0x0415}, + {"pt", 0x0816}, + {"sl", 0x041b}, + {"sv", 0x081d}, + {"tr", 0x041f}, +}; + +static int set_keyboard_lang_command(int command) +{ + acpi_handle sskl_handle; + int output; + + if (ACPI_FAILURE(acpi_get_handle(hkey_handle, "SSKL", &sskl_handle))) { + /* Platform doesn't support SSKL */ + return -ENODEV; + } + + if (!acpi_evalf(sskl_handle, &output, NULL, "dd", command)) + return -EIO; + + return 0; +} + +static int get_keyboard_lang(int *output) +{ + acpi_handle gskl_handle; + int kbd_lang; + + if (ACPI_FAILURE(acpi_get_handle(hkey_handle, "GSKL", &gskl_handle))) { + /* Platform doesn't support GSKL */ + return -ENODEV; + } + + if (!acpi_evalf(gskl_handle, &kbd_lang, NULL, "dd", 0x02000000)) + return -EIO; + + *output = kbd_lang; + + return 0; +} + +/* sysfs keyboard language entry */ +static ssize_t keyboard_lang_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + int output, err, i; + char select_lang[80] = ""; + char lang[8] = ""; + + err = get_keyboard_lang(&output); + if (err) + return err; + + for (i = 0; i < ARRAY_SIZE(keyboard_lang_data); i++) { + if (i) + strcat(select_lang, " "); + + if (output == keyboard_lang_data[i].lang_code) { + strcat(lang, "["); + strcat(lang, keyboard_lang_data[i].lang_str); + strcat(lang, "]"); + strcat(select_lang, lang); + } else { + strcat(select_lang, keyboard_lang_data[i].lang_str); + } + } + + return sysfs_emit(buf, "%s\n", select_lang); +} + +static ssize_t keyboard_lang_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + int err, i; + bool lang_found = false; + int lang_code = 0; + + for (i = 0; i < ARRAY_SIZE(keyboard_lang_data); i++) { + if (sysfs_streq(buf, keyboard_lang_data[i].lang_str)) { + lang_code = keyboard_lang_data[i].lang_code; + lang_found = true; + break; + } + } + + if (lang_found) { + lang_code = lang_code | 1 << 24; + + /* Set language code */ + err = set_keyboard_lang_command(lang_code); + if (err) + return err; + } else { + pr_err("Unknown Keyboard language. Ignoring\n"); + return -EINVAL; + } + + tpacpi_disclose_usertask(attr->attr.name, + "keyboard language is set to %s\n", buf); + + sysfs_notify(&tpacpi_pdev->dev.kobj, NULL, "keyboard_lang"); + + return count; +} + +static DEVICE_ATTR_RW(keyboard_lang); + +static struct attribute *kbdlang_attributes[] = { + &dev_attr_keyboard_lang.attr, + NULL +}; + +static const struct attribute_group kbdlang_attr_group = { + .attrs = kbdlang_attributes, +}; + +static int tpacpi_kbdlang_init(struct ibm_init_struct *iibm) +{ + int err, output; + + err = get_keyboard_lang(&output); + /* + * If support isn't available (ENODEV) then don't return an error + * just don't create the sysfs group + */ + if (err == -ENODEV) + return 0; + + if (err) + return err; + + /* Platform supports this feature - create the sysfs file */ + err = sysfs_create_group(&tpacpi_pdev->dev.kobj, &kbdlang_attr_group); + + return err; +} + +static void kbdlang_exit(void) +{ + sysfs_remove_group(&tpacpi_pdev->dev.kobj, &kbdlang_attr_group); +} + +static struct ibm_struct kbdlang_driver_data = { + .name = "kbdlang", + .exit = kbdlang_exit, +}; + /**************************************************************************** **************************************************************************** * @@ -10475,6 +10652,10 @@ static struct ibm_init_struct ibms_init[] __initdata = { .init = tpacpi_proxsensor_init, .data = &proxsensor_driver_data, }, + { + .init = tpacpi_kbdlang_init, + .data = &kbdlang_driver_data, + }, }; static int __init set_ibm_param(const char *val, const struct kernel_param *kp) -- cgit v1.2.3 From cb18a7979a35f5f14cab49715e97efe7700fd349 Mon Sep 17 00:00:00 2001 From: Stefan Wahren Date: Wed, 13 Jan 2021 20:08:37 +0100 Subject: dt-bindings: gpu: Convert v3d to json-schema This converts the v3d bindings to yaml format. Signed-off-by: Stefan Wahren Acked-by: Maxime Ripard Reviewed-by: Nicolas Saenz Julienne Link: https://lore.kernel.org/r/1610564917-11559-1-git-send-email-stefan.wahren@i2se.com Signed-off-by: Rob Herring --- .../devicetree/bindings/gpu/brcm,bcm-v3d.txt | 33 ---------- .../devicetree/bindings/gpu/brcm,bcm-v3d.yaml | 75 ++++++++++++++++++++++ 2 files changed, 75 insertions(+), 33 deletions(-) delete mode 100644 Documentation/devicetree/bindings/gpu/brcm,bcm-v3d.txt create mode 100644 Documentation/devicetree/bindings/gpu/brcm,bcm-v3d.yaml (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/gpu/brcm,bcm-v3d.txt b/Documentation/devicetree/bindings/gpu/brcm,bcm-v3d.txt deleted file mode 100644 index b2df82b44625..000000000000 --- a/Documentation/devicetree/bindings/gpu/brcm,bcm-v3d.txt +++ /dev/null @@ -1,33 +0,0 @@ -Broadcom V3D GPU - -Only the Broadcom V3D 3.x and newer GPUs are covered by this binding. -For V3D 2.x, see brcm,bcm-vc4.txt. - -Required properties: -- compatible: Should be "brcm,7268-v3d" or "brcm,7278-v3d" -- reg: Physical base addresses and lengths of the register areas -- reg-names: Names for the register areas. The "hub" and "core0" - register areas are always required. The "gca" register area - is required if the GCA cache controller is present. The - "bridge" register area is required if an external reset - controller is not present. -- interrupts: The interrupt numbers. The first interrupt is for the hub, - while the following interrupts are separate interrupt lines - for the cores (if they don't share the hub's interrupt). - See bindings/interrupt-controller/interrupts.txt - -Optional properties: -- clocks: The core clock the unit runs on -- resets: The reset line for v3d, if not using a mapping of the bridge - See bindings/reset/reset.txt - -v3d { - compatible = "brcm,7268-v3d"; - reg = <0xf1204000 0x100>, - <0xf1200000 0x4000>, - <0xf1208000 0x4000>, - <0xf1204100 0x100>; - reg-names = "bridge", "hub", "core0", "gca"; - interrupts = <0 78 4>, - <0 77 4>; -}; diff --git a/Documentation/devicetree/bindings/gpu/brcm,bcm-v3d.yaml b/Documentation/devicetree/bindings/gpu/brcm,bcm-v3d.yaml new file mode 100644 index 000000000000..9d72264fa90a --- /dev/null +++ b/Documentation/devicetree/bindings/gpu/brcm,bcm-v3d.yaml @@ -0,0 +1,75 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/gpu/brcm,bcm-v3d.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Broadcom V3D GPU Bindings + +maintainers: + - Eric Anholt + - Nicolas Saenz Julienne + +properties: + $nodename: + pattern: '^gpu@[a-f0-9]+$' + + compatible: + enum: + - brcm,7268-v3d + - brcm,7278-v3d + + reg: + items: + - description: hub register (required) + - description: core0 register (required) + - description: GCA cache controller register (if GCA controller present) + - description: bridge register (if no external reset controller) + minItems: 2 + + reg-names: + items: + - const: hub + - const: core0 + - enum: [ bridge, gca ] + - enum: [ bridge, gca ] + minItems: 2 + maxItems: 4 + + interrupts: + items: + - description: hub interrupt (required) + - description: core interrupts (if it doesn't share the hub's interrupt) + minItems: 1 + + clocks: + maxItems: 1 + + resets: + maxItems: 1 + + power-domains: + maxItems: 1 + +required: + - compatible + - reg + - reg-names + - interrupts + +additionalProperties: false + +examples: + - | + gpu@f1200000 { + compatible = "brcm,7268-v3d"; + reg = <0xf1200000 0x4000>, + <0xf1208000 0x4000>, + <0xf1204000 0x100>, + <0xf1204100 0x100>; + reg-names = "hub", "core0", "bridge", "gca"; + interrupts = <0 78 4>, + <0 77 4>; + }; + +... -- cgit v1.2.3 From 164b67705681ed90c056529743b507229ae613a1 Mon Sep 17 00:00:00 2001 From: Robin van der Gracht Date: Mon, 18 Jan 2021 13:35:36 +0100 Subject: dt-bindings: auxdisplay: ht16k33: Keyscan function should be optional Keyscan should be optional to support simple LED matrix displays (output only). Reported-by: Michael Kaplan Signed-off-by: Robin van der Gracht [geert: Rebased] Signed-off-by: Geert Uytterhoeven Acked-by: Robin van der Gracht Signed-off-by: Miguel Ojeda --- Documentation/devicetree/bindings/display/ht16k33.txt | 11 +++++++---- drivers/auxdisplay/ht16k33.c | 14 ++++++-------- 2 files changed, 13 insertions(+), 12 deletions(-) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/display/ht16k33.txt b/Documentation/devicetree/bindings/display/ht16k33.txt index d5a8b070b467..3d602f5b9eb6 100644 --- a/Documentation/devicetree/bindings/display/ht16k33.txt +++ b/Documentation/devicetree/bindings/display/ht16k33.txt @@ -4,16 +4,19 @@ Holtek ht16k33 RAM mapping 16*8 LED controller driver with keyscan Required properties: - compatible: "holtek,ht16k33" - reg: I2C slave address of the chip. -- interrupts: Interrupt specification for the key pressed interrupt. - refresh-rate-hz: Display update interval in HZ. -- debounce-delay-ms: Debouncing interval time in milliseconds. -- linux,keymap: The keymap for keys as described in the binding - document (devicetree/bindings/input/matrix-keymap.txt). Optional properties: - linux,no-autorepeat: Disable keyrepeat. - default-brightness-level: Initial brightness level [0-15] (default: 15). +- Keypad + Supply the 'interrupts' property to enable the keyscan feature. + - interrupts: Interrupt specification for the key pressed interrupt. + - debounce-delay-ms: Debouncing interval time in milliseconds. + - linux,keymap: The keymap for keys as described in the binding + document (devicetree/bindings/input/matrix-keymap.txt). + Example: &i2c1 { diff --git a/drivers/auxdisplay/ht16k33.c b/drivers/auxdisplay/ht16k33.c index d951d54b26f5..444f3b1019e3 100644 --- a/drivers/auxdisplay/ht16k33.c +++ b/drivers/auxdisplay/ht16k33.c @@ -402,11 +402,6 @@ static int ht16k33_probe(struct i2c_client *client, return -EIO; } - if (client->irq <= 0) { - dev_err(&client->dev, "No IRQ specified\n"); - return -EINVAL; - } - priv = devm_kzalloc(&client->dev, sizeof(*priv), GFP_KERNEL); if (!priv) return -ENOMEM; @@ -459,9 +454,12 @@ static int ht16k33_probe(struct i2c_client *client, if (err) goto err_fbdev_info; - err = ht16k33_keypad_probe(client, &priv->keypad); - if (err) - goto err_fbdev_unregister; + /* Keypad */ + if (client->irq > 0) { + err = ht16k33_keypad_probe(client, &priv->keypad); + if (err) + goto err_fbdev_unregister; + } /* Backlight */ memset(&bl_props, 0, sizeof(struct backlight_properties)); -- cgit v1.2.3 From f15cf04db3e706711d1311d570c3a9f493b30904 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Mon, 18 Jan 2021 13:35:37 +0100 Subject: dt-bindings: auxdisplay: ht16k33: Fix default-brightness-level range V4 changed the range from 0..15 to 1..16 in the driver, to match the dimming set hardware register, but forgot to update the DT binding documentation. Signed-off-by: Geert Uytterhoeven Acked-by: Robin van der Gracht Signed-off-by: Miguel Ojeda --- Documentation/devicetree/bindings/display/ht16k33.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/display/ht16k33.txt b/Documentation/devicetree/bindings/display/ht16k33.txt index 3d602f5b9eb6..ec4377697016 100644 --- a/Documentation/devicetree/bindings/display/ht16k33.txt +++ b/Documentation/devicetree/bindings/display/ht16k33.txt @@ -8,7 +8,7 @@ Required properties: Optional properties: - linux,no-autorepeat: Disable keyrepeat. -- default-brightness-level: Initial brightness level [0-15] (default: 15). +- default-brightness-level: Initial brightness level [1-16] (default: 16). - Keypad Supply the 'interrupts' property to enable the keyscan feature. -- cgit v1.2.3 From f12b457c6b25c530499438dffab4f2184e67e819 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Mon, 18 Jan 2021 13:35:38 +0100 Subject: dt-bindings: auxdisplay: ht16k33: Convert to json-schema Convert the Holtek HT16K33 LED controller with keyscan Device Tree binding documentation to json-schema. Move the file from display to auxdisplay. Update the example: - Sort properties in order of documentation, - Group tuples using angle brackets to improve human readability and enable automatic validation. Signed-off-by: Geert Uytterhoeven Acked-by: Robin van der Gracht Signed-off-by: Miguel Ojeda --- .../bindings/auxdisplay/holtek,ht16k33.yaml | 77 ++++++++++++++++++++++ .../devicetree/bindings/display/ht16k33.txt | 43 ------------ MAINTAINERS | 2 +- 3 files changed, 78 insertions(+), 44 deletions(-) create mode 100644 Documentation/devicetree/bindings/auxdisplay/holtek,ht16k33.yaml delete mode 100644 Documentation/devicetree/bindings/display/ht16k33.txt (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/auxdisplay/holtek,ht16k33.yaml b/Documentation/devicetree/bindings/auxdisplay/holtek,ht16k33.yaml new file mode 100644 index 000000000000..64ffff460026 --- /dev/null +++ b/Documentation/devicetree/bindings/auxdisplay/holtek,ht16k33.yaml @@ -0,0 +1,77 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/auxdisplay/holtek,ht16k33.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Holtek HT16K33 RAM mapping 16*8 LED controller with keyscan + +maintainers: + - Robin van der Gracht + +allOf: + - $ref: "/schemas/input/matrix-keymap.yaml#" + +properties: + compatible: + const: holtek,ht16k33 + + reg: + maxItems: 1 + + refresh-rate-hz: + maxItems: 1 + description: Display update interval in Hertz + + interrupts: + maxItems: 1 + + debounce-delay-ms: + maxItems: 1 + description: Debouncing interval time in milliseconds + + linux,keymap: true + + linux,no-autorepeat: + description: Disable keyrepeat + + default-brightness-level: + minimum: 1 + maximum: 16 + default: 16 + description: Initial brightness level + +required: + - compatible + - reg + - refresh-rate-hz + +additionalProperties: false + +examples: + - | + #include + #include + i2c1 { + #address-cells = <1>; + #size-cells = <0>; + + ht16k33: ht16k33@70 { + compatible = "holtek,ht16k33"; + reg = <0x70>; + refresh-rate-hz = <20>; + interrupt-parent = <&gpio4>; + interrupts = <5 (IRQ_TYPE_LEVEL_HIGH | IRQ_TYPE_EDGE_RISING)>; + debounce-delay-ms = <50>; + linux,keymap = , + , + , + , + , + , + , + , + , + ; + }; + }; diff --git a/Documentation/devicetree/bindings/display/ht16k33.txt b/Documentation/devicetree/bindings/display/ht16k33.txt deleted file mode 100644 index ec4377697016..000000000000 --- a/Documentation/devicetree/bindings/display/ht16k33.txt +++ /dev/null @@ -1,43 +0,0 @@ -Holtek ht16k33 RAM mapping 16*8 LED controller driver with keyscan -------------------------------------------------------------------------------- - -Required properties: -- compatible: "holtek,ht16k33" -- reg: I2C slave address of the chip. -- refresh-rate-hz: Display update interval in HZ. - -Optional properties: -- linux,no-autorepeat: Disable keyrepeat. -- default-brightness-level: Initial brightness level [1-16] (default: 16). - -- Keypad - Supply the 'interrupts' property to enable the keyscan feature. - - interrupts: Interrupt specification for the key pressed interrupt. - - debounce-delay-ms: Debouncing interval time in milliseconds. - - linux,keymap: The keymap for keys as described in the binding - document (devicetree/bindings/input/matrix-keymap.txt). - -Example: - -&i2c1 { - ht16k33: ht16k33@70 { - compatible = "holtek,ht16k33"; - reg = <0x70>; - refresh-rate-hz = <20>; - debounce-delay-ms = <50>; - interrupt-parent = <&gpio4>; - interrupts = <5 (IRQ_TYPE_LEVEL_HIGH | IRQ_TYPE_EDGE_RISING)>; - linux,keymap = < - MATRIX_KEY(2, 0, KEY_F6) - MATRIX_KEY(3, 0, KEY_F8) - MATRIX_KEY(4, 0, KEY_F10) - MATRIX_KEY(5, 0, KEY_F4) - MATRIX_KEY(6, 0, KEY_F2) - MATRIX_KEY(2, 1, KEY_F5) - MATRIX_KEY(3, 1, KEY_F7) - MATRIX_KEY(4, 1, KEY_F9) - MATRIX_KEY(5, 1, KEY_F3) - MATRIX_KEY(6, 1, KEY_F1) - >; - }; -}; diff --git a/MAINTAINERS b/MAINTAINERS index 992fe3b0900a..efa686f028a9 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -8159,7 +8159,7 @@ F: net/hsr/ HT16K33 LED CONTROLLER DRIVER M: Robin van der Gracht S: Maintained -F: Documentation/devicetree/bindings/display/ht16k33.txt +F: Documentation/devicetree/bindings/auxdisplay/holtek,ht16k33.yaml F: drivers/auxdisplay/ht16k33.c HTCPEN TOUCHSCREEN DRIVER -- cgit v1.2.3 From 9b6164342e981d751e69f5a165dd596ffcdfd6fe Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Sat, 23 Jan 2021 22:33:33 +0900 Subject: doc: gcc-plugins: update gcc-plugins.rst This document was written a long time ago. Update it. [1] Drop the version information The range of the supported GCC versions are always changing. The current minimal GCC version is 4.9, and commit 1e860048c53e ("gcc-plugins: simplify GCC plugin-dev capability test") removed the old code accordingly. We do not need to mention specific version ranges like "all gcc versions from 4.5 to 6.0" since we forget to update the documentation when we raise the minimal compiler version. [2] Drop the C compiler statements Since commit 77342a02ff6e ("gcc-plugins: drop support for GCC <= 4.7") the GCC plugin infrastructure only supports g++. [3] Drop supported architectures As of v5.11-rc4, the infrastructure supports more architectures; arm, arm64, mips, powerpc, riscv, s390, um, and x86. (just grep "select HAVE_GCC_PLUGINS") Again, we miss to update this document when a new architecture is supported. Let's just say "only some architectures". [4] Update the apt-get example We are now discussing to bump the minimal version to GCC 5. The GCC 4.9 support will be removed sooner or later. Change the package example to gcc-10-plugin-dev while we are here. [5] Update the build target Since commit ce2fd53a10c7 ("kbuild: descend into scripts/gcc-plugins/ via scripts/Makefile"), "make gcc-plugins" is not supported. "make scripts" builds all the enabled plugins, including some other tools. [6] Update the steps for adding a new plugin At first, all CONFIG options for GCC plugins were located in arch/Kconfig. After commit 45332b1bdfdc ("gcc-plugins: split out Kconfig entries to scripts/gcc-plugins/Kconfig"), scripts/gcc-plugins/Kconfig became the central place to collect plugin CONFIG options. In my understanding, this requirement no longer exists because commit 9f671e58159a ("security: Create "kernel hardening" config area") moved some of plugin CONFIG options to another file. Find an appropriate place to add the new CONFIG. The sub-directory support was never used by anyone, and removed by commit c17d6179ad5a ("gcc-plugins: remove unused GCC_PLUGIN_SUBDIR"). Remove the useless $(src)/ prefix. Signed-off-by: Masahiro Yamada --- Documentation/kbuild/gcc-plugins.rst | 41 ++++++++++++++++++------------------ 1 file changed, 21 insertions(+), 20 deletions(-) (limited to 'Documentation') diff --git a/Documentation/kbuild/gcc-plugins.rst b/Documentation/kbuild/gcc-plugins.rst index 63379d0150e3..3349966f213d 100644 --- a/Documentation/kbuild/gcc-plugins.rst +++ b/Documentation/kbuild/gcc-plugins.rst @@ -11,16 +11,13 @@ compiler [1]_. They are useful for runtime instrumentation and static analysis. We can analyse, change and add further code during compilation via callbacks [2]_, GIMPLE [3]_, IPA [4]_ and RTL passes [5]_. -The GCC plugin infrastructure of the kernel supports all gcc versions from -4.5 to 6.0, building out-of-tree modules, cross-compilation and building in a -separate directory. -Plugin source files have to be compilable by both a C and a C++ compiler as well -because gcc versions 4.5 and 4.6 are compiled by a C compiler, -gcc-4.7 can be compiled by a C or a C++ compiler, -and versions 4.8+ can only be compiled by a C++ compiler. +The GCC plugin infrastructure of the kernel supports building out-of-tree +modules, cross-compilation and building in a separate directory. +Plugin source files have to be compilable by a C++ compiler. -Currently the GCC plugin infrastructure supports only the x86, arm, arm64 and -powerpc architectures. +Currently the GCC plugin infrastructure supports only some architectures. +Grep "select HAVE_GCC_PLUGINS" to find out which architectures support +GCC plugins. This infrastructure was ported from grsecurity [6]_ and PaX [7]_. @@ -53,8 +50,7 @@ $(src)/scripts/gcc-plugins/gcc-generate-simple_ipa-pass.h, $(src)/scripts/gcc-plugins/gcc-generate-rtl-pass.h** These headers automatically generate the registration structures for - GIMPLE, SIMPLE_IPA, IPA and RTL passes. They support all gcc versions - from 4.5 to 6.0. + GIMPLE, SIMPLE_IPA, IPA and RTL passes. They should be preferred to creating the structures by hand. @@ -62,21 +58,25 @@ Usage ===== You must install the gcc plugin headers for your gcc version, -e.g., on Ubuntu for gcc-4.9:: +e.g., on Ubuntu for gcc-10:: - apt-get install gcc-4.9-plugin-dev + apt-get install gcc-10-plugin-dev Or on Fedora:: dnf install gcc-plugin-devel -Enable a GCC plugin based feature in the kernel config:: +Enable the GCC plugin infrastructure and some plugin(s) you want to use +in the kernel config:: - CONFIG_GCC_PLUGIN_CYC_COMPLEXITY = y + CONFIG_GCC_PLUGINS=y + CONFIG_GCC_PLUGIN_CYC_COMPLEXITY=y + CONFIG_GCC_PLUGIN_LATENT_ENTROPY=y + ... -To compile only the plugin(s):: +To compile the minimum tool set including the plugin(s):: - make gcc-plugins + make scripts or just run the kernel make and compile the whole kernel with the cyclomatic complexity GCC plugin. @@ -85,7 +85,8 @@ the cyclomatic complexity GCC plugin. 4. How to add a new GCC plugin ============================== -The GCC plugins are in $(src)/scripts/gcc-plugins/. You can use a file or a directory -here. It must be added to $(src)/scripts/gcc-plugins/Makefile, -$(src)/scripts/Makefile.gcc-plugins and $(src)/arch/Kconfig. +The GCC plugins are in scripts/gcc-plugins/. You need to put plugin source files +right under scripts/gcc-plugins/. Creating subdirectories is not supported. +It must be added to scripts/gcc-plugins/Makefile, scripts/Makefile.gcc-plugins +and a relevant Kconfig file. See the cyc_complexity_plugin.c (CONFIG_GCC_PLUGIN_CYC_COMPLEXITY) GCC plugin. -- cgit v1.2.3 From 453b674178327950e8517172c82107c43af222e4 Mon Sep 17 00:00:00 2001 From: Grygorii Strashko Date: Fri, 15 Jan 2021 21:31:24 +0200 Subject: dt-bindings: usb: j721e: add ranges and dma-coherent props Add missed 'ranges' and 'dma-coherent' properties as cdns-usb DT nodes has child node and DMA IO is coherent on TI K3 J721E/J7200 SoCs. This also fixes dtbs_check warning: cdns-usb@4104000: 'dma-coherent', 'ranges' do not match any of the regexes: '^usb@', 'pinctrl-[0-9]+' Signed-off-by: Grygorii Strashko Acked-by: Aswath Govindraju Reviewed-by: Aswath Govindraju Link: https://lore.kernel.org/r/20210115193124.5706-1-grygorii.strashko@ti.com Signed-off-by: Rob Herring --- Documentation/devicetree/bindings/usb/ti,j721e-usb.yaml | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/usb/ti,j721e-usb.yaml b/Documentation/devicetree/bindings/usb/ti,j721e-usb.yaml index 388245b91a55..64b0b92aa050 100644 --- a/Documentation/devicetree/bindings/usb/ti,j721e-usb.yaml +++ b/Documentation/devicetree/bindings/usb/ti,j721e-usb.yaml @@ -17,6 +17,8 @@ properties: reg: description: module registers + ranges: true + power-domains: description: PM domain provider node and an args specifier containing @@ -58,6 +60,8 @@ properties: '#size-cells': const: 2 + dma-coherent: true + patternProperties: "^usb@": type: object -- cgit v1.2.3 From a10f373ad3c760dd40b41e2f69a800ee7b8da15e Mon Sep 17 00:00:00 2001 From: Quentin Perret Date: Fri, 8 Jan 2021 16:53:49 +0000 Subject: KVM: Documentation: Fix spec for KVM_CAP_ENABLE_CAP_VM The documentation classifies KVM_ENABLE_CAP with KVM_CAP_ENABLE_CAP_VM as a vcpu ioctl, which is incorrect. Fix it by specifying it as a VM ioctl. Fixes: e5d83c74a580 ("kvm: make KVM_CAP_ENABLE_CAP_VM architecture agnostic") Signed-off-by: Quentin Perret Message-Id: <20210108165349.747359-1-qperret@google.com> Signed-off-by: Paolo Bonzini --- Documentation/virt/kvm/api.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Documentation') diff --git a/Documentation/virt/kvm/api.rst b/Documentation/virt/kvm/api.rst index a9bf7f2ab76f..40b943a9bd1d 100644 --- a/Documentation/virt/kvm/api.rst +++ b/Documentation/virt/kvm/api.rst @@ -1336,7 +1336,7 @@ documentation when it pops into existence). :Capability: KVM_CAP_ENABLE_CAP_VM :Architectures: all -:Type: vcpu ioctl +:Type: vm ioctl :Parameters: struct kvm_enable_cap (in) :Returns: 0 on success; -1 on error -- cgit v1.2.3 From 01ead84ccd23afadebe66aea0eda002ac29ca9be Mon Sep 17 00:00:00 2001 From: Zenghui Yu Date: Tue, 8 Dec 2020 12:34:39 +0800 Subject: KVM: Documentation: Update description of KVM_{GET,CLEAR}_DIRTY_LOG Update various words, including the wrong parameter name and the vague description of the usage of "slot" field. Signed-off-by: Zenghui Yu Message-Id: <20201208043439.895-1-yuzenghui@huawei.com> Signed-off-by: Paolo Bonzini --- Documentation/virt/kvm/api.rst | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) (limited to 'Documentation') diff --git a/Documentation/virt/kvm/api.rst b/Documentation/virt/kvm/api.rst index 40b943a9bd1d..99ceb978c8b0 100644 --- a/Documentation/virt/kvm/api.rst +++ b/Documentation/virt/kvm/api.rst @@ -360,10 +360,9 @@ since the last call to this ioctl. Bit 0 is the first page in the memory slot. Ensure the entire structure is cleared to avoid padding issues. -If KVM_CAP_MULTI_ADDRESS_SPACE is available, bits 16-31 specifies -the address space for which you want to return the dirty bitmap. -They must be less than the value that KVM_CHECK_EXTENSION returns for -the KVM_CAP_MULTI_ADDRESS_SPACE capability. +If KVM_CAP_MULTI_ADDRESS_SPACE is available, bits 16-31 of slot field specifies +the address space for which you want to return the dirty bitmap. See +KVM_SET_USER_MEMORY_REGION for details on the usage of slot field. The bits in the dirty bitmap are cleared before the ioctl returns, unless KVM_CAP_MANUAL_DIRTY_LOG_PROTECT2 is enabled. For more information, @@ -4435,7 +4434,7 @@ to I/O ports. :Capability: KVM_CAP_MANUAL_DIRTY_LOG_PROTECT2 :Architectures: x86, arm, arm64, mips :Type: vm ioctl -:Parameters: struct kvm_dirty_log (in) +:Parameters: struct kvm_clear_dirty_log (in) :Returns: 0 on success, -1 on error :: @@ -4462,10 +4461,9 @@ in KVM's dirty bitmap, and dirty tracking is re-enabled for that page (for example via write-protection, or by clearing the dirty bit in a page table entry). -If KVM_CAP_MULTI_ADDRESS_SPACE is available, bits 16-31 specifies -the address space for which you want to return the dirty bitmap. -They must be less than the value that KVM_CHECK_EXTENSION returns for -the KVM_CAP_MULTI_ADDRESS_SPACE capability. +If KVM_CAP_MULTI_ADDRESS_SPACE is available, bits 16-31 of slot field specifies +the address space for which you want to clear the dirty status. See +KVM_SET_USER_MEMORY_REGION for details on the usage of slot field. This ioctl is mostly useful when KVM_CAP_MANUAL_DIRTY_LOG_PROTECT2 is enabled; for more information, see the description of the capability. -- cgit v1.2.3 From 974d5ba60df74483c69a2ccf580308de68769ec7 Mon Sep 17 00:00:00 2001 From: DENG Qingfang Date: Mon, 25 Jan 2021 12:43:21 +0800 Subject: dt-bindings: net: dsa: add MT7530 GPIO controller binding Add device tree binding to support MT7530 GPIO controller. Signed-off-by: DENG Qingfang Acked-by: Rob Herring Reviewed-by: Andrew Lunn Reviewed-by: Linus Walleij Signed-off-by: Jakub Kicinski --- Documentation/devicetree/bindings/net/dsa/mt7530.txt | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/net/dsa/mt7530.txt b/Documentation/devicetree/bindings/net/dsa/mt7530.txt index 560369efad6c..de04626a8e9d 100644 --- a/Documentation/devicetree/bindings/net/dsa/mt7530.txt +++ b/Documentation/devicetree/bindings/net/dsa/mt7530.txt @@ -76,6 +76,12 @@ phy-mode must be set, see also example 2 below! * mt7621: phy-mode = "rgmii-txid"; * mt7623: phy-mode = "rgmii"; +Optional properties: + +- gpio-controller: Boolean; if defined, MT7530's LED controller will run on + GPIO mode. +- #gpio-cells: Must be 2 if gpio-controller is defined. + See Documentation/devicetree/bindings/net/dsa/dsa.txt for a list of additional required, optional properties and how the integrated switch subnodes must be specified. -- cgit v1.2.3 From 65d41b143329669e46f5306b867ac97b3beb38df Mon Sep 17 00:00:00 2001 From: Claudiu Beznea Date: Fri, 22 Jan 2021 14:21:36 +0200 Subject: dt-bindings: atmel-sysreg: add "microchip, sama7g5-chipid" Add DT binding for SAMA7G5's CHIPID. Signed-off-by: Claudiu Beznea Signed-off-by: Nicolas Ferre Link: https://lore.kernel.org/r/1611318097-8970-7-git-send-email-claudiu.beznea@microchip.com --- Documentation/devicetree/bindings/arm/atmel-sysregs.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/arm/atmel-sysregs.txt b/Documentation/devicetree/bindings/arm/atmel-sysregs.txt index 62cd4e89817c..67719f15eb4c 100644 --- a/Documentation/devicetree/bindings/arm/atmel-sysregs.txt +++ b/Documentation/devicetree/bindings/arm/atmel-sysregs.txt @@ -1,7 +1,7 @@ Atmel system registers Chipid required properties: -- compatible: Should be "atmel,sama5d2-chipid" +- compatible: Should be "atmel,sama5d2-chipid" or "microchip,sama7g5-chipid" - reg : Should contain registers location and length PIT Timer required properties: -- cgit v1.2.3 From e6f93c0115cb24ae4b473f28a27294e99faf129a Mon Sep 17 00:00:00 2001 From: Vinod Koul Date: Fri, 15 Jan 2021 14:39:40 +0530 Subject: dt-bindings: qcom,pdc: Add compatible for SM8250 Add the compatible string for SM8250 SoC from Qualcomm. This compatible is used already in DTS files but not documented yet Signed-off-by: Vinod Koul Reviewed-by: Bjorn Andersson Acked-by: Rob Herring Signed-off-by: Marc Zyngier Link: https://lore.kernel.org/r/20210115090941.2289416-1-vkoul@kernel.org --- Documentation/devicetree/bindings/interrupt-controller/qcom,pdc.txt | 1 + 1 file changed, 1 insertion(+) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/interrupt-controller/qcom,pdc.txt b/Documentation/devicetree/bindings/interrupt-controller/qcom,pdc.txt index 1df293953327..9c1a046e6fd9 100644 --- a/Documentation/devicetree/bindings/interrupt-controller/qcom,pdc.txt +++ b/Documentation/devicetree/bindings/interrupt-controller/qcom,pdc.txt @@ -20,6 +20,7 @@ Properties: Definition: Should contain "qcom,-pdc" and "qcom,pdc" - "qcom,sc7180-pdc": For SC7180 - "qcom,sdm845-pdc": For SDM845 + - "qcom,sdm8250-pdc": For SM8250 - reg: Usage: required -- cgit v1.2.3 From 9eaad15e5a409f59660f9fdf867f7d3e6e3db15a Mon Sep 17 00:00:00 2001 From: Vinod Koul Date: Fri, 15 Jan 2021 14:39:41 +0530 Subject: dt-bindings: qcom,pdc: Add compatible for SM8350 Add the compatible string for SM8350 SoC from Qualcomm. Signed-off-by: Vinod Koul Acked-by: Rob Herring Signed-off-by: Marc Zyngier Link: https://lore.kernel.org/r/20210115090941.2289416-2-vkoul@kernel.org --- Documentation/devicetree/bindings/interrupt-controller/qcom,pdc.txt | 1 + 1 file changed, 1 insertion(+) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/interrupt-controller/qcom,pdc.txt b/Documentation/devicetree/bindings/interrupt-controller/qcom,pdc.txt index 9c1a046e6fd9..e9afb48182c7 100644 --- a/Documentation/devicetree/bindings/interrupt-controller/qcom,pdc.txt +++ b/Documentation/devicetree/bindings/interrupt-controller/qcom,pdc.txt @@ -21,6 +21,7 @@ Properties: - "qcom,sc7180-pdc": For SC7180 - "qcom,sdm845-pdc": For SDM845 - "qcom,sdm8250-pdc": For SM8250 + - "qcom,sdm8350-pdc": For SM8350 - reg: Usage: required -- cgit v1.2.3 From 7af6fbddbd3379243f11367ca03e2635e42b89ba Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Wed, 20 Jan 2021 16:47:13 +0000 Subject: Documentation: livepatch: Convert to automatically generated contents Automatically generate the tables of contents for livepatch documentation files that have tables of contents rather than open coding them so things are a little easier to maintain. Signed-off-by: Mark Brown Acked-by: Josh Poimboeuf Signed-off-by: Jiri Kosina --- Documentation/livepatch/livepatch.rst | 15 +-------------- Documentation/livepatch/module-elf-format.rst | 10 ++-------- 2 files changed, 3 insertions(+), 22 deletions(-) (limited to 'Documentation') diff --git a/Documentation/livepatch/livepatch.rst b/Documentation/livepatch/livepatch.rst index c2c598c4ead8..68e3651e8af9 100644 --- a/Documentation/livepatch/livepatch.rst +++ b/Documentation/livepatch/livepatch.rst @@ -6,20 +6,7 @@ This document outlines basic information about kernel livepatching. .. Table of Contents: - 1. Motivation - 2. Kprobes, Ftrace, Livepatching - 3. Consistency model - 4. Livepatch module - 4.1. New functions - 4.2. Metadata - 5. Livepatch life-cycle - 5.1. Loading - 5.2. Enabling - 5.3. Replacing - 5.4. Disabling - 5.5. Removing - 6. Sysfs - 7. Limitations +.. contents:: :local: 1. Motivation diff --git a/Documentation/livepatch/module-elf-format.rst b/Documentation/livepatch/module-elf-format.rst index 8c6b894c4661..dbe9b400e39f 100644 --- a/Documentation/livepatch/module-elf-format.rst +++ b/Documentation/livepatch/module-elf-format.rst @@ -7,14 +7,8 @@ This document outlines the Elf format requirements that livepatch modules must f .. Table of Contents - 1. Background and motivation - 2. Livepatch modinfo field - 3. Livepatch relocation sections - 3.1 Livepatch relocation section format - 4. Livepatch symbols - 4.1 A livepatch module's symbol table - 4.2 Livepatch symbol format - 5. Symbol table and Elf section access +.. contents:: :local: + 1. Background and motivation ============================ -- cgit v1.2.3 From f89f20acff2d0f7a4801dc6ecde3de1ef0abe1d2 Mon Sep 17 00:00:00 2001 From: Mark Rutland Date: Wed, 20 Jan 2021 16:47:14 +0000 Subject: Documentation: livepatch: document reliable stacktrace Add documentation for reliable stacktrace. This is intended to describe the semantics and to be an aid for implementing architecture support for HAVE_RELIABLE_STACKTRACE. Unwinding is a subtle area, and architectures vary greatly in both implementation and the set of concerns that affect them, so I've tried to avoid making this too specific to any given architecture. I've used examples from both x86_64 and arm64 to explain corner cases in more detail, but I've tried to keep the descriptions sufficient for those who are unfamiliar with the particular architecture. This document aims to give rationale for all the recommendations and requirements, since that makes it easier to spot nearby issues, or when a check happens to catch a few things at once. Signed-off-by: Mark Rutland [Updates following review -- broonie] Acked-by: Josh Poimboeuf Reviewed-by: Randy Dunlap Signed-off-by: Mark Brown Signed-off-by: Jiri Kosina --- Documentation/livepatch/index.rst | 1 + Documentation/livepatch/reliable-stacktrace.rst | 309 ++++++++++++++++++++++++ 2 files changed, 310 insertions(+) create mode 100644 Documentation/livepatch/reliable-stacktrace.rst (limited to 'Documentation') diff --git a/Documentation/livepatch/index.rst b/Documentation/livepatch/index.rst index 525944063be7..43cce5fad705 100644 --- a/Documentation/livepatch/index.rst +++ b/Documentation/livepatch/index.rst @@ -13,6 +13,7 @@ Kernel Livepatching module-elf-format shadow-vars system-state + reliable-stacktrace .. only:: subproject and html diff --git a/Documentation/livepatch/reliable-stacktrace.rst b/Documentation/livepatch/reliable-stacktrace.rst new file mode 100644 index 000000000000..67459d2ca2af --- /dev/null +++ b/Documentation/livepatch/reliable-stacktrace.rst @@ -0,0 +1,309 @@ +=================== +Reliable Stacktrace +=================== + +This document outlines basic information about reliable stacktracing. + +.. Table of Contents: + +.. contents:: :local: + +1. Introduction +=============== + +The kernel livepatch consistency model relies on accurately identifying which +functions may have live state and therefore may not be safe to patch. One way +to identify which functions are live is to use a stacktrace. + +Existing stacktrace code may not always give an accurate picture of all +functions with live state, and best-effort approaches which can be helpful for +debugging are unsound for livepatching. Livepatching depends on architectures +to provide a *reliable* stacktrace which ensures it never omits any live +functions from a trace. + + +2. Requirements +=============== + +Architectures must implement one of the reliable stacktrace functions. +Architectures using CONFIG_ARCH_STACKWALK must implement +'arch_stack_walk_reliable', and other architectures must implement +'save_stack_trace_tsk_reliable'. + +Principally, the reliable stacktrace function must ensure that either: + +* The trace includes all functions that the task may be returned to, and the + return code is zero to indicate that the trace is reliable. + +* The return code is non-zero to indicate that the trace is not reliable. + +.. note:: + In some cases it is legitimate to omit specific functions from the trace, + but all other functions must be reported. These cases are described in + futher detail below. + +Secondly, the reliable stacktrace function must be robust to cases where +the stack or other unwind state is corrupt or otherwise unreliable. The +function should attempt to detect such cases and return a non-zero error +code, and should not get stuck in an infinite loop or access memory in +an unsafe way. Specific cases are described in further detail below. + + +3. Compile-time analysis +======================== + +To ensure that kernel code can be correctly unwound in all cases, +architectures may need to verify that code has been compiled in a manner +expected by the unwinder. For example, an unwinder may expect that +functions manipulate the stack pointer in a limited way, or that all +functions use specific prologue and epilogue sequences. Architectures +with such requirements should verify the kernel compilation using +objtool. + +In some cases, an unwinder may require metadata to correctly unwind. +Where necessary, this metadata should be generated at build time using +objtool. + + +4. Considerations +================= + +The unwinding process varies across architectures, their respective procedure +call standards, and kernel configurations. This section describes common +details that architectures should consider. + +4.1 Identifying successful termination +-------------------------------------- + +Unwinding may terminate early for a number of reasons, including: + +* Stack or frame pointer corruption. + +* Missing unwind support for an uncommon scenario, or a bug in the unwinder. + +* Dynamically generated code (e.g. eBPF) or foreign code (e.g. EFI runtime + services) not following the conventions expected by the unwinder. + +To ensure that this does not result in functions being omitted from the trace, +even if not caught by other checks, it is strongly recommended that +architectures verify that a stacktrace ends at an expected location, e.g. + +* Within a specific function that is an entry point to the kernel. + +* At a specific location on a stack expected for a kernel entry point. + +* On a specific stack expected for a kernel entry point (e.g. if the + architecture has separate task and IRQ stacks). + +4.2 Identifying unwindable code +------------------------------- + +Unwinding typically relies on code following specific conventions (e.g. +manipulating a frame pointer), but there can be code which may not follow these +conventions and may require special handling in the unwinder, e.g. + +* Exception vectors and entry assembly. + +* Procedure Linkage Table (PLT) entries and veneer functions. + +* Trampoline assembly (e.g. ftrace, kprobes). + +* Dynamically generated code (e.g. eBPF, optprobe trampolines). + +* Foreign code (e.g. EFI runtime services). + +To ensure that such cases do not result in functions being omitted from a +trace, it is strongly recommended that architectures positively identify code +which is known to be reliable to unwind from, and reject unwinding from all +other code. + +Kernel code including modules and eBPF can be distinguished from foreign code +using '__kernel_text_address()'. Checking for this also helps to detect stack +corruption. + +There are several ways an architecture may identify kernel code which is deemed +unreliable to unwind from, e.g. + +* Placing such code into special linker sections, and rejecting unwinding from + any code in these sections. + +* Identifying specific portions of code using bounds information. + +4.3 Unwinding across interrupts and exceptions +---------------------------------------------- + +At function call boundaries the stack and other unwind state is expected to be +in a consistent state suitable for reliable unwinding, but this may not be the +case part-way through a function. For example, during a function prologue or +epilogue a frame pointer may be transiently invalid, or during the function +body the return address may be held in an arbitrary general purpose register. +For some architectures this may change at runtime as a result of dynamic +instrumentation. + +If an interrupt or other exception is taken while the stack or other unwind +state is in an inconsistent state, it may not be possible to reliably unwind, +and it may not be possible to identify whether such unwinding will be reliable. +See below for examples. + +Architectures which cannot identify when it is reliable to unwind such cases +(or where it is never reliable) must reject unwinding across exception +boundaries. Note that it may be reliable to unwind across certain +exceptions (e.g. IRQ) but unreliable to unwind across other exceptions +(e.g. NMI). + +Architectures which can identify when it is reliable to unwind such cases (or +have no such cases) should attempt to unwind across exception boundaries, as +doing so can prevent unnecessarily stalling livepatch consistency checks and +permits livepatch transitions to complete more quickly. + +4.4 Rewriting of return addresses +--------------------------------- + +Some trampolines temporarily modify the return address of a function in order +to intercept when that function returns with a return trampoline, e.g. + +* An ftrace trampoline may modify the return address so that function graph + tracing can intercept returns. + +* A kprobes (or optprobes) trampoline may modify the return address so that + kretprobes can intercept returns. + +When this happens, the original return address will not be in its usual +location. For trampolines which are not subject to live patching, where an +unwinder can reliably determine the original return address and no unwind state +is altered by the trampoline, the unwinder may report the original return +address in place of the trampoline and report this as reliable. Otherwise, an +unwinder must report these cases as unreliable. + +Special care is required when identifying the original return address, as this +information is not in a consistent location for the duration of the entry +trampoline or return trampoline. For example, considering the x86_64 +'return_to_handler' return trampoline: + +.. code-block:: none + + SYM_CODE_START(return_to_handler) + UNWIND_HINT_EMPTY + subq $24, %rsp + + /* Save the return values */ + movq %rax, (%rsp) + movq %rdx, 8(%rsp) + movq %rbp, %rdi + + call ftrace_return_to_handler + + movq %rax, %rdi + movq 8(%rsp), %rdx + movq (%rsp), %rax + addq $24, %rsp + JMP_NOSPEC rdi + SYM_CODE_END(return_to_handler) + +While the traced function runs its return address on the stack points to +the start of return_to_handler, and the original return address is stored in +the task's cur_ret_stack. During this time the unwinder can find the return +address using ftrace_graph_ret_addr(). + +When the traced function returns to return_to_handler, there is no longer a +return address on the stack, though the original return address is still stored +in the task's cur_ret_stack. Within ftrace_return_to_handler(), the original +return address is removed from cur_ret_stack and is transiently moved +arbitrarily by the compiler before being returned in rax. The return_to_handler +trampoline moves this into rdi before jumping to it. + +Architectures might not always be able to unwind such sequences, such as when +ftrace_return_to_handler() has removed the address from cur_ret_stack, and the +location of the return address cannot be reliably determined. + +It is recommended that architectures unwind cases where return_to_handler has +not yet been returned to, but architectures are not required to unwind from the +middle of return_to_handler and can report this as unreliable. Architectures +are not required to unwind from other trampolines which modify the return +address. + +4.5 Obscuring of return addresses +--------------------------------- + +Some trampolines do not rewrite the return address in order to intercept +returns, but do transiently clobber the return address or other unwind state. + +For example, the x86_64 implementation of optprobes patches the probed function +with a JMP instruction which targets the associated optprobe trampoline. When +the probe is hit, the CPU will branch to the optprobe trampoline, and the +address of the probed function is not held in any register or on the stack. + +Similarly, the arm64 implementation of DYNAMIC_FTRACE_WITH_REGS patches traced +functions with the following: + +.. code-block:: none + + MOV X9, X30 + BL + +The MOV saves the link register (X30) into X9 to preserve the return address +before the BL clobbers the link register and branches to the trampoline. At the +start of the trampoline, the address of the traced function is in X9 rather +than the link register as would usually be the case. + +Architectures must either ensure that unwinders either reliably unwind +such cases, or report the unwinding as unreliable. + +4.6 Link register unreliability +------------------------------- + +On some other architectures, 'call' instructions place the return address into a +link register, and 'return' instructions consume the return address from the +link register without modifying the register. On these architectures software +must save the return address to the stack prior to making a function call. Over +the duration of a function call, the return address may be held in the link +register alone, on the stack alone, or in both locations. + +Unwinders typically assume the link register is always live, but this +assumption can lead to unreliable stack traces. For example, consider the +following arm64 assembly for a simple function: + +.. code-block:: none + + function: + STP X29, X30, [SP, -16]! + MOV X29, SP + BL + LDP X29, X30, [SP], #16 + RET + +At entry to the function, the link register (x30) points to the caller, and the +frame pointer (X29) points to the caller's frame including the caller's return +address. The first two instructions create a new stackframe and update the +frame pointer, and at this point the link register and the frame pointer both +describe this function's return address. A trace at this point may describe +this function twice, and if the function return is being traced, the unwinder +may consume two entries from the fgraph return stack rather than one entry. + +The BL invokes 'other_function' with the link register pointing to this +function's LDR and the frame pointer pointing to this function's stackframe. +When 'other_function' returns, the link register is left pointing at the BL, +and so a trace at this point could result in 'function' appearing twice in the +backtrace. + +Similarly, a function may deliberately clobber the LR, e.g. + +.. code-block:: none + + caller: + STP X29, X30, [SP, -16]! + MOV X29, SP + ADR LR, + BLR LR + LDP X29, X30, [SP], #16 + RET + +The ADR places the address of 'callee' into the LR, before the BLR branches to +this address. If a trace is made immediately after the ADR, 'callee' will +appear to be the parent of 'caller', rather than the child. + +Due to cases such as the above, it may only be possible to reliably consume a +link register value at a function call boundary. Architectures where this is +the case must reject unwinding across exception boundaries unless they can +reliably identify when the LR or stack value should be used (e.g. using +metadata generated by objtool). -- cgit v1.2.3 From 6589daf8bb98c75ad1065edad87c099ffb9f5d87 Mon Sep 17 00:00:00 2001 From: Andre Przywara Date: Mon, 25 Jan 2021 15:18:03 +0000 Subject: dt-bindings: spi: sunxi: Add H616 compatible string Add the obvious compatible name to the existing SPI binding, and pair it with the existing H3 fallback compatible string, as the devices are compatible. Signed-off-by: Andre Przywara Acked-by: Rob Herring Link: https://lore.kernel.org/r/20210125151811.11871-14-andre.przywara@arm.com Signed-off-by: Mark Brown --- Documentation/devicetree/bindings/spi/allwinner,sun6i-a31-spi.yaml | 1 + 1 file changed, 1 insertion(+) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/spi/allwinner,sun6i-a31-spi.yaml b/Documentation/devicetree/bindings/spi/allwinner,sun6i-a31-spi.yaml index 7866a655d81c..908248260afa 100644 --- a/Documentation/devicetree/bindings/spi/allwinner,sun6i-a31-spi.yaml +++ b/Documentation/devicetree/bindings/spi/allwinner,sun6i-a31-spi.yaml @@ -25,6 +25,7 @@ properties: - enum: - allwinner,sun8i-r40-spi - allwinner,sun50i-h6-spi + - allwinner,sun50i-h616-spi - const: allwinner,sun8i-h3-spi reg: -- cgit v1.2.3 From 564272718686ea1b3c8cea5e581c3b0e94c9d545 Mon Sep 17 00:00:00 2001 From: Konrad Dybcio Date: Fri, 15 Jan 2021 18:11:14 +0100 Subject: pinctrl: qcom: spmi-mpp: Add PM8019 compatible PM8019 provides 6 MPPs. Add a compatible to support them. Signed-off-by: Konrad Dybcio Acked-by: Rob Herring Link: https://lore.kernel.org/r/20210115171115.123155-2-konrad.dybcio@somainline.org Signed-off-by: Linus Walleij --- Documentation/devicetree/bindings/pinctrl/qcom,pmic-mpp.txt | 1 + drivers/pinctrl/qcom/pinctrl-spmi-mpp.c | 1 + 2 files changed, 2 insertions(+) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/pinctrl/qcom,pmic-mpp.txt b/Documentation/devicetree/bindings/pinctrl/qcom,pmic-mpp.txt index 448d36a85730..0ba07bc96c55 100644 --- a/Documentation/devicetree/bindings/pinctrl/qcom,pmic-mpp.txt +++ b/Documentation/devicetree/bindings/pinctrl/qcom,pmic-mpp.txt @@ -8,6 +8,7 @@ of PMIC's from Qualcomm. Value type: Definition: Should contain one of: "qcom,pm8018-mpp", + "qcom,pm8019-mpp", "qcom,pm8038-mpp", "qcom,pm8058-mpp", "qcom,pm8821-mpp", diff --git a/drivers/pinctrl/qcom/pinctrl-spmi-mpp.c b/drivers/pinctrl/qcom/pinctrl-spmi-mpp.c index 48602dba4967..3c213f799feb 100644 --- a/drivers/pinctrl/qcom/pinctrl-spmi-mpp.c +++ b/drivers/pinctrl/qcom/pinctrl-spmi-mpp.c @@ -912,6 +912,7 @@ static int pmic_mpp_remove(struct platform_device *pdev) } static const struct of_device_id pmic_mpp_of_match[] = { + { .compatible = "qcom,pm8019-mpp" }, /* 6 MPP's */ { .compatible = "qcom,pm8841-mpp" }, /* 4 MPP's */ { .compatible = "qcom,pm8916-mpp" }, /* 4 MPP's */ { .compatible = "qcom,pm8941-mpp" }, /* 8 MPP's */ -- cgit v1.2.3 From 9d5032f97e9e0655e8c507ab1f43237e31520b00 Mon Sep 17 00:00:00 2001 From: Robert Foss Date: Tue, 26 Jan 2021 14:25:31 +0100 Subject: dt-bindings: mediatek: mt8192: Fix dt_binding_check warning Silence indentation level warning reported by dt_binding_check in order to reduce noise during routine checks. $ make dt_binding_check mt8192-mt6359-rt1015-rt5682.yaml:10:4: [warning] wrong indentation: expected 2 but found 3 (indentation) Signed-off-by: Robert Foss Link: https://lore.kernel.org/r/20210126132531.2084711-2-robert.foss@linaro.org Signed-off-by: Linus Walleij --- .../devicetree/bindings/sound/mt8192-mt6359-rt1015-rt5682.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/sound/mt8192-mt6359-rt1015-rt5682.yaml b/Documentation/devicetree/bindings/sound/mt8192-mt6359-rt1015-rt5682.yaml index bf8c8ba25009..54650823b29a 100644 --- a/Documentation/devicetree/bindings/sound/mt8192-mt6359-rt1015-rt5682.yaml +++ b/Documentation/devicetree/bindings/sound/mt8192-mt6359-rt1015-rt5682.yaml @@ -7,8 +7,8 @@ $schema: http://devicetree.org/meta-schemas/core.yaml# title: Mediatek MT8192 with MT6359, RT1015 and RT5682 ASoC sound card driver maintainers: - - Jiaxin Yu - - Shane Chien + - Jiaxin Yu + - Shane Chien description: This binding describes the MT8192 sound card. -- cgit v1.2.3 From 6ce6acf6771e8e97611d989d1f97b0406425b961 Mon Sep 17 00:00:00 2001 From: Paul Cercueil Date: Wed, 20 Jan 2021 10:53:21 +0000 Subject: dt-bindings: dma: ingenic: Add compatible strings for JZ4760(B) SoCs Add ingenic,jz4760-dma and ingenic,jz4760b-dma compatible strings to support the DMA engines present in the JZ4760 and JZ4760B SoCs. Signed-off-by: Paul Cercueil Link: https://lore.kernel.org/r/20210120105322.16116-1-paul@crapouillou.net Signed-off-by: Vinod Koul --- Documentation/devicetree/bindings/dma/ingenic,dma.yaml | 2 ++ 1 file changed, 2 insertions(+) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/dma/ingenic,dma.yaml b/Documentation/devicetree/bindings/dma/ingenic,dma.yaml index 6a2043721b95..ac4d59494fc8 100644 --- a/Documentation/devicetree/bindings/dma/ingenic,dma.yaml +++ b/Documentation/devicetree/bindings/dma/ingenic,dma.yaml @@ -17,6 +17,8 @@ properties: enum: - ingenic,jz4740-dma - ingenic,jz4725b-dma + - ingenic,jz4760-dma + - ingenic,jz4760b-dma - ingenic,jz4770-dma - ingenic,jz4780-dma - ingenic,x1000-dma -- cgit v1.2.3 From be7ccfa6c303e619e92e4fc0398cf01922ee9603 Mon Sep 17 00:00:00 2001 From: Bjorn Andersson Date: Wed, 20 Jan 2021 10:09:39 -0800 Subject: dt-bindings: dma: intel-ldma: Fix $ref specifier The $ref for "intel,dma-poll-cnt" is missing an '/', causing dt_binding_check to fail. Fix this. Fixes: afd4df85602d ("dt-bindings: dma: Add bindings for Intel LGM SoC") Signed-off-by: Bjorn Andersson Acked-by: Rob Herring Link: https://lore.kernel.org/r/20210120180939.1580984-1-bjorn.andersson@linaro.org Signed-off-by: Vinod Koul --- Documentation/devicetree/bindings/dma/intel,ldma.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/dma/intel,ldma.yaml b/Documentation/devicetree/bindings/dma/intel,ldma.yaml index 866d4c758a7a..a5c4be783593 100644 --- a/Documentation/devicetree/bindings/dma/intel,ldma.yaml +++ b/Documentation/devicetree/bindings/dma/intel,ldma.yaml @@ -56,7 +56,7 @@ properties: maxItems: 1 intel,dma-poll-cnt: - $ref: /schemas/types.yaml#definitions/uint32 + $ref: /schemas/types.yaml#/definitions/uint32 description: DMA descriptor polling counter is used to control the poling mechanism for the descriptor fetching for all channels. -- cgit v1.2.3 From ec6ab42f5aadd765b0b8c4e2d21508ac1e20f2ed Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Wed, 20 Jan 2021 14:18:57 +0100 Subject: dmaengine: remove sirfsoc driver The CSR SiRF prima2/atlas platforms are getting removed, so this driver is no longer needed. Signed-off-by: Arnd Bergmann Acked-by: Barry Song Cc: Barry Song Link: https://lore.kernel.org/r/20210120131859.2056308-2-arnd@kernel.org Signed-off-by: Vinod Koul --- .../devicetree/bindings/dma/sirfsoc-dma.txt | 44 - drivers/dma/Kconfig | 7 - drivers/dma/Makefile | 1 - drivers/dma/sirf-dma.c | 1170 -------------------- include/linux/sirfsoc_dma.h | 7 - 5 files changed, 1229 deletions(-) delete mode 100644 Documentation/devicetree/bindings/dma/sirfsoc-dma.txt delete mode 100644 drivers/dma/sirf-dma.c delete mode 100644 include/linux/sirfsoc_dma.h (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/dma/sirfsoc-dma.txt b/Documentation/devicetree/bindings/dma/sirfsoc-dma.txt deleted file mode 100644 index ccd52d6a231a..000000000000 --- a/Documentation/devicetree/bindings/dma/sirfsoc-dma.txt +++ /dev/null @@ -1,44 +0,0 @@ -* CSR SiRFSoC DMA controller - -See dma.txt first - -Required properties: -- compatible: Should be "sirf,prima2-dmac", "sirf,atlas7-dmac" or - "sirf,atlas7-dmac-v2" -- reg: Should contain DMA registers location and length. -- interrupts: Should contain one interrupt shared by all channel -- #dma-cells: must be <1>. used to represent the number of integer - cells in the dmas property of client device. -- clocks: clock required - -Example: - -Controller: -dmac0: dma-controller@b00b0000 { - compatible = "sirf,prima2-dmac"; - reg = <0xb00b0000 0x10000>; - interrupts = <12>; - clocks = <&clks 24>; - #dma-cells = <1>; -}; - - -Client: -Fill the specific dma request line in dmas. In the below example, spi0 read -channel request line is 9 of the 2nd dma controller, while write channel uses -4 of the 2nd dma controller; spi1 read channel request line is 12 of the 1st -dma controller, while write channel uses 13 of the 1st dma controller: - -spi0: spi@b00d0000 { - compatible = "sirf,prima2-spi"; - dmas = <&dmac1 9>, - <&dmac1 4>; - dma-names = "rx", "tx"; -}; - -spi1: spi@b0170000 { - compatible = "sirf,prima2-spi"; - dmas = <&dmac0 12>, - <&dmac0 13>; - dma-names = "rx", "tx"; -}; diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig index 6c92f075f7ce..2201ff280f7a 100644 --- a/drivers/dma/Kconfig +++ b/drivers/dma/Kconfig @@ -519,13 +519,6 @@ config PLX_DMA These are exposed via extra functions on the switch's upstream port. Each function exposes one DMA channel. -config SIRF_DMA - tristate "CSR SiRFprimaII/SiRFmarco DMA support" - depends on ARCH_SIRF - select DMA_ENGINE - help - Enable support for the CSR SiRFprimaII DMA engine. - config STE_DMA40 bool "ST-Ericsson DMA40 support" depends on ARCH_U8500 diff --git a/drivers/dma/Makefile b/drivers/dma/Makefile index 649a4f95ea4b..b5b34c65b075 100644 --- a/drivers/dma/Makefile +++ b/drivers/dma/Makefile @@ -65,7 +65,6 @@ obj-$(CONFIG_PPC_BESTCOMM) += bestcomm/ obj-$(CONFIG_PXA_DMA) += pxa_dma.o obj-$(CONFIG_RENESAS_DMA) += sh/ obj-$(CONFIG_SF_PDMA) += sf-pdma/ -obj-$(CONFIG_SIRF_DMA) += sirf-dma.o obj-$(CONFIG_STE_DMA40) += ste_dma40.o ste_dma40_ll.o obj-$(CONFIG_STM32_DMA) += stm32-dma.o obj-$(CONFIG_STM32_DMAMUX) += stm32-dmamux.o diff --git a/drivers/dma/sirf-dma.c b/drivers/dma/sirf-dma.c deleted file mode 100644 index a5c2843384fd..000000000000 --- a/drivers/dma/sirf-dma.c +++ /dev/null @@ -1,1170 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * DMA controller driver for CSR SiRFprimaII - * - * Copyright (c) 2011 Cambridge Silicon Radio Limited, a CSR plc group company. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "dmaengine.h" - -#define SIRFSOC_DMA_VER_A7V1 1 -#define SIRFSOC_DMA_VER_A7V2 2 -#define SIRFSOC_DMA_VER_A6 4 - -#define SIRFSOC_DMA_DESCRIPTORS 16 -#define SIRFSOC_DMA_CHANNELS 16 -#define SIRFSOC_DMA_TABLE_NUM 256 - -#define SIRFSOC_DMA_CH_ADDR 0x00 -#define SIRFSOC_DMA_CH_XLEN 0x04 -#define SIRFSOC_DMA_CH_YLEN 0x08 -#define SIRFSOC_DMA_CH_CTRL 0x0C - -#define SIRFSOC_DMA_WIDTH_0 0x100 -#define SIRFSOC_DMA_CH_VALID 0x140 -#define SIRFSOC_DMA_CH_INT 0x144 -#define SIRFSOC_DMA_INT_EN 0x148 -#define SIRFSOC_DMA_INT_EN_CLR 0x14C -#define SIRFSOC_DMA_CH_LOOP_CTRL 0x150 -#define SIRFSOC_DMA_CH_LOOP_CTRL_CLR 0x154 -#define SIRFSOC_DMA_WIDTH_ATLAS7 0x10 -#define SIRFSOC_DMA_VALID_ATLAS7 0x14 -#define SIRFSOC_DMA_INT_ATLAS7 0x18 -#define SIRFSOC_DMA_INT_EN_ATLAS7 0x1c -#define SIRFSOC_DMA_LOOP_CTRL_ATLAS7 0x20 -#define SIRFSOC_DMA_CUR_DATA_ADDR 0x34 -#define SIRFSOC_DMA_MUL_ATLAS7 0x38 -#define SIRFSOC_DMA_CH_LOOP_CTRL_ATLAS7 0x158 -#define SIRFSOC_DMA_CH_LOOP_CTRL_CLR_ATLAS7 0x15C -#define SIRFSOC_DMA_IOBG_SCMD_EN 0x800 -#define SIRFSOC_DMA_EARLY_RESP_SET 0x818 -#define SIRFSOC_DMA_EARLY_RESP_CLR 0x81C - -#define SIRFSOC_DMA_MODE_CTRL_BIT 4 -#define SIRFSOC_DMA_DIR_CTRL_BIT 5 -#define SIRFSOC_DMA_MODE_CTRL_BIT_ATLAS7 2 -#define SIRFSOC_DMA_CHAIN_CTRL_BIT_ATLAS7 3 -#define SIRFSOC_DMA_DIR_CTRL_BIT_ATLAS7 4 -#define SIRFSOC_DMA_TAB_NUM_ATLAS7 7 -#define SIRFSOC_DMA_CHAIN_INT_BIT_ATLAS7 5 -#define SIRFSOC_DMA_CHAIN_FLAG_SHIFT_ATLAS7 25 -#define SIRFSOC_DMA_CHAIN_ADDR_SHIFT 32 - -#define SIRFSOC_DMA_INT_FINI_INT_ATLAS7 BIT(0) -#define SIRFSOC_DMA_INT_CNT_INT_ATLAS7 BIT(1) -#define SIRFSOC_DMA_INT_PAU_INT_ATLAS7 BIT(2) -#define SIRFSOC_DMA_INT_LOOP_INT_ATLAS7 BIT(3) -#define SIRFSOC_DMA_INT_INV_INT_ATLAS7 BIT(4) -#define SIRFSOC_DMA_INT_END_INT_ATLAS7 BIT(5) -#define SIRFSOC_DMA_INT_ALL_ATLAS7 0x3F - -/* xlen and dma_width register is in 4 bytes boundary */ -#define SIRFSOC_DMA_WORD_LEN 4 -#define SIRFSOC_DMA_XLEN_MAX_V1 0x800 -#define SIRFSOC_DMA_XLEN_MAX_V2 0x1000 - -struct sirfsoc_dma_desc { - struct dma_async_tx_descriptor desc; - struct list_head node; - - /* SiRFprimaII 2D-DMA parameters */ - - int xlen; /* DMA xlen */ - int ylen; /* DMA ylen */ - int width; /* DMA width */ - int dir; - bool cyclic; /* is loop DMA? */ - bool chain; /* is chain DMA? */ - u32 addr; /* DMA buffer address */ - u64 chain_table[SIRFSOC_DMA_TABLE_NUM]; /* chain tbl */ -}; - -struct sirfsoc_dma_chan { - struct dma_chan chan; - struct list_head free; - struct list_head prepared; - struct list_head queued; - struct list_head active; - struct list_head completed; - unsigned long happened_cyclic; - unsigned long completed_cyclic; - - /* Lock for this structure */ - spinlock_t lock; - - int mode; -}; - -struct sirfsoc_dma_regs { - u32 ctrl[SIRFSOC_DMA_CHANNELS]; - u32 interrupt_en; -}; - -struct sirfsoc_dma { - struct dma_device dma; - struct tasklet_struct tasklet; - struct sirfsoc_dma_chan channels[SIRFSOC_DMA_CHANNELS]; - void __iomem *base; - int irq; - struct clk *clk; - int type; - void (*exec_desc)(struct sirfsoc_dma_desc *sdesc, - int cid, int burst_mode, void __iomem *base); - struct sirfsoc_dma_regs regs_save; -}; - -struct sirfsoc_dmadata { - void (*exec)(struct sirfsoc_dma_desc *sdesc, - int cid, int burst_mode, void __iomem *base); - int type; -}; - -enum sirfsoc_dma_chain_flag { - SIRFSOC_DMA_CHAIN_NORMAL = 0x01, - SIRFSOC_DMA_CHAIN_PAUSE = 0x02, - SIRFSOC_DMA_CHAIN_LOOP = 0x03, - SIRFSOC_DMA_CHAIN_END = 0x04 -}; - -#define DRV_NAME "sirfsoc_dma" - -static int sirfsoc_dma_runtime_suspend(struct device *dev); - -/* Convert struct dma_chan to struct sirfsoc_dma_chan */ -static inline -struct sirfsoc_dma_chan *dma_chan_to_sirfsoc_dma_chan(struct dma_chan *c) -{ - return container_of(c, struct sirfsoc_dma_chan, chan); -} - -/* Convert struct dma_chan to struct sirfsoc_dma */ -static inline struct sirfsoc_dma *dma_chan_to_sirfsoc_dma(struct dma_chan *c) -{ - struct sirfsoc_dma_chan *schan = dma_chan_to_sirfsoc_dma_chan(c); - return container_of(schan, struct sirfsoc_dma, channels[c->chan_id]); -} - -static void sirfsoc_dma_execute_hw_a7v2(struct sirfsoc_dma_desc *sdesc, - int cid, int burst_mode, void __iomem *base) -{ - if (sdesc->chain) { - /* DMA v2 HW chain mode */ - writel_relaxed((sdesc->dir << SIRFSOC_DMA_DIR_CTRL_BIT_ATLAS7) | - (sdesc->chain << - SIRFSOC_DMA_CHAIN_CTRL_BIT_ATLAS7) | - (0x8 << SIRFSOC_DMA_TAB_NUM_ATLAS7) | 0x3, - base + SIRFSOC_DMA_CH_CTRL); - } else { - /* DMA v2 legacy mode */ - writel_relaxed(sdesc->xlen, base + SIRFSOC_DMA_CH_XLEN); - writel_relaxed(sdesc->ylen, base + SIRFSOC_DMA_CH_YLEN); - writel_relaxed(sdesc->width, base + SIRFSOC_DMA_WIDTH_ATLAS7); - writel_relaxed((sdesc->width*((sdesc->ylen+1)>>1)), - base + SIRFSOC_DMA_MUL_ATLAS7); - writel_relaxed((sdesc->dir << SIRFSOC_DMA_DIR_CTRL_BIT_ATLAS7) | - (sdesc->chain << - SIRFSOC_DMA_CHAIN_CTRL_BIT_ATLAS7) | - 0x3, base + SIRFSOC_DMA_CH_CTRL); - } - writel_relaxed(sdesc->chain ? SIRFSOC_DMA_INT_END_INT_ATLAS7 : - (SIRFSOC_DMA_INT_FINI_INT_ATLAS7 | - SIRFSOC_DMA_INT_LOOP_INT_ATLAS7), - base + SIRFSOC_DMA_INT_EN_ATLAS7); - writel(sdesc->addr, base + SIRFSOC_DMA_CH_ADDR); - if (sdesc->cyclic) - writel(0x10001, base + SIRFSOC_DMA_LOOP_CTRL_ATLAS7); -} - -static void sirfsoc_dma_execute_hw_a7v1(struct sirfsoc_dma_desc *sdesc, - int cid, int burst_mode, void __iomem *base) -{ - writel_relaxed(1, base + SIRFSOC_DMA_IOBG_SCMD_EN); - writel_relaxed((1 << cid), base + SIRFSOC_DMA_EARLY_RESP_SET); - writel_relaxed(sdesc->width, base + SIRFSOC_DMA_WIDTH_0 + cid * 4); - writel_relaxed(cid | (burst_mode << SIRFSOC_DMA_MODE_CTRL_BIT) | - (sdesc->dir << SIRFSOC_DMA_DIR_CTRL_BIT), - base + cid * 0x10 + SIRFSOC_DMA_CH_CTRL); - writel_relaxed(sdesc->xlen, base + cid * 0x10 + SIRFSOC_DMA_CH_XLEN); - writel_relaxed(sdesc->ylen, base + cid * 0x10 + SIRFSOC_DMA_CH_YLEN); - writel_relaxed(readl_relaxed(base + SIRFSOC_DMA_INT_EN) | - (1 << cid), base + SIRFSOC_DMA_INT_EN); - writel(sdesc->addr >> 2, base + cid * 0x10 + SIRFSOC_DMA_CH_ADDR); - if (sdesc->cyclic) { - writel((1 << cid) | 1 << (cid + 16) | - readl_relaxed(base + SIRFSOC_DMA_CH_LOOP_CTRL_ATLAS7), - base + SIRFSOC_DMA_CH_LOOP_CTRL_ATLAS7); - } - -} - -static void sirfsoc_dma_execute_hw_a6(struct sirfsoc_dma_desc *sdesc, - int cid, int burst_mode, void __iomem *base) -{ - writel_relaxed(sdesc->width, base + SIRFSOC_DMA_WIDTH_0 + cid * 4); - writel_relaxed(cid | (burst_mode << SIRFSOC_DMA_MODE_CTRL_BIT) | - (sdesc->dir << SIRFSOC_DMA_DIR_CTRL_BIT), - base + cid * 0x10 + SIRFSOC_DMA_CH_CTRL); - writel_relaxed(sdesc->xlen, base + cid * 0x10 + SIRFSOC_DMA_CH_XLEN); - writel_relaxed(sdesc->ylen, base + cid * 0x10 + SIRFSOC_DMA_CH_YLEN); - writel_relaxed(readl_relaxed(base + SIRFSOC_DMA_INT_EN) | - (1 << cid), base + SIRFSOC_DMA_INT_EN); - writel(sdesc->addr >> 2, base + cid * 0x10 + SIRFSOC_DMA_CH_ADDR); - if (sdesc->cyclic) { - writel((1 << cid) | 1 << (cid + 16) | - readl_relaxed(base + SIRFSOC_DMA_CH_LOOP_CTRL), - base + SIRFSOC_DMA_CH_LOOP_CTRL); - } - -} - -/* Execute all queued DMA descriptors */ -static void sirfsoc_dma_execute(struct sirfsoc_dma_chan *schan) -{ - struct sirfsoc_dma *sdma = dma_chan_to_sirfsoc_dma(&schan->chan); - int cid = schan->chan.chan_id; - struct sirfsoc_dma_desc *sdesc = NULL; - void __iomem *base; - - /* - * lock has been held by functions calling this, so we don't hold - * lock again - */ - base = sdma->base; - sdesc = list_first_entry(&schan->queued, struct sirfsoc_dma_desc, - node); - /* Move the first queued descriptor to active list */ - list_move_tail(&sdesc->node, &schan->active); - - if (sdma->type == SIRFSOC_DMA_VER_A7V2) - cid = 0; - - /* Start the DMA transfer */ - sdma->exec_desc(sdesc, cid, schan->mode, base); - - if (sdesc->cyclic) - schan->happened_cyclic = schan->completed_cyclic = 0; -} - -/* Interrupt handler */ -static irqreturn_t sirfsoc_dma_irq(int irq, void *data) -{ - struct sirfsoc_dma *sdma = data; - struct sirfsoc_dma_chan *schan; - struct sirfsoc_dma_desc *sdesc = NULL; - u32 is; - bool chain; - int ch; - void __iomem *reg; - - switch (sdma->type) { - case SIRFSOC_DMA_VER_A6: - case SIRFSOC_DMA_VER_A7V1: - is = readl(sdma->base + SIRFSOC_DMA_CH_INT); - reg = sdma->base + SIRFSOC_DMA_CH_INT; - while ((ch = fls(is) - 1) >= 0) { - is &= ~(1 << ch); - writel_relaxed(1 << ch, reg); - schan = &sdma->channels[ch]; - spin_lock(&schan->lock); - sdesc = list_first_entry(&schan->active, - struct sirfsoc_dma_desc, node); - if (!sdesc->cyclic) { - /* Execute queued descriptors */ - list_splice_tail_init(&schan->active, - &schan->completed); - dma_cookie_complete(&sdesc->desc); - if (!list_empty(&schan->queued)) - sirfsoc_dma_execute(schan); - } else - schan->happened_cyclic++; - spin_unlock(&schan->lock); - } - break; - - case SIRFSOC_DMA_VER_A7V2: - is = readl(sdma->base + SIRFSOC_DMA_INT_ATLAS7); - - reg = sdma->base + SIRFSOC_DMA_INT_ATLAS7; - writel_relaxed(SIRFSOC_DMA_INT_ALL_ATLAS7, reg); - schan = &sdma->channels[0]; - spin_lock(&schan->lock); - sdesc = list_first_entry(&schan->active, - struct sirfsoc_dma_desc, node); - if (!sdesc->cyclic) { - chain = sdesc->chain; - if ((chain && (is & SIRFSOC_DMA_INT_END_INT_ATLAS7)) || - (!chain && - (is & SIRFSOC_DMA_INT_FINI_INT_ATLAS7))) { - /* Execute queued descriptors */ - list_splice_tail_init(&schan->active, - &schan->completed); - dma_cookie_complete(&sdesc->desc); - if (!list_empty(&schan->queued)) - sirfsoc_dma_execute(schan); - } - } else if (sdesc->cyclic && (is & - SIRFSOC_DMA_INT_LOOP_INT_ATLAS7)) - schan->happened_cyclic++; - - spin_unlock(&schan->lock); - break; - - default: - break; - } - - /* Schedule tasklet */ - tasklet_schedule(&sdma->tasklet); - - return IRQ_HANDLED; -} - -/* process completed descriptors */ -static void sirfsoc_dma_process_completed(struct sirfsoc_dma *sdma) -{ - dma_cookie_t last_cookie = 0; - struct sirfsoc_dma_chan *schan; - struct sirfsoc_dma_desc *sdesc; - struct dma_async_tx_descriptor *desc; - unsigned long flags; - unsigned long happened_cyclic; - LIST_HEAD(list); - int i; - - for (i = 0; i < sdma->dma.chancnt; i++) { - schan = &sdma->channels[i]; - - /* Get all completed descriptors */ - spin_lock_irqsave(&schan->lock, flags); - if (!list_empty(&schan->completed)) { - list_splice_tail_init(&schan->completed, &list); - spin_unlock_irqrestore(&schan->lock, flags); - - /* Execute callbacks and run dependencies */ - list_for_each_entry(sdesc, &list, node) { - desc = &sdesc->desc; - - dmaengine_desc_get_callback_invoke(desc, NULL); - last_cookie = desc->cookie; - dma_run_dependencies(desc); - } - - /* Free descriptors */ - spin_lock_irqsave(&schan->lock, flags); - list_splice_tail_init(&list, &schan->free); - schan->chan.completed_cookie = last_cookie; - spin_unlock_irqrestore(&schan->lock, flags); - } else { - if (list_empty(&schan->active)) { - spin_unlock_irqrestore(&schan->lock, flags); - continue; - } - - /* for cyclic channel, desc is always in active list */ - sdesc = list_first_entry(&schan->active, - struct sirfsoc_dma_desc, node); - - /* cyclic DMA */ - happened_cyclic = schan->happened_cyclic; - spin_unlock_irqrestore(&schan->lock, flags); - - desc = &sdesc->desc; - while (happened_cyclic != schan->completed_cyclic) { - dmaengine_desc_get_callback_invoke(desc, NULL); - schan->completed_cyclic++; - } - } - } -} - -/* DMA Tasklet */ -static void sirfsoc_dma_tasklet(struct tasklet_struct *t) -{ - struct sirfsoc_dma *sdma = from_tasklet(sdma, t, tasklet); - - sirfsoc_dma_process_completed(sdma); -} - -/* Submit descriptor to hardware */ -static dma_cookie_t sirfsoc_dma_tx_submit(struct dma_async_tx_descriptor *txd) -{ - struct sirfsoc_dma_chan *schan = dma_chan_to_sirfsoc_dma_chan(txd->chan); - struct sirfsoc_dma_desc *sdesc; - unsigned long flags; - dma_cookie_t cookie; - - sdesc = container_of(txd, struct sirfsoc_dma_desc, desc); - - spin_lock_irqsave(&schan->lock, flags); - - /* Move descriptor to queue */ - list_move_tail(&sdesc->node, &schan->queued); - - cookie = dma_cookie_assign(txd); - - spin_unlock_irqrestore(&schan->lock, flags); - - return cookie; -} - -static int sirfsoc_dma_slave_config(struct dma_chan *chan, - struct dma_slave_config *config) -{ - struct sirfsoc_dma_chan *schan = dma_chan_to_sirfsoc_dma_chan(chan); - unsigned long flags; - - if ((config->src_addr_width != DMA_SLAVE_BUSWIDTH_4_BYTES) || - (config->dst_addr_width != DMA_SLAVE_BUSWIDTH_4_BYTES)) - return -EINVAL; - - spin_lock_irqsave(&schan->lock, flags); - schan->mode = (config->src_maxburst == 4 ? 1 : 0); - spin_unlock_irqrestore(&schan->lock, flags); - - return 0; -} - -static int sirfsoc_dma_terminate_all(struct dma_chan *chan) -{ - struct sirfsoc_dma_chan *schan = dma_chan_to_sirfsoc_dma_chan(chan); - struct sirfsoc_dma *sdma = dma_chan_to_sirfsoc_dma(&schan->chan); - int cid = schan->chan.chan_id; - unsigned long flags; - - spin_lock_irqsave(&schan->lock, flags); - - switch (sdma->type) { - case SIRFSOC_DMA_VER_A7V1: - writel_relaxed(1 << cid, sdma->base + SIRFSOC_DMA_INT_EN_CLR); - writel_relaxed(1 << cid, sdma->base + SIRFSOC_DMA_CH_INT); - writel_relaxed((1 << cid) | 1 << (cid + 16), - sdma->base + - SIRFSOC_DMA_CH_LOOP_CTRL_CLR_ATLAS7); - writel_relaxed(1 << cid, sdma->base + SIRFSOC_DMA_CH_VALID); - break; - case SIRFSOC_DMA_VER_A7V2: - writel_relaxed(0, sdma->base + SIRFSOC_DMA_INT_EN_ATLAS7); - writel_relaxed(SIRFSOC_DMA_INT_ALL_ATLAS7, - sdma->base + SIRFSOC_DMA_INT_ATLAS7); - writel_relaxed(0, sdma->base + SIRFSOC_DMA_LOOP_CTRL_ATLAS7); - writel_relaxed(0, sdma->base + SIRFSOC_DMA_VALID_ATLAS7); - break; - case SIRFSOC_DMA_VER_A6: - writel_relaxed(readl_relaxed(sdma->base + SIRFSOC_DMA_INT_EN) & - ~(1 << cid), sdma->base + SIRFSOC_DMA_INT_EN); - writel_relaxed(readl_relaxed(sdma->base + - SIRFSOC_DMA_CH_LOOP_CTRL) & - ~((1 << cid) | 1 << (cid + 16)), - sdma->base + SIRFSOC_DMA_CH_LOOP_CTRL); - writel_relaxed(1 << cid, sdma->base + SIRFSOC_DMA_CH_VALID); - break; - default: - break; - } - - list_splice_tail_init(&schan->active, &schan->free); - list_splice_tail_init(&schan->queued, &schan->free); - - spin_unlock_irqrestore(&schan->lock, flags); - - return 0; -} - -static int sirfsoc_dma_pause_chan(struct dma_chan *chan) -{ - struct sirfsoc_dma_chan *schan = dma_chan_to_sirfsoc_dma_chan(chan); - struct sirfsoc_dma *sdma = dma_chan_to_sirfsoc_dma(&schan->chan); - int cid = schan->chan.chan_id; - unsigned long flags; - - spin_lock_irqsave(&schan->lock, flags); - - switch (sdma->type) { - case SIRFSOC_DMA_VER_A7V1: - writel_relaxed((1 << cid) | 1 << (cid + 16), - sdma->base + - SIRFSOC_DMA_CH_LOOP_CTRL_CLR_ATLAS7); - break; - case SIRFSOC_DMA_VER_A7V2: - writel_relaxed(0, sdma->base + SIRFSOC_DMA_LOOP_CTRL_ATLAS7); - break; - case SIRFSOC_DMA_VER_A6: - writel_relaxed(readl_relaxed(sdma->base + - SIRFSOC_DMA_CH_LOOP_CTRL) & - ~((1 << cid) | 1 << (cid + 16)), - sdma->base + SIRFSOC_DMA_CH_LOOP_CTRL); - break; - - default: - break; - } - - spin_unlock_irqrestore(&schan->lock, flags); - - return 0; -} - -static int sirfsoc_dma_resume_chan(struct dma_chan *chan) -{ - struct sirfsoc_dma_chan *schan = dma_chan_to_sirfsoc_dma_chan(chan); - struct sirfsoc_dma *sdma = dma_chan_to_sirfsoc_dma(&schan->chan); - int cid = schan->chan.chan_id; - unsigned long flags; - - spin_lock_irqsave(&schan->lock, flags); - switch (sdma->type) { - case SIRFSOC_DMA_VER_A7V1: - writel_relaxed((1 << cid) | 1 << (cid + 16), - sdma->base + SIRFSOC_DMA_CH_LOOP_CTRL_ATLAS7); - break; - case SIRFSOC_DMA_VER_A7V2: - writel_relaxed(0x10001, - sdma->base + SIRFSOC_DMA_LOOP_CTRL_ATLAS7); - break; - case SIRFSOC_DMA_VER_A6: - writel_relaxed(readl_relaxed(sdma->base + - SIRFSOC_DMA_CH_LOOP_CTRL) | - ((1 << cid) | 1 << (cid + 16)), - sdma->base + SIRFSOC_DMA_CH_LOOP_CTRL); - break; - - default: - break; - } - - spin_unlock_irqrestore(&schan->lock, flags); - - return 0; -} - -/* Alloc channel resources */ -static int sirfsoc_dma_alloc_chan_resources(struct dma_chan *chan) -{ - struct sirfsoc_dma *sdma = dma_chan_to_sirfsoc_dma(chan); - struct sirfsoc_dma_chan *schan = dma_chan_to_sirfsoc_dma_chan(chan); - struct sirfsoc_dma_desc *sdesc; - unsigned long flags; - LIST_HEAD(descs); - int i; - - pm_runtime_get_sync(sdma->dma.dev); - - /* Alloc descriptors for this channel */ - for (i = 0; i < SIRFSOC_DMA_DESCRIPTORS; i++) { - sdesc = kzalloc(sizeof(*sdesc), GFP_KERNEL); - if (!sdesc) { - dev_notice(sdma->dma.dev, "Memory allocation error. " - "Allocated only %u descriptors\n", i); - break; - } - - dma_async_tx_descriptor_init(&sdesc->desc, chan); - sdesc->desc.flags = DMA_CTRL_ACK; - sdesc->desc.tx_submit = sirfsoc_dma_tx_submit; - - list_add_tail(&sdesc->node, &descs); - } - - /* Return error only if no descriptors were allocated */ - if (i == 0) - return -ENOMEM; - - spin_lock_irqsave(&schan->lock, flags); - - list_splice_tail_init(&descs, &schan->free); - spin_unlock_irqrestore(&schan->lock, flags); - - return i; -} - -/* Free channel resources */ -static void sirfsoc_dma_free_chan_resources(struct dma_chan *chan) -{ - struct sirfsoc_dma_chan *schan = dma_chan_to_sirfsoc_dma_chan(chan); - struct sirfsoc_dma *sdma = dma_chan_to_sirfsoc_dma(chan); - struct sirfsoc_dma_desc *sdesc, *tmp; - unsigned long flags; - LIST_HEAD(descs); - - spin_lock_irqsave(&schan->lock, flags); - - /* Channel must be idle */ - BUG_ON(!list_empty(&schan->prepared)); - BUG_ON(!list_empty(&schan->queued)); - BUG_ON(!list_empty(&schan->active)); - BUG_ON(!list_empty(&schan->completed)); - - /* Move data */ - list_splice_tail_init(&schan->free, &descs); - - spin_unlock_irqrestore(&schan->lock, flags); - - /* Free descriptors */ - list_for_each_entry_safe(sdesc, tmp, &descs, node) - kfree(sdesc); - - pm_runtime_put(sdma->dma.dev); -} - -/* Send pending descriptor to hardware */ -static void sirfsoc_dma_issue_pending(struct dma_chan *chan) -{ - struct sirfsoc_dma_chan *schan = dma_chan_to_sirfsoc_dma_chan(chan); - unsigned long flags; - - spin_lock_irqsave(&schan->lock, flags); - - if (list_empty(&schan->active) && !list_empty(&schan->queued)) - sirfsoc_dma_execute(schan); - - spin_unlock_irqrestore(&schan->lock, flags); -} - -/* Check request completion status */ -static enum dma_status -sirfsoc_dma_tx_status(struct dma_chan *chan, dma_cookie_t cookie, - struct dma_tx_state *txstate) -{ - struct sirfsoc_dma *sdma = dma_chan_to_sirfsoc_dma(chan); - struct sirfsoc_dma_chan *schan = dma_chan_to_sirfsoc_dma_chan(chan); - unsigned long flags; - enum dma_status ret; - struct sirfsoc_dma_desc *sdesc; - int cid = schan->chan.chan_id; - unsigned long dma_pos; - unsigned long dma_request_bytes; - unsigned long residue; - - spin_lock_irqsave(&schan->lock, flags); - - if (list_empty(&schan->active)) { - ret = dma_cookie_status(chan, cookie, txstate); - dma_set_residue(txstate, 0); - spin_unlock_irqrestore(&schan->lock, flags); - return ret; - } - sdesc = list_first_entry(&schan->active, struct sirfsoc_dma_desc, node); - if (sdesc->cyclic) - dma_request_bytes = (sdesc->xlen + 1) * (sdesc->ylen + 1) * - (sdesc->width * SIRFSOC_DMA_WORD_LEN); - else - dma_request_bytes = sdesc->xlen * SIRFSOC_DMA_WORD_LEN; - - ret = dma_cookie_status(chan, cookie, txstate); - - if (sdma->type == SIRFSOC_DMA_VER_A7V2) - cid = 0; - - if (sdma->type == SIRFSOC_DMA_VER_A7V2) { - dma_pos = readl_relaxed(sdma->base + SIRFSOC_DMA_CUR_DATA_ADDR); - } else { - dma_pos = readl_relaxed( - sdma->base + cid * 0x10 + SIRFSOC_DMA_CH_ADDR) << 2; - } - - residue = dma_request_bytes - (dma_pos - sdesc->addr); - dma_set_residue(txstate, residue); - - spin_unlock_irqrestore(&schan->lock, flags); - - return ret; -} - -static struct dma_async_tx_descriptor *sirfsoc_dma_prep_interleaved( - struct dma_chan *chan, struct dma_interleaved_template *xt, - unsigned long flags) -{ - struct sirfsoc_dma *sdma = dma_chan_to_sirfsoc_dma(chan); - struct sirfsoc_dma_chan *schan = dma_chan_to_sirfsoc_dma_chan(chan); - struct sirfsoc_dma_desc *sdesc = NULL; - unsigned long iflags; - int ret; - - if ((xt->dir != DMA_MEM_TO_DEV) && (xt->dir != DMA_DEV_TO_MEM)) { - ret = -EINVAL; - goto err_dir; - } - - /* Get free descriptor */ - spin_lock_irqsave(&schan->lock, iflags); - if (!list_empty(&schan->free)) { - sdesc = list_first_entry(&schan->free, struct sirfsoc_dma_desc, - node); - list_del(&sdesc->node); - } - spin_unlock_irqrestore(&schan->lock, iflags); - - if (!sdesc) { - /* try to free completed descriptors */ - sirfsoc_dma_process_completed(sdma); - ret = 0; - goto no_desc; - } - - /* Place descriptor in prepared list */ - spin_lock_irqsave(&schan->lock, iflags); - - /* - * Number of chunks in a frame can only be 1 for prima2 - * and ylen (number of frame - 1) must be at least 0 - */ - if ((xt->frame_size == 1) && (xt->numf > 0)) { - sdesc->cyclic = 0; - sdesc->xlen = xt->sgl[0].size / SIRFSOC_DMA_WORD_LEN; - sdesc->width = (xt->sgl[0].size + xt->sgl[0].icg) / - SIRFSOC_DMA_WORD_LEN; - sdesc->ylen = xt->numf - 1; - if (xt->dir == DMA_MEM_TO_DEV) { - sdesc->addr = xt->src_start; - sdesc->dir = 1; - } else { - sdesc->addr = xt->dst_start; - sdesc->dir = 0; - } - - list_add_tail(&sdesc->node, &schan->prepared); - } else { - pr_err("sirfsoc DMA Invalid xfer\n"); - ret = -EINVAL; - goto err_xfer; - } - spin_unlock_irqrestore(&schan->lock, iflags); - - return &sdesc->desc; -err_xfer: - spin_unlock_irqrestore(&schan->lock, iflags); -no_desc: -err_dir: - return ERR_PTR(ret); -} - -static struct dma_async_tx_descriptor * -sirfsoc_dma_prep_cyclic(struct dma_chan *chan, dma_addr_t addr, - size_t buf_len, size_t period_len, - enum dma_transfer_direction direction, unsigned long flags) -{ - struct sirfsoc_dma_chan *schan = dma_chan_to_sirfsoc_dma_chan(chan); - struct sirfsoc_dma_desc *sdesc = NULL; - unsigned long iflags; - - /* - * we only support cycle transfer with 2 period - * If the X-length is set to 0, it would be the loop mode. - * The DMA address keeps increasing until reaching the end of a loop - * area whose size is defined by (DMA_WIDTH x (Y_LENGTH + 1)). Then - * the DMA address goes back to the beginning of this area. - * In loop mode, the DMA data region is divided into two parts, BUFA - * and BUFB. DMA controller generates interrupts twice in each loop: - * when the DMA address reaches the end of BUFA or the end of the - * BUFB - */ - if (buf_len != 2 * period_len) - return ERR_PTR(-EINVAL); - - /* Get free descriptor */ - spin_lock_irqsave(&schan->lock, iflags); - if (!list_empty(&schan->free)) { - sdesc = list_first_entry(&schan->free, struct sirfsoc_dma_desc, - node); - list_del(&sdesc->node); - } - spin_unlock_irqrestore(&schan->lock, iflags); - - if (!sdesc) - return NULL; - - /* Place descriptor in prepared list */ - spin_lock_irqsave(&schan->lock, iflags); - sdesc->addr = addr; - sdesc->cyclic = 1; - sdesc->xlen = 0; - sdesc->ylen = buf_len / SIRFSOC_DMA_WORD_LEN - 1; - sdesc->width = 1; - list_add_tail(&sdesc->node, &schan->prepared); - spin_unlock_irqrestore(&schan->lock, iflags); - - return &sdesc->desc; -} - -/* - * The DMA controller consists of 16 independent DMA channels. - * Each channel is allocated to a different function - */ -bool sirfsoc_dma_filter_id(struct dma_chan *chan, void *chan_id) -{ - unsigned int ch_nr = (unsigned int) chan_id; - - if (ch_nr == chan->chan_id + - chan->device->dev_id * SIRFSOC_DMA_CHANNELS) - return true; - - return false; -} -EXPORT_SYMBOL(sirfsoc_dma_filter_id); - -#define SIRFSOC_DMA_BUSWIDTHS \ - (BIT(DMA_SLAVE_BUSWIDTH_UNDEFINED) | \ - BIT(DMA_SLAVE_BUSWIDTH_1_BYTE) | \ - BIT(DMA_SLAVE_BUSWIDTH_2_BYTES) | \ - BIT(DMA_SLAVE_BUSWIDTH_4_BYTES) | \ - BIT(DMA_SLAVE_BUSWIDTH_8_BYTES)) - -static struct dma_chan *of_dma_sirfsoc_xlate(struct of_phandle_args *dma_spec, - struct of_dma *ofdma) -{ - struct sirfsoc_dma *sdma = ofdma->of_dma_data; - unsigned int request = dma_spec->args[0]; - - if (request >= SIRFSOC_DMA_CHANNELS) - return NULL; - - return dma_get_slave_channel(&sdma->channels[request].chan); -} - -static int sirfsoc_dma_probe(struct platform_device *op) -{ - struct device_node *dn = op->dev.of_node; - struct device *dev = &op->dev; - struct dma_device *dma; - struct sirfsoc_dma *sdma; - struct sirfsoc_dma_chan *schan; - struct sirfsoc_dmadata *data; - struct resource res; - ulong regs_start, regs_size; - u32 id; - int ret, i; - - sdma = devm_kzalloc(dev, sizeof(*sdma), GFP_KERNEL); - if (!sdma) - return -ENOMEM; - - data = (struct sirfsoc_dmadata *) - (of_match_device(op->dev.driver->of_match_table, - &op->dev)->data); - sdma->exec_desc = data->exec; - sdma->type = data->type; - - if (of_property_read_u32(dn, "cell-index", &id)) { - dev_err(dev, "Fail to get DMAC index\n"); - return -ENODEV; - } - - sdma->irq = irq_of_parse_and_map(dn, 0); - if (!sdma->irq) { - dev_err(dev, "Error mapping IRQ!\n"); - return -EINVAL; - } - - sdma->clk = devm_clk_get(dev, NULL); - if (IS_ERR(sdma->clk)) { - dev_err(dev, "failed to get a clock.\n"); - return PTR_ERR(sdma->clk); - } - - ret = of_address_to_resource(dn, 0, &res); - if (ret) { - dev_err(dev, "Error parsing memory region!\n"); - goto irq_dispose; - } - - regs_start = res.start; - regs_size = resource_size(&res); - - sdma->base = devm_ioremap(dev, regs_start, regs_size); - if (!sdma->base) { - dev_err(dev, "Error mapping memory region!\n"); - ret = -ENOMEM; - goto irq_dispose; - } - - ret = request_irq(sdma->irq, &sirfsoc_dma_irq, 0, DRV_NAME, sdma); - if (ret) { - dev_err(dev, "Error requesting IRQ!\n"); - ret = -EINVAL; - goto irq_dispose; - } - - dma = &sdma->dma; - dma->dev = dev; - - dma->device_alloc_chan_resources = sirfsoc_dma_alloc_chan_resources; - dma->device_free_chan_resources = sirfsoc_dma_free_chan_resources; - dma->device_issue_pending = sirfsoc_dma_issue_pending; - dma->device_config = sirfsoc_dma_slave_config; - dma->device_pause = sirfsoc_dma_pause_chan; - dma->device_resume = sirfsoc_dma_resume_chan; - dma->device_terminate_all = sirfsoc_dma_terminate_all; - dma->device_tx_status = sirfsoc_dma_tx_status; - dma->device_prep_interleaved_dma = sirfsoc_dma_prep_interleaved; - dma->device_prep_dma_cyclic = sirfsoc_dma_prep_cyclic; - dma->src_addr_widths = SIRFSOC_DMA_BUSWIDTHS; - dma->dst_addr_widths = SIRFSOC_DMA_BUSWIDTHS; - dma->directions = BIT(DMA_DEV_TO_MEM) | BIT(DMA_MEM_TO_DEV); - - INIT_LIST_HEAD(&dma->channels); - dma_cap_set(DMA_SLAVE, dma->cap_mask); - dma_cap_set(DMA_CYCLIC, dma->cap_mask); - dma_cap_set(DMA_INTERLEAVE, dma->cap_mask); - dma_cap_set(DMA_PRIVATE, dma->cap_mask); - - for (i = 0; i < SIRFSOC_DMA_CHANNELS; i++) { - schan = &sdma->channels[i]; - - schan->chan.device = dma; - dma_cookie_init(&schan->chan); - - INIT_LIST_HEAD(&schan->free); - INIT_LIST_HEAD(&schan->prepared); - INIT_LIST_HEAD(&schan->queued); - INIT_LIST_HEAD(&schan->active); - INIT_LIST_HEAD(&schan->completed); - - spin_lock_init(&schan->lock); - list_add_tail(&schan->chan.device_node, &dma->channels); - } - - tasklet_setup(&sdma->tasklet, sirfsoc_dma_tasklet); - - /* Register DMA engine */ - dev_set_drvdata(dev, sdma); - - ret = dma_async_device_register(dma); - if (ret) - goto free_irq; - - /* Device-tree DMA controller registration */ - ret = of_dma_controller_register(dn, of_dma_sirfsoc_xlate, sdma); - if (ret) { - dev_err(dev, "failed to register DMA controller\n"); - goto unreg_dma_dev; - } - - pm_runtime_enable(&op->dev); - dev_info(dev, "initialized SIRFSOC DMAC driver\n"); - - return 0; - -unreg_dma_dev: - dma_async_device_unregister(dma); -free_irq: - free_irq(sdma->irq, sdma); -irq_dispose: - irq_dispose_mapping(sdma->irq); - return ret; -} - -static int sirfsoc_dma_remove(struct platform_device *op) -{ - struct device *dev = &op->dev; - struct sirfsoc_dma *sdma = dev_get_drvdata(dev); - - of_dma_controller_free(op->dev.of_node); - dma_async_device_unregister(&sdma->dma); - free_irq(sdma->irq, sdma); - tasklet_kill(&sdma->tasklet); - irq_dispose_mapping(sdma->irq); - pm_runtime_disable(&op->dev); - if (!pm_runtime_status_suspended(&op->dev)) - sirfsoc_dma_runtime_suspend(&op->dev); - - return 0; -} - -static int __maybe_unused sirfsoc_dma_runtime_suspend(struct device *dev) -{ - struct sirfsoc_dma *sdma = dev_get_drvdata(dev); - - clk_disable_unprepare(sdma->clk); - return 0; -} - -static int __maybe_unused sirfsoc_dma_runtime_resume(struct device *dev) -{ - struct sirfsoc_dma *sdma = dev_get_drvdata(dev); - int ret; - - ret = clk_prepare_enable(sdma->clk); - if (ret < 0) { - dev_err(dev, "clk_enable failed: %d\n", ret); - return ret; - } - return 0; -} - -static int __maybe_unused sirfsoc_dma_pm_suspend(struct device *dev) -{ - struct sirfsoc_dma *sdma = dev_get_drvdata(dev); - struct sirfsoc_dma_regs *save = &sdma->regs_save; - struct sirfsoc_dma_chan *schan; - int ch; - int ret; - int count; - u32 int_offset; - - /* - * if we were runtime-suspended before, resume to enable clock - * before accessing register - */ - if (pm_runtime_status_suspended(dev)) { - ret = sirfsoc_dma_runtime_resume(dev); - if (ret < 0) - return ret; - } - - if (sdma->type == SIRFSOC_DMA_VER_A7V2) { - count = 1; - int_offset = SIRFSOC_DMA_INT_EN_ATLAS7; - } else { - count = SIRFSOC_DMA_CHANNELS; - int_offset = SIRFSOC_DMA_INT_EN; - } - - /* - * DMA controller will lose all registers while suspending - * so we need to save registers for active channels - */ - for (ch = 0; ch < count; ch++) { - schan = &sdma->channels[ch]; - if (list_empty(&schan->active)) - continue; - save->ctrl[ch] = readl_relaxed(sdma->base + - ch * 0x10 + SIRFSOC_DMA_CH_CTRL); - } - save->interrupt_en = readl_relaxed(sdma->base + int_offset); - - /* Disable clock */ - sirfsoc_dma_runtime_suspend(dev); - - return 0; -} - -static int __maybe_unused sirfsoc_dma_pm_resume(struct device *dev) -{ - struct sirfsoc_dma *sdma = dev_get_drvdata(dev); - struct sirfsoc_dma_regs *save = &sdma->regs_save; - struct sirfsoc_dma_desc *sdesc; - struct sirfsoc_dma_chan *schan; - int ch; - int ret; - int count; - u32 int_offset; - u32 width_offset; - - /* Enable clock before accessing register */ - ret = sirfsoc_dma_runtime_resume(dev); - if (ret < 0) - return ret; - - if (sdma->type == SIRFSOC_DMA_VER_A7V2) { - count = 1; - int_offset = SIRFSOC_DMA_INT_EN_ATLAS7; - width_offset = SIRFSOC_DMA_WIDTH_ATLAS7; - } else { - count = SIRFSOC_DMA_CHANNELS; - int_offset = SIRFSOC_DMA_INT_EN; - width_offset = SIRFSOC_DMA_WIDTH_0; - } - - writel_relaxed(save->interrupt_en, sdma->base + int_offset); - for (ch = 0; ch < count; ch++) { - schan = &sdma->channels[ch]; - if (list_empty(&schan->active)) - continue; - sdesc = list_first_entry(&schan->active, - struct sirfsoc_dma_desc, - node); - writel_relaxed(sdesc->width, - sdma->base + width_offset + ch * 4); - writel_relaxed(sdesc->xlen, - sdma->base + ch * 0x10 + SIRFSOC_DMA_CH_XLEN); - writel_relaxed(sdesc->ylen, - sdma->base + ch * 0x10 + SIRFSOC_DMA_CH_YLEN); - writel_relaxed(save->ctrl[ch], - sdma->base + ch * 0x10 + SIRFSOC_DMA_CH_CTRL); - if (sdma->type == SIRFSOC_DMA_VER_A7V2) { - writel_relaxed(sdesc->addr, - sdma->base + SIRFSOC_DMA_CH_ADDR); - } else { - writel_relaxed(sdesc->addr >> 2, - sdma->base + ch * 0x10 + SIRFSOC_DMA_CH_ADDR); - - } - } - - /* if we were runtime-suspended before, suspend again */ - if (pm_runtime_status_suspended(dev)) - sirfsoc_dma_runtime_suspend(dev); - - return 0; -} - -static const struct dev_pm_ops sirfsoc_dma_pm_ops = { - SET_RUNTIME_PM_OPS(sirfsoc_dma_runtime_suspend, sirfsoc_dma_runtime_resume, NULL) - SET_SYSTEM_SLEEP_PM_OPS(sirfsoc_dma_pm_suspend, sirfsoc_dma_pm_resume) -}; - -static struct sirfsoc_dmadata sirfsoc_dmadata_a6 = { - .exec = sirfsoc_dma_execute_hw_a6, - .type = SIRFSOC_DMA_VER_A6, -}; - -static struct sirfsoc_dmadata sirfsoc_dmadata_a7v1 = { - .exec = sirfsoc_dma_execute_hw_a7v1, - .type = SIRFSOC_DMA_VER_A7V1, -}; - -static struct sirfsoc_dmadata sirfsoc_dmadata_a7v2 = { - .exec = sirfsoc_dma_execute_hw_a7v2, - .type = SIRFSOC_DMA_VER_A7V2, -}; - -static const struct of_device_id sirfsoc_dma_match[] = { - { .compatible = "sirf,prima2-dmac", .data = &sirfsoc_dmadata_a6,}, - { .compatible = "sirf,atlas7-dmac", .data = &sirfsoc_dmadata_a7v1,}, - { .compatible = "sirf,atlas7-dmac-v2", .data = &sirfsoc_dmadata_a7v2,}, - {}, -}; -MODULE_DEVICE_TABLE(of, sirfsoc_dma_match); - -static struct platform_driver sirfsoc_dma_driver = { - .probe = sirfsoc_dma_probe, - .remove = sirfsoc_dma_remove, - .driver = { - .name = DRV_NAME, - .pm = &sirfsoc_dma_pm_ops, - .of_match_table = sirfsoc_dma_match, - }, -}; - -static __init int sirfsoc_dma_init(void) -{ - return platform_driver_register(&sirfsoc_dma_driver); -} - -static void __exit sirfsoc_dma_exit(void) -{ - platform_driver_unregister(&sirfsoc_dma_driver); -} - -subsys_initcall(sirfsoc_dma_init); -module_exit(sirfsoc_dma_exit); - -MODULE_AUTHOR("Rongjun Ying "); -MODULE_AUTHOR("Barry Song "); -MODULE_DESCRIPTION("SIRFSOC DMA control driver"); -MODULE_LICENSE("GPL v2"); diff --git a/include/linux/sirfsoc_dma.h b/include/linux/sirfsoc_dma.h deleted file mode 100644 index 50161b6afb61..000000000000 --- a/include/linux/sirfsoc_dma.h +++ /dev/null @@ -1,7 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -#ifndef _SIRFSOC_DMA_H_ -#define _SIRFSOC_DMA_H_ - -bool sirfsoc_dma_filter_id(struct dma_chan *chan, void *chan_id); - -#endif -- cgit v1.2.3 From 1c8963f830136c26f01af5d2523470a2b958ce80 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Wed, 20 Jan 2021 14:18:58 +0100 Subject: dmaengine: remove zte zx driver The zte zx platform is getting removed, so this driver is no longer needed. Signed-off-by: Arnd Bergmann Cc: Jun Nie Cc: Shawn Guo Link: https://lore.kernel.org/r/20210120131859.2056308-3-arnd@kernel.org Signed-off-by: Vinod Koul --- Documentation/devicetree/bindings/dma/zxdma.txt | 38 - drivers/dma/Kconfig | 9 - drivers/dma/Makefile | 1 - drivers/dma/zx_dma.c | 941 ------------------------ 4 files changed, 989 deletions(-) delete mode 100644 Documentation/devicetree/bindings/dma/zxdma.txt delete mode 100644 drivers/dma/zx_dma.c (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/dma/zxdma.txt b/Documentation/devicetree/bindings/dma/zxdma.txt deleted file mode 100644 index 0ab80f69e566..000000000000 --- a/Documentation/devicetree/bindings/dma/zxdma.txt +++ /dev/null @@ -1,38 +0,0 @@ -* ZTE ZX296702 DMA controller - -Required properties: -- compatible: Should be "zte,zx296702-dma" -- reg: Should contain DMA registers location and length. -- interrupts: Should contain one interrupt shared by all channel -- #dma-cells: see dma.txt, should be 1, para number -- dma-channels: physical channels supported -- dma-requests: virtual channels supported, each virtual channel - have specific request line -- clocks: clock required - -Example: - -Controller: - dma: dma-controller@09c00000{ - compatible = "zte,zx296702-dma"; - reg = <0x09c00000 0x1000>; - clocks = <&topclk ZX296702_DMA_ACLK>; - interrupts = ; - #dma-cells = <1>; - dma-channels = <24>; - dma-requests = <24>; - }; - -Client: -Use specific request line passing from dmax -For example, spdif0 tx channel request line is 4 - spdif0: spdif0@b004000 { - #sound-dai-cells = <0>; - compatible = "zte,zx296702-spdif"; - reg = <0x0b004000 0x1000>; - clocks = <&lsp0clk ZX296702_SPDIF0_DIV>; - clock-names = "tx"; - interrupts = ; - dmas = <&dma 4>; - dma-names = "tx"; - } diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig index 2201ff280f7a..4fd6a90cfadf 100644 --- a/drivers/dma/Kconfig +++ b/drivers/dma/Kconfig @@ -703,15 +703,6 @@ config XILINX_ZYNQMP_DPDMA driver provides the dmaengine required by the DisplayPort subsystem display driver. -config ZX_DMA - tristate "ZTE ZX DMA support" - depends on ARCH_ZX || COMPILE_TEST - select DMA_ENGINE - select DMA_VIRTUAL_CHANNELS - help - Support the DMA engine for ZTE ZX family platform devices. - - # driver files source "drivers/dma/bestcomm/Kconfig" diff --git a/drivers/dma/Makefile b/drivers/dma/Makefile index b5b34c65b075..4aed5ea59922 100644 --- a/drivers/dma/Makefile +++ b/drivers/dma/Makefile @@ -78,7 +78,6 @@ obj-$(CONFIG_TIMB_DMA) += timb_dma.o obj-$(CONFIG_UNIPHIER_MDMAC) += uniphier-mdmac.o obj-$(CONFIG_UNIPHIER_XDMAC) += uniphier-xdmac.o obj-$(CONFIG_XGENE_DMA) += xgene-dma.o -obj-$(CONFIG_ZX_DMA) += zx_dma.o obj-$(CONFIG_ST_FDMA) += st_fdma.o obj-$(CONFIG_FSL_DPAA2_QDMA) += fsl-dpaa2-qdma/ obj-$(CONFIG_INTEL_LDMA) += lgm/ diff --git a/drivers/dma/zx_dma.c b/drivers/dma/zx_dma.c deleted file mode 100644 index b057582b2fac..000000000000 --- a/drivers/dma/zx_dma.c +++ /dev/null @@ -1,941 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Copyright 2015 Linaro. - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "virt-dma.h" - -#define DRIVER_NAME "zx-dma" -#define DMA_ALIGN 4 -#define DMA_MAX_SIZE (0x10000 - 512) -#define LLI_BLOCK_SIZE (4 * PAGE_SIZE) - -#define REG_ZX_SRC_ADDR 0x00 -#define REG_ZX_DST_ADDR 0x04 -#define REG_ZX_TX_X_COUNT 0x08 -#define REG_ZX_TX_ZY_COUNT 0x0c -#define REG_ZX_SRC_ZY_STEP 0x10 -#define REG_ZX_DST_ZY_STEP 0x14 -#define REG_ZX_LLI_ADDR 0x1c -#define REG_ZX_CTRL 0x20 -#define REG_ZX_TC_IRQ 0x800 -#define REG_ZX_SRC_ERR_IRQ 0x804 -#define REG_ZX_DST_ERR_IRQ 0x808 -#define REG_ZX_CFG_ERR_IRQ 0x80c -#define REG_ZX_TC_IRQ_RAW 0x810 -#define REG_ZX_SRC_ERR_IRQ_RAW 0x814 -#define REG_ZX_DST_ERR_IRQ_RAW 0x818 -#define REG_ZX_CFG_ERR_IRQ_RAW 0x81c -#define REG_ZX_STATUS 0x820 -#define REG_ZX_DMA_GRP_PRIO 0x824 -#define REG_ZX_DMA_ARB 0x828 - -#define ZX_FORCE_CLOSE BIT(31) -#define ZX_DST_BURST_WIDTH(x) (((x) & 0x7) << 13) -#define ZX_MAX_BURST_LEN 16 -#define ZX_SRC_BURST_LEN(x) (((x) & 0xf) << 9) -#define ZX_SRC_BURST_WIDTH(x) (((x) & 0x7) << 6) -#define ZX_IRQ_ENABLE_ALL (3 << 4) -#define ZX_DST_FIFO_MODE BIT(3) -#define ZX_SRC_FIFO_MODE BIT(2) -#define ZX_SOFT_REQ BIT(1) -#define ZX_CH_ENABLE BIT(0) - -#define ZX_DMA_BUSWIDTHS \ - (BIT(DMA_SLAVE_BUSWIDTH_UNDEFINED) | \ - BIT(DMA_SLAVE_BUSWIDTH_1_BYTE) | \ - BIT(DMA_SLAVE_BUSWIDTH_2_BYTES) | \ - BIT(DMA_SLAVE_BUSWIDTH_4_BYTES) | \ - BIT(DMA_SLAVE_BUSWIDTH_8_BYTES)) - -enum zx_dma_burst_width { - ZX_DMA_WIDTH_8BIT = 0, - ZX_DMA_WIDTH_16BIT = 1, - ZX_DMA_WIDTH_32BIT = 2, - ZX_DMA_WIDTH_64BIT = 3, -}; - -struct zx_desc_hw { - u32 saddr; - u32 daddr; - u32 src_x; - u32 src_zy; - u32 src_zy_step; - u32 dst_zy_step; - u32 reserved1; - u32 lli; - u32 ctr; - u32 reserved[7]; /* pack as hardware registers region size */ -} __aligned(32); - -struct zx_dma_desc_sw { - struct virt_dma_desc vd; - dma_addr_t desc_hw_lli; - size_t desc_num; - size_t size; - struct zx_desc_hw *desc_hw; -}; - -struct zx_dma_phy; - -struct zx_dma_chan { - struct dma_slave_config slave_cfg; - int id; /* Request phy chan id */ - u32 ccfg; - u32 cyclic; - struct virt_dma_chan vc; - struct zx_dma_phy *phy; - struct list_head node; - dma_addr_t dev_addr; - enum dma_status status; -}; - -struct zx_dma_phy { - u32 idx; - void __iomem *base; - struct zx_dma_chan *vchan; - struct zx_dma_desc_sw *ds_run; - struct zx_dma_desc_sw *ds_done; -}; - -struct zx_dma_dev { - struct dma_device slave; - void __iomem *base; - spinlock_t lock; /* lock for ch and phy */ - struct list_head chan_pending; - struct zx_dma_phy *phy; - struct zx_dma_chan *chans; - struct clk *clk; - struct dma_pool *pool; - u32 dma_channels; - u32 dma_requests; - int irq; -}; - -#define to_zx_dma(dmadev) container_of(dmadev, struct zx_dma_dev, slave) - -static struct zx_dma_chan *to_zx_chan(struct dma_chan *chan) -{ - return container_of(chan, struct zx_dma_chan, vc.chan); -} - -static void zx_dma_terminate_chan(struct zx_dma_phy *phy, struct zx_dma_dev *d) -{ - u32 val = 0; - - val = readl_relaxed(phy->base + REG_ZX_CTRL); - val &= ~ZX_CH_ENABLE; - val |= ZX_FORCE_CLOSE; - writel_relaxed(val, phy->base + REG_ZX_CTRL); - - val = 0x1 << phy->idx; - writel_relaxed(val, d->base + REG_ZX_TC_IRQ_RAW); - writel_relaxed(val, d->base + REG_ZX_SRC_ERR_IRQ_RAW); - writel_relaxed(val, d->base + REG_ZX_DST_ERR_IRQ_RAW); - writel_relaxed(val, d->base + REG_ZX_CFG_ERR_IRQ_RAW); -} - -static void zx_dma_set_desc(struct zx_dma_phy *phy, struct zx_desc_hw *hw) -{ - writel_relaxed(hw->saddr, phy->base + REG_ZX_SRC_ADDR); - writel_relaxed(hw->daddr, phy->base + REG_ZX_DST_ADDR); - writel_relaxed(hw->src_x, phy->base + REG_ZX_TX_X_COUNT); - writel_relaxed(0, phy->base + REG_ZX_TX_ZY_COUNT); - writel_relaxed(0, phy->base + REG_ZX_SRC_ZY_STEP); - writel_relaxed(0, phy->base + REG_ZX_DST_ZY_STEP); - writel_relaxed(hw->lli, phy->base + REG_ZX_LLI_ADDR); - writel_relaxed(hw->ctr, phy->base + REG_ZX_CTRL); -} - -static u32 zx_dma_get_curr_lli(struct zx_dma_phy *phy) -{ - return readl_relaxed(phy->base + REG_ZX_LLI_ADDR); -} - -static u32 zx_dma_get_chan_stat(struct zx_dma_dev *d) -{ - return readl_relaxed(d->base + REG_ZX_STATUS); -} - -static void zx_dma_init_state(struct zx_dma_dev *d) -{ - /* set same priority */ - writel_relaxed(0x0, d->base + REG_ZX_DMA_ARB); - /* clear all irq */ - writel_relaxed(0xffffffff, d->base + REG_ZX_TC_IRQ_RAW); - writel_relaxed(0xffffffff, d->base + REG_ZX_SRC_ERR_IRQ_RAW); - writel_relaxed(0xffffffff, d->base + REG_ZX_DST_ERR_IRQ_RAW); - writel_relaxed(0xffffffff, d->base + REG_ZX_CFG_ERR_IRQ_RAW); -} - -static int zx_dma_start_txd(struct zx_dma_chan *c) -{ - struct zx_dma_dev *d = to_zx_dma(c->vc.chan.device); - struct virt_dma_desc *vd = vchan_next_desc(&c->vc); - - if (!c->phy) - return -EAGAIN; - - if (BIT(c->phy->idx) & zx_dma_get_chan_stat(d)) - return -EAGAIN; - - if (vd) { - struct zx_dma_desc_sw *ds = - container_of(vd, struct zx_dma_desc_sw, vd); - /* - * fetch and remove request from vc->desc_issued - * so vc->desc_issued only contains desc pending - */ - list_del(&ds->vd.node); - c->phy->ds_run = ds; - c->phy->ds_done = NULL; - /* start dma */ - zx_dma_set_desc(c->phy, ds->desc_hw); - return 0; - } - c->phy->ds_done = NULL; - c->phy->ds_run = NULL; - return -EAGAIN; -} - -static void zx_dma_task(struct zx_dma_dev *d) -{ - struct zx_dma_phy *p; - struct zx_dma_chan *c, *cn; - unsigned pch, pch_alloc = 0; - unsigned long flags; - - /* check new dma request of running channel in vc->desc_issued */ - list_for_each_entry_safe(c, cn, &d->slave.channels, - vc.chan.device_node) { - spin_lock_irqsave(&c->vc.lock, flags); - p = c->phy; - if (p && p->ds_done && zx_dma_start_txd(c)) { - /* No current txd associated with this channel */ - dev_dbg(d->slave.dev, "pchan %u: free\n", p->idx); - /* Mark this channel free */ - c->phy = NULL; - p->vchan = NULL; - } - spin_unlock_irqrestore(&c->vc.lock, flags); - } - - /* check new channel request in d->chan_pending */ - spin_lock_irqsave(&d->lock, flags); - while (!list_empty(&d->chan_pending)) { - c = list_first_entry(&d->chan_pending, - struct zx_dma_chan, node); - p = &d->phy[c->id]; - if (!p->vchan) { - /* remove from d->chan_pending */ - list_del_init(&c->node); - pch_alloc |= 1 << c->id; - /* Mark this channel allocated */ - p->vchan = c; - c->phy = p; - } else { - dev_dbg(d->slave.dev, "pchan %u: busy!\n", c->id); - } - } - spin_unlock_irqrestore(&d->lock, flags); - - for (pch = 0; pch < d->dma_channels; pch++) { - if (pch_alloc & (1 << pch)) { - p = &d->phy[pch]; - c = p->vchan; - if (c) { - spin_lock_irqsave(&c->vc.lock, flags); - zx_dma_start_txd(c); - spin_unlock_irqrestore(&c->vc.lock, flags); - } - } - } -} - -static irqreturn_t zx_dma_int_handler(int irq, void *dev_id) -{ - struct zx_dma_dev *d = (struct zx_dma_dev *)dev_id; - struct zx_dma_phy *p; - struct zx_dma_chan *c; - u32 tc = readl_relaxed(d->base + REG_ZX_TC_IRQ); - u32 serr = readl_relaxed(d->base + REG_ZX_SRC_ERR_IRQ); - u32 derr = readl_relaxed(d->base + REG_ZX_DST_ERR_IRQ); - u32 cfg = readl_relaxed(d->base + REG_ZX_CFG_ERR_IRQ); - u32 i, irq_chan = 0, task = 0; - - while (tc) { - i = __ffs(tc); - tc &= ~BIT(i); - p = &d->phy[i]; - c = p->vchan; - if (c) { - spin_lock(&c->vc.lock); - if (c->cyclic) { - vchan_cyclic_callback(&p->ds_run->vd); - } else { - vchan_cookie_complete(&p->ds_run->vd); - p->ds_done = p->ds_run; - task = 1; - } - spin_unlock(&c->vc.lock); - irq_chan |= BIT(i); - } - } - - if (serr || derr || cfg) - dev_warn(d->slave.dev, "DMA ERR src 0x%x, dst 0x%x, cfg 0x%x\n", - serr, derr, cfg); - - writel_relaxed(irq_chan, d->base + REG_ZX_TC_IRQ_RAW); - writel_relaxed(serr, d->base + REG_ZX_SRC_ERR_IRQ_RAW); - writel_relaxed(derr, d->base + REG_ZX_DST_ERR_IRQ_RAW); - writel_relaxed(cfg, d->base + REG_ZX_CFG_ERR_IRQ_RAW); - - if (task) - zx_dma_task(d); - return IRQ_HANDLED; -} - -static void zx_dma_free_chan_resources(struct dma_chan *chan) -{ - struct zx_dma_chan *c = to_zx_chan(chan); - struct zx_dma_dev *d = to_zx_dma(chan->device); - unsigned long flags; - - spin_lock_irqsave(&d->lock, flags); - list_del_init(&c->node); - spin_unlock_irqrestore(&d->lock, flags); - - vchan_free_chan_resources(&c->vc); - c->ccfg = 0; -} - -static enum dma_status zx_dma_tx_status(struct dma_chan *chan, - dma_cookie_t cookie, - struct dma_tx_state *state) -{ - struct zx_dma_chan *c = to_zx_chan(chan); - struct zx_dma_phy *p; - struct virt_dma_desc *vd; - unsigned long flags; - enum dma_status ret; - size_t bytes = 0; - - ret = dma_cookie_status(&c->vc.chan, cookie, state); - if (ret == DMA_COMPLETE || !state) - return ret; - - spin_lock_irqsave(&c->vc.lock, flags); - p = c->phy; - ret = c->status; - - /* - * If the cookie is on our issue queue, then the residue is - * its total size. - */ - vd = vchan_find_desc(&c->vc, cookie); - if (vd) { - bytes = container_of(vd, struct zx_dma_desc_sw, vd)->size; - } else if ((!p) || (!p->ds_run)) { - bytes = 0; - } else { - struct zx_dma_desc_sw *ds = p->ds_run; - u32 clli = 0, index = 0; - - bytes = 0; - clli = zx_dma_get_curr_lli(p); - index = (clli - ds->desc_hw_lli) / - sizeof(struct zx_desc_hw) + 1; - for (; index < ds->desc_num; index++) { - bytes += ds->desc_hw[index].src_x; - /* end of lli */ - if (!ds->desc_hw[index].lli) - break; - } - } - spin_unlock_irqrestore(&c->vc.lock, flags); - dma_set_residue(state, bytes); - return ret; -} - -static void zx_dma_issue_pending(struct dma_chan *chan) -{ - struct zx_dma_chan *c = to_zx_chan(chan); - struct zx_dma_dev *d = to_zx_dma(chan->device); - unsigned long flags; - int issue = 0; - - spin_lock_irqsave(&c->vc.lock, flags); - /* add request to vc->desc_issued */ - if (vchan_issue_pending(&c->vc)) { - spin_lock(&d->lock); - if (!c->phy && list_empty(&c->node)) { - /* if new channel, add chan_pending */ - list_add_tail(&c->node, &d->chan_pending); - issue = 1; - dev_dbg(d->slave.dev, "vchan %p: issued\n", &c->vc); - } - spin_unlock(&d->lock); - } else { - dev_dbg(d->slave.dev, "vchan %p: nothing to issue\n", &c->vc); - } - spin_unlock_irqrestore(&c->vc.lock, flags); - - if (issue) - zx_dma_task(d); -} - -static void zx_dma_fill_desc(struct zx_dma_desc_sw *ds, dma_addr_t dst, - dma_addr_t src, size_t len, u32 num, u32 ccfg) -{ - if ((num + 1) < ds->desc_num) - ds->desc_hw[num].lli = ds->desc_hw_lli + (num + 1) * - sizeof(struct zx_desc_hw); - ds->desc_hw[num].saddr = src; - ds->desc_hw[num].daddr = dst; - ds->desc_hw[num].src_x = len; - ds->desc_hw[num].ctr = ccfg; -} - -static struct zx_dma_desc_sw *zx_alloc_desc_resource(int num, - struct dma_chan *chan) -{ - struct zx_dma_chan *c = to_zx_chan(chan); - struct zx_dma_desc_sw *ds; - struct zx_dma_dev *d = to_zx_dma(chan->device); - int lli_limit = LLI_BLOCK_SIZE / sizeof(struct zx_desc_hw); - - if (num > lli_limit) { - dev_dbg(chan->device->dev, "vch %p: sg num %d exceed max %d\n", - &c->vc, num, lli_limit); - return NULL; - } - - ds = kzalloc(sizeof(*ds), GFP_ATOMIC); - if (!ds) - return NULL; - - ds->desc_hw = dma_pool_zalloc(d->pool, GFP_NOWAIT, &ds->desc_hw_lli); - if (!ds->desc_hw) { - dev_dbg(chan->device->dev, "vch %p: dma alloc fail\n", &c->vc); - kfree(ds); - return NULL; - } - ds->desc_num = num; - return ds; -} - -static enum zx_dma_burst_width zx_dma_burst_width(enum dma_slave_buswidth width) -{ - switch (width) { - case DMA_SLAVE_BUSWIDTH_1_BYTE: - case DMA_SLAVE_BUSWIDTH_2_BYTES: - case DMA_SLAVE_BUSWIDTH_4_BYTES: - case DMA_SLAVE_BUSWIDTH_8_BYTES: - return ffs(width) - 1; - default: - return ZX_DMA_WIDTH_32BIT; - } -} - -static int zx_pre_config(struct zx_dma_chan *c, enum dma_transfer_direction dir) -{ - struct dma_slave_config *cfg = &c->slave_cfg; - enum zx_dma_burst_width src_width; - enum zx_dma_burst_width dst_width; - u32 maxburst = 0; - - switch (dir) { - case DMA_MEM_TO_MEM: - c->ccfg = ZX_CH_ENABLE | ZX_SOFT_REQ - | ZX_SRC_BURST_LEN(ZX_MAX_BURST_LEN - 1) - | ZX_SRC_BURST_WIDTH(ZX_DMA_WIDTH_32BIT) - | ZX_DST_BURST_WIDTH(ZX_DMA_WIDTH_32BIT); - break; - case DMA_MEM_TO_DEV: - c->dev_addr = cfg->dst_addr; - /* dst len is calculated from src width, len and dst width. - * We need make sure dst len not exceed MAX LEN. - * Trailing single transaction that does not fill a full - * burst also require identical src/dst data width. - */ - dst_width = zx_dma_burst_width(cfg->dst_addr_width); - maxburst = cfg->dst_maxburst; - maxburst = maxburst < ZX_MAX_BURST_LEN ? - maxburst : ZX_MAX_BURST_LEN; - c->ccfg = ZX_DST_FIFO_MODE | ZX_CH_ENABLE - | ZX_SRC_BURST_LEN(maxburst - 1) - | ZX_SRC_BURST_WIDTH(dst_width) - | ZX_DST_BURST_WIDTH(dst_width); - break; - case DMA_DEV_TO_MEM: - c->dev_addr = cfg->src_addr; - src_width = zx_dma_burst_width(cfg->src_addr_width); - maxburst = cfg->src_maxburst; - maxburst = maxburst < ZX_MAX_BURST_LEN ? - maxburst : ZX_MAX_BURST_LEN; - c->ccfg = ZX_SRC_FIFO_MODE | ZX_CH_ENABLE - | ZX_SRC_BURST_LEN(maxburst - 1) - | ZX_SRC_BURST_WIDTH(src_width) - | ZX_DST_BURST_WIDTH(src_width); - break; - default: - return -EINVAL; - } - return 0; -} - -static struct dma_async_tx_descriptor *zx_dma_prep_memcpy( - struct dma_chan *chan, dma_addr_t dst, dma_addr_t src, - size_t len, unsigned long flags) -{ - struct zx_dma_chan *c = to_zx_chan(chan); - struct zx_dma_desc_sw *ds; - size_t copy = 0; - int num = 0; - - if (!len) - return NULL; - - if (zx_pre_config(c, DMA_MEM_TO_MEM)) - return NULL; - - num = DIV_ROUND_UP(len, DMA_MAX_SIZE); - - ds = zx_alloc_desc_resource(num, chan); - if (!ds) - return NULL; - - ds->size = len; - num = 0; - - do { - copy = min_t(size_t, len, DMA_MAX_SIZE); - zx_dma_fill_desc(ds, dst, src, copy, num++, c->ccfg); - - src += copy; - dst += copy; - len -= copy; - } while (len); - - c->cyclic = 0; - ds->desc_hw[num - 1].lli = 0; /* end of link */ - ds->desc_hw[num - 1].ctr |= ZX_IRQ_ENABLE_ALL; - return vchan_tx_prep(&c->vc, &ds->vd, flags); -} - -static struct dma_async_tx_descriptor *zx_dma_prep_slave_sg( - struct dma_chan *chan, struct scatterlist *sgl, unsigned int sglen, - enum dma_transfer_direction dir, unsigned long flags, void *context) -{ - struct zx_dma_chan *c = to_zx_chan(chan); - struct zx_dma_desc_sw *ds; - size_t len, avail, total = 0; - struct scatterlist *sg; - dma_addr_t addr, src = 0, dst = 0; - int num = sglen, i; - - if (!sgl) - return NULL; - - if (zx_pre_config(c, dir)) - return NULL; - - for_each_sg(sgl, sg, sglen, i) { - avail = sg_dma_len(sg); - if (avail > DMA_MAX_SIZE) - num += DIV_ROUND_UP(avail, DMA_MAX_SIZE) - 1; - } - - ds = zx_alloc_desc_resource(num, chan); - if (!ds) - return NULL; - - c->cyclic = 0; - num = 0; - for_each_sg(sgl, sg, sglen, i) { - addr = sg_dma_address(sg); - avail = sg_dma_len(sg); - total += avail; - - do { - len = min_t(size_t, avail, DMA_MAX_SIZE); - - if (dir == DMA_MEM_TO_DEV) { - src = addr; - dst = c->dev_addr; - } else if (dir == DMA_DEV_TO_MEM) { - src = c->dev_addr; - dst = addr; - } - - zx_dma_fill_desc(ds, dst, src, len, num++, c->ccfg); - - addr += len; - avail -= len; - } while (avail); - } - - ds->desc_hw[num - 1].lli = 0; /* end of link */ - ds->desc_hw[num - 1].ctr |= ZX_IRQ_ENABLE_ALL; - ds->size = total; - return vchan_tx_prep(&c->vc, &ds->vd, flags); -} - -static struct dma_async_tx_descriptor *zx_dma_prep_dma_cyclic( - struct dma_chan *chan, dma_addr_t dma_addr, size_t buf_len, - size_t period_len, enum dma_transfer_direction dir, - unsigned long flags) -{ - struct zx_dma_chan *c = to_zx_chan(chan); - struct zx_dma_desc_sw *ds; - dma_addr_t src = 0, dst = 0; - int num_periods = buf_len / period_len; - int buf = 0, num = 0; - - if (period_len > DMA_MAX_SIZE) { - dev_err(chan->device->dev, "maximum period size exceeded\n"); - return NULL; - } - - if (zx_pre_config(c, dir)) - return NULL; - - ds = zx_alloc_desc_resource(num_periods, chan); - if (!ds) - return NULL; - c->cyclic = 1; - - while (buf < buf_len) { - if (dir == DMA_MEM_TO_DEV) { - src = dma_addr; - dst = c->dev_addr; - } else if (dir == DMA_DEV_TO_MEM) { - src = c->dev_addr; - dst = dma_addr; - } - zx_dma_fill_desc(ds, dst, src, period_len, num++, - c->ccfg | ZX_IRQ_ENABLE_ALL); - dma_addr += period_len; - buf += period_len; - } - - ds->desc_hw[num - 1].lli = ds->desc_hw_lli; - ds->size = buf_len; - return vchan_tx_prep(&c->vc, &ds->vd, flags); -} - -static int zx_dma_config(struct dma_chan *chan, - struct dma_slave_config *cfg) -{ - struct zx_dma_chan *c = to_zx_chan(chan); - - if (!cfg) - return -EINVAL; - - memcpy(&c->slave_cfg, cfg, sizeof(*cfg)); - - return 0; -} - -static int zx_dma_terminate_all(struct dma_chan *chan) -{ - struct zx_dma_chan *c = to_zx_chan(chan); - struct zx_dma_dev *d = to_zx_dma(chan->device); - struct zx_dma_phy *p = c->phy; - unsigned long flags; - LIST_HEAD(head); - - dev_dbg(d->slave.dev, "vchan %p: terminate all\n", &c->vc); - - /* Prevent this channel being scheduled */ - spin_lock(&d->lock); - list_del_init(&c->node); - spin_unlock(&d->lock); - - /* Clear the tx descriptor lists */ - spin_lock_irqsave(&c->vc.lock, flags); - vchan_get_all_descriptors(&c->vc, &head); - if (p) { - /* vchan is assigned to a pchan - stop the channel */ - zx_dma_terminate_chan(p, d); - c->phy = NULL; - p->vchan = NULL; - p->ds_run = NULL; - p->ds_done = NULL; - } - spin_unlock_irqrestore(&c->vc.lock, flags); - vchan_dma_desc_free_list(&c->vc, &head); - - return 0; -} - -static int zx_dma_transfer_pause(struct dma_chan *chan) -{ - struct zx_dma_chan *c = to_zx_chan(chan); - u32 val = 0; - - val = readl_relaxed(c->phy->base + REG_ZX_CTRL); - val &= ~ZX_CH_ENABLE; - writel_relaxed(val, c->phy->base + REG_ZX_CTRL); - - return 0; -} - -static int zx_dma_transfer_resume(struct dma_chan *chan) -{ - struct zx_dma_chan *c = to_zx_chan(chan); - u32 val = 0; - - val = readl_relaxed(c->phy->base + REG_ZX_CTRL); - val |= ZX_CH_ENABLE; - writel_relaxed(val, c->phy->base + REG_ZX_CTRL); - - return 0; -} - -static void zx_dma_free_desc(struct virt_dma_desc *vd) -{ - struct zx_dma_desc_sw *ds = - container_of(vd, struct zx_dma_desc_sw, vd); - struct zx_dma_dev *d = to_zx_dma(vd->tx.chan->device); - - dma_pool_free(d->pool, ds->desc_hw, ds->desc_hw_lli); - kfree(ds); -} - -static const struct of_device_id zx6702_dma_dt_ids[] = { - { .compatible = "zte,zx296702-dma", }, - {} -}; -MODULE_DEVICE_TABLE(of, zx6702_dma_dt_ids); - -static struct dma_chan *zx_of_dma_simple_xlate(struct of_phandle_args *dma_spec, - struct of_dma *ofdma) -{ - struct zx_dma_dev *d = ofdma->of_dma_data; - unsigned int request = dma_spec->args[0]; - struct dma_chan *chan; - struct zx_dma_chan *c; - - if (request >= d->dma_requests) - return NULL; - - chan = dma_get_any_slave_channel(&d->slave); - if (!chan) { - dev_err(d->slave.dev, "get channel fail in %s.\n", __func__); - return NULL; - } - c = to_zx_chan(chan); - c->id = request; - dev_info(d->slave.dev, "zx_dma: pchan %u: alloc vchan %p\n", - c->id, &c->vc); - return chan; -} - -static int zx_dma_probe(struct platform_device *op) -{ - struct zx_dma_dev *d; - int i, ret = 0; - - d = devm_kzalloc(&op->dev, sizeof(*d), GFP_KERNEL); - if (!d) - return -ENOMEM; - - d->base = devm_platform_ioremap_resource(op, 0); - if (IS_ERR(d->base)) - return PTR_ERR(d->base); - - of_property_read_u32((&op->dev)->of_node, - "dma-channels", &d->dma_channels); - of_property_read_u32((&op->dev)->of_node, - "dma-requests", &d->dma_requests); - if (!d->dma_requests || !d->dma_channels) - return -EINVAL; - - d->clk = devm_clk_get(&op->dev, NULL); - if (IS_ERR(d->clk)) { - dev_err(&op->dev, "no dma clk\n"); - return PTR_ERR(d->clk); - } - - d->irq = platform_get_irq(op, 0); - ret = devm_request_irq(&op->dev, d->irq, zx_dma_int_handler, - 0, DRIVER_NAME, d); - if (ret) - return ret; - - /* A DMA memory pool for LLIs, align on 32-byte boundary */ - d->pool = dmam_pool_create(DRIVER_NAME, &op->dev, - LLI_BLOCK_SIZE, 32, 0); - if (!d->pool) - return -ENOMEM; - - /* init phy channel */ - d->phy = devm_kcalloc(&op->dev, - d->dma_channels, sizeof(struct zx_dma_phy), GFP_KERNEL); - if (!d->phy) - return -ENOMEM; - - for (i = 0; i < d->dma_channels; i++) { - struct zx_dma_phy *p = &d->phy[i]; - - p->idx = i; - p->base = d->base + i * 0x40; - } - - INIT_LIST_HEAD(&d->slave.channels); - dma_cap_set(DMA_SLAVE, d->slave.cap_mask); - dma_cap_set(DMA_MEMCPY, d->slave.cap_mask); - dma_cap_set(DMA_CYCLIC, d->slave.cap_mask); - dma_cap_set(DMA_PRIVATE, d->slave.cap_mask); - d->slave.dev = &op->dev; - d->slave.device_free_chan_resources = zx_dma_free_chan_resources; - d->slave.device_tx_status = zx_dma_tx_status; - d->slave.device_prep_dma_memcpy = zx_dma_prep_memcpy; - d->slave.device_prep_slave_sg = zx_dma_prep_slave_sg; - d->slave.device_prep_dma_cyclic = zx_dma_prep_dma_cyclic; - d->slave.device_issue_pending = zx_dma_issue_pending; - d->slave.device_config = zx_dma_config; - d->slave.device_terminate_all = zx_dma_terminate_all; - d->slave.device_pause = zx_dma_transfer_pause; - d->slave.device_resume = zx_dma_transfer_resume; - d->slave.copy_align = DMA_ALIGN; - d->slave.src_addr_widths = ZX_DMA_BUSWIDTHS; - d->slave.dst_addr_widths = ZX_DMA_BUSWIDTHS; - d->slave.directions = BIT(DMA_MEM_TO_MEM) | BIT(DMA_MEM_TO_DEV) - | BIT(DMA_DEV_TO_MEM); - d->slave.residue_granularity = DMA_RESIDUE_GRANULARITY_SEGMENT; - - /* init virtual channel */ - d->chans = devm_kcalloc(&op->dev, - d->dma_requests, sizeof(struct zx_dma_chan), GFP_KERNEL); - if (!d->chans) - return -ENOMEM; - - for (i = 0; i < d->dma_requests; i++) { - struct zx_dma_chan *c = &d->chans[i]; - - c->status = DMA_IN_PROGRESS; - INIT_LIST_HEAD(&c->node); - c->vc.desc_free = zx_dma_free_desc; - vchan_init(&c->vc, &d->slave); - } - - /* Enable clock before accessing registers */ - ret = clk_prepare_enable(d->clk); - if (ret < 0) { - dev_err(&op->dev, "clk_prepare_enable failed: %d\n", ret); - goto zx_dma_out; - } - - zx_dma_init_state(d); - - spin_lock_init(&d->lock); - INIT_LIST_HEAD(&d->chan_pending); - platform_set_drvdata(op, d); - - ret = dma_async_device_register(&d->slave); - if (ret) - goto clk_dis; - - ret = of_dma_controller_register((&op->dev)->of_node, - zx_of_dma_simple_xlate, d); - if (ret) - goto of_dma_register_fail; - - dev_info(&op->dev, "initialized\n"); - return 0; - -of_dma_register_fail: - dma_async_device_unregister(&d->slave); -clk_dis: - clk_disable_unprepare(d->clk); -zx_dma_out: - return ret; -} - -static int zx_dma_remove(struct platform_device *op) -{ - struct zx_dma_chan *c, *cn; - struct zx_dma_dev *d = platform_get_drvdata(op); - - /* explictly free the irq */ - devm_free_irq(&op->dev, d->irq, d); - - dma_async_device_unregister(&d->slave); - of_dma_controller_free((&op->dev)->of_node); - - list_for_each_entry_safe(c, cn, &d->slave.channels, - vc.chan.device_node) { - list_del(&c->vc.chan.device_node); - } - clk_disable_unprepare(d->clk); - - return 0; -} - -#ifdef CONFIG_PM_SLEEP -static int zx_dma_suspend_dev(struct device *dev) -{ - struct zx_dma_dev *d = dev_get_drvdata(dev); - u32 stat = 0; - - stat = zx_dma_get_chan_stat(d); - if (stat) { - dev_warn(d->slave.dev, - "chan %d is running fail to suspend\n", stat); - return -1; - } - clk_disable_unprepare(d->clk); - return 0; -} - -static int zx_dma_resume_dev(struct device *dev) -{ - struct zx_dma_dev *d = dev_get_drvdata(dev); - int ret = 0; - - ret = clk_prepare_enable(d->clk); - if (ret < 0) { - dev_err(d->slave.dev, "clk_prepare_enable failed: %d\n", ret); - return ret; - } - zx_dma_init_state(d); - return 0; -} -#endif - -static SIMPLE_DEV_PM_OPS(zx_dma_pmops, zx_dma_suspend_dev, zx_dma_resume_dev); - -static struct platform_driver zx_pdma_driver = { - .driver = { - .name = DRIVER_NAME, - .pm = &zx_dma_pmops, - .of_match_table = zx6702_dma_dt_ids, - }, - .probe = zx_dma_probe, - .remove = zx_dma_remove, -}; - -module_platform_driver(zx_pdma_driver); - -MODULE_DESCRIPTION("ZTE ZX296702 DMA Driver"); -MODULE_AUTHOR("Jun Nie jun.nie@linaro.org"); -MODULE_LICENSE("GPL v2"); -- cgit v1.2.3 From a033a74e8b66336fc2ea379842be6bcf176cbfbc Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Wed, 20 Jan 2021 14:18:59 +0100 Subject: dmaengine: remove coh901318 driver The ST-Ericsson U300 platform is getting removed, so this driver is no longer needed. Signed-off-by: Arnd Bergmann Reviewed-by: Linus Walleij Cc: Linus Walleij Link: https://lore.kernel.org/r/20210120131859.2056308-4-arnd@kernel.org Signed-off-by: Vinod Koul --- .../devicetree/bindings/dma/ste-coh901318.txt | 32 - drivers/dma/Kconfig | 7 - drivers/dma/Makefile | 1 - drivers/dma/coh901318.c | 2808 -------------------- drivers/dma/coh901318.h | 141 - drivers/dma/coh901318_lli.c | 313 --- include/linux/platform_data/dma-coh901318.h | 72 - 7 files changed, 3374 deletions(-) delete mode 100644 Documentation/devicetree/bindings/dma/ste-coh901318.txt delete mode 100644 drivers/dma/coh901318.c delete mode 100644 drivers/dma/coh901318.h delete mode 100644 drivers/dma/coh901318_lli.c delete mode 100644 include/linux/platform_data/dma-coh901318.h (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/dma/ste-coh901318.txt b/Documentation/devicetree/bindings/dma/ste-coh901318.txt deleted file mode 100644 index 091ad057e9cf..000000000000 --- a/Documentation/devicetree/bindings/dma/ste-coh901318.txt +++ /dev/null @@ -1,32 +0,0 @@ -ST-Ericsson COH 901 318 DMA Controller - -This is a DMA controller which has begun as a fork of the -ARM PL08x PrimeCell VHDL code. - -Required properties: -- compatible: should be "stericsson,coh901318" -- reg: register locations and length -- interrupts: the single DMA IRQ -- #dma-cells: must be set to <1>, as the channels on the - COH 901 318 are simple and identified by a single number -- dma-channels: the number of DMA channels handled - -Example: - -dmac: dma-controller@c00020000 { - compatible = "stericsson,coh901318"; - reg = <0xc0020000 0x1000>; - interrupt-parent = <&vica>; - interrupts = <2>; - #dma-cells = <1>; - dma-channels = <40>; -}; - -Consumers example: - -uart0: serial@c0013000 { - compatible = "..."; - (...) - dmas = <&dmac 17 &dmac 18>; - dma-names = "tx", "rx"; -}; diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig index 4fd6a90cfadf..725cda4aa2a3 100644 --- a/drivers/dma/Kconfig +++ b/drivers/dma/Kconfig @@ -124,13 +124,6 @@ config BCM_SBA_RAID has the capability to offload memcpy, xor and pq computation for raid5/6. -config COH901318 - bool "ST-Ericsson COH901318 DMA support" - select DMA_ENGINE - depends on ARCH_U300 || COMPILE_TEST - help - Enable support for ST-Ericsson COH 901 318 DMA. - config DMA_BCM2835 tristate "BCM2835 DMA engine support" depends on ARCH_BCM2835 diff --git a/drivers/dma/Makefile b/drivers/dma/Makefile index 4aed5ea59922..aa69094e3547 100644 --- a/drivers/dma/Makefile +++ b/drivers/dma/Makefile @@ -20,7 +20,6 @@ obj-$(CONFIG_AT_HDMAC) += at_hdmac.o obj-$(CONFIG_AT_XDMAC) += at_xdmac.o obj-$(CONFIG_AXI_DMAC) += dma-axi-dmac.o obj-$(CONFIG_BCM_SBA_RAID) += bcm-sba-raid.o -obj-$(CONFIG_COH901318) += coh901318.o coh901318_lli.o obj-$(CONFIG_DMA_BCM2835) += bcm2835-dma.o obj-$(CONFIG_DMA_JZ4780) += dma-jz4780.o obj-$(CONFIG_DMA_SA11X0) += sa11x0-dma.o diff --git a/drivers/dma/coh901318.c b/drivers/dma/coh901318.c deleted file mode 100644 index 95b9b2f5358e..000000000000 --- a/drivers/dma/coh901318.c +++ /dev/null @@ -1,2808 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * driver/dma/coh901318.c - * - * Copyright (C) 2007-2009 ST-Ericsson - * DMA driver for COH 901 318 - * Author: Per Friden - */ - -#include -#include -#include /* printk() */ -#include /* everything... */ -#include -#include /* kmalloc() */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "coh901318.h" -#include "dmaengine.h" - -#define COH901318_MOD32_MASK (0x1F) -#define COH901318_WORD_MASK (0xFFFFFFFF) -/* INT_STATUS - Interrupt Status Registers 32bit (R/-) */ -#define COH901318_INT_STATUS1 (0x0000) -#define COH901318_INT_STATUS2 (0x0004) -/* TC_INT_STATUS - Terminal Count Interrupt Status Registers 32bit (R/-) */ -#define COH901318_TC_INT_STATUS1 (0x0008) -#define COH901318_TC_INT_STATUS2 (0x000C) -/* TC_INT_CLEAR - Terminal Count Interrupt Clear Registers 32bit (-/W) */ -#define COH901318_TC_INT_CLEAR1 (0x0010) -#define COH901318_TC_INT_CLEAR2 (0x0014) -/* RAW_TC_INT_STATUS - Raw Term Count Interrupt Status Registers 32bit (R/-) */ -#define COH901318_RAW_TC_INT_STATUS1 (0x0018) -#define COH901318_RAW_TC_INT_STATUS2 (0x001C) -/* BE_INT_STATUS - Bus Error Interrupt Status Registers 32bit (R/-) */ -#define COH901318_BE_INT_STATUS1 (0x0020) -#define COH901318_BE_INT_STATUS2 (0x0024) -/* BE_INT_CLEAR - Bus Error Interrupt Clear Registers 32bit (-/W) */ -#define COH901318_BE_INT_CLEAR1 (0x0028) -#define COH901318_BE_INT_CLEAR2 (0x002C) -/* RAW_BE_INT_STATUS - Raw Term Count Interrupt Status Registers 32bit (R/-) */ -#define COH901318_RAW_BE_INT_STATUS1 (0x0030) -#define COH901318_RAW_BE_INT_STATUS2 (0x0034) - -/* - * CX_CFG - Channel Configuration Registers 32bit (R/W) - */ -#define COH901318_CX_CFG (0x0100) -#define COH901318_CX_CFG_SPACING (0x04) -/* Channel enable activates tha dma job */ -#define COH901318_CX_CFG_CH_ENABLE (0x00000001) -#define COH901318_CX_CFG_CH_DISABLE (0x00000000) -/* Request Mode */ -#define COH901318_CX_CFG_RM_MASK (0x00000006) -#define COH901318_CX_CFG_RM_MEMORY_TO_MEMORY (0x0 << 1) -#define COH901318_CX_CFG_RM_PRIMARY_TO_MEMORY (0x1 << 1) -#define COH901318_CX_CFG_RM_MEMORY_TO_PRIMARY (0x1 << 1) -#define COH901318_CX_CFG_RM_PRIMARY_TO_SECONDARY (0x3 << 1) -#define COH901318_CX_CFG_RM_SECONDARY_TO_PRIMARY (0x3 << 1) -/* Linked channel request field. RM must == 11 */ -#define COH901318_CX_CFG_LCRF_SHIFT 3 -#define COH901318_CX_CFG_LCRF_MASK (0x000001F8) -#define COH901318_CX_CFG_LCR_DISABLE (0x00000000) -/* Terminal Counter Interrupt Request Mask */ -#define COH901318_CX_CFG_TC_IRQ_ENABLE (0x00000200) -#define COH901318_CX_CFG_TC_IRQ_DISABLE (0x00000000) -/* Bus Error interrupt Mask */ -#define COH901318_CX_CFG_BE_IRQ_ENABLE (0x00000400) -#define COH901318_CX_CFG_BE_IRQ_DISABLE (0x00000000) - -/* - * CX_STAT - Channel Status Registers 32bit (R/-) - */ -#define COH901318_CX_STAT (0x0200) -#define COH901318_CX_STAT_SPACING (0x04) -#define COH901318_CX_STAT_RBE_IRQ_IND (0x00000008) -#define COH901318_CX_STAT_RTC_IRQ_IND (0x00000004) -#define COH901318_CX_STAT_ACTIVE (0x00000002) -#define COH901318_CX_STAT_ENABLED (0x00000001) - -/* - * CX_CTRL - Channel Control Registers 32bit (R/W) - */ -#define COH901318_CX_CTRL (0x0400) -#define COH901318_CX_CTRL_SPACING (0x10) -/* Transfer Count Enable */ -#define COH901318_CX_CTRL_TC_ENABLE (0x00001000) -#define COH901318_CX_CTRL_TC_DISABLE (0x00000000) -/* Transfer Count Value 0 - 4095 */ -#define COH901318_CX_CTRL_TC_VALUE_MASK (0x00000FFF) -/* Burst count */ -#define COH901318_CX_CTRL_BURST_COUNT_MASK (0x0000E000) -#define COH901318_CX_CTRL_BURST_COUNT_64_BYTES (0x7 << 13) -#define COH901318_CX_CTRL_BURST_COUNT_48_BYTES (0x6 << 13) -#define COH901318_CX_CTRL_BURST_COUNT_32_BYTES (0x5 << 13) -#define COH901318_CX_CTRL_BURST_COUNT_16_BYTES (0x4 << 13) -#define COH901318_CX_CTRL_BURST_COUNT_8_BYTES (0x3 << 13) -#define COH901318_CX_CTRL_BURST_COUNT_4_BYTES (0x2 << 13) -#define COH901318_CX_CTRL_BURST_COUNT_2_BYTES (0x1 << 13) -#define COH901318_CX_CTRL_BURST_COUNT_1_BYTE (0x0 << 13) -/* Source bus size */ -#define COH901318_CX_CTRL_SRC_BUS_SIZE_MASK (0x00030000) -#define COH901318_CX_CTRL_SRC_BUS_SIZE_32_BITS (0x2 << 16) -#define COH901318_CX_CTRL_SRC_BUS_SIZE_16_BITS (0x1 << 16) -#define COH901318_CX_CTRL_SRC_BUS_SIZE_8_BITS (0x0 << 16) -/* Source address increment */ -#define COH901318_CX_CTRL_SRC_ADDR_INC_ENABLE (0x00040000) -#define COH901318_CX_CTRL_SRC_ADDR_INC_DISABLE (0x00000000) -/* Destination Bus Size */ -#define COH901318_CX_CTRL_DST_BUS_SIZE_MASK (0x00180000) -#define COH901318_CX_CTRL_DST_BUS_SIZE_32_BITS (0x2 << 19) -#define COH901318_CX_CTRL_DST_BUS_SIZE_16_BITS (0x1 << 19) -#define COH901318_CX_CTRL_DST_BUS_SIZE_8_BITS (0x0 << 19) -/* Destination address increment */ -#define COH901318_CX_CTRL_DST_ADDR_INC_ENABLE (0x00200000) -#define COH901318_CX_CTRL_DST_ADDR_INC_DISABLE (0x00000000) -/* Master Mode (Master2 is only connected to MSL) */ -#define COH901318_CX_CTRL_MASTER_MODE_MASK (0x00C00000) -#define COH901318_CX_CTRL_MASTER_MODE_M2R_M1W (0x3 << 22) -#define COH901318_CX_CTRL_MASTER_MODE_M1R_M2W (0x2 << 22) -#define COH901318_CX_CTRL_MASTER_MODE_M2RW (0x1 << 22) -#define COH901318_CX_CTRL_MASTER_MODE_M1RW (0x0 << 22) -/* Terminal Count flag to PER enable */ -#define COH901318_CX_CTRL_TCP_ENABLE (0x01000000) -#define COH901318_CX_CTRL_TCP_DISABLE (0x00000000) -/* Terminal Count flags to CPU enable */ -#define COH901318_CX_CTRL_TC_IRQ_ENABLE (0x02000000) -#define COH901318_CX_CTRL_TC_IRQ_DISABLE (0x00000000) -/* Hand shake to peripheral */ -#define COH901318_CX_CTRL_HSP_ENABLE (0x04000000) -#define COH901318_CX_CTRL_HSP_DISABLE (0x00000000) -#define COH901318_CX_CTRL_HSS_ENABLE (0x08000000) -#define COH901318_CX_CTRL_HSS_DISABLE (0x00000000) -/* DMA mode */ -#define COH901318_CX_CTRL_DDMA_MASK (0x30000000) -#define COH901318_CX_CTRL_DDMA_LEGACY (0x0 << 28) -#define COH901318_CX_CTRL_DDMA_DEMAND_DMA1 (0x1 << 28) -#define COH901318_CX_CTRL_DDMA_DEMAND_DMA2 (0x2 << 28) -/* Primary Request Data Destination */ -#define COH901318_CX_CTRL_PRDD_MASK (0x40000000) -#define COH901318_CX_CTRL_PRDD_DEST (0x1 << 30) -#define COH901318_CX_CTRL_PRDD_SOURCE (0x0 << 30) - -/* - * CX_SRC_ADDR - Channel Source Address Registers 32bit (R/W) - */ -#define COH901318_CX_SRC_ADDR (0x0404) -#define COH901318_CX_SRC_ADDR_SPACING (0x10) - -/* - * CX_DST_ADDR - Channel Destination Address Registers 32bit R/W - */ -#define COH901318_CX_DST_ADDR (0x0408) -#define COH901318_CX_DST_ADDR_SPACING (0x10) - -/* - * CX_LNK_ADDR - Channel Link Address Registers 32bit (R/W) - */ -#define COH901318_CX_LNK_ADDR (0x040C) -#define COH901318_CX_LNK_ADDR_SPACING (0x10) -#define COH901318_CX_LNK_LINK_IMMEDIATE (0x00000001) - -/** - * struct coh901318_params - parameters for DMAC configuration - * @config: DMA config register - * @ctrl_lli_last: DMA control register for the last lli in the list - * @ctrl_lli: DMA control register for an lli - * @ctrl_lli_chained: DMA control register for a chained lli - */ -struct coh901318_params { - u32 config; - u32 ctrl_lli_last; - u32 ctrl_lli; - u32 ctrl_lli_chained; -}; - -/** - * struct coh_dma_channel - dma channel base - * @name: ascii name of dma channel - * @number: channel id number - * @desc_nbr_max: number of preallocated descriptors - * @priority_high: prio of channel, 0 low otherwise high. - * @param: configuration parameters - */ -struct coh_dma_channel { - const char name[32]; - const int number; - const int desc_nbr_max; - const int priority_high; - const struct coh901318_params param; -}; - -/** - * struct powersave - DMA power save structure - * @lock: lock protecting data in this struct - * @started_channels: bit mask indicating active dma channels - */ -struct powersave { - spinlock_t lock; - u64 started_channels; -}; - -/* points out all dma slave channels. - * Syntax is [A1, B1, A2, B2, .... ,-1,-1] - * Select all channels from A to B, end of list is marked with -1,-1 - */ -static int dma_slave_channels[] = { - U300_DMA_MSL_TX_0, U300_DMA_SPI_RX, - U300_DMA_UART1_TX, U300_DMA_UART1_RX, -1, -1}; - -/* points out all dma memcpy channels. */ -static int dma_memcpy_channels[] = { - U300_DMA_GENERAL_PURPOSE_0, U300_DMA_GENERAL_PURPOSE_8, -1, -1}; - -#define flags_memcpy_config (COH901318_CX_CFG_CH_DISABLE | \ - COH901318_CX_CFG_RM_MEMORY_TO_MEMORY | \ - COH901318_CX_CFG_LCR_DISABLE | \ - COH901318_CX_CFG_TC_IRQ_ENABLE | \ - COH901318_CX_CFG_BE_IRQ_ENABLE) -#define flags_memcpy_lli_chained (COH901318_CX_CTRL_TC_ENABLE | \ - COH901318_CX_CTRL_BURST_COUNT_32_BYTES | \ - COH901318_CX_CTRL_SRC_BUS_SIZE_32_BITS | \ - COH901318_CX_CTRL_SRC_ADDR_INC_ENABLE | \ - COH901318_CX_CTRL_DST_BUS_SIZE_32_BITS | \ - COH901318_CX_CTRL_DST_ADDR_INC_ENABLE | \ - COH901318_CX_CTRL_MASTER_MODE_M1RW | \ - COH901318_CX_CTRL_TCP_DISABLE | \ - COH901318_CX_CTRL_TC_IRQ_DISABLE | \ - COH901318_CX_CTRL_HSP_DISABLE | \ - COH901318_CX_CTRL_HSS_DISABLE | \ - COH901318_CX_CTRL_DDMA_LEGACY | \ - COH901318_CX_CTRL_PRDD_SOURCE) -#define flags_memcpy_lli (COH901318_CX_CTRL_TC_ENABLE | \ - COH901318_CX_CTRL_BURST_COUNT_32_BYTES | \ - COH901318_CX_CTRL_SRC_BUS_SIZE_32_BITS | \ - COH901318_CX_CTRL_SRC_ADDR_INC_ENABLE | \ - COH901318_CX_CTRL_DST_BUS_SIZE_32_BITS | \ - COH901318_CX_CTRL_DST_ADDR_INC_ENABLE | \ - COH901318_CX_CTRL_MASTER_MODE_M1RW | \ - COH901318_CX_CTRL_TCP_DISABLE | \ - COH901318_CX_CTRL_TC_IRQ_DISABLE | \ - COH901318_CX_CTRL_HSP_DISABLE | \ - COH901318_CX_CTRL_HSS_DISABLE | \ - COH901318_CX_CTRL_DDMA_LEGACY | \ - COH901318_CX_CTRL_PRDD_SOURCE) -#define flags_memcpy_lli_last (COH901318_CX_CTRL_TC_ENABLE | \ - COH901318_CX_CTRL_BURST_COUNT_32_BYTES | \ - COH901318_CX_CTRL_SRC_BUS_SIZE_32_BITS | \ - COH901318_CX_CTRL_SRC_ADDR_INC_ENABLE | \ - COH901318_CX_CTRL_DST_BUS_SIZE_32_BITS | \ - COH901318_CX_CTRL_DST_ADDR_INC_ENABLE | \ - COH901318_CX_CTRL_MASTER_MODE_M1RW | \ - COH901318_CX_CTRL_TCP_DISABLE | \ - COH901318_CX_CTRL_TC_IRQ_ENABLE | \ - COH901318_CX_CTRL_HSP_DISABLE | \ - COH901318_CX_CTRL_HSS_DISABLE | \ - COH901318_CX_CTRL_DDMA_LEGACY | \ - COH901318_CX_CTRL_PRDD_SOURCE) - -static const struct coh_dma_channel chan_config[U300_DMA_CHANNELS] = { - { - .number = U300_DMA_MSL_TX_0, - .name = "MSL TX 0", - .priority_high = 0, - }, - { - .number = U300_DMA_MSL_TX_1, - .name = "MSL TX 1", - .priority_high = 0, - .param.config = COH901318_CX_CFG_CH_DISABLE | - COH901318_CX_CFG_LCR_DISABLE | - COH901318_CX_CFG_TC_IRQ_ENABLE | - COH901318_CX_CFG_BE_IRQ_ENABLE, - .param.ctrl_lli_chained = 0 | - COH901318_CX_CTRL_TC_ENABLE | - COH901318_CX_CTRL_BURST_COUNT_32_BYTES | - COH901318_CX_CTRL_SRC_BUS_SIZE_32_BITS | - COH901318_CX_CTRL_SRC_ADDR_INC_ENABLE | - COH901318_CX_CTRL_DST_BUS_SIZE_32_BITS | - COH901318_CX_CTRL_DST_ADDR_INC_DISABLE | - COH901318_CX_CTRL_MASTER_MODE_M1R_M2W | - COH901318_CX_CTRL_TCP_DISABLE | - COH901318_CX_CTRL_TC_IRQ_DISABLE | - COH901318_CX_CTRL_HSP_ENABLE | - COH901318_CX_CTRL_HSS_DISABLE | - COH901318_CX_CTRL_DDMA_LEGACY | - COH901318_CX_CTRL_PRDD_SOURCE, - .param.ctrl_lli = 0 | - COH901318_CX_CTRL_TC_ENABLE | - COH901318_CX_CTRL_BURST_COUNT_32_BYTES | - COH901318_CX_CTRL_SRC_BUS_SIZE_32_BITS | - COH901318_CX_CTRL_SRC_ADDR_INC_ENABLE | - COH901318_CX_CTRL_DST_BUS_SIZE_32_BITS | - COH901318_CX_CTRL_DST_ADDR_INC_DISABLE | - COH901318_CX_CTRL_MASTER_MODE_M1R_M2W | - COH901318_CX_CTRL_TCP_ENABLE | - COH901318_CX_CTRL_TC_IRQ_DISABLE | - COH901318_CX_CTRL_HSP_ENABLE | - COH901318_CX_CTRL_HSS_DISABLE | - COH901318_CX_CTRL_DDMA_LEGACY | - COH901318_CX_CTRL_PRDD_SOURCE, - .param.ctrl_lli_last = 0 | - COH901318_CX_CTRL_TC_ENABLE | - COH901318_CX_CTRL_BURST_COUNT_32_BYTES | - COH901318_CX_CTRL_SRC_BUS_SIZE_32_BITS | - COH901318_CX_CTRL_SRC_ADDR_INC_ENABLE | - COH901318_CX_CTRL_DST_BUS_SIZE_32_BITS | - COH901318_CX_CTRL_DST_ADDR_INC_DISABLE | - COH901318_CX_CTRL_MASTER_MODE_M1R_M2W | - COH901318_CX_CTRL_TCP_ENABLE | - COH901318_CX_CTRL_TC_IRQ_ENABLE | - COH901318_CX_CTRL_HSP_ENABLE | - COH901318_CX_CTRL_HSS_DISABLE | - COH901318_CX_CTRL_DDMA_LEGACY | - COH901318_CX_CTRL_PRDD_SOURCE, - }, - { - .number = U300_DMA_MSL_TX_2, - .name = "MSL TX 2", - .priority_high = 0, - .param.config = COH901318_CX_CFG_CH_DISABLE | - COH901318_CX_CFG_LCR_DISABLE | - COH901318_CX_CFG_TC_IRQ_ENABLE | - COH901318_CX_CFG_BE_IRQ_ENABLE, - .param.ctrl_lli_chained = 0 | - COH901318_CX_CTRL_TC_ENABLE | - COH901318_CX_CTRL_BURST_COUNT_32_BYTES | - COH901318_CX_CTRL_SRC_BUS_SIZE_32_BITS | - COH901318_CX_CTRL_SRC_ADDR_INC_ENABLE | - COH901318_CX_CTRL_DST_BUS_SIZE_32_BITS | - COH901318_CX_CTRL_DST_ADDR_INC_DISABLE | - COH901318_CX_CTRL_MASTER_MODE_M1R_M2W | - COH901318_CX_CTRL_TCP_DISABLE | - COH901318_CX_CTRL_TC_IRQ_DISABLE | - COH901318_CX_CTRL_HSP_ENABLE | - COH901318_CX_CTRL_HSS_DISABLE | - COH901318_CX_CTRL_DDMA_LEGACY | - COH901318_CX_CTRL_PRDD_SOURCE, - .param.ctrl_lli = 0 | - COH901318_CX_CTRL_TC_ENABLE | - COH901318_CX_CTRL_BURST_COUNT_32_BYTES | - COH901318_CX_CTRL_SRC_BUS_SIZE_32_BITS | - COH901318_CX_CTRL_SRC_ADDR_INC_ENABLE | - COH901318_CX_CTRL_DST_BUS_SIZE_32_BITS | - COH901318_CX_CTRL_DST_ADDR_INC_DISABLE | - COH901318_CX_CTRL_MASTER_MODE_M1R_M2W | - COH901318_CX_CTRL_TCP_ENABLE | - COH901318_CX_CTRL_TC_IRQ_DISABLE | - COH901318_CX_CTRL_HSP_ENABLE | - COH901318_CX_CTRL_HSS_DISABLE | - COH901318_CX_CTRL_DDMA_LEGACY | - COH901318_CX_CTRL_PRDD_SOURCE, - .param.ctrl_lli_last = 0 | - COH901318_CX_CTRL_TC_ENABLE | - COH901318_CX_CTRL_BURST_COUNT_32_BYTES | - COH901318_CX_CTRL_SRC_BUS_SIZE_32_BITS | - COH901318_CX_CTRL_SRC_ADDR_INC_ENABLE | - COH901318_CX_CTRL_DST_BUS_SIZE_32_BITS | - COH901318_CX_CTRL_DST_ADDR_INC_DISABLE | - COH901318_CX_CTRL_MASTER_MODE_M1R_M2W | - COH901318_CX_CTRL_TCP_ENABLE | - COH901318_CX_CTRL_TC_IRQ_ENABLE | - COH901318_CX_CTRL_HSP_ENABLE | - COH901318_CX_CTRL_HSS_DISABLE | - COH901318_CX_CTRL_DDMA_LEGACY | - COH901318_CX_CTRL_PRDD_SOURCE, - .desc_nbr_max = 10, - }, - { - .number = U300_DMA_MSL_TX_3, - .name = "MSL TX 3", - .priority_high = 0, - .param.config = COH901318_CX_CFG_CH_DISABLE | - COH901318_CX_CFG_LCR_DISABLE | - COH901318_CX_CFG_TC_IRQ_ENABLE | - COH901318_CX_CFG_BE_IRQ_ENABLE, - .param.ctrl_lli_chained = 0 | - COH901318_CX_CTRL_TC_ENABLE | - COH901318_CX_CTRL_BURST_COUNT_32_BYTES | - COH901318_CX_CTRL_SRC_BUS_SIZE_32_BITS | - COH901318_CX_CTRL_SRC_ADDR_INC_ENABLE | - COH901318_CX_CTRL_DST_BUS_SIZE_32_BITS | - COH901318_CX_CTRL_DST_ADDR_INC_DISABLE | - COH901318_CX_CTRL_MASTER_MODE_M1R_M2W | - COH901318_CX_CTRL_TCP_DISABLE | - COH901318_CX_CTRL_TC_IRQ_DISABLE | - COH901318_CX_CTRL_HSP_ENABLE | - COH901318_CX_CTRL_HSS_DISABLE | - COH901318_CX_CTRL_DDMA_LEGACY | - COH901318_CX_CTRL_PRDD_SOURCE, - .param.ctrl_lli = 0 | - COH901318_CX_CTRL_TC_ENABLE | - COH901318_CX_CTRL_BURST_COUNT_32_BYTES | - COH901318_CX_CTRL_SRC_BUS_SIZE_32_BITS | - COH901318_CX_CTRL_SRC_ADDR_INC_ENABLE | - COH901318_CX_CTRL_DST_BUS_SIZE_32_BITS | - COH901318_CX_CTRL_DST_ADDR_INC_DISABLE | - COH901318_CX_CTRL_MASTER_MODE_M1R_M2W | - COH901318_CX_CTRL_TCP_ENABLE | - COH901318_CX_CTRL_TC_IRQ_DISABLE | - COH901318_CX_CTRL_HSP_ENABLE | - COH901318_CX_CTRL_HSS_DISABLE | - COH901318_CX_CTRL_DDMA_LEGACY | - COH901318_CX_CTRL_PRDD_SOURCE, - .param.ctrl_lli_last = 0 | - COH901318_CX_CTRL_TC_ENABLE | - COH901318_CX_CTRL_BURST_COUNT_32_BYTES | - COH901318_CX_CTRL_SRC_BUS_SIZE_32_BITS | - COH901318_CX_CTRL_SRC_ADDR_INC_ENABLE | - COH901318_CX_CTRL_DST_BUS_SIZE_32_BITS | - COH901318_CX_CTRL_DST_ADDR_INC_DISABLE | - COH901318_CX_CTRL_MASTER_MODE_M1R_M2W | - COH901318_CX_CTRL_TCP_ENABLE | - COH901318_CX_CTRL_TC_IRQ_ENABLE | - COH901318_CX_CTRL_HSP_ENABLE | - COH901318_CX_CTRL_HSS_DISABLE | - COH901318_CX_CTRL_DDMA_LEGACY | - COH901318_CX_CTRL_PRDD_SOURCE, - }, - { - .number = U300_DMA_MSL_TX_4, - .name = "MSL TX 4", - .priority_high = 0, - .param.config = COH901318_CX_CFG_CH_DISABLE | - COH901318_CX_CFG_LCR_DISABLE | - COH901318_CX_CFG_TC_IRQ_ENABLE | - COH901318_CX_CFG_BE_IRQ_ENABLE, - .param.ctrl_lli_chained = 0 | - COH901318_CX_CTRL_TC_ENABLE | - COH901318_CX_CTRL_BURST_COUNT_32_BYTES | - COH901318_CX_CTRL_SRC_BUS_SIZE_32_BITS | - COH901318_CX_CTRL_SRC_ADDR_INC_ENABLE | - COH901318_CX_CTRL_DST_BUS_SIZE_32_BITS | - COH901318_CX_CTRL_DST_ADDR_INC_DISABLE | - COH901318_CX_CTRL_MASTER_MODE_M1R_M2W | - COH901318_CX_CTRL_TCP_DISABLE | - COH901318_CX_CTRL_TC_IRQ_DISABLE | - COH901318_CX_CTRL_HSP_ENABLE | - COH901318_CX_CTRL_HSS_DISABLE | - COH901318_CX_CTRL_DDMA_LEGACY | - COH901318_CX_CTRL_PRDD_SOURCE, - .param.ctrl_lli = 0 | - COH901318_CX_CTRL_TC_ENABLE | - COH901318_CX_CTRL_BURST_COUNT_32_BYTES | - COH901318_CX_CTRL_SRC_BUS_SIZE_32_BITS | - COH901318_CX_CTRL_SRC_ADDR_INC_ENABLE | - COH901318_CX_CTRL_DST_BUS_SIZE_32_BITS | - COH901318_CX_CTRL_DST_ADDR_INC_DISABLE | - COH901318_CX_CTRL_MASTER_MODE_M1R_M2W | - COH901318_CX_CTRL_TCP_ENABLE | - COH901318_CX_CTRL_TC_IRQ_DISABLE | - COH901318_CX_CTRL_HSP_ENABLE | - COH901318_CX_CTRL_HSS_DISABLE | - COH901318_CX_CTRL_DDMA_LEGACY | - COH901318_CX_CTRL_PRDD_SOURCE, - .param.ctrl_lli_last = 0 | - COH901318_CX_CTRL_TC_ENABLE | - COH901318_CX_CTRL_BURST_COUNT_32_BYTES | - COH901318_CX_CTRL_SRC_BUS_SIZE_32_BITS | - COH901318_CX_CTRL_SRC_ADDR_INC_ENABLE | - COH901318_CX_CTRL_DST_BUS_SIZE_32_BITS | - COH901318_CX_CTRL_DST_ADDR_INC_DISABLE | - COH901318_CX_CTRL_MASTER_MODE_M1R_M2W | - COH901318_CX_CTRL_TCP_ENABLE | - COH901318_CX_CTRL_TC_IRQ_ENABLE | - COH901318_CX_CTRL_HSP_ENABLE | - COH901318_CX_CTRL_HSS_DISABLE | - COH901318_CX_CTRL_DDMA_LEGACY | - COH901318_CX_CTRL_PRDD_SOURCE, - }, - { - .number = U300_DMA_MSL_TX_5, - .name = "MSL TX 5", - .priority_high = 0, - }, - { - .number = U300_DMA_MSL_TX_6, - .name = "MSL TX 6", - .priority_high = 0, - }, - { - .number = U300_DMA_MSL_RX_0, - .name = "MSL RX 0", - .priority_high = 0, - }, - { - .number = U300_DMA_MSL_RX_1, - .name = "MSL RX 1", - .priority_high = 0, - .param.config = COH901318_CX_CFG_CH_DISABLE | - COH901318_CX_CFG_LCR_DISABLE | - COH901318_CX_CFG_TC_IRQ_ENABLE | - COH901318_CX_CFG_BE_IRQ_ENABLE, - .param.ctrl_lli_chained = 0 | - COH901318_CX_CTRL_TC_ENABLE | - COH901318_CX_CTRL_BURST_COUNT_32_BYTES | - COH901318_CX_CTRL_SRC_BUS_SIZE_32_BITS | - COH901318_CX_CTRL_SRC_ADDR_INC_DISABLE | - COH901318_CX_CTRL_DST_BUS_SIZE_32_BITS | - COH901318_CX_CTRL_DST_ADDR_INC_ENABLE | - COH901318_CX_CTRL_MASTER_MODE_M2R_M1W | - COH901318_CX_CTRL_TCP_DISABLE | - COH901318_CX_CTRL_TC_IRQ_DISABLE | - COH901318_CX_CTRL_HSP_ENABLE | - COH901318_CX_CTRL_HSS_DISABLE | - COH901318_CX_CTRL_DDMA_DEMAND_DMA1 | - COH901318_CX_CTRL_PRDD_DEST, - .param.ctrl_lli = 0, - .param.ctrl_lli_last = 0 | - COH901318_CX_CTRL_TC_ENABLE | - COH901318_CX_CTRL_BURST_COUNT_32_BYTES | - COH901318_CX_CTRL_SRC_BUS_SIZE_32_BITS | - COH901318_CX_CTRL_SRC_ADDR_INC_DISABLE | - COH901318_CX_CTRL_DST_BUS_SIZE_32_BITS | - COH901318_CX_CTRL_DST_ADDR_INC_ENABLE | - COH901318_CX_CTRL_MASTER_MODE_M2R_M1W | - COH901318_CX_CTRL_TCP_DISABLE | - COH901318_CX_CTRL_TC_IRQ_ENABLE | - COH901318_CX_CTRL_HSP_ENABLE | - COH901318_CX_CTRL_HSS_DISABLE | - COH901318_CX_CTRL_DDMA_DEMAND_DMA1 | - COH901318_CX_CTRL_PRDD_DEST, - }, - { - .number = U300_DMA_MSL_RX_2, - .name = "MSL RX 2", - .priority_high = 0, - .param.config = COH901318_CX_CFG_CH_DISABLE | - COH901318_CX_CFG_LCR_DISABLE | - COH901318_CX_CFG_TC_IRQ_ENABLE | - COH901318_CX_CFG_BE_IRQ_ENABLE, - .param.ctrl_lli_chained = 0 | - COH901318_CX_CTRL_TC_ENABLE | - COH901318_CX_CTRL_BURST_COUNT_32_BYTES | - COH901318_CX_CTRL_SRC_BUS_SIZE_32_BITS | - COH901318_CX_CTRL_SRC_ADDR_INC_DISABLE | - COH901318_CX_CTRL_DST_BUS_SIZE_32_BITS | - COH901318_CX_CTRL_DST_ADDR_INC_ENABLE | - COH901318_CX_CTRL_MASTER_MODE_M2R_M1W | - COH901318_CX_CTRL_TCP_DISABLE | - COH901318_CX_CTRL_TC_IRQ_DISABLE | - COH901318_CX_CTRL_HSP_ENABLE | - COH901318_CX_CTRL_HSS_DISABLE | - COH901318_CX_CTRL_DDMA_DEMAND_DMA1 | - COH901318_CX_CTRL_PRDD_DEST, - .param.ctrl_lli = 0 | - COH901318_CX_CTRL_TC_ENABLE | - COH901318_CX_CTRL_BURST_COUNT_32_BYTES | - COH901318_CX_CTRL_SRC_BUS_SIZE_32_BITS | - COH901318_CX_CTRL_SRC_ADDR_INC_DISABLE | - COH901318_CX_CTRL_DST_BUS_SIZE_32_BITS | - COH901318_CX_CTRL_DST_ADDR_INC_ENABLE | - COH901318_CX_CTRL_MASTER_MODE_M2R_M1W | - COH901318_CX_CTRL_TCP_DISABLE | - COH901318_CX_CTRL_TC_IRQ_ENABLE | - COH901318_CX_CTRL_HSP_ENABLE | - COH901318_CX_CTRL_HSS_DISABLE | - COH901318_CX_CTRL_DDMA_DEMAND_DMA1 | - COH901318_CX_CTRL_PRDD_DEST, - .param.ctrl_lli_last = 0 | - COH901318_CX_CTRL_TC_ENABLE | - COH901318_CX_CTRL_BURST_COUNT_32_BYTES | - COH901318_CX_CTRL_SRC_BUS_SIZE_32_BITS | - COH901318_CX_CTRL_SRC_ADDR_INC_DISABLE | - COH901318_CX_CTRL_DST_BUS_SIZE_32_BITS | - COH901318_CX_CTRL_DST_ADDR_INC_ENABLE | - COH901318_CX_CTRL_MASTER_MODE_M2R_M1W | - COH901318_CX_CTRL_TCP_DISABLE | - COH901318_CX_CTRL_TC_IRQ_ENABLE | - COH901318_CX_CTRL_HSP_ENABLE | - COH901318_CX_CTRL_HSS_DISABLE | - COH901318_CX_CTRL_DDMA_DEMAND_DMA1 | - COH901318_CX_CTRL_PRDD_DEST, - }, - { - .number = U300_DMA_MSL_RX_3, - .name = "MSL RX 3", - .priority_high = 0, - .param.config = COH901318_CX_CFG_CH_DISABLE | - COH901318_CX_CFG_LCR_DISABLE | - COH901318_CX_CFG_TC_IRQ_ENABLE | - COH901318_CX_CFG_BE_IRQ_ENABLE, - .param.ctrl_lli_chained = 0 | - COH901318_CX_CTRL_TC_ENABLE | - COH901318_CX_CTRL_BURST_COUNT_32_BYTES | - COH901318_CX_CTRL_SRC_BUS_SIZE_32_BITS | - COH901318_CX_CTRL_SRC_ADDR_INC_DISABLE | - COH901318_CX_CTRL_DST_BUS_SIZE_32_BITS | - COH901318_CX_CTRL_DST_ADDR_INC_ENABLE | - COH901318_CX_CTRL_MASTER_MODE_M2R_M1W | - COH901318_CX_CTRL_TCP_DISABLE | - COH901318_CX_CTRL_TC_IRQ_DISABLE | - COH901318_CX_CTRL_HSP_ENABLE | - COH901318_CX_CTRL_HSS_DISABLE | - COH901318_CX_CTRL_DDMA_DEMAND_DMA1 | - COH901318_CX_CTRL_PRDD_DEST, - .param.ctrl_lli = 0 | - COH901318_CX_CTRL_TC_ENABLE | - COH901318_CX_CTRL_BURST_COUNT_32_BYTES | - COH901318_CX_CTRL_SRC_BUS_SIZE_32_BITS | - COH901318_CX_CTRL_SRC_ADDR_INC_DISABLE | - COH901318_CX_CTRL_DST_BUS_SIZE_32_BITS | - COH901318_CX_CTRL_DST_ADDR_INC_ENABLE | - COH901318_CX_CTRL_MASTER_MODE_M2R_M1W | - COH901318_CX_CTRL_TCP_DISABLE | - COH901318_CX_CTRL_TC_IRQ_ENABLE | - COH901318_CX_CTRL_HSP_ENABLE | - COH901318_CX_CTRL_HSS_DISABLE | - COH901318_CX_CTRL_DDMA_DEMAND_DMA1 | - COH901318_CX_CTRL_PRDD_DEST, - .param.ctrl_lli_last = 0 | - COH901318_CX_CTRL_TC_ENABLE | - COH901318_CX_CTRL_BURST_COUNT_32_BYTES | - COH901318_CX_CTRL_SRC_BUS_SIZE_32_BITS | - COH901318_CX_CTRL_SRC_ADDR_INC_DISABLE | - COH901318_CX_CTRL_DST_BUS_SIZE_32_BITS | - COH901318_CX_CTRL_DST_ADDR_INC_ENABLE | - COH901318_CX_CTRL_MASTER_MODE_M2R_M1W | - COH901318_CX_CTRL_TCP_DISABLE | - COH901318_CX_CTRL_TC_IRQ_ENABLE | - COH901318_CX_CTRL_HSP_ENABLE | - COH901318_CX_CTRL_HSS_DISABLE | - COH901318_CX_CTRL_DDMA_DEMAND_DMA1 | - COH901318_CX_CTRL_PRDD_DEST, - }, - { - .number = U300_DMA_MSL_RX_4, - .name = "MSL RX 4", - .priority_high = 0, - .param.config = COH901318_CX_CFG_CH_DISABLE | - COH901318_CX_CFG_LCR_DISABLE | - COH901318_CX_CFG_TC_IRQ_ENABLE | - COH901318_CX_CFG_BE_IRQ_ENABLE, - .param.ctrl_lli_chained = 0 | - COH901318_CX_CTRL_TC_ENABLE | - COH901318_CX_CTRL_BURST_COUNT_32_BYTES | - COH901318_CX_CTRL_SRC_BUS_SIZE_32_BITS | - COH901318_CX_CTRL_SRC_ADDR_INC_DISABLE | - COH901318_CX_CTRL_DST_BUS_SIZE_32_BITS | - COH901318_CX_CTRL_DST_ADDR_INC_ENABLE | - COH901318_CX_CTRL_MASTER_MODE_M2R_M1W | - COH901318_CX_CTRL_TCP_DISABLE | - COH901318_CX_CTRL_TC_IRQ_DISABLE | - COH901318_CX_CTRL_HSP_ENABLE | - COH901318_CX_CTRL_HSS_DISABLE | - COH901318_CX_CTRL_DDMA_DEMAND_DMA1 | - COH901318_CX_CTRL_PRDD_DEST, - .param.ctrl_lli = 0 | - COH901318_CX_CTRL_TC_ENABLE | - COH901318_CX_CTRL_BURST_COUNT_32_BYTES | - COH901318_CX_CTRL_SRC_BUS_SIZE_32_BITS | - COH901318_CX_CTRL_SRC_ADDR_INC_DISABLE | - COH901318_CX_CTRL_DST_BUS_SIZE_32_BITS | - COH901318_CX_CTRL_DST_ADDR_INC_ENABLE | - COH901318_CX_CTRL_MASTER_MODE_M2R_M1W | - COH901318_CX_CTRL_TCP_DISABLE | - COH901318_CX_CTRL_TC_IRQ_ENABLE | - COH901318_CX_CTRL_HSP_ENABLE | - COH901318_CX_CTRL_HSS_DISABLE | - COH901318_CX_CTRL_DDMA_DEMAND_DMA1 | - COH901318_CX_CTRL_PRDD_DEST, - .param.ctrl_lli_last = 0 | - COH901318_CX_CTRL_TC_ENABLE | - COH901318_CX_CTRL_BURST_COUNT_32_BYTES | - COH901318_CX_CTRL_SRC_BUS_SIZE_32_BITS | - COH901318_CX_CTRL_SRC_ADDR_INC_DISABLE | - COH901318_CX_CTRL_DST_BUS_SIZE_32_BITS | - COH901318_CX_CTRL_DST_ADDR_INC_ENABLE | - COH901318_CX_CTRL_MASTER_MODE_M2R_M1W | - COH901318_CX_CTRL_TCP_DISABLE | - COH901318_CX_CTRL_TC_IRQ_ENABLE | - COH901318_CX_CTRL_HSP_ENABLE | - COH901318_CX_CTRL_HSS_DISABLE | - COH901318_CX_CTRL_DDMA_DEMAND_DMA1 | - COH901318_CX_CTRL_PRDD_DEST, - }, - { - .number = U300_DMA_MSL_RX_5, - .name = "MSL RX 5", - .priority_high = 0, - .param.config = COH901318_CX_CFG_CH_DISABLE | - COH901318_CX_CFG_LCR_DISABLE | - COH901318_CX_CFG_TC_IRQ_ENABLE | - COH901318_CX_CFG_BE_IRQ_ENABLE, - .param.ctrl_lli_chained = 0 | - COH901318_CX_CTRL_TC_ENABLE | - COH901318_CX_CTRL_BURST_COUNT_32_BYTES | - COH901318_CX_CTRL_SRC_BUS_SIZE_32_BITS | - COH901318_CX_CTRL_SRC_ADDR_INC_DISABLE | - COH901318_CX_CTRL_DST_BUS_SIZE_32_BITS | - COH901318_CX_CTRL_DST_ADDR_INC_ENABLE | - COH901318_CX_CTRL_MASTER_MODE_M2R_M1W | - COH901318_CX_CTRL_TCP_DISABLE | - COH901318_CX_CTRL_TC_IRQ_DISABLE | - COH901318_CX_CTRL_HSP_ENABLE | - COH901318_CX_CTRL_HSS_DISABLE | - COH901318_CX_CTRL_DDMA_DEMAND_DMA1 | - COH901318_CX_CTRL_PRDD_DEST, - .param.ctrl_lli = 0 | - COH901318_CX_CTRL_TC_ENABLE | - COH901318_CX_CTRL_BURST_COUNT_32_BYTES | - COH901318_CX_CTRL_SRC_BUS_SIZE_32_BITS | - COH901318_CX_CTRL_SRC_ADDR_INC_DISABLE | - COH901318_CX_CTRL_DST_BUS_SIZE_32_BITS | - COH901318_CX_CTRL_DST_ADDR_INC_ENABLE | - COH901318_CX_CTRL_MASTER_MODE_M2R_M1W | - COH901318_CX_CTRL_TCP_DISABLE | - COH901318_CX_CTRL_TC_IRQ_ENABLE | - COH901318_CX_CTRL_HSP_ENABLE | - COH901318_CX_CTRL_HSS_DISABLE | - COH901318_CX_CTRL_DDMA_DEMAND_DMA1 | - COH901318_CX_CTRL_PRDD_DEST, - .param.ctrl_lli_last = 0 | - COH901318_CX_CTRL_TC_ENABLE | - COH901318_CX_CTRL_BURST_COUNT_32_BYTES | - COH901318_CX_CTRL_SRC_BUS_SIZE_32_BITS | - COH901318_CX_CTRL_SRC_ADDR_INC_DISABLE | - COH901318_CX_CTRL_DST_BUS_SIZE_32_BITS | - COH901318_CX_CTRL_DST_ADDR_INC_ENABLE | - COH901318_CX_CTRL_MASTER_MODE_M2R_M1W | - COH901318_CX_CTRL_TCP_DISABLE | - COH901318_CX_CTRL_TC_IRQ_ENABLE | - COH901318_CX_CTRL_HSP_ENABLE | - COH901318_CX_CTRL_HSS_DISABLE | - COH901318_CX_CTRL_DDMA_DEMAND_DMA1 | - COH901318_CX_CTRL_PRDD_DEST, - }, - { - .number = U300_DMA_MSL_RX_6, - .name = "MSL RX 6", - .priority_high = 0, - }, - /* - * Don't set up device address, burst count or size of src - * or dst bus for this peripheral - handled by PrimeCell - * DMA extension. - */ - { - .number = U300_DMA_MMCSD_RX_TX, - .name = "MMCSD RX TX", - .priority_high = 0, - .param.config = COH901318_CX_CFG_CH_DISABLE | - COH901318_CX_CFG_LCR_DISABLE | - COH901318_CX_CFG_TC_IRQ_ENABLE | - COH901318_CX_CFG_BE_IRQ_ENABLE, - .param.ctrl_lli_chained = 0 | - COH901318_CX_CTRL_TC_ENABLE | - COH901318_CX_CTRL_MASTER_MODE_M1RW | - COH901318_CX_CTRL_TCP_ENABLE | - COH901318_CX_CTRL_TC_IRQ_DISABLE | - COH901318_CX_CTRL_HSP_ENABLE | - COH901318_CX_CTRL_HSS_DISABLE | - COH901318_CX_CTRL_DDMA_LEGACY, - .param.ctrl_lli = 0 | - COH901318_CX_CTRL_TC_ENABLE | - COH901318_CX_CTRL_MASTER_MODE_M1RW | - COH901318_CX_CTRL_TCP_ENABLE | - COH901318_CX_CTRL_TC_IRQ_DISABLE | - COH901318_CX_CTRL_HSP_ENABLE | - COH901318_CX_CTRL_HSS_DISABLE | - COH901318_CX_CTRL_DDMA_LEGACY, - .param.ctrl_lli_last = 0 | - COH901318_CX_CTRL_TC_ENABLE | - COH901318_CX_CTRL_MASTER_MODE_M1RW | - COH901318_CX_CTRL_TCP_DISABLE | - COH901318_CX_CTRL_TC_IRQ_ENABLE | - COH901318_CX_CTRL_HSP_ENABLE | - COH901318_CX_CTRL_HSS_DISABLE | - COH901318_CX_CTRL_DDMA_LEGACY, - - }, - { - .number = U300_DMA_MSPRO_TX, - .name = "MSPRO TX", - .priority_high = 0, - }, - { - .number = U300_DMA_MSPRO_RX, - .name = "MSPRO RX", - .priority_high = 0, - }, - /* - * Don't set up device address, burst count or size of src - * or dst bus for this peripheral - handled by PrimeCell - * DMA extension. - */ - { - .number = U300_DMA_UART0_TX, - .name = "UART0 TX", - .priority_high = 0, - .param.config = COH901318_CX_CFG_CH_DISABLE | - COH901318_CX_CFG_LCR_DISABLE | - COH901318_CX_CFG_TC_IRQ_ENABLE | - COH901318_CX_CFG_BE_IRQ_ENABLE, - .param.ctrl_lli_chained = 0 | - COH901318_CX_CTRL_TC_ENABLE | - COH901318_CX_CTRL_MASTER_MODE_M1RW | - COH901318_CX_CTRL_TCP_ENABLE | - COH901318_CX_CTRL_TC_IRQ_DISABLE | - COH901318_CX_CTRL_HSP_ENABLE | - COH901318_CX_CTRL_HSS_DISABLE | - COH901318_CX_CTRL_DDMA_LEGACY, - .param.ctrl_lli = 0 | - COH901318_CX_CTRL_TC_ENABLE | - COH901318_CX_CTRL_MASTER_MODE_M1RW | - COH901318_CX_CTRL_TCP_ENABLE | - COH901318_CX_CTRL_TC_IRQ_ENABLE | - COH901318_CX_CTRL_HSP_ENABLE | - COH901318_CX_CTRL_HSS_DISABLE | - COH901318_CX_CTRL_DDMA_LEGACY, - .param.ctrl_lli_last = 0 | - COH901318_CX_CTRL_TC_ENABLE | - COH901318_CX_CTRL_MASTER_MODE_M1RW | - COH901318_CX_CTRL_TCP_ENABLE | - COH901318_CX_CTRL_TC_IRQ_ENABLE | - COH901318_CX_CTRL_HSP_ENABLE | - COH901318_CX_CTRL_HSS_DISABLE | - COH901318_CX_CTRL_DDMA_LEGACY, - }, - { - .number = U300_DMA_UART0_RX, - .name = "UART0 RX", - .priority_high = 0, - .param.config = COH901318_CX_CFG_CH_DISABLE | - COH901318_CX_CFG_LCR_DISABLE | - COH901318_CX_CFG_TC_IRQ_ENABLE | - COH901318_CX_CFG_BE_IRQ_ENABLE, - .param.ctrl_lli_chained = 0 | - COH901318_CX_CTRL_TC_ENABLE | - COH901318_CX_CTRL_MASTER_MODE_M1RW | - COH901318_CX_CTRL_TCP_ENABLE | - COH901318_CX_CTRL_TC_IRQ_DISABLE | - COH901318_CX_CTRL_HSP_ENABLE | - COH901318_CX_CTRL_HSS_DISABLE | - COH901318_CX_CTRL_DDMA_LEGACY, - .param.ctrl_lli = 0 | - COH901318_CX_CTRL_TC_ENABLE | - COH901318_CX_CTRL_MASTER_MODE_M1RW | - COH901318_CX_CTRL_TCP_ENABLE | - COH901318_CX_CTRL_TC_IRQ_ENABLE | - COH901318_CX_CTRL_HSP_ENABLE | - COH901318_CX_CTRL_HSS_DISABLE | - COH901318_CX_CTRL_DDMA_LEGACY, - .param.ctrl_lli_last = 0 | - COH901318_CX_CTRL_TC_ENABLE | - COH901318_CX_CTRL_MASTER_MODE_M1RW | - COH901318_CX_CTRL_TCP_ENABLE | - COH901318_CX_CTRL_TC_IRQ_ENABLE | - COH901318_CX_CTRL_HSP_ENABLE | - COH901318_CX_CTRL_HSS_DISABLE | - COH901318_CX_CTRL_DDMA_LEGACY, - }, - { - .number = U300_DMA_APEX_TX, - .name = "APEX TX", - .priority_high = 0, - }, - { - .number = U300_DMA_APEX_RX, - .name = "APEX RX", - .priority_high = 0, - }, - { - .number = U300_DMA_PCM_I2S0_TX, - .name = "PCM I2S0 TX", - .priority_high = 1, - .param.config = COH901318_CX_CFG_CH_DISABLE | - COH901318_CX_CFG_LCR_DISABLE | - COH901318_CX_CFG_TC_IRQ_ENABLE | - COH901318_CX_CFG_BE_IRQ_ENABLE, - .param.ctrl_lli_chained = 0 | - COH901318_CX_CTRL_TC_ENABLE | - COH901318_CX_CTRL_BURST_COUNT_16_BYTES | - COH901318_CX_CTRL_SRC_BUS_SIZE_32_BITS | - COH901318_CX_CTRL_SRC_ADDR_INC_ENABLE | - COH901318_CX_CTRL_DST_BUS_SIZE_32_BITS | - COH901318_CX_CTRL_DST_ADDR_INC_DISABLE | - COH901318_CX_CTRL_MASTER_MODE_M1RW | - COH901318_CX_CTRL_TCP_DISABLE | - COH901318_CX_CTRL_TC_IRQ_DISABLE | - COH901318_CX_CTRL_HSP_ENABLE | - COH901318_CX_CTRL_HSS_DISABLE | - COH901318_CX_CTRL_DDMA_LEGACY | - COH901318_CX_CTRL_PRDD_SOURCE, - .param.ctrl_lli = 0 | - COH901318_CX_CTRL_TC_ENABLE | - COH901318_CX_CTRL_BURST_COUNT_16_BYTES | - COH901318_CX_CTRL_SRC_BUS_SIZE_32_BITS | - COH901318_CX_CTRL_SRC_ADDR_INC_ENABLE | - COH901318_CX_CTRL_DST_BUS_SIZE_32_BITS | - COH901318_CX_CTRL_DST_ADDR_INC_DISABLE | - COH901318_CX_CTRL_MASTER_MODE_M1RW | - COH901318_CX_CTRL_TCP_ENABLE | - COH901318_CX_CTRL_TC_IRQ_DISABLE | - COH901318_CX_CTRL_HSP_ENABLE | - COH901318_CX_CTRL_HSS_DISABLE | - COH901318_CX_CTRL_DDMA_LEGACY | - COH901318_CX_CTRL_PRDD_SOURCE, - .param.ctrl_lli_last = 0 | - COH901318_CX_CTRL_TC_ENABLE | - COH901318_CX_CTRL_BURST_COUNT_16_BYTES | - COH901318_CX_CTRL_SRC_BUS_SIZE_32_BITS | - COH901318_CX_CTRL_SRC_ADDR_INC_ENABLE | - COH901318_CX_CTRL_DST_BUS_SIZE_32_BITS | - COH901318_CX_CTRL_DST_ADDR_INC_DISABLE | - COH901318_CX_CTRL_MASTER_MODE_M1RW | - COH901318_CX_CTRL_TCP_ENABLE | - COH901318_CX_CTRL_TC_IRQ_DISABLE | - COH901318_CX_CTRL_HSP_ENABLE | - COH901318_CX_CTRL_HSS_DISABLE | - COH901318_CX_CTRL_DDMA_LEGACY | - COH901318_CX_CTRL_PRDD_SOURCE, - }, - { - .number = U300_DMA_PCM_I2S0_RX, - .name = "PCM I2S0 RX", - .priority_high = 1, - .param.config = COH901318_CX_CFG_CH_DISABLE | - COH901318_CX_CFG_LCR_DISABLE | - COH901318_CX_CFG_TC_IRQ_ENABLE | - COH901318_CX_CFG_BE_IRQ_ENABLE, - .param.ctrl_lli_chained = 0 | - COH901318_CX_CTRL_TC_ENABLE | - COH901318_CX_CTRL_BURST_COUNT_16_BYTES | - COH901318_CX_CTRL_SRC_BUS_SIZE_32_BITS | - COH901318_CX_CTRL_SRC_ADDR_INC_DISABLE | - COH901318_CX_CTRL_DST_BUS_SIZE_32_BITS | - COH901318_CX_CTRL_DST_ADDR_INC_ENABLE | - COH901318_CX_CTRL_MASTER_MODE_M1RW | - COH901318_CX_CTRL_TCP_DISABLE | - COH901318_CX_CTRL_TC_IRQ_DISABLE | - COH901318_CX_CTRL_HSP_ENABLE | - COH901318_CX_CTRL_HSS_DISABLE | - COH901318_CX_CTRL_DDMA_LEGACY | - COH901318_CX_CTRL_PRDD_DEST, - .param.ctrl_lli = 0 | - COH901318_CX_CTRL_TC_ENABLE | - COH901318_CX_CTRL_BURST_COUNT_16_BYTES | - COH901318_CX_CTRL_SRC_BUS_SIZE_32_BITS | - COH901318_CX_CTRL_SRC_ADDR_INC_DISABLE | - COH901318_CX_CTRL_DST_BUS_SIZE_32_BITS | - COH901318_CX_CTRL_DST_ADDR_INC_ENABLE | - COH901318_CX_CTRL_MASTER_MODE_M1RW | - COH901318_CX_CTRL_TCP_ENABLE | - COH901318_CX_CTRL_TC_IRQ_DISABLE | - COH901318_CX_CTRL_HSP_ENABLE | - COH901318_CX_CTRL_HSS_DISABLE | - COH901318_CX_CTRL_DDMA_LEGACY | - COH901318_CX_CTRL_PRDD_DEST, - .param.ctrl_lli_last = 0 | - COH901318_CX_CTRL_TC_ENABLE | - COH901318_CX_CTRL_BURST_COUNT_16_BYTES | - COH901318_CX_CTRL_SRC_BUS_SIZE_32_BITS | - COH901318_CX_CTRL_SRC_ADDR_INC_DISABLE | - COH901318_CX_CTRL_DST_BUS_SIZE_32_BITS | - COH901318_CX_CTRL_DST_ADDR_INC_ENABLE | - COH901318_CX_CTRL_MASTER_MODE_M1RW | - COH901318_CX_CTRL_TCP_ENABLE | - COH901318_CX_CTRL_TC_IRQ_ENABLE | - COH901318_CX_CTRL_HSP_ENABLE | - COH901318_CX_CTRL_HSS_DISABLE | - COH901318_CX_CTRL_DDMA_LEGACY | - COH901318_CX_CTRL_PRDD_DEST, - }, - { - .number = U300_DMA_PCM_I2S1_TX, - .name = "PCM I2S1 TX", - .priority_high = 1, - .param.config = COH901318_CX_CFG_CH_DISABLE | - COH901318_CX_CFG_LCR_DISABLE | - COH901318_CX_CFG_TC_IRQ_ENABLE | - COH901318_CX_CFG_BE_IRQ_ENABLE, - .param.ctrl_lli_chained = 0 | - COH901318_CX_CTRL_TC_ENABLE | - COH901318_CX_CTRL_BURST_COUNT_16_BYTES | - COH901318_CX_CTRL_SRC_BUS_SIZE_32_BITS | - COH901318_CX_CTRL_SRC_ADDR_INC_ENABLE | - COH901318_CX_CTRL_DST_BUS_SIZE_32_BITS | - COH901318_CX_CTRL_DST_ADDR_INC_DISABLE | - COH901318_CX_CTRL_MASTER_MODE_M1RW | - COH901318_CX_CTRL_TCP_DISABLE | - COH901318_CX_CTRL_TC_IRQ_DISABLE | - COH901318_CX_CTRL_HSP_ENABLE | - COH901318_CX_CTRL_HSS_DISABLE | - COH901318_CX_CTRL_DDMA_LEGACY | - COH901318_CX_CTRL_PRDD_SOURCE, - .param.ctrl_lli = 0 | - COH901318_CX_CTRL_TC_ENABLE | - COH901318_CX_CTRL_BURST_COUNT_16_BYTES | - COH901318_CX_CTRL_SRC_BUS_SIZE_32_BITS | - COH901318_CX_CTRL_SRC_ADDR_INC_ENABLE | - COH901318_CX_CTRL_DST_BUS_SIZE_32_BITS | - COH901318_CX_CTRL_DST_ADDR_INC_DISABLE | - COH901318_CX_CTRL_MASTER_MODE_M1RW | - COH901318_CX_CTRL_TCP_ENABLE | - COH901318_CX_CTRL_TC_IRQ_DISABLE | - COH901318_CX_CTRL_HSP_ENABLE | - COH901318_CX_CTRL_HSS_DISABLE | - COH901318_CX_CTRL_DDMA_LEGACY | - COH901318_CX_CTRL_PRDD_SOURCE, - .param.ctrl_lli_last = 0 | - COH901318_CX_CTRL_TC_ENABLE | - COH901318_CX_CTRL_BURST_COUNT_16_BYTES | - COH901318_CX_CTRL_SRC_BUS_SIZE_32_BITS | - COH901318_CX_CTRL_SRC_ADDR_INC_ENABLE | - COH901318_CX_CTRL_DST_BUS_SIZE_32_BITS | - COH901318_CX_CTRL_DST_ADDR_INC_DISABLE | - COH901318_CX_CTRL_MASTER_MODE_M1RW | - COH901318_CX_CTRL_TCP_ENABLE | - COH901318_CX_CTRL_TC_IRQ_ENABLE | - COH901318_CX_CTRL_HSP_ENABLE | - COH901318_CX_CTRL_HSS_DISABLE | - COH901318_CX_CTRL_DDMA_LEGACY | - COH901318_CX_CTRL_PRDD_SOURCE, - }, - { - .number = U300_DMA_PCM_I2S1_RX, - .name = "PCM I2S1 RX", - .priority_high = 1, - .param.config = COH901318_CX_CFG_CH_DISABLE | - COH901318_CX_CFG_LCR_DISABLE | - COH901318_CX_CFG_TC_IRQ_ENABLE | - COH901318_CX_CFG_BE_IRQ_ENABLE, - .param.ctrl_lli_chained = 0 | - COH901318_CX_CTRL_TC_ENABLE | - COH901318_CX_CTRL_BURST_COUNT_16_BYTES | - COH901318_CX_CTRL_SRC_BUS_SIZE_32_BITS | - COH901318_CX_CTRL_SRC_ADDR_INC_DISABLE | - COH901318_CX_CTRL_DST_BUS_SIZE_32_BITS | - COH901318_CX_CTRL_DST_ADDR_INC_ENABLE | - COH901318_CX_CTRL_MASTER_MODE_M1RW | - COH901318_CX_CTRL_TCP_DISABLE | - COH901318_CX_CTRL_TC_IRQ_DISABLE | - COH901318_CX_CTRL_HSP_ENABLE | - COH901318_CX_CTRL_HSS_DISABLE | - COH901318_CX_CTRL_DDMA_LEGACY | - COH901318_CX_CTRL_PRDD_DEST, - .param.ctrl_lli = 0 | - COH901318_CX_CTRL_TC_ENABLE | - COH901318_CX_CTRL_BURST_COUNT_16_BYTES | - COH901318_CX_CTRL_SRC_BUS_SIZE_32_BITS | - COH901318_CX_CTRL_SRC_ADDR_INC_DISABLE | - COH901318_CX_CTRL_DST_BUS_SIZE_32_BITS | - COH901318_CX_CTRL_DST_ADDR_INC_ENABLE | - COH901318_CX_CTRL_MASTER_MODE_M1RW | - COH901318_CX_CTRL_TCP_ENABLE | - COH901318_CX_CTRL_TC_IRQ_DISABLE | - COH901318_CX_CTRL_HSP_ENABLE | - COH901318_CX_CTRL_HSS_DISABLE | - COH901318_CX_CTRL_DDMA_LEGACY | - COH901318_CX_CTRL_PRDD_DEST, - .param.ctrl_lli_last = 0 | - COH901318_CX_CTRL_TC_ENABLE | - COH901318_CX_CTRL_BURST_COUNT_16_BYTES | - COH901318_CX_CTRL_SRC_BUS_SIZE_32_BITS | - COH901318_CX_CTRL_SRC_ADDR_INC_DISABLE | - COH901318_CX_CTRL_DST_BUS_SIZE_32_BITS | - COH901318_CX_CTRL_DST_ADDR_INC_ENABLE | - COH901318_CX_CTRL_MASTER_MODE_M1RW | - COH901318_CX_CTRL_TCP_ENABLE | - COH901318_CX_CTRL_TC_IRQ_ENABLE | - COH901318_CX_CTRL_HSP_ENABLE | - COH901318_CX_CTRL_HSS_DISABLE | - COH901318_CX_CTRL_DDMA_LEGACY | - COH901318_CX_CTRL_PRDD_DEST, - }, - { - .number = U300_DMA_XGAM_CDI, - .name = "XGAM CDI", - .priority_high = 0, - }, - { - .number = U300_DMA_XGAM_PDI, - .name = "XGAM PDI", - .priority_high = 0, - }, - /* - * Don't set up device address, burst count or size of src - * or dst bus for this peripheral - handled by PrimeCell - * DMA extension. - */ - { - .number = U300_DMA_SPI_TX, - .name = "SPI TX", - .priority_high = 0, - .param.config = COH901318_CX_CFG_CH_DISABLE | - COH901318_CX_CFG_LCR_DISABLE | - COH901318_CX_CFG_TC_IRQ_ENABLE | - COH901318_CX_CFG_BE_IRQ_ENABLE, - .param.ctrl_lli_chained = 0 | - COH901318_CX_CTRL_TC_ENABLE | - COH901318_CX_CTRL_MASTER_MODE_M1RW | - COH901318_CX_CTRL_TCP_DISABLE | - COH901318_CX_CTRL_TC_IRQ_DISABLE | - COH901318_CX_CTRL_HSP_ENABLE | - COH901318_CX_CTRL_HSS_DISABLE | - COH901318_CX_CTRL_DDMA_LEGACY, - .param.ctrl_lli = 0 | - COH901318_CX_CTRL_TC_ENABLE | - COH901318_CX_CTRL_MASTER_MODE_M1RW | - COH901318_CX_CTRL_TCP_DISABLE | - COH901318_CX_CTRL_TC_IRQ_ENABLE | - COH901318_CX_CTRL_HSP_ENABLE | - COH901318_CX_CTRL_HSS_DISABLE | - COH901318_CX_CTRL_DDMA_LEGACY, - .param.ctrl_lli_last = 0 | - COH901318_CX_CTRL_TC_ENABLE | - COH901318_CX_CTRL_MASTER_MODE_M1RW | - COH901318_CX_CTRL_TCP_DISABLE | - COH901318_CX_CTRL_TC_IRQ_ENABLE | - COH901318_CX_CTRL_HSP_ENABLE | - COH901318_CX_CTRL_HSS_DISABLE | - COH901318_CX_CTRL_DDMA_LEGACY, - }, - { - .number = U300_DMA_SPI_RX, - .name = "SPI RX", - .priority_high = 0, - .param.config = COH901318_CX_CFG_CH_DISABLE | - COH901318_CX_CFG_LCR_DISABLE | - COH901318_CX_CFG_TC_IRQ_ENABLE | - COH901318_CX_CFG_BE_IRQ_ENABLE, - .param.ctrl_lli_chained = 0 | - COH901318_CX_CTRL_TC_ENABLE | - COH901318_CX_CTRL_MASTER_MODE_M1RW | - COH901318_CX_CTRL_TCP_DISABLE | - COH901318_CX_CTRL_TC_IRQ_DISABLE | - COH901318_CX_CTRL_HSP_ENABLE | - COH901318_CX_CTRL_HSS_DISABLE | - COH901318_CX_CTRL_DDMA_LEGACY, - .param.ctrl_lli = 0 | - COH901318_CX_CTRL_TC_ENABLE | - COH901318_CX_CTRL_MASTER_MODE_M1RW | - COH901318_CX_CTRL_TCP_DISABLE | - COH901318_CX_CTRL_TC_IRQ_ENABLE | - COH901318_CX_CTRL_HSP_ENABLE | - COH901318_CX_CTRL_HSS_DISABLE | - COH901318_CX_CTRL_DDMA_LEGACY, - .param.ctrl_lli_last = 0 | - COH901318_CX_CTRL_TC_ENABLE | - COH901318_CX_CTRL_MASTER_MODE_M1RW | - COH901318_CX_CTRL_TCP_DISABLE | - COH901318_CX_CTRL_TC_IRQ_ENABLE | - COH901318_CX_CTRL_HSP_ENABLE | - COH901318_CX_CTRL_HSS_DISABLE | - COH901318_CX_CTRL_DDMA_LEGACY, - - }, - { - .number = U300_DMA_GENERAL_PURPOSE_0, - .name = "GENERAL 00", - .priority_high = 0, - - .param.config = flags_memcpy_config, - .param.ctrl_lli_chained = flags_memcpy_lli_chained, - .param.ctrl_lli = flags_memcpy_lli, - .param.ctrl_lli_last = flags_memcpy_lli_last, - }, - { - .number = U300_DMA_GENERAL_PURPOSE_1, - .name = "GENERAL 01", - .priority_high = 0, - - .param.config = flags_memcpy_config, - .param.ctrl_lli_chained = flags_memcpy_lli_chained, - .param.ctrl_lli = flags_memcpy_lli, - .param.ctrl_lli_last = flags_memcpy_lli_last, - }, - { - .number = U300_DMA_GENERAL_PURPOSE_2, - .name = "GENERAL 02", - .priority_high = 0, - - .param.config = flags_memcpy_config, - .param.ctrl_lli_chained = flags_memcpy_lli_chained, - .param.ctrl_lli = flags_memcpy_lli, - .param.ctrl_lli_last = flags_memcpy_lli_last, - }, - { - .number = U300_DMA_GENERAL_PURPOSE_3, - .name = "GENERAL 03", - .priority_high = 0, - - .param.config = flags_memcpy_config, - .param.ctrl_lli_chained = flags_memcpy_lli_chained, - .param.ctrl_lli = flags_memcpy_lli, - .param.ctrl_lli_last = flags_memcpy_lli_last, - }, - { - .number = U300_DMA_GENERAL_PURPOSE_4, - .name = "GENERAL 04", - .priority_high = 0, - - .param.config = flags_memcpy_config, - .param.ctrl_lli_chained = flags_memcpy_lli_chained, - .param.ctrl_lli = flags_memcpy_lli, - .param.ctrl_lli_last = flags_memcpy_lli_last, - }, - { - .number = U300_DMA_GENERAL_PURPOSE_5, - .name = "GENERAL 05", - .priority_high = 0, - - .param.config = flags_memcpy_config, - .param.ctrl_lli_chained = flags_memcpy_lli_chained, - .param.ctrl_lli = flags_memcpy_lli, - .param.ctrl_lli_last = flags_memcpy_lli_last, - }, - { - .number = U300_DMA_GENERAL_PURPOSE_6, - .name = "GENERAL 06", - .priority_high = 0, - - .param.config = flags_memcpy_config, - .param.ctrl_lli_chained = flags_memcpy_lli_chained, - .param.ctrl_lli = flags_memcpy_lli, - .param.ctrl_lli_last = flags_memcpy_lli_last, - }, - { - .number = U300_DMA_GENERAL_PURPOSE_7, - .name = "GENERAL 07", - .priority_high = 0, - - .param.config = flags_memcpy_config, - .param.ctrl_lli_chained = flags_memcpy_lli_chained, - .param.ctrl_lli = flags_memcpy_lli, - .param.ctrl_lli_last = flags_memcpy_lli_last, - }, - { - .number = U300_DMA_GENERAL_PURPOSE_8, - .name = "GENERAL 08", - .priority_high = 0, - - .param.config = flags_memcpy_config, - .param.ctrl_lli_chained = flags_memcpy_lli_chained, - .param.ctrl_lli = flags_memcpy_lli, - .param.ctrl_lli_last = flags_memcpy_lli_last, - }, - { - .number = U300_DMA_UART1_TX, - .name = "UART1 TX", - .priority_high = 0, - }, - { - .number = U300_DMA_UART1_RX, - .name = "UART1 RX", - .priority_high = 0, - } -}; - -#define COHC_2_DEV(cohc) (&cohc->chan.dev->device) - -#ifdef VERBOSE_DEBUG -#define COH_DBG(x) ({ if (1) x; 0; }) -#else -#define COH_DBG(x) ({ if (0) x; 0; }) -#endif - -struct coh901318_desc { - struct dma_async_tx_descriptor desc; - struct list_head node; - struct scatterlist *sg; - unsigned int sg_len; - struct coh901318_lli *lli; - enum dma_transfer_direction dir; - unsigned long flags; - u32 head_config; - u32 head_ctrl; -}; - -struct coh901318_base { - struct device *dev; - void __iomem *virtbase; - unsigned int irq; - struct coh901318_pool pool; - struct powersave pm; - struct dma_device dma_slave; - struct dma_device dma_memcpy; - struct coh901318_chan *chans; -}; - -struct coh901318_chan { - spinlock_t lock; - int allocated; - int id; - int stopped; - - struct work_struct free_work; - struct dma_chan chan; - - struct tasklet_struct tasklet; - - struct list_head active; - struct list_head queue; - struct list_head free; - - unsigned long nbr_active_done; - unsigned long busy; - - struct dma_slave_config config; - u32 addr; - u32 ctrl; - - struct coh901318_base *base; -}; - -static void coh901318_list_print(struct coh901318_chan *cohc, - struct coh901318_lli *lli) -{ - struct coh901318_lli *l = lli; - int i = 0; - - while (l) { - dev_vdbg(COHC_2_DEV(cohc), "i %d, lli %p, ctrl 0x%x, src %pad" - ", dst %pad, link %pad virt_link_addr 0x%p\n", - i, l, l->control, &l->src_addr, &l->dst_addr, - &l->link_addr, l->virt_link_addr); - i++; - l = l->virt_link_addr; - } -} - -#ifdef CONFIG_DEBUG_FS - -#define COH901318_DEBUGFS_ASSIGN(x, y) (x = y) - -static struct coh901318_base *debugfs_dma_base; -static struct dentry *dma_dentry; - -static ssize_t coh901318_debugfs_read(struct file *file, char __user *buf, - size_t count, loff_t *f_pos) -{ - u64 started_channels = debugfs_dma_base->pm.started_channels; - int pool_count = debugfs_dma_base->pool.debugfs_pool_counter; - char *dev_buf; - char *tmp; - int ret; - int i; - - dev_buf = kmalloc(4*1024, GFP_KERNEL); - if (dev_buf == NULL) - return -ENOMEM; - tmp = dev_buf; - - tmp += sprintf(tmp, "DMA -- enabled dma channels\n"); - - for (i = 0; i < U300_DMA_CHANNELS; i++) { - if (started_channels & (1ULL << i)) - tmp += sprintf(tmp, "channel %d\n", i); - } - - tmp += sprintf(tmp, "Pool alloc nbr %d\n", pool_count); - - ret = simple_read_from_buffer(buf, count, f_pos, dev_buf, - tmp - dev_buf); - kfree(dev_buf); - return ret; -} - -static const struct file_operations coh901318_debugfs_status_operations = { - .open = simple_open, - .read = coh901318_debugfs_read, - .llseek = default_llseek, -}; - - -static int __init init_coh901318_debugfs(void) -{ - - dma_dentry = debugfs_create_dir("dma", NULL); - - debugfs_create_file("status", S_IFREG | S_IRUGO, dma_dentry, NULL, - &coh901318_debugfs_status_operations); - return 0; -} - -static void __exit exit_coh901318_debugfs(void) -{ - debugfs_remove_recursive(dma_dentry); -} - -module_init(init_coh901318_debugfs); -module_exit(exit_coh901318_debugfs); -#else - -#define COH901318_DEBUGFS_ASSIGN(x, y) - -#endif /* CONFIG_DEBUG_FS */ - -static inline struct coh901318_chan *to_coh901318_chan(struct dma_chan *chan) -{ - return container_of(chan, struct coh901318_chan, chan); -} - -static int coh901318_dma_set_runtimeconfig(struct dma_chan *chan, - struct dma_slave_config *config, - enum dma_transfer_direction direction); - -static inline const struct coh901318_params * -cohc_chan_param(struct coh901318_chan *cohc) -{ - return &chan_config[cohc->id].param; -} - -static inline const struct coh_dma_channel * -cohc_chan_conf(struct coh901318_chan *cohc) -{ - return &chan_config[cohc->id]; -} - -static void enable_powersave(struct coh901318_chan *cohc) -{ - unsigned long flags; - struct powersave *pm = &cohc->base->pm; - - spin_lock_irqsave(&pm->lock, flags); - - pm->started_channels &= ~(1ULL << cohc->id); - - spin_unlock_irqrestore(&pm->lock, flags); -} -static void disable_powersave(struct coh901318_chan *cohc) -{ - unsigned long flags; - struct powersave *pm = &cohc->base->pm; - - spin_lock_irqsave(&pm->lock, flags); - - pm->started_channels |= (1ULL << cohc->id); - - spin_unlock_irqrestore(&pm->lock, flags); -} - -static inline int coh901318_set_ctrl(struct coh901318_chan *cohc, u32 control) -{ - int channel = cohc->id; - void __iomem *virtbase = cohc->base->virtbase; - - writel(control, - virtbase + COH901318_CX_CTRL + - COH901318_CX_CTRL_SPACING * channel); - return 0; -} - -static inline int coh901318_set_conf(struct coh901318_chan *cohc, u32 conf) -{ - int channel = cohc->id; - void __iomem *virtbase = cohc->base->virtbase; - - writel(conf, - virtbase + COH901318_CX_CFG + - COH901318_CX_CFG_SPACING*channel); - return 0; -} - - -static int coh901318_start(struct coh901318_chan *cohc) -{ - u32 val; - int channel = cohc->id; - void __iomem *virtbase = cohc->base->virtbase; - - disable_powersave(cohc); - - val = readl(virtbase + COH901318_CX_CFG + - COH901318_CX_CFG_SPACING * channel); - - /* Enable channel */ - val |= COH901318_CX_CFG_CH_ENABLE; - writel(val, virtbase + COH901318_CX_CFG + - COH901318_CX_CFG_SPACING * channel); - - return 0; -} - -static int coh901318_prep_linked_list(struct coh901318_chan *cohc, - struct coh901318_lli *lli) -{ - int channel = cohc->id; - void __iomem *virtbase = cohc->base->virtbase; - - BUG_ON(readl(virtbase + COH901318_CX_STAT + - COH901318_CX_STAT_SPACING*channel) & - COH901318_CX_STAT_ACTIVE); - - writel(lli->src_addr, - virtbase + COH901318_CX_SRC_ADDR + - COH901318_CX_SRC_ADDR_SPACING * channel); - - writel(lli->dst_addr, virtbase + - COH901318_CX_DST_ADDR + - COH901318_CX_DST_ADDR_SPACING * channel); - - writel(lli->link_addr, virtbase + COH901318_CX_LNK_ADDR + - COH901318_CX_LNK_ADDR_SPACING * channel); - - writel(lli->control, virtbase + COH901318_CX_CTRL + - COH901318_CX_CTRL_SPACING * channel); - - return 0; -} - -static struct coh901318_desc * -coh901318_desc_get(struct coh901318_chan *cohc) -{ - struct coh901318_desc *desc; - - if (list_empty(&cohc->free)) { - /* alloc new desc because we're out of used ones - * TODO: alloc a pile of descs instead of just one, - * avoid many small allocations. - */ - desc = kzalloc(sizeof(struct coh901318_desc), GFP_NOWAIT); - if (desc == NULL) - goto out; - INIT_LIST_HEAD(&desc->node); - dma_async_tx_descriptor_init(&desc->desc, &cohc->chan); - } else { - /* Reuse an old desc. */ - desc = list_first_entry(&cohc->free, - struct coh901318_desc, - node); - list_del(&desc->node); - /* Initialize it a bit so it's not insane */ - desc->sg = NULL; - desc->sg_len = 0; - desc->desc.callback = NULL; - desc->desc.callback_param = NULL; - } - - out: - return desc; -} - -static void -coh901318_desc_free(struct coh901318_chan *cohc, struct coh901318_desc *cohd) -{ - list_add_tail(&cohd->node, &cohc->free); -} - -/* call with irq lock held */ -static void -coh901318_desc_submit(struct coh901318_chan *cohc, struct coh901318_desc *desc) -{ - list_add_tail(&desc->node, &cohc->active); -} - -static struct coh901318_desc * -coh901318_first_active_get(struct coh901318_chan *cohc) -{ - return list_first_entry_or_null(&cohc->active, struct coh901318_desc, - node); -} - -static void -coh901318_desc_remove(struct coh901318_desc *cohd) -{ - list_del(&cohd->node); -} - -static void -coh901318_desc_queue(struct coh901318_chan *cohc, struct coh901318_desc *desc) -{ - list_add_tail(&desc->node, &cohc->queue); -} - -static struct coh901318_desc * -coh901318_first_queued(struct coh901318_chan *cohc) -{ - return list_first_entry_or_null(&cohc->queue, struct coh901318_desc, - node); -} - -static inline u32 coh901318_get_bytes_in_lli(struct coh901318_lli *in_lli) -{ - struct coh901318_lli *lli = in_lli; - u32 bytes = 0; - - while (lli) { - bytes += lli->control & COH901318_CX_CTRL_TC_VALUE_MASK; - lli = lli->virt_link_addr; - } - return bytes; -} - -/* - * Get the number of bytes left to transfer on this channel, - * it is unwise to call this before stopping the channel for - * absolute measures, but for a rough guess you can still call - * it. - */ -static u32 coh901318_get_bytes_left(struct dma_chan *chan) -{ - struct coh901318_chan *cohc = to_coh901318_chan(chan); - struct coh901318_desc *cohd; - struct list_head *pos; - unsigned long flags; - u32 left = 0; - int i = 0; - - spin_lock_irqsave(&cohc->lock, flags); - - /* - * If there are many queued jobs, we iterate and add the - * size of them all. We take a special look on the first - * job though, since it is probably active. - */ - list_for_each(pos, &cohc->active) { - /* - * The first job in the list will be working on the - * hardware. The job can be stopped but still active, - * so that the transfer counter is somewhere inside - * the buffer. - */ - cohd = list_entry(pos, struct coh901318_desc, node); - - if (i == 0) { - struct coh901318_lli *lli; - dma_addr_t ladd; - - /* Read current transfer count value */ - left = readl(cohc->base->virtbase + - COH901318_CX_CTRL + - COH901318_CX_CTRL_SPACING * cohc->id) & - COH901318_CX_CTRL_TC_VALUE_MASK; - - /* See if the transfer is linked... */ - ladd = readl(cohc->base->virtbase + - COH901318_CX_LNK_ADDR + - COH901318_CX_LNK_ADDR_SPACING * - cohc->id) & - ~COH901318_CX_LNK_LINK_IMMEDIATE; - /* Single transaction */ - if (!ladd) - continue; - - /* - * Linked transaction, follow the lli, find the - * currently processing lli, and proceed to the next - */ - lli = cohd->lli; - while (lli && lli->link_addr != ladd) - lli = lli->virt_link_addr; - - if (lli) - lli = lli->virt_link_addr; - - /* - * Follow remaining lli links around to count the total - * number of bytes left - */ - left += coh901318_get_bytes_in_lli(lli); - } else { - left += coh901318_get_bytes_in_lli(cohd->lli); - } - i++; - } - - /* Also count bytes in the queued jobs */ - list_for_each(pos, &cohc->queue) { - cohd = list_entry(pos, struct coh901318_desc, node); - left += coh901318_get_bytes_in_lli(cohd->lli); - } - - spin_unlock_irqrestore(&cohc->lock, flags); - - return left; -} - -/* - * Pauses a transfer without losing data. Enables power save. - * Use this function in conjunction with coh901318_resume. - */ -static int coh901318_pause(struct dma_chan *chan) -{ - u32 val; - unsigned long flags; - struct coh901318_chan *cohc = to_coh901318_chan(chan); - int channel = cohc->id; - void __iomem *virtbase = cohc->base->virtbase; - - spin_lock_irqsave(&cohc->lock, flags); - - /* Disable channel in HW */ - val = readl(virtbase + COH901318_CX_CFG + - COH901318_CX_CFG_SPACING * channel); - - /* Stopping infinite transfer */ - if ((val & COH901318_CX_CTRL_TC_ENABLE) == 0 && - (val & COH901318_CX_CFG_CH_ENABLE)) - cohc->stopped = 1; - - - val &= ~COH901318_CX_CFG_CH_ENABLE; - /* Enable twice, HW bug work around */ - writel(val, virtbase + COH901318_CX_CFG + - COH901318_CX_CFG_SPACING * channel); - writel(val, virtbase + COH901318_CX_CFG + - COH901318_CX_CFG_SPACING * channel); - - /* Spin-wait for it to actually go inactive */ - while (readl(virtbase + COH901318_CX_STAT+COH901318_CX_STAT_SPACING * - channel) & COH901318_CX_STAT_ACTIVE) - cpu_relax(); - - /* Check if we stopped an active job */ - if ((readl(virtbase + COH901318_CX_CTRL+COH901318_CX_CTRL_SPACING * - channel) & COH901318_CX_CTRL_TC_VALUE_MASK) > 0) - cohc->stopped = 1; - - enable_powersave(cohc); - - spin_unlock_irqrestore(&cohc->lock, flags); - return 0; -} - -/* Resumes a transfer that has been stopped via 300_dma_stop(..). - Power save is handled. -*/ -static int coh901318_resume(struct dma_chan *chan) -{ - u32 val; - unsigned long flags; - struct coh901318_chan *cohc = to_coh901318_chan(chan); - int channel = cohc->id; - - spin_lock_irqsave(&cohc->lock, flags); - - disable_powersave(cohc); - - if (cohc->stopped) { - /* Enable channel in HW */ - val = readl(cohc->base->virtbase + COH901318_CX_CFG + - COH901318_CX_CFG_SPACING * channel); - - val |= COH901318_CX_CFG_CH_ENABLE; - - writel(val, cohc->base->virtbase + COH901318_CX_CFG + - COH901318_CX_CFG_SPACING*channel); - - cohc->stopped = 0; - } - - spin_unlock_irqrestore(&cohc->lock, flags); - return 0; -} - -bool coh901318_filter_id(struct dma_chan *chan, void *chan_id) -{ - unsigned long ch_nr = (unsigned long) chan_id; - - if (ch_nr == to_coh901318_chan(chan)->id) - return true; - - return false; -} -EXPORT_SYMBOL(coh901318_filter_id); - -struct coh901318_filter_args { - struct coh901318_base *base; - unsigned int ch_nr; -}; - -static bool coh901318_filter_base_and_id(struct dma_chan *chan, void *data) -{ - struct coh901318_filter_args *args = data; - - if (&args->base->dma_slave == chan->device && - args->ch_nr == to_coh901318_chan(chan)->id) - return true; - - return false; -} - -static struct dma_chan *coh901318_xlate(struct of_phandle_args *dma_spec, - struct of_dma *ofdma) -{ - struct coh901318_filter_args args = { - .base = ofdma->of_dma_data, - .ch_nr = dma_spec->args[0], - }; - dma_cap_mask_t cap; - dma_cap_zero(cap); - dma_cap_set(DMA_SLAVE, cap); - - return dma_request_channel(cap, coh901318_filter_base_and_id, &args); -} -/* - * DMA channel allocation - */ -static int coh901318_config(struct coh901318_chan *cohc, - struct coh901318_params *param) -{ - const struct coh901318_params *p; - int channel = cohc->id; - void __iomem *virtbase = cohc->base->virtbase; - - if (param) - p = param; - else - p = cohc_chan_param(cohc); - - /* Clear any pending BE or TC interrupt */ - if (channel < 32) { - writel(1 << channel, virtbase + COH901318_BE_INT_CLEAR1); - writel(1 << channel, virtbase + COH901318_TC_INT_CLEAR1); - } else { - writel(1 << (channel - 32), virtbase + - COH901318_BE_INT_CLEAR2); - writel(1 << (channel - 32), virtbase + - COH901318_TC_INT_CLEAR2); - } - - coh901318_set_conf(cohc, p->config); - coh901318_set_ctrl(cohc, p->ctrl_lli_last); - - return 0; -} - -/* must lock when calling this function - * start queued jobs, if any - * TODO: start all queued jobs in one go - * - * Returns descriptor if queued job is started otherwise NULL. - * If the queue is empty NULL is returned. - */ -static struct coh901318_desc *coh901318_queue_start(struct coh901318_chan *cohc) -{ - struct coh901318_desc *cohd; - - /* - * start queued jobs, if any - * TODO: transmit all queued jobs in one go - */ - cohd = coh901318_first_queued(cohc); - - if (cohd != NULL) { - /* Remove from queue */ - coh901318_desc_remove(cohd); - /* initiate DMA job */ - cohc->busy = 1; - - coh901318_desc_submit(cohc, cohd); - - /* Program the transaction head */ - coh901318_set_conf(cohc, cohd->head_config); - coh901318_set_ctrl(cohc, cohd->head_ctrl); - coh901318_prep_linked_list(cohc, cohd->lli); - - /* start dma job on this channel */ - coh901318_start(cohc); - - } - - return cohd; -} - -/* - * This tasklet is called from the interrupt handler to - * handle each descriptor (DMA job) that is sent to a channel. - */ -static void dma_tasklet(struct tasklet_struct *t) -{ - struct coh901318_chan *cohc = from_tasklet(cohc, t, tasklet); - struct coh901318_desc *cohd_fin; - unsigned long flags; - struct dmaengine_desc_callback cb; - - dev_vdbg(COHC_2_DEV(cohc), "[%s] chan_id %d" - " nbr_active_done %ld\n", __func__, - cohc->id, cohc->nbr_active_done); - - spin_lock_irqsave(&cohc->lock, flags); - - /* get first active descriptor entry from list */ - cohd_fin = coh901318_first_active_get(cohc); - - if (cohd_fin == NULL) - goto err; - - /* locate callback to client */ - dmaengine_desc_get_callback(&cohd_fin->desc, &cb); - - /* sign this job as completed on the channel */ - dma_cookie_complete(&cohd_fin->desc); - - /* release the lli allocation and remove the descriptor */ - coh901318_lli_free(&cohc->base->pool, &cohd_fin->lli); - - /* return desc to free-list */ - coh901318_desc_remove(cohd_fin); - coh901318_desc_free(cohc, cohd_fin); - - spin_unlock_irqrestore(&cohc->lock, flags); - - /* Call the callback when we're done */ - dmaengine_desc_callback_invoke(&cb, NULL); - - spin_lock_irqsave(&cohc->lock, flags); - - /* - * If another interrupt fired while the tasklet was scheduling, - * we don't get called twice, so we have this number of active - * counter that keep track of the number of IRQs expected to - * be handled for this channel. If there happen to be more than - * one IRQ to be ack:ed, we simply schedule this tasklet again. - */ - cohc->nbr_active_done--; - if (cohc->nbr_active_done) { - dev_dbg(COHC_2_DEV(cohc), "scheduling tasklet again, new IRQs " - "came in while we were scheduling this tasklet\n"); - if (cohc_chan_conf(cohc)->priority_high) - tasklet_hi_schedule(&cohc->tasklet); - else - tasklet_schedule(&cohc->tasklet); - } - - spin_unlock_irqrestore(&cohc->lock, flags); - - return; - - err: - spin_unlock_irqrestore(&cohc->lock, flags); - dev_err(COHC_2_DEV(cohc), "[%s] No active dma desc\n", __func__); -} - - -/* called from interrupt context */ -static void dma_tc_handle(struct coh901318_chan *cohc) -{ - /* - * If the channel is not allocated, then we shouldn't have - * any TC interrupts on it. - */ - if (!cohc->allocated) { - dev_err(COHC_2_DEV(cohc), "spurious interrupt from " - "unallocated channel\n"); - return; - } - - /* - * When we reach this point, at least one queue item - * should have been moved over from cohc->queue to - * cohc->active and run to completion, that is why we're - * getting a terminal count interrupt is it not? - * If you get this BUG() the most probable cause is that - * the individual nodes in the lli chain have IRQ enabled, - * so check your platform config for lli chain ctrl. - */ - BUG_ON(list_empty(&cohc->active)); - - cohc->nbr_active_done++; - - /* - * This attempt to take a job from cohc->queue, put it - * into cohc->active and start it. - */ - if (coh901318_queue_start(cohc) == NULL) - cohc->busy = 0; - - /* - * This tasklet will remove items from cohc->active - * and thus terminates them. - */ - if (cohc_chan_conf(cohc)->priority_high) - tasklet_hi_schedule(&cohc->tasklet); - else - tasklet_schedule(&cohc->tasklet); -} - - -static irqreturn_t dma_irq_handler(int irq, void *dev_id) -{ - u32 status1; - u32 status2; - int i; - int ch; - struct coh901318_base *base = dev_id; - struct coh901318_chan *cohc; - void __iomem *virtbase = base->virtbase; - - status1 = readl(virtbase + COH901318_INT_STATUS1); - status2 = readl(virtbase + COH901318_INT_STATUS2); - - if (unlikely(status1 == 0 && status2 == 0)) { - dev_warn(base->dev, "spurious DMA IRQ from no channel!\n"); - return IRQ_HANDLED; - } - - /* TODO: consider handle IRQ in tasklet here to - * minimize interrupt latency */ - - /* Check the first 32 DMA channels for IRQ */ - while (status1) { - /* Find first bit set, return as a number. */ - i = ffs(status1) - 1; - ch = i; - - cohc = &base->chans[ch]; - spin_lock(&cohc->lock); - - /* Mask off this bit */ - status1 &= ~(1 << i); - /* Check the individual channel bits */ - if (test_bit(i, virtbase + COH901318_BE_INT_STATUS1)) { - dev_crit(COHC_2_DEV(cohc), - "DMA bus error on channel %d!\n", ch); - BUG_ON(1); - /* Clear BE interrupt */ - __set_bit(i, virtbase + COH901318_BE_INT_CLEAR1); - } else { - /* Caused by TC, really? */ - if (unlikely(!test_bit(i, virtbase + - COH901318_TC_INT_STATUS1))) { - dev_warn(COHC_2_DEV(cohc), - "ignoring interrupt not caused by terminal count on channel %d\n", ch); - /* Clear TC interrupt */ - BUG_ON(1); - __set_bit(i, virtbase + COH901318_TC_INT_CLEAR1); - } else { - /* Enable powersave if transfer has finished */ - if (!(readl(virtbase + COH901318_CX_STAT + - COH901318_CX_STAT_SPACING*ch) & - COH901318_CX_STAT_ENABLED)) { - enable_powersave(cohc); - } - - /* Must clear TC interrupt before calling - * dma_tc_handle - * in case tc_handle initiate a new dma job - */ - __set_bit(i, virtbase + COH901318_TC_INT_CLEAR1); - - dma_tc_handle(cohc); - } - } - spin_unlock(&cohc->lock); - } - - /* Check the remaining 32 DMA channels for IRQ */ - while (status2) { - /* Find first bit set, return as a number. */ - i = ffs(status2) - 1; - ch = i + 32; - cohc = &base->chans[ch]; - spin_lock(&cohc->lock); - - /* Mask off this bit */ - status2 &= ~(1 << i); - /* Check the individual channel bits */ - if (test_bit(i, virtbase + COH901318_BE_INT_STATUS2)) { - dev_crit(COHC_2_DEV(cohc), - "DMA bus error on channel %d!\n", ch); - /* Clear BE interrupt */ - BUG_ON(1); - __set_bit(i, virtbase + COH901318_BE_INT_CLEAR2); - } else { - /* Caused by TC, really? */ - if (unlikely(!test_bit(i, virtbase + - COH901318_TC_INT_STATUS2))) { - dev_warn(COHC_2_DEV(cohc), - "ignoring interrupt not caused by terminal count on channel %d\n", ch); - /* Clear TC interrupt */ - __set_bit(i, virtbase + COH901318_TC_INT_CLEAR2); - BUG_ON(1); - } else { - /* Enable powersave if transfer has finished */ - if (!(readl(virtbase + COH901318_CX_STAT + - COH901318_CX_STAT_SPACING*ch) & - COH901318_CX_STAT_ENABLED)) { - enable_powersave(cohc); - } - /* Must clear TC interrupt before calling - * dma_tc_handle - * in case tc_handle initiate a new dma job - */ - __set_bit(i, virtbase + COH901318_TC_INT_CLEAR2); - - dma_tc_handle(cohc); - } - } - spin_unlock(&cohc->lock); - } - - return IRQ_HANDLED; -} - -static int coh901318_terminate_all(struct dma_chan *chan) -{ - unsigned long flags; - struct coh901318_chan *cohc = to_coh901318_chan(chan); - struct coh901318_desc *cohd; - void __iomem *virtbase = cohc->base->virtbase; - - /* The remainder of this function terminates the transfer */ - coh901318_pause(chan); - spin_lock_irqsave(&cohc->lock, flags); - - /* Clear any pending BE or TC interrupt */ - if (cohc->id < 32) { - writel(1 << cohc->id, virtbase + COH901318_BE_INT_CLEAR1); - writel(1 << cohc->id, virtbase + COH901318_TC_INT_CLEAR1); - } else { - writel(1 << (cohc->id - 32), virtbase + - COH901318_BE_INT_CLEAR2); - writel(1 << (cohc->id - 32), virtbase + - COH901318_TC_INT_CLEAR2); - } - - enable_powersave(cohc); - - while ((cohd = coh901318_first_active_get(cohc))) { - /* release the lli allocation*/ - coh901318_lli_free(&cohc->base->pool, &cohd->lli); - - /* return desc to free-list */ - coh901318_desc_remove(cohd); - coh901318_desc_free(cohc, cohd); - } - - while ((cohd = coh901318_first_queued(cohc))) { - /* release the lli allocation*/ - coh901318_lli_free(&cohc->base->pool, &cohd->lli); - - /* return desc to free-list */ - coh901318_desc_remove(cohd); - coh901318_desc_free(cohc, cohd); - } - - - cohc->nbr_active_done = 0; - cohc->busy = 0; - - spin_unlock_irqrestore(&cohc->lock, flags); - - return 0; -} - -static int coh901318_alloc_chan_resources(struct dma_chan *chan) -{ - struct coh901318_chan *cohc = to_coh901318_chan(chan); - unsigned long flags; - - dev_vdbg(COHC_2_DEV(cohc), "[%s] DMA channel %d\n", - __func__, cohc->id); - - if (chan->client_count > 1) - return -EBUSY; - - spin_lock_irqsave(&cohc->lock, flags); - - coh901318_config(cohc, NULL); - - cohc->allocated = 1; - dma_cookie_init(chan); - - spin_unlock_irqrestore(&cohc->lock, flags); - - return 1; -} - -static void -coh901318_free_chan_resources(struct dma_chan *chan) -{ - struct coh901318_chan *cohc = to_coh901318_chan(chan); - int channel = cohc->id; - unsigned long flags; - - spin_lock_irqsave(&cohc->lock, flags); - - /* Disable HW */ - writel(0x00000000U, cohc->base->virtbase + COH901318_CX_CFG + - COH901318_CX_CFG_SPACING*channel); - writel(0x00000000U, cohc->base->virtbase + COH901318_CX_CTRL + - COH901318_CX_CTRL_SPACING*channel); - - cohc->allocated = 0; - - spin_unlock_irqrestore(&cohc->lock, flags); - - coh901318_terminate_all(chan); -} - - -static dma_cookie_t -coh901318_tx_submit(struct dma_async_tx_descriptor *tx) -{ - struct coh901318_desc *cohd = container_of(tx, struct coh901318_desc, - desc); - struct coh901318_chan *cohc = to_coh901318_chan(tx->chan); - unsigned long flags; - dma_cookie_t cookie; - - spin_lock_irqsave(&cohc->lock, flags); - cookie = dma_cookie_assign(tx); - - coh901318_desc_queue(cohc, cohd); - - spin_unlock_irqrestore(&cohc->lock, flags); - - return cookie; -} - -static struct dma_async_tx_descriptor * -coh901318_prep_memcpy(struct dma_chan *chan, dma_addr_t dest, dma_addr_t src, - size_t size, unsigned long flags) -{ - struct coh901318_lli *lli; - struct coh901318_desc *cohd; - unsigned long flg; - struct coh901318_chan *cohc = to_coh901318_chan(chan); - int lli_len; - u32 ctrl_last = cohc_chan_param(cohc)->ctrl_lli_last; - int ret; - - spin_lock_irqsave(&cohc->lock, flg); - - dev_vdbg(COHC_2_DEV(cohc), - "[%s] channel %d src %pad dest %pad size %zu\n", - __func__, cohc->id, &src, &dest, size); - - if (flags & DMA_PREP_INTERRUPT) - /* Trigger interrupt after last lli */ - ctrl_last |= COH901318_CX_CTRL_TC_IRQ_ENABLE; - - lli_len = size >> MAX_DMA_PACKET_SIZE_SHIFT; - if ((lli_len << MAX_DMA_PACKET_SIZE_SHIFT) < size) - lli_len++; - - lli = coh901318_lli_alloc(&cohc->base->pool, lli_len); - - if (lli == NULL) - goto err; - - ret = coh901318_lli_fill_memcpy( - &cohc->base->pool, lli, src, size, dest, - cohc_chan_param(cohc)->ctrl_lli_chained, - ctrl_last); - if (ret) - goto err; - - COH_DBG(coh901318_list_print(cohc, lli)); - - /* Pick a descriptor to handle this transfer */ - cohd = coh901318_desc_get(cohc); - cohd->lli = lli; - cohd->flags = flags; - cohd->desc.tx_submit = coh901318_tx_submit; - - spin_unlock_irqrestore(&cohc->lock, flg); - - return &cohd->desc; - err: - spin_unlock_irqrestore(&cohc->lock, flg); - return NULL; -} - -static struct dma_async_tx_descriptor * -coh901318_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl, - unsigned int sg_len, enum dma_transfer_direction direction, - unsigned long flags, void *context) -{ - struct coh901318_chan *cohc = to_coh901318_chan(chan); - struct coh901318_lli *lli; - struct coh901318_desc *cohd; - const struct coh901318_params *params; - struct scatterlist *sg; - int len = 0; - int size; - int i; - u32 ctrl_chained = cohc_chan_param(cohc)->ctrl_lli_chained; - u32 ctrl = cohc_chan_param(cohc)->ctrl_lli; - u32 ctrl_last = cohc_chan_param(cohc)->ctrl_lli_last; - u32 config; - unsigned long flg; - int ret; - - if (!sgl) - goto out; - if (sg_dma_len(sgl) == 0) - goto out; - - spin_lock_irqsave(&cohc->lock, flg); - - dev_vdbg(COHC_2_DEV(cohc), "[%s] sg_len %d dir %d\n", - __func__, sg_len, direction); - - if (flags & DMA_PREP_INTERRUPT) - /* Trigger interrupt after last lli */ - ctrl_last |= COH901318_CX_CTRL_TC_IRQ_ENABLE; - - params = cohc_chan_param(cohc); - config = params->config; - /* - * Add runtime-specific control on top, make - * sure the bits you set per peripheral channel are - * cleared in the default config from the platform. - */ - ctrl_chained |= cohc->ctrl; - ctrl_last |= cohc->ctrl; - ctrl |= cohc->ctrl; - - if (direction == DMA_MEM_TO_DEV) { - u32 tx_flags = COH901318_CX_CTRL_PRDD_SOURCE | - COH901318_CX_CTRL_SRC_ADDR_INC_ENABLE; - - config |= COH901318_CX_CFG_RM_MEMORY_TO_PRIMARY; - ctrl_chained |= tx_flags; - ctrl_last |= tx_flags; - ctrl |= tx_flags; - } else if (direction == DMA_DEV_TO_MEM) { - u32 rx_flags = COH901318_CX_CTRL_PRDD_DEST | - COH901318_CX_CTRL_DST_ADDR_INC_ENABLE; - - config |= COH901318_CX_CFG_RM_PRIMARY_TO_MEMORY; - ctrl_chained |= rx_flags; - ctrl_last |= rx_flags; - ctrl |= rx_flags; - } else - goto err_direction; - - /* The dma only supports transmitting packages up to - * MAX_DMA_PACKET_SIZE. Calculate to total number of - * dma elemts required to send the entire sg list - */ - for_each_sg(sgl, sg, sg_len, i) { - unsigned int factor; - size = sg_dma_len(sg); - - if (size <= MAX_DMA_PACKET_SIZE) { - len++; - continue; - } - - factor = size >> MAX_DMA_PACKET_SIZE_SHIFT; - if ((factor << MAX_DMA_PACKET_SIZE_SHIFT) < size) - factor++; - - len += factor; - } - - pr_debug("Allocate %d lli:s for this transfer\n", len); - lli = coh901318_lli_alloc(&cohc->base->pool, len); - - if (lli == NULL) - goto err_dma_alloc; - - coh901318_dma_set_runtimeconfig(chan, &cohc->config, direction); - - /* initiate allocated lli list */ - ret = coh901318_lli_fill_sg(&cohc->base->pool, lli, sgl, sg_len, - cohc->addr, - ctrl_chained, - ctrl, - ctrl_last, - direction, COH901318_CX_CTRL_TC_IRQ_ENABLE); - if (ret) - goto err_lli_fill; - - - COH_DBG(coh901318_list_print(cohc, lli)); - - /* Pick a descriptor to handle this transfer */ - cohd = coh901318_desc_get(cohc); - cohd->head_config = config; - /* - * Set the default head ctrl for the channel to the one from the - * lli, things may have changed due to odd buffer alignment - * etc. - */ - cohd->head_ctrl = lli->control; - cohd->dir = direction; - cohd->flags = flags; - cohd->desc.tx_submit = coh901318_tx_submit; - cohd->lli = lli; - - spin_unlock_irqrestore(&cohc->lock, flg); - - return &cohd->desc; - err_lli_fill: - err_dma_alloc: - err_direction: - spin_unlock_irqrestore(&cohc->lock, flg); - out: - return NULL; -} - -static enum dma_status -coh901318_tx_status(struct dma_chan *chan, dma_cookie_t cookie, - struct dma_tx_state *txstate) -{ - struct coh901318_chan *cohc = to_coh901318_chan(chan); - enum dma_status ret; - - ret = dma_cookie_status(chan, cookie, txstate); - if (ret == DMA_COMPLETE || !txstate) - return ret; - - dma_set_residue(txstate, coh901318_get_bytes_left(chan)); - - if (ret == DMA_IN_PROGRESS && cohc->stopped) - ret = DMA_PAUSED; - - return ret; -} - -static void -coh901318_issue_pending(struct dma_chan *chan) -{ - struct coh901318_chan *cohc = to_coh901318_chan(chan); - unsigned long flags; - - spin_lock_irqsave(&cohc->lock, flags); - - /* - * Busy means that pending jobs are already being processed, - * and then there is no point in starting the queue: the - * terminal count interrupt on the channel will take the next - * job on the queue and execute it anyway. - */ - if (!cohc->busy) - coh901318_queue_start(cohc); - - spin_unlock_irqrestore(&cohc->lock, flags); -} - -/* - * Here we wrap in the runtime dma control interface - */ -struct burst_table { - int burst_8bit; - int burst_16bit; - int burst_32bit; - u32 reg; -}; - -static const struct burst_table burst_sizes[] = { - { - .burst_8bit = 64, - .burst_16bit = 32, - .burst_32bit = 16, - .reg = COH901318_CX_CTRL_BURST_COUNT_64_BYTES, - }, - { - .burst_8bit = 48, - .burst_16bit = 24, - .burst_32bit = 12, - .reg = COH901318_CX_CTRL_BURST_COUNT_48_BYTES, - }, - { - .burst_8bit = 32, - .burst_16bit = 16, - .burst_32bit = 8, - .reg = COH901318_CX_CTRL_BURST_COUNT_32_BYTES, - }, - { - .burst_8bit = 16, - .burst_16bit = 8, - .burst_32bit = 4, - .reg = COH901318_CX_CTRL_BURST_COUNT_16_BYTES, - }, - { - .burst_8bit = 8, - .burst_16bit = 4, - .burst_32bit = 2, - .reg = COH901318_CX_CTRL_BURST_COUNT_8_BYTES, - }, - { - .burst_8bit = 4, - .burst_16bit = 2, - .burst_32bit = 1, - .reg = COH901318_CX_CTRL_BURST_COUNT_4_BYTES, - }, - { - .burst_8bit = 2, - .burst_16bit = 1, - .burst_32bit = 0, - .reg = COH901318_CX_CTRL_BURST_COUNT_2_BYTES, - }, - { - .burst_8bit = 1, - .burst_16bit = 0, - .burst_32bit = 0, - .reg = COH901318_CX_CTRL_BURST_COUNT_1_BYTE, - }, -}; - -static int coh901318_dma_set_runtimeconfig(struct dma_chan *chan, - struct dma_slave_config *config, - enum dma_transfer_direction direction) -{ - struct coh901318_chan *cohc = to_coh901318_chan(chan); - dma_addr_t addr; - enum dma_slave_buswidth addr_width; - u32 maxburst; - u32 ctrl = 0; - int i = 0; - - /* We only support mem to per or per to mem transfers */ - if (direction == DMA_DEV_TO_MEM) { - addr = config->src_addr; - addr_width = config->src_addr_width; - maxburst = config->src_maxburst; - } else if (direction == DMA_MEM_TO_DEV) { - addr = config->dst_addr; - addr_width = config->dst_addr_width; - maxburst = config->dst_maxburst; - } else { - dev_err(COHC_2_DEV(cohc), "illegal channel mode\n"); - return -EINVAL; - } - - dev_dbg(COHC_2_DEV(cohc), "configure channel for %d byte transfers\n", - addr_width); - switch (addr_width) { - case DMA_SLAVE_BUSWIDTH_1_BYTE: - ctrl |= - COH901318_CX_CTRL_SRC_BUS_SIZE_8_BITS | - COH901318_CX_CTRL_DST_BUS_SIZE_8_BITS; - - while (i < ARRAY_SIZE(burst_sizes)) { - if (burst_sizes[i].burst_8bit <= maxburst) - break; - i++; - } - - break; - case DMA_SLAVE_BUSWIDTH_2_BYTES: - ctrl |= - COH901318_CX_CTRL_SRC_BUS_SIZE_16_BITS | - COH901318_CX_CTRL_DST_BUS_SIZE_16_BITS; - - while (i < ARRAY_SIZE(burst_sizes)) { - if (burst_sizes[i].burst_16bit <= maxburst) - break; - i++; - } - - break; - case DMA_SLAVE_BUSWIDTH_4_BYTES: - /* Direction doesn't matter here, it's 32/32 bits */ - ctrl |= - COH901318_CX_CTRL_SRC_BUS_SIZE_32_BITS | - COH901318_CX_CTRL_DST_BUS_SIZE_32_BITS; - - while (i < ARRAY_SIZE(burst_sizes)) { - if (burst_sizes[i].burst_32bit <= maxburst) - break; - i++; - } - - break; - default: - dev_err(COHC_2_DEV(cohc), - "bad runtimeconfig: alien address width\n"); - return -EINVAL; - } - - ctrl |= burst_sizes[i].reg; - dev_dbg(COHC_2_DEV(cohc), - "selected burst size %d bytes for address width %d bytes, maxburst %d\n", - burst_sizes[i].burst_8bit, addr_width, maxburst); - - cohc->addr = addr; - cohc->ctrl = ctrl; - - return 0; -} - -static int coh901318_dma_slave_config(struct dma_chan *chan, - struct dma_slave_config *config) -{ - struct coh901318_chan *cohc = to_coh901318_chan(chan); - - memcpy(&cohc->config, config, sizeof(*config)); - - return 0; -} - -static void coh901318_base_init(struct dma_device *dma, const int *pick_chans, - struct coh901318_base *base) -{ - int chans_i; - int i = 0; - struct coh901318_chan *cohc; - - INIT_LIST_HEAD(&dma->channels); - - for (chans_i = 0; pick_chans[chans_i] != -1; chans_i += 2) { - for (i = pick_chans[chans_i]; i <= pick_chans[chans_i+1]; i++) { - cohc = &base->chans[i]; - - cohc->base = base; - cohc->chan.device = dma; - cohc->id = i; - - /* TODO: do we really need this lock if only one - * client is connected to each channel? - */ - - spin_lock_init(&cohc->lock); - - cohc->nbr_active_done = 0; - cohc->busy = 0; - INIT_LIST_HEAD(&cohc->free); - INIT_LIST_HEAD(&cohc->active); - INIT_LIST_HEAD(&cohc->queue); - - tasklet_setup(&cohc->tasklet, dma_tasklet); - - list_add_tail(&cohc->chan.device_node, - &dma->channels); - } - } -} - -static int __init coh901318_probe(struct platform_device *pdev) -{ - int err = 0; - struct coh901318_base *base; - int irq; - struct resource *io; - - io = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!io) - return -ENODEV; - - /* Map DMA controller registers to virtual memory */ - if (devm_request_mem_region(&pdev->dev, - io->start, - resource_size(io), - pdev->dev.driver->name) == NULL) - return -ENOMEM; - - base = devm_kzalloc(&pdev->dev, - ALIGN(sizeof(struct coh901318_base), 4) + - U300_DMA_CHANNELS * - sizeof(struct coh901318_chan), - GFP_KERNEL); - if (!base) - return -ENOMEM; - - base->chans = ((void *)base) + ALIGN(sizeof(struct coh901318_base), 4); - - base->virtbase = devm_ioremap(&pdev->dev, io->start, resource_size(io)); - if (!base->virtbase) - return -ENOMEM; - - base->dev = &pdev->dev; - spin_lock_init(&base->pm.lock); - base->pm.started_channels = 0; - - COH901318_DEBUGFS_ASSIGN(debugfs_dma_base, base); - - irq = platform_get_irq(pdev, 0); - if (irq < 0) - return irq; - - err = devm_request_irq(&pdev->dev, irq, dma_irq_handler, 0, - "coh901318", base); - if (err) - return err; - - base->irq = irq; - - err = coh901318_pool_create(&base->pool, &pdev->dev, - sizeof(struct coh901318_lli), - 32); - if (err) - return err; - - /* init channels for device transfers */ - coh901318_base_init(&base->dma_slave, dma_slave_channels, - base); - - dma_cap_zero(base->dma_slave.cap_mask); - dma_cap_set(DMA_SLAVE, base->dma_slave.cap_mask); - - base->dma_slave.device_alloc_chan_resources = coh901318_alloc_chan_resources; - base->dma_slave.device_free_chan_resources = coh901318_free_chan_resources; - base->dma_slave.device_prep_slave_sg = coh901318_prep_slave_sg; - base->dma_slave.device_tx_status = coh901318_tx_status; - base->dma_slave.device_issue_pending = coh901318_issue_pending; - base->dma_slave.device_config = coh901318_dma_slave_config; - base->dma_slave.device_pause = coh901318_pause; - base->dma_slave.device_resume = coh901318_resume; - base->dma_slave.device_terminate_all = coh901318_terminate_all; - base->dma_slave.dev = &pdev->dev; - - err = dma_async_device_register(&base->dma_slave); - - if (err) - goto err_register_slave; - - /* init channels for memcpy */ - coh901318_base_init(&base->dma_memcpy, dma_memcpy_channels, - base); - - dma_cap_zero(base->dma_memcpy.cap_mask); - dma_cap_set(DMA_MEMCPY, base->dma_memcpy.cap_mask); - - base->dma_memcpy.device_alloc_chan_resources = coh901318_alloc_chan_resources; - base->dma_memcpy.device_free_chan_resources = coh901318_free_chan_resources; - base->dma_memcpy.device_prep_dma_memcpy = coh901318_prep_memcpy; - base->dma_memcpy.device_tx_status = coh901318_tx_status; - base->dma_memcpy.device_issue_pending = coh901318_issue_pending; - base->dma_memcpy.device_config = coh901318_dma_slave_config; - base->dma_memcpy.device_pause = coh901318_pause; - base->dma_memcpy.device_resume = coh901318_resume; - base->dma_memcpy.device_terminate_all = coh901318_terminate_all; - base->dma_memcpy.dev = &pdev->dev; - /* - * This controller can only access address at even 32bit boundaries, - * i.e. 2^2 - */ - base->dma_memcpy.copy_align = DMAENGINE_ALIGN_4_BYTES; - err = dma_async_device_register(&base->dma_memcpy); - - if (err) - goto err_register_memcpy; - - err = of_dma_controller_register(pdev->dev.of_node, coh901318_xlate, - base); - if (err) - goto err_register_of_dma; - - platform_set_drvdata(pdev, base); - dev_info(&pdev->dev, "Initialized COH901318 DMA on virtual base 0x%p\n", - base->virtbase); - - return err; - - err_register_of_dma: - dma_async_device_unregister(&base->dma_memcpy); - err_register_memcpy: - dma_async_device_unregister(&base->dma_slave); - err_register_slave: - coh901318_pool_destroy(&base->pool); - return err; -} -static void coh901318_base_remove(struct coh901318_base *base, const int *pick_chans) -{ - int chans_i; - int i = 0; - struct coh901318_chan *cohc; - - for (chans_i = 0; pick_chans[chans_i] != -1; chans_i += 2) { - for (i = pick_chans[chans_i]; i <= pick_chans[chans_i+1]; i++) { - cohc = &base->chans[i]; - - tasklet_kill(&cohc->tasklet); - } - } - -} - -static int coh901318_remove(struct platform_device *pdev) -{ - struct coh901318_base *base = platform_get_drvdata(pdev); - - devm_free_irq(&pdev->dev, base->irq, base); - - coh901318_base_remove(base, dma_slave_channels); - coh901318_base_remove(base, dma_memcpy_channels); - - of_dma_controller_free(pdev->dev.of_node); - dma_async_device_unregister(&base->dma_memcpy); - dma_async_device_unregister(&base->dma_slave); - coh901318_pool_destroy(&base->pool); - return 0; -} - -static const struct of_device_id coh901318_dt_match[] = { - { .compatible = "stericsson,coh901318" }, - {}, -}; - -static struct platform_driver coh901318_driver = { - .remove = coh901318_remove, - .driver = { - .name = "coh901318", - .of_match_table = coh901318_dt_match, - }, -}; - -static int __init coh901318_init(void) -{ - return platform_driver_probe(&coh901318_driver, coh901318_probe); -} -subsys_initcall(coh901318_init); - -static void __exit coh901318_exit(void) -{ - platform_driver_unregister(&coh901318_driver); -} -module_exit(coh901318_exit); - -MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Per Friden"); diff --git a/drivers/dma/coh901318.h b/drivers/dma/coh901318.h deleted file mode 100644 index bbf533600558..000000000000 --- a/drivers/dma/coh901318.h +++ /dev/null @@ -1,141 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ -/* - * Copyright (C) 2007-2013 ST-Ericsson - * DMA driver for COH 901 318 - * Author: Per Friden - */ - -#ifndef COH901318_H -#define COH901318_H - -#define MAX_DMA_PACKET_SIZE_SHIFT 11 -#define MAX_DMA_PACKET_SIZE (1 << MAX_DMA_PACKET_SIZE_SHIFT) - -struct device; - -struct coh901318_pool { - spinlock_t lock; - struct dma_pool *dmapool; - struct device *dev; - -#ifdef CONFIG_DEBUG_FS - int debugfs_pool_counter; -#endif -}; - -/** - * struct coh901318_lli - linked list item for DMAC - * @control: control settings for DMAC - * @src_addr: transfer source address - * @dst_addr: transfer destination address - * @link_addr: physical address to next lli - * @virt_link_addr: virtual address of next lli (only used by pool_free) - * @phy_this: physical address of current lli (only used by pool_free) - */ -struct coh901318_lli { - u32 control; - dma_addr_t src_addr; - dma_addr_t dst_addr; - dma_addr_t link_addr; - - void *virt_link_addr; - dma_addr_t phy_this; -}; - -/** - * coh901318_pool_create() - Creates an dma pool for lli:s - * @pool: pool handle - * @dev: dma device - * @lli_nbr: number of lli:s in the pool - * @algin: address alignemtn of lli:s - * returns 0 on success otherwise none zero - */ -int coh901318_pool_create(struct coh901318_pool *pool, - struct device *dev, - size_t lli_nbr, size_t align); - -/** - * coh901318_pool_destroy() - Destroys the dma pool - * @pool: pool handle - * returns 0 on success otherwise none zero - */ -int coh901318_pool_destroy(struct coh901318_pool *pool); - -/** - * coh901318_lli_alloc() - Allocates a linked list - * - * @pool: pool handle - * @len: length to list - * return: none NULL if success otherwise NULL - */ -struct coh901318_lli * -coh901318_lli_alloc(struct coh901318_pool *pool, - unsigned int len); - -/** - * coh901318_lli_free() - Returns the linked list items to the pool - * @pool: pool handle - * @lli: reference to lli pointer to be freed - */ -void coh901318_lli_free(struct coh901318_pool *pool, - struct coh901318_lli **lli); - -/** - * coh901318_lli_fill_memcpy() - Prepares the lli:s for dma memcpy - * @pool: pool handle - * @lli: allocated lli - * @src: src address - * @size: transfer size - * @dst: destination address - * @ctrl_chained: ctrl for chained lli - * @ctrl_last: ctrl for the last lli - * returns number of CPU interrupts for the lli, negative on error. - */ -int -coh901318_lli_fill_memcpy(struct coh901318_pool *pool, - struct coh901318_lli *lli, - dma_addr_t src, unsigned int size, - dma_addr_t dst, u32 ctrl_chained, u32 ctrl_last); - -/** - * coh901318_lli_fill_single() - Prepares the lli:s for dma single transfer - * @pool: pool handle - * @lli: allocated lli - * @buf: transfer buffer - * @size: transfer size - * @dev_addr: address of periphal - * @ctrl_chained: ctrl for chained lli - * @ctrl_last: ctrl for the last lli - * @dir: direction of transfer (to or from device) - * returns number of CPU interrupts for the lli, negative on error. - */ -int -coh901318_lli_fill_single(struct coh901318_pool *pool, - struct coh901318_lli *lli, - dma_addr_t buf, unsigned int size, - dma_addr_t dev_addr, u32 ctrl_chained, u32 ctrl_last, - enum dma_transfer_direction dir); - -/** - * coh901318_lli_fill_single() - Prepares the lli:s for dma scatter list transfer - * @pool: pool handle - * @lli: allocated lli - * @sg: scatter gather list - * @nents: number of entries in sg - * @dev_addr: address of periphal - * @ctrl_chained: ctrl for chained lli - * @ctrl: ctrl of middle lli - * @ctrl_last: ctrl for the last lli - * @dir: direction of transfer (to or from device) - * @ctrl_irq_mask: ctrl mask for CPU interrupt - * returns number of CPU interrupts for the lli, negative on error. - */ -int -coh901318_lli_fill_sg(struct coh901318_pool *pool, - struct coh901318_lli *lli, - struct scatterlist *sg, unsigned int nents, - dma_addr_t dev_addr, u32 ctrl_chained, - u32 ctrl, u32 ctrl_last, - enum dma_transfer_direction dir, u32 ctrl_irq_mask); - -#endif /* COH901318_H */ diff --git a/drivers/dma/coh901318_lli.c b/drivers/dma/coh901318_lli.c deleted file mode 100644 index 6b6c2fd0865a..000000000000 --- a/drivers/dma/coh901318_lli.c +++ /dev/null @@ -1,313 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * driver/dma/coh901318_lli.c - * - * Copyright (C) 2007-2009 ST-Ericsson - * Support functions for handling lli for dma - * Author: Per Friden - */ - -#include -#include -#include -#include -#include - -#include "coh901318.h" - -#if (defined(CONFIG_DEBUG_FS) && defined(CONFIG_U300_DEBUG)) -#define DEBUGFS_POOL_COUNTER_RESET(pool) (pool->debugfs_pool_counter = 0) -#define DEBUGFS_POOL_COUNTER_ADD(pool, add) (pool->debugfs_pool_counter += add) -#else -#define DEBUGFS_POOL_COUNTER_RESET(pool) -#define DEBUGFS_POOL_COUNTER_ADD(pool, add) -#endif - -static struct coh901318_lli * -coh901318_lli_next(struct coh901318_lli *data) -{ - if (data == NULL || data->link_addr == 0) - return NULL; - - return (struct coh901318_lli *) data->virt_link_addr; -} - -int coh901318_pool_create(struct coh901318_pool *pool, - struct device *dev, - size_t size, size_t align) -{ - spin_lock_init(&pool->lock); - pool->dev = dev; - pool->dmapool = dma_pool_create("lli_pool", dev, size, align, 0); - - DEBUGFS_POOL_COUNTER_RESET(pool); - return 0; -} - -int coh901318_pool_destroy(struct coh901318_pool *pool) -{ - - dma_pool_destroy(pool->dmapool); - return 0; -} - -struct coh901318_lli * -coh901318_lli_alloc(struct coh901318_pool *pool, unsigned int len) -{ - int i; - struct coh901318_lli *head; - struct coh901318_lli *lli; - struct coh901318_lli *lli_prev; - dma_addr_t phy; - - if (len == 0) - return NULL; - - spin_lock(&pool->lock); - - head = dma_pool_alloc(pool->dmapool, GFP_NOWAIT, &phy); - - if (head == NULL) - goto err; - - DEBUGFS_POOL_COUNTER_ADD(pool, 1); - - lli = head; - lli->phy_this = phy; - lli->link_addr = 0x00000000; - lli->virt_link_addr = NULL; - - for (i = 1; i < len; i++) { - lli_prev = lli; - - lli = dma_pool_alloc(pool->dmapool, GFP_NOWAIT, &phy); - - if (lli == NULL) - goto err_clean_up; - - DEBUGFS_POOL_COUNTER_ADD(pool, 1); - lli->phy_this = phy; - lli->link_addr = 0x00000000; - lli->virt_link_addr = NULL; - - lli_prev->link_addr = phy; - lli_prev->virt_link_addr = lli; - } - - spin_unlock(&pool->lock); - - return head; - - err: - spin_unlock(&pool->lock); - return NULL; - - err_clean_up: - lli_prev->link_addr = 0x00000000U; - spin_unlock(&pool->lock); - coh901318_lli_free(pool, &head); - return NULL; -} - -void coh901318_lli_free(struct coh901318_pool *pool, - struct coh901318_lli **lli) -{ - struct coh901318_lli *l; - struct coh901318_lli *next; - - if (lli == NULL) - return; - - l = *lli; - - if (l == NULL) - return; - - spin_lock(&pool->lock); - - while (l->link_addr) { - next = l->virt_link_addr; - dma_pool_free(pool->dmapool, l, l->phy_this); - DEBUGFS_POOL_COUNTER_ADD(pool, -1); - l = next; - } - dma_pool_free(pool->dmapool, l, l->phy_this); - DEBUGFS_POOL_COUNTER_ADD(pool, -1); - - spin_unlock(&pool->lock); - *lli = NULL; -} - -int -coh901318_lli_fill_memcpy(struct coh901318_pool *pool, - struct coh901318_lli *lli, - dma_addr_t source, unsigned int size, - dma_addr_t destination, u32 ctrl_chained, - u32 ctrl_eom) -{ - int s = size; - dma_addr_t src = source; - dma_addr_t dst = destination; - - lli->src_addr = src; - lli->dst_addr = dst; - - while (lli->link_addr) { - lli->control = ctrl_chained | MAX_DMA_PACKET_SIZE; - lli->src_addr = src; - lli->dst_addr = dst; - - s -= MAX_DMA_PACKET_SIZE; - lli = coh901318_lli_next(lli); - - src += MAX_DMA_PACKET_SIZE; - dst += MAX_DMA_PACKET_SIZE; - } - - lli->control = ctrl_eom | s; - lli->src_addr = src; - lli->dst_addr = dst; - - return 0; -} - -int -coh901318_lli_fill_single(struct coh901318_pool *pool, - struct coh901318_lli *lli, - dma_addr_t buf, unsigned int size, - dma_addr_t dev_addr, u32 ctrl_chained, u32 ctrl_eom, - enum dma_transfer_direction dir) -{ - int s = size; - dma_addr_t src; - dma_addr_t dst; - - - if (dir == DMA_MEM_TO_DEV) { - src = buf; - dst = dev_addr; - - } else if (dir == DMA_DEV_TO_MEM) { - - src = dev_addr; - dst = buf; - } else { - return -EINVAL; - } - - while (lli->link_addr) { - size_t block_size = MAX_DMA_PACKET_SIZE; - lli->control = ctrl_chained | MAX_DMA_PACKET_SIZE; - - /* If we are on the next-to-final block and there will - * be less than half a DMA packet left for the last - * block, then we want to make this block a little - * smaller to balance the sizes. This is meant to - * avoid too small transfers if the buffer size is - * (MAX_DMA_PACKET_SIZE*N + 1) */ - if (s < (MAX_DMA_PACKET_SIZE + MAX_DMA_PACKET_SIZE/2)) - block_size = MAX_DMA_PACKET_SIZE/2; - - s -= block_size; - lli->src_addr = src; - lli->dst_addr = dst; - - lli = coh901318_lli_next(lli); - - if (dir == DMA_MEM_TO_DEV) - src += block_size; - else if (dir == DMA_DEV_TO_MEM) - dst += block_size; - } - - lli->control = ctrl_eom | s; - lli->src_addr = src; - lli->dst_addr = dst; - - return 0; -} - -int -coh901318_lli_fill_sg(struct coh901318_pool *pool, - struct coh901318_lli *lli, - struct scatterlist *sgl, unsigned int nents, - dma_addr_t dev_addr, u32 ctrl_chained, u32 ctrl, - u32 ctrl_last, - enum dma_transfer_direction dir, u32 ctrl_irq_mask) -{ - int i; - struct scatterlist *sg; - u32 ctrl_sg; - dma_addr_t src = 0; - dma_addr_t dst = 0; - u32 bytes_to_transfer; - u32 elem_size; - - if (lli == NULL) - goto err; - - spin_lock(&pool->lock); - - if (dir == DMA_MEM_TO_DEV) - dst = dev_addr; - else if (dir == DMA_DEV_TO_MEM) - src = dev_addr; - else - goto err; - - for_each_sg(sgl, sg, nents, i) { - if (sg_is_chain(sg)) { - /* sg continues to the next sg-element don't - * send ctrl_finish until the last - * sg-element in the chain - */ - ctrl_sg = ctrl_chained; - } else if (i == nents - 1) - ctrl_sg = ctrl_last; - else - ctrl_sg = ctrl ? ctrl : ctrl_last; - - - if (dir == DMA_MEM_TO_DEV) - /* increment source address */ - src = sg_dma_address(sg); - else - /* increment destination address */ - dst = sg_dma_address(sg); - - bytes_to_transfer = sg_dma_len(sg); - - while (bytes_to_transfer) { - u32 val; - - if (bytes_to_transfer > MAX_DMA_PACKET_SIZE) { - elem_size = MAX_DMA_PACKET_SIZE; - val = ctrl_chained; - } else { - elem_size = bytes_to_transfer; - val = ctrl_sg; - } - - lli->control = val | elem_size; - lli->src_addr = src; - lli->dst_addr = dst; - - if (dir == DMA_DEV_TO_MEM) - dst += elem_size; - else - src += elem_size; - - BUG_ON(lli->link_addr & 3); - - bytes_to_transfer -= elem_size; - lli = coh901318_lli_next(lli); - } - - } - spin_unlock(&pool->lock); - - return 0; - err: - spin_unlock(&pool->lock); - return -EINVAL; -} diff --git a/include/linux/platform_data/dma-coh901318.h b/include/linux/platform_data/dma-coh901318.h deleted file mode 100644 index 4cca529f8d56..000000000000 --- a/include/linux/platform_data/dma-coh901318.h +++ /dev/null @@ -1,72 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ -/* - * Platform data for the COH901318 DMA controller - * Copyright (C) 2007-2013 ST-Ericsson - */ - -#ifndef PLAT_COH901318_H -#define PLAT_COH901318_H - -#ifdef CONFIG_COH901318 - -/* We only support the U300 DMA channels */ -#define U300_DMA_MSL_TX_0 0 -#define U300_DMA_MSL_TX_1 1 -#define U300_DMA_MSL_TX_2 2 -#define U300_DMA_MSL_TX_3 3 -#define U300_DMA_MSL_TX_4 4 -#define U300_DMA_MSL_TX_5 5 -#define U300_DMA_MSL_TX_6 6 -#define U300_DMA_MSL_RX_0 7 -#define U300_DMA_MSL_RX_1 8 -#define U300_DMA_MSL_RX_2 9 -#define U300_DMA_MSL_RX_3 10 -#define U300_DMA_MSL_RX_4 11 -#define U300_DMA_MSL_RX_5 12 -#define U300_DMA_MSL_RX_6 13 -#define U300_DMA_MMCSD_RX_TX 14 -#define U300_DMA_MSPRO_TX 15 -#define U300_DMA_MSPRO_RX 16 -#define U300_DMA_UART0_TX 17 -#define U300_DMA_UART0_RX 18 -#define U300_DMA_APEX_TX 19 -#define U300_DMA_APEX_RX 20 -#define U300_DMA_PCM_I2S0_TX 21 -#define U300_DMA_PCM_I2S0_RX 22 -#define U300_DMA_PCM_I2S1_TX 23 -#define U300_DMA_PCM_I2S1_RX 24 -#define U300_DMA_XGAM_CDI 25 -#define U300_DMA_XGAM_PDI 26 -#define U300_DMA_SPI_TX 27 -#define U300_DMA_SPI_RX 28 -#define U300_DMA_GENERAL_PURPOSE_0 29 -#define U300_DMA_GENERAL_PURPOSE_1 30 -#define U300_DMA_GENERAL_PURPOSE_2 31 -#define U300_DMA_GENERAL_PURPOSE_3 32 -#define U300_DMA_GENERAL_PURPOSE_4 33 -#define U300_DMA_GENERAL_PURPOSE_5 34 -#define U300_DMA_GENERAL_PURPOSE_6 35 -#define U300_DMA_GENERAL_PURPOSE_7 36 -#define U300_DMA_GENERAL_PURPOSE_8 37 -#define U300_DMA_UART1_TX 38 -#define U300_DMA_UART1_RX 39 - -#define U300_DMA_DEVICE_CHANNELS 32 -#define U300_DMA_CHANNELS 40 - -/** - * coh901318_filter_id() - DMA channel filter function - * @chan: dma channel handle - * @chan_id: id of dma channel to be filter out - * - * In dma_request_channel() it specifies what channel id to be requested - */ -bool coh901318_filter_id(struct dma_chan *chan, void *chan_id); -#else -static inline bool coh901318_filter_id(struct dma_chan *chan, void *chan_id) -{ - return false; -} -#endif - -#endif /* PLAT_COH901318_H */ -- cgit v1.2.3 From 03d939c7e3d8800a9feb54808929c5776ac510eb Mon Sep 17 00:00:00 2001 From: Dave Jiang Date: Fri, 22 Jan 2021 11:46:00 -0700 Subject: dmaengine: idxd: add module parameter to force disable of SVA Add a module parameter that overrides the SVA feature enabling. This keeps the driver in legacy mode even when intel_iommu=sm_on is set. In this mode, the descriptor fields must be programmed with dma_addr_t from the Linux DMA API for source, destination, and completion descriptors. Signed-off-by: Dave Jiang Link: https://lore.kernel.org/r/161134110457.4005461.13171197785259115852.stgit@djiang5-desk3.ch.intel.com Signed-off-by: Vinod Koul --- Documentation/admin-guide/kernel-parameters.txt | 6 ++++++ drivers/dma/idxd/init.c | 8 +++++++- 2 files changed, 13 insertions(+), 1 deletion(-) (limited to 'Documentation') diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt index c722ec19cd00..c25786b95419 100644 --- a/Documentation/admin-guide/kernel-parameters.txt +++ b/Documentation/admin-guide/kernel-parameters.txt @@ -1673,6 +1673,12 @@ In such case C2/C3 won't be used again. idle=nomwait: Disable mwait for CPU C-states + idxd.sva= [HW] + Format: + Allow force disabling of Shared Virtual Memory (SVA) + support for the idxd driver. By default it is set to + true (1). + ieee754= [MIPS] Select IEEE Std 754 conformance mode Format: { strict | legacy | 2008 | relaxed } Default: strict diff --git a/drivers/dma/idxd/init.c b/drivers/dma/idxd/init.c index 25cc947c6179..9687a24ff982 100644 --- a/drivers/dma/idxd/init.c +++ b/drivers/dma/idxd/init.c @@ -26,6 +26,10 @@ MODULE_VERSION(IDXD_DRIVER_VERSION); MODULE_LICENSE("GPL v2"); MODULE_AUTHOR("Intel Corporation"); +static bool sva = true; +module_param(sva, bool, 0644); +MODULE_PARM_DESC(sva, "Toggle SVA support on/off"); + #define DRV_NAME "idxd" bool support_enqcmd; @@ -338,12 +342,14 @@ static int idxd_probe(struct idxd_device *idxd) idxd_device_init_reset(idxd); dev_dbg(dev, "IDXD reset complete\n"); - if (IS_ENABLED(CONFIG_INTEL_IDXD_SVM)) { + if (IS_ENABLED(CONFIG_INTEL_IDXD_SVM) && sva) { rc = idxd_enable_system_pasid(idxd); if (rc < 0) dev_warn(dev, "Failed to enable PASID. No SVA support: %d\n", rc); else set_bit(IDXD_FLAG_PASID_ENABLED, &idxd->flags); + } else if (!sva) { + dev_warn(dev, "User forced SVA off via module param.\n"); } idxd_read_caps(idxd); -- cgit v1.2.3 From 7a35a5ca26376f0c0e7ac44c5f1324d5d980b2ef Mon Sep 17 00:00:00 2001 From: Andrey Konovalov Date: Sat, 23 Jan 2021 20:14:17 +0100 Subject: usb: raw-gadget: update documentation and Kconfig Update Raw Gadget documentation and Kconfig. Make the description more precise and clear, fix typos and grammar mistakes, and do other cleanups. Signed-off-by: Andrey Konovalov Link: https://lore.kernel.org/r/f4c650c94ae2b910e38819d51109cd5f0b251a2a.1611429174.git.andreyknvl@google.com Signed-off-by: Greg Kroah-Hartman --- Documentation/usb/raw-gadget.rst | 102 +++++++++++++++++++++----------------- drivers/usb/gadget/legacy/Kconfig | 13 +++-- 2 files changed, 65 insertions(+), 50 deletions(-) (limited to 'Documentation') diff --git a/Documentation/usb/raw-gadget.rst b/Documentation/usb/raw-gadget.rst index 68d879a8009e..818a1648b387 100644 --- a/Documentation/usb/raw-gadget.rst +++ b/Documentation/usb/raw-gadget.rst @@ -2,83 +2,93 @@ USB Raw Gadget ============== -USB Raw Gadget is a kernel module that provides a userspace interface for -the USB Gadget subsystem. Essentially it allows to emulate USB devices -from userspace. Enabled with CONFIG_USB_RAW_GADGET. Raw Gadget is -currently a strictly debugging feature and shouldn't be used in -production, use GadgetFS instead. +USB Raw Gadget is a gadget driver that gives userspace low-level control over +the gadget's communication process. + +Like any other gadget driver, Raw Gadget implements USB devices via the +USB gadget API. Unlike most gadget drivers, Raw Gadget does not implement +any concrete USB functions itself but requires userspace to do that. + +Raw Gadget is currently a strictly debugging feature and should not be used +in production. Use GadgetFS instead. + +Enabled with CONFIG_USB_RAW_GADGET. Comparison to GadgetFS ~~~~~~~~~~~~~~~~~~~~~~ -Raw Gadget is similar to GadgetFS, but provides a more low-level and -direct access to the USB Gadget layer for the userspace. The key -differences are: +Raw Gadget is similar to GadgetFS but provides more direct access to the +USB gadget layer for userspace. The key differences are: -1. Every USB request is passed to the userspace to get a response, while +1. Raw Gadget passes every USB request to userspace to get a response, while GadgetFS responds to some USB requests internally based on the provided - descriptors. However note, that the UDC driver might respond to some - requests on its own and never forward them to the Gadget layer. + descriptors. Note that the UDC driver might respond to some requests on + its own and never forward them to the gadget layer. -2. GadgetFS performs some sanity checks on the provided USB descriptors, - while Raw Gadget allows you to provide arbitrary data as responses to - USB requests. +2. Raw Gadget allows providing arbitrary data as responses to USB requests, + while GadgetFS performs sanity checks on the provided USB descriptors. + This makes Raw Gadget suitable for fuzzing by providing malformed data as + responses to USB requests. 3. Raw Gadget provides a way to select a UDC device/driver to bind to, - while GadgetFS currently binds to the first available UDC. + while GadgetFS currently binds to the first available UDC. This allows + having multiple Raw Gadget instances bound to different UDCs. 4. Raw Gadget explicitly exposes information about endpoints addresses and - capabilities allowing a user to write UDC-agnostic gadgets. + capabilities. This allows the user to write UDC-agnostic gadgets. -5. Raw Gadget has ioctl-based interface instead of a filesystem-based one. +5. Raw Gadget has an ioctl-based interface instead of a filesystem-based + one. Userspace interface ~~~~~~~~~~~~~~~~~~~ -To create a Raw Gadget instance open /dev/raw-gadget. Multiple raw-gadget -instances (bound to different UDCs) can be used at the same time. The -interaction with the opened file happens through the ioctl() calls, see -comments in include/uapi/linux/usb/raw_gadget.h for details. +The user can interact with Raw Gadget by opening ``/dev/raw-gadget`` and +issuing ioctl calls; see the comments in include/uapi/linux/usb/raw_gadget.h +for details. Multiple Raw Gadget instances (bound to different UDCs) can be +used at the same time. -The typical usage of Raw Gadget looks like: +A typical usage scenario of Raw Gadget: -1. Open Raw Gadget instance via /dev/raw-gadget. -2. Initialize the instance via USB_RAW_IOCTL_INIT. -3. Launch the instance with USB_RAW_IOCTL_RUN. -4. In a loop issue USB_RAW_IOCTL_EVENT_FETCH calls to receive events from - Raw Gadget and react to those depending on what kind of USB device - needs to be emulated. +1. Create a Raw Gadget instance by opening ``/dev/raw-gadget``. +2. Initialize the instance via ``USB_RAW_IOCTL_INIT``. +3. Launch the instance with ``USB_RAW_IOCTL_RUN``. +4. In a loop issue ``USB_RAW_IOCTL_EVENT_FETCH`` to receive events from + Raw Gadget and react to those depending on what kind of USB gadget must + be implemented. -Note, that some UDC drivers have fixed addresses assigned to endpoints, and -therefore arbitrary endpoint addresses can't be used in the descriptors. -Nevertheles, Raw Gadget provides a UDC-agnostic way to write USB gadgets. -Once a USB_RAW_EVENT_CONNECT event is received via USB_RAW_IOCTL_EVENT_FETCH, -the USB_RAW_IOCTL_EPS_INFO ioctl can be used to find out information about -endpoints that the UDC driver has. Based on that information, the user must -chose UDC endpoints that will be used for the gadget being emulated, and -properly assign addresses in endpoint descriptors. +Note that some UDC drivers have fixed addresses assigned to endpoints, and +therefore arbitrary endpoint addresses cannot be used in the descriptors. +Nevertheless, Raw Gadget provides a UDC-agnostic way to write USB gadgets. +Once ``USB_RAW_EVENT_CONNECT`` is received via ``USB_RAW_IOCTL_EVENT_FETCH``, +``USB_RAW_IOCTL_EPS_INFO`` can be used to find out information about the +endpoints that the UDC driver has. Based on that, userspace must choose UDC +endpoints for the gadget and assign addresses in the endpoint descriptors +correspondingly. -You can find usage examples (along with a test suite) here: +Raw Gadget usage examples and a test suite: https://github.com/xairy/raw-gadget Internal details ~~~~~~~~~~~~~~~~ -Currently every endpoint read/write ioctl submits a USB request and waits until -its completion. This is the desired mode for coverage-guided fuzzing (as we'd -like all USB request processing happen during the lifetime of a syscall), -and must be kept in the implementation. (This might be slow for real world -applications, thus the O_NONBLOCK improvement suggestion below.) +Every Raw Gadget endpoint read/write ioctl submits a USB request and waits +until its completion. This is done deliberately to assist with coverage-guided +fuzzing by having a single syscall fully process a single USB request. This +feature must be kept in the implementation. Potential future improvements ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -- Report more events (suspend, resume, etc.) through USB_RAW_IOCTL_EVENT_FETCH. +- Report more events (suspend, resume, etc.) through + ``USB_RAW_IOCTL_EVENT_FETCH``. -- Support O_NONBLOCK I/O. +- Support ``O_NONBLOCK`` I/O. This would be another mode of operation, where + Raw Gadget would not wait until the completion of each USB request. - Support USB 3 features (accept SS endpoint companion descriptor when - enabling endpoints; allow providing stream_id for bulk transfers). + enabling endpoints; allow providing ``stream_id`` for bulk transfers). -- Support ISO transfer features (expose frame_number for completed requests). +- Support ISO transfer features (expose ``frame_number`` for completed + requests). diff --git a/drivers/usb/gadget/legacy/Kconfig b/drivers/usb/gadget/legacy/Kconfig index f02c38b32a2b..11dd6e8adc8a 100644 --- a/drivers/usb/gadget/legacy/Kconfig +++ b/drivers/usb/gadget/legacy/Kconfig @@ -515,10 +515,15 @@ config USB_G_WEBCAM config USB_RAW_GADGET tristate "USB Raw Gadget" help - USB Raw Gadget is a kernel module that provides a userspace interface - for the USB Gadget subsystem. Essentially it allows to emulate USB - devices from userspace. See Documentation/usb/raw-gadget.rst for - details. + USB Raw Gadget is a gadget driver that gives userspace low-level + control over the gadget's communication process. + + Like any other gadget driver, Raw Gadget implements USB devices via + the USB gadget API. Unlike most gadget drivers, Raw Gadget does not + implement any concrete USB functions itself but requires userspace + to do that. + + See Documentation/usb/raw-gadget.rst for details. Say "y" to link the driver statically, or "m" to build a dynamically linked module called "raw_gadget". -- cgit v1.2.3 From 7961b77c0d489764166d789adb2c1d21b71b5aad Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Thu, 21 Jan 2021 13:42:49 +0100 Subject: dt-bindings: dwc3-xilinx: Add missing comma in example Trivial example fix. Signed-off-by: Michal Simek Link: https://lore.kernel.org/r/8fa5edcaa6b93859cfda97d080aad378e89c1b44.1611232967.git.michal.simek@xilinx.com Signed-off-by: Greg Kroah-Hartman --- Documentation/devicetree/bindings/usb/dwc3-xilinx.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/usb/dwc3-xilinx.txt b/Documentation/devicetree/bindings/usb/dwc3-xilinx.txt index 4aae5b2cef56..a668f43bedf5 100644 --- a/Documentation/devicetree/bindings/usb/dwc3-xilinx.txt +++ b/Documentation/devicetree/bindings/usb/dwc3-xilinx.txt @@ -19,7 +19,7 @@ Example device node: #address-cells = <0x2>; #size-cells = <0x1>; compatible = "xlnx,zynqmp-dwc3"; - clock-names = "bus_clk" "ref_clk"; + clock-names = "bus_clk", "ref_clk"; clocks = <&clk125>, <&clk125>; ranges; -- cgit v1.2.3 From 54c261891ced2566cdd5a54c84fcc94a7322912a Mon Sep 17 00:00:00 2001 From: Sakari Ailus Date: Wed, 13 Jan 2021 09:34:41 +0100 Subject: media: Documentation: media: Fix recently introduced build warning in subdev docs A reference to the sub-device pad ops was not follwed by a whitespace, resulting in a warning during documentation build. Fix it. Reported-by: Stephen Rothwell Fixes: 25c8d9a7689e ("media: Documentation: v4l: Document that link_validate op is valid for sink only") Signed-off-by: Sakari Ailus Signed-off-by: Mauro Carvalho Chehab --- Documentation/driver-api/media/v4l2-subdev.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Documentation') diff --git a/Documentation/driver-api/media/v4l2-subdev.rst b/Documentation/driver-api/media/v4l2-subdev.rst index 6d5c799c49fe..0e82c77cf3e2 100644 --- a/Documentation/driver-api/media/v4l2-subdev.rst +++ b/Documentation/driver-api/media/v4l2-subdev.rst @@ -123,7 +123,7 @@ Don't forget to cleanup the media entity before the sub-device is destroyed: media_entity_cleanup(&sd->entity); If a sub-device driver implements sink pads, the subdev driver may set the -link_validate field in :c:type:`v4l2_subdev_pad_ops`to provide its own link +link_validate field in :c:type:`v4l2_subdev_pad_ops` to provide its own link validation function. For every link in the pipeline, the link_validate pad operation of the sink end of the link is called. In both cases the driver is still responsible for validating the correctness of the format configuration -- cgit v1.2.3 From b3f82afc1041a6a7d5347a01883f4aab7ec133b2 Mon Sep 17 00:00:00 2001 From: Raphael Gianotti Date: Tue, 26 Jan 2021 11:14:53 -0800 Subject: IMA: Measure kernel version in early boot The integrity of a kernel can be verified by the boot loader on cold boot, and during kexec, by the current running kernel, before it is loaded. However, it is still possible that the new kernel being loaded is older than the current kernel, and/or has known vulnerabilities. Therefore, it is imperative that an attestation service be able to verify the version of the kernel being loaded on the client, from cold boot and subsequent kexec system calls, ensuring that only kernels with versions known to be good are loaded. Measure the kernel version using ima_measure_critical_data() early on in the boot sequence, reducing the chances of known kernel vulnerabilities being exploited. With IMA being part of the kernel, this overall approach makes the measurement itself more trustworthy. To enable measuring the kernel version "ima_policy=critical_data" needs to be added to the kernel command line arguments. For example, BOOT_IMAGE=/boot/vmlinuz-5.11.0-rc3+ root=UUID=fd643309-a5d2-4ed3-b10d-3c579a5fab2f ro nomodeset ima_policy=critical_data If runtime measurement of the kernel version is ever needed, the following should be added to /etc/ima/ima-policy: measure func=CRITICAL_DATA label=kernel_info To extract the measured data after boot, the following command can be used: grep -m 1 "kernel_version" \ /sys/kernel/security/integrity/ima/ascii_runtime_measurements Sample output from the command above: 10 a8297d408e9d5155728b619761d0dd4cedf5ef5f ima-buf sha256:5660e19945be0119bc19cbbf8d9c33a09935ab5d30dad48aa11f879c67d70988 kernel_version 352e31312e302d7263332d31363138372d676564623634666537383234342d6469727479 The above hex-ascii string corresponds to the kernel version (e.g. xxd -r -p): 5.11.0-rc3-16187-gedb64fe78244-dirty Signed-off-by: Raphael Gianotti Signed-off-by: Mimi Zohar --- Documentation/ABI/testing/ima_policy | 2 +- security/integrity/ima/ima_init.c | 5 +++++ 2 files changed, 6 insertions(+), 1 deletion(-) (limited to 'Documentation') diff --git a/Documentation/ABI/testing/ima_policy b/Documentation/ABI/testing/ima_policy index 8365596cb42b..bc8e1cbe5e61 100644 --- a/Documentation/ABI/testing/ima_policy +++ b/Documentation/ABI/testing/ima_policy @@ -52,7 +52,7 @@ Description: template:= name of a defined IMA template type (eg, ima-ng). Only valid when action is "measure". pcr:= decimal value - label:= [selinux]|[data_label] + label:= [selinux]|[kernel_info]|[data_label] data_label:= a unique string used for grouping and limiting critical data. For example, "selinux" to measure critical data for SELinux. diff --git a/security/integrity/ima/ima_init.c b/security/integrity/ima/ima_init.c index 4902fe7bd570..6e8742916d1d 100644 --- a/security/integrity/ima/ima_init.c +++ b/security/integrity/ima/ima_init.c @@ -15,6 +15,8 @@ #include #include #include +#include +#include #include "ima.h" @@ -147,5 +149,8 @@ int __init ima_init(void) ima_init_key_queue(); + ima_measure_critical_data("kernel_info", "kernel_version", + UTS_RELEASE, strlen(UTS_RELEASE), false); + return rc; } -- cgit v1.2.3 From 6b2e04bc240fe9be9e690059f710e9f95346d34d Mon Sep 17 00:00:00 2001 From: Praveen Chaudhary Date: Mon, 25 Jan 2021 13:44:30 -0800 Subject: net: allow user to set metric on default route learned via Router Advertisement For IPv4, default route is learned via DHCPv4 and user is allowed to change metric using config etc/network/interfaces. But for IPv6, default route can be learned via RA, for which, currently a fixed metric value 1024 is used. Ideally, user should be able to configure metric on default route for IPv6 similar to IPv4. This patch adds sysctl for the same. Logs: For IPv4: Config in etc/network/interfaces: auto eth0 iface eth0 inet dhcp metric 4261413864 IPv4 Kernel Route Table: $ ip route list default via 172.21.47.1 dev eth0 metric 4261413864 FRR Table, if a static route is configured: [In real scenario, it is useful to prefer BGP learned default route over DHCPv4 default route.] Codes: K - kernel route, C - connected, S - static, R - RIP, O - OSPF, I - IS-IS, B - BGP, P - PIM, E - EIGRP, N - NHRP, T - Table, v - VNC, V - VNC-Direct, A - Babel, D - SHARP, > - selected route, * - FIB route S>* 0.0.0.0/0 [20/0] is directly connected, eth0, 00:00:03 K 0.0.0.0/0 [254/1000] via 172.21.47.1, eth0, 6d08h51m i.e. User can prefer Default Router learned via Routing Protocol in IPv4. Similar behavior is not possible for IPv6, without this fix. After fix [for IPv6]: sudo sysctl -w net.ipv6.conf.eth0.net.ipv6.conf.eth0.ra_defrtr_metric=1996489705 IP monitor: [When IPv6 RA is received] default via fe80::xx16:xxxx:feb3:ce8e dev eth0 proto ra metric 1996489705 pref high Kernel IPv6 routing table $ ip -6 route list default via fe80::be16:65ff:feb3:ce8e dev eth0 proto ra metric 1996489705 expires 21sec hoplimit 64 pref high FRR Table, if a static route is configured: [In real scenario, it is useful to prefer BGP learned default route over IPv6 RA default route.] Codes: K - kernel route, C - connected, S - static, R - RIPng, O - OSPFv3, I - IS-IS, B - BGP, N - NHRP, T - Table, v - VNC, V - VNC-Direct, A - Babel, D - SHARP, > - selected route, * - FIB route S>* ::/0 [20/0] is directly connected, eth0, 00:00:06 K ::/0 [119/1001] via fe80::xx16:xxxx:feb3:ce8e, eth0, 6d07h43m If the metric is changed later, the effect will be seen only when next IPv6 RA is received, because the default route must be fully controlled by RA msg. Below metric is changed from 1996489705 to 1996489704. $ sudo sysctl -w net.ipv6.conf.eth0.ra_defrtr_metric=1996489704 net.ipv6.conf.eth0.ra_defrtr_metric = 1996489704 IP monitor: [On next IPv6 RA msg, Kernel deletes prev route and installs new route with updated metric] Deleted default via fe80::xx16:xxxx:feb3:ce8e dev eth0 proto ra metric 1996489705 expires 3sec hoplimit 64 pref high default via fe80::xx16:xxxx:feb3:ce8e dev eth0 proto ra metric 1996489704 pref high Signed-off-by: Praveen Chaudhary Signed-off-by: Zhenggen Xu Reviewed-by: David Ahern Link: https://lore.kernel.org/r/20210125214430.24079-1-pchaudhary@linkedin.com Signed-off-by: Jakub Kicinski --- Documentation/networking/ip-sysctl.rst | 10 ++++++++++ include/linux/ipv6.h | 1 + include/net/ip6_route.h | 3 ++- include/uapi/linux/ipv6.h | 1 + include/uapi/linux/sysctl.h | 1 + net/ipv6/addrconf.c | 11 +++++++++++ net/ipv6/ndisc.c | 12 ++++++++---- net/ipv6/route.c | 5 +++-- 8 files changed, 37 insertions(+), 7 deletions(-) (limited to 'Documentation') diff --git a/Documentation/networking/ip-sysctl.rst b/Documentation/networking/ip-sysctl.rst index dd2b12a32b73..0e51ddd9a2f1 100644 --- a/Documentation/networking/ip-sysctl.rst +++ b/Documentation/networking/ip-sysctl.rst @@ -1871,6 +1871,16 @@ accept_ra_defrtr - BOOLEAN - enabled if accept_ra is enabled. - disabled if accept_ra is disabled. +ra_defrtr_metric - UNSIGNED INTEGER + Route metric for default route learned in Router Advertisement. This value + will be assigned as metric for the default route learned via IPv6 Router + Advertisement. Takes affect only if accept_ra_defrtr is enabled. + + Possible values: + 1 to 0xFFFFFFFF + + Default: IP6_RT_PRIO_USER i.e. 1024. + accept_ra_from_local - BOOLEAN Accept RA with source-address that is found on local machine if the RA is otherwise proper and able to be accepted. diff --git a/include/linux/ipv6.h b/include/linux/ipv6.h index dda61d150a13..9d1f29f0c512 100644 --- a/include/linux/ipv6.h +++ b/include/linux/ipv6.h @@ -31,6 +31,7 @@ struct ipv6_devconf { __s32 max_desync_factor; __s32 max_addresses; __s32 accept_ra_defrtr; + __u32 ra_defrtr_metric; __s32 accept_ra_min_hop_limit; __s32 accept_ra_pinfo; __s32 ignore_routes_with_linkdown; diff --git a/include/net/ip6_route.h b/include/net/ip6_route.h index 2a5277758379..f51a118bfce8 100644 --- a/include/net/ip6_route.h +++ b/include/net/ip6_route.h @@ -174,7 +174,8 @@ struct fib6_info *rt6_get_dflt_router(struct net *net, struct net_device *dev); struct fib6_info *rt6_add_dflt_router(struct net *net, const struct in6_addr *gwaddr, - struct net_device *dev, unsigned int pref); + struct net_device *dev, unsigned int pref, + u32 defrtr_usr_metric); void rt6_purge_dflt_routers(struct net *net); diff --git a/include/uapi/linux/ipv6.h b/include/uapi/linux/ipv6.h index 13e8751bf24a..70603775fe91 100644 --- a/include/uapi/linux/ipv6.h +++ b/include/uapi/linux/ipv6.h @@ -189,6 +189,7 @@ enum { DEVCONF_ACCEPT_RA_RT_INFO_MIN_PLEN, DEVCONF_NDISC_TCLASS, DEVCONF_RPL_SEG_ENABLED, + DEVCONF_RA_DEFRTR_METRIC, DEVCONF_MAX }; diff --git a/include/uapi/linux/sysctl.h b/include/uapi/linux/sysctl.h index 458179df9b27..1e05d3caa712 100644 --- a/include/uapi/linux/sysctl.h +++ b/include/uapi/linux/sysctl.h @@ -571,6 +571,7 @@ enum { NET_IPV6_ACCEPT_SOURCE_ROUTE=25, NET_IPV6_ACCEPT_RA_FROM_LOCAL=26, NET_IPV6_ACCEPT_RA_RT_INFO_MIN_PLEN=27, + NET_IPV6_RA_DEFRTR_METRIC=28, __NET_IPV6_MAX }; diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c index 9edc5bb2d531..f2337fb756ac 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c @@ -205,6 +205,7 @@ static struct ipv6_devconf ipv6_devconf __read_mostly = { .max_desync_factor = MAX_DESYNC_FACTOR, .max_addresses = IPV6_MAX_ADDRESSES, .accept_ra_defrtr = 1, + .ra_defrtr_metric = IP6_RT_PRIO_USER, .accept_ra_from_local = 0, .accept_ra_min_hop_limit= 1, .accept_ra_pinfo = 1, @@ -260,6 +261,7 @@ static struct ipv6_devconf ipv6_devconf_dflt __read_mostly = { .max_desync_factor = MAX_DESYNC_FACTOR, .max_addresses = IPV6_MAX_ADDRESSES, .accept_ra_defrtr = 1, + .ra_defrtr_metric = IP6_RT_PRIO_USER, .accept_ra_from_local = 0, .accept_ra_min_hop_limit= 1, .accept_ra_pinfo = 1, @@ -5476,6 +5478,7 @@ static inline void ipv6_store_devconf(struct ipv6_devconf *cnf, array[DEVCONF_MAX_DESYNC_FACTOR] = cnf->max_desync_factor; array[DEVCONF_MAX_ADDRESSES] = cnf->max_addresses; array[DEVCONF_ACCEPT_RA_DEFRTR] = cnf->accept_ra_defrtr; + array[DEVCONF_RA_DEFRTR_METRIC] = cnf->ra_defrtr_metric; array[DEVCONF_ACCEPT_RA_MIN_HOP_LIMIT] = cnf->accept_ra_min_hop_limit; array[DEVCONF_ACCEPT_RA_PINFO] = cnf->accept_ra_pinfo; #ifdef CONFIG_IPV6_ROUTER_PREF @@ -6668,6 +6671,14 @@ static const struct ctl_table addrconf_sysctl[] = { .mode = 0644, .proc_handler = proc_dointvec, }, + { + .procname = "ra_defrtr_metric", + .data = &ipv6_devconf.ra_defrtr_metric, + .maxlen = sizeof(u32), + .mode = 0644, + .proc_handler = proc_douintvec_minmax, + .extra1 = (void *)SYSCTL_ONE, + }, { .procname = "accept_ra_min_hop_limit", .data = &ipv6_devconf.accept_ra_min_hop_limit, diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c index 76717478f173..c467c6419893 100644 --- a/net/ipv6/ndisc.c +++ b/net/ipv6/ndisc.c @@ -1173,6 +1173,7 @@ static void ndisc_router_discovery(struct sk_buff *skb) struct neighbour *neigh = NULL; struct inet6_dev *in6_dev; struct fib6_info *rt = NULL; + u32 defrtr_usr_metric; struct net *net; int lifetime; struct ndisc_options ndopts; @@ -1303,18 +1304,21 @@ static void ndisc_router_discovery(struct sk_buff *skb) return; } } - if (rt && lifetime == 0) { + /* Set default route metric as specified by user */ + defrtr_usr_metric = in6_dev->cnf.ra_defrtr_metric; + /* delete the route if lifetime is 0 or if metric needs change */ + if (rt && (lifetime == 0 || rt->fib6_metric != defrtr_usr_metric)) { ip6_del_rt(net, rt, false); rt = NULL; } - ND_PRINTK(3, info, "RA: rt: %p lifetime: %d, for dev: %s\n", - rt, lifetime, skb->dev->name); + ND_PRINTK(3, info, "RA: rt: %p lifetime: %d, metric: %d, for dev: %s\n", + rt, lifetime, defrtr_usr_metric, skb->dev->name); if (!rt && lifetime) { ND_PRINTK(3, info, "RA: adding default router\n"); rt = rt6_add_dflt_router(net, &ipv6_hdr(skb)->saddr, - skb->dev, pref); + skb->dev, pref, defrtr_usr_metric); if (!rt) { ND_PRINTK(0, err, "RA: %s failed to add default route\n", diff --git a/net/ipv6/route.c b/net/ipv6/route.c index 188e114b29b4..41d8f801b75f 100644 --- a/net/ipv6/route.c +++ b/net/ipv6/route.c @@ -4252,11 +4252,12 @@ struct fib6_info *rt6_get_dflt_router(struct net *net, struct fib6_info *rt6_add_dflt_router(struct net *net, const struct in6_addr *gwaddr, struct net_device *dev, - unsigned int pref) + unsigned int pref, + u32 defrtr_usr_metric) { struct fib6_config cfg = { .fc_table = l3mdev_fib_table(dev) ? : RT6_TABLE_DFLT, - .fc_metric = IP6_RT_PRIO_USER, + .fc_metric = defrtr_usr_metric, .fc_ifindex = dev->ifindex, .fc_flags = RTF_GATEWAY | RTF_ADDRCONF | RTF_DEFAULT | RTF_UP | RTF_EXPIRES | RTF_PREF(pref), -- cgit v1.2.3 From acda36189cb8df27ef073d391ebd67c64ac36cf9 Mon Sep 17 00:00:00 2001 From: Manivannan Sadhasivam Date: Wed, 27 Jan 2021 13:11:33 +0200 Subject: dt-bindings: interconnect: Add Qualcomm SDX55 DT bindings The Qualcomm SDX55 platform has several bus fabrics that could be controlled and tuned dynamically over RPMh according to the bandwidth demand. Signed-off-by: Manivannan Sadhasivam Link: https://lore.kernel.org/r/20210121053254.8355-2-manivannan.sadhasivam@linaro.org Signed-off-by: Georgi Djakov --- .../bindings/interconnect/qcom,rpmh.yaml | 4 ++ include/dt-bindings/interconnect/qcom,sdx55.h | 76 ++++++++++++++++++++++ 2 files changed, 80 insertions(+) create mode 100644 include/dt-bindings/interconnect/qcom,sdx55.h (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/interconnect/qcom,rpmh.yaml b/Documentation/devicetree/bindings/interconnect/qcom,rpmh.yaml index 30c2a092d2d3..f9b150b817d8 100644 --- a/Documentation/devicetree/bindings/interconnect/qcom,rpmh.yaml +++ b/Documentation/devicetree/bindings/interconnect/qcom,rpmh.yaml @@ -45,6 +45,10 @@ properties: - qcom,sdm845-mem-noc - qcom,sdm845-mmss-noc - qcom,sdm845-system-noc + - qcom,sdx55-ipa-virt + - qcom,sdx55-mc-virt + - qcom,sdx55-mem-noc + - qcom,sdx55-system-noc - qcom,sm8150-aggre1-noc - qcom,sm8150-aggre2-noc - qcom,sm8150-camnoc-noc diff --git a/include/dt-bindings/interconnect/qcom,sdx55.h b/include/dt-bindings/interconnect/qcom,sdx55.h new file mode 100644 index 000000000000..bfb6524a2d90 --- /dev/null +++ b/include/dt-bindings/interconnect/qcom,sdx55.h @@ -0,0 +1,76 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Qualcomm SDX55 interconnect IDs + * + * Copyright (c) 2021, Linaro Ltd. + * Author: Manivannan Sadhasivam + */ + +#ifndef __DT_BINDINGS_INTERCONNECT_QCOM_SDX55_H +#define __DT_BINDINGS_INTERCONNECT_QCOM_SDX55_H + +#define MASTER_LLCC 0 +#define SLAVE_EBI_CH0 1 + +#define MASTER_TCU_0 0 +#define MASTER_SNOC_GC_MEM_NOC 1 +#define MASTER_AMPSS_M0 2 +#define SLAVE_LLCC 3 +#define SLAVE_MEM_NOC_SNOC 4 +#define SLAVE_MEM_NOC_PCIE_SNOC 5 + +#define MASTER_AUDIO 0 +#define MASTER_BLSP_1 1 +#define MASTER_QDSS_BAM 2 +#define MASTER_QPIC 3 +#define MASTER_SNOC_CFG 4 +#define MASTER_SPMI_FETCHER 5 +#define MASTER_ANOC_SNOC 6 +#define MASTER_IPA 7 +#define MASTER_MEM_NOC_SNOC 8 +#define MASTER_MEM_NOC_PCIE_SNOC 9 +#define MASTER_CRYPTO_CORE_0 10 +#define MASTER_EMAC 11 +#define MASTER_IPA_PCIE 12 +#define MASTER_PCIE 13 +#define MASTER_QDSS_ETR 14 +#define MASTER_SDCC_1 15 +#define MASTER_USB3 16 +#define SLAVE_AOP 17 +#define SLAVE_AOSS 18 +#define SLAVE_APPSS 19 +#define SLAVE_AUDIO 20 +#define SLAVE_BLSP_1 21 +#define SLAVE_CLK_CTL 22 +#define SLAVE_CRYPTO_0_CFG 23 +#define SLAVE_CNOC_DDRSS 24 +#define SLAVE_ECC_CFG 25 +#define SLAVE_EMAC_CFG 26 +#define SLAVE_IMEM_CFG 27 +#define SLAVE_IPA_CFG 28 +#define SLAVE_CNOC_MSS 29 +#define SLAVE_PCIE_PARF 30 +#define SLAVE_PDM 31 +#define SLAVE_PRNG 32 +#define SLAVE_QDSS_CFG 33 +#define SLAVE_QPIC 34 +#define SLAVE_SDCC_1 35 +#define SLAVE_SNOC_CFG 36 +#define SLAVE_SPMI_FETCHER 37 +#define SLAVE_SPMI_VGI_COEX 38 +#define SLAVE_TCSR 39 +#define SLAVE_TLMM 40 +#define SLAVE_USB3 41 +#define SLAVE_USB3_PHY_CFG 42 +#define SLAVE_ANOC_SNOC 43 +#define SLAVE_SNOC_MEM_NOC_GC 44 +#define SLAVE_OCIMEM 45 +#define SLAVE_SERVICE_SNOC 46 +#define SLAVE_PCIE_0 47 +#define SLAVE_QDSS_STM 48 +#define SLAVE_TCU 49 + +#define MASTER_IPA_CORE 0 +#define SLAVE_IPA_CORE 1 + +#endif -- cgit v1.2.3 From cae2181b498fe52885022772465a7610fd7701f4 Mon Sep 17 00:00:00 2001 From: Samuel Thibault Date: Tue, 26 Jan 2021 23:21:47 +0100 Subject: speakup: Add documentation on changing the speakup messages language This documents how to use speakup_setlocale to set the speakup messages language. Signed-off-by: Samuel Thibault Link: https://lore.kernel.org/r/20210126222147.3848175-5-samuel.thibault@ens-lyon.org Signed-off-by: Greg Kroah-Hartman --- Documentation/admin-guide/spkguide.txt | 48 ++++++++++++++++++++++++++++++++-- 1 file changed, 46 insertions(+), 2 deletions(-) (limited to 'Documentation') diff --git a/Documentation/admin-guide/spkguide.txt b/Documentation/admin-guide/spkguide.txt index 5ff6a0fe87d1..977ab3f5a0a8 100644 --- a/Documentation/admin-guide/spkguide.txt +++ b/Documentation/admin-guide/spkguide.txt @@ -1033,7 +1033,9 @@ speakup + keypad 3, you would hear: The speakup key is depressed, so the name of the key state is speakup. This part of the message comes from the states collection. -14.2. Loading Your Own Messages +14.2. Changing language + +14.2.1. Loading Your Own Messages The files under the i18n subdirectory all follow the same format. They consist of lines, with one message per line. @@ -1066,8 +1068,50 @@ echo '1 azul' > /speakup/i18n/colors The next time that Speakup says message 1 from the colors group, it will say "azul", rather than "blue." +14.2.2. Choose a language + In the future, translations into various languages will be made available, -and most users will just load the files necessary for their language. +and most users will just load the files necessary for their language. So far, +only French language is available beyond native Canadian English language. + +French is only available after you are logged in. + +Canadian English is the default language. To toggle another language, +download the source of Speakup and untar it in your home directory. The +following command should let you do this: + +tar xvjf speakup-.tar.bz2 + +where is the version number of the application. + +Next, change to the newly created directory, then into the tools/ directory, and +run the script speakup_setlocale. You are asked the language that you want to +use. Type the number associated to your language (e.g. fr for French) then press +Enter. Needed files are copied in the i18n directory. + +Note: the speakupconf must be installed on your system so that settings are saved. +Otherwise, you will have an error: your language will be loaded but you will +have to run the script again every time Speakup restarts. +See section 16.1. for information about speakupconf. + +You will have to repeat these steps for any change of locale, i.e. if you wish +change the speakup's language or charset (iso-8859-15 ou UTF-8). + +If you wish store the settings, note that at your next login, you will need to +do: + +speakup load + +Alternatively, you can add the above line to your file +~/.bashrc or ~/.bash_profile. + +If your system administrator ran himself the script, all the users will be able +to change from English to the language choosed by root and do directly +speakupconf load (or add this to the ~/.bashrc or +~/.bash_profile file). If there are several languages to handle, the +administrator (or every user) will have to run the first steps until speakupconf +save, choosing the appropriate language, in every user's home directory. Every +user will then be able to do speakupconf load, Speakup will load his own settings. 14.3. No Support for Non-Western-European Languages -- cgit v1.2.3 From 8ba59e9dee31246fc34b4d4bec032093e9c06510 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Fri, 22 Jan 2021 13:43:58 +0200 Subject: misc: pti: Remove driver for deprecated platform Intel Moorestown and Medfield are quite old Intel Atom based 32-bit platforms, which were in limited use in some Android phones, tablets and consumer electronics more than eight years ago. There are no bugs or problems ever reported outside from Intel for breaking any of that platforms for years. It seems no real users exists who run more or less fresh kernel on it. The commit 05f4434bc130 ("ASoC: Intel: remove mfld_machine") also in align with this theory. Due to above and to reduce a burden of supporting outdated drivers we remove the support of outdated platforms completely. Cc: Alexander Shishkin Acked-by: Linus Walleij Acked-by: Arnd Bergmann Acked-by: Alexander Shishkin Signed-off-by: Andy Shevchenko Link: https://lore.kernel.org/r/20210122114358.39299-1-andriy.shevchenko@linux.intel.com Signed-off-by: Greg Kroah-Hartman --- Documentation/driver-api/pti_intel_mid.rst | 108 ---- drivers/misc/Kconfig | 13 - drivers/misc/Makefile | 1 - drivers/misc/pti.c | 978 ----------------------------- drivers/tty/Makefile | 2 - drivers/tty/n_tracerouter.c | 233 ------- drivers/tty/n_tracesink.c | 228 ------- drivers/tty/n_tracesink.h | 26 - include/linux/intel-pti.h | 35 -- 9 files changed, 1624 deletions(-) delete mode 100644 Documentation/driver-api/pti_intel_mid.rst delete mode 100644 drivers/misc/pti.c delete mode 100644 drivers/tty/n_tracerouter.c delete mode 100644 drivers/tty/n_tracesink.c delete mode 100644 drivers/tty/n_tracesink.h delete mode 100644 include/linux/intel-pti.h (limited to 'Documentation') diff --git a/Documentation/driver-api/pti_intel_mid.rst b/Documentation/driver-api/pti_intel_mid.rst deleted file mode 100644 index bacc2a4ee89f..000000000000 --- a/Documentation/driver-api/pti_intel_mid.rst +++ /dev/null @@ -1,108 +0,0 @@ -.. SPDX-License-Identifier: GPL-2.0 - -============= -Intel MID PTI -============= - -The Intel MID PTI project is HW implemented in Intel Atom -system-on-a-chip designs based on the Parallel Trace -Interface for MIPI P1149.7 cJTAG standard. The kernel solution -for this platform involves the following files:: - - ./include/linux/pti.h - ./drivers/.../n_tracesink.h - ./drivers/.../n_tracerouter.c - ./drivers/.../n_tracesink.c - ./drivers/.../pti.c - -pti.c is the driver that enables various debugging features -popular on platforms from certain mobile manufacturers. -n_tracerouter.c and n_tracesink.c allow extra system information to -be collected and routed to the pti driver, such as trace -debugging data from a modem. Although n_tracerouter -and n_tracesink are a part of the complete PTI solution, -these two line disciplines can work separately from -pti.c and route any data stream from one /dev/tty node -to another /dev/tty node via kernel-space. This provides -a stable, reliable connection that will not break unless -the user-space application shuts down (plus avoids -kernel->user->kernel context switch overheads of routing -data). - -An example debugging usage for this driver system: - - * Hook /dev/ttyPTI0 to syslogd. Opening this port will also start - a console device to further capture debugging messages to PTI. - * Hook /dev/ttyPTI1 to modem debugging data to write to PTI HW. - This is where n_tracerouter and n_tracesink are used. - * Hook /dev/pti to a user-level debugging application for writing - to PTI HW. - * `Use mipi_` Kernel Driver API in other device drivers for - debugging to PTI by first requesting a PTI write address via - mipi_request_masterchannel(1). - -Below is example pseudo-code on how a 'privileged' application -can hook up n_tracerouter and n_tracesink to any tty on -a system. 'Privileged' means the application has enough -privileges to successfully manipulate the ldisc drivers -but is not just blindly executing as 'root'. Keep in mind -the use of ioctl(,TIOCSETD,) is not specific to the n_tracerouter -and n_tracesink line discpline drivers but is a generic -operation for a program to use a line discpline driver -on a tty port other than the default n_tty: - -.. code-block:: c - - /////////// To hook up n_tracerouter and n_tracesink ///////// - - // Note that n_tracerouter depends on n_tracesink. - #include - #define ONE_TTY "/dev/ttyOne" - #define TWO_TTY "/dev/ttyTwo" - - // needed global to hand onto ldisc connection - static int g_fd_source = -1; - static int g_fd_sink = -1; - - // these two vars used to grab LDISC values from loaded ldisc drivers - // in OS. Look at /proc/tty/ldiscs to get the right numbers from - // the ldiscs loaded in the system. - int source_ldisc_num, sink_ldisc_num = -1; - int retval; - - g_fd_source = open(ONE_TTY, O_RDWR); // must be R/W - g_fd_sink = open(TWO_TTY, O_RDWR); // must be R/W - - if (g_fd_source <= 0) || (g_fd_sink <= 0) { - // doubt you'll want to use these exact error lines of code - printf("Error on open(). errno: %d\n",errno); - return errno; - } - - retval = ioctl(g_fd_sink, TIOCSETD, &sink_ldisc_num); - if (retval < 0) { - printf("Error on ioctl(). errno: %d\n", errno); - return errno; - } - - retval = ioctl(g_fd_source, TIOCSETD, &source_ldisc_num); - if (retval < 0) { - printf("Error on ioctl(). errno: %d\n", errno); - return errno; - } - - /////////// To disconnect n_tracerouter and n_tracesink //////// - - // First make sure data through the ldiscs has stopped. - - // Second, disconnect ldiscs. This provides a - // little cleaner shutdown on tty stack. - sink_ldisc_num = 0; - source_ldisc_num = 0; - ioctl(g_fd_uart, TIOCSETD, &sink_ldisc_num); - ioctl(g_fd_gadget, TIOCSETD, &source_ldisc_num); - - // Three, program closes connection, and cleanup: - close(g_fd_uart); - close(g_fd_gadget); - g_fd_uart = g_fd_gadget = NULL; diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig index 8085213913cc..f532c59bb59b 100644 --- a/drivers/misc/Kconfig +++ b/drivers/misc/Kconfig @@ -104,19 +104,6 @@ config PHANTOM If you choose to build module, its name will be phantom. If unsure, say N here. -config INTEL_MID_PTI - tristate "Parallel Trace Interface for MIPI P1149.7 cJTAG standard" - depends on PCI && TTY && (X86_INTEL_MID || COMPILE_TEST) - help - The PTI (Parallel Trace Interface) driver directs - trace data routed from various parts in the system out - through an Intel Penwell PTI port and out of the mobile - device for analysis with a debugging tool (Lauterbach or Fido). - - You should select this driver if the target kernel is meant for - an Intel Atom (non-netbook) mobile device containing a MIPI - P1149.7 standard implementation. - config TIFM_CORE tristate "TI Flash Media interface support" depends on PCI diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile index 456aa8a4c896..99b6f15a3c70 100644 --- a/drivers/misc/Makefile +++ b/drivers/misc/Makefile @@ -8,7 +8,6 @@ obj-$(CONFIG_IBMVMC) += ibmvmc.o obj-$(CONFIG_AD525X_DPOT) += ad525x_dpot.o obj-$(CONFIG_AD525X_DPOT_I2C) += ad525x_dpot-i2c.o obj-$(CONFIG_AD525X_DPOT_SPI) += ad525x_dpot-spi.o -obj-$(CONFIG_INTEL_MID_PTI) += pti.o obj-$(CONFIG_ATMEL_SSC) += atmel-ssc.o obj-$(CONFIG_DUMMY_IRQ) += dummy-irq.o obj-$(CONFIG_ICS932S401) += ics932s401.o diff --git a/drivers/misc/pti.c b/drivers/misc/pti.c deleted file mode 100644 index 7236ae527b19..000000000000 --- a/drivers/misc/pti.c +++ /dev/null @@ -1,978 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * pti.c - PTI driver for cJTAG data extration - * - * Copyright (C) Intel 2010 - * - * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - * - * The PTI (Parallel Trace Interface) driver directs trace data routed from - * various parts in the system out through the Intel Penwell PTI port and - * out of the mobile device for analysis with a debugging tool - * (Lauterbach, Fido). This is part of a solution for the MIPI P1149.7, - * compact JTAG, standard. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define DRIVERNAME "pti" -#define PCINAME "pciPTI" -#define TTYNAME "ttyPTI" -#define CHARNAME "pti" -#define PTITTY_MINOR_START 0 -#define PTITTY_MINOR_NUM 2 -#define MAX_APP_IDS 16 /* 128 channel ids / u8 bit size */ -#define MAX_OS_IDS 16 /* 128 channel ids / u8 bit size */ -#define MAX_MODEM_IDS 16 /* 128 channel ids / u8 bit size */ -#define MODEM_BASE_ID 71 /* modem master ID address */ -#define CONTROL_ID 72 /* control master ID address */ -#define CONSOLE_ID 73 /* console master ID address */ -#define OS_BASE_ID 74 /* base OS master ID address */ -#define APP_BASE_ID 80 /* base App master ID address */ -#define CONTROL_FRAME_LEN 32 /* PTI control frame maximum size */ -#define USER_COPY_SIZE 8192 /* 8Kb buffer for user space copy */ -#define APERTURE_14 0x3800000 /* offset to first OS write addr */ -#define APERTURE_LEN 0x400000 /* address length */ - -struct pti_tty { - struct pti_masterchannel *mc; -}; - -struct pti_dev { - struct tty_port port[PTITTY_MINOR_NUM]; - unsigned long pti_addr; - unsigned long aperture_base; - void __iomem *pti_ioaddr; - u8 ia_app[MAX_APP_IDS]; - u8 ia_os[MAX_OS_IDS]; - u8 ia_modem[MAX_MODEM_IDS]; -}; - -/* - * This protects access to ia_app, ia_os, and ia_modem, - * which keeps track of channels allocated in - * an aperture write id. - */ -static DEFINE_MUTEX(alloclock); - -static const struct pci_device_id pci_ids[] = { - {PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x82B)}, - {0} -}; - -static struct tty_driver *pti_tty_driver; -static struct pti_dev *drv_data; - -static unsigned int pti_console_channel; -static unsigned int pti_control_channel; - -/** - * pti_write_to_aperture()- The private write function to PTI HW. - * - * @mc: The 'aperture'. It's part of a write address that holds - * a master and channel ID. - * @buf: Data being written to the HW that will ultimately be seen - * in a debugging tool (Fido, Lauterbach). - * @len: Size of buffer. - * - * Since each aperture is specified by a unique - * master/channel ID, no two processes will be writing - * to the same aperture at the same time so no lock is required. The - * PTI-Output agent will send these out in the order that they arrived, and - * thus, it will intermix these messages. The debug tool can then later - * regroup the appropriate message segments together reconstituting each - * message. - */ -static void pti_write_to_aperture(struct pti_masterchannel *mc, - u8 *buf, - int len) -{ - int dwordcnt; - int final; - int i; - u32 ptiword; - u32 __iomem *aperture; - u8 *p = buf; - - /* - * calculate the aperture offset from the base using the master and - * channel id's. - */ - aperture = drv_data->pti_ioaddr + (mc->master << 15) - + (mc->channel << 8); - - dwordcnt = len >> 2; - final = len - (dwordcnt << 2); /* final = trailing bytes */ - if (final == 0 && dwordcnt != 0) { /* always need a final dword */ - final += 4; - dwordcnt--; - } - - for (i = 0; i < dwordcnt; i++) { - ptiword = be32_to_cpu(*(u32 *)p); - p += 4; - iowrite32(ptiword, aperture); - } - - aperture += PTI_LASTDWORD_DTS; /* adding DTS signals that is EOM */ - - ptiword = 0; - for (i = 0; i < final; i++) - ptiword |= *p++ << (24-(8*i)); - - iowrite32(ptiword, aperture); - return; -} - -/** - * pti_control_frame_built_and_sent()- control frame build and send function. - * - * @mc: The master / channel structure on which the function - * built a control frame. - * @thread_name: The thread name associated with the master / channel or - * 'NULL' if using the 'current' global variable. - * - * To be able to post process the PTI contents on host side, a control frame - * is added before sending any PTI content. So the host side knows on - * each PTI frame the name of the thread using a dedicated master / channel. - * The thread name is retrieved from 'current' global variable if 'thread_name' - * is 'NULL', else it is retrieved from 'thread_name' parameter. - * This function builds this frame and sends it to a master ID CONTROL_ID. - * The overhead is only 32 bytes since the driver only writes to HW - * in 32 byte chunks. - */ -static void pti_control_frame_built_and_sent(struct pti_masterchannel *mc, - const char *thread_name) -{ - /* - * Since we access the comm member in current's task_struct, we only - * need to be as large as what 'comm' in that structure is. - */ - char comm[TASK_COMM_LEN]; - struct pti_masterchannel mccontrol = {.master = CONTROL_ID, - .channel = 0}; - const char *thread_name_p; - const char *control_format = "%3d %3d %s"; - u8 control_frame[CONTROL_FRAME_LEN]; - - if (!thread_name) { - if (!in_interrupt()) - get_task_comm(comm, current); - else - strncpy(comm, "Interrupt", TASK_COMM_LEN); - - /* Absolutely ensure our buffer is zero terminated. */ - comm[TASK_COMM_LEN-1] = 0; - thread_name_p = comm; - } else { - thread_name_p = thread_name; - } - - mccontrol.channel = pti_control_channel; - pti_control_channel = (pti_control_channel + 1) & 0x7f; - - snprintf(control_frame, CONTROL_FRAME_LEN, control_format, mc->master, - mc->channel, thread_name_p); - pti_write_to_aperture(&mccontrol, control_frame, strlen(control_frame)); -} - -/** - * pti_write_full_frame_to_aperture()- high level function to - * write to PTI. - * - * @mc: The 'aperture'. It's part of a write address that holds - * a master and channel ID. - * @buf: Data being written to the HW that will ultimately be seen - * in a debugging tool (Fido, Lauterbach). - * @len: Size of buffer. - * - * All threads sending data (either console, user space application, ...) - * are calling the high level function to write to PTI meaning that it is - * possible to add a control frame before sending the content. - */ -static void pti_write_full_frame_to_aperture(struct pti_masterchannel *mc, - const unsigned char *buf, - int len) -{ - pti_control_frame_built_and_sent(mc, NULL); - pti_write_to_aperture(mc, (u8 *)buf, len); -} - -/** - * get_id()- Allocate a master and channel ID. - * - * @id_array: an array of bits representing what channel - * id's are allocated for writing. - * @max_ids: The max amount of available write IDs to use. - * @base_id: The starting SW channel ID, based on the Intel - * PTI arch. - * @thread_name: The thread name associated with the master / channel or - * 'NULL' if using the 'current' global variable. - * - * Returns: - * pti_masterchannel struct with master, channel ID address - * 0 for error - * - * Each bit in the arrays ia_app and ia_os correspond to a master and - * channel id. The bit is one if the id is taken and 0 if free. For - * every master there are 128 channel id's. - */ -static struct pti_masterchannel *get_id(u8 *id_array, - int max_ids, - int base_id, - const char *thread_name) -{ - struct pti_masterchannel *mc; - int i, j, mask; - - mc = kmalloc(sizeof(struct pti_masterchannel), GFP_KERNEL); - if (mc == NULL) - return NULL; - - /* look for a byte with a free bit */ - for (i = 0; i < max_ids; i++) - if (id_array[i] != 0xff) - break; - if (i == max_ids) { - kfree(mc); - return NULL; - } - /* find the bit in the 128 possible channel opportunities */ - mask = 0x80; - for (j = 0; j < 8; j++) { - if ((id_array[i] & mask) == 0) - break; - mask >>= 1; - } - - /* grab it */ - id_array[i] |= mask; - mc->master = base_id; - mc->channel = ((i & 0xf)<<3) + j; - /* write new master Id / channel Id allocation to channel control */ - pti_control_frame_built_and_sent(mc, thread_name); - return mc; -} - -/* - * The following three functions: - * pti_request_mastercahannel(), mipi_release_masterchannel() - * and pti_writedata() are an API for other kernel drivers to - * access PTI. - */ - -/** - * pti_request_masterchannel()- Kernel API function used to allocate - * a master, channel ID address - * to write to PTI HW. - * - * @type: 0- request Application master, channel aperture ID - * write address. - * 1- request OS master, channel aperture ID write - * address. - * 2- request Modem master, channel aperture ID - * write address. - * Other values, error. - * @thread_name: The thread name associated with the master / channel or - * 'NULL' if using the 'current' global variable. - * - * Returns: - * pti_masterchannel struct - * 0 for error - */ -struct pti_masterchannel *pti_request_masterchannel(u8 type, - const char *thread_name) -{ - struct pti_masterchannel *mc; - - mutex_lock(&alloclock); - - switch (type) { - - case 0: - mc = get_id(drv_data->ia_app, MAX_APP_IDS, - APP_BASE_ID, thread_name); - break; - - case 1: - mc = get_id(drv_data->ia_os, MAX_OS_IDS, - OS_BASE_ID, thread_name); - break; - - case 2: - mc = get_id(drv_data->ia_modem, MAX_MODEM_IDS, - MODEM_BASE_ID, thread_name); - break; - default: - mc = NULL; - } - - mutex_unlock(&alloclock); - return mc; -} -EXPORT_SYMBOL_GPL(pti_request_masterchannel); - -/** - * pti_release_masterchannel()- Kernel API function used to release - * a master, channel ID address - * used to write to PTI HW. - * - * @mc: master, channel apeture ID address to be released. This - * will de-allocate the structure via kfree(). - */ -void pti_release_masterchannel(struct pti_masterchannel *mc) -{ - u8 master, channel, i; - - mutex_lock(&alloclock); - - if (mc) { - master = mc->master; - channel = mc->channel; - - if (master == APP_BASE_ID) { - i = channel >> 3; - drv_data->ia_app[i] &= ~(0x80>>(channel & 0x7)); - } else if (master == OS_BASE_ID) { - i = channel >> 3; - drv_data->ia_os[i] &= ~(0x80>>(channel & 0x7)); - } else { - i = channel >> 3; - drv_data->ia_modem[i] &= ~(0x80>>(channel & 0x7)); - } - - kfree(mc); - } - - mutex_unlock(&alloclock); -} -EXPORT_SYMBOL_GPL(pti_release_masterchannel); - -/** - * pti_writedata()- Kernel API function used to write trace - * debugging data to PTI HW. - * - * @mc: Master, channel aperture ID address to write to. - * Null value will return with no write occurring. - * @buf: Trace debuging data to write to the PTI HW. - * Null value will return with no write occurring. - * @count: Size of buf. Value of 0 or a negative number will - * return with no write occuring. - */ -void pti_writedata(struct pti_masterchannel *mc, u8 *buf, int count) -{ - /* - * since this function is exported, this is treated like an - * API function, thus, all parameters should - * be checked for validity. - */ - if ((mc != NULL) && (buf != NULL) && (count > 0)) - pti_write_to_aperture(mc, buf, count); - return; -} -EXPORT_SYMBOL_GPL(pti_writedata); - -/* - * for the tty_driver_*() basic function descriptions, see tty_driver.h. - * Specific header comments made for PTI-related specifics. - */ - -/** - * pti_tty_driver_open()- Open an Application master, channel aperture - * ID to the PTI device via tty device. - * - * @tty: tty interface. - * @filp: filp interface pased to tty_port_open() call. - * - * Returns: - * int, 0 for success - * otherwise, fail value - * - * The main purpose of using the tty device interface is for - * each tty port to have a unique PTI write aperture. In an - * example use case, ttyPTI0 gets syslogd and an APP aperture - * ID and ttyPTI1 is where the n_tracesink ldisc hooks to route - * modem messages into PTI. Modem trace data does not have to - * go to ttyPTI1, but ttyPTI0 and ttyPTI1 do need to be distinct - * master IDs. These messages go through the PTI HW and out of - * the handheld platform and to the Fido/Lauterbach device. - */ -static int pti_tty_driver_open(struct tty_struct *tty, struct file *filp) -{ - /* - * we actually want to allocate a new channel per open, per - * system arch. HW gives more than plenty channels for a single - * system task to have its own channel to write trace data. This - * also removes a locking requirement for the actual write - * procedure. - */ - return tty_port_open(tty->port, tty, filp); -} - -/** - * pti_tty_driver_close()- close tty device and release Application - * master, channel aperture ID to the PTI device via tty device. - * - * @tty: tty interface. - * @filp: filp interface pased to tty_port_close() call. - * - * The main purpose of using the tty device interface is to route - * syslog daemon messages to the PTI HW and out of the handheld platform - * and to the Fido/Lauterbach device. - */ -static void pti_tty_driver_close(struct tty_struct *tty, struct file *filp) -{ - tty_port_close(tty->port, tty, filp); -} - -/** - * pti_tty_install()- Used to set up specific master-channels - * to tty ports for organizational purposes when - * tracing viewed from debuging tools. - * - * @driver: tty driver information. - * @tty: tty struct containing pti information. - * - * Returns: - * 0 for success - * otherwise, error - */ -static int pti_tty_install(struct tty_driver *driver, struct tty_struct *tty) -{ - int idx = tty->index; - struct pti_tty *pti_tty_data; - int ret = tty_standard_install(driver, tty); - - if (ret == 0) { - pti_tty_data = kmalloc(sizeof(struct pti_tty), GFP_KERNEL); - if (pti_tty_data == NULL) - return -ENOMEM; - - if (idx == PTITTY_MINOR_START) - pti_tty_data->mc = pti_request_masterchannel(0, NULL); - else - pti_tty_data->mc = pti_request_masterchannel(2, NULL); - - if (pti_tty_data->mc == NULL) { - kfree(pti_tty_data); - return -ENXIO; - } - tty->driver_data = pti_tty_data; - } - - return ret; -} - -/** - * pti_tty_cleanup()- Used to de-allocate master-channel resources - * tied to tty's of this driver. - * - * @tty: tty struct containing pti information. - */ -static void pti_tty_cleanup(struct tty_struct *tty) -{ - struct pti_tty *pti_tty_data = tty->driver_data; - if (pti_tty_data == NULL) - return; - pti_release_masterchannel(pti_tty_data->mc); - kfree(pti_tty_data); - tty->driver_data = NULL; -} - -/** - * pti_tty_driver_write()- Write trace debugging data through the char - * interface to the PTI HW. Part of the misc device implementation. - * - * @tty: tty struct containing pti information. - * @buf: trace data to be written. - * @len: # of byte to write. - * - * Returns: - * int, # of bytes written - * otherwise, error - */ -static int pti_tty_driver_write(struct tty_struct *tty, - const unsigned char *buf, int len) -{ - struct pti_tty *pti_tty_data = tty->driver_data; - if ((pti_tty_data != NULL) && (pti_tty_data->mc != NULL)) { - pti_write_to_aperture(pti_tty_data->mc, (u8 *)buf, len); - return len; - } - /* - * we can't write to the pti hardware if the private driver_data - * and the mc address is not there. - */ - else - return -EFAULT; -} - -/** - * pti_tty_write_room()- Always returns 2048. - * - * @tty: contains tty info of the pti driver. - */ -static int pti_tty_write_room(struct tty_struct *tty) -{ - return 2048; -} - -/** - * pti_char_open()- Open an Application master, channel aperture - * ID to the PTI device. Part of the misc device implementation. - * - * @inode: not used. - * @filp: Output- will have a masterchannel struct set containing - * the allocated application PTI aperture write address. - * - * Returns: - * int, 0 for success - * otherwise, a fail value - */ -static int pti_char_open(struct inode *inode, struct file *filp) -{ - struct pti_masterchannel *mc; - - /* - * We really do want to fail immediately if - * pti_request_masterchannel() fails, - * before assigning the value to filp->private_data. - * Slightly easier to debug if this driver needs debugging. - */ - mc = pti_request_masterchannel(0, NULL); - if (mc == NULL) - return -ENOMEM; - filp->private_data = mc; - return 0; -} - -/** - * pti_char_release()- Close a char channel to the PTI device. Part - * of the misc device implementation. - * - * @inode: Not used in this implementaiton. - * @filp: Contains private_data that contains the master, channel - * ID to be released by the PTI device. - * - * Returns: - * always 0 - */ -static int pti_char_release(struct inode *inode, struct file *filp) -{ - pti_release_masterchannel(filp->private_data); - filp->private_data = NULL; - return 0; -} - -/** - * pti_char_write()- Write trace debugging data through the char - * interface to the PTI HW. Part of the misc device implementation. - * - * @filp: Contains private data which is used to obtain - * master, channel write ID. - * @data: trace data to be written. - * @len: # of byte to write. - * @ppose: Not used in this function implementation. - * - * Returns: - * int, # of bytes written - * otherwise, error value - * - * Notes: From side discussions with Alan Cox and experimenting - * with PTI debug HW like Nokia's Fido box and Lauterbach - * devices, 8192 byte write buffer used by USER_COPY_SIZE was - * deemed an appropriate size for this type of usage with - * debugging HW. - */ -static ssize_t pti_char_write(struct file *filp, const char __user *data, - size_t len, loff_t *ppose) -{ - struct pti_masterchannel *mc; - void *kbuf; - const char __user *tmp; - size_t size = USER_COPY_SIZE; - size_t n = 0; - - tmp = data; - mc = filp->private_data; - - kbuf = kmalloc(size, GFP_KERNEL); - if (kbuf == NULL) { - pr_err("%s(%d): buf allocation failed\n", - __func__, __LINE__); - return -ENOMEM; - } - - do { - if (len - n > USER_COPY_SIZE) - size = USER_COPY_SIZE; - else - size = len - n; - - if (copy_from_user(kbuf, tmp, size)) { - kfree(kbuf); - return n ? n : -EFAULT; - } - - pti_write_to_aperture(mc, kbuf, size); - n += size; - tmp += size; - - } while (len > n); - - kfree(kbuf); - return len; -} - -static const struct tty_operations pti_tty_driver_ops = { - .open = pti_tty_driver_open, - .close = pti_tty_driver_close, - .write = pti_tty_driver_write, - .write_room = pti_tty_write_room, - .install = pti_tty_install, - .cleanup = pti_tty_cleanup -}; - -static const struct file_operations pti_char_driver_ops = { - .owner = THIS_MODULE, - .write = pti_char_write, - .open = pti_char_open, - .release = pti_char_release, -}; - -static struct miscdevice pti_char_driver = { - .minor = MISC_DYNAMIC_MINOR, - .name = CHARNAME, - .fops = &pti_char_driver_ops -}; - -/** - * pti_console_write()- Write to the console that has been acquired. - * - * @c: Not used in this implementaiton. - * @buf: Data to be written. - * @len: Length of buf. - */ -static void pti_console_write(struct console *c, const char *buf, unsigned len) -{ - static struct pti_masterchannel mc = {.master = CONSOLE_ID, - .channel = 0}; - - mc.channel = pti_console_channel; - pti_console_channel = (pti_console_channel + 1) & 0x7f; - - pti_write_full_frame_to_aperture(&mc, buf, len); -} - -/** - * pti_console_device()- Return the driver tty structure and set the - * associated index implementation. - * - * @c: Console device of the driver. - * @index: index associated with c. - * - * Returns: - * always value of pti_tty_driver structure when this function - * is called. - */ -static struct tty_driver *pti_console_device(struct console *c, int *index) -{ - *index = c->index; - return pti_tty_driver; -} - -/** - * pti_console_setup()- Initialize console variables used by the driver. - * - * @c: Not used. - * @opts: Not used. - * - * Returns: - * always 0. - */ -static int pti_console_setup(struct console *c, char *opts) -{ - pti_console_channel = 0; - pti_control_channel = 0; - return 0; -} - -/* - * pti_console struct, used to capture OS printk()'s and shift - * out to the PTI device for debugging. This cannot be - * enabled upon boot because of the possibility of eating - * any serial console printk's (race condition discovered). - * The console should be enabled upon when the tty port is - * used for the first time. Since the primary purpose for - * the tty port is to hook up syslog to it, the tty port - * will be open for a really long time. - */ -static struct console pti_console = { - .name = TTYNAME, - .write = pti_console_write, - .device = pti_console_device, - .setup = pti_console_setup, - .flags = CON_PRINTBUFFER, - .index = 0, -}; - -/** - * pti_port_activate()- Used to start/initialize any items upon - * first opening of tty_port(). - * - * @port: The tty port number of the PTI device. - * @tty: The tty struct associated with this device. - * - * Returns: - * always returns 0 - * - * Notes: The primary purpose of the PTI tty port 0 is to hook - * the syslog daemon to it; thus this port will be open for a - * very long time. - */ -static int pti_port_activate(struct tty_port *port, struct tty_struct *tty) -{ - if (port->tty->index == PTITTY_MINOR_START) - console_start(&pti_console); - return 0; -} - -/** - * pti_port_shutdown()- Used to stop/shutdown any items upon the - * last tty port close. - * - * @port: The tty port number of the PTI device. - * - * Notes: The primary purpose of the PTI tty port 0 is to hook - * the syslog daemon to it; thus this port will be open for a - * very long time. - */ -static void pti_port_shutdown(struct tty_port *port) -{ - if (port->tty->index == PTITTY_MINOR_START) - console_stop(&pti_console); -} - -static const struct tty_port_operations tty_port_ops = { - .activate = pti_port_activate, - .shutdown = pti_port_shutdown, -}; - -/* - * Note the _probe() call sets everything up and ties the char and tty - * to successfully detecting the PTI device on the pci bus. - */ - -/** - * pti_pci_probe()- Used to detect pti on the pci bus and set - * things up in the driver. - * - * @pdev: pci_dev struct values for pti. - * @ent: pci_device_id struct for pti driver. - * - * Returns: - * 0 for success - * otherwise, error - */ -static int pti_pci_probe(struct pci_dev *pdev, - const struct pci_device_id *ent) -{ - unsigned int a; - int retval; - int pci_bar = 1; - - dev_dbg(&pdev->dev, "%s %s(%d): PTI PCI ID %04x:%04x\n", __FILE__, - __func__, __LINE__, pdev->vendor, pdev->device); - - retval = misc_register(&pti_char_driver); - if (retval) { - pr_err("%s(%d): CHAR registration failed of pti driver\n", - __func__, __LINE__); - pr_err("%s(%d): Error value returned: %d\n", - __func__, __LINE__, retval); - goto err; - } - - retval = pci_enable_device(pdev); - if (retval != 0) { - dev_err(&pdev->dev, - "%s: pci_enable_device() returned error %d\n", - __func__, retval); - goto err_unreg_misc; - } - - drv_data = kzalloc(sizeof(*drv_data), GFP_KERNEL); - if (drv_data == NULL) { - retval = -ENOMEM; - dev_err(&pdev->dev, - "%s(%d): kmalloc() returned NULL memory.\n", - __func__, __LINE__); - goto err_disable_pci; - } - drv_data->pti_addr = pci_resource_start(pdev, pci_bar); - - retval = pci_request_region(pdev, pci_bar, dev_name(&pdev->dev)); - if (retval != 0) { - dev_err(&pdev->dev, - "%s(%d): pci_request_region() returned error %d\n", - __func__, __LINE__, retval); - goto err_free_dd; - } - drv_data->aperture_base = drv_data->pti_addr+APERTURE_14; - drv_data->pti_ioaddr = - ioremap((u32)drv_data->aperture_base, - APERTURE_LEN); - if (!drv_data->pti_ioaddr) { - retval = -ENOMEM; - goto err_rel_reg; - } - - pci_set_drvdata(pdev, drv_data); - - for (a = 0; a < PTITTY_MINOR_NUM; a++) { - struct tty_port *port = &drv_data->port[a]; - tty_port_init(port); - port->ops = &tty_port_ops; - - tty_port_register_device(port, pti_tty_driver, a, &pdev->dev); - } - - register_console(&pti_console); - - return 0; -err_rel_reg: - pci_release_region(pdev, pci_bar); -err_free_dd: - kfree(drv_data); -err_disable_pci: - pci_disable_device(pdev); -err_unreg_misc: - misc_deregister(&pti_char_driver); -err: - return retval; -} - -/** - * pti_pci_remove()- Driver exit method to remove PTI from - * PCI bus. - * @pdev: variable containing pci info of PTI. - */ -static void pti_pci_remove(struct pci_dev *pdev) -{ - struct pti_dev *drv_data = pci_get_drvdata(pdev); - unsigned int a; - - unregister_console(&pti_console); - - for (a = 0; a < PTITTY_MINOR_NUM; a++) { - tty_unregister_device(pti_tty_driver, a); - tty_port_destroy(&drv_data->port[a]); - } - - iounmap(drv_data->pti_ioaddr); - kfree(drv_data); - pci_release_region(pdev, 1); - pci_disable_device(pdev); - - misc_deregister(&pti_char_driver); -} - -static struct pci_driver pti_pci_driver = { - .name = PCINAME, - .id_table = pci_ids, - .probe = pti_pci_probe, - .remove = pti_pci_remove, -}; - -/** - * pti_init()- Overall entry/init call to the pti driver. - * It starts the registration process with the kernel. - * - * Returns: - * int __init, 0 for success - * otherwise value is an error - * - */ -static int __init pti_init(void) -{ - int retval; - - /* First register module as tty device */ - - pti_tty_driver = alloc_tty_driver(PTITTY_MINOR_NUM); - if (pti_tty_driver == NULL) { - pr_err("%s(%d): Memory allocation failed for ptiTTY driver\n", - __func__, __LINE__); - return -ENOMEM; - } - - pti_tty_driver->driver_name = DRIVERNAME; - pti_tty_driver->name = TTYNAME; - pti_tty_driver->major = 0; - pti_tty_driver->minor_start = PTITTY_MINOR_START; - pti_tty_driver->type = TTY_DRIVER_TYPE_SYSTEM; - pti_tty_driver->subtype = SYSTEM_TYPE_SYSCONS; - pti_tty_driver->flags = TTY_DRIVER_REAL_RAW | - TTY_DRIVER_DYNAMIC_DEV; - pti_tty_driver->init_termios = tty_std_termios; - - tty_set_operations(pti_tty_driver, &pti_tty_driver_ops); - - retval = tty_register_driver(pti_tty_driver); - if (retval) { - pr_err("%s(%d): TTY registration failed of pti driver\n", - __func__, __LINE__); - pr_err("%s(%d): Error value returned: %d\n", - __func__, __LINE__, retval); - - goto put_tty; - } - - retval = pci_register_driver(&pti_pci_driver); - if (retval) { - pr_err("%s(%d): PCI registration failed of pti driver\n", - __func__, __LINE__); - pr_err("%s(%d): Error value returned: %d\n", - __func__, __LINE__, retval); - goto unreg_tty; - } - - return 0; -unreg_tty: - tty_unregister_driver(pti_tty_driver); -put_tty: - put_tty_driver(pti_tty_driver); - pti_tty_driver = NULL; - return retval; -} - -/** - * pti_exit()- Unregisters this module as a tty and pci driver. - */ -static void __exit pti_exit(void) -{ - tty_unregister_driver(pti_tty_driver); - pci_unregister_driver(&pti_pci_driver); - put_tty_driver(pti_tty_driver); -} - -module_init(pti_init); -module_exit(pti_exit); - -MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Ken Mills, Jay Freyensee"); -MODULE_DESCRIPTION("PTI Driver"); - diff --git a/drivers/tty/Makefile b/drivers/tty/Makefile index b3ccae932660..730de6bf048b 100644 --- a/drivers/tty/Makefile +++ b/drivers/tty/Makefile @@ -9,8 +9,6 @@ obj-$(CONFIG_AUDIT) += tty_audit.o obj-$(CONFIG_MAGIC_SYSRQ) += sysrq.o obj-$(CONFIG_N_HDLC) += n_hdlc.o obj-$(CONFIG_N_GSM) += n_gsm.o -obj-$(CONFIG_TRACE_ROUTER) += n_tracerouter.o -obj-$(CONFIG_TRACE_SINK) += n_tracesink.o obj-$(CONFIG_R3964) += n_r3964.o obj-y += vt/ diff --git a/drivers/tty/n_tracerouter.c b/drivers/tty/n_tracerouter.c deleted file mode 100644 index 4479af4d2fa5..000000000000 --- a/drivers/tty/n_tracerouter.c +++ /dev/null @@ -1,233 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* - * n_tracerouter.c - Trace data router through tty space - * - * Copyright (C) Intel 2011 - * - * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - * - * This trace router uses the Linux line discipline framework to route - * trace data coming from a HW Modem to a PTI (Parallel Trace Module) port. - * The solution is not specific to a HW modem and this line disciple can - * be used to route any stream of data in kernel space. - * This is part of a solution for the P1149.7, compact JTAG, standard. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "n_tracesink.h" - -/* - * Other ldisc drivers use 65536 which basically means, - * 'I can always accept 64k' and flow control is off. - * This number is deemed appropriate for this driver. - */ -#define RECEIVE_ROOM 65536 -#define DRIVERNAME "n_tracerouter" - -/* - * struct to hold private configuration data for this ldisc. - * opencalled is used to hold if this ldisc has been opened. - * kref_tty holds the tty reference the ldisc sits on top of. - */ -struct tracerouter_data { - u8 opencalled; - struct tty_struct *kref_tty; -}; -static struct tracerouter_data *tr_data; - -/* lock for when tty reference is being used */ -static DEFINE_MUTEX(routelock); - -/** - * n_tracerouter_open() - Called when a tty is opened by a SW entity. - * @tty: terminal device to the ldisc. - * - * Return: - * 0 for success. - * - * Caveats: This should only be opened one time per SW entity. - */ -static int n_tracerouter_open(struct tty_struct *tty) -{ - int retval = -EEXIST; - - mutex_lock(&routelock); - if (tr_data->opencalled == 0) { - - tr_data->kref_tty = tty_kref_get(tty); - if (tr_data->kref_tty == NULL) { - retval = -EFAULT; - } else { - tr_data->opencalled = 1; - tty->disc_data = tr_data; - tty->receive_room = RECEIVE_ROOM; - tty_driver_flush_buffer(tty); - retval = 0; - } - } - mutex_unlock(&routelock); - return retval; -} - -/** - * n_tracerouter_close() - close connection - * @tty: terminal device to the ldisc. - * - * Called when a software entity wants to close a connection. - */ -static void n_tracerouter_close(struct tty_struct *tty) -{ - struct tracerouter_data *tptr = tty->disc_data; - - mutex_lock(&routelock); - WARN_ON(tptr->kref_tty != tr_data->kref_tty); - tty_driver_flush_buffer(tty); - tty_kref_put(tr_data->kref_tty); - tr_data->kref_tty = NULL; - tr_data->opencalled = 0; - tty->disc_data = NULL; - mutex_unlock(&routelock); -} - -/** - * n_tracerouter_read() - read request from user space - * @tty: terminal device passed into the ldisc. - * @file: pointer to open file object. - * @buf: pointer to the data buffer that gets eventually returned. - * @nr: number of bytes of the data buffer that is returned. - * - * function that allows read() functionality in userspace. By default if this - * is not implemented it returns -EIO. This module is functioning like a - * router via n_tracerouter_receivebuf(), and there is no real requirement - * to implement this function. However, an error return value other than - * -EIO should be used just to show that there was an intent not to have - * this function implemented. Return value based on read() man pages. - * - * Return: - * -EINVAL - */ -static ssize_t n_tracerouter_read(struct tty_struct *tty, struct file *file, - unsigned char __user *buf, size_t nr) { - return -EINVAL; -} - -/** - * n_tracerouter_write() - Function that allows write() in userspace. - * @tty: terminal device passed into the ldisc. - * @file: pointer to open file object. - * @buf: pointer to the data buffer that gets eventually returned. - * @nr: number of bytes of the data buffer that is returned. - * - * By default if this is not implemented, it returns -EIO. - * This should not be implemented, ever, because - * 1. this driver is functioning like a router via - * n_tracerouter_receivebuf() - * 2. No writes to HW will ever go through this line discpline driver. - * However, an error return value other than -EIO should be used - * just to show that there was an intent not to have this function - * implemented. Return value based on write() man pages. - * - * Return: - * -EINVAL - */ -static ssize_t n_tracerouter_write(struct tty_struct *tty, struct file *file, - const unsigned char *buf, size_t nr) { - return -EINVAL; -} - -/** - * n_tracerouter_receivebuf() - Routing function for driver. - * @tty: terminal device passed into the ldisc. It's assumed - * tty will never be NULL. - * @cp: buffer, block of characters to be eventually read by - * someone, somewhere (user read() call or some kernel function). - * @fp: flag buffer. - * @count: number of characters (aka, bytes) in cp. - * - * This function takes the input buffer, cp, and passes it to - * an external API function for processing. - */ -static void n_tracerouter_receivebuf(struct tty_struct *tty, - const unsigned char *cp, - char *fp, int count) -{ - mutex_lock(&routelock); - n_tracesink_datadrain((u8 *) cp, count); - mutex_unlock(&routelock); -} - -/* - * Flush buffer is not impelemented as the ldisc has no internal buffering - * so the tty_driver_flush_buffer() is sufficient for this driver's needs. - */ - -static struct tty_ldisc_ops tty_ptirouter_ldisc = { - .owner = THIS_MODULE, - .magic = TTY_LDISC_MAGIC, - .name = DRIVERNAME, - .open = n_tracerouter_open, - .close = n_tracerouter_close, - .read = n_tracerouter_read, - .write = n_tracerouter_write, - .receive_buf = n_tracerouter_receivebuf -}; - -/** - * n_tracerouter_init - module initialisation - * - * Registers this module as a line discipline driver. - * - * Return: - * 0 for success, any other value error. - */ -static int __init n_tracerouter_init(void) -{ - int retval; - - tr_data = kzalloc(sizeof(struct tracerouter_data), GFP_KERNEL); - if (tr_data == NULL) - return -ENOMEM; - - - /* Note N_TRACEROUTER is defined in linux/tty.h */ - retval = tty_register_ldisc(N_TRACEROUTER, &tty_ptirouter_ldisc); - if (retval < 0) { - pr_err("%s: Registration failed: %d\n", __func__, retval); - kfree(tr_data); - } - return retval; -} - -/** - * n_tracerouter_exit - module unload - * - * Removes this module as a line discipline driver. - */ -static void __exit n_tracerouter_exit(void) -{ - int retval = tty_unregister_ldisc(N_TRACEROUTER); - - if (retval < 0) - pr_err("%s: Unregistration failed: %d\n", __func__, retval); - else - kfree(tr_data); -} - -module_init(n_tracerouter_init); -module_exit(n_tracerouter_exit); - -MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Jay Freyensee"); -MODULE_ALIAS_LDISC(N_TRACEROUTER); -MODULE_DESCRIPTION("Trace router ldisc driver"); diff --git a/drivers/tty/n_tracesink.c b/drivers/tty/n_tracesink.c deleted file mode 100644 index d96ba82cc356..000000000000 --- a/drivers/tty/n_tracesink.c +++ /dev/null @@ -1,228 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* - * n_tracesink.c - Trace data router and sink path through tty space. - * - * Copyright (C) Intel 2011 - * - * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - * - * The trace sink uses the Linux line discipline framework to receive - * trace data coming from the PTI source line discipline driver - * to a user-desired tty port, like USB. - * This is to provide a way to extract modem trace data on - * devices that do not have a PTI HW module, or just need modem - * trace data to come out of a different HW output port. - * This is part of a solution for the P1149.7, compact JTAG, standard. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "n_tracesink.h" - -/* - * Other ldisc drivers use 65536 which basically means, - * 'I can always accept 64k' and flow control is off. - * This number is deemed appropriate for this driver. - */ -#define RECEIVE_ROOM 65536 -#define DRIVERNAME "n_tracesink" - -/* - * there is a quirk with this ldisc is he can write data - * to a tty from anyone calling his kernel API, which - * meets customer requirements in the drivers/misc/pti.c - * project. So he needs to know when he can and cannot write when - * the API is called. In theory, the API can be called - * after an init() but before a successful open() which - * would crash the system if tty is not checked. - */ -static struct tty_struct *this_tty; -static DEFINE_MUTEX(writelock); - -/** - * n_tracesink_open() - Called when a tty is opened by a SW entity. - * @tty: terminal device to the ldisc. - * - * Return: - * 0 for success, - * -EFAULT = couldn't get a tty kref n_tracesink will sit - * on top of - * -EEXIST = open() called successfully once and it cannot - * be called again. - * - * Caveats: open() should only be successful the first time a - * SW entity calls it. - */ -static int n_tracesink_open(struct tty_struct *tty) -{ - int retval = -EEXIST; - - mutex_lock(&writelock); - if (this_tty == NULL) { - this_tty = tty_kref_get(tty); - if (this_tty == NULL) { - retval = -EFAULT; - } else { - tty->disc_data = this_tty; - tty_driver_flush_buffer(tty); - retval = 0; - } - } - mutex_unlock(&writelock); - - return retval; -} - -/** - * n_tracesink_close() - close connection - * @tty: terminal device to the ldisc. - * - * Called when a software entity wants to close a connection. - */ -static void n_tracesink_close(struct tty_struct *tty) -{ - mutex_lock(&writelock); - tty_driver_flush_buffer(tty); - tty_kref_put(this_tty); - this_tty = NULL; - tty->disc_data = NULL; - mutex_unlock(&writelock); -} - -/** - * n_tracesink_read() - read request from user space - * @tty: terminal device passed into the ldisc. - * @file: pointer to open file object. - * @buf: pointer to the data buffer that gets eventually returned. - * @nr: number of bytes of the data buffer that is returned. - * - * function that allows read() functionality in userspace. By default if this - * is not implemented it returns -EIO. This module is functioning like a - * router via n_tracesink_receivebuf(), and there is no real requirement - * to implement this function. However, an error return value other than - * -EIO should be used just to show that there was an intent not to have - * this function implemented. Return value based on read() man pages. - * - * Return: - * -EINVAL - */ -static ssize_t n_tracesink_read(struct tty_struct *tty, struct file *file, - unsigned char __user *buf, size_t nr) { - return -EINVAL; -} - -/** - * n_tracesink_write() - Function that allows write() in userspace. - * @tty: terminal device passed into the ldisc. - * @file: pointer to open file object. - * @buf: pointer to the data buffer that gets eventually returned. - * @nr: number of bytes of the data buffer that is returned. - * - * By default if this is not implemented, it returns -EIO. - * This should not be implemented, ever, because - * 1. this driver is functioning like a router via - * n_tracesink_receivebuf() - * 2. No writes to HW will ever go through this line discpline driver. - * However, an error return value other than -EIO should be used - * just to show that there was an intent not to have this function - * implemented. Return value based on write() man pages. - * - * Return: - * -EINVAL - */ -static ssize_t n_tracesink_write(struct tty_struct *tty, struct file *file, - const unsigned char *buf, size_t nr) { - return -EINVAL; -} - -/** - * n_tracesink_datadrain() - Kernel API function used to route - * trace debugging data to user-defined - * port like USB. - * - * @buf: Trace debuging data buffer to write to tty target - * port. Null value will return with no write occurring. - * @count: Size of buf. Value of 0 or a negative number will - * return with no write occuring. - * - * Caveat: If this line discipline does not set the tty it sits - * on top of via an open() call, this API function will not - * call the tty's write() call because it will have no pointer - * to call the write(). - */ -void n_tracesink_datadrain(u8 *buf, int count) -{ - mutex_lock(&writelock); - - if ((buf != NULL) && (count > 0) && (this_tty != NULL)) - this_tty->ops->write(this_tty, buf, count); - - mutex_unlock(&writelock); -} -EXPORT_SYMBOL_GPL(n_tracesink_datadrain); - -/* - * Flush buffer is not impelemented as the ldisc has no internal buffering - * so the tty_driver_flush_buffer() is sufficient for this driver's needs. - */ - -/* - * tty_ldisc function operations for this driver. - */ -static struct tty_ldisc_ops tty_n_tracesink = { - .owner = THIS_MODULE, - .magic = TTY_LDISC_MAGIC, - .name = DRIVERNAME, - .open = n_tracesink_open, - .close = n_tracesink_close, - .read = n_tracesink_read, - .write = n_tracesink_write -}; - -/** - * n_tracesink_init- module initialisation - * - * Registers this module as a line discipline driver. - * - * Return: - * 0 for success, any other value error. - */ -static int __init n_tracesink_init(void) -{ - /* Note N_TRACESINK is defined in linux/tty.h */ - int retval = tty_register_ldisc(N_TRACESINK, &tty_n_tracesink); - - if (retval < 0) - pr_err("%s: Registration failed: %d\n", __func__, retval); - - return retval; -} - -/** - * n_tracesink_exit - module unload - * - * Removes this module as a line discipline driver. - */ -static void __exit n_tracesink_exit(void) -{ - int retval = tty_unregister_ldisc(N_TRACESINK); - - if (retval < 0) - pr_err("%s: Unregistration failed: %d\n", __func__, retval); -} - -module_init(n_tracesink_init); -module_exit(n_tracesink_exit); - -MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Jay Freyensee"); -MODULE_ALIAS_LDISC(N_TRACESINK); -MODULE_DESCRIPTION("Trace sink ldisc driver"); diff --git a/drivers/tty/n_tracesink.h b/drivers/tty/n_tracesink.h deleted file mode 100644 index 7031d515a700..000000000000 --- a/drivers/tty/n_tracesink.h +++ /dev/null @@ -1,26 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/* - * n_tracesink.h - Kernel driver API to route trace data in kernel space. - * - * Copyright (C) Intel 2011 - * - * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - * - * The PTI (Parallel Trace Interface) driver directs trace data routed from - * various parts in the system out through the Intel Penwell PTI port and - * out of the mobile device for analysis with a debugging tool - * (Lauterbach, Fido). This is part of a solution for the MIPI P1149.7, - * compact JTAG, standard. - * - * This header file is used by n_tracerouter to be able to send the - * data of it's tty port to the tty port this module sits. This - * mechanism can also be used independent of the PTI module. - * - */ - -#ifndef N_TRACESINK_H_ -#define N_TRACESINK_H_ - -void n_tracesink_datadrain(u8 *buf, int count); - -#endif diff --git a/include/linux/intel-pti.h b/include/linux/intel-pti.h deleted file mode 100644 index fcd841a90f2f..000000000000 --- a/include/linux/intel-pti.h +++ /dev/null @@ -1,35 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ -/* - * Copyright (C) Intel 2011 - * - * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - * - * The PTI (Parallel Trace Interface) driver directs trace data routed from - * various parts in the system out through the Intel Penwell PTI port and - * out of the mobile device for analysis with a debugging tool - * (Lauterbach, Fido). This is part of a solution for the MIPI P1149.7, - * compact JTAG, standard. - * - * This header file will allow other parts of the OS to use the - * interface to write out it's contents for debugging a mobile system. - */ - -#ifndef LINUX_INTEL_PTI_H_ -#define LINUX_INTEL_PTI_H_ - -/* offset for last dword of any PTI message. Part of MIPI P1149.7 */ -#define PTI_LASTDWORD_DTS 0x30 - -/* basic structure used as a write address to the PTI HW */ -struct pti_masterchannel { - u8 master; - u8 channel; -}; - -/* the following functions are defined in misc/pti.c */ -void pti_writedata(struct pti_masterchannel *mc, u8 *buf, int count); -struct pti_masterchannel *pti_request_masterchannel(u8 type, - const char *thread_name); -void pti_release_masterchannel(struct pti_masterchannel *mc); - -#endif /* LINUX_INTEL_PTI_H_ */ -- cgit v1.2.3 From 487709fa1be2f27aa8e7de6c60587b4302a21467 Mon Sep 17 00:00:00 2001 From: zhenwei pi Date: Sun, 10 Jan 2021 19:53:57 +0800 Subject: misc: pvpanic: introduce device capability According to pvpanic spec: https://git.qemu.org/?p=qemu.git;a=blob_plain;f=docs/specs/pvpanic.txt The guest should determine pvpanic capability by RDPT, so initialize capability during device probing. There is no need to register panic notifier callback function if no events supported. Before sending event to host side, check capability firstly. Suggested by Greg KH, use sysfs to expose capability to user space, also add new sysfs attribute in document. Signed-off-by: zhenwei pi Reviewed-by: Paolo Bonzini Link: https://lore.kernel.org/r/20210110115358.79100-2-pizhenwei@bytedance.com Signed-off-by: Greg Kroah-Hartman --- .../ABI/testing/sysfs-bus-pci-devices-pvpanic | 12 +++++++++ drivers/misc/pvpanic.c | 31 ++++++++++++++++++---- 2 files changed, 38 insertions(+), 5 deletions(-) create mode 100644 Documentation/ABI/testing/sysfs-bus-pci-devices-pvpanic (limited to 'Documentation') diff --git a/Documentation/ABI/testing/sysfs-bus-pci-devices-pvpanic b/Documentation/ABI/testing/sysfs-bus-pci-devices-pvpanic new file mode 100644 index 000000000000..79b7dc31cd55 --- /dev/null +++ b/Documentation/ABI/testing/sysfs-bus-pci-devices-pvpanic @@ -0,0 +1,12 @@ +What: /sys/devices/pci0000:00/*/QEMU0001:00/capability +Date: Jan 2021 +Contact: zhenwei pi +Description: + Read-only attribute. Capabilities of pvpanic device which + are supported by QEMU. + + Format: %x. + + Detailed bit definition refers to section + from pvpanic device specification: + https://git.qemu.org/?p=qemu.git;a=blob_plain;f=docs/specs/pvpanic.txt diff --git a/drivers/misc/pvpanic.c b/drivers/misc/pvpanic.c index 41cab297d66e..80cdfa8f951a 100644 --- a/drivers/misc/pvpanic.c +++ b/drivers/misc/pvpanic.c @@ -19,6 +19,20 @@ #include static void __iomem *base; +static unsigned int capability = PVPANIC_PANICKED | PVPANIC_CRASH_LOADED; + +static ssize_t capability_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + return sysfs_emit(buf, "%x", capability); +} +static DEVICE_ATTR_RO(capability); + +static struct attribute *pvpanic_dev_attrs[] = { + &dev_attr_capability.attr, + NULL +}; +ATTRIBUTE_GROUPS(pvpanic_dev); MODULE_AUTHOR("Hu Tao "); MODULE_DESCRIPTION("pvpanic device driver"); @@ -27,7 +41,8 @@ MODULE_LICENSE("GPL"); static void pvpanic_send_event(unsigned int event) { - iowrite8(event, base); + if (event & capability) + iowrite8(event, base); } static int @@ -73,8 +88,12 @@ static int pvpanic_mmio_probe(struct platform_device *pdev) return -EINVAL; } - atomic_notifier_chain_register(&panic_notifier_list, - &pvpanic_panic_nb); + /* initlize capability by RDPT */ + capability &= ioread8(base); + + if (capability) + atomic_notifier_chain_register(&panic_notifier_list, + &pvpanic_panic_nb); return 0; } @@ -82,8 +101,9 @@ static int pvpanic_mmio_probe(struct platform_device *pdev) static int pvpanic_mmio_remove(struct platform_device *pdev) { - atomic_notifier_chain_unregister(&panic_notifier_list, - &pvpanic_panic_nb); + if (capability) + atomic_notifier_chain_unregister(&panic_notifier_list, + &pvpanic_panic_nb); return 0; } @@ -104,6 +124,7 @@ static struct platform_driver pvpanic_mmio_driver = { .name = "pvpanic-mmio", .of_match_table = pvpanic_mmio_match, .acpi_match_table = pvpanic_device_ids, + .dev_groups = pvpanic_dev_groups, }, .probe = pvpanic_mmio_probe, .remove = pvpanic_mmio_remove, -- cgit v1.2.3 From 8d6da6575ffec171161d36a06c015142b0049637 Mon Sep 17 00:00:00 2001 From: zhenwei pi Date: Sun, 10 Jan 2021 19:53:58 +0800 Subject: misc: pvpanic: introduce events device attribue Suggested by Paolo & Greg, add 'events' device attribute that can be used to limit which capabilities the driver uses. Finally, the pvpanic guest driver works by the limitation of both device capability and user setting. Signed-off-by: zhenwei pi Reviewed-by: Paolo Bonzini Link: https://lore.kernel.org/r/20210110115358.79100-3-pizhenwei@bytedance.com Signed-off-by: Greg Kroah-Hartman --- .../ABI/testing/sysfs-bus-pci-devices-pvpanic | 12 +++++++++ drivers/misc/pvpanic.c | 30 +++++++++++++++++++++- 2 files changed, 41 insertions(+), 1 deletion(-) (limited to 'Documentation') diff --git a/Documentation/ABI/testing/sysfs-bus-pci-devices-pvpanic b/Documentation/ABI/testing/sysfs-bus-pci-devices-pvpanic index 79b7dc31cd55..1936f7324155 100644 --- a/Documentation/ABI/testing/sysfs-bus-pci-devices-pvpanic +++ b/Documentation/ABI/testing/sysfs-bus-pci-devices-pvpanic @@ -10,3 +10,15 @@ Description: Detailed bit definition refers to section from pvpanic device specification: https://git.qemu.org/?p=qemu.git;a=blob_plain;f=docs/specs/pvpanic.txt + +What: /sys/devices/pci0000:00/*/QEMU0001:00/events +Date: Jan 2021 +Contact: zhenwei pi +Description: + RW attribute. Set/get which features in-use. This attribute + is used to enable/disable feature(s) of pvpanic device. + Notice that this value should be a subset of capability. + + Format: %x. + + Also refer to pvpanic device specification. diff --git a/drivers/misc/pvpanic.c b/drivers/misc/pvpanic.c index 80cdfa8f951a..b1e4922a7fda 100644 --- a/drivers/misc/pvpanic.c +++ b/drivers/misc/pvpanic.c @@ -20,6 +20,7 @@ static void __iomem *base; static unsigned int capability = PVPANIC_PANICKED | PVPANIC_CRASH_LOADED; +static unsigned int events; static ssize_t capability_show(struct device *dev, struct device_attribute *attr, char *buf) @@ -28,8 +29,34 @@ static ssize_t capability_show(struct device *dev, } static DEVICE_ATTR_RO(capability); +static ssize_t events_show(struct device *dev, struct device_attribute *attr, char *buf) +{ + return sysfs_emit(buf, "%x", events); +} + +static ssize_t events_store(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) +{ + unsigned int tmp; + int err; + + err = kstrtouint(buf, 16, &tmp); + if (err) + return err; + + if ((tmp & capability) != tmp) + return -EINVAL; + + events = tmp; + + return count; + +} +static DEVICE_ATTR_RW(events); + static struct attribute *pvpanic_dev_attrs[] = { &dev_attr_capability.attr, + &dev_attr_events.attr, NULL }; ATTRIBUTE_GROUPS(pvpanic_dev); @@ -41,7 +68,7 @@ MODULE_LICENSE("GPL"); static void pvpanic_send_event(unsigned int event) { - if (event & capability) + if (event & capability & events) iowrite8(event, base); } @@ -90,6 +117,7 @@ static int pvpanic_mmio_probe(struct platform_device *pdev) /* initlize capability by RDPT */ capability &= ioread8(base); + events = capability; if (capability) atomic_notifier_chain_register(&panic_notifier_list, -- cgit v1.2.3 From 711ae4f6f3535c1638836e6c52db03bc324a8b4c Mon Sep 17 00:00:00 2001 From: ivan tkachenko Date: Wed, 23 Dec 2020 22:43:54 +0100 Subject: media: hdmi: cec: replace broken link to HDMI specs Current link died, according to Wayback Machine, back in 2017. And the website is completely down since 2019. Moreover, there was a custom cover on that PDF, i.e. it was modified. According to HDMI licence agreement (LA), HDMI specification and technical information are supposed to be hosted on www.hdmi.org exclusively, and not redistributed by third-parties. Sure, there are still many more or less reliable "mirrors" out there with a direct download straight from a search engine's page. However, for example, from FPGA4fun[1] website it was removed "per HDMI LA request". Unfortunately, the official download page is protected by email CAPTCHA, but that seems to be the only legit way to obtain a copy. [1] https://www.fpga4fun.com/HDMI.html Signed-off-by: ivan tkachenko Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- Documentation/driver-api/media/cec-core.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Documentation') diff --git a/Documentation/driver-api/media/cec-core.rst b/Documentation/driver-api/media/cec-core.rst index a26dc87eee8f..56345eae9a26 100644 --- a/Documentation/driver-api/media/cec-core.rst +++ b/Documentation/driver-api/media/cec-core.rst @@ -26,7 +26,7 @@ It is documented in the HDMI 1.4 specification with the new 2.0 bits documented in the HDMI 2.0 specification. But for most of the features the freely available HDMI 1.3a specification is sufficient: -http://www.microprocessor.org/HDMISpecification13a.pdf +https://www.hdmi.org/spec/index CEC Adapter Interface -- cgit v1.2.3 From 2cf1e703f066cfa82eb5a358ae84c29fe15a3b3a Mon Sep 17 00:00:00 2001 From: Ioana Ciornei Date: Thu, 14 Jan 2021 19:07:50 +0200 Subject: bus: fsl-mc: add fsl-mc userspace support Adding userspace support for the MC (Management Complex) means exporting an ioctl capable device file representing the root resource container. This new functionality in the fsl-mc bus driver intends to provide userspace applications an interface to interact with the MC firmware. Commands that are composed in userspace are sent to the MC firmware through the FSL_MC_SEND_MC_COMMAND ioctl. By default the implicit MC I/O portal is used for this operation, but if the implicit one is busy, a dynamic portal is allocated and then freed upon execution. The command received through the ioctl interface is checked against a known whitelist of accepted MC commands. Commands that attempt a change in hardware configuration will need CAP_NET_ADMIN, while commands used in debugging do not need it. Acked-by: Laurentiu Tudor Signed-off-by: Ioana Ciornei Link: https://lore.kernel.org/r/20210114170752.2927915-4-ciorneiioana@gmail.com Signed-off-by: Greg Kroah-Hartman --- Documentation/userspace-api/ioctl/ioctl-number.rst | 1 + drivers/bus/fsl-mc/Kconfig | 7 + drivers/bus/fsl-mc/Makefile | 3 + drivers/bus/fsl-mc/dprc-driver.c | 12 + drivers/bus/fsl-mc/fsl-mc-private.h | 39 ++ drivers/bus/fsl-mc/fsl-mc-uapi.c | 547 +++++++++++++++++++++ include/uapi/linux/fsl_mc.h | 9 + 7 files changed, 618 insertions(+) create mode 100644 drivers/bus/fsl-mc/fsl-mc-uapi.c (limited to 'Documentation') diff --git a/Documentation/userspace-api/ioctl/ioctl-number.rst b/Documentation/userspace-api/ioctl/ioctl-number.rst index a4c75a28c839..19d730f9d136 100644 --- a/Documentation/userspace-api/ioctl/ioctl-number.rst +++ b/Documentation/userspace-api/ioctl/ioctl-number.rst @@ -180,6 +180,7 @@ Code Seq# Include File Comments 'R' 00-1F linux/random.h conflict! 'R' 01 linux/rfkill.h conflict! 'R' C0-DF net/bluetooth/rfcomm.h +'R' E0 uapi/linux/fsl_mc.h 'S' all linux/cdrom.h conflict! 'S' 80-81 scsi/scsi_ioctl.h conflict! 'S' 82-FF scsi/scsi.h conflict! diff --git a/drivers/bus/fsl-mc/Kconfig b/drivers/bus/fsl-mc/Kconfig index c23c77c9b705..b1fd55901c50 100644 --- a/drivers/bus/fsl-mc/Kconfig +++ b/drivers/bus/fsl-mc/Kconfig @@ -14,3 +14,10 @@ config FSL_MC_BUS architecture. The fsl-mc bus driver handles discovery of DPAA2 objects (which are represented as Linux devices) and binding objects to drivers. + +config FSL_MC_UAPI_SUPPORT + bool "Management Complex (MC) userspace support" + depends on FSL_MC_BUS + help + Provides userspace support for interrogating, creating, destroying or + configuring DPAA2 objects exported by the Management Complex. diff --git a/drivers/bus/fsl-mc/Makefile b/drivers/bus/fsl-mc/Makefile index 3c518c7e8374..4ae292a30e53 100644 --- a/drivers/bus/fsl-mc/Makefile +++ b/drivers/bus/fsl-mc/Makefile @@ -16,3 +16,6 @@ mc-bus-driver-objs := fsl-mc-bus.o \ fsl-mc-allocator.o \ fsl-mc-msi.o \ dpmcp.o + +# MC userspace support +obj-$(CONFIG_FSL_MC_UAPI_SUPPORT) += fsl-mc-uapi.o diff --git a/drivers/bus/fsl-mc/dprc-driver.c b/drivers/bus/fsl-mc/dprc-driver.c index 68488a7ad0d6..ccec375095f2 100644 --- a/drivers/bus/fsl-mc/dprc-driver.c +++ b/drivers/bus/fsl-mc/dprc-driver.c @@ -603,6 +603,7 @@ int dprc_setup(struct fsl_mc_device *mc_dev) struct irq_domain *mc_msi_domain; bool mc_io_created = false; bool msi_domain_set = false; + bool uapi_created = false; u16 major_ver, minor_ver; size_t region_size; int error; @@ -635,6 +636,11 @@ int dprc_setup(struct fsl_mc_device *mc_dev) return error; mc_io_created = true; + } else { + error = fsl_mc_uapi_create_device_file(mc_bus); + if (error < 0) + return -EPROBE_DEFER; + uapi_created = true; } mc_msi_domain = fsl_mc_find_msi_domain(&mc_dev->dev); @@ -692,6 +698,9 @@ error_cleanup_msi_domain: mc_dev->mc_io = NULL; } + if (uapi_created) + fsl_mc_uapi_remove_device_file(mc_bus); + return error; } EXPORT_SYMBOL_GPL(dprc_setup); @@ -763,6 +772,7 @@ static void dprc_teardown_irq(struct fsl_mc_device *mc_dev) int dprc_cleanup(struct fsl_mc_device *mc_dev) { + struct fsl_mc_bus *mc_bus = to_fsl_mc_bus(mc_dev); int error; /* this function should be called only for DPRCs, it @@ -793,6 +803,8 @@ int dprc_cleanup(struct fsl_mc_device *mc_dev) if (!fsl_mc_is_root_dprc(&mc_dev->dev)) { fsl_destroy_mc_io(mc_dev->mc_io); mc_dev->mc_io = NULL; + } else { + fsl_mc_uapi_remove_device_file(mc_bus); } return 0; diff --git a/drivers/bus/fsl-mc/fsl-mc-private.h b/drivers/bus/fsl-mc/fsl-mc-private.h index be686c363121..6293a24de456 100644 --- a/drivers/bus/fsl-mc/fsl-mc-private.h +++ b/drivers/bus/fsl-mc/fsl-mc-private.h @@ -10,6 +10,8 @@ #include #include +#include +#include /* * Data Path Management Complex (DPMNG) General API @@ -542,6 +544,22 @@ struct fsl_mc_resource_pool { struct fsl_mc_bus *mc_bus; }; +/** + * struct fsl_mc_uapi - information associated with a device file + * @misc: struct miscdevice linked to the root dprc + * @device: newly created device in /dev + * @mutex: mutex lock to serialize the open/release operations + * @local_instance_in_use: local MC I/O instance in use or not + * @static_mc_io: pointer to the static MC I/O object + */ +struct fsl_mc_uapi { + struct miscdevice misc; + struct device *device; + struct mutex mutex; /* serialize open/release operations */ + u32 local_instance_in_use; + struct fsl_mc_io *static_mc_io; +}; + /** * struct fsl_mc_bus - logical bus that corresponds to a physical DPRC * @mc_dev: fsl-mc device for the bus device itself. @@ -551,6 +569,7 @@ struct fsl_mc_resource_pool { * @irq_resources: Pointer to array of IRQ objects for the IRQ pool * @scan_mutex: Serializes bus scanning * @dprc_attr: DPRC attributes + * @uapi_misc: struct that abstracts the interaction with userspace */ struct fsl_mc_bus { struct fsl_mc_device mc_dev; @@ -558,6 +577,7 @@ struct fsl_mc_bus { struct fsl_mc_device_irq *irq_resources; struct mutex scan_mutex; /* serializes bus scanning */ struct dprc_attributes dprc_attr; + struct fsl_mc_uapi uapi_misc; }; #define to_fsl_mc_bus(_mc_dev) \ @@ -614,4 +634,23 @@ struct fsl_mc_device *fsl_mc_device_lookup(struct fsl_mc_obj_desc *obj_desc, u16 mc_cmd_hdr_read_cmdid(struct fsl_mc_command *cmd); +#ifdef CONFIG_FSL_MC_UAPI_SUPPORT + +int fsl_mc_uapi_create_device_file(struct fsl_mc_bus *mc_bus); + +void fsl_mc_uapi_remove_device_file(struct fsl_mc_bus *mc_bus); + +#else + +static inline int fsl_mc_uapi_create_device_file(struct fsl_mc_bus *mc_bus) +{ + return 0; +} + +static inline void fsl_mc_uapi_remove_device_file(struct fsl_mc_bus *mc_bus) +{ +} + +#endif + #endif /* _FSL_MC_PRIVATE_H_ */ diff --git a/drivers/bus/fsl-mc/fsl-mc-uapi.c b/drivers/bus/fsl-mc/fsl-mc-uapi.c new file mode 100644 index 000000000000..eeb988c9f4bb --- /dev/null +++ b/drivers/bus/fsl-mc/fsl-mc-uapi.c @@ -0,0 +1,547 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Management Complex (MC) userspace support + * + * Copyright 2021 NXP + * + */ + +#include +#include +#include +#include + +#include "fsl-mc-private.h" + +struct uapi_priv_data { + struct fsl_mc_uapi *uapi; + struct fsl_mc_io *mc_io; +}; + +struct fsl_mc_cmd_desc { + u16 cmdid_value; + u16 cmdid_mask; + int size; + bool token; + int flags; +}; + +#define FSL_MC_CHECK_MODULE_ID BIT(0) +#define FSL_MC_CAP_NET_ADMIN_NEEDED BIT(1) + +enum fsl_mc_cmd_index { + DPDBG_DUMP = 0, + DPDBG_SET, + DPRC_GET_CONTAINER_ID, + DPRC_CREATE_CONT, + DPRC_DESTROY_CONT, + DPRC_ASSIGN, + DPRC_UNASSIGN, + DPRC_GET_OBJ_COUNT, + DPRC_GET_OBJ, + DPRC_GET_RES_COUNT, + DPRC_GET_RES_IDS, + DPRC_SET_OBJ_LABEL, + DPRC_SET_LOCKED, + DPRC_CONNECT, + DPRC_DISCONNECT, + DPRC_GET_POOL, + DPRC_GET_POOL_COUNT, + DPRC_GET_CONNECTION, + DPCI_GET_LINK_STATE, + DPCI_GET_PEER_ATTR, + DPAIOP_GET_SL_VERSION, + DPAIOP_GET_STATE, + DPMNG_GET_VERSION, + DPSECI_GET_TX_QUEUE, + DPMAC_GET_COUNTER, + DPMAC_GET_MAC_ADDR, + DPNI_SET_PRIM_MAC, + DPNI_GET_PRIM_MAC, + DPNI_GET_STATISTICS, + DPNI_GET_LINK_STATE, + GET_ATTR, + GET_IRQ_MASK, + GET_IRQ_STATUS, + CLOSE, + OPEN, + GET_API_VERSION, + DESTROY, + CREATE, +}; + +static struct fsl_mc_cmd_desc fsl_mc_accepted_cmds[] = { + [DPDBG_DUMP] = { + .cmdid_value = 0x1300, + .cmdid_mask = 0xFFF0, + .token = true, + .size = 28, + }, + [DPDBG_SET] = { + .cmdid_value = 0x1400, + .cmdid_mask = 0xFFF0, + .token = true, + .size = 28, + }, + [DPRC_GET_CONTAINER_ID] = { + .cmdid_value = 0x8300, + .cmdid_mask = 0xFFF0, + .token = false, + .size = 8, + }, + [DPRC_CREATE_CONT] = { + .cmdid_value = 0x1510, + .cmdid_mask = 0xFFF0, + .token = true, + .size = 40, + .flags = FSL_MC_CAP_NET_ADMIN_NEEDED, + }, + [DPRC_DESTROY_CONT] = { + .cmdid_value = 0x1520, + .cmdid_mask = 0xFFF0, + .token = true, + .size = 12, + .flags = FSL_MC_CAP_NET_ADMIN_NEEDED, + }, + [DPRC_ASSIGN] = { + .cmdid_value = 0x1570, + .cmdid_mask = 0xFFF0, + .token = true, + .size = 40, + .flags = FSL_MC_CAP_NET_ADMIN_NEEDED, + }, + [DPRC_UNASSIGN] = { + .cmdid_value = 0x1580, + .cmdid_mask = 0xFFF0, + .token = true, + .size = 40, + .flags = FSL_MC_CAP_NET_ADMIN_NEEDED, + }, + [DPRC_GET_OBJ_COUNT] = { + .cmdid_value = 0x1590, + .cmdid_mask = 0xFFF0, + .token = true, + .size = 16, + }, + [DPRC_GET_OBJ] = { + .cmdid_value = 0x15A0, + .cmdid_mask = 0xFFF0, + .token = true, + .size = 12, + }, + [DPRC_GET_RES_COUNT] = { + .cmdid_value = 0x15B0, + .cmdid_mask = 0xFFF0, + .token = true, + .size = 32, + }, + [DPRC_GET_RES_IDS] = { + .cmdid_value = 0x15C0, + .cmdid_mask = 0xFFF0, + .token = true, + .size = 40, + }, + [DPRC_SET_OBJ_LABEL] = { + .cmdid_value = 0x1610, + .cmdid_mask = 0xFFF0, + .token = true, + .size = 48, + .flags = FSL_MC_CAP_NET_ADMIN_NEEDED, + }, + [DPRC_SET_LOCKED] = { + .cmdid_value = 0x16B0, + .cmdid_mask = 0xFFF0, + .token = true, + .size = 16, + .flags = FSL_MC_CAP_NET_ADMIN_NEEDED, + }, + [DPRC_CONNECT] = { + .cmdid_value = 0x1670, + .cmdid_mask = 0xFFF0, + .token = true, + .size = 56, + .flags = FSL_MC_CAP_NET_ADMIN_NEEDED, + }, + [DPRC_DISCONNECT] = { + .cmdid_value = 0x1680, + .cmdid_mask = 0xFFF0, + .token = true, + .size = 32, + .flags = FSL_MC_CAP_NET_ADMIN_NEEDED, + }, + [DPRC_GET_POOL] = { + .cmdid_value = 0x1690, + .cmdid_mask = 0xFFF0, + .token = true, + .size = 12, + }, + [DPRC_GET_POOL_COUNT] = { + .cmdid_value = 0x16A0, + .cmdid_mask = 0xFFF0, + .token = true, + .size = 8, + }, + [DPRC_GET_CONNECTION] = { + .cmdid_value = 0x16C0, + .cmdid_mask = 0xFFF0, + .token = true, + .size = 32, + }, + + [DPCI_GET_LINK_STATE] = { + .cmdid_value = 0x0E10, + .cmdid_mask = 0xFFF0, + .token = true, + .size = 8, + }, + [DPCI_GET_PEER_ATTR] = { + .cmdid_value = 0x0E20, + .cmdid_mask = 0xFFF0, + .token = true, + .size = 8, + }, + [DPAIOP_GET_SL_VERSION] = { + .cmdid_value = 0x2820, + .cmdid_mask = 0xFFF0, + .token = true, + .size = 8, + }, + [DPAIOP_GET_STATE] = { + .cmdid_value = 0x2830, + .cmdid_mask = 0xFFF0, + .token = true, + .size = 8, + }, + [DPMNG_GET_VERSION] = { + .cmdid_value = 0x8310, + .cmdid_mask = 0xFFF0, + .token = false, + .size = 8, + }, + [DPSECI_GET_TX_QUEUE] = { + .cmdid_value = 0x1970, + .cmdid_mask = 0xFFF0, + .token = true, + .size = 14, + }, + [DPMAC_GET_COUNTER] = { + .cmdid_value = 0x0c40, + .cmdid_mask = 0xFFF0, + .token = true, + .size = 9, + }, + [DPMAC_GET_MAC_ADDR] = { + .cmdid_value = 0x0c50, + .cmdid_mask = 0xFFF0, + .token = true, + .size = 8, + }, + [DPNI_SET_PRIM_MAC] = { + .cmdid_value = 0x2240, + .cmdid_mask = 0xFFF0, + .token = true, + .size = 16, + .flags = FSL_MC_CAP_NET_ADMIN_NEEDED, + }, + [DPNI_GET_PRIM_MAC] = { + .cmdid_value = 0x2250, + .cmdid_mask = 0xFFF0, + .token = true, + .size = 8, + }, + [DPNI_GET_STATISTICS] = { + .cmdid_value = 0x25D0, + .cmdid_mask = 0xFFF0, + .token = true, + .size = 10, + }, + [DPNI_GET_LINK_STATE] = { + .cmdid_value = 0x2150, + .cmdid_mask = 0xFFF0, + .token = true, + .size = 8, + }, + [GET_ATTR] = { + .cmdid_value = 0x0040, + .cmdid_mask = 0xFFF0, + .token = true, + .size = 8, + }, + [GET_IRQ_MASK] = { + .cmdid_value = 0x0150, + .cmdid_mask = 0xFFF0, + .token = true, + .size = 13, + }, + [GET_IRQ_STATUS] = { + .cmdid_value = 0x0160, + .cmdid_mask = 0xFFF0, + .token = true, + .size = 13, + }, + [CLOSE] = { + .cmdid_value = 0x8000, + .cmdid_mask = 0xFFF0, + .token = true, + .size = 8, + }, + + /* Common commands amongst all types of objects. Must be checked last. */ + [OPEN] = { + .cmdid_value = 0x8000, + .cmdid_mask = 0xFC00, + .token = false, + .size = 12, + .flags = FSL_MC_CHECK_MODULE_ID, + }, + [GET_API_VERSION] = { + .cmdid_value = 0xA000, + .cmdid_mask = 0xFC00, + .token = false, + .size = 8, + .flags = FSL_MC_CHECK_MODULE_ID, + }, + [DESTROY] = { + .cmdid_value = 0x9800, + .cmdid_mask = 0xFC00, + .token = true, + .size = 12, + .flags = FSL_MC_CHECK_MODULE_ID | FSL_MC_CAP_NET_ADMIN_NEEDED, + }, + [CREATE] = { + .cmdid_value = 0x9000, + .cmdid_mask = 0xFC00, + .token = true, + .size = 64, + .flags = FSL_MC_CHECK_MODULE_ID | FSL_MC_CAP_NET_ADMIN_NEEDED, + }, +}; + +#define FSL_MC_NUM_ACCEPTED_CMDS ARRAY_SIZE(fsl_mc_accepted_cmds) + +#define FSL_MC_MAX_MODULE_ID 0x10 + +static int fsl_mc_command_check(struct fsl_mc_device *mc_dev, + struct fsl_mc_command *mc_cmd) +{ + struct fsl_mc_cmd_desc *desc = NULL; + int mc_cmd_max_size, i; + bool token_provided; + u16 cmdid, module_id; + char *mc_cmd_end; + char sum = 0; + + /* Check if this is an accepted MC command */ + cmdid = mc_cmd_hdr_read_cmdid(mc_cmd); + for (i = 0; i < FSL_MC_NUM_ACCEPTED_CMDS; i++) { + desc = &fsl_mc_accepted_cmds[i]; + if ((cmdid & desc->cmdid_mask) == desc->cmdid_value) + break; + } + if (!desc) { + dev_err(&mc_dev->dev, "MC command 0x%04x: cmdid not accepted\n", cmdid); + return -EACCES; + } + + /* Check if the size of the command is honored. Anything beyond the + * last valid byte of the command should be zeroed. + */ + mc_cmd_max_size = sizeof(*mc_cmd); + mc_cmd_end = ((char *)mc_cmd) + desc->size; + for (i = desc->size; i < mc_cmd_max_size; i++) + sum |= *mc_cmd_end++; + if (sum) { + dev_err(&mc_dev->dev, "MC command 0x%04x: garbage beyond max size of %d bytes!\n", + cmdid, desc->size); + return -EACCES; + } + + /* Some MC commands request a token to be passed so that object + * identification is possible. Check if the token passed in the command + * is as expected. + */ + token_provided = mc_cmd_hdr_read_token(mc_cmd) ? true : false; + if (token_provided != desc->token) { + dev_err(&mc_dev->dev, "MC command 0x%04x: token 0x%04x is invalid!\n", + cmdid, mc_cmd_hdr_read_token(mc_cmd)); + return -EACCES; + } + + /* If needed, check if the module ID passed is valid */ + if (desc->flags & FSL_MC_CHECK_MODULE_ID) { + /* The module ID is represented by bits [4:9] from the cmdid */ + module_id = (cmdid & GENMASK(9, 4)) >> 4; + if (module_id == 0 || module_id > FSL_MC_MAX_MODULE_ID) { + dev_err(&mc_dev->dev, "MC command 0x%04x: unknown module ID 0x%x\n", + cmdid, module_id); + return -EACCES; + } + } + + /* Some commands alter how hardware resources are managed. For these + * commands, check for CAP_NET_ADMIN. + */ + if (desc->flags & FSL_MC_CAP_NET_ADMIN_NEEDED) { + if (!capable(CAP_NET_ADMIN)) { + dev_err(&mc_dev->dev, "MC command 0x%04x: needs CAP_NET_ADMIN!\n", + cmdid); + return -EPERM; + } + } + + return 0; +} + +static int fsl_mc_uapi_send_command(struct fsl_mc_device *mc_dev, unsigned long arg, + struct fsl_mc_io *mc_io) +{ + struct fsl_mc_command mc_cmd; + int error; + + error = copy_from_user(&mc_cmd, (void __user *)arg, sizeof(mc_cmd)); + if (error) + return -EFAULT; + + error = fsl_mc_command_check(mc_dev, &mc_cmd); + if (error) + return error; + + error = mc_send_command(mc_io, &mc_cmd); + if (error) + return error; + + error = copy_to_user((void __user *)arg, &mc_cmd, sizeof(mc_cmd)); + if (error) + return -EFAULT; + + return 0; +} + +static int fsl_mc_uapi_dev_open(struct inode *inode, struct file *filep) +{ + struct fsl_mc_device *root_mc_device; + struct uapi_priv_data *priv_data; + struct fsl_mc_io *dynamic_mc_io; + struct fsl_mc_uapi *mc_uapi; + struct fsl_mc_bus *mc_bus; + int error; + + priv_data = kzalloc(sizeof(*priv_data), GFP_KERNEL); + if (!priv_data) + return -ENOMEM; + + mc_uapi = container_of(filep->private_data, struct fsl_mc_uapi, misc); + mc_bus = container_of(mc_uapi, struct fsl_mc_bus, uapi_misc); + root_mc_device = &mc_bus->mc_dev; + + mutex_lock(&mc_uapi->mutex); + + if (!mc_uapi->local_instance_in_use) { + priv_data->mc_io = mc_uapi->static_mc_io; + mc_uapi->local_instance_in_use = 1; + } else { + error = fsl_mc_portal_allocate(root_mc_device, 0, + &dynamic_mc_io); + if (error) { + dev_dbg(&root_mc_device->dev, + "Could not allocate MC portal\n"); + goto error_portal_allocate; + } + + priv_data->mc_io = dynamic_mc_io; + } + priv_data->uapi = mc_uapi; + filep->private_data = priv_data; + + mutex_unlock(&mc_uapi->mutex); + + return 0; + +error_portal_allocate: + mutex_unlock(&mc_uapi->mutex); + kfree(priv_data); + + return error; +} + +static int fsl_mc_uapi_dev_release(struct inode *inode, struct file *filep) +{ + struct uapi_priv_data *priv_data; + struct fsl_mc_uapi *mc_uapi; + struct fsl_mc_io *mc_io; + + priv_data = filep->private_data; + mc_uapi = priv_data->uapi; + mc_io = priv_data->mc_io; + + mutex_lock(&mc_uapi->mutex); + + if (mc_io == mc_uapi->static_mc_io) + mc_uapi->local_instance_in_use = 0; + else + fsl_mc_portal_free(mc_io); + + kfree(filep->private_data); + filep->private_data = NULL; + + mutex_unlock(&mc_uapi->mutex); + + return 0; +} + +static long fsl_mc_uapi_dev_ioctl(struct file *file, + unsigned int cmd, + unsigned long arg) +{ + struct uapi_priv_data *priv_data = file->private_data; + struct fsl_mc_device *root_mc_device; + struct fsl_mc_bus *mc_bus; + int error; + + mc_bus = container_of(priv_data->uapi, struct fsl_mc_bus, uapi_misc); + root_mc_device = &mc_bus->mc_dev; + + switch (cmd) { + case FSL_MC_SEND_MC_COMMAND: + error = fsl_mc_uapi_send_command(root_mc_device, arg, priv_data->mc_io); + break; + default: + dev_dbg(&root_mc_device->dev, "unexpected ioctl call number\n"); + error = -EINVAL; + } + + return error; +} + +static const struct file_operations fsl_mc_uapi_dev_fops = { + .owner = THIS_MODULE, + .open = fsl_mc_uapi_dev_open, + .release = fsl_mc_uapi_dev_release, + .unlocked_ioctl = fsl_mc_uapi_dev_ioctl, +}; + +int fsl_mc_uapi_create_device_file(struct fsl_mc_bus *mc_bus) +{ + struct fsl_mc_device *mc_dev = &mc_bus->mc_dev; + struct fsl_mc_uapi *mc_uapi = &mc_bus->uapi_misc; + int error; + + mc_uapi->misc.minor = MISC_DYNAMIC_MINOR; + mc_uapi->misc.name = dev_name(&mc_dev->dev); + mc_uapi->misc.fops = &fsl_mc_uapi_dev_fops; + + error = misc_register(&mc_uapi->misc); + if (error) + return error; + + mc_uapi->static_mc_io = mc_bus->mc_dev.mc_io; + + mutex_init(&mc_uapi->mutex); + + return 0; +} + +void fsl_mc_uapi_remove_device_file(struct fsl_mc_bus *mc_bus) +{ + misc_deregister(&mc_bus->uapi_misc.misc); +} diff --git a/include/uapi/linux/fsl_mc.h b/include/uapi/linux/fsl_mc.h index cf56d46f052e..e57451570033 100644 --- a/include/uapi/linux/fsl_mc.h +++ b/include/uapi/linux/fsl_mc.h @@ -16,10 +16,19 @@ * struct fsl_mc_command - Management Complex (MC) command structure * @header: MC command header * @params: MC command parameters + * + * Used by FSL_MC_SEND_MC_COMMAND */ struct fsl_mc_command { __le64 header; __le64 params[MC_CMD_NUM_OF_PARAMS]; }; +#define FSL_MC_SEND_CMD_IOCTL_TYPE 'R' +#define FSL_MC_SEND_CMD_IOCTL_SEQ 0xE0 + +#define FSL_MC_SEND_MC_COMMAND \ + _IOWR(FSL_MC_SEND_CMD_IOCTL_TYPE, FSL_MC_SEND_CMD_IOCTL_SEQ, \ + struct fsl_mc_command) + #endif /* _UAPI_FSL_MC_H_ */ -- cgit v1.2.3 From 3f6099438181d269d56f9d4040d93ffae65f9e4c Mon Sep 17 00:00:00 2001 From: Ioana Ciornei Date: Thu, 14 Jan 2021 19:07:51 +0200 Subject: bus: fsl-mc: add bus rescan attribute Introduce the rescan attribute as a bus attribute to synchronize the fsl-mc bus objects and the MC firmware. To rescan the fsl-mc bus, e.g., echo 1 > /sys/bus/fsl-mc/rescan Acked-by: Laurentiu Tudor Signed-off-by: Ioana Ciornei Link: https://lore.kernel.org/r/20210114170752.2927915-5-ciorneiioana@gmail.com Signed-off-by: Greg Kroah-Hartman --- Documentation/ABI/stable/sysfs-bus-fsl-mc | 9 +++++++ MAINTAINERS | 1 + drivers/bus/fsl-mc/dprc-driver.c | 4 +-- drivers/bus/fsl-mc/fsl-mc-bus.c | 41 +++++++++++++++++++++++++++++++ drivers/bus/fsl-mc/fsl-mc-private.h | 3 +++ 5 files changed, 56 insertions(+), 2 deletions(-) create mode 100644 Documentation/ABI/stable/sysfs-bus-fsl-mc (limited to 'Documentation') diff --git a/Documentation/ABI/stable/sysfs-bus-fsl-mc b/Documentation/ABI/stable/sysfs-bus-fsl-mc new file mode 100644 index 000000000000..a4d384df9ba8 --- /dev/null +++ b/Documentation/ABI/stable/sysfs-bus-fsl-mc @@ -0,0 +1,9 @@ +What: /sys/bus/fsl-mc/rescan +Date: January 2021 +KernelVersion: 5.12 +Contact: Ioana Ciornei +Description: Writing a non-zero value to this attribute will + force a rescan of fsl-mc bus in the system and + synchronize the objects under fsl-mc bus and the + Management Complex firmware. +Users: Userspace drivers and management tools diff --git a/MAINTAINERS b/MAINTAINERS index 128455811980..1d9d112af51a 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -14649,6 +14649,7 @@ M: Stuart Yoder M: Laurentiu Tudor L: linux-kernel@vger.kernel.org S: Maintained +F: Documentation/ABI/stable/sysfs-bus-fsl-mc F: Documentation/devicetree/bindings/misc/fsl,qoriq-mc.txt F: Documentation/networking/device_drivers/ethernet/freescale/dpaa2/overview.rst F: drivers/bus/fsl-mc/ diff --git a/drivers/bus/fsl-mc/dprc-driver.c b/drivers/bus/fsl-mc/dprc-driver.c index ccec375095f2..4adb6f318884 100644 --- a/drivers/bus/fsl-mc/dprc-driver.c +++ b/drivers/bus/fsl-mc/dprc-driver.c @@ -237,8 +237,8 @@ static void dprc_add_new_devices(struct fsl_mc_device *mc_bus_dev, * populated before they can get allocation requests from probe callbacks * of the device drivers for the non-allocatable devices. */ -static int dprc_scan_objects(struct fsl_mc_device *mc_bus_dev, - bool alloc_interrupts) +int dprc_scan_objects(struct fsl_mc_device *mc_bus_dev, + bool alloc_interrupts) { int num_child_objects; int dprc_get_obj_failures; diff --git a/drivers/bus/fsl-mc/fsl-mc-bus.c b/drivers/bus/fsl-mc/fsl-mc-bus.c index 5a8fc68d6109..ee3e6252ffc3 100644 --- a/drivers/bus/fsl-mc/fsl-mc-bus.c +++ b/drivers/bus/fsl-mc/fsl-mc-bus.c @@ -208,12 +208,53 @@ static struct attribute *fsl_mc_dev_attrs[] = { ATTRIBUTE_GROUPS(fsl_mc_dev); +static int scan_fsl_mc_bus(struct device *dev, void *data) +{ + struct fsl_mc_device *root_mc_dev; + struct fsl_mc_bus *root_mc_bus; + + if (!fsl_mc_is_root_dprc(dev)) + goto exit; + + root_mc_dev = to_fsl_mc_device(dev); + root_mc_bus = to_fsl_mc_bus(root_mc_dev); + mutex_lock(&root_mc_bus->scan_mutex); + dprc_scan_objects(root_mc_dev, NULL); + mutex_unlock(&root_mc_bus->scan_mutex); + +exit: + return 0; +} + +static ssize_t rescan_store(struct bus_type *bus, + const char *buf, size_t count) +{ + unsigned long val; + + if (kstrtoul(buf, 0, &val) < 0) + return -EINVAL; + + if (val) + bus_for_each_dev(bus, NULL, NULL, scan_fsl_mc_bus); + + return count; +} +static BUS_ATTR_WO(rescan); + +static struct attribute *fsl_mc_bus_attrs[] = { + &bus_attr_rescan.attr, + NULL, +}; + +ATTRIBUTE_GROUPS(fsl_mc_bus); + struct bus_type fsl_mc_bus_type = { .name = "fsl-mc", .match = fsl_mc_bus_match, .uevent = fsl_mc_bus_uevent, .dma_configure = fsl_mc_dma_configure, .dev_groups = fsl_mc_dev_groups, + .bus_groups = fsl_mc_bus_groups, }; EXPORT_SYMBOL_GPL(fsl_mc_bus_type); diff --git a/drivers/bus/fsl-mc/fsl-mc-private.h b/drivers/bus/fsl-mc/fsl-mc-private.h index 6293a24de456..42bdb8679a36 100644 --- a/drivers/bus/fsl-mc/fsl-mc-private.h +++ b/drivers/bus/fsl-mc/fsl-mc-private.h @@ -594,6 +594,9 @@ int __init dprc_driver_init(void); void dprc_driver_exit(void); +int dprc_scan_objects(struct fsl_mc_device *mc_bus_dev, + bool alloc_interrupts); + int __init fsl_mc_allocator_driver_init(void); void fsl_mc_allocator_driver_exit(void); -- cgit v1.2.3 From 296c6264d4b19554dc8367e3f409bd248f504c2d Mon Sep 17 00:00:00 2001 From: Ioana Ciornei Date: Thu, 14 Jan 2021 19:07:52 +0200 Subject: bus: fsl-mc: add autorescan sysfs Add the autorescan sysfs in order to enable/disable the DPRC IRQs on which automatic rescan of the bus is performed. This is important when dynamic creation of objects is needed to happen in a timely manner because object creation can be bundled together. Acked-by: Laurentiu Tudor Signed-off-by: Ioana Ciornei Link: https://lore.kernel.org/r/20210114170752.2927915-6-ciorneiioana@gmail.com Signed-off-by: Greg Kroah-Hartman --- Documentation/ABI/stable/sysfs-bus-fsl-mc | 10 ++++++ drivers/bus/fsl-mc/dprc-driver.c | 17 ++++++++-- drivers/bus/fsl-mc/fsl-mc-bus.c | 55 +++++++++++++++++++++++++++++++ drivers/bus/fsl-mc/fsl-mc-private.h | 5 +++ 4 files changed, 85 insertions(+), 2 deletions(-) (limited to 'Documentation') diff --git a/Documentation/ABI/stable/sysfs-bus-fsl-mc b/Documentation/ABI/stable/sysfs-bus-fsl-mc index a4d384df9ba8..58f06c7eeed7 100644 --- a/Documentation/ABI/stable/sysfs-bus-fsl-mc +++ b/Documentation/ABI/stable/sysfs-bus-fsl-mc @@ -7,3 +7,13 @@ Description: Writing a non-zero value to this attribute will synchronize the objects under fsl-mc bus and the Management Complex firmware. Users: Userspace drivers and management tools + +What: /sys/bus/fsl-mc/autorescan +Date: January 2021 +KernelVersion: 5.12 +Contact: Ioana Ciornei +Description: Writing a zero value to this attribute will + disable the DPRC IRQs on which automatic rescan + of the fsl-mc bus is performed. A non-zero value + will enable the DPRC IRQs. +Users: Userspace drivers and management tools diff --git a/drivers/bus/fsl-mc/dprc-driver.c b/drivers/bus/fsl-mc/dprc-driver.c index 4adb6f318884..e3e2ae41c22b 100644 --- a/drivers/bus/fsl-mc/dprc-driver.c +++ b/drivers/bus/fsl-mc/dprc-driver.c @@ -458,8 +458,9 @@ out: /* * Disable and clear interrupt for a given DPRC object */ -static int disable_dprc_irq(struct fsl_mc_device *mc_dev) +int disable_dprc_irq(struct fsl_mc_device *mc_dev) { + struct fsl_mc_bus *mc_bus = to_fsl_mc_bus(mc_dev); int error; struct fsl_mc_io *mc_io = mc_dev->mc_io; @@ -496,9 +497,18 @@ static int disable_dprc_irq(struct fsl_mc_device *mc_dev) return error; } + mc_bus->irq_enabled = 0; + return 0; } +int get_dprc_irq_state(struct fsl_mc_device *mc_dev) +{ + struct fsl_mc_bus *mc_bus = to_fsl_mc_bus(mc_dev); + + return mc_bus->irq_enabled; +} + static int register_dprc_irq_handler(struct fsl_mc_device *mc_dev) { int error; @@ -525,8 +535,9 @@ static int register_dprc_irq_handler(struct fsl_mc_device *mc_dev) return 0; } -static int enable_dprc_irq(struct fsl_mc_device *mc_dev) +int enable_dprc_irq(struct fsl_mc_device *mc_dev) { + struct fsl_mc_bus *mc_bus = to_fsl_mc_bus(mc_dev); int error; /* @@ -554,6 +565,8 @@ static int enable_dprc_irq(struct fsl_mc_device *mc_dev) return error; } + mc_bus->irq_enabled = 1; + return 0; } diff --git a/drivers/bus/fsl-mc/fsl-mc-bus.c b/drivers/bus/fsl-mc/fsl-mc-bus.c index ee3e6252ffc3..70f4b69556f5 100644 --- a/drivers/bus/fsl-mc/fsl-mc-bus.c +++ b/drivers/bus/fsl-mc/fsl-mc-bus.c @@ -241,8 +241,63 @@ static ssize_t rescan_store(struct bus_type *bus, } static BUS_ATTR_WO(rescan); +static int fsl_mc_bus_set_autorescan(struct device *dev, void *data) +{ + struct fsl_mc_device *root_mc_dev; + unsigned long val; + char *buf = data; + + if (!fsl_mc_is_root_dprc(dev)) + goto exit; + + root_mc_dev = to_fsl_mc_device(dev); + + if (kstrtoul(buf, 0, &val) < 0) + return -EINVAL; + + if (val) + enable_dprc_irq(root_mc_dev); + else + disable_dprc_irq(root_mc_dev); + +exit: + return 0; +} + +static int fsl_mc_bus_get_autorescan(struct device *dev, void *data) +{ + struct fsl_mc_device *root_mc_dev; + char *buf = data; + + if (!fsl_mc_is_root_dprc(dev)) + goto exit; + + root_mc_dev = to_fsl_mc_device(dev); + + sprintf(buf, "%d\n", get_dprc_irq_state(root_mc_dev)); +exit: + return 0; +} + +static ssize_t autorescan_store(struct bus_type *bus, + const char *buf, size_t count) +{ + bus_for_each_dev(bus, NULL, (void *)buf, fsl_mc_bus_set_autorescan); + + return count; +} + +static ssize_t autorescan_show(struct bus_type *bus, char *buf) +{ + bus_for_each_dev(bus, NULL, (void *)buf, fsl_mc_bus_get_autorescan); + return strlen(buf); +} + +static BUS_ATTR_RW(autorescan); + static struct attribute *fsl_mc_bus_attrs[] = { &bus_attr_rescan.attr, + &bus_attr_autorescan.attr, NULL, }; diff --git a/drivers/bus/fsl-mc/fsl-mc-private.h b/drivers/bus/fsl-mc/fsl-mc-private.h index 42bdb8679a36..1958fa065360 100644 --- a/drivers/bus/fsl-mc/fsl-mc-private.h +++ b/drivers/bus/fsl-mc/fsl-mc-private.h @@ -578,6 +578,7 @@ struct fsl_mc_bus { struct mutex scan_mutex; /* serializes bus scanning */ struct dprc_attributes dprc_attr; struct fsl_mc_uapi uapi_misc; + int irq_enabled; }; #define to_fsl_mc_bus(_mc_dev) \ @@ -656,4 +657,8 @@ static inline void fsl_mc_uapi_remove_device_file(struct fsl_mc_bus *mc_bus) #endif +int disable_dprc_irq(struct fsl_mc_device *mc_dev); +int enable_dprc_irq(struct fsl_mc_device *mc_dev); +int get_dprc_irq_state(struct fsl_mc_device *mc_dev); + #endif /* _FSL_MC_PRIVATE_H_ */ -- cgit v1.2.3 From e161ce8e4cc12f2c681b13a160f709d84dee4d4f Mon Sep 17 00:00:00 2001 From: Vinod Koul Date: Wed, 27 Jan 2021 18:00:50 +0530 Subject: soc: qcom: aoss: Add SM8350 compatible Add SM8350 compatible to the qcom_aoss binding and driver. Acked-by: Rob Herring Signed-off-by: Vinod Koul Link: https://lore.kernel.org/r/20210127123054.263231-3-vkoul@kernel.org Signed-off-by: Bjorn Andersson --- Documentation/devicetree/bindings/soc/qcom/qcom,aoss-qmp.txt | 1 + drivers/soc/qcom/qcom_aoss.c | 1 + 2 files changed, 2 insertions(+) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/soc/qcom/qcom,aoss-qmp.txt b/Documentation/devicetree/bindings/soc/qcom/qcom,aoss-qmp.txt index 953add19e937..19c059e44681 100644 --- a/Documentation/devicetree/bindings/soc/qcom/qcom,aoss-qmp.txt +++ b/Documentation/devicetree/bindings/soc/qcom/qcom,aoss-qmp.txt @@ -20,6 +20,7 @@ power-domains. "qcom,sdm845-aoss-qmp" "qcom,sm8150-aoss-qmp" "qcom,sm8250-aoss-qmp" + "qcom,sm8350-aoss-qmp" - reg: Usage: required diff --git a/drivers/soc/qcom/qcom_aoss.c b/drivers/soc/qcom/qcom_aoss.c index b5840d624bc6..53acb9423bd6 100644 --- a/drivers/soc/qcom/qcom_aoss.c +++ b/drivers/soc/qcom/qcom_aoss.c @@ -600,6 +600,7 @@ static const struct of_device_id qmp_dt_match[] = { { .compatible = "qcom,sdm845-aoss-qmp", }, { .compatible = "qcom,sm8150-aoss-qmp", }, { .compatible = "qcom,sm8250-aoss-qmp", }, + { .compatible = "qcom,sm8350-aoss-qmp", }, {} }; MODULE_DEVICE_TABLE(of, qmp_dt_match); -- cgit v1.2.3 From 35cb6aa82656f11196b13cd94cdbc5816d12b5a0 Mon Sep 17 00:00:00 2001 From: Jacopo Mondi Date: Fri, 15 Jan 2021 11:16:52 +0100 Subject: media: dt-bindings: media: ov5647: Fix filename Commit 1b5071af8240 ("media: dt-bindings: media: i2c: Rename ov5647.yaml") renamed the bindings file but did not update the Id: field there. Fix it by using the new filename. Fixes: 1b5071af8240 ("media: dt-bindings: media: i2c: Rename ov5647.yaml") Signed-off-by: Jacopo Mondi Reviewed-by: Kieran Bingham Reviewed-by: Rob Herring Signed-off-by: Sakari Ailus Signed-off-by: Mauro Carvalho Chehab --- Documentation/devicetree/bindings/media/i2c/ovti,ov5647.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/media/i2c/ovti,ov5647.yaml b/Documentation/devicetree/bindings/media/i2c/ovti,ov5647.yaml index 280c62afae13..429566c9ee1d 100644 --- a/Documentation/devicetree/bindings/media/i2c/ovti,ov5647.yaml +++ b/Documentation/devicetree/bindings/media/i2c/ovti,ov5647.yaml @@ -1,7 +1,7 @@ # SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) %YAML 1.2 --- -$id: http://devicetree.org/schemas/media/i2c/ov5647.yaml# +$id: http://devicetree.org/schemas/media/i2c/ovti,ov5647.yaml# $schema: http://devicetree.org/meta-schemas/core.yaml# title: Omnivision OV5647 raw image sensor -- cgit v1.2.3 From 3daa96d67274653b7c461b30ef9581d68e905fe1 Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Tue, 10 Nov 2020 16:37:51 +0100 Subject: perf/intel: Remove Perfmon-v4 counter_freezing support Perfmon-v4 counter freezing is fundamentally broken; remove this default disabled code to make sure nobody uses it. The feature is called Freeze-on-PMI in the SDM, and if it would do that, there wouldn't actually be a problem, *however* it does something subtly different. It globally disables the whole PMU when it raises the PMI, not when the PMI hits. This means there's a window between the PMI getting raised and the PMI actually getting served where we loose events and this violates the perf counter independence. That is, a counting event should not result in a different event count when there is a sampling event co-scheduled. This is known to break existing software (RR). Signed-off-by: Peter Zijlstra (Intel) --- Documentation/admin-guide/kernel-parameters.txt | 6 - arch/x86/events/intel/core.c | 152 ------------------------ arch/x86/events/perf_event.h | 3 +- 3 files changed, 1 insertion(+), 160 deletions(-) (limited to 'Documentation') diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt index c722ec19cd00..628493901b02 100644 --- a/Documentation/admin-guide/kernel-parameters.txt +++ b/Documentation/admin-guide/kernel-parameters.txt @@ -944,12 +944,6 @@ causing system reset or hang due to sending INIT from AP to BSP. - perf_v4_pmi= [X86,INTEL] - Format: - Disable Intel PMU counter freezing feature. - The feature only exists starting from - Arch Perfmon v4 (Skylake and newer). - disable_ddw [PPC/PSERIES] Disable Dynamic DMA Window support. Use this to workaround buggy firmware. diff --git a/arch/x86/events/intel/core.c b/arch/x86/events/intel/core.c index 93adf53cce5f..fe940082d49a 100644 --- a/arch/x86/events/intel/core.c +++ b/arch/x86/events/intel/core.c @@ -2134,18 +2134,6 @@ static void intel_tfa_pmu_enable_all(int added) intel_pmu_enable_all(added); } -static void enable_counter_freeze(void) -{ - update_debugctlmsr(get_debugctlmsr() | - DEBUGCTLMSR_FREEZE_PERFMON_ON_PMI); -} - -static void disable_counter_freeze(void) -{ - update_debugctlmsr(get_debugctlmsr() & - ~DEBUGCTLMSR_FREEZE_PERFMON_ON_PMI); -} - static inline u64 intel_pmu_get_status(void) { u64 status; @@ -2709,95 +2697,6 @@ static int handle_pmi_common(struct pt_regs *regs, u64 status) return handled; } -static bool disable_counter_freezing = true; -static int __init intel_perf_counter_freezing_setup(char *s) -{ - bool res; - - if (kstrtobool(s, &res)) - return -EINVAL; - - disable_counter_freezing = !res; - return 1; -} -__setup("perf_v4_pmi=", intel_perf_counter_freezing_setup); - -/* - * Simplified handler for Arch Perfmon v4: - * - We rely on counter freezing/unfreezing to enable/disable the PMU. - * This is done automatically on PMU ack. - * - Ack the PMU only after the APIC. - */ - -static int intel_pmu_handle_irq_v4(struct pt_regs *regs) -{ - struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events); - int handled = 0; - bool bts = false; - u64 status; - int pmu_enabled = cpuc->enabled; - int loops = 0; - - /* PMU has been disabled because of counter freezing */ - cpuc->enabled = 0; - if (test_bit(INTEL_PMC_IDX_FIXED_BTS, cpuc->active_mask)) { - bts = true; - intel_bts_disable_local(); - handled = intel_pmu_drain_bts_buffer(); - handled += intel_bts_interrupt(); - } - status = intel_pmu_get_status(); - if (!status) - goto done; -again: - intel_pmu_lbr_read(); - if (++loops > 100) { - static bool warned; - - if (!warned) { - WARN(1, "perfevents: irq loop stuck!\n"); - perf_event_print_debug(); - warned = true; - } - intel_pmu_reset(); - goto done; - } - - - handled += handle_pmi_common(regs, status); -done: - /* Ack the PMI in the APIC */ - apic_write(APIC_LVTPC, APIC_DM_NMI); - - /* - * The counters start counting immediately while ack the status. - * Make it as close as possible to IRET. This avoids bogus - * freezing on Skylake CPUs. - */ - if (status) { - intel_pmu_ack_status(status); - } else { - /* - * CPU may issues two PMIs very close to each other. - * When the PMI handler services the first one, the - * GLOBAL_STATUS is already updated to reflect both. - * When it IRETs, the second PMI is immediately - * handled and it sees clear status. At the meantime, - * there may be a third PMI, because the freezing bit - * isn't set since the ack in first PMI handlers. - * Double check if there is more work to be done. - */ - status = intel_pmu_get_status(); - if (status) - goto again; - } - - if (bts) - intel_bts_enable_local(); - cpuc->enabled = pmu_enabled; - return handled; -} - /* * This handler is triggered by the local APIC, so the APIC IRQ handling * rules apply: @@ -4074,9 +3973,6 @@ static void intel_pmu_cpu_starting(int cpu) if (x86_pmu.version > 1) flip_smm_bit(&x86_pmu.attr_freeze_on_smi); - if (x86_pmu.counter_freezing) - enable_counter_freeze(); - /* Disable perf metrics if any added CPU doesn't support it. */ if (x86_pmu.intel_cap.perf_metrics) { union perf_capabilities perf_cap; @@ -4147,9 +4043,6 @@ static void free_excl_cntrs(struct cpu_hw_events *cpuc) static void intel_pmu_cpu_dying(int cpu) { fini_debug_store_on_cpu(cpu); - - if (x86_pmu.counter_freezing) - disable_counter_freeze(); } void intel_cpuc_finish(struct cpu_hw_events *cpuc) @@ -4541,39 +4434,6 @@ static __init void intel_nehalem_quirk(void) } } -static const struct x86_cpu_desc counter_freezing_ucodes[] = { - INTEL_CPU_DESC(INTEL_FAM6_ATOM_GOLDMONT, 2, 0x0000000e), - INTEL_CPU_DESC(INTEL_FAM6_ATOM_GOLDMONT, 9, 0x0000002e), - INTEL_CPU_DESC(INTEL_FAM6_ATOM_GOLDMONT, 10, 0x00000008), - INTEL_CPU_DESC(INTEL_FAM6_ATOM_GOLDMONT_D, 1, 0x00000028), - INTEL_CPU_DESC(INTEL_FAM6_ATOM_GOLDMONT_PLUS, 1, 0x00000028), - INTEL_CPU_DESC(INTEL_FAM6_ATOM_GOLDMONT_PLUS, 8, 0x00000006), - {} -}; - -static bool intel_counter_freezing_broken(void) -{ - return !x86_cpu_has_min_microcode_rev(counter_freezing_ucodes); -} - -static __init void intel_counter_freezing_quirk(void) -{ - /* Check if it's already disabled */ - if (disable_counter_freezing) - return; - - /* - * If the system starts with the wrong ucode, leave the - * counter-freezing feature permanently disabled. - */ - if (intel_counter_freezing_broken()) { - pr_info("PMU counter freezing disabled due to CPU errata," - "please upgrade microcode\n"); - x86_pmu.counter_freezing = false; - x86_pmu.handle_irq = intel_pmu_handle_irq; - } -} - /* * enable software workaround for errata: * SNB: BJ122 @@ -4959,9 +4819,6 @@ __init int intel_pmu_init(void) max((int)edx.split.num_counters_fixed, assume); } - if (version >= 4) - x86_pmu.counter_freezing = !disable_counter_freezing; - if (boot_cpu_has(X86_FEATURE_PDCM)) { u64 capabilities; @@ -5089,7 +4946,6 @@ __init int intel_pmu_init(void) case INTEL_FAM6_ATOM_GOLDMONT: case INTEL_FAM6_ATOM_GOLDMONT_D: - x86_add_quirk(intel_counter_freezing_quirk); memcpy(hw_cache_event_ids, glm_hw_cache_event_ids, sizeof(hw_cache_event_ids)); memcpy(hw_cache_extra_regs, glm_hw_cache_extra_regs, @@ -5116,7 +4972,6 @@ __init int intel_pmu_init(void) break; case INTEL_FAM6_ATOM_GOLDMONT_PLUS: - x86_add_quirk(intel_counter_freezing_quirk); memcpy(hw_cache_event_ids, glp_hw_cache_event_ids, sizeof(hw_cache_event_ids)); memcpy(hw_cache_extra_regs, glp_hw_cache_extra_regs, @@ -5581,13 +5436,6 @@ __init int intel_pmu_init(void) pr_cont("full-width counters, "); } - /* - * For arch perfmon 4 use counter freezing to avoid - * several MSR accesses in the PMI. - */ - if (x86_pmu.counter_freezing) - x86_pmu.handle_irq = intel_pmu_handle_irq_v4; - if (x86_pmu.intel_cap.perf_metrics) x86_pmu.intel_ctrl |= 1ULL << GLOBAL_CTRL_EN_PERF_METRICS; diff --git a/arch/x86/events/perf_event.h b/arch/x86/events/perf_event.h index 7895cf4c59a7..978a16e7a8d0 100644 --- a/arch/x86/events/perf_event.h +++ b/arch/x86/events/perf_event.h @@ -682,8 +682,7 @@ struct x86_pmu { /* PMI handler bits */ unsigned int late_ack :1, - enabled_ack :1, - counter_freezing :1; + enabled_ack :1; /* * sysfs attrs */ -- cgit v1.2.3 From 67883ade7a98a7589ca50e97b1c7b7893886d30e Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Tue, 26 Jan 2021 15:52:38 +0100 Subject: f2fs: remove FAULT_ALLOC_BIO Sleeping bio allocations do not fail, which means that injecting an error into sleeping bio allocations is a little silly. Signed-off-by: Christoph Hellwig Reviewed-by: Johannes Thumshirn Reviewed-by: Chaitanya Kulkarni Acked-by: Damien Le Moal Signed-off-by: Jens Axboe --- Documentation/filesystems/f2fs.rst | 1 - fs/f2fs/data.c | 29 ++++------------------------- fs/f2fs/f2fs.h | 1 - fs/f2fs/super.c | 1 - 4 files changed, 4 insertions(+), 28 deletions(-) (limited to 'Documentation') diff --git a/Documentation/filesystems/f2fs.rst b/Documentation/filesystems/f2fs.rst index dae15c96e659..624f5f3ed93e 100644 --- a/Documentation/filesystems/f2fs.rst +++ b/Documentation/filesystems/f2fs.rst @@ -179,7 +179,6 @@ fault_type=%d Support configuring fault injection type, should be FAULT_KVMALLOC 0x000000002 FAULT_PAGE_ALLOC 0x000000004 FAULT_PAGE_GET 0x000000008 - FAULT_ALLOC_BIO 0x000000010 FAULT_ALLOC_NID 0x000000020 FAULT_ORPHAN 0x000000040 FAULT_BLOCK 0x000000080 diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c index 0cf0c6059924..9fb6be65592b 100644 --- a/fs/f2fs/data.c +++ b/fs/f2fs/data.c @@ -50,28 +50,6 @@ void f2fs_destroy_bioset(void) bioset_exit(&f2fs_bioset); } -static inline struct bio *__f2fs_bio_alloc(gfp_t gfp_mask, - unsigned int nr_iovecs) -{ - return bio_alloc_bioset(gfp_mask, nr_iovecs, &f2fs_bioset); -} - -static struct bio *f2fs_bio_alloc(struct f2fs_sb_info *sbi, int npages, - bool noio) -{ - if (noio) { - /* No failure on bio allocation */ - return __f2fs_bio_alloc(GFP_NOIO, npages); - } - - if (time_to_inject(sbi, FAULT_ALLOC_BIO)) { - f2fs_show_injection_info(sbi, FAULT_ALLOC_BIO); - return NULL; - } - - return __f2fs_bio_alloc(GFP_KERNEL, npages); -} - static bool __is_cp_guaranteed(struct page *page) { struct address_space *mapping = page->mapping; @@ -433,7 +411,7 @@ static struct bio *__bio_alloc(struct f2fs_io_info *fio, int npages) struct f2fs_sb_info *sbi = fio->sbi; struct bio *bio; - bio = f2fs_bio_alloc(sbi, npages, true); + bio = bio_alloc_bioset(GFP_NOIO, npages, &f2fs_bioset); f2fs_target_device(sbi, fio->new_blkaddr, bio); if (is_read_io(fio->op)) { @@ -1029,8 +1007,9 @@ static struct bio *f2fs_grab_read_bio(struct inode *inode, block_t blkaddr, struct bio_post_read_ctx *ctx; unsigned int post_read_steps = 0; - bio = f2fs_bio_alloc(sbi, min_t(int, nr_pages, BIO_MAX_PAGES), - for_write); + bio = bio_alloc_bioset(for_write ? GFP_NOIO : GFP_KERNEL, + min_t(int, nr_pages, BIO_MAX_PAGES), + &f2fs_bioset); if (!bio) return ERR_PTR(-ENOMEM); diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h index 902bd3267c03..6c78365d80ce 100644 --- a/fs/f2fs/f2fs.h +++ b/fs/f2fs/f2fs.h @@ -43,7 +43,6 @@ enum { FAULT_KVMALLOC, FAULT_PAGE_ALLOC, FAULT_PAGE_GET, - FAULT_ALLOC_BIO, FAULT_ALLOC_NID, FAULT_ORPHAN, FAULT_BLOCK, diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c index b4a07fe62d1a..3a312642907e 100644 --- a/fs/f2fs/super.c +++ b/fs/f2fs/super.c @@ -45,7 +45,6 @@ const char *f2fs_fault_name[FAULT_MAX] = { [FAULT_KVMALLOC] = "kvmalloc", [FAULT_PAGE_ALLOC] = "page alloc", [FAULT_PAGE_GET] = "page get", - [FAULT_ALLOC_BIO] = "alloc bio", [FAULT_ALLOC_NID] = "alloc nid", [FAULT_ORPHAN] = "orphan", [FAULT_BLOCK] = "no more block", -- cgit v1.2.3 From 309663093c8aba02cbea83b0bc8ee9a99833c482 Mon Sep 17 00:00:00 2001 From: Bjorn Helgaas Date: Tue, 26 Jan 2021 15:26:55 -0600 Subject: PM: runtime: Fix typos and grammar Fix minor typos and grammatical issues. Signed-off-by: Bjorn Helgaas Signed-off-by: Rafael J. Wysocki --- Documentation/power/runtime_pm.rst | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'Documentation') diff --git a/Documentation/power/runtime_pm.rst b/Documentation/power/runtime_pm.rst index 0553008b6279..d9c777b18f7a 100644 --- a/Documentation/power/runtime_pm.rst +++ b/Documentation/power/runtime_pm.rst @@ -579,7 +579,7 @@ should be used. Of course, for this purpose the device's runtime PM has to be enabled earlier by calling pm_runtime_enable(). Note, if the device may execute pm_runtime calls during the probe (such as -if it is registers with a subsystem that may call back in) then the +if it is registered with a subsystem that may call back in) then the pm_runtime_get_sync() call paired with a pm_runtime_put() call will be appropriate to ensure that the device is not put back to sleep during the probe. This can happen with systems such as the network device layer. @@ -587,11 +587,11 @@ probe. This can happen with systems such as the network device layer. It may be desirable to suspend the device once ->probe() has finished. Therefore the driver core uses the asynchronous pm_request_idle() to submit a request to execute the subsystem-level idle callback for the device at that -time. A driver that makes use of the runtime autosuspend feature, may want to +time. A driver that makes use of the runtime autosuspend feature may want to update the last busy mark before returning from ->probe(). Moreover, the driver core prevents runtime PM callbacks from racing with the bus -notifier callback in __device_release_driver(), which is necessary, because the +notifier callback in __device_release_driver(), which is necessary because the notifier is used by some subsystems to carry out operations affecting the runtime PM functionality. It does so by calling pm_runtime_get_sync() before driver_sysfs_remove() and the BUS_NOTIFY_UNBIND_DRIVER notifications. This @@ -603,7 +603,7 @@ calling pm_runtime_suspend() from their ->remove() routines, the driver core executes pm_runtime_put_sync() after running the BUS_NOTIFY_UNBIND_DRIVER notifications in __device_release_driver(). This requires bus types and drivers to make their ->remove() callbacks avoid races with runtime PM directly, -but also it allows of more flexibility in the handling of devices during the +but it also allows more flexibility in the handling of devices during the removal of their drivers. Drivers in ->remove() callback should undo the runtime PM changes done @@ -693,7 +693,7 @@ that the device appears to be runtime-suspended and its state is fine, so it may be left in runtime suspend provided that all of its descendants are also left in runtime suspend. If that happens, the PM core will not execute any system suspend and resume callbacks for all of those devices, except for the -complete callback, which is then entirely responsible for handling the device +.complete() callback, which is then entirely responsible for handling the device as appropriate. This only applies to system suspend transitions that are not related to hibernation (see Documentation/driver-api/pm/devices.rst for more information). @@ -706,7 +706,7 @@ out the following operations: right before executing the subsystem-level .prepare() callback for it and pm_runtime_barrier() is called for every device right before executing the subsystem-level .suspend() callback for it. In addition to that the PM core - calls __pm_runtime_disable() with 'false' as the second argument for every + calls __pm_runtime_disable() with 'false' as the second argument for every device right before executing the subsystem-level .suspend_late() callback for it. @@ -783,7 +783,7 @@ driver/base/power/generic_ops.c: `int pm_generic_restore_noirq(struct device *dev);` - invoke the ->restore_noirq() callback provided by the device's driver -These functions are the defaults used by the PM core, if a subsystem doesn't +These functions are the defaults used by the PM core if a subsystem doesn't provide its own callbacks for ->runtime_idle(), ->runtime_suspend(), ->runtime_resume(), ->suspend(), ->suspend_noirq(), ->resume(), ->resume_noirq(), ->freeze(), ->freeze_noirq(), ->thaw(), ->thaw_noirq(), -- cgit v1.2.3 From d2b980f3299e9bdef55399c9cde6a72e0b6d446c Mon Sep 17 00:00:00 2001 From: Ofir Bitton Date: Thu, 7 Jan 2021 12:14:17 +0200 Subject: habanalabs: add security violations dump to debugfs In order to improve driver security debuggability, we add security violations dump to debugfs. Signed-off-by: Ofir Bitton Reviewed-by: Oded Gabbay Signed-off-by: Oded Gabbay --- .../ABI/testing/debugfs-driver-habanalabs | 8 ++++++++ drivers/misc/habanalabs/common/debugfs.c | 22 ++++++++++++++++++++++ drivers/misc/habanalabs/common/habanalabs.h | 2 ++ drivers/misc/habanalabs/gaudi/gaudi.c | 3 ++- drivers/misc/habanalabs/gaudi/gaudiP.h | 1 + drivers/misc/habanalabs/gaudi/gaudi_security.c | 5 +++++ drivers/misc/habanalabs/goya/goya.c | 3 ++- drivers/misc/habanalabs/goya/goyaP.h | 1 + drivers/misc/habanalabs/goya/goya_security.c | 5 +++++ 9 files changed, 48 insertions(+), 2 deletions(-) (limited to 'Documentation') diff --git a/Documentation/ABI/testing/debugfs-driver-habanalabs b/Documentation/ABI/testing/debugfs-driver-habanalabs index c5d678d39144..3979bfdaa080 100644 --- a/Documentation/ABI/testing/debugfs-driver-habanalabs +++ b/Documentation/ABI/testing/debugfs-driver-habanalabs @@ -182,3 +182,11 @@ KernelVersion: 5.6 Contact: oded.gabbay@gmail.com Description: Sets the stop-on_error option for the device engines. Value of "0" is for disable, otherwise enable. + +What: /sys/kernel/debug/habanalabs/hl/dump_security_violations +Date: Jan 2021 +KernelVersion: 5.12 +Contact: oded.gabbay@gmail.com +Description: Dumps all security violations to dmesg. This will also ack + all security violations meanings those violations will not be + dumped next time user calls this API diff --git a/drivers/misc/habanalabs/common/debugfs.c b/drivers/misc/habanalabs/common/debugfs.c index 50ca8eea6648..323d0381a60a 100644 --- a/drivers/misc/habanalabs/common/debugfs.c +++ b/drivers/misc/habanalabs/common/debugfs.c @@ -867,6 +867,17 @@ static ssize_t hl_stop_on_err_write(struct file *f, const char __user *buf, return count; } +static ssize_t hl_security_violations_read(struct file *f, char __user *buf, + size_t count, loff_t *ppos) +{ + struct hl_dbg_device_entry *entry = file_inode(f)->i_private; + struct hl_device *hdev = entry->hdev; + + hdev->asic_funcs->ack_protection_bits_errors(hdev); + + return 0; +} + static const struct file_operations hl_data32b_fops = { .owner = THIS_MODULE, .read = hl_data_read32, @@ -924,6 +935,11 @@ static const struct file_operations hl_stop_on_err_fops = { .write = hl_stop_on_err_write }; +static const struct file_operations hl_security_violations_fops = { + .owner = THIS_MODULE, + .read = hl_security_violations_read +}; + static const struct hl_info_list hl_debugfs_list[] = { {"command_buffers", command_buffers_show, NULL}, {"command_submission", command_submission_show, NULL}, @@ -1073,6 +1089,12 @@ void hl_debugfs_add_device(struct hl_device *hdev) dev_entry, &hl_stop_on_err_fops); + debugfs_create_file("dump_security_violations", + 0644, + dev_entry->root, + dev_entry, + &hl_security_violations_fops); + for (i = 0, entry = dev_entry->entry_arr ; i < count ; i++, entry++) { ent = debugfs_create_file(hl_debugfs_list[i].name, diff --git a/drivers/misc/habanalabs/common/habanalabs.h b/drivers/misc/habanalabs/common/habanalabs.h index 8e0553bf3e0e..3923b03e99aa 100644 --- a/drivers/misc/habanalabs/common/habanalabs.h +++ b/drivers/misc/habanalabs/common/habanalabs.h @@ -850,6 +850,7 @@ enum div_select_defs { * @collective_wait_create_jobs: allocate collective wait cs jobs * @scramble_vaddr: Routine to scramble the virtual address prior of mapping it * in the MMU. + * @ack_protection_bits_errors: ack and dump all security violations */ struct hl_asic_funcs { int (*early_init)(struct hl_device *hdev); @@ -960,6 +961,7 @@ struct hl_asic_funcs { struct hl_ctx *ctx, struct hl_cs *cs, u32 wait_queue_id, u32 collective_engine_id); u64 (*scramble_vaddr)(struct hl_device *hdev, u64 virt_addr); + void (*ack_protection_bits_errors)(struct hl_device *hdev); }; diff --git a/drivers/misc/habanalabs/gaudi/gaudi.c b/drivers/misc/habanalabs/gaudi/gaudi.c index d9f1b646aac9..2b01c081404a 100644 --- a/drivers/misc/habanalabs/gaudi/gaudi.c +++ b/drivers/misc/habanalabs/gaudi/gaudi.c @@ -8546,7 +8546,8 @@ static const struct hl_asic_funcs gaudi_funcs = { .get_device_time = gaudi_get_device_time, .collective_wait_init_cs = gaudi_collective_wait_init_cs, .collective_wait_create_jobs = gaudi_collective_wait_create_jobs, - .scramble_vaddr = hl_mmu_scramble_vaddr + .scramble_vaddr = hl_mmu_scramble_vaddr, + .ack_protection_bits_errors = gaudi_ack_protection_bits_errors }; /** diff --git a/drivers/misc/habanalabs/gaudi/gaudiP.h b/drivers/misc/habanalabs/gaudi/gaudiP.h index 78830443341d..50bb4ad570fd 100644 --- a/drivers/misc/habanalabs/gaudi/gaudiP.h +++ b/drivers/misc/habanalabs/gaudi/gaudiP.h @@ -335,6 +335,7 @@ struct gaudi_device { }; void gaudi_init_security(struct hl_device *hdev); +void gaudi_ack_protection_bits_errors(struct hl_device *hdev); void gaudi_add_device_attr(struct hl_device *hdev, struct attribute_group *dev_attr_grp); void gaudi_set_pll_profile(struct hl_device *hdev, enum hl_pll_frequency freq); diff --git a/drivers/misc/habanalabs/gaudi/gaudi_security.c b/drivers/misc/habanalabs/gaudi/gaudi_security.c index e10181692d0b..7085f45814ae 100644 --- a/drivers/misc/habanalabs/gaudi/gaudi_security.c +++ b/drivers/misc/habanalabs/gaudi/gaudi_security.c @@ -13052,3 +13052,8 @@ void gaudi_init_security(struct hl_device *hdev) gaudi_init_protection_bits(hdev); } + +void gaudi_ack_protection_bits_errors(struct hl_device *hdev) +{ + +} diff --git a/drivers/misc/habanalabs/goya/goya.c b/drivers/misc/habanalabs/goya/goya.c index cf0496b04044..50dcefc02cdd 100644 --- a/drivers/misc/habanalabs/goya/goya.c +++ b/drivers/misc/habanalabs/goya/goya.c @@ -5457,7 +5457,8 @@ static const struct hl_asic_funcs goya_funcs = { .get_device_time = goya_get_device_time, .collective_wait_init_cs = goya_collective_wait_init_cs, .collective_wait_create_jobs = goya_collective_wait_create_jobs, - .scramble_vaddr = hl_mmu_scramble_vaddr + .scramble_vaddr = hl_mmu_scramble_vaddr, + .ack_protection_bits_errors = goya_ack_protection_bits_errors }; /* diff --git a/drivers/misc/habanalabs/goya/goyaP.h b/drivers/misc/habanalabs/goya/goyaP.h index 8b3408211af6..23fe099ed218 100644 --- a/drivers/misc/habanalabs/goya/goyaP.h +++ b/drivers/misc/habanalabs/goya/goyaP.h @@ -173,6 +173,7 @@ void goya_init_mme_qmans(struct hl_device *hdev); void goya_init_tpc_qmans(struct hl_device *hdev); int goya_init_cpu_queues(struct hl_device *hdev); void goya_init_security(struct hl_device *hdev); +void goya_ack_protection_bits_errors(struct hl_device *hdev); int goya_late_init(struct hl_device *hdev); void goya_late_fini(struct hl_device *hdev); diff --git a/drivers/misc/habanalabs/goya/goya_security.c b/drivers/misc/habanalabs/goya/goya_security.c index 14701836f92b..14c3bae3ccdc 100644 --- a/drivers/misc/habanalabs/goya/goya_security.c +++ b/drivers/misc/habanalabs/goya/goya_security.c @@ -3120,3 +3120,8 @@ void goya_init_security(struct hl_device *hdev) goya_init_protection_bits(hdev); } + +void goya_ack_protection_bits_errors(struct hl_device *hdev) +{ + +} -- cgit v1.2.3 From 2f8db5a1754416ba869ce200e1de37a0ccfb3087 Mon Sep 17 00:00:00 2001 From: Oded Gabbay Date: Tue, 12 Jan 2021 15:13:06 +0200 Subject: habanalabs: update email address in sysfs/debugfs docs Use my kernel.org address for contact point instead of my private email address. Signed-off-by: Oded Gabbay --- .../ABI/testing/debugfs-driver-habanalabs | 44 ++++++++-------- Documentation/ABI/testing/sysfs-driver-habanalabs | 58 +++++++++++----------- 2 files changed, 51 insertions(+), 51 deletions(-) (limited to 'Documentation') diff --git a/Documentation/ABI/testing/debugfs-driver-habanalabs b/Documentation/ABI/testing/debugfs-driver-habanalabs index 3979bfdaa080..d447a611c41b 100644 --- a/Documentation/ABI/testing/debugfs-driver-habanalabs +++ b/Documentation/ABI/testing/debugfs-driver-habanalabs @@ -1,7 +1,7 @@ What: /sys/kernel/debug/habanalabs/hl/addr Date: Jan 2019 KernelVersion: 5.1 -Contact: oded.gabbay@gmail.com +Contact: ogabbay@kernel.org Description: Sets the device address to be used for read or write through PCI bar, or the device VA of a host mapped memory to be read or written directly from the host. The latter option is allowed @@ -11,7 +11,7 @@ Description: Sets the device address to be used for read or write through What: /sys/kernel/debug/habanalabs/hl/clk_gate Date: May 2020 KernelVersion: 5.8 -Contact: oded.gabbay@gmail.com +Contact: ogabbay@kernel.org Description: Allow the root user to disable/enable in runtime the clock gating mechanism in Gaudi. Due to how Gaudi is built, the clock gating needs to be disabled in order to access the @@ -34,28 +34,28 @@ Description: Allow the root user to disable/enable in runtime the clock What: /sys/kernel/debug/habanalabs/hl/command_buffers Date: Jan 2019 KernelVersion: 5.1 -Contact: oded.gabbay@gmail.com +Contact: ogabbay@kernel.org Description: Displays a list with information about the currently allocated command buffers What: /sys/kernel/debug/habanalabs/hl/command_submission Date: Jan 2019 KernelVersion: 5.1 -Contact: oded.gabbay@gmail.com +Contact: ogabbay@kernel.org Description: Displays a list with information about the currently active command submissions What: /sys/kernel/debug/habanalabs/hl/command_submission_jobs Date: Jan 2019 KernelVersion: 5.1 -Contact: oded.gabbay@gmail.com +Contact: ogabbay@kernel.org Description: Displays a list with detailed information about each JOB (CB) of each active command submission What: /sys/kernel/debug/habanalabs/hl/data32 Date: Jan 2019 KernelVersion: 5.1 -Contact: oded.gabbay@gmail.com +Contact: ogabbay@kernel.org Description: Allows the root user to read or write directly through the device's PCI bar. Writing to this file generates a write transaction while reading from the file generates a read @@ -70,7 +70,7 @@ Description: Allows the root user to read or write directly through the What: /sys/kernel/debug/habanalabs/hl/data64 Date: Jan 2020 KernelVersion: 5.6 -Contact: oded.gabbay@gmail.com +Contact: ogabbay@kernel.org Description: Allows the root user to read or write 64 bit data directly through the device's PCI bar. Writing to this file generates a write transaction while reading from the file generates a read @@ -85,7 +85,7 @@ Description: Allows the root user to read or write 64 bit data directly What: /sys/kernel/debug/habanalabs/hl/device Date: Jan 2019 KernelVersion: 5.1 -Contact: oded.gabbay@gmail.com +Contact: ogabbay@kernel.org Description: Enables the root user to set the device to specific state. Valid values are "disable", "enable", "suspend", "resume". User can read this property to see the valid values @@ -93,28 +93,28 @@ Description: Enables the root user to set the device to specific state. What: /sys/kernel/debug/habanalabs/hl/engines Date: Jul 2019 KernelVersion: 5.3 -Contact: oded.gabbay@gmail.com +Contact: ogabbay@kernel.org Description: Displays the status registers values of the device engines and their derived idle status What: /sys/kernel/debug/habanalabs/hl/i2c_addr Date: Jan 2019 KernelVersion: 5.1 -Contact: oded.gabbay@gmail.com +Contact: ogabbay@kernel.org Description: Sets I2C device address for I2C transaction that is generated by the device's CPU What: /sys/kernel/debug/habanalabs/hl/i2c_bus Date: Jan 2019 KernelVersion: 5.1 -Contact: oded.gabbay@gmail.com +Contact: ogabbay@kernel.org Description: Sets I2C bus address for I2C transaction that is generated by the device's CPU What: /sys/kernel/debug/habanalabs/hl/i2c_data Date: Jan 2019 KernelVersion: 5.1 -Contact: oded.gabbay@gmail.com +Contact: ogabbay@kernel.org Description: Triggers an I2C transaction that is generated by the device's CPU. Writing to this file generates a write transaction while reading from the file generates a read transcation @@ -122,32 +122,32 @@ Description: Triggers an I2C transaction that is generated by the device's What: /sys/kernel/debug/habanalabs/hl/i2c_reg Date: Jan 2019 KernelVersion: 5.1 -Contact: oded.gabbay@gmail.com +Contact: ogabbay@kernel.org Description: Sets I2C register id for I2C transaction that is generated by the device's CPU What: /sys/kernel/debug/habanalabs/hl/led0 Date: Jan 2019 KernelVersion: 5.1 -Contact: oded.gabbay@gmail.com +Contact: ogabbay@kernel.org Description: Sets the state of the first S/W led on the device What: /sys/kernel/debug/habanalabs/hl/led1 Date: Jan 2019 KernelVersion: 5.1 -Contact: oded.gabbay@gmail.com +Contact: ogabbay@kernel.org Description: Sets the state of the second S/W led on the device What: /sys/kernel/debug/habanalabs/hl/led2 Date: Jan 2019 KernelVersion: 5.1 -Contact: oded.gabbay@gmail.com +Contact: ogabbay@kernel.org Description: Sets the state of the third S/W led on the device What: /sys/kernel/debug/habanalabs/hl/mmu Date: Jan 2019 KernelVersion: 5.1 -Contact: oded.gabbay@gmail.com +Contact: ogabbay@kernel.org Description: Displays the hop values and physical address for a given ASID and virtual address. The user should write the ASID and VA into the file and then read the file to get the result. @@ -157,14 +157,14 @@ Description: Displays the hop values and physical address for a given ASID What: /sys/kernel/debug/habanalabs/hl/set_power_state Date: Jan 2019 KernelVersion: 5.1 -Contact: oded.gabbay@gmail.com +Contact: ogabbay@kernel.org Description: Sets the PCI power state. Valid values are "1" for D0 and "2" for D3Hot What: /sys/kernel/debug/habanalabs/hl/userptr Date: Jan 2019 KernelVersion: 5.1 -Contact: oded.gabbay@gmail.com +Contact: ogabbay@kernel.org Description: Displays a list with information about the currently user pointers (user virtual addresses) that are pinned and mapped to DMA addresses @@ -172,21 +172,21 @@ Description: Displays a list with information about the currently user What: /sys/kernel/debug/habanalabs/hl/vm Date: Jan 2019 KernelVersion: 5.1 -Contact: oded.gabbay@gmail.com +Contact: ogabbay@kernel.org Description: Displays a list with information about all the active virtual address mappings per ASID What: /sys/kernel/debug/habanalabs/hl/stop_on_err Date: Mar 2020 KernelVersion: 5.6 -Contact: oded.gabbay@gmail.com +Contact: ogabbay@kernel.org Description: Sets the stop-on_error option for the device engines. Value of "0" is for disable, otherwise enable. What: /sys/kernel/debug/habanalabs/hl/dump_security_violations Date: Jan 2021 KernelVersion: 5.12 -Contact: oded.gabbay@gmail.com +Contact: ogabbay@kernel.org Description: Dumps all security violations to dmesg. This will also ack all security violations meanings those violations will not be dumped next time user calls this API diff --git a/Documentation/ABI/testing/sysfs-driver-habanalabs b/Documentation/ABI/testing/sysfs-driver-habanalabs index 169ae4b2a180..1f127f71d2b4 100644 --- a/Documentation/ABI/testing/sysfs-driver-habanalabs +++ b/Documentation/ABI/testing/sysfs-driver-habanalabs @@ -1,7 +1,7 @@ What: /sys/class/habanalabs/hl/armcp_kernel_ver Date: Jan 2019 KernelVersion: 5.1 -Contact: oded.gabbay@gmail.com +Contact: ogabbay@kernel.org Description: Version of the Linux kernel running on the device's CPU. Will be DEPRECATED in Linux kernel version 5.10, and be replaced with cpucp_kernel_ver @@ -9,7 +9,7 @@ Description: Version of the Linux kernel running on the device's CPU. What: /sys/class/habanalabs/hl/armcp_ver Date: Jan 2019 KernelVersion: 5.1 -Contact: oded.gabbay@gmail.com +Contact: ogabbay@kernel.org Description: Version of the application running on the device's CPU Will be DEPRECATED in Linux kernel version 5.10, and be replaced with cpucp_ver @@ -17,7 +17,7 @@ Description: Version of the application running on the device's CPU What: /sys/class/habanalabs/hl/clk_max_freq_mhz Date: Jun 2019 KernelVersion: not yet upstreamed -Contact: oded.gabbay@gmail.com +Contact: ogabbay@kernel.org Description: Allows the user to set the maximum clock frequency, in MHz. The device clock might be set to lower value than the maximum. The user should read the clk_cur_freq_mhz to see the actual @@ -27,52 +27,52 @@ Description: Allows the user to set the maximum clock frequency, in MHz. What: /sys/class/habanalabs/hl/clk_cur_freq_mhz Date: Jun 2019 KernelVersion: not yet upstreamed -Contact: oded.gabbay@gmail.com +Contact: ogabbay@kernel.org Description: Displays the current frequency, in MHz, of the device clock. This property is valid only for the Gaudi ASIC family What: /sys/class/habanalabs/hl/cpld_ver Date: Jan 2019 KernelVersion: 5.1 -Contact: oded.gabbay@gmail.com +Contact: ogabbay@kernel.org Description: Version of the Device's CPLD F/W What: /sys/class/habanalabs/hl/cpucp_kernel_ver Date: Oct 2020 KernelVersion: 5.10 -Contact: oded.gabbay@gmail.com +Contact: ogabbay@kernel.org Description: Version of the Linux kernel running on the device's CPU What: /sys/class/habanalabs/hl/cpucp_ver Date: Oct 2020 KernelVersion: 5.10 -Contact: oded.gabbay@gmail.com +Contact: ogabbay@kernel.org Description: Version of the application running on the device's CPU What: /sys/class/habanalabs/hl/device_type Date: Jan 2019 KernelVersion: 5.1 -Contact: oded.gabbay@gmail.com +Contact: ogabbay@kernel.org Description: Displays the code name of the device according to its type. The supported values are: "GOYA" What: /sys/class/habanalabs/hl/eeprom Date: Jan 2019 KernelVersion: 5.1 -Contact: oded.gabbay@gmail.com +Contact: ogabbay@kernel.org Description: A binary file attribute that contains the contents of the on-board EEPROM What: /sys/class/habanalabs/hl/fuse_ver Date: Jan 2019 KernelVersion: 5.1 -Contact: oded.gabbay@gmail.com +Contact: ogabbay@kernel.org Description: Displays the device's version from the eFuse What: /sys/class/habanalabs/hl/hard_reset Date: Jan 2019 KernelVersion: 5.1 -Contact: oded.gabbay@gmail.com +Contact: ogabbay@kernel.org Description: Interface to trigger a hard-reset operation for the device. Hard-reset will reset ALL internal components of the device except for the PCI interface and the internal PLLs @@ -80,14 +80,14 @@ Description: Interface to trigger a hard-reset operation for the device. What: /sys/class/habanalabs/hl/hard_reset_cnt Date: Jan 2019 KernelVersion: 5.1 -Contact: oded.gabbay@gmail.com +Contact: ogabbay@kernel.org Description: Displays how many times the device have undergone a hard-reset operation since the driver was loaded What: /sys/class/habanalabs/hl/high_pll Date: Jan 2019 KernelVersion: 5.1 -Contact: oded.gabbay@gmail.com +Contact: ogabbay@kernel.org Description: Allows the user to set the maximum clock frequency for MME, TPC and IC when the power management profile is set to "automatic". This property is valid only for the Goya ASIC family @@ -95,7 +95,7 @@ Description: Allows the user to set the maximum clock frequency for MME, TPC What: /sys/class/habanalabs/hl/ic_clk Date: Jan 2019 KernelVersion: 5.1 -Contact: oded.gabbay@gmail.com +Contact: ogabbay@kernel.org Description: Allows the user to set the maximum clock frequency, in Hz, of the Interconnect fabric. Writes to this parameter affect the device only when the power management profile is set to "manual" @@ -107,27 +107,27 @@ Description: Allows the user to set the maximum clock frequency, in Hz, of What: /sys/class/habanalabs/hl/ic_clk_curr Date: Jan 2019 KernelVersion: 5.1 -Contact: oded.gabbay@gmail.com +Contact: ogabbay@kernel.org Description: Displays the current clock frequency, in Hz, of the Interconnect fabric. This property is valid only for the Goya ASIC family What: /sys/class/habanalabs/hl/infineon_ver Date: Jan 2019 KernelVersion: 5.1 -Contact: oded.gabbay@gmail.com +Contact: ogabbay@kernel.org Description: Version of the Device's power supply F/W code What: /sys/class/habanalabs/hl/max_power Date: Jan 2019 KernelVersion: 5.1 -Contact: oded.gabbay@gmail.com +Contact: ogabbay@kernel.org Description: Allows the user to set the maximum power consumption of the device in milliwatts. What: /sys/class/habanalabs/hl/mme_clk Date: Jan 2019 KernelVersion: 5.1 -Contact: oded.gabbay@gmail.com +Contact: ogabbay@kernel.org Description: Allows the user to set the maximum clock frequency, in Hz, of the MME compute engine. Writes to this parameter affect the device only when the power management profile is set to "manual" @@ -139,21 +139,21 @@ Description: Allows the user to set the maximum clock frequency, in Hz, of What: /sys/class/habanalabs/hl/mme_clk_curr Date: Jan 2019 KernelVersion: 5.1 -Contact: oded.gabbay@gmail.com +Contact: ogabbay@kernel.org Description: Displays the current clock frequency, in Hz, of the MME compute engine. This property is valid only for the Goya ASIC family What: /sys/class/habanalabs/hl/pci_addr Date: Jan 2019 KernelVersion: 5.1 -Contact: oded.gabbay@gmail.com +Contact: ogabbay@kernel.org Description: Displays the PCI address of the device. This is needed so the user would be able to open a device based on its PCI address What: /sys/class/habanalabs/hl/pm_mng_profile Date: Jan 2019 KernelVersion: 5.1 -Contact: oded.gabbay@gmail.com +Contact: ogabbay@kernel.org Description: Power management profile. Values are "auto", "manual". In "auto" mode, the driver will set the maximum clock frequency to a high value when a user-space process opens the device's file (unless @@ -167,13 +167,13 @@ Description: Power management profile. Values are "auto", "manual". In "auto" What: /sys/class/habanalabs/hl/preboot_btl_ver Date: Jan 2019 KernelVersion: 5.1 -Contact: oded.gabbay@gmail.com +Contact: ogabbay@kernel.org Description: Version of the device's preboot F/W code What: /sys/class/habanalabs/hl/soft_reset Date: Jan 2019 KernelVersion: 5.1 -Contact: oded.gabbay@gmail.com +Contact: ogabbay@kernel.org Description: Interface to trigger a soft-reset operation for the device. Soft-reset will reset only the compute and DMA engines of the device @@ -181,26 +181,26 @@ Description: Interface to trigger a soft-reset operation for the device. What: /sys/class/habanalabs/hl/soft_reset_cnt Date: Jan 2019 KernelVersion: 5.1 -Contact: oded.gabbay@gmail.com +Contact: ogabbay@kernel.org Description: Displays how many times the device have undergone a soft-reset operation since the driver was loaded What: /sys/class/habanalabs/hl/status Date: Jan 2019 KernelVersion: 5.1 -Contact: oded.gabbay@gmail.com +Contact: ogabbay@kernel.org Description: Status of the card: "Operational", "Malfunction", "In reset". What: /sys/class/habanalabs/hl/thermal_ver Date: Jan 2019 KernelVersion: 5.1 -Contact: oded.gabbay@gmail.com +Contact: ogabbay@kernel.org Description: Version of the Device's thermal daemon What: /sys/class/habanalabs/hl/tpc_clk Date: Jan 2019 KernelVersion: 5.1 -Contact: oded.gabbay@gmail.com +Contact: ogabbay@kernel.org Description: Allows the user to set the maximum clock frequency, in Hz, of the TPC compute engines. Writes to this parameter affect the device only when the power management profile is set to "manual" @@ -212,12 +212,12 @@ Description: Allows the user to set the maximum clock frequency, in Hz, of What: /sys/class/habanalabs/hl/tpc_clk_curr Date: Jan 2019 KernelVersion: 5.1 -Contact: oded.gabbay@gmail.com +Contact: ogabbay@kernel.org Description: Displays the current clock frequency, in Hz, of the TPC compute engines. This property is valid only for the Goya ASIC family What: /sys/class/habanalabs/hl/uboot_ver Date: Jan 2019 KernelVersion: 5.1 -Contact: oded.gabbay@gmail.com +Contact: ogabbay@kernel.org Description: Version of the u-boot running on the device's CPU \ No newline at end of file -- cgit v1.2.3 From 3fde13f817e23f05ce407d136325df4cbc913e67 Mon Sep 17 00:00:00 2001 From: Chao Yu Date: Fri, 22 Jan 2021 17:46:43 +0800 Subject: f2fs: compress: support compress level Expand 'compress_algorithm' mount option to accept parameter as format of :, by this way, it gives a way to allow user to do more specified config on lz4 and zstd compression level, then f2fs compression can provide higher compress ratio. In order to set compress level for lz4 algorithm, it needs to set CONFIG_LZ4HC_COMPRESS and CONFIG_F2FS_FS_LZ4HC config to enable lz4hc compress algorithm. CR and performance number on lz4/lz4hc algorithm: dd if=enwik9 of=compressed_file conv=fsync Original blocks: 244382 lz4 lz4hc-9 compressed blocks 170647 163270 compress ratio 69.8% 66.8% speed 16.4207 s, 60.9 MB/s 26.7299 s, 37.4 MB/s compress ratio = after / before Signed-off-by: Chao Yu Signed-off-by: Jaegeuk Kim --- Documentation/filesystems/f2fs.rst | 5 +++ fs/f2fs/Kconfig | 10 +++++ fs/f2fs/compress.c | 41 ++++++++++++++++-- fs/f2fs/f2fs.h | 9 ++++ fs/f2fs/super.c | 89 +++++++++++++++++++++++++++++++++++++- include/linux/f2fs_fs.h | 3 ++ 6 files changed, 152 insertions(+), 5 deletions(-) (limited to 'Documentation') diff --git a/Documentation/filesystems/f2fs.rst b/Documentation/filesystems/f2fs.rst index dae15c96e659..5eff4009e77e 100644 --- a/Documentation/filesystems/f2fs.rst +++ b/Documentation/filesystems/f2fs.rst @@ -249,6 +249,11 @@ checkpoint=%s[:%u[%]] Set to "disable" to turn off checkpointing. Set to "enabl This space is reclaimed once checkpoint=enable. compress_algorithm=%s Control compress algorithm, currently f2fs supports "lzo", "lz4", "zstd" and "lzo-rle" algorithm. +compress_algorithm=%s:%d Control compress algorithm and its compress level, now, only + "lz4" and "zstd" support compress level config. + algorithm level range + lz4 3 - 16 + zstd 1 - 22 compress_log_size=%u Support configuring compress cluster size, the size will be 4KB * (1 << %u), 16KB is minimum size, also it's default size. diff --git a/fs/f2fs/Kconfig b/fs/f2fs/Kconfig index d13c5c6a9787..63c1fc1a0e3b 100644 --- a/fs/f2fs/Kconfig +++ b/fs/f2fs/Kconfig @@ -119,6 +119,16 @@ config F2FS_FS_LZ4 help Support LZ4 compress algorithm, if unsure, say Y. +config F2FS_FS_LZ4HC + bool "LZ4HC compression support" + depends on F2FS_FS_COMPRESSION + depends on F2FS_FS_LZ4 + select LZ4HC_COMPRESS + default y + help + Support LZ4HC compress algorithm, LZ4HC has compatible on-disk + layout with LZ4, if unsure, say Y. + config F2FS_FS_ZSTD bool "ZSTD compression support" depends on F2FS_FS_COMPRESSION diff --git a/fs/f2fs/compress.c b/fs/f2fs/compress.c index 4bcbacfe3325..a345a41e2119 100644 --- a/fs/f2fs/compress.c +++ b/fs/f2fs/compress.c @@ -252,8 +252,14 @@ static const struct f2fs_compress_ops f2fs_lzo_ops = { #ifdef CONFIG_F2FS_FS_LZ4 static int lz4_init_compress_ctx(struct compress_ctx *cc) { - cc->private = f2fs_kvmalloc(F2FS_I_SB(cc->inode), - LZ4_MEM_COMPRESS, GFP_NOFS); + unsigned int size = LZ4_MEM_COMPRESS; + +#ifdef CONFIG_F2FS_FS_LZ4HC + if (F2FS_I(cc->inode)->i_compress_flag >> COMPRESS_LEVEL_OFFSET) + size = LZ4HC_MEM_COMPRESS; +#endif + + cc->private = f2fs_kvmalloc(F2FS_I_SB(cc->inode), size, GFP_NOFS); if (!cc->private) return -ENOMEM; @@ -272,10 +278,34 @@ static void lz4_destroy_compress_ctx(struct compress_ctx *cc) cc->private = NULL; } +#ifdef CONFIG_F2FS_FS_LZ4HC +static int lz4hc_compress_pages(struct compress_ctx *cc) +{ + unsigned char level = F2FS_I(cc->inode)->i_compress_flag >> + COMPRESS_LEVEL_OFFSET; + int len; + + if (level) + len = LZ4_compress_HC(cc->rbuf, cc->cbuf->cdata, cc->rlen, + cc->clen, level, cc->private); + else + len = LZ4_compress_default(cc->rbuf, cc->cbuf->cdata, cc->rlen, + cc->clen, cc->private); + if (!len) + return -EAGAIN; + + cc->clen = len; + return 0; +} +#endif + static int lz4_compress_pages(struct compress_ctx *cc) { int len; +#ifdef CONFIG_F2FS_FS_LZ4HC + return lz4hc_compress_pages(cc); +#endif len = LZ4_compress_default(cc->rbuf, cc->cbuf->cdata, cc->rlen, cc->clen, cc->private); if (!len) @@ -325,8 +355,13 @@ static int zstd_init_compress_ctx(struct compress_ctx *cc) ZSTD_CStream *stream; void *workspace; unsigned int workspace_size; + unsigned char level = F2FS_I(cc->inode)->i_compress_flag >> + COMPRESS_LEVEL_OFFSET; + + if (!level) + level = F2FS_ZSTD_DEFAULT_CLEVEL; - params = ZSTD_getParams(F2FS_ZSTD_DEFAULT_CLEVEL, cc->rlen, 0); + params = ZSTD_getParams(level, cc->rlen, 0); workspace_size = ZSTD_CStreamWorkspaceBound(params.cParams); workspace = f2fs_kvmalloc(F2FS_I_SB(cc->inode), diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h index bb11759191dc..36012181c17f 100644 --- a/fs/f2fs/f2fs.h +++ b/fs/f2fs/f2fs.h @@ -146,6 +146,7 @@ struct f2fs_mount_info { /* For compression */ unsigned char compress_algorithm; /* algorithm type */ unsigned char compress_log_size; /* cluster log size */ + unsigned char compress_level; /* compress level */ bool compress_chksum; /* compressed data chksum */ unsigned char compress_ext_cnt; /* extension count */ int compress_mode; /* compression mode */ @@ -735,6 +736,7 @@ struct f2fs_inode_info { atomic_t i_compr_blocks; /* # of compressed blocks */ unsigned char i_compress_algorithm; /* algorithm type */ unsigned char i_log_cluster_size; /* log of cluster size */ + unsigned char i_compress_level; /* compress level (lz4hc,zstd) */ unsigned short i_compress_flag; /* compress flag */ unsigned int i_cluster_size; /* cluster size */ }; @@ -1310,6 +1312,8 @@ struct compress_data { #define F2FS_COMPRESSED_PAGE_MAGIC 0xF5F2C000 +#define COMPRESS_LEVEL_OFFSET 8 + /* compress context */ struct compress_ctx { struct inode *inode; /* inode the context belong to */ @@ -3934,6 +3938,11 @@ static inline void set_compress_context(struct inode *inode) 1 << COMPRESS_CHKSUM : 0; F2FS_I(inode)->i_cluster_size = 1 << F2FS_I(inode)->i_log_cluster_size; + if (F2FS_I(inode)->i_compress_algorithm == COMPRESS_LZ4 && + F2FS_OPTION(sbi).compress_level) + F2FS_I(inode)->i_compress_flag |= + F2FS_OPTION(sbi).compress_level << + COMPRESS_LEVEL_OFFSET; F2FS_I(inode)->i_flags |= F2FS_COMPR_FL; set_inode_flag(inode, FI_COMPRESSED_FILE); stat_inc_compr_inode(inode); diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c index a275bd312ae5..c8be27a9eed6 100644 --- a/fs/f2fs/super.c +++ b/fs/f2fs/super.c @@ -25,6 +25,8 @@ #include #include #include +#include +#include #include "f2fs.h" #include "node.h" @@ -464,6 +466,74 @@ static int f2fs_set_test_dummy_encryption(struct super_block *sb, return 0; } +#ifdef CONFIG_F2FS_FS_COMPRESSION +#ifdef CONFIG_F2FS_FS_LZ4 +static int f2fs_set_lz4hc_level(struct f2fs_sb_info *sbi, const char *str) +{ +#ifdef CONFIG_F2FS_FS_LZ4HC + unsigned int level; +#endif + + if (strlen(str) == 3) { + F2FS_OPTION(sbi).compress_level = 0; + return 0; + } + +#ifdef CONFIG_F2FS_FS_LZ4HC + str += 3; + + if (str[0] != ':') { + f2fs_info(sbi, "wrong format, e.g. :"); + return -EINVAL; + } + if (kstrtouint(str + 1, 10, &level)) + return -EINVAL; + + if (level < LZ4HC_MIN_CLEVEL || level > LZ4HC_MAX_CLEVEL) { + f2fs_info(sbi, "invalid lz4hc compress level: %d", level); + return -EINVAL; + } + + F2FS_OPTION(sbi).compress_level = level; + return 0; +#else + f2fs_info(sbi, "kernel doesn't support lz4hc compression"); + return -EINVAL; +#endif +} +#endif + +#ifdef CONFIG_F2FS_FS_ZSTD +static int f2fs_set_zstd_level(struct f2fs_sb_info *sbi, const char *str) +{ + unsigned int level; + int len = 4; + + if (strlen(str) == len) { + F2FS_OPTION(sbi).compress_level = 0; + return 0; + } + + str += len; + + if (str[0] != ':') { + f2fs_info(sbi, "wrong format, e.g. :"); + return -EINVAL; + } + if (kstrtouint(str + 1, 10, &level)) + return -EINVAL; + + if (!level || level > ZSTD_maxCLevel()) { + f2fs_info(sbi, "invalid zstd compress level: %d", level); + return -EINVAL; + } + + F2FS_OPTION(sbi).compress_level = level; + return 0; +} +#endif +#endif + static int parse_options(struct super_block *sb, char *options, bool is_remount) { struct f2fs_sb_info *sbi = F2FS_SB(sb); @@ -883,20 +953,31 @@ static int parse_options(struct super_block *sb, char *options, bool is_remount) return -ENOMEM; if (!strcmp(name, "lzo")) { #ifdef CONFIG_F2FS_FS_LZO + F2FS_OPTION(sbi).compress_level = 0; F2FS_OPTION(sbi).compress_algorithm = COMPRESS_LZO; #else f2fs_info(sbi, "kernel doesn't support lzo compression"); #endif - } else if (!strcmp(name, "lz4")) { + } else if (!strncmp(name, "lz4", 3)) { #ifdef CONFIG_F2FS_FS_LZ4 + ret = f2fs_set_lz4hc_level(sbi, name); + if (ret) { + kfree(name); + return -EINVAL; + } F2FS_OPTION(sbi).compress_algorithm = COMPRESS_LZ4; #else f2fs_info(sbi, "kernel doesn't support lz4 compression"); #endif - } else if (!strcmp(name, "zstd")) { + } else if (!strncmp(name, "zstd", 4)) { #ifdef CONFIG_F2FS_FS_ZSTD + ret = f2fs_set_zstd_level(sbi, name); + if (ret) { + kfree(name); + return -EINVAL; + } F2FS_OPTION(sbi).compress_algorithm = COMPRESS_ZSTD; #else @@ -904,6 +985,7 @@ static int parse_options(struct super_block *sb, char *options, bool is_remount) #endif } else if (!strcmp(name, "lzo-rle")) { #ifdef CONFIG_F2FS_FS_LZORLE + F2FS_OPTION(sbi).compress_level = 0; F2FS_OPTION(sbi).compress_algorithm = COMPRESS_LZORLE; #else @@ -1555,6 +1637,9 @@ static inline void f2fs_show_compress_options(struct seq_file *seq, } seq_printf(seq, ",compress_algorithm=%s", algtype); + if (F2FS_OPTION(sbi).compress_level) + seq_printf(seq, ":%d", F2FS_OPTION(sbi).compress_level); + seq_printf(seq, ",compress_log_size=%u", F2FS_OPTION(sbi).compress_log_size); diff --git a/include/linux/f2fs_fs.h b/include/linux/f2fs_fs.h index 7dc2a06cf19a..c6cc0a566ef5 100644 --- a/include/linux/f2fs_fs.h +++ b/include/linux/f2fs_fs.h @@ -274,6 +274,9 @@ struct f2fs_inode { __u8 i_compress_algorithm; /* compress algorithm */ __u8 i_log_cluster_size; /* log of cluster size */ __le16 i_compress_flag; /* compress flag */ + /* 0 bit: chksum flag + * [10,15] bits: compress level + */ __le32 i_extra_end[0]; /* for attribute size calculation */ } __packed; __le32 i_addr[DEF_ADDRS_PER_INODE]; /* Pointers to data blocks */ -- cgit v1.2.3 From 0bfe9f790448012ef38abf4e78feb2e691e2d366 Mon Sep 17 00:00:00 2001 From: Chao Yu Date: Thu, 14 Jan 2021 09:41:27 +0800 Subject: f2fs: introduce sb_status sysfs node Introduce /sys/fs/f2fs//stat/sb_status to show superblock status in real time as a hexadecimal value. value sb status macro description 0x1 SBI_IS_DIRTY, /* dirty flag for checkpoint */ 0x2 SBI_IS_CLOSE, /* specify unmounting */ 0x4 SBI_NEED_FSCK, /* need fsck.f2fs to fix */ 0x8 SBI_POR_DOING, /* recovery is doing or not */ 0x10 SBI_NEED_SB_WRITE, /* need to recover superblock */ 0x20 SBI_NEED_CP, /* need to checkpoint */ 0x40 SBI_IS_SHUTDOWN, /* shutdown by ioctl */ 0x80 SBI_IS_RECOVERED, /* recovered orphan/data */ 0x100 SBI_CP_DISABLED, /* CP was disabled last mount */ 0x200 SBI_CP_DISABLED_QUICK, /* CP was disabled quickly */ 0x400 SBI_QUOTA_NEED_FLUSH, /* need to flush quota info in CP */ 0x800 SBI_QUOTA_SKIP_FLUSH, /* skip flushing quota in current CP */ 0x1000 SBI_QUOTA_NEED_REPAIR, /* quota file may be corrupted */ 0x2000 SBI_IS_RESIZEFS, /* resizefs is in process */ Signed-off-by: Chao Yu Signed-off-by: Jaegeuk Kim --- Documentation/ABI/testing/sysfs-fs-f2fs | 23 +++++++++++++++++++++++ fs/f2fs/sysfs.c | 8 ++++++++ 2 files changed, 31 insertions(+) (limited to 'Documentation') diff --git a/Documentation/ABI/testing/sysfs-fs-f2fs b/Documentation/ABI/testing/sysfs-fs-f2fs index 3dfee94e0618..362803901614 100644 --- a/Documentation/ABI/testing/sysfs-fs-f2fs +++ b/Documentation/ABI/testing/sysfs-fs-f2fs @@ -377,3 +377,26 @@ Description: This gives a control to limit the bio size in f2fs. Default is zero, which will follow underlying block layer limit, whereas, if it has a certain bytes value, f2fs won't submit a bio larger than that size. + +What: /sys/fs/f2fs//stat/sb_status +Date: December 2020 +Contact: "Chao Yu" +Description: Show status of f2fs superblock in real time. + + ====== ===================== ================================= + value sb status macro description + 0x1 SBI_IS_DIRTY dirty flag for checkpoint + 0x2 SBI_IS_CLOSE specify unmounting + 0x4 SBI_NEED_FSCK need fsck.f2fs to fix + 0x8 SBI_POR_DOING recovery is doing or not + 0x10 SBI_NEED_SB_WRITE need to recover superblock + 0x20 SBI_NEED_CP need to checkpoint + 0x40 SBI_IS_SHUTDOWN shutdown by ioctl + 0x80 SBI_IS_RECOVERED recovered orphan/data + 0x100 SBI_CP_DISABLED CP was disabled last mount + 0x200 SBI_CP_DISABLED_QUICK CP was disabled quickly + 0x400 SBI_QUOTA_NEED_FLUSH need to flush quota info in CP + 0x800 SBI_QUOTA_SKIP_FLUSH skip flushing quota in current CP + 0x1000 SBI_QUOTA_NEED_REPAIR quota file may be corrupted + 0x2000 SBI_IS_RESIZEFS resizefs is in process + ====== ===================== ================================= diff --git a/fs/f2fs/sysfs.c b/fs/f2fs/sysfs.c index bd1174ed2e6f..f39874d512ea 100644 --- a/fs/f2fs/sysfs.c +++ b/fs/f2fs/sysfs.c @@ -96,6 +96,12 @@ static ssize_t lifetime_write_kbytes_show(struct f2fs_attr *a, sbi->sectors_written_start) >> 1))); } +static ssize_t sb_status_show(struct f2fs_attr *a, + struct f2fs_sb_info *sbi, char *buf) +{ + return sprintf(buf, "%lx\n", sbi->s_flag); +} + static ssize_t features_show(struct f2fs_attr *a, struct f2fs_sb_info *sbi, char *buf) { @@ -702,7 +708,9 @@ static struct attribute *f2fs_feat_attrs[] = { }; ATTRIBUTE_GROUPS(f2fs_feat); +F2FS_GENERAL_RO_ATTR(sb_status); static struct attribute *f2fs_stat_attrs[] = { + ATTR_LIST(sb_status), NULL, }; ATTRIBUTE_GROUPS(f2fs_stat); -- cgit v1.2.3 From d349626b42f5dbd08ffcb3f2c383b1f6f433b3c1 Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Mon, 21 Dec 2020 10:59:33 -0800 Subject: hwmon: (abx500) Decomission abx500 driver This deletes the ABx500 hwmon driver, the only supported variant being the AB8500. This driver has been replaced by generic frameworks. By inspecting the abx500 sysfs files we see that it contains things such as temp1_max, temp1_max_alarm, temp1_max_hyst, temp1_max_hyst_alarm, temp1_min, temp1_min_alarm. It becomes obvious that the abx500.c is a reimplementation of thermal zones. This is not very strange as the generic thermal zones were not invented when this driver was merged so people were rolling their own. The ab8500.c driver contains conversion tables for handling a thermistor on ADC channels AUX1 and AUX2. I managed to replace the functionality of the driver with: - Activation of the ntc_thermistor.c driver, CONFIG_SENSORS_NTC_THERMISTOR - Activation of thermal zones, CONFIG_THERMAL - In the device tree, connecting the NTC driver to the processed IIO channels from the AB8500 GPADC ADC forming two instances of NTC sensors. - Connecting the two NTC sensors to a "chassis" thermal zone in the device tree and setting that to hit the CPU frequency at 50 degrees celsius and do a critical shutdown at 70 degrees celsius, deploying a policy using the sensors. After talking to the original authors we concluded that the driver was never properly parameterized in production so what we now have in the device tree is already puts the thermistors to better use than what the hwmon driver did. The two remaining channels for two battery temperatures is already handled in the charging algorithms but can be optionally extended to thermal zones as well if we want these to trigger critical shutdown for the platform. Signed-off-by: Linus Walleij Link: https://lore.kernel.org/r/20201221125521.768082-1-linus.walleij@linaro.org [groeck: Removed documentation and fixed up Makefile, Kconfig] Signed-off-by: Guenter Roeck --- Documentation/hwmon/ab8500.rst | 26 --- Documentation/hwmon/abx500.rst | 32 --- Documentation/hwmon/index.rst | 2 - drivers/hwmon/Kconfig | 13 -- drivers/hwmon/Makefile | 1 - drivers/hwmon/ab8500.c | 224 ------------------- drivers/hwmon/abx500.c | 487 ----------------------------------------- drivers/hwmon/abx500.h | 69 ------ 8 files changed, 854 deletions(-) delete mode 100644 Documentation/hwmon/ab8500.rst delete mode 100644 Documentation/hwmon/abx500.rst delete mode 100644 drivers/hwmon/ab8500.c delete mode 100644 drivers/hwmon/abx500.c delete mode 100644 drivers/hwmon/abx500.h (limited to 'Documentation') diff --git a/Documentation/hwmon/ab8500.rst b/Documentation/hwmon/ab8500.rst deleted file mode 100644 index 33f93a9cec04..000000000000 --- a/Documentation/hwmon/ab8500.rst +++ /dev/null @@ -1,26 +0,0 @@ -Kernel driver ab8500 -==================== - -Supported chips: - - * ST-Ericsson AB8500 - - Prefix: 'ab8500' - - Addresses scanned: - - - Datasheet: http://www.stericsson.com/developers/documentation.jsp - -Authors: - - Martin Persson - - Hongbo Zhang - -Description ------------ - -See also Documentation/hwmon/abx500.rst. This is the ST-Ericsson AB8500 specific -driver. - -Currently only the AB8500 internal sensor and one external sensor for battery -temperature are monitored. Other GPADC channels can also be monitored if needed -in future. diff --git a/Documentation/hwmon/abx500.rst b/Documentation/hwmon/abx500.rst deleted file mode 100644 index 3d88b2ce0f00..000000000000 --- a/Documentation/hwmon/abx500.rst +++ /dev/null @@ -1,32 +0,0 @@ -Kernel driver abx500 -==================== - -Supported chips: - - * ST-Ericsson ABx500 series - - Prefix: 'abx500' - - Addresses scanned: - - - Datasheet: http://www.stericsson.com/developers/documentation.jsp - -Authors: - Martin Persson - Hongbo Zhang - -Description ------------ - -Every ST-Ericsson Ux500 SOC consists of both ABx500 and DBx500 physically, -this is kernel hwmon driver for ABx500. - -There are some GPADCs inside ABx500 which are designed for connecting to -thermal sensors, and there is also a thermal sensor inside ABx500 too, which -raises interrupt when critical temperature reached. - -This abx500 is a common layer which can monitor all of the sensors, every -specific abx500 chip has its special configurations in its own file, e.g. some -sensors can be configured invisible if they are not available on that chip, and -the corresponding gpadc_addr should be set to 0, thus this sensor won't be -polled. diff --git a/Documentation/hwmon/index.rst b/Documentation/hwmon/index.rst index fcb870ce6286..ebe53bb771dd 100644 --- a/Documentation/hwmon/index.rst +++ b/Documentation/hwmon/index.rst @@ -18,10 +18,8 @@ Hardware Monitoring Kernel Drivers .. toctree:: :maxdepth: 1 - ab8500 abituguru abituguru3 - abx500 acpi_power_meter ad7314 adc128d818 diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig index 1ecf697d8d99..c6c4f404399b 100644 --- a/drivers/hwmon/Kconfig +++ b/drivers/hwmon/Kconfig @@ -38,19 +38,6 @@ config HWMON_DEBUG_CHIP comment "Native drivers" -config SENSORS_AB8500 - tristate "AB8500 thermal monitoring" - depends on AB8500_GPADC && AB8500_BM && (IIO = y) - default n - help - If you say yes here you get support for the thermal sensor part - of the AB8500 chip. The driver includes thermal management for - AB8500 die and two GPADC channels. The GPADC channel are preferably - used to access sensors outside the AB8500 chip. - - This driver can also be built as a module. If so, the module - will be called abx500-temp. - config SENSORS_ABITUGURU tristate "Abit uGuru (rev 1 & 2)" depends on X86 && DMI diff --git a/drivers/hwmon/Makefile b/drivers/hwmon/Makefile index 09a86c5e1d29..990891a8c89d 100644 --- a/drivers/hwmon/Makefile +++ b/drivers/hwmon/Makefile @@ -21,7 +21,6 @@ obj-$(CONFIG_SENSORS_W83795) += w83795.o obj-$(CONFIG_SENSORS_W83781D) += w83781d.o obj-$(CONFIG_SENSORS_W83791D) += w83791d.o -obj-$(CONFIG_SENSORS_AB8500) += abx500.o ab8500.o obj-$(CONFIG_SENSORS_ABITUGURU) += abituguru.o obj-$(CONFIG_SENSORS_ABITUGURU3)+= abituguru3.o obj-$(CONFIG_SENSORS_AD7314) += ad7314.o diff --git a/drivers/hwmon/ab8500.c b/drivers/hwmon/ab8500.c deleted file mode 100644 index 53f3379d799d..000000000000 --- a/drivers/hwmon/ab8500.c +++ /dev/null @@ -1,224 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Copyright (C) ST-Ericsson 2010 - 2013 - * Author: Martin Persson - * Hongbo Zhang - * - * When the AB8500 thermal warning temperature is reached (threshold cannot - * be changed by SW), an interrupt is set, and if no further action is taken - * within a certain time frame, kernel_power_off will be called. - * - * When AB8500 thermal shutdown temperature is reached a hardware shutdown of - * the AB8500 will occur. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "abx500.h" - -#define DEFAULT_POWER_OFF_DELAY (HZ * 10) -#define THERMAL_VCC 1800 -#define PULL_UP_RESISTOR 47000 - -#define AB8500_SENSOR_AUX1 0 -#define AB8500_SENSOR_AUX2 1 -#define AB8500_SENSOR_BTEMP_BALL 2 -#define AB8500_SENSOR_BAT_CTRL 3 -#define NUM_MONITORED_SENSORS 4 - -struct ab8500_gpadc_cfg { - const struct abx500_res_to_temp *temp_tbl; - int tbl_sz; - int vcc; - int r_up; -}; - -struct ab8500_temp { - struct iio_channel *aux1; - struct iio_channel *aux2; - struct ab8500_btemp *btemp; - struct delayed_work power_off_work; - struct ab8500_gpadc_cfg cfg; - struct abx500_temp *abx500_data; -}; - -/* - * The hardware connection is like this: - * VCC----[ R_up ]-----[ NTC ]----GND - * where R_up is pull-up resistance, and GPADC measures voltage on NTC. - * and res_to_temp table is strictly sorted by falling resistance values. - */ -static int ab8500_voltage_to_temp(struct ab8500_gpadc_cfg *cfg, - int v_ntc, int *temp) -{ - int r_ntc, i = 0, tbl_sz = cfg->tbl_sz; - const struct abx500_res_to_temp *tbl = cfg->temp_tbl; - - if (cfg->vcc < 0 || v_ntc >= cfg->vcc) - return -EINVAL; - - r_ntc = v_ntc * cfg->r_up / (cfg->vcc - v_ntc); - if (r_ntc > tbl[0].resist || r_ntc < tbl[tbl_sz - 1].resist) - return -EINVAL; - - while (!(r_ntc <= tbl[i].resist && r_ntc > tbl[i + 1].resist) && - i < tbl_sz - 2) - i++; - - /* return milli-Celsius */ - *temp = tbl[i].temp * 1000 + ((tbl[i + 1].temp - tbl[i].temp) * 1000 * - (r_ntc - tbl[i].resist)) / (tbl[i + 1].resist - tbl[i].resist); - - return 0; -} - -static int ab8500_read_sensor(struct abx500_temp *data, u8 sensor, int *temp) -{ - int voltage, ret; - struct ab8500_temp *ab8500_data = data->plat_data; - - if (sensor == AB8500_SENSOR_BTEMP_BALL) { - *temp = ab8500_btemp_get_temp(ab8500_data->btemp); - } else if (sensor == AB8500_SENSOR_BAT_CTRL) { - *temp = ab8500_btemp_get_batctrl_temp(ab8500_data->btemp); - } else if (sensor == AB8500_SENSOR_AUX1) { - ret = iio_read_channel_processed(ab8500_data->aux1, &voltage); - if (ret < 0) - return ret; - ret = ab8500_voltage_to_temp(&ab8500_data->cfg, voltage, temp); - if (ret < 0) - return ret; - } else if (sensor == AB8500_SENSOR_AUX2) { - ret = iio_read_channel_processed(ab8500_data->aux2, &voltage); - if (ret < 0) - return ret; - ret = ab8500_voltage_to_temp(&ab8500_data->cfg, voltage, temp); - if (ret < 0) - return ret; - } - - return 0; -} - -static void ab8500_thermal_power_off(struct work_struct *work) -{ - struct ab8500_temp *ab8500_data = container_of(work, - struct ab8500_temp, power_off_work.work); - struct abx500_temp *abx500_data = ab8500_data->abx500_data; - - dev_warn(&abx500_data->pdev->dev, "Power off due to critical temp\n"); - - kernel_power_off(); -} - -static ssize_t ab8500_show_name(struct device *dev, - struct device_attribute *devattr, char *buf) -{ - return sprintf(buf, "ab8500\n"); -} - -static ssize_t ab8500_show_label(struct device *dev, - struct device_attribute *devattr, char *buf) -{ - char *label; - struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); - int index = attr->index; - - switch (index) { - case 1: - label = "ext_adc1"; - break; - case 2: - label = "ext_adc2"; - break; - case 3: - label = "bat_temp"; - break; - case 4: - label = "bat_ctrl"; - break; - default: - return -EINVAL; - } - - return sprintf(buf, "%s\n", label); -} - -static int ab8500_temp_irq_handler(int irq, struct abx500_temp *data) -{ - struct ab8500_temp *ab8500_data = data->plat_data; - - dev_warn(&data->pdev->dev, "Power off in %d s\n", - DEFAULT_POWER_OFF_DELAY / HZ); - - schedule_delayed_work(&ab8500_data->power_off_work, - DEFAULT_POWER_OFF_DELAY); - return 0; -} - -int abx500_hwmon_init(struct abx500_temp *data) -{ - struct ab8500_temp *ab8500_data; - - ab8500_data = devm_kzalloc(&data->pdev->dev, sizeof(*ab8500_data), - GFP_KERNEL); - if (!ab8500_data) - return -ENOMEM; - - ab8500_data->btemp = ab8500_btemp_get(); - if (IS_ERR(ab8500_data->btemp)) - return PTR_ERR(ab8500_data->btemp); - - INIT_DELAYED_WORK(&ab8500_data->power_off_work, - ab8500_thermal_power_off); - - ab8500_data->cfg.vcc = THERMAL_VCC; - ab8500_data->cfg.r_up = PULL_UP_RESISTOR; - ab8500_data->cfg.temp_tbl = ab8500_temp_tbl_a_thermistor; - ab8500_data->cfg.tbl_sz = ab8500_temp_tbl_a_size; - - data->plat_data = ab8500_data; - ab8500_data->aux1 = devm_iio_channel_get(&data->pdev->dev, "aux1"); - if (IS_ERR(ab8500_data->aux1)) { - if (PTR_ERR(ab8500_data->aux1) == -ENODEV) - return -EPROBE_DEFER; - dev_err(&data->pdev->dev, "failed to get AUX1 ADC channel\n"); - return PTR_ERR(ab8500_data->aux1); - } - ab8500_data->aux2 = devm_iio_channel_get(&data->pdev->dev, "aux2"); - if (IS_ERR(ab8500_data->aux2)) { - if (PTR_ERR(ab8500_data->aux2) == -ENODEV) - return -EPROBE_DEFER; - dev_err(&data->pdev->dev, "failed to get AUX2 ADC channel\n"); - return PTR_ERR(ab8500_data->aux2); - } - - data->gpadc_addr[0] = AB8500_SENSOR_AUX1; - data->gpadc_addr[1] = AB8500_SENSOR_AUX2; - data->gpadc_addr[2] = AB8500_SENSOR_BTEMP_BALL; - data->gpadc_addr[3] = AB8500_SENSOR_BAT_CTRL; - data->monitored_sensors = NUM_MONITORED_SENSORS; - - data->ops.read_sensor = ab8500_read_sensor; - data->ops.irq_handler = ab8500_temp_irq_handler; - data->ops.show_name = ab8500_show_name; - data->ops.show_label = ab8500_show_label; - data->ops.is_visible = NULL; - - return 0; -} -EXPORT_SYMBOL(abx500_hwmon_init); - -MODULE_AUTHOR("Hongbo Zhang "); -MODULE_DESCRIPTION("AB8500 temperature driver"); -MODULE_LICENSE("GPL"); diff --git a/drivers/hwmon/abx500.c b/drivers/hwmon/abx500.c deleted file mode 100644 index 4b9648819836..000000000000 --- a/drivers/hwmon/abx500.c +++ /dev/null @@ -1,487 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Copyright (C) ST-Ericsson 2010 - 2013 - * Author: Martin Persson - * Hongbo Zhang - * - * ABX500 does not provide auto ADC, so to monitor the required temperatures, - * a periodic work is used. It is more important to not wake up the CPU than - * to perform this job, hence the use of a deferred delay. - * - * A deferred delay for thermal monitor is considered safe because: - * If the chip gets too hot during a sleep state it's most likely due to - * external factors, such as the surrounding temperature. I.e. no SW decisions - * will make any difference. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "abx500.h" - -#define DEFAULT_MONITOR_DELAY HZ -#define DEFAULT_MAX_TEMP 130 - -static inline void schedule_monitor(struct abx500_temp *data) -{ - data->work_active = true; - schedule_delayed_work(&data->work, DEFAULT_MONITOR_DELAY); -} - -static void threshold_updated(struct abx500_temp *data) -{ - int i; - for (i = 0; i < data->monitored_sensors; i++) - if (data->max[i] != 0 || data->min[i] != 0) { - schedule_monitor(data); - return; - } - - dev_dbg(&data->pdev->dev, "No active thresholds.\n"); - cancel_delayed_work_sync(&data->work); - data->work_active = false; -} - -static void gpadc_monitor(struct work_struct *work) -{ - int temp, i, ret; - char alarm_node[30]; - bool updated_min_alarm, updated_max_alarm; - struct abx500_temp *data; - - data = container_of(work, struct abx500_temp, work.work); - mutex_lock(&data->lock); - - for (i = 0; i < data->monitored_sensors; i++) { - /* Thresholds are considered inactive if set to 0 */ - if (data->max[i] == 0 && data->min[i] == 0) - continue; - - if (data->max[i] < data->min[i]) - continue; - - ret = data->ops.read_sensor(data, data->gpadc_addr[i], &temp); - if (ret < 0) { - dev_err(&data->pdev->dev, "GPADC read failed\n"); - continue; - } - - updated_min_alarm = false; - updated_max_alarm = false; - - if (data->min[i] != 0) { - if (temp < data->min[i]) { - if (data->min_alarm[i] == false) { - data->min_alarm[i] = true; - updated_min_alarm = true; - } - } else { - if (data->min_alarm[i] == true) { - data->min_alarm[i] = false; - updated_min_alarm = true; - } - } - } - if (data->max[i] != 0) { - if (temp > data->max[i]) { - if (data->max_alarm[i] == false) { - data->max_alarm[i] = true; - updated_max_alarm = true; - } - } else if (temp < data->max[i] - data->max_hyst[i]) { - if (data->max_alarm[i] == true) { - data->max_alarm[i] = false; - updated_max_alarm = true; - } - } - } - - if (updated_min_alarm) { - ret = sprintf(alarm_node, "temp%d_min_alarm", i + 1); - sysfs_notify(&data->pdev->dev.kobj, NULL, alarm_node); - } - if (updated_max_alarm) { - ret = sprintf(alarm_node, "temp%d_max_alarm", i + 1); - sysfs_notify(&data->pdev->dev.kobj, NULL, alarm_node); - } - } - - schedule_monitor(data); - mutex_unlock(&data->lock); -} - -/* HWMON sysfs interfaces */ -static ssize_t name_show(struct device *dev, struct device_attribute *devattr, - char *buf) -{ - struct abx500_temp *data = dev_get_drvdata(dev); - /* Show chip name */ - return data->ops.show_name(dev, devattr, buf); -} - -static ssize_t label_show(struct device *dev, - struct device_attribute *devattr, char *buf) -{ - struct abx500_temp *data = dev_get_drvdata(dev); - /* Show each sensor label */ - return data->ops.show_label(dev, devattr, buf); -} - -static ssize_t input_show(struct device *dev, - struct device_attribute *devattr, char *buf) -{ - int ret, temp; - struct abx500_temp *data = dev_get_drvdata(dev); - struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); - u8 gpadc_addr = data->gpadc_addr[attr->index]; - - ret = data->ops.read_sensor(data, gpadc_addr, &temp); - if (ret < 0) - return ret; - - return sprintf(buf, "%d\n", temp); -} - -/* Set functions (RW nodes) */ -static ssize_t min_store(struct device *dev, struct device_attribute *devattr, - const char *buf, size_t count) -{ - unsigned long val; - struct abx500_temp *data = dev_get_drvdata(dev); - struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); - int res = kstrtol(buf, 10, &val); - if (res < 0) - return res; - - val = clamp_val(val, 0, DEFAULT_MAX_TEMP); - - mutex_lock(&data->lock); - data->min[attr->index] = val; - threshold_updated(data); - mutex_unlock(&data->lock); - - return count; -} - -static ssize_t max_store(struct device *dev, struct device_attribute *devattr, - const char *buf, size_t count) -{ - unsigned long val; - struct abx500_temp *data = dev_get_drvdata(dev); - struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); - int res = kstrtol(buf, 10, &val); - if (res < 0) - return res; - - val = clamp_val(val, 0, DEFAULT_MAX_TEMP); - - mutex_lock(&data->lock); - data->max[attr->index] = val; - threshold_updated(data); - mutex_unlock(&data->lock); - - return count; -} - -static ssize_t max_hyst_store(struct device *dev, - struct device_attribute *devattr, - const char *buf, size_t count) -{ - unsigned long val; - struct abx500_temp *data = dev_get_drvdata(dev); - struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); - int res = kstrtoul(buf, 10, &val); - if (res < 0) - return res; - - val = clamp_val(val, 0, DEFAULT_MAX_TEMP); - - mutex_lock(&data->lock); - data->max_hyst[attr->index] = val; - threshold_updated(data); - mutex_unlock(&data->lock); - - return count; -} - -/* Show functions (RO nodes) */ -static ssize_t min_show(struct device *dev, struct device_attribute *devattr, - char *buf) -{ - struct abx500_temp *data = dev_get_drvdata(dev); - struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); - - return sprintf(buf, "%lu\n", data->min[attr->index]); -} - -static ssize_t max_show(struct device *dev, struct device_attribute *devattr, - char *buf) -{ - struct abx500_temp *data = dev_get_drvdata(dev); - struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); - - return sprintf(buf, "%lu\n", data->max[attr->index]); -} - -static ssize_t max_hyst_show(struct device *dev, - struct device_attribute *devattr, char *buf) -{ - struct abx500_temp *data = dev_get_drvdata(dev); - struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); - - return sprintf(buf, "%lu\n", data->max_hyst[attr->index]); -} - -static ssize_t min_alarm_show(struct device *dev, - struct device_attribute *devattr, char *buf) -{ - struct abx500_temp *data = dev_get_drvdata(dev); - struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); - - return sprintf(buf, "%d\n", data->min_alarm[attr->index]); -} - -static ssize_t max_alarm_show(struct device *dev, - struct device_attribute *devattr, char *buf) -{ - struct abx500_temp *data = dev_get_drvdata(dev); - struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); - - return sprintf(buf, "%d\n", data->max_alarm[attr->index]); -} - -static umode_t abx500_attrs_visible(struct kobject *kobj, - struct attribute *attr, int n) -{ - struct device *dev = kobj_to_dev(kobj); - struct abx500_temp *data = dev_get_drvdata(dev); - - if (data->ops.is_visible) - return data->ops.is_visible(attr, n); - - return attr->mode; -} - -/* Chip name, required by hwmon */ -static SENSOR_DEVICE_ATTR_RO(name, name, 0); - -/* GPADC - SENSOR1 */ -static SENSOR_DEVICE_ATTR_RO(temp1_label, label, 0); -static SENSOR_DEVICE_ATTR_RO(temp1_input, input, 0); -static SENSOR_DEVICE_ATTR_RW(temp1_min, min, 0); -static SENSOR_DEVICE_ATTR_RW(temp1_max, max, 0); -static SENSOR_DEVICE_ATTR_RW(temp1_max_hyst, max_hyst, 0); -static SENSOR_DEVICE_ATTR_RO(temp1_min_alarm, min_alarm, 0); -static SENSOR_DEVICE_ATTR_RO(temp1_max_alarm, max_alarm, 0); - -/* GPADC - SENSOR2 */ -static SENSOR_DEVICE_ATTR_RO(temp2_label, label, 1); -static SENSOR_DEVICE_ATTR_RO(temp2_input, input, 1); -static SENSOR_DEVICE_ATTR_RW(temp2_min, min, 1); -static SENSOR_DEVICE_ATTR_RW(temp2_max, max, 1); -static SENSOR_DEVICE_ATTR_RW(temp2_max_hyst, max_hyst, 1); -static SENSOR_DEVICE_ATTR_RO(temp2_min_alarm, min_alarm, 1); -static SENSOR_DEVICE_ATTR_RO(temp2_max_alarm, max_alarm, 1); - -/* GPADC - SENSOR3 */ -static SENSOR_DEVICE_ATTR_RO(temp3_label, label, 2); -static SENSOR_DEVICE_ATTR_RO(temp3_input, input, 2); -static SENSOR_DEVICE_ATTR_RW(temp3_min, min, 2); -static SENSOR_DEVICE_ATTR_RW(temp3_max, max, 2); -static SENSOR_DEVICE_ATTR_RW(temp3_max_hyst, max_hyst, 2); -static SENSOR_DEVICE_ATTR_RO(temp3_min_alarm, min_alarm, 2); -static SENSOR_DEVICE_ATTR_RO(temp3_max_alarm, max_alarm, 2); - -/* GPADC - SENSOR4 */ -static SENSOR_DEVICE_ATTR_RO(temp4_label, label, 3); -static SENSOR_DEVICE_ATTR_RO(temp4_input, input, 3); -static SENSOR_DEVICE_ATTR_RW(temp4_min, min, 3); -static SENSOR_DEVICE_ATTR_RW(temp4_max, max, 3); -static SENSOR_DEVICE_ATTR_RW(temp4_max_hyst, max_hyst, 3); -static SENSOR_DEVICE_ATTR_RO(temp4_min_alarm, min_alarm, 3); -static SENSOR_DEVICE_ATTR_RO(temp4_max_alarm, max_alarm, 3); - -static struct attribute *abx500_temp_attributes[] = { - &sensor_dev_attr_name.dev_attr.attr, - - &sensor_dev_attr_temp1_label.dev_attr.attr, - &sensor_dev_attr_temp1_input.dev_attr.attr, - &sensor_dev_attr_temp1_min.dev_attr.attr, - &sensor_dev_attr_temp1_max.dev_attr.attr, - &sensor_dev_attr_temp1_max_hyst.dev_attr.attr, - &sensor_dev_attr_temp1_min_alarm.dev_attr.attr, - &sensor_dev_attr_temp1_max_alarm.dev_attr.attr, - - &sensor_dev_attr_temp2_label.dev_attr.attr, - &sensor_dev_attr_temp2_input.dev_attr.attr, - &sensor_dev_attr_temp2_min.dev_attr.attr, - &sensor_dev_attr_temp2_max.dev_attr.attr, - &sensor_dev_attr_temp2_max_hyst.dev_attr.attr, - &sensor_dev_attr_temp2_min_alarm.dev_attr.attr, - &sensor_dev_attr_temp2_max_alarm.dev_attr.attr, - - &sensor_dev_attr_temp3_label.dev_attr.attr, - &sensor_dev_attr_temp3_input.dev_attr.attr, - &sensor_dev_attr_temp3_min.dev_attr.attr, - &sensor_dev_attr_temp3_max.dev_attr.attr, - &sensor_dev_attr_temp3_max_hyst.dev_attr.attr, - &sensor_dev_attr_temp3_min_alarm.dev_attr.attr, - &sensor_dev_attr_temp3_max_alarm.dev_attr.attr, - - &sensor_dev_attr_temp4_label.dev_attr.attr, - &sensor_dev_attr_temp4_input.dev_attr.attr, - &sensor_dev_attr_temp4_min.dev_attr.attr, - &sensor_dev_attr_temp4_max.dev_attr.attr, - &sensor_dev_attr_temp4_max_hyst.dev_attr.attr, - &sensor_dev_attr_temp4_min_alarm.dev_attr.attr, - &sensor_dev_attr_temp4_max_alarm.dev_attr.attr, - NULL -}; - -static const struct attribute_group abx500_temp_group = { - .attrs = abx500_temp_attributes, - .is_visible = abx500_attrs_visible, -}; - -static irqreturn_t abx500_temp_irq_handler(int irq, void *irq_data) -{ - struct platform_device *pdev = irq_data; - struct abx500_temp *data = platform_get_drvdata(pdev); - - data->ops.irq_handler(irq, data); - return IRQ_HANDLED; -} - -static int setup_irqs(struct platform_device *pdev) -{ - int ret; - int irq = platform_get_irq_byname(pdev, "ABX500_TEMP_WARM"); - - if (irq < 0) { - dev_err(&pdev->dev, "Get irq by name failed\n"); - return irq; - } - - ret = devm_request_threaded_irq(&pdev->dev, irq, NULL, - abx500_temp_irq_handler, 0, "abx500-temp", pdev); - if (ret < 0) - dev_err(&pdev->dev, "Request threaded irq failed (%d)\n", ret); - - return ret; -} - -static int abx500_temp_probe(struct platform_device *pdev) -{ - struct abx500_temp *data; - int err; - - data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL); - if (!data) - return -ENOMEM; - - data->pdev = pdev; - mutex_init(&data->lock); - - /* Chip specific initialization */ - err = abx500_hwmon_init(data); - if (err < 0 || !data->ops.read_sensor || !data->ops.show_name || - !data->ops.show_label) - return err; - - INIT_DEFERRABLE_WORK(&data->work, gpadc_monitor); - - platform_set_drvdata(pdev, data); - - err = sysfs_create_group(&pdev->dev.kobj, &abx500_temp_group); - if (err < 0) { - dev_err(&pdev->dev, "Create sysfs group failed (%d)\n", err); - return err; - } - - data->hwmon_dev = hwmon_device_register(&pdev->dev); - if (IS_ERR(data->hwmon_dev)) { - err = PTR_ERR(data->hwmon_dev); - dev_err(&pdev->dev, "Class registration failed (%d)\n", err); - goto exit_sysfs_group; - } - - if (data->ops.irq_handler) { - err = setup_irqs(pdev); - if (err < 0) - goto exit_hwmon_reg; - } - return 0; - -exit_hwmon_reg: - hwmon_device_unregister(data->hwmon_dev); -exit_sysfs_group: - sysfs_remove_group(&pdev->dev.kobj, &abx500_temp_group); - return err; -} - -static int abx500_temp_remove(struct platform_device *pdev) -{ - struct abx500_temp *data = platform_get_drvdata(pdev); - - cancel_delayed_work_sync(&data->work); - hwmon_device_unregister(data->hwmon_dev); - sysfs_remove_group(&pdev->dev.kobj, &abx500_temp_group); - - return 0; -} - -static int abx500_temp_suspend(struct platform_device *pdev, - pm_message_t state) -{ - struct abx500_temp *data = platform_get_drvdata(pdev); - - if (data->work_active) - cancel_delayed_work_sync(&data->work); - - return 0; -} - -static int abx500_temp_resume(struct platform_device *pdev) -{ - struct abx500_temp *data = platform_get_drvdata(pdev); - - if (data->work_active) - schedule_monitor(data); - - return 0; -} - -#ifdef CONFIG_OF -static const struct of_device_id abx500_temp_match[] = { - { .compatible = "stericsson,abx500-temp" }, - {}, -}; -MODULE_DEVICE_TABLE(of, abx500_temp_match); -#endif - -static struct platform_driver abx500_temp_driver = { - .driver = { - .name = "abx500-temp", - .of_match_table = of_match_ptr(abx500_temp_match), - }, - .suspend = abx500_temp_suspend, - .resume = abx500_temp_resume, - .probe = abx500_temp_probe, - .remove = abx500_temp_remove, -}; - -module_platform_driver(abx500_temp_driver); - -MODULE_AUTHOR("Martin Persson "); -MODULE_DESCRIPTION("ABX500 temperature driver"); -MODULE_LICENSE("GPL"); diff --git a/drivers/hwmon/abx500.h b/drivers/hwmon/abx500.h deleted file mode 100644 index 4517594260f2..000000000000 --- a/drivers/hwmon/abx500.h +++ /dev/null @@ -1,69 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ -/* - * Copyright (C) ST-Ericsson 2010 - 2013 - * Author: Martin Persson - * Hongbo Zhang - */ - -#ifndef _ABX500_H -#define _ABX500_H - -#define NUM_SENSORS 5 - -struct abx500_temp; - -/* - * struct abx500_temp_ops - abx500 chip specific ops - * @read_sensor: reads gpadc output - * @irq_handler: irq handler - * @show_name: hwmon device name - * @show_label: hwmon attribute label - * @is_visible: is attribute visible - */ -struct abx500_temp_ops { - int (*read_sensor)(struct abx500_temp *, u8, int *); - int (*irq_handler)(int, struct abx500_temp *); - ssize_t (*show_name)(struct device *, - struct device_attribute *, char *); - ssize_t (*show_label) (struct device *, - struct device_attribute *, char *); - int (*is_visible)(struct attribute *, int); -}; - -/* - * struct abx500_temp - representation of temp mon device - * @pdev: platform device - * @hwmon_dev: hwmon device - * @ops: abx500 chip specific ops - * @gpadc_addr: gpadc channel address - * @min: sensor temperature min value - * @max: sensor temperature max value - * @max_hyst: sensor temperature hysteresis value for max limit - * @min_alarm: sensor temperature min alarm - * @max_alarm: sensor temperature max alarm - * @work: delayed work scheduled to monitor temperature periodically - * @work_active: True if work is active - * @lock: mutex - * @monitored_sensors: number of monitored sensors - * @plat_data: private usage, usually points to platform specific data - */ -struct abx500_temp { - struct platform_device *pdev; - struct device *hwmon_dev; - struct abx500_temp_ops ops; - u8 gpadc_addr[NUM_SENSORS]; - unsigned long min[NUM_SENSORS]; - unsigned long max[NUM_SENSORS]; - unsigned long max_hyst[NUM_SENSORS]; - bool min_alarm[NUM_SENSORS]; - bool max_alarm[NUM_SENSORS]; - struct delayed_work work; - bool work_active; - struct mutex lock; - int monitored_sensors; - void *plat_data; -}; - -int abx500_hwmon_init(struct abx500_temp *data); - -#endif /* _ABX500_H */ -- cgit v1.2.3 From bd433537fef88d76e7f427bafda18791ae60e721 Mon Sep 17 00:00:00 2001 From: Blaž Hrastnik Date: Tue, 19 Jan 2021 14:12:41 +0900 Subject: hwmon: (nct6683) Support ASRock boards MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Tested with ASRock X570 Phantom Gaming-ITX/TB3. It also appears on other ASRock boards. Signed-off-by: Blaž Hrastnik Link: https://lore.kernel.org/r/b08d641c-3fb5-4845-85f7-e1753149cd7d@www.fastmail.com Signed-off-by: Guenter Roeck --- Documentation/hwmon/nct6683.rst | 1 + drivers/hwmon/nct6683.c | 3 +++ 2 files changed, 4 insertions(+) (limited to 'Documentation') diff --git a/Documentation/hwmon/nct6683.rst b/Documentation/hwmon/nct6683.rst index 8646ad519fcd..2e1408d174bd 100644 --- a/Documentation/hwmon/nct6683.rst +++ b/Documentation/hwmon/nct6683.rst @@ -61,5 +61,6 @@ Board Firmware version Intel DH87RL NCT6683D EC firmware version 1.0 build 04/03/13 Intel DH87MC NCT6683D EC firmware version 1.0 build 04/03/13 Intel DB85FL NCT6683D EC firmware version 1.0 build 04/03/13 +ASRock X570 NCT6683D EC firmware version 1.0 build 06/28/19 MSI B550 NCT6687D EC firmware version 1.0 build 05/07/20 =============== =============================================== diff --git a/drivers/hwmon/nct6683.c b/drivers/hwmon/nct6683.c index 7f7e30f0de7b..a23047a3bfe2 100644 --- a/drivers/hwmon/nct6683.c +++ b/drivers/hwmon/nct6683.c @@ -169,6 +169,7 @@ superio_exit(int ioreg) #define NCT6683_CUSTOMER_ID_INTEL 0x805 #define NCT6683_CUSTOMER_ID_MITAC 0xa0e #define NCT6683_CUSTOMER_ID_MSI 0x201 +#define NCT6683_CUSTOMER_ID_ASROCK 0xe2c #define NCT6683_REG_BUILD_YEAR 0x604 #define NCT6683_REG_BUILD_MONTH 0x605 @@ -1225,6 +1226,8 @@ static int nct6683_probe(struct platform_device *pdev) break; case NCT6683_CUSTOMER_ID_MSI: break; + case NCT6683_CUSTOMER_ID_ASROCK: + break; default: if (!force) return -ENODEV; -- cgit v1.2.3 From 8c78f0dee4371ab3b0422edf08597525c6219512 Mon Sep 17 00:00:00 2001 From: "Johannes Cornelis Draaijer (datdenkikniet)" Date: Thu, 7 Jan 2021 20:40:14 +0100 Subject: hwmon: Add AHT10 Temperature and Humidity Sensor Driver This patch adds a hwmon driver for the AHT10 Temperature and Humidity sensor. It has a maximum sample rate, as the datasheet states that the chip may heat up if it is sampled more than once every two seconds. Has been tested a to work on a raspberrypi0w Signed-off-by: Johannes Cornelis Draaijer (datdenkikniet) Link: https://lore.kernel.org/r/20210107194014.GA88780@desktop [groeck: dropped AHT10_ADDR (unused) and use AHT10_MEAS_SIZE where appropriate; dropped change log] Signed-off-by: Guenter Roeck --- Documentation/hwmon/aht10.rst | 46 ++++++ Documentation/hwmon/index.rst | 1 + drivers/hwmon/Kconfig | 10 ++ drivers/hwmon/Makefile | 1 + drivers/hwmon/aht10.c | 346 ++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 404 insertions(+) create mode 100644 Documentation/hwmon/aht10.rst create mode 100644 drivers/hwmon/aht10.c (limited to 'Documentation') diff --git a/Documentation/hwmon/aht10.rst b/Documentation/hwmon/aht10.rst new file mode 100644 index 000000000000..482262ca117c --- /dev/null +++ b/Documentation/hwmon/aht10.rst @@ -0,0 +1,46 @@ +.. SPDX-License-Identifier: GPL-2.0 + +Kernel driver aht10 +===================== + +Supported chips: + + * Aosong AHT10 + + Prefix: 'aht10' + + Addresses scanned: None + + Datasheet: + + Chinese: http://www.aosong.com/userfiles/files/media/AHT10%E4%BA%A7%E5%93%81%E6%89%8B%E5%86%8C%20A3%2020201210.pdf + English: https://server4.eca.ir/eshop/AHT10/Aosong_AHT10_en_draft_0c.pdf + +Author: Johannes Cornelis Draaijer + + +Description +----------- + +The AHT10 is a Temperature and Humidity sensor + +The address of this i2c device may only be 0x38 + +Usage Notes +----------- + +This driver does not probe for AHT10 devices, as there is no reliable +way to determine if an i2c chip is or isn't an AHT10. The device has +to be instantiated explicitly with the address 0x38. See +Documentation/i2c/instantiating-devices.rst for details. + +Sysfs entries +------------- + +=============== ============================================ +temp1_input Measured temperature in millidegrees Celcius +humidity1_input Measured humidity in %H +update_interval The minimum interval for polling the sensor, + in milliseconds. Writable. Must be at + least 2000. +=============== ============================================ diff --git a/Documentation/hwmon/index.rst b/Documentation/hwmon/index.rst index ebe53bb771dd..3589151bcefb 100644 --- a/Documentation/hwmon/index.rst +++ b/Documentation/hwmon/index.rst @@ -37,6 +37,7 @@ Hardware Monitoring Kernel Drivers adt7462 adt7470 adt7475 + aht10 amc6821 amd_energy asb100 diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig index c6c4f404399b..fd0da6295d5e 100644 --- a/drivers/hwmon/Kconfig +++ b/drivers/hwmon/Kconfig @@ -244,6 +244,16 @@ config SENSORS_ADT7475 This driver can also be built as a module. If so, the module will be called adt7475. +config SENSORS_AHT10 + tristate "Aosong AHT10" + depends on I2C + help + If you say yes here, you get support for the Aosong AHT10 + temperature and humidity sensors + + This driver can also be built as a module. If so, the module + will be called aht10. + config SENSORS_AS370 tristate "Synaptics AS370 SoC hardware monitoring driver" help diff --git a/drivers/hwmon/Makefile b/drivers/hwmon/Makefile index 990891a8c89d..51dd97437bfd 100644 --- a/drivers/hwmon/Makefile +++ b/drivers/hwmon/Makefile @@ -44,6 +44,7 @@ obj-$(CONFIG_SENSORS_ADT7411) += adt7411.o obj-$(CONFIG_SENSORS_ADT7462) += adt7462.o obj-$(CONFIG_SENSORS_ADT7470) += adt7470.o obj-$(CONFIG_SENSORS_ADT7475) += adt7475.o +obj-$(CONFIG_SENSORS_AHT10) += aht10.o obj-$(CONFIG_SENSORS_AMD_ENERGY) += amd_energy.o obj-$(CONFIG_SENSORS_APPLESMC) += applesmc.o obj-$(CONFIG_SENSORS_ARM_SCMI) += scmi-hwmon.o diff --git a/drivers/hwmon/aht10.c b/drivers/hwmon/aht10.c new file mode 100644 index 000000000000..c70d8c2d0c1f --- /dev/null +++ b/drivers/hwmon/aht10.c @@ -0,0 +1,346 @@ +// SPDX-License-Identifier: GPL-2.0-only + +/* + * aht10.c - Linux hwmon driver for AHT10 Temperature and Humidity sensor + * Copyright (C) 2020 Johannes Cornelis Draaijer + */ + +#include +#include +#include +#include +#include + +#define AHT10_MEAS_SIZE 6 + +/* + * Poll intervals (in milliseconds) + */ +#define AHT10_DEFAULT_MIN_POLL_INTERVAL 2000 +#define AHT10_MIN_POLL_INTERVAL 2000 + +/* + * I2C command delays (in microseconds) + */ +#define AHT10_MEAS_DELAY 80000 +#define AHT10_CMD_DELAY 350000 +#define AHT10_DELAY_EXTRA 100000 + +/* + * Command bytes + */ +#define AHT10_CMD_INIT 0b11100001 +#define AHT10_CMD_MEAS 0b10101100 +#define AHT10_CMD_RST 0b10111010 + +/* + * Flags in the answer byte/command + */ +#define AHT10_CAL_ENABLED BIT(3) +#define AHT10_BUSY BIT(7) +#define AHT10_MODE_NOR (BIT(5) | BIT(6)) +#define AHT10_MODE_CYC BIT(5) +#define AHT10_MODE_CMD BIT(6) + +#define AHT10_MAX_POLL_INTERVAL_LEN 30 + +/** + * struct aht10_data - All the data required to operate an AHT10 chip + * @client: the i2c client associated with the AHT10 + * @lock: a mutex that is used to prevent parallel access to the + * i2c client + * @min_poll_interval: the minimum poll interval + * While the poll rate limit is not 100% necessary, + * the datasheet recommends that a measurement + * is not performed too often to prevent + * the chip from warming up due to the heat it generates. + * If it's unwanted, it can be ignored setting it to + * it to 0. Default value is 2000 ms + * @previous_poll_time: the previous time that the AHT10 + * was polled + * @temperature: the latest temperature value received from + * the AHT10 + * @humidity: the latest humidity value received from the + * AHT10 + */ + +struct aht10_data { + struct i2c_client *client; + /* + * Prevent simultaneous access to the i2c + * client and previous_poll_time + */ + struct mutex lock; + ktime_t min_poll_interval; + ktime_t previous_poll_time; + int temperature; + int humidity; +}; + +/** + * aht10_init() - Initialize an AHT10 chip + * @client: the i2c client associated with the AHT10 + * @data: the data associated with this AHT10 chip + * Return: 0 if succesfull, 1 if not + */ +static int aht10_init(struct aht10_data *data) +{ + const u8 cmd_init[] = {AHT10_CMD_INIT, AHT10_CAL_ENABLED | AHT10_MODE_CYC, + 0x00}; + int res; + u8 status; + struct i2c_client *client = data->client; + + res = i2c_master_send(client, cmd_init, 3); + if (res < 0) + return res; + + usleep_range(AHT10_CMD_DELAY, AHT10_CMD_DELAY + + AHT10_DELAY_EXTRA); + + res = i2c_master_recv(client, &status, 1); + if (res != 1) + return -ENODATA; + + if (status & AHT10_BUSY) + return -EBUSY; + + return 0; +} + +/** + * aht10_polltime_expired() - check if the minimum poll interval has + * expired + * @data: the data containing the time to compare + * Return: 1 if the minimum poll interval has expired, 0 if not + */ +static int aht10_polltime_expired(struct aht10_data *data) +{ + ktime_t current_time = ktime_get_boottime(); + ktime_t difference = ktime_sub(current_time, data->previous_poll_time); + + return ktime_after(difference, data->min_poll_interval); +} + +/** + * aht10_read_values() - read and parse the raw data from the AHT10 + * @aht10_data: the struct aht10_data to use for the lock + * Return: 0 if succesfull, 1 if not + */ +static int aht10_read_values(struct aht10_data *data) +{ + const u8 cmd_meas[] = {AHT10_CMD_MEAS, 0x33, 0x00}; + u32 temp, hum; + int res; + u8 raw_data[AHT10_MEAS_SIZE]; + struct i2c_client *client = data->client; + + mutex_lock(&data->lock); + if (aht10_polltime_expired(data)) { + res = i2c_master_send(client, cmd_meas, sizeof(cmd_meas)); + if (res < 0) + return res; + + usleep_range(AHT10_MEAS_DELAY, + AHT10_MEAS_DELAY + AHT10_DELAY_EXTRA); + + res = i2c_master_recv(client, raw_data, AHT10_MEAS_SIZE); + if (res != AHT10_MEAS_SIZE) { + mutex_unlock(&data->lock); + if (res >= 0) + return -ENODATA; + else + return res; + } + + hum = ((u32)raw_data[1] << 12u) | + ((u32)raw_data[2] << 4u) | + ((raw_data[3] & 0xF0u) >> 4u); + + temp = ((u32)(raw_data[3] & 0x0Fu) << 16u) | + ((u32)raw_data[4] << 8u) | + raw_data[5]; + + temp = ((temp * 625) >> 15u) * 10; + hum = ((hum * 625) >> 16u) * 10; + + data->temperature = (int)temp - 50000; + data->humidity = hum; + data->previous_poll_time = ktime_get_boottime(); + } + mutex_unlock(&data->lock); + return 0; +} + +/** + * aht10_interval_write() - store the given minimum poll interval. + * Return: 0 on success, -EINVAL if a value lower than the + * AHT10_MIN_POLL_INTERVAL is given + */ +static ssize_t aht10_interval_write(struct aht10_data *data, + long val) +{ + data->min_poll_interval = ms_to_ktime(clamp_val(val, 2000, LONG_MAX)); + return 0; +} + +/** + * aht10_interval_read() - read the minimum poll interval + * in milliseconds + */ +static ssize_t aht10_interval_read(struct aht10_data *data, + long *val) +{ + *val = ktime_to_ms(data->min_poll_interval); + return 0; +} + +/** + * aht10_temperature1_read() - read the temperature in millidegrees + */ +static int aht10_temperature1_read(struct aht10_data *data, long *val) +{ + int res; + + res = aht10_read_values(data); + if (res < 0) + return res; + + *val = data->temperature; + return 0; +} + +/** + * aht10_humidity1_read() - read the relative humidity in millipercent + */ +static int aht10_humidity1_read(struct aht10_data *data, long *val) +{ + int res; + + res = aht10_read_values(data); + if (res < 0) + return res; + + *val = data->humidity; + return 0; +} + +static umode_t aht10_hwmon_visible(const void *data, enum hwmon_sensor_types type, + u32 attr, int channel) +{ + switch (type) { + case hwmon_temp: + case hwmon_humidity: + return 0444; + case hwmon_chip: + return 0644; + default: + return 0; + } +} + +static int aht10_hwmon_read(struct device *dev, enum hwmon_sensor_types type, + u32 attr, int channel, long *val) +{ + struct aht10_data *data = dev_get_drvdata(dev); + + switch (type) { + case hwmon_temp: + return aht10_temperature1_read(data, val); + case hwmon_humidity: + return aht10_humidity1_read(data, val); + case hwmon_chip: + return aht10_interval_read(data, val); + default: + return -EOPNOTSUPP; + } +} + +static int aht10_hwmon_write(struct device *dev, enum hwmon_sensor_types type, + u32 attr, int channel, long val) +{ + struct aht10_data *data = dev_get_drvdata(dev); + + switch (type) { + case hwmon_chip: + return aht10_interval_write(data, val); + default: + return -EOPNOTSUPP; + } +} + +static const struct hwmon_channel_info *aht10_info[] = { + HWMON_CHANNEL_INFO(chip, HWMON_C_UPDATE_INTERVAL), + HWMON_CHANNEL_INFO(temp, HWMON_T_INPUT), + HWMON_CHANNEL_INFO(humidity, HWMON_H_INPUT), + NULL, +}; + +static const struct hwmon_ops aht10_hwmon_ops = { + .is_visible = aht10_hwmon_visible, + .read = aht10_hwmon_read, + .write = aht10_hwmon_write, +}; + +static const struct hwmon_chip_info aht10_chip_info = { + .ops = &aht10_hwmon_ops, + .info = aht10_info, +}; + +static int aht10_probe(struct i2c_client *client, + const struct i2c_device_id *aht10_id) +{ + struct device *device = &client->dev; + struct device *hwmon_dev; + struct aht10_data *data; + int res; + + if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) + return -ENOENT; + + data = devm_kzalloc(device, sizeof(*data), GFP_KERNEL); + if (!data) + return -ENOMEM; + + data->min_poll_interval = ms_to_ktime(AHT10_DEFAULT_MIN_POLL_INTERVAL); + data->client = client; + + mutex_init(&data->lock); + + res = aht10_init(data); + if (res < 0) + return res; + + res = aht10_read_values(data); + if (res < 0) + return res; + + hwmon_dev = devm_hwmon_device_register_with_info(device, + client->name, + data, + &aht10_chip_info, + NULL); + + return PTR_ERR_OR_ZERO(hwmon_dev); +} + +static const struct i2c_device_id aht10_id[] = { + { "aht10", 0 }, + { }, +}; +MODULE_DEVICE_TABLE(i2c, aht10_id); + +static struct i2c_driver aht10_driver = { + .driver = { + .name = "aht10", + }, + .probe = aht10_probe, + .id_table = aht10_id, +}; + +module_i2c_driver(aht10_driver); + +MODULE_AUTHOR("Johannes Cornelis Draaijer "); +MODULE_DESCRIPTION("AHT10 Temperature and Humidity sensor driver"); +MODULE_VERSION("1.0"); +MODULE_LICENSE("GPL v2"); -- cgit v1.2.3 From e78ab164591ffd55d2771401ed0d9b083dad55fa Mon Sep 17 00:00:00 2001 From: Aya Levin Date: Tue, 26 Jan 2021 15:24:06 -0800 Subject: devlink: Add DMAC filter generic packet trap Add packet trap that can report packets that were dropped due to destination MAC filtering. Signed-off-by: Aya Levin Reviewed-by: Ido Schimmel Reviewed-by: Moshe Shemesh Reviewed-by: Tariq Toukan Signed-off-by: Tariq Toukan Signed-off-by: Saeed Mahameed Signed-off-by: Jakub Kicinski --- Documentation/networking/devlink/devlink-trap.rst | 5 +++++ include/net/devlink.h | 3 +++ net/core/devlink.c | 1 + 3 files changed, 9 insertions(+) (limited to 'Documentation') diff --git a/Documentation/networking/devlink/devlink-trap.rst b/Documentation/networking/devlink/devlink-trap.rst index d875f3e1e9cf..935b6397e8cf 100644 --- a/Documentation/networking/devlink/devlink-trap.rst +++ b/Documentation/networking/devlink/devlink-trap.rst @@ -480,6 +480,11 @@ be added to the following table: - ``drop`` - Traps packets that the device decided to drop in case they hit a blackhole nexthop + * - ``dmac_filter`` + - ``drop`` + - Traps incoming packets that the device decided to drop because + the destination MAC is not configured in the MAC table and + the interface is not in promiscuous mode Driver-specific Packet Traps ============================ diff --git a/include/net/devlink.h b/include/net/devlink.h index d12ed2854c34..426b98e74b6e 100644 --- a/include/net/devlink.h +++ b/include/net/devlink.h @@ -838,6 +838,7 @@ enum devlink_trap_generic_id { DEVLINK_TRAP_GENERIC_ID_GTP_PARSING, DEVLINK_TRAP_GENERIC_ID_ESP_PARSING, DEVLINK_TRAP_GENERIC_ID_BLACKHOLE_NEXTHOP, + DEVLINK_TRAP_GENERIC_ID_DMAC_FILTER, /* Add new generic trap IDs above */ __DEVLINK_TRAP_GENERIC_ID_MAX, @@ -1063,6 +1064,8 @@ enum devlink_trap_group_generic_id { "esp_parsing" #define DEVLINK_TRAP_GENERIC_NAME_BLACKHOLE_NEXTHOP \ "blackhole_nexthop" +#define DEVLINK_TRAP_GENERIC_NAME_DMAC_FILTER \ + "dest_mac_filter" #define DEVLINK_TRAP_GROUP_GENERIC_NAME_L2_DROPS \ "l2_drops" diff --git a/net/core/devlink.c b/net/core/devlink.c index 72ea79879762..f6e6445b9801 100644 --- a/net/core/devlink.c +++ b/net/core/devlink.c @@ -9512,6 +9512,7 @@ static const struct devlink_trap devlink_trap_generic[] = { DEVLINK_TRAP(GTP_PARSING, DROP), DEVLINK_TRAP(ESP_PARSING, DROP), DEVLINK_TRAP(BLACKHOLE_NEXTHOP, DROP), + DEVLINK_TRAP(DMAC_FILTER, DROP), }; #define DEVLINK_TRAP_GROUP(_id) \ -- cgit v1.2.3 From 3567932c56e8b7785a41d58dd3eaeb0ab86aeb76 Mon Sep 17 00:00:00 2001 From: Andre Przywara Date: Wed, 27 Jan 2021 17:24:50 +0000 Subject: dt-bindings: i2c: mv64xxx: Add H616 compatible string Add the obvious compatible name to the existing I2C binding, and pair it with the existing A31 fallback compatible string, as the devices are compatible. On the way use enums to group all compatible devices together. Signed-off-by: Andre Przywara Acked-by: Rob Herring Signed-off-by: Wolfram Sang --- .../bindings/i2c/marvell,mv64xxx-i2c.yaml | 21 +++++++-------------- 1 file changed, 7 insertions(+), 14 deletions(-) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/i2c/marvell,mv64xxx-i2c.yaml b/Documentation/devicetree/bindings/i2c/marvell,mv64xxx-i2c.yaml index 5b5ae402f97a..eb72dd571def 100644 --- a/Documentation/devicetree/bindings/i2c/marvell,mv64xxx-i2c.yaml +++ b/Documentation/devicetree/bindings/i2c/marvell,mv64xxx-i2c.yaml @@ -18,21 +18,14 @@ properties: - const: allwinner,sun4i-a10-i2c - const: allwinner,sun6i-a31-i2c - items: - - const: allwinner,sun8i-a23-i2c + - enum: + - allwinner,sun8i-a23-i2c + - allwinner,sun8i-a83t-i2c + - allwinner,sun50i-a64-i2c + - allwinner,sun50i-a100-i2c + - allwinner,sun50i-h6-i2c + - allwinner,sun50i-h616-i2c - const: allwinner,sun6i-a31-i2c - - items: - - const: allwinner,sun8i-a83t-i2c - - const: allwinner,sun6i-a31-i2c - - items: - - const: allwinner,sun50i-a64-i2c - - const: allwinner,sun6i-a31-i2c - - items: - - const: allwinner,sun50i-a100-i2c - - const: allwinner,sun6i-a31-i2c - - items: - - const: allwinner,sun50i-h6-i2c - - const: allwinner,sun6i-a31-i2c - - const: marvell,mv64xxx-i2c - const: marvell,mv78230-i2c - const: marvell,mv78230-a0-i2c -- cgit v1.2.3 From 73cc584cfced260133cfc635f9921d66da676749 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Wed, 20 Jan 2021 14:28:34 +0100 Subject: i2c: remove zte zx bus driver The zte zx platform is getting removed, so this driver is no longer needed. Signed-off-by: Arnd Bergmann Signed-off-by: Wolfram Sang --- .../devicetree/bindings/i2c/i2c-zx2967.txt | 22 - drivers/i2c/busses/Kconfig | 9 - drivers/i2c/busses/Makefile | 1 - drivers/i2c/busses/i2c-zx2967.c | 602 --------------------- 4 files changed, 634 deletions(-) delete mode 100644 Documentation/devicetree/bindings/i2c/i2c-zx2967.txt delete mode 100644 drivers/i2c/busses/i2c-zx2967.c (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/i2c/i2c-zx2967.txt b/Documentation/devicetree/bindings/i2c/i2c-zx2967.txt deleted file mode 100644 index cb806d1ae4c9..000000000000 --- a/Documentation/devicetree/bindings/i2c/i2c-zx2967.txt +++ /dev/null @@ -1,22 +0,0 @@ -ZTE zx2967 I2C controller - -Required properties: - - compatible: must be "zte,zx296718-i2c" - - reg: physical address and length of the device registers - - interrupts: a single interrupt specifier - - clocks: clock for the device - - #address-cells: should be <1> - - #size-cells: should be <0> - - clock-frequency: the desired I2C bus clock frequency. - -Examples: - - i2c@112000 { - compatible = "zte,zx296718-i2c"; - reg = <0x00112000 0x1000>; - interrupts = ; - clocks = <&osc24m>; - #address-cells = <1> - #size-cells = <0>; - clock-frequency = <1600000>; - }; diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig index 4fe74259d44c..2a89d0b061ee 100644 --- a/drivers/i2c/busses/Kconfig +++ b/drivers/i2c/busses/Kconfig @@ -1370,15 +1370,6 @@ config I2C_OPAL This driver can also be built as a module. If so, the module will be called as i2c-opal. -config I2C_ZX2967 - tristate "ZTE ZX2967 I2C support" - depends on ARCH_ZX - default y - help - Selecting this option will add ZX2967 I2C driver. - This driver can also be built as a module. If so, the module will be - called i2c-zx2967. - config I2C_FSI tristate "FSI I2C driver" depends on FSI diff --git a/drivers/i2c/busses/Makefile b/drivers/i2c/busses/Makefile index 572d5fcc6016..615f35e3e31f 100644 --- a/drivers/i2c/busses/Makefile +++ b/drivers/i2c/busses/Makefile @@ -119,7 +119,6 @@ obj-$(CONFIG_I2C_XILINX) += i2c-xiic.o obj-$(CONFIG_I2C_XLR) += i2c-xlr.o obj-$(CONFIG_I2C_XLP9XX) += i2c-xlp9xx.o obj-$(CONFIG_I2C_RCAR) += i2c-rcar.o -obj-$(CONFIG_I2C_ZX2967) += i2c-zx2967.o # External I2C/SMBus adapter drivers obj-$(CONFIG_I2C_DIOLAN_U2C) += i2c-diolan-u2c.o diff --git a/drivers/i2c/busses/i2c-zx2967.c b/drivers/i2c/busses/i2c-zx2967.c deleted file mode 100644 index 8db9519695a6..000000000000 --- a/drivers/i2c/busses/i2c-zx2967.c +++ /dev/null @@ -1,602 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Copyright (C) 2017 Sanechips Technology Co., Ltd. - * Copyright 2017 Linaro Ltd. - * - * Author: Baoyou Xie - */ - -#include -#include -#include -#include -#include -#include - -#define REG_CMD 0x04 -#define REG_DEVADDR_H 0x0C -#define REG_DEVADDR_L 0x10 -#define REG_CLK_DIV_FS 0x14 -#define REG_CLK_DIV_HS 0x18 -#define REG_WRCONF 0x1C -#define REG_RDCONF 0x20 -#define REG_DATA 0x24 -#define REG_STAT 0x28 - -#define I2C_STOP 0 -#define I2C_MASTER BIT(0) -#define I2C_ADDR_MODE_TEN BIT(1) -#define I2C_IRQ_MSK_ENABLE BIT(3) -#define I2C_RW_READ BIT(4) -#define I2C_CMB_RW_EN BIT(5) -#define I2C_START BIT(6) - -#define I2C_ADDR_LOW_MASK GENMASK(6, 0) -#define I2C_ADDR_LOW_SHIFT 0 -#define I2C_ADDR_HI_MASK GENMASK(2, 0) -#define I2C_ADDR_HI_SHIFT 7 - -#define I2C_WFIFO_RESET BIT(7) -#define I2C_RFIFO_RESET BIT(7) - -#define I2C_IRQ_ACK_CLEAR BIT(7) -#define I2C_INT_MASK GENMASK(6, 0) - -#define I2C_TRANS_DONE BIT(0) -#define I2C_SR_EDEVICE BIT(1) -#define I2C_SR_EDATA BIT(2) - -#define I2C_FIFO_MAX 16 - -#define I2C_TIMEOUT msecs_to_jiffies(1000) - -#define DEV(i2c) ((i2c)->adap.dev.parent) - -struct zx2967_i2c { - struct i2c_adapter adap; - struct clk *clk; - struct completion complete; - u32 clk_freq; - void __iomem *reg_base; - size_t residue; - int irq; - int msg_rd; - u8 *cur_trans; - u8 access_cnt; - int error; -}; - -static void zx2967_i2c_writel(struct zx2967_i2c *i2c, - u32 val, unsigned long reg) -{ - writel_relaxed(val, i2c->reg_base + reg); -} - -static u32 zx2967_i2c_readl(struct zx2967_i2c *i2c, unsigned long reg) -{ - return readl_relaxed(i2c->reg_base + reg); -} - -static void zx2967_i2c_writesb(struct zx2967_i2c *i2c, - void *data, unsigned long reg, int len) -{ - writesb(i2c->reg_base + reg, data, len); -} - -static void zx2967_i2c_readsb(struct zx2967_i2c *i2c, - void *data, unsigned long reg, int len) -{ - readsb(i2c->reg_base + reg, data, len); -} - -static void zx2967_i2c_start_ctrl(struct zx2967_i2c *i2c) -{ - u32 status; - u32 ctl; - - status = zx2967_i2c_readl(i2c, REG_STAT); - status |= I2C_IRQ_ACK_CLEAR; - zx2967_i2c_writel(i2c, status, REG_STAT); - - ctl = zx2967_i2c_readl(i2c, REG_CMD); - if (i2c->msg_rd) - ctl |= I2C_RW_READ; - else - ctl &= ~I2C_RW_READ; - ctl &= ~I2C_CMB_RW_EN; - ctl |= I2C_START; - zx2967_i2c_writel(i2c, ctl, REG_CMD); -} - -static void zx2967_i2c_flush_fifos(struct zx2967_i2c *i2c) -{ - u32 offset; - u32 val; - - if (i2c->msg_rd) { - offset = REG_RDCONF; - val = I2C_RFIFO_RESET; - } else { - offset = REG_WRCONF; - val = I2C_WFIFO_RESET; - } - - val |= zx2967_i2c_readl(i2c, offset); - zx2967_i2c_writel(i2c, val, offset); -} - -static int zx2967_i2c_empty_rx_fifo(struct zx2967_i2c *i2c, u32 size) -{ - u8 val[I2C_FIFO_MAX] = {0}; - int i; - - if (size > I2C_FIFO_MAX) { - dev_err(DEV(i2c), "fifo size %d over the max value %d\n", - size, I2C_FIFO_MAX); - return -EINVAL; - } - - zx2967_i2c_readsb(i2c, val, REG_DATA, size); - for (i = 0; i < size; i++) { - *i2c->cur_trans++ = val[i]; - i2c->residue--; - } - - barrier(); - - return 0; -} - -static int zx2967_i2c_fill_tx_fifo(struct zx2967_i2c *i2c) -{ - size_t residue = i2c->residue; - u8 *buf = i2c->cur_trans; - - if (residue == 0) { - dev_err(DEV(i2c), "residue is %d\n", (int)residue); - return -EINVAL; - } - - if (residue <= I2C_FIFO_MAX) { - zx2967_i2c_writesb(i2c, buf, REG_DATA, residue); - - /* Again update before writing to FIFO to make sure isr sees. */ - i2c->residue = 0; - i2c->cur_trans = NULL; - } else { - zx2967_i2c_writesb(i2c, buf, REG_DATA, I2C_FIFO_MAX); - i2c->residue -= I2C_FIFO_MAX; - i2c->cur_trans += I2C_FIFO_MAX; - } - - barrier(); - - return 0; -} - -static int zx2967_i2c_reset_hardware(struct zx2967_i2c *i2c) -{ - u32 val; - u32 clk_div; - - val = I2C_MASTER | I2C_IRQ_MSK_ENABLE; - zx2967_i2c_writel(i2c, val, REG_CMD); - - clk_div = clk_get_rate(i2c->clk) / i2c->clk_freq - 1; - zx2967_i2c_writel(i2c, clk_div, REG_CLK_DIV_FS); - zx2967_i2c_writel(i2c, clk_div, REG_CLK_DIV_HS); - - zx2967_i2c_writel(i2c, I2C_FIFO_MAX - 1, REG_WRCONF); - zx2967_i2c_writel(i2c, I2C_FIFO_MAX - 1, REG_RDCONF); - zx2967_i2c_writel(i2c, 1, REG_RDCONF); - - zx2967_i2c_flush_fifos(i2c); - - return 0; -} - -static void zx2967_i2c_isr_clr(struct zx2967_i2c *i2c) -{ - u32 status; - - status = zx2967_i2c_readl(i2c, REG_STAT); - status |= I2C_IRQ_ACK_CLEAR; - zx2967_i2c_writel(i2c, status, REG_STAT); -} - -static irqreturn_t zx2967_i2c_isr(int irq, void *dev_id) -{ - u32 status; - struct zx2967_i2c *i2c = (struct zx2967_i2c *)dev_id; - - status = zx2967_i2c_readl(i2c, REG_STAT) & I2C_INT_MASK; - zx2967_i2c_isr_clr(i2c); - - if (status & I2C_SR_EDEVICE) - i2c->error = -ENXIO; - else if (status & I2C_SR_EDATA) - i2c->error = -EIO; - else if (status & I2C_TRANS_DONE) - i2c->error = 0; - else - goto done; - - complete(&i2c->complete); -done: - return IRQ_HANDLED; -} - -static void zx2967_set_addr(struct zx2967_i2c *i2c, u16 addr) -{ - u16 val; - - val = (addr >> I2C_ADDR_LOW_SHIFT) & I2C_ADDR_LOW_MASK; - zx2967_i2c_writel(i2c, val, REG_DEVADDR_L); - - val = (addr >> I2C_ADDR_HI_SHIFT) & I2C_ADDR_HI_MASK; - zx2967_i2c_writel(i2c, val, REG_DEVADDR_H); - if (val) - val = zx2967_i2c_readl(i2c, REG_CMD) | I2C_ADDR_MODE_TEN; - else - val = zx2967_i2c_readl(i2c, REG_CMD) & ~I2C_ADDR_MODE_TEN; - zx2967_i2c_writel(i2c, val, REG_CMD); -} - -static int zx2967_i2c_xfer_bytes(struct zx2967_i2c *i2c, u32 bytes) -{ - unsigned long time_left; - int rd = i2c->msg_rd; - int ret; - - reinit_completion(&i2c->complete); - - if (rd) { - zx2967_i2c_writel(i2c, bytes - 1, REG_RDCONF); - } else { - ret = zx2967_i2c_fill_tx_fifo(i2c); - if (ret) - return ret; - } - - zx2967_i2c_start_ctrl(i2c); - - time_left = wait_for_completion_timeout(&i2c->complete, - I2C_TIMEOUT); - if (time_left == 0) - return -ETIMEDOUT; - - if (i2c->error) - return i2c->error; - - return rd ? zx2967_i2c_empty_rx_fifo(i2c, bytes) : 0; -} - -static int zx2967_i2c_xfer_msg(struct zx2967_i2c *i2c, - struct i2c_msg *msg) -{ - int ret; - int i; - - zx2967_i2c_flush_fifos(i2c); - - i2c->cur_trans = msg->buf; - i2c->residue = msg->len; - i2c->access_cnt = msg->len / I2C_FIFO_MAX; - i2c->msg_rd = msg->flags & I2C_M_RD; - - for (i = 0; i < i2c->access_cnt; i++) { - ret = zx2967_i2c_xfer_bytes(i2c, I2C_FIFO_MAX); - if (ret) - return ret; - } - - if (i2c->residue > 0) { - ret = zx2967_i2c_xfer_bytes(i2c, i2c->residue); - if (ret) - return ret; - } - - i2c->residue = 0; - i2c->access_cnt = 0; - - return 0; -} - -static int zx2967_i2c_xfer(struct i2c_adapter *adap, - struct i2c_msg *msgs, int num) -{ - struct zx2967_i2c *i2c = i2c_get_adapdata(adap); - int ret; - int i; - - zx2967_set_addr(i2c, msgs->addr); - - for (i = 0; i < num; i++) { - ret = zx2967_i2c_xfer_msg(i2c, &msgs[i]); - if (ret) - return ret; - } - - return num; -} - -static void -zx2967_smbus_xfer_prepare(struct zx2967_i2c *i2c, u16 addr, - char read_write, u8 command, int size, - union i2c_smbus_data *data) -{ - u32 val; - - val = zx2967_i2c_readl(i2c, REG_RDCONF); - val |= I2C_RFIFO_RESET; - zx2967_i2c_writel(i2c, val, REG_RDCONF); - zx2967_set_addr(i2c, addr); - val = zx2967_i2c_readl(i2c, REG_CMD); - val &= ~I2C_RW_READ; - zx2967_i2c_writel(i2c, val, REG_CMD); - - switch (size) { - case I2C_SMBUS_BYTE: - zx2967_i2c_writel(i2c, command, REG_DATA); - break; - case I2C_SMBUS_BYTE_DATA: - zx2967_i2c_writel(i2c, command, REG_DATA); - if (read_write == I2C_SMBUS_WRITE) - zx2967_i2c_writel(i2c, data->byte, REG_DATA); - break; - case I2C_SMBUS_WORD_DATA: - zx2967_i2c_writel(i2c, command, REG_DATA); - if (read_write == I2C_SMBUS_WRITE) { - zx2967_i2c_writel(i2c, (data->word >> 8), REG_DATA); - zx2967_i2c_writel(i2c, (data->word & 0xff), - REG_DATA); - } - break; - } -} - -static int zx2967_smbus_xfer_read(struct zx2967_i2c *i2c, int size, - union i2c_smbus_data *data) -{ - unsigned long time_left; - u8 buf[2]; - u32 val; - - reinit_completion(&i2c->complete); - - val = zx2967_i2c_readl(i2c, REG_CMD); - val |= I2C_CMB_RW_EN; - zx2967_i2c_writel(i2c, val, REG_CMD); - - val = zx2967_i2c_readl(i2c, REG_CMD); - val |= I2C_START; - zx2967_i2c_writel(i2c, val, REG_CMD); - - time_left = wait_for_completion_timeout(&i2c->complete, - I2C_TIMEOUT); - if (time_left == 0) - return -ETIMEDOUT; - - if (i2c->error) - return i2c->error; - - switch (size) { - case I2C_SMBUS_BYTE: - case I2C_SMBUS_BYTE_DATA: - val = zx2967_i2c_readl(i2c, REG_DATA); - data->byte = val; - break; - case I2C_SMBUS_WORD_DATA: - case I2C_SMBUS_PROC_CALL: - buf[0] = zx2967_i2c_readl(i2c, REG_DATA); - buf[1] = zx2967_i2c_readl(i2c, REG_DATA); - data->word = (buf[0] << 8) | buf[1]; - break; - default: - return -EOPNOTSUPP; - } - - return 0; -} - -static int zx2967_smbus_xfer_write(struct zx2967_i2c *i2c) -{ - unsigned long time_left; - u32 val; - - reinit_completion(&i2c->complete); - val = zx2967_i2c_readl(i2c, REG_CMD); - val |= I2C_START; - zx2967_i2c_writel(i2c, val, REG_CMD); - - time_left = wait_for_completion_timeout(&i2c->complete, - I2C_TIMEOUT); - if (time_left == 0) - return -ETIMEDOUT; - - if (i2c->error) - return i2c->error; - - return 0; -} - -static int zx2967_smbus_xfer(struct i2c_adapter *adap, u16 addr, - unsigned short flags, char read_write, - u8 command, int size, union i2c_smbus_data *data) -{ - struct zx2967_i2c *i2c = i2c_get_adapdata(adap); - - if (size == I2C_SMBUS_QUICK) - read_write = I2C_SMBUS_WRITE; - - switch (size) { - case I2C_SMBUS_QUICK: - case I2C_SMBUS_BYTE: - case I2C_SMBUS_BYTE_DATA: - case I2C_SMBUS_WORD_DATA: - zx2967_smbus_xfer_prepare(i2c, addr, read_write, - command, size, data); - break; - default: - return -EOPNOTSUPP; - } - - if (read_write == I2C_SMBUS_READ) - return zx2967_smbus_xfer_read(i2c, size, data); - - return zx2967_smbus_xfer_write(i2c); -} - -static u32 zx2967_i2c_func(struct i2c_adapter *adap) -{ - return I2C_FUNC_I2C | - I2C_FUNC_SMBUS_QUICK | - I2C_FUNC_SMBUS_BYTE | - I2C_FUNC_SMBUS_BYTE_DATA | - I2C_FUNC_SMBUS_WORD_DATA | - I2C_FUNC_SMBUS_BLOCK_DATA | - I2C_FUNC_SMBUS_PROC_CALL | - I2C_FUNC_SMBUS_I2C_BLOCK; -} - -static int __maybe_unused zx2967_i2c_suspend(struct device *dev) -{ - struct zx2967_i2c *i2c = dev_get_drvdata(dev); - - i2c_mark_adapter_suspended(&i2c->adap); - clk_disable_unprepare(i2c->clk); - - return 0; -} - -static int __maybe_unused zx2967_i2c_resume(struct device *dev) -{ - struct zx2967_i2c *i2c = dev_get_drvdata(dev); - - clk_prepare_enable(i2c->clk); - i2c_mark_adapter_resumed(&i2c->adap); - - return 0; -} - -static SIMPLE_DEV_PM_OPS(zx2967_i2c_dev_pm_ops, - zx2967_i2c_suspend, zx2967_i2c_resume); - -static const struct i2c_algorithm zx2967_i2c_algo = { - .master_xfer = zx2967_i2c_xfer, - .smbus_xfer = zx2967_smbus_xfer, - .functionality = zx2967_i2c_func, -}; - -static const struct i2c_adapter_quirks zx2967_i2c_quirks = { - .flags = I2C_AQ_NO_ZERO_LEN, -}; - -static const struct of_device_id zx2967_i2c_of_match[] = { - { .compatible = "zte,zx296718-i2c", }, - { }, -}; -MODULE_DEVICE_TABLE(of, zx2967_i2c_of_match); - -static int zx2967_i2c_probe(struct platform_device *pdev) -{ - struct zx2967_i2c *i2c; - void __iomem *reg_base; - struct clk *clk; - int ret; - - i2c = devm_kzalloc(&pdev->dev, sizeof(*i2c), GFP_KERNEL); - if (!i2c) - return -ENOMEM; - - reg_base = devm_platform_ioremap_resource(pdev, 0); - if (IS_ERR(reg_base)) - return PTR_ERR(reg_base); - - clk = devm_clk_get(&pdev->dev, NULL); - if (IS_ERR(clk)) { - dev_err(&pdev->dev, "missing controller clock"); - return PTR_ERR(clk); - } - - ret = clk_prepare_enable(clk); - if (ret) { - dev_err(&pdev->dev, "failed to enable i2c_clk\n"); - return ret; - } - - ret = device_property_read_u32(&pdev->dev, "clock-frequency", - &i2c->clk_freq); - if (ret) { - dev_err(&pdev->dev, "missing clock-frequency"); - return ret; - } - - ret = platform_get_irq(pdev, 0); - if (ret < 0) - return ret; - - i2c->irq = ret; - i2c->reg_base = reg_base; - i2c->clk = clk; - - init_completion(&i2c->complete); - platform_set_drvdata(pdev, i2c); - - ret = zx2967_i2c_reset_hardware(i2c); - if (ret) { - dev_err(&pdev->dev, "failed to initialize i2c controller\n"); - goto err_clk_unprepare; - } - - ret = devm_request_irq(&pdev->dev, i2c->irq, - zx2967_i2c_isr, 0, dev_name(&pdev->dev), i2c); - if (ret) { - dev_err(&pdev->dev, "failed to request irq %i\n", i2c->irq); - goto err_clk_unprepare; - } - - i2c_set_adapdata(&i2c->adap, i2c); - strlcpy(i2c->adap.name, "zx2967 i2c adapter", - sizeof(i2c->adap.name)); - i2c->adap.algo = &zx2967_i2c_algo; - i2c->adap.quirks = &zx2967_i2c_quirks; - i2c->adap.nr = pdev->id; - i2c->adap.dev.parent = &pdev->dev; - i2c->adap.dev.of_node = pdev->dev.of_node; - - ret = i2c_add_numbered_adapter(&i2c->adap); - if (ret) - goto err_clk_unprepare; - - return 0; - -err_clk_unprepare: - clk_disable_unprepare(i2c->clk); - return ret; -} - -static int zx2967_i2c_remove(struct platform_device *pdev) -{ - struct zx2967_i2c *i2c = platform_get_drvdata(pdev); - - i2c_del_adapter(&i2c->adap); - clk_disable_unprepare(i2c->clk); - - return 0; -} - -static struct platform_driver zx2967_i2c_driver = { - .probe = zx2967_i2c_probe, - .remove = zx2967_i2c_remove, - .driver = { - .name = "zx2967_i2c", - .of_match_table = zx2967_i2c_of_match, - .pm = &zx2967_i2c_dev_pm_ops, - }, -}; -module_platform_driver(zx2967_i2c_driver); - -MODULE_AUTHOR("Baoyou Xie "); -MODULE_DESCRIPTION("ZTE ZX2967 I2C Bus Controller driver"); -MODULE_LICENSE("GPL v2"); -- cgit v1.2.3 From 335d3fc57941e5c6164c69d439aec1cb7a800876 Mon Sep 17 00:00:00 2001 From: Sargun Dhillon Date: Thu, 7 Jan 2021 16:10:43 -0800 Subject: ovl: implement volatile-specific fsync error behaviour Overlayfs's volatile option allows the user to bypass all forced sync calls to the upperdir filesystem. This comes at the cost of safety. We can never ensure that the user's data is intact, but we can make a best effort to expose whether or not the data is likely to be in a bad state. The best way to handle this in the time being is that if an overlayfs's upperdir experiences an error after a volatile mount occurs, that error will be returned on fsync, fdatasync, sync, and syncfs. This is contradictory to the traditional behaviour of VFS which fails the call once, and only raises an error if a subsequent fsync error has occurred, and been raised by the filesystem. One awkward aspect of the patch is that we have to manually set the superblock's errseq_t after the sync_fs callback as opposed to just returning an error from syncfs. This is because the call chain looks something like this: sys_syncfs -> sync_filesystem -> __sync_filesystem -> /* The return value is ignored here sb->s_op->sync_fs(sb) _sync_blockdev /* Where the VFS fetches the error to raise to userspace */ errseq_check_and_advance Because of this we call errseq_set every time the sync_fs callback occurs. Due to the nature of this seen / unseen dichotomy, if the upperdir is an inconsistent state at the initial mount time, overlayfs will refuse to mount, as overlayfs cannot get a snapshot of the upperdir's errseq that will increment on error until the user calls syncfs. Signed-off-by: Sargun Dhillon Suggested-by: Amir Goldstein Reviewed-by: Amir Goldstein Fixes: c86243b090bc ("ovl: provide a mount option "volatile"") Cc: stable@vger.kernel.org Reviewed-by: Vivek Goyal Reviewed-by: Jeff Layton Signed-off-by: Miklos Szeredi --- Documentation/filesystems/overlayfs.rst | 8 ++++++++ fs/overlayfs/file.c | 5 +++-- fs/overlayfs/overlayfs.h | 1 + fs/overlayfs/ovl_entry.h | 2 ++ fs/overlayfs/readdir.c | 5 +++-- fs/overlayfs/super.c | 34 ++++++++++++++++++++++++++------- fs/overlayfs/util.c | 27 ++++++++++++++++++++++++++ 7 files changed, 71 insertions(+), 11 deletions(-) (limited to 'Documentation') diff --git a/Documentation/filesystems/overlayfs.rst b/Documentation/filesystems/overlayfs.rst index 587a93973929..78240e29b0bb 100644 --- a/Documentation/filesystems/overlayfs.rst +++ b/Documentation/filesystems/overlayfs.rst @@ -586,6 +586,14 @@ without significant effort. The advantage of mounting with the "volatile" option is that all forms of sync calls to the upper filesystem are omitted. +In order to avoid a giving a false sense of safety, the syncfs (and fsync) +semantics of volatile mounts are slightly different than that of the rest of +VFS. If any writeback error occurs on the upperdir's filesystem after a +volatile mount takes place, all sync functions will return an error. Once this +condition is reached, the filesystem will not recover, and every subsequent sync +call will return an error, even if the upperdir has not experience a new error +since the last sync call. + When overlay is mounted with "volatile" option, the directory "$workdir/work/incompat/volatile" is created. During next mount, overlay checks for this directory and refuses to mount if present. This is a strong diff --git a/fs/overlayfs/file.c b/fs/overlayfs/file.c index bd9dd38347ae..077d3ad343f6 100644 --- a/fs/overlayfs/file.c +++ b/fs/overlayfs/file.c @@ -398,8 +398,9 @@ static int ovl_fsync(struct file *file, loff_t start, loff_t end, int datasync) const struct cred *old_cred; int ret; - if (!ovl_should_sync(OVL_FS(file_inode(file)->i_sb))) - return 0; + ret = ovl_sync_status(OVL_FS(file_inode(file)->i_sb)); + if (ret <= 0) + return ret; ret = ovl_real_fdget_meta(file, &real, !datasync); if (ret) diff --git a/fs/overlayfs/overlayfs.h b/fs/overlayfs/overlayfs.h index b487e48c7fd4..cb4e2d60ecf9 100644 --- a/fs/overlayfs/overlayfs.h +++ b/fs/overlayfs/overlayfs.h @@ -324,6 +324,7 @@ int ovl_check_metacopy_xattr(struct ovl_fs *ofs, struct dentry *dentry); bool ovl_is_metacopy_dentry(struct dentry *dentry); char *ovl_get_redirect_xattr(struct ovl_fs *ofs, struct dentry *dentry, int padding); +int ovl_sync_status(struct ovl_fs *ofs); static inline bool ovl_is_impuredir(struct super_block *sb, struct dentry *dentry) diff --git a/fs/overlayfs/ovl_entry.h b/fs/overlayfs/ovl_entry.h index fbd5e27ce66b..63efee554f69 100644 --- a/fs/overlayfs/ovl_entry.h +++ b/fs/overlayfs/ovl_entry.h @@ -81,6 +81,8 @@ struct ovl_fs { atomic_long_t last_ino; /* Whiteout dentry cache */ struct dentry *whiteout; + /* r/o snapshot of upperdir sb's only taken on volatile mounts */ + errseq_t errseq; }; static inline struct vfsmount *ovl_upper_mnt(struct ovl_fs *ofs) diff --git a/fs/overlayfs/readdir.c b/fs/overlayfs/readdir.c index 60d751f28fea..f404a78e6b60 100644 --- a/fs/overlayfs/readdir.c +++ b/fs/overlayfs/readdir.c @@ -900,8 +900,9 @@ static int ovl_dir_fsync(struct file *file, loff_t start, loff_t end, struct file *realfile; int err; - if (!ovl_should_sync(OVL_FS(file->f_path.dentry->d_sb))) - return 0; + err = ovl_sync_status(OVL_FS(file->f_path.dentry->d_sb)); + if (err <= 0) + return err; realfile = ovl_dir_real_file(file, true); err = PTR_ERR_OR_ZERO(realfile); diff --git a/fs/overlayfs/super.c b/fs/overlayfs/super.c index 82cd6d55a5a1..d58b8f2bf9d0 100644 --- a/fs/overlayfs/super.c +++ b/fs/overlayfs/super.c @@ -264,11 +264,20 @@ static int ovl_sync_fs(struct super_block *sb, int wait) struct super_block *upper_sb; int ret; - if (!ovl_upper_mnt(ofs)) - return 0; + ret = ovl_sync_status(ofs); + /* + * We have to always set the err, because the return value isn't + * checked in syncfs, and instead indirectly return an error via + * the sb's writeback errseq, which VFS inspects after this call. + */ + if (ret < 0) { + errseq_set(&sb->s_wb_err, -EIO); + return -EIO; + } + + if (!ret) + return ret; - if (!ovl_should_sync(ofs)) - return 0; /* * Not called for sync(2) call or an emergency sync (SB_I_SKIP_SYNC). * All the super blocks will be iterated, including upper_sb. @@ -1993,6 +2002,8 @@ static int ovl_fill_super(struct super_block *sb, void *data, int silent) sb->s_op = &ovl_super_operations; if (ofs->config.upperdir) { + struct super_block *upper_sb; + if (!ofs->config.workdir) { pr_err("missing 'workdir'\n"); goto out_err; @@ -2002,6 +2013,16 @@ static int ovl_fill_super(struct super_block *sb, void *data, int silent) if (err) goto out_err; + upper_sb = ovl_upper_mnt(ofs)->mnt_sb; + if (!ovl_should_sync(ofs)) { + ofs->errseq = errseq_sample(&upper_sb->s_wb_err); + if (errseq_check(&upper_sb->s_wb_err, ofs->errseq)) { + err = -EIO; + pr_err("Cannot mount volatile when upperdir has an unseen error. Sync upperdir fs to clear state.\n"); + goto out_err; + } + } + err = ovl_get_workdir(sb, ofs, &upperpath); if (err) goto out_err; @@ -2009,9 +2030,8 @@ static int ovl_fill_super(struct super_block *sb, void *data, int silent) if (!ofs->workdir) sb->s_flags |= SB_RDONLY; - sb->s_stack_depth = ovl_upper_mnt(ofs)->mnt_sb->s_stack_depth; - sb->s_time_gran = ovl_upper_mnt(ofs)->mnt_sb->s_time_gran; - + sb->s_stack_depth = upper_sb->s_stack_depth; + sb->s_time_gran = upper_sb->s_time_gran; } oe = ovl_get_lowerstack(sb, splitlower, numlower, ofs, layers); err = PTR_ERR(oe); diff --git a/fs/overlayfs/util.c b/fs/overlayfs/util.c index 6569031af3cd..9826b003f1d2 100644 --- a/fs/overlayfs/util.c +++ b/fs/overlayfs/util.c @@ -962,3 +962,30 @@ err_free: kfree(buf); return ERR_PTR(res); } + +/* + * ovl_sync_status() - Check fs sync status for volatile mounts + * + * Returns 1 if this is not a volatile mount and a real sync is required. + * + * Returns 0 if syncing can be skipped because mount is volatile, and no errors + * have occurred on the upperdir since the mount. + * + * Returns -errno if it is a volatile mount, and the error that occurred since + * the last mount. If the error code changes, it'll return the latest error + * code. + */ + +int ovl_sync_status(struct ovl_fs *ofs) +{ + struct vfsmount *mnt; + + if (ovl_should_sync(ofs)) + return 1; + + mnt = ovl_upper_mnt(ofs); + if (!mnt) + return 0; + + return errseq_check(&mnt->mnt_sb->s_wb_err, ofs->errseq); +} -- cgit v1.2.3 From f8d0e2bae6315343faadba647fc2e8ac995b8ecf Mon Sep 17 00:00:00 2001 From: Andre Przywara Date: Wed, 27 Jan 2021 17:24:41 +0000 Subject: dt-bindings: clk: sunxi-ccu: Add compatible string for Allwinner H616 Signed-off-by: Andre Przywara Acked-by: Rob Herring Acked-by: Maxime Ripard Signed-off-by: Maxime Ripard Link: https://lore.kernel.org/r/20210127172500.13356-2-andre.przywara@arm.com --- Documentation/devicetree/bindings/clock/allwinner,sun4i-a10-ccu.yaml | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/clock/allwinner,sun4i-a10-ccu.yaml b/Documentation/devicetree/bindings/clock/allwinner,sun4i-a10-ccu.yaml index 3b45344ed758..a27025cd3909 100644 --- a/Documentation/devicetree/bindings/clock/allwinner,sun4i-a10-ccu.yaml +++ b/Documentation/devicetree/bindings/clock/allwinner,sun4i-a10-ccu.yaml @@ -41,6 +41,8 @@ properties: - allwinner,sun50i-h5-ccu - allwinner,sun50i-h6-ccu - allwinner,sun50i-h6-r-ccu + - allwinner,sun50i-h616-ccu + - allwinner,sun50i-h616-r-ccu - allwinner,suniv-f1c100s-ccu - nextthing,gr8-ccu @@ -82,6 +84,7 @@ if: - allwinner,sun50i-a64-r-ccu - allwinner,sun50i-a100-r-ccu - allwinner,sun50i-h6-r-ccu + - allwinner,sun50i-h616-r-ccu then: properties: @@ -100,6 +103,7 @@ else: enum: - allwinner,sun50i-a100-ccu - allwinner,sun50i-h6-ccu + - allwinner,sun50i-h616-ccu then: properties: -- cgit v1.2.3 From 59657d55d1a04fa5d50f96487c96c1d82f02a7f6 Mon Sep 17 00:00:00 2001 From: Andre Przywara Date: Wed, 27 Jan 2021 17:24:47 +0000 Subject: dt-bindings: sram: sunxi-sram: Add H616 compatible string The H616 adds a second EMAC clock register. We don't know about the exact SRAM properties yet, so this gets omitted for now. Signed-off-by: Andre Przywara Acked-by: Rob Herring Signed-off-by: Maxime Ripard Link: https://lore.kernel.org/r/20210127172500.13356-8-andre.przywara@arm.com --- .../devicetree/bindings/sram/allwinner,sun4i-a10-system-control.yaml | 1 + 1 file changed, 1 insertion(+) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/sram/allwinner,sun4i-a10-system-control.yaml b/Documentation/devicetree/bindings/sram/allwinner,sun4i-a10-system-control.yaml index b66a07e21d1e..1c426c211e36 100644 --- a/Documentation/devicetree/bindings/sram/allwinner,sun4i-a10-system-control.yaml +++ b/Documentation/devicetree/bindings/sram/allwinner,sun4i-a10-system-control.yaml @@ -49,6 +49,7 @@ properties: - items: - const: allwinner,suniv-f1c100s-system-control - const: allwinner,sun4i-a10-system-control + - const: allwinner,sun50i-h616-system-control reg: maxItems: 1 -- cgit v1.2.3 From 308e78946a73e2bfe0ebd4ca9559c153c80bd45f Mon Sep 17 00:00:00 2001 From: Andre Przywara Date: Wed, 27 Jan 2021 17:24:54 +0000 Subject: dt-bindings: bus: rsb: Add H616 compatible string Add the obvious compatible name to the existing RSB binding, and pair it with the existing A23 fallback compatible string, as the devices are compatible. Signed-off-by: Andre Przywara Signed-off-by: Maxime Ripard Link: https://lore.kernel.org/r/20210127172500.13356-15-andre.przywara@arm.com --- Documentation/devicetree/bindings/bus/allwinner,sun8i-a23-rsb.yaml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/bus/allwinner,sun8i-a23-rsb.yaml b/Documentation/devicetree/bindings/bus/allwinner,sun8i-a23-rsb.yaml index 32d33b983d66..3d719f468a5b 100644 --- a/Documentation/devicetree/bindings/bus/allwinner,sun8i-a23-rsb.yaml +++ b/Documentation/devicetree/bindings/bus/allwinner,sun8i-a23-rsb.yaml @@ -21,7 +21,9 @@ properties: oneOf: - const: allwinner,sun8i-a23-rsb - items: - - const: allwinner,sun8i-a83t-rsb + - enum: + - allwinner,sun8i-a83t-rsb + - allwinner,sun50i-h616-rsb - const: allwinner,sun8i-a23-rsb reg: -- cgit v1.2.3 From fc672d806bd77eff26117479e90ccdcfd2a8ecb4 Mon Sep 17 00:00:00 2001 From: Heiko Stuebner Date: Thu, 21 Jan 2021 15:44:06 +0100 Subject: media: rockchip: rkisp1: carry ip version information The IP block evolved from its rk3288/rk3399 base and the vendor designates them with a numerical version. rk3399 for example is designated V10 probably meaning V1.0. There doesn't seem to be an actual version register we could read that information from, so allow the match_data to carry that information for future differentiation. Also carry that information in the hw_revision field of the media- controller API, so that userspace also has access to that. The added versions are: - V10: at least rk3288 + rk3399 - V11: seemingly unused as of now, but probably appeared in some soc - V12: at least rk3326 + px30 - V13: at least rk1808 [fix checkpatch warning don't use multiple blank lines] Signed-off-by: Heiko Stuebner Signed-off-by: Dafna Hirschfeld Reviewed-by: Ezequiel Garcia Acked-by: Helen Koike Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- Documentation/admin-guide/media/rkisp1.rst | 16 ++++++++++++++++ drivers/media/platform/rockchip/rkisp1/rkisp1-dev.c | 21 ++++++++++++--------- include/uapi/linux/rkisp1-config.h | 15 +++++++++++++++ 3 files changed, 43 insertions(+), 9 deletions(-) (limited to 'Documentation') diff --git a/Documentation/admin-guide/media/rkisp1.rst b/Documentation/admin-guide/media/rkisp1.rst index 2267e4fb475e..ccf418713623 100644 --- a/Documentation/admin-guide/media/rkisp1.rst +++ b/Documentation/admin-guide/media/rkisp1.rst @@ -13,6 +13,22 @@ This file documents the driver for the Rockchip ISP1 that is part of RK3288 and RK3399 SoCs. The driver is located under drivers/staging/media/rkisp1 and uses the Media-Controller API. +Revisions +========= + +There exist multiple smaller revisions to this ISP that got introduced in +later SoCs. Revisions can be found in the enum :c:type:`rkisp1_cif_isp_version` +in the UAPI and the revision of the ISP inside the running SoC can be read +in the field hw_revision of struct media_device_info as returned by +ioctl MEDIA_IOC_DEVICE_INFO. + +Versions in use are: + +- RKISP1_V10: used at least in rk3288 and rk3399 +- RKISP1_V11: declared in the original vendor code, but not used +- RKISP1_V12: used at least in rk3326 and px30 +- RKISP1_V13: used at least in rk1808 + Topology ======== .. _rkisp1_topology_graph: diff --git a/drivers/media/platform/rockchip/rkisp1/rkisp1-dev.c b/drivers/media/platform/rockchip/rkisp1/rkisp1-dev.c index 68da1eed753d..f7e9fd305548 100644 --- a/drivers/media/platform/rockchip/rkisp1/rkisp1-dev.c +++ b/drivers/media/platform/rockchip/rkisp1/rkisp1-dev.c @@ -104,6 +104,7 @@ struct rkisp1_match_data { const char * const *clks; unsigned int size; + enum rkisp1_cif_isp_version isp_ver; }; /* ---------------------------------------------------------------------------- @@ -411,15 +412,16 @@ static const char * const rk3399_isp_clks[] = { "hclk", }; -static const struct rkisp1_match_data rk3399_isp_clk_data = { +static const struct rkisp1_match_data rk3399_isp_match_data = { .clks = rk3399_isp_clks, .size = ARRAY_SIZE(rk3399_isp_clks), + .isp_ver = RKISP1_V10, }; static const struct of_device_id rkisp1_of_match[] = { { .compatible = "rockchip,rk3399-cif-isp", - .data = &rk3399_isp_clk_data, + .data = &rk3399_isp_match_data, }, {}, }; @@ -457,15 +459,15 @@ static void rkisp1_debug_init(struct rkisp1_device *rkisp1) static int rkisp1_probe(struct platform_device *pdev) { - const struct rkisp1_match_data *clk_data; + const struct rkisp1_match_data *match_data; struct device *dev = &pdev->dev; struct rkisp1_device *rkisp1; struct v4l2_device *v4l2_dev; unsigned int i; int ret, irq; - clk_data = of_device_get_match_data(&pdev->dev); - if (!clk_data) + match_data = of_device_get_match_data(&pdev->dev); + if (!match_data) return -ENODEV; rkisp1 = devm_kzalloc(dev, sizeof(*rkisp1), GFP_KERNEL); @@ -494,15 +496,16 @@ static int rkisp1_probe(struct platform_device *pdev) rkisp1->irq = irq; - for (i = 0; i < clk_data->size; i++) - rkisp1->clks[i].id = clk_data->clks[i]; - ret = devm_clk_bulk_get(dev, clk_data->size, rkisp1->clks); + for (i = 0; i < match_data->size; i++) + rkisp1->clks[i].id = match_data->clks[i]; + ret = devm_clk_bulk_get(dev, match_data->size, rkisp1->clks); if (ret) return ret; - rkisp1->clk_size = clk_data->size; + rkisp1->clk_size = match_data->size; pm_runtime_enable(&pdev->dev); + rkisp1->media_dev.hw_revision = match_data->isp_ver; strscpy(rkisp1->media_dev.model, RKISP1_DRIVER_NAME, sizeof(rkisp1->media_dev.model)); rkisp1->media_dev.dev = &pdev->dev; diff --git a/include/uapi/linux/rkisp1-config.h b/include/uapi/linux/rkisp1-config.h index 35aa82d5f6dd..bee4413fe0d3 100644 --- a/include/uapi/linux/rkisp1-config.h +++ b/include/uapi/linux/rkisp1-config.h @@ -123,6 +123,21 @@ #define RKISP1_CIF_ISP_STAT_AFM (1U << 2) #define RKISP1_CIF_ISP_STAT_HIST (1U << 3) +/** + * enum rkisp1_cif_isp_version - ISP variants + * + * @RKISP1_V10: used at least in rk3288 and rk3399 + * @RKISP1_V11: declared in the original vendor code, but not used + * @RKISP1_V12: used at least in rk3326 and px30 + * @RKISP1_V13: used at least in rk1808 + */ +enum rkisp1_cif_isp_version { + RKISP1_V10 = 10, + RKISP1_V11, + RKISP1_V12, + RKISP1_V13, +}; + enum rkisp1_cif_isp_histogram_mode { RKISP1_CIF_ISP_HISTOGRAM_MODE_DISABLE, RKISP1_CIF_ISP_HISTOGRAM_MODE_RGB_COMBINED, -- cgit v1.2.3 From ae000861b95cc4521c498430eb9c61ad62cea51c Mon Sep 17 00:00:00 2001 From: Yu Zhang Date: Thu, 28 Jan 2021 23:47:47 +0800 Subject: KVM: Documentation: Fix documentation for nested. Nested VMX was enabled by default in commit 1e58e5e59148 ("KVM: VMX: enable nested virtualization by default"), which was merged in Linux 4.20. This patch is to fix the documentation accordingly. Signed-off-by: Yu Zhang Message-Id: <20210128154747.4242-1-yu.c.zhang@linux.intel.com> Signed-off-by: Paolo Bonzini --- Documentation/virt/kvm/nested-vmx.rst | 6 ++++-- Documentation/virt/kvm/running-nested-guests.rst | 2 +- 2 files changed, 5 insertions(+), 3 deletions(-) (limited to 'Documentation') diff --git a/Documentation/virt/kvm/nested-vmx.rst b/Documentation/virt/kvm/nested-vmx.rst index 6ab4e35cee23..ac2095d41f02 100644 --- a/Documentation/virt/kvm/nested-vmx.rst +++ b/Documentation/virt/kvm/nested-vmx.rst @@ -37,8 +37,10 @@ call L2. Running nested VMX ------------------ -The nested VMX feature is disabled by default. It can be enabled by giving -the "nested=1" option to the kvm-intel module. +The nested VMX feature is enabled by default since Linux kernel v4.20. For +older Linux kernel, it can be enabled by giving the "nested=1" option to the +kvm-intel module. + No modifications are required to user space (qemu). However, qemu's default emulated CPU type (qemu64) does not list the "VMX" CPU feature, so it must be diff --git a/Documentation/virt/kvm/running-nested-guests.rst b/Documentation/virt/kvm/running-nested-guests.rst index d0a1fc754c84..bd70c69468ae 100644 --- a/Documentation/virt/kvm/running-nested-guests.rst +++ b/Documentation/virt/kvm/running-nested-guests.rst @@ -74,7 +74,7 @@ few: Enabling "nested" (x86) ----------------------- -From Linux kernel v4.19 onwards, the ``nested`` KVM parameter is enabled +From Linux kernel v4.20 onwards, the ``nested`` KVM parameter is enabled by default for Intel and AMD. (Though your Linux distribution might override this default.) -- cgit v1.2.3 From 79d7c3dca99fa96033695ddf5d495b775a3a137b Mon Sep 17 00:00:00 2001 From: Robin Murphy Date: Thu, 28 Jan 2021 13:12:43 +0000 Subject: perf/arm-cmn: Fix PMU instance naming Although it's neat to avoid the suffix for the typical case of a single PMU, it means systems with multiple CMN instances end up with inconsistent naming. I think it also breaks perf tool's "uncore alias" logic if the common instance prefix is also the full name of one. Avoid any surprises by not trying to be clever and simply numbering every instance, even when it might technically prove redundant. Fixes: 0ba64770a2f2 ("perf: Add Arm CMN-600 PMU driver") Signed-off-by: Robin Murphy Link: https://lore.kernel.org/r/649a2281233f193d59240b13ed91b57337c77b32.1611839564.git.robin.murphy@arm.com Signed-off-by: Will Deacon --- Documentation/admin-guide/perf/arm-cmn.rst | 2 +- drivers/perf/arm-cmn.c | 13 ++++--------- 2 files changed, 5 insertions(+), 10 deletions(-) (limited to 'Documentation') diff --git a/Documentation/admin-guide/perf/arm-cmn.rst b/Documentation/admin-guide/perf/arm-cmn.rst index 0e4809346014..796e25b7027b 100644 --- a/Documentation/admin-guide/perf/arm-cmn.rst +++ b/Documentation/admin-guide/perf/arm-cmn.rst @@ -17,7 +17,7 @@ PMU events ---------- The PMU driver registers a single PMU device for the whole interconnect, -see /sys/bus/event_source/devices/arm_cmn. Multi-chip systems may link +see /sys/bus/event_source/devices/arm_cmn_0. Multi-chip systems may link more than one CMN together via external CCIX links - in this situation, each mesh counts its own events entirely independently, and additional PMU devices will be named arm_cmn_{1..n}. diff --git a/drivers/perf/arm-cmn.c b/drivers/perf/arm-cmn.c index f30fcd330899..6bdf13f65875 100644 --- a/drivers/perf/arm-cmn.c +++ b/drivers/perf/arm-cmn.c @@ -1502,7 +1502,7 @@ static int arm_cmn_probe(struct platform_device *pdev) struct arm_cmn *cmn; const char *name; static atomic_t id; - int err, rootnode, this_id; + int err, rootnode; cmn = devm_kzalloc(&pdev->dev, sizeof(*cmn), GFP_KERNEL); if (!cmn) @@ -1549,14 +1549,9 @@ static int arm_cmn_probe(struct platform_device *pdev) .cancel_txn = arm_cmn_end_txn, }; - this_id = atomic_fetch_inc(&id); - if (this_id == 0) { - name = "arm_cmn"; - } else { - name = devm_kasprintf(cmn->dev, GFP_KERNEL, "arm_cmn_%d", this_id); - if (!name) - return -ENOMEM; - } + name = devm_kasprintf(cmn->dev, GFP_KERNEL, "arm_cmn_%d", atomic_fetch_inc(&id)); + if (!name) + return -ENOMEM; err = cpuhp_state_add_instance(arm_cmn_hp_state, &cmn->cpuhp_node); if (err) -- cgit v1.2.3 From 187623b1d8b21b6fdab9b963465f71ad47b8c279 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Wed, 27 Jan 2021 11:43:43 +0100 Subject: Documentation: kernel-parameters: add missing '<' Acked-by: Randy Dunlap Signed-off-by: Wolfram Sang Link: https://lore.kernel.org/r/20210127104343.5647-1-wsa+renesas@sang-engineering.com Signed-off-by: Jonathan Corbet --- Documentation/admin-guide/kernel-parameters.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Documentation') diff --git a/Documentation/admin-guide/kernel-parameters.rst b/Documentation/admin-guide/kernel-parameters.rst index 682ab28b5c94..1132796a8d96 100644 --- a/Documentation/admin-guide/kernel-parameters.rst +++ b/Documentation/admin-guide/kernel-parameters.rst @@ -60,7 +60,7 @@ Note that for the special case of a range one can split the range into equal sized groups and for each group use some amount from the beginning of that group: - -cpu number>:/ + -:/ For example one can add to the command line following parameter: -- cgit v1.2.3 From bcadb65fd64889cc3cf1ca4b8025d91b59ec1b02 Mon Sep 17 00:00:00 2001 From: Cao jin Date: Wed, 27 Jan 2021 16:49:11 +0800 Subject: Documentation/x86/boot.rst: Correct the example of SETUP_INDIRECT struct setup_data.len is the length of data field. In case of SETUP_INDIRECT, it should be sizeof(setup_indirect). Signed-off-by: Cao jin Reviewed-by: Daniel Kiper Link: https://lore.kernel.org/r/20210127084911.63438-1-jojing64@gmail.com Signed-off-by: Jonathan Corbet --- Documentation/x86/boot.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Documentation') diff --git a/Documentation/x86/boot.rst b/Documentation/x86/boot.rst index abb9fc164657..fc844913dece 100644 --- a/Documentation/x86/boot.rst +++ b/Documentation/x86/boot.rst @@ -851,7 +851,7 @@ Protocol: 2.09+ struct setup_data { __u64 next = 0 or ; __u32 type = SETUP_INDIRECT; - __u32 len = sizeof(setup_data); + __u32 len = sizeof(setup_indirect); __u8 data[sizeof(setup_indirect)] = struct setup_indirect { __u32 type = SETUP_INDIRECT | SETUP_E820_EXT; __u32 reserved = 0; -- cgit v1.2.3 From dde0dc3a8e6770e79fa05fdf3d0d9f679d245cc7 Mon Sep 17 00:00:00 2001 From: Pali Rohár Date: Thu, 21 Jan 2021 20:34:17 +0100 Subject: Documentation: arm: Fix marvell file name MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes: dc7a12bdfccd ("docs: arm: convert docs to ReST and rename to *.rst") Signed-off-by: Pali Rohár Reviewed-by: Andrew Lunn Link: https://lore.kernel.org/r/20210121193418.22678-1-pali@kernel.org Signed-off-by: Jonathan Corbet --- Documentation/arm/index.rst | 2 +- Documentation/arm/marvel.rst | 488 ------------------------------------------ Documentation/arm/marvell.rst | 488 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 489 insertions(+), 489 deletions(-) delete mode 100644 Documentation/arm/marvel.rst create mode 100644 Documentation/arm/marvell.rst (limited to 'Documentation') diff --git a/Documentation/arm/index.rst b/Documentation/arm/index.rst index a2e9e1bba7b9..b4bea32472b6 100644 --- a/Documentation/arm/index.rst +++ b/Documentation/arm/index.rst @@ -33,7 +33,7 @@ SoC-specific documents ixp4xx - marvel + marvell microchip netwinder diff --git a/Documentation/arm/marvel.rst b/Documentation/arm/marvel.rst deleted file mode 100644 index 16ab2eb085b8..000000000000 --- a/Documentation/arm/marvel.rst +++ /dev/null @@ -1,488 +0,0 @@ -================ -ARM Marvell SoCs -================ - -This document lists all the ARM Marvell SoCs that are currently -supported in mainline by the Linux kernel. As the Marvell families of -SoCs are large and complex, it is hard to understand where the support -for a particular SoC is available in the Linux kernel. This document -tries to help in understanding where those SoCs are supported, and to -match them with their corresponding public datasheet, when available. - -Orion family ------------- - - Flavors: - - 88F5082 - - 88F5181 - - 88F5181L - - 88F5182 - - - Datasheet: http://www.embeddedarm.com/documentation/third-party/MV88F5182-datasheet.pdf - - Programmer's User Guide: http://www.embeddedarm.com/documentation/third-party/MV88F5182-opensource-manual.pdf - - User Manual: http://www.embeddedarm.com/documentation/third-party/MV88F5182-usermanual.pdf - - 88F5281 - - - Datasheet: http://www.ocmodshop.com/images/reviews/networking/qnap_ts409u/marvel_88f5281_data_sheet.pdf - - 88F6183 - Core: - Feroceon 88fr331 (88f51xx) or 88fr531-vd (88f52xx) ARMv5 compatible - Linux kernel mach directory: - arch/arm/mach-orion5x - Linux kernel plat directory: - arch/arm/plat-orion - -Kirkwood family ---------------- - - Flavors: - - 88F6282 a.k.a Armada 300 - - - Product Brief : http://www.marvell.com/embedded-processors/armada-300/assets/armada_310.pdf - - 88F6283 a.k.a Armada 310 - - - Product Brief : http://www.marvell.com/embedded-processors/armada-300/assets/armada_310.pdf - - 88F6190 - - - Product Brief : http://www.marvell.com/embedded-processors/kirkwood/assets/88F6190-003_WEB.pdf - - Hardware Spec : http://www.marvell.com/embedded-processors/kirkwood/assets/HW_88F619x_OpenSource.pdf - - Functional Spec: http://www.marvell.com/embedded-processors/kirkwood/assets/FS_88F6180_9x_6281_OpenSource.pdf - - 88F6192 - - - Product Brief : http://www.marvell.com/embedded-processors/kirkwood/assets/88F6192-003_ver1.pdf - - Hardware Spec : http://www.marvell.com/embedded-processors/kirkwood/assets/HW_88F619x_OpenSource.pdf - - Functional Spec: http://www.marvell.com/embedded-processors/kirkwood/assets/FS_88F6180_9x_6281_OpenSource.pdf - - 88F6182 - - 88F6180 - - - Product Brief : http://www.marvell.com/embedded-processors/kirkwood/assets/88F6180-003_ver1.pdf - - Hardware Spec : http://www.marvell.com/embedded-processors/kirkwood/assets/HW_88F6180_OpenSource.pdf - - Functional Spec: http://www.marvell.com/embedded-processors/kirkwood/assets/FS_88F6180_9x_6281_OpenSource.pdf - - 88F6281 - - - Product Brief : http://www.marvell.com/embedded-processors/kirkwood/assets/88F6281-004_ver1.pdf - - Hardware Spec : http://www.marvell.com/embedded-processors/kirkwood/assets/HW_88F6281_OpenSource.pdf - - Functional Spec: http://www.marvell.com/embedded-processors/kirkwood/assets/FS_88F6180_9x_6281_OpenSource.pdf - Homepage: - http://www.marvell.com/embedded-processors/kirkwood/ - Core: - Feroceon 88fr131 ARMv5 compatible - Linux kernel mach directory: - arch/arm/mach-mvebu - Linux kernel plat directory: - none - -Discovery family ----------------- - - Flavors: - - MV78100 - - - Product Brief : http://www.marvell.com/embedded-processors/discovery-innovation/assets/MV78100-003_WEB.pdf - - Hardware Spec : http://www.marvell.com/embedded-processors/discovery-innovation/assets/HW_MV78100_OpenSource.pdf - - Functional Spec: http://www.marvell.com/embedded-processors/discovery-innovation/assets/FS_MV76100_78100_78200_OpenSource.pdf - - MV78200 - - - Product Brief : http://www.marvell.com/embedded-processors/discovery-innovation/assets/MV78200-002_WEB.pdf - - Hardware Spec : http://www.marvell.com/embedded-processors/discovery-innovation/assets/HW_MV78200_OpenSource.pdf - - Functional Spec: http://www.marvell.com/embedded-processors/discovery-innovation/assets/FS_MV76100_78100_78200_OpenSource.pdf - - MV76100 - - Not supported by the Linux kernel. - - Core: - Feroceon 88fr571-vd ARMv5 compatible - - Linux kernel mach directory: - arch/arm/mach-mv78xx0 - Linux kernel plat directory: - arch/arm/plat-orion - -EBU Armada family ------------------ - - Armada 370 Flavors: - - 88F6710 - - 88F6707 - - 88F6W11 - - - Product Brief: http://www.marvell.com/embedded-processors/armada-300/assets/Marvell_ARMADA_370_SoC.pdf - - Hardware Spec: http://www.marvell.com/embedded-processors/armada-300/assets/ARMADA370-datasheet.pdf - - Functional Spec: http://www.marvell.com/embedded-processors/armada-300/assets/ARMADA370-FunctionalSpec-datasheet.pdf - - Core: - Sheeva ARMv7 compatible PJ4B - - Armada 375 Flavors: - - 88F6720 - - - Product Brief: http://www.marvell.com/embedded-processors/armada-300/assets/ARMADA_375_SoC-01_product_brief.pdf - - Core: - ARM Cortex-A9 - - Armada 38x Flavors: - - 88F6810 Armada 380 - - 88F6820 Armada 385 - - 88F6828 Armada 388 - - - Product infos: http://www.marvell.com/embedded-processors/armada-38x/ - - Functional Spec: https://marvellcorp.wufoo.com/forms/marvell-armada-38x-functional-specifications/ - - Core: - ARM Cortex-A9 - - Armada 39x Flavors: - - 88F6920 Armada 390 - - 88F6928 Armada 398 - - - Product infos: http://www.marvell.com/embedded-processors/armada-39x/ - - Core: - ARM Cortex-A9 - - Armada XP Flavors: - - MV78230 - - MV78260 - - MV78460 - - NOTE: - not to be confused with the non-SMP 78xx0 SoCs - - Product Brief: - http://www.marvell.com/embedded-processors/armada-xp/assets/Marvell-ArmadaXP-SoC-product%20brief.pdf - - Functional Spec: - http://www.marvell.com/embedded-processors/armada-xp/assets/ARMADA-XP-Functional-SpecDatasheet.pdf - - - Hardware Specs: - - - http://www.marvell.com/embedded-processors/armada-xp/assets/HW_MV78230_OS.PDF - - http://www.marvell.com/embedded-processors/armada-xp/assets/HW_MV78260_OS.PDF - - http://www.marvell.com/embedded-processors/armada-xp/assets/HW_MV78460_OS.PDF - - Core: - Sheeva ARMv7 compatible Dual-core or Quad-core PJ4B-MP - - Linux kernel mach directory: - arch/arm/mach-mvebu - Linux kernel plat directory: - none - -EBU Armada family ARMv8 ------------------------ - - Armada 3710/3720 Flavors: - - 88F3710 - - 88F3720 - - Core: - ARM Cortex A53 (ARMv8) - - Homepage: - http://www.marvell.com/embedded-processors/armada-3700/ - - Product Brief: - http://www.marvell.com/embedded-processors/assets/PB-88F3700-FNL.pdf - - Device tree files: - arch/arm64/boot/dts/marvell/armada-37* - - Armada 7K Flavors: - - 88F7020 (AP806 Dual + one CP110) - - 88F7040 (AP806 Quad + one CP110) - - Core: ARM Cortex A72 - - Homepage: - http://www.marvell.com/embedded-processors/armada-70xx/ - - Product Brief: - - http://www.marvell.com/embedded-processors/assets/Armada7020PB-Jan2016.pdf - - http://www.marvell.com/embedded-processors/assets/Armada7040PB-Jan2016.pdf - - Device tree files: - arch/arm64/boot/dts/marvell/armada-70* - - Armada 8K Flavors: - - 88F8020 (AP806 Dual + two CP110) - - 88F8040 (AP806 Quad + two CP110) - Core: - ARM Cortex A72 - - Homepage: - http://www.marvell.com/embedded-processors/armada-80xx/ - - Product Brief: - - http://www.marvell.com/embedded-processors/assets/Armada8020PB-Jan2016.pdf - - http://www.marvell.com/embedded-processors/assets/Armada8040PB-Jan2016.pdf - - Device tree files: - arch/arm64/boot/dts/marvell/armada-80* - -Avanta family -------------- - - Flavors: - - 88F6510 - - 88F6530P - - 88F6550 - - 88F6560 - - Homepage: - http://www.marvell.com/broadband/ - - Product Brief: - http://www.marvell.com/broadband/assets/Marvell_Avanta_88F6510_305_060-001_product_brief.pdf - - No public datasheet available. - - Core: - ARMv5 compatible - - Linux kernel mach directory: - no code in mainline yet, planned for the future - Linux kernel plat directory: - no code in mainline yet, planned for the future - -Storage family --------------- - - Armada SP: - - 88RC1580 - - Product infos: - http://www.marvell.com/storage/armada-sp/ - - Core: - Sheeva ARMv7 comatible Quad-core PJ4C - - (not supported in upstream Linux kernel) - -Dove family (application processor) ------------------------------------ - - Flavors: - - 88AP510 a.k.a Armada 510 - - Product Brief: - http://www.marvell.com/application-processors/armada-500/assets/Marvell_Armada510_SoC.pdf - - Hardware Spec: - http://www.marvell.com/application-processors/armada-500/assets/Armada-510-Hardware-Spec.pdf - - Functional Spec: - http://www.marvell.com/application-processors/armada-500/assets/Armada-510-Functional-Spec.pdf - - Homepage: - http://www.marvell.com/application-processors/armada-500/ - - Core: - ARMv7 compatible - - Directory: - - arch/arm/mach-mvebu (DT enabled platforms) - - arch/arm/mach-dove (non-DT enabled platforms) - -PXA 2xx/3xx/93x/95x family --------------------------- - - Flavors: - - PXA21x, PXA25x, PXA26x - - Application processor only - - Core: ARMv5 XScale1 core - - PXA270, PXA271, PXA272 - - Product Brief : http://www.marvell.com/application-processors/pxa-family/assets/pxa_27x_pb.pdf - - Design guide : http://www.marvell.com/application-processors/pxa-family/assets/pxa_27x_design_guide.pdf - - Developers manual : http://www.marvell.com/application-processors/pxa-family/assets/pxa_27x_dev_man.pdf - - Specification : http://www.marvell.com/application-processors/pxa-family/assets/pxa_27x_emts.pdf - - Specification update : http://www.marvell.com/application-processors/pxa-family/assets/pxa_27x_spec_update.pdf - - Application processor only - - Core: ARMv5 XScale2 core - - PXA300, PXA310, PXA320 - - PXA 300 Product Brief : http://www.marvell.com/application-processors/pxa-family/assets/PXA300_PB_R4.pdf - - PXA 310 Product Brief : http://www.marvell.com/application-processors/pxa-family/assets/PXA310_PB_R4.pdf - - PXA 320 Product Brief : http://www.marvell.com/application-processors/pxa-family/assets/PXA320_PB_R4.pdf - - Design guide : http://www.marvell.com/application-processors/pxa-family/assets/PXA3xx_Design_Guide.pdf - - Developers manual : http://www.marvell.com/application-processors/pxa-family/assets/PXA3xx_Developers_Manual.zip - - Specifications : http://www.marvell.com/application-processors/pxa-family/assets/PXA3xx_EMTS.pdf - - Specification Update : http://www.marvell.com/application-processors/pxa-family/assets/PXA3xx_Spec_Update.zip - - Reference Manual : http://www.marvell.com/application-processors/pxa-family/assets/PXA3xx_TavorP_BootROM_Ref_Manual.pdf - - Application processor only - - Core: ARMv5 XScale3 core - - PXA930, PXA935 - - Application processor with Communication processor - - Core: ARMv5 XScale3 core - - PXA955 - - Application processor with Communication processor - - Core: ARMv7 compatible Sheeva PJ4 core - - Comments: - - * This line of SoCs originates from the XScale family developed by - Intel and acquired by Marvell in ~2006. The PXA21x, PXA25x, - PXA26x, PXA27x, PXA3xx and PXA93x were developed by Intel, while - the later PXA95x were developed by Marvell. - - * Due to their XScale origin, these SoCs have virtually nothing in - common with the other (Kirkwood, Dove, etc.) families of Marvell - SoCs, except with the MMP/MMP2 family of SoCs. - - Linux kernel mach directory: - arch/arm/mach-pxa - Linux kernel plat directory: - arch/arm/plat-pxa - -MMP/MMP2/MMP3 family (communication processor) ----------------------------------------------- - - Flavors: - - PXA168, a.k.a Armada 168 - - Homepage : http://www.marvell.com/application-processors/armada-100/armada-168.jsp - - Product brief : http://www.marvell.com/application-processors/armada-100/assets/pxa_168_pb.pdf - - Hardware manual : http://www.marvell.com/application-processors/armada-100/assets/armada_16x_datasheet.pdf - - Software manual : http://www.marvell.com/application-processors/armada-100/assets/armada_16x_software_manual.pdf - - Specification update : http://www.marvell.com/application-processors/armada-100/assets/ARMADA16x_Spec_update.pdf - - Boot ROM manual : http://www.marvell.com/application-processors/armada-100/assets/armada_16x_ref_manual.pdf - - App node package : http://www.marvell.com/application-processors/armada-100/assets/armada_16x_app_note_package.pdf - - Application processor only - - Core: ARMv5 compatible Marvell PJ1 88sv331 (Mohawk) - - PXA910/PXA920 - - Homepage : http://www.marvell.com/communication-processors/pxa910/ - - Product Brief : http://www.marvell.com/communication-processors/pxa910/assets/Marvell_PXA910_Platform-001_PB_final.pdf - - Application processor with Communication processor - - Core: ARMv5 compatible Marvell PJ1 88sv331 (Mohawk) - - PXA688, a.k.a. MMP2, a.k.a Armada 610 - - Product Brief : http://www.marvell.com/application-processors/armada-600/assets/armada610_pb.pdf - - Application processor only - - Core: ARMv7 compatible Sheeva PJ4 88sv581x core - - PXA2128, a.k.a. MMP3 (OLPC XO4, Linux support not upstream) - - Product Brief : http://www.marvell.com/application-processors/armada/pxa2128/assets/Marvell-ARMADA-PXA2128-SoC-PB.pdf - - Application processor only - - Core: Dual-core ARMv7 compatible Sheeva PJ4C core - - PXA960/PXA968/PXA978 (Linux support not upstream) - - Application processor with Communication Processor - - Core: ARMv7 compatible Sheeva PJ4 core - - PXA986/PXA988 (Linux support not upstream) - - Application processor with Communication Processor - - Core: Dual-core ARMv7 compatible Sheeva PJ4B-MP core - - PXA1088/PXA1920 (Linux support not upstream) - - Application processor with Communication Processor - - Core: quad-core ARMv7 Cortex-A7 - - PXA1908/PXA1928/PXA1936 - - Application processor with Communication Processor - - Core: multi-core ARMv8 Cortex-A53 - - Comments: - - * This line of SoCs originates from the XScale family developed by - Intel and acquired by Marvell in ~2006. All the processors of - this MMP/MMP2 family were developed by Marvell. - - * Due to their XScale origin, these SoCs have virtually nothing in - common with the other (Kirkwood, Dove, etc.) families of Marvell - SoCs, except with the PXA family of SoCs listed above. - - Linux kernel mach directory: - arch/arm/mach-mmp - Linux kernel plat directory: - arch/arm/plat-pxa - -Berlin family (Multimedia Solutions) -------------------------------------- - - - Flavors: - - 88DE3010, Armada 1000 (no Linux support) - - Core: Marvell PJ1 (ARMv5TE), Dual-core - - Product Brief: http://www.marvell.com.cn/digital-entertainment/assets/armada_1000_pb.pdf - - 88DE3005, Armada 1500 Mini - - Design name: BG2CD - - Core: ARM Cortex-A9, PL310 L2CC - - 88DE3006, Armada 1500 Mini Plus - - Design name: BG2CDP - - Core: Dual Core ARM Cortex-A7 - - 88DE3100, Armada 1500 - - Design name: BG2 - - Core: Marvell PJ4B-MP (ARMv7), Tauros3 L2CC - - 88DE3114, Armada 1500 Pro - - Design name: BG2Q - - Core: Quad Core ARM Cortex-A9, PL310 L2CC - - 88DE3214, Armada 1500 Pro 4K - - Design name: BG3 - - Core: ARM Cortex-A15, CA15 integrated L2CC - - 88DE3218, ARMADA 1500 Ultra - - Core: ARM Cortex-A53 - - Homepage: https://www.synaptics.com/products/multimedia-solutions - Directory: arch/arm/mach-berlin - - Comments: - - * This line of SoCs is based on Marvell Sheeva or ARM Cortex CPUs - with Synopsys DesignWare (IRQ, GPIO, Timers, ...) and PXA IP (SDHCI, USB, ETH, ...). - - * The Berlin family was acquired by Synaptics from Marvell in 2017. - -CPU Cores ---------- - -The XScale cores were designed by Intel, and shipped by Marvell in the older -PXA processors. Feroceon is a Marvell designed core that developed in-house, -and that evolved into Sheeva. The XScale and Feroceon cores were phased out -over time and replaced with Sheeva cores in later products, which subsequently -got replaced with licensed ARM Cortex-A cores. - - XScale 1 - CPUID 0x69052xxx - ARMv5, iWMMXt - XScale 2 - CPUID 0x69054xxx - ARMv5, iWMMXt - XScale 3 - CPUID 0x69056xxx or 0x69056xxx - ARMv5, iWMMXt - Feroceon-1850 88fr331 "Mohawk" - CPUID 0x5615331x or 0x41xx926x - ARMv5TE, single issue - Feroceon-2850 88fr531-vd "Jolteon" - CPUID 0x5605531x or 0x41xx926x - ARMv5TE, VFP, dual-issue - Feroceon 88fr571-vd "Jolteon" - CPUID 0x5615571x - ARMv5TE, VFP, dual-issue - Feroceon 88fr131 "Mohawk-D" - CPUID 0x5625131x - ARMv5TE, single-issue in-order - Sheeva PJ1 88sv331 "Mohawk" - CPUID 0x561584xx - ARMv5, single-issue iWMMXt v2 - Sheeva PJ4 88sv581x "Flareon" - CPUID 0x560f581x - ARMv7, idivt, optional iWMMXt v2 - Sheeva PJ4B 88sv581x - CPUID 0x561f581x - ARMv7, idivt, optional iWMMXt v2 - Sheeva PJ4B-MP / PJ4C - CPUID 0x562f584x - ARMv7, idivt/idiva, LPAE, optional iWMMXt v2 and/or NEON - -Long-term plans ---------------- - - * Unify the mach-dove/, mach-mv78xx0/, mach-orion5x/ into the - mach-mvebu/ to support all SoCs from the Marvell EBU (Engineering - Business Unit) in a single mach- directory. The plat-orion/ - would therefore disappear. - - * Unify the mach-mmp/ and mach-pxa/ into the same mach-pxa - directory. The plat-pxa/ would therefore disappear. - -Credits -------- - -- Maen Suleiman -- Lior Amsalem -- Thomas Petazzoni -- Andrew Lunn -- Nicolas Pitre -- Eric Miao diff --git a/Documentation/arm/marvell.rst b/Documentation/arm/marvell.rst new file mode 100644 index 000000000000..16ab2eb085b8 --- /dev/null +++ b/Documentation/arm/marvell.rst @@ -0,0 +1,488 @@ +================ +ARM Marvell SoCs +================ + +This document lists all the ARM Marvell SoCs that are currently +supported in mainline by the Linux kernel. As the Marvell families of +SoCs are large and complex, it is hard to understand where the support +for a particular SoC is available in the Linux kernel. This document +tries to help in understanding where those SoCs are supported, and to +match them with their corresponding public datasheet, when available. + +Orion family +------------ + + Flavors: + - 88F5082 + - 88F5181 + - 88F5181L + - 88F5182 + + - Datasheet: http://www.embeddedarm.com/documentation/third-party/MV88F5182-datasheet.pdf + - Programmer's User Guide: http://www.embeddedarm.com/documentation/third-party/MV88F5182-opensource-manual.pdf + - User Manual: http://www.embeddedarm.com/documentation/third-party/MV88F5182-usermanual.pdf + - 88F5281 + + - Datasheet: http://www.ocmodshop.com/images/reviews/networking/qnap_ts409u/marvel_88f5281_data_sheet.pdf + - 88F6183 + Core: + Feroceon 88fr331 (88f51xx) or 88fr531-vd (88f52xx) ARMv5 compatible + Linux kernel mach directory: + arch/arm/mach-orion5x + Linux kernel plat directory: + arch/arm/plat-orion + +Kirkwood family +--------------- + + Flavors: + - 88F6282 a.k.a Armada 300 + + - Product Brief : http://www.marvell.com/embedded-processors/armada-300/assets/armada_310.pdf + - 88F6283 a.k.a Armada 310 + + - Product Brief : http://www.marvell.com/embedded-processors/armada-300/assets/armada_310.pdf + - 88F6190 + + - Product Brief : http://www.marvell.com/embedded-processors/kirkwood/assets/88F6190-003_WEB.pdf + - Hardware Spec : http://www.marvell.com/embedded-processors/kirkwood/assets/HW_88F619x_OpenSource.pdf + - Functional Spec: http://www.marvell.com/embedded-processors/kirkwood/assets/FS_88F6180_9x_6281_OpenSource.pdf + - 88F6192 + + - Product Brief : http://www.marvell.com/embedded-processors/kirkwood/assets/88F6192-003_ver1.pdf + - Hardware Spec : http://www.marvell.com/embedded-processors/kirkwood/assets/HW_88F619x_OpenSource.pdf + - Functional Spec: http://www.marvell.com/embedded-processors/kirkwood/assets/FS_88F6180_9x_6281_OpenSource.pdf + - 88F6182 + - 88F6180 + + - Product Brief : http://www.marvell.com/embedded-processors/kirkwood/assets/88F6180-003_ver1.pdf + - Hardware Spec : http://www.marvell.com/embedded-processors/kirkwood/assets/HW_88F6180_OpenSource.pdf + - Functional Spec: http://www.marvell.com/embedded-processors/kirkwood/assets/FS_88F6180_9x_6281_OpenSource.pdf + - 88F6281 + + - Product Brief : http://www.marvell.com/embedded-processors/kirkwood/assets/88F6281-004_ver1.pdf + - Hardware Spec : http://www.marvell.com/embedded-processors/kirkwood/assets/HW_88F6281_OpenSource.pdf + - Functional Spec: http://www.marvell.com/embedded-processors/kirkwood/assets/FS_88F6180_9x_6281_OpenSource.pdf + Homepage: + http://www.marvell.com/embedded-processors/kirkwood/ + Core: + Feroceon 88fr131 ARMv5 compatible + Linux kernel mach directory: + arch/arm/mach-mvebu + Linux kernel plat directory: + none + +Discovery family +---------------- + + Flavors: + - MV78100 + + - Product Brief : http://www.marvell.com/embedded-processors/discovery-innovation/assets/MV78100-003_WEB.pdf + - Hardware Spec : http://www.marvell.com/embedded-processors/discovery-innovation/assets/HW_MV78100_OpenSource.pdf + - Functional Spec: http://www.marvell.com/embedded-processors/discovery-innovation/assets/FS_MV76100_78100_78200_OpenSource.pdf + - MV78200 + + - Product Brief : http://www.marvell.com/embedded-processors/discovery-innovation/assets/MV78200-002_WEB.pdf + - Hardware Spec : http://www.marvell.com/embedded-processors/discovery-innovation/assets/HW_MV78200_OpenSource.pdf + - Functional Spec: http://www.marvell.com/embedded-processors/discovery-innovation/assets/FS_MV76100_78100_78200_OpenSource.pdf + - MV76100 + + Not supported by the Linux kernel. + + Core: + Feroceon 88fr571-vd ARMv5 compatible + + Linux kernel mach directory: + arch/arm/mach-mv78xx0 + Linux kernel plat directory: + arch/arm/plat-orion + +EBU Armada family +----------------- + + Armada 370 Flavors: + - 88F6710 + - 88F6707 + - 88F6W11 + + - Product Brief: http://www.marvell.com/embedded-processors/armada-300/assets/Marvell_ARMADA_370_SoC.pdf + - Hardware Spec: http://www.marvell.com/embedded-processors/armada-300/assets/ARMADA370-datasheet.pdf + - Functional Spec: http://www.marvell.com/embedded-processors/armada-300/assets/ARMADA370-FunctionalSpec-datasheet.pdf + + Core: + Sheeva ARMv7 compatible PJ4B + + Armada 375 Flavors: + - 88F6720 + + - Product Brief: http://www.marvell.com/embedded-processors/armada-300/assets/ARMADA_375_SoC-01_product_brief.pdf + + Core: + ARM Cortex-A9 + + Armada 38x Flavors: + - 88F6810 Armada 380 + - 88F6820 Armada 385 + - 88F6828 Armada 388 + + - Product infos: http://www.marvell.com/embedded-processors/armada-38x/ + - Functional Spec: https://marvellcorp.wufoo.com/forms/marvell-armada-38x-functional-specifications/ + + Core: + ARM Cortex-A9 + + Armada 39x Flavors: + - 88F6920 Armada 390 + - 88F6928 Armada 398 + + - Product infos: http://www.marvell.com/embedded-processors/armada-39x/ + + Core: + ARM Cortex-A9 + + Armada XP Flavors: + - MV78230 + - MV78260 + - MV78460 + + NOTE: + not to be confused with the non-SMP 78xx0 SoCs + + Product Brief: + http://www.marvell.com/embedded-processors/armada-xp/assets/Marvell-ArmadaXP-SoC-product%20brief.pdf + + Functional Spec: + http://www.marvell.com/embedded-processors/armada-xp/assets/ARMADA-XP-Functional-SpecDatasheet.pdf + + - Hardware Specs: + + - http://www.marvell.com/embedded-processors/armada-xp/assets/HW_MV78230_OS.PDF + - http://www.marvell.com/embedded-processors/armada-xp/assets/HW_MV78260_OS.PDF + - http://www.marvell.com/embedded-processors/armada-xp/assets/HW_MV78460_OS.PDF + + Core: + Sheeva ARMv7 compatible Dual-core or Quad-core PJ4B-MP + + Linux kernel mach directory: + arch/arm/mach-mvebu + Linux kernel plat directory: + none + +EBU Armada family ARMv8 +----------------------- + + Armada 3710/3720 Flavors: + - 88F3710 + - 88F3720 + + Core: + ARM Cortex A53 (ARMv8) + + Homepage: + http://www.marvell.com/embedded-processors/armada-3700/ + + Product Brief: + http://www.marvell.com/embedded-processors/assets/PB-88F3700-FNL.pdf + + Device tree files: + arch/arm64/boot/dts/marvell/armada-37* + + Armada 7K Flavors: + - 88F7020 (AP806 Dual + one CP110) + - 88F7040 (AP806 Quad + one CP110) + + Core: ARM Cortex A72 + + Homepage: + http://www.marvell.com/embedded-processors/armada-70xx/ + + Product Brief: + - http://www.marvell.com/embedded-processors/assets/Armada7020PB-Jan2016.pdf + - http://www.marvell.com/embedded-processors/assets/Armada7040PB-Jan2016.pdf + + Device tree files: + arch/arm64/boot/dts/marvell/armada-70* + + Armada 8K Flavors: + - 88F8020 (AP806 Dual + two CP110) + - 88F8040 (AP806 Quad + two CP110) + Core: + ARM Cortex A72 + + Homepage: + http://www.marvell.com/embedded-processors/armada-80xx/ + + Product Brief: + - http://www.marvell.com/embedded-processors/assets/Armada8020PB-Jan2016.pdf + - http://www.marvell.com/embedded-processors/assets/Armada8040PB-Jan2016.pdf + + Device tree files: + arch/arm64/boot/dts/marvell/armada-80* + +Avanta family +------------- + + Flavors: + - 88F6510 + - 88F6530P + - 88F6550 + - 88F6560 + + Homepage: + http://www.marvell.com/broadband/ + + Product Brief: + http://www.marvell.com/broadband/assets/Marvell_Avanta_88F6510_305_060-001_product_brief.pdf + + No public datasheet available. + + Core: + ARMv5 compatible + + Linux kernel mach directory: + no code in mainline yet, planned for the future + Linux kernel plat directory: + no code in mainline yet, planned for the future + +Storage family +-------------- + + Armada SP: + - 88RC1580 + + Product infos: + http://www.marvell.com/storage/armada-sp/ + + Core: + Sheeva ARMv7 comatible Quad-core PJ4C + + (not supported in upstream Linux kernel) + +Dove family (application processor) +----------------------------------- + + Flavors: + - 88AP510 a.k.a Armada 510 + + Product Brief: + http://www.marvell.com/application-processors/armada-500/assets/Marvell_Armada510_SoC.pdf + + Hardware Spec: + http://www.marvell.com/application-processors/armada-500/assets/Armada-510-Hardware-Spec.pdf + + Functional Spec: + http://www.marvell.com/application-processors/armada-500/assets/Armada-510-Functional-Spec.pdf + + Homepage: + http://www.marvell.com/application-processors/armada-500/ + + Core: + ARMv7 compatible + + Directory: + - arch/arm/mach-mvebu (DT enabled platforms) + - arch/arm/mach-dove (non-DT enabled platforms) + +PXA 2xx/3xx/93x/95x family +-------------------------- + + Flavors: + - PXA21x, PXA25x, PXA26x + - Application processor only + - Core: ARMv5 XScale1 core + - PXA270, PXA271, PXA272 + - Product Brief : http://www.marvell.com/application-processors/pxa-family/assets/pxa_27x_pb.pdf + - Design guide : http://www.marvell.com/application-processors/pxa-family/assets/pxa_27x_design_guide.pdf + - Developers manual : http://www.marvell.com/application-processors/pxa-family/assets/pxa_27x_dev_man.pdf + - Specification : http://www.marvell.com/application-processors/pxa-family/assets/pxa_27x_emts.pdf + - Specification update : http://www.marvell.com/application-processors/pxa-family/assets/pxa_27x_spec_update.pdf + - Application processor only + - Core: ARMv5 XScale2 core + - PXA300, PXA310, PXA320 + - PXA 300 Product Brief : http://www.marvell.com/application-processors/pxa-family/assets/PXA300_PB_R4.pdf + - PXA 310 Product Brief : http://www.marvell.com/application-processors/pxa-family/assets/PXA310_PB_R4.pdf + - PXA 320 Product Brief : http://www.marvell.com/application-processors/pxa-family/assets/PXA320_PB_R4.pdf + - Design guide : http://www.marvell.com/application-processors/pxa-family/assets/PXA3xx_Design_Guide.pdf + - Developers manual : http://www.marvell.com/application-processors/pxa-family/assets/PXA3xx_Developers_Manual.zip + - Specifications : http://www.marvell.com/application-processors/pxa-family/assets/PXA3xx_EMTS.pdf + - Specification Update : http://www.marvell.com/application-processors/pxa-family/assets/PXA3xx_Spec_Update.zip + - Reference Manual : http://www.marvell.com/application-processors/pxa-family/assets/PXA3xx_TavorP_BootROM_Ref_Manual.pdf + - Application processor only + - Core: ARMv5 XScale3 core + - PXA930, PXA935 + - Application processor with Communication processor + - Core: ARMv5 XScale3 core + - PXA955 + - Application processor with Communication processor + - Core: ARMv7 compatible Sheeva PJ4 core + + Comments: + + * This line of SoCs originates from the XScale family developed by + Intel and acquired by Marvell in ~2006. The PXA21x, PXA25x, + PXA26x, PXA27x, PXA3xx and PXA93x were developed by Intel, while + the later PXA95x were developed by Marvell. + + * Due to their XScale origin, these SoCs have virtually nothing in + common with the other (Kirkwood, Dove, etc.) families of Marvell + SoCs, except with the MMP/MMP2 family of SoCs. + + Linux kernel mach directory: + arch/arm/mach-pxa + Linux kernel plat directory: + arch/arm/plat-pxa + +MMP/MMP2/MMP3 family (communication processor) +---------------------------------------------- + + Flavors: + - PXA168, a.k.a Armada 168 + - Homepage : http://www.marvell.com/application-processors/armada-100/armada-168.jsp + - Product brief : http://www.marvell.com/application-processors/armada-100/assets/pxa_168_pb.pdf + - Hardware manual : http://www.marvell.com/application-processors/armada-100/assets/armada_16x_datasheet.pdf + - Software manual : http://www.marvell.com/application-processors/armada-100/assets/armada_16x_software_manual.pdf + - Specification update : http://www.marvell.com/application-processors/armada-100/assets/ARMADA16x_Spec_update.pdf + - Boot ROM manual : http://www.marvell.com/application-processors/armada-100/assets/armada_16x_ref_manual.pdf + - App node package : http://www.marvell.com/application-processors/armada-100/assets/armada_16x_app_note_package.pdf + - Application processor only + - Core: ARMv5 compatible Marvell PJ1 88sv331 (Mohawk) + - PXA910/PXA920 + - Homepage : http://www.marvell.com/communication-processors/pxa910/ + - Product Brief : http://www.marvell.com/communication-processors/pxa910/assets/Marvell_PXA910_Platform-001_PB_final.pdf + - Application processor with Communication processor + - Core: ARMv5 compatible Marvell PJ1 88sv331 (Mohawk) + - PXA688, a.k.a. MMP2, a.k.a Armada 610 + - Product Brief : http://www.marvell.com/application-processors/armada-600/assets/armada610_pb.pdf + - Application processor only + - Core: ARMv7 compatible Sheeva PJ4 88sv581x core + - PXA2128, a.k.a. MMP3 (OLPC XO4, Linux support not upstream) + - Product Brief : http://www.marvell.com/application-processors/armada/pxa2128/assets/Marvell-ARMADA-PXA2128-SoC-PB.pdf + - Application processor only + - Core: Dual-core ARMv7 compatible Sheeva PJ4C core + - PXA960/PXA968/PXA978 (Linux support not upstream) + - Application processor with Communication Processor + - Core: ARMv7 compatible Sheeva PJ4 core + - PXA986/PXA988 (Linux support not upstream) + - Application processor with Communication Processor + - Core: Dual-core ARMv7 compatible Sheeva PJ4B-MP core + - PXA1088/PXA1920 (Linux support not upstream) + - Application processor with Communication Processor + - Core: quad-core ARMv7 Cortex-A7 + - PXA1908/PXA1928/PXA1936 + - Application processor with Communication Processor + - Core: multi-core ARMv8 Cortex-A53 + + Comments: + + * This line of SoCs originates from the XScale family developed by + Intel and acquired by Marvell in ~2006. All the processors of + this MMP/MMP2 family were developed by Marvell. + + * Due to their XScale origin, these SoCs have virtually nothing in + common with the other (Kirkwood, Dove, etc.) families of Marvell + SoCs, except with the PXA family of SoCs listed above. + + Linux kernel mach directory: + arch/arm/mach-mmp + Linux kernel plat directory: + arch/arm/plat-pxa + +Berlin family (Multimedia Solutions) +------------------------------------- + + - Flavors: + - 88DE3010, Armada 1000 (no Linux support) + - Core: Marvell PJ1 (ARMv5TE), Dual-core + - Product Brief: http://www.marvell.com.cn/digital-entertainment/assets/armada_1000_pb.pdf + - 88DE3005, Armada 1500 Mini + - Design name: BG2CD + - Core: ARM Cortex-A9, PL310 L2CC + - 88DE3006, Armada 1500 Mini Plus + - Design name: BG2CDP + - Core: Dual Core ARM Cortex-A7 + - 88DE3100, Armada 1500 + - Design name: BG2 + - Core: Marvell PJ4B-MP (ARMv7), Tauros3 L2CC + - 88DE3114, Armada 1500 Pro + - Design name: BG2Q + - Core: Quad Core ARM Cortex-A9, PL310 L2CC + - 88DE3214, Armada 1500 Pro 4K + - Design name: BG3 + - Core: ARM Cortex-A15, CA15 integrated L2CC + - 88DE3218, ARMADA 1500 Ultra + - Core: ARM Cortex-A53 + + Homepage: https://www.synaptics.com/products/multimedia-solutions + Directory: arch/arm/mach-berlin + + Comments: + + * This line of SoCs is based on Marvell Sheeva or ARM Cortex CPUs + with Synopsys DesignWare (IRQ, GPIO, Timers, ...) and PXA IP (SDHCI, USB, ETH, ...). + + * The Berlin family was acquired by Synaptics from Marvell in 2017. + +CPU Cores +--------- + +The XScale cores were designed by Intel, and shipped by Marvell in the older +PXA processors. Feroceon is a Marvell designed core that developed in-house, +and that evolved into Sheeva. The XScale and Feroceon cores were phased out +over time and replaced with Sheeva cores in later products, which subsequently +got replaced with licensed ARM Cortex-A cores. + + XScale 1 + CPUID 0x69052xxx + ARMv5, iWMMXt + XScale 2 + CPUID 0x69054xxx + ARMv5, iWMMXt + XScale 3 + CPUID 0x69056xxx or 0x69056xxx + ARMv5, iWMMXt + Feroceon-1850 88fr331 "Mohawk" + CPUID 0x5615331x or 0x41xx926x + ARMv5TE, single issue + Feroceon-2850 88fr531-vd "Jolteon" + CPUID 0x5605531x or 0x41xx926x + ARMv5TE, VFP, dual-issue + Feroceon 88fr571-vd "Jolteon" + CPUID 0x5615571x + ARMv5TE, VFP, dual-issue + Feroceon 88fr131 "Mohawk-D" + CPUID 0x5625131x + ARMv5TE, single-issue in-order + Sheeva PJ1 88sv331 "Mohawk" + CPUID 0x561584xx + ARMv5, single-issue iWMMXt v2 + Sheeva PJ4 88sv581x "Flareon" + CPUID 0x560f581x + ARMv7, idivt, optional iWMMXt v2 + Sheeva PJ4B 88sv581x + CPUID 0x561f581x + ARMv7, idivt, optional iWMMXt v2 + Sheeva PJ4B-MP / PJ4C + CPUID 0x562f584x + ARMv7, idivt/idiva, LPAE, optional iWMMXt v2 and/or NEON + +Long-term plans +--------------- + + * Unify the mach-dove/, mach-mv78xx0/, mach-orion5x/ into the + mach-mvebu/ to support all SoCs from the Marvell EBU (Engineering + Business Unit) in a single mach- directory. The plat-orion/ + would therefore disappear. + + * Unify the mach-mmp/ and mach-pxa/ into the same mach-pxa + directory. The plat-pxa/ would therefore disappear. + +Credits +------- + +- Maen Suleiman +- Lior Amsalem +- Thomas Petazzoni +- Andrew Lunn +- Nicolas Pitre +- Eric Miao -- cgit v1.2.3 From feb47df1faaa7d7be0791bc17183c9bbdb8c9352 Mon Sep 17 00:00:00 2001 From: Pali Rohár Date: Thu, 21 Jan 2021 20:34:18 +0100 Subject: Documentation: arm: marvell: Add link to public Armada 37xx Hardware Spec MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Pali Rohár Reviewed-by: Andrew Lunn Link: https://lore.kernel.org/r/20210121193418.22678-2-pali@kernel.org Signed-off-by: Jonathan Corbet --- Documentation/arm/marvell.rst | 3 +++ 1 file changed, 3 insertions(+) (limited to 'Documentation') diff --git a/Documentation/arm/marvell.rst b/Documentation/arm/marvell.rst index 16ab2eb085b8..b16e6f7e8dbe 100644 --- a/Documentation/arm/marvell.rst +++ b/Documentation/arm/marvell.rst @@ -185,6 +185,9 @@ EBU Armada family ARMv8 Product Brief: http://www.marvell.com/embedded-processors/assets/PB-88F3700-FNL.pdf + Hardware Spec: + http://www.marvell.com/content/dam/marvell/en/public-collateral/embedded-processors/marvell-embedded-processors-armada-37xx-hardware-specifications-2019-09.pdf + Device tree files: arch/arm64/boot/dts/marvell/armada-37* -- cgit v1.2.3 From c4822bd66fb147b4441343e9a235717229828258 Mon Sep 17 00:00:00 2001 From: Pali Rohár Date: Mon, 25 Jan 2021 15:13:41 +0100 Subject: Documentation: arm: marvell: Fix dead link to Armada 37xx Product Brief MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Pali Rohár Link: https://lore.kernel.org/r/20210125141341.32200-1-pali@kernel.org Signed-off-by: Jonathan Corbet --- Documentation/arm/marvell.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Documentation') diff --git a/Documentation/arm/marvell.rst b/Documentation/arm/marvell.rst index b16e6f7e8dbe..fa22a72d4391 100644 --- a/Documentation/arm/marvell.rst +++ b/Documentation/arm/marvell.rst @@ -183,7 +183,7 @@ EBU Armada family ARMv8 http://www.marvell.com/embedded-processors/armada-3700/ Product Brief: - http://www.marvell.com/embedded-processors/assets/PB-88F3700-FNL.pdf + http://www.marvell.com/content/dam/marvell/en/public-collateral/embedded-processors/marvell-embedded-processors-armada-37xx-product-brief-2016-01.pdf Hardware Spec: http://www.marvell.com/content/dam/marvell/en/public-collateral/embedded-processors/marvell-embedded-processors-armada-37xx-hardware-specifications-2019-09.pdf -- cgit v1.2.3 From 5d2699d28c4dc5f99f84ec0bf197bdc6ea23f80f Mon Sep 17 00:00:00 2001 From: Pali Rohár Date: Mon, 25 Jan 2021 15:15:29 +0100 Subject: Documentation: arm: marvell: Update link to unrestricted Armada 38x Functional Spec MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit On Marvell website is documentation accessible without need to register or fill any other forms. Signed-off-by: Pali Rohár Link: https://lore.kernel.org/r/20210125141529.32357-1-pali@kernel.org Signed-off-by: Jonathan Corbet --- Documentation/arm/marvell.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Documentation') diff --git a/Documentation/arm/marvell.rst b/Documentation/arm/marvell.rst index fa22a72d4391..94cd73383594 100644 --- a/Documentation/arm/marvell.rst +++ b/Documentation/arm/marvell.rst @@ -127,7 +127,7 @@ EBU Armada family - 88F6828 Armada 388 - Product infos: http://www.marvell.com/embedded-processors/armada-38x/ - - Functional Spec: https://marvellcorp.wufoo.com/forms/marvell-armada-38x-functional-specifications/ + - Functional Spec: http://www.marvell.com/content/dam/marvell/en/public-collateral/embedded-processors/marvell-embedded-processors-armada-38x-functional-specifications-2015-11.pdf Core: ARM Cortex-A9 -- cgit v1.2.3 From bc47190d4f14f0ef0cb40c828a65316bde9259b2 Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Sun, 24 Jan 2021 20:32:02 -0800 Subject: Documentation/admin-guide: kernel-parameters: update CMA entries Add qualifying build option legend [CMA] to kernel boot options that requirce CMA support to be enabled for them to be usable. Also capitalize 'CMA' when it is used as an acronym. Signed-off-by: Randy Dunlap Acked-by: Mike Kravetz Link: https://lore.kernel.org/r/20210125043202.22399-1-rdunlap@infradead.org Signed-off-by: Jonathan Corbet --- Documentation/admin-guide/kernel-parameters.txt | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'Documentation') diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt index 9e3cdb271d06..50d9b9bfcd6e 100644 --- a/Documentation/admin-guide/kernel-parameters.txt +++ b/Documentation/admin-guide/kernel-parameters.txt @@ -600,7 +600,7 @@ kernel/dma/contiguous.c cma_pernuma=nn[MG] - [ARM64,KNL] + [ARM64,KNL,CMA] Sets the size of kernel per-numa memory area for contiguous memory allocations. A value of 0 disables per-numa CMA altogether. And If this option is not @@ -1524,12 +1524,12 @@ hpet_mmap= [X86, HPET_MMAP] Allow userspace to mmap HPET registers. Default set by CONFIG_HPET_MMAP_DEFAULT. - hugetlb_cma= [HW] The size of a cma area used for allocation + hugetlb_cma= [HW,CMA] The size of a CMA area used for allocation of gigantic hugepages. Format: nn[KMGTPE] - Reserve a cma area of given size and allocate gigantic - hugepages using the cma allocator. If enabled, the + Reserve a CMA area of given size and allocate gigantic + hugepages using the CMA allocator. If enabled, the boot-time allocation of gigantic hugepages is skipped. hugepages= [HW] Number of HugeTLB pages to allocate at boot. -- cgit v1.2.3 From 56c6092be2a145eadab19700688d9716e9de01d6 Mon Sep 17 00:00:00 2001 From: Baruch Siach Date: Mon, 25 Jan 2021 09:10:30 +0200 Subject: Documentation: ARM: fix reference to DT format documentation The booting-without-of.rst file is no longer there. Link to devicetree.org instead. Fixes: 441848282c590 ("dt: Remove booting-without-of.rst") Signed-off-by: Baruch Siach Cc: Rob Herring Link: https://lore.kernel.org/r/7f07e544d9fc584242d496c2f54f9303d8de0724.1611558630.git.baruch@tkos.co.il Signed-off-by: Jonathan Corbet --- Documentation/arm/booting.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Documentation') diff --git a/Documentation/arm/booting.rst b/Documentation/arm/booting.rst index a2263451dc2c..5974e37b3d20 100644 --- a/Documentation/arm/booting.rst +++ b/Documentation/arm/booting.rst @@ -128,7 +128,7 @@ it. The recommended placement is in the first 16KiB of RAM. The boot loader must load a device tree image (dtb) into system ram at a 64bit aligned address and initialize it with the boot data. The -dtb format is documented in Documentation/devicetree/booting-without-of.rst. +dtb format is documented at https://www.devicetree.org/specifications/. The kernel will look for the dtb magic value of 0xd00dfeed at the dtb physical address to determine if a dtb has been passed instead of a tagged list. -- cgit v1.2.3 From 452f81ed05e2c0762b27ab252dca59aa2457baca Mon Sep 17 00:00:00 2001 From: Yanteng Si Date: Thu, 21 Jan 2021 11:33:00 +0800 Subject: docs/zh_CN: add iio iio_configfs.rst translation This patch translates Documentation/iio/iio_configfs.rst into Chinese. Signed-off-by: Yanteng Si Reviewed-by: Alex Shi Reviewed-by: Huacai Chen Link: https://lore.kernel.org/r/20210121033302.558935-1-siyanteng@loongson.cn Signed-off-by: Jonathan Corbet --- .../translations/zh_CN/iio/iio_configfs.rst | 102 +++++++++++++++++++++ 1 file changed, 102 insertions(+) create mode 100644 Documentation/translations/zh_CN/iio/iio_configfs.rst (limited to 'Documentation') diff --git a/Documentation/translations/zh_CN/iio/iio_configfs.rst b/Documentation/translations/zh_CN/iio/iio_configfs.rst new file mode 100644 index 000000000000..274488e8dce4 --- /dev/null +++ b/Documentation/translations/zh_CN/iio/iio_configfs.rst @@ -0,0 +1,102 @@ +.. include:: ../disclaimer-zh_CN.rst + +:Original: :doc:`../../../iio/iio_configfs` +:Translator: Yanteng Si + +.. _cn_iio_configfs: + + +===================== +工业 IIO configfs支持 +===================== + +1. 概述 +======= + +Configfs是一种内核对象的基于文件系统的管理系统,IIO使用一些可以通过 +configfs轻松配置的对象(例如:设备,触发器)。 + +关于configfs是如何运行的,请查阅Documentation/filesystems/configfs.rst +了解更多信息。 + +2. 用法 +======= +为了使configfs支持IIO,我们需要在编译时选中config的CONFIG_IIO_CONFIGFS +选项。 + +然后,挂载configfs文件系统(通常在 /config directory目录下):: + + $ mkdir/config + $ mount -t configfs none/config + +此时,将创建所有默认IIO组,并可以在/ config / iio下对其进行访问。 下一章 +将介绍可用的IIO配置对象。 + +3. 软件触发器 +============= + +IIO默认configfs组之一是“触发器”组。 挂载configfs后可以自动访问它,并且可 +以在/config/iio/triggers下找到。 + +IIO软件触发器为创建多种触发器类型提供了支持。 通常在include/linux/iio +/sw_trigger.h:中的接口下将新的触发器类型实现为单独的内核模块: +:: + + /* + * drivers/iio/trigger/iio-trig-sample.c + * 一种新触发器类型的内核模块实例 + */ + #include + + + static struct iio_sw_trigger *iio_trig_sample_probe(const char *name) + { + /* + * 这将分配并注册一个IIO触发器以及其他触发器类型特性的初始化。 + */ + } + + static int iio_trig_sample_remove(struct iio_sw_trigger *swt) + { + /* + * 这会废弃iio_trig_sample_probe中的操作 + */ + } + + static const struct iio_sw_trigger_ops iio_trig_sample_ops = { + .probe = iio_trig_sample_probe, + .remove = iio_trig_sample_remove, + }; + + static struct iio_sw_trigger_type iio_trig_sample = { + .name = "trig-sample", + .owner = THIS_MODULE, + .ops = &iio_trig_sample_ops, + }; + +module_iio_sw_trigger_driver(iio_trig_sample); + +每种触发器类型在/config/iio/triggers下都有其自己的目录。 加载iio-trig-sample +模块将创建“ trig-sample”触发器类型目录/config/iio/triggers/trig-sample. + +我们支持以下中断源(触发器类型) + + * hrtimer,使用高分辨率定时器作为中断源 + +3.1 Hrtimer触发器创建与销毁 +--------------------------- + +加载iio-trig-hrtimer模块将注册hrtimer触发器类型,从而允许用户在 +/config/iio/triggers/hrtimer下创建hrtimer触发器。 + +例如:: + + $ mkdir /config/iio/triggers/hrtimer/instance1 + $ rmdir /config/iio/triggers/hrtimer/instance1 + +每个触发器可以具有一个或多个独特的触发器类型的属性。 + +3.2 "hrtimer" 触发器类型属性 +---------------------------- + +"hrtimer”触发器类型没有来自/config dir的任何可配置属性。 -- cgit v1.2.3 From 9ea800c0113d377e71324b668115f4ae24835931 Mon Sep 17 00:00:00 2001 From: Yanteng Si Date: Thu, 21 Jan 2021 11:33:01 +0800 Subject: docs/zh_CN: add iio ep93xx_adc.rst translation This patch translates Documentation/iio/ep93xx_adc.rst into Chinese. Signed-off-by: Yanteng Si Reviewed-by: Alex Shi Reviewed-by: Huacai Chen Link: https://lore.kernel.org/r/20210121033302.558935-2-siyanteng@loongson.cn Signed-off-by: Jonathan Corbet --- .../translations/zh_CN/iio/ep93xx_adc.rst | 46 ++++++++++++++++++++++ 1 file changed, 46 insertions(+) create mode 100644 Documentation/translations/zh_CN/iio/ep93xx_adc.rst (limited to 'Documentation') diff --git a/Documentation/translations/zh_CN/iio/ep93xx_adc.rst b/Documentation/translations/zh_CN/iio/ep93xx_adc.rst new file mode 100644 index 000000000000..7e91d2197867 --- /dev/null +++ b/Documentation/translations/zh_CN/iio/ep93xx_adc.rst @@ -0,0 +1,46 @@ +.. include:: ../disclaimer-zh_CN.rst + +:Original: :doc:`../../../iio/ep93xx_adc` +:Translator: Yanteng Si + +.. _cn_iio_ep93xx_adc: + + +================================== +思睿逻辑 EP93xx 模拟数字转换器驱动 +================================== + +1. 概述 +======= + +该驱动同时适用于具有5通道模拟数字转换器的低端 (EP9301, Ep9302) 设备和10通道 +触摸屏/模拟数字转换器的高端设备(EP9307, EP9312, EP9315)。 + +2. 通道编号 +=========== + +EP9301和EP9302数据表定义了通道0..4的编号方案。虽然EP9307, EP9312和EP9315多 +了3个通道(一共8个),但是编号并没有定义。所以说最后三个通道是随机编号的。 + +如果ep93xx_adc是IIO设备0,您将在以下位置找到条目 +/sys/bus/iio/devices/iio:device0/: + + +-----------------+---------------+ + | sysfs 入口 | ball/pin 名称 | + +=================+===============+ + | in_voltage0_raw | YM | + +-----------------+---------------+ + | in_voltage1_raw | SXP | + +-----------------+---------------+ + | in_voltage2_raw | SXM | + +-----------------+---------------+ + | in_voltage3_raw | SYP | + +-----------------+---------------+ + | in_voltage4_raw | SYM | + +-----------------+---------------+ + | in_voltage5_raw | XP | + +-----------------+---------------+ + | in_voltage6_raw | XM | + +-----------------+---------------+ + | in_voltage7_raw | YP | + +-----------------+---------------+ -- cgit v1.2.3 From 7720357d16a7cfe4c9efb596e7d47fc80236eaa8 Mon Sep 17 00:00:00 2001 From: Yanteng Si Date: Thu, 21 Jan 2021 11:33:02 +0800 Subject: docs: zh_CN: add iio index.rst translation This patch translates Documentation/iio/index.rst into Chinese. Signed-off-by: Yanteng Si Reviewed-by: Alex Shi Reviewed-by: Huacai Chen Link: https://lore.kernel.org/r/20210121033302.558935-3-siyanteng@loongson.cn Signed-off-by: Jonathan Corbet --- Documentation/translations/zh_CN/iio/index.rst | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 Documentation/translations/zh_CN/iio/index.rst (limited to 'Documentation') diff --git a/Documentation/translations/zh_CN/iio/index.rst b/Documentation/translations/zh_CN/iio/index.rst new file mode 100644 index 000000000000..7087076a10f6 --- /dev/null +++ b/Documentation/translations/zh_CN/iio/index.rst @@ -0,0 +1,20 @@ +.. SPDX-License-Identifier: GPL-2.0 + +.. include:: ../disclaimer-zh_CN.rst + +:Original: :doc:`../../../iio/index` +:Translator: Yanteng Si + +.. _cn_iio_index: + + +======== +工业 I/O +======== + +.. toctree:: + :maxdepth: 1 + + iio_configfs + + ep93xx_adc -- cgit v1.2.3 From 798eb4cc64492c302d80a258a71a0802cf24be5a Mon Sep 17 00:00:00 2001 From: Milan Lakhani Date: Wed, 20 Jan 2021 13:31:51 +0000 Subject: docs: Update DTB format references There were two references to devicetree/booting-without-of.rst (which has been removed) for DTB format information, and devicetree/usage-model.rst pointed to https://elinux.org/Device_Tree_Usage. Change all three of these references to https://www.devicetree.org/specifications/. Signed-off-by: Milan Lakhani Link: https://lore.kernel.org/r/1611149511-4990-1-git-send-email-milan.lakhani@codethink.co.uk Signed-off-by: Jonathan Corbet --- Documentation/devicetree/usage-model.rst | 2 +- Documentation/translations/zh_CN/arm/Booting | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'Documentation') diff --git a/Documentation/devicetree/usage-model.rst b/Documentation/devicetree/usage-model.rst index e1b42dc63f01..1eb83496ca1e 100644 --- a/Documentation/devicetree/usage-model.rst +++ b/Documentation/devicetree/usage-model.rst @@ -12,7 +12,7 @@ This article describes how Linux uses the device tree. An overview of the device tree data format can be found on the device tree usage page at devicetree.org\ [1]_. -.. [1] https://elinux.org/Device_Tree_Usage +.. [1] https://www.devicetree.org/specifications/ The "Open Firmware Device Tree", or simply Device Tree (DT), is a data structure and language for describing hardware. More specifically, it diff --git a/Documentation/translations/zh_CN/arm/Booting b/Documentation/translations/zh_CN/arm/Booting index c3d26ce5f6de..5ecea0767893 100644 --- a/Documentation/translations/zh_CN/arm/Booting +++ b/Documentation/translations/zh_CN/arm/Booting @@ -124,7 +124,7 @@ bootloader 必须传递一个系统内存的位置和最小值,以及根文件 bootloader 必须以 64bit 地址对齐的形式加载一个设备树映像(dtb)到系统 RAM 中,并用启动数据初始化它。dtb 格式在文档 -Documentation/devicetree/booting-without-of.rst 中。内核将会在 +https://www.devicetree.org/specifications/ 中。内核将会在 dtb 物理地址处查找 dtb 魔数值(0xd00dfeed),以确定 dtb 是否已经代替 标签列表被传递进来。 -- cgit v1.2.3 From c66cb171bc308c64083f3bb173152db68e06e79f Mon Sep 17 00:00:00 2001 From: Eric Curtin Date: Wed, 20 Jan 2021 13:26:47 +0000 Subject: Update Documentation/admin-guide/sysctl/fs.rst max_user_watches for epoll should say 1/25, rather than 1/32 Signed-off-by: Eric Curtin Link: https://lore.kernel.org/r/20210120132648.19046-1-ericcurtin17@gmail.com Signed-off-by: Jonathan Corbet --- Documentation/admin-guide/sysctl/fs.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'Documentation') diff --git a/Documentation/admin-guide/sysctl/fs.rst b/Documentation/admin-guide/sysctl/fs.rst index f48277a0a850..2a501c9ddc55 100644 --- a/Documentation/admin-guide/sysctl/fs.rst +++ b/Documentation/admin-guide/sysctl/fs.rst @@ -380,5 +380,5 @@ This configuration option sets the maximum number of "watches" that are allowed for each user. Each "watch" costs roughly 90 bytes on a 32bit kernel, and roughly 160 bytes on a 64bit one. -The current default value for max_user_watches is the 1/32 of the available -low memory, divided for the "watch" cost in bytes. +The current default value for max_user_watches is the 1/25 (4%) of the +available low memory, divided for the "watch" cost in bytes. -- cgit v1.2.3 From 20ccc8dd38a391daba3a5a5dbd5443855100c517 Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Wed, 13 Jan 2021 09:03:10 +1000 Subject: Documentation: input: define ABS_PRESSURE/ABS_MT_PRESSURE resolution as grams ABS_PRESSURE and ABS_MT_PRESSURE on touch devices usually represent contact size (as a finger flattens with higher pressure the contact size increases) and userspace translates the kernel pressure value back into contact size. For example, libinput has pressure thresholds when a touch is considered a palm (palm == large contact area -> high pressure). The values themselves are on an arbitrary scale and device-specific. On pressurepads however, the pressure axis may represent the real physical pressure. Pressurepads are touchpads without a hinge but an actual pressure sensor underneath the device instead, for example the Lenovo Yoga 9i. A high-enough pressure is converted to a button click by the firmware. Microsoft does not require a pressure axis to be present, see [1], so as seen from userspace most pressurepads are identical to clickpads - one button and INPUT_PROP_BUTTONPAD set. However, pressurepads that export the pressure axis break userspace because that axis no longer represents contact size, resulting in inconsistent touch tracking, e.g. [2]. Userspace needs to know when a pressure axis represents real pressure and the best way to do so is to define what the resolution field means. Userspace can then treat data with a pressure resolution as true pressure. This patch documents that the pressure resolution is in units/gram. This allows for fine-grained detail and tops out at roughly ~2000t, enough for the devices we're dealing with. Grams is not a scientific pressure unit but the alternative is: - Pascal: defined as force per area and area is unreliable on many devices and seems like the wrong option here anyway, especially for devices with a single pressure sensor only. - Newton: defined as mass * distance/acceleration and for the purposes of a pressure axis, the distance is tricky to interpret and we get the data to calculate acceleration from event timestamps anyway. For the purposes of touch devices and digitizers, grams seems the best choice and the easiest to interpret. Bonus side effect: we can use the existing hwdb infrastructure in userspace to fix devices that advertise false pressure. [1] https://docs.microsoft.com/en-us/windows-hardware/design/component-guidelines/windows-precision-touchpad-required-hid-top-level-collections#windows-precision-touchpad-input-reports [2] https://gitlab.freedesktop.org/libinput/libinput/-/issues/562 Signed-off-by: Peter Hutterer Acked-by: Benjamin Tissoires Link: https://lore.kernel.org/r/20210112230310.GA149342@jelly Signed-off-by: Jonathan Corbet --- Documentation/input/event-codes.rst | 15 +++++++++++++++ Documentation/input/multi-touch-protocol.rst | 4 ++++ 2 files changed, 19 insertions(+) (limited to 'Documentation') diff --git a/Documentation/input/event-codes.rst b/Documentation/input/event-codes.rst index b24b5343f5eb..3118fc1c1e26 100644 --- a/Documentation/input/event-codes.rst +++ b/Documentation/input/event-codes.rst @@ -236,6 +236,21 @@ A few EV_ABS codes have special meanings: - Used to describe multitouch input events. Please see multi-touch-protocol.txt for details. +* ABS_PRESSURE/ABS_MT_PRESSURE: + + - For touch devices, many devices converted contact size into pressure. + A finger flattens with pressure, causing a larger contact area and thus + pressure and contact size are directly related. This is not the case + for other devices, for example digitizers and touchpads with a true + pressure sensor ("pressure pads"). + + A device should set the resolution of the axis to indicate whether the + pressure is in measurable units. If the resolution is zero, the + pressure data is in arbitrary units. If the resolution is nonzero, the + pressure data is in units/gram. For example, a value of 10 with a + resolution of 1 represents 10 gram, a value of 10 with a resolution on + 1000 represents 10 microgram. + EV_SW ----- diff --git a/Documentation/input/multi-touch-protocol.rst b/Documentation/input/multi-touch-protocol.rst index 307fe22d9668..21c1e6a22888 100644 --- a/Documentation/input/multi-touch-protocol.rst +++ b/Documentation/input/multi-touch-protocol.rst @@ -260,6 +260,10 @@ ABS_MT_PRESSURE of TOUCH and WIDTH for pressure-based devices or any device with a spatial signal intensity distribution. + If the resolution is zero, the pressure data is in arbitrary units. + If the resolution is nonzero, the pressure data is in units/gram. See + :ref:`input-event-codes` for details. + ABS_MT_DISTANCE The distance, in surface units, between the contact and the surface. Zero distance means the contact is touching the surface. A positive number means -- cgit v1.2.3 From b4b91e24094ad54b3d176e3fd2997fae62a315dc Mon Sep 17 00:00:00 2001 From: Daniele Palmas Date: Wed, 27 Jan 2021 16:34:33 +0100 Subject: net: qmi_wwan: document qmap/mux_id sysfs file MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Document qmap/mux_id sysfs file showing qmimux interface id Signed-off-by: Daniele Palmas Acked-by: Bjørn Mork Signed-off-by: Jakub Kicinski --- Documentation/ABI/testing/sysfs-class-net-qmi | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'Documentation') diff --git a/Documentation/ABI/testing/sysfs-class-net-qmi b/Documentation/ABI/testing/sysfs-class-net-qmi index c310db4ccbc2..ed79f5893421 100644 --- a/Documentation/ABI/testing/sysfs-class-net-qmi +++ b/Documentation/ABI/testing/sysfs-class-net-qmi @@ -48,3 +48,13 @@ Description: Write a number ranging from 1 to 254 to delete a previously created qmap mux based network device. + +What: /sys/class/net//qmap/mux_id +Date: January 2021 +KernelVersion: 5.12 +Contact: Daniele Palmas +Description: + Unsigned integer + + Indicates the mux id associated to the qmimux network interface + during its creation. -- cgit v1.2.3 From 2083fecd1c12fecb419dfb767ba7f18143490b82 Mon Sep 17 00:00:00 2001 From: Viresh Kumar Date: Thu, 14 Jan 2021 17:05:27 +0530 Subject: arch: sparc: Remove CONFIG_OPROFILE support The "oprofile" user-space tools don't use the kernel OPROFILE support any more, and haven't in a long time. User-space has been converted to the perf interfaces. Remove the old oprofile's architecture specific support. Suggested-by: Christoph Hellwig Suggested-by: Linus Torvalds Signed-off-by: Viresh Kumar Acked-by: Robert Richter Acked-by: William Cohen Acked-by: Al Viro Acked-by: Thomas Gleixner --- Documentation/kbuild/makefiles.rst | 1 - arch/sparc/Kconfig | 1 - arch/sparc/Makefile | 1 - arch/sparc/configs/sparc64_defconfig | 1 - arch/sparc/oprofile/Makefile | 10 ----- arch/sparc/oprofile/init.c | 87 ------------------------------------ 6 files changed, 101 deletions(-) delete mode 100644 arch/sparc/oprofile/Makefile delete mode 100644 arch/sparc/oprofile/init.c (limited to 'Documentation') diff --git a/Documentation/kbuild/makefiles.rst b/Documentation/kbuild/makefiles.rst index 9f6a11881951..d7b2e027c1f8 100644 --- a/Documentation/kbuild/makefiles.rst +++ b/Documentation/kbuild/makefiles.rst @@ -1317,7 +1317,6 @@ When kbuild executes, the following steps are followed (roughly): libs-y += arch/sparc/lib/ drivers-$(CONFIG_PM) += arch/sparc/power/ - drivers-$(CONFIG_OPROFILE) += arch/sparc/oprofile/ 7.5 Architecture-specific boot images ------------------------------------- diff --git a/arch/sparc/Kconfig b/arch/sparc/Kconfig index c9c34dc52b7d..caf95e61162b 100644 --- a/arch/sparc/Kconfig +++ b/arch/sparc/Kconfig @@ -20,7 +20,6 @@ config SPARC select OF_PROMTREE select HAVE_ASM_MODVERSIONS select HAVE_IDE - select HAVE_OPROFILE select HAVE_ARCH_KGDB if !SMP || SPARC64 select HAVE_ARCH_TRACEHOOK select HAVE_ARCH_SECCOMP if SPARC64 diff --git a/arch/sparc/Makefile b/arch/sparc/Makefile index 4a0919581697..bee99e65fe23 100644 --- a/arch/sparc/Makefile +++ b/arch/sparc/Makefile @@ -65,7 +65,6 @@ libs-y += arch/sparc/prom/ libs-y += arch/sparc/lib/ drivers-$(CONFIG_PM) += arch/sparc/power/ -drivers-$(CONFIG_OPROFILE) += arch/sparc/oprofile/ boot := arch/sparc/boot diff --git a/arch/sparc/configs/sparc64_defconfig b/arch/sparc/configs/sparc64_defconfig index bde4d21a8ac8..d91eb6a76dd1 100644 --- a/arch/sparc/configs/sparc64_defconfig +++ b/arch/sparc/configs/sparc64_defconfig @@ -8,7 +8,6 @@ CONFIG_PERF_EVENTS=y # CONFIG_COMPAT_BRK is not set CONFIG_SLAB=y CONFIG_PROFILING=y -CONFIG_OPROFILE=m CONFIG_KPROBES=y CONFIG_MODULES=y CONFIG_MODULE_UNLOAD=y diff --git a/arch/sparc/oprofile/Makefile b/arch/sparc/oprofile/Makefile deleted file mode 100644 index fe906e403d3a..000000000000 --- a/arch/sparc/oprofile/Makefile +++ /dev/null @@ -1,10 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0-only -obj-$(CONFIG_OPROFILE) += oprofile.o - -DRIVER_OBJS = $(addprefix ../../../drivers/oprofile/, \ - oprof.o cpu_buffer.o buffer_sync.o \ - event_buffer.o oprofile_files.o \ - oprofilefs.o oprofile_stats.o \ - timer_int.o ) - -oprofile-y := $(DRIVER_OBJS) init.o diff --git a/arch/sparc/oprofile/init.c b/arch/sparc/oprofile/init.c deleted file mode 100644 index 43730c9b1c86..000000000000 --- a/arch/sparc/oprofile/init.c +++ /dev/null @@ -1,87 +0,0 @@ -/** - * @file init.c - * - * @remark Copyright 2002 OProfile authors - * @remark Read the file COPYING - * - * @author John Levon - */ - -#include -#include -#include -#include -#include /* for HZ */ - -#ifdef CONFIG_SPARC64 -#include -#include -#include -#include - -static int profile_timer_exceptions_notify(struct notifier_block *self, - unsigned long val, void *data) -{ - struct die_args *args = data; - int ret = NOTIFY_DONE; - - switch (val) { - case DIE_NMI: - oprofile_add_sample(args->regs, 0); - ret = NOTIFY_STOP; - break; - default: - break; - } - return ret; -} - -static struct notifier_block profile_timer_exceptions_nb = { - .notifier_call = profile_timer_exceptions_notify, -}; - -static int timer_start(void) -{ - if (register_die_notifier(&profile_timer_exceptions_nb)) - return 1; - nmi_adjust_hz(HZ); - return 0; -} - - -static void timer_stop(void) -{ - nmi_adjust_hz(1); - unregister_die_notifier(&profile_timer_exceptions_nb); - synchronize_rcu(); /* Allow already-started NMIs to complete. */ -} - -static int op_nmi_timer_init(struct oprofile_operations *ops) -{ - if (atomic_read(&nmi_active) <= 0) - return -ENODEV; - - ops->start = timer_start; - ops->stop = timer_stop; - ops->cpu_type = "timer"; - printk(KERN_INFO "oprofile: Using perfctr NMI timer interrupt.\n"); - return 0; -} -#endif - -int __init oprofile_arch_init(struct oprofile_operations *ops) -{ - int ret = -ENODEV; - -#ifdef CONFIG_SPARC64 - ret = op_nmi_timer_init(ops); - if (!ret) - return ret; -#endif - - return ret; -} - -void oprofile_arch_exit(void) -{ -} -- cgit v1.2.3 From f8408264c77a0cebb20244d1f4750501b36abe0e Mon Sep 17 00:00:00 2001 From: Viresh Kumar Date: Thu, 14 Jan 2021 17:05:30 +0530 Subject: drivers: Remove CONFIG_OPROFILE support The "oprofile" user-space tools don't use the kernel OPROFILE support any more, and haven't in a long time. User-space has been converted to the perf interfaces. Remove kernel's old oprofile support. Suggested-by: Christoph Hellwig Suggested-by: Linus Torvalds Signed-off-by: Viresh Kumar Acked-by: Robert Richter Acked-by: Paul E. McKenney #RCU Acked-by: William Cohen Acked-by: Al Viro Acked-by: Thomas Gleixner --- Documentation/RCU/NMI-RCU.rst | 3 +- Documentation/admin-guide/kernel-parameters.txt | 14 - Documentation/process/magic-number.rst | 1 - .../translations/it_IT/process/magic-number.rst | 1 - .../translations/zh_CN/process/magic-number.rst | 1 - MAINTAINERS | 11 - arch/Kconfig | 32 -- drivers/oprofile/buffer_sync.c | 591 --------------------- drivers/oprofile/buffer_sync.h | 22 - drivers/oprofile/cpu_buffer.c | 465 ---------------- drivers/oprofile/cpu_buffer.h | 121 ----- drivers/oprofile/event_buffer.c | 209 -------- drivers/oprofile/event_buffer.h | 40 -- drivers/oprofile/nmi_timer_int.c | 157 ------ drivers/oprofile/oprof.c | 286 ---------- drivers/oprofile/oprof.h | 50 -- drivers/oprofile/oprofile_files.c | 201 ------- drivers/oprofile/oprofile_perf.c | 328 ------------ drivers/oprofile/oprofile_stats.c | 84 --- drivers/oprofile/oprofile_stats.h | 33 -- drivers/oprofile/oprofilefs.c | 300 ----------- drivers/oprofile/timer_int.c | 122 ----- include/linux/oprofile.h | 209 -------- init/Kconfig | 2 +- 24 files changed, 2 insertions(+), 3281 deletions(-) delete mode 100644 drivers/oprofile/buffer_sync.c delete mode 100644 drivers/oprofile/buffer_sync.h delete mode 100644 drivers/oprofile/cpu_buffer.c delete mode 100644 drivers/oprofile/cpu_buffer.h delete mode 100644 drivers/oprofile/event_buffer.c delete mode 100644 drivers/oprofile/event_buffer.h delete mode 100644 drivers/oprofile/nmi_timer_int.c delete mode 100644 drivers/oprofile/oprof.c delete mode 100644 drivers/oprofile/oprof.h delete mode 100644 drivers/oprofile/oprofile_files.c delete mode 100644 drivers/oprofile/oprofile_perf.c delete mode 100644 drivers/oprofile/oprofile_stats.c delete mode 100644 drivers/oprofile/oprofile_stats.h delete mode 100644 drivers/oprofile/oprofilefs.c delete mode 100644 drivers/oprofile/timer_int.c delete mode 100644 include/linux/oprofile.h (limited to 'Documentation') diff --git a/Documentation/RCU/NMI-RCU.rst b/Documentation/RCU/NMI-RCU.rst index 180958388ff9..2a92bc685ef1 100644 --- a/Documentation/RCU/NMI-RCU.rst +++ b/Documentation/RCU/NMI-RCU.rst @@ -8,8 +8,7 @@ Although RCU is usually used to protect read-mostly data structures, it is possible to use RCU to provide dynamic non-maskable interrupt handlers, as well as dynamic irq handlers. This document describes how to do this, drawing loosely from Zwane Mwaikambo's NMI-timer -work in "arch/x86/oprofile/nmi_timer_int.c" and in -"arch/x86/kernel/traps.c". +work in "arch/x86/kernel/traps.c". The relevant pieces of code are listed below, each followed by a brief explanation:: diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt index 9e3cdb271d06..e860c681766b 100644 --- a/Documentation/admin-guide/kernel-parameters.txt +++ b/Documentation/admin-guide/kernel-parameters.txt @@ -3458,20 +3458,6 @@ For example, to override I2C bus2: omap_mux=i2c2_scl.i2c2_scl=0x100,i2c2_sda.i2c2_sda=0x100 - oprofile.timer= [HW] - Use timer interrupt instead of performance counters - - oprofile.cpu_type= Force an oprofile cpu type - This might be useful if you have an older oprofile - userland or if you want common events. - Format: { arch_perfmon } - arch_perfmon: [X86] Force use of architectural - perfmon on Intel CPUs instead of the - CPU specific event set. - timer: [X86] Force use of architectural NMI - timer mode (see also oprofile.timer - for generic hr timer mode) - oops=panic Always panic on oopses. Default is to just kill the process, but there is a small probability of deadlocking the machine. diff --git a/Documentation/process/magic-number.rst b/Documentation/process/magic-number.rst index e02ff5ffb653..c6dfe060ec2f 100644 --- a/Documentation/process/magic-number.rst +++ b/Documentation/process/magic-number.rst @@ -135,7 +135,6 @@ FW_HEADER_MAGIC 0x65726F66 fw_header ``drivers/atm/fo SLOT_MAGIC 0x67267321 slot ``drivers/hotplug/cpqphp.h`` SLOT_MAGIC 0x67267322 slot ``drivers/hotplug/acpiphp.h`` LO_MAGIC 0x68797548 nbd_device ``include/linux/nbd.h`` -OPROFILE_MAGIC 0x6f70726f super_block ``drivers/oprofile/oprofilefs.h`` M3_STATE_MAGIC 0x734d724d m3_state ``sound/oss/maestro3.c`` VMALLOC_MAGIC 0x87654320 snd_alloc_track ``sound/core/memory.c`` KMALLOC_MAGIC 0x87654321 snd_alloc_track ``sound/core/memory.c`` diff --git a/Documentation/translations/it_IT/process/magic-number.rst b/Documentation/translations/it_IT/process/magic-number.rst index 0243d32a0b59..1af30f4228f2 100644 --- a/Documentation/translations/it_IT/process/magic-number.rst +++ b/Documentation/translations/it_IT/process/magic-number.rst @@ -141,7 +141,6 @@ FW_HEADER_MAGIC 0x65726F66 fw_header ``drivers/atm/fo SLOT_MAGIC 0x67267321 slot ``drivers/hotplug/cpqphp.h`` SLOT_MAGIC 0x67267322 slot ``drivers/hotplug/acpiphp.h`` LO_MAGIC 0x68797548 nbd_device ``include/linux/nbd.h`` -OPROFILE_MAGIC 0x6f70726f super_block ``drivers/oprofile/oprofilefs.h`` M3_STATE_MAGIC 0x734d724d m3_state ``sound/oss/maestro3.c`` VMALLOC_MAGIC 0x87654320 snd_alloc_track ``sound/core/memory.c`` KMALLOC_MAGIC 0x87654321 snd_alloc_track ``sound/core/memory.c`` diff --git a/Documentation/translations/zh_CN/process/magic-number.rst b/Documentation/translations/zh_CN/process/magic-number.rst index de182bf4191c..7bb9d4165ed3 100644 --- a/Documentation/translations/zh_CN/process/magic-number.rst +++ b/Documentation/translations/zh_CN/process/magic-number.rst @@ -124,7 +124,6 @@ FW_HEADER_MAGIC 0x65726F66 fw_header ``drivers/atm/fo SLOT_MAGIC 0x67267321 slot ``drivers/hotplug/cpqphp.h`` SLOT_MAGIC 0x67267322 slot ``drivers/hotplug/acpiphp.h`` LO_MAGIC 0x68797548 nbd_device ``include/linux/nbd.h`` -OPROFILE_MAGIC 0x6f70726f super_block ``drivers/oprofile/oprofilefs.h`` M3_STATE_MAGIC 0x734d724d m3_state ``sound/oss/maestro3.c`` VMALLOC_MAGIC 0x87654320 snd_alloc_track ``sound/core/memory.c`` KMALLOC_MAGIC 0x87654321 snd_alloc_track ``sound/core/memory.c`` diff --git a/MAINTAINERS b/MAINTAINERS index cc1e6a5ee6e6..ae2c2cef9d96 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -1414,7 +1414,6 @@ F: arch/arm*/include/asm/hw_breakpoint.h F: arch/arm*/include/asm/perf_event.h F: arch/arm*/kernel/hw_breakpoint.c F: arch/arm*/kernel/perf_* -F: arch/arm/oprofile/common.c F: drivers/perf/ F: include/linux/perf/arm_pmu.h @@ -4083,7 +4082,6 @@ W: http://www.ibm.com/developerworks/power/cell/ F: arch/powerpc/include/asm/cell*.h F: arch/powerpc/include/asm/spu*.h F: arch/powerpc/include/uapi/asm/spu*.h -F: arch/powerpc/oprofile/*cell* F: arch/powerpc/platforms/cell/ CELLWISE CW2015 BATTERY DRIVER @@ -13311,15 +13309,6 @@ S: Maintained T: git git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound.git F: sound/drivers/opl4/ -OPROFILE -M: Robert Richter -L: oprofile-list@lists.sf.net -S: Maintained -F: arch/*/include/asm/oprofile*.h -F: arch/*/oprofile/ -F: drivers/oprofile/ -F: include/linux/oprofile.h - ORACLE CLUSTER FILESYSTEM 2 (OCFS2) M: Mark Fasheh M: Joel Becker diff --git a/arch/Kconfig b/arch/Kconfig index 24862d15f3a3..40277027a255 100644 --- a/arch/Kconfig +++ b/arch/Kconfig @@ -33,38 +33,6 @@ config HOTPLUG_SMT config GENERIC_ENTRY bool -config OPROFILE - tristate "OProfile system profiling" - depends on PROFILING - depends on HAVE_OPROFILE - select RING_BUFFER - select RING_BUFFER_ALLOW_SWAP - help - OProfile is a profiling system capable of profiling the - whole system, include the kernel, kernel modules, libraries, - and applications. - - If unsure, say N. - -config OPROFILE_EVENT_MULTIPLEX - bool "OProfile multiplexing support (EXPERIMENTAL)" - default n - depends on OPROFILE && X86 - help - The number of hardware counters is limited. The multiplexing - feature enables OProfile to gather more events than counters - are provided by the hardware. This is realized by switching - between events at a user specified time interval. - - If unsure, say N. - -config HAVE_OPROFILE - bool - -config OPROFILE_NMI_TIMER - def_bool y - depends on PERF_EVENTS && HAVE_PERF_EVENTS_NMI && !PPC64 - config KPROBES bool "Kprobes" depends on MODULES diff --git a/drivers/oprofile/buffer_sync.c b/drivers/oprofile/buffer_sync.c deleted file mode 100644 index cc917865f13a..000000000000 --- a/drivers/oprofile/buffer_sync.c +++ /dev/null @@ -1,591 +0,0 @@ -/** - * @file buffer_sync.c - * - * @remark Copyright 2002-2009 OProfile authors - * @remark Read the file COPYING - * - * @author John Levon - * @author Barry Kasindorf - * @author Robert Richter - * - * This is the core of the buffer management. Each - * CPU buffer is processed and entered into the - * global event buffer. Such processing is necessary - * in several circumstances, mentioned below. - * - * The processing does the job of converting the - * transitory EIP value into a persistent dentry/offset - * value that the profiler can record at its leisure. - * - * See fs/dcookies.c for a description of the dentry/offset - * objects. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "oprofile_stats.h" -#include "event_buffer.h" -#include "cpu_buffer.h" -#include "buffer_sync.h" - -static LIST_HEAD(dying_tasks); -static LIST_HEAD(dead_tasks); -static cpumask_var_t marked_cpus; -static DEFINE_SPINLOCK(task_mortuary); -static void process_task_mortuary(void); - -/* Take ownership of the task struct and place it on the - * list for processing. Only after two full buffer syncs - * does the task eventually get freed, because by then - * we are sure we will not reference it again. - * Can be invoked from softirq via RCU callback due to - * call_rcu() of the task struct, hence the _irqsave. - */ -static int -task_free_notify(struct notifier_block *self, unsigned long val, void *data) -{ - unsigned long flags; - struct task_struct *task = data; - spin_lock_irqsave(&task_mortuary, flags); - list_add(&task->tasks, &dying_tasks); - spin_unlock_irqrestore(&task_mortuary, flags); - return NOTIFY_OK; -} - - -/* The task is on its way out. A sync of the buffer means we can catch - * any remaining samples for this task. - */ -static int -task_exit_notify(struct notifier_block *self, unsigned long val, void *data) -{ - /* To avoid latency problems, we only process the current CPU, - * hoping that most samples for the task are on this CPU - */ - sync_buffer(raw_smp_processor_id()); - return 0; -} - - -/* The task is about to try a do_munmap(). We peek at what it's going to - * do, and if it's an executable region, process the samples first, so - * we don't lose any. This does not have to be exact, it's a QoI issue - * only. - */ -static int -munmap_notify(struct notifier_block *self, unsigned long val, void *data) -{ - unsigned long addr = (unsigned long)data; - struct mm_struct *mm = current->mm; - struct vm_area_struct *mpnt; - - mmap_read_lock(mm); - - mpnt = find_vma(mm, addr); - if (mpnt && mpnt->vm_file && (mpnt->vm_flags & VM_EXEC)) { - mmap_read_unlock(mm); - /* To avoid latency problems, we only process the current CPU, - * hoping that most samples for the task are on this CPU - */ - sync_buffer(raw_smp_processor_id()); - return 0; - } - - mmap_read_unlock(mm); - return 0; -} - - -/* We need to be told about new modules so we don't attribute to a previously - * loaded module, or drop the samples on the floor. - */ -static int -module_load_notify(struct notifier_block *self, unsigned long val, void *data) -{ -#ifdef CONFIG_MODULES - if (val != MODULE_STATE_COMING) - return NOTIFY_DONE; - - /* FIXME: should we process all CPU buffers ? */ - mutex_lock(&buffer_mutex); - add_event_entry(ESCAPE_CODE); - add_event_entry(MODULE_LOADED_CODE); - mutex_unlock(&buffer_mutex); -#endif - return NOTIFY_OK; -} - - -static struct notifier_block task_free_nb = { - .notifier_call = task_free_notify, -}; - -static struct notifier_block task_exit_nb = { - .notifier_call = task_exit_notify, -}; - -static struct notifier_block munmap_nb = { - .notifier_call = munmap_notify, -}; - -static struct notifier_block module_load_nb = { - .notifier_call = module_load_notify, -}; - -static void free_all_tasks(void) -{ - /* make sure we don't leak task structs */ - process_task_mortuary(); - process_task_mortuary(); -} - -int sync_start(void) -{ - int err; - - if (!zalloc_cpumask_var(&marked_cpus, GFP_KERNEL)) - return -ENOMEM; - - err = task_handoff_register(&task_free_nb); - if (err) - goto out1; - err = profile_event_register(PROFILE_TASK_EXIT, &task_exit_nb); - if (err) - goto out2; - err = profile_event_register(PROFILE_MUNMAP, &munmap_nb); - if (err) - goto out3; - err = register_module_notifier(&module_load_nb); - if (err) - goto out4; - - start_cpu_work(); - -out: - return err; -out4: - profile_event_unregister(PROFILE_MUNMAP, &munmap_nb); -out3: - profile_event_unregister(PROFILE_TASK_EXIT, &task_exit_nb); -out2: - task_handoff_unregister(&task_free_nb); - free_all_tasks(); -out1: - free_cpumask_var(marked_cpus); - goto out; -} - - -void sync_stop(void) -{ - end_cpu_work(); - unregister_module_notifier(&module_load_nb); - profile_event_unregister(PROFILE_MUNMAP, &munmap_nb); - profile_event_unregister(PROFILE_TASK_EXIT, &task_exit_nb); - task_handoff_unregister(&task_free_nb); - barrier(); /* do all of the above first */ - - flush_cpu_work(); - - free_all_tasks(); - free_cpumask_var(marked_cpus); -} - - -/* Optimisation. We can manage without taking the dcookie sem - * because we cannot reach this code without at least one - * dcookie user still being registered (namely, the reader - * of the event buffer). */ -static inline unsigned long fast_get_dcookie(const struct path *path) -{ - unsigned long cookie; - - if (path->dentry->d_flags & DCACHE_COOKIE) - return (unsigned long)path->dentry; - get_dcookie(path, &cookie); - return cookie; -} - - -/* Look up the dcookie for the task's mm->exe_file, - * which corresponds loosely to "application name". This is - * not strictly necessary but allows oprofile to associate - * shared-library samples with particular applications - */ -static unsigned long get_exec_dcookie(struct mm_struct *mm) -{ - unsigned long cookie = NO_COOKIE; - struct file *exe_file; - - if (!mm) - goto done; - - exe_file = get_mm_exe_file(mm); - if (!exe_file) - goto done; - - cookie = fast_get_dcookie(&exe_file->f_path); - fput(exe_file); -done: - return cookie; -} - - -/* Convert the EIP value of a sample into a persistent dentry/offset - * pair that can then be added to the global event buffer. We make - * sure to do this lookup before a mm->mmap modification happens so - * we don't lose track. - * - * The caller must ensure the mm is not nil (ie: not a kernel thread). - */ -static unsigned long -lookup_dcookie(struct mm_struct *mm, unsigned long addr, off_t *offset) -{ - unsigned long cookie = NO_COOKIE; - struct vm_area_struct *vma; - - mmap_read_lock(mm); - for (vma = find_vma(mm, addr); vma; vma = vma->vm_next) { - - if (addr < vma->vm_start || addr >= vma->vm_end) - continue; - - if (vma->vm_file) { - cookie = fast_get_dcookie(&vma->vm_file->f_path); - *offset = (vma->vm_pgoff << PAGE_SHIFT) + addr - - vma->vm_start; - } else { - /* must be an anonymous map */ - *offset = addr; - } - - break; - } - - if (!vma) - cookie = INVALID_COOKIE; - mmap_read_unlock(mm); - - return cookie; -} - -static unsigned long last_cookie = INVALID_COOKIE; - -static void add_cpu_switch(int i) -{ - add_event_entry(ESCAPE_CODE); - add_event_entry(CPU_SWITCH_CODE); - add_event_entry(i); - last_cookie = INVALID_COOKIE; -} - -static void add_kernel_ctx_switch(unsigned int in_kernel) -{ - add_event_entry(ESCAPE_CODE); - if (in_kernel) - add_event_entry(KERNEL_ENTER_SWITCH_CODE); - else - add_event_entry(KERNEL_EXIT_SWITCH_CODE); -} - -static void -add_user_ctx_switch(struct task_struct const *task, unsigned long cookie) -{ - add_event_entry(ESCAPE_CODE); - add_event_entry(CTX_SWITCH_CODE); - add_event_entry(task->pid); - add_event_entry(cookie); - /* Another code for daemon back-compat */ - add_event_entry(ESCAPE_CODE); - add_event_entry(CTX_TGID_CODE); - add_event_entry(task->tgid); -} - - -static void add_cookie_switch(unsigned long cookie) -{ - add_event_entry(ESCAPE_CODE); - add_event_entry(COOKIE_SWITCH_CODE); - add_event_entry(cookie); -} - - -static void add_trace_begin(void) -{ - add_event_entry(ESCAPE_CODE); - add_event_entry(TRACE_BEGIN_CODE); -} - -static void add_data(struct op_entry *entry, struct mm_struct *mm) -{ - unsigned long code, pc, val; - unsigned long cookie; - off_t offset; - - if (!op_cpu_buffer_get_data(entry, &code)) - return; - if (!op_cpu_buffer_get_data(entry, &pc)) - return; - if (!op_cpu_buffer_get_size(entry)) - return; - - if (mm) { - cookie = lookup_dcookie(mm, pc, &offset); - - if (cookie == NO_COOKIE) - offset = pc; - if (cookie == INVALID_COOKIE) { - atomic_inc(&oprofile_stats.sample_lost_no_mapping); - offset = pc; - } - if (cookie != last_cookie) { - add_cookie_switch(cookie); - last_cookie = cookie; - } - } else - offset = pc; - - add_event_entry(ESCAPE_CODE); - add_event_entry(code); - add_event_entry(offset); /* Offset from Dcookie */ - - while (op_cpu_buffer_get_data(entry, &val)) - add_event_entry(val); -} - -static inline void add_sample_entry(unsigned long offset, unsigned long event) -{ - add_event_entry(offset); - add_event_entry(event); -} - - -/* - * Add a sample to the global event buffer. If possible the - * sample is converted into a persistent dentry/offset pair - * for later lookup from userspace. Return 0 on failure. - */ -static int -add_sample(struct mm_struct *mm, struct op_sample *s, int in_kernel) -{ - unsigned long cookie; - off_t offset; - - if (in_kernel) { - add_sample_entry(s->eip, s->event); - return 1; - } - - /* add userspace sample */ - - if (!mm) { - atomic_inc(&oprofile_stats.sample_lost_no_mm); - return 0; - } - - cookie = lookup_dcookie(mm, s->eip, &offset); - - if (cookie == INVALID_COOKIE) { - atomic_inc(&oprofile_stats.sample_lost_no_mapping); - return 0; - } - - if (cookie != last_cookie) { - add_cookie_switch(cookie); - last_cookie = cookie; - } - - add_sample_entry(offset, s->event); - - return 1; -} - - -static void release_mm(struct mm_struct *mm) -{ - if (!mm) - return; - mmput(mm); -} - -static inline int is_code(unsigned long val) -{ - return val == ESCAPE_CODE; -} - - -/* Move tasks along towards death. Any tasks on dead_tasks - * will definitely have no remaining references in any - * CPU buffers at this point, because we use two lists, - * and to have reached the list, it must have gone through - * one full sync already. - */ -static void process_task_mortuary(void) -{ - unsigned long flags; - LIST_HEAD(local_dead_tasks); - struct task_struct *task; - struct task_struct *ttask; - - spin_lock_irqsave(&task_mortuary, flags); - - list_splice_init(&dead_tasks, &local_dead_tasks); - list_splice_init(&dying_tasks, &dead_tasks); - - spin_unlock_irqrestore(&task_mortuary, flags); - - list_for_each_entry_safe(task, ttask, &local_dead_tasks, tasks) { - list_del(&task->tasks); - free_task(task); - } -} - - -static void mark_done(int cpu) -{ - int i; - - cpumask_set_cpu(cpu, marked_cpus); - - for_each_online_cpu(i) { - if (!cpumask_test_cpu(i, marked_cpus)) - return; - } - - /* All CPUs have been processed at least once, - * we can process the mortuary once - */ - process_task_mortuary(); - - cpumask_clear(marked_cpus); -} - - -/* FIXME: this is not sufficient if we implement syscall barrier backtrace - * traversal, the code switch to sb_sample_start at first kernel enter/exit - * switch so we need a fifth state and some special handling in sync_buffer() - */ -typedef enum { - sb_bt_ignore = -2, - sb_buffer_start, - sb_bt_start, - sb_sample_start, -} sync_buffer_state; - -/* Sync one of the CPU's buffers into the global event buffer. - * Here we need to go through each batch of samples punctuated - * by context switch notes, taking the task's mmap_lock and doing - * lookup in task->mm->mmap to convert EIP into dcookie/offset - * value. - */ -void sync_buffer(int cpu) -{ - struct mm_struct *mm = NULL; - struct mm_struct *oldmm; - unsigned long val; - struct task_struct *new; - unsigned long cookie = 0; - int in_kernel = 1; - sync_buffer_state state = sb_buffer_start; - unsigned int i; - unsigned long available; - unsigned long flags; - struct op_entry entry; - struct op_sample *sample; - - mutex_lock(&buffer_mutex); - - add_cpu_switch(cpu); - - op_cpu_buffer_reset(cpu); - available = op_cpu_buffer_entries(cpu); - - for (i = 0; i < available; ++i) { - sample = op_cpu_buffer_read_entry(&entry, cpu); - if (!sample) - break; - - if (is_code(sample->eip)) { - flags = sample->event; - if (flags & TRACE_BEGIN) { - state = sb_bt_start; - add_trace_begin(); - } - if (flags & KERNEL_CTX_SWITCH) { - /* kernel/userspace switch */ - in_kernel = flags & IS_KERNEL; - if (state == sb_buffer_start) - state = sb_sample_start; - add_kernel_ctx_switch(flags & IS_KERNEL); - } - if (flags & USER_CTX_SWITCH - && op_cpu_buffer_get_data(&entry, &val)) { - /* userspace context switch */ - new = (struct task_struct *)val; - oldmm = mm; - release_mm(oldmm); - mm = get_task_mm(new); - if (mm != oldmm) - cookie = get_exec_dcookie(mm); - add_user_ctx_switch(new, cookie); - } - if (op_cpu_buffer_get_size(&entry)) - add_data(&entry, mm); - continue; - } - - if (state < sb_bt_start) - /* ignore sample */ - continue; - - if (add_sample(mm, sample, in_kernel)) - continue; - - /* ignore backtraces if failed to add a sample */ - if (state == sb_bt_start) { - state = sb_bt_ignore; - atomic_inc(&oprofile_stats.bt_lost_no_mapping); - } - } - release_mm(mm); - - mark_done(cpu); - - mutex_unlock(&buffer_mutex); -} - -/* The function can be used to add a buffer worth of data directly to - * the kernel buffer. The buffer is assumed to be a circular buffer. - * Take the entries from index start and end at index end, wrapping - * at max_entries. - */ -void oprofile_put_buff(unsigned long *buf, unsigned int start, - unsigned int stop, unsigned int max) -{ - int i; - - i = start; - - mutex_lock(&buffer_mutex); - while (i != stop) { - add_event_entry(buf[i++]); - - if (i >= max) - i = 0; - } - - mutex_unlock(&buffer_mutex); -} - diff --git a/drivers/oprofile/buffer_sync.h b/drivers/oprofile/buffer_sync.h deleted file mode 100644 index 3110732c1835..000000000000 --- a/drivers/oprofile/buffer_sync.h +++ /dev/null @@ -1,22 +0,0 @@ -/** - * @file buffer_sync.h - * - * @remark Copyright 2002 OProfile authors - * @remark Read the file COPYING - * - * @author John Levon - */ - -#ifndef OPROFILE_BUFFER_SYNC_H -#define OPROFILE_BUFFER_SYNC_H - -/* add the necessary profiling hooks */ -int sync_start(void); - -/* remove the hooks */ -void sync_stop(void); - -/* sync the given CPU's buffer */ -void sync_buffer(int cpu); - -#endif /* OPROFILE_BUFFER_SYNC_H */ diff --git a/drivers/oprofile/cpu_buffer.c b/drivers/oprofile/cpu_buffer.c deleted file mode 100644 index 9210a95cb4e6..000000000000 --- a/drivers/oprofile/cpu_buffer.c +++ /dev/null @@ -1,465 +0,0 @@ -/** - * @file cpu_buffer.c - * - * @remark Copyright 2002-2009 OProfile authors - * @remark Read the file COPYING - * - * @author John Levon - * @author Barry Kasindorf - * @author Robert Richter - * - * Each CPU has a local buffer that stores PC value/event - * pairs. We also log context switches when we notice them. - * Eventually each CPU's buffer is processed into the global - * event buffer by sync_buffer(). - * - * We use a local buffer for two reasons: an NMI or similar - * interrupt cannot synchronise, and high sampling rates - * would lead to catastrophic global synchronisation if - * a global buffer was used. - */ - -#include -#include -#include - -#include - -#include "event_buffer.h" -#include "cpu_buffer.h" -#include "buffer_sync.h" -#include "oprof.h" - -#define OP_BUFFER_FLAGS 0 - -static struct trace_buffer *op_ring_buffer; -DEFINE_PER_CPU(struct oprofile_cpu_buffer, op_cpu_buffer); - -static void wq_sync_buffer(struct work_struct *work); - -#define DEFAULT_TIMER_EXPIRE (HZ / 10) -static int work_enabled; - -unsigned long oprofile_get_cpu_buffer_size(void) -{ - return oprofile_cpu_buffer_size; -} - -void oprofile_cpu_buffer_inc_smpl_lost(void) -{ - struct oprofile_cpu_buffer *cpu_buf = this_cpu_ptr(&op_cpu_buffer); - - cpu_buf->sample_lost_overflow++; -} - -void free_cpu_buffers(void) -{ - if (op_ring_buffer) - ring_buffer_free(op_ring_buffer); - op_ring_buffer = NULL; -} - -#define RB_EVENT_HDR_SIZE 4 - -int alloc_cpu_buffers(void) -{ - int i; - - unsigned long buffer_size = oprofile_cpu_buffer_size; - unsigned long byte_size = buffer_size * (sizeof(struct op_sample) + - RB_EVENT_HDR_SIZE); - - op_ring_buffer = ring_buffer_alloc(byte_size, OP_BUFFER_FLAGS); - if (!op_ring_buffer) - goto fail; - - for_each_possible_cpu(i) { - struct oprofile_cpu_buffer *b = &per_cpu(op_cpu_buffer, i); - - b->last_task = NULL; - b->last_is_kernel = -1; - b->tracing = 0; - b->buffer_size = buffer_size; - b->sample_received = 0; - b->sample_lost_overflow = 0; - b->backtrace_aborted = 0; - b->sample_invalid_eip = 0; - b->cpu = i; - INIT_DELAYED_WORK(&b->work, wq_sync_buffer); - } - return 0; - -fail: - free_cpu_buffers(); - return -ENOMEM; -} - -void start_cpu_work(void) -{ - int i; - - work_enabled = 1; - - for_each_online_cpu(i) { - struct oprofile_cpu_buffer *b = &per_cpu(op_cpu_buffer, i); - - /* - * Spread the work by 1 jiffy per cpu so they dont all - * fire at once. - */ - schedule_delayed_work_on(i, &b->work, DEFAULT_TIMER_EXPIRE + i); - } -} - -void end_cpu_work(void) -{ - work_enabled = 0; -} - -void flush_cpu_work(void) -{ - int i; - - for_each_online_cpu(i) { - struct oprofile_cpu_buffer *b = &per_cpu(op_cpu_buffer, i); - - /* these works are per-cpu, no need for flush_sync */ - flush_delayed_work(&b->work); - } -} - -/* - * This function prepares the cpu buffer to write a sample. - * - * Struct op_entry is used during operations on the ring buffer while - * struct op_sample contains the data that is stored in the ring - * buffer. Struct entry can be uninitialized. The function reserves a - * data array that is specified by size. Use - * op_cpu_buffer_write_commit() after preparing the sample. In case of - * errors a null pointer is returned, otherwise the pointer to the - * sample. - * - */ -struct op_sample -*op_cpu_buffer_write_reserve(struct op_entry *entry, unsigned long size) -{ - entry->event = ring_buffer_lock_reserve - (op_ring_buffer, sizeof(struct op_sample) + - size * sizeof(entry->sample->data[0])); - if (!entry->event) - return NULL; - entry->sample = ring_buffer_event_data(entry->event); - entry->size = size; - entry->data = entry->sample->data; - - return entry->sample; -} - -int op_cpu_buffer_write_commit(struct op_entry *entry) -{ - return ring_buffer_unlock_commit(op_ring_buffer, entry->event); -} - -struct op_sample *op_cpu_buffer_read_entry(struct op_entry *entry, int cpu) -{ - struct ring_buffer_event *e; - e = ring_buffer_consume(op_ring_buffer, cpu, NULL, NULL); - if (!e) - return NULL; - - entry->event = e; - entry->sample = ring_buffer_event_data(e); - entry->size = (ring_buffer_event_length(e) - sizeof(struct op_sample)) - / sizeof(entry->sample->data[0]); - entry->data = entry->sample->data; - return entry->sample; -} - -unsigned long op_cpu_buffer_entries(int cpu) -{ - return ring_buffer_entries_cpu(op_ring_buffer, cpu); -} - -static int -op_add_code(struct oprofile_cpu_buffer *cpu_buf, unsigned long backtrace, - int is_kernel, struct task_struct *task) -{ - struct op_entry entry; - struct op_sample *sample; - unsigned long flags; - int size; - - flags = 0; - - if (backtrace) - flags |= TRACE_BEGIN; - - /* notice a switch from user->kernel or vice versa */ - is_kernel = !!is_kernel; - if (cpu_buf->last_is_kernel != is_kernel) { - cpu_buf->last_is_kernel = is_kernel; - flags |= KERNEL_CTX_SWITCH; - if (is_kernel) - flags |= IS_KERNEL; - } - - /* notice a task switch */ - if (cpu_buf->last_task != task) { - cpu_buf->last_task = task; - flags |= USER_CTX_SWITCH; - } - - if (!flags) - /* nothing to do */ - return 0; - - if (flags & USER_CTX_SWITCH) - size = 1; - else - size = 0; - - sample = op_cpu_buffer_write_reserve(&entry, size); - if (!sample) - return -ENOMEM; - - sample->eip = ESCAPE_CODE; - sample->event = flags; - - if (size) - op_cpu_buffer_add_data(&entry, (unsigned long)task); - - op_cpu_buffer_write_commit(&entry); - - return 0; -} - -static inline int -op_add_sample(struct oprofile_cpu_buffer *cpu_buf, - unsigned long pc, unsigned long event) -{ - struct op_entry entry; - struct op_sample *sample; - - sample = op_cpu_buffer_write_reserve(&entry, 0); - if (!sample) - return -ENOMEM; - - sample->eip = pc; - sample->event = event; - - return op_cpu_buffer_write_commit(&entry); -} - -/* - * This must be safe from any context. - * - * is_kernel is needed because on some architectures you cannot - * tell if you are in kernel or user space simply by looking at - * pc. We tag this in the buffer by generating kernel enter/exit - * events whenever is_kernel changes - */ -static int -log_sample(struct oprofile_cpu_buffer *cpu_buf, unsigned long pc, - unsigned long backtrace, int is_kernel, unsigned long event, - struct task_struct *task) -{ - struct task_struct *tsk = task ? task : current; - cpu_buf->sample_received++; - - if (pc == ESCAPE_CODE) { - cpu_buf->sample_invalid_eip++; - return 0; - } - - if (op_add_code(cpu_buf, backtrace, is_kernel, tsk)) - goto fail; - - if (op_add_sample(cpu_buf, pc, event)) - goto fail; - - return 1; - -fail: - cpu_buf->sample_lost_overflow++; - return 0; -} - -static inline void oprofile_begin_trace(struct oprofile_cpu_buffer *cpu_buf) -{ - cpu_buf->tracing = 1; -} - -static inline void oprofile_end_trace(struct oprofile_cpu_buffer *cpu_buf) -{ - cpu_buf->tracing = 0; -} - -static inline void -__oprofile_add_ext_sample(unsigned long pc, struct pt_regs * const regs, - unsigned long event, int is_kernel, - struct task_struct *task) -{ - struct oprofile_cpu_buffer *cpu_buf = this_cpu_ptr(&op_cpu_buffer); - unsigned long backtrace = oprofile_backtrace_depth; - - /* - * if log_sample() fail we can't backtrace since we lost the - * source of this event - */ - if (!log_sample(cpu_buf, pc, backtrace, is_kernel, event, task)) - /* failed */ - return; - - if (!backtrace) - return; - - oprofile_begin_trace(cpu_buf); - oprofile_ops.backtrace(regs, backtrace); - oprofile_end_trace(cpu_buf); -} - -void oprofile_add_ext_hw_sample(unsigned long pc, struct pt_regs * const regs, - unsigned long event, int is_kernel, - struct task_struct *task) -{ - __oprofile_add_ext_sample(pc, regs, event, is_kernel, task); -} - -void oprofile_add_ext_sample(unsigned long pc, struct pt_regs * const regs, - unsigned long event, int is_kernel) -{ - __oprofile_add_ext_sample(pc, regs, event, is_kernel, NULL); -} - -void oprofile_add_sample(struct pt_regs * const regs, unsigned long event) -{ - int is_kernel; - unsigned long pc; - - if (likely(regs)) { - is_kernel = !user_mode(regs); - pc = profile_pc(regs); - } else { - is_kernel = 0; /* This value will not be used */ - pc = ESCAPE_CODE; /* as this causes an early return. */ - } - - __oprofile_add_ext_sample(pc, regs, event, is_kernel, NULL); -} - -/* - * Add samples with data to the ring buffer. - * - * Use oprofile_add_data(&entry, val) to add data and - * oprofile_write_commit(&entry) to commit the sample. - */ -void -oprofile_write_reserve(struct op_entry *entry, struct pt_regs * const regs, - unsigned long pc, int code, int size) -{ - struct op_sample *sample; - int is_kernel = !user_mode(regs); - struct oprofile_cpu_buffer *cpu_buf = this_cpu_ptr(&op_cpu_buffer); - - cpu_buf->sample_received++; - - /* no backtraces for samples with data */ - if (op_add_code(cpu_buf, 0, is_kernel, current)) - goto fail; - - sample = op_cpu_buffer_write_reserve(entry, size + 2); - if (!sample) - goto fail; - sample->eip = ESCAPE_CODE; - sample->event = 0; /* no flags */ - - op_cpu_buffer_add_data(entry, code); - op_cpu_buffer_add_data(entry, pc); - - return; - -fail: - entry->event = NULL; - cpu_buf->sample_lost_overflow++; -} - -int oprofile_add_data(struct op_entry *entry, unsigned long val) -{ - if (!entry->event) - return 0; - return op_cpu_buffer_add_data(entry, val); -} - -int oprofile_add_data64(struct op_entry *entry, u64 val) -{ - if (!entry->event) - return 0; - if (op_cpu_buffer_get_size(entry) < 2) - /* - * the function returns 0 to indicate a too small - * buffer, even if there is some space left - */ - return 0; - if (!op_cpu_buffer_add_data(entry, (u32)val)) - return 0; - return op_cpu_buffer_add_data(entry, (u32)(val >> 32)); -} - -int oprofile_write_commit(struct op_entry *entry) -{ - if (!entry->event) - return -EINVAL; - return op_cpu_buffer_write_commit(entry); -} - -void oprofile_add_pc(unsigned long pc, int is_kernel, unsigned long event) -{ - struct oprofile_cpu_buffer *cpu_buf = this_cpu_ptr(&op_cpu_buffer); - log_sample(cpu_buf, pc, 0, is_kernel, event, NULL); -} - -void oprofile_add_trace(unsigned long pc) -{ - struct oprofile_cpu_buffer *cpu_buf = this_cpu_ptr(&op_cpu_buffer); - - if (!cpu_buf->tracing) - return; - - /* - * broken frame can give an eip with the same value as an - * escape code, abort the trace if we get it - */ - if (pc == ESCAPE_CODE) - goto fail; - - if (op_add_sample(cpu_buf, pc, 0)) - goto fail; - - return; -fail: - cpu_buf->tracing = 0; - cpu_buf->backtrace_aborted++; - return; -} - -/* - * This serves to avoid cpu buffer overflow, and makes sure - * the task mortuary progresses - * - * By using schedule_delayed_work_on and then schedule_delayed_work - * we guarantee this will stay on the correct cpu - */ -static void wq_sync_buffer(struct work_struct *work) -{ - struct oprofile_cpu_buffer *b = - container_of(work, struct oprofile_cpu_buffer, work.work); - if (b->cpu != smp_processor_id() && !cpu_online(b->cpu)) { - cancel_delayed_work(&b->work); - return; - } - sync_buffer(b->cpu); - - /* don't re-add the work if we're shutting down */ - if (work_enabled) - schedule_delayed_work(&b->work, DEFAULT_TIMER_EXPIRE); -} diff --git a/drivers/oprofile/cpu_buffer.h b/drivers/oprofile/cpu_buffer.h deleted file mode 100644 index 31478c0cff87..000000000000 --- a/drivers/oprofile/cpu_buffer.h +++ /dev/null @@ -1,121 +0,0 @@ -/** - * @file cpu_buffer.h - * - * @remark Copyright 2002-2009 OProfile authors - * @remark Read the file COPYING - * - * @author John Levon - * @author Robert Richter - */ - -#ifndef OPROFILE_CPU_BUFFER_H -#define OPROFILE_CPU_BUFFER_H - -#include -#include -#include -#include -#include -#include - -struct task_struct; - -int alloc_cpu_buffers(void); -void free_cpu_buffers(void); - -void start_cpu_work(void); -void end_cpu_work(void); -void flush_cpu_work(void); - -/* CPU buffer is composed of such entries (which are - * also used for context switch notes) - */ -struct op_sample { - unsigned long eip; - unsigned long event; - unsigned long data[]; -}; - -struct op_entry; - -struct oprofile_cpu_buffer { - unsigned long buffer_size; - struct task_struct *last_task; - int last_is_kernel; - int tracing; - unsigned long sample_received; - unsigned long sample_lost_overflow; - unsigned long backtrace_aborted; - unsigned long sample_invalid_eip; - int cpu; - struct delayed_work work; -}; - -DECLARE_PER_CPU(struct oprofile_cpu_buffer, op_cpu_buffer); - -/* - * Resets the cpu buffer to a sane state. - * - * reset these to invalid values; the next sample collected will - * populate the buffer with proper values to initialize the buffer - */ -static inline void op_cpu_buffer_reset(int cpu) -{ - struct oprofile_cpu_buffer *cpu_buf = &per_cpu(op_cpu_buffer, cpu); - - cpu_buf->last_is_kernel = -1; - cpu_buf->last_task = NULL; -} - -/* - * op_cpu_buffer_add_data() and op_cpu_buffer_write_commit() may be - * called only if op_cpu_buffer_write_reserve() did not return NULL or - * entry->event != NULL, otherwise entry->size or entry->event will be - * used uninitialized. - */ - -struct op_sample -*op_cpu_buffer_write_reserve(struct op_entry *entry, unsigned long size); -int op_cpu_buffer_write_commit(struct op_entry *entry); -struct op_sample *op_cpu_buffer_read_entry(struct op_entry *entry, int cpu); -unsigned long op_cpu_buffer_entries(int cpu); - -/* returns the remaining free size of data in the entry */ -static inline -int op_cpu_buffer_add_data(struct op_entry *entry, unsigned long val) -{ - if (!entry->size) - return 0; - *entry->data = val; - entry->size--; - entry->data++; - return entry->size; -} - -/* returns the size of data in the entry */ -static inline -int op_cpu_buffer_get_size(struct op_entry *entry) -{ - return entry->size; -} - -/* returns 0 if empty or the size of data including the current value */ -static inline -int op_cpu_buffer_get_data(struct op_entry *entry, unsigned long *val) -{ - int size = entry->size; - if (!size) - return 0; - *val = *entry->data; - entry->size--; - entry->data++; - return size; -} - -/* extra data flags */ -#define KERNEL_CTX_SWITCH (1UL << 0) -#define IS_KERNEL (1UL << 1) -#define TRACE_BEGIN (1UL << 2) -#define USER_CTX_SWITCH (1UL << 3) - -#endif /* OPROFILE_CPU_BUFFER_H */ diff --git a/drivers/oprofile/event_buffer.c b/drivers/oprofile/event_buffer.c deleted file mode 100644 index 6c9edc8bbc95..000000000000 --- a/drivers/oprofile/event_buffer.c +++ /dev/null @@ -1,209 +0,0 @@ -/** - * @file event_buffer.c - * - * @remark Copyright 2002 OProfile authors - * @remark Read the file COPYING - * - * @author John Levon - * - * This is the global event buffer that the user-space - * daemon reads from. The event buffer is an untyped array - * of unsigned longs. Entries are prefixed by the - * escape value ESCAPE_CODE followed by an identifying code. - */ - -#include -#include -#include -#include -#include -#include -#include - -#include "oprof.h" -#include "event_buffer.h" -#include "oprofile_stats.h" - -DEFINE_MUTEX(buffer_mutex); - -static unsigned long buffer_opened; -static DECLARE_WAIT_QUEUE_HEAD(buffer_wait); -static unsigned long *event_buffer; -static unsigned long buffer_size; -static unsigned long buffer_watershed; -static size_t buffer_pos; -/* atomic_t because wait_event checks it outside of buffer_mutex */ -static atomic_t buffer_ready = ATOMIC_INIT(0); - -/* - * Add an entry to the event buffer. When we get near to the end we - * wake up the process sleeping on the read() of the file. To protect - * the event_buffer this function may only be called when buffer_mutex - * is set. - */ -void add_event_entry(unsigned long value) -{ - /* - * This shouldn't happen since all workqueues or handlers are - * canceled or flushed before the event buffer is freed. - */ - if (!event_buffer) { - WARN_ON_ONCE(1); - return; - } - - if (buffer_pos == buffer_size) { - atomic_inc(&oprofile_stats.event_lost_overflow); - return; - } - - event_buffer[buffer_pos] = value; - if (++buffer_pos == buffer_size - buffer_watershed) { - atomic_set(&buffer_ready, 1); - wake_up(&buffer_wait); - } -} - - -/* Wake up the waiting process if any. This happens - * on "echo 0 >/dev/oprofile/enable" so the daemon - * processes the data remaining in the event buffer. - */ -void wake_up_buffer_waiter(void) -{ - mutex_lock(&buffer_mutex); - atomic_set(&buffer_ready, 1); - wake_up(&buffer_wait); - mutex_unlock(&buffer_mutex); -} - - -int alloc_event_buffer(void) -{ - unsigned long flags; - - raw_spin_lock_irqsave(&oprofilefs_lock, flags); - buffer_size = oprofile_buffer_size; - buffer_watershed = oprofile_buffer_watershed; - raw_spin_unlock_irqrestore(&oprofilefs_lock, flags); - - if (buffer_watershed >= buffer_size) - return -EINVAL; - - buffer_pos = 0; - event_buffer = vmalloc(array_size(buffer_size, sizeof(unsigned long))); - if (!event_buffer) - return -ENOMEM; - - return 0; -} - - -void free_event_buffer(void) -{ - mutex_lock(&buffer_mutex); - vfree(event_buffer); - buffer_pos = 0; - event_buffer = NULL; - mutex_unlock(&buffer_mutex); -} - - -static int event_buffer_open(struct inode *inode, struct file *file) -{ - int err = -EPERM; - - if (!perfmon_capable()) - return -EPERM; - - if (test_and_set_bit_lock(0, &buffer_opened)) - return -EBUSY; - - /* Register as a user of dcookies - * to ensure they persist for the lifetime of - * the open event file - */ - err = -EINVAL; - file->private_data = dcookie_register(); - if (!file->private_data) - goto out; - - if ((err = oprofile_setup())) - goto fail; - - /* NB: the actual start happens from userspace - * echo 1 >/dev/oprofile/enable - */ - - return nonseekable_open(inode, file); - -fail: - dcookie_unregister(file->private_data); -out: - __clear_bit_unlock(0, &buffer_opened); - return err; -} - - -static int event_buffer_release(struct inode *inode, struct file *file) -{ - oprofile_stop(); - oprofile_shutdown(); - dcookie_unregister(file->private_data); - buffer_pos = 0; - atomic_set(&buffer_ready, 0); - __clear_bit_unlock(0, &buffer_opened); - return 0; -} - - -static ssize_t event_buffer_read(struct file *file, char __user *buf, - size_t count, loff_t *offset) -{ - int retval = -EINVAL; - size_t const max = buffer_size * sizeof(unsigned long); - - /* handling partial reads is more trouble than it's worth */ - if (count != max || *offset) - return -EINVAL; - - wait_event_interruptible(buffer_wait, atomic_read(&buffer_ready)); - - if (signal_pending(current)) - return -EINTR; - - /* can't currently happen */ - if (!atomic_read(&buffer_ready)) - return -EAGAIN; - - mutex_lock(&buffer_mutex); - - /* May happen if the buffer is freed during pending reads. */ - if (!event_buffer) { - retval = -EINTR; - goto out; - } - - atomic_set(&buffer_ready, 0); - - retval = -EFAULT; - - count = buffer_pos * sizeof(unsigned long); - - if (copy_to_user(buf, event_buffer, count)) - goto out; - - retval = count; - buffer_pos = 0; - -out: - mutex_unlock(&buffer_mutex); - return retval; -} - -const struct file_operations event_buffer_fops = { - .open = event_buffer_open, - .release = event_buffer_release, - .read = event_buffer_read, - .llseek = no_llseek, -}; diff --git a/drivers/oprofile/event_buffer.h b/drivers/oprofile/event_buffer.h deleted file mode 100644 index a8d5bb3cba89..000000000000 --- a/drivers/oprofile/event_buffer.h +++ /dev/null @@ -1,40 +0,0 @@ -/** - * @file event_buffer.h - * - * @remark Copyright 2002 OProfile authors - * @remark Read the file COPYING - * - * @author John Levon - */ - -#ifndef EVENT_BUFFER_H -#define EVENT_BUFFER_H - -#include -#include - -int alloc_event_buffer(void); - -void free_event_buffer(void); - -/** - * Add data to the event buffer. - * The data passed is free-form, but typically consists of - * file offsets, dcookies, context information, and ESCAPE codes. - */ -void add_event_entry(unsigned long data); - -/* wake up the process sleeping on the event file */ -void wake_up_buffer_waiter(void); - -#define INVALID_COOKIE ~0UL -#define NO_COOKIE 0UL - -extern const struct file_operations event_buffer_fops; - -/* mutex between sync_cpu_buffers() and the - * file reading code. - */ -extern struct mutex buffer_mutex; - -#endif /* EVENT_BUFFER_H */ diff --git a/drivers/oprofile/nmi_timer_int.c b/drivers/oprofile/nmi_timer_int.c deleted file mode 100644 index f343bd96609a..000000000000 --- a/drivers/oprofile/nmi_timer_int.c +++ /dev/null @@ -1,157 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/** - * @file nmi_timer_int.c - * - * @remark Copyright 2011 Advanced Micro Devices, Inc. - * - * @author Robert Richter - */ - -#include -#include -#include -#include -#include - -#ifdef CONFIG_OPROFILE_NMI_TIMER - -static DEFINE_PER_CPU(struct perf_event *, nmi_timer_events); -static int ctr_running; - -static struct perf_event_attr nmi_timer_attr = { - .type = PERF_TYPE_HARDWARE, - .config = PERF_COUNT_HW_CPU_CYCLES, - .size = sizeof(struct perf_event_attr), - .pinned = 1, - .disabled = 1, -}; - -static void nmi_timer_callback(struct perf_event *event, - struct perf_sample_data *data, - struct pt_regs *regs) -{ - event->hw.interrupts = 0; /* don't throttle interrupts */ - oprofile_add_sample(regs, 0); -} - -static int nmi_timer_start_cpu(int cpu) -{ - struct perf_event *event = per_cpu(nmi_timer_events, cpu); - - if (!event) { - event = perf_event_create_kernel_counter(&nmi_timer_attr, cpu, NULL, - nmi_timer_callback, NULL); - if (IS_ERR(event)) - return PTR_ERR(event); - per_cpu(nmi_timer_events, cpu) = event; - } - - if (event && ctr_running) - perf_event_enable(event); - - return 0; -} - -static void nmi_timer_stop_cpu(int cpu) -{ - struct perf_event *event = per_cpu(nmi_timer_events, cpu); - - if (event && ctr_running) - perf_event_disable(event); -} - -static int nmi_timer_cpu_online(unsigned int cpu) -{ - nmi_timer_start_cpu(cpu); - return 0; -} -static int nmi_timer_cpu_predown(unsigned int cpu) -{ - nmi_timer_stop_cpu(cpu); - return 0; -} - -static int nmi_timer_start(void) -{ - int cpu; - - get_online_cpus(); - ctr_running = 1; - for_each_online_cpu(cpu) - nmi_timer_start_cpu(cpu); - put_online_cpus(); - - return 0; -} - -static void nmi_timer_stop(void) -{ - int cpu; - - get_online_cpus(); - for_each_online_cpu(cpu) - nmi_timer_stop_cpu(cpu); - ctr_running = 0; - put_online_cpus(); -} - -static enum cpuhp_state hp_online; - -static void nmi_timer_shutdown(void) -{ - struct perf_event *event; - int cpu; - - cpuhp_remove_state(hp_online); - for_each_possible_cpu(cpu) { - event = per_cpu(nmi_timer_events, cpu); - if (!event) - continue; - perf_event_disable(event); - per_cpu(nmi_timer_events, cpu) = NULL; - perf_event_release_kernel(event); - } -} - -static int nmi_timer_setup(void) -{ - int err; - u64 period; - - /* clock cycles per tick: */ - period = (u64)cpu_khz * 1000; - do_div(period, HZ); - nmi_timer_attr.sample_period = period; - - err = cpuhp_setup_state(CPUHP_AP_ONLINE_DYN, "oprofile/nmi:online", - nmi_timer_cpu_online, nmi_timer_cpu_predown); - if (err < 0) { - nmi_timer_shutdown(); - return err; - } - hp_online = err; - return 0; -} - -int __init op_nmi_timer_init(struct oprofile_operations *ops) -{ - int err = 0; - - err = nmi_timer_setup(); - if (err) - return err; - nmi_timer_shutdown(); /* only check, don't alloc */ - - ops->create_files = NULL; - ops->setup = nmi_timer_setup; - ops->shutdown = nmi_timer_shutdown; - ops->start = nmi_timer_start; - ops->stop = nmi_timer_stop; - ops->cpu_type = "timer"; - - printk(KERN_INFO "oprofile: using NMI timer interrupt.\n"); - - return 0; -} - -#endif diff --git a/drivers/oprofile/oprof.c b/drivers/oprofile/oprof.c deleted file mode 100644 index ed2c3ec07024..000000000000 --- a/drivers/oprofile/oprof.c +++ /dev/null @@ -1,286 +0,0 @@ -/** - * @file oprof.c - * - * @remark Copyright 2002 OProfile authors - * @remark Read the file COPYING - * - * @author John Levon - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -#include "oprof.h" -#include "event_buffer.h" -#include "cpu_buffer.h" -#include "buffer_sync.h" -#include "oprofile_stats.h" - -struct oprofile_operations oprofile_ops; - -unsigned long oprofile_started; -unsigned long oprofile_backtrace_depth; -static unsigned long is_setup; -static DEFINE_MUTEX(start_mutex); - -/* timer - 0 - use performance monitoring hardware if available - 1 - use the timer int mechanism regardless - */ -static int timer = 0; - -int oprofile_setup(void) -{ - int err; - - mutex_lock(&start_mutex); - - if ((err = alloc_cpu_buffers())) - goto out; - - if ((err = alloc_event_buffer())) - goto out1; - - if (oprofile_ops.setup && (err = oprofile_ops.setup())) - goto out2; - - /* Note even though this starts part of the - * profiling overhead, it's necessary to prevent - * us missing task deaths and eventually oopsing - * when trying to process the event buffer. - */ - if (oprofile_ops.sync_start) { - int sync_ret = oprofile_ops.sync_start(); - switch (sync_ret) { - case 0: - goto post_sync; - case 1: - goto do_generic; - case -1: - goto out3; - default: - goto out3; - } - } -do_generic: - if ((err = sync_start())) - goto out3; - -post_sync: - is_setup = 1; - mutex_unlock(&start_mutex); - return 0; - -out3: - if (oprofile_ops.shutdown) - oprofile_ops.shutdown(); -out2: - free_event_buffer(); -out1: - free_cpu_buffers(); -out: - mutex_unlock(&start_mutex); - return err; -} - -#ifdef CONFIG_OPROFILE_EVENT_MULTIPLEX - -static void switch_worker(struct work_struct *work); -static DECLARE_DELAYED_WORK(switch_work, switch_worker); - -static void start_switch_worker(void) -{ - if (oprofile_ops.switch_events) - schedule_delayed_work(&switch_work, oprofile_time_slice); -} - -static void stop_switch_worker(void) -{ - cancel_delayed_work_sync(&switch_work); -} - -static void switch_worker(struct work_struct *work) -{ - if (oprofile_ops.switch_events()) - return; - - atomic_inc(&oprofile_stats.multiplex_counter); - start_switch_worker(); -} - -/* User inputs in ms, converts to jiffies */ -int oprofile_set_timeout(unsigned long val_msec) -{ - int err = 0; - unsigned long time_slice; - - mutex_lock(&start_mutex); - - if (oprofile_started) { - err = -EBUSY; - goto out; - } - - if (!oprofile_ops.switch_events) { - err = -EINVAL; - goto out; - } - - time_slice = msecs_to_jiffies(val_msec); - if (time_slice == MAX_JIFFY_OFFSET) { - err = -EINVAL; - goto out; - } - - oprofile_time_slice = time_slice; - -out: - mutex_unlock(&start_mutex); - return err; - -} - -#else - -static inline void start_switch_worker(void) { } -static inline void stop_switch_worker(void) { } - -#endif - -/* Actually start profiling (echo 1>/dev/oprofile/enable) */ -int oprofile_start(void) -{ - int err = -EINVAL; - - mutex_lock(&start_mutex); - - if (!is_setup) - goto out; - - err = 0; - - if (oprofile_started) - goto out; - - oprofile_reset_stats(); - - if ((err = oprofile_ops.start())) - goto out; - - start_switch_worker(); - - oprofile_started = 1; -out: - mutex_unlock(&start_mutex); - return err; -} - - -/* echo 0>/dev/oprofile/enable */ -void oprofile_stop(void) -{ - mutex_lock(&start_mutex); - if (!oprofile_started) - goto out; - oprofile_ops.stop(); - oprofile_started = 0; - - stop_switch_worker(); - - /* wake up the daemon to read what remains */ - wake_up_buffer_waiter(); -out: - mutex_unlock(&start_mutex); -} - - -void oprofile_shutdown(void) -{ - mutex_lock(&start_mutex); - if (oprofile_ops.sync_stop) { - int sync_ret = oprofile_ops.sync_stop(); - switch (sync_ret) { - case 0: - goto post_sync; - case 1: - goto do_generic; - default: - goto post_sync; - } - } -do_generic: - sync_stop(); -post_sync: - if (oprofile_ops.shutdown) - oprofile_ops.shutdown(); - is_setup = 0; - free_event_buffer(); - free_cpu_buffers(); - mutex_unlock(&start_mutex); -} - -int oprofile_set_ulong(unsigned long *addr, unsigned long val) -{ - int err = -EBUSY; - - mutex_lock(&start_mutex); - if (!oprofile_started) { - *addr = val; - err = 0; - } - mutex_unlock(&start_mutex); - - return err; -} - -static int timer_mode; - -static int __init oprofile_init(void) -{ - int err; - - /* always init architecture to setup backtrace support */ - timer_mode = 0; - err = oprofile_arch_init(&oprofile_ops); - if (!err) { - if (!timer && !oprofilefs_register()) - return 0; - oprofile_arch_exit(); - } - - /* setup timer mode: */ - timer_mode = 1; - /* no nmi timer mode if oprofile.timer is set */ - if (timer || op_nmi_timer_init(&oprofile_ops)) { - err = oprofile_timer_init(&oprofile_ops); - if (err) - return err; - } - - return oprofilefs_register(); -} - - -static void __exit oprofile_exit(void) -{ - oprofilefs_unregister(); - if (!timer_mode) - oprofile_arch_exit(); -} - - -module_init(oprofile_init); -module_exit(oprofile_exit); - -module_param_named(timer, timer, int, 0644); -MODULE_PARM_DESC(timer, "force use of timer interrupt"); - -MODULE_LICENSE("GPL"); -MODULE_AUTHOR("John Levon "); -MODULE_DESCRIPTION("OProfile system profiler"); diff --git a/drivers/oprofile/oprof.h b/drivers/oprofile/oprof.h deleted file mode 100644 index d5412060ab0f..000000000000 --- a/drivers/oprofile/oprof.h +++ /dev/null @@ -1,50 +0,0 @@ -/** - * @file oprof.h - * - * @remark Copyright 2002 OProfile authors - * @remark Read the file COPYING - * - * @author John Levon - */ - -#ifndef OPROF_H -#define OPROF_H - -int oprofile_setup(void); -void oprofile_shutdown(void); - -int oprofilefs_register(void); -void oprofilefs_unregister(void); - -int oprofile_start(void); -void oprofile_stop(void); - -struct oprofile_operations; - -extern unsigned long oprofile_buffer_size; -extern unsigned long oprofile_cpu_buffer_size; -extern unsigned long oprofile_buffer_watershed; -extern unsigned long oprofile_time_slice; - -extern struct oprofile_operations oprofile_ops; -extern unsigned long oprofile_started; -extern unsigned long oprofile_backtrace_depth; - -struct dentry; - -void oprofile_create_files(struct dentry *root); -int oprofile_timer_init(struct oprofile_operations *ops); -#ifdef CONFIG_OPROFILE_NMI_TIMER -int op_nmi_timer_init(struct oprofile_operations *ops); -#else -static inline int op_nmi_timer_init(struct oprofile_operations *ops) -{ - return -ENODEV; -} -#endif - - -int oprofile_set_ulong(unsigned long *addr, unsigned long val); -int oprofile_set_timeout(unsigned long time); - -#endif /* OPROF_H */ diff --git a/drivers/oprofile/oprofile_files.c b/drivers/oprofile/oprofile_files.c deleted file mode 100644 index ee2cfce358b9..000000000000 --- a/drivers/oprofile/oprofile_files.c +++ /dev/null @@ -1,201 +0,0 @@ -/** - * @file oprofile_files.c - * - * @remark Copyright 2002 OProfile authors - * @remark Read the file COPYING - * - * @author John Levon - */ - -#include -#include -#include - -#include "event_buffer.h" -#include "oprofile_stats.h" -#include "oprof.h" - -#define BUFFER_SIZE_DEFAULT 131072 -#define CPU_BUFFER_SIZE_DEFAULT 8192 -#define BUFFER_WATERSHED_DEFAULT 32768 /* FIXME: tune */ -#define TIME_SLICE_DEFAULT 1 - -unsigned long oprofile_buffer_size; -unsigned long oprofile_cpu_buffer_size; -unsigned long oprofile_buffer_watershed; -unsigned long oprofile_time_slice; - -#ifdef CONFIG_OPROFILE_EVENT_MULTIPLEX - -static ssize_t timeout_read(struct file *file, char __user *buf, - size_t count, loff_t *offset) -{ - return oprofilefs_ulong_to_user(jiffies_to_msecs(oprofile_time_slice), - buf, count, offset); -} - - -static ssize_t timeout_write(struct file *file, char const __user *buf, - size_t count, loff_t *offset) -{ - unsigned long val; - int retval; - - if (*offset) - return -EINVAL; - - retval = oprofilefs_ulong_from_user(&val, buf, count); - if (retval <= 0) - return retval; - - retval = oprofile_set_timeout(val); - - if (retval) - return retval; - return count; -} - - -static const struct file_operations timeout_fops = { - .read = timeout_read, - .write = timeout_write, - .llseek = default_llseek, -}; - -#endif - - -static ssize_t depth_read(struct file *file, char __user *buf, size_t count, loff_t *offset) -{ - return oprofilefs_ulong_to_user(oprofile_backtrace_depth, buf, count, - offset); -} - - -static ssize_t depth_write(struct file *file, char const __user *buf, size_t count, loff_t *offset) -{ - unsigned long val; - int retval; - - if (*offset) - return -EINVAL; - - if (!oprofile_ops.backtrace) - return -EINVAL; - - retval = oprofilefs_ulong_from_user(&val, buf, count); - if (retval <= 0) - return retval; - - retval = oprofile_set_ulong(&oprofile_backtrace_depth, val); - if (retval) - return retval; - - return count; -} - - -static const struct file_operations depth_fops = { - .read = depth_read, - .write = depth_write, - .llseek = default_llseek, -}; - - -static ssize_t pointer_size_read(struct file *file, char __user *buf, size_t count, loff_t *offset) -{ - return oprofilefs_ulong_to_user(sizeof(void *), buf, count, offset); -} - - -static const struct file_operations pointer_size_fops = { - .read = pointer_size_read, - .llseek = default_llseek, -}; - - -static ssize_t cpu_type_read(struct file *file, char __user *buf, size_t count, loff_t *offset) -{ - return oprofilefs_str_to_user(oprofile_ops.cpu_type, buf, count, offset); -} - - -static const struct file_operations cpu_type_fops = { - .read = cpu_type_read, - .llseek = default_llseek, -}; - - -static ssize_t enable_read(struct file *file, char __user *buf, size_t count, loff_t *offset) -{ - return oprofilefs_ulong_to_user(oprofile_started, buf, count, offset); -} - - -static ssize_t enable_write(struct file *file, char const __user *buf, size_t count, loff_t *offset) -{ - unsigned long val; - int retval; - - if (*offset) - return -EINVAL; - - retval = oprofilefs_ulong_from_user(&val, buf, count); - if (retval <= 0) - return retval; - - retval = 0; - if (val) - retval = oprofile_start(); - else - oprofile_stop(); - - if (retval) - return retval; - return count; -} - - -static const struct file_operations enable_fops = { - .read = enable_read, - .write = enable_write, - .llseek = default_llseek, -}; - - -static ssize_t dump_write(struct file *file, char const __user *buf, size_t count, loff_t *offset) -{ - wake_up_buffer_waiter(); - return count; -} - - -static const struct file_operations dump_fops = { - .write = dump_write, - .llseek = noop_llseek, -}; - -void oprofile_create_files(struct dentry *root) -{ - /* reinitialize default values */ - oprofile_buffer_size = BUFFER_SIZE_DEFAULT; - oprofile_cpu_buffer_size = CPU_BUFFER_SIZE_DEFAULT; - oprofile_buffer_watershed = BUFFER_WATERSHED_DEFAULT; - oprofile_time_slice = msecs_to_jiffies(TIME_SLICE_DEFAULT); - - oprofilefs_create_file(root, "enable", &enable_fops); - oprofilefs_create_file_perm(root, "dump", &dump_fops, 0666); - oprofilefs_create_file(root, "buffer", &event_buffer_fops); - oprofilefs_create_ulong(root, "buffer_size", &oprofile_buffer_size); - oprofilefs_create_ulong(root, "buffer_watershed", &oprofile_buffer_watershed); - oprofilefs_create_ulong(root, "cpu_buffer_size", &oprofile_cpu_buffer_size); - oprofilefs_create_file(root, "cpu_type", &cpu_type_fops); - oprofilefs_create_file(root, "backtrace_depth", &depth_fops); - oprofilefs_create_file(root, "pointer_size", &pointer_size_fops); -#ifdef CONFIG_OPROFILE_EVENT_MULTIPLEX - oprofilefs_create_file(root, "time_slice", &timeout_fops); -#endif - oprofile_create_stats_files(root); - if (oprofile_ops.create_files) - oprofile_ops.create_files(root); -} diff --git a/drivers/oprofile/oprofile_perf.c b/drivers/oprofile/oprofile_perf.c deleted file mode 100644 index 98a63a5f8763..000000000000 --- a/drivers/oprofile/oprofile_perf.c +++ /dev/null @@ -1,328 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* - * Copyright 2010 ARM Ltd. - * Copyright 2012 Advanced Micro Devices, Inc., Robert Richter - * - * Perf-events backend for OProfile. - */ -#include -#include -#include -#include - -/* - * Per performance monitor configuration as set via oprofilefs. - */ -struct op_counter_config { - unsigned long count; - unsigned long enabled; - unsigned long event; - unsigned long unit_mask; - unsigned long kernel; - unsigned long user; - struct perf_event_attr attr; -}; - -static int oprofile_perf_enabled; -static DEFINE_MUTEX(oprofile_perf_mutex); - -static struct op_counter_config *counter_config; -static DEFINE_PER_CPU(struct perf_event **, perf_events); -static int num_counters; - -/* - * Overflow callback for oprofile. - */ -static void op_overflow_handler(struct perf_event *event, - struct perf_sample_data *data, struct pt_regs *regs) -{ - int id; - u32 cpu = smp_processor_id(); - - for (id = 0; id < num_counters; ++id) - if (per_cpu(perf_events, cpu)[id] == event) - break; - - if (id != num_counters) - oprofile_add_sample(regs, id); - else - pr_warn("oprofile: ignoring spurious overflow on cpu %u\n", - cpu); -} - -/* - * Called by oprofile_perf_setup to create perf attributes to mirror the oprofile - * settings in counter_config. Attributes are created as `pinned' events and - * so are permanently scheduled on the PMU. - */ -static void op_perf_setup(void) -{ - int i; - u32 size = sizeof(struct perf_event_attr); - struct perf_event_attr *attr; - - for (i = 0; i < num_counters; ++i) { - attr = &counter_config[i].attr; - memset(attr, 0, size); - attr->type = PERF_TYPE_RAW; - attr->size = size; - attr->config = counter_config[i].event; - attr->sample_period = counter_config[i].count; - attr->pinned = 1; - } -} - -static int op_create_counter(int cpu, int event) -{ - struct perf_event *pevent; - - if (!counter_config[event].enabled || per_cpu(perf_events, cpu)[event]) - return 0; - - pevent = perf_event_create_kernel_counter(&counter_config[event].attr, - cpu, NULL, - op_overflow_handler, NULL); - - if (IS_ERR(pevent)) - return PTR_ERR(pevent); - - if (pevent->state != PERF_EVENT_STATE_ACTIVE) { - perf_event_release_kernel(pevent); - pr_warn("oprofile: failed to enable event %d on CPU %d\n", - event, cpu); - return -EBUSY; - } - - per_cpu(perf_events, cpu)[event] = pevent; - - return 0; -} - -static void op_destroy_counter(int cpu, int event) -{ - struct perf_event *pevent = per_cpu(perf_events, cpu)[event]; - - if (pevent) { - perf_event_release_kernel(pevent); - per_cpu(perf_events, cpu)[event] = NULL; - } -} - -/* - * Called by oprofile_perf_start to create active perf events based on the - * perviously configured attributes. - */ -static int op_perf_start(void) -{ - int cpu, event, ret = 0; - - for_each_online_cpu(cpu) { - for (event = 0; event < num_counters; ++event) { - ret = op_create_counter(cpu, event); - if (ret) - return ret; - } - } - - return ret; -} - -/* - * Called by oprofile_perf_stop at the end of a profiling run. - */ -static void op_perf_stop(void) -{ - int cpu, event; - - for_each_online_cpu(cpu) - for (event = 0; event < num_counters; ++event) - op_destroy_counter(cpu, event); -} - -static int oprofile_perf_create_files(struct dentry *root) -{ - unsigned int i; - - for (i = 0; i < num_counters; i++) { - struct dentry *dir; - char buf[4]; - - snprintf(buf, sizeof buf, "%d", i); - dir = oprofilefs_mkdir(root, buf); - oprofilefs_create_ulong(dir, "enabled", &counter_config[i].enabled); - oprofilefs_create_ulong(dir, "event", &counter_config[i].event); - oprofilefs_create_ulong(dir, "count", &counter_config[i].count); - oprofilefs_create_ulong(dir, "unit_mask", &counter_config[i].unit_mask); - oprofilefs_create_ulong(dir, "kernel", &counter_config[i].kernel); - oprofilefs_create_ulong(dir, "user", &counter_config[i].user); - } - - return 0; -} - -static int oprofile_perf_setup(void) -{ - raw_spin_lock(&oprofilefs_lock); - op_perf_setup(); - raw_spin_unlock(&oprofilefs_lock); - return 0; -} - -static int oprofile_perf_start(void) -{ - int ret = -EBUSY; - - mutex_lock(&oprofile_perf_mutex); - if (!oprofile_perf_enabled) { - ret = 0; - op_perf_start(); - oprofile_perf_enabled = 1; - } - mutex_unlock(&oprofile_perf_mutex); - return ret; -} - -static void oprofile_perf_stop(void) -{ - mutex_lock(&oprofile_perf_mutex); - if (oprofile_perf_enabled) - op_perf_stop(); - oprofile_perf_enabled = 0; - mutex_unlock(&oprofile_perf_mutex); -} - -#ifdef CONFIG_PM - -static int oprofile_perf_suspend(struct platform_device *dev, pm_message_t state) -{ - mutex_lock(&oprofile_perf_mutex); - if (oprofile_perf_enabled) - op_perf_stop(); - mutex_unlock(&oprofile_perf_mutex); - return 0; -} - -static int oprofile_perf_resume(struct platform_device *dev) -{ - mutex_lock(&oprofile_perf_mutex); - if (oprofile_perf_enabled && op_perf_start()) - oprofile_perf_enabled = 0; - mutex_unlock(&oprofile_perf_mutex); - return 0; -} - -static struct platform_driver oprofile_driver = { - .driver = { - .name = "oprofile-perf", - }, - .resume = oprofile_perf_resume, - .suspend = oprofile_perf_suspend, -}; - -static struct platform_device *oprofile_pdev; - -static int __init init_driverfs(void) -{ - int ret; - - ret = platform_driver_register(&oprofile_driver); - if (ret) - return ret; - - oprofile_pdev = platform_device_register_simple( - oprofile_driver.driver.name, 0, NULL, 0); - if (IS_ERR(oprofile_pdev)) { - ret = PTR_ERR(oprofile_pdev); - platform_driver_unregister(&oprofile_driver); - } - - return ret; -} - -static void exit_driverfs(void) -{ - platform_device_unregister(oprofile_pdev); - platform_driver_unregister(&oprofile_driver); -} - -#else - -static inline int init_driverfs(void) { return 0; } -static inline void exit_driverfs(void) { } - -#endif /* CONFIG_PM */ - -void oprofile_perf_exit(void) -{ - int cpu, id; - struct perf_event *event; - - for_each_possible_cpu(cpu) { - for (id = 0; id < num_counters; ++id) { - event = per_cpu(perf_events, cpu)[id]; - if (event) - perf_event_release_kernel(event); - } - - kfree(per_cpu(perf_events, cpu)); - } - - kfree(counter_config); - exit_driverfs(); -} - -int __init oprofile_perf_init(struct oprofile_operations *ops) -{ - int cpu, ret = 0; - - ret = init_driverfs(); - if (ret) - return ret; - - num_counters = perf_num_counters(); - if (num_counters <= 0) { - pr_info("oprofile: no performance counters\n"); - ret = -ENODEV; - goto out; - } - - counter_config = kcalloc(num_counters, - sizeof(struct op_counter_config), GFP_KERNEL); - - if (!counter_config) { - pr_info("oprofile: failed to allocate %d " - "counters\n", num_counters); - ret = -ENOMEM; - num_counters = 0; - goto out; - } - - for_each_possible_cpu(cpu) { - per_cpu(perf_events, cpu) = kcalloc(num_counters, - sizeof(struct perf_event *), GFP_KERNEL); - if (!per_cpu(perf_events, cpu)) { - pr_info("oprofile: failed to allocate %d perf events " - "for cpu %d\n", num_counters, cpu); - ret = -ENOMEM; - goto out; - } - } - - ops->create_files = oprofile_perf_create_files; - ops->setup = oprofile_perf_setup; - ops->start = oprofile_perf_start; - ops->stop = oprofile_perf_stop; - ops->shutdown = oprofile_perf_stop; - ops->cpu_type = op_name_from_perf_id(); - - if (!ops->cpu_type) - ret = -ENODEV; - else - pr_info("oprofile: using %s\n", ops->cpu_type); - -out: - if (ret) - oprofile_perf_exit(); - - return ret; -} diff --git a/drivers/oprofile/oprofile_stats.c b/drivers/oprofile/oprofile_stats.c deleted file mode 100644 index 59659cea4582..000000000000 --- a/drivers/oprofile/oprofile_stats.c +++ /dev/null @@ -1,84 +0,0 @@ -/** - * @file oprofile_stats.c - * - * @remark Copyright 2002 OProfile authors - * @remark Read the file COPYING - * - * @author John Levon - */ - -#include -#include -#include -#include - -#include "oprofile_stats.h" -#include "cpu_buffer.h" - -struct oprofile_stat_struct oprofile_stats; - -void oprofile_reset_stats(void) -{ - struct oprofile_cpu_buffer *cpu_buf; - int i; - - for_each_possible_cpu(i) { - cpu_buf = &per_cpu(op_cpu_buffer, i); - cpu_buf->sample_received = 0; - cpu_buf->sample_lost_overflow = 0; - cpu_buf->backtrace_aborted = 0; - cpu_buf->sample_invalid_eip = 0; - } - - atomic_set(&oprofile_stats.sample_lost_no_mm, 0); - atomic_set(&oprofile_stats.sample_lost_no_mapping, 0); - atomic_set(&oprofile_stats.event_lost_overflow, 0); - atomic_set(&oprofile_stats.bt_lost_no_mapping, 0); - atomic_set(&oprofile_stats.multiplex_counter, 0); -} - - -void oprofile_create_stats_files(struct dentry *root) -{ - struct oprofile_cpu_buffer *cpu_buf; - struct dentry *cpudir; - struct dentry *dir; - char buf[10]; - int i; - - dir = oprofilefs_mkdir(root, "stats"); - if (!dir) - return; - - for_each_possible_cpu(i) { - cpu_buf = &per_cpu(op_cpu_buffer, i); - snprintf(buf, 10, "cpu%d", i); - cpudir = oprofilefs_mkdir(dir, buf); - - /* Strictly speaking access to these ulongs is racy, - * but we can't simply lock them, and they are - * informational only. - */ - oprofilefs_create_ro_ulong(cpudir, "sample_received", - &cpu_buf->sample_received); - oprofilefs_create_ro_ulong(cpudir, "sample_lost_overflow", - &cpu_buf->sample_lost_overflow); - oprofilefs_create_ro_ulong(cpudir, "backtrace_aborted", - &cpu_buf->backtrace_aborted); - oprofilefs_create_ro_ulong(cpudir, "sample_invalid_eip", - &cpu_buf->sample_invalid_eip); - } - - oprofilefs_create_ro_atomic(dir, "sample_lost_no_mm", - &oprofile_stats.sample_lost_no_mm); - oprofilefs_create_ro_atomic(dir, "sample_lost_no_mapping", - &oprofile_stats.sample_lost_no_mapping); - oprofilefs_create_ro_atomic(dir, "event_lost_overflow", - &oprofile_stats.event_lost_overflow); - oprofilefs_create_ro_atomic(dir, "bt_lost_no_mapping", - &oprofile_stats.bt_lost_no_mapping); -#ifdef CONFIG_OPROFILE_EVENT_MULTIPLEX - oprofilefs_create_ro_atomic(dir, "multiplex_counter", - &oprofile_stats.multiplex_counter); -#endif -} diff --git a/drivers/oprofile/oprofile_stats.h b/drivers/oprofile/oprofile_stats.h deleted file mode 100644 index 1fc622bd1834..000000000000 --- a/drivers/oprofile/oprofile_stats.h +++ /dev/null @@ -1,33 +0,0 @@ -/** - * @file oprofile_stats.h - * - * @remark Copyright 2002 OProfile authors - * @remark Read the file COPYING - * - * @author John Levon - */ - -#ifndef OPROFILE_STATS_H -#define OPROFILE_STATS_H - -#include - -struct oprofile_stat_struct { - atomic_t sample_lost_no_mm; - atomic_t sample_lost_no_mapping; - atomic_t bt_lost_no_mapping; - atomic_t event_lost_overflow; - atomic_t multiplex_counter; -}; - -extern struct oprofile_stat_struct oprofile_stats; - -/* reset all stats to zero */ -void oprofile_reset_stats(void); - -struct dentry; - -/* create the stats/ dir */ -void oprofile_create_stats_files(struct dentry *root); - -#endif /* OPROFILE_STATS_H */ diff --git a/drivers/oprofile/oprofilefs.c b/drivers/oprofile/oprofilefs.c deleted file mode 100644 index 0875f2f122b3..000000000000 --- a/drivers/oprofile/oprofilefs.c +++ /dev/null @@ -1,300 +0,0 @@ -/** - * @file oprofilefs.c - * - * @remark Copyright 2002 OProfile authors - * @remark Read the file COPYING - * - * @author John Levon - * - * A simple filesystem for configuration and - * access of oprofile. - */ - -#include -#include -#include -#include -#include -#include -#include - -#include "oprof.h" - -#define OPROFILEFS_MAGIC 0x6f70726f - -DEFINE_RAW_SPINLOCK(oprofilefs_lock); - -static struct inode *oprofilefs_get_inode(struct super_block *sb, int mode) -{ - struct inode *inode = new_inode(sb); - - if (inode) { - inode->i_ino = get_next_ino(); - inode->i_mode = mode; - inode->i_atime = inode->i_mtime = inode->i_ctime = current_time(inode); - } - return inode; -} - - -static const struct super_operations s_ops = { - .statfs = simple_statfs, - .drop_inode = generic_delete_inode, -}; - - -ssize_t oprofilefs_str_to_user(char const *str, char __user *buf, size_t count, loff_t *offset) -{ - return simple_read_from_buffer(buf, count, offset, str, strlen(str)); -} - - -#define TMPBUFSIZE 50 - -ssize_t oprofilefs_ulong_to_user(unsigned long val, char __user *buf, size_t count, loff_t *offset) -{ - char tmpbuf[TMPBUFSIZE]; - size_t maxlen = snprintf(tmpbuf, TMPBUFSIZE, "%lu\n", val); - if (maxlen > TMPBUFSIZE) - maxlen = TMPBUFSIZE; - return simple_read_from_buffer(buf, count, offset, tmpbuf, maxlen); -} - - -/* - * Note: If oprofilefs_ulong_from_user() returns 0, then *val remains - * unchanged and might be uninitialized. This follows write syscall - * implementation when count is zero: "If count is zero ... [and if] - * no errors are detected, 0 will be returned without causing any - * other effect." (man 2 write) - */ -int oprofilefs_ulong_from_user(unsigned long *val, char const __user *buf, size_t count) -{ - char tmpbuf[TMPBUFSIZE]; - unsigned long flags; - - if (!count) - return 0; - - if (count > TMPBUFSIZE - 1) - return -EINVAL; - - memset(tmpbuf, 0x0, TMPBUFSIZE); - - if (copy_from_user(tmpbuf, buf, count)) - return -EFAULT; - - raw_spin_lock_irqsave(&oprofilefs_lock, flags); - *val = simple_strtoul(tmpbuf, NULL, 0); - raw_spin_unlock_irqrestore(&oprofilefs_lock, flags); - return count; -} - - -static ssize_t ulong_read_file(struct file *file, char __user *buf, size_t count, loff_t *offset) -{ - unsigned long *val = file->private_data; - return oprofilefs_ulong_to_user(*val, buf, count, offset); -} - - -static ssize_t ulong_write_file(struct file *file, char const __user *buf, size_t count, loff_t *offset) -{ - unsigned long value; - int retval; - - if (*offset) - return -EINVAL; - - retval = oprofilefs_ulong_from_user(&value, buf, count); - if (retval <= 0) - return retval; - - retval = oprofile_set_ulong(file->private_data, value); - if (retval) - return retval; - - return count; -} - - -static const struct file_operations ulong_fops = { - .read = ulong_read_file, - .write = ulong_write_file, - .open = simple_open, - .llseek = default_llseek, -}; - - -static const struct file_operations ulong_ro_fops = { - .read = ulong_read_file, - .open = simple_open, - .llseek = default_llseek, -}; - - -static int __oprofilefs_create_file(struct dentry *root, char const *name, - const struct file_operations *fops, int perm, void *priv) -{ - struct dentry *dentry; - struct inode *inode; - - if (!root) - return -ENOMEM; - - inode_lock(d_inode(root)); - dentry = d_alloc_name(root, name); - if (!dentry) { - inode_unlock(d_inode(root)); - return -ENOMEM; - } - inode = oprofilefs_get_inode(root->d_sb, S_IFREG | perm); - if (!inode) { - dput(dentry); - inode_unlock(d_inode(root)); - return -ENOMEM; - } - inode->i_fop = fops; - inode->i_private = priv; - d_add(dentry, inode); - inode_unlock(d_inode(root)); - return 0; -} - - -int oprofilefs_create_ulong(struct dentry *root, - char const *name, unsigned long *val) -{ - return __oprofilefs_create_file(root, name, - &ulong_fops, 0644, val); -} - - -int oprofilefs_create_ro_ulong(struct dentry *root, - char const *name, unsigned long *val) -{ - return __oprofilefs_create_file(root, name, - &ulong_ro_fops, 0444, val); -} - - -static ssize_t atomic_read_file(struct file *file, char __user *buf, size_t count, loff_t *offset) -{ - atomic_t *val = file->private_data; - return oprofilefs_ulong_to_user(atomic_read(val), buf, count, offset); -} - - -static const struct file_operations atomic_ro_fops = { - .read = atomic_read_file, - .open = simple_open, - .llseek = default_llseek, -}; - - -int oprofilefs_create_ro_atomic(struct dentry *root, - char const *name, atomic_t *val) -{ - return __oprofilefs_create_file(root, name, - &atomic_ro_fops, 0444, val); -} - - -int oprofilefs_create_file(struct dentry *root, - char const *name, const struct file_operations *fops) -{ - return __oprofilefs_create_file(root, name, fops, 0644, NULL); -} - - -int oprofilefs_create_file_perm(struct dentry *root, - char const *name, const struct file_operations *fops, int perm) -{ - return __oprofilefs_create_file(root, name, fops, perm, NULL); -} - - -struct dentry *oprofilefs_mkdir(struct dentry *parent, char const *name) -{ - struct dentry *dentry; - struct inode *inode; - - inode_lock(d_inode(parent)); - dentry = d_alloc_name(parent, name); - if (!dentry) { - inode_unlock(d_inode(parent)); - return NULL; - } - inode = oprofilefs_get_inode(parent->d_sb, S_IFDIR | 0755); - if (!inode) { - dput(dentry); - inode_unlock(d_inode(parent)); - return NULL; - } - inode->i_op = &simple_dir_inode_operations; - inode->i_fop = &simple_dir_operations; - d_add(dentry, inode); - inode_unlock(d_inode(parent)); - return dentry; -} - - -static int oprofilefs_fill_super(struct super_block *sb, struct fs_context *fc) -{ - struct inode *root_inode; - - sb->s_blocksize = PAGE_SIZE; - sb->s_blocksize_bits = PAGE_SHIFT; - sb->s_magic = OPROFILEFS_MAGIC; - sb->s_op = &s_ops; - sb->s_time_gran = 1; - - root_inode = oprofilefs_get_inode(sb, S_IFDIR | 0755); - if (!root_inode) - return -ENOMEM; - root_inode->i_op = &simple_dir_inode_operations; - root_inode->i_fop = &simple_dir_operations; - sb->s_root = d_make_root(root_inode); - if (!sb->s_root) - return -ENOMEM; - - oprofile_create_files(sb->s_root); - - // FIXME: verify kill_litter_super removes our dentries - return 0; -} - -static int oprofilefs_get_tree(struct fs_context *fc) -{ - return get_tree_single(fc, oprofilefs_fill_super); -} - -static const struct fs_context_operations oprofilefs_context_ops = { - .get_tree = oprofilefs_get_tree, -}; - -static int oprofilefs_init_fs_context(struct fs_context *fc) -{ - fc->ops = &oprofilefs_context_ops; - return 0; -} - -static struct file_system_type oprofilefs_type = { - .owner = THIS_MODULE, - .name = "oprofilefs", - .init_fs_context = oprofilefs_init_fs_context, - .kill_sb = kill_litter_super, -}; -MODULE_ALIAS_FS("oprofilefs"); - - -int __init oprofilefs_register(void) -{ - return register_filesystem(&oprofilefs_type); -} - - -void __exit oprofilefs_unregister(void) -{ - unregister_filesystem(&oprofilefs_type); -} diff --git a/drivers/oprofile/timer_int.c b/drivers/oprofile/timer_int.c deleted file mode 100644 index 2498a6cd7c24..000000000000 --- a/drivers/oprofile/timer_int.c +++ /dev/null @@ -1,122 +0,0 @@ -/** - * @file timer_int.c - * - * @remark Copyright 2002 OProfile authors - * @remark Read the file COPYING - * - * @author John Levon - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "oprof.h" - -static DEFINE_PER_CPU(struct hrtimer, oprofile_hrtimer); -static int ctr_running; - -static enum hrtimer_restart oprofile_hrtimer_notify(struct hrtimer *hrtimer) -{ - oprofile_add_sample(get_irq_regs(), 0); - hrtimer_forward_now(hrtimer, ns_to_ktime(TICK_NSEC)); - return HRTIMER_RESTART; -} - -static void __oprofile_hrtimer_start(void *unused) -{ - struct hrtimer *hrtimer = this_cpu_ptr(&oprofile_hrtimer); - - if (!ctr_running) - return; - - hrtimer_init(hrtimer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); - hrtimer->function = oprofile_hrtimer_notify; - - hrtimer_start(hrtimer, ns_to_ktime(TICK_NSEC), - HRTIMER_MODE_REL_PINNED); -} - -static int oprofile_hrtimer_start(void) -{ - get_online_cpus(); - ctr_running = 1; - on_each_cpu(__oprofile_hrtimer_start, NULL, 1); - put_online_cpus(); - return 0; -} - -static void __oprofile_hrtimer_stop(int cpu) -{ - struct hrtimer *hrtimer = &per_cpu(oprofile_hrtimer, cpu); - - if (!ctr_running) - return; - - hrtimer_cancel(hrtimer); -} - -static void oprofile_hrtimer_stop(void) -{ - int cpu; - - get_online_cpus(); - for_each_online_cpu(cpu) - __oprofile_hrtimer_stop(cpu); - ctr_running = 0; - put_online_cpus(); -} - -static int oprofile_timer_online(unsigned int cpu) -{ - local_irq_disable(); - __oprofile_hrtimer_start(NULL); - local_irq_enable(); - return 0; -} - -static int oprofile_timer_prep_down(unsigned int cpu) -{ - __oprofile_hrtimer_stop(cpu); - return 0; -} - -static enum cpuhp_state hp_online; - -static int oprofile_hrtimer_setup(void) -{ - int ret; - - ret = cpuhp_setup_state_nocalls(CPUHP_AP_ONLINE_DYN, - "oprofile/timer:online", - oprofile_timer_online, - oprofile_timer_prep_down); - if (ret < 0) - return ret; - hp_online = ret; - return 0; -} - -static void oprofile_hrtimer_shutdown(void) -{ - cpuhp_remove_state_nocalls(hp_online); -} - -int oprofile_timer_init(struct oprofile_operations *ops) -{ - ops->create_files = NULL; - ops->setup = oprofile_hrtimer_setup; - ops->shutdown = oprofile_hrtimer_shutdown; - ops->start = oprofile_hrtimer_start; - ops->stop = oprofile_hrtimer_stop; - ops->cpu_type = "timer"; - printk(KERN_INFO "oprofile: using timer interrupt.\n"); - return 0; -} diff --git a/include/linux/oprofile.h b/include/linux/oprofile.h deleted file mode 100644 index b2a0f15f11fe..000000000000 --- a/include/linux/oprofile.h +++ /dev/null @@ -1,209 +0,0 @@ -/** - * @file oprofile.h - * - * API for machine-specific interrupts to interface - * to oprofile. - * - * @remark Copyright 2002 OProfile authors - * @remark Read the file COPYING - * - * @author John Levon - */ - -#ifndef OPROFILE_H -#define OPROFILE_H - -#include -#include -#include -#include -#include -#include - -/* Each escaped entry is prefixed by ESCAPE_CODE - * then one of the following codes, then the - * relevant data. - * These #defines live in this file so that arch-specific - * buffer sync'ing code can access them. - */ -#define ESCAPE_CODE ~0UL -#define CTX_SWITCH_CODE 1 -#define CPU_SWITCH_CODE 2 -#define COOKIE_SWITCH_CODE 3 -#define KERNEL_ENTER_SWITCH_CODE 4 -#define KERNEL_EXIT_SWITCH_CODE 5 -#define MODULE_LOADED_CODE 6 -#define CTX_TGID_CODE 7 -#define TRACE_BEGIN_CODE 8 -#define TRACE_END_CODE 9 -#define XEN_ENTER_SWITCH_CODE 10 -#define SPU_PROFILING_CODE 11 -#define SPU_CTX_SWITCH_CODE 12 -#define IBS_FETCH_CODE 13 -#define IBS_OP_CODE 14 - -struct dentry; -struct file_operations; -struct pt_regs; - -/* Operations structure to be filled in */ -struct oprofile_operations { - /* create any necessary configuration files in the oprofile fs. - * Optional. */ - int (*create_files)(struct dentry * root); - /* Do any necessary interrupt setup. Optional. */ - int (*setup)(void); - /* Do any necessary interrupt shutdown. Optional. */ - void (*shutdown)(void); - /* Start delivering interrupts. */ - int (*start)(void); - /* Stop delivering interrupts. */ - void (*stop)(void); - /* Arch-specific buffer sync functions. - * Return value = 0: Success - * Return value = -1: Failure - * Return value = 1: Run generic sync function - */ - int (*sync_start)(void); - int (*sync_stop)(void); - - /* Initiate a stack backtrace. Optional. */ - void (*backtrace)(struct pt_regs * const regs, unsigned int depth); - - /* Multiplex between different events. Optional. */ - int (*switch_events)(void); - /* CPU identification string. */ - char * cpu_type; -}; - -/** - * One-time initialisation. *ops must be set to a filled-in - * operations structure. This is called even in timer interrupt - * mode so an arch can set a backtrace callback. - * - * If an error occurs, the fields should be left untouched. - */ -int oprofile_arch_init(struct oprofile_operations * ops); - -/** - * One-time exit/cleanup for the arch. - */ -void oprofile_arch_exit(void); - -/** - * Add a sample. This may be called from any context. - */ -void oprofile_add_sample(struct pt_regs * const regs, unsigned long event); - -/** - * Add an extended sample. Use this when the PC is not from the regs, and - * we cannot determine if we're in kernel mode from the regs. - * - * This function does perform a backtrace. - * - */ -void oprofile_add_ext_sample(unsigned long pc, struct pt_regs * const regs, - unsigned long event, int is_kernel); - -/** - * Add an hardware sample. - */ -void oprofile_add_ext_hw_sample(unsigned long pc, struct pt_regs * const regs, - unsigned long event, int is_kernel, - struct task_struct *task); - -/* Use this instead when the PC value is not from the regs. Doesn't - * backtrace. */ -void oprofile_add_pc(unsigned long pc, int is_kernel, unsigned long event); - -/* add a backtrace entry, to be called from the ->backtrace callback */ -void oprofile_add_trace(unsigned long eip); - - -/** - * Create a file of the given name as a child of the given root, with - * the specified file operations. - */ -int oprofilefs_create_file(struct dentry * root, - char const * name, const struct file_operations * fops); - -int oprofilefs_create_file_perm(struct dentry * root, - char const * name, const struct file_operations * fops, int perm); - -/** Create a file for read/write access to an unsigned long. */ -int oprofilefs_create_ulong(struct dentry * root, - char const * name, ulong * val); - -/** Create a file for read-only access to an unsigned long. */ -int oprofilefs_create_ro_ulong(struct dentry * root, - char const * name, ulong * val); - -/** Create a file for read-only access to an atomic_t. */ -int oprofilefs_create_ro_atomic(struct dentry * root, - char const * name, atomic_t * val); - -/** create a directory */ -struct dentry *oprofilefs_mkdir(struct dentry *parent, char const *name); - -/** - * Write the given asciz string to the given user buffer @buf, updating *offset - * appropriately. Returns bytes written or -EFAULT. - */ -ssize_t oprofilefs_str_to_user(char const * str, char __user * buf, size_t count, loff_t * offset); - -/** - * Convert an unsigned long value into ASCII and copy it to the user buffer @buf, - * updating *offset appropriately. Returns bytes written or -EFAULT. - */ -ssize_t oprofilefs_ulong_to_user(unsigned long val, char __user * buf, size_t count, loff_t * offset); - -/** - * Read an ASCII string for a number from a userspace buffer and fill *val on success. - * Returns 0 on success, < 0 on error. - */ -int oprofilefs_ulong_from_user(unsigned long * val, char const __user * buf, size_t count); - -/** lock for read/write safety */ -extern raw_spinlock_t oprofilefs_lock; - -/** - * Add the contents of a circular buffer to the event buffer. - */ -void oprofile_put_buff(unsigned long *buf, unsigned int start, - unsigned int stop, unsigned int max); - -unsigned long oprofile_get_cpu_buffer_size(void); -void oprofile_cpu_buffer_inc_smpl_lost(void); - -/* cpu buffer functions */ - -struct op_sample; - -struct op_entry { - struct ring_buffer_event *event; - struct op_sample *sample; - unsigned long size; - unsigned long *data; -}; - -void oprofile_write_reserve(struct op_entry *entry, - struct pt_regs * const regs, - unsigned long pc, int code, int size); -int oprofile_add_data(struct op_entry *entry, unsigned long val); -int oprofile_add_data64(struct op_entry *entry, u64 val); -int oprofile_write_commit(struct op_entry *entry); - -#ifdef CONFIG_HW_PERF_EVENTS -int __init oprofile_perf_init(struct oprofile_operations *ops); -void oprofile_perf_exit(void); -char *op_name_from_perf_id(void); -#else -static inline int __init oprofile_perf_init(struct oprofile_operations *ops) -{ - pr_info("oprofile: hardware counters not available\n"); - return -ENODEV; -} -static inline void oprofile_perf_exit(void) { } -#endif /* CONFIG_HW_PERF_EVENTS */ - -#endif /* OPROFILE_H */ diff --git a/init/Kconfig b/init/Kconfig index b77c60f8b963..03eb36256405 100644 --- a/init/Kconfig +++ b/init/Kconfig @@ -2024,7 +2024,7 @@ config PROFILING bool "Profiling support" help Say Y here to enable the extended profiling support mechanisms used - by profilers such as OProfile. + by profilers. # # Place an empty function call at each tracepoint site. Can be -- cgit v1.2.3 From 663f63ee6d9cdc68adf9afca5427e5c2b5b4ae2d Mon Sep 17 00:00:00 2001 From: Ard Biesheuvel Date: Thu, 21 Jan 2021 14:07:33 +0100 Subject: crypto: salsa20 - remove Salsa20 stream cipher algorithm Salsa20 is not used anywhere in the kernel, is not suitable for disk encryption, and widely considered to have been superseded by ChaCha20. So let's remove it. Signed-off-by: Ard Biesheuvel Acked-by: Mike Snitzer Signed-off-by: Herbert Xu --- .../admin-guide/device-mapper/dm-integrity.rst | 4 +- crypto/Kconfig | 12 - crypto/Makefile | 1 - crypto/salsa20_generic.c | 212 ---- crypto/tcrypt.c | 11 +- crypto/testmgr.c | 6 - crypto/testmgr.h | 1162 -------------------- 7 files changed, 3 insertions(+), 1405 deletions(-) delete mode 100644 crypto/salsa20_generic.c (limited to 'Documentation') diff --git a/Documentation/admin-guide/device-mapper/dm-integrity.rst b/Documentation/admin-guide/device-mapper/dm-integrity.rst index 4e6f504474ac..d56112e2e354 100644 --- a/Documentation/admin-guide/device-mapper/dm-integrity.rst +++ b/Documentation/admin-guide/device-mapper/dm-integrity.rst @@ -143,8 +143,8 @@ recalculate journal_crypt:algorithm(:key) (the key is optional) Encrypt the journal using given algorithm to make sure that the attacker can't read the journal. You can use a block cipher here - (such as "cbc(aes)") or a stream cipher (for example "chacha20", - "salsa20" or "ctr(aes)"). + (such as "cbc(aes)") or a stream cipher (for example "chacha20" + or "ctr(aes)"). The journal contains history of last writes to the block device, an attacker reading the journal could see the last sector numbers diff --git a/crypto/Kconfig b/crypto/Kconfig index 8d25d689a705..9779c7f7531f 100644 --- a/crypto/Kconfig +++ b/crypto/Kconfig @@ -1400,18 +1400,6 @@ config CRYPTO_KHAZAD See also: -config CRYPTO_SALSA20 - tristate "Salsa20 stream cipher algorithm" - select CRYPTO_SKCIPHER - help - Salsa20 stream cipher algorithm. - - Salsa20 is a stream cipher submitted to eSTREAM, the ECRYPT - Stream Cipher Project. See - - The Salsa20 stream cipher algorithm is designed by Daniel J. - Bernstein . See - config CRYPTO_CHACHA20 tristate "ChaCha stream cipher algorithms" select CRYPTO_LIB_CHACHA_GENERIC diff --git a/crypto/Makefile b/crypto/Makefile index 6b9622f21f7f..cf23affb1678 100644 --- a/crypto/Makefile +++ b/crypto/Makefile @@ -138,7 +138,6 @@ obj-$(CONFIG_CRYPTO_TEA) += tea.o obj-$(CONFIG_CRYPTO_KHAZAD) += khazad.o obj-$(CONFIG_CRYPTO_ANUBIS) += anubis.o obj-$(CONFIG_CRYPTO_SEED) += seed.o -obj-$(CONFIG_CRYPTO_SALSA20) += salsa20_generic.o obj-$(CONFIG_CRYPTO_CHACHA20) += chacha_generic.o obj-$(CONFIG_CRYPTO_POLY1305) += poly1305_generic.o obj-$(CONFIG_CRYPTO_DEFLATE) += deflate.o diff --git a/crypto/salsa20_generic.c b/crypto/salsa20_generic.c deleted file mode 100644 index 3418869dabef..000000000000 --- a/crypto/salsa20_generic.c +++ /dev/null @@ -1,212 +0,0 @@ -/* - * Salsa20: Salsa20 stream cipher algorithm - * - * Copyright (c) 2007 Tan Swee Heng - * - * Derived from: - * - salsa20.c: Public domain C code by Daniel J. Bernstein - * - * Salsa20 is a stream cipher candidate in eSTREAM, the ECRYPT Stream - * Cipher Project. It is designed by Daniel J. Bernstein . - * More information about eSTREAM and Salsa20 can be found here: - * https://www.ecrypt.eu.org/stream/ - * https://cr.yp.to/snuffle.html - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the Free - * Software Foundation; either version 2 of the License, or (at your option) - * any later version. - * - */ - -#include -#include -#include - -#define SALSA20_IV_SIZE 8 -#define SALSA20_MIN_KEY_SIZE 16 -#define SALSA20_MAX_KEY_SIZE 32 -#define SALSA20_BLOCK_SIZE 64 - -struct salsa20_ctx { - u32 initial_state[16]; -}; - -static void salsa20_block(u32 *state, __le32 *stream) -{ - u32 x[16]; - int i; - - memcpy(x, state, sizeof(x)); - - for (i = 0; i < 20; i += 2) { - x[ 4] ^= rol32((x[ 0] + x[12]), 7); - x[ 8] ^= rol32((x[ 4] + x[ 0]), 9); - x[12] ^= rol32((x[ 8] + x[ 4]), 13); - x[ 0] ^= rol32((x[12] + x[ 8]), 18); - x[ 9] ^= rol32((x[ 5] + x[ 1]), 7); - x[13] ^= rol32((x[ 9] + x[ 5]), 9); - x[ 1] ^= rol32((x[13] + x[ 9]), 13); - x[ 5] ^= rol32((x[ 1] + x[13]), 18); - x[14] ^= rol32((x[10] + x[ 6]), 7); - x[ 2] ^= rol32((x[14] + x[10]), 9); - x[ 6] ^= rol32((x[ 2] + x[14]), 13); - x[10] ^= rol32((x[ 6] + x[ 2]), 18); - x[ 3] ^= rol32((x[15] + x[11]), 7); - x[ 7] ^= rol32((x[ 3] + x[15]), 9); - x[11] ^= rol32((x[ 7] + x[ 3]), 13); - x[15] ^= rol32((x[11] + x[ 7]), 18); - x[ 1] ^= rol32((x[ 0] + x[ 3]), 7); - x[ 2] ^= rol32((x[ 1] + x[ 0]), 9); - x[ 3] ^= rol32((x[ 2] + x[ 1]), 13); - x[ 0] ^= rol32((x[ 3] + x[ 2]), 18); - x[ 6] ^= rol32((x[ 5] + x[ 4]), 7); - x[ 7] ^= rol32((x[ 6] + x[ 5]), 9); - x[ 4] ^= rol32((x[ 7] + x[ 6]), 13); - x[ 5] ^= rol32((x[ 4] + x[ 7]), 18); - x[11] ^= rol32((x[10] + x[ 9]), 7); - x[ 8] ^= rol32((x[11] + x[10]), 9); - x[ 9] ^= rol32((x[ 8] + x[11]), 13); - x[10] ^= rol32((x[ 9] + x[ 8]), 18); - x[12] ^= rol32((x[15] + x[14]), 7); - x[13] ^= rol32((x[12] + x[15]), 9); - x[14] ^= rol32((x[13] + x[12]), 13); - x[15] ^= rol32((x[14] + x[13]), 18); - } - - for (i = 0; i < 16; i++) - stream[i] = cpu_to_le32(x[i] + state[i]); - - if (++state[8] == 0) - state[9]++; -} - -static void salsa20_docrypt(u32 *state, u8 *dst, const u8 *src, - unsigned int bytes) -{ - __le32 stream[SALSA20_BLOCK_SIZE / sizeof(__le32)]; - - while (bytes >= SALSA20_BLOCK_SIZE) { - salsa20_block(state, stream); - crypto_xor_cpy(dst, src, (const u8 *)stream, - SALSA20_BLOCK_SIZE); - bytes -= SALSA20_BLOCK_SIZE; - dst += SALSA20_BLOCK_SIZE; - src += SALSA20_BLOCK_SIZE; - } - if (bytes) { - salsa20_block(state, stream); - crypto_xor_cpy(dst, src, (const u8 *)stream, bytes); - } -} - -static void salsa20_init(u32 *state, const struct salsa20_ctx *ctx, - const u8 *iv) -{ - memcpy(state, ctx->initial_state, sizeof(ctx->initial_state)); - state[6] = get_unaligned_le32(iv + 0); - state[7] = get_unaligned_le32(iv + 4); -} - -static int salsa20_setkey(struct crypto_skcipher *tfm, const u8 *key, - unsigned int keysize) -{ - static const char sigma[16] = "expand 32-byte k"; - static const char tau[16] = "expand 16-byte k"; - struct salsa20_ctx *ctx = crypto_skcipher_ctx(tfm); - const char *constants; - - if (keysize != SALSA20_MIN_KEY_SIZE && - keysize != SALSA20_MAX_KEY_SIZE) - return -EINVAL; - - ctx->initial_state[1] = get_unaligned_le32(key + 0); - ctx->initial_state[2] = get_unaligned_le32(key + 4); - ctx->initial_state[3] = get_unaligned_le32(key + 8); - ctx->initial_state[4] = get_unaligned_le32(key + 12); - if (keysize == 32) { /* recommended */ - key += 16; - constants = sigma; - } else { /* keysize == 16 */ - constants = tau; - } - ctx->initial_state[11] = get_unaligned_le32(key + 0); - ctx->initial_state[12] = get_unaligned_le32(key + 4); - ctx->initial_state[13] = get_unaligned_le32(key + 8); - ctx->initial_state[14] = get_unaligned_le32(key + 12); - ctx->initial_state[0] = get_unaligned_le32(constants + 0); - ctx->initial_state[5] = get_unaligned_le32(constants + 4); - ctx->initial_state[10] = get_unaligned_le32(constants + 8); - ctx->initial_state[15] = get_unaligned_le32(constants + 12); - - /* space for the nonce; it will be overridden for each request */ - ctx->initial_state[6] = 0; - ctx->initial_state[7] = 0; - - /* initial block number */ - ctx->initial_state[8] = 0; - ctx->initial_state[9] = 0; - - return 0; -} - -static int salsa20_crypt(struct skcipher_request *req) -{ - struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req); - const struct salsa20_ctx *ctx = crypto_skcipher_ctx(tfm); - struct skcipher_walk walk; - u32 state[16]; - int err; - - err = skcipher_walk_virt(&walk, req, false); - - salsa20_init(state, ctx, req->iv); - - while (walk.nbytes > 0) { - unsigned int nbytes = walk.nbytes; - - if (nbytes < walk.total) - nbytes = round_down(nbytes, walk.stride); - - salsa20_docrypt(state, walk.dst.virt.addr, walk.src.virt.addr, - nbytes); - err = skcipher_walk_done(&walk, walk.nbytes - nbytes); - } - - return err; -} - -static struct skcipher_alg alg = { - .base.cra_name = "salsa20", - .base.cra_driver_name = "salsa20-generic", - .base.cra_priority = 100, - .base.cra_blocksize = 1, - .base.cra_ctxsize = sizeof(struct salsa20_ctx), - .base.cra_module = THIS_MODULE, - - .min_keysize = SALSA20_MIN_KEY_SIZE, - .max_keysize = SALSA20_MAX_KEY_SIZE, - .ivsize = SALSA20_IV_SIZE, - .chunksize = SALSA20_BLOCK_SIZE, - .setkey = salsa20_setkey, - .encrypt = salsa20_crypt, - .decrypt = salsa20_crypt, -}; - -static int __init salsa20_generic_mod_init(void) -{ - return crypto_register_skcipher(&alg); -} - -static void __exit salsa20_generic_mod_fini(void) -{ - crypto_unregister_skcipher(&alg); -} - -subsys_initcall(salsa20_generic_mod_init); -module_exit(salsa20_generic_mod_fini); - -MODULE_LICENSE("GPL"); -MODULE_DESCRIPTION ("Salsa20 stream cipher algorithm"); -MODULE_ALIAS_CRYPTO("salsa20"); -MODULE_ALIAS_CRYPTO("salsa20-generic"); diff --git a/crypto/tcrypt.c b/crypto/tcrypt.c index 696c44ef465e..2877b88cfa45 100644 --- a/crypto/tcrypt.c +++ b/crypto/tcrypt.c @@ -71,7 +71,7 @@ static const char *check[] = { "blowfish", "twofish", "serpent", "sha384", "sha512", "md4", "aes", "cast6", "arc4", "michael_mic", "deflate", "crc32c", "tea", "xtea", "khazad", "wp512", "wp384", "wp256", "tnepres", "xeta", "fcrypt", - "camellia", "seed", "salsa20", "rmd160", + "camellia", "seed", "rmd160", "lzo", "lzo-rle", "cts", "sha3-224", "sha3-256", "sha3-384", "sha3-512", "streebog256", "streebog512", NULL @@ -1835,10 +1835,6 @@ static int do_test(const char *alg, u32 type, u32 mask, int m, u32 num_mb) ret += tcrypt_test("sha224"); break; - case 34: - ret += tcrypt_test("salsa20"); - break; - case 35: ret += tcrypt_test("gcm(aes)"); break; @@ -2153,11 +2149,6 @@ static int do_test(const char *alg, u32 type, u32 mask, int m, u32 num_mb) speed_template_32_48_64); break; - case 206: - test_cipher_speed("salsa20", ENCRYPT, sec, NULL, 0, - speed_template_16_32); - break; - case 207: test_cipher_speed("ecb(serpent)", ENCRYPT, sec, NULL, 0, speed_template_16_32); diff --git a/crypto/testmgr.c b/crypto/testmgr.c index b87802ffb554..1a4103b1b202 100644 --- a/crypto/testmgr.c +++ b/crypto/testmgr.c @@ -5282,12 +5282,6 @@ static const struct alg_test_desc alg_test_descs[] = { .suite = { .akcipher = __VECS(rsa_tv_template) } - }, { - .alg = "salsa20", - .test = alg_test_skcipher, - .suite = { - .cipher = __VECS(salsa20_stream_tv_template) - } }, { .alg = "sha1", .test = alg_test_hash, diff --git a/crypto/testmgr.h b/crypto/testmgr.h index 851c107a5584..99aca08263d2 100644 --- a/crypto/testmgr.h +++ b/crypto/testmgr.h @@ -24409,1168 +24409,6 @@ static const struct cipher_testvec seed_tv_template[] = { } }; -static const struct cipher_testvec salsa20_stream_tv_template[] = { - /* - * Testvectors from verified.test-vectors submitted to ECRYPT. - * They are truncated to size 39, 64, 111, 129 to test a variety - * of input length. - */ - { /* Set 3, vector 0 */ - .key = "\x00\x01\x02\x03\x04\x05\x06\x07" - "\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F", - .klen = 16, - .iv = "\x00\x00\x00\x00\x00\x00\x00\x00", - .ptext = "\x00\x00\x00\x00\x00\x00\x00\x00" - "\x00\x00\x00\x00\x00\x00\x00\x00" - "\x00\x00\x00\x00\x00\x00\x00\x00" - "\x00\x00\x00\x00\x00\x00\x00\x00" - "\x00\x00\x00\x00\x00\x00\x00", - .ctext = "\x2D\xD5\xC3\xF7\xBA\x2B\x20\xF7" - "\x68\x02\x41\x0C\x68\x86\x88\x89" - "\x5A\xD8\xC1\xBD\x4E\xA6\xC9\xB1" - "\x40\xFB\x9B\x90\xE2\x10\x49\xBF" - "\x58\x3F\x52\x79\x70\xEB\xC1", - .len = 39, - }, { /* Set 5, vector 0 */ - .key = "\x00\x00\x00\x00\x00\x00\x00\x00" - "\x00\x00\x00\x00\x00\x00\x00\x00", - .klen = 16, - .iv = "\x80\x00\x00\x00\x00\x00\x00\x00", - .ptext = "\x00\x00\x00\x00\x00\x00\x00\x00" - "\x00\x00\x00\x00\x00\x00\x00\x00" - "\x00\x00\x00\x00\x00\x00\x00\x00" - "\x00\x00\x00\x00\x00\x00\x00\x00" - "\x00\x00\x00\x00\x00\x00\x00\x00" - "\x00\x00\x00\x00\x00\x00\x00\x00" - "\x00\x00\x00\x00\x00\x00\x00\x00" - "\x00\x00\x00\x00\x00\x00\x00\x00", - .ctext = "\xB6\x6C\x1E\x44\x46\xDD\x95\x57" - "\xE5\x78\xE2\x23\xB0\xB7\x68\x01" - "\x7B\x23\xB2\x67\xBB\x02\x34\xAE" - "\x46\x26\xBF\x44\x3F\x21\x97\x76" - "\x43\x6F\xB1\x9F\xD0\xE8\x86\x6F" - "\xCD\x0D\xE9\xA9\x53\x8F\x4A\x09" - "\xCA\x9A\xC0\x73\x2E\x30\xBC\xF9" - "\x8E\x4F\x13\xE4\xB9\xE2\x01\xD9", - .len = 64, - }, { /* Set 3, vector 27 */ - .key = "\x1B\x1C\x1D\x1E\x1F\x20\x21\x22" - "\x23\x24\x25\x26\x27\x28\x29\x2A" - "\x2B\x2C\x2D\x2E\x2F\x30\x31\x32" - "\x33\x34\x35\x36\x37\x38\x39\x3A", - .klen = 32, - .iv = "\x00\x00\x00\x00\x00\x00\x00\x00", - .ptext = "\x00\x00\x00\x00\x00\x00\x00\x00" - "\x00\x00\x00\x00\x00\x00\x00\x00" - "\x00\x00\x00\x00\x00\x00\x00\x00" - "\x00\x00\x00\x00\x00\x00\x00\x00" - "\x00\x00\x00\x00\x00\x00\x00\x00" - "\x00\x00\x00\x00\x00\x00\x00\x00" - "\x00\x00\x00\x00\x00\x00\x00\x00" - "\x00\x00\x00\x00\x00\x00\x00\x00" - "\x00\x00\x00\x00\x00\x00\x00\x00" - "\x00\x00\x00\x00\x00\x00\x00\x00" - "\x00\x00\x00\x00\x00\x00\x00\x00" - "\x00\x00\x00\x00\x00\x00\x00\x00" - "\x00\x00\x00\x00\x00\x00\x00\x00" - "\x00\x00\x00\x00\x00\x00\x00", - .ctext = "\xAE\x39\x50\x8E\xAC\x9A\xEC\xE7" - "\xBF\x97\xBB\x20\xB9\xDE\xE4\x1F" - "\x87\xD9\x47\xF8\x28\x91\x35\x98" - "\xDB\x72\xCC\x23\x29\x48\x56\x5E" - "\x83\x7E\x0B\xF3\x7D\x5D\x38\x7B" - "\x2D\x71\x02\xB4\x3B\xB5\xD8\x23" - "\xB0\x4A\xDF\x3C\xEC\xB6\xD9\x3B" - "\x9B\xA7\x52\xBE\xC5\xD4\x50\x59" - "\x15\x14\xB4\x0E\x40\xE6\x53\xD1" - "\x83\x9C\x5B\xA0\x92\x29\x6B\x5E" - "\x96\x5B\x1E\x2F\xD3\xAC\xC1\x92" - "\xB1\x41\x3F\x19\x2F\xC4\x3B\xC6" - "\x95\x46\x45\x54\xE9\x75\x03\x08" - "\x44\xAF\xE5\x8A\x81\x12\x09", - .len = 111, - }, { /* Set 5, vector 27 */ - .key = "\x00\x00\x00\x00\x00\x00\x00\x00" - "\x00\x00\x00\x00\x00\x00\x00\x00" - "\x00\x00\x00\x00\x00\x00\x00\x00" - "\x00\x00\x00\x00\x00\x00\x00\x00", - .klen = 32, - .iv = "\x00\x00\x00\x10\x00\x00\x00\x00", - .ptext = "\x00\x00\x00\x00\x00\x00\x00\x00" - "\x00\x00\x00\x00\x00\x00\x00\x00" - "\x00\x00\x00\x00\x00\x00\x00\x00" - "\x00\x00\x00\x00\x00\x00\x00\x00" - "\x00\x00\x00\x00\x00\x00\x00\x00" - "\x00\x00\x00\x00\x00\x00\x00\x00" - "\x00\x00\x00\x00\x00\x00\x00\x00" - "\x00\x00\x00\x00\x00\x00\x00\x00" - "\x00\x00\x00\x00\x00\x00\x00\x00" - "\x00\x00\x00\x00\x00\x00\x00\x00" - "\x00\x00\x00\x00\x00\x00\x00\x00" - "\x00\x00\x00\x00\x00\x00\x00\x00" - "\x00\x00\x00\x00\x00\x00\x00\x00" - "\x00\x00\x00\x00\x00\x00\x00\x00" - "\x00\x00\x00\x00\x00\x00\x00\x00" - "\x00\x00\x00\x00\x00\x00\x00\x00" - "\x00", - .ctext = "\xD2\xDB\x1A\x5C\xF1\xC1\xAC\xDB" - "\xE8\x1A\x7A\x43\x40\xEF\x53\x43" - "\x5E\x7F\x4B\x1A\x50\x52\x3F\x8D" - "\x28\x3D\xCF\x85\x1D\x69\x6E\x60" - "\xF2\xDE\x74\x56\x18\x1B\x84\x10" - "\xD4\x62\xBA\x60\x50\xF0\x61\xF2" - "\x1C\x78\x7F\xC1\x24\x34\xAF\x58" - "\xBF\x2C\x59\xCA\x90\x77\xF3\xB0" - "\x5B\x4A\xDF\x89\xCE\x2C\x2F\xFC" - "\x67\xF0\xE3\x45\xE8\xB3\xB3\x75" - "\xA0\x95\x71\xA1\x29\x39\x94\xCA" - "\x45\x2F\xBD\xCB\x10\xB6\xBE\x9F" - "\x8E\xF9\xB2\x01\x0A\x5A\x0A\xB7" - "\x6B\x9D\x70\x8E\x4B\xD6\x2F\xCD" - "\x2E\x40\x48\x75\xE9\xE2\x21\x45" - "\x0B\xC9\xB6\xB5\x66\xBC\x9A\x59" - "\x5A", - .len = 129, - }, { /* large test vector generated using Crypto++ */ - .key = "\x00\x01\x02\x03\x04\x05\x06\x07" - "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f" - "\x10\x11\x12\x13\x14\x15\x16\x17" - "\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f", - .klen = 32, - .iv = "\x00\x00\x00\x00\x00\x00\x00\x00" - "\x00\x00\x00\x00\x00\x00\x00\x00", - .ptext = - "\x00\x01\x02\x03\x04\x05\x06\x07" - "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f" - "\x10\x11\x12\x13\x14\x15\x16\x17" - "\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f" - "\x20\x21\x22\x23\x24\x25\x26\x27" - "\x28\x29\x2a\x2b\x2c\x2d\x2e\x2f" - "\x30\x31\x32\x33\x34\x35\x36\x37" - "\x38\x39\x3a\x3b\x3c\x3d\x3e\x3f" - "\x40\x41\x42\x43\x44\x45\x46\x47" - "\x48\x49\x4a\x4b\x4c\x4d\x4e\x4f" - "\x50\x51\x52\x53\x54\x55\x56\x57" - "\x58\x59\x5a\x5b\x5c\x5d\x5e\x5f" - "\x60\x61\x62\x63\x64\x65\x66\x67" - "\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f" - "\x70\x71\x72\x73\x74\x75\x76\x77" - "\x78\x79\x7a\x7b\x7c\x7d\x7e\x7f" - "\x80\x81\x82\x83\x84\x85\x86\x87" - "\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f" - "\x90\x91\x92\x93\x94\x95\x96\x97" - "\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f" - "\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7" - "\xa8\xa9\xaa\xab\xac\xad\xae\xaf" - "\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7" - "\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf" - "\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7" - "\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf" - "\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7" - "\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf" - "\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7" - "\xe8\xe9\xea\xeb\xec\xed\xee\xef" - "\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7" - "\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff" - "\x00\x03\x06\x09\x0c\x0f\x12\x15" - "\x18\x1b\x1e\x21\x24\x27\x2a\x2d" - "\x30\x33\x36\x39\x3c\x3f\x42\x45" - "\x48\x4b\x4e\x51\x54\x57\x5a\x5d" - "\x60\x63\x66\x69\x6c\x6f\x72\x75" - "\x78\x7b\x7e\x81\x84\x87\x8a\x8d" - "\x90\x93\x96\x99\x9c\x9f\xa2\xa5" - "\xa8\xab\xae\xb1\xb4\xb7\xba\xbd" - "\xc0\xc3\xc6\xc9\xcc\xcf\xd2\xd5" - "\xd8\xdb\xde\xe1\xe4\xe7\xea\xed" - "\xf0\xf3\xf6\xf9\xfc\xff\x02\x05" - "\x08\x0b\x0e\x11\x14\x17\x1a\x1d" - "\x20\x23\x26\x29\x2c\x2f\x32\x35" - "\x38\x3b\x3e\x41\x44\x47\x4a\x4d" - "\x50\x53\x56\x59\x5c\x5f\x62\x65" - "\x68\x6b\x6e\x71\x74\x77\x7a\x7d" - "\x80\x83\x86\x89\x8c\x8f\x92\x95" - "\x98\x9b\x9e\xa1\xa4\xa7\xaa\xad" - "\xb0\xb3\xb6\xb9\xbc\xbf\xc2\xc5" - "\xc8\xcb\xce\xd1\xd4\xd7\xda\xdd" - "\xe0\xe3\xe6\xe9\xec\xef\xf2\xf5" - "\xf8\xfb\xfe\x01\x04\x07\x0a\x0d" - "\x10\x13\x16\x19\x1c\x1f\x22\x25" - "\x28\x2b\x2e\x31\x34\x37\x3a\x3d" - "\x40\x43\x46\x49\x4c\x4f\x52\x55" - "\x58\x5b\x5e\x61\x64\x67\x6a\x6d" - "\x70\x73\x76\x79\x7c\x7f\x82\x85" - "\x88\x8b\x8e\x91\x94\x97\x9a\x9d" - "\xa0\xa3\xa6\xa9\xac\xaf\xb2\xb5" - "\xb8\xbb\xbe\xc1\xc4\xc7\xca\xcd" - "\xd0\xd3\xd6\xd9\xdc\xdf\xe2\xe5" - "\xe8\xeb\xee\xf1\xf4\xf7\xfa\xfd" - "\x00\x05\x0a\x0f\x14\x19\x1e\x23" - "\x28\x2d\x32\x37\x3c\x41\x46\x4b" - "\x50\x55\x5a\x5f\x64\x69\x6e\x73" - "\x78\x7d\x82\x87\x8c\x91\x96\x9b" - "\xa0\xa5\xaa\xaf\xb4\xb9\xbe\xc3" - "\xc8\xcd\xd2\xd7\xdc\xe1\xe6\xeb" - "\xf0\xf5\xfa\xff\x04\x09\x0e\x13" - "\x18\x1d\x22\x27\x2c\x31\x36\x3b" - "\x40\x45\x4a\x4f\x54\x59\x5e\x63" - "\x68\x6d\x72\x77\x7c\x81\x86\x8b" - "\x90\x95\x9a\x9f\xa4\xa9\xae\xb3" - "\xb8\xbd\xc2\xc7\xcc\xd1\xd6\xdb" - "\xe0\xe5\xea\xef\xf4\xf9\xfe\x03" - "\x08\x0d\x12\x17\x1c\x21\x26\x2b" - "\x30\x35\x3a\x3f\x44\x49\x4e\x53" - "\x58\x5d\x62\x67\x6c\x71\x76\x7b" - "\x80\x85\x8a\x8f\x94\x99\x9e\xa3" - "\xa8\xad\xb2\xb7\xbc\xc1\xc6\xcb" - "\xd0\xd5\xda\xdf\xe4\xe9\xee\xf3" - "\xf8\xfd\x02\x07\x0c\x11\x16\x1b" - "\x20\x25\x2a\x2f\x34\x39\x3e\x43" - "\x48\x4d\x52\x57\x5c\x61\x66\x6b" - "\x70\x75\x7a\x7f\x84\x89\x8e\x93" - "\x98\x9d\xa2\xa7\xac\xb1\xb6\xbb" - "\xc0\xc5\xca\xcf\xd4\xd9\xde\xe3" - "\xe8\xed\xf2\xf7\xfc\x01\x06\x0b" - "\x10\x15\x1a\x1f\x24\x29\x2e\x33" - "\x38\x3d\x42\x47\x4c\x51\x56\x5b" - "\x60\x65\x6a\x6f\x74\x79\x7e\x83" - "\x88\x8d\x92\x97\x9c\xa1\xa6\xab" - "\xb0\xb5\xba\xbf\xc4\xc9\xce\xd3" - "\xd8\xdd\xe2\xe7\xec\xf1\xf6\xfb" - "\x00\x07\x0e\x15\x1c\x23\x2a\x31" - "\x38\x3f\x46\x4d\x54\x5b\x62\x69" - "\x70\x77\x7e\x85\x8c\x93\x9a\xa1" - "\xa8\xaf\xb6\xbd\xc4\xcb\xd2\xd9" - "\xe0\xe7\xee\xf5\xfc\x03\x0a\x11" - "\x18\x1f\x26\x2d\x34\x3b\x42\x49" - "\x50\x57\x5e\x65\x6c\x73\x7a\x81" - "\x88\x8f\x96\x9d\xa4\xab\xb2\xb9" - "\xc0\xc7\xce\xd5\xdc\xe3\xea\xf1" - "\xf8\xff\x06\x0d\x14\x1b\x22\x29" - "\x30\x37\x3e\x45\x4c\x53\x5a\x61" - "\x68\x6f\x76\x7d\x84\x8b\x92\x99" - "\xa0\xa7\xae\xb5\xbc\xc3\xca\xd1" - "\xd8\xdf\xe6\xed\xf4\xfb\x02\x09" - "\x10\x17\x1e\x25\x2c\x33\x3a\x41" - "\x48\x4f\x56\x5d\x64\x6b\x72\x79" - "\x80\x87\x8e\x95\x9c\xa3\xaa\xb1" - "\xb8\xbf\xc6\xcd\xd4\xdb\xe2\xe9" - "\xf0\xf7\xfe\x05\x0c\x13\x1a\x21" - "\x28\x2f\x36\x3d\x44\x4b\x52\x59" - "\x60\x67\x6e\x75\x7c\x83\x8a\x91" - "\x98\x9f\xa6\xad\xb4\xbb\xc2\xc9" - "\xd0\xd7\xde\xe5\xec\xf3\xfa\x01" - "\x08\x0f\x16\x1d\x24\x2b\x32\x39" - "\x40\x47\x4e\x55\x5c\x63\x6a\x71" - "\x78\x7f\x86\x8d\x94\x9b\xa2\xa9" - "\xb0\xb7\xbe\xc5\xcc\xd3\xda\xe1" - "\xe8\xef\xf6\xfd\x04\x0b\x12\x19" - "\x20\x27\x2e\x35\x3c\x43\x4a\x51" - "\x58\x5f\x66\x6d\x74\x7b\x82\x89" - "\x90\x97\x9e\xa5\xac\xb3\xba\xc1" - "\xc8\xcf\xd6\xdd\xe4\xeb\xf2\xf9" - "\x00\x09\x12\x1b\x24\x2d\x36\x3f" - "\x48\x51\x5a\x63\x6c\x75\x7e\x87" - "\x90\x99\xa2\xab\xb4\xbd\xc6\xcf" - "\xd8\xe1\xea\xf3\xfc\x05\x0e\x17" - "\x20\x29\x32\x3b\x44\x4d\x56\x5f" - "\x68\x71\x7a\x83\x8c\x95\x9e\xa7" - "\xb0\xb9\xc2\xcb\xd4\xdd\xe6\xef" - "\xf8\x01\x0a\x13\x1c\x25\x2e\x37" - "\x40\x49\x52\x5b\x64\x6d\x76\x7f" - "\x88\x91\x9a\xa3\xac\xb5\xbe\xc7" - "\xd0\xd9\xe2\xeb\xf4\xfd\x06\x0f" - "\x18\x21\x2a\x33\x3c\x45\x4e\x57" - "\x60\x69\x72\x7b\x84\x8d\x96\x9f" - "\xa8\xb1\xba\xc3\xcc\xd5\xde\xe7" - "\xf0\xf9\x02\x0b\x14\x1d\x26\x2f" - "\x38\x41\x4a\x53\x5c\x65\x6e\x77" - "\x80\x89\x92\x9b\xa4\xad\xb6\xbf" - "\xc8\xd1\xda\xe3\xec\xf5\xfe\x07" - "\x10\x19\x22\x2b\x34\x3d\x46\x4f" - "\x58\x61\x6a\x73\x7c\x85\x8e\x97" - "\xa0\xa9\xb2\xbb\xc4\xcd\xd6\xdf" - "\xe8\xf1\xfa\x03\x0c\x15\x1e\x27" - "\x30\x39\x42\x4b\x54\x5d\x66\x6f" - "\x78\x81\x8a\x93\x9c\xa5\xae\xb7" - "\xc0\xc9\xd2\xdb\xe4\xed\xf6\xff" - "\x08\x11\x1a\x23\x2c\x35\x3e\x47" - "\x50\x59\x62\x6b\x74\x7d\x86\x8f" - "\x98\xa1\xaa\xb3\xbc\xc5\xce\xd7" - "\xe0\xe9\xf2\xfb\x04\x0d\x16\x1f" - "\x28\x31\x3a\x43\x4c\x55\x5e\x67" - "\x70\x79\x82\x8b\x94\x9d\xa6\xaf" - "\xb8\xc1\xca\xd3\xdc\xe5\xee\xf7" - "\x00\x0b\x16\x21\x2c\x37\x42\x4d" - "\x58\x63\x6e\x79\x84\x8f\x9a\xa5" - "\xb0\xbb\xc6\xd1\xdc\xe7\xf2\xfd" - "\x08\x13\x1e\x29\x34\x3f\x4a\x55" - "\x60\x6b\x76\x81\x8c\x97\xa2\xad" - "\xb8\xc3\xce\xd9\xe4\xef\xfa\x05" - "\x10\x1b\x26\x31\x3c\x47\x52\x5d" - "\x68\x73\x7e\x89\x94\x9f\xaa\xb5" - "\xc0\xcb\xd6\xe1\xec\xf7\x02\x0d" - "\x18\x23\x2e\x39\x44\x4f\x5a\x65" - "\x70\x7b\x86\x91\x9c\xa7\xb2\xbd" - "\xc8\xd3\xde\xe9\xf4\xff\x0a\x15" - "\x20\x2b\x36\x41\x4c\x57\x62\x6d" - "\x78\x83\x8e\x99\xa4\xaf\xba\xc5" - "\xd0\xdb\xe6\xf1\xfc\x07\x12\x1d" - "\x28\x33\x3e\x49\x54\x5f\x6a\x75" - "\x80\x8b\x96\xa1\xac\xb7\xc2\xcd" - "\xd8\xe3\xee\xf9\x04\x0f\x1a\x25" - "\x30\x3b\x46\x51\x5c\x67\x72\x7d" - "\x88\x93\x9e\xa9\xb4\xbf\xca\xd5" - "\xe0\xeb\xf6\x01\x0c\x17\x22\x2d" - "\x38\x43\x4e\x59\x64\x6f\x7a\x85" - "\x90\x9b\xa6\xb1\xbc\xc7\xd2\xdd" - "\xe8\xf3\xfe\x09\x14\x1f\x2a\x35" - "\x40\x4b\x56\x61\x6c\x77\x82\x8d" - "\x98\xa3\xae\xb9\xc4\xcf\xda\xe5" - "\xf0\xfb\x06\x11\x1c\x27\x32\x3d" - "\x48\x53\x5e\x69\x74\x7f\x8a\x95" - "\xa0\xab\xb6\xc1\xcc\xd7\xe2\xed" - "\xf8\x03\x0e\x19\x24\x2f\x3a\x45" - "\x50\x5b\x66\x71\x7c\x87\x92\x9d" - "\xa8\xb3\xbe\xc9\xd4\xdf\xea\xf5" - "\x00\x0d\x1a\x27\x34\x41\x4e\x5b" - "\x68\x75\x82\x8f\x9c\xa9\xb6\xc3" - "\xd0\xdd\xea\xf7\x04\x11\x1e\x2b" - "\x38\x45\x52\x5f\x6c\x79\x86\x93" - "\xa0\xad\xba\xc7\xd4\xe1\xee\xfb" - "\x08\x15\x22\x2f\x3c\x49\x56\x63" - "\x70\x7d\x8a\x97\xa4\xb1\xbe\xcb" - "\xd8\xe5\xf2\xff\x0c\x19\x26\x33" - "\x40\x4d\x5a\x67\x74\x81\x8e\x9b" - "\xa8\xb5\xc2\xcf\xdc\xe9\xf6\x03" - "\x10\x1d\x2a\x37\x44\x51\x5e\x6b" - "\x78\x85\x92\x9f\xac\xb9\xc6\xd3" - "\xe0\xed\xfa\x07\x14\x21\x2e\x3b" - "\x48\x55\x62\x6f\x7c\x89\x96\xa3" - "\xb0\xbd\xca\xd7\xe4\xf1\xfe\x0b" - "\x18\x25\x32\x3f\x4c\x59\x66\x73" - "\x80\x8d\x9a\xa7\xb4\xc1\xce\xdb" - "\xe8\xf5\x02\x0f\x1c\x29\x36\x43" - "\x50\x5d\x6a\x77\x84\x91\x9e\xab" - "\xb8\xc5\xd2\xdf\xec\xf9\x06\x13" - "\x20\x2d\x3a\x47\x54\x61\x6e\x7b" - "\x88\x95\xa2\xaf\xbc\xc9\xd6\xe3" - "\xf0\xfd\x0a\x17\x24\x31\x3e\x4b" - "\x58\x65\x72\x7f\x8c\x99\xa6\xb3" - "\xc0\xcd\xda\xe7\xf4\x01\x0e\x1b" - "\x28\x35\x42\x4f\x5c\x69\x76\x83" - "\x90\x9d\xaa\xb7\xc4\xd1\xde\xeb" - "\xf8\x05\x12\x1f\x2c\x39\x46\x53" - "\x60\x6d\x7a\x87\x94\xa1\xae\xbb" - "\xc8\xd5\xe2\xef\xfc\x09\x16\x23" - "\x30\x3d\x4a\x57\x64\x71\x7e\x8b" - "\x98\xa5\xb2\xbf\xcc\xd9\xe6\xf3" - "\x00\x0f\x1e\x2d\x3c\x4b\x5a\x69" - "\x78\x87\x96\xa5\xb4\xc3\xd2\xe1" - "\xf0\xff\x0e\x1d\x2c\x3b\x4a\x59" - "\x68\x77\x86\x95\xa4\xb3\xc2\xd1" - "\xe0\xef\xfe\x0d\x1c\x2b\x3a\x49" - "\x58\x67\x76\x85\x94\xa3\xb2\xc1" - "\xd0\xdf\xee\xfd\x0c\x1b\x2a\x39" - "\x48\x57\x66\x75\x84\x93\xa2\xb1" - "\xc0\xcf\xde\xed\xfc\x0b\x1a\x29" - "\x38\x47\x56\x65\x74\x83\x92\xa1" - "\xb0\xbf\xce\xdd\xec\xfb\x0a\x19" - "\x28\x37\x46\x55\x64\x73\x82\x91" - "\xa0\xaf\xbe\xcd\xdc\xeb\xfa\x09" - "\x18\x27\x36\x45\x54\x63\x72\x81" - "\x90\x9f\xae\xbd\xcc\xdb\xea\xf9" - "\x08\x17\x26\x35\x44\x53\x62\x71" - "\x80\x8f\x9e\xad\xbc\xcb\xda\xe9" - "\xf8\x07\x16\x25\x34\x43\x52\x61" - "\x70\x7f\x8e\x9d\xac\xbb\xca\xd9" - "\xe8\xf7\x06\x15\x24\x33\x42\x51" - "\x60\x6f\x7e\x8d\x9c\xab\xba\xc9" - "\xd8\xe7\xf6\x05\x14\x23\x32\x41" - "\x50\x5f\x6e\x7d\x8c\x9b\xaa\xb9" - "\xc8\xd7\xe6\xf5\x04\x13\x22\x31" - "\x40\x4f\x5e\x6d\x7c\x8b\x9a\xa9" - "\xb8\xc7\xd6\xe5\xf4\x03\x12\x21" - "\x30\x3f\x4e\x5d\x6c\x7b\x8a\x99" - "\xa8\xb7\xc6\xd5\xe4\xf3\x02\x11" - "\x20\x2f\x3e\x4d\x5c\x6b\x7a\x89" - "\x98\xa7\xb6\xc5\xd4\xe3\xf2\x01" - "\x10\x1f\x2e\x3d\x4c\x5b\x6a\x79" - "\x88\x97\xa6\xb5\xc4\xd3\xe2\xf1" - "\x00\x11\x22\x33\x44\x55\x66\x77" - "\x88\x99\xaa\xbb\xcc\xdd\xee\xff" - "\x10\x21\x32\x43\x54\x65\x76\x87" - "\x98\xa9\xba\xcb\xdc\xed\xfe\x0f" - "\x20\x31\x42\x53\x64\x75\x86\x97" - "\xa8\xb9\xca\xdb\xec\xfd\x0e\x1f" - "\x30\x41\x52\x63\x74\x85\x96\xa7" - "\xb8\xc9\xda\xeb\xfc\x0d\x1e\x2f" - "\x40\x51\x62\x73\x84\x95\xa6\xb7" - "\xc8\xd9\xea\xfb\x0c\x1d\x2e\x3f" - "\x50\x61\x72\x83\x94\xa5\xb6\xc7" - "\xd8\xe9\xfa\x0b\x1c\x2d\x3e\x4f" - "\x60\x71\x82\x93\xa4\xb5\xc6\xd7" - "\xe8\xf9\x0a\x1b\x2c\x3d\x4e\x5f" - "\x70\x81\x92\xa3\xb4\xc5\xd6\xe7" - "\xf8\x09\x1a\x2b\x3c\x4d\x5e\x6f" - "\x80\x91\xa2\xb3\xc4\xd5\xe6\xf7" - "\x08\x19\x2a\x3b\x4c\x5d\x6e\x7f" - "\x90\xa1\xb2\xc3\xd4\xe5\xf6\x07" - "\x18\x29\x3a\x4b\x5c\x6d\x7e\x8f" - "\xa0\xb1\xc2\xd3\xe4\xf5\x06\x17" - "\x28\x39\x4a\x5b\x6c\x7d\x8e\x9f" - "\xb0\xc1\xd2\xe3\xf4\x05\x16\x27" - "\x38\x49\x5a\x6b\x7c\x8d\x9e\xaf" - "\xc0\xd1\xe2\xf3\x04\x15\x26\x37" - "\x48\x59\x6a\x7b\x8c\x9d\xae\xbf" - "\xd0\xe1\xf2\x03\x14\x25\x36\x47" - "\x58\x69\x7a\x8b\x9c\xad\xbe\xcf" - "\xe0\xf1\x02\x13\x24\x35\x46\x57" - "\x68\x79\x8a\x9b\xac\xbd\xce\xdf" - "\xf0\x01\x12\x23\x34\x45\x56\x67" - "\x78\x89\x9a\xab\xbc\xcd\xde\xef" - "\x00\x13\x26\x39\x4c\x5f\x72\x85" - "\x98\xab\xbe\xd1\xe4\xf7\x0a\x1d" - "\x30\x43\x56\x69\x7c\x8f\xa2\xb5" - "\xc8\xdb\xee\x01\x14\x27\x3a\x4d" - "\x60\x73\x86\x99\xac\xbf\xd2\xe5" - "\xf8\x0b\x1e\x31\x44\x57\x6a\x7d" - "\x90\xa3\xb6\xc9\xdc\xef\x02\x15" - "\x28\x3b\x4e\x61\x74\x87\x9a\xad" - "\xc0\xd3\xe6\xf9\x0c\x1f\x32\x45" - "\x58\x6b\x7e\x91\xa4\xb7\xca\xdd" - "\xf0\x03\x16\x29\x3c\x4f\x62\x75" - "\x88\x9b\xae\xc1\xd4\xe7\xfa\x0d" - "\x20\x33\x46\x59\x6c\x7f\x92\xa5" - "\xb8\xcb\xde\xf1\x04\x17\x2a\x3d" - "\x50\x63\x76\x89\x9c\xaf\xc2\xd5" - "\xe8\xfb\x0e\x21\x34\x47\x5a\x6d" - "\x80\x93\xa6\xb9\xcc\xdf\xf2\x05" - "\x18\x2b\x3e\x51\x64\x77\x8a\x9d" - "\xb0\xc3\xd6\xe9\xfc\x0f\x22\x35" - "\x48\x5b\x6e\x81\x94\xa7\xba\xcd" - "\xe0\xf3\x06\x19\x2c\x3f\x52\x65" - "\x78\x8b\x9e\xb1\xc4\xd7\xea\xfd" - "\x10\x23\x36\x49\x5c\x6f\x82\x95" - "\xa8\xbb\xce\xe1\xf4\x07\x1a\x2d" - "\x40\x53\x66\x79\x8c\x9f\xb2\xc5" - "\xd8\xeb\xfe\x11\x24\x37\x4a\x5d" - "\x70\x83\x96\xa9\xbc\xcf\xe2\xf5" - "\x08\x1b\x2e\x41\x54\x67\x7a\x8d" - "\xa0\xb3\xc6\xd9\xec\xff\x12\x25" - "\x38\x4b\x5e\x71\x84\x97\xaa\xbd" - "\xd0\xe3\xf6\x09\x1c\x2f\x42\x55" - "\x68\x7b\x8e\xa1\xb4\xc7\xda\xed" - "\x00\x15\x2a\x3f\x54\x69\x7e\x93" - "\xa8\xbd\xd2\xe7\xfc\x11\x26\x3b" - "\x50\x65\x7a\x8f\xa4\xb9\xce\xe3" - "\xf8\x0d\x22\x37\x4c\x61\x76\x8b" - "\xa0\xb5\xca\xdf\xf4\x09\x1e\x33" - "\x48\x5d\x72\x87\x9c\xb1\xc6\xdb" - "\xf0\x05\x1a\x2f\x44\x59\x6e\x83" - "\x98\xad\xc2\xd7\xec\x01\x16\x2b" - "\x40\x55\x6a\x7f\x94\xa9\xbe\xd3" - "\xe8\xfd\x12\x27\x3c\x51\x66\x7b" - "\x90\xa5\xba\xcf\xe4\xf9\x0e\x23" - "\x38\x4d\x62\x77\x8c\xa1\xb6\xcb" - "\xe0\xf5\x0a\x1f\x34\x49\x5e\x73" - "\x88\x9d\xb2\xc7\xdc\xf1\x06\x1b" - "\x30\x45\x5a\x6f\x84\x99\xae\xc3" - "\xd8\xed\x02\x17\x2c\x41\x56\x6b" - "\x80\x95\xaa\xbf\xd4\xe9\xfe\x13" - "\x28\x3d\x52\x67\x7c\x91\xa6\xbb" - "\xd0\xe5\xfa\x0f\x24\x39\x4e\x63" - "\x78\x8d\xa2\xb7\xcc\xe1\xf6\x0b" - "\x20\x35\x4a\x5f\x74\x89\x9e\xb3" - "\xc8\xdd\xf2\x07\x1c\x31\x46\x5b" - "\x70\x85\x9a\xaf\xc4\xd9\xee\x03" - "\x18\x2d\x42\x57\x6c\x81\x96\xab" - "\xc0\xd5\xea\xff\x14\x29\x3e\x53" - "\x68\x7d\x92\xa7\xbc\xd1\xe6\xfb" - "\x10\x25\x3a\x4f\x64\x79\x8e\xa3" - "\xb8\xcd\xe2\xf7\x0c\x21\x36\x4b" - "\x60\x75\x8a\x9f\xb4\xc9\xde\xf3" - "\x08\x1d\x32\x47\x5c\x71\x86\x9b" - "\xb0\xc5\xda\xef\x04\x19\x2e\x43" - "\x58\x6d\x82\x97\xac\xc1\xd6\xeb" - "\x00\x17\x2e\x45\x5c\x73\x8a\xa1" - "\xb8\xcf\xe6\xfd\x14\x2b\x42\x59" - "\x70\x87\x9e\xb5\xcc\xe3\xfa\x11" - "\x28\x3f\x56\x6d\x84\x9b\xb2\xc9" - "\xe0\xf7\x0e\x25\x3c\x53\x6a\x81" - "\x98\xaf\xc6\xdd\xf4\x0b\x22\x39" - "\x50\x67\x7e\x95\xac\xc3\xda\xf1" - "\x08\x1f\x36\x4d\x64\x7b\x92\xa9" - "\xc0\xd7\xee\x05\x1c\x33\x4a\x61" - "\x78\x8f\xa6\xbd\xd4\xeb\x02\x19" - "\x30\x47\x5e\x75\x8c\xa3\xba\xd1" - "\xe8\xff\x16\x2d\x44\x5b\x72\x89" - "\xa0\xb7\xce\xe5\xfc\x13\x2a\x41" - "\x58\x6f\x86\x9d\xb4\xcb\xe2\xf9" - "\x10\x27\x3e\x55\x6c\x83\x9a\xb1" - "\xc8\xdf\xf6\x0d\x24\x3b\x52\x69" - "\x80\x97\xae\xc5\xdc\xf3\x0a\x21" - "\x38\x4f\x66\x7d\x94\xab\xc2\xd9" - "\xf0\x07\x1e\x35\x4c\x63\x7a\x91" - "\xa8\xbf\xd6\xed\x04\x1b\x32\x49" - "\x60\x77\x8e\xa5\xbc\xd3\xea\x01" - "\x18\x2f\x46\x5d\x74\x8b\xa2\xb9" - "\xd0\xe7\xfe\x15\x2c\x43\x5a\x71" - "\x88\x9f\xb6\xcd\xe4\xfb\x12\x29" - "\x40\x57\x6e\x85\x9c\xb3\xca\xe1" - "\xf8\x0f\x26\x3d\x54\x6b\x82\x99" - "\xb0\xc7\xde\xf5\x0c\x23\x3a\x51" - "\x68\x7f\x96\xad\xc4\xdb\xf2\x09" - "\x20\x37\x4e\x65\x7c\x93\xaa\xc1" - "\xd8\xef\x06\x1d\x34\x4b\x62\x79" - "\x90\xa7\xbe\xd5\xec\x03\x1a\x31" - "\x48\x5f\x76\x8d\xa4\xbb\xd2\xe9" - "\x00\x19\x32\x4b\x64\x7d\x96\xaf" - "\xc8\xe1\xfa\x13\x2c\x45\x5e\x77" - "\x90\xa9\xc2\xdb\xf4\x0d\x26\x3f" - "\x58\x71\x8a\xa3\xbc\xd5\xee\x07" - "\x20\x39\x52\x6b\x84\x9d\xb6\xcf" - "\xe8\x01\x1a\x33\x4c\x65\x7e\x97" - "\xb0\xc9\xe2\xfb\x14\x2d\x46\x5f" - "\x78\x91\xaa\xc3\xdc\xf5\x0e\x27" - "\x40\x59\x72\x8b\xa4\xbd\xd6\xef" - "\x08\x21\x3a\x53\x6c\x85\x9e\xb7" - "\xd0\xe9\x02\x1b\x34\x4d\x66\x7f" - "\x98\xb1\xca\xe3\xfc\x15\x2e\x47" - "\x60\x79\x92\xab\xc4\xdd\xf6\x0f" - "\x28\x41\x5a\x73\x8c\xa5\xbe\xd7" - "\xf0\x09\x22\x3b\x54\x6d\x86\x9f" - "\xb8\xd1\xea\x03\x1c\x35\x4e\x67" - "\x80\x99\xb2\xcb\xe4\xfd\x16\x2f" - "\x48\x61\x7a\x93\xac\xc5\xde\xf7" - "\x10\x29\x42\x5b\x74\x8d\xa6\xbf" - "\xd8\xf1\x0a\x23\x3c\x55\x6e\x87" - "\xa0\xb9\xd2\xeb\x04\x1d\x36\x4f" - "\x68\x81\x9a\xb3\xcc\xe5\xfe\x17" - "\x30\x49\x62\x7b\x94\xad\xc6\xdf" - "\xf8\x11\x2a\x43\x5c\x75\x8e\xa7" - "\xc0\xd9\xf2\x0b\x24\x3d\x56\x6f" - "\x88\xa1\xba\xd3\xec\x05\x1e\x37" - "\x50\x69\x82\x9b\xb4\xcd\xe6\xff" - "\x18\x31\x4a\x63\x7c\x95\xae\xc7" - "\xe0\xf9\x12\x2b\x44\x5d\x76\x8f" - "\xa8\xc1\xda\xf3\x0c\x25\x3e\x57" - "\x70\x89\xa2\xbb\xd4\xed\x06\x1f" - "\x38\x51\x6a\x83\x9c\xb5\xce\xe7" - "\x00\x1b\x36\x51\x6c\x87\xa2\xbd" - "\xd8\xf3\x0e\x29\x44\x5f\x7a\x95" - "\xb0\xcb\xe6\x01\x1c\x37\x52\x6d" - "\x88\xa3\xbe\xd9\xf4\x0f\x2a\x45" - "\x60\x7b\x96\xb1\xcc\xe7\x02\x1d" - "\x38\x53\x6e\x89\xa4\xbf\xda\xf5" - "\x10\x2b\x46\x61\x7c\x97\xb2\xcd" - "\xe8\x03\x1e\x39\x54\x6f\x8a\xa5" - "\xc0\xdb\xf6\x11\x2c\x47\x62\x7d" - "\x98\xb3\xce\xe9\x04\x1f\x3a\x55" - "\x70\x8b\xa6\xc1\xdc\xf7\x12\x2d" - "\x48\x63\x7e\x99\xb4\xcf\xea\x05" - "\x20\x3b\x56\x71\x8c\xa7\xc2\xdd" - "\xf8\x13\x2e\x49\x64\x7f\x9a\xb5" - "\xd0\xeb\x06\x21\x3c\x57\x72\x8d" - "\xa8\xc3\xde\xf9\x14\x2f\x4a\x65" - "\x80\x9b\xb6\xd1\xec\x07\x22\x3d" - "\x58\x73\x8e\xa9\xc4\xdf\xfa\x15" - "\x30\x4b\x66\x81\x9c\xb7\xd2\xed" - "\x08\x23\x3e\x59\x74\x8f\xaa\xc5" - "\xe0\xfb\x16\x31\x4c\x67\x82\x9d" - "\xb8\xd3\xee\x09\x24\x3f\x5a\x75" - "\x90\xab\xc6\xe1\xfc\x17\x32\x4d" - "\x68\x83\x9e\xb9\xd4\xef\x0a\x25" - "\x40\x5b\x76\x91\xac\xc7\xe2\xfd" - "\x18\x33\x4e\x69\x84\x9f\xba\xd5" - "\xf0\x0b\x26\x41\x5c\x77\x92\xad" - "\xc8\xe3\xfe\x19\x34\x4f\x6a\x85" - "\xa0\xbb\xd6\xf1\x0c\x27\x42\x5d" - "\x78\x93\xae\xc9\xe4\xff\x1a\x35" - "\x50\x6b\x86\xa1\xbc\xd7\xf2\x0d" - "\x28\x43\x5e\x79\x94\xaf\xca\xe5" - "\x00\x1d\x3a\x57\x74\x91\xae\xcb" - "\xe8\x05\x22\x3f\x5c\x79\x96\xb3" - "\xd0\xed\x0a\x27\x44\x61\x7e\x9b" - "\xb8\xd5\xf2\x0f\x2c\x49\x66\x83" - "\xa0\xbd\xda\xf7\x14\x31\x4e\x6b" - "\x88\xa5\xc2\xdf\xfc\x19\x36\x53" - "\x70\x8d\xaa\xc7\xe4\x01\x1e\x3b" - "\x58\x75\x92\xaf\xcc\xe9\x06\x23" - "\x40\x5d\x7a\x97\xb4\xd1\xee\x0b" - "\x28\x45\x62\x7f\x9c\xb9\xd6\xf3" - "\x10\x2d\x4a\x67\x84\xa1\xbe\xdb" - "\xf8\x15\x32\x4f\x6c\x89\xa6\xc3" - "\xe0\xfd\x1a\x37\x54\x71\x8e\xab" - "\xc8\xe5\x02\x1f\x3c\x59\x76\x93" - "\xb0\xcd\xea\x07\x24\x41\x5e\x7b" - "\x98\xb5\xd2\xef\x0c\x29\x46\x63" - "\x80\x9d\xba\xd7\xf4\x11\x2e\x4b" - "\x68\x85\xa2\xbf\xdc\xf9\x16\x33" - "\x50\x6d\x8a\xa7\xc4\xe1\xfe\x1b" - "\x38\x55\x72\x8f\xac\xc9\xe6\x03" - "\x20\x3d\x5a\x77\x94\xb1\xce\xeb" - "\x08\x25\x42\x5f\x7c\x99\xb6\xd3" - "\xf0\x0d\x2a\x47\x64\x81\x9e\xbb" - "\xd8\xf5\x12\x2f\x4c\x69\x86\xa3" - "\xc0\xdd\xfa\x17\x34\x51\x6e\x8b" - "\xa8\xc5\xe2\xff\x1c\x39\x56\x73" - "\x90\xad\xca\xe7\x04\x21\x3e\x5b" - "\x78\x95\xb2\xcf\xec\x09\x26\x43" - "\x60\x7d\x9a\xb7\xd4\xf1\x0e\x2b" - "\x48\x65\x82\x9f\xbc\xd9\xf6\x13" - "\x30\x4d\x6a\x87\xa4\xc1\xde\xfb" - "\x18\x35\x52\x6f\x8c\xa9\xc6\xe3" - "\x00\x1f\x3e\x5d\x7c\x9b\xba\xd9" - "\xf8\x17\x36\x55\x74\x93\xb2\xd1" - "\xf0\x0f\x2e\x4d\x6c\x8b\xaa\xc9" - "\xe8\x07\x26\x45\x64\x83\xa2\xc1" - "\xe0\xff\x1e\x3d\x5c\x7b\x9a\xb9" - "\xd8\xf7\x16\x35\x54\x73\x92\xb1" - "\xd0\xef\x0e\x2d\x4c\x6b\x8a\xa9" - "\xc8\xe7\x06\x25\x44\x63\x82\xa1" - "\xc0\xdf\xfe\x1d\x3c\x5b\x7a\x99" - "\xb8\xd7\xf6\x15\x34\x53\x72\x91" - "\xb0\xcf\xee\x0d\x2c\x4b\x6a\x89" - "\xa8\xc7\xe6\x05\x24\x43\x62\x81" - "\xa0\xbf\xde\xfd\x1c\x3b\x5a\x79" - "\x98\xb7\xd6\xf5\x14\x33\x52\x71" - "\x90\xaf\xce\xed\x0c\x2b\x4a\x69" - "\x88\xa7\xc6\xe5\x04\x23\x42\x61" - "\x80\x9f\xbe\xdd\xfc\x1b\x3a\x59" - "\x78\x97\xb6\xd5\xf4\x13\x32\x51" - "\x70\x8f\xae\xcd\xec\x0b\x2a\x49" - "\x68\x87\xa6\xc5\xe4\x03\x22\x41" - "\x60\x7f\x9e\xbd\xdc\xfb\x1a\x39" - "\x58\x77\x96\xb5\xd4\xf3\x12\x31" - "\x50\x6f\x8e\xad\xcc\xeb\x0a\x29" - "\x48\x67\x86\xa5\xc4\xe3\x02\x21" - "\x40\x5f\x7e\x9d\xbc\xdb\xfa\x19" - "\x38\x57\x76\x95\xb4\xd3\xf2\x11" - "\x30\x4f\x6e\x8d\xac\xcb\xea\x09" - "\x28\x47\x66\x85\xa4\xc3\xe2\x01" - "\x20\x3f\x5e\x7d\x9c\xbb\xda\xf9" - "\x18\x37\x56\x75\x94\xb3\xd2\xf1" - "\x10\x2f\x4e\x6d\x8c\xab\xca\xe9" - "\x08\x27\x46\x65\x84\xa3\xc2\xe1" - "\x00\x21\x42\x63", - .ctext = - "\xb5\x81\xf5\x64\x18\x73\xe3\xf0" - "\x4c\x13\xf2\x77\x18\x60\x65\x5e" - "\x29\x01\xce\x98\x55\x53\xf9\x0c" - "\x2a\x08\xd5\x09\xb3\x57\x55\x56" - "\xc5\xe9\x56\x90\xcb\x6a\xa3\xc0" - "\xff\xc4\x79\xb4\xd2\x97\x5d\xc4" - "\x43\xd1\xfe\x94\x7b\x88\x06\x5a" - "\xb2\x9e\x2c\xfc\x44\x03\xb7\x90" - "\xa0\xc1\xba\x6a\x33\xb8\xc7\xb2" - "\x9d\xe1\x12\x4f\xc0\x64\xd4\x01" - "\xfe\x8c\x7a\x66\xf7\xe6\x5a\x91" - "\xbb\xde\x56\x86\xab\x65\x21\x30" - "\x00\x84\x65\x24\xa5\x7d\x85\xb4" - "\xe3\x17\xed\x3a\xb7\x6f\xb4\x0b" - "\x0b\xaf\x15\xae\x5a\x8f\xf2\x0c" - "\x2f\x27\xf4\x09\xd8\xd2\x96\xb7" - "\x71\xf2\xc5\x99\x4d\x7e\x7f\x75" - "\x77\x89\x30\x8b\x59\xdb\xa2\xb2" - "\xa0\xf3\x19\x39\x2b\xc5\x7e\x3f" - "\x4f\xd9\xd3\x56\x28\x97\x44\xdc" - "\xc0\x8b\x77\x24\xd9\x52\xe7\xc5" - "\xaf\xf6\x7d\x59\xb2\x44\x05\x1d" - "\xb1\xb0\x11\xa5\x0f\xec\x33\xe1" - "\x6d\x1b\x4e\x1f\xff\x57\x91\xb4" - "\x5b\x9a\x96\xc5\x53\xbc\xae\x20" - "\x3c\xbb\x14\xe2\xe8\x22\x33\xc1" - "\x5e\x76\x9e\x46\x99\xf6\x2a\x15" - "\xc6\x97\x02\xa0\x66\x43\xd1\xa6" - "\x31\xa6\x9f\xfb\xf4\xd3\x69\xe5" - "\xcd\x76\x95\xb8\x7a\x82\x7f\x21" - "\x45\xff\x3f\xce\x55\xf6\x95\x10" - "\x08\x77\x10\x43\xc6\xf3\x09\xe5" - "\x68\xe7\x3c\xad\x00\x52\x45\x0d" - "\xfe\x2d\xc6\xc2\x94\x8c\x12\x1d" - "\xe6\x25\xae\x98\x12\x8e\x19\x9c" - "\x81\x68\xb1\x11\xf6\x69\xda\xe3" - "\x62\x08\x18\x7a\x25\x49\x28\xac" - "\xba\x71\x12\x0b\xe4\xa2\xe5\xc7" - "\x5d\x8e\xec\x49\x40\x21\xbf\x5a" - "\x98\xf3\x02\x68\x55\x03\x7f\x8a" - "\xe5\x94\x0c\x32\x5c\x07\x82\x63" - "\xaf\x6f\x91\x40\x84\x8e\x52\x25" - "\xd0\xb0\x29\x53\x05\xe2\x50\x7a" - "\x34\xeb\xc9\x46\x20\xa8\x3d\xde" - "\x7f\x16\x5f\x36\xc5\x2e\xdc\xd1" - "\x15\x47\xc7\x50\x40\x6d\x91\xc5" - "\xe7\x93\x95\x1a\xd3\x57\xbc\x52" - "\x33\xee\x14\x19\x22\x52\x89\xa7" - "\x4a\x25\x56\x77\x4b\xca\xcf\x0a" - "\xe1\xf5\x35\x85\x30\x7e\x59\x4a" - "\xbd\x14\x5b\xdf\xe3\x46\xcb\xac" - "\x1f\x6c\x96\x0e\xf4\x81\xd1\x99" - "\xca\x88\x63\x3d\x02\x58\x6b\xa9" - "\xe5\x9f\xb3\x00\xb2\x54\xc6\x74" - "\x1c\xbf\x46\xab\x97\xcc\xf8\x54" - "\x04\x07\x08\x52\xe6\xc0\xda\x93" - "\x74\x7d\x93\x99\x5d\x78\x68\xa6" - "\x2e\x6b\xd3\x6a\x69\xcc\x12\x6b" - "\xd4\xc7\xa5\xc6\xe7\xf6\x03\x04" - "\x5d\xcd\x61\x5e\x17\x40\xdc\xd1" - "\x5c\xf5\x08\xdf\x5c\x90\x85\xa4" - "\xaf\xf6\x78\xbb\x0d\xf1\xf4\xa4" - "\x54\x26\x72\x9e\x61\xfa\x86\xcf" - "\xe8\x9e\xa1\xe0\xc7\x48\x23\xae" - "\x5a\x90\xae\x75\x0a\x74\x18\x89" - "\x05\xb1\x92\xb2\x7f\xd0\x1b\xa6" - "\x62\x07\x25\x01\xc7\xc2\x4f\xf9" - "\xe8\xfe\x63\x95\x80\x07\xb4\x26" - "\xcc\xd1\x26\xb6\xc4\x3f\x9e\xcb" - "\x8e\x3b\x2e\x44\x16\xd3\x10\x9a" - "\x95\x08\xeb\xc8\xcb\xeb\xbf\x6f" - "\x0b\xcd\x1f\xc8\xca\x86\xaa\xec" - "\x33\xe6\x69\xf4\x45\x25\x86\x3a" - "\x22\x94\x4f\x00\x23\x6a\x44\xc2" - "\x49\x97\x33\xab\x36\x14\x0a\x70" - "\x24\xc3\xbe\x04\x3b\x79\xa0\xf9" - "\xb8\xe7\x76\x29\x22\x83\xd7\xf2" - "\x94\xf4\x41\x49\xba\x5f\x7b\x07" - "\xb5\xfb\xdb\x03\x1a\x9f\xb6\x4c" - "\xc2\x2e\x37\x40\x49\xc3\x38\x16" - "\xe2\x4f\x77\x82\xb0\x68\x4c\x71" - "\x1d\x57\x61\x9c\xd9\x4e\x54\x99" - "\x47\x13\x28\x73\x3c\xbb\x00\x90" - "\xf3\x4d\xc9\x0e\xfd\xe7\xb1\x71" - "\xd3\x15\x79\xbf\xcc\x26\x2f\xbd" - "\xad\x6c\x50\x69\x6c\x3e\x6d\x80" - "\x9a\xea\x78\xaf\x19\xb2\x0d\x4d" - "\xad\x04\x07\xae\x22\x90\x4a\x93" - "\x32\x0e\x36\x9b\x1b\x46\xba\x3b" - "\xb4\xac\xc6\xd1\xa2\x31\x53\x3b" - "\x2a\x3d\x45\xfe\x03\x61\x10\x85" - "\x17\x69\xa6\x78\xcc\x6c\x87\x49" - "\x53\xf9\x80\x10\xde\x80\xa2\x41" - "\x6a\xc3\x32\x02\xad\x6d\x3c\x56" - "\x00\x71\x51\x06\xa7\xbd\xfb\xef" - "\x3c\xb5\x9f\xfc\x48\x7d\x53\x7c" - "\x66\xb0\x49\x23\xc4\x47\x10\x0e" - "\xe5\x6c\x74\x13\xe6\xc5\x3f\xaa" - "\xde\xff\x07\x44\xdd\x56\x1b\xad" - "\x09\x77\xfb\x5b\x12\xb8\x0d\x38" - "\x17\x37\x35\x7b\x9b\xbc\xfe\xd4" - "\x7e\x8b\xda\x7e\x5b\x04\xa7\x22" - "\xa7\x31\xa1\x20\x86\xc7\x1b\x99" - "\xdb\xd1\x89\xf4\x94\xa3\x53\x69" - "\x8d\xe7\xe8\x74\x11\x8d\x74\xd6" - "\x07\x37\x91\x9f\xfd\x67\x50\x3a" - "\xc9\xe1\xf4\x36\xd5\xa0\x47\xd1" - "\xf9\xe5\x39\xa3\x31\xac\x07\x36" - "\x23\xf8\x66\x18\x14\x28\x34\x0f" - "\xb8\xd0\xe7\x29\xb3\x04\x4b\x55" - "\x01\x41\xb2\x75\x8d\xcb\x96\x85" - "\x3a\xfb\xab\x2b\x9e\xfa\x58\x20" - "\x44\x1f\xc0\x14\x22\x75\x61\xe8" - "\xaa\x19\xcf\xf1\x82\x56\xf4\xd7" - "\x78\x7b\x3d\x5f\xb3\x9e\x0b\x8a" - "\x57\x50\xdb\x17\x41\x65\x4d\xa3" - "\x02\xc9\x9c\x9c\x53\xfb\x39\x39" - "\x9b\x1d\x72\x24\xda\xb7\x39\xbe" - "\x13\x3b\xfa\x29\xda\x9e\x54\x64" - "\x6e\xba\xd8\xa1\xcb\xb3\x36\xfa" - "\xcb\x47\x85\xe9\x61\x38\xbc\xbe" - "\xc5\x00\x38\x2a\x54\xf7\xc4\xb9" - "\xb3\xd3\x7b\xa0\xa0\xf8\x72\x7f" - "\x8c\x8e\x82\x0e\xc6\x1c\x75\x9d" - "\xca\x8e\x61\x87\xde\xad\x80\xd2" - "\xf5\xf9\x80\xef\x15\x75\xaf\xf5" - "\x80\xfb\xff\x6d\x1e\x25\xb7\x40" - "\x61\x6a\x39\x5a\x6a\xb5\x31\xab" - "\x97\x8a\x19\x89\x44\x40\xc0\xa6" - "\xb4\x4e\x30\x32\x7b\x13\xe7\x67" - "\xa9\x8b\x57\x04\xc2\x01\xa6\xf4" - "\x28\x99\xad\x2c\x76\xa3\x78\xc2" - "\x4a\xe6\xca\x5c\x50\x6a\xc1\xb0" - "\x62\x4b\x10\x8e\x7c\x17\x43\xb3" - "\x17\x66\x1c\x3e\x8d\x69\xf0\x5a" - "\x71\xf5\x97\xdc\xd1\x45\xdd\x28" - "\xf3\x5d\xdf\x53\x7b\x11\xe5\xbc" - "\x4c\xdb\x1b\x51\x6b\xe9\xfb\x3d" - "\xc1\xc3\x2c\xb9\x71\xf5\xb6\xb2" - "\x13\x36\x79\x80\x53\xe8\xd3\xa6" - "\x0a\xaf\xfd\x56\x97\xf7\x40\x8e" - "\x45\xce\xf8\xb0\x9e\x5c\x33\x82" - "\xb0\x44\x56\xfc\x05\x09\xe9\x2a" - "\xac\x26\x80\x14\x1d\xc8\x3a\x35" - "\x4c\x82\x97\xfd\x76\xb7\xa9\x0a" - "\x35\x58\x79\x8e\x0f\x66\xea\xaf" - "\x51\x6c\x09\xa9\x6e\x9b\xcb\x9a" - "\x31\x47\xa0\x2f\x7c\x71\xb4\x4a" - "\x11\xaa\x8c\x66\xc5\x64\xe6\x3a" - "\x54\xda\x24\x6a\xc4\x41\x65\x46" - "\x82\xa0\x0a\x0f\x5f\xfb\x25\xd0" - "\x2c\x91\xa7\xee\xc4\x81\x07\x86" - "\x75\x5e\x33\x69\x97\xe4\x2c\xa8" - "\x9d\x9f\x0b\x6a\xbe\xad\x98\xda" - "\x6d\x94\x41\xda\x2c\x1e\x89\xc4" - "\xc2\xaf\x1e\x00\x05\x0b\x83\x60" - "\xbd\x43\xea\x15\x23\x7f\xb9\xac" - "\xee\x4f\x2c\xaf\x2a\xf3\xdf\xd0" - "\xf3\x19\x31\xbb\x4a\x74\x84\x17" - "\x52\x32\x2c\x7d\x61\xe4\xcb\xeb" - "\x80\x38\x15\x52\xcb\x6f\xea\xe5" - "\x73\x9c\xd9\x24\x69\xc6\x95\x32" - "\x21\xc8\x11\xe4\xdc\x36\xd7\x93" - "\x38\x66\xfb\xb2\x7f\x3a\xb9\xaf" - "\x31\xdd\x93\x75\x78\x8a\x2c\x94" - "\x87\x1a\x58\xec\x9e\x7d\x4d\xba" - "\xe1\xe5\x4d\xfc\xbc\xa4\x2a\x14" - "\xef\xcc\xa7\xec\xab\x43\x09\x18" - "\xd3\xab\x68\xd1\x07\x99\x44\x47" - "\xd6\x83\x85\x3b\x30\xea\xa9\x6b" - "\x63\xea\xc4\x07\xfb\x43\x2f\xa4" - "\xaa\xb0\xab\x03\x89\xce\x3f\x8c" - "\x02\x7c\x86\x54\xbc\x88\xaf\x75" - "\xd2\xdc\x63\x17\xd3\x26\xf6\x96" - "\xa9\x3c\xf1\x61\x8c\x11\x18\xcc" - "\xd6\xea\x5b\xe2\xcd\xf0\xf1\xb2" - "\xe5\x35\x90\x1f\x85\x4c\x76\x5b" - "\x66\xce\x44\xa4\x32\x9f\xe6\x7b" - "\x71\x6e\x9f\x58\x15\x67\x72\x87" - "\x64\x8e\x3a\x44\x45\xd4\x76\xfa" - "\xc2\xf6\xef\x85\x05\x18\x7a\x9b" - "\xba\x41\x54\xac\xf0\xfc\x59\x12" - "\x3f\xdf\xa0\xe5\x8a\x65\xfd\x3a" - "\x62\x8d\x83\x2c\x03\xbe\x05\x76" - "\x2e\x53\x49\x97\x94\x33\xae\x40" - "\x81\x15\xdb\x6e\xad\xaa\xf5\x4b" - "\xe3\x98\x70\xdf\xe0\x7c\xcd\xdb" - "\x02\xd4\x7d\x2f\xc1\xe6\xb4\xf3" - "\xd7\x0d\x7a\xd9\x23\x9e\x87\x2d" - "\xce\x87\xad\xcc\x72\x05\x00\x29" - "\xdc\x73\x7f\x64\xc1\x15\x0e\xc2" - "\xdf\xa7\x5f\xeb\x41\xa1\xcd\xef" - "\x5c\x50\x79\x2a\x56\x56\x71\x8c" - "\xac\xc0\x79\x50\x69\xca\x59\x32" - "\x65\xf2\x54\xe4\x52\x38\x76\xd1" - "\x5e\xde\x26\x9e\xfb\x75\x2e\x11" - "\xb5\x10\xf4\x17\x73\xf5\x89\xc7" - "\x4f\x43\x5c\x8e\x7c\xb9\x05\x52" - "\x24\x40\x99\xfe\x9b\x85\x0b\x6c" - "\x22\x3e\x8b\xae\x86\xa1\xd2\x79" - "\x05\x68\x6b\xab\xe3\x41\x49\xed" - "\x15\xa1\x8d\x40\x2d\x61\xdf\x1a" - "\x59\xc9\x26\x8b\xef\x30\x4c\x88" - "\x4b\x10\xf8\x8d\xa6\x92\x9f\x4b" - "\xf3\xc4\x53\x0b\x89\x5d\x28\x92" - "\xcf\x78\xb2\xc0\x5d\xed\x7e\xfc" - "\xc0\x12\x23\x5f\x5a\x78\x86\x43" - "\x6e\x27\xf7\x5a\xa7\x6a\xed\x19" - "\x04\xf0\xb3\x12\xd1\xbd\x0e\x89" - "\x6e\xbc\x96\xa8\xd8\x49\x39\x9f" - "\x7e\x67\xf0\x2e\x3e\x01\xa9\xba" - "\xec\x8b\x62\x8e\xcb\x4a\x70\x43" - "\xc7\xc2\xc4\xca\x82\x03\x73\xe9" - "\x11\xdf\xcf\x54\xea\xc9\xb0\x95" - "\x51\xc0\x13\x3d\x92\x05\xfa\xf4" - "\xa9\x34\xc8\xce\x6c\x3d\x54\xcc" - "\xc4\xaf\xf1\xdc\x11\x44\x26\xa2" - "\xaf\xf1\x85\x75\x7d\x03\x61\x68" - "\x4e\x78\xc6\x92\x7d\x86\x7d\x77" - "\xdc\x71\x72\xdb\xc6\xae\xa1\xcb" - "\x70\x9a\x0b\x19\xbe\x4a\x6c\x2a" - "\xe2\xba\x6c\x64\x9a\x13\x28\xdf" - "\x85\x75\xe6\x43\xf6\x87\x08\x68" - "\x6e\xba\x6e\x79\x9f\x04\xbc\x23" - "\x50\xf6\x33\x5c\x1f\x24\x25\xbe" - "\x33\x47\x80\x45\x56\xa3\xa7\xd7" - "\x7a\xb1\x34\x0b\x90\x3c\x9c\xad" - "\x44\x5f\x9e\x0e\x9d\xd4\xbd\x93" - "\x5e\xfa\x3c\xe0\xb0\xd9\xed\xf3" - "\xd6\x2e\xff\x24\xd8\x71\x6c\xed" - "\xaf\x55\xeb\x22\xac\x93\x68\x32" - "\x05\x5b\x47\xdd\xc6\x4a\xcb\xc7" - "\x10\xe1\x3c\x92\x1a\xf3\x23\x78" - "\x2b\xa1\xd2\x80\xf4\x12\xb1\x20" - "\x8f\xff\x26\x35\xdd\xfb\xc7\x4e" - "\x78\xf1\x2d\x50\x12\x77\xa8\x60" - "\x7c\x0f\xf5\x16\x2f\x63\x70\x2a" - "\xc0\x96\x80\x4e\x0a\xb4\x93\x35" - "\x5d\x1d\x3f\x56\xf7\x2f\xbb\x90" - "\x11\x16\x8f\xa2\xec\x47\xbe\xac" - "\x56\x01\x26\x56\xb1\x8c\xb2\x10" - "\xf9\x1a\xca\xf5\xd1\xb7\x39\x20" - "\x63\xf1\x69\x20\x4f\x13\x12\x1f" - "\x5b\x65\xfc\x98\xf7\xc4\x7a\xbe" - "\xf7\x26\x4d\x2b\x84\x7b\x42\xad" - "\xd8\x7a\x0a\xb4\xd8\x74\xbf\xc1" - "\xf0\x6e\xb4\x29\xa3\xbb\xca\x46" - "\x67\x70\x6a\x2d\xce\x0e\xa2\x8a" - "\xa9\x87\xbf\x05\xc4\xc1\x04\xa3" - "\xab\xd4\x45\x43\x8c\xb6\x02\xb0" - "\x41\xc8\xfc\x44\x3d\x59\xaa\x2e" - "\x44\x21\x2a\x8d\x88\x9d\x57\xf4" - "\xa0\x02\x77\xb8\xa6\xa0\xe6\x75" - "\x5c\x82\x65\x3e\x03\x5c\x29\x8f" - "\x38\x55\xab\x33\x26\xef\x9f\x43" - "\x52\xfd\x68\xaf\x36\xb4\xbb\x9a" - "\x58\x09\x09\x1b\xc3\x65\x46\x46" - "\x1d\xa7\x94\x18\x23\x50\x2c\xca" - "\x2c\x55\x19\x97\x01\x9d\x93\x3b" - "\x63\x86\xf2\x03\x67\x45\xd2\x72" - "\x28\x52\x6c\xf4\xe3\x1c\xb5\x11" - "\x13\xf1\xeb\x21\xc7\xd9\x56\x82" - "\x2b\x82\x39\xbd\x69\x54\xed\x62" - "\xc3\xe2\xde\x73\xd4\x6a\x12\xae" - "\x13\x21\x7f\x4b\x5b\xfc\xbf\xe8" - "\x2b\xbe\x56\xba\x68\x8b\x9a\xb1" - "\x6e\xfa\xbf\x7e\x5a\x4b\xf1\xac" - "\x98\x65\x85\xd1\x93\x53\xd3\x7b" - "\x09\xdd\x4b\x10\x6d\x84\xb0\x13" - "\x65\xbd\xcf\x52\x09\xc4\x85\xe2" - "\x84\x74\x15\x65\xb7\xf7\x51\xaf" - "\x55\xad\xa4\xd1\x22\x54\x70\x94" - "\xa0\x1c\x90\x41\xfd\x99\xd7\x5a" - "\x31\xef\xaa\x25\xd0\x7f\x4f\xea" - "\x1d\x55\x42\xe5\x49\xb0\xd0\x46" - "\x62\x36\x43\xb2\x82\x15\x75\x50" - "\xa4\x72\xeb\x54\x27\x1f\x8a\xe4" - "\x7d\xe9\x66\xc5\xf1\x53\xa4\xd1" - "\x0c\xeb\xb8\xf8\xbc\xd4\xe2\xe7" - "\xe1\xf8\x4b\xcb\xa9\xa1\xaf\x15" - "\x83\xcb\x72\xd0\x33\x79\x00\x2d" - "\x9f\xd7\xf1\x2e\x1e\x10\xe4\x45" - "\xc0\x75\x3a\x39\xea\x68\xf7\x5d" - "\x1b\x73\x8f\xe9\x8e\x0f\x72\x47" - "\xae\x35\x0a\x31\x7a\x14\x4d\x4a" - "\x6f\x47\xf7\x7e\x91\x6e\x74\x8b" - "\x26\x47\xf9\xc3\xf9\xde\x70\xf5" - "\x61\xab\xa9\x27\x9f\x82\xe4\x9c" - "\x89\x91\x3f\x2e\x6a\xfd\xb5\x49" - "\xe9\xfd\x59\x14\x36\x49\x40\x6d" - "\x32\xd8\x85\x42\xf3\xa5\xdf\x0c" - "\xa8\x27\xd7\x54\xe2\x63\x2f\xf2" - "\x7e\x8b\x8b\xe7\xf1\x9a\x95\x35" - "\x43\xdc\x3a\xe4\xb6\xf4\xd0\xdf" - "\x9c\xcb\x94\xf3\x21\xa0\x77\x50" - "\xe2\xc6\xc4\xc6\x5f\x09\x64\x5b" - "\x92\x90\xd8\xe1\xd1\xed\x4b\x42" - "\xd7\x37\xaf\x65\x3d\x11\x39\xb6" - "\x24\x8a\x60\xae\xd6\x1e\xbf\x0e" - "\x0d\xd7\xdc\x96\x0e\x65\x75\x4e" - "\x29\x06\x9d\xa4\x51\x3a\x10\x63" - "\x8f\x17\x07\xd5\x8e\x3c\xf4\x28" - "\x00\x5a\x5b\x05\x19\xd8\xc0\x6c" - "\xe5\x15\xe4\x9c\x9d\x71\x9d\x5e" - "\x94\x29\x1a\xa7\x80\xfa\x0e\x33" - "\x03\xdd\xb7\x3e\x9a\xa9\x26\x18" - "\x37\xa9\x64\x08\x4d\x94\x5a\x88" - "\xca\x35\xce\x81\x02\xe3\x1f\x1b" - "\x89\x1a\x77\x85\xe3\x41\x6d\x32" - "\x42\x19\x23\x7d\xc8\x73\xee\x25" - "\x85\x0d\xf8\x31\x25\x79\x1b\x6f" - "\x79\x25\xd2\xd8\xd4\x23\xfd\xf7" - "\x82\x36\x6a\x0c\x46\x22\x15\xe9" - "\xff\x72\x41\x91\x91\x7d\x3a\xb7" - "\xdd\x65\x99\x70\xf6\x8d\x84\xf8" - "\x67\x15\x20\x11\xd6\xb2\x55\x7b" - "\xdb\x87\xee\xef\x55\x89\x2a\x59" - "\x2b\x07\x8f\x43\x8a\x59\x3c\x01" - "\x8b\x65\x54\xa1\x66\xd5\x38\xbd" - "\xc6\x30\xa9\xcc\x49\xb6\xa8\x1b" - "\xb8\xc0\x0e\xe3\x45\x28\xe2\xff" - "\x41\x9f\x7e\x7c\xd1\xae\x9e\x25" - "\x3f\x4c\x7c\x7c\xf4\xa8\x26\x4d" - "\x5c\xfd\x4b\x27\x18\xf9\x61\x76" - "\x48\xba\x0c\x6b\xa9\x4d\xfc\xf5" - "\x3b\x35\x7e\x2f\x4a\xa9\xc2\x9a" - "\xae\xab\x86\x09\x89\xc9\xc2\x40" - "\x39\x2c\x81\xb3\xb8\x17\x67\xc2" - "\x0d\x32\x4a\x3a\x67\x81\xd7\x1a" - "\x34\x52\xc5\xdb\x0a\xf5\x63\x39" - "\xea\x1f\xe1\x7c\xa1\x9e\xc1\x35" - "\xe3\xb1\x18\x45\x67\xf9\x22\x38" - "\x95\xd9\x34\x34\x86\xc6\x41\x94" - "\x15\xf9\x5b\x41\xa6\x87\x8b\xf8" - "\xd5\xe1\x1b\xe2\x5b\xf3\x86\x10" - "\xff\xe6\xae\x69\x76\xbc\x0d\xb4" - "\x09\x90\x0c\xa2\x65\x0c\xad\x74" - "\xf5\xd7\xff\xda\xc1\xce\x85\xbe" - "\x00\xa7\xff\x4d\x2f\x65\xd3\x8c" - "\x86\x2d\x05\xe8\xed\x3e\x6b\x8b" - "\x0f\x3d\x83\x8c\xf1\x1d\x5b\x96" - "\x2e\xb1\x9c\xc2\x98\xe1\x70\xb9" - "\xba\x5c\x8a\x43\xd6\x34\xa7\x2d" - "\xc9\x92\xae\xf2\xa5\x7b\x05\x49" - "\xa7\x33\x34\x86\xca\xe4\x96\x23" - "\x76\x5b\xf2\xc6\xf1\x51\x28\x42" - "\x7b\xcc\x76\x8f\xfa\xa2\xad\x31" - "\xd4\xd6\x7a\x6d\x25\x25\x54\xe4" - "\x3f\x50\x59\xe1\x5c\x05\xb7\x27" - "\x48\xbf\x07\xec\x1b\x13\xbe\x2b" - "\xa1\x57\x2b\xd5\xab\xd7\xd0\x4c" - "\x1e\xcb\x71\x9b\xc5\x90\x85\xd3" - "\xde\x59\xec\x71\xeb\x89\xbb\xd0" - "\x09\x50\xe1\x16\x3f\xfd\x1c\x34" - "\xc3\x1c\xa1\x10\x77\x53\x98\xef" - "\xf2\xfd\xa5\x01\x59\xc2\x9b\x26" - "\xc7\x42\xd9\x49\xda\x58\x2b\x6e" - "\x9f\x53\x19\x76\x7e\xd9\xc9\x0e" - "\x68\xc8\x7f\x51\x22\x42\xef\x49" - "\xa4\x55\xb6\x36\xac\x09\xc7\x31" - "\x88\x15\x4b\x2e\x8f\x3a\x08\xf7" - "\xd8\xf7\xa8\xc5\xa9\x33\xa6\x45" - "\xe4\xc4\x94\x76\xf3\x0d\x8f\x7e" - "\xc8\xf6\xbc\x23\x0a\xb6\x4c\xd3" - "\x6a\xcd\x36\xc2\x90\x5c\x5c\x3c" - "\x65\x7b\xc2\xd6\xcc\xe6\x0d\x87" - "\x73\x2e\x71\x79\x16\x06\x63\x28" - "\x09\x15\xd8\x89\x38\x38\x3d\xb5" - "\x42\x1c\x08\x24\xf7\x2a\xd2\x9d" - "\xc8\xca\xef\xf9\x27\xd8\x07\x86" - "\xf7\x43\x0b\x55\x15\x3f\x9f\x83" - "\xef\xdc\x49\x9d\x2a\xc1\x54\x62" - "\xbd\x9b\x66\x55\x9f\xb7\x12\xf3" - "\x1b\x4d\x9d\x2a\x5c\xed\x87\x75" - "\x87\x26\xec\x61\x2c\xb4\x0f\x89" - "\xb0\xfb\x2e\x68\x5d\x15\xc7\x8d" - "\x2e\xc0\xd9\xec\xaf\x4f\xd2\x25" - "\x29\xe8\xd2\x26\x2b\x67\xe9\xfc" - "\x2b\xa8\x67\x96\x12\x1f\x5b\x96" - "\xc6\x14\x53\xaf\x44\xea\xd6\xe2" - "\x94\x98\xe4\x12\x93\x4c\x92\xe0" - "\x18\xa5\x8d\x2d\xe4\x71\x3c\x47" - "\x4c\xf7\xe6\x47\x9e\xc0\x68\xdf" - "\xd4\xf5\x5a\x74\xb1\x2b\x29\x03" - "\x19\x07\xaf\x90\x62\x5c\x68\x98" - "\x48\x16\x11\x02\x9d\xee\xb4\x9b" - "\xe5\x42\x7f\x08\xfd\x16\x32\x0b" - "\xd0\xb3\xfa\x2b\xb7\x99\xf9\x29" - "\xcd\x20\x45\x9f\xb3\x1a\x5d\xa2" - "\xaf\x4d\xe0\xbd\x42\x0d\xbc\x74" - "\x99\x9c\x8e\x53\x1a\xb4\x3e\xbd" - "\xa2\x9a\x2d\xf7\xf8\x39\x0f\x67" - "\x63\xfc\x6b\xc0\xaf\xb3\x4b\x4f" - "\x55\xc4\xcf\xa7\xc8\x04\x11\x3e" - "\x14\x32\xbb\x1b\x38\x77\xd6\x7f" - "\x54\x4c\xdf\x75\xf3\x07\x2d\x33" - "\x9b\xa8\x20\xe1\x7b\x12\xb5\xf3" - "\xef\x2f\xce\x72\xe5\x24\x60\xc1" - "\x30\xe2\xab\xa1\x8e\x11\x09\xa8" - "\x21\x33\x44\xfe\x7f\x35\x32\x93" - "\x39\xa7\xad\x8b\x79\x06\xb2\xcb" - "\x4e\xa9\x5f\xc7\xba\x74\x29\xec" - "\x93\xa0\x4e\x54\x93\xc0\xbc\x55" - "\x64\xf0\x48\xe5\x57\x99\xee\x75" - "\xd6\x79\x0f\x66\xb7\xc6\x57\x76" - "\xf7\xb7\xf3\x9c\xc5\x60\xe8\x7f" - "\x83\x76\xd6\x0e\xaa\xe6\x90\x39" - "\x1d\xa6\x32\x6a\x34\xe3\x55\xf8" - "\x58\xa0\x58\x7d\x33\xe0\x22\x39" - "\x44\x64\x87\x86\x5a\x2f\xa7\x7e" - "\x0f\x38\xea\xb0\x30\xcc\x61\xa5" - "\x6a\x32\xae\x1e\xf7\xe9\xd0\xa9" - "\x0c\x32\x4b\xb5\x49\x28\xab\x85" - "\x2f\x8e\x01\x36\x38\x52\xd0\xba" - "\xd6\x02\x78\xf8\x0e\x3e\x9c\x8b" - "\x6b\x45\x99\x3f\x5c\xfe\x58\xf1" - "\x5c\x94\x04\xe1\xf5\x18\x6d\x51" - "\xb2\x5d\x18\x20\xb6\xc2\x9a\x42" - "\x1d\xb3\xab\x3c\xb6\x3a\x13\x03" - "\xb2\x46\x82\x4f\xfc\x64\xbc\x4f" - "\xca\xfa\x9c\xc0\xd5\xa7\xbd\x11" - "\xb7\xe4\x5a\xf6\x6f\x4d\x4d\x54" - "\xea\xa4\x98\x66\xd4\x22\x3b\xd3" - "\x8f\x34\x47\xd9\x7c\xf4\x72\x3b" - "\x4d\x02\x77\xf6\xd6\xdd\x08\x0a" - "\x81\xe1\x86\x89\x3e\x56\x10\x3c" - "\xba\xd7\x81\x8c\x08\xbc\x8b\xe2" - "\x53\xec\xa7\x89\xee\xc8\x56\xb5" - "\x36\x2c\xb2\x03\xba\x99\xdd\x7c" - "\x48\xa0\xb0\xbc\x91\x33\xe9\xa8" - "\xcb\xcd\xcf\x59\x5f\x1f\x15\xe2" - "\x56\xf5\x4e\x01\x35\x27\x45\x77" - "\x47\xc8\xbc\xcb\x7e\x39\xc1\x97" - "\x28\xd3\x84\xfc\x2c\x3e\xc8\xad" - "\x9c\xf8\x8a\x61\x9c\x28\xaa\xc5" - "\x99\x20\x43\x85\x9d\xa5\xe2\x8b" - "\xb8\xae\xeb\xd0\x32\x0d\x52\x78" - "\x09\x56\x3f\xc7\xd8\x7e\x26\xfc" - "\x37\xfb\x6f\x04\xfc\xfa\x92\x10" - "\xac\xf8\x3e\x21\xdc\x8c\x21\x16" - "\x7d\x67\x6e\xf6\xcd\xda\xb6\x98" - "\x23\xab\x23\x3c\xb2\x10\xa0\x53" - "\x5a\x56\x9f\xc5\xd0\xff\xbb\xe4" - "\x98\x3c\x69\x1e\xdb\x38\x8f\x7e" - "\x0f\xd2\x98\x88\x81\x8b\x45\x67" - "\xea\x33\xf1\xeb\xe9\x97\x55\x2e" - "\xd9\xaa\xeb\x5a\xec\xda\xe1\x68" - "\xa8\x9d\x3c\x84\x7c\x05\x3d\x62" - "\x87\x8f\x03\x21\x28\x95\x0c\x89" - "\x25\x22\x4a\xb0\x93\xa9\x50\xa2" - "\x2f\x57\x6e\x18\x42\x19\x54\x0c" - "\x55\x67\xc6\x11\x49\xf4\x5c\xd2" - "\xe9\x3d\xdd\x8b\x48\x71\x21\x00" - "\xc3\x9a\x6c\x85\x74\x28\x83\x4a" - "\x1b\x31\x05\xe1\x06\x92\xe7\xda" - "\x85\x73\x78\x45\x20\x7f\xae\x13" - "\x7c\x33\x06\x22\xf4\x83\xf9\x35" - "\x3f\x6c\x71\xa8\x4e\x48\xbe\x9b" - "\xce\x8a\xba\xda\xbe\x28\x08\xf7" - "\xe2\x14\x8c\x71\xea\x72\xf9\x33" - "\xf2\x88\x3f\xd7\xbb\x69\x6c\x29" - "\x19\xdc\x84\xce\x1f\x12\x4f\xc8" - "\xaf\xa5\x04\xba\x5a\xab\xb0\xd9" - "\x14\x1f\x6c\x68\x98\x39\x89\x7a" - "\xd9\xd8\x2f\xdf\xa8\x47\x4a\x25" - "\xe2\xfb\x33\xf4\x59\x78\xe1\x68" - "\x85\xcf\xfe\x59\x20\xd4\x05\x1d" - "\x80\x99\xae\xbc\xca\xae\x0f\x2f" - "\x65\x43\x34\x8e\x7e\xac\xd3\x93" - "\x2f\xac\x6d\x14\x3d\x02\x07\x70" - "\x9d\xa4\xf3\x1b\x5c\x36\xfc\x01" - "\x73\x34\x85\x0c\x6c\xd6\xf1\xbd" - "\x3f\xdf\xee\xf5\xd9\xba\x56\xef" - "\xf4\x9b\x6b\xee\x9f\x5a\x78\x6d" - "\x32\x19\xf4\xf7\xf8\x4c\x69\x0b" - "\x4b\xbc\xbb\xb7\xf2\x85\xaf\x70" - "\x75\x24\x6c\x54\xa7\x0e\x4d\x1d" - "\x01\xbf\x08\xac\xcf\x7f\x2c\xe3" - "\x14\x89\x5e\x70\x5a\x99\x92\xcd" - "\x01\x84\xc8\xd2\xab\xe5\x4f\x58" - "\xe7\x0f\x2f\x0e\xff\x68\xea\xfd" - "\x15\xb3\x17\xe6\xb0\xe7\x85\xd8" - "\x23\x2e\x05\xc7\xc9\xc4\x46\x1f" - "\xe1\x9e\x49\x20\x23\x24\x4d\x7e" - "\x29\x65\xff\xf4\xb6\xfd\x1a\x85" - "\xc4\x16\xec\xfc\xea\x7b\xd6\x2c" - "\x43\xf8\xb7\xbf\x79\xc0\x85\xcd" - "\xef\xe1\x98\xd3\xa5\xf7\x90\x8c" - "\xe9\x7f\x80\x6b\xd2\xac\x4c\x30" - "\xa7\xc6\x61\x6c\xd2\xf9\x2c\xff" - "\x30\xbc\x22\x81\x7d\x93\x12\xe4" - "\x0a\xcd\xaf\xdd\xe8\xab\x0a\x1e" - "\x13\xa4\x27\xc3\x5f\xf7\x4b\xbb" - "\x37\x09\x4b\x91\x6f\x92\x4f\xaf" - "\x52\xee\xdf\xef\x09\x6f\xf7\x5c" - "\x6e\x12\x17\x72\x63\x57\xc7\xba" - "\x3b\x6b\x38\x32\x73\x1b\x9c\x80" - "\xc1\x7a\xc6\xcf\xcd\x35\xc0\x6b" - "\x31\x1a\x6b\xe9\xd8\x2c\x29\x3f" - "\x96\xfb\xb6\xcd\x13\x91\x3b\xc2" - "\xd2\xa3\x31\x8d\xa4\xcd\x57\xcd" - "\x13\x3d\x64\xfd\x06\xce\xe6\xdc" - "\x0c\x24\x43\x31\x40\x57\xf1\x72" - "\x17\xe3\x3a\x63\x6d\x35\xcf\x5d" - "\x97\x40\x59\xdd\xf7\x3c\x02\xf7" - "\x1c\x7e\x05\xbb\xa9\x0d\x01\xb1" - "\x8e\xc0\x30\xa9\x53\x24\xc9\x89" - "\x84\x6d\xaa\xd0\xcd\x91\xc2\x4d" - "\x91\xb0\x89\xe2\xbf\x83\x44\xaa" - "\x28\x72\x23\xa0\xc2\xad\xad\x1c" - "\xfc\x3f\x09\x7a\x0b\xdc\xc5\x1b" - "\x87\x13\xc6\x5b\x59\x8d\xf2\xc8" - "\xaf\xdf\x11\x95", - .len = 4100, - }, -}; - static const struct cipher_testvec chacha20_tv_template[] = { { /* RFC7539 A.2. Test Vector #1 */ .key = "\x00\x00\x00\x00\x00\x00\x00\x00" -- cgit v1.2.3 From 894fe3398a2175a471fae33fdbada36a66ddce12 Mon Sep 17 00:00:00 2001 From: Martin Kepplinger Date: Mon, 18 Jan 2021 11:54:24 +0100 Subject: dt-bindings: arm: fsl: Add the librem 5 Evergreen revision Add an entry for the Librem 5 phone, Evergreen revision which is supported by "r4". Schematics and more information can be found at https://developer.puri.sm/Librem5/Hardware_Reference/Evergreen.html Signed-off-by: Martin Kepplinger Reviewed-by: Krzysztof Kozlowski Acked-by: Rob Herring Signed-off-by: Shawn Guo --- Documentation/devicetree/bindings/arm/fsl.yaml | 1 + 1 file changed, 1 insertion(+) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/arm/fsl.yaml b/Documentation/devicetree/bindings/arm/fsl.yaml index 65038b16302e..47220e2f522c 100644 --- a/Documentation/devicetree/bindings/arm/fsl.yaml +++ b/Documentation/devicetree/bindings/arm/fsl.yaml @@ -742,6 +742,7 @@ properties: - enum: - purism,librem5r2 # Purism Librem5 phone "Chestnut" - purism,librem5r3 # Purism Librem5 phone "Dogwood" + - purism,librem5r4 # Purism Librem5 phone "Evergreen" - const: purism,librem5 - const: fsl,imx8mq -- cgit v1.2.3 From e4612ecd6f36e60c7bf0ad8922f11f6c3d557aea Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Fri, 29 Jan 2021 13:27:29 +0200 Subject: misc: pti: Remove a leftover in documentation Driver is gone, so is the documentation. Remove a leftover in documentation. Fixes: 8ba59e9dee31 ("misc: pti: Remove driver for deprecated platform") Reported-by: Stephen Rothwell Signed-off-by: Andy Shevchenko Link: https://lore.kernel.org/r/20210129112729.65363-1-andriy.shevchenko@linux.intel.com Signed-off-by: Greg Kroah-Hartman --- Documentation/driver-api/index.rst | 1 - 1 file changed, 1 deletion(-) (limited to 'Documentation') diff --git a/Documentation/driver-api/index.rst b/Documentation/driver-api/index.rst index 2456d0a97ed8..ef4bed8f3758 100644 --- a/Documentation/driver-api/index.rst +++ b/Documentation/driver-api/index.rst @@ -93,7 +93,6 @@ available subsections can be seen below. pps ptp phy/index - pti_intel_mid pwm pldmfw/index rfkill -- cgit v1.2.3 From 02bd88b4834d22cedd47f17fbce6cfa66a323287 Mon Sep 17 00:00:00 2001 From: Coiby Xu Date: Sat, 23 Jan 2021 18:46:13 +0800 Subject: staging: qlge: add documentation for debugging qlge Instructions and examples on kernel data structures dumping and coredump. Signed-off-by: Coiby Xu Link: https://lore.kernel.org/r/20210123104613.38359-9-coiby.xu@gmail.com Signed-off-by: Greg Kroah-Hartman --- Documentation/networking/device_drivers/index.rst | 1 + .../networking/device_drivers/qlogic/index.rst | 18 ++++ .../networking/device_drivers/qlogic/qlge.rst | 118 +++++++++++++++++++++ MAINTAINERS | 6 ++ 4 files changed, 143 insertions(+) create mode 100644 Documentation/networking/device_drivers/qlogic/index.rst create mode 100644 Documentation/networking/device_drivers/qlogic/qlge.rst (limited to 'Documentation') diff --git a/Documentation/networking/device_drivers/index.rst b/Documentation/networking/device_drivers/index.rst index a3113ffd7a16..d8279de7bf25 100644 --- a/Documentation/networking/device_drivers/index.rst +++ b/Documentation/networking/device_drivers/index.rst @@ -15,6 +15,7 @@ Contents: ethernet/index fddi/index hamradio/index + qlogic/index wan/index wifi/index diff --git a/Documentation/networking/device_drivers/qlogic/index.rst b/Documentation/networking/device_drivers/qlogic/index.rst new file mode 100644 index 000000000000..ad05b04286e4 --- /dev/null +++ b/Documentation/networking/device_drivers/qlogic/index.rst @@ -0,0 +1,18 @@ +.. SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) + +QLogic QLGE Device Drivers +=============================================== + +Contents: + +.. toctree:: + :maxdepth: 2 + + qlge + +.. only:: subproject and html + + Indices + ======= + + * :ref:`genindex` diff --git a/Documentation/networking/device_drivers/qlogic/qlge.rst b/Documentation/networking/device_drivers/qlogic/qlge.rst new file mode 100644 index 000000000000..0b888253d152 --- /dev/null +++ b/Documentation/networking/device_drivers/qlogic/qlge.rst @@ -0,0 +1,118 @@ +.. SPDX-License-Identifier: GPL-2.0 + +======================================= +QLogic QLGE 10Gb Ethernet device driver +======================================= + +This driver use drgn and devlink for debugging. + +Dump kernel data structures in drgn +----------------------------------- + +To dump kernel data structures, the following Python script can be used +in drgn: + +.. code-block:: python + + def align(x, a): + """the alignment a should be a power of 2 + """ + mask = a - 1 + return (x+ mask) & ~mask + + def struct_size(struct_type): + struct_str = "struct {}".format(struct_type) + return sizeof(Object(prog, struct_str, address=0x0)) + + def netdev_priv(netdevice): + NETDEV_ALIGN = 32 + return netdevice.value_() + align(struct_size("net_device"), NETDEV_ALIGN) + + name = 'xxx' + qlge_device = None + netdevices = prog['init_net'].dev_base_head.address_of_() + for netdevice in list_for_each_entry("struct net_device", netdevices, "dev_list"): + if netdevice.name.string_().decode('ascii') == name: + print(netdevice.name) + + ql_adapter = Object(prog, "struct ql_adapter", address=netdev_priv(qlge_device)) + +The struct ql_adapter will be printed in drgn as follows, + + >>> ql_adapter + (struct ql_adapter){ + .ricb = (struct ricb){ + .base_cq = (u8)0, + .flags = (u8)120, + .mask = (__le16)26637, + .hash_cq_id = (u8 [1024]){ 172, 142, 255, 255 }, + .ipv6_hash_key = (__le32 [10]){}, + .ipv4_hash_key = (__le32 [4]){}, + }, + .flags = (unsigned long)0, + .wol = (u32)0, + .nic_stats = (struct nic_stats){ + .tx_pkts = (u64)0, + .tx_bytes = (u64)0, + .tx_mcast_pkts = (u64)0, + .tx_bcast_pkts = (u64)0, + .tx_ucast_pkts = (u64)0, + .tx_ctl_pkts = (u64)0, + .tx_pause_pkts = (u64)0, + ... + }, + .active_vlans = (unsigned long [64]){ + 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 52780853100545, 18446744073709551615, + 18446619461681283072, 0, 42949673024, 2147483647, + }, + .rx_ring = (struct rx_ring [17]){ + { + .cqicb = (struct cqicb){ + .msix_vect = (u8)0, + .reserved1 = (u8)0, + .reserved2 = (u8)0, + .flags = (u8)0, + .len = (__le16)0, + .rid = (__le16)0, + ... + }, + .cq_base = (void *)0x0, + .cq_base_dma = (dma_addr_t)0, + } + ... + } + } + +coredump via devlink +-------------------- + + +And the coredump obtained via devlink in json format looks like, + +.. code:: shell + + $ devlink health dump show DEVICE reporter coredump -p -j + { + "Core Registers": { + "segment": 1, + "values": [ 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,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,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,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,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ] + }, + "Test Logic Regs": { + "segment": 2, + "values": [ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ] + }, + "RMII Registers": { + "segment": 3, + "values": [ 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,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 ] + }, + ... + "Sem Registers": { + "segment": 50, + "values": [ 0,0,0,0 ] + } + } + +When the module parameter qlge_force_coredump is set to be true, the MPI +RISC reset before coredumping. So coredumping will much longer since +devlink tool has to wait for 5 secs for the resetting to be +finished. diff --git a/MAINTAINERS b/MAINTAINERS index 992fe3b0900a..b835e83475e9 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -14616,6 +14616,12 @@ L: netdev@vger.kernel.org S: Supported F: drivers/staging/qlge/ +QLOGIC QLGE 10Gb ETHERNET DRIVER +M: Coiby Xu +L: netdev@vger.kernel.org +S: Maintained +F: Documentation/networking/device_drivers/qlogic/qlge.rst + QM1D1B0004 MEDIA DRIVER M: Akihiro Tsukada L: linux-media@vger.kernel.org -- cgit v1.2.3 From 6c50321fd65135a28450f16b5745b72368d61006 Mon Sep 17 00:00:00 2001 From: Thierry Reding Date: Thu, 28 Jan 2021 19:29:40 +0100 Subject: dt-bindings: arm: tegra: Document Jetson Xavier NX eMMC SKU Two different SKUs exist for the Jetson Xavier NX module, so document the compatible strings for both, as well as the developer kits that come with each of the SKUs. Signed-off-by: Thierry Reding --- Documentation/devicetree/bindings/arm/tegra.yaml | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/arm/tegra.yaml b/Documentation/devicetree/bindings/arm/tegra.yaml index c5fbf869aa93..b9f75e20fef5 100644 --- a/Documentation/devicetree/bindings/arm/tegra.yaml +++ b/Documentation/devicetree/bindings/arm/tegra.yaml @@ -120,10 +120,18 @@ properties: items: - const: nvidia,p3668-0000 - const: nvidia,tegra194 + - description: Jetson Xavier NX (eMMC) + items: + - const: nvidia,p3668-0001 + - const: nvidia,tegra194 - description: Jetson Xavier NX Developer Kit items: - const: nvidia,p3509-0000+p3668-0000 - const: nvidia,tegra194 + - description: Jetson Xavier NX Developer Kit (eMMC) + items: + - const: nvidia,p3509-0000+p3668-0001 + - const: nvidia,tegra194 - items: - enum: - nvidia,tegra234-vdk -- cgit v1.2.3 From 220c404dc7a5f94779db741fa96cb63ef03b6d08 Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Mon, 25 Jan 2021 10:53:26 -0800 Subject: hwmon: (pmbus/max16601) Determine and use number of populated phases The MAX16601 can report the number of populated phases. Use this information to only create sysfs attributes for populated phases. Cc: Alex Qiu Cc: Ugur Usug Signed-off-by: Guenter Roeck Link: https://lore.kernel.org/r/20210125185327.93282-1-linux@roeck-us.net Reviewed-by: Alex Qiu Signed-off-by: Guenter Roeck --- Documentation/hwmon/max16601.rst | 185 +++++++++++++++------------------------ drivers/hwmon/pmbus/max16601.c | 17 +++- 2 files changed, 89 insertions(+), 113 deletions(-) (limited to 'Documentation') diff --git a/Documentation/hwmon/max16601.rst b/Documentation/hwmon/max16601.rst index 346e74674c51..4813af0cc39d 100644 --- a/Documentation/hwmon/max16601.rst +++ b/Documentation/hwmon/max16601.rst @@ -45,115 +45,76 @@ Sysfs entries The following attributes are supported. -======================= ======================================================= -in1_label "vin1" -in1_input VCORE input voltage. -in1_alarm Input voltage alarm. - -in2_label "vout1" -in2_input VCORE output voltage. -in2_alarm Output voltage alarm. - -curr1_label "iin1" -curr1_input VCORE input current, derived from duty cycle and output - current. -curr1_max Maximum input current. -curr1_max_alarm Current high alarm. - -curr2_label "iin1.0" -curr2_input VCORE phase 0 input current. - -curr3_label "iin1.1" -curr3_input VCORE phase 1 input current. - -curr4_label "iin1.2" -curr4_input VCORE phase 2 input current. - -curr5_label "iin1.3" -curr5_input VCORE phase 3 input current. - -curr6_label "iin1.4" -curr6_input VCORE phase 4 input current. - -curr7_label "iin1.5" -curr7_input VCORE phase 5 input current. - -curr8_label "iin1.6" -curr8_input VCORE phase 6 input current. - -curr9_label "iin1.7" -curr9_input VCORE phase 7 input current. - -curr10_label "iin2" -curr10_input VCORE input current, derived from sensor element. - -curr11_label "iin3" -curr11_input VSA input current. - -curr12_label "iout1" -curr12_input VCORE output current. -curr12_crit Critical output current. -curr12_crit_alarm Output current critical alarm. -curr12_max Maximum output current. -curr12_max_alarm Output current high alarm. - -curr13_label "iout1.0" -curr13_input VCORE phase 0 output current. - -curr14_label "iout1.1" -curr14_input VCORE phase 1 output current. - -curr15_label "iout1.2" -curr15_input VCORE phase 2 output current. - -curr16_label "iout1.3" -curr16_input VCORE phase 3 output current. - -curr17_label "iout1.4" -curr17_input VCORE phase 4 output current. - -curr18_label "iout1.5" -curr18_input VCORE phase 5 output current. - -curr19_label "iout1.6" -curr19_input VCORE phase 6 output current. - -curr20_label "iout1.7" -curr20_input VCORE phase 7 output current. - -curr21_label "iout3" -curr21_input VSA output current. -curr21_highest Historical maximum VSA output current. -curr21_reset_history Write any value to reset curr21_highest. -curr21_crit Critical output current. -curr21_crit_alarm Output current critical alarm. -curr21_max Maximum output current. -curr21_max_alarm Output current high alarm. - -power1_label "pin1" -power1_input Input power, derived from duty cycle and output current. -power1_alarm Input power alarm. - -power2_label "pin2" -power2_input Input power, derived from input current sensor. - -power3_label "pout" -power3_input Output power. - -temp1_input VCORE temperature. -temp1_crit Critical high temperature. -temp1_crit_alarm Chip temperature critical high alarm. -temp1_max Maximum temperature. -temp1_max_alarm Chip temperature high alarm. - -temp2_input TSENSE_0 temperature -temp3_input TSENSE_1 temperature -temp4_input TSENSE_2 temperature -temp5_input TSENSE_3 temperature - -temp6_input VSA temperature. -temp6_crit Critical high temperature. -temp6_crit_alarm Chip temperature critical high alarm. -temp6_max Maximum temperature. -temp6_max_alarm Chip temperature high alarm. -======================= ======================================================= +=============================== =============================================== +in1_label "vin1" +in1_input VCORE input voltage. +in1_alarm Input voltage alarm. + +in2_label "vout1" +in2_input VCORE output voltage. +in2_alarm Output voltage alarm. + +curr1_label "iin1" +curr1_input VCORE input current, derived from duty cycle + and output current. +curr1_max Maximum input current. +curr1_max_alarm Current high alarm. + +curr[P+2]_label "iin1.P" +curr[P+2]_input VCORE phase P input current. + +curr[N+2]_label "iin2" +curr[N+2]_input VCORE input current, derived from sensor + element. + 'N' is the number of enabled/populated phases. + +curr[N+3]_label "iin3" +curr[N+3]_input VSA input current. + +curr[N+4]_label "iout1" +curr[N+4]_input VCORE output current. +curr[N+4]_crit Critical output current. +curr[N+4]_crit_alarm Output current critical alarm. +curr[N+4]_max Maximum output current. +curr[N+4]_max_alarm Output current high alarm. + +curr[N+P+5]_label "iout1.P" +curr[N+P+5]_input VCORE phase P output current. + +curr[2*N+5]_label "iout3" +curr[2*N+5]_input VSA output current. +curr[2*N+5]_highest Historical maximum VSA output current. +curr[2*N+5]_reset_history Write any value to reset curr21_highest. +curr[2*N+5]_crit Critical output current. +curr[2*N+5]_crit_alarm Output current critical alarm. +curr[2*N+5]_max Maximum output current. +curr[2*N+5]_max_alarm Output current high alarm. + +power1_label "pin1" +power1_input Input power, derived from duty cycle and output + current. +power1_alarm Input power alarm. + +power2_label "pin2" +power2_input Input power, derived from input current sensor. + +power3_label "pout" +power3_input Output power. + +temp1_input VCORE temperature. +temp1_crit Critical high temperature. +temp1_crit_alarm Chip temperature critical high alarm. +temp1_max Maximum temperature. +temp1_max_alarm Chip temperature high alarm. + +temp2_input TSENSE_0 temperature +temp3_input TSENSE_1 temperature +temp4_input TSENSE_2 temperature +temp5_input TSENSE_3 temperature + +temp6_input VSA temperature. +temp6_crit Critical high temperature. +temp6_crit_alarm Chip temperature critical high alarm. +temp6_max Maximum temperature. +temp6_max_alarm Chip temperature high alarm. +=============================== =============================================== diff --git a/drivers/hwmon/pmbus/max16601.c b/drivers/hwmon/pmbus/max16601.c index a960b86e72d2..efe6da3bc8d0 100644 --- a/drivers/hwmon/pmbus/max16601.c +++ b/drivers/hwmon/pmbus/max16601.c @@ -31,6 +31,7 @@ #include "pmbus.h" +#define REG_DEFAULT_NUM_POP 0xc4 #define REG_SETPT_DVID 0xd1 #define DAC_10MV_MODE BIT(4) #define REG_IOUT_AVG_PK 0xee @@ -40,6 +41,8 @@ #define CORE_RAIL_INDICATOR BIT(7) #define REG_PHASE_REPORTING 0xf4 +#define MAX16601_NUM_PHASES 8 + struct max16601_data { struct pmbus_driver_info info; struct i2c_client *vsa; @@ -195,6 +198,18 @@ static int max16601_identify(struct i2c_client *client, else info->vrm_version[0] = vr12; + reg = i2c_smbus_read_byte_data(client, REG_DEFAULT_NUM_POP); + if (reg < 0) + return reg; + + /* + * If REG_DEFAULT_NUM_POP returns 0, we don't know how many phases + * are populated. Stick with the default in that case. + */ + reg &= 0x0f; + if (reg && reg <= MAX16601_NUM_PHASES) + info->phases[0] = reg; + return 0; } @@ -216,7 +231,7 @@ static struct pmbus_driver_info max16601_info = { .func[2] = PMBUS_HAVE_IIN | PMBUS_HAVE_STATUS_INPUT | PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT | PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP | PMBUS_PAGE_VIRTUAL, - .phases[0] = 8, + .phases[0] = MAX16601_NUM_PHASES, .pfunc[0] = PMBUS_HAVE_IIN | PMBUS_HAVE_IOUT | PMBUS_HAVE_TEMP, .pfunc[1] = PMBUS_HAVE_IIN | PMBUS_HAVE_IOUT, .pfunc[2] = PMBUS_HAVE_IIN | PMBUS_HAVE_IOUT | PMBUS_HAVE_TEMP, -- cgit v1.2.3 From 66102281f94afdf1f41cf6147c7ddce73a8e75f2 Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Mon, 25 Jan 2021 10:53:27 -0800 Subject: hwmon: (pmbus/max16601) Add support for MAX16508 MAX16508 is quite similar to MAX16601, except that it does not support the DEFAULT_NUM_POP register and we thus can not dynamically determine the number of populated phases. Cc: Alex Qiu Cc: Ugur Usug Signed-off-by: Guenter Roeck Link: https://lore.kernel.org/r/20210125185327.93282-2-linux@roeck-us.net Reviewed-by: Alex Qiu Tested-by: Alex Qiu Signed-off-by: Guenter Roeck --- Documentation/hwmon/max16601.rst | 12 +++++-- drivers/hwmon/pmbus/Kconfig | 4 +-- drivers/hwmon/pmbus/max16601.c | 74 +++++++++++++++++++++++++++++----------- 3 files changed, 66 insertions(+), 24 deletions(-) (limited to 'Documentation') diff --git a/Documentation/hwmon/max16601.rst b/Documentation/hwmon/max16601.rst index 4813af0cc39d..92c0a7d7808c 100644 --- a/Documentation/hwmon/max16601.rst +++ b/Documentation/hwmon/max16601.rst @@ -5,6 +5,14 @@ Kernel driver max16601 Supported chips: + * Maxim MAX16508 + + Prefix: 'max16508' + + Addresses scanned: - + + Datasheet: Not published + * Maxim MAX16601 Prefix: 'max16601' @@ -19,8 +27,8 @@ Author: Guenter Roeck Description ----------- -This driver supports the MAX16601 VR13.HC Dual-Output Voltage Regulator -Chipset. +This driver supports the MAX16508 VR13 Dual-Output Voltage Regulator +as well as the MAX16601 VR13.HC Dual-Output Voltage Regulator chipsets. The driver is a client driver to the core PMBus driver. Please see Documentation/hwmon/pmbus.rst for details on PMBus client drivers. diff --git a/drivers/hwmon/pmbus/Kconfig b/drivers/hwmon/pmbus/Kconfig index 03606d4298a4..32d2fc850621 100644 --- a/drivers/hwmon/pmbus/Kconfig +++ b/drivers/hwmon/pmbus/Kconfig @@ -158,10 +158,10 @@ config SENSORS_MAX16064 be called max16064. config SENSORS_MAX16601 - tristate "Maxim MAX16601" + tristate "Maxim MAX16508, MAX16601" help If you say yes here you get hardware monitoring support for Maxim - MAX16601. + MAX16508 and MAX16601. This driver can also be built as a module. If so, the module will be called max16601. diff --git a/drivers/hwmon/pmbus/max16601.c b/drivers/hwmon/pmbus/max16601.c index efe6da3bc8d0..0d1204c2dd54 100644 --- a/drivers/hwmon/pmbus/max16601.c +++ b/drivers/hwmon/pmbus/max16601.c @@ -1,11 +1,11 @@ // SPDX-License-Identifier: GPL-2.0 /* - * Hardware monitoring driver for Maxim MAX16601 + * Hardware monitoring driver for Maxim MAX16508 and MAX16601. * * Implementation notes: * - * Ths chip supports two rails, VCORE and VSA. Telemetry information for the - * two rails is reported in two subsequent I2C addresses. The driver + * This chip series supports two rails, VCORE and VSA. Telemetry information + * for the two rails is reported in two subsequent I2C addresses. The driver * instantiates a dummy I2C client at the second I2C address to report * information for the VSA rail in a single instance of the driver. * Telemetry for the VSA rail is reported to the PMBus core in PMBus page 2. @@ -31,6 +31,8 @@ #include "pmbus.h" +enum chips { max16508, max16601 }; + #define REG_DEFAULT_NUM_POP 0xc4 #define REG_SETPT_DVID 0xd1 #define DAC_10MV_MODE BIT(4) @@ -44,6 +46,7 @@ #define MAX16601_NUM_PHASES 8 struct max16601_data { + enum chips id; struct pmbus_driver_info info; struct i2c_client *vsa; int iout_avg_pkg; @@ -188,6 +191,7 @@ static int max16601_write_word(struct i2c_client *client, int page, int reg, static int max16601_identify(struct i2c_client *client, struct pmbus_driver_info *info) { + struct max16601_data *data = to_max16601_data(info); int reg; reg = i2c_smbus_read_byte_data(client, REG_SETPT_DVID); @@ -198,6 +202,9 @@ static int max16601_identify(struct i2c_client *client, else info->vrm_version[0] = vr12; + if (data->id != max16601) + return 0; + reg = i2c_smbus_read_byte_data(client, REG_DEFAULT_NUM_POP); if (reg < 0) return reg; @@ -254,28 +261,61 @@ static void max16601_remove(void *_data) i2c_unregister_device(data->vsa); } -static int max16601_probe(struct i2c_client *client) +static const struct i2c_device_id max16601_id[] = { + {"max16508", max16508}, + {"max16601", max16601}, + {} +}; +MODULE_DEVICE_TABLE(i2c, max16601_id); + +static int max16601_get_id(struct i2c_client *client) { struct device *dev = &client->dev; u8 buf[I2C_SMBUS_BLOCK_MAX + 1]; - struct max16601_data *data; + enum chips id; int ret; - if (!i2c_check_functionality(client->adapter, - I2C_FUNC_SMBUS_READ_BYTE_DATA | - I2C_FUNC_SMBUS_READ_BLOCK_DATA)) - return -ENODEV; - ret = i2c_smbus_read_block_data(client, PMBUS_IC_DEVICE_ID, buf); - if (ret < 0) + if (ret < 0 || ret < 11) return -ENODEV; - /* PMBUS_IC_DEVICE_ID is expected to return "MAX16601y.xx" */ - if (ret < 11 || strncmp(buf, "MAX16601", 8)) { + /* + * PMBUS_IC_DEVICE_ID is expected to return "MAX16601y.xx" + * or "MAX16500y.xx". + */ + if (!strncmp(buf, "MAX16500", 8)) { + id = max16508; + } else if (!strncmp(buf, "MAX16601", 8)) { + id = max16601; + } else { buf[ret] = '\0'; dev_err(dev, "Unsupported chip '%s'\n", buf); return -ENODEV; } + return id; +} + +static int max16601_probe(struct i2c_client *client) +{ + struct device *dev = &client->dev; + const struct i2c_device_id *id; + struct max16601_data *data; + int ret, chip_id; + + if (!i2c_check_functionality(client->adapter, + I2C_FUNC_SMBUS_READ_BYTE_DATA | + I2C_FUNC_SMBUS_READ_BLOCK_DATA)) + return -ENODEV; + + chip_id = max16601_get_id(client); + if (chip_id < 0) + return chip_id; + + id = i2c_match_id(max16601_id, client); + if (chip_id != id->driver_data) + dev_warn(&client->dev, + "Device mismatch: Configured %s (%d), detected %d\n", + id->name, (int) id->driver_data, chip_id); ret = i2c_smbus_read_byte_data(client, REG_PHASE_ID); if (ret < 0) @@ -290,6 +330,7 @@ static int max16601_probe(struct i2c_client *client) if (!data) return -ENOMEM; + data->id = chip_id; data->iout_avg_pkg = 0xfc00; data->vsa = i2c_new_dummy_device(client->adapter, client->addr + 1); if (IS_ERR(data->vsa)) { @@ -305,13 +346,6 @@ static int max16601_probe(struct i2c_client *client) return pmbus_do_probe(client, &data->info); } -static const struct i2c_device_id max16601_id[] = { - {"max16601", 0}, - {} -}; - -MODULE_DEVICE_TABLE(i2c, max16601_id); - static struct i2c_driver max16601_driver = { .driver = { .name = "max16601", -- cgit v1.2.3 From d1eb86e59be09c12447fcb959783cbc70a9bec01 Mon Sep 17 00:00:00 2001 From: Zhang Rui Date: Fri, 29 Jan 2021 14:15:48 +0800 Subject: ACPI: tables: introduce support for FPDT table ACPI Firmware Performance Data Table (FPDT) provides information about firmware performance during system boot, S3 suspend and S3 resume. Have the kernel parse the FPDT table, and expose the firmware performance data to userspace as sysfs attributes under /sys/firmware/acpi/fpdt/. Tested-by: Todd Brandt Signed-off-by: Zhang Rui Signed-off-by: Rafael J. Wysocki --- Documentation/ABI/testing/sysfs-firmware-acpi | 43 +++++ drivers/acpi/Kconfig | 8 + drivers/acpi/Makefile | 1 + drivers/acpi/acpi_fpdt.c | 264 ++++++++++++++++++++++++++ 4 files changed, 316 insertions(+) create mode 100644 drivers/acpi/acpi_fpdt.c (limited to 'Documentation') diff --git a/Documentation/ABI/testing/sysfs-firmware-acpi b/Documentation/ABI/testing/sysfs-firmware-acpi index b16d30a71709..819939d858c9 100644 --- a/Documentation/ABI/testing/sysfs-firmware-acpi +++ b/Documentation/ABI/testing/sysfs-firmware-acpi @@ -1,3 +1,46 @@ +What: /sys/firmware/acpi/fpdt/ +Date: Jan 2021 +Contact: Zhang Rui +Description: + ACPI Firmware Performance Data Table (FPDT) provides + information for firmware performance data for system boot, + S3 suspend and S3 resume. This sysfs entry contains the + performance data retrieved from the FPDT. + + boot: + firmware_start_ns: Timer value logged at the beginning + of firmware image execution. In nanoseconds. + bootloader_load_ns: Timer value logged just prior to + loading the OS boot loader into memory. + In nanoseconds. + bootloader_launch_ns: Timer value logged just prior to + launching the currently loaded OS boot loader + image. In nanoseconds. + exitbootservice_start_ns: Timer value logged at the + point when the OS loader calls the + ExitBootServices function for UEFI compatible + firmware. In nanoseconds. + exitbootservice_end_ns: Timer value logged at the point + just prior to the OS loader gaining control + back from the ExitBootServices function for + UEFI compatible firmware. In nanoseconds. + suspend: + suspend_start_ns: Timer value recorded at the previous + OS write to SLP_TYP upon entry to S3. In + nanoseconds. + suspend_end_ns: Timer value recorded at the previous + firmware write to SLP_TYP used to trigger + hardware entry to S3. In nanoseconds. + resume: + resume_count: A count of the number of S3 resume cycles + since the last full boot sequence. + resume_avg_ns: Average timer value of all resume cycles + logged since the last full boot sequence, + including the most recent resume. In nanoseconds. + resume_prev_ns: Timer recorded at the end of the previous + platform runtime firmware S3 resume, just prior to + handoff to the OS waking vector. In nanoseconds. + What: /sys/firmware/acpi/bgrt/ Date: January 2012 Contact: Matthew Garrett diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig index ebcf534514be..cdfe5c75aa53 100644 --- a/drivers/acpi/Kconfig +++ b/drivers/acpi/Kconfig @@ -87,6 +87,14 @@ config ACPI_SPCR_TABLE This table provides information about the configuration of the earlycon console. +config ACPI_FPDT + bool "ACPI Firmware Performance Data Table (FPDT) support" + depends on X86_64 + help + Enable support for the Firmware Performance Data Table (FPDT). + This table provides information on the timing of the system + boot, S3 suspend and S3 resume firmware code paths. + config ACPI_LPIT bool depends on X86_64 diff --git a/drivers/acpi/Makefile b/drivers/acpi/Makefile index 076894a3330f..eb93bb7b6479 100644 --- a/drivers/acpi/Makefile +++ b/drivers/acpi/Makefile @@ -57,6 +57,7 @@ acpi-$(CONFIG_X86) += x86/utils.o acpi-$(CONFIG_X86) += x86/s2idle.o acpi-$(CONFIG_DEBUG_FS) += debugfs.o acpi-y += acpi_lpat.o +acpi-$(CONFIG_ACPI_FPDT) += acpi_fpdt.o acpi-$(CONFIG_ACPI_LPIT) += acpi_lpit.o acpi-$(CONFIG_ACPI_GENERIC_GSI) += irq.o acpi-$(CONFIG_ACPI_WATCHDOG) += acpi_watchdog.o diff --git a/drivers/acpi/acpi_fpdt.c b/drivers/acpi/acpi_fpdt.c new file mode 100644 index 000000000000..a89a806a7a2a --- /dev/null +++ b/drivers/acpi/acpi_fpdt.c @@ -0,0 +1,264 @@ +// SPDX-License-Identifier: GPL-2.0-only + +/* + * FPDT support for exporting boot and suspend/resume performance data + * + * Copyright (C) 2021 Intel Corporation. All rights reserved. + */ + +#define pr_fmt(fmt) "ACPI FPDT: " fmt + +#include + +/* + * FPDT contains ACPI table header and a number of fpdt_subtable_entries. + * Each fpdt_subtable_entry points to a subtable: FBPT or S3PT. + * Each FPDT subtable (FBPT/S3PT) is composed of a fpdt_subtable_header + * and a number of fpdt performance records. + * Each FPDT performance record is composed of a fpdt_record_header and + * performance data fields, for boot or suspend or resume phase. + */ +enum fpdt_subtable_type { + SUBTABLE_FBPT, + SUBTABLE_S3PT, +}; + +struct fpdt_subtable_entry { + u16 type; /* refer to enum fpdt_subtable_type */ + u8 length; + u8 revision; + u32 reserved; + u64 address; /* physical address of the S3PT/FBPT table */ +}; + +struct fpdt_subtable_header { + u32 signature; + u32 length; +}; + +enum fpdt_record_type { + RECORD_S3_RESUME, + RECORD_S3_SUSPEND, + RECORD_BOOT, +}; + +struct fpdt_record_header { + u16 type; /* refer to enum fpdt_record_type */ + u8 length; + u8 revision; +}; + +struct resume_performance_record { + struct fpdt_record_header header; + u32 resume_count; + u64 resume_prev; + u64 resume_avg; +} __attribute__((packed)); + +struct boot_performance_record { + struct fpdt_record_header header; + u32 reserved; + u64 firmware_start; + u64 bootloader_load; + u64 bootloader_launch; + u64 exitbootservice_start; + u64 exitbootservice_end; +} __attribute__((packed)); + +struct suspend_performance_record { + struct fpdt_record_header header; + u64 suspend_start; + u64 suspend_end; +} __attribute__((packed)); + + +static struct resume_performance_record *record_resume; +static struct suspend_performance_record *record_suspend; +static struct boot_performance_record *record_boot; + +#define FPDT_ATTR(phase, name) \ +static ssize_t name##_show(struct kobject *kobj, \ + struct kobj_attribute *attr, char *buf) \ +{ \ + return sprintf(buf, "%llu\n", record_##phase->name); \ +} \ +static struct kobj_attribute name##_attr = \ +__ATTR(name##_ns, 0444, name##_show, NULL) + +FPDT_ATTR(resume, resume_prev); +FPDT_ATTR(resume, resume_avg); +FPDT_ATTR(suspend, suspend_start); +FPDT_ATTR(suspend, suspend_end); +FPDT_ATTR(boot, firmware_start); +FPDT_ATTR(boot, bootloader_load); +FPDT_ATTR(boot, bootloader_launch); +FPDT_ATTR(boot, exitbootservice_start); +FPDT_ATTR(boot, exitbootservice_end); + +static ssize_t resume_count_show(struct kobject *kobj, + struct kobj_attribute *attr, char *buf) +{ + return sprintf(buf, "%u\n", record_resume->resume_count); +} + +static struct kobj_attribute resume_count_attr = +__ATTR_RO(resume_count); + +static struct attribute *resume_attrs[] = { + &resume_count_attr.attr, + &resume_prev_attr.attr, + &resume_avg_attr.attr, + NULL +}; + +static const struct attribute_group resume_attr_group = { + .attrs = resume_attrs, + .name = "resume", +}; + +static struct attribute *suspend_attrs[] = { + &suspend_start_attr.attr, + &suspend_end_attr.attr, + NULL +}; + +static const struct attribute_group suspend_attr_group = { + .attrs = suspend_attrs, + .name = "suspend", +}; + +static struct attribute *boot_attrs[] = { + &firmware_start_attr.attr, + &bootloader_load_attr.attr, + &bootloader_launch_attr.attr, + &exitbootservice_start_attr.attr, + &exitbootservice_end_attr.attr, + NULL +}; + +static const struct attribute_group boot_attr_group = { + .attrs = boot_attrs, + .name = "boot", +}; + +static struct kobject *fpdt_kobj; + +static int fpdt_process_subtable(u64 address, u32 subtable_type) +{ + struct fpdt_subtable_header *subtable_header; + struct fpdt_record_header *record_header; + char *signature = (subtable_type == SUBTABLE_FBPT ? "FBPT" : "S3PT"); + u32 length, offset; + int result; + + subtable_header = acpi_os_map_memory(address, sizeof(*subtable_header)); + if (!subtable_header) + return -ENOMEM; + + if (strncmp((char *)&subtable_header->signature, signature, 4)) { + pr_info(FW_BUG "subtable signature and type mismatch!\n"); + return -EINVAL; + } + + length = subtable_header->length; + acpi_os_unmap_memory(subtable_header, sizeof(*subtable_header)); + + subtable_header = acpi_os_map_memory(address, length); + if (!subtable_header) + return -ENOMEM; + + offset = sizeof(*subtable_header); + while (offset < length) { + record_header = (void *)subtable_header + offset; + offset += record_header->length; + + switch (record_header->type) { + case RECORD_S3_RESUME: + if (subtable_type != SUBTABLE_S3PT) { + pr_err(FW_BUG "Invalid record %d for subtable %s\n", + record_header->type, signature); + return -EINVAL; + } + if (record_resume) { + pr_err("Duplicate resume performance record found.\n"); + continue; + } + record_resume = (struct resume_performance_record *)record_header; + result = sysfs_create_group(fpdt_kobj, &resume_attr_group); + if (result) + return result; + break; + case RECORD_S3_SUSPEND: + if (subtable_type != SUBTABLE_S3PT) { + pr_err(FW_BUG "Invalid %d for subtable %s\n", + record_header->type, signature); + continue; + } + if (record_suspend) { + pr_err("Duplicate suspend performance record found.\n"); + continue; + } + record_suspend = (struct suspend_performance_record *)record_header; + result = sysfs_create_group(fpdt_kobj, &suspend_attr_group); + if (result) + return result; + break; + case RECORD_BOOT: + if (subtable_type != SUBTABLE_FBPT) { + pr_err(FW_BUG "Invalid %d for subtable %s\n", + record_header->type, signature); + return -EINVAL; + } + if (record_boot) { + pr_err("Duplicate boot performance record found.\n"); + continue; + } + record_boot = (struct boot_performance_record *)record_header; + result = sysfs_create_group(fpdt_kobj, &boot_attr_group); + if (result) + return result; + break; + + default: + pr_err(FW_BUG "Invalid record %d found.\n", record_header->type); + return -EINVAL; + } + } + return 0; +} + +static int __init acpi_init_fpdt(void) +{ + acpi_status status; + struct acpi_table_header *header; + struct fpdt_subtable_entry *subtable; + u32 offset = sizeof(*header); + + status = acpi_get_table(ACPI_SIG_FPDT, 0, &header); + + if (ACPI_FAILURE(status)) + return 0; + + fpdt_kobj = kobject_create_and_add("fpdt", acpi_kobj); + if (!fpdt_kobj) + return -ENOMEM; + + while (offset < header->length) { + subtable = (void *)header + offset; + switch (subtable->type) { + case SUBTABLE_FBPT: + case SUBTABLE_S3PT: + fpdt_process_subtable(subtable->address, + subtable->type); + break; + default: + pr_info(FW_BUG "Invalid subtable type %d found.\n", + subtable->type); + break; + } + offset += sizeof(*subtable); + } + return 0; +} + +fs_initcall(acpi_init_fpdt); -- cgit v1.2.3 From ed4e9e615b7ec4992a4eba1643e62ec2d9d979db Mon Sep 17 00:00:00 2001 From: Nathan Chancellor Date: Wed, 13 Jan 2021 17:34:47 -0700 Subject: Documentation/llvm: Add a section about supported architectures The most common question around building the Linux kernel with clang is "does it work?" and the answer has always been "it depends on your architecture, configuration, and LLVM version" with no hard answers for users wanting to experiment. LLVM support has significantly improved over the past couple of years, resulting in more architectures and configurations supported, and continuous integration has made it easier to see what works and what does not. Add a section that goes over what architectures are supported in the current kernel version, how they should be built (with just clang or the LLVM utilities as well), and the level of support they receive. This will make it easier for people to try out building their kernel with LLVM and reporting issues that come about from it. Suggested-by: Miguel Ojeda Signed-off-by: Nathan Chancellor Reviewed-by: Nick Desaulniers Signed-off-by: Masahiro Yamada --- Documentation/kbuild/llvm.rst | 44 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) (limited to 'Documentation') diff --git a/Documentation/kbuild/llvm.rst b/Documentation/kbuild/llvm.rst index 21c847890d03..b18401d2ba82 100644 --- a/Documentation/kbuild/llvm.rst +++ b/Documentation/kbuild/llvm.rst @@ -63,6 +63,50 @@ They can be enabled individually. The full list of the parameters: :: Currently, the integrated assembler is disabled by default. You can pass ``LLVM_IAS=1`` to enable it. +Supported Architectures +----------------------- + +LLVM does not target all of the architectures that Linux supports and +just because a target is supported in LLVM does not mean that the kernel +will build or work without any issues. Below is a general summary of +architectures that currently work with ``CC=clang`` or ``LLVM=1``. Level +of support corresponds to "S" values in the MAINTAINERS files. If an +architecture is not present, it either means that LLVM does not target +it or there are known issues. Using the latest stable version of LLVM or +even the development tree will generally yield the best results. +An architecture's ``defconfig`` is generally expected to work well, +certain configurations may have problems that have not been uncovered +yet. Bug reports are always welcome at the issue tracker below! + +.. list-table:: + :widths: 10 10 10 + :header-rows: 1 + + * - Architecture + - Level of support + - ``make`` command + * - arm + - Supported + - ``LLVM=1`` + * - arm64 + - Supported + - ``LLVM=1`` + * - mips + - Maintained + - ``CC=clang`` + * - powerpc + - Maintained + - ``CC=clang`` + * - riscv + - Maintained + - ``CC=clang`` + * - s390 + - Maintained + - ``CC=clang`` + * - x86 + - Supported + - ``LLVM=1`` + Getting Help ------------ -- cgit v1.2.3 From 32ada6b0980d86133d080d62371a5787ea2ec5ed Mon Sep 17 00:00:00 2001 From: Rob Herring Date: Thu, 28 Jan 2021 13:45:15 -0600 Subject: dt-bindings: Cleanup standard unit properties Properties with standard unit suffixes already have a type and don't need type definitions. They also default to a single entry, so 'maxItems: 1' can be dropped. adi,ad5758 is an oddball which defined an enum of arrays. While a valid schema, it is simpler as a whole to only define scalar constraints. Cc: Jean Delvare Cc: Lars-Peter Clausen Cc: Dmitry Torokhov Cc: Ulf Hansson Cc: "David S. Miller" Cc: Jakub Kicinski Cc: Serge Semin Cc: linux-hwmon@vger.kernel.org Cc: linux-i2c@vger.kernel.org Cc: linux-iio@vger.kernel.org Cc: linux-arm-kernel@lists.infradead.org Cc: linux-input@vger.kernel.org Cc: linux-mmc@vger.kernel.org Cc: netdev@vger.kernel.org Cc: linux-pm@vger.kernel.org Cc: linux-rtc@vger.kernel.org Cc: linux-serial@vger.kernel.org Cc: alsa-devel@alsa-project.org Cc: linux-watchdog@vger.kernel.org Signed-off-by: Rob Herring Acked-by: Guenter Roeck Acked-by: Mark Brown Acked-by: Wolfram Sang # for I2C Acked-by: Alexandre Belloni Acked-by: Greg Kroah-Hartman Acked-by: Sebastian Reichel # for power-supply Acked-by: Jonathan Cameron #for-iio Acked-by: Alexandre TORGUE Link: https://lore.kernel.org/r/20210128194515.743252-1-robh@kernel.org --- Documentation/devicetree/bindings/arm/cpus.yaml | 1 - .../devicetree/bindings/extcon/wlf,arizona.yaml | 1 - .../devicetree/bindings/hwmon/adi,ltc2947.yaml | 1 - .../devicetree/bindings/hwmon/baikal,bt1-pvt.yaml | 8 ++--- .../devicetree/bindings/hwmon/ti,tmp513.yaml | 1 - .../devicetree/bindings/i2c/i2c-gpio.yaml | 2 -- .../bindings/i2c/snps,designware-i2c.yaml | 3 -- .../devicetree/bindings/iio/adc/maxim,max9611.yaml | 1 - .../devicetree/bindings/iio/adc/st,stm32-adc.yaml | 1 - .../bindings/iio/adc/ti,palmas-gpadc.yaml | 2 -- .../devicetree/bindings/iio/dac/adi,ad5758.yaml | 41 ++++++++++++++-------- .../bindings/iio/health/maxim,max30100.yaml | 1 - .../bindings/input/touchscreen/touchscreen.yaml | 2 -- .../devicetree/bindings/mmc/mmc-controller.yaml | 1 - .../devicetree/bindings/mmc/mmc-pwrseq-simple.yaml | 2 -- .../bindings/net/ethernet-controller.yaml | 2 -- .../devicetree/bindings/net/snps,dwmac.yaml | 1 - .../devicetree/bindings/power/supply/battery.yaml | 3 -- .../devicetree/bindings/power/supply/bq2515x.yaml | 1 - .../devicetree/bindings/regulator/dlg,da9121.yaml | 1 - .../bindings/regulator/fixed-regulator.yaml | 2 -- Documentation/devicetree/bindings/rtc/rtc.yaml | 2 -- .../devicetree/bindings/serial/pl011.yaml | 2 -- .../devicetree/bindings/sound/sgtl5000.yaml | 2 -- .../devicetree/bindings/watchdog/watchdog.yaml | 1 - 25 files changed, 29 insertions(+), 56 deletions(-) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/arm/cpus.yaml b/Documentation/devicetree/bindings/arm/cpus.yaml index 14cd727d3c4b..f02fd10de604 100644 --- a/Documentation/devicetree/bindings/arm/cpus.yaml +++ b/Documentation/devicetree/bindings/arm/cpus.yaml @@ -232,7 +232,6 @@ properties: by this cpu (see ./idle-states.yaml). capacity-dmips-mhz: - $ref: '/schemas/types.yaml#/definitions/uint32' description: u32 value representing CPU capacity (see ./cpu-capacity.txt) in DMIPS/MHz, relative to highest capacity-dmips-mhz diff --git a/Documentation/devicetree/bindings/extcon/wlf,arizona.yaml b/Documentation/devicetree/bindings/extcon/wlf,arizona.yaml index 5fe784f487c5..efdf59abb2e1 100644 --- a/Documentation/devicetree/bindings/extcon/wlf,arizona.yaml +++ b/Documentation/devicetree/bindings/extcon/wlf,arizona.yaml @@ -85,7 +85,6 @@ properties: wlf,micd-timeout-ms: description: Timeout for microphone detection, specified in milliseconds. - $ref: "/schemas/types.yaml#/definitions/uint32" wlf,micd-force-micbias: description: diff --git a/Documentation/devicetree/bindings/hwmon/adi,ltc2947.yaml b/Documentation/devicetree/bindings/hwmon/adi,ltc2947.yaml index eef614962b10..bf04151b63d2 100644 --- a/Documentation/devicetree/bindings/hwmon/adi,ltc2947.yaml +++ b/Documentation/devicetree/bindings/hwmon/adi,ltc2947.yaml @@ -49,7 +49,6 @@ properties: description: This property controls the Accumulation Dead band which allows to set the level of current below which no accumulation takes place. - $ref: /schemas/types.yaml#/definitions/uint32 maximum: 255 default: 0 diff --git a/Documentation/devicetree/bindings/hwmon/baikal,bt1-pvt.yaml b/Documentation/devicetree/bindings/hwmon/baikal,bt1-pvt.yaml index 00a6511354e6..5d3ce641fcde 100644 --- a/Documentation/devicetree/bindings/hwmon/baikal,bt1-pvt.yaml +++ b/Documentation/devicetree/bindings/hwmon/baikal,bt1-pvt.yaml @@ -73,11 +73,9 @@ properties: description: | Temperature sensor trimming factor. It can be used to manually adjust the temperature measurements within 7.130 degrees Celsius. - maxItems: 1 - items: - default: 0 - minimum: 0 - maximum: 7130 + default: 0 + minimum: 0 + maximum: 7130 additionalProperties: false diff --git a/Documentation/devicetree/bindings/hwmon/ti,tmp513.yaml b/Documentation/devicetree/bindings/hwmon/ti,tmp513.yaml index 8020d739a078..1502b22c77cc 100644 --- a/Documentation/devicetree/bindings/hwmon/ti,tmp513.yaml +++ b/Documentation/devicetree/bindings/hwmon/ti,tmp513.yaml @@ -52,7 +52,6 @@ properties: ti,bus-range-microvolt: description: | This is the operating range of the bus voltage in microvolt - $ref: /schemas/types.yaml#/definitions/uint32 enum: [16000000, 32000000] default: 32000000 diff --git a/Documentation/devicetree/bindings/i2c/i2c-gpio.yaml b/Documentation/devicetree/bindings/i2c/i2c-gpio.yaml index cc3aa2a5e70b..ff99344788ab 100644 --- a/Documentation/devicetree/bindings/i2c/i2c-gpio.yaml +++ b/Documentation/devicetree/bindings/i2c/i2c-gpio.yaml @@ -39,11 +39,9 @@ properties: i2c-gpio,delay-us: description: delay between GPIO operations (may depend on each platform) - $ref: /schemas/types.yaml#/definitions/uint32 i2c-gpio,timeout-ms: description: timeout to get data - $ref: /schemas/types.yaml#/definitions/uint32 # Deprecated properties, do not use in new device tree sources: gpios: diff --git a/Documentation/devicetree/bindings/i2c/snps,designware-i2c.yaml b/Documentation/devicetree/bindings/i2c/snps,designware-i2c.yaml index c22b66b6219e..d9293c57f573 100644 --- a/Documentation/devicetree/bindings/i2c/snps,designware-i2c.yaml +++ b/Documentation/devicetree/bindings/i2c/snps,designware-i2c.yaml @@ -66,21 +66,18 @@ properties: default: 400000 i2c-sda-hold-time-ns: - maxItems: 1 description: | The property should contain the SDA hold time in nanoseconds. This option is only supported in hardware blocks version 1.11a or newer or on Microsemi SoCs. i2c-scl-falling-time-ns: - maxItems: 1 description: | The property should contain the SCL falling time in nanoseconds. This value is used to compute the tLOW period. default: 300 i2c-sda-falling-time-ns: - maxItems: 1 description: | The property should contain the SDA falling time in nanoseconds. This value is used to compute the tHIGH period. diff --git a/Documentation/devicetree/bindings/iio/adc/maxim,max9611.yaml b/Documentation/devicetree/bindings/iio/adc/maxim,max9611.yaml index 9475a9e6e920..95774a55629d 100644 --- a/Documentation/devicetree/bindings/iio/adc/maxim,max9611.yaml +++ b/Documentation/devicetree/bindings/iio/adc/maxim,max9611.yaml @@ -23,7 +23,6 @@ properties: maxItems: 1 shunt-resistor-micro-ohms: - $ref: /schemas/types.yaml#/definitions/uint32 description: | Value in micro Ohms of the shunt resistor connected between the RS+ and RS- inputs, across which the current is measured. Value needed to compute diff --git a/Documentation/devicetree/bindings/iio/adc/st,stm32-adc.yaml b/Documentation/devicetree/bindings/iio/adc/st,stm32-adc.yaml index 28417b31b558..517e32976c30 100644 --- a/Documentation/devicetree/bindings/iio/adc/st,stm32-adc.yaml +++ b/Documentation/devicetree/bindings/iio/adc/st,stm32-adc.yaml @@ -246,7 +246,6 @@ patternProperties: Resolution (bits) to use for conversions: - can be 6, 8, 10 or 12 on stm32f4 - can be 8, 10, 12, 14 or 16 on stm32h7 and stm32mp1 - $ref: /schemas/types.yaml#/definitions/uint32 st,adc-channels: description: | diff --git a/Documentation/devicetree/bindings/iio/adc/ti,palmas-gpadc.yaml b/Documentation/devicetree/bindings/iio/adc/ti,palmas-gpadc.yaml index 692dacd0fee5..7b895784e008 100644 --- a/Documentation/devicetree/bindings/iio/adc/ti,palmas-gpadc.yaml +++ b/Documentation/devicetree/bindings/iio/adc/ti,palmas-gpadc.yaml @@ -42,7 +42,6 @@ properties: const: 1 ti,channel0-current-microamp: - $ref: /schemas/types.yaml#/definitions/uint32 description: Channel 0 current in uA. enum: - 0 @@ -51,7 +50,6 @@ properties: - 20 ti,channel3-current-microamp: - $ref: /schemas/types.yaml#/definitions/uint32 description: Channel 3 current in uA. enum: - 0 diff --git a/Documentation/devicetree/bindings/iio/dac/adi,ad5758.yaml b/Documentation/devicetree/bindings/iio/dac/adi,ad5758.yaml index 626ccb6fe21e..fd4edca34a28 100644 --- a/Documentation/devicetree/bindings/iio/dac/adi,ad5758.yaml +++ b/Documentation/devicetree/bindings/iio/dac/adi,ad5758.yaml @@ -46,31 +46,42 @@ properties: two properties must be present: adi,range-microvolt: - $ref: /schemas/types.yaml#/definitions/int32-array description: | Voltage output range specified as - enum: - - [[0, 5000000]] - - [[0, 10000000]] - - [[-5000000, 5000000]] - - [[-10000000, 10000000]] + oneOf: + - items: + - const: 0 + - enum: [5000000, 10000000] + - items: + - const: -5000000 + - const: 5000000 + - items: + - const: -10000000 + - const: 10000000 adi,range-microamp: - $ref: /schemas/types.yaml#/definitions/int32-array description: | Current output range specified as - enum: - - [[0, 20000]] - - [[0, 24000]] - - [[4, 24000]] - - [[-20000, 20000]] - - [[-24000, 24000]] - - [[-1000, 22000]] + oneOf: + - items: + - const: 0 + - enum: [20000, 24000] + - items: + - const: 4 + - const: 24000 + - items: + - const: -20000 + - const: 20000 + - items: + - const: -24000 + - const: 24000 + - items: + - const: -1000 + - const: 22000 reset-gpios: true adi,dc-dc-ilim-microamp: - $ref: /schemas/types.yaml#/definitions/uint32 enum: [150000, 200000, 250000, 300000, 350000, 400000] description: | The dc-to-dc converter current limit. diff --git a/Documentation/devicetree/bindings/iio/health/maxim,max30100.yaml b/Documentation/devicetree/bindings/iio/health/maxim,max30100.yaml index 64b862637039..967778fb0ce8 100644 --- a/Documentation/devicetree/bindings/iio/health/maxim,max30100.yaml +++ b/Documentation/devicetree/bindings/iio/health/maxim,max30100.yaml @@ -21,7 +21,6 @@ properties: description: Connected to ADC_RDY pin. maxim,led-current-microamp: - $ref: /schemas/types.yaml#/definitions/uint32-array minItems: 2 maxItems: 2 description: | diff --git a/Documentation/devicetree/bindings/input/touchscreen/touchscreen.yaml b/Documentation/devicetree/bindings/input/touchscreen/touchscreen.yaml index a771a15f053f..046ace461cc9 100644 --- a/Documentation/devicetree/bindings/input/touchscreen/touchscreen.yaml +++ b/Documentation/devicetree/bindings/input/touchscreen/touchscreen.yaml @@ -70,11 +70,9 @@ properties: touchscreen-x-mm: description: horizontal length in mm of the touchscreen - $ref: /schemas/types.yaml#/definitions/uint32 touchscreen-y-mm: description: vertical length in mm of the touchscreen - $ref: /schemas/types.yaml#/definitions/uint32 dependencies: touchscreen-size-x: [ touchscreen-size-y ] diff --git a/Documentation/devicetree/bindings/mmc/mmc-controller.yaml b/Documentation/devicetree/bindings/mmc/mmc-controller.yaml index 186f04ba9357..e674bba52ee9 100644 --- a/Documentation/devicetree/bindings/mmc/mmc-controller.yaml +++ b/Documentation/devicetree/bindings/mmc/mmc-controller.yaml @@ -259,7 +259,6 @@ properties: waiting for I/O signalling and card power supply to be stable, regardless of whether pwrseq-simple is used. Default to 10ms if no available. - $ref: /schemas/types.yaml#/definitions/uint32 default: 10 supports-cqe: diff --git a/Documentation/devicetree/bindings/mmc/mmc-pwrseq-simple.yaml b/Documentation/devicetree/bindings/mmc/mmc-pwrseq-simple.yaml index 6cd57863c1db..226fb191913d 100644 --- a/Documentation/devicetree/bindings/mmc/mmc-pwrseq-simple.yaml +++ b/Documentation/devicetree/bindings/mmc/mmc-pwrseq-simple.yaml @@ -41,13 +41,11 @@ properties: description: Delay in ms after powering the card and de-asserting the reset-gpios (if any). - $ref: /schemas/types.yaml#/definitions/uint32 power-off-delay-us: description: Delay in us after asserting the reset-gpios (if any) during power off of the card. - $ref: /schemas/types.yaml#/definitions/uint32 required: - compatible diff --git a/Documentation/devicetree/bindings/net/ethernet-controller.yaml b/Documentation/devicetree/bindings/net/ethernet-controller.yaml index 0965f6515f9e..dac4aadb6e2e 100644 --- a/Documentation/devicetree/bindings/net/ethernet-controller.yaml +++ b/Documentation/devicetree/bindings/net/ethernet-controller.yaml @@ -122,7 +122,6 @@ properties: such as flow control thresholds. rx-internal-delay-ps: - $ref: /schemas/types.yaml#/definitions/uint32 description: | RGMII Receive Clock Delay defined in pico seconds. This is used for controllers that have configurable RX internal delays. @@ -140,7 +139,6 @@ properties: is used for components that can have configurable fifo sizes. tx-internal-delay-ps: - $ref: /schemas/types.yaml#/definitions/uint32 description: | RGMII Transmit Clock Delay defined in pico seconds. This is used for controllers that have configurable TX internal delays. diff --git a/Documentation/devicetree/bindings/net/snps,dwmac.yaml b/Documentation/devicetree/bindings/net/snps,dwmac.yaml index b2f6083f556a..9ac77b8cb767 100644 --- a/Documentation/devicetree/bindings/net/snps,dwmac.yaml +++ b/Documentation/devicetree/bindings/net/snps,dwmac.yaml @@ -208,7 +208,6 @@ properties: Triplet of delays. The 1st cell is reset pre-delay in micro seconds. The 2nd cell is reset pulse in micro seconds. The 3rd cell is reset post-delay in micro seconds. - $ref: /schemas/types.yaml#/definitions/uint32-array minItems: 3 maxItems: 3 diff --git a/Documentation/devicetree/bindings/power/supply/battery.yaml b/Documentation/devicetree/bindings/power/supply/battery.yaml index 0c7e2e44793b..c3b4b7543591 100644 --- a/Documentation/devicetree/bindings/power/supply/battery.yaml +++ b/Documentation/devicetree/bindings/power/supply/battery.yaml @@ -83,21 +83,18 @@ properties: for each of the battery capacity lookup table. operating-range-celsius: - $ref: /schemas/types.yaml#/definitions/uint32-array description: operating temperature range of a battery items: - description: minimum temperature at which battery can operate - description: maximum temperature at which battery can operate ambient-celsius: - $ref: /schemas/types.yaml#/definitions/uint32-array description: safe range of ambient temperature items: - description: alert when ambient temperature is lower than this value - description: alert when ambient temperature is higher than this value alert-celsius: - $ref: /schemas/types.yaml#/definitions/uint32-array description: safe range of battery temperature items: - description: alert when battery temperature is lower than this value diff --git a/Documentation/devicetree/bindings/power/supply/bq2515x.yaml b/Documentation/devicetree/bindings/power/supply/bq2515x.yaml index 75a56773be4a..813d6afde606 100644 --- a/Documentation/devicetree/bindings/power/supply/bq2515x.yaml +++ b/Documentation/devicetree/bindings/power/supply/bq2515x.yaml @@ -50,7 +50,6 @@ properties: maxItems: 1 input-current-limit-microamp: - $ref: /schemas/types.yaml#/definitions/uint32 description: Maximum input current in micro Amps. minimum: 50000 maximum: 500000 diff --git a/Documentation/devicetree/bindings/regulator/dlg,da9121.yaml b/Documentation/devicetree/bindings/regulator/dlg,da9121.yaml index 6f2164f7bc57..228018c87bea 100644 --- a/Documentation/devicetree/bindings/regulator/dlg,da9121.yaml +++ b/Documentation/devicetree/bindings/regulator/dlg,da9121.yaml @@ -62,7 +62,6 @@ properties: description: IRQ line information. dlg,irq-polling-delay-passive-ms: - $ref: "/schemas/types.yaml#/definitions/uint32" minimum: 1000 maximum: 10000 description: | diff --git a/Documentation/devicetree/bindings/regulator/fixed-regulator.yaml b/Documentation/devicetree/bindings/regulator/fixed-regulator.yaml index d3d0dc13dd8b..8850c01bd470 100644 --- a/Documentation/devicetree/bindings/regulator/fixed-regulator.yaml +++ b/Documentation/devicetree/bindings/regulator/fixed-regulator.yaml @@ -72,11 +72,9 @@ properties: startup-delay-us: description: startup time in microseconds - $ref: /schemas/types.yaml#/definitions/uint32 off-on-delay-us: description: off delay time in microseconds - $ref: /schemas/types.yaml#/definitions/uint32 enable-active-high: description: diff --git a/Documentation/devicetree/bindings/rtc/rtc.yaml b/Documentation/devicetree/bindings/rtc/rtc.yaml index d30dc045aac6..0ec3551f12dd 100644 --- a/Documentation/devicetree/bindings/rtc/rtc.yaml +++ b/Documentation/devicetree/bindings/rtc/rtc.yaml @@ -27,7 +27,6 @@ properties: 1: chargeable quartz-load-femtofarads: - $ref: /schemas/types.yaml#/definitions/uint32 description: The capacitive load of the quartz(x-tal), expressed in femto Farad (fF). The default value shall be listed (if optional), @@ -47,7 +46,6 @@ properties: deprecated: true trickle-resistor-ohms: - $ref: /schemas/types.yaml#/definitions/uint32 description: Selected resistor for trickle charger. Should be given if trickle charger should be enabled. diff --git a/Documentation/devicetree/bindings/serial/pl011.yaml b/Documentation/devicetree/bindings/serial/pl011.yaml index c23c93b400f0..07fa6d26f2b4 100644 --- a/Documentation/devicetree/bindings/serial/pl011.yaml +++ b/Documentation/devicetree/bindings/serial/pl011.yaml @@ -88,14 +88,12 @@ properties: description: Rate at which poll occurs when auto-poll is set. default 100ms. - $ref: /schemas/types.yaml#/definitions/uint32 default: 100 poll-timeout-ms: description: Poll timeout when auto-poll is set, default 3000ms. - $ref: /schemas/types.yaml#/definitions/uint32 default: 3000 required: diff --git a/Documentation/devicetree/bindings/sound/sgtl5000.yaml b/Documentation/devicetree/bindings/sound/sgtl5000.yaml index d116c174b545..70b4a8831073 100644 --- a/Documentation/devicetree/bindings/sound/sgtl5000.yaml +++ b/Documentation/devicetree/bindings/sound/sgtl5000.yaml @@ -41,14 +41,12 @@ properties: values of 2k, 4k or 8k. If set to 0 it will be off. If this node is not mentioned or if the value is unknown, then micbias resistor is set to 4k. - $ref: "/schemas/types.yaml#/definitions/uint32" enum: [ 0, 2, 4, 8 ] micbias-voltage-m-volts: description: The bias voltage to be used in mVolts. The voltage can take values from 1.25V to 3V by 250mV steps. If this node is not mentioned or the value is unknown, then the value is set to 1.25V. - $ref: "/schemas/types.yaml#/definitions/uint32" enum: [ 1250, 1500, 1750, 2000, 2250, 2500, 2750, 3000 ] lrclk-strength: diff --git a/Documentation/devicetree/bindings/watchdog/watchdog.yaml b/Documentation/devicetree/bindings/watchdog/watchdog.yaml index 4e2c26cd981d..e3dfb02f0ca5 100644 --- a/Documentation/devicetree/bindings/watchdog/watchdog.yaml +++ b/Documentation/devicetree/bindings/watchdog/watchdog.yaml @@ -19,7 +19,6 @@ properties: pattern: "^watchdog(@.*|-[0-9a-f])?$" timeout-sec: - $ref: /schemas/types.yaml#/definitions/uint32 description: Contains the watchdog timeout in seconds. -- cgit v1.2.3 From 5daf83846cdb67a3ef0c17f9826738567598ed19 Mon Sep 17 00:00:00 2001 From: Jan Luebbe Date: Thu, 28 Jan 2021 12:19:30 +0100 Subject: docs: networking: timestamping: fix section title markup This section was missed during the conversion to ReST, so convert it in the same style as the surrounding section titles. Signed-off-by: Jan Luebbe Link: https://lore.kernel.org/r/20210128111930.29473-1-jlu@pengutronix.de Signed-off-by: Jakub Kicinski --- Documentation/networking/timestamping.rst | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'Documentation') diff --git a/Documentation/networking/timestamping.rst b/Documentation/networking/timestamping.rst index 03f7beade470..f682e88fa87e 100644 --- a/Documentation/networking/timestamping.rst +++ b/Documentation/networking/timestamping.rst @@ -55,7 +55,8 @@ struct __kernel_sock_timeval format. SO_TIMESTAMP_OLD returns incorrect timestamps after the year 2038 on 32 bit machines. -1.2 SO_TIMESTAMPNS (also SO_TIMESTAMPNS_OLD and SO_TIMESTAMPNS_NEW): +1.2 SO_TIMESTAMPNS (also SO_TIMESTAMPNS_OLD and SO_TIMESTAMPNS_NEW) +------------------------------------------------------------------- This option is identical to SO_TIMESTAMP except for the returned data type. Its struct timespec allows for higher resolution (ns) timestamps than the -- cgit v1.2.3 From 53da0ebaad102626f56495e0967a614f89a2acc8 Mon Sep 17 00:00:00 2001 From: Vladimir Oltean Date: Fri, 29 Jan 2021 03:00:06 +0200 Subject: net: dsa: allow changing the tag protocol via the "tagging" device attribute Currently DSA exposes the following sysfs: $ cat /sys/class/net/eno2/dsa/tagging ocelot which is a read-only device attribute, introduced in the kernel as commit 98cdb4807123 ("net: dsa: Expose tagging protocol to user-space"), and used by libpcap since its commit 993db3800d7d ("Add support for DSA link-layer types"). It would be nice if we could extend this device attribute by making it writable: $ echo ocelot-8021q > /sys/class/net/eno2/dsa/tagging This is useful with DSA switches that can make use of more than one tagging protocol. It may be useful in dsa_loop in the future too, to perform offline testing of various taggers, or for changing between dsa and edsa on Marvell switches, if that is desirable. In terms of implementation, drivers can support this feature by implementing .change_tag_protocol, which should always leave the switch in a consistent state: either with the new protocol if things went well, or with the old one if something failed. Teardown of the old protocol, if necessary, must be handled by the driver. Some things remain as before: - The .get_tag_protocol is currently only called at probe time, to load the initial tagging protocol driver. Nonetheless, new drivers should report the tagging protocol in current use now. - The driver should manage by itself the initial setup of tagging protocol, no later than the .setup() method, as well as destroying resources used by the last tagger in use, no earlier than the .teardown() method. For multi-switch DSA trees, error handling is a bit more complicated, since e.g. the 5th out of 7 switches may fail to change the tag protocol. When that happens, a revert to the original tag protocol is attempted, but that may fail too, leaving the tree in an inconsistent state despite each individual switch implementing .change_tag_protocol transactionally. Since the intersection between drivers that implement .change_tag_protocol and drivers that support D in DSA is currently the empty set, the possibility for this error to happen is ignored for now. Testing: $ insmod mscc_felix.ko [ 79.549784] mscc_felix 0000:00:00.5: Adding to iommu group 14 [ 79.565712] mscc_felix 0000:00:00.5: Failed to register DSA switch: -517 $ insmod tag_ocelot.ko $ rmmod mscc_felix.ko $ insmod mscc_felix.ko [ 97.261724] libphy: VSC9959 internal MDIO bus: probed [ 97.267363] mscc_felix 0000:00:00.5: Found PCS at internal MDIO address 0 [ 97.274998] mscc_felix 0000:00:00.5: Found PCS at internal MDIO address 1 [ 97.282561] mscc_felix 0000:00:00.5: Found PCS at internal MDIO address 2 [ 97.289700] mscc_felix 0000:00:00.5: Found PCS at internal MDIO address 3 [ 97.599163] mscc_felix 0000:00:00.5 swp0 (uninitialized): PHY [0000:00:00.3:10] driver [Microsemi GE VSC8514 SyncE] (irq=POLL) [ 97.862034] mscc_felix 0000:00:00.5 swp1 (uninitialized): PHY [0000:00:00.3:11] driver [Microsemi GE VSC8514 SyncE] (irq=POLL) [ 97.950731] mscc_felix 0000:00:00.5 swp0: configuring for inband/qsgmii link mode [ 97.964278] 8021q: adding VLAN 0 to HW filter on device swp0 [ 98.146161] mscc_felix 0000:00:00.5 swp2 (uninitialized): PHY [0000:00:00.3:12] driver [Microsemi GE VSC8514 SyncE] (irq=POLL) [ 98.238649] mscc_felix 0000:00:00.5 swp1: configuring for inband/qsgmii link mode [ 98.251845] 8021q: adding VLAN 0 to HW filter on device swp1 [ 98.433916] mscc_felix 0000:00:00.5 swp3 (uninitialized): PHY [0000:00:00.3:13] driver [Microsemi GE VSC8514 SyncE] (irq=POLL) [ 98.485542] mscc_felix 0000:00:00.5: configuring for fixed/internal link mode [ 98.503584] mscc_felix 0000:00:00.5: Link is Up - 2.5Gbps/Full - flow control rx/tx [ 98.527948] device eno2 entered promiscuous mode [ 98.544755] DSA: tree 0 setup $ ping 10.0.0.1 PING 10.0.0.1 (10.0.0.1): 56 data bytes 64 bytes from 10.0.0.1: seq=0 ttl=64 time=2.337 ms 64 bytes from 10.0.0.1: seq=1 ttl=64 time=0.754 ms ^C - 10.0.0.1 ping statistics - 2 packets transmitted, 2 packets received, 0% packet loss round-trip min/avg/max = 0.754/1.545/2.337 ms $ cat /sys/class/net/eno2/dsa/tagging ocelot $ cat ./test_ocelot_8021q.sh #!/bin/bash ip link set swp0 down ip link set swp1 down ip link set swp2 down ip link set swp3 down ip link set swp5 down ip link set eno2 down echo ocelot-8021q > /sys/class/net/eno2/dsa/tagging ip link set eno2 up ip link set swp0 up ip link set swp1 up ip link set swp2 up ip link set swp3 up ip link set swp5 up $ ./test_ocelot_8021q.sh ./test_ocelot_8021q.sh: line 9: echo: write error: Protocol not available $ rmmod tag_ocelot.ko rmmod: can't unload module 'tag_ocelot': Resource temporarily unavailable $ insmod tag_ocelot_8021q.ko $ ./test_ocelot_8021q.sh $ cat /sys/class/net/eno2/dsa/tagging ocelot-8021q $ rmmod tag_ocelot.ko $ rmmod tag_ocelot_8021q.ko rmmod: can't unload module 'tag_ocelot_8021q': Resource temporarily unavailable $ ping 10.0.0.1 PING 10.0.0.1 (10.0.0.1): 56 data bytes 64 bytes from 10.0.0.1: seq=0 ttl=64 time=0.953 ms 64 bytes from 10.0.0.1: seq=1 ttl=64 time=0.787 ms 64 bytes from 10.0.0.1: seq=2 ttl=64 time=0.771 ms $ rmmod mscc_felix.ko [ 645.544426] mscc_felix 0000:00:00.5: Link is Down [ 645.838608] DSA: tree 0 torn down $ rmmod tag_ocelot_8021q.ko Signed-off-by: Vladimir Oltean Signed-off-by: Jakub Kicinski --- Documentation/ABI/testing/sysfs-class-net-dsa | 11 +++++- include/net/dsa.h | 9 +++++ net/dsa/dsa.c | 26 +++++++++++++ net/dsa/dsa2.c | 55 +++++++++++++++++++++++++-- net/dsa/dsa_priv.h | 15 ++++++++ net/dsa/master.c | 39 ++++++++++++++++++- net/dsa/port.c | 8 ++++ net/dsa/slave.c | 35 +++++++++++------ net/dsa/switch.c | 55 +++++++++++++++++++++++++++ 9 files changed, 235 insertions(+), 18 deletions(-) (limited to 'Documentation') diff --git a/Documentation/ABI/testing/sysfs-class-net-dsa b/Documentation/ABI/testing/sysfs-class-net-dsa index 985d84c585c6..e2da26b44dd0 100644 --- a/Documentation/ABI/testing/sysfs-class-net-dsa +++ b/Documentation/ABI/testing/sysfs-class-net-dsa @@ -3,5 +3,12 @@ Date: August 2018 KernelVersion: 4.20 Contact: netdev@vger.kernel.org Description: - String indicating the type of tagging protocol used by the - DSA slave network device. + On read, this file returns a string indicating the type of + tagging protocol used by the DSA network devices that are + attached to this master interface. + On write, this file changes the tagging protocol of the + attached DSA switches, if this operation is supported by the + driver. Changing the tagging protocol must be done with the DSA + interfaces and the master interface all administratively down. + See the "name" field of each registered struct dsa_device_ops + for a list of valid values. diff --git a/include/net/dsa.h b/include/net/dsa.h index b8af1d6c879a..7ea3918b2e61 100644 --- a/include/net/dsa.h +++ b/include/net/dsa.h @@ -485,9 +485,18 @@ static inline bool dsa_port_is_vlan_filtering(const struct dsa_port *dp) typedef int dsa_fdb_dump_cb_t(const unsigned char *addr, u16 vid, bool is_static, void *data); struct dsa_switch_ops { + /* + * Tagging protocol helpers called for the CPU ports and DSA links. + * @get_tag_protocol retrieves the initial tagging protocol and is + * mandatory. Switches which can operate using multiple tagging + * protocols should implement @change_tag_protocol and report in + * @get_tag_protocol the tagger in current use. + */ enum dsa_tag_protocol (*get_tag_protocol)(struct dsa_switch *ds, int port, enum dsa_tag_protocol mprot); + int (*change_tag_protocol)(struct dsa_switch *ds, int port, + enum dsa_tag_protocol proto); int (*setup)(struct dsa_switch *ds); void (*teardown)(struct dsa_switch *ds); diff --git a/net/dsa/dsa.c b/net/dsa/dsa.c index f4ce3c5826a0..84cad1be9ce4 100644 --- a/net/dsa/dsa.c +++ b/net/dsa/dsa.c @@ -84,6 +84,32 @@ const char *dsa_tag_protocol_to_str(const struct dsa_device_ops *ops) return ops->name; }; +/* Function takes a reference on the module owning the tagger, + * so dsa_tag_driver_put must be called afterwards. + */ +const struct dsa_device_ops *dsa_find_tagger_by_name(const char *buf) +{ + const struct dsa_device_ops *ops = ERR_PTR(-ENOPROTOOPT); + struct dsa_tag_driver *dsa_tag_driver; + + mutex_lock(&dsa_tag_drivers_lock); + list_for_each_entry(dsa_tag_driver, &dsa_tag_drivers_list, list) { + const struct dsa_device_ops *tmp = dsa_tag_driver->ops; + + if (!sysfs_streq(buf, tmp->name)) + continue; + + if (!try_module_get(dsa_tag_driver->owner)) + break; + + ops = tmp; + break; + } + mutex_unlock(&dsa_tag_drivers_lock); + + return ops; +} + const struct dsa_device_ops *dsa_tag_driver_get(int tag_protocol) { struct dsa_tag_driver *dsa_tag_driver; diff --git a/net/dsa/dsa2.c b/net/dsa/dsa2.c index 63035a898ca8..96249c4ad5f2 100644 --- a/net/dsa/dsa2.c +++ b/net/dsa/dsa2.c @@ -942,6 +942,57 @@ static void dsa_tree_teardown(struct dsa_switch_tree *dst) dst->setup = false; } +/* Since the dsa/tagging sysfs device attribute is per master, the assumption + * is that all DSA switches within a tree share the same tagger, otherwise + * they would have formed disjoint trees (different "dsa,member" values). + */ +int dsa_tree_change_tag_proto(struct dsa_switch_tree *dst, + struct net_device *master, + const struct dsa_device_ops *tag_ops, + const struct dsa_device_ops *old_tag_ops) +{ + struct dsa_notifier_tag_proto_info info; + struct dsa_port *dp; + int err = -EBUSY; + + if (!rtnl_trylock()) + return restart_syscall(); + + /* At the moment we don't allow changing the tag protocol under + * traffic. The rtnl_mutex also happens to serialize concurrent + * attempts to change the tagging protocol. If we ever lift the IFF_UP + * restriction, there needs to be another mutex which serializes this. + */ + if (master->flags & IFF_UP) + goto out_unlock; + + list_for_each_entry(dp, &dst->ports, list) { + if (!dsa_is_user_port(dp->ds, dp->index)) + continue; + + if (dp->slave->flags & IFF_UP) + goto out_unlock; + } + + info.tag_ops = tag_ops; + err = dsa_tree_notify(dst, DSA_NOTIFIER_TAG_PROTO, &info); + if (err) + goto out_unwind_tagger; + + dst->tag_ops = tag_ops; + + rtnl_unlock(); + + return 0; + +out_unwind_tagger: + info.tag_ops = old_tag_ops; + dsa_tree_notify(dst, DSA_NOTIFIER_TAG_PROTO, &info); +out_unlock: + rtnl_unlock(); + return err; +} + static struct dsa_port *dsa_port_touch(struct dsa_switch *ds, int index) { struct dsa_switch_tree *dst = ds->dst; @@ -1038,9 +1089,7 @@ static int dsa_port_parse_cpu(struct dsa_port *dp, struct net_device *master) dp->master = master; dp->type = DSA_PORT_TYPE_CPU; - dp->filter = dst->tag_ops->filter; - dp->rcv = dst->tag_ops->rcv; - dp->tag_ops = dst->tag_ops; + dsa_port_set_tag_protocol(dp, dst->tag_ops); dp->dst = dst; return 0; diff --git a/net/dsa/dsa_priv.h b/net/dsa/dsa_priv.h index 3cc1e6d76e3a..edca57b558ad 100644 --- a/net/dsa/dsa_priv.h +++ b/net/dsa/dsa_priv.h @@ -28,6 +28,7 @@ enum { DSA_NOTIFIER_VLAN_ADD, DSA_NOTIFIER_VLAN_DEL, DSA_NOTIFIER_MTU, + DSA_NOTIFIER_TAG_PROTO, }; /* DSA_NOTIFIER_AGEING_TIME */ @@ -82,6 +83,11 @@ struct dsa_notifier_mtu_info { int mtu; }; +/* DSA_NOTIFIER_TAG_PROTO_* */ +struct dsa_notifier_tag_proto_info { + const struct dsa_device_ops *tag_ops; +}; + struct dsa_switchdev_event_work { struct dsa_switch *ds; int port; @@ -115,6 +121,7 @@ struct dsa_slave_priv { /* dsa.c */ const struct dsa_device_ops *dsa_tag_driver_get(int tag_protocol); void dsa_tag_driver_put(const struct dsa_device_ops *ops); +const struct dsa_device_ops *dsa_find_tagger_by_name(const char *buf); bool dsa_schedule_work(struct work_struct *work); const char *dsa_tag_protocol_to_str(const struct dsa_device_ops *ops); @@ -139,6 +146,8 @@ static inline struct net_device *dsa_master_find_slave(struct net_device *dev, } /* port.c */ +void dsa_port_set_tag_protocol(struct dsa_port *cpu_dp, + const struct dsa_device_ops *tag_ops); int dsa_port_set_state(struct dsa_port *dp, u8 state); int dsa_port_enable_rt(struct dsa_port *dp, struct phy_device *phy); int dsa_port_enable(struct dsa_port *dp, struct phy_device *phy); @@ -201,6 +210,8 @@ int dsa_slave_suspend(struct net_device *slave_dev); int dsa_slave_resume(struct net_device *slave_dev); int dsa_slave_register_notifier(void); void dsa_slave_unregister_notifier(void); +void dsa_slave_setup_tagger(struct net_device *slave); +int dsa_slave_change_mtu(struct net_device *dev, int new_mtu); static inline struct dsa_port *dsa_slave_to_port(const struct net_device *dev) { @@ -285,6 +296,10 @@ void dsa_lag_map(struct dsa_switch_tree *dst, struct net_device *lag); void dsa_lag_unmap(struct dsa_switch_tree *dst, struct net_device *lag); int dsa_tree_notify(struct dsa_switch_tree *dst, unsigned long e, void *v); int dsa_broadcast(unsigned long e, void *v); +int dsa_tree_change_tag_proto(struct dsa_switch_tree *dst, + struct net_device *master, + const struct dsa_device_ops *tag_ops, + const struct dsa_device_ops *old_tag_ops); extern struct list_head dsa_tree_list; diff --git a/net/dsa/master.c b/net/dsa/master.c index cb3a5cf99b25..052a977914a6 100644 --- a/net/dsa/master.c +++ b/net/dsa/master.c @@ -280,7 +280,44 @@ static ssize_t tagging_show(struct device *d, struct device_attribute *attr, return sprintf(buf, "%s\n", dsa_tag_protocol_to_str(cpu_dp->tag_ops)); } -static DEVICE_ATTR_RO(tagging); + +static ssize_t tagging_store(struct device *d, struct device_attribute *attr, + const char *buf, size_t count) +{ + const struct dsa_device_ops *new_tag_ops, *old_tag_ops; + struct net_device *dev = to_net_dev(d); + struct dsa_port *cpu_dp = dev->dsa_ptr; + int err; + + old_tag_ops = cpu_dp->tag_ops; + new_tag_ops = dsa_find_tagger_by_name(buf); + /* Bad tagger name, or module is not loaded? */ + if (IS_ERR(new_tag_ops)) + return PTR_ERR(new_tag_ops); + + if (new_tag_ops == old_tag_ops) + /* Drop the temporarily held duplicate reference, since + * the DSA switch tree uses this tagger. + */ + goto out; + + err = dsa_tree_change_tag_proto(cpu_dp->ds->dst, dev, new_tag_ops, + old_tag_ops); + if (err) { + /* On failure the old tagger is restored, so we don't need the + * driver for the new one. + */ + dsa_tag_driver_put(new_tag_ops); + return err; + } + + /* On success we no longer need the module for the old tagging protocol + */ +out: + dsa_tag_driver_put(old_tag_ops); + return count; +} +static DEVICE_ATTR_RW(tagging); static struct attribute *dsa_slave_attrs[] = { &dev_attr_tagging.attr, diff --git a/net/dsa/port.c b/net/dsa/port.c index a8886cf40160..5e079a61528e 100644 --- a/net/dsa/port.c +++ b/net/dsa/port.c @@ -526,6 +526,14 @@ int dsa_port_vlan_del(struct dsa_port *dp, return dsa_port_notify(dp, DSA_NOTIFIER_VLAN_DEL, &info); } +void dsa_port_set_tag_protocol(struct dsa_port *cpu_dp, + const struct dsa_device_ops *tag_ops) +{ + cpu_dp->filter = tag_ops->filter; + cpu_dp->rcv = tag_ops->rcv; + cpu_dp->tag_ops = tag_ops; +} + static struct phy_device *dsa_port_get_phy_device(struct dsa_port *dp) { struct device_node *phy_dn; diff --git a/net/dsa/slave.c b/net/dsa/slave.c index f2fb433f3828..b0571ab4e5a7 100644 --- a/net/dsa/slave.c +++ b/net/dsa/slave.c @@ -1430,7 +1430,7 @@ out: dsa_hw_port_list_free(&hw_port_list); } -static int dsa_slave_change_mtu(struct net_device *dev, int new_mtu) +int dsa_slave_change_mtu(struct net_device *dev, int new_mtu) { struct net_device *master = dsa_slave_to_master(dev); struct dsa_port *dp = dsa_slave_to_port(dev); @@ -1708,6 +1708,27 @@ static int dsa_slave_phy_setup(struct net_device *slave_dev) return ret; } +void dsa_slave_setup_tagger(struct net_device *slave) +{ + struct dsa_port *dp = dsa_slave_to_port(slave); + struct dsa_slave_priv *p = netdev_priv(slave); + const struct dsa_port *cpu_dp = dp->cpu_dp; + struct net_device *master = cpu_dp->master; + + if (cpu_dp->tag_ops->tail_tag) + slave->needed_tailroom = cpu_dp->tag_ops->overhead; + else + slave->needed_headroom = cpu_dp->tag_ops->overhead; + /* Try to save one extra realloc later in the TX path (in the master) + * by also inheriting the master's needed headroom and tailroom. + * The 8021q driver also does this. + */ + slave->needed_headroom += master->needed_headroom; + slave->needed_tailroom += master->needed_tailroom; + + p->xmit = cpu_dp->tag_ops->xmit; +} + static struct lock_class_key dsa_slave_netdev_xmit_lock_key; static void dsa_slave_set_lockdep_class_one(struct net_device *dev, struct netdev_queue *txq, @@ -1782,16 +1803,6 @@ int dsa_slave_create(struct dsa_port *port) slave_dev->netdev_ops = &dsa_slave_netdev_ops; if (ds->ops->port_max_mtu) slave_dev->max_mtu = ds->ops->port_max_mtu(ds, port->index); - if (cpu_dp->tag_ops->tail_tag) - slave_dev->needed_tailroom = cpu_dp->tag_ops->overhead; - else - slave_dev->needed_headroom = cpu_dp->tag_ops->overhead; - /* Try to save one extra realloc later in the TX path (in the master) - * by also inheriting the master's needed headroom and tailroom. - * The 8021q driver also does this. - */ - slave_dev->needed_headroom += master->needed_headroom; - slave_dev->needed_tailroom += master->needed_tailroom; SET_NETDEV_DEVTYPE(slave_dev, &dsa_type); netdev_for_each_tx_queue(slave_dev, dsa_slave_set_lockdep_class_one, @@ -1814,8 +1825,8 @@ int dsa_slave_create(struct dsa_port *port) p->dp = port; INIT_LIST_HEAD(&p->mall_tc_list); - p->xmit = cpu_dp->tag_ops->xmit; port->slave = slave_dev; + dsa_slave_setup_tagger(slave_dev); rtnl_lock(); ret = dsa_slave_change_mtu(slave_dev, ETH_DATA_LEN); diff --git a/net/dsa/switch.c b/net/dsa/switch.c index cc0b25f3adea..5026e4143663 100644 --- a/net/dsa/switch.c +++ b/net/dsa/switch.c @@ -297,6 +297,58 @@ static int dsa_switch_vlan_del(struct dsa_switch *ds, return 0; } +static bool dsa_switch_tag_proto_match(struct dsa_switch *ds, int port, + struct dsa_notifier_tag_proto_info *info) +{ + if (dsa_is_cpu_port(ds, port) || dsa_is_dsa_port(ds, port)) + return true; + + return false; +} + +static int dsa_switch_change_tag_proto(struct dsa_switch *ds, + struct dsa_notifier_tag_proto_info *info) +{ + const struct dsa_device_ops *tag_ops = info->tag_ops; + int port, err; + + if (!ds->ops->change_tag_protocol) + return -EOPNOTSUPP; + + ASSERT_RTNL(); + + for (port = 0; port < ds->num_ports; port++) { + if (dsa_switch_tag_proto_match(ds, port, info)) { + err = ds->ops->change_tag_protocol(ds, port, + tag_ops->proto); + if (err) + return err; + + if (dsa_is_cpu_port(ds, port)) + dsa_port_set_tag_protocol(dsa_to_port(ds, port), + tag_ops); + } + } + + /* Now that changing the tag protocol can no longer fail, let's update + * the remaining bits which are "duplicated for faster access", and the + * bits that depend on the tagger, such as the MTU. + */ + for (port = 0; port < ds->num_ports; port++) { + if (dsa_is_user_port(ds, port)) { + struct net_device *slave; + + slave = dsa_to_port(ds, port)->slave; + dsa_slave_setup_tagger(slave); + + /* rtnl_mutex is held in dsa_tree_change_tag_proto */ + dsa_slave_change_mtu(slave, slave->mtu); + } + } + + return 0; +} + static int dsa_switch_event(struct notifier_block *nb, unsigned long event, void *info) { @@ -343,6 +395,9 @@ static int dsa_switch_event(struct notifier_block *nb, case DSA_NOTIFIER_MTU: err = dsa_switch_mtu(ds, info); break; + case DSA_NOTIFIER_TAG_PROTO: + err = dsa_switch_change_tag_proto(ds, info); + break; default: err = -EOPNOTSUPP; break; -- cgit v1.2.3 From 1447e43c0b735ffc0d48a6aec4f74d6877caffc2 Mon Sep 17 00:00:00 2001 From: Adrien Grassein Date: Thu, 28 Jan 2021 20:35:52 +0100 Subject: dt-bindings: arm: imx: add imx8mm nitrogen support The Nitrogen8M Mini is an ARM based single board computer (SBC). Signed-off-by: Adrien Grassein Reviewed-by: Krzysztof Kozlowski Signed-off-by: Shawn Guo --- Documentation/devicetree/bindings/arm/fsl.yaml | 1 + 1 file changed, 1 insertion(+) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/arm/fsl.yaml b/Documentation/devicetree/bindings/arm/fsl.yaml index 47220e2f522c..297c87f45db8 100644 --- a/Documentation/devicetree/bindings/arm/fsl.yaml +++ b/Documentation/devicetree/bindings/arm/fsl.yaml @@ -678,6 +678,7 @@ properties: items: - enum: - beacon,imx8mm-beacon-kit # i.MX8MM Beacon Development Kit + - boundary,imx8mm-nitrogen8mm # i.MX8MM Nitrogen Board - fsl,imx8mm-ddr4-evk # i.MX8MM DDR4 EVK Board - fsl,imx8mm-evk # i.MX8MM EVK Board - gw,imx8mm-gw71xx-0x # i.MX8MM Gateworks Development Kit -- cgit v1.2.3 From c8283eb79d879ef898f4224ba30e554f83904b0a Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Sun, 3 Jan 2021 00:15:09 +0100 Subject: dt-bindings: leds: Add DT binding for Richtek RT8515 Add a YAML devicetree binding for the Richtek RT8515 dual channel flash/torch LED driver. Cc: Sakari Ailus Cc: newbytee@protonmail.com Cc: Stephan Gerhold Cc: phone-devel@vger.kernel.org Cc: linux-media@vger.kernel.org Cc: devicetree@vger.kernel.org Reviewed-by: Rob Herring Reviewed-by: Sakari Ailus Signed-off-by: Linus Walleij Signed-off-by: Pavel Machek --- .../devicetree/bindings/leds/richtek,rt8515.yaml | 111 +++++++++++++++++++++ 1 file changed, 111 insertions(+) create mode 100644 Documentation/devicetree/bindings/leds/richtek,rt8515.yaml (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/leds/richtek,rt8515.yaml b/Documentation/devicetree/bindings/leds/richtek,rt8515.yaml new file mode 100644 index 000000000000..68c328eec03b --- /dev/null +++ b/Documentation/devicetree/bindings/leds/richtek,rt8515.yaml @@ -0,0 +1,111 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/leds/richtek,rt8515.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Richtek RT8515 1.5A dual channel LED driver + +maintainers: + - Linus Walleij + +description: | + The Richtek RT8515 is a dual channel (two mode) LED driver that + supports driving a white LED in flash or torch mode. The maximum + current for each mode is defined in hardware using two resistors + RFS and RTS. + +properties: + compatible: + const: richtek,rt8515 + + enf-gpios: + maxItems: 1 + description: A connection to the 'ENF' (enable flash) pin. + + ent-gpios: + maxItems: 1 + description: A connection to the 'ENT' (enable torch) pin. + + richtek,rfs-ohms: + minimum: 7680 + maximum: 367000 + description: The resistance value of the RFS resistor. This + resistors limits the maximum flash current. This must be set + for the property flash-max-microamp to work, the RFS resistor + defines the range of the dimmer setting (brightness) of the + flash LED. + + richtek,rts-ohms: + minimum: 7680 + maximum: 367000 + description: The resistance value of the RTS resistor. This + resistors limits the maximum torch current. This must be set + for the property torch-max-microamp to work, the RTS resistor + defines the range of the dimmer setting (brightness) of the + torch LED. + + led: + type: object + $ref: common.yaml# + properties: + function: true + color: true + flash-max-timeout-us: true + + flash-max-microamp: + maximum: 700000 + description: The maximum current for flash mode + is hardwired to the component using the RFS resistor to + ground. The maximum hardware current setting is calculated + according to the formula Imax = 5500 / RFS. The lowest + allowed resistance value is 7.86 kOhm giving an absolute + maximum current of 700mA. By setting this attribute in + the device tree, you can further restrict the maximum + current below the hardware limit. This requires the RFS + to be defined as it defines the maximum range. + + led-max-microamp: + maximum: 700000 + description: The maximum current for torch mode + is hardwired to the component using the RTS resistor to + ground. The maximum hardware current setting is calculated + according to the formula Imax = 5500 / RTS. The lowest + allowed resistance value is 7.86 kOhm giving an absolute + maximum current of 700mA. By setting this attribute in + the device tree, you can further restrict the maximum + current below the hardware limit. This requires the RTS + to be defined as it defines the maximum range. + + additionalProperties: false + +required: + - compatible + - ent-gpios + - enf-gpios + - led + +additionalProperties: false + +examples: + - | + #include + #include + + led-controller { + compatible = "richtek,rt8515"; + enf-gpios = <&gpio4 12 GPIO_ACTIVE_HIGH>; + ent-gpios = <&gpio4 13 GPIO_ACTIVE_HIGH>; + richtek,rfs-ohms = <16000>; + richtek,rts-ohms = <100000>; + + led { + function = LED_FUNCTION_FLASH; + color = ; + flash-max-timeout-us = <250000>; + flash-max-microamp = <150000>; + led-max-microamp = <25000>; + }; + }; + +... -- cgit v1.2.3 From c70d0f16f38c3c25830db2854203444b566d30a9 Mon Sep 17 00:00:00 2001 From: Fabien Parent Date: Wed, 9 Dec 2020 14:32:36 +0100 Subject: dt-bindings: power: Add MT8167 power domains Add power domains dt-bindings for MT8167. Signed-off-by: Fabien Parent Acked-by: Rob Herring Link: https://lore.kernel.org/r/20201209133238.384030-1-fparent@baylibre.com Signed-off-by: Matthias Brugger --- .../bindings/power/mediatek,power-controller.yaml | 2 ++ include/dt-bindings/power/mt8167-power.h | 17 +++++++++++++++++ 2 files changed, 19 insertions(+) create mode 100644 include/dt-bindings/power/mt8167-power.h (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/power/mediatek,power-controller.yaml b/Documentation/devicetree/bindings/power/mediatek,power-controller.yaml index d14cb9bac849..52e77315c163 100644 --- a/Documentation/devicetree/bindings/power/mediatek,power-controller.yaml +++ b/Documentation/devicetree/bindings/power/mediatek,power-controller.yaml @@ -23,6 +23,7 @@ properties: compatible: enum: + - mediatek,mt8167-power-controller - mediatek,mt8173-power-controller - mediatek,mt8183-power-controller - mediatek,mt8192-power-controller @@ -59,6 +60,7 @@ patternProperties: reg: description: | Power domain index. Valid values are defined in: + "include/dt-bindings/power/mt8167-power.h" - for MT8167 type power domain. "include/dt-bindings/power/mt8173-power.h" - for MT8173 type power domain. "include/dt-bindings/power/mt8183-power.h" - for MT8183 type power domain. "include/dt-bindings/power/mt8192-power.h" - for MT8192 type power domain. diff --git a/include/dt-bindings/power/mt8167-power.h b/include/dt-bindings/power/mt8167-power.h new file mode 100644 index 000000000000..c8ec9983a4bc --- /dev/null +++ b/include/dt-bindings/power/mt8167-power.h @@ -0,0 +1,17 @@ +/* SPDX-License-Identifier: GPL-2.0 + * + * Copyright (c) 2020 MediaTek Inc. + */ + +#ifndef _DT_BINDINGS_POWER_MT8167_POWER_H +#define _DT_BINDINGS_POWER_MT8167_POWER_H + +#define MT8167_POWER_DOMAIN_MM 0 +#define MT8167_POWER_DOMAIN_VDEC 1 +#define MT8167_POWER_DOMAIN_ISP 2 +#define MT8167_POWER_DOMAIN_CONN 3 +#define MT8167_POWER_DOMAIN_MFG_ASYNC 4 +#define MT8167_POWER_DOMAIN_MFG_2D 5 +#define MT8167_POWER_DOMAIN_MFG 6 + +#endif /* _DT_BINDINGS_POWER_MT8167_POWER_H */ -- cgit v1.2.3 From ebfe73f7079a9ef5e6487ae8dfe48c43787118e8 Mon Sep 17 00:00:00 2001 From: Hsin-Yi Wang Date: Fri, 29 Jan 2021 18:12:06 +0800 Subject: dt-bindings: power: Add domain regulator supply Some power domains (eg. mfg) needs to turn on power supply before power on. Signed-off-by: Hsin-Yi Wang Reviewed-by: Rob Herring Reviewed-by: Enric Balletbo i Serra Link: https://lore.kernel.org/r/20210129101208.2625249-2-hsinyi@chromium.org Signed-off-by: Matthias Brugger --- .../devicetree/bindings/power/mediatek,power-controller.yaml | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/power/mediatek,power-controller.yaml b/Documentation/devicetree/bindings/power/mediatek,power-controller.yaml index 52e77315c163..f234a756c193 100644 --- a/Documentation/devicetree/bindings/power/mediatek,power-controller.yaml +++ b/Documentation/devicetree/bindings/power/mediatek,power-controller.yaml @@ -84,6 +84,9 @@ patternProperties: be specified by order, adding first the BASIC clocks followed by the SUSBSYS clocks. + domain-supply: + description: domain regulator supply. + mediatek,infracfg: $ref: /schemas/types.yaml#/definitions/phandle description: phandle to the device containing the INFRACFG register range. @@ -132,6 +135,9 @@ patternProperties: be specified by order, adding first the BASIC clocks followed by the SUSBSYS clocks. + domain-supply: + description: domain regulator supply. + mediatek,infracfg: $ref: /schemas/types.yaml#/definitions/phandle description: phandle to the device containing the INFRACFG register range. @@ -180,6 +186,9 @@ patternProperties: be specified by order, adding first the BASIC clocks followed by the SUSBSYS clocks. + domain-supply: + description: domain regulator supply. + mediatek,infracfg: $ref: /schemas/types.yaml#/definitions/phandle description: phandle to the device containing the INFRACFG register range. -- cgit v1.2.3 From 81004f0bf7f04fcdb6344692a563c49897424f14 Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Sat, 30 Jan 2021 11:47:51 -0300 Subject: dt-bindings: serial: imx: Switch to my personal address My nxp account will expire soon, so switch to my personal e-mail address. Signed-off-by: Fabio Estevam Link: https://lore.kernel.org/r/20210130144751.133641-1-festevam@gmail.com Signed-off-by: Greg Kroah-Hartman --- Documentation/devicetree/bindings/serial/fsl-imx-uart.yaml | 2 +- Documentation/devicetree/bindings/serial/fsl-mxs-auart.yaml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/serial/fsl-imx-uart.yaml b/Documentation/devicetree/bindings/serial/fsl-imx-uart.yaml index 9702c07a6b6c..2b06c6ce4a75 100644 --- a/Documentation/devicetree/bindings/serial/fsl-imx-uart.yaml +++ b/Documentation/devicetree/bindings/serial/fsl-imx-uart.yaml @@ -7,7 +7,7 @@ $schema: http://devicetree.org/meta-schemas/core.yaml# title: Freescale i.MX Universal Asynchronous Receiver/Transmitter (UART) maintainers: - - Fabio Estevam + - Fabio Estevam allOf: - $ref: "serial.yaml" diff --git a/Documentation/devicetree/bindings/serial/fsl-mxs-auart.yaml b/Documentation/devicetree/bindings/serial/fsl-mxs-auart.yaml index ce1d89496342..14c7594c88c6 100644 --- a/Documentation/devicetree/bindings/serial/fsl-mxs-auart.yaml +++ b/Documentation/devicetree/bindings/serial/fsl-mxs-auart.yaml @@ -7,7 +7,7 @@ $schema: http://devicetree.org/meta-schemas/core.yaml# title: Freescale MXS Application UART (AUART) maintainers: - - Fabio Estevam + - Fabio Estevam allOf: - $ref: "serial.yaml" -- cgit v1.2.3 From f93b04efaf80fe3d8ea1776a71a9e8e7fb3cfeab Mon Sep 17 00:00:00 2001 From: Hsin-Yi Wang Date: Wed, 13 Jan 2021 19:04:03 +0800 Subject: dt-bindings: arm64: dts: mediatek: Add krane sku0 Krane-sku0 is similar to krane-sku176 but using a different panel source. Signed-off-by: Hsin-Yi Wang Reviewed-by: Rob Herring Reviewed-by: Enric Balletbo i Serra Link: https://lore.kernel.org/r/20210113110400.616319-3-hsinyi@chromium.org Signed-off-by: Matthias Brugger --- Documentation/devicetree/bindings/arm/mediatek.yaml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/arm/mediatek.yaml b/Documentation/devicetree/bindings/arm/mediatek.yaml index 53f0d4e3ea98..93b3bdf6eaeb 100644 --- a/Documentation/devicetree/bindings/arm/mediatek.yaml +++ b/Documentation/devicetree/bindings/arm/mediatek.yaml @@ -120,7 +120,9 @@ properties: - const: mediatek,mt8183 - description: Google Krane (Lenovo IdeaPad Duet, 10e,...) items: - - const: google,krane-sku176 + - enum: + - google,krane-sku0 + - google,krane-sku176 - const: google,krane - const: mediatek,mt8183 -- cgit v1.2.3 From d8d2d38275c1b2d3936c0d809e0559e88912fbb5 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Mon, 1 Feb 2021 10:00:24 +0900 Subject: kbuild: remove PYTHON variable Python retired in 2020, and some distributions do not provide the 'python' command any more. As in commit 51839e29cb59 ("scripts: switch explicitly to Python 3"), we need to use more specific 'python3' to invoke scripts even if they are written in a way compatible with both Python 2 and 3. This commit removes the variable 'PYTHON', and switches the existing users to 'PYTHON3'. BTW, PEP 394 (https://www.python.org/dev/peps/pep-0394/) is a helpful material. Signed-off-by: Masahiro Yamada --- Documentation/Makefile | 2 +- Documentation/kbuild/makefiles.rst | 2 +- Makefile | 3 +-- arch/ia64/Makefile | 2 +- arch/ia64/scripts/unwcheck.py | 2 +- scripts/jobserver-exec | 2 +- 6 files changed, 6 insertions(+), 7 deletions(-) (limited to 'Documentation') diff --git a/Documentation/Makefile b/Documentation/Makefile index 61a7310b49e0..9c42dde97671 100644 --- a/Documentation/Makefile +++ b/Documentation/Makefile @@ -75,7 +75,7 @@ quiet_cmd_sphinx = SPHINX $@ --> file://$(abspath $(BUILDDIR)/$3/$4) cmd_sphinx = $(MAKE) BUILDDIR=$(abspath $(BUILDDIR)) $(build)=Documentation/userspace-api/media $2 && \ PYTHONDONTWRITEBYTECODE=1 \ BUILDDIR=$(abspath $(BUILDDIR)) SPHINX_CONF=$(abspath $(srctree)/$(src)/$5/$(SPHINX_CONF)) \ - $(PYTHON) $(srctree)/scripts/jobserver-exec \ + $(PYTHON3) $(srctree)/scripts/jobserver-exec \ $(SHELL) $(srctree)/Documentation/sphinx/parallel-wrapper.sh \ $(SPHINXBUILD) \ -b $2 \ diff --git a/Documentation/kbuild/makefiles.rst b/Documentation/kbuild/makefiles.rst index 9f6a11881951..300d8edcb994 100644 --- a/Documentation/kbuild/makefiles.rst +++ b/Documentation/kbuild/makefiles.rst @@ -755,7 +755,7 @@ more details, with real examples. bits on the scripts nonetheless. Kbuild provides variables $(CONFIG_SHELL), $(AWK), $(PERL), - $(PYTHON) and $(PYTHON3) to refer to interpreters for the respective + and $(PYTHON3) to refer to interpreters for the respective scripts. Example:: diff --git a/Makefile b/Makefile index b0e4767735dc..89217e4e68c6 100644 --- a/Makefile +++ b/Makefile @@ -452,7 +452,6 @@ AWK = awk INSTALLKERNEL := installkernel DEPMOD = depmod PERL = perl -PYTHON = python PYTHON3 = python3 CHECK = sparse BASH = bash @@ -508,7 +507,7 @@ CLANG_FLAGS := export ARCH SRCARCH CONFIG_SHELL BASH HOSTCC KBUILD_HOSTCFLAGS CROSS_COMPILE LD CC export CPP AR NM STRIP OBJCOPY OBJDUMP READELF PAHOLE RESOLVE_BTFIDS LEX YACC AWK INSTALLKERNEL -export PERL PYTHON PYTHON3 CHECK CHECKFLAGS MAKE UTS_MACHINE HOSTCXX +export PERL PYTHON3 CHECK CHECKFLAGS MAKE UTS_MACHINE HOSTCXX export KGZIP KBZIP2 KLZOP LZMA LZ4 XZ ZSTD export KBUILD_HOSTCXXFLAGS KBUILD_HOSTLDFLAGS KBUILD_HOSTLDLIBS LDFLAGS_MODULE diff --git a/arch/ia64/Makefile b/arch/ia64/Makefile index 703b1c4f6d12..45d5368d6a99 100644 --- a/arch/ia64/Makefile +++ b/arch/ia64/Makefile @@ -69,7 +69,7 @@ vmlinux.bin: vmlinux FORCE $(call if_changed,objcopy) unwcheck: vmlinux - -$(Q)READELF=$(READELF) $(PYTHON) $(srctree)/arch/ia64/scripts/unwcheck.py $< + -$(Q)READELF=$(READELF) $(PYTHON3) $(srctree)/arch/ia64/scripts/unwcheck.py $< archclean: diff --git a/arch/ia64/scripts/unwcheck.py b/arch/ia64/scripts/unwcheck.py index bfd1b671e35f..9581742f0db2 100644 --- a/arch/ia64/scripts/unwcheck.py +++ b/arch/ia64/scripts/unwcheck.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/env python3 # SPDX-License-Identifier: GPL-2.0 # # Usage: unwcheck.py FILE diff --git a/scripts/jobserver-exec b/scripts/jobserver-exec index 0fdb31a790a8..48d141e3ec56 100755 --- a/scripts/jobserver-exec +++ b/scripts/jobserver-exec @@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/env python3 # SPDX-License-Identifier: GPL-2.0+ # # This determines how many parallel tasks "make" is expecting, as it is -- cgit v1.2.3 From 72ec393ba324fdaab4378b46a74514c406228d3a Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Thu, 28 Jan 2021 09:44:52 +0100 Subject: dt-bindings: renesas,rcar-dmac: Add r8a779a0 support Document the compatible value for the Direct Memory Access Controller blocks in the Renesas R-Car V3U (R8A779A0) SoC. The most visible difference with DMAC blocks on other R-Car SoCs is the move of the per-channel registers to a separate register block. Signed-off-by: Geert Uytterhoeven Tested-by: Yoshihiro Shimoda Reviewed-by: Rob Herring Reviewed-by: Laurent Pinchart Reviewed-by: Yoshihiro Shimoda Link: https://lore.kernel.org/r/20210128084455.2237256-2-geert+renesas@glider.be Signed-off-by: Vinod Koul --- .../devicetree/bindings/dma/renesas,rcar-dmac.yaml | 76 ++++++++++++++-------- 1 file changed, 48 insertions(+), 28 deletions(-) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/dma/renesas,rcar-dmac.yaml b/Documentation/devicetree/bindings/dma/renesas,rcar-dmac.yaml index c07eb6f2fc8d..7f2a54bc732d 100644 --- a/Documentation/devicetree/bindings/dma/renesas,rcar-dmac.yaml +++ b/Documentation/devicetree/bindings/dma/renesas,rcar-dmac.yaml @@ -14,34 +14,37 @@ allOf: properties: compatible: - items: - - enum: - - renesas,dmac-r8a7742 # RZ/G1H - - renesas,dmac-r8a7743 # RZ/G1M - - renesas,dmac-r8a7744 # RZ/G1N - - renesas,dmac-r8a7745 # RZ/G1E - - renesas,dmac-r8a77470 # RZ/G1C - - renesas,dmac-r8a774a1 # RZ/G2M - - renesas,dmac-r8a774b1 # RZ/G2N - - renesas,dmac-r8a774c0 # RZ/G2E - - renesas,dmac-r8a774e1 # RZ/G2H - - renesas,dmac-r8a7790 # R-Car H2 - - renesas,dmac-r8a7791 # R-Car M2-W - - renesas,dmac-r8a7792 # R-Car V2H - - renesas,dmac-r8a7793 # R-Car M2-N - - renesas,dmac-r8a7794 # R-Car E2 - - renesas,dmac-r8a7795 # R-Car H3 - - renesas,dmac-r8a7796 # R-Car M3-W - - renesas,dmac-r8a77961 # R-Car M3-W+ - - renesas,dmac-r8a77965 # R-Car M3-N - - renesas,dmac-r8a77970 # R-Car V3M - - renesas,dmac-r8a77980 # R-Car V3H - - renesas,dmac-r8a77990 # R-Car E3 - - renesas,dmac-r8a77995 # R-Car D3 - - const: renesas,rcar-dmac - - reg: - maxItems: 1 + oneOf: + - items: + - enum: + - renesas,dmac-r8a7742 # RZ/G1H + - renesas,dmac-r8a7743 # RZ/G1M + - renesas,dmac-r8a7744 # RZ/G1N + - renesas,dmac-r8a7745 # RZ/G1E + - renesas,dmac-r8a77470 # RZ/G1C + - renesas,dmac-r8a774a1 # RZ/G2M + - renesas,dmac-r8a774b1 # RZ/G2N + - renesas,dmac-r8a774c0 # RZ/G2E + - renesas,dmac-r8a774e1 # RZ/G2H + - renesas,dmac-r8a7790 # R-Car H2 + - renesas,dmac-r8a7791 # R-Car M2-W + - renesas,dmac-r8a7792 # R-Car V2H + - renesas,dmac-r8a7793 # R-Car M2-N + - renesas,dmac-r8a7794 # R-Car E2 + - renesas,dmac-r8a7795 # R-Car H3 + - renesas,dmac-r8a7796 # R-Car M3-W + - renesas,dmac-r8a77961 # R-Car M3-W+ + - renesas,dmac-r8a77965 # R-Car M3-N + - renesas,dmac-r8a77970 # R-Car V3M + - renesas,dmac-r8a77980 # R-Car V3H + - renesas,dmac-r8a77990 # R-Car E3 + - renesas,dmac-r8a77995 # R-Car D3 + - const: renesas,rcar-dmac + + - items: + - const: renesas,dmac-r8a779a0 # R-Car V3U + + reg: true interrupts: minItems: 9 @@ -110,6 +113,23 @@ required: - power-domains - resets +if: + properties: + compatible: + contains: + enum: + - renesas,dmac-r8a779a0 +then: + properties: + reg: + items: + - description: Base register block + - description: Channel register block +else: + properties: + reg: + maxItems: 1 + additionalProperties: false examples: -- cgit v1.2.3 From 127b856f67fc7bf9f753f99d247347833543ee42 Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Thu, 21 Jan 2021 11:27:00 +0100 Subject: arm64: dts: zynqmp: Add description for zcu104 revC Xilinx ZynqMP zcu104 revC and newer board revisions have different i2c structure compare to revA. The rest of the board is the same from software perspective. Also enable DMAs and QSPI. Signed-off-by: Michal Simek Link: https://lore.kernel.org/r/17f68c235ea1ce96c3293ca0cf3178951d6663f7.1611224800.git.michal.simek@xilinx.com --- Documentation/devicetree/bindings/arm/xilinx.yaml | 1 + arch/arm64/boot/dts/xilinx/Makefile | 1 + arch/arm64/boot/dts/xilinx/zynqmp-zcu104-revC.dts | 282 ++++++++++++++++++++++ 3 files changed, 284 insertions(+) create mode 100644 arch/arm64/boot/dts/xilinx/zynqmp-zcu104-revC.dts (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/arm/xilinx.yaml b/Documentation/devicetree/bindings/arm/xilinx.yaml index e0c6787f6e94..ae0ef1bf7965 100644 --- a/Documentation/devicetree/bindings/arm/xilinx.yaml +++ b/Documentation/devicetree/bindings/arm/xilinx.yaml @@ -91,6 +91,7 @@ properties: items: - enum: - xlnx,zynqmp-zcu104-revA + - xlnx,zynqmp-zcu104-revC - xlnx,zynqmp-zcu104-rev1.0 - const: xlnx,zynqmp-zcu104 - const: xlnx,zynqmp diff --git a/arch/arm64/boot/dts/xilinx/Makefile b/arch/arm64/boot/dts/xilinx/Makefile index 60f5443f3ef4..11fb4fd3ebd4 100644 --- a/arch/arm64/boot/dts/xilinx/Makefile +++ b/arch/arm64/boot/dts/xilinx/Makefile @@ -13,5 +13,6 @@ dtb-$(CONFIG_ARCH_ZYNQMP) += zynqmp-zcu102-revA.dtb dtb-$(CONFIG_ARCH_ZYNQMP) += zynqmp-zcu102-revB.dtb dtb-$(CONFIG_ARCH_ZYNQMP) += zynqmp-zcu102-rev1.0.dtb dtb-$(CONFIG_ARCH_ZYNQMP) += zynqmp-zcu104-revA.dtb +dtb-$(CONFIG_ARCH_ZYNQMP) += zynqmp-zcu104-revC.dtb dtb-$(CONFIG_ARCH_ZYNQMP) += zynqmp-zcu106-revA.dtb dtb-$(CONFIG_ARCH_ZYNQMP) += zynqmp-zcu111-revA.dtb diff --git a/arch/arm64/boot/dts/xilinx/zynqmp-zcu104-revC.dts b/arch/arm64/boot/dts/xilinx/zynqmp-zcu104-revC.dts new file mode 100644 index 000000000000..414f98f1831e --- /dev/null +++ b/arch/arm64/boot/dts/xilinx/zynqmp-zcu104-revC.dts @@ -0,0 +1,282 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * dts file for Xilinx ZynqMP ZCU104 + * + * (C) Copyright 2017 - 2020, Xilinx, Inc. + * + * Michal Simek + */ + +/dts-v1/; + +#include "zynqmp.dtsi" +#include "zynqmp-clk-ccf.dtsi" +#include +#include + +/ { + model = "ZynqMP ZCU104 RevC"; + compatible = "xlnx,zynqmp-zcu104-revC", "xlnx,zynqmp-zcu104", "xlnx,zynqmp"; + + aliases { + ethernet0 = &gem3; + i2c0 = &i2c1; + mmc0 = &sdhci1; + rtc0 = &rtc; + serial0 = &uart0; + serial1 = &uart1; + serial2 = &dcc; + }; + + chosen { + bootargs = "earlycon"; + stdout-path = "serial0:115200n8"; + }; + + memory@0 { + device_type = "memory"; + reg = <0x0 0x0 0x0 0x80000000>; + }; + + ina226 { + compatible = "iio-hwmon"; + io-channels = <&u183 0>, <&u183 1>, <&u183 2>, <&u183 3>; + }; + + clock_8t49n287_5: clk125 { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <125000000>; + }; + + clock_8t49n287_2: clk26 { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <26000000>; + }; + + clock_8t49n287_3: clk27 { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <27000000>; + }; +}; + +&can1 { + status = "okay"; +}; + +&dcc { + status = "okay"; +}; + +&fpd_dma_chan1 { + status = "okay"; +}; + +&fpd_dma_chan2 { + status = "okay"; +}; + +&fpd_dma_chan3 { + status = "okay"; +}; + +&fpd_dma_chan4 { + status = "okay"; +}; + +&fpd_dma_chan5 { + status = "okay"; +}; + +&fpd_dma_chan6 { + status = "okay"; +}; + +&fpd_dma_chan7 { + status = "okay"; +}; + +&fpd_dma_chan8 { + status = "okay"; +}; + +&gem3 { + status = "okay"; + phy-handle = <&phy0>; + phy-mode = "rgmii-id"; + phy0: ethernet-phy@c { + reg = <0xc>; + ti,rx-internal-delay = <0x8>; + ti,tx-internal-delay = <0xa>; + ti,fifo-depth = <0x1>; + ti,dp83867-rxctrl-strap-quirk; + }; +}; + +&gpio { + status = "okay"; +}; + +&i2c1 { + status = "okay"; + clock-frequency = <400000>; + + tca6416_u97: gpio@20 { + compatible = "ti,tca6416"; + reg = <0x20>; + gpio-controller; + #gpio-cells = <2>; + /* + * IRQ not connected + * Lines: + * 0 - IRPS5401_ALERT_B + * 1 - HDMI_8T49N241_INT_ALM + * 2 - MAX6643_OT_B + * 3 - MAX6643_FANFAIL_B + * 5 - IIC_MUX_RESET_B + * 6 - GEM3_EXP_RESET_B + * 7 - FMC_LPC_PRSNT_M2C_B + * 4, 10 - 17 - not connected + */ + }; + + /* Another connection to this bus via PL i2c via PCA9306 - u45 */ + i2c-mux@74 { /* u34 */ + compatible = "nxp,pca9548"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x74>; + i2c@0 { + #address-cells = <1>; + #size-cells = <0>; + reg = <0>; + /* + * IIC_EEPROM 1kB memory which uses 256B blocks + * where every block has different address. + * 0 - 256B address 0x54 + * 256B - 512B address 0x55 + * 512B - 768B address 0x56 + * 768B - 1024B address 0x57 + */ + eeprom: eeprom@54 { /* u23 */ + compatible = "atmel,24c08"; + reg = <0x54>; + #address-cells = <1>; + #size-cells = <1>; + }; + }; + + i2c@1 { + #address-cells = <1>; + #size-cells = <0>; + reg = <1>; + clock_8t49n287: clock-generator@6c { /* 8T49N287 - u182 */ + reg = <0x6c>; + }; + }; + + i2c@2 { + #address-cells = <1>; + #size-cells = <0>; + reg = <2>; + irps5401_43: irps5401@43 { /* IRPS5401 - u175 */ + compatible = "infineon,irps5401"; + reg = <0x43>; /* pmbus / i2c 0x13 */ + }; + irps5401_44: irps5401@44 { /* IRPS5401 - u180 */ + compatible = "infineon,irps5401"; + reg = <0x44>; /* pmbus / i2c 0x14 */ + }; + }; + + i2c@3 { + #address-cells = <1>; + #size-cells = <0>; + reg = <3>; + u183: ina226@40 { /* u183 */ + compatible = "ti,ina226"; + #io-channel-cells = <1>; + reg = <0x40>; + shunt-resistor = <5000>; + }; + }; + + i2c@5 { + #address-cells = <1>; + #size-cells = <0>; + reg = <5>; + }; + + i2c@7 { + #address-cells = <1>; + #size-cells = <0>; + reg = <7>; + }; + + /* 4, 6 not connected */ + }; +}; + +&qspi { + status = "okay"; + flash@0 { + compatible = "m25p80", "jedec,spi-nor"; /* n25q512a 128MiB */ + #address-cells = <1>; + #size-cells = <1>; + reg = <0x0>; + }; +}; + +&rtc { + status = "okay"; +}; + +&psgtr { + status = "okay"; + /* nc, sata, usb3, dp */ + clocks = <&clock_8t49n287_5>, <&clock_8t49n287_2>, <&clock_8t49n287_3>; + clock-names = "ref1", "ref2", "ref3"; +}; + +&sata { + status = "okay"; + /* SATA OOB timing settings */ + ceva,p0-cominit-params = /bits/ 8 <0x18 0x40 0x18 0x28>; + ceva,p0-comwake-params = /bits/ 8 <0x06 0x14 0x08 0x0E>; + ceva,p0-burst-params = /bits/ 8 <0x13 0x08 0x4A 0x06>; + ceva,p0-retry-params = /bits/ 16 <0x96A4 0x3FFC>; + ceva,p1-cominit-params = /bits/ 8 <0x18 0x40 0x18 0x28>; + ceva,p1-comwake-params = /bits/ 8 <0x06 0x14 0x08 0x0E>; + ceva,p1-burst-params = /bits/ 8 <0x13 0x08 0x4A 0x06>; + ceva,p1-retry-params = /bits/ 16 <0x96A4 0x3FFC>; + phy-names = "sata-phy"; + phys = <&psgtr 3 PHY_TYPE_SATA 1 1>; +}; + +/* SD1 with level shifter */ +&sdhci1 { + status = "okay"; + no-1-8-v; + xlnx,mio-bank = <1>; + disable-wp; +}; + +&uart0 { + status = "okay"; +}; + +&uart1 { + status = "okay"; +}; + +/* ULPI SMSC USB3320 */ +&usb0 { + status = "okay"; + dr_mode = "host"; +}; + +&watchdog0 { + status = "okay"; +}; -- cgit v1.2.3 From 8c70fb7e0a0ab477504e0bd761d301ddd616c8eb Mon Sep 17 00:00:00 2001 From: Sia Jee Heng Date: Mon, 25 Jan 2021 09:32:39 +0800 Subject: dt-bindings: dma: Add YAML schemas for dw-axi-dmac YAML schemas Device Tree (DT) binding is the new format for DT to replace the old format. Introduce YAML schemas DT binding for dw-axi-dmac and remove the old version. Signed-off-by: Sia Jee Heng Reviewed-by: Eugeniy Paltsev Reviewed-by: Rob Herring Link: https://lore.kernel.org/r/20210125013255.25799-2-jee.heng.sia@intel.com Signed-off-by: Vinod Koul --- .../devicetree/bindings/dma/snps,dw-axi-dmac.txt | 39 ------- .../devicetree/bindings/dma/snps,dw-axi-dmac.yaml | 121 +++++++++++++++++++++ 2 files changed, 121 insertions(+), 39 deletions(-) delete mode 100644 Documentation/devicetree/bindings/dma/snps,dw-axi-dmac.txt create mode 100644 Documentation/devicetree/bindings/dma/snps,dw-axi-dmac.yaml (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/dma/snps,dw-axi-dmac.txt b/Documentation/devicetree/bindings/dma/snps,dw-axi-dmac.txt deleted file mode 100644 index dbe160400adc..000000000000 --- a/Documentation/devicetree/bindings/dma/snps,dw-axi-dmac.txt +++ /dev/null @@ -1,39 +0,0 @@ -Synopsys DesignWare AXI DMA Controller - -Required properties: -- compatible: "snps,axi-dma-1.01a" -- reg: Address range of the DMAC registers. This should include - all of the per-channel registers. -- interrupt: Should contain the DMAC interrupt number. -- dma-channels: Number of channels supported by hardware. -- snps,dma-masters: Number of AXI masters supported by the hardware. -- snps,data-width: Maximum AXI data width supported by hardware. - (0 - 8bits, 1 - 16bits, 2 - 32bits, ..., 6 - 512bits) -- snps,priority: Priority of channel. Array size is equal to the number of - dma-channels. Priority value must be programmed within [0:dma-channels-1] - range. (0 - minimum priority) -- snps,block-size: Maximum block size supported by the controller channel. - Array size is equal to the number of dma-channels. - -Optional properties: -- snps,axi-max-burst-len: Restrict master AXI burst length by value specified - in this property. If this property is missing the maximum AXI burst length - supported by DMAC is used. [1:256] - -Example: - -dmac: dma-controller@80000 { - compatible = "snps,axi-dma-1.01a"; - reg = <0x80000 0x400>; - clocks = <&core_clk>, <&cfgr_clk>; - clock-names = "core-clk", "cfgr-clk"; - interrupt-parent = <&intc>; - interrupts = <27>; - - dma-channels = <4>; - snps,dma-masters = <2>; - snps,data-width = <3>; - snps,block-size = <4096 4096 4096 4096>; - snps,priority = <0 1 2 3>; - snps,axi-max-burst-len = <16>; -}; diff --git a/Documentation/devicetree/bindings/dma/snps,dw-axi-dmac.yaml b/Documentation/devicetree/bindings/dma/snps,dw-axi-dmac.yaml new file mode 100644 index 000000000000..3d2515463d56 --- /dev/null +++ b/Documentation/devicetree/bindings/dma/snps,dw-axi-dmac.yaml @@ -0,0 +1,121 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/dma/snps,dw-axi-dmac.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Synopsys DesignWare AXI DMA Controller + +maintainers: + - Eugeniy Paltsev + +description: + Synopsys DesignWare AXI DMA Controller DT Binding + +allOf: + - $ref: "dma-controller.yaml#" + +properties: + compatible: + enum: + - snps,axi-dma-1.01a + + reg: + items: + - description: Address range of the DMAC registers + + reg-names: + items: + - const: axidma_ctrl_regs + + interrupts: + maxItems: 1 + + clocks: + items: + - description: Bus Clock + - description: Module Clock + + clock-names: + items: + - const: core-clk + - const: cfgr-clk + + '#dma-cells': + const: 1 + + dma-channels: + minimum: 1 + maximum: 8 + + snps,dma-masters: + description: | + Number of AXI masters supported by the hardware. + $ref: /schemas/types.yaml#/definitions/uint32 + enum: [1, 2] + + snps,data-width: + description: | + AXI data width supported by hardware. + (0 - 8bits, 1 - 16bits, 2 - 32bits, ..., 6 - 512bits) + $ref: /schemas/types.yaml#/definitions/uint32 + enum: [0, 1, 2, 3, 4, 5, 6] + + snps,priority: + description: | + Channel priority specifier associated with the DMA channels. + $ref: /schemas/types.yaml#/definitions/uint32-array + minItems: 1 + maxItems: 8 + + snps,block-size: + description: | + Channel block size specifier associated with the DMA channels. + $ref: /schemas/types.yaml#/definitions/uint32-array + minItems: 1 + maxItems: 8 + + snps,axi-max-burst-len: + description: | + Restrict master AXI burst length by value specified in this property. + If this property is missing the maximum AXI burst length supported by + DMAC is used. + $ref: /schemas/types.yaml#/definitions/uint32 + minimum: 1 + maximum: 256 + +required: + - compatible + - reg + - clocks + - clock-names + - interrupts + - '#dma-cells' + - dma-channels + - snps,dma-masters + - snps,data-width + - snps,priority + - snps,block-size + +additionalProperties: false + +examples: + - | + #include + #include + /* example with snps,dw-axi-dmac */ + dmac: dma-controller@80000 { + compatible = "snps,axi-dma-1.01a"; + reg = <0x80000 0x400>; + clocks = <&core_clk>, <&cfgr_clk>; + clock-names = "core-clk", "cfgr-clk"; + interrupt-parent = <&intc>; + interrupts = <27>; + #dma-cells = <1>; + dma-channels = <4>; + snps,dma-masters = <2>; + snps,data-width = <3>; + snps,block-size = <4096 4096 4096 4096>; + snps,priority = <0 1 2 3>; + snps,axi-max-burst-len = <16>; + }; -- cgit v1.2.3 From 0a35c9a017d3e4d7f8eb503827a8cdbb8a47d7b0 Mon Sep 17 00:00:00 2001 From: Sia Jee Heng Date: Mon, 25 Jan 2021 09:32:48 +0800 Subject: dt-binding: dma: dw-axi-dmac: Add support for Intel KeemBay AxiDMA Add support for Intel KeemBay AxiDMA to the dw-axi-dmac Schemas DT binding. Signed-off-by: Sia Jee Heng Reviewed-by: Eugeniy Paltsev Reviewed-by: Rob Herring Link: https://lore.kernel.org/r/20210125013255.25799-11-jee.heng.sia@intel.com Signed-off-by: Vinod Koul --- Documentation/devicetree/bindings/dma/snps,dw-axi-dmac.yaml | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/dma/snps,dw-axi-dmac.yaml b/Documentation/devicetree/bindings/dma/snps,dw-axi-dmac.yaml index 3d2515463d56..79e241498e25 100644 --- a/Documentation/devicetree/bindings/dma/snps,dw-axi-dmac.yaml +++ b/Documentation/devicetree/bindings/dma/snps,dw-axi-dmac.yaml @@ -8,6 +8,7 @@ title: Synopsys DesignWare AXI DMA Controller maintainers: - Eugeniy Paltsev + - Jee Heng Sia description: Synopsys DesignWare AXI DMA Controller DT Binding @@ -19,14 +20,18 @@ properties: compatible: enum: - snps,axi-dma-1.01a + - intel,kmb-axi-dma reg: + minItems: 1 items: - description: Address range of the DMAC registers + - description: Address range of the DMAC APB registers reg-names: items: - const: axidma_ctrl_regs + - const: axidma_apb_regs interrupts: maxItems: 1 -- cgit v1.2.3 From 1cabd1181f157f2d00b81653af4c276119f8cfb3 Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Thu, 21 Jan 2021 11:56:03 +0100 Subject: dt-bindings: arm: Fix typo in zcu111 board Trivial fix. Signed-off-by: Michal Simek Link: https://lore.kernel.org/r/13d064fc4850f96904a04e330cea5295d3751e46.1611226560.git.michal.simek@xilinx.com --- Documentation/devicetree/bindings/arm/xilinx.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/arm/xilinx.yaml b/Documentation/devicetree/bindings/arm/xilinx.yaml index ae0ef1bf7965..97e77b4e077c 100644 --- a/Documentation/devicetree/bindings/arm/xilinx.yaml +++ b/Documentation/devicetree/bindings/arm/xilinx.yaml @@ -108,7 +108,7 @@ properties: items: - enum: - xlnx,zynqmp-zcu111-revA - - xlnx,zynqmp-zcu11-rev1.0 + - xlnx,zynqmp-zcu111-rev1.0 - const: xlnx,zynqmp-zcu111 - const: xlnx,zynqmp -- cgit v1.2.3 From b79ee3852c364c62e126f1e9031e46ffccaeeaac Mon Sep 17 00:00:00 2001 From: Yangtao Li Date: Fri, 11 Dec 2020 01:19:21 +0000 Subject: dt-bindings: mmc: sunxi: Add Allwinner A100 and H616 compatibles Add binding for A100's and H616's mmc and emmc controller. Signed-off-by: Yangtao Li Signed-off-by: Andre Przywara Link: https://lore.kernel.org/r/20201211011934.6171-9-andre.przywara@arm.com Signed-off-by: Ulf Hansson --- .../devicetree/bindings/mmc/allwinner,sun4i-a10-mmc.yaml | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/mmc/allwinner,sun4i-a10-mmc.yaml b/Documentation/devicetree/bindings/mmc/allwinner,sun4i-a10-mmc.yaml index e82c9a07b6fb..e75b3a8ba816 100644 --- a/Documentation/devicetree/bindings/mmc/allwinner,sun4i-a10-mmc.yaml +++ b/Documentation/devicetree/bindings/mmc/allwinner,sun4i-a10-mmc.yaml @@ -26,6 +26,8 @@ properties: - const: allwinner,sun9i-a80-mmc - const: allwinner,sun50i-a64-emmc - const: allwinner,sun50i-a64-mmc + - const: allwinner,sun50i-a100-emmc + - const: allwinner,sun50i-a100-mmc - items: - const: allwinner,sun8i-a83t-mmc - const: allwinner,sun7i-a20-mmc @@ -47,6 +49,12 @@ properties: - items: - const: allwinner,sun50i-h6-mmc - const: allwinner,sun50i-a64-mmc + - items: + - const: allwinner,sun50i-h616-emmc + - const: allwinner,sun50i-a100-emmc + - items: + - const: allwinner,sun50i-h616-mmc + - const: allwinner,sun50i-a100-mmc reg: maxItems: 1 -- cgit v1.2.3 From a5ca4c32121297e2306438ef0b2c08f98bafa3f3 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Sun, 27 Dec 2020 18:41:55 +0100 Subject: dt-bindings: mmc: renesas,sdhi: Add r8a779a0 support Signed-off-by: Wolfram Sang Acked-by: Rob Herring Reviewed-by: Geert Uytterhoeven Link: https://lore.kernel.org/r/20201227174202.40834-2-wsa+renesas@sang-engineering.com Signed-off-by: Ulf Hansson --- Documentation/devicetree/bindings/mmc/renesas,sdhi.yaml | 1 + 1 file changed, 1 insertion(+) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/mmc/renesas,sdhi.yaml b/Documentation/devicetree/bindings/mmc/renesas,sdhi.yaml index 6bbf29b5c239..5908a717d2e8 100644 --- a/Documentation/devicetree/bindings/mmc/renesas,sdhi.yaml +++ b/Documentation/devicetree/bindings/mmc/renesas,sdhi.yaml @@ -59,6 +59,7 @@ properties: - renesas,sdhi-r8a77980 # R-Car V3H - renesas,sdhi-r8a77990 # R-Car E3 - renesas,sdhi-r8a77995 # R-Car D3 + - renesas,sdhi-r8a779a0 # R-Car V3U - const: renesas,rcar-gen3-sdhi # R-Car Gen3 or RZ/G2 reg: -- cgit v1.2.3 From 9476e27bb5ce224c37b5d614336f3bec8dc3a956 Mon Sep 17 00:00:00 2001 From: Manivannan Sadhasivam Date: Thu, 7 Jan 2021 20:01:17 +0530 Subject: dt-bindings: mmc: sdhci-msm: Document the SDX55 compatible The SDHCI controller on SDX55 is based on MSM SDHCI v5 IP. Hence, document the compatible with "qcom,sdhci-msm-v5" as the fallback. While at it, let's also sort the compatibles in ascending order. Cc: Ulf Hansson Cc: linux-mmc@vger.kernel.org Signed-off-by: Manivannan Sadhasivam Reviewed-by: Vinod Koul Acked-by: Rob Herring Link: https://lore.kernel.org/r/20210107143118.2386-1-manivannan.sadhasivam@linaro.org Signed-off-by: Ulf Hansson --- Documentation/devicetree/bindings/mmc/sdhci-msm.txt | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/mmc/sdhci-msm.txt b/Documentation/devicetree/bindings/mmc/sdhci-msm.txt index 3b602fd6180b..9fa8a24fbc97 100644 --- a/Documentation/devicetree/bindings/mmc/sdhci-msm.txt +++ b/Documentation/devicetree/bindings/mmc/sdhci-msm.txt @@ -17,10 +17,11 @@ Required properties: "qcom,msm8916-sdhci", "qcom,sdhci-msm-v4" "qcom,msm8992-sdhci", "qcom,sdhci-msm-v4" "qcom,msm8996-sdhci", "qcom,sdhci-msm-v4" - "qcom,sm8250-sdhci", "qcom,sdhci-msm-v5" - "qcom,sdm845-sdhci", "qcom,sdhci-msm-v5" "qcom,qcs404-sdhci", "qcom,sdhci-msm-v5" "qcom,sc7180-sdhci", "qcom,sdhci-msm-v5"; + "qcom,sdm845-sdhci", "qcom,sdhci-msm-v5" + "qcom,sdx55-sdhci", "qcom,sdhci-msm-v5"; + "qcom,sm8250-sdhci", "qcom,sdhci-msm-v5" NOTE that some old device tree files may be floating around that only have the string "qcom,sdhci-msm-v4" without the SoC compatible string but doing that should be considered a deprecated practice. -- cgit v1.2.3 From 783be176eb2775447b6f6254ecf2e3499334941a Mon Sep 17 00:00:00 2001 From: Marcin Wojtas Date: Tue, 12 Jan 2021 11:46:52 +0200 Subject: dt-bindings: mmc: xenon: add AP807 compatible string This patch adds DT binding description for the Xenon SD/MMC controller included in AP807 north bridge. Signed-off-by: Marcin Wojtas Signed-off-by: Konstantin Porotchkin Link: https://lore.kernel.org/r/20210112094655.12274-2-kostap@marvell.com Signed-off-by: Ulf Hansson --- Documentation/devicetree/bindings/mmc/marvell,xenon-sdhci.txt | 1 + 1 file changed, 1 insertion(+) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/mmc/marvell,xenon-sdhci.txt b/Documentation/devicetree/bindings/mmc/marvell,xenon-sdhci.txt index ed1456f5c94d..c51a62d751dc 100644 --- a/Documentation/devicetree/bindings/mmc/marvell,xenon-sdhci.txt +++ b/Documentation/devicetree/bindings/mmc/marvell,xenon-sdhci.txt @@ -12,6 +12,7 @@ Required Properties: - "marvell,armada-3700-sdhci": For controllers on Armada-3700 SoC. Must provide a second register area and marvell,pad-type. - "marvell,armada-ap806-sdhci": For controllers on Armada AP806. + - "marvell,armada-ap807-sdhci": For controllers on Armada AP807. - "marvell,armada-cp110-sdhci": For controllers on Armada CP110. - clocks: -- cgit v1.2.3 From 81aa9876f9439287eab4ddc6b70377d3774cb2e6 Mon Sep 17 00:00:00 2001 From: Aswath Govindraju Date: Wed, 13 Jan 2021 17:29:07 +0530 Subject: dt-bindings: mmc: sdhci-am654: Add compatible string for AM64 SoC Add compatible string for AM64 SoC in device tree binding of AM654 SDHCI module as the same IP is used. Signed-off-by: Aswath Govindraju Acked-by: Rob Herring Link: https://lore.kernel.org/r/20210113115908.3882-2-a-govindraju@ti.com Signed-off-by: Ulf Hansson --- Documentation/devicetree/bindings/mmc/sdhci-am654.yaml | 2 ++ 1 file changed, 2 insertions(+) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/mmc/sdhci-am654.yaml b/Documentation/devicetree/bindings/mmc/sdhci-am654.yaml index 1ae945434c53..34e53db29428 100644 --- a/Documentation/devicetree/bindings/mmc/sdhci-am654.yaml +++ b/Documentation/devicetree/bindings/mmc/sdhci-am654.yaml @@ -21,6 +21,8 @@ properties: - ti,j721e-sdhci-4bit - ti,j7200-sdhci-8bit - ti,j721e-sdhci-4bit + - ti,am64-sdhci-8bit + - ti,am64-sdhci-4bit reg: maxItems: 2 -- cgit v1.2.3 From 7c7905df68c5ca5b3b20f41ef3f0d245ae6f32c3 Mon Sep 17 00:00:00 2001 From: Grygorii Strashko Date: Fri, 15 Jan 2021 21:32:18 +0200 Subject: dt-bindings: mmc: sdhci-am654: fix compatible for j7200 On TI J7200 SoC the SDHCI controller compatible defined as "ti,j7200-sdhci-8bit", "ti,j721e-sdhci-8bit" or "ti,j7200-sdhci-4bit", "ti,j721e-sdhci-4bit" which causes dtbs_check warnings: mmc@4f80000: compatible: ['ti,j7200-sdhci-8bit', 'ti,j721e-sdhci-8bit'] is too long mmc@4f80000: compatible: Additional items are not allowed ('ti,j721e-sdhci-8bit' was unexpected) mmc@4fb0000: compatible:0: 'ti,j7200-sdhci-4bit' is not one of ['ti,am654-sdhci-5.1', 'ti,j721e-sdhci-8bit', 'ti,j721e-sdhci-4bit', 'ti,j7200-sdhci-8bit', 'ti,j721e-sdhci-4bit', 'ti,am64-sdhci-8bit', 'ti,am64-sdhci-4bit'] mmc@4fb0000: compatible: ['ti,j7200-sdhci-4bit', 'ti,j721e-sdhci-4bit'] is too long mmc@4fb0000: compatible: Additional items are not allowed ('ti,j721e-sdhci-4bit' was unexpected) Fix it by adding missing compatible strings and their combinations. Fixes: 407d0c2cdd12 ("dt-bindings: mmc: sdhci-am654: Convert sdhci-am654 controller documentation to json schema") Signed-off-by: Grygorii Strashko Link: https://lore.kernel.org/r/20210115193218.5809-1-grygorii.strashko@ti.com Signed-off-by: Ulf Hansson --- .../devicetree/bindings/mmc/sdhci-am654.yaml | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/mmc/sdhci-am654.yaml b/Documentation/devicetree/bindings/mmc/sdhci-am654.yaml index 34e53db29428..3a79e39253d2 100644 --- a/Documentation/devicetree/bindings/mmc/sdhci-am654.yaml +++ b/Documentation/devicetree/bindings/mmc/sdhci-am654.yaml @@ -15,14 +15,19 @@ allOf: properties: compatible: - enum: - - ti,am654-sdhci-5.1 - - ti,j721e-sdhci-8bit - - ti,j721e-sdhci-4bit - - ti,j7200-sdhci-8bit - - ti,j721e-sdhci-4bit - - ti,am64-sdhci-8bit - - ti,am64-sdhci-4bit + oneOf: + - const: ti,am654-sdhci-5.1 + - const: ti,j721e-sdhci-8bit + - const: ti,j721e-sdhci-4bit + - const: ti,j721e-sdhci-4bit + - const: ti,am64-sdhci-8bit + - const: ti,am64-sdhci-4bit + - items: + - const: ti,j7200-sdhci-8bit + - const: ti,j721e-sdhci-8bit + - items: + - const: ti,j7200-sdhci-4bit + - const: ti,j721e-sdhci-4bit reg: maxItems: 2 -- cgit v1.2.3 From 1a9705936aff95fe2bf03684a586c0c83b71f71f Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Tue, 19 Jan 2021 11:06:55 +0100 Subject: mmc: mmci: Convert bindings to DT schema This converts the MMCI bindings from simple text to a proper schema. Cc: devicetree@vger.kernel.org Cc: Marek Vasut Signed-off-by: Linus Walleij Tested-by: Marek Vasut Link: https://lore.kernel.org/r/20210119100655.2755164-1-linus.walleij@linaro.org Signed-off-by: Ulf Hansson --- .../devicetree/bindings/mmc/arm,pl18x.yaml | 203 +++++++++++++++++++++ Documentation/devicetree/bindings/mmc/mmci.txt | 74 -------- 2 files changed, 203 insertions(+), 74 deletions(-) create mode 100644 Documentation/devicetree/bindings/mmc/arm,pl18x.yaml delete mode 100644 Documentation/devicetree/bindings/mmc/mmci.txt (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/mmc/arm,pl18x.yaml b/Documentation/devicetree/bindings/mmc/arm,pl18x.yaml new file mode 100644 index 000000000000..eddc1f6bdbe5 --- /dev/null +++ b/Documentation/devicetree/bindings/mmc/arm,pl18x.yaml @@ -0,0 +1,203 @@ +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/mmc/arm,pl18x.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: ARM PrimeCell MultiMedia Card Interface (MMCI) PL180 and PL181 + +maintainers: + - Linus Walleij + - Ulf Hansson + +description: + The ARM PrimeCells MMCI PL180 and PL181 provides an interface for + reading and writing to MultiMedia and SD cards alike. Over the years + vendors have use the VHDL code from ARM to create derivative MMC/SD/SDIO + host controllers with very similar characteristics. + +allOf: + - $ref: /schemas/arm/primecell.yaml# + - $ref: mmc-controller.yaml# + +# We need a select here so we don't match all nodes with 'arm,primecell' +select: + properties: + compatible: + contains: + enum: + - arm,pl180 + - arm,pl181 + - arm,pl18x + required: + - compatible + +properties: + compatible: + oneOf: + - description: The first version of the block, simply called + PL180 and found in the ARM Integrator IM/PD1 logic module. + items: + - const: arm,pl180 + - const: arm,primecell + - description: The improved version of the block, found in the + ARM Versatile and later reference designs. Further revisions + exist but get detected at runtime by reading some magic numbers + in the PrimeCell ID registers. + items: + - const: arm,pl181 + - const: arm,primecell + - description: Wildcard entry that will let the operating system + inspect the PrimeCell ID registers to determine which hardware + variant of PL180 or PL181 this is. + items: + - const: arm,pl18x + - const: arm,primecell + + clocks: + description: One or two clocks, the "apb_pclk" and the "MCLK" + which is the core block clock. The names are not compulsory. + minItems: 1 + maxItems: 2 + + power-domains: true + + resets: + maxItems: 1 + + reg: + description: the MMIO memory window must be exactly 4KB (0x1000) and the + layout should provide the PrimeCell ID registers so that the device can + be discovered. On ST Micro variants, a second register window may be + defined if a delay block is present and used for tuning. + + interrupts: + description: The first interrupt is the command interrupt and corresponds + to the event at the end of a command. The second interrupt is the + PIO (polled I/O) interrupt and occurs when the FIFO needs to be + emptied as part of a bulk read from the card. Some variants have these + two interrupts wired into the same line (logic OR) and in that case + only one interrupt may be provided. + minItems: 1 + maxItems: 2 + + st,sig-dir-dat0: + $ref: /schemas/types.yaml#/definitions/flag + description: ST Micro-specific property, bus signal direction pins used for + DAT[0]. + + st,sig-dir-dat2: + $ref: /schemas/types.yaml#/definitions/flag + description: ST Micro-specific property, bus signal direction pins used for + DAT[2]. + + st,sig-dir-dat31: + $ref: /schemas/types.yaml#/definitions/flag + description: ST Micro-specific property, bus signal direction pins used for + DAT[3] and DAT[1]. + + st,sig-dir-dat74: + $ref: /schemas/types.yaml#/definitions/flag + description: ST Micro-specific property, bus signal direction pins used for + DAT[7] and DAT[4]. + + st,sig-dir-cmd: + $ref: /schemas/types.yaml#/definitions/flag + description: ST Micro-specific property, CMD signal direction used for + pin CMD. + + st,sig-pin-fbclk: + $ref: /schemas/types.yaml#/definitions/flag + description: ST Micro-specific property, feedback clock FBCLK signal pin + in use. + + st,sig-dir: + $ref: /schemas/types.yaml#/definitions/flag + description: ST Micro-specific property, signal direction polarity used for + pins CMD, DAT[0], DAT[1], DAT[2] and DAT[3]. + + st,neg-edge: + $ref: /schemas/types.yaml#/definitions/flag + description: ST Micro-specific property, data and command phase relation, + generated on the sd clock falling edge. + + st,use-ckin: + $ref: /schemas/types.yaml#/definitions/flag + description: ST Micro-specific property, use CKIN pin from an external + driver to sample the receive data (for example with a voltage switch + transceiver). + +unevaluatedProperties: false + +required: + - compatible + - reg + - interrupts + +examples: + - | + #include + #include + + mmc@5000 { + compatible = "arm,pl180", "arm,primecell"; + reg = <0x5000 0x1000>; + interrupts-extended = <&vic 22 &sic 1>; + clocks = <&xtal24mhz>, <&pclk>; + clock-names = "mclk", "apb_pclk"; + }; + + mmc@80126000 { + compatible = "arm,pl18x", "arm,primecell"; + reg = <0x80126000 0x1000>; + interrupts = <0 60 IRQ_TYPE_LEVEL_HIGH>; + dmas = <&dma 29 0 0x2>, <&dma 29 0 0x0>; + dma-names = "rx", "tx"; + clocks = <&prcc_kclk 1 5>, <&prcc_pclk 1 5>; + clock-names = "sdi", "apb_pclk"; + max-frequency = <100000000>; + bus-width = <4>; + cap-sd-highspeed; + cap-mmc-highspeed; + cd-gpios = <&gpio2 31 0x4>; + st,sig-dir-dat0; + st,sig-dir-dat2; + st,sig-dir-cmd; + st,sig-pin-fbclk; + vmmc-supply = <&ab8500_ldo_aux3_reg>; + vqmmc-supply = <&vmmci>; + }; + + mmc@101f6000 { + compatible = "arm,pl18x", "arm,primecell"; + reg = <0x101f6000 0x1000>; + clocks = <&sdiclk>, <&pclksdi>; + clock-names = "mclk", "apb_pclk"; + interrupt-parent = <&vica>; + interrupts = <22>; + max-frequency = <400000>; + bus-width = <4>; + cap-mmc-highspeed; + cap-sd-highspeed; + full-pwr-cycle; + st,sig-dir-dat0; + st,sig-dir-dat2; + st,sig-dir-dat31; + st,sig-dir-cmd; + st,sig-pin-fbclk; + vmmc-supply = <&vmmc_regulator>; + }; + + mmc@52007000 { + compatible = "arm,pl18x", "arm,primecell"; + arm,primecell-periphid = <0x10153180>; + reg = <0x52007000 0x1000>; + interrupts = <49>; + interrupt-names = "cmd_irq"; + clocks = <&rcc 0>; + clock-names = "apb_pclk"; + resets = <&rcc 1>; + cap-sd-highspeed; + cap-mmc-highspeed; + max-frequency = <120000000>; + }; diff --git a/Documentation/devicetree/bindings/mmc/mmci.txt b/Documentation/devicetree/bindings/mmc/mmci.txt deleted file mode 100644 index 4ec921e4bf34..000000000000 --- a/Documentation/devicetree/bindings/mmc/mmci.txt +++ /dev/null @@ -1,74 +0,0 @@ -* ARM PrimeCell MultiMedia Card Interface (MMCI) PL180/1 - -The ARM PrimeCell MMCI PL180 and PL181 provides an interface for -reading and writing to MultiMedia and SD cards alike. - -This file documents differences between the core properties described -by mmc.txt and the properties used by the mmci driver. Using "st" as -the prefix for a property, indicates support by the ST Micro variant. - -Required properties: -- compatible : contains "arm,pl18x", "arm,primecell". -- vmmc-supply : phandle to the regulator device tree node, mentioned - as the VCC/VDD supply in the eMMC/SD specs. - -Optional properties: -- arm,primecell-periphid : contains the PrimeCell Peripheral ID, it overrides - the ID provided by the HW -- resets : phandle to internal reset line. - Should be defined for sdmmc variant. -- vqmmc-supply : phandle to the regulator device tree node, mentioned - as the VCCQ/VDD_IO supply in the eMMC/SD specs. -specific for ux500 variant: -- st,sig-dir-dat0 : bus signal direction pin used for DAT[0]. -- st,sig-dir-dat2 : bus signal direction pin used for DAT[2]. -- st,sig-dir-dat31 : bus signal direction pin used for DAT[3] and DAT[1]. -- st,sig-dir-dat74 : bus signal direction pin used for DAT[4] to DAT[7]. -- st,sig-dir-cmd : cmd signal direction pin used for CMD. -- st,sig-pin-fbclk : feedback clock signal pin used. - -specific for sdmmc variant: -- reg : a second base register may be defined if a delay - block is present and used for tuning. -- st,sig-dir : signal direction polarity used for cmd, dat0 dat123. -- st,neg-edge : data & command phase relation, generated on - sd clock falling edge. -- st,use-ckin : use ckin pin from an external driver to sample - the receive data (example: with voltage - switch transceiver). - -Deprecated properties: -- mmc-cap-mmc-highspeed : indicates whether MMC is high speed capable. -- mmc-cap-sd-highspeed : indicates whether SD is high speed capable. - -Example: - -sdi0_per1@80126000 { - compatible = "arm,pl18x", "arm,primecell"; - reg = <0x80126000 0x1000>; - interrupts = <0 60 IRQ_TYPE_LEVEL_HIGH>; - - dmas = <&dma 29 0 0x2>, /* Logical - DevToMem */ - <&dma 29 0 0x0>; /* Logical - MemToDev */ - dma-names = "rx", "tx"; - - clocks = <&prcc_kclk 1 5>, <&prcc_pclk 1 5>; - clock-names = "sdi", "apb_pclk"; - - max-frequency = <100000000>; - bus-width = <4>; - cap-sd-highspeed; - cap-mmc-highspeed; - cd-gpios = <&gpio2 31 0x4>; // 95 - st,sig-dir-dat0; - st,sig-dir-dat2; - st,sig-dir-cmd; - st,sig-pin-fbclk; - - vmmc-supply = <&ab8500_ldo_aux3_reg>; - vqmmc-supply = <&vmmci>; - - pinctrl-names = "default", "sleep"; - pinctrl-0 = <&sdi0_default_mode>; - pinctrl-1 = <&sdi0_sleep_mode>; -}; -- cgit v1.2.3 From e55f2cf512591dc0051a32e14b8866668d02706a Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Wed, 20 Jan 2021 15:28:00 +0100 Subject: mmc: remove dw_mmc-zx driver The zte zx platform is getting removed, so this driver is no longer needed. Cc: Jun Nie Cc: Shawn Guo Signed-off-by: Arnd Bergmann Link: https://lore.kernel.org/r/20210120142801.334550-2-arnd@kernel.org Signed-off-by: Ulf Hansson --- .../devicetree/bindings/mmc/zx-dw-mshc.txt | 31 --- drivers/mmc/host/Kconfig | 9 - drivers/mmc/host/Makefile | 1 - drivers/mmc/host/dw_mmc-zx.c | 234 --------------------- drivers/mmc/host/dw_mmc-zx.h | 32 --- 5 files changed, 307 deletions(-) delete mode 100644 Documentation/devicetree/bindings/mmc/zx-dw-mshc.txt delete mode 100644 drivers/mmc/host/dw_mmc-zx.c delete mode 100644 drivers/mmc/host/dw_mmc-zx.h (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/mmc/zx-dw-mshc.txt b/Documentation/devicetree/bindings/mmc/zx-dw-mshc.txt deleted file mode 100644 index 0f59bd5361f5..000000000000 --- a/Documentation/devicetree/bindings/mmc/zx-dw-mshc.txt +++ /dev/null @@ -1,31 +0,0 @@ -* ZTE specific extensions to the Synopsys Designware Mobile Storage - Host Controller - -The Synopsys designware mobile storage host controller is used to interface -a SoC with storage medium such as eMMC or SD/MMC cards. This file documents -differences between the core Synopsys dw mshc controller properties described -by synopsys-dw-mshc.txt and the properties used by the ZTE specific -extensions to the Synopsys Designware Mobile Storage Host Controller. - -Required Properties: - -* compatible: should be - - "zte,zx296718-dw-mshc": for ZX SoCs - -Example: - - mmc1: mmc@1110000 { - compatible = "zte,zx296718-dw-mshc"; - reg = <0x01110000 0x1000>; - interrupts = ; - fifo-depth = <32>; - data-addr = <0x200>; - fifo-watermark-aligned; - bus-width = <4>; - clock-frequency = <50000000>; - clocks = <&topcrm SD0_AHB>, <&topcrm SD0_WCLK>; - clock-names = "biu", "ciu"; - max-frequency = <50000000>; - cap-sdio-irq; - cap-sd-highspeed; - }; diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig index d6f00d1d6251..1c87ffe9192d 100644 --- a/drivers/mmc/host/Kconfig +++ b/drivers/mmc/host/Kconfig @@ -882,15 +882,6 @@ config MMC_DW_ROCKCHIP Synopsys DesignWare Memory Card Interface driver. Select this option for platforms based on RK3066, RK3188 and RK3288 SoC's. -config MMC_DW_ZX - tristate "ZTE specific extensions for Synopsys DW Memory Card Interface" - depends on MMC_DW && ARCH_ZX - select MMC_DW_PLTFM - help - This selects support for ZTE SoC specific extensions to the - Synopsys DesignWare Memory Card Interface driver. Select this option - for platforms based on ZX296718 SoC's. - config MMC_SH_MMCIF tristate "SuperH Internal MMCIF support" depends on SUPERH || ARCH_RENESAS || COMPILE_TEST diff --git a/drivers/mmc/host/Makefile b/drivers/mmc/host/Makefile index 451c25fc2c69..43136d382d5f 100644 --- a/drivers/mmc/host/Makefile +++ b/drivers/mmc/host/Makefile @@ -61,7 +61,6 @@ obj-$(CONFIG_MMC_DW_HI3798CV200) += dw_mmc-hi3798cv200.o obj-$(CONFIG_MMC_DW_K3) += dw_mmc-k3.o obj-$(CONFIG_MMC_DW_PCI) += dw_mmc-pci.o obj-$(CONFIG_MMC_DW_ROCKCHIP) += dw_mmc-rockchip.o -obj-$(CONFIG_MMC_DW_ZX) += dw_mmc-zx.o obj-$(CONFIG_MMC_SH_MMCIF) += sh_mmcif.o obj-$(CONFIG_MMC_JZ4740) += jz4740_mmc.o obj-$(CONFIG_MMC_VUB300) += vub300.o diff --git a/drivers/mmc/host/dw_mmc-zx.c b/drivers/mmc/host/dw_mmc-zx.c deleted file mode 100644 index 51bcc6332f3a..000000000000 --- a/drivers/mmc/host/dw_mmc-zx.c +++ /dev/null @@ -1,234 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * ZX Specific Extensions for Synopsys DW Multimedia Card Interface driver - * - * Copyright (C) 2016, Linaro Ltd. - * Copyright (C) 2016, ZTE Corp. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "dw_mmc.h" -#include "dw_mmc-pltfm.h" -#include "dw_mmc-zx.h" - -struct dw_mci_zx_priv_data { - struct regmap *sysc_base; -}; - -enum delay_type { - DELAY_TYPE_READ, /* read dqs delay */ - DELAY_TYPE_CLK, /* clk sample delay */ -}; - -static int dw_mci_zx_emmc_set_delay(struct dw_mci *host, unsigned int delay, - enum delay_type dflag) -{ - struct dw_mci_zx_priv_data *priv = host->priv; - struct regmap *sysc_base = priv->sysc_base; - unsigned int clksel; - unsigned int loop = 1000; - int ret; - - if (!sysc_base) - return -EINVAL; - - ret = regmap_update_bits(sysc_base, LB_AON_EMMC_CFG_REG0, - PARA_HALF_CLK_MODE | PARA_DLL_BYPASS_MODE | - PARA_PHASE_DET_SEL_MASK | - PARA_DLL_LOCK_NUM_MASK | - DLL_REG_SET | PARA_DLL_START_MASK, - PARA_DLL_START(4) | PARA_DLL_LOCK_NUM(4)); - if (ret) - return ret; - - ret = regmap_read(sysc_base, LB_AON_EMMC_CFG_REG1, &clksel); - if (ret) - return ret; - - if (dflag == DELAY_TYPE_CLK) { - clksel &= ~CLK_SAMP_DELAY_MASK; - clksel |= CLK_SAMP_DELAY(delay); - } else { - clksel &= ~READ_DQS_DELAY_MASK; - clksel |= READ_DQS_DELAY(delay); - } - - regmap_write(sysc_base, LB_AON_EMMC_CFG_REG1, clksel); - regmap_update_bits(sysc_base, LB_AON_EMMC_CFG_REG0, - PARA_DLL_START_MASK | PARA_DLL_LOCK_NUM_MASK | - DLL_REG_SET, - PARA_DLL_START(4) | PARA_DLL_LOCK_NUM(4) | - DLL_REG_SET); - - do { - ret = regmap_read(sysc_base, LB_AON_EMMC_CFG_REG2, &clksel); - if (ret) - return ret; - - } while (--loop && !(clksel & ZX_DLL_LOCKED)); - - if (!loop) { - dev_err(host->dev, "Error: %s dll lock fail\n", __func__); - return -EIO; - } - - return 0; -} - -static int dw_mci_zx_emmc_execute_tuning(struct dw_mci_slot *slot, u32 opcode) -{ - struct dw_mci *host = slot->host; - struct mmc_host *mmc = slot->mmc; - int ret, len = 0, start = 0, end = 0, delay, best = 0; - - for (delay = 1; delay < 128; delay++) { - ret = dw_mci_zx_emmc_set_delay(host, delay, DELAY_TYPE_CLK); - if (!ret && mmc_send_tuning(mmc, opcode, NULL)) { - if (start >= 0) { - end = delay - 1; - /* check and update longest good range */ - if ((end - start) > len) { - best = (start + end) >> 1; - len = end - start; - } - } - start = -1; - end = 0; - continue; - } - if (start < 0) - start = delay; - } - - if (start >= 0) { - end = delay - 1; - if ((end - start) > len) { - best = (start + end) >> 1; - len = end - start; - } - } - if (best < 0) - return -EIO; - - dev_info(host->dev, "%s best range: start %d end %d\n", __func__, - start, end); - return dw_mci_zx_emmc_set_delay(host, best, DELAY_TYPE_CLK); -} - -static int dw_mci_zx_prepare_hs400_tuning(struct dw_mci *host, - struct mmc_ios *ios) -{ - int ret; - - /* config phase shift as 90 degree */ - ret = dw_mci_zx_emmc_set_delay(host, 32, DELAY_TYPE_READ); - if (ret < 0) - return -EIO; - - return 0; -} - -static int dw_mci_zx_execute_tuning(struct dw_mci_slot *slot, u32 opcode) -{ - struct dw_mci *host = slot->host; - - if (host->verid == 0x290a) /* only for emmc */ - return dw_mci_zx_emmc_execute_tuning(slot, opcode); - /* TODO: Add 0x210a dedicated tuning for sd/sdio */ - - return 0; -} - -static int dw_mci_zx_parse_dt(struct dw_mci *host) -{ - struct device_node *np = host->dev->of_node; - struct device_node *node; - struct dw_mci_zx_priv_data *priv; - struct regmap *sysc_base; - - /* syscon is needed only by emmc */ - node = of_parse_phandle(np, "zte,aon-syscon", 0); - if (node) { - sysc_base = syscon_node_to_regmap(node); - of_node_put(node); - - if (IS_ERR(sysc_base)) - return dev_err_probe(host->dev, PTR_ERR(sysc_base), - "Can't get syscon\n"); - } else { - return 0; - } - - priv = devm_kzalloc(host->dev, sizeof(*priv), GFP_KERNEL); - if (!priv) - return -ENOMEM; - priv->sysc_base = sysc_base; - host->priv = priv; - - return 0; -} - -static unsigned long zx_dwmmc_caps[3] = { - MMC_CAP_CMD23, - MMC_CAP_CMD23, - MMC_CAP_CMD23, -}; - -static const struct dw_mci_drv_data zx_drv_data = { - .caps = zx_dwmmc_caps, - .num_caps = ARRAY_SIZE(zx_dwmmc_caps), - .execute_tuning = dw_mci_zx_execute_tuning, - .prepare_hs400_tuning = dw_mci_zx_prepare_hs400_tuning, - .parse_dt = dw_mci_zx_parse_dt, -}; - -static const struct of_device_id dw_mci_zx_match[] = { - { .compatible = "zte,zx296718-dw-mshc", .data = &zx_drv_data}, - {}, -}; -MODULE_DEVICE_TABLE(of, dw_mci_zx_match); - -static int dw_mci_zx_probe(struct platform_device *pdev) -{ - const struct dw_mci_drv_data *drv_data; - const struct of_device_id *match; - - match = of_match_node(dw_mci_zx_match, pdev->dev.of_node); - drv_data = match->data; - - return dw_mci_pltfm_register(pdev, drv_data); -} - -static const struct dev_pm_ops dw_mci_zx_dev_pm_ops = { - SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, - pm_runtime_force_resume) - SET_RUNTIME_PM_OPS(dw_mci_runtime_suspend, - dw_mci_runtime_resume, - NULL) -}; - -static struct platform_driver dw_mci_zx_pltfm_driver = { - .probe = dw_mci_zx_probe, - .remove = dw_mci_pltfm_remove, - .driver = { - .name = "dwmmc_zx", - .probe_type = PROBE_PREFER_ASYNCHRONOUS, - .of_match_table = dw_mci_zx_match, - .pm = &dw_mci_zx_dev_pm_ops, - }, -}; - -module_platform_driver(dw_mci_zx_pltfm_driver); - -MODULE_DESCRIPTION("ZTE emmc/sd driver"); -MODULE_LICENSE("GPL v2"); diff --git a/drivers/mmc/host/dw_mmc-zx.h b/drivers/mmc/host/dw_mmc-zx.h deleted file mode 100644 index 09ac52766f14..000000000000 --- a/drivers/mmc/host/dw_mmc-zx.h +++ /dev/null @@ -1,32 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -#ifndef _DW_MMC_ZX_H_ -#define _DW_MMC_ZX_H_ - -/* ZX296718 SoC specific DLL register offset. */ -#define LB_AON_EMMC_CFG_REG0 0x1B0 -#define LB_AON_EMMC_CFG_REG1 0x1B4 -#define LB_AON_EMMC_CFG_REG2 0x1B8 - -/* LB_AON_EMMC_CFG_REG0 register defines */ -#define PARA_DLL_START(x) ((x) & 0xFF) -#define PARA_DLL_START_MASK 0xFF -#define DLL_REG_SET BIT(8) -#define PARA_DLL_LOCK_NUM(x) (((x) & 7) << 16) -#define PARA_DLL_LOCK_NUM_MASK (7 << 16) -#define PARA_PHASE_DET_SEL(x) (((x) & 7) << 20) -#define PARA_PHASE_DET_SEL_MASK (7 << 20) -#define PARA_DLL_BYPASS_MODE BIT(23) -#define PARA_HALF_CLK_MODE BIT(24) - -/* LB_AON_EMMC_CFG_REG1 register defines */ -#define READ_DQS_DELAY(x) ((x) & 0x7F) -#define READ_DQS_DELAY_MASK (0x7F) -#define READ_DQS_BYPASS_MODE BIT(7) -#define CLK_SAMP_DELAY(x) (((x) & 0x7F) << 8) -#define CLK_SAMP_DELAY_MASK (0x7F << 8) -#define CLK_SAMP_BYPASS_MODE BIT(15) - -/* LB_AON_EMMC_CFG_REG2 register defines */ -#define ZX_DLL_LOCKED BIT(2) - -#endif /* _DW_MMC_ZX_H_ */ -- cgit v1.2.3 From c7b9f01fd12a46333c917f416b0df6ee39e7c774 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Wed, 20 Jan 2021 15:28:01 +0100 Subject: mmc: remove sirf prima/atlas driver The CSR SiRF prima2/atlas platforms are getting removed, so this driver is no longer needed. Cc: Barry Song Signed-off-by: Arnd Bergmann Acked-by: Barry Song Link: https://lore.kernel.org/r/20210120142801.334550-3-arnd@kernel.org Signed-off-by: Ulf Hansson --- .../devicetree/bindings/mmc/sdhci-sirf.txt | 18 -- drivers/mmc/host/Kconfig | 12 -- drivers/mmc/host/Makefile | 1 - drivers/mmc/host/sdhci-sirf.c | 235 --------------------- 4 files changed, 266 deletions(-) delete mode 100644 Documentation/devicetree/bindings/mmc/sdhci-sirf.txt delete mode 100644 drivers/mmc/host/sdhci-sirf.c (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/mmc/sdhci-sirf.txt b/Documentation/devicetree/bindings/mmc/sdhci-sirf.txt deleted file mode 100644 index dd6ed464bcb8..000000000000 --- a/Documentation/devicetree/bindings/mmc/sdhci-sirf.txt +++ /dev/null @@ -1,18 +0,0 @@ -* SiRFprimII/marco/atlas6 SDHCI Controller - -This file documents differences between the core properties in mmc.txt -and the properties used by the sdhci-sirf driver. - -Required properties: -- compatible: sirf,prima2-sdhc - -Optional properties: -- cd-gpios: card detect gpio, with zero flags. - -Example: - - sd0: sdhci@56000000 { - compatible = "sirf,prima2-sdhc"; - reg = <0xcd000000 0x100000>; - cd-gpios = <&gpio 6 0>; - }; diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig index 1c87ffe9192d..bbf6989e3638 100644 --- a/drivers/mmc/host/Kconfig +++ b/drivers/mmc/host/Kconfig @@ -326,18 +326,6 @@ config MMC_SDHCI_S3C If unsure, say N. -config MMC_SDHCI_SIRF - tristate "SDHCI support on CSR SiRFprimaII and SiRFmarco SoCs" - depends on ARCH_SIRF || COMPILE_TEST - depends on MMC_SDHCI_PLTFM - select MMC_SDHCI_IO_ACCESSORS - help - This selects the SDHCI support for SiRF System-on-Chip devices. - - If you have a controller with this interface, say Y or M here. - - If unsure, say N. - config MMC_SDHCI_PXAV3 tristate "Marvell MMP2 SD Host Controller support (PXAV3)" depends on CLKDEV_LOOKUP diff --git a/drivers/mmc/host/Makefile b/drivers/mmc/host/Makefile index 43136d382d5f..d2ec428cc808 100644 --- a/drivers/mmc/host/Makefile +++ b/drivers/mmc/host/Makefile @@ -19,7 +19,6 @@ obj-$(CONFIG_MMC_SDHCI_ACPI) += sdhci-acpi.o obj-$(CONFIG_MMC_SDHCI_PXAV3) += sdhci-pxav3.o obj-$(CONFIG_MMC_SDHCI_PXAV2) += sdhci-pxav2.o obj-$(CONFIG_MMC_SDHCI_S3C) += sdhci-s3c.o -obj-$(CONFIG_MMC_SDHCI_SIRF) += sdhci-sirf.o obj-$(CONFIG_MMC_SDHCI_F_SDH30) += sdhci_f_sdh30.o obj-$(CONFIG_MMC_SDHCI_MILBEAUT) += sdhci-milbeaut.o obj-$(CONFIG_MMC_SDHCI_SPEAR) += sdhci-spear.o diff --git a/drivers/mmc/host/sdhci-sirf.c b/drivers/mmc/host/sdhci-sirf.c deleted file mode 100644 index e9b347b3af7e..000000000000 --- a/drivers/mmc/host/sdhci-sirf.c +++ /dev/null @@ -1,235 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * SDHCI support for SiRF primaII and marco SoCs - * - * Copyright (c) 2011 Cambridge Silicon Radio Limited, a CSR plc group company. - */ - -#include -#include -#include -#include -#include -#include -#include "sdhci-pltfm.h" - -#define SDHCI_CLK_DELAY_SETTING 0x4C -#define SDHCI_SIRF_8BITBUS BIT(3) -#define SIRF_TUNING_COUNT 16384 - -static void sdhci_sirf_set_bus_width(struct sdhci_host *host, int width) -{ - u8 ctrl; - - ctrl = sdhci_readb(host, SDHCI_HOST_CONTROL); - ctrl &= ~(SDHCI_CTRL_4BITBUS | SDHCI_SIRF_8BITBUS); - - /* - * CSR atlas7 and prima2 SD host version is not 3.0 - * 8bit-width enable bit of CSR SD hosts is 3, - * while stardard hosts use bit 5 - */ - if (width == MMC_BUS_WIDTH_8) - ctrl |= SDHCI_SIRF_8BITBUS; - else if (width == MMC_BUS_WIDTH_4) - ctrl |= SDHCI_CTRL_4BITBUS; - - sdhci_writeb(host, ctrl, SDHCI_HOST_CONTROL); -} - -static u32 sdhci_sirf_readl_le(struct sdhci_host *host, int reg) -{ - u32 val = readl(host->ioaddr + reg); - - if (unlikely((reg == SDHCI_CAPABILITIES_1) && - (host->mmc->caps & MMC_CAP_UHS_SDR50))) { - /* fake CAP_1 register */ - val = SDHCI_SUPPORT_DDR50 | - SDHCI_SUPPORT_SDR50 | SDHCI_USE_SDR50_TUNING; - } - - if (unlikely(reg == SDHCI_SLOT_INT_STATUS)) { - u32 prss = val; - /* fake chips as V3.0 host conreoller */ - prss &= ~(0xFF << 16); - val = prss | (SDHCI_SPEC_300 << 16); - } - return val; -} - -static u16 sdhci_sirf_readw_le(struct sdhci_host *host, int reg) -{ - u16 ret = 0; - - ret = readw(host->ioaddr + reg); - - if (unlikely(reg == SDHCI_HOST_VERSION)) { - ret = readw(host->ioaddr + SDHCI_HOST_VERSION); - ret |= SDHCI_SPEC_300; - } - - return ret; -} - -static int sdhci_sirf_execute_tuning(struct sdhci_host *host, u32 opcode) -{ - int tuning_seq_cnt = 3; - int phase; - u8 tuned_phase_cnt = 0; - int rc = 0, longest_range = 0; - int start = -1, end = 0, tuning_value = -1, range = 0; - u16 clock_setting; - struct mmc_host *mmc = host->mmc; - - clock_setting = sdhci_readw(host, SDHCI_CLK_DELAY_SETTING); - clock_setting &= ~0x3fff; - -retry: - phase = 0; - tuned_phase_cnt = 0; - do { - sdhci_writel(host, - clock_setting | phase, - SDHCI_CLK_DELAY_SETTING); - - if (!mmc_send_tuning(mmc, opcode, NULL)) { - /* Tuning is successful at this tuning point */ - tuned_phase_cnt++; - dev_dbg(mmc_dev(mmc), "%s: Found good phase = %d\n", - mmc_hostname(mmc), phase); - if (start == -1) - start = phase; - end = phase; - range++; - if (phase == (SIRF_TUNING_COUNT - 1) - && range > longest_range) - tuning_value = (start + end) / 2; - } else { - dev_dbg(mmc_dev(mmc), "%s: Found bad phase = %d\n", - mmc_hostname(mmc), phase); - if (range > longest_range) { - tuning_value = (start + end) / 2; - longest_range = range; - } - start = -1; - end = range = 0; - } - } while (++phase < SIRF_TUNING_COUNT); - - if (tuned_phase_cnt && tuning_value > 0) { - /* - * Finally set the selected phase in delay - * line hw block. - */ - phase = tuning_value; - sdhci_writel(host, - clock_setting | phase, - SDHCI_CLK_DELAY_SETTING); - - dev_dbg(mmc_dev(mmc), "%s: Setting the tuning phase to %d\n", - mmc_hostname(mmc), phase); - } else { - if (--tuning_seq_cnt) - goto retry; - /* Tuning failed */ - dev_dbg(mmc_dev(mmc), "%s: No tuning point found\n", - mmc_hostname(mmc)); - rc = -EIO; - } - - return rc; -} - -static const struct sdhci_ops sdhci_sirf_ops = { - .read_l = sdhci_sirf_readl_le, - .read_w = sdhci_sirf_readw_le, - .platform_execute_tuning = sdhci_sirf_execute_tuning, - .set_clock = sdhci_set_clock, - .get_max_clock = sdhci_pltfm_clk_get_max_clock, - .set_bus_width = sdhci_sirf_set_bus_width, - .reset = sdhci_reset, - .set_uhs_signaling = sdhci_set_uhs_signaling, -}; - -static const struct sdhci_pltfm_data sdhci_sirf_pdata = { - .ops = &sdhci_sirf_ops, - .quirks = SDHCI_QUIRK_BROKEN_TIMEOUT_VAL | - SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK | - SDHCI_QUIRK_CAP_CLOCK_BASE_BROKEN | - SDHCI_QUIRK_RESET_CMD_DATA_ON_IOS, - .quirks2 = SDHCI_QUIRK2_PRESET_VALUE_BROKEN, -}; - -static int sdhci_sirf_probe(struct platform_device *pdev) -{ - struct sdhci_host *host; - struct sdhci_pltfm_host *pltfm_host; - struct clk *clk; - int ret; - - clk = devm_clk_get(&pdev->dev, NULL); - if (IS_ERR(clk)) { - dev_err(&pdev->dev, "unable to get clock"); - return PTR_ERR(clk); - } - - host = sdhci_pltfm_init(pdev, &sdhci_sirf_pdata, 0); - if (IS_ERR(host)) - return PTR_ERR(host); - - pltfm_host = sdhci_priv(host); - pltfm_host->clk = clk; - - sdhci_get_of_property(pdev); - - ret = clk_prepare_enable(pltfm_host->clk); - if (ret) - goto err_clk_prepare; - - ret = sdhci_add_host(host); - if (ret) - goto err_sdhci_add; - - /* - * We must request the IRQ after sdhci_add_host(), as the tasklet only - * gets setup in sdhci_add_host() and we oops. - */ - ret = mmc_gpiod_request_cd(host->mmc, "cd", 0, false, 0); - if (ret == -EPROBE_DEFER) - goto err_request_cd; - if (!ret) - mmc_gpiod_request_cd_irq(host->mmc); - - return 0; - -err_request_cd: - sdhci_remove_host(host, 0); -err_sdhci_add: - clk_disable_unprepare(pltfm_host->clk); -err_clk_prepare: - sdhci_pltfm_free(pdev); - return ret; -} - -static const struct of_device_id sdhci_sirf_of_match[] = { - { .compatible = "sirf,prima2-sdhc" }, - { } -}; -MODULE_DEVICE_TABLE(of, sdhci_sirf_of_match); - -static struct platform_driver sdhci_sirf_driver = { - .driver = { - .name = "sdhci-sirf", - .probe_type = PROBE_PREFER_ASYNCHRONOUS, - .of_match_table = sdhci_sirf_of_match, - .pm = &sdhci_pltfm_pmops, - }, - .probe = sdhci_sirf_probe, - .remove = sdhci_pltfm_unregister, -}; - -module_platform_driver(sdhci_sirf_driver); - -MODULE_DESCRIPTION("SDHCI driver for SiRFprimaII/SiRFmarco"); -MODULE_AUTHOR("Barry Song <21cnbao@gmail.com>"); -MODULE_LICENSE("GPL v2"); -- cgit v1.2.3 From 5851d3b042b694839d2241fbb3200ce958135cdf Mon Sep 17 00:00:00 2001 From: Eric Biggers Date: Thu, 21 Jan 2021 00:21:54 -0800 Subject: block/keyslot-manager: introduce devm_blk_ksm_init() Add a resource-managed variant of blk_ksm_init() so that drivers don't have to worry about calling blk_ksm_destroy(). Note that the implementation uses a custom devres action to call blk_ksm_destroy() rather than switching the two allocations to be directly devres-managed, e.g. with devm_kmalloc(). This is because we need to keep zeroing the memory containing the keyslots when it is freed, and also because we want to continue using kvmalloc() (and there is no devm_kvmalloc()). Signed-off-by: Eric Biggers Reviewed-by: Satya Tangirala Acked-by: Jens Axboe Link: https://lore.kernel.org/r/20210121082155.111333-2-ebiggers@kernel.org Signed-off-by: Ulf Hansson --- Documentation/block/inline-encryption.rst | 12 ++++++------ block/keyslot-manager.c | 29 +++++++++++++++++++++++++++++ include/linux/keyslot-manager.h | 3 +++ 3 files changed, 38 insertions(+), 6 deletions(-) (limited to 'Documentation') diff --git a/Documentation/block/inline-encryption.rst b/Documentation/block/inline-encryption.rst index e75151e467d3..7f9b40d6b416 100644 --- a/Documentation/block/inline-encryption.rst +++ b/Documentation/block/inline-encryption.rst @@ -182,8 +182,9 @@ API presented to device drivers A :c:type:``struct blk_keyslot_manager`` should be set up by device drivers in the ``request_queue`` of the device. The device driver needs to call -``blk_ksm_init`` on the ``blk_keyslot_manager``, which specifying the number of -keyslots supported by the hardware. +``blk_ksm_init`` (or its resource-managed variant ``devm_blk_ksm_init``) on the +``blk_keyslot_manager``, while specifying the number of keyslots supported by +the hardware. The device driver also needs to tell the KSM how to actually manipulate the IE hardware in the device to do things like programming the crypto key into @@ -202,10 +203,9 @@ needs each and every of its keyslots to be reprogrammed with the key it "should have" at the point in time when the function is called. This is useful e.g. if a device loses all its keys on runtime power down/up. -``blk_ksm_destroy`` should be called to free up all resources used by a keyslot -manager upon ``blk_ksm_init``, once the ``blk_keyslot_manager`` is no longer -needed. - +If the driver used ``blk_ksm_init`` instead of ``devm_blk_ksm_init``, then +``blk_ksm_destroy`` should be called to free up all resources used by a +``blk_keyslot_manager`` once it is no longer needed. Layered Devices =============== diff --git a/block/keyslot-manager.c b/block/keyslot-manager.c index 86f8195d8039..324bf4244f5f 100644 --- a/block/keyslot-manager.c +++ b/block/keyslot-manager.c @@ -29,6 +29,7 @@ #define pr_fmt(fmt) "blk-crypto: " fmt #include +#include #include #include #include @@ -127,6 +128,34 @@ err_destroy_ksm: } EXPORT_SYMBOL_GPL(blk_ksm_init); +static void blk_ksm_destroy_callback(void *ksm) +{ + blk_ksm_destroy(ksm); +} + +/** + * devm_blk_ksm_init() - Resource-managed blk_ksm_init() + * @dev: The device which owns the blk_keyslot_manager. + * @ksm: The blk_keyslot_manager to initialize. + * @num_slots: The number of key slots to manage. + * + * Like blk_ksm_init(), but causes blk_ksm_destroy() to be called automatically + * on driver detach. + * + * Return: 0 on success, or else a negative error code. + */ +int devm_blk_ksm_init(struct device *dev, struct blk_keyslot_manager *ksm, + unsigned int num_slots) +{ + int err = blk_ksm_init(ksm, num_slots); + + if (err) + return err; + + return devm_add_action_or_reset(dev, blk_ksm_destroy_callback, ksm); +} +EXPORT_SYMBOL_GPL(devm_blk_ksm_init); + static inline struct hlist_head * blk_ksm_hash_bucket_for_key(struct blk_keyslot_manager *ksm, const struct blk_crypto_key *key) diff --git a/include/linux/keyslot-manager.h b/include/linux/keyslot-manager.h index 18f3f5346843..443ad817c6c5 100644 --- a/include/linux/keyslot-manager.h +++ b/include/linux/keyslot-manager.h @@ -85,6 +85,9 @@ struct blk_keyslot_manager { int blk_ksm_init(struct blk_keyslot_manager *ksm, unsigned int num_slots); +int devm_blk_ksm_init(struct device *dev, struct blk_keyslot_manager *ksm, + unsigned int num_slots); + blk_status_t blk_ksm_get_slot_for_key(struct blk_keyslot_manager *ksm, const struct blk_crypto_key *key, struct blk_ksm_keyslot **slot_ptr); -- cgit v1.2.3 From 5cc046eb134f680f3ab6e2bb4ff43b94683336eb Mon Sep 17 00:00:00 2001 From: Eric Biggers Date: Mon, 25 Jan 2021 16:14:54 -0800 Subject: dt-bindings: mmc: sdhci-msm: add ICE registers and clock Document the bindings for the registers and clock for the MMC instance of the Inline Crypto Engine (ICE) on Snapdragon SoCs. These bindings are needed in order for sdhci-msm to support inline encryption. Reviewed-by: Satya Tangirala Acked-by: Rob Herring Signed-off-by: Eric Biggers Link: https://lore.kernel.org/r/20210126001456.382989-8-ebiggers@kernel.org Signed-off-by: Ulf Hansson --- Documentation/devicetree/bindings/mmc/sdhci-msm.txt | 3 +++ 1 file changed, 3 insertions(+) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/mmc/sdhci-msm.txt b/Documentation/devicetree/bindings/mmc/sdhci-msm.txt index 9fa8a24fbc97..4c7fa6a4ed15 100644 --- a/Documentation/devicetree/bindings/mmc/sdhci-msm.txt +++ b/Documentation/devicetree/bindings/mmc/sdhci-msm.txt @@ -31,10 +31,12 @@ Required properties: - SD Core register map (required for controllers earlier than msm-v5) - CQE register map (Optional, CQE support is present on SDHC instance meant for eMMC and version v4.2 and above) + - Inline Crypto Engine register map (optional) - reg-names: When CQE register map is supplied, below reg-names are required - "hc" for Host controller register map - "core" for SD core register map - "cqhci" for CQE register map + - "ice" for Inline Crypto Engine register map (optional) - interrupts: Should contain an interrupt-specifiers for the interrupts: - Host controller interrupt (required) - pinctrl-names: Should contain only one value - "default". @@ -47,6 +49,7 @@ Required properties: "xo" - TCXO clock (optional) "cal" - reference clock for RCLK delay calibration (optional) "sleep" - sleep clock for RCLK delay calibration (optional) + "ice" - clock for Inline Crypto Engine (optional) - qcom,ddr-config: Certain chipsets and platforms require particular settings for the DDR_CONFIG register. Use this field to specify the register -- cgit v1.2.3 From bbaa298f57cbcd214a4bffc4d877579686ee709e Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Sun, 24 Jan 2021 18:02:55 +0100 Subject: mmc: mmci: Add bindings to operate CMD, CK, CKIN pins as GPIO Add DT bindings to describe GPIO line associated with CMD, CK, CKIN pins. Signed-off-by: Marek Vasut Cc: Alexandre Torgue Cc: Ludovic Barre Reviewed-by: Linus Walleij Link: https://lore.kernel.org/r/20210124170258.32862-1-marex@denx.de Signed-off-by: Ulf Hansson --- Documentation/devicetree/bindings/mmc/arm,pl18x.yaml | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/mmc/arm,pl18x.yaml b/Documentation/devicetree/bindings/mmc/arm,pl18x.yaml index eddc1f6bdbe5..47595cb483be 100644 --- a/Documentation/devicetree/bindings/mmc/arm,pl18x.yaml +++ b/Documentation/devicetree/bindings/mmc/arm,pl18x.yaml @@ -127,6 +127,26 @@ properties: driver to sample the receive data (for example with a voltage switch transceiver). + st,cmd-gpios: + maxItems: 1 + description: + The GPIO matching the CMD pin. + + st,ck-gpios: + maxItems: 1 + description: + The GPIO matching the CK pin. + + st,ckin-gpios: + maxItems: 1 + description: + The GPIO matching the CKIN pin. + +dependencies: + st,cmd-gpios: [ "st,use-ckin" ] + st,ck-gpios: [ "st,use-ckin" ] + st,ckin-gpios: [ "st,use-ckin" ] + unevaluatedProperties: false required: -- cgit v1.2.3 From bca28426805dc3a87b3b0d2fd528caf1a3e1b119 Mon Sep 17 00:00:00 2001 From: Yong Wu Date: Mon, 11 Jan 2021 19:18:42 +0800 Subject: dt-bindings: iommu: mediatek: Convert IOMMU to DT schema Convert MediaTek IOMMU to DT schema. Signed-off-by: Yong Wu Reviewed-by: Rob Herring Reviewed-by: Tomasz Figa Link: https://lore.kernel.org/r/20210111111914.22211-2-yong.wu@mediatek.com Signed-off-by: Will Deacon --- .../devicetree/bindings/iommu/mediatek,iommu.txt | 105 ------------- .../devicetree/bindings/iommu/mediatek,iommu.yaml | 167 +++++++++++++++++++++ 2 files changed, 167 insertions(+), 105 deletions(-) delete mode 100644 Documentation/devicetree/bindings/iommu/mediatek,iommu.txt create mode 100644 Documentation/devicetree/bindings/iommu/mediatek,iommu.yaml (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/iommu/mediatek,iommu.txt b/Documentation/devicetree/bindings/iommu/mediatek,iommu.txt deleted file mode 100644 index ac949f7fe3d4..000000000000 --- a/Documentation/devicetree/bindings/iommu/mediatek,iommu.txt +++ /dev/null @@ -1,105 +0,0 @@ -* Mediatek IOMMU Architecture Implementation - - Some Mediatek SOCs contain a Multimedia Memory Management Unit (M4U), and -this M4U have two generations of HW architecture. Generation one uses flat -pagetable, and only supports 4K size page mapping. Generation two uses the -ARM Short-Descriptor translation table format for address translation. - - About the M4U Hardware Block Diagram, please check below: - - EMI (External Memory Interface) - | - m4u (Multimedia Memory Management Unit) - | - +--------+ - | | - gals0-rx gals1-rx (Global Async Local Sync rx) - | | - | | - gals0-tx gals1-tx (Global Async Local Sync tx) - | | Some SoCs may have GALS. - +--------+ - | - SMI Common(Smart Multimedia Interface Common) - | - +----------------+------- - | | - | gals-rx There may be GALS in some larbs. - | | - | | - | gals-tx - | | - SMI larb0 SMI larb1 ... SoCs have several SMI local arbiter(larb). - (display) (vdec) - | | - | | - +-----+-----+ +----+----+ - | | | | | | - | | |... | | | ... There are different ports in each larb. - | | | | | | -OVL0 RDMA0 WDMA0 MC PP VLD - - As above, The Multimedia HW will go through SMI and M4U while it -access EMI. SMI is a bridge between m4u and the Multimedia HW. It contain -smi local arbiter and smi common. It will control whether the Multimedia -HW should go though the m4u for translation or bypass it and talk -directly with EMI. And also SMI help control the power domain and clocks for -each local arbiter. - Normally we specify a local arbiter(larb) for each multimedia HW -like display, video decode, and camera. And there are different ports -in each larb. Take a example, There are many ports like MC, PP, VLD in the -video decode local arbiter, all these ports are according to the video HW. - In some SoCs, there may be a GALS(Global Async Local Sync) module between -smi-common and m4u, and additional GALS module between smi-larb and -smi-common. GALS can been seen as a "asynchronous fifo" which could help -synchronize for the modules in different clock frequency. - -Required properties: -- compatible : must be one of the following string: - "mediatek,mt2701-m4u" for mt2701 which uses generation one m4u HW. - "mediatek,mt2712-m4u" for mt2712 which uses generation two m4u HW. - "mediatek,mt6779-m4u" for mt6779 which uses generation two m4u HW. - "mediatek,mt7623-m4u", "mediatek,mt2701-m4u" for mt7623 which uses - generation one m4u HW. - "mediatek,mt8167-m4u" for mt8167 which uses generation two m4u HW. - "mediatek,mt8173-m4u" for mt8173 which uses generation two m4u HW. - "mediatek,mt8183-m4u" for mt8183 which uses generation two m4u HW. -- reg : m4u register base and size. -- interrupts : the interrupt of m4u. -- clocks : must contain one entry for each clock-names. -- clock-names : Only 1 optional clock: - - "bclk": the block clock of m4u. - Here is the list which require this "bclk": - - mt2701, mt2712, mt7623 and mt8173. - Note that m4u use the EMI clock which always has been enabled before kernel - if there is no this "bclk". -- mediatek,larbs : List of phandle to the local arbiters in the current Socs. - Refer to bindings/memory-controllers/mediatek,smi-larb.txt. It must sort - according to the local arbiter index, like larb0, larb1, larb2... -- iommu-cells : must be 1. This is the mtk_m4u_id according to the HW. - Specifies the mtk_m4u_id as defined in - dt-binding/memory/mt2701-larb-port.h for mt2701, mt7623 - dt-binding/memory/mt2712-larb-port.h for mt2712, - dt-binding/memory/mt6779-larb-port.h for mt6779, - dt-binding/memory/mt8167-larb-port.h for mt8167, - dt-binding/memory/mt8173-larb-port.h for mt8173, and - dt-binding/memory/mt8183-larb-port.h for mt8183. - -Example: - iommu: iommu@10205000 { - compatible = "mediatek,mt8173-m4u"; - reg = <0 0x10205000 0 0x1000>; - interrupts = ; - clocks = <&infracfg CLK_INFRA_M4U>; - clock-names = "bclk"; - mediatek,larbs = <&larb0 &larb1 &larb2 &larb3 &larb4 &larb5>; - #iommu-cells = <1>; - }; - -Example for a client device: - display { - compatible = "mediatek,mt8173-disp"; - iommus = <&iommu M4U_PORT_DISP_OVL0>, - <&iommu M4U_PORT_DISP_RDMA0>; - ... - }; diff --git a/Documentation/devicetree/bindings/iommu/mediatek,iommu.yaml b/Documentation/devicetree/bindings/iommu/mediatek,iommu.yaml new file mode 100644 index 000000000000..b9946809fc2b --- /dev/null +++ b/Documentation/devicetree/bindings/iommu/mediatek,iommu.yaml @@ -0,0 +1,167 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/iommu/mediatek,iommu.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: MediaTek IOMMU Architecture Implementation + +maintainers: + - Yong Wu + +description: |+ + Some MediaTek SOCs contain a Multimedia Memory Management Unit (M4U), and + this M4U have two generations of HW architecture. Generation one uses flat + pagetable, and only supports 4K size page mapping. Generation two uses the + ARM Short-Descriptor translation table format for address translation. + + About the M4U Hardware Block Diagram, please check below: + + EMI (External Memory Interface) + | + m4u (Multimedia Memory Management Unit) + | + +--------+ + | | + gals0-rx gals1-rx (Global Async Local Sync rx) + | | + | | + gals0-tx gals1-tx (Global Async Local Sync tx) + | | Some SoCs may have GALS. + +--------+ + | + SMI Common(Smart Multimedia Interface Common) + | + +----------------+------- + | | + | gals-rx There may be GALS in some larbs. + | | + | | + | gals-tx + | | + SMI larb0 SMI larb1 ... SoCs have several SMI local arbiter(larb). + (display) (vdec) + | | + | | + +-----+-----+ +----+----+ + | | | | | | + | | |... | | | ... There are different ports in each larb. + | | | | | | + OVL0 RDMA0 WDMA0 MC PP VLD + + As above, The Multimedia HW will go through SMI and M4U while it + access EMI. SMI is a bridge between m4u and the Multimedia HW. It contain + smi local arbiter and smi common. It will control whether the Multimedia + HW should go though the m4u for translation or bypass it and talk + directly with EMI. And also SMI help control the power domain and clocks for + each local arbiter. + + Normally we specify a local arbiter(larb) for each multimedia HW + like display, video decode, and camera. And there are different ports + in each larb. Take a example, There are many ports like MC, PP, VLD in the + video decode local arbiter, all these ports are according to the video HW. + + In some SoCs, there may be a GALS(Global Async Local Sync) module between + smi-common and m4u, and additional GALS module between smi-larb and + smi-common. GALS can been seen as a "asynchronous fifo" which could help + synchronize for the modules in different clock frequency. + +properties: + compatible: + oneOf: + - enum: + - mediatek,mt2701-m4u # generation one + - mediatek,mt2712-m4u # generation two + - mediatek,mt6779-m4u # generation two + - mediatek,mt8167-m4u # generation two + - mediatek,mt8173-m4u # generation two + - mediatek,mt8183-m4u # generation two + + - description: mt7623 generation one + items: + - const: mediatek,mt7623-m4u + - const: mediatek,mt2701-m4u + + reg: + maxItems: 1 + + interrupts: + maxItems: 1 + + clocks: + items: + - description: bclk is the block clock. + + clock-names: + items: + - const: bclk + + mediatek,larbs: + $ref: /schemas/types.yaml#/definitions/phandle-array + minItems: 1 + maxItems: 16 + description: | + List of phandle to the local arbiters in the current Socs. + Refer to bindings/memory-controllers/mediatek,smi-larb.yaml. It must sort + according to the local arbiter index, like larb0, larb1, larb2... + + '#iommu-cells': + const: 1 + description: | + This is the mtk_m4u_id according to the HW. Specifies the mtk_m4u_id as + defined in + dt-binding/memory/mt2701-larb-port.h for mt2701 and mt7623, + dt-binding/memory/mt2712-larb-port.h for mt2712, + dt-binding/memory/mt6779-larb-port.h for mt6779, + dt-binding/memory/mt8167-larb-port.h for mt8167, + dt-binding/memory/mt8173-larb-port.h for mt8173, + dt-binding/memory/mt8183-larb-port.h for mt8183. + +required: + - compatible + - reg + - interrupts + - mediatek,larbs + - '#iommu-cells' + +allOf: + - if: + properties: + compatible: + contains: + enum: + - mediatek,mt2701-m4u + - mediatek,mt2712-m4u + - mediatek,mt8173-m4u + + then: + required: + - clocks + +additionalProperties: false + +examples: + - | + #include + #include + + iommu: iommu@10205000 { + compatible = "mediatek,mt8173-m4u"; + reg = <0x10205000 0x1000>; + interrupts = ; + clocks = <&infracfg CLK_INFRA_M4U>; + clock-names = "bclk"; + mediatek,larbs = <&larb0 &larb1 &larb2 + &larb3 &larb4 &larb5>; + #iommu-cells = <1>; + }; + + - | + #include + + /* Example for a client device */ + display { + compatible = "mediatek,mt8173-disp"; + iommus = <&iommu M4U_PORT_DISP_OVL0>, + <&iommu M4U_PORT_DISP_RDMA0>; + }; -- cgit v1.2.3 From ca49a4b4c9895a873213ae93abae5855e8d226c6 Mon Sep 17 00:00:00 2001 From: Yong Wu Date: Mon, 11 Jan 2021 19:18:44 +0800 Subject: dt-bindings: memory: mediatek: Extend LARB_NR_MAX to 32 Extend the max larb number definition as mt8192 has larb_nr over 16. Signed-off-by: Yong Wu Acked-by: Rob Herring Acked-by: Krzysztof Kozlowski Reviewed-by: Tomasz Figa Link: https://lore.kernel.org/r/20210111111914.22211-4-yong.wu@mediatek.com Signed-off-by: Will Deacon --- Documentation/devicetree/bindings/iommu/mediatek,iommu.yaml | 2 +- include/dt-bindings/memory/mtk-memory-port.h | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/iommu/mediatek,iommu.yaml b/Documentation/devicetree/bindings/iommu/mediatek,iommu.yaml index b9946809fc2b..ba6626347381 100644 --- a/Documentation/devicetree/bindings/iommu/mediatek,iommu.yaml +++ b/Documentation/devicetree/bindings/iommu/mediatek,iommu.yaml @@ -99,7 +99,7 @@ properties: mediatek,larbs: $ref: /schemas/types.yaml#/definitions/phandle-array minItems: 1 - maxItems: 16 + maxItems: 32 description: | List of phandle to the local arbiters in the current Socs. Refer to bindings/memory-controllers/mediatek,smi-larb.yaml. It must sort diff --git a/include/dt-bindings/memory/mtk-memory-port.h b/include/dt-bindings/memory/mtk-memory-port.h index 53354cf4f6e3..7d64103209af 100644 --- a/include/dt-bindings/memory/mtk-memory-port.h +++ b/include/dt-bindings/memory/mtk-memory-port.h @@ -6,10 +6,10 @@ #ifndef __DT_BINDINGS_MEMORY_MTK_MEMORY_PORT_H_ #define __DT_BINDINGS_MEMORY_MTK_MEMORY_PORT_H_ -#define MTK_LARB_NR_MAX 16 +#define MTK_LARB_NR_MAX 32 #define MTK_M4U_ID(larb, port) (((larb) << 5) | (port)) -#define MTK_M4U_TO_LARB(id) (((id) >> 5) & 0xf) +#define MTK_M4U_TO_LARB(id) (((id) >> 5) & 0x1f) #define MTK_M4U_TO_PORT(id) ((id) & 0x1f) #endif -- cgit v1.2.3 From fc3734698a435b301183acc8332f0a5fba868bc3 Mon Sep 17 00:00:00 2001 From: Yong Wu Date: Mon, 11 Jan 2021 19:18:46 +0800 Subject: dt-bindings: mediatek: Add binding for mt8192 IOMMU This patch adds decriptions for mt8192 IOMMU and SMI. mt8192 also is MTK IOMMU gen2 which uses ARM Short-Descriptor translation table format. The M4U-SMI HW diagram is as below: EMI | M4U | ------------ SMI Common ------------ | +-------+------+------+----------------------+-------+ | | | | ...... | | | | | | | | larb0 larb1 larb2 larb4 ...... larb19 larb20 disp0 disp1 mdp vdec IPE IPE All the connections are HW fixed, SW can NOT adjust it. mt8192 M4U support 0~16GB iova range. we preassign different engines into different iova ranges: domain-id module iova-range larbs 0 disp 0 ~ 4G larb0/1 1 vcodec 4G ~ 8G larb4/5/7 2 cam/mdp 8G ~ 12G larb2/9/11/13/14/16/17/18/19/20 3 CCU0 0x4000_0000 ~ 0x43ff_ffff larb13: port 9/10 4 CCU1 0x4400_0000 ~ 0x47ff_ffff larb14: port 4/5 The iova range for CCU0/1(camera control unit) is HW requirement. Signed-off-by: Yong Wu Reviewed-by: Rob Herring Acked-by: Krzysztof Kozlowski Reviewed-by: Tomasz Figa Link: https://lore.kernel.org/r/20210111111914.22211-6-yong.wu@mediatek.com Signed-off-by: Will Deacon --- .../devicetree/bindings/iommu/mediatek,iommu.yaml | 18 +- include/dt-bindings/memory/mt8192-larb-port.h | 243 +++++++++++++++++++++ 2 files changed, 260 insertions(+), 1 deletion(-) create mode 100644 include/dt-bindings/memory/mt8192-larb-port.h (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/iommu/mediatek,iommu.yaml b/Documentation/devicetree/bindings/iommu/mediatek,iommu.yaml index ba6626347381..0f26fe14c8e2 100644 --- a/Documentation/devicetree/bindings/iommu/mediatek,iommu.yaml +++ b/Documentation/devicetree/bindings/iommu/mediatek,iommu.yaml @@ -76,6 +76,7 @@ properties: - mediatek,mt8167-m4u # generation two - mediatek,mt8173-m4u # generation two - mediatek,mt8183-m4u # generation two + - mediatek,mt8192-m4u # generation two - description: mt7623 generation one items: @@ -115,7 +116,11 @@ properties: dt-binding/memory/mt6779-larb-port.h for mt6779, dt-binding/memory/mt8167-larb-port.h for mt8167, dt-binding/memory/mt8173-larb-port.h for mt8173, - dt-binding/memory/mt8183-larb-port.h for mt8183. + dt-binding/memory/mt8183-larb-port.h for mt8183, + dt-binding/memory/mt8192-larb-port.h for mt8192. + + power-domains: + maxItems: 1 required: - compatible @@ -133,11 +138,22 @@ allOf: - mediatek,mt2701-m4u - mediatek,mt2712-m4u - mediatek,mt8173-m4u + - mediatek,mt8192-m4u then: required: - clocks + - if: + properties: + compatible: + enum: + - mediatek,mt8192-m4u + + then: + required: + - power-domains + additionalProperties: false examples: diff --git a/include/dt-bindings/memory/mt8192-larb-port.h b/include/dt-bindings/memory/mt8192-larb-port.h new file mode 100644 index 000000000000..23035a52c675 --- /dev/null +++ b/include/dt-bindings/memory/mt8192-larb-port.h @@ -0,0 +1,243 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (c) 2020 MediaTek Inc. + * + * Author: Chao Hao + * Author: Yong Wu + */ +#ifndef _DT_BINDINGS_MEMORY_MT8192_LARB_PORT_H_ +#define _DT_BINDINGS_MEMORY_MT8192_LARB_PORT_H_ + +#include + +/* + * MM IOMMU supports 16GB dma address. + * + * The address will preassign like this: + * + * modules dma-address-region larbs-ports + * disp 0 ~ 4G larb0/1 + * vcodec 4G ~ 8G larb4/5/7 + * cam/mdp 8G ~ 12G larb2/9/11/13/14/16/17/18/19/20 + * CCU0 0x4000_0000 ~ 0x43ff_ffff larb13: port 9/10 + * CCU1 0x4400_0000 ~ 0x47ff_ffff larb14: port 4/5 + * + * larb3/6/8/10/12/15 is null. + */ + +/* larb0 */ +#define M4U_PORT_L0_DISP_POSTMASK0 MTK_M4U_ID(0, 0) +#define M4U_PORT_L0_OVL_RDMA0_HDR MTK_M4U_ID(0, 1) +#define M4U_PORT_L0_OVL_RDMA0 MTK_M4U_ID(0, 2) +#define M4U_PORT_L0_DISP_RDMA0 MTK_M4U_ID(0, 3) +#define M4U_PORT_L0_DISP_WDMA0 MTK_M4U_ID(0, 4) +#define M4U_PORT_L0_DISP_FAKE0 MTK_M4U_ID(0, 5) + +/* larb1 */ +#define M4U_PORT_L1_OVL_2L_RDMA0_HDR MTK_M4U_ID(1, 0) +#define M4U_PORT_L1_OVL_2L_RDMA2_HDR MTK_M4U_ID(1, 1) +#define M4U_PORT_L1_OVL_2L_RDMA0 MTK_M4U_ID(1, 2) +#define M4U_PORT_L1_OVL_2L_RDMA2 MTK_M4U_ID(1, 3) +#define M4U_PORT_L1_DISP_MDP_RDMA4 MTK_M4U_ID(1, 4) +#define M4U_PORT_L1_DISP_RDMA4 MTK_M4U_ID(1, 5) +#define M4U_PORT_L1_DISP_UFBC_WDMA0 MTK_M4U_ID(1, 6) +#define M4U_PORT_L1_DISP_FAKE1 MTK_M4U_ID(1, 7) + +/* larb2 */ +#define M4U_PORT_L2_MDP_RDMA0 MTK_M4U_ID(2, 0) +#define M4U_PORT_L2_MDP_RDMA1 MTK_M4U_ID(2, 1) +#define M4U_PORT_L2_MDP_WROT0 MTK_M4U_ID(2, 2) +#define M4U_PORT_L2_MDP_WROT1 MTK_M4U_ID(2, 3) +#define M4U_PORT_L2_MDP_DISP_FAKE0 MTK_M4U_ID(2, 4) + +/* larb3: null */ + +/* larb4 */ +#define M4U_PORT_L4_VDEC_MC_EXT MTK_M4U_ID(4, 0) +#define M4U_PORT_L4_VDEC_UFO_EXT MTK_M4U_ID(4, 1) +#define M4U_PORT_L4_VDEC_PP_EXT MTK_M4U_ID(4, 2) +#define M4U_PORT_L4_VDEC_PRED_RD_EXT MTK_M4U_ID(4, 3) +#define M4U_PORT_L4_VDEC_PRED_WR_EXT MTK_M4U_ID(4, 4) +#define M4U_PORT_L4_VDEC_PPWRAP_EXT MTK_M4U_ID(4, 5) +#define M4U_PORT_L4_VDEC_TILE_EXT MTK_M4U_ID(4, 6) +#define M4U_PORT_L4_VDEC_VLD_EXT MTK_M4U_ID(4, 7) +#define M4U_PORT_L4_VDEC_VLD2_EXT MTK_M4U_ID(4, 8) +#define M4U_PORT_L4_VDEC_AVC_MV_EXT MTK_M4U_ID(4, 9) +#define M4U_PORT_L4_VDEC_RG_CTRL_DMA_EXT MTK_M4U_ID(4, 10) + +/* larb5 */ +#define M4U_PORT_L5_VDEC_LAT0_VLD_EXT MTK_M4U_ID(5, 0) +#define M4U_PORT_L5_VDEC_LAT0_VLD2_EXT MTK_M4U_ID(5, 1) +#define M4U_PORT_L5_VDEC_LAT0_AVC_MV_EXT MTK_M4U_ID(5, 2) +#define M4U_PORT_L5_VDEC_LAT0_PRED_RD_EXT MTK_M4U_ID(5, 3) +#define M4U_PORT_L5_VDEC_LAT0_TILE_EXT MTK_M4U_ID(5, 4) +#define M4U_PORT_L5_VDEC_LAT0_WDMA_EXT MTK_M4U_ID(5, 5) +#define M4U_PORT_L5_VDEC_LAT0_RG_CTRL_DMA_EXT MTK_M4U_ID(5, 6) +#define M4U_PORT_L5_VDEC_UFO_ENC_EXT MTK_M4U_ID(5, 7) + +/* larb6: null */ + +/* larb7 */ +#define M4U_PORT_L7_VENC_RCPU MTK_M4U_ID(7, 0) +#define M4U_PORT_L7_VENC_REC MTK_M4U_ID(7, 1) +#define M4U_PORT_L7_VENC_BSDMA MTK_M4U_ID(7, 2) +#define M4U_PORT_L7_VENC_SV_COMV MTK_M4U_ID(7, 3) +#define M4U_PORT_L7_VENC_RD_COMV MTK_M4U_ID(7, 4) +#define M4U_PORT_L7_VENC_CUR_LUMA MTK_M4U_ID(7, 5) +#define M4U_PORT_L7_VENC_CUR_CHROMA MTK_M4U_ID(7, 6) +#define M4U_PORT_L7_VENC_REF_LUMA MTK_M4U_ID(7, 7) +#define M4U_PORT_L7_VENC_REF_CHROMA MTK_M4U_ID(7, 8) +#define M4U_PORT_L7_JPGENC_Y_RDMA MTK_M4U_ID(7, 9) +#define M4U_PORT_L7_JPGENC_Q_RDMA MTK_M4U_ID(7, 10) +#define M4U_PORT_L7_JPGENC_C_TABLE MTK_M4U_ID(7, 11) +#define M4U_PORT_L7_JPGENC_BSDMA MTK_M4U_ID(7, 12) +#define M4U_PORT_L7_VENC_SUB_R_LUMA MTK_M4U_ID(7, 13) +#define M4U_PORT_L7_VENC_SUB_W_LUMA MTK_M4U_ID(7, 14) + +/* larb8: null */ + +/* larb9 */ +#define M4U_PORT_L9_IMG_IMGI_D1 MTK_M4U_ID(9, 0) +#define M4U_PORT_L9_IMG_IMGBI_D1 MTK_M4U_ID(9, 1) +#define M4U_PORT_L9_IMG_DMGI_D1 MTK_M4U_ID(9, 2) +#define M4U_PORT_L9_IMG_DEPI_D1 MTK_M4U_ID(9, 3) +#define M4U_PORT_L9_IMG_ICE_D1 MTK_M4U_ID(9, 4) +#define M4U_PORT_L9_IMG_SMTI_D1 MTK_M4U_ID(9, 5) +#define M4U_PORT_L9_IMG_SMTO_D2 MTK_M4U_ID(9, 6) +#define M4U_PORT_L9_IMG_SMTO_D1 MTK_M4U_ID(9, 7) +#define M4U_PORT_L9_IMG_CRZO_D1 MTK_M4U_ID(9, 8) +#define M4U_PORT_L9_IMG_IMG3O_D1 MTK_M4U_ID(9, 9) +#define M4U_PORT_L9_IMG_VIPI_D1 MTK_M4U_ID(9, 10) +#define M4U_PORT_L9_IMG_SMTI_D5 MTK_M4U_ID(9, 11) +#define M4U_PORT_L9_IMG_TIMGO_D1 MTK_M4U_ID(9, 12) +#define M4U_PORT_L9_IMG_UFBC_W0 MTK_M4U_ID(9, 13) +#define M4U_PORT_L9_IMG_UFBC_R0 MTK_M4U_ID(9, 14) + +/* larb10: null */ + +/* larb11 */ +#define M4U_PORT_L11_IMG_IMGI_D1 MTK_M4U_ID(11, 0) +#define M4U_PORT_L11_IMG_IMGBI_D1 MTK_M4U_ID(11, 1) +#define M4U_PORT_L11_IMG_DMGI_D1 MTK_M4U_ID(11, 2) +#define M4U_PORT_L11_IMG_DEPI_D1 MTK_M4U_ID(11, 3) +#define M4U_PORT_L11_IMG_ICE_D1 MTK_M4U_ID(11, 4) +#define M4U_PORT_L11_IMG_SMTI_D1 MTK_M4U_ID(11, 5) +#define M4U_PORT_L11_IMG_SMTO_D2 MTK_M4U_ID(11, 6) +#define M4U_PORT_L11_IMG_SMTO_D1 MTK_M4U_ID(11, 7) +#define M4U_PORT_L11_IMG_CRZO_D1 MTK_M4U_ID(11, 8) +#define M4U_PORT_L11_IMG_IMG3O_D1 MTK_M4U_ID(11, 9) +#define M4U_PORT_L11_IMG_VIPI_D1 MTK_M4U_ID(11, 10) +#define M4U_PORT_L11_IMG_SMTI_D5 MTK_M4U_ID(11, 11) +#define M4U_PORT_L11_IMG_TIMGO_D1 MTK_M4U_ID(11, 12) +#define M4U_PORT_L11_IMG_UFBC_W0 MTK_M4U_ID(11, 13) +#define M4U_PORT_L11_IMG_UFBC_R0 MTK_M4U_ID(11, 14) +#define M4U_PORT_L11_IMG_WPE_RDMA1 MTK_M4U_ID(11, 15) +#define M4U_PORT_L11_IMG_WPE_RDMA0 MTK_M4U_ID(11, 16) +#define M4U_PORT_L11_IMG_WPE_WDMA MTK_M4U_ID(11, 17) +#define M4U_PORT_L11_IMG_MFB_RDMA0 MTK_M4U_ID(11, 18) +#define M4U_PORT_L11_IMG_MFB_RDMA1 MTK_M4U_ID(11, 19) +#define M4U_PORT_L11_IMG_MFB_RDMA2 MTK_M4U_ID(11, 20) +#define M4U_PORT_L11_IMG_MFB_RDMA3 MTK_M4U_ID(11, 21) +#define M4U_PORT_L11_IMG_MFB_RDMA4 MTK_M4U_ID(11, 22) +#define M4U_PORT_L11_IMG_MFB_RDMA5 MTK_M4U_ID(11, 23) +#define M4U_PORT_L11_IMG_MFB_WDMA0 MTK_M4U_ID(11, 24) +#define M4U_PORT_L11_IMG_MFB_WDMA1 MTK_M4U_ID(11, 25) + +/* larb12: null */ + +/* larb13 */ +#define M4U_PORT_L13_CAM_MRAWI MTK_M4U_ID(13, 0) +#define M4U_PORT_L13_CAM_MRAWO0 MTK_M4U_ID(13, 1) +#define M4U_PORT_L13_CAM_MRAWO1 MTK_M4U_ID(13, 2) +#define M4U_PORT_L13_CAM_CAMSV1 MTK_M4U_ID(13, 3) +#define M4U_PORT_L13_CAM_CAMSV2 MTK_M4U_ID(13, 4) +#define M4U_PORT_L13_CAM_CAMSV3 MTK_M4U_ID(13, 5) +#define M4U_PORT_L13_CAM_CAMSV4 MTK_M4U_ID(13, 6) +#define M4U_PORT_L13_CAM_CAMSV5 MTK_M4U_ID(13, 7) +#define M4U_PORT_L13_CAM_CAMSV6 MTK_M4U_ID(13, 8) +#define M4U_PORT_L13_CAM_CCUI MTK_M4U_ID(13, 9) +#define M4U_PORT_L13_CAM_CCUO MTK_M4U_ID(13, 10) +#define M4U_PORT_L13_CAM_FAKE MTK_M4U_ID(13, 11) + +/* larb14 */ +#define M4U_PORT_L14_CAM_RESERVE1 MTK_M4U_ID(14, 0) +#define M4U_PORT_L14_CAM_RESERVE2 MTK_M4U_ID(14, 1) +#define M4U_PORT_L14_CAM_RESERVE3 MTK_M4U_ID(14, 2) +#define M4U_PORT_L14_CAM_CAMSV0 MTK_M4U_ID(14, 3) +#define M4U_PORT_L14_CAM_CCUI MTK_M4U_ID(14, 4) +#define M4U_PORT_L14_CAM_CCUO MTK_M4U_ID(14, 5) + +/* larb15: null */ + +/* larb16 */ +#define M4U_PORT_L16_CAM_IMGO_R1_A MTK_M4U_ID(16, 0) +#define M4U_PORT_L16_CAM_RRZO_R1_A MTK_M4U_ID(16, 1) +#define M4U_PORT_L16_CAM_CQI_R1_A MTK_M4U_ID(16, 2) +#define M4U_PORT_L16_CAM_BPCI_R1_A MTK_M4U_ID(16, 3) +#define M4U_PORT_L16_CAM_YUVO_R1_A MTK_M4U_ID(16, 4) +#define M4U_PORT_L16_CAM_UFDI_R2_A MTK_M4U_ID(16, 5) +#define M4U_PORT_L16_CAM_RAWI_R2_A MTK_M4U_ID(16, 6) +#define M4U_PORT_L16_CAM_RAWI_R3_A MTK_M4U_ID(16, 7) +#define M4U_PORT_L16_CAM_AAO_R1_A MTK_M4U_ID(16, 8) +#define M4U_PORT_L16_CAM_AFO_R1_A MTK_M4U_ID(16, 9) +#define M4U_PORT_L16_CAM_FLKO_R1_A MTK_M4U_ID(16, 10) +#define M4U_PORT_L16_CAM_LCESO_R1_A MTK_M4U_ID(16, 11) +#define M4U_PORT_L16_CAM_CRZO_R1_A MTK_M4U_ID(16, 12) +#define M4U_PORT_L16_CAM_LTMSO_R1_A MTK_M4U_ID(16, 13) +#define M4U_PORT_L16_CAM_RSSO_R1_A MTK_M4U_ID(16, 14) +#define M4U_PORT_L16_CAM_AAHO_R1_A MTK_M4U_ID(16, 15) +#define M4U_PORT_L16_CAM_LSCI_R1_A MTK_M4U_ID(16, 16) + +/* larb17 */ +#define M4U_PORT_L17_CAM_IMGO_R1_B MTK_M4U_ID(17, 0) +#define M4U_PORT_L17_CAM_RRZO_R1_B MTK_M4U_ID(17, 1) +#define M4U_PORT_L17_CAM_CQI_R1_B MTK_M4U_ID(17, 2) +#define M4U_PORT_L17_CAM_BPCI_R1_B MTK_M4U_ID(17, 3) +#define M4U_PORT_L17_CAM_YUVO_R1_B MTK_M4U_ID(17, 4) +#define M4U_PORT_L17_CAM_UFDI_R2_B MTK_M4U_ID(17, 5) +#define M4U_PORT_L17_CAM_RAWI_R2_B MTK_M4U_ID(17, 6) +#define M4U_PORT_L17_CAM_RAWI_R3_B MTK_M4U_ID(17, 7) +#define M4U_PORT_L17_CAM_AAO_R1_B MTK_M4U_ID(17, 8) +#define M4U_PORT_L17_CAM_AFO_R1_B MTK_M4U_ID(17, 9) +#define M4U_PORT_L17_CAM_FLKO_R1_B MTK_M4U_ID(17, 10) +#define M4U_PORT_L17_CAM_LCESO_R1_B MTK_M4U_ID(17, 11) +#define M4U_PORT_L17_CAM_CRZO_R1_B MTK_M4U_ID(17, 12) +#define M4U_PORT_L17_CAM_LTMSO_R1_B MTK_M4U_ID(17, 13) +#define M4U_PORT_L17_CAM_RSSO_R1_B MTK_M4U_ID(17, 14) +#define M4U_PORT_L17_CAM_AAHO_R1_B MTK_M4U_ID(17, 15) +#define M4U_PORT_L17_CAM_LSCI_R1_B MTK_M4U_ID(17, 16) + +/* larb18 */ +#define M4U_PORT_L18_CAM_IMGO_R1_C MTK_M4U_ID(18, 0) +#define M4U_PORT_L18_CAM_RRZO_R1_C MTK_M4U_ID(18, 1) +#define M4U_PORT_L18_CAM_CQI_R1_C MTK_M4U_ID(18, 2) +#define M4U_PORT_L18_CAM_BPCI_R1_C MTK_M4U_ID(18, 3) +#define M4U_PORT_L18_CAM_YUVO_R1_C MTK_M4U_ID(18, 4) +#define M4U_PORT_L18_CAM_UFDI_R2_C MTK_M4U_ID(18, 5) +#define M4U_PORT_L18_CAM_RAWI_R2_C MTK_M4U_ID(18, 6) +#define M4U_PORT_L18_CAM_RAWI_R3_C MTK_M4U_ID(18, 7) +#define M4U_PORT_L18_CAM_AAO_R1_C MTK_M4U_ID(18, 8) +#define M4U_PORT_L18_CAM_AFO_R1_C MTK_M4U_ID(18, 9) +#define M4U_PORT_L18_CAM_FLKO_R1_C MTK_M4U_ID(18, 10) +#define M4U_PORT_L18_CAM_LCESO_R1_C MTK_M4U_ID(18, 11) +#define M4U_PORT_L18_CAM_CRZO_R1_C MTK_M4U_ID(18, 12) +#define M4U_PORT_L18_CAM_LTMSO_R1_C MTK_M4U_ID(18, 13) +#define M4U_PORT_L18_CAM_RSSO_R1_C MTK_M4U_ID(18, 14) +#define M4U_PORT_L18_CAM_AAHO_R1_C MTK_M4U_ID(18, 15) +#define M4U_PORT_L18_CAM_LSCI_R1_C MTK_M4U_ID(18, 16) + +/* larb19 */ +#define M4U_PORT_L19_IPE_DVS_RDMA MTK_M4U_ID(19, 0) +#define M4U_PORT_L19_IPE_DVS_WDMA MTK_M4U_ID(19, 1) +#define M4U_PORT_L19_IPE_DVP_RDMA MTK_M4U_ID(19, 2) +#define M4U_PORT_L19_IPE_DVP_WDMA MTK_M4U_ID(19, 3) + +/* larb20 */ +#define M4U_PORT_L20_IPE_FDVT_RDA MTK_M4U_ID(20, 0) +#define M4U_PORT_L20_IPE_FDVT_RDB MTK_M4U_ID(20, 1) +#define M4U_PORT_L20_IPE_FDVT_WRA MTK_M4U_ID(20, 2) +#define M4U_PORT_L20_IPE_FDVT_WRB MTK_M4U_ID(20, 3) +#define M4U_PORT_L20_IPE_RSC_RDMA0 MTK_M4U_ID(20, 4) +#define M4U_PORT_L20_IPE_RSC_WDMA MTK_M4U_ID(20, 5) + +#endif -- cgit v1.2.3 From 6bbb859012e905736c852b518be16c653e451967 Mon Sep 17 00:00:00 2001 From: Sameer Pujar Date: Fri, 29 Jan 2021 23:57:38 +0530 Subject: ASoC: dt-bindings: rt5659: Update binding doc Update following in rt5659.txt binding doc - Add JD source for Intel HDA header: Commit 041e74b71491 ("ASoC: rt5659: Add the support of Intel HDA Header") added driver support. Add missing info here. - sound-name-prefix: Used to prefix component widgets/kcontrols with given prefix. - ports: Helps to use the Codec with audio graph card Signed-off-by: Sameer Pujar Reported-by: Jon Hunter Cc: Oder Chiou Cc: Bard Liao Link: https://lore.kernel.org/r/1611944866-29373-2-git-send-email-spujar@nvidia.com Signed-off-by: Mark Brown --- Documentation/devicetree/bindings/sound/rt5659.txt | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/sound/rt5659.txt b/Documentation/devicetree/bindings/sound/rt5659.txt index 56788f50b6cf..c473df5c878c 100644 --- a/Documentation/devicetree/bindings/sound/rt5659.txt +++ b/Documentation/devicetree/bindings/sound/rt5659.txt @@ -37,10 +37,21 @@ Optional properties: - realtek,jd-src 0: No JD is used 1: using JD3 as JD source + 2: JD source for Intel HDA header - realtek,ldo1-en-gpios : The GPIO that controls the CODEC's LDO1_EN pin. - realtek,reset-gpios : The GPIO that controls the CODEC's RESET pin. +- sound-name-prefix: Please refer to name-prefix.txt + +- ports: A Codec may have a single or multiple I2S interfaces. These + interfaces on Codec side can be described under 'ports' or 'port'. + When the SoC or host device is connected to multiple interfaces of + the Codec, the connectivity can be described using 'ports' property. + If a single interface is used, then 'port' can be used. The usage + depends on the platform or board design. + Please refer to Documentation/devicetree/bindings/graph.txt + Pins on the device (for linking into audio routes) for RT5659/RT5658: * DMIC L1 -- cgit v1.2.3 From 70f0bc65f6cf757fa4cca2d6fcb84f613bc0d8cc Mon Sep 17 00:00:00 2001 From: Sameer Pujar Date: Fri, 29 Jan 2021 23:57:39 +0530 Subject: ASoC: dt-bindings: tegra: Add iommus property to Tegra graph card Document 'iommus' property for APE (Audio Processing Engine) sound card. Signed-off-by: Sameer Pujar Link: https://lore.kernel.org/r/1611944866-29373-3-git-send-email-spujar@nvidia.com Signed-off-by: Mark Brown --- .../devicetree/bindings/sound/nvidia,tegra-audio-graph-card.yaml | 3 +++ 1 file changed, 3 insertions(+) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/sound/nvidia,tegra-audio-graph-card.yaml b/Documentation/devicetree/bindings/sound/nvidia,tegra-audio-graph-card.yaml index fc271f644aaf..249970952202 100644 --- a/Documentation/devicetree/bindings/sound/nvidia,tegra-audio-graph-card.yaml +++ b/Documentation/devicetree/bindings/sound/nvidia,tegra-audio-graph-card.yaml @@ -45,6 +45,9 @@ properties: minItems: 1 maxItems: 3 + iommus: + maxItems: 1 + required: - clocks - clock-names -- cgit v1.2.3 From 531e5b7abbde3c190aeff5b13c17f7ef3e0f3543 Mon Sep 17 00:00:00 2001 From: Sameer Pujar Date: Fri, 29 Jan 2021 23:57:40 +0530 Subject: ASoC: audio-graph-card: Add clocks property to endpoint node Add optional 'clocks' property to audio port 'endpoint' node. One such example is where SoC supplies a clock to external audio codec component. Signed-off-by: Sameer Pujar Cc: Kuninori Morimoto Reviewed-by: Jon Hunter Link: https://lore.kernel.org/r/1611944866-29373-4-git-send-email-spujar@nvidia.com Signed-off-by: Mark Brown --- Documentation/devicetree/bindings/sound/audio-graph-port.yaml | 3 +++ 1 file changed, 3 insertions(+) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/sound/audio-graph-port.yaml b/Documentation/devicetree/bindings/sound/audio-graph-port.yaml index 766e9109b2f7..08ed8f52c962 100644 --- a/Documentation/devicetree/bindings/sound/audio-graph-port.yaml +++ b/Documentation/devicetree/bindings/sound/audio-graph-port.yaml @@ -33,6 +33,9 @@ properties: properties: remote-endpoint: maxItems: 1 + clocks: + maxItems: 1 + description: Describes the clock used by audio component. mclk-fs: description: | Multiplication factor between stream rate and codec mclk. -- cgit v1.2.3 From 1ed8459d8f1060c87c7d66fe2d3cbbe4bc9cdd24 Mon Sep 17 00:00:00 2001 From: Benson Leung Date: Thu, 28 Jan 2021 22:14:01 -0800 Subject: usb: typec: Standardize PD Revision format with Type-C Revision The Type-C Revision was in a specific BCD format "0120H" for 1.2. USB PD revision numbers follow a similar pattern with "0300H" for 3.0. Standardizes the sysfs format for usb_power_delivery_revision to align with the BCD format used for usb_typec_revision. Example values: - "2.0": USB Power Delivery Release 2.0 - "3.0": USB Power Delivery Release 3.0 - "3.1": USB Power Delivery Release 3.1 Reviewed-by: Heikki Krogerus Signed-off-by: Benson Leung Link: https://lore.kernel.org/r/20210129061406.2680146-2-bleung@chromium.org Signed-off-by: Greg Kroah-Hartman --- Documentation/ABI/testing/sysfs-class-typec | 7 ++++++- drivers/usb/typec/class.c | 3 ++- 2 files changed, 8 insertions(+), 2 deletions(-) (limited to 'Documentation') diff --git a/Documentation/ABI/testing/sysfs-class-typec b/Documentation/ABI/testing/sysfs-class-typec index 8eab41e79ce6..b61480535fdc 100644 --- a/Documentation/ABI/testing/sysfs-class-typec +++ b/Documentation/ABI/testing/sysfs-class-typec @@ -105,7 +105,12 @@ Date: April 2017 Contact: Heikki Krogerus Description: Revision number of the supported USB Power Delivery - specification, or 0 when USB Power Delivery is not supported. + specification, or 0.0 when USB Power Delivery is not supported. + + Example values: + - "2.0": USB Power Delivery Release 2.0 + - "3.0": USB Power Delivery Release 3.0 + - "3.1": USB Power Delivery Release 3.1 What: /sys/class/typec//usb_typec_revision Date: April 2017 diff --git a/drivers/usb/typec/class.c b/drivers/usb/typec/class.c index 8f77669f9cf4..4f60ee7ba76a 100644 --- a/drivers/usb/typec/class.c +++ b/drivers/usb/typec/class.c @@ -1500,8 +1500,9 @@ static ssize_t usb_power_delivery_revision_show(struct device *dev, char *buf) { struct typec_port *p = to_typec_port(dev); + u16 rev = p->cap->pd_revision; - return sprintf(buf, "%d\n", (p->cap->pd_revision >> 8) & 0xff); + return sprintf(buf, "%d.%d\n", (rev >> 8) & 0xff, (rev >> 4) & 0xf); } static DEVICE_ATTR_RO(usb_power_delivery_revision); -- cgit v1.2.3 From f5030e252687be6e999bd52feb1f79d515b2f684 Mon Sep 17 00:00:00 2001 From: Benson Leung Date: Thu, 28 Jan 2021 22:14:02 -0800 Subject: usb: typec: Provide PD Specification Revision for cable and partner The USB Power Delivery specification Section 6.2.1.1.5 outlines revision backward compatibility requirements starting from Revision 3.0. The Port, the Cable Plug, and the Port Partner may support either revision 2 or revision 3 independently, and communication between ports, partners, and cables of different revisions are allowed under rules that the parties agree to communicate between each other using the lowest common operating revision. This may mean that Port-to-Partner operating revision comms may be different than Port-to-CablePlug operating revision comms. For example, it is possible for a R3.0 port to communicate with a R3.0 partner using R3.0 messages, while the R3.0 port (in the same session) must communicate with the R2.0 cable using R2.0 messages only. Introduce individual revision number properties for cable and port partner so that the port can track them independently. Reviewed-by: Heikki Krogerus Signed-off-by: Benson Leung Link: https://lore.kernel.org/r/20210129061406.2680146-3-bleung@chromium.org Signed-off-by: Greg Kroah-Hartman --- Documentation/ABI/testing/sysfs-class-typec | 13 +++++++++++++ drivers/usb/typec/class.c | 30 +++++++++++++++++++++++++---- include/linux/usb/typec.h | 10 ++++++++++ 3 files changed, 49 insertions(+), 4 deletions(-) (limited to 'Documentation') diff --git a/Documentation/ABI/testing/sysfs-class-typec b/Documentation/ABI/testing/sysfs-class-typec index b61480535fdc..40122d915ae1 100644 --- a/Documentation/ABI/testing/sysfs-class-typec +++ b/Documentation/ABI/testing/sysfs-class-typec @@ -112,6 +112,19 @@ Description: - "3.0": USB Power Delivery Release 3.0 - "3.1": USB Power Delivery Release 3.1 +What: /sys/class/typec/-{partner|cable}/usb_power_delivery_revision +Date: January 2021 +Contact: Benson Leung +Description: + Revision number of the supported USB Power Delivery + specification of the port partner or cable, or 0.0 when USB + Power Delivery is not supported. + + Example values: + - "2.0": USB Power Delivery Release 2.0 + - "3.0": USB Power Delivery Release 3.0 + - "3.1": USB Power Delivery Release 3.1 + What: /sys/class/typec//usb_typec_revision Date: April 2017 Contact: Heikki Krogerus diff --git a/drivers/usb/typec/class.c b/drivers/usb/typec/class.c index 4f60ee7ba76a..b5241f4756c2 100644 --- a/drivers/usb/typec/class.c +++ b/drivers/usb/typec/class.c @@ -27,6 +27,7 @@ struct typec_cable { enum typec_plug_type type; struct usb_pd_identity *identity; unsigned int active:1; + u16 pd_revision; /* 0300H = "3.0" */ }; struct typec_partner { @@ -36,6 +37,7 @@ struct typec_partner { enum typec_accessory accessory; struct ida mode_ids; int num_altmodes; + u16 pd_revision; /* 0300H = "3.0" */ }; struct typec_port { @@ -264,6 +266,11 @@ type_show(struct device *dev, struct device_attribute *attr, char *buf) } static DEVICE_ATTR_RO(type); +static ssize_t usb_power_delivery_revision_show(struct device *dev, + struct device_attribute *attr, + char *buf); +static DEVICE_ATTR_RO(usb_power_delivery_revision); + /* ------------------------------------------------------------------------- */ /* Alternate Modes */ @@ -680,6 +687,7 @@ static struct attribute *typec_partner_attrs[] = { &dev_attr_supports_usb_power_delivery.attr, &dev_attr_number_of_alternate_modes.attr, &dev_attr_type.attr, + &dev_attr_usb_power_delivery_revision.attr, NULL }; @@ -815,6 +823,7 @@ struct typec_partner *typec_register_partner(struct typec_port *port, partner->usb_pd = desc->usb_pd; partner->accessory = desc->accessory; partner->num_altmodes = -1; + partner->pd_revision = desc->pd_revision; if (desc->identity) { /* @@ -1028,6 +1037,7 @@ static DEVICE_ATTR_RO(plug_type); static struct attribute *typec_cable_attrs[] = { &dev_attr_type.attr, &dev_attr_plug_type.attr, + &dev_attr_usb_power_delivery_revision.attr, NULL }; ATTRIBUTE_GROUPS(typec_cable); @@ -1130,6 +1140,7 @@ struct typec_cable *typec_register_cable(struct typec_port *port, cable->type = desc->type; cable->active = desc->active; + cable->pd_revision = desc->pd_revision; if (desc->identity) { /* @@ -1499,12 +1510,23 @@ static ssize_t usb_power_delivery_revision_show(struct device *dev, struct device_attribute *attr, char *buf) { - struct typec_port *p = to_typec_port(dev); - u16 rev = p->cap->pd_revision; + u16 rev = 0; - return sprintf(buf, "%d.%d\n", (rev >> 8) & 0xff, (rev >> 4) & 0xf); + if (is_typec_partner(dev)) { + struct typec_partner *partner = to_typec_partner(dev); + + rev = partner->pd_revision; + } else if (is_typec_cable(dev)) { + struct typec_cable *cable = to_typec_cable(dev); + + rev = cable->pd_revision; + } else if (is_typec_port(dev)) { + struct typec_port *p = to_typec_port(dev); + + rev = p->cap->pd_revision; + } + return sysfs_emit(buf, "%d.%d\n", (rev >> 8) & 0xff, (rev >> 4) & 0xf); } -static DEVICE_ATTR_RO(usb_power_delivery_revision); static ssize_t orientation_show(struct device *dev, struct device_attribute *attr, diff --git a/include/linux/usb/typec.h b/include/linux/usb/typec.h index 54475323f83b..42c6b7c07a99 100644 --- a/include/linux/usb/typec.h +++ b/include/linux/usb/typec.h @@ -164,6 +164,7 @@ struct typec_plug_desc { * @type: The plug type from USB PD Cable VDO * @active: Is the cable active or passive * @identity: Result of Discover Identity command + * @pd_revision: USB Power Delivery Specification revision if supported * * Represents USB Type-C Cable attached to USB Type-C port. */ @@ -171,6 +172,8 @@ struct typec_cable_desc { enum typec_plug_type type; unsigned int active:1; struct usb_pd_identity *identity; + u16 pd_revision; /* 0300H = "3.0" */ + }; /* @@ -178,15 +181,22 @@ struct typec_cable_desc { * @usb_pd: USB Power Delivery support * @accessory: Audio, Debug or none. * @identity: Discover Identity command data + * @pd_revision: USB Power Delivery Specification Revision if supported * * Details about a partner that is attached to USB Type-C port. If @identity * member exists when partner is registered, a directory named "identity" is * created to sysfs for the partner device. + * + * @pd_revision is based on the setting of the "Specification Revision" field + * in the message header on the initial "Source Capabilities" message received + * from the partner, or a "Request" message received from the partner, depending + * on whether our port is a Sink or a Source. */ struct typec_partner_desc { unsigned int usb_pd:1; enum typec_accessory accessory; struct usb_pd_identity *identity; + u16 pd_revision; /* 0300H = "3.0" */ }; /** -- cgit v1.2.3 From f546ff0c0c07969f2892db10f1fe029f841ddf10 Mon Sep 17 00:00:00 2001 From: Jonathan Corbet Date: Mon, 1 Feb 2021 16:26:25 -0700 Subject: Move our minimum Sphinx version to 1.7 As promised, drop support for some ancient sphinx releases, along with a lot of the cruft that was required to make that support work. Signed-off-by: Jonathan Corbet --- Documentation/conf.py | 75 ++----------------------------------- Documentation/sphinx/cdomain.py | 8 +--- Documentation/sphinx/kernel_abi.py | 27 ++----------- Documentation/sphinx/kernel_feat.py | 25 ++----------- Documentation/sphinx/kerneldoc.py | 26 ++----------- Documentation/sphinx/kernellog.py | 26 ++++--------- 6 files changed, 21 insertions(+), 166 deletions(-) (limited to 'Documentation') diff --git a/Documentation/conf.py b/Documentation/conf.py index 6a767294887e..5bd45d5fb0a0 100644 --- a/Documentation/conf.py +++ b/Documentation/conf.py @@ -31,7 +31,7 @@ from load_config import loadConfig # -- General configuration ------------------------------------------------ # If your documentation needs a minimal Sphinx version, state it here. -needs_sphinx = '1.3' +needs_sphinx = '1.7' # Add any Sphinx extension module names here, as strings. They can be # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom @@ -112,19 +112,12 @@ if major >= 3: else: extensions.append('cdomain') - if major == 1 and minor < 7: - sys.stderr.write('WARNING: Sphinx 1.7 or greater will be required as of ' - 'the 5.12 release\n') # Ensure that autosectionlabel will produce unique names autosectionlabel_prefix_document = True autosectionlabel_maxdepth = 2 -# The name of the math extension changed on Sphinx 1.4 -if (major == 1 and minor > 3) or (major > 1): - extensions.append("sphinx.ext.imgmath") -else: - extensions.append("sphinx.ext.pngmath") +extensions.append("sphinx.ext.imgmath") # Add any paths that contain templates here, relative to this directory. templates_path = ['_templates'] @@ -375,71 +368,9 @@ if cjk_cmd.find("Noto Sans CJK SC") >= 0: ''' # Fix reference escape troubles with Sphinx 1.4.x -if major == 1 and minor > 3: +if major == 1: latex_elements['preamble'] += '\\renewcommand*{\\DUrole}[2]{ #2 }\n' -if major == 1 and minor <= 4: - latex_elements['preamble'] += '\\usepackage[margin=0.5in, top=1in, bottom=1in]{geometry}' -elif major == 1 and (minor > 5 or (minor == 5 and patch >= 3)): - latex_elements['sphinxsetup'] = 'hmargin=0.5in, vmargin=1in' - latex_elements['preamble'] += '\\fvset{fontsize=auto}\n' - -# Customize notice background colors on Sphinx < 1.6: -if major == 1 and minor < 6: - latex_elements['preamble'] += ''' - \\usepackage{ifthen} - - % Put notes in color and let them be inside a table - \\definecolor{NoteColor}{RGB}{204,255,255} - \\definecolor{WarningColor}{RGB}{255,204,204} - \\definecolor{AttentionColor}{RGB}{255,255,204} - \\definecolor{ImportantColor}{RGB}{192,255,204} - \\definecolor{OtherColor}{RGB}{204,204,204} - \\newlength{\\mynoticelength} - \\makeatletter\\newenvironment{coloredbox}[1]{% - \\setlength{\\fboxrule}{1pt} - \\setlength{\\fboxsep}{7pt} - \\setlength{\\mynoticelength}{\\linewidth} - \\addtolength{\\mynoticelength}{-2\\fboxsep} - \\addtolength{\\mynoticelength}{-2\\fboxrule} - \\begin{lrbox}{\\@tempboxa}\\begin{minipage}{\\mynoticelength}}{\\end{minipage}\\end{lrbox}% - \\ifthenelse% - {\\equal{\\py@noticetype}{note}}% - {\\colorbox{NoteColor}{\\usebox{\\@tempboxa}}}% - {% - \\ifthenelse% - {\\equal{\\py@noticetype}{warning}}% - {\\colorbox{WarningColor}{\\usebox{\\@tempboxa}}}% - {% - \\ifthenelse% - {\\equal{\\py@noticetype}{attention}}% - {\\colorbox{AttentionColor}{\\usebox{\\@tempboxa}}}% - {% - \\ifthenelse% - {\\equal{\\py@noticetype}{important}}% - {\\colorbox{ImportantColor}{\\usebox{\\@tempboxa}}}% - {\\colorbox{OtherColor}{\\usebox{\\@tempboxa}}}% - }% - }% - }% - }\\makeatother - - \\makeatletter - \\renewenvironment{notice}[2]{% - \\def\\py@noticetype{#1} - \\begin{coloredbox}{#1} - \\bf\\it - \\par\\strong{#2} - \\csname py@noticestart@#1\\endcsname - } - { - \\csname py@noticeend@\\py@noticetype\\endcsname - \\end{coloredbox} - } - \\makeatother - - ''' - # With Sphinx 1.6, it is possible to change the Bg color directly # by using: # \definecolor{sphinxnoteBgColor}{RGB}{204,255,255} diff --git a/Documentation/sphinx/cdomain.py b/Documentation/sphinx/cdomain.py index 014a5229e57a..ca8ac9e59ded 100644 --- a/Documentation/sphinx/cdomain.py +++ b/Documentation/sphinx/cdomain.py @@ -236,13 +236,7 @@ class CObject(Base_CObject): indextext = self.get_index_text(name) if indextext: - if major == 1 and minor < 4: - # indexnode's tuple changed in 1.4 - # https://github.com/sphinx-doc/sphinx/commit/e6a5a3a92e938fcd75866b4227db9e0524d58f7c - self.indexnode['entries'].append( - ('single', indextext, targetname, '')) - else: - self.indexnode['entries'].append( + self.indexnode['entries'].append( ('single', indextext, targetname, '', None)) class CDomain(Base_CDomain): diff --git a/Documentation/sphinx/kernel_abi.py b/Documentation/sphinx/kernel_abi.py index f3da859c9878..efe760e410c4 100644 --- a/Documentation/sphinx/kernel_abi.py +++ b/Documentation/sphinx/kernel_abi.py @@ -45,17 +45,7 @@ from docutils import nodes, statemachine from docutils.statemachine import ViewList from docutils.parsers.rst import directives, Directive from docutils.utils.error_reporting import ErrorString - -# -# AutodocReporter is only good up to Sphinx 1.7 -# -import sphinx - -Use_SSI = sphinx.__version__[:3] >= '1.7' -if Use_SSI: - from sphinx.util.docutils import switch_source_input -else: - from sphinx.ext.autodoc import AutodocReporter +from sphinx.util.docutils import switch_source_input __version__ = '1.0' @@ -179,16 +169,5 @@ class KernelCmd(Directive): return node.children def do_parse(self, content, node): - if Use_SSI: - with switch_source_input(self.state, content): - self.state.nested_parse(content, 0, node, match_titles=1) - else: - buf = self.state.memo.title_styles, self.state.memo.section_level, self.state.memo.reporter - - self.state.memo.title_styles = [] - self.state.memo.section_level = 0 - self.state.memo.reporter = AutodocReporter(content, self.state.memo.reporter) - try: - self.state.nested_parse(content, 0, node, match_titles=1) - finally: - self.state.memo.title_styles, self.state.memo.section_level, self.state.memo.reporter = buf + with switch_source_input(self.state, content): + self.state.nested_parse(content, 0, node, match_titles=1) diff --git a/Documentation/sphinx/kernel_feat.py b/Documentation/sphinx/kernel_feat.py index 2fee04f1dedd..c91ea2b27697 100644 --- a/Documentation/sphinx/kernel_feat.py +++ b/Documentation/sphinx/kernel_feat.py @@ -42,17 +42,7 @@ from docutils import nodes, statemachine from docutils.statemachine import ViewList from docutils.parsers.rst import directives, Directive from docutils.utils.error_reporting import ErrorString - -# -# AutodocReporter is only good up to Sphinx 1.7 -# -import sphinx - -Use_SSI = sphinx.__version__[:3] >= '1.7' -if Use_SSI: - from sphinx.util.docutils import switch_source_input -else: - from sphinx.ext.autodoc import AutodocReporter +from sphinx.util.docutils import switch_source_input __version__ = '1.0' @@ -154,16 +144,7 @@ class KernelFeat(Directive): buf = self.state.memo.title_styles, self.state.memo.section_level, self.state.memo.reporter - if Use_SSI: - with switch_source_input(self.state, content): - self.state.nested_parse(content, 0, node, match_titles=1) - else: - self.state.memo.title_styles = [] - self.state.memo.section_level = 0 - self.state.memo.reporter = AutodocReporter(content, self.state.memo.reporter) - try: - self.state.nested_parse(content, 0, node, match_titles=1) - finally: - self.state.memo.title_styles, self.state.memo.section_level, self.state.memo.reporter = buf + with switch_source_input(self.state, content): + self.state.nested_parse(content, 0, node, match_titles=1) return node.children diff --git a/Documentation/sphinx/kerneldoc.py b/Documentation/sphinx/kerneldoc.py index e9857ab904f1..8189c33b9dda 100644 --- a/Documentation/sphinx/kerneldoc.py +++ b/Documentation/sphinx/kerneldoc.py @@ -37,18 +37,8 @@ import glob from docutils import nodes, statemachine from docutils.statemachine import ViewList from docutils.parsers.rst import directives, Directive - -# -# AutodocReporter is only good up to Sphinx 1.7 -# import sphinx - -Use_SSI = sphinx.__version__[:3] >= '1.7' -if Use_SSI: - from sphinx.util.docutils import switch_source_input -else: - from sphinx.ext.autodoc import AutodocReporter - +from sphinx.util.docutils import switch_source_input import kernellog __version__ = '1.0' @@ -163,18 +153,8 @@ class KernelDocDirective(Directive): return [nodes.error(None, nodes.paragraph(text = "kernel-doc missing"))] def do_parse(self, result, node): - if Use_SSI: - with switch_source_input(self.state, result): - self.state.nested_parse(result, 0, node, match_titles=1) - else: - save = self.state.memo.title_styles, self.state.memo.section_level, self.state.memo.reporter - self.state.memo.reporter = AutodocReporter(result, self.state.memo.reporter) - self.state.memo.title_styles, self.state.memo.section_level = [], 0 - try: - self.state.nested_parse(result, 0, node, match_titles=1) - finally: - self.state.memo.title_styles, self.state.memo.section_level, self.state.memo.reporter = save - + with switch_source_input(self.state, result): + self.state.nested_parse(result, 0, node, match_titles=1) def setup(app): app.add_config_value('kerneldoc_bin', None, 'env') diff --git a/Documentation/sphinx/kernellog.py b/Documentation/sphinx/kernellog.py index 8ac7d274f542..0bc00c138cad 100644 --- a/Documentation/sphinx/kernellog.py +++ b/Documentation/sphinx/kernellog.py @@ -4,29 +4,19 @@ # only goes back to 1.6. So here's a wrapper layer to keep around for # as long as we support 1.4. # +# We don't support 1.4 anymore, but we'll keep the wrappers around until +# we change all the code to not use them anymore :) +# import sphinx +from sphinx.util import logging -if sphinx.__version__[:3] >= '1.6': - UseLogging = True - from sphinx.util import logging - logger = logging.getLogger('kerneldoc') -else: - UseLogging = False +logger = logging.getLogger('kerneldoc') def warn(app, message): - if UseLogging: - logger.warning(message) - else: - app.warn(message) + logger.warning(message) def verbose(app, message): - if UseLogging: - logger.verbose(message) - else: - app.verbose(message) + logger.verbose(message) def info(app, message): - if UseLogging: - logger.info(message) - else: - app.info(message) + logger.info(message) -- cgit v1.2.3 From 4217e5074f33d855873370378d427e329b60a7b4 Mon Sep 17 00:00:00 2001 From: Jonathan Corbet Date: Mon, 1 Feb 2021 17:17:14 -0700 Subject: Docs: drop Python 2 support The kernel build system as a whole is dropping support for Python 2, so we should do the same. The effects are rather small, especially considering that much of the deleted code was not doing anything under any version of Python anyway. Signed-off-by: Jonathan Corbet --- Documentation/sphinx/kfigure.py | 14 +------------- Documentation/sphinx/maintainers_include.py | 2 -- Documentation/sphinx/requirements.txt | 1 - Documentation/sphinx/rstFlatTable.py | 10 ---------- scripts/sphinx-pre-install | 4 ++-- 5 files changed, 3 insertions(+), 28 deletions(-) (limited to 'Documentation') diff --git a/Documentation/sphinx/kfigure.py b/Documentation/sphinx/kfigure.py index 788704886eec..3c78828330be 100644 --- a/Documentation/sphinx/kfigure.py +++ b/Documentation/sphinx/kfigure.py @@ -49,26 +49,14 @@ import os from os import path import subprocess from hashlib import sha1 -import sys - from docutils import nodes from docutils.statemachine import ViewList from docutils.parsers.rst import directives from docutils.parsers.rst.directives import images import sphinx - from sphinx.util.nodes import clean_astext -from six import iteritems - import kernellog -PY3 = sys.version_info[0] == 3 - -if PY3: - _unicode = str -else: - _unicode = unicode - # Get Sphinx version major, minor, patch = sphinx.version_info[:3] if major == 1 and minor > 3: @@ -540,7 +528,7 @@ def add_kernel_figure_to_std_domain(app, doctree): docname = app.env.docname labels = std.data["labels"] - for name, explicit in iteritems(doctree.nametypes): + for name, explicit in doctree.nametypes.items(): if not explicit: continue labelid = doctree.nameids[name] diff --git a/Documentation/sphinx/maintainers_include.py b/Documentation/sphinx/maintainers_include.py index dc8fed48d3c2..328b3631a585 100755 --- a/Documentation/sphinx/maintainers_include.py +++ b/Documentation/sphinx/maintainers_include.py @@ -61,8 +61,6 @@ class MaintainersInclude(Include): field_content = "" for line in open(path): - if sys.version_info.major == 2: - line = unicode(line, 'utf-8') # Have we reached the end of the preformatted Descriptions text? if descriptions and line.startswith('Maintainers'): descriptions = False diff --git a/Documentation/sphinx/requirements.txt b/Documentation/sphinx/requirements.txt index 5030d346d23b..489f6626de67 100644 --- a/Documentation/sphinx/requirements.txt +++ b/Documentation/sphinx/requirements.txt @@ -1,4 +1,3 @@ docutils Sphinx==2.4.4 sphinx_rtd_theme -six diff --git a/Documentation/sphinx/rstFlatTable.py b/Documentation/sphinx/rstFlatTable.py index 2019a55f6b18..a3eea0bbe6ba 100755 --- a/Documentation/sphinx/rstFlatTable.py +++ b/Documentation/sphinx/rstFlatTable.py @@ -42,8 +42,6 @@ u""" # imports # ============================================================================== -import sys - from docutils import nodes from docutils.parsers.rst import directives, roles from docutils.parsers.rst.directives.tables import Table @@ -55,14 +53,6 @@ from docutils.utils import SystemMessagePropagation __version__ = '1.0' -PY3 = sys.version_info[0] == 3 -PY2 = sys.version_info[0] == 2 - -if PY3: - # pylint: disable=C0103, W0622 - unicode = str - basestring = str - # ============================================================================== def setup(app): # ============================================================================== diff --git a/scripts/sphinx-pre-install b/scripts/sphinx-pre-install index 828a8615a918..b5f9fd5b2880 100755 --- a/scripts/sphinx-pre-install +++ b/scripts/sphinx-pre-install @@ -728,8 +728,8 @@ sub check_needs() $need_virtualenv = 1; } if ($1 < 3) { - # Complain if it finds python2 (or worse) - printf "Warning: python$1 support is deprecated. Use it with caution!\n"; + # Fail if it finds python2 (or worse) + die "Python 3 is required to build the kernel docs\n"; } } else { die "Warning: couldn't identify $python_cmd version!"; -- cgit v1.2.3 From 31628201545548e1ef167f2c55eb6fd7d3562f12 Mon Sep 17 00:00:00 2001 From: Vincent Bernat Date: Sat, 30 Jan 2021 20:05:18 +0100 Subject: docs: networking: swap words in icmp_errors_use_inbound_ifaddr doc Signed-off-by: Vincent Bernat Link: https://lore.kernel.org/r/20210130190518.854806-1-vincent@bernat.ch Signed-off-by: Jakub Kicinski --- Documentation/networking/ip-sysctl.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Documentation') diff --git a/Documentation/networking/ip-sysctl.rst b/Documentation/networking/ip-sysctl.rst index c7b775da9554..fa544e9037b9 100644 --- a/Documentation/networking/ip-sysctl.rst +++ b/Documentation/networking/ip-sysctl.rst @@ -1196,7 +1196,7 @@ icmp_errors_use_inbound_ifaddr - BOOLEAN If non-zero, the message will be sent with the primary address of the interface that received the packet that caused the icmp error. - This is the behaviour network many administrators will expect from + This is the behaviour many network administrators will expect from a router. And it can make debugging complicated network layouts much easier. -- cgit v1.2.3 From 2d670ea2bd53a9792f453bb5b97cb8ef695988ff Mon Sep 17 00:00:00 2001 From: Hui Wang Date: Wed, 27 Jan 2021 16:56:39 +0800 Subject: ALSA: jack: implement software jack injection via debugfs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This change adds audio jack injection feature through debugfs, with this feature, we could validate alsa userspace changes by injecting plugin or plugout events to the non-phantom audio jacks. With this change, the sound core will build the folders $debugfs_mount_dir/sound/cardN if SND_DEBUG and DEBUG_FS are enabled. And if users also enable the SND_JACK_INJECTION_DEBUG, the jack injection nodes will be built in the folder cardN like below: $tree $debugfs_mount_dir/sound $debugfs_mount_dir/sound ├── card0 │   ├── HDMI_DP_pcm_10_Jack │   │   ├── jackin_inject │   │   ├── kctl_id │   │   ├── mask_bits │   │   ├── status │   │   ├── sw_inject_enable │   │   └── type ... │   └── HDMI_DP_pcm_9_Jack │   ├── jackin_inject │   ├── kctl_id │   ├── mask_bits │   ├── status │   ├── sw_inject_enable │   └── type └── card1 ├── HDMI_DP_pcm_5_Jack │   ├── jackin_inject │   ├── kctl_id │   ├── mask_bits │   ├── status │   ├── sw_inject_enable │   └── type ... ├── Headphone_Jack │   ├── jackin_inject │   ├── kctl_id │   ├── mask_bits │   ├── status │   ├── sw_inject_enable │   └── type └── Headset_Mic_Jack ├── jackin_inject ├── kctl_id ├── mask_bits ├── status ├── sw_inject_enable └── type The nodes kctl_id, mask_bits, status and type are read-only, users could check jack or jack_kctl's information through them. The nodes sw_inject_enable and jackin_inject are directly used for injection. The sw_inject_enable is read-write, users could check if software injection is enabled or not on this jack, and users could echo 1 or 0 to enable or disable software injection on this jack. Once the injection is enabled, the jack will not change by hardware events anymore, once the injection is disabled, the jack will restore the last reported hardware events to the jack. The jackin_inject is write-only, if the injection is enabled, users could echo 1 or 0 to this node to inject plugin or plugout events to this jack. For the detailed usage information on these nodes, please refer to Documentation/sound/designs/jack-injection.rst. Reviewed-by: Takashi Iwai Reviewed-by: Jaroslav Kysela Reviewed-by: Kai Vehmanen Signed-off-by: Hui Wang Link: https://lore.kernel.org/r/20210127085639.74954-2-hui.wang@canonical.com Signed-off-by: Takashi Iwai --- Documentation/sound/designs/index.rst | 1 + Documentation/sound/designs/jack-injection.rst | 166 ++++++++++++++ include/sound/core.h | 6 + include/sound/jack.h | 1 + sound/core/Kconfig | 9 + sound/core/init.c | 16 ++ sound/core/jack.c | 304 ++++++++++++++++++++++++- sound/core/sound.c | 13 ++ 8 files changed, 512 insertions(+), 4 deletions(-) create mode 100644 Documentation/sound/designs/jack-injection.rst (limited to 'Documentation') diff --git a/Documentation/sound/designs/index.rst b/Documentation/sound/designs/index.rst index f0749943ccb2..1eb08e7bae52 100644 --- a/Documentation/sound/designs/index.rst +++ b/Documentation/sound/designs/index.rst @@ -14,3 +14,4 @@ Designs and Implementations powersave oss-emulation seq-oss + jack-injection diff --git a/Documentation/sound/designs/jack-injection.rst b/Documentation/sound/designs/jack-injection.rst new file mode 100644 index 000000000000..f9790521523e --- /dev/null +++ b/Documentation/sound/designs/jack-injection.rst @@ -0,0 +1,166 @@ +============================ +ALSA Jack Software Injection +============================ + +Simple Introduction On Jack Injection +===================================== + +Here jack injection means users could inject plugin or plugout events +to the audio jacks through debugfs interface, it is helpful to +validate ALSA userspace changes. For example, we change the audio +profile switching code in the pulseaudio, and we want to verify if the +change works as expected and if the change introduce the regression, +in this case, we could inject plugin or plugout events to an audio +jack or to some audio jacks, we don't need to physically access the +machine and plug/unplug physical devices to the audio jack. + +In this design, an audio jack doesn't equal to a physical audio jack. +Sometimes a physical audio jack contains multi functions, and the +ALSA driver creates multi ``jack_kctl`` for a ``snd_jack``, here the +``snd_jack`` represents a physical audio jack and the ``jack_kctl`` +represents a function, for example a physical jack has two functions: +headphone and mic_in, the ALSA ASoC driver will build 2 ``jack_kctl`` +for this jack. The jack injection is implemented based on the +``jack_kctl`` instead of ``snd_jack``. + +To inject events to audio jacks, we need to enable the jack injection +via ``sw_inject_enable`` first, once it is enabled, this jack will not +change the state by hardware events anymore, we could inject plugin or +plugout events via ``jackin_inject`` and check the jack state via +``status``, after we finish our test, we need to disable the jack +injection via ``sw_inject_enable`` too, once it is disabled, the jack +state will be restored according to the last reported hardware events +and will change by future hardware events. + +The Layout of Jack Injection Interface +====================================== + +If users enable the SND_JACK_INJECTION_DEBUG in the kernel, the audio +jack injection interface will be created as below: +:: + + $debugfs_mount_dir/sound + |-- card0 + |-- |-- HDMI_DP_pcm_10_Jack + |-- |-- |-- jackin_inject + |-- |-- |-- kctl_id + |-- |-- |-- mask_bits + |-- |-- |-- status + |-- |-- |-- sw_inject_enable + |-- |-- |-- type + ... + |-- |-- HDMI_DP_pcm_9_Jack + |-- |-- jackin_inject + |-- |-- kctl_id + |-- |-- mask_bits + |-- |-- status + |-- |-- sw_inject_enable + |-- |-- type + |-- card1 + |-- HDMI_DP_pcm_5_Jack + |-- |-- jackin_inject + |-- |-- kctl_id + |-- |-- mask_bits + |-- |-- status + |-- |-- sw_inject_enable + |-- |-- type + ... + |-- Headphone_Jack + |-- |-- jackin_inject + |-- |-- kctl_id + |-- |-- mask_bits + |-- |-- status + |-- |-- sw_inject_enable + |-- |-- type + |-- Headset_Mic_Jack + |-- jackin_inject + |-- kctl_id + |-- mask_bits + |-- status + |-- sw_inject_enable + |-- type + +The Explanation Of The Nodes +====================================== + +kctl_id + read-only, get jack_kctl->kctl's id + :: + + sound/card1/Headphone_Jack# cat kctl_id + Headphone Jack + +mask_bits + read-only, get jack_kctl's supported events mask_bits + :: + + sound/card1/Headphone_Jack# cat mask_bits + 0x0001 HEADPHONE(0x0001) + +status + read-only, get jack_kctl's current status + +- headphone unplugged: + + :: + + sound/card1/Headphone_Jack# cat status + Unplugged + +- headphone plugged: + + :: + + sound/card1/Headphone_Jack# cat status + Plugged + +type + read-only, get snd_jack's supported events from type (all supported events on the physical audio jack) + :: + + sound/card1/Headphone_Jack# cat type + 0x7803 HEADPHONE(0x0001) MICROPHONE(0x0002) BTN_3(0x0800) BTN_2(0x1000) BTN_1(0x2000) BTN_0(0x4000) + +sw_inject_enable + read-write, enable or disable injection + +- injection disabled: + + :: + + sound/card1/Headphone_Jack# cat sw_inject_enable + Jack: Headphone Jack Inject Enabled: 0 + +- injection enabled: + + :: + + sound/card1/Headphone_Jack# cat sw_inject_enable + Jack: Headphone Jack Inject Enabled: 1 + +- to enable jack injection: + + :: + + sound/card1/Headphone_Jack# echo 1 > sw_inject_enable + +- to disable jack injection: + + :: + + sound/card1/Headphone_Jack# echo 0 > sw_inject_enable + +jackin_inject + write-only, inject plugin or plugout + +- to inject plugin: + + :: + + sound/card1/Headphone_Jack# echo 1 > jackin_inject + +- to inject plugout: + + :: + + sound/card1/Headphone_Jack# echo 0 > jackin_inject diff --git a/include/sound/core.h b/include/sound/core.h index 0462c577d7a3..2e24f194ef70 100644 --- a/include/sound/core.h +++ b/include/sound/core.h @@ -122,6 +122,9 @@ struct snd_card { size_t total_pcm_alloc_bytes; /* total amount of allocated buffers */ struct mutex memory_mutex; /* protection for the above */ +#ifdef CONFIG_SND_DEBUG + struct dentry *debugfs_root; /* debugfs root for card */ +#endif #ifdef CONFIG_PM unsigned int power_state; /* power state */ @@ -180,6 +183,9 @@ static inline struct device *snd_card_get_device_link(struct snd_card *card) extern int snd_major; extern int snd_ecards_limit; extern struct class *sound_class; +#ifdef CONFIG_SND_DEBUG +extern struct dentry *sound_debugfs_root; +#endif void snd_request_card(int card); diff --git a/include/sound/jack.h b/include/sound/jack.h index 9eb2b5ec1ec4..1181f536557e 100644 --- a/include/sound/jack.h +++ b/include/sound/jack.h @@ -67,6 +67,7 @@ struct snd_jack { char name[100]; unsigned int key[6]; /* Keep in sync with definitions above */ #endif /* CONFIG_SND_JACK_INPUT_DEV */ + int hw_status_cache; void *private_data; void (*private_free)(struct snd_jack *); }; diff --git a/sound/core/Kconfig b/sound/core/Kconfig index d4554f376160..a4050f87f230 100644 --- a/sound/core/Kconfig +++ b/sound/core/Kconfig @@ -187,6 +187,15 @@ config SND_CTL_VALIDATION from the driver are in the proper ranges or the check of the invalid access at out-of-array areas. +config SND_JACK_INJECTION_DEBUG + bool "Sound jack injection interface via debugfs" + depends on SND_JACK && SND_DEBUG && DEBUG_FS + help + This option can be used to enable or disable sound jack + software injection. + Say Y if you are debugging via jack injection interface. + If unsure select "N". + config SND_VMASTER bool diff --git a/sound/core/init.c b/sound/core/init.c index 56834febc7a4..d4e78b176793 100644 --- a/sound/core/init.c +++ b/sound/core/init.c @@ -13,6 +13,7 @@ #include #include #include +#include #include #include @@ -161,6 +162,9 @@ int snd_card_new(struct device *parent, int idx, const char *xid, { struct snd_card *card; int err; +#ifdef CONFIG_SND_DEBUG + char name[8]; +#endif if (snd_BUG_ON(!card_ret)) return -EINVAL; @@ -244,6 +248,12 @@ int snd_card_new(struct device *parent, int idx, const char *xid, dev_err(parent, "unable to create card info\n"); goto __error_ctl; } + +#ifdef CONFIG_SND_DEBUG + sprintf(name, "card%d", idx); + card->debugfs_root = debugfs_create_dir(name, sound_debugfs_root); +#endif + *card_ret = card; return 0; @@ -526,6 +536,12 @@ int snd_card_free(struct snd_card *card) return ret; /* wait, until all devices are ready for the free operation */ wait_for_completion(&released); + +#ifdef CONFIG_SND_DEBUG + debugfs_remove(card->debugfs_root); + card->debugfs_root = NULL; +#endif + return 0; } EXPORT_SYMBOL(snd_card_free); diff --git a/sound/core/jack.c b/sound/core/jack.c index 503c8af79d55..32350c6aba84 100644 --- a/sound/core/jack.c +++ b/sound/core/jack.c @@ -8,6 +8,9 @@ #include #include #include +#include +#include +#include #include #include #include @@ -16,6 +19,11 @@ struct snd_jack_kctl { struct snd_kcontrol *kctl; struct list_head list; /* list of controls belong to the same jack */ unsigned int mask_bits; /* only masked status bits are reported via kctl */ + struct snd_jack *jack; /* pointer to struct snd_jack */ + bool sw_inject_enable; /* allow to inject plug event via debugfs */ +#ifdef CONFIG_SND_JACK_INJECTION_DEBUG + struct dentry *jack_debugfs_root; /* jack_kctl debugfs root */ +#endif }; #ifdef CONFIG_SND_JACK_INPUT_DEV @@ -109,12 +117,291 @@ static int snd_jack_dev_register(struct snd_device *device) } #endif /* CONFIG_SND_JACK_INPUT_DEV */ +#ifdef CONFIG_SND_JACK_INJECTION_DEBUG +static void snd_jack_inject_report(struct snd_jack_kctl *jack_kctl, int status) +{ + struct snd_jack *jack; +#ifdef CONFIG_SND_JACK_INPUT_DEV + int i; +#endif + if (!jack_kctl) + return; + + jack = jack_kctl->jack; + + if (jack_kctl->sw_inject_enable) + snd_kctl_jack_report(jack->card, jack_kctl->kctl, + status & jack_kctl->mask_bits); + +#ifdef CONFIG_SND_JACK_INPUT_DEV + if (!jack->input_dev) + return; + + for (i = 0; i < ARRAY_SIZE(jack->key); i++) { + int testbit = ((SND_JACK_BTN_0 >> i) & jack_kctl->mask_bits); + + if (jack->type & testbit) + input_report_key(jack->input_dev, jack->key[i], + status & testbit); + } + + for (i = 0; i < ARRAY_SIZE(jack_switch_types); i++) { + int testbit = ((1 << i) & jack_kctl->mask_bits); + + if (jack->type & testbit) + input_report_switch(jack->input_dev, + jack_switch_types[i], + status & testbit); + } + + input_sync(jack->input_dev); +#endif /* CONFIG_SND_JACK_INPUT_DEV */ +} + +static ssize_t sw_inject_enable_read(struct file *file, + char __user *to, size_t count, loff_t *ppos) +{ + struct snd_jack_kctl *jack_kctl = file->private_data; + int len, ret; + char buf[128]; + + len = scnprintf(buf, sizeof(buf), "%s: %s\t\t%s: %i\n", "Jack", jack_kctl->kctl->id.name, + "Inject Enabled", jack_kctl->sw_inject_enable); + ret = simple_read_from_buffer(to, count, ppos, buf, len); + + return ret; +} + +static ssize_t sw_inject_enable_write(struct file *file, + const char __user *from, size_t count, loff_t *ppos) +{ + struct snd_jack_kctl *jack_kctl = file->private_data; + int ret, err; + unsigned long enable; + char buf[8] = { 0 }; + + ret = simple_write_to_buffer(buf, sizeof(buf) - 1, ppos, from, count); + err = kstrtoul(buf, 0, &enable); + if (err) + return err; + + if (jack_kctl->sw_inject_enable == (!!enable)) + return ret; + + jack_kctl->sw_inject_enable = !!enable; + + if (!jack_kctl->sw_inject_enable) + snd_jack_report(jack_kctl->jack, jack_kctl->jack->hw_status_cache); + + return ret; +} + +static ssize_t jackin_inject_write(struct file *file, + const char __user *from, size_t count, loff_t *ppos) +{ + struct snd_jack_kctl *jack_kctl = file->private_data; + int ret, err; + unsigned long enable; + char buf[8] = { 0 }; + + if (!jack_kctl->sw_inject_enable) + return -EINVAL; + + ret = simple_write_to_buffer(buf, sizeof(buf) - 1, ppos, from, count); + err = kstrtoul(buf, 0, &enable); + if (err) + return err; + + snd_jack_inject_report(jack_kctl, !!enable ? jack_kctl->mask_bits : 0); + + return ret; +} + +static ssize_t jack_kctl_id_read(struct file *file, + char __user *to, size_t count, loff_t *ppos) +{ + struct snd_jack_kctl *jack_kctl = file->private_data; + char buf[64]; + int len, ret; + + len = scnprintf(buf, sizeof(buf), "%s\n", jack_kctl->kctl->id.name); + ret = simple_read_from_buffer(to, count, ppos, buf, len); + + return ret; +} + +/* the bit definition is aligned with snd_jack_types in jack.h */ +static const char * const jack_events_name[] = { + "HEADPHONE(0x0001)", "MICROPHONE(0x0002)", "LINEOUT(0x0004)", + "MECHANICAL(0x0008)", "VIDEOOUT(0x0010)", "LINEIN(0x0020)", + "", "", "", "BTN_5(0x0200)", "BTN_4(0x0400)", "BTN_3(0x0800)", + "BTN_2(0x1000)", "BTN_1(0x2000)", "BTN_0(0x4000)", "", +}; + +/* the recommended buffer size is 256 */ +static int parse_mask_bits(unsigned int mask_bits, char *buf, size_t buf_size) +{ + int i; + + scnprintf(buf, buf_size, "0x%04x", mask_bits); + + for (i = 0; i < ARRAY_SIZE(jack_events_name); i++) + if (mask_bits & (1 << i)) { + strlcat(buf, " ", buf_size); + strlcat(buf, jack_events_name[i], buf_size); + } + strlcat(buf, "\n", buf_size); + + return strlen(buf); +} + +static ssize_t jack_kctl_mask_bits_read(struct file *file, + char __user *to, size_t count, loff_t *ppos) +{ + struct snd_jack_kctl *jack_kctl = file->private_data; + char buf[256]; + int len, ret; + + len = parse_mask_bits(jack_kctl->mask_bits, buf, sizeof(buf)); + ret = simple_read_from_buffer(to, count, ppos, buf, len); + + return ret; +} + +static ssize_t jack_kctl_status_read(struct file *file, + char __user *to, size_t count, loff_t *ppos) +{ + struct snd_jack_kctl *jack_kctl = file->private_data; + char buf[16]; + int len, ret; + + len = scnprintf(buf, sizeof(buf), "%s\n", jack_kctl->kctl->private_value ? + "Plugged" : "Unplugged"); + ret = simple_read_from_buffer(to, count, ppos, buf, len); + + return ret; +} + +#ifdef CONFIG_SND_JACK_INPUT_DEV +static ssize_t jack_type_read(struct file *file, + char __user *to, size_t count, loff_t *ppos) +{ + struct snd_jack_kctl *jack_kctl = file->private_data; + char buf[256]; + int len, ret; + + len = parse_mask_bits(jack_kctl->jack->type, buf, sizeof(buf)); + ret = simple_read_from_buffer(to, count, ppos, buf, len); + + return ret; +} + +static const struct file_operations jack_type_fops = { + .open = simple_open, + .read = jack_type_read, + .llseek = default_llseek, +}; +#endif + +static const struct file_operations sw_inject_enable_fops = { + .open = simple_open, + .read = sw_inject_enable_read, + .write = sw_inject_enable_write, + .llseek = default_llseek, +}; + +static const struct file_operations jackin_inject_fops = { + .open = simple_open, + .write = jackin_inject_write, + .llseek = default_llseek, +}; + +static const struct file_operations jack_kctl_id_fops = { + .open = simple_open, + .read = jack_kctl_id_read, + .llseek = default_llseek, +}; + +static const struct file_operations jack_kctl_mask_bits_fops = { + .open = simple_open, + .read = jack_kctl_mask_bits_read, + .llseek = default_llseek, +}; + +static const struct file_operations jack_kctl_status_fops = { + .open = simple_open, + .read = jack_kctl_status_read, + .llseek = default_llseek, +}; + +static int snd_jack_debugfs_add_inject_node(struct snd_jack *jack, + struct snd_jack_kctl *jack_kctl) +{ + char *tname; + int i; + + /* Don't create injection interface for Phantom jacks */ + if (strstr(jack_kctl->kctl->id.name, "Phantom")) + return 0; + + tname = kstrdup(jack_kctl->kctl->id.name, GFP_KERNEL); + if (!tname) + return -ENOMEM; + + /* replace the chars which are not suitable for folder's name with _ */ + for (i = 0; tname[i]; i++) + if (!isalnum(tname[i])) + tname[i] = '_'; + + jack_kctl->jack_debugfs_root = debugfs_create_dir(tname, jack->card->debugfs_root); + kfree(tname); + + debugfs_create_file("sw_inject_enable", 0644, jack_kctl->jack_debugfs_root, jack_kctl, + &sw_inject_enable_fops); + + debugfs_create_file("jackin_inject", 0200, jack_kctl->jack_debugfs_root, jack_kctl, + &jackin_inject_fops); + + debugfs_create_file("kctl_id", 0444, jack_kctl->jack_debugfs_root, jack_kctl, + &jack_kctl_id_fops); + + debugfs_create_file("mask_bits", 0444, jack_kctl->jack_debugfs_root, jack_kctl, + &jack_kctl_mask_bits_fops); + + debugfs_create_file("status", 0444, jack_kctl->jack_debugfs_root, jack_kctl, + &jack_kctl_status_fops); + +#ifdef CONFIG_SND_JACK_INPUT_DEV + debugfs_create_file("type", 0444, jack_kctl->jack_debugfs_root, jack_kctl, + &jack_type_fops); +#endif + return 0; +} + +static void snd_jack_debugfs_clear_inject_node(struct snd_jack_kctl *jack_kctl) +{ + debugfs_remove(jack_kctl->jack_debugfs_root); + jack_kctl->jack_debugfs_root = NULL; +} +#else /* CONFIG_SND_JACK_INJECTION_DEBUG */ +static int snd_jack_debugfs_add_inject_node(struct snd_jack *jack, + struct snd_jack_kctl *jack_kctl) +{ + return 0; +} + +static void snd_jack_debugfs_clear_inject_node(struct snd_jack_kctl *jack_kctl) +{ +} +#endif /* CONFIG_SND_JACK_INJECTION_DEBUG */ + static void snd_jack_kctl_private_free(struct snd_kcontrol *kctl) { struct snd_jack_kctl *jack_kctl; jack_kctl = kctl->private_data; if (jack_kctl) { + snd_jack_debugfs_clear_inject_node(jack_kctl); list_del(&jack_kctl->list); kfree(jack_kctl); } @@ -122,7 +409,9 @@ static void snd_jack_kctl_private_free(struct snd_kcontrol *kctl) static void snd_jack_kctl_add(struct snd_jack *jack, struct snd_jack_kctl *jack_kctl) { + jack_kctl->jack = jack; list_add_tail(&jack_kctl->list, &jack->kctl_list); + snd_jack_debugfs_add_inject_node(jack, jack_kctl); } static struct snd_jack_kctl * snd_jack_kctl_new(struct snd_card *card, const char *name, unsigned int mask) @@ -340,6 +629,7 @@ EXPORT_SYMBOL(snd_jack_set_key); void snd_jack_report(struct snd_jack *jack, int status) { struct snd_jack_kctl *jack_kctl; + unsigned int mask_bits = 0; #ifdef CONFIG_SND_JACK_INPUT_DEV int i; #endif @@ -347,16 +637,21 @@ void snd_jack_report(struct snd_jack *jack, int status) if (!jack) return; + jack->hw_status_cache = status; + list_for_each_entry(jack_kctl, &jack->kctl_list, list) - snd_kctl_jack_report(jack->card, jack_kctl->kctl, - status & jack_kctl->mask_bits); + if (jack_kctl->sw_inject_enable) + mask_bits |= jack_kctl->mask_bits; + else + snd_kctl_jack_report(jack->card, jack_kctl->kctl, + status & jack_kctl->mask_bits); #ifdef CONFIG_SND_JACK_INPUT_DEV if (!jack->input_dev) return; for (i = 0; i < ARRAY_SIZE(jack->key); i++) { - int testbit = SND_JACK_BTN_0 >> i; + int testbit = ((SND_JACK_BTN_0 >> i) & ~mask_bits); if (jack->type & testbit) input_report_key(jack->input_dev, jack->key[i], @@ -364,7 +659,8 @@ void snd_jack_report(struct snd_jack *jack, int status) } for (i = 0; i < ARRAY_SIZE(jack_switch_types); i++) { - int testbit = 1 << i; + int testbit = ((1 << i) & ~mask_bits); + if (jack->type & testbit) input_report_switch(jack->input_dev, jack_switch_types[i], diff --git a/sound/core/sound.c b/sound/core/sound.c index b75f78f2c4b8..2f759febe365 100644 --- a/sound/core/sound.c +++ b/sound/core/sound.c @@ -9,6 +9,7 @@ #include #include #include +#include #include #include #include @@ -39,6 +40,11 @@ MODULE_ALIAS_CHARDEV_MAJOR(CONFIG_SND_MAJOR); int snd_ecards_limit; EXPORT_SYMBOL(snd_ecards_limit); +#ifdef CONFIG_SND_DEBUG +struct dentry *sound_debugfs_root; +EXPORT_SYMBOL_GPL(sound_debugfs_root); +#endif + static struct snd_minor *snd_minors[SNDRV_OS_MINORS]; static DEFINE_MUTEX(sound_mutex); @@ -395,6 +401,10 @@ static int __init alsa_sound_init(void) unregister_chrdev(major, "alsa"); return -ENOMEM; } + +#ifdef CONFIG_SND_DEBUG + sound_debugfs_root = debugfs_create_dir("sound", NULL); +#endif #ifndef MODULE pr_info("Advanced Linux Sound Architecture Driver Initialized.\n"); #endif @@ -403,6 +413,9 @@ static int __init alsa_sound_init(void) static void __exit alsa_sound_exit(void) { +#ifdef CONFIG_SND_DEBUG + debugfs_remove(sound_debugfs_root); +#endif snd_info_done(); unregister_chrdev(major, "alsa"); } -- cgit v1.2.3 From a78b96fe95019d5e21f39ac1f2bb764e9c130bfc Mon Sep 17 00:00:00 2001 From: Lukas Bulwahn Date: Fri, 29 Jan 2021 05:08:49 +0100 Subject: platform/x86: thinkpad_acpi: rectify length of title underline Commit d7cbe2773aed ("platform/x86: thinkpad_acpi: set keyboard language") adds information on keyboard setting to the thinkpad documentation, but made the subsection title underline too short. Hence, make htmldocs warns: Documentation/admin-guide/laptops/thinkpad-acpi.rst:1472: \ WARNING: Title underline too short. Rectify length of subsection title underline. Signed-off-by: Lukas Bulwahn Link: https://lore.kernel.org/r/20210129040849.26740-1-lukas.bulwahn@gmail.com Signed-off-by: Hans de Goede --- Documentation/admin-guide/laptops/thinkpad-acpi.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Documentation') diff --git a/Documentation/admin-guide/laptops/thinkpad-acpi.rst b/Documentation/admin-guide/laptops/thinkpad-acpi.rst index b1188f05a99a..0e4c5bb7fb70 100644 --- a/Documentation/admin-guide/laptops/thinkpad-acpi.rst +++ b/Documentation/admin-guide/laptops/thinkpad-acpi.rst @@ -1469,7 +1469,7 @@ Sysfs notes Setting keyboard language -------------------- +------------------------- sysfs: keyboard_lang -- cgit v1.2.3 From cfa75cca618ef35cbbc05ff74ca9af6c7ff274ea Mon Sep 17 00:00:00 2001 From: Nitin Joshi Date: Tue, 2 Feb 2021 09:32:10 +0900 Subject: platform/x86: thinkpad_acpi: fixed warning and incorporated review comments The previous commit adding new sysfs for keyboard language has warning and few code correction has to be done as per new review comments. Below changes has been addressed in this version: - corrected warning. Many thanks to kernel test robot for reporting and determining this warning. - used sysfs_emit_at() API instead of strcat. - sorted keyboard language array. - removed unwanted space and corrected sentences. Reported-by: kernel test robot Signed-off-by: Nitin Joshi Reviewed-by: Hans de Goede Link: https://lore.kernel.org/r/20210202003210.91773-1-njoshi1@lenovo.com Signed-off-by: Hans de Goede --- .../admin-guide/laptops/thinkpad-acpi.rst | 15 +++++----- drivers/platform/x86/thinkpad_acpi.c | 33 ++++++++-------------- 2 files changed, 19 insertions(+), 29 deletions(-) (limited to 'Documentation') diff --git a/Documentation/admin-guide/laptops/thinkpad-acpi.rst b/Documentation/admin-guide/laptops/thinkpad-acpi.rst index 0e4c5bb7fb70..91fd6846ce17 100644 --- a/Documentation/admin-guide/laptops/thinkpad-acpi.rst +++ b/Documentation/admin-guide/laptops/thinkpad-acpi.rst @@ -1476,18 +1476,19 @@ sysfs: keyboard_lang This feature is used to set keyboard language to ECFW using ASL interface. Fewer thinkpads models like T580 , T590 , T15 Gen 1 etc.. has "=", "(', ")" numeric keys, which are not displaying correctly, when keyboard language -is other than "english". This is because of default keyboard language in ECFW -is set as "english". Hence using this sysfs, user can set correct keyboard -language to ECFW and then these key's will work correctly . +is other than "english". This is because the default keyboard language in ECFW +is set as "english". Hence using this sysfs, user can set the correct keyboard +language to ECFW and then these key's will work correctly. Example of command to set keyboard language is mentioned below:: echo jp > /sys/devices/platform/thinkpad_acpi/keyboard_lang -Text corresponding to keyboard layout to be set in sysfs are : jp (Japan), be(Belgian), -cz(Czech), en(English), da(Danish), de(German), es(Spain) , et(Estonian), -fr(French) , fr-ch (French(Switzerland)), pl(Polish), sl(Slovenian), hu -(Hungarian), nl(Dutch), tr(Turkey), it(Italy), sv(Sweden), pt(portugese) +Text corresponding to keyboard layout to be set in sysfs are: be(Belgian), +cz(Czech), da(Danish), de(German), en(English), es(Spain), et(Estonian), +fr(French), fr-ch(French(Switzerland)), hu(Hungarian), it(Italy), jp (Japan), +nl(Dutch), nn(Norway), pl(Polish), pt(portugese), sl(Slovenian), sv(Sweden), +tr(Turkey) Adaptive keyboard diff --git a/drivers/platform/x86/thinkpad_acpi.c b/drivers/platform/x86/thinkpad_acpi.c index 4a1dba3099a6..48575efb5ae8 100644 --- a/drivers/platform/x86/thinkpad_acpi.c +++ b/drivers/platform/x86/thinkpad_acpi.c @@ -9992,16 +9992,12 @@ struct keyboard_lang_data { int lang_code; }; -/* - * When adding new entries to keyboard_lang_data, please check that - * the select_lang[] buffer in keyboard_lang_show() is still large enough. - */ -struct keyboard_lang_data keyboard_lang_data[] = { - {"en", 0}, +static const struct keyboard_lang_data keyboard_lang_data[] = { {"be", 0x080c}, {"cz", 0x0405}, {"da", 0x0406}, {"de", 0x0c07}, + {"en", 0x0000}, {"es", 0x2c0a}, {"et", 0x0425}, {"fr", 0x040c}, @@ -10064,9 +10060,7 @@ static ssize_t keyboard_lang_show(struct device *dev, struct device_attribute *attr, char *buf) { - int output, err, i; - char select_lang[80] = ""; - char lang[8] = ""; + int output, err, i, len = 0; err = get_keyboard_lang(&output); if (err) @@ -10074,19 +10068,17 @@ static ssize_t keyboard_lang_show(struct device *dev, for (i = 0; i < ARRAY_SIZE(keyboard_lang_data); i++) { if (i) - strcat(select_lang, " "); + len += sysfs_emit_at(buf, len, "%s", " "); if (output == keyboard_lang_data[i].lang_code) { - strcat(lang, "["); - strcat(lang, keyboard_lang_data[i].lang_str); - strcat(lang, "]"); - strcat(select_lang, lang); + len += sysfs_emit_at(buf, len, "[%s]", keyboard_lang_data[i].lang_str); } else { - strcat(select_lang, keyboard_lang_data[i].lang_str); + len += sysfs_emit_at(buf, len, "%s", keyboard_lang_data[i].lang_str); } } + len += sysfs_emit_at(buf, len, "\n"); - return sysfs_emit(buf, "%s\n", select_lang); + return len; } static ssize_t keyboard_lang_store(struct device *dev, @@ -10113,7 +10105,7 @@ static ssize_t keyboard_lang_store(struct device *dev, if (err) return err; } else { - pr_err("Unknown Keyboard language. Ignoring\n"); + dev_err(&tpacpi_pdev->dev, "Unknown Keyboard language. Ignoring\n"); return -EINVAL; } @@ -10124,7 +10116,6 @@ static ssize_t keyboard_lang_store(struct device *dev, return count; } - static DEVICE_ATTR_RW(keyboard_lang); static struct attribute *kbdlang_attributes[] = { @@ -10143,7 +10134,7 @@ static int tpacpi_kbdlang_init(struct ibm_init_struct *iibm) err = get_keyboard_lang(&output); /* * If support isn't available (ENODEV) then don't return an error - * just don't create the sysfs group + * just don't create the sysfs group. */ if (err == -ENODEV) return 0; @@ -10152,9 +10143,7 @@ static int tpacpi_kbdlang_init(struct ibm_init_struct *iibm) return err; /* Platform supports this feature - create the sysfs file */ - err = sysfs_create_group(&tpacpi_pdev->dev.kobj, &kbdlang_attr_group); - - return err; + return sysfs_create_group(&tpacpi_pdev->dev.kobj, &kbdlang_attr_group); } static void kbdlang_exit(void) -- cgit v1.2.3 From 1adacc4919099bc115efb61a6db89c7f663c90e0 Mon Sep 17 00:00:00 2001 From: Lubomir Rintel Date: Thu, 21 Jan 2021 04:41:19 +0100 Subject: dt-bindings: gpio: mrvl-gpio: Fix the gpio-ranges property The property specifies a list of GPIO-capable pins. Don't limit it to a single element as there's presumably more than one GPIO pin. Signed-off-by: Lubomir Rintel Link: https://lore.kernel.org/r/20210121034130.1381872-2-lkundrak@v3.sk' Signed-off-by: Arnd Bergmann --- Documentation/devicetree/bindings/gpio/mrvl-gpio.yaml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/gpio/mrvl-gpio.yaml b/Documentation/devicetree/bindings/gpio/mrvl-gpio.yaml index 4db3b8a3332c..9cf6137dd524 100644 --- a/Documentation/devicetree/bindings/gpio/mrvl-gpio.yaml +++ b/Documentation/devicetree/bindings/gpio/mrvl-gpio.yaml @@ -82,8 +82,7 @@ properties: '#gpio-cells': const: 2 - gpio-ranges: - maxItems: 1 + gpio-ranges: true interrupts: true -- cgit v1.2.3 From fa432444095a35cfffdea87688d6e33db9cc9aff Mon Sep 17 00:00:00 2001 From: Lubomir Rintel Date: Thu, 21 Jan 2021 04:41:20 +0100 Subject: media: dt-bindings: marvell,mmp2-ccic: Allow power-domains property On MMP3 the camera interface is on a separate power island. This property tells the driver to enable it when appropriate. Signed-off-by: Lubomir Rintel Link: https://lore.kernel.org/r/20210121034130.1381872-3-lkundrak@v3.sk' Signed-off-by: Arnd Bergmann --- Documentation/devicetree/bindings/media/marvell,mmp2-ccic.yaml | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/media/marvell,mmp2-ccic.yaml b/Documentation/devicetree/bindings/media/marvell,mmp2-ccic.yaml index 49bff738aca5..52eab686a177 100644 --- a/Documentation/devicetree/bindings/media/marvell,mmp2-ccic.yaml +++ b/Documentation/devicetree/bindings/media/marvell,mmp2-ccic.yaml @@ -23,6 +23,9 @@ properties: interrupts: maxItems: 1 + power-domains: + maxItems: 1 + port: type: object additionalProperties: false @@ -75,6 +78,7 @@ additionalProperties: false examples: - | #include + #include camera@d420a000 { compatible = "marvell,mmp2-ccic"; @@ -84,6 +88,7 @@ examples: clock-names = "axi"; #clock-cells = <0>; clock-output-names = "mclk"; + power-domains = <&soc_clocks MMP3_POWER_DOMAIN_CAMERA>; port { camera0_0: endpoint { -- cgit v1.2.3 From bd67534d18b4a1ca8755f59702d4acf5a9ba7b1a Mon Sep 17 00:00:00 2001 From: Vincent Knecht Date: Sat, 30 Jan 2021 11:57:10 +0100 Subject: dt-bindings: vendor-prefixes: add Alcatel Document vendor prefix for Alcatel Signed-off-by: Vincent Knecht Link: https://lore.kernel.org/r/20210130105717.2628781-2-vincent.knecht@mailoo.org Signed-off-by: Bjorn Andersson --- Documentation/devicetree/bindings/vendor-prefixes.yaml | 2 ++ 1 file changed, 2 insertions(+) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/vendor-prefixes.yaml b/Documentation/devicetree/bindings/vendor-prefixes.yaml index 041ae90b0d8f..08150a1217e9 100644 --- a/Documentation/devicetree/bindings/vendor-prefixes.yaml +++ b/Documentation/devicetree/bindings/vendor-prefixes.yaml @@ -59,6 +59,8 @@ patternProperties: description: Aeroflex Gaisler AB "^al,.*": description: Annapurna Labs + "^alcatel,.*": + description: Alcatel "^allegro,.*": description: Allegro DVT "^allo,.*": -- cgit v1.2.3 From 2c1b8ebe929f1d452c95f8a4d32e3a265eb5b2c2 Mon Sep 17 00:00:00 2001 From: Vinod Koul Date: Wed, 27 Jan 2021 18:00:49 +0530 Subject: dt-bindings: arm: qcom: Document SM8350 SoC and boards Document the SM8350 SoC binding and also the boards using it. Reviewed-by: Bjorn Andersson Acked-by: Rob Herring Signed-off-by: Vinod Koul Link: https://lore.kernel.org/r/20210127123054.263231-2-vkoul@kernel.org Signed-off-by: Bjorn Andersson --- Documentation/devicetree/bindings/arm/qcom.yaml | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/arm/qcom.yaml b/Documentation/devicetree/bindings/arm/qcom.yaml index c97d4a580f47..8fe7e473bfdf 100644 --- a/Documentation/devicetree/bindings/arm/qcom.yaml +++ b/Documentation/devicetree/bindings/arm/qcom.yaml @@ -41,6 +41,7 @@ description: | sdm660 sdm845 sm8250 + sm8350 The 'board' element must be one of the following strings: @@ -178,6 +179,11 @@ properties: - qcom,sm8250-mtp - const: qcom,sm8250 + - items: + - enum: + - qcom,sm8350-mtp + - const: qcom,sm8350 + additionalProperties: true ... -- cgit v1.2.3 From 8767fe36d90e3433bd18eb0f84d852da73d5c8c6 Mon Sep 17 00:00:00 2001 From: Vinod Koul Date: Wed, 27 Jan 2021 18:00:51 +0530 Subject: dt-bindings: arm: cpus: Add kryo685 compatible Kryo685 is found in SM8350, so add it to the list of cpu compatibles Signed-off-by: Vinod Koul Link: https://lore.kernel.org/r/20210127123054.263231-4-vkoul@kernel.org Signed-off-by: Bjorn Andersson --- Documentation/devicetree/bindings/arm/cpus.yaml | 1 + 1 file changed, 1 insertion(+) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/arm/cpus.yaml b/Documentation/devicetree/bindings/arm/cpus.yaml index 14cd727d3c4b..3a0b4c54cd8e 100644 --- a/Documentation/devicetree/bindings/arm/cpus.yaml +++ b/Documentation/devicetree/bindings/arm/cpus.yaml @@ -169,6 +169,7 @@ properties: - qcom,kryo385 - qcom,kryo468 - qcom,kryo485 + - qcom,kryo685 - qcom,scorpion enable-method: -- cgit v1.2.3 From 80ad7f3349e63a12b9b9ba767884a513df362ec2 Mon Sep 17 00:00:00 2001 From: Vinod Koul Date: Wed, 27 Jan 2021 18:00:52 +0530 Subject: dt-bindings: firmware: scm: Add SM8250 and SM8350 compatible Add compatible for SM8150 and SM8350 SoCs. Signed-off-by: Vinod Koul Link: https://lore.kernel.org/r/20210127123054.263231-5-vkoul@kernel.org Signed-off-by: Bjorn Andersson --- Documentation/devicetree/bindings/firmware/qcom,scm.txt | 2 ++ 1 file changed, 2 insertions(+) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/firmware/qcom,scm.txt b/Documentation/devicetree/bindings/firmware/qcom,scm.txt index 78456437df5f..a884955f861e 100644 --- a/Documentation/devicetree/bindings/firmware/qcom,scm.txt +++ b/Documentation/devicetree/bindings/firmware/qcom,scm.txt @@ -22,6 +22,8 @@ Required properties: * "qcom,scm-sc7180" * "qcom,scm-sdm845" * "qcom,scm-sm8150" + * "qcom,scm-sm8250" + * "qcom,scm-sm8350" and: * "qcom,scm" - clocks: Specifies clocks needed by the SCM interface, if any: -- cgit v1.2.3 From 680aea08e78c003292415518ad270bc20f9c80b1 Mon Sep 17 00:00:00 2001 From: Amit Cohen Date: Mon, 1 Feb 2021 21:47:52 +0200 Subject: net: ipv4: Emit notification when fib hardware flags are changed After installing a route to the kernel, user space receives an acknowledgment, which means the route was installed in the kernel, but not necessarily in hardware. The asynchronous nature of route installation in hardware can lead to a routing daemon advertising a route before it was actually installed in hardware. This can result in packet loss or mis-routed packets until the route is installed in hardware. It is also possible for a route already installed in hardware to change its action and therefore its flags. For example, a host route that is trapping packets can be "promoted" to perform decapsulation following the installation of an IPinIP/VXLAN tunnel. Emit RTM_NEWROUTE notifications whenever RTM_F_OFFLOAD/RTM_F_TRAP flags are changed. The aim is to provide an indication to user-space (e.g., routing daemons) about the state of the route in hardware. Introduce a sysctl that controls this behavior. Keep the default value at 0 (i.e., do not emit notifications) for several reasons: - Multiple RTM_NEWROUTE notification per-route might confuse existing routing daemons. - Convergence reasons in routing daemons. - The extra notifications will negatively impact the insertion rate. - Not all users are interested in these notifications. Signed-off-by: Amit Cohen Acked-by: Roopa Prabhu Signed-off-by: Ido Schimmel Reviewed-by: David Ahern Signed-off-by: Jakub Kicinski --- Documentation/networking/ip-sysctl.rst | 20 ++++++++++++++++++++ include/net/netns/ipv4.h | 2 ++ net/ipv4/af_inet.c | 2 ++ net/ipv4/fib_trie.c | 27 +++++++++++++++++++++++++++ net/ipv4/sysctl_net_ipv4.c | 9 +++++++++ 5 files changed, 60 insertions(+) (limited to 'Documentation') diff --git a/Documentation/networking/ip-sysctl.rst b/Documentation/networking/ip-sysctl.rst index 2685ec161060..b0e800e68366 100644 --- a/Documentation/networking/ip-sysctl.rst +++ b/Documentation/networking/ip-sysctl.rst @@ -178,6 +178,26 @@ min_adv_mss - INTEGER The advertised MSS depends on the first hop route MTU, but will never be lower than this setting. +fib_notify_on_flag_change - INTEGER + Whether to emit RTM_NEWROUTE notifications whenever RTM_F_OFFLOAD/ + RTM_F_TRAP flags are changed. + + After installing a route to the kernel, user space receives an + acknowledgment, which means the route was installed in the kernel, + but not necessarily in hardware. + It is also possible for a route already installed in hardware to change + its action and therefore its flags. For example, a host route that is + trapping packets can be "promoted" to perform decapsulation following + the installation of an IPinIP/VXLAN tunnel. + The notifications will indicate to user-space the state of the route. + + Default: 0 (Do not emit notifications.) + + Possible values: + + - 0 - Do not emit notifications. + - 1 - Emit notifications. + IP Fragmentation: ipfrag_high_thresh - LONG INTEGER diff --git a/include/net/netns/ipv4.h b/include/net/netns/ipv4.h index 8e4fcac4df72..70a2a085dd1a 100644 --- a/include/net/netns/ipv4.h +++ b/include/net/netns/ipv4.h @@ -188,6 +188,8 @@ struct netns_ipv4 { int sysctl_udp_wmem_min; int sysctl_udp_rmem_min; + int sysctl_fib_notify_on_flag_change; + #ifdef CONFIG_NET_L3_MASTER_DEV int sysctl_udp_l3mdev_accept; #endif diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c index b94fa8eb831b..ab42f6404fc6 100644 --- a/net/ipv4/af_inet.c +++ b/net/ipv4/af_inet.c @@ -1871,6 +1871,8 @@ static __net_init int inet_init_net(struct net *net) net->ipv4.sysctl_igmp_llm_reports = 1; net->ipv4.sysctl_igmp_qrv = 2; + net->ipv4.sysctl_fib_notify_on_flag_change = 0; + return 0; } diff --git a/net/ipv4/fib_trie.c b/net/ipv4/fib_trie.c index 28117c05dc35..60559b708158 100644 --- a/net/ipv4/fib_trie.c +++ b/net/ipv4/fib_trie.c @@ -1038,6 +1038,8 @@ fib_find_matching_alias(struct net *net, const struct fib_rt_info *fri) void fib_alias_hw_flags_set(struct net *net, const struct fib_rt_info *fri) { struct fib_alias *fa_match; + struct sk_buff *skb; + int err; rcu_read_lock(); @@ -1045,9 +1047,34 @@ void fib_alias_hw_flags_set(struct net *net, const struct fib_rt_info *fri) if (!fa_match) goto out; + if (fa_match->offload == fri->offload && fa_match->trap == fri->trap) + goto out; + fa_match->offload = fri->offload; fa_match->trap = fri->trap; + if (!net->ipv4.sysctl_fib_notify_on_flag_change) + goto out; + + skb = nlmsg_new(fib_nlmsg_size(fa_match->fa_info), GFP_ATOMIC); + if (!skb) { + err = -ENOBUFS; + goto errout; + } + + err = fib_dump_info(skb, 0, 0, RTM_NEWROUTE, fri, 0); + if (err < 0) { + /* -EMSGSIZE implies BUG in fib_nlmsg_size() */ + WARN_ON(err == -EMSGSIZE); + kfree_skb(skb); + goto errout; + } + + rtnl_notify(skb, net, 0, RTNLGRP_IPV4_ROUTE, NULL, GFP_ATOMIC); + goto out; + +errout: + rtnl_set_sk_err(net, RTNLGRP_IPV4_ROUTE, err); out: rcu_read_unlock(); } diff --git a/net/ipv4/sysctl_net_ipv4.c b/net/ipv4/sysctl_net_ipv4.c index 3e5f4f2e705e..e5798b3b59d2 100644 --- a/net/ipv4/sysctl_net_ipv4.c +++ b/net/ipv4/sysctl_net_ipv4.c @@ -1354,6 +1354,15 @@ static struct ctl_table ipv4_net_table[] = { .proc_handler = proc_dointvec_minmax, .extra1 = SYSCTL_ONE }, + { + .procname = "fib_notify_on_flag_change", + .data = &init_net.ipv4.sysctl_fib_notify_on_flag_change, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = proc_dointvec_minmax, + .extra1 = SYSCTL_ZERO, + .extra2 = SYSCTL_ONE, + }, { } }; -- cgit v1.2.3 From 907eea486888cfe118c19759bbc4b8fca2e004df Mon Sep 17 00:00:00 2001 From: Amit Cohen Date: Mon, 1 Feb 2021 21:47:55 +0200 Subject: net: ipv6: Emit notification when fib hardware flags are changed After installing a route to the kernel, user space receives an acknowledgment, which means the route was installed in the kernel, but not necessarily in hardware. The asynchronous nature of route installation in hardware can lead to a routing daemon advertising a route before it was actually installed in hardware. This can result in packet loss or mis-routed packets until the route is installed in hardware. It is also possible for a route already installed in hardware to change its action and therefore its flags. For example, a host route that is trapping packets can be "promoted" to perform decapsulation following the installation of an IPinIP/VXLAN tunnel. Emit RTM_NEWROUTE notifications whenever RTM_F_OFFLOAD/RTM_F_TRAP flags are changed. The aim is to provide an indication to user-space (e.g., routing daemons) about the state of the route in hardware. Introduce a sysctl that controls this behavior. Keep the default value at 0 (i.e., do not emit notifications) for several reasons: - Multiple RTM_NEWROUTE notification per-route might confuse existing routing daemons. - Convergence reasons in routing daemons. - The extra notifications will negatively impact the insertion rate. - Not all users are interested in these notifications. Move fib6_info_hw_flags_set() to C file because it is no longer a short function. Signed-off-by: Amit Cohen Signed-off-by: Ido Schimmel Reviewed-by: David Ahern Signed-off-by: Jakub Kicinski --- Documentation/networking/ip-sysctl.rst | 20 ++++++++++++++++ include/net/ip6_fib.h | 10 ++------ include/net/netns/ipv6.h | 1 + net/ipv6/af_inet6.c | 1 + net/ipv6/route.c | 44 ++++++++++++++++++++++++++++++++++ net/ipv6/sysctl_net_ipv6.c | 9 +++++++ 6 files changed, 77 insertions(+), 8 deletions(-) (limited to 'Documentation') diff --git a/Documentation/networking/ip-sysctl.rst b/Documentation/networking/ip-sysctl.rst index b0e800e68366..61a358301f12 100644 --- a/Documentation/networking/ip-sysctl.rst +++ b/Documentation/networking/ip-sysctl.rst @@ -1795,6 +1795,26 @@ nexthop_compat_mode - BOOLEAN and extraneous notifications. Default: true (backward compat mode) +fib_notify_on_flag_change - INTEGER + Whether to emit RTM_NEWROUTE notifications whenever RTM_F_OFFLOAD/ + RTM_F_TRAP flags are changed. + + After installing a route to the kernel, user space receives an + acknowledgment, which means the route was installed in the kernel, + but not necessarily in hardware. + It is also possible for a route already installed in hardware to change + its action and therefore its flags. For example, a host route that is + trapping packets can be "promoted" to perform decapsulation following + the installation of an IPinIP/VXLAN tunnel. + The notifications will indicate to user-space the state of the route. + + Default: 0 (Do not emit notifications.) + + Possible values: + + - 0 - Do not emit notifications. + - 1 - Emit notifications. + IPv6 Fragmentation: ip6frag_high_thresh - INTEGER diff --git a/include/net/ip6_fib.h b/include/net/ip6_fib.h index cc189e668adf..1e262b23c68b 100644 --- a/include/net/ip6_fib.h +++ b/include/net/ip6_fib.h @@ -336,14 +336,6 @@ static inline void fib6_info_release(struct fib6_info *f6i) call_rcu(&f6i->rcu, fib6_info_destroy_rcu); } -static inline void -fib6_info_hw_flags_set(struct net *net, struct fib6_info *f6i, bool offload, - bool trap) -{ - f6i->offload = offload; - f6i->trap = trap; -} - enum fib6_walk_state { #ifdef CONFIG_IPV6_SUBTREES FWS_S, @@ -546,6 +538,8 @@ static inline bool fib6_metric_locked(struct fib6_info *f6i, int metric) { return !!(f6i->fib6_metrics->metrics[RTAX_LOCK - 1] & (1 << metric)); } +void fib6_info_hw_flags_set(struct net *net, struct fib6_info *f6i, + bool offload, bool trap); #if IS_BUILTIN(CONFIG_IPV6) && defined(CONFIG_BPF_SYSCALL) struct bpf_iter__ipv6_route { diff --git a/include/net/netns/ipv6.h b/include/net/netns/ipv6.h index 5ec054473d81..21c0debbd39e 100644 --- a/include/net/netns/ipv6.h +++ b/include/net/netns/ipv6.h @@ -51,6 +51,7 @@ struct netns_sysctl_ipv6 { int max_hbh_opts_len; int seg6_flowlabel; bool skip_notify_on_dev_down; + int fib_notify_on_flag_change; }; struct netns_ipv6 { diff --git a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c index 8e9c3e9ea36e..0e9994e0ecd7 100644 --- a/net/ipv6/af_inet6.c +++ b/net/ipv6/af_inet6.c @@ -954,6 +954,7 @@ static int __net_init inet6_net_init(struct net *net) net->ipv6.sysctl.max_hbh_opts_cnt = IP6_DEFAULT_MAX_HBH_OPTS_CNT; net->ipv6.sysctl.max_dst_opts_len = IP6_DEFAULT_MAX_DST_OPTS_LEN; net->ipv6.sysctl.max_hbh_opts_len = IP6_DEFAULT_MAX_HBH_OPTS_LEN; + net->ipv6.sysctl.fib_notify_on_flag_change = 0; atomic_set(&net->ipv6.fib6_sernum, 1); err = ipv6_init_mibs(net); diff --git a/net/ipv6/route.c b/net/ipv6/route.c index 41d8f801b75f..92b400eb8476 100644 --- a/net/ipv6/route.c +++ b/net/ipv6/route.c @@ -6064,6 +6064,50 @@ errout: rtnl_set_sk_err(net, RTNLGRP_IPV6_ROUTE, err); } +void fib6_info_hw_flags_set(struct net *net, struct fib6_info *f6i, + bool offload, bool trap) +{ + struct sk_buff *skb; + int err; + + if (f6i->offload == offload && f6i->trap == trap) + return; + + f6i->offload = offload; + f6i->trap = trap; + + if (!rcu_access_pointer(f6i->fib6_node)) + /* The route was removed from the tree, do not send + * notfication. + */ + return; + + if (!net->ipv6.sysctl.fib_notify_on_flag_change) + return; + + skb = nlmsg_new(rt6_nlmsg_size(f6i), GFP_KERNEL); + if (!skb) { + err = -ENOBUFS; + goto errout; + } + + err = rt6_fill_node(net, skb, f6i, NULL, NULL, NULL, 0, RTM_NEWROUTE, 0, + 0, 0); + if (err < 0) { + /* -EMSGSIZE implies BUG in rt6_nlmsg_size() */ + WARN_ON(err == -EMSGSIZE); + kfree_skb(skb); + goto errout; + } + + rtnl_notify(skb, net, 0, RTNLGRP_IPV6_ROUTE, NULL, GFP_KERNEL); + return; + +errout: + rtnl_set_sk_err(net, RTNLGRP_IPV6_ROUTE, err); +} +EXPORT_SYMBOL(fib6_info_hw_flags_set); + static int ip6_route_dev_notify(struct notifier_block *this, unsigned long event, void *ptr) { diff --git a/net/ipv6/sysctl_net_ipv6.c b/net/ipv6/sysctl_net_ipv6.c index 5b60a4bdd36a..392ef01e3366 100644 --- a/net/ipv6/sysctl_net_ipv6.c +++ b/net/ipv6/sysctl_net_ipv6.c @@ -160,6 +160,15 @@ static struct ctl_table ipv6_table_template[] = { .mode = 0644, .proc_handler = proc_dointvec }, + { + .procname = "fib_notify_on_flag_change", + .data = &init_net.ipv6.sysctl.fib_notify_on_flag_change, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = proc_dointvec_minmax, + .extra1 = SYSCTL_ZERO, + .extra2 = SYSCTL_ONE, + }, { } }; -- cgit v1.2.3 From 33105406764f7f13c5e7279826f77342c82c41b5 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Wed, 20 Jan 2021 14:15:56 +0100 Subject: clocksource/drivers/u300: Remove the u300 driver The ST-Ericsson U300 platform is getting removed, so this driver is no longer needed. Cc: Linus Walleij Signed-off-by: Arnd Bergmann Reviewed-by: Linus Walleij Signed-off-by: Daniel Lezcano Link: https://lore.kernel.org/r/20210120131559.1971359-2-arnd@kernel.org --- .../bindings/timer/stericsson-u300-apptimer.txt | 18 - drivers/clocksource/Kconfig | 7 - drivers/clocksource/Makefile | 1 - drivers/clocksource/timer-u300.c | 457 --------------------- 4 files changed, 483 deletions(-) delete mode 100644 Documentation/devicetree/bindings/timer/stericsson-u300-apptimer.txt delete mode 100644 drivers/clocksource/timer-u300.c (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/timer/stericsson-u300-apptimer.txt b/Documentation/devicetree/bindings/timer/stericsson-u300-apptimer.txt deleted file mode 100644 index 9499bc8ee9e3..000000000000 --- a/Documentation/devicetree/bindings/timer/stericsson-u300-apptimer.txt +++ /dev/null @@ -1,18 +0,0 @@ -ST-Ericsson U300 apptimer - -Required properties: - -- compatible : should be "stericsson,u300-apptimer" -- reg : Specifies base physical address and size of the registers. -- interrupts : A list of 4 interrupts; one for each subtimer. These - are, in order: OS (operating system), DD (device driver) both - adopted for EPOC/Symbian with two specific IRQs for these tasks, - then GP1 and GP2, which are general-purpose timers. - -Example: - -timer { - compatible = "stericsson,u300-apptimer"; - reg = <0xc0014000 0x1000>; - interrupts = <24 25 26 27>; -}; diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig index 6bf89e242c36..b26bb9ea3e60 100644 --- a/drivers/clocksource/Kconfig +++ b/drivers/clocksource/Kconfig @@ -216,13 +216,6 @@ config PRIMA2_TIMER help Enables support for the Prima2 timer. -config U300_TIMER - bool "U300 timer driver" if COMPILE_TEST - depends on ARM - select CLKSRC_MMIO - help - Enables support for the U300 timer. - config NSPIRE_TIMER bool "NSpire timer driver" if COMPILE_TEST select CLKSRC_MMIO diff --git a/drivers/clocksource/Makefile b/drivers/clocksource/Makefile index 08173383f2d9..ce8a3c01a72d 100644 --- a/drivers/clocksource/Makefile +++ b/drivers/clocksource/Makefile @@ -34,7 +34,6 @@ obj-$(CONFIG_ATLAS7_TIMER) += timer-atlas7.o obj-$(CONFIG_MXS_TIMER) += mxs_timer.o obj-$(CONFIG_CLKSRC_PXA) += timer-pxa.o obj-$(CONFIG_PRIMA2_TIMER) += timer-prima2.o -obj-$(CONFIG_U300_TIMER) += timer-u300.o obj-$(CONFIG_SUN4I_TIMER) += timer-sun4i.o obj-$(CONFIG_SUN5I_HSTIMER) += timer-sun5i.o obj-$(CONFIG_MESON6_TIMER) += timer-meson6.o diff --git a/drivers/clocksource/timer-u300.c b/drivers/clocksource/timer-u300.c deleted file mode 100644 index 37cba8dfd45f..000000000000 --- a/drivers/clocksource/timer-u300.c +++ /dev/null @@ -1,457 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Copyright (C) 2007-2009 ST-Ericsson AB - * Timer COH 901 328, runs the OS timer interrupt. - * Author: Linus Walleij - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* Generic stuff */ -#include -#include - -/* - * APP side special timer registers - * This timer contains four timers which can fire an interrupt each. - * OS (operating system) timer @ 32768 Hz - * DD (device driver) timer @ 1 kHz - * GP1 (general purpose 1) timer @ 1MHz - * GP2 (general purpose 2) timer @ 1MHz - */ - -/* Reset OS Timer 32bit (-/W) */ -#define U300_TIMER_APP_ROST (0x0000) -#define U300_TIMER_APP_ROST_TIMER_RESET (0x00000000) -/* Enable OS Timer 32bit (-/W) */ -#define U300_TIMER_APP_EOST (0x0004) -#define U300_TIMER_APP_EOST_TIMER_ENABLE (0x00000000) -/* Disable OS Timer 32bit (-/W) */ -#define U300_TIMER_APP_DOST (0x0008) -#define U300_TIMER_APP_DOST_TIMER_DISABLE (0x00000000) -/* OS Timer Mode Register 32bit (-/W) */ -#define U300_TIMER_APP_SOSTM (0x000c) -#define U300_TIMER_APP_SOSTM_MODE_CONTINUOUS (0x00000000) -#define U300_TIMER_APP_SOSTM_MODE_ONE_SHOT (0x00000001) -/* OS Timer Status Register 32bit (R/-) */ -#define U300_TIMER_APP_OSTS (0x0010) -#define U300_TIMER_APP_OSTS_TIMER_STATE_MASK (0x0000000F) -#define U300_TIMER_APP_OSTS_TIMER_STATE_IDLE (0x00000001) -#define U300_TIMER_APP_OSTS_TIMER_STATE_ACTIVE (0x00000002) -#define U300_TIMER_APP_OSTS_ENABLE_IND (0x00000010) -#define U300_TIMER_APP_OSTS_MODE_MASK (0x00000020) -#define U300_TIMER_APP_OSTS_MODE_CONTINUOUS (0x00000000) -#define U300_TIMER_APP_OSTS_MODE_ONE_SHOT (0x00000020) -#define U300_TIMER_APP_OSTS_IRQ_ENABLED_IND (0x00000040) -#define U300_TIMER_APP_OSTS_IRQ_PENDING_IND (0x00000080) -/* OS Timer Current Count Register 32bit (R/-) */ -#define U300_TIMER_APP_OSTCC (0x0014) -/* OS Timer Terminal Count Register 32bit (R/W) */ -#define U300_TIMER_APP_OSTTC (0x0018) -/* OS Timer Interrupt Enable Register 32bit (-/W) */ -#define U300_TIMER_APP_OSTIE (0x001c) -#define U300_TIMER_APP_OSTIE_IRQ_DISABLE (0x00000000) -#define U300_TIMER_APP_OSTIE_IRQ_ENABLE (0x00000001) -/* OS Timer Interrupt Acknowledge Register 32bit (-/W) */ -#define U300_TIMER_APP_OSTIA (0x0020) -#define U300_TIMER_APP_OSTIA_IRQ_ACK (0x00000080) - -/* Reset DD Timer 32bit (-/W) */ -#define U300_TIMER_APP_RDDT (0x0040) -#define U300_TIMER_APP_RDDT_TIMER_RESET (0x00000000) -/* Enable DD Timer 32bit (-/W) */ -#define U300_TIMER_APP_EDDT (0x0044) -#define U300_TIMER_APP_EDDT_TIMER_ENABLE (0x00000000) -/* Disable DD Timer 32bit (-/W) */ -#define U300_TIMER_APP_DDDT (0x0048) -#define U300_TIMER_APP_DDDT_TIMER_DISABLE (0x00000000) -/* DD Timer Mode Register 32bit (-/W) */ -#define U300_TIMER_APP_SDDTM (0x004c) -#define U300_TIMER_APP_SDDTM_MODE_CONTINUOUS (0x00000000) -#define U300_TIMER_APP_SDDTM_MODE_ONE_SHOT (0x00000001) -/* DD Timer Status Register 32bit (R/-) */ -#define U300_TIMER_APP_DDTS (0x0050) -#define U300_TIMER_APP_DDTS_TIMER_STATE_MASK (0x0000000F) -#define U300_TIMER_APP_DDTS_TIMER_STATE_IDLE (0x00000001) -#define U300_TIMER_APP_DDTS_TIMER_STATE_ACTIVE (0x00000002) -#define U300_TIMER_APP_DDTS_ENABLE_IND (0x00000010) -#define U300_TIMER_APP_DDTS_MODE_MASK (0x00000020) -#define U300_TIMER_APP_DDTS_MODE_CONTINUOUS (0x00000000) -#define U300_TIMER_APP_DDTS_MODE_ONE_SHOT (0x00000020) -#define U300_TIMER_APP_DDTS_IRQ_ENABLED_IND (0x00000040) -#define U300_TIMER_APP_DDTS_IRQ_PENDING_IND (0x00000080) -/* DD Timer Current Count Register 32bit (R/-) */ -#define U300_TIMER_APP_DDTCC (0x0054) -/* DD Timer Terminal Count Register 32bit (R/W) */ -#define U300_TIMER_APP_DDTTC (0x0058) -/* DD Timer Interrupt Enable Register 32bit (-/W) */ -#define U300_TIMER_APP_DDTIE (0x005c) -#define U300_TIMER_APP_DDTIE_IRQ_DISABLE (0x00000000) -#define U300_TIMER_APP_DDTIE_IRQ_ENABLE (0x00000001) -/* DD Timer Interrupt Acknowledge Register 32bit (-/W) */ -#define U300_TIMER_APP_DDTIA (0x0060) -#define U300_TIMER_APP_DDTIA_IRQ_ACK (0x00000080) - -/* Reset GP1 Timer 32bit (-/W) */ -#define U300_TIMER_APP_RGPT1 (0x0080) -#define U300_TIMER_APP_RGPT1_TIMER_RESET (0x00000000) -/* Enable GP1 Timer 32bit (-/W) */ -#define U300_TIMER_APP_EGPT1 (0x0084) -#define U300_TIMER_APP_EGPT1_TIMER_ENABLE (0x00000000) -/* Disable GP1 Timer 32bit (-/W) */ -#define U300_TIMER_APP_DGPT1 (0x0088) -#define U300_TIMER_APP_DGPT1_TIMER_DISABLE (0x00000000) -/* GP1 Timer Mode Register 32bit (-/W) */ -#define U300_TIMER_APP_SGPT1M (0x008c) -#define U300_TIMER_APP_SGPT1M_MODE_CONTINUOUS (0x00000000) -#define U300_TIMER_APP_SGPT1M_MODE_ONE_SHOT (0x00000001) -/* GP1 Timer Status Register 32bit (R/-) */ -#define U300_TIMER_APP_GPT1S (0x0090) -#define U300_TIMER_APP_GPT1S_TIMER_STATE_MASK (0x0000000F) -#define U300_TIMER_APP_GPT1S_TIMER_STATE_IDLE (0x00000001) -#define U300_TIMER_APP_GPT1S_TIMER_STATE_ACTIVE (0x00000002) -#define U300_TIMER_APP_GPT1S_ENABLE_IND (0x00000010) -#define U300_TIMER_APP_GPT1S_MODE_MASK (0x00000020) -#define U300_TIMER_APP_GPT1S_MODE_CONTINUOUS (0x00000000) -#define U300_TIMER_APP_GPT1S_MODE_ONE_SHOT (0x00000020) -#define U300_TIMER_APP_GPT1S_IRQ_ENABLED_IND (0x00000040) -#define U300_TIMER_APP_GPT1S_IRQ_PENDING_IND (0x00000080) -/* GP1 Timer Current Count Register 32bit (R/-) */ -#define U300_TIMER_APP_GPT1CC (0x0094) -/* GP1 Timer Terminal Count Register 32bit (R/W) */ -#define U300_TIMER_APP_GPT1TC (0x0098) -/* GP1 Timer Interrupt Enable Register 32bit (-/W) */ -#define U300_TIMER_APP_GPT1IE (0x009c) -#define U300_TIMER_APP_GPT1IE_IRQ_DISABLE (0x00000000) -#define U300_TIMER_APP_GPT1IE_IRQ_ENABLE (0x00000001) -/* GP1 Timer Interrupt Acknowledge Register 32bit (-/W) */ -#define U300_TIMER_APP_GPT1IA (0x00a0) -#define U300_TIMER_APP_GPT1IA_IRQ_ACK (0x00000080) - -/* Reset GP2 Timer 32bit (-/W) */ -#define U300_TIMER_APP_RGPT2 (0x00c0) -#define U300_TIMER_APP_RGPT2_TIMER_RESET (0x00000000) -/* Enable GP2 Timer 32bit (-/W) */ -#define U300_TIMER_APP_EGPT2 (0x00c4) -#define U300_TIMER_APP_EGPT2_TIMER_ENABLE (0x00000000) -/* Disable GP2 Timer 32bit (-/W) */ -#define U300_TIMER_APP_DGPT2 (0x00c8) -#define U300_TIMER_APP_DGPT2_TIMER_DISABLE (0x00000000) -/* GP2 Timer Mode Register 32bit (-/W) */ -#define U300_TIMER_APP_SGPT2M (0x00cc) -#define U300_TIMER_APP_SGPT2M_MODE_CONTINUOUS (0x00000000) -#define U300_TIMER_APP_SGPT2M_MODE_ONE_SHOT (0x00000001) -/* GP2 Timer Status Register 32bit (R/-) */ -#define U300_TIMER_APP_GPT2S (0x00d0) -#define U300_TIMER_APP_GPT2S_TIMER_STATE_MASK (0x0000000F) -#define U300_TIMER_APP_GPT2S_TIMER_STATE_IDLE (0x00000001) -#define U300_TIMER_APP_GPT2S_TIMER_STATE_ACTIVE (0x00000002) -#define U300_TIMER_APP_GPT2S_ENABLE_IND (0x00000010) -#define U300_TIMER_APP_GPT2S_MODE_MASK (0x00000020) -#define U300_TIMER_APP_GPT2S_MODE_CONTINUOUS (0x00000000) -#define U300_TIMER_APP_GPT2S_MODE_ONE_SHOT (0x00000020) -#define U300_TIMER_APP_GPT2S_IRQ_ENABLED_IND (0x00000040) -#define U300_TIMER_APP_GPT2S_IRQ_PENDING_IND (0x00000080) -/* GP2 Timer Current Count Register 32bit (R/-) */ -#define U300_TIMER_APP_GPT2CC (0x00d4) -/* GP2 Timer Terminal Count Register 32bit (R/W) */ -#define U300_TIMER_APP_GPT2TC (0x00d8) -/* GP2 Timer Interrupt Enable Register 32bit (-/W) */ -#define U300_TIMER_APP_GPT2IE (0x00dc) -#define U300_TIMER_APP_GPT2IE_IRQ_DISABLE (0x00000000) -#define U300_TIMER_APP_GPT2IE_IRQ_ENABLE (0x00000001) -/* GP2 Timer Interrupt Acknowledge Register 32bit (-/W) */ -#define U300_TIMER_APP_GPT2IA (0x00e0) -#define U300_TIMER_APP_GPT2IA_IRQ_ACK (0x00000080) - -/* Clock request control register - all four timers */ -#define U300_TIMER_APP_CRC (0x100) -#define U300_TIMER_APP_CRC_CLOCK_REQUEST_ENABLE (0x00000001) - -static void __iomem *u300_timer_base; - -struct u300_clockevent_data { - struct clock_event_device cevd; - unsigned ticks_per_jiffy; -}; - -static int u300_shutdown(struct clock_event_device *evt) -{ - /* Disable interrupts on GP1 */ - writel(U300_TIMER_APP_GPT1IE_IRQ_DISABLE, - u300_timer_base + U300_TIMER_APP_GPT1IE); - /* Disable GP1 */ - writel(U300_TIMER_APP_DGPT1_TIMER_DISABLE, - u300_timer_base + U300_TIMER_APP_DGPT1); - return 0; -} - -/* - * If we have oneshot timer active, the oneshot scheduling function - * u300_set_next_event() is called immediately after. - */ -static int u300_set_oneshot(struct clock_event_device *evt) -{ - /* Just return; here? */ - /* - * The actual event will be programmed by the next event hook, - * so we just set a dummy value somewhere at the end of the - * universe here. - */ - /* Disable interrupts on GPT1 */ - writel(U300_TIMER_APP_GPT1IE_IRQ_DISABLE, - u300_timer_base + U300_TIMER_APP_GPT1IE); - /* Disable GP1 while we're reprogramming it. */ - writel(U300_TIMER_APP_DGPT1_TIMER_DISABLE, - u300_timer_base + U300_TIMER_APP_DGPT1); - /* - * Expire far in the future, u300_set_next_event() will be - * called soon... - */ - writel(0xFFFFFFFF, u300_timer_base + U300_TIMER_APP_GPT1TC); - /* We run one shot per tick here! */ - writel(U300_TIMER_APP_SGPT1M_MODE_ONE_SHOT, - u300_timer_base + U300_TIMER_APP_SGPT1M); - /* Enable interrupts for this timer */ - writel(U300_TIMER_APP_GPT1IE_IRQ_ENABLE, - u300_timer_base + U300_TIMER_APP_GPT1IE); - /* Enable timer */ - writel(U300_TIMER_APP_EGPT1_TIMER_ENABLE, - u300_timer_base + U300_TIMER_APP_EGPT1); - return 0; -} - -static int u300_set_periodic(struct clock_event_device *evt) -{ - struct u300_clockevent_data *cevdata = - container_of(evt, struct u300_clockevent_data, cevd); - - /* Disable interrupts on GPT1 */ - writel(U300_TIMER_APP_GPT1IE_IRQ_DISABLE, - u300_timer_base + U300_TIMER_APP_GPT1IE); - /* Disable GP1 while we're reprogramming it. */ - writel(U300_TIMER_APP_DGPT1_TIMER_DISABLE, - u300_timer_base + U300_TIMER_APP_DGPT1); - /* - * Set the periodic mode to a certain number of ticks per - * jiffy. - */ - writel(cevdata->ticks_per_jiffy, - u300_timer_base + U300_TIMER_APP_GPT1TC); - /* - * Set continuous mode, so the timer keeps triggering - * interrupts. - */ - writel(U300_TIMER_APP_SGPT1M_MODE_CONTINUOUS, - u300_timer_base + U300_TIMER_APP_SGPT1M); - /* Enable timer interrupts */ - writel(U300_TIMER_APP_GPT1IE_IRQ_ENABLE, - u300_timer_base + U300_TIMER_APP_GPT1IE); - /* Then enable the OS timer again */ - writel(U300_TIMER_APP_EGPT1_TIMER_ENABLE, - u300_timer_base + U300_TIMER_APP_EGPT1); - return 0; -} - -/* - * The app timer in one shot mode obviously has to be reprogrammed - * in EXACTLY this sequence to work properly. Do NOT try to e.g. replace - * the interrupt disable + timer disable commands with a reset command, - * it will fail miserably. Apparently (and I found this the hard way) - * the timer is very sensitive to the instruction order, though you don't - * get that impression from the data sheet. - */ -static int u300_set_next_event(unsigned long cycles, - struct clock_event_device *evt) - -{ - /* Disable interrupts on GPT1 */ - writel(U300_TIMER_APP_GPT1IE_IRQ_DISABLE, - u300_timer_base + U300_TIMER_APP_GPT1IE); - /* Disable GP1 while we're reprogramming it. */ - writel(U300_TIMER_APP_DGPT1_TIMER_DISABLE, - u300_timer_base + U300_TIMER_APP_DGPT1); - /* Reset the General Purpose timer 1. */ - writel(U300_TIMER_APP_RGPT1_TIMER_RESET, - u300_timer_base + U300_TIMER_APP_RGPT1); - /* IRQ in n * cycles */ - writel(cycles, u300_timer_base + U300_TIMER_APP_GPT1TC); - /* - * We run one shot per tick here! (This is necessary to reconfigure, - * the timer will tilt if you don't!) - */ - writel(U300_TIMER_APP_SGPT1M_MODE_ONE_SHOT, - u300_timer_base + U300_TIMER_APP_SGPT1M); - /* Enable timer interrupts */ - writel(U300_TIMER_APP_GPT1IE_IRQ_ENABLE, - u300_timer_base + U300_TIMER_APP_GPT1IE); - /* Then enable the OS timer again */ - writel(U300_TIMER_APP_EGPT1_TIMER_ENABLE, - u300_timer_base + U300_TIMER_APP_EGPT1); - return 0; -} - -static struct u300_clockevent_data u300_clockevent_data = { - /* Use general purpose timer 1 as clock event */ - .cevd = { - .name = "GPT1", - /* Reasonably fast and accurate clock event */ - .rating = 300, - .features = CLOCK_EVT_FEAT_PERIODIC | - CLOCK_EVT_FEAT_ONESHOT, - .set_next_event = u300_set_next_event, - .set_state_shutdown = u300_shutdown, - .set_state_periodic = u300_set_periodic, - .set_state_oneshot = u300_set_oneshot, - }, -}; - -/* Clock event timer interrupt handler */ -static irqreturn_t u300_timer_interrupt(int irq, void *dev_id) -{ - struct clock_event_device *evt = &u300_clockevent_data.cevd; - /* ACK/Clear timer IRQ for the APP GPT1 Timer */ - - writel(U300_TIMER_APP_GPT1IA_IRQ_ACK, - u300_timer_base + U300_TIMER_APP_GPT1IA); - evt->event_handler(evt); - return IRQ_HANDLED; -} - -/* - * Override the global weak sched_clock symbol with this - * local implementation which uses the clocksource to get some - * better resolution when scheduling the kernel. We accept that - * this wraps around for now, since it is just a relative time - * stamp. (Inspired by OMAP implementation.) - */ - -static u64 notrace u300_read_sched_clock(void) -{ - return readl(u300_timer_base + U300_TIMER_APP_GPT2CC); -} - -static unsigned long u300_read_current_timer(void) -{ - return readl(u300_timer_base + U300_TIMER_APP_GPT2CC); -} - -static struct delay_timer u300_delay_timer; - -/* - * This sets up the system timers, clock source and clock event. - */ -static int __init u300_timer_init_of(struct device_node *np) -{ - unsigned int irq; - struct clk *clk; - unsigned long rate; - int ret; - - u300_timer_base = of_iomap(np, 0); - if (!u300_timer_base) { - pr_err("could not ioremap system timer\n"); - return -ENXIO; - } - - /* Get the IRQ for the GP1 timer */ - irq = irq_of_parse_and_map(np, 2); - if (!irq) { - pr_err("no IRQ for system timer\n"); - return -EINVAL; - } - - pr_info("U300 GP1 timer @ base: %p, IRQ: %u\n", u300_timer_base, irq); - - /* Clock the interrupt controller */ - clk = of_clk_get(np, 0); - if (IS_ERR(clk)) - return PTR_ERR(clk); - - ret = clk_prepare_enable(clk); - if (ret) - return ret; - - rate = clk_get_rate(clk); - - u300_clockevent_data.ticks_per_jiffy = DIV_ROUND_CLOSEST(rate, HZ); - - sched_clock_register(u300_read_sched_clock, 32, rate); - - u300_delay_timer.read_current_timer = &u300_read_current_timer; - u300_delay_timer.freq = rate; - register_current_timer_delay(&u300_delay_timer); - - /* - * Disable the "OS" and "DD" timers - these are designed for Symbian! - * Example usage in cnh1601578 cpu subsystem pd_timer_app.c - */ - writel(U300_TIMER_APP_CRC_CLOCK_REQUEST_ENABLE, - u300_timer_base + U300_TIMER_APP_CRC); - writel(U300_TIMER_APP_ROST_TIMER_RESET, - u300_timer_base + U300_TIMER_APP_ROST); - writel(U300_TIMER_APP_DOST_TIMER_DISABLE, - u300_timer_base + U300_TIMER_APP_DOST); - writel(U300_TIMER_APP_RDDT_TIMER_RESET, - u300_timer_base + U300_TIMER_APP_RDDT); - writel(U300_TIMER_APP_DDDT_TIMER_DISABLE, - u300_timer_base + U300_TIMER_APP_DDDT); - - /* Reset the General Purpose timer 1. */ - writel(U300_TIMER_APP_RGPT1_TIMER_RESET, - u300_timer_base + U300_TIMER_APP_RGPT1); - - /* Set up the IRQ handler */ - ret = request_irq(irq, u300_timer_interrupt, - IRQF_TIMER | IRQF_IRQPOLL, "U300 Timer Tick", NULL); - if (ret) - return ret; - - /* Reset the General Purpose timer 2 */ - writel(U300_TIMER_APP_RGPT2_TIMER_RESET, - u300_timer_base + U300_TIMER_APP_RGPT2); - /* Set this timer to run around forever */ - writel(0xFFFFFFFFU, u300_timer_base + U300_TIMER_APP_GPT2TC); - /* Set continuous mode so it wraps around */ - writel(U300_TIMER_APP_SGPT2M_MODE_CONTINUOUS, - u300_timer_base + U300_TIMER_APP_SGPT2M); - /* Disable timer interrupts */ - writel(U300_TIMER_APP_GPT2IE_IRQ_DISABLE, - u300_timer_base + U300_TIMER_APP_GPT2IE); - /* Then enable the GP2 timer to use as a free running us counter */ - writel(U300_TIMER_APP_EGPT2_TIMER_ENABLE, - u300_timer_base + U300_TIMER_APP_EGPT2); - - /* Use general purpose timer 2 as clock source */ - ret = clocksource_mmio_init(u300_timer_base + U300_TIMER_APP_GPT2CC, - "GPT2", rate, 300, 32, clocksource_mmio_readl_up); - if (ret) { - pr_err("timer: failed to initialize U300 clock source\n"); - return ret; - } - - /* Configure and register the clockevent */ - clockevents_config_and_register(&u300_clockevent_data.cevd, rate, - 1, 0xffffffff); - - /* - * TODO: init and register the rest of the timers too, they can be - * used by hrtimers! - */ - return 0; -} - -TIMER_OF_DECLARE(u300_timer, "stericsson,u300-apptimer", - u300_timer_init_of); -- cgit v1.2.3 From 8fefe3ce6b7d11a551d98557d5dfc5eba6477409 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Wed, 20 Jan 2021 17:23:59 +0100 Subject: thermal/drivers/tango: Remove tango driver The tango platform is getting removed, so the driver is no longer needed. Cc: Marc Gonzalez Cc: Mans Rullgard Signed-off-by: Arnd Bergmann Acked-by: Mans Rullgard Signed-off-by: Daniel Lezcano Link: https://lore.kernel.org/r/20210120162400.4115366-2-arnd@kernel.org --- .../devicetree/bindings/thermal/tango-thermal.txt | 17 --- drivers/thermal/Kconfig | 9 -- drivers/thermal/Makefile | 1 - drivers/thermal/tango_thermal.c | 126 --------------------- 4 files changed, 153 deletions(-) delete mode 100644 Documentation/devicetree/bindings/thermal/tango-thermal.txt delete mode 100644 drivers/thermal/tango_thermal.c (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/thermal/tango-thermal.txt b/Documentation/devicetree/bindings/thermal/tango-thermal.txt deleted file mode 100644 index 2c918d742867..000000000000 --- a/Documentation/devicetree/bindings/thermal/tango-thermal.txt +++ /dev/null @@ -1,17 +0,0 @@ -* Tango Thermal - -The SMP8758 SoC includes 3 instances of this temperature sensor -(in the CPU, video decoder, and PCIe controller). - -Required properties: -- #thermal-sensor-cells: Should be 0 (see Documentation/devicetree/bindings/thermal/thermal-sensor.yaml) -- compatible: "sigma,smp8758-thermal" -- reg: Address range of the thermal registers - -Example: - - cpu_temp: thermal@920100 { - #thermal-sensor-cells = <0>; - compatible = "sigma,smp8758-thermal"; - reg = <0x920100 12>; - }; diff --git a/drivers/thermal/Kconfig b/drivers/thermal/Kconfig index 7edc8dc6bbab..cf199574c096 100644 --- a/drivers/thermal/Kconfig +++ b/drivers/thermal/Kconfig @@ -450,15 +450,6 @@ depends on (ARCH_STI || ARCH_STM32) && OF source "drivers/thermal/st/Kconfig" endmenu -config TANGO_THERMAL - tristate "Tango thermal management" - depends on ARCH_TANGO || COMPILE_TEST - help - Enable the Tango thermal driver, which supports the primitive - temperature sensor embedded in Tango chips since the SMP8758. - This sensor only generates a 1-bit signal to indicate whether - the die temperature exceeds a programmable threshold. - source "drivers/thermal/tegra/Kconfig" config GENERIC_ADC_THERMAL diff --git a/drivers/thermal/Makefile b/drivers/thermal/Makefile index b64dd50a6629..a44dda2d03bc 100644 --- a/drivers/thermal/Makefile +++ b/drivers/thermal/Makefile @@ -42,7 +42,6 @@ obj-y += samsung/ obj-$(CONFIG_DOVE_THERMAL) += dove_thermal.o obj-$(CONFIG_DB8500_THERMAL) += db8500_thermal.o obj-$(CONFIG_ARMADA_THERMAL) += armada_thermal.o -obj-$(CONFIG_TANGO_THERMAL) += tango_thermal.o obj-$(CONFIG_IMX_THERMAL) += imx_thermal.o obj-$(CONFIG_IMX_SC_THERMAL) += imx_sc_thermal.o obj-$(CONFIG_IMX8MM_THERMAL) += imx8mm_thermal.o diff --git a/drivers/thermal/tango_thermal.c b/drivers/thermal/tango_thermal.c deleted file mode 100644 index 304b461e12aa..000000000000 --- a/drivers/thermal/tango_thermal.c +++ /dev/null @@ -1,126 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -#include -#include -#include -#include -#include - -/* - * According to a data sheet draft, "this temperature sensor uses a bandgap - * type of circuit to compare a voltage which has a negative temperature - * coefficient with a voltage that is proportional to absolute temperature. - * A resistor bank allows 41 different temperature thresholds to be selected - * and the logic output will then indicate whether the actual die temperature - * lies above or below the selected threshold." - */ - -#define TEMPSI_CMD 0 -#define TEMPSI_RES 4 -#define TEMPSI_CFG 8 - -#define CMD_OFF 0 -#define CMD_ON 1 -#define CMD_READ 2 - -#define IDX_MIN 15 -#define IDX_MAX 40 - -struct tango_thermal_priv { - void __iomem *base; - int thresh_idx; -}; - -static bool temp_above_thresh(void __iomem *base, int thresh_idx) -{ - writel(CMD_READ | thresh_idx << 8, base + TEMPSI_CMD); - usleep_range(10, 20); - writel(CMD_READ | thresh_idx << 8, base + TEMPSI_CMD); - - return readl(base + TEMPSI_RES); -} - -static int tango_get_temp(void *arg, int *res) -{ - struct tango_thermal_priv *priv = arg; - int idx = priv->thresh_idx; - - if (temp_above_thresh(priv->base, idx)) { - /* Search upward by incrementing thresh_idx */ - while (idx < IDX_MAX && temp_above_thresh(priv->base, ++idx)) - cpu_relax(); - idx = idx - 1; /* always return lower bound */ - } else { - /* Search downward by decrementing thresh_idx */ - while (idx > IDX_MIN && !temp_above_thresh(priv->base, --idx)) - cpu_relax(); - } - - *res = (idx * 9 / 2 - 38) * 1000; /* millidegrees Celsius */ - priv->thresh_idx = idx; - - return 0; -} - -static const struct thermal_zone_of_device_ops ops = { - .get_temp = tango_get_temp, -}; - -static void tango_thermal_init(struct tango_thermal_priv *priv) -{ - writel(0, priv->base + TEMPSI_CFG); - writel(CMD_ON, priv->base + TEMPSI_CMD); -} - -static int tango_thermal_probe(struct platform_device *pdev) -{ - struct resource *res; - struct tango_thermal_priv *priv; - struct thermal_zone_device *tzdev; - - priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); - if (!priv) - return -ENOMEM; - - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - priv->base = devm_ioremap_resource(&pdev->dev, res); - if (IS_ERR(priv->base)) - return PTR_ERR(priv->base); - - platform_set_drvdata(pdev, priv); - priv->thresh_idx = IDX_MIN; - tango_thermal_init(priv); - - tzdev = devm_thermal_zone_of_sensor_register(&pdev->dev, 0, priv, &ops); - return PTR_ERR_OR_ZERO(tzdev); -} - -static int __maybe_unused tango_thermal_resume(struct device *dev) -{ - tango_thermal_init(dev_get_drvdata(dev)); - return 0; -} - -static SIMPLE_DEV_PM_OPS(tango_thermal_pm, NULL, tango_thermal_resume); - -static const struct of_device_id tango_sensor_ids[] = { - { - .compatible = "sigma,smp8758-thermal", - }, - { /* sentinel */ } -}; -MODULE_DEVICE_TABLE(of, tango_sensor_ids); - -static struct platform_driver tango_thermal_driver = { - .probe = tango_thermal_probe, - .driver = { - .name = "tango-thermal", - .of_match_table = tango_sensor_ids, - .pm = &tango_thermal_pm, - }, -}; - -module_platform_driver(tango_thermal_driver); - -MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Sigma Designs"); -MODULE_DESCRIPTION("Tango temperature sensor"); -- cgit v1.2.3 From 73da3f0cca94555d08d62b60ec9b8b9582bc1313 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Wed, 20 Jan 2021 17:24:00 +0100 Subject: thermal/drivers/zx: Remove zx driver The zte zx platform is getting removed, so this driver is no longer needed. Cc: Jun Nie Cc: Shawn Guo Signed-off-by: Arnd Bergmann Signed-off-by: Daniel Lezcano Link: https://lore.kernel.org/r/20210120162400.4115366-3-arnd@kernel.org --- .../devicetree/bindings/thermal/zx2967-thermal.txt | 116 ---------- drivers/thermal/Kconfig | 8 - drivers/thermal/Makefile | 1 - drivers/thermal/zx2967_thermal.c | 256 --------------------- 4 files changed, 381 deletions(-) delete mode 100644 Documentation/devicetree/bindings/thermal/zx2967-thermal.txt delete mode 100644 drivers/thermal/zx2967_thermal.c (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/thermal/zx2967-thermal.txt b/Documentation/devicetree/bindings/thermal/zx2967-thermal.txt deleted file mode 100644 index 3dc1c6bf0478..000000000000 --- a/Documentation/devicetree/bindings/thermal/zx2967-thermal.txt +++ /dev/null @@ -1,116 +0,0 @@ -* ZTE zx2967 family Thermal - -Required Properties: -- compatible: should be one of the following. - * zte,zx296718-thermal -- reg: physical base address of the controller and length of memory mapped - region. -- clocks : Pairs of phandle and specifier referencing the controller's clocks. -- clock-names: "topcrm" for the topcrm clock. - "apb" for the apb clock. -- #thermal-sensor-cells: must be 0. - -Please note: slope coefficient defined in thermal-zones section need to be -multiplied by 1000. - -Example for tempsensor: - - tempsensor: tempsensor@148a000 { - compatible = "zte,zx296718-thermal"; - reg = <0x0148a000 0x20>; - clocks = <&topcrm TEMPSENSOR_GATE>, <&audiocrm AUDIO_TS_PCLK>; - clock-names = "topcrm", "apb"; - #thermal-sensor-cells = <0>; - }; - -Example for cooling device: - - cooling_dev: cooling_dev { - cluster0_cooling_dev: cluster0-cooling-dev { - #cooling-cells = <2>; - cpumask = <0xf>; - capacitance = <1500>; - }; - - cluster1_cooling_dev: cluster1-cooling-dev { - #cooling-cells = <2>; - cpumask = <0x30>; - capacitance = <2000>; - }; - }; - -Example for thermal zones: - - thermal-zones { - zx296718_thermal: zx296718_thermal { - polling-delay-passive = <500>; - polling-delay = <1000>; - sustainable-power = <6500>; - - thermal-sensors = <&tempsensor 0>; - /* - * slope need to be multiplied by 1000. - */ - coefficients = <1951 (-922)>; - - trips { - trip0: switch_on_temperature { - temperature = <90000>; - hysteresis = <2000>; - type = "passive"; - }; - - trip1: desired_temperature { - temperature = <100000>; - hysteresis = <2000>; - type = "passive"; - }; - - crit: critical_temperature { - temperature = <110000>; - hysteresis = <2000>; - type = "critical"; - }; - }; - - cooling-maps { - map0 { - trip = <&trip0>; - cooling-device = <&gpu 2 5>; - }; - - map1 { - trip = <&trip0>; - cooling-device = <&cluster0_cooling_dev 1 2>; - }; - - map2 { - trip = <&trip1>; - cooling-device = <&cluster0_cooling_dev 1 2>; - }; - - map3 { - trip = <&crit>; - cooling-device = <&cluster0_cooling_dev 1 2>; - }; - - map4 { - trip = <&trip0>; - cooling-device = <&cluster1_cooling_dev 1 2>; - contribution = <9000>; - }; - - map5 { - trip = <&trip1>; - cooling-device = <&cluster1_cooling_dev 1 2>; - contribution = <4096>; - }; - - map6 { - trip = <&crit>; - cooling-device = <&cluster1_cooling_dev 1 2>; - contribution = <4096>; - }; - }; - }; - }; diff --git a/drivers/thermal/Kconfig b/drivers/thermal/Kconfig index cf199574c096..d7f44deab5b1 100644 --- a/drivers/thermal/Kconfig +++ b/drivers/thermal/Kconfig @@ -467,14 +467,6 @@ depends on (ARCH_QCOM && OF) || COMPILE_TEST source "drivers/thermal/qcom/Kconfig" endmenu -config ZX2967_THERMAL - tristate "Thermal sensors on zx2967 SoC" - depends on ARCH_ZX || COMPILE_TEST - help - Enable the zx2967 thermal sensors driver, which supports - the primitive temperature sensor embedded in zx2967 SoCs. - This sensor generates the real time die temperature. - config UNIPHIER_THERMAL tristate "Socionext UniPhier thermal driver" depends on ARCH_UNIPHIER || COMPILE_TEST diff --git a/drivers/thermal/Makefile b/drivers/thermal/Makefile index a44dda2d03bc..82fc3e616e54 100644 --- a/drivers/thermal/Makefile +++ b/drivers/thermal/Makefile @@ -56,7 +56,6 @@ obj-y += tegra/ obj-$(CONFIG_HISI_THERMAL) += hisi_thermal.o obj-$(CONFIG_MTK_THERMAL) += mtk_thermal.o obj-$(CONFIG_GENERIC_ADC_THERMAL) += thermal-generic-adc.o -obj-$(CONFIG_ZX2967_THERMAL) += zx2967_thermal.o obj-$(CONFIG_UNIPHIER_THERMAL) += uniphier_thermal.o obj-$(CONFIG_AMLOGIC_THERMAL) += amlogic_thermal.o obj-$(CONFIG_SPRD_THERMAL) += sprd_thermal.o diff --git a/drivers/thermal/zx2967_thermal.c b/drivers/thermal/zx2967_thermal.c deleted file mode 100644 index 8e3a2d3c2f9a..000000000000 --- a/drivers/thermal/zx2967_thermal.c +++ /dev/null @@ -1,256 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * ZTE's zx2967 family thermal sensor driver - * - * Copyright (C) 2017 ZTE Ltd. - * - * Author: Baoyou Xie - */ - -#include -#include -#include -#include -#include -#include -#include - -/* Power Mode: 0->low 1->high */ -#define ZX2967_THERMAL_POWER_MODE 0 -#define ZX2967_POWER_MODE_LOW 0 -#define ZX2967_POWER_MODE_HIGH 1 - -/* DCF Control Register */ -#define ZX2967_THERMAL_DCF 0x4 -#define ZX2967_DCF_EN BIT(1) -#define ZX2967_DCF_FREEZE BIT(0) - -/* Selection Register */ -#define ZX2967_THERMAL_SEL 0x8 - -/* Control Register */ -#define ZX2967_THERMAL_CTRL 0x10 - -#define ZX2967_THERMAL_READY BIT(12) -#define ZX2967_THERMAL_TEMP_MASK GENMASK(11, 0) -#define ZX2967_THERMAL_ID_MASK 0x18 -#define ZX2967_THERMAL_ID 0x10 - -#define ZX2967_GET_TEMP_TIMEOUT_US (100 * 1024) - -/** - * struct zx2967_thermal_priv - zx2967 thermal sensor private structure - * @tzd: struct thermal_zone_device where the sensor is registered - * @lock: prevents read sensor in parallel - * @clk_topcrm: topcrm clk structure - * @clk_apb: apb clk structure - * @regs: pointer to base address of the thermal sensor - * @dev: struct device pointer - */ - -struct zx2967_thermal_priv { - struct thermal_zone_device *tzd; - struct mutex lock; - struct clk *clk_topcrm; - struct clk *clk_apb; - void __iomem *regs; - struct device *dev; -}; - -static int zx2967_thermal_get_temp(void *data, int *temp) -{ - void __iomem *regs; - struct zx2967_thermal_priv *priv = data; - u32 val; - int ret; - - if (!priv->tzd) - return -EAGAIN; - - regs = priv->regs; - mutex_lock(&priv->lock); - writel_relaxed(ZX2967_POWER_MODE_LOW, - regs + ZX2967_THERMAL_POWER_MODE); - writel_relaxed(ZX2967_DCF_EN, regs + ZX2967_THERMAL_DCF); - - val = readl_relaxed(regs + ZX2967_THERMAL_SEL); - val &= ~ZX2967_THERMAL_ID_MASK; - val |= ZX2967_THERMAL_ID; - writel_relaxed(val, regs + ZX2967_THERMAL_SEL); - - /* - * Must wait for a while, surely it's a bit odd. - * otherwise temperature value we got has a few deviation, even if - * the THERMAL_READY bit is set. - */ - usleep_range(100, 300); - ret = readx_poll_timeout(readl, regs + ZX2967_THERMAL_CTRL, - val, val & ZX2967_THERMAL_READY, 300, - ZX2967_GET_TEMP_TIMEOUT_US); - if (ret) { - dev_err(priv->dev, "Thermal sensor data timeout\n"); - goto unlock; - } - - writel_relaxed(ZX2967_DCF_FREEZE | ZX2967_DCF_EN, - regs + ZX2967_THERMAL_DCF); - val = readl_relaxed(regs + ZX2967_THERMAL_CTRL) - & ZX2967_THERMAL_TEMP_MASK; - writel_relaxed(ZX2967_POWER_MODE_HIGH, - regs + ZX2967_THERMAL_POWER_MODE); - - /* - * Calculate temperature - * In dts, slope is multiplied by 1000. - */ - *temp = DIV_ROUND_CLOSEST(((s32)val + priv->tzd->tzp->offset) * 1000, - priv->tzd->tzp->slope); - -unlock: - mutex_unlock(&priv->lock); - return ret; -} - -static const struct thermal_zone_of_device_ops zx2967_of_thermal_ops = { - .get_temp = zx2967_thermal_get_temp, -}; - -static int zx2967_thermal_probe(struct platform_device *pdev) -{ - struct zx2967_thermal_priv *priv; - struct resource *res; - int ret; - - priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); - if (!priv) - return -ENOMEM; - - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - priv->regs = devm_ioremap_resource(&pdev->dev, res); - if (IS_ERR(priv->regs)) - return PTR_ERR(priv->regs); - - priv->clk_topcrm = devm_clk_get(&pdev->dev, "topcrm"); - if (IS_ERR(priv->clk_topcrm)) { - ret = PTR_ERR(priv->clk_topcrm); - dev_err(&pdev->dev, "failed to get topcrm clock: %d\n", ret); - return ret; - } - - ret = clk_prepare_enable(priv->clk_topcrm); - if (ret) { - dev_err(&pdev->dev, "failed to enable topcrm clock: %d\n", - ret); - return ret; - } - - priv->clk_apb = devm_clk_get(&pdev->dev, "apb"); - if (IS_ERR(priv->clk_apb)) { - ret = PTR_ERR(priv->clk_apb); - dev_err(&pdev->dev, "failed to get apb clock: %d\n", ret); - goto disable_clk_topcrm; - } - - ret = clk_prepare_enable(priv->clk_apb); - if (ret) { - dev_err(&pdev->dev, "failed to enable apb clock: %d\n", - ret); - goto disable_clk_topcrm; - } - - mutex_init(&priv->lock); - priv->tzd = thermal_zone_of_sensor_register(&pdev->dev, - 0, priv, &zx2967_of_thermal_ops); - - if (IS_ERR(priv->tzd)) { - ret = PTR_ERR(priv->tzd); - dev_err(&pdev->dev, "failed to register sensor: %d\n", ret); - goto disable_clk_all; - } - - if (priv->tzd->tzp->slope == 0) { - thermal_zone_of_sensor_unregister(&pdev->dev, priv->tzd); - dev_err(&pdev->dev, "coefficients of sensor is invalid\n"); - ret = -EINVAL; - goto disable_clk_all; - } - - priv->dev = &pdev->dev; - platform_set_drvdata(pdev, priv); - - return 0; - -disable_clk_all: - clk_disable_unprepare(priv->clk_apb); -disable_clk_topcrm: - clk_disable_unprepare(priv->clk_topcrm); - return ret; -} - -static int zx2967_thermal_exit(struct platform_device *pdev) -{ - struct zx2967_thermal_priv *priv = platform_get_drvdata(pdev); - - thermal_zone_of_sensor_unregister(&pdev->dev, priv->tzd); - clk_disable_unprepare(priv->clk_topcrm); - clk_disable_unprepare(priv->clk_apb); - - return 0; -} - -static const struct of_device_id zx2967_thermal_id_table[] = { - { .compatible = "zte,zx296718-thermal" }, - {} -}; -MODULE_DEVICE_TABLE(of, zx2967_thermal_id_table); - -#ifdef CONFIG_PM_SLEEP -static int zx2967_thermal_suspend(struct device *dev) -{ - struct zx2967_thermal_priv *priv = dev_get_drvdata(dev); - - if (priv && priv->clk_topcrm) - clk_disable_unprepare(priv->clk_topcrm); - - if (priv && priv->clk_apb) - clk_disable_unprepare(priv->clk_apb); - - return 0; -} - -static int zx2967_thermal_resume(struct device *dev) -{ - struct zx2967_thermal_priv *priv = dev_get_drvdata(dev); - int error; - - error = clk_prepare_enable(priv->clk_topcrm); - if (error) - return error; - - error = clk_prepare_enable(priv->clk_apb); - if (error) { - clk_disable_unprepare(priv->clk_topcrm); - return error; - } - - return 0; -} -#endif - -static SIMPLE_DEV_PM_OPS(zx2967_thermal_pm_ops, - zx2967_thermal_suspend, zx2967_thermal_resume); - -static struct platform_driver zx2967_thermal_driver = { - .probe = zx2967_thermal_probe, - .remove = zx2967_thermal_exit, - .driver = { - .name = "zx2967_thermal", - .of_match_table = zx2967_thermal_id_table, - .pm = &zx2967_thermal_pm_ops, - }, -}; -module_platform_driver(zx2967_thermal_driver); - -MODULE_AUTHOR("Baoyou Xie "); -MODULE_DESCRIPTION("ZTE zx2967 thermal driver"); -MODULE_LICENSE("GPL v2"); -- cgit v1.2.3 From 09d85f8d8909ec8baa07479ba5777bbca24961f3 Mon Sep 17 00:00:00 2001 From: Mikulas Patocka Date: Thu, 21 Jan 2021 10:09:32 -0500 Subject: dm integrity: introduce the "fix_hmac" argument The "fix_hmac" argument improves security of internal_hash and journal_mac: - the section number is mixed to the mac, so that an attacker can't copy sectors from one journal section to another journal section - the superblock is protected by journal_mac - a 16-byte salt stored in the superblock is mixed to the mac, so that the attacker can't detect that two disks have the same hmac key and also to disallow the attacker to move sectors from one disk to another Signed-off-by: Mikulas Patocka Reported-by: Daniel Glockner Signed-off-by: Lukas Bulwahn # ReST fix Tested-by: Milan Broz Signed-off-by: Mike Snitzer --- .../admin-guide/device-mapper/dm-integrity.rst | 11 ++ drivers/md/dm-integrity.c | 138 +++++++++++++++++++-- 2 files changed, 136 insertions(+), 13 deletions(-) (limited to 'Documentation') diff --git a/Documentation/admin-guide/device-mapper/dm-integrity.rst b/Documentation/admin-guide/device-mapper/dm-integrity.rst index 2cc5488acbd9..ef762857da95 100644 --- a/Documentation/admin-guide/device-mapper/dm-integrity.rst +++ b/Documentation/admin-guide/device-mapper/dm-integrity.rst @@ -186,6 +186,17 @@ fix_padding space-efficient. If this option is not present, large padding is used - that is for compatibility with older kernels. +fix_hmac + Improve security of internal_hash and journal_mac: + + - the section number is mixed to the mac, so that an attacker can't + copy sectors from one journal section to another journal section + - the superblock is protected by journal_mac + - a 16-byte salt stored in the superblock is mixed to the mac, so + that the attacker can't detect that two disks have the same hmac + key and also to disallow the attacker to move sectors from one + disk to another + legacy_recalculate Allow recalculating of volumes with HMAC keys. This is disabled by default for security reasons - an attacker could modify the volume, diff --git a/drivers/md/dm-integrity.c b/drivers/md/dm-integrity.c index 7e48639e4036..46b5d542b8fe 100644 --- a/drivers/md/dm-integrity.c +++ b/drivers/md/dm-integrity.c @@ -40,6 +40,7 @@ #define BITMAP_BLOCK_SIZE 4096 /* don't change it */ #define BITMAP_FLUSH_INTERVAL (10 * HZ) #define DISCARD_FILLER 0xf6 +#define SALT_SIZE 16 /* * Warning - DEBUG_PRINT prints security-sensitive data to the log, @@ -57,6 +58,7 @@ #define SB_VERSION_2 2 #define SB_VERSION_3 3 #define SB_VERSION_4 4 +#define SB_VERSION_5 5 #define SB_SECTORS 8 #define MAX_SECTORS_PER_BLOCK 8 @@ -72,12 +74,15 @@ struct superblock { __u8 log2_blocks_per_bitmap_bit; __u8 pad[2]; __u64 recalc_sector; + __u8 pad2[8]; + __u8 salt[SALT_SIZE]; }; #define SB_FLAG_HAVE_JOURNAL_MAC 0x1 #define SB_FLAG_RECALCULATING 0x2 #define SB_FLAG_DIRTY_BITMAP 0x4 #define SB_FLAG_FIXED_PADDING 0x8 +#define SB_FLAG_FIXED_HMAC 0x10 #define JOURNAL_ENTRY_ROUNDUP 8 @@ -259,6 +264,7 @@ struct dm_integrity_c { bool recalculate_flag; bool discard; bool fix_padding; + bool fix_hmac; bool legacy_recalculate; struct alg_spec internal_hash_alg; @@ -389,8 +395,11 @@ static int dm_integrity_failed(struct dm_integrity_c *ic) static bool dm_integrity_disable_recalculate(struct dm_integrity_c *ic) { - if ((ic->internal_hash_alg.key || ic->journal_mac_alg.key) && - !ic->legacy_recalculate) + if (ic->legacy_recalculate) + return false; + if (!(ic->sb->flags & cpu_to_le32(SB_FLAG_FIXED_HMAC)) ? + ic->internal_hash_alg.key || ic->journal_mac_alg.key : + ic->internal_hash_alg.key && !ic->journal_mac_alg.key) return true; return false; } @@ -477,7 +486,9 @@ static void wraparound_section(struct dm_integrity_c *ic, unsigned *sec_ptr) static void sb_set_version(struct dm_integrity_c *ic) { - if (ic->sb->flags & cpu_to_le32(SB_FLAG_FIXED_PADDING)) + if (ic->sb->flags & cpu_to_le32(SB_FLAG_FIXED_HMAC)) + ic->sb->version = SB_VERSION_5; + else if (ic->sb->flags & cpu_to_le32(SB_FLAG_FIXED_PADDING)) ic->sb->version = SB_VERSION_4; else if (ic->mode == 'B' || ic->sb->flags & cpu_to_le32(SB_FLAG_DIRTY_BITMAP)) ic->sb->version = SB_VERSION_3; @@ -487,10 +498,58 @@ static void sb_set_version(struct dm_integrity_c *ic) ic->sb->version = SB_VERSION_1; } +static int sb_mac(struct dm_integrity_c *ic, bool wr) +{ + SHASH_DESC_ON_STACK(desc, ic->journal_mac); + int r; + unsigned size = crypto_shash_digestsize(ic->journal_mac); + + if (sizeof(struct superblock) + size > 1 << SECTOR_SHIFT) { + dm_integrity_io_error(ic, "digest is too long", -EINVAL); + return -EINVAL; + } + + desc->tfm = ic->journal_mac; + + r = crypto_shash_init(desc); + if (unlikely(r < 0)) { + dm_integrity_io_error(ic, "crypto_shash_init", r); + return r; + } + + r = crypto_shash_update(desc, (__u8 *)ic->sb, (1 << SECTOR_SHIFT) - size); + if (unlikely(r < 0)) { + dm_integrity_io_error(ic, "crypto_shash_update", r); + return r; + } + + if (likely(wr)) { + r = crypto_shash_final(desc, (__u8 *)ic->sb + (1 << SECTOR_SHIFT) - size); + if (unlikely(r < 0)) { + dm_integrity_io_error(ic, "crypto_shash_final", r); + return r; + } + } else { + __u8 result[HASH_MAX_DIGESTSIZE]; + r = crypto_shash_final(desc, result); + if (unlikely(r < 0)) { + dm_integrity_io_error(ic, "crypto_shash_final", r); + return r; + } + if (memcmp((__u8 *)ic->sb + (1 << SECTOR_SHIFT) - size, result, size)) { + dm_integrity_io_error(ic, "superblock mac", -EILSEQ); + return -EILSEQ; + } + } + + return 0; +} + static int sync_rw_sb(struct dm_integrity_c *ic, int op, int op_flags) { struct dm_io_request io_req; struct dm_io_region io_loc; + int r; io_req.bi_op = op; io_req.bi_op_flags = op_flags; @@ -502,10 +561,28 @@ static int sync_rw_sb(struct dm_integrity_c *ic, int op, int op_flags) io_loc.sector = ic->start; io_loc.count = SB_SECTORS; - if (op == REQ_OP_WRITE) + if (op == REQ_OP_WRITE) { sb_set_version(ic); + if (ic->journal_mac && ic->sb->flags & cpu_to_le32(SB_FLAG_FIXED_HMAC)) { + r = sb_mac(ic, true); + if (unlikely(r)) + return r; + } + } - return dm_io(&io_req, 1, &io_loc, NULL); + r = dm_io(&io_req, 1, &io_loc, NULL); + if (unlikely(r)) + return r; + + if (op == REQ_OP_READ) { + if (ic->mode != 'R' && ic->journal_mac && ic->sb->flags & cpu_to_le32(SB_FLAG_FIXED_HMAC)) { + r = sb_mac(ic, false); + if (unlikely(r)) + return r; + } + } + + return 0; } #define BITMAP_OP_TEST_ALL_SET 0 @@ -722,15 +799,32 @@ static void section_mac(struct dm_integrity_c *ic, unsigned section, __u8 result desc->tfm = ic->journal_mac; r = crypto_shash_init(desc); - if (unlikely(r)) { + if (unlikely(r < 0)) { dm_integrity_io_error(ic, "crypto_shash_init", r); goto err; } + if (ic->sb->flags & cpu_to_le32(SB_FLAG_FIXED_HMAC)) { + uint64_t section_le; + + r = crypto_shash_update(desc, (__u8 *)&ic->sb->salt, SALT_SIZE); + if (unlikely(r < 0)) { + dm_integrity_io_error(ic, "crypto_shash_update", r); + goto err; + } + + section_le = cpu_to_le64(section); + r = crypto_shash_update(desc, (__u8 *)§ion_le, sizeof section_le); + if (unlikely(r < 0)) { + dm_integrity_io_error(ic, "crypto_shash_update", r); + goto err; + } + } + for (j = 0; j < ic->journal_section_entries; j++) { struct journal_entry *je = access_journal_entry(ic, section, j); r = crypto_shash_update(desc, (__u8 *)&je->u.sector, sizeof je->u.sector); - if (unlikely(r)) { + if (unlikely(r < 0)) { dm_integrity_io_error(ic, "crypto_shash_update", r); goto err; } @@ -740,7 +834,7 @@ static void section_mac(struct dm_integrity_c *ic, unsigned section, __u8 result if (likely(size <= JOURNAL_MAC_SIZE)) { r = crypto_shash_final(desc, result); - if (unlikely(r)) { + if (unlikely(r < 0)) { dm_integrity_io_error(ic, "crypto_shash_final", r); goto err; } @@ -753,7 +847,7 @@ static void section_mac(struct dm_integrity_c *ic, unsigned section, __u8 result goto err; } r = crypto_shash_final(desc, digest); - if (unlikely(r)) { + if (unlikely(r < 0)) { dm_integrity_io_error(ic, "crypto_shash_final", r); goto err; } @@ -1556,6 +1650,14 @@ static void integrity_sector_checksum(struct dm_integrity_c *ic, sector_t sector goto failed; } + if (ic->sb->flags & cpu_to_le32(SB_FLAG_FIXED_HMAC)) { + r = crypto_shash_update(req, (__u8 *)&ic->sb->salt, SALT_SIZE); + if (unlikely(r < 0)) { + dm_integrity_io_error(ic, "crypto_shash_update", r); + goto failed; + } + } + r = crypto_shash_update(req, (const __u8 *)§or_le, sizeof sector_le); if (unlikely(r < 0)) { dm_integrity_io_error(ic, "crypto_shash_update", r); @@ -3149,6 +3251,7 @@ static void dm_integrity_status(struct dm_target *ti, status_type_t type, arg_count += !!ic->journal_crypt_alg.alg_string; arg_count += !!ic->journal_mac_alg.alg_string; arg_count += (ic->sb->flags & cpu_to_le32(SB_FLAG_FIXED_PADDING)) != 0; + arg_count += (ic->sb->flags & cpu_to_le32(SB_FLAG_FIXED_HMAC)) != 0; arg_count += ic->legacy_recalculate; DMEMIT("%s %llu %u %c %u", ic->dev->name, ic->start, ic->tag_size, ic->mode, arg_count); @@ -3173,6 +3276,8 @@ static void dm_integrity_status(struct dm_target *ti, status_type_t type, } if ((ic->sb->flags & cpu_to_le32(SB_FLAG_FIXED_PADDING)) != 0) DMEMIT(" fix_padding"); + if ((ic->sb->flags & cpu_to_le32(SB_FLAG_FIXED_HMAC)) != 0) + DMEMIT(" fix_hmac"); if (ic->legacy_recalculate) DMEMIT(" legacy_recalculate"); @@ -3310,6 +3415,11 @@ static int initialize_superblock(struct dm_integrity_c *ic, unsigned journal_sec if (!journal_sections) journal_sections = 1; + if (ic->fix_hmac && (ic->internal_hash_alg.alg_string || ic->journal_mac_alg.alg_string)) { + ic->sb->flags |= cpu_to_le32(SB_FLAG_FIXED_HMAC); + get_random_bytes(ic->sb->salt, SALT_SIZE); + } + if (!ic->meta_dev) { if (ic->fix_padding) ic->sb->flags |= cpu_to_le32(SB_FLAG_FIXED_PADDING); @@ -3804,7 +3914,7 @@ static int dm_integrity_ctr(struct dm_target *ti, unsigned argc, char **argv) unsigned extra_args; struct dm_arg_set as; static const struct dm_arg _args[] = { - {0, 16, "Invalid number of feature args"}, + {0, 17, "Invalid number of feature args"}, }; unsigned journal_sectors, interleave_sectors, buffer_sectors, journal_watermark, sync_msec; bool should_write_sb; @@ -3942,7 +4052,7 @@ static int dm_integrity_ctr(struct dm_target *ti, unsigned argc, char **argv) if (r) goto bad; } else if (!strncmp(opt_string, "journal_mac:", strlen("journal_mac:"))) { - r = get_alg_and_key(opt_string, &ic->journal_mac_alg, &ti->error, + r = get_alg_and_key(opt_string, &ic->journal_mac_alg, &ti->error, "Invalid journal_mac argument"); if (r) goto bad; @@ -3952,6 +4062,8 @@ static int dm_integrity_ctr(struct dm_target *ti, unsigned argc, char **argv) ic->discard = true; } else if (!strcmp(opt_string, "fix_padding")) { ic->fix_padding = true; + } else if (!strcmp(opt_string, "fix_hmac")) { + ic->fix_hmac = true; } else if (!strcmp(opt_string, "legacy_recalculate")) { ic->legacy_recalculate = true; } else { @@ -4110,7 +4222,7 @@ static int dm_integrity_ctr(struct dm_target *ti, unsigned argc, char **argv) should_write_sb = true; } - if (!ic->sb->version || ic->sb->version > SB_VERSION_4) { + if (!ic->sb->version || ic->sb->version > SB_VERSION_5) { r = -EINVAL; ti->error = "Unknown version"; goto bad; @@ -4442,7 +4554,7 @@ static void dm_integrity_dtr(struct dm_target *ti) static struct target_type integrity_target = { .name = "integrity", - .version = {1, 6, 0}, + .version = {1, 7, 0}, .module = THIS_MODULE, .features = DM_TARGET_SINGLETON | DM_TARGET_INTEGRITY, .ctr = dm_integrity_ctr, -- cgit v1.2.3 From 363880c4eb36bd2a70104c165fbc7a6d49858a91 Mon Sep 17 00:00:00 2001 From: Ahmad Fatoum Date: Fri, 22 Jan 2021 09:43:21 +0100 Subject: dm crypt: support using trusted keys Commit 27f5411a718c ("dm crypt: support using encrypted keys") extended dm-crypt to allow use of "encrypted" keys along with "user" and "logon". Along the same lines, teach dm-crypt to support "trusted" keys as well. Signed-off-by: Ahmad Fatoum Signed-off-by: Mike Snitzer --- .../admin-guide/device-mapper/dm-crypt.rst | 2 +- drivers/md/Kconfig | 1 + drivers/md/dm-crypt.c | 23 +++++++++++++++++++++- 3 files changed, 24 insertions(+), 2 deletions(-) (limited to 'Documentation') diff --git a/Documentation/admin-guide/device-mapper/dm-crypt.rst b/Documentation/admin-guide/device-mapper/dm-crypt.rst index 1a6753b76dbb..aa2d04d95df6 100644 --- a/Documentation/admin-guide/device-mapper/dm-crypt.rst +++ b/Documentation/admin-guide/device-mapper/dm-crypt.rst @@ -67,7 +67,7 @@ Parameters:: the value passed in . - Either 'logon', 'user' or 'encrypted' kernel key type. + Either 'logon', 'user', 'encrypted' or 'trusted' kernel key type. The kernel keyring key description crypt target should look for diff --git a/drivers/md/Kconfig b/drivers/md/Kconfig index 9e44c09f6410..f2014385d48b 100644 --- a/drivers/md/Kconfig +++ b/drivers/md/Kconfig @@ -270,6 +270,7 @@ config DM_CRYPT tristate "Crypt target support" depends on BLK_DEV_DM depends on (ENCRYPTED_KEYS || ENCRYPTED_KEYS=n) + depends on (TRUSTED_KEYS || TRUSTED_KEYS=n) select CRYPTO select CRYPTO_CBC select CRYPTO_ESSIV diff --git a/drivers/md/dm-crypt.c b/drivers/md/dm-crypt.c index 1b3b1a806377..ee20b586f526 100644 --- a/drivers/md/dm-crypt.c +++ b/drivers/md/dm-crypt.c @@ -37,6 +37,7 @@ #include #include #include +#include #include @@ -2452,6 +2453,22 @@ static int set_key_encrypted(struct crypt_config *cc, struct key *key) return 0; } +static int set_key_trusted(struct crypt_config *cc, struct key *key) +{ + const struct trusted_key_payload *tkp; + + tkp = key->payload.data[0]; + if (!tkp) + return -EKEYREVOKED; + + if (cc->key_size != tkp->key_len) + return -EINVAL; + + memcpy(cc->key, tkp->key, cc->key_size); + + return 0; +} + static int crypt_set_keyring_key(struct crypt_config *cc, const char *key_string) { char *new_key_string, *key_desc; @@ -2484,6 +2501,10 @@ static int crypt_set_keyring_key(struct crypt_config *cc, const char *key_string !strncmp(key_string, "encrypted:", key_desc - key_string + 1)) { type = &key_type_encrypted; set_key = set_key_encrypted; + } else if (IS_ENABLED(CONFIG_TRUSTED_KEYS) && + !strncmp(key_string, "trusted:", key_desc - key_string + 1)) { + type = &key_type_trusted; + set_key = set_key_trusted; } else { return -EINVAL; } @@ -3555,7 +3576,7 @@ static void crypt_io_hints(struct dm_target *ti, struct queue_limits *limits) static struct target_type crypt_target = { .name = "crypt", - .version = {1, 22, 0}, + .version = {1, 23, 0}, .module = THIS_MODULE, .ctr = crypt_ctr, .dtr = crypt_dtr, -- cgit v1.2.3 From 41a8a027f4d3f81d83b8942ef29f84223ca35ffc Mon Sep 17 00:00:00 2001 From: Timon Baetz Date: Sat, 30 Jan 2021 17:29:17 +0000 Subject: regulator: dt-bindings: Document charger-supply for max8997 Add charger-supply optional property to enable charging control. Signed-off-by: Timon Baetz Reviewed-by: Krzysztof Kozlowski Link: https://lore.kernel.org/r/20210130172747.2022977-2-timon.baetz@protonmail.com Signed-off-by: Mark Brown --- Documentation/devicetree/bindings/regulator/max8997-regulator.txt | 1 + 1 file changed, 1 insertion(+) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/regulator/max8997-regulator.txt b/Documentation/devicetree/bindings/regulator/max8997-regulator.txt index 6fe825b8ac1b..b53c5e2b335f 100644 --- a/Documentation/devicetree/bindings/regulator/max8997-regulator.txt +++ b/Documentation/devicetree/bindings/regulator/max8997-regulator.txt @@ -35,6 +35,7 @@ Optional properties: - interrupts: Interrupt specifiers for two interrupt sources. - First interrupt specifier is for 'irq1' interrupt. - Second interrupt specifier is for 'alert' interrupt. +- charger-supply: regulator node for charging current. - max8997,pmic-buck1-uses-gpio-dvs: 'buck1' can be controlled by gpio dvs. - max8997,pmic-buck2-uses-gpio-dvs: 'buck2' can be controlled by gpio dvs. - max8997,pmic-buck5-uses-gpio-dvs: 'buck5' can be controlled by gpio dvs. -- cgit v1.2.3 From f83d436aef5def77b318effc14809fdc57092588 Mon Sep 17 00:00:00 2001 From: "Darrick J. Wong" Date: Fri, 22 Jan 2021 16:48:41 -0800 Subject: xfs: increase the default parallelism levels of pwork clients Increase the parallelism level for pwork clients to the workqueue defaults so that we can take advantage of computers with a lot of CPUs and a lot of hardware. On fast systems this will speed up quotacheck by a large factor, and the following posteof/cowblocks cleanup series will use the functionality presented in this patch to run garbage collection as quickly as possible. We do this by switching the pwork workqueue to unbounded, since the current user (quotacheck) runs lengthy scans for each work item and we don't care about dispatching the work on a warm cpu cache or anything like that. Also set WQ_SYSFS so that we can monitor where the wq is running. Signed-off-by: Darrick J. Wong Reviewed-by: Christoph Hellwig Reviewed-by: Brian Foster --- Documentation/admin-guide/xfs.rst | 38 ++++++++++++++++++++++++++++++++++++++ fs/xfs/xfs_iwalk.c | 5 +---- fs/xfs/xfs_pwork.c | 25 +++++-------------------- fs/xfs/xfs_pwork.h | 4 +--- 4 files changed, 45 insertions(+), 27 deletions(-) (limited to 'Documentation') diff --git a/Documentation/admin-guide/xfs.rst b/Documentation/admin-guide/xfs.rst index 86de8a1ad91c..b00b1eece9de 100644 --- a/Documentation/admin-guide/xfs.rst +++ b/Documentation/admin-guide/xfs.rst @@ -495,3 +495,41 @@ the class and error context. For example, the default values for "metadata/ENODEV" are "0" rather than "-1" so that this error handler defaults to "fail immediately" behaviour. This is done because ENODEV is a fatal, unrecoverable error no matter how many times the metadata IO is retried. + +Workqueue Concurrency +===================== + +XFS uses kernel workqueues to parallelize metadata update processes. This +enables it to take advantage of storage hardware that can service many IO +operations simultaneously. This interface exposes internal implementation +details of XFS, and as such is explicitly not part of any userspace API/ABI +guarantee the kernel may give userspace. These are undocumented features of +the generic workqueue implementation XFS uses for concurrency, and they are +provided here purely for diagnostic and tuning purposes and may change at any +time in the future. + +The control knobs for a filesystem's workqueues are organized by task at hand +and the short name of the data device. They all can be found in: + + /sys/bus/workqueue/devices/${task}!${device} + +================ =========== + Task Description +================ =========== + xfs_iwalk-$pid Inode scans of the entire filesystem. Currently limited to + mount time quotacheck. +================ =========== + +For example, the knobs for the quotacheck workqueue for /dev/nvme0n1 would be +found in /sys/bus/workqueue/devices/xfs_iwalk-1111!nvme0n1/. + +The interesting knobs for XFS workqueues are as follows: + +============ =========== + Knob Description +============ =========== + max_active Maximum number of background threads that can be started to + run the work. + cpumask CPUs upon which the threads are allowed to run. + nice Relative priority of scheduling the threads. These are the + same nice levels that can be applied to userspace processes. diff --git a/fs/xfs/xfs_iwalk.c b/fs/xfs/xfs_iwalk.c index eae3aff9bc97..c4a340f1f1e1 100644 --- a/fs/xfs/xfs_iwalk.c +++ b/fs/xfs/xfs_iwalk.c @@ -618,15 +618,12 @@ xfs_iwalk_threaded( { struct xfs_pwork_ctl pctl; xfs_agnumber_t agno = XFS_INO_TO_AGNO(mp, startino); - unsigned int nr_threads; int error; ASSERT(agno < mp->m_sb.sb_agcount); ASSERT(!(flags & ~XFS_IWALK_FLAGS_ALL)); - nr_threads = xfs_pwork_guess_datadev_parallelism(mp); - error = xfs_pwork_init(mp, &pctl, xfs_iwalk_ag_work, "xfs_iwalk", - nr_threads); + error = xfs_pwork_init(mp, &pctl, xfs_iwalk_ag_work, "xfs_iwalk"); if (error) return error; diff --git a/fs/xfs/xfs_pwork.c b/fs/xfs/xfs_pwork.c index b03333f1c84a..c283b801cc5d 100644 --- a/fs/xfs/xfs_pwork.c +++ b/fs/xfs/xfs_pwork.c @@ -61,16 +61,18 @@ xfs_pwork_init( struct xfs_mount *mp, struct xfs_pwork_ctl *pctl, xfs_pwork_work_fn work_fn, - const char *tag, - unsigned int nr_threads) + const char *tag) { + unsigned int nr_threads = 0; + #ifdef DEBUG if (xfs_globals.pwork_threads >= 0) nr_threads = xfs_globals.pwork_threads; #endif trace_xfs_pwork_init(mp, nr_threads, current->pid); - pctl->wq = alloc_workqueue("%s-%d", WQ_FREEZABLE, nr_threads, tag, + pctl->wq = alloc_workqueue("%s-%d", + WQ_UNBOUND | WQ_SYSFS | WQ_FREEZABLE, nr_threads, tag, current->pid); if (!pctl->wq) return -ENOMEM; @@ -117,20 +119,3 @@ xfs_pwork_poll( atomic_read(&pctl->nr_work) == 0, HZ) == 0) touch_softlockup_watchdog(); } - -/* - * Return the amount of parallelism that the data device can handle, or 0 for - * no limit. - */ -unsigned int -xfs_pwork_guess_datadev_parallelism( - struct xfs_mount *mp) -{ - struct xfs_buftarg *btp = mp->m_ddev_targp; - - /* - * For now we'll go with the most conservative setting possible, - * which is two threads for an SSD and 1 thread everywhere else. - */ - return blk_queue_nonrot(btp->bt_bdev->bd_disk->queue) ? 2 : 1; -} diff --git a/fs/xfs/xfs_pwork.h b/fs/xfs/xfs_pwork.h index 8133124cf3bb..c0ef81fc85dd 100644 --- a/fs/xfs/xfs_pwork.h +++ b/fs/xfs/xfs_pwork.h @@ -51,11 +51,9 @@ xfs_pwork_want_abort( } int xfs_pwork_init(struct xfs_mount *mp, struct xfs_pwork_ctl *pctl, - xfs_pwork_work_fn work_fn, const char *tag, - unsigned int nr_threads); + xfs_pwork_work_fn work_fn, const char *tag); void xfs_pwork_queue(struct xfs_pwork_ctl *pctl, struct xfs_pwork *pwork); int xfs_pwork_destroy(struct xfs_pwork_ctl *pctl); void xfs_pwork_poll(struct xfs_pwork_ctl *pctl); -unsigned int xfs_pwork_guess_datadev_parallelism(struct xfs_mount *mp); #endif /* __XFS_PWORK_H__ */ -- cgit v1.2.3 From 47bd6d3457fb96d287278027aed8a78d14f1d32d Mon Sep 17 00:00:00 2001 From: "Darrick J. Wong" Date: Mon, 25 Jan 2021 16:39:01 -0800 Subject: xfs: expose the blockgc workqueue knobs publicly Expose the workqueue sysfs knobs for the speculative preallocation gc workers on all kernels, and update the sysadmin information. Signed-off-by: Darrick J. Wong Reviewed-by: Christoph Hellwig --- Documentation/admin-guide/xfs.rst | 3 +++ fs/xfs/xfs_super.c | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) (limited to 'Documentation') diff --git a/Documentation/admin-guide/xfs.rst b/Documentation/admin-guide/xfs.rst index b00b1eece9de..d2064a52811b 100644 --- a/Documentation/admin-guide/xfs.rst +++ b/Documentation/admin-guide/xfs.rst @@ -518,6 +518,9 @@ and the short name of the data device. They all can be found in: ================ =========== xfs_iwalk-$pid Inode scans of the entire filesystem. Currently limited to mount time quotacheck. + xfs-blockgc Background garbage collection of disk space that have been + speculatively allocated beyond EOF or for staging copy on + write operations. ================ =========== For example, the knobs for the quotacheck workqueue for /dev/nvme0n1 would be diff --git a/fs/xfs/xfs_super.c b/fs/xfs/xfs_super.c index 2b04818627e9..21b1d034aca3 100644 --- a/fs/xfs/xfs_super.c +++ b/fs/xfs/xfs_super.c @@ -520,7 +520,7 @@ xfs_init_mount_workqueues( goto out_destroy_cil; mp->m_blockgc_workqueue = alloc_workqueue("xfs-blockgc/%s", - XFS_WQFLAGS(WQ_UNBOUND | WQ_FREEZABLE | WQ_MEM_RECLAIM), + WQ_SYSFS | WQ_UNBOUND | WQ_FREEZABLE | WQ_MEM_RECLAIM, 0, mp->m_super->s_id); if (!mp->m_blockgc_workqueue) goto out_destroy_reclaim; -- cgit v1.2.3 From fc4aa3804ec78a726f235b7f3440ba8034e9d88e Mon Sep 17 00:00:00 2001 From: Christian Hewitt Date: Tue, 19 Jan 2021 14:57:33 +0000 Subject: dt-bindings: arm: amlogic: add support for the Beelink GS-King-X The Shenzen AZW (Beelink) GS-King-X is based on the Amlogic W400 reference board with an S922X-H chip. Signed-off-by: Christian Hewitt Acked-by: Rob Herring Reviewed-by: Martin Blumenstingl Signed-off-by: Kevin Hilman Link: https://lore.kernel.org/r/20210119145734.12675-2-christianshewitt@gmail.com --- Documentation/devicetree/bindings/arm/amlogic.yaml | 1 + 1 file changed, 1 insertion(+) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/arm/amlogic.yaml b/Documentation/devicetree/bindings/arm/amlogic.yaml index 3341788d1096..6bef60ddda64 100644 --- a/Documentation/devicetree/bindings/arm/amlogic.yaml +++ b/Documentation/devicetree/bindings/arm/amlogic.yaml @@ -151,6 +151,7 @@ properties: - description: Boards with the Amlogic Meson G12B S922X SoC items: - enum: + - azw,gsking-x - azw,gtking - azw,gtking-pro - hardkernel,odroid-n2 -- cgit v1.2.3 From 5d3f5d46de425ff0cbbc39faea0d7580c8afdb44 Mon Sep 17 00:00:00 2001 From: Martin Blumenstingl Date: Sat, 2 Jan 2021 21:59:00 +0100 Subject: dt-bindings: sram: Add compatible strings for the Meson AO ARC SRAM Amlogic Meson8, Meson8b and Meson8m2 SoCs embed an ARC EM4 core typically used for managing system suspend. A section of the SoCs SRAM is mapped as memory for this ARC core. Add new compatible strings for the SRAM section for the ARC core memory. Signed-off-by: Martin Blumenstingl Acked-by: Rob Herring Signed-off-by: Kevin Hilman Link: https://lore.kernel.org/r/20210102205904.2691120-2-martin.blumenstingl@googlemail.com --- Documentation/devicetree/bindings/sram/sram.yaml | 2 ++ 1 file changed, 2 insertions(+) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/sram/sram.yaml b/Documentation/devicetree/bindings/sram/sram.yaml index 19d116ff9ddc..6d65771e979c 100644 --- a/Documentation/devicetree/bindings/sram/sram.yaml +++ b/Documentation/devicetree/bindings/sram/sram.yaml @@ -72,6 +72,8 @@ patternProperties: - allwinner,sun4i-a10-sram-d - allwinner,sun9i-a80-smp-sram - allwinner,sun50i-a64-sram-c + - amlogic,meson8-ao-arc-sram + - amlogic,meson8b-ao-arc-sram - amlogic,meson8-smp-sram - amlogic,meson8b-smp-sram - amlogic,meson-gxbb-scp-shmem -- cgit v1.2.3 From 68f3a096d0f3552320635347de68a3bd7abd5d36 Mon Sep 17 00:00:00 2001 From: Martin Blumenstingl Date: Sat, 2 Jan 2021 21:59:01 +0100 Subject: dt-bindings: Amlogic: add the documentation for the SECBUS2 registers The Meson8/Meson8b/Meson8m2 SoCs have a register bank called SECBUS2 which contains registers for various IP blocks such as pin-controller bits for the BSD_EN and TEST_N GPIOs as well as some AO ARC core control bits. The registers can be accessed directly when not running in "secure mode". When "secure mode" is enabled then these registers have to be accessed through secure monitor calls. So far these SoCs are always known to boot in "non-secure mode". Add a binding documentation using syscon (as these registers are shared across different IPs) for the SECBUS2 registers. Signed-off-by: Martin Blumenstingl Reviewed-by: Rob Herring Signed-off-by: Kevin Hilman Link: https://lore.kernel.org/r/20210102205904.2691120-3-martin.blumenstingl@googlemail.com --- .../arm/amlogic/amlogic,meson-mx-secbus2.yaml | 42 ++++++++++++++++++++++ 1 file changed, 42 insertions(+) create mode 100644 Documentation/devicetree/bindings/arm/amlogic/amlogic,meson-mx-secbus2.yaml (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/arm/amlogic/amlogic,meson-mx-secbus2.yaml b/Documentation/devicetree/bindings/arm/amlogic/amlogic,meson-mx-secbus2.yaml new file mode 100644 index 000000000000..eee7cda9f91b --- /dev/null +++ b/Documentation/devicetree/bindings/arm/amlogic/amlogic,meson-mx-secbus2.yaml @@ -0,0 +1,42 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: "http://devicetree.org/schemas/arm/amlogic/amlogic,meson-mx-secbus2.yaml#" +$schema: "http://devicetree.org/meta-schemas/core.yaml#" + +title: Amlogic Meson8/Meson8b/Meson8m2 SECBUS2 register interface + +maintainers: + - Martin Blumenstingl + +description: | + The Meson8/Meson8b/Meson8m2 SoCs have a register bank called SECBUS2 which + contains registers for various IP blocks such as pin-controller bits for + the BSD_EN and TEST_N GPIOs as well as some AO ARC core control bits. + The registers can be accessed directly when not running in "secure mode". + When "secure mode" is enabled then these registers have to be accessed + through secure monitor calls. + +properties: + compatible: + items: + - enum: + - amlogic,meson8-secbus2 + - amlogic,meson8b-secbus2 + - const: syscon + + reg: + maxItems: 1 + +required: + - compatible + - reg + +additionalProperties: false + +examples: + - | + secbus2: system-controller@4000 { + compatible = "amlogic,meson8-secbus2", "syscon"; + reg = <0x4000 0x2000>; + }; -- cgit v1.2.3 From ad6d08d9e909be81c135355716590304e99543b7 Mon Sep 17 00:00:00 2001 From: Christian Hewitt Date: Tue, 2 Feb 2021 02:10:17 +0000 Subject: dt-bindings: arm: amlogic: sort SM1 bindings Sort the bindings before adding new SM1 devices. Signed-off-by: Christian Hewitt Acked-by: Neil Armstrong Signed-off-by: Kevin Hilman Link: https://lore.kernel.org/r/20210202021021.11068-2-christianshewitt@gmail.com --- Documentation/devicetree/bindings/arm/amlogic.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/arm/amlogic.yaml b/Documentation/devicetree/bindings/arm/amlogic.yaml index 6bef60ddda64..b21ba8ba23dd 100644 --- a/Documentation/devicetree/bindings/arm/amlogic.yaml +++ b/Documentation/devicetree/bindings/arm/amlogic.yaml @@ -164,9 +164,9 @@ properties: - description: Boards with the Amlogic Meson SM1 S905X3/D3/Y3 SoC items: - enum: - - seirobotics,sei610 - - khadas,vim3l - hardkernel,odroid-c4 + - khadas,vim3l + - seirobotics,sei610 - const: amlogic,sm1 - description: Boards with the Amlogic Meson A1 A113L SoC -- cgit v1.2.3 From 750d43b4a79e5f3767ee1db933b42abdf967ce1e Mon Sep 17 00:00:00 2001 From: Seiya Wang Date: Wed, 3 Feb 2021 13:53:48 +0800 Subject: dt-bindings: arm: add Cortex-A78 binding Add compatible for Cortex-A78 PMU Signed-off-by: Seiya Wang Acked-by: Mark Rutland Link: https://lore.kernel.org/r/20210203055348.4935-3-seiya.wang@mediatek.com Signed-off-by: Will Deacon --- Documentation/devicetree/bindings/arm/pmu.yaml | 1 + 1 file changed, 1 insertion(+) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/arm/pmu.yaml b/Documentation/devicetree/bindings/arm/pmu.yaml index 693ef3f185a8..e17ac049e890 100644 --- a/Documentation/devicetree/bindings/arm/pmu.yaml +++ b/Documentation/devicetree/bindings/arm/pmu.yaml @@ -43,6 +43,7 @@ properties: - arm,cortex-a75-pmu - arm,cortex-a76-pmu - arm,cortex-a77-pmu + - arm,cortex-a78-pmu - arm,neoverse-e1-pmu - arm,neoverse-n1-pmu - brcm,vulcan-pmu -- cgit v1.2.3 From d7839ddfefc143d4113987296ff3abf96ac08f20 Mon Sep 17 00:00:00 2001 From: Rob Herring Date: Tue, 2 Feb 2021 15:55:03 -0600 Subject: dt-bindings: iio: dac: Fix AD5686 references The example and filename use 'adi,ad5686', but the schema doesn't document it. The AD5686 is also a SPI interface variant while all the documented variants have an I2C interface. So let's update all the references to AD5686 to AD5696. Cc: Lars-Peter Clausen Cc: Michael Hennerich Cc: Jonathan Cameron Cc: Peter Meerwald-Stadler Cc: Michael Auchter Cc: linux-iio@vger.kernel.org Signed-off-by: Rob Herring Acked-by: Lars-Peter Clausen Link: https://lore.kernel.org/r/20210202215503.114113-1-robh@kernel.org --- .../devicetree/bindings/iio/dac/adi,ad5686.yaml | 57 ---------------------- .../devicetree/bindings/iio/dac/adi,ad5696.yaml | 57 ++++++++++++++++++++++ 2 files changed, 57 insertions(+), 57 deletions(-) delete mode 100644 Documentation/devicetree/bindings/iio/dac/adi,ad5686.yaml create mode 100644 Documentation/devicetree/bindings/iio/dac/adi,ad5696.yaml (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/iio/dac/adi,ad5686.yaml b/Documentation/devicetree/bindings/iio/dac/adi,ad5686.yaml deleted file mode 100644 index 8065228e5df8..000000000000 --- a/Documentation/devicetree/bindings/iio/dac/adi,ad5686.yaml +++ /dev/null @@ -1,57 +0,0 @@ -# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) -%YAML 1.2 ---- -$id: http://devicetree.org/schemas/iio/dac/adi,ad5686.yaml# -$schema: http://devicetree.org/meta-schemas/core.yaml# - -title: Analog Devices AD5686 and similar multi-channel DACs - -maintainers: - - Michael Auchter - -description: | - Binding for Analog Devices AD5686 and similar multi-channel DACs - -properties: - compatible: - enum: - - adi,ad5311r - - adi,ad5338r - - adi,ad5671r - - adi,ad5675r - - adi,ad5691r - - adi,ad5692r - - adi,ad5693 - - adi,ad5693r - - adi,ad5694 - - adi,ad5694r - - adi,ad5695r - - adi,ad5696 - - adi,ad5696r - - reg: - maxItems: 1 - - vcc-supply: - description: | - The regulator supply for DAC reference voltage. - -required: - - compatible - - reg - -additionalProperties: false - -examples: - - | - i2c { - #address-cells = <1>; - #size-cells = <0>; - - ad5686: dac@0 { - compatible = "adi,ad5686"; - reg = <0>; - vcc-supply = <&dac_vref>; - }; - }; -... diff --git a/Documentation/devicetree/bindings/iio/dac/adi,ad5696.yaml b/Documentation/devicetree/bindings/iio/dac/adi,ad5696.yaml new file mode 100644 index 000000000000..56b0cda0f30a --- /dev/null +++ b/Documentation/devicetree/bindings/iio/dac/adi,ad5696.yaml @@ -0,0 +1,57 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/iio/dac/adi,ad5696.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Analog Devices AD5696 and similar multi-channel DACs + +maintainers: + - Michael Auchter + +description: | + Binding for Analog Devices AD5696 and similar multi-channel DACs + +properties: + compatible: + enum: + - adi,ad5311r + - adi,ad5338r + - adi,ad5671r + - adi,ad5675r + - adi,ad5691r + - adi,ad5692r + - adi,ad5693 + - adi,ad5693r + - adi,ad5694 + - adi,ad5694r + - adi,ad5695r + - adi,ad5696 + - adi,ad5696r + + reg: + maxItems: 1 + + vcc-supply: + description: | + The regulator supply for DAC reference voltage. + +required: + - compatible + - reg + +additionalProperties: false + +examples: + - | + i2c { + #address-cells = <1>; + #size-cells = <0>; + + ad5696: dac@0 { + compatible = "adi,ad5696"; + reg = <0>; + vcc-supply = <&dac_vref>; + }; + }; +... -- cgit v1.2.3 From 261eeb9c1585de4515a770b48a3c89672c08ae7f Mon Sep 17 00:00:00 2001 From: Daeho Jeong Date: Tue, 19 Jan 2021 09:00:42 +0900 Subject: f2fs: introduce checkpoint_merge mount option We've added a new mount options, "checkpoint_merge" and "nocheckpoint_merge", which creates a kernel daemon and makes it to merge concurrent checkpoint requests as much as possible to eliminate redundant checkpoint issues. Plus, we can eliminate the sluggish issue caused by slow checkpoint operation when the checkpoint is done in a process context in a cgroup having low i/o budget and cpu shares. To make this do better, we set the default i/o priority of the kernel daemon to "3", to give one higher priority than other kernel threads. The below verification result explains this. The basic idea has come from https://opensource.samsung.com. [Verification] Android Pixel Device(ARM64, 7GB RAM, 256GB UFS) Create two I/O cgroups (fg w/ weight 100, bg w/ wight 20) Set "strict_guarantees" to "1" in BFQ tunables In "fg" cgroup, - thread A => trigger 1000 checkpoint operations "for i in `seq 1 1000`; do touch test_dir1/file; fsync test_dir1; done" - thread B => gererating async. I/O "fio --rw=write --numjobs=1 --bs=128k --runtime=3600 --time_based=1 --filename=test_img --name=test" In "bg" cgroup, - thread C => trigger repeated checkpoint operations "echo $$ > /dev/blkio/bg/tasks; while true; do touch test_dir2/file; fsync test_dir2; done" We've measured thread A's execution time. [ w/o patch ] Elapsed Time: Avg. 68 seconds [ w/ patch ] Elapsed Time: Avg. 48 seconds Reported-by: kernel test robot Reported-by: Dan Carpenter [Jaegeuk Kim: fix the return value in f2fs_start_ckpt_thread, reported by Dan] Signed-off-by: Daeho Jeong Signed-off-by: Sungjong Seo Reviewed-by: Chao Yu Signed-off-by: Jaegeuk Kim --- Documentation/filesystems/f2fs.rst | 11 +++ fs/f2fs/checkpoint.c | 177 +++++++++++++++++++++++++++++++++++++ fs/f2fs/debug.c | 12 +++ fs/f2fs/f2fs.h | 27 ++++++ fs/f2fs/super.c | 58 ++++++++++-- 5 files changed, 277 insertions(+), 8 deletions(-) (limited to 'Documentation') diff --git a/Documentation/filesystems/f2fs.rst b/Documentation/filesystems/f2fs.rst index 5eff4009e77e..f75ec244762f 100644 --- a/Documentation/filesystems/f2fs.rst +++ b/Documentation/filesystems/f2fs.rst @@ -247,6 +247,17 @@ checkpoint=%s[:%u[%]] Set to "disable" to turn off checkpointing. Set to "enabl hide up to all remaining free space. The actual space that would be unusable can be viewed at /sys/fs/f2fs//unusable This space is reclaimed once checkpoint=enable. +checkpoint_merge When checkpoint is enabled, this can be used to create a kernel + daemon and make it to merge concurrent checkpoint requests as + much as possible to eliminate redundant checkpoint issues. Plus, + we can eliminate the sluggish issue caused by slow checkpoint + operation when the checkpoint is done in a process context in + a cgroup having low i/o budget and cpu shares. To make this + do better, we set the default i/o priority of the kernel daemon + to "3", to give one higher priority than other kernel threads. + This is the same way to give a I/O priority to the jbd2 + journaling thread of ext4 filesystem. +nocheckpoint_merge Disable checkpoint merge feature. compress_algorithm=%s Control compress algorithm, currently f2fs supports "lzo", "lz4", "zstd" and "lzo-rle" algorithm. compress_algorithm=%s:%d Control compress algorithm and its compress level, now, only diff --git a/fs/f2fs/checkpoint.c b/fs/f2fs/checkpoint.c index 8c79ba0566b1..6f6ecba8f920 100644 --- a/fs/f2fs/checkpoint.c +++ b/fs/f2fs/checkpoint.c @@ -13,12 +13,15 @@ #include #include #include +#include #include "f2fs.h" #include "node.h" #include "segment.h" #include +#define DEFAULT_CHECKPOINT_IOPRIO (IOPRIO_PRIO_VALUE(IOPRIO_CLASS_BE, 3)) + static struct kmem_cache *ino_entry_slab; struct kmem_cache *f2fs_inode_entry_slab; @@ -1704,3 +1707,177 @@ void f2fs_destroy_checkpoint_caches(void) kmem_cache_destroy(ino_entry_slab); kmem_cache_destroy(f2fs_inode_entry_slab); } + +static int __write_checkpoint_sync(struct f2fs_sb_info *sbi) +{ + struct cp_control cpc = { .reason = CP_SYNC, }; + int err; + + down_write(&sbi->gc_lock); + err = f2fs_write_checkpoint(sbi, &cpc); + up_write(&sbi->gc_lock); + + return err; +} + +static void __checkpoint_and_complete_reqs(struct f2fs_sb_info *sbi) +{ + struct ckpt_req_control *cprc = &sbi->cprc_info; + struct ckpt_req *req, *next; + struct llist_node *dispatch_list; + u64 sum_diff = 0, diff, count = 0; + int ret; + + dispatch_list = llist_del_all(&cprc->issue_list); + if (!dispatch_list) + return; + dispatch_list = llist_reverse_order(dispatch_list); + + ret = __write_checkpoint_sync(sbi); + atomic_inc(&cprc->issued_ckpt); + + llist_for_each_entry_safe(req, next, dispatch_list, llnode) { + diff = (u64)ktime_ms_delta(ktime_get(), req->queue_time); + req->ret = ret; + complete(&req->wait); + + sum_diff += diff; + count++; + } + atomic_sub(count, &cprc->queued_ckpt); + atomic_add(count, &cprc->total_ckpt); + + spin_lock(&cprc->stat_lock); + cprc->cur_time = (unsigned int)div64_u64(sum_diff, count); + if (cprc->peak_time < cprc->cur_time) + cprc->peak_time = cprc->cur_time; + spin_unlock(&cprc->stat_lock); +} + +static int issue_checkpoint_thread(void *data) +{ + struct f2fs_sb_info *sbi = data; + struct ckpt_req_control *cprc = &sbi->cprc_info; + wait_queue_head_t *q = &cprc->ckpt_wait_queue; +repeat: + if (kthread_should_stop()) + return 0; + + sb_start_intwrite(sbi->sb); + + if (!llist_empty(&cprc->issue_list)) + __checkpoint_and_complete_reqs(sbi); + + sb_end_intwrite(sbi->sb); + + wait_event_interruptible(*q, + kthread_should_stop() || !llist_empty(&cprc->issue_list)); + goto repeat; +} + +static void flush_remained_ckpt_reqs(struct f2fs_sb_info *sbi, + struct ckpt_req *wait_req) +{ + struct ckpt_req_control *cprc = &sbi->cprc_info; + + if (!llist_empty(&cprc->issue_list)) { + __checkpoint_and_complete_reqs(sbi); + } else { + /* already dispatched by issue_checkpoint_thread */ + if (wait_req) + wait_for_completion(&wait_req->wait); + } +} + +static void init_ckpt_req(struct ckpt_req *req) +{ + memset(req, 0, sizeof(struct ckpt_req)); + + init_completion(&req->wait); + req->queue_time = ktime_get(); +} + +int f2fs_issue_checkpoint(struct f2fs_sb_info *sbi) +{ + struct ckpt_req_control *cprc = &sbi->cprc_info; + struct ckpt_req req; + struct cp_control cpc; + + cpc.reason = __get_cp_reason(sbi); + if (!test_opt(sbi, MERGE_CHECKPOINT) || cpc.reason != CP_SYNC) { + int ret; + + down_write(&sbi->gc_lock); + ret = f2fs_write_checkpoint(sbi, &cpc); + up_write(&sbi->gc_lock); + + return ret; + } + + if (!cprc->f2fs_issue_ckpt) + return __write_checkpoint_sync(sbi); + + init_ckpt_req(&req); + + llist_add(&req.llnode, &cprc->issue_list); + atomic_inc(&cprc->queued_ckpt); + + /* update issue_list before we wake up issue_checkpoint thread */ + smp_mb(); + + if (waitqueue_active(&cprc->ckpt_wait_queue)) + wake_up(&cprc->ckpt_wait_queue); + + if (cprc->f2fs_issue_ckpt) + wait_for_completion(&req.wait); + else + flush_remained_ckpt_reqs(sbi, &req); + + return req.ret; +} + +int f2fs_start_ckpt_thread(struct f2fs_sb_info *sbi) +{ + dev_t dev = sbi->sb->s_bdev->bd_dev; + struct ckpt_req_control *cprc = &sbi->cprc_info; + + if (cprc->f2fs_issue_ckpt) + return 0; + + cprc->f2fs_issue_ckpt = kthread_run(issue_checkpoint_thread, sbi, + "f2fs_ckpt-%u:%u", MAJOR(dev), MINOR(dev)); + if (IS_ERR(cprc->f2fs_issue_ckpt)) { + cprc->f2fs_issue_ckpt = NULL; + return -ENOMEM; + } + + set_task_ioprio(cprc->f2fs_issue_ckpt, DEFAULT_CHECKPOINT_IOPRIO); + + return 0; +} + +void f2fs_stop_ckpt_thread(struct f2fs_sb_info *sbi) +{ + struct ckpt_req_control *cprc = &sbi->cprc_info; + + if (cprc->f2fs_issue_ckpt) { + struct task_struct *ckpt_task = cprc->f2fs_issue_ckpt; + + cprc->f2fs_issue_ckpt = NULL; + kthread_stop(ckpt_task); + + flush_remained_ckpt_reqs(sbi, NULL); + } +} + +void f2fs_init_ckpt_req_control(struct f2fs_sb_info *sbi) +{ + struct ckpt_req_control *cprc = &sbi->cprc_info; + + atomic_set(&cprc->issued_ckpt, 0); + atomic_set(&cprc->total_ckpt, 0); + atomic_set(&cprc->queued_ckpt, 0); + init_waitqueue_head(&cprc->ckpt_wait_queue); + init_llist_head(&cprc->issue_list); + spin_lock_init(&cprc->stat_lock); +} diff --git a/fs/f2fs/debug.c b/fs/f2fs/debug.c index 197c914119da..91855d5721cd 100644 --- a/fs/f2fs/debug.c +++ b/fs/f2fs/debug.c @@ -120,6 +120,13 @@ static void update_general_status(struct f2fs_sb_info *sbi) atomic_read(&SM_I(sbi)->dcc_info->discard_cmd_cnt); si->undiscard_blks = SM_I(sbi)->dcc_info->undiscard_blks; } + si->nr_issued_ckpt = atomic_read(&sbi->cprc_info.issued_ckpt); + si->nr_total_ckpt = atomic_read(&sbi->cprc_info.total_ckpt); + si->nr_queued_ckpt = atomic_read(&sbi->cprc_info.queued_ckpt); + spin_lock(&sbi->cprc_info.stat_lock); + si->cur_ckpt_time = sbi->cprc_info.cur_time; + si->peak_ckpt_time = sbi->cprc_info.peak_time; + spin_unlock(&sbi->cprc_info.stat_lock); si->total_count = (int)sbi->user_block_count / sbi->blocks_per_seg; si->rsvd_segs = reserved_segments(sbi); si->overp_segs = overprovision_segments(sbi); @@ -417,6 +424,11 @@ static int stat_show(struct seq_file *s, void *v) si->meta_count[META_NAT]); seq_printf(s, " - ssa blocks : %u\n", si->meta_count[META_SSA]); + seq_printf(s, "CP merge (Queued: %4d, Issued: %4d, Total: %4d, " + "Cur time: %4d(ms), Peak time: %4d(ms))\n", + si->nr_queued_ckpt, si->nr_issued_ckpt, + si->nr_total_ckpt, si->cur_ckpt_time, + si->peak_ckpt_time); seq_printf(s, "GC calls: %d (BG: %d)\n", si->call_count, si->bg_gc); seq_printf(s, " - data segments : %d (%d)\n", diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h index a2e520a13630..f7536aca8a31 100644 --- a/fs/f2fs/f2fs.h +++ b/fs/f2fs/f2fs.h @@ -97,6 +97,7 @@ extern const char *f2fs_fault_name[FAULT_MAX]; #define F2FS_MOUNT_DISABLE_CHECKPOINT 0x02000000 #define F2FS_MOUNT_NORECOVERY 0x04000000 #define F2FS_MOUNT_ATGC 0x08000000 +#define F2FS_MOUNT_MERGE_CHECKPOINT 0x10000000 #define F2FS_OPTION(sbi) ((sbi)->mount_opt) #define clear_opt(sbi, option) (F2FS_OPTION(sbi).opt &= ~F2FS_MOUNT_##option) @@ -267,6 +268,25 @@ struct fsync_node_entry { unsigned int seq_id; /* sequence id */ }; +struct ckpt_req { + struct completion wait; /* completion for checkpoint done */ + struct llist_node llnode; /* llist_node to be linked in wait queue */ + int ret; /* return code of checkpoint */ + ktime_t queue_time; /* request queued time */ +}; + +struct ckpt_req_control { + struct task_struct *f2fs_issue_ckpt; /* checkpoint task */ + wait_queue_head_t ckpt_wait_queue; /* waiting queue for wake-up */ + atomic_t issued_ckpt; /* # of actually issued ckpts */ + atomic_t total_ckpt; /* # of total ckpts */ + atomic_t queued_ckpt; /* # of queued ckpts */ + struct llist_head issue_list; /* list for command issue */ + spinlock_t stat_lock; /* lock for below checkpoint time stats */ + unsigned int cur_time; /* cur wait time in msec for currently issued checkpoint */ + unsigned int peak_time; /* peak wait time in msec until now */ +}; + /* for the bitmap indicate blocks to be discarded */ struct discard_entry { struct list_head list; /* list head */ @@ -1433,6 +1453,7 @@ struct f2fs_sb_info { wait_queue_head_t cp_wait; unsigned long last_time[MAX_TIME]; /* to store time in jiffies */ long interval_time[MAX_TIME]; /* to store thresholds */ + struct ckpt_req_control cprc_info; /* for checkpoint request control */ struct inode_management im[MAX_INO_ENTRY]; /* manage inode cache */ @@ -3450,6 +3471,10 @@ int f2fs_write_checkpoint(struct f2fs_sb_info *sbi, struct cp_control *cpc); void f2fs_init_ino_entry_info(struct f2fs_sb_info *sbi); int __init f2fs_create_checkpoint_caches(void); void f2fs_destroy_checkpoint_caches(void); +int f2fs_issue_checkpoint(struct f2fs_sb_info *sbi); +int f2fs_start_ckpt_thread(struct f2fs_sb_info *sbi); +void f2fs_stop_ckpt_thread(struct f2fs_sb_info *sbi); +void f2fs_init_ckpt_req_control(struct f2fs_sb_info *sbi); /* * data.c @@ -3562,6 +3587,8 @@ struct f2fs_stat_info { int nr_discarding, nr_discarded; int nr_discard_cmd; unsigned int undiscard_blks; + int nr_issued_ckpt, nr_total_ckpt, nr_queued_ckpt; + unsigned int cur_ckpt_time, peak_ckpt_time; int inline_xattr, inline_inode, inline_dir, append, update, orphans; int compr_inode; unsigned long long compr_blocks; diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c index 429bc00af440..1000d21120ca 100644 --- a/fs/f2fs/super.c +++ b/fs/f2fs/super.c @@ -144,6 +144,8 @@ enum { Opt_checkpoint_disable_cap, Opt_checkpoint_disable_cap_perc, Opt_checkpoint_enable, + Opt_checkpoint_merge, + Opt_nocheckpoint_merge, Opt_compress_algorithm, Opt_compress_log_size, Opt_compress_extension, @@ -214,6 +216,8 @@ static match_table_t f2fs_tokens = { {Opt_checkpoint_disable_cap, "checkpoint=disable:%u"}, {Opt_checkpoint_disable_cap_perc, "checkpoint=disable:%u%%"}, {Opt_checkpoint_enable, "checkpoint=enable"}, + {Opt_checkpoint_merge, "checkpoint_merge"}, + {Opt_nocheckpoint_merge, "nocheckpoint_merge"}, {Opt_compress_algorithm, "compress_algorithm=%s"}, {Opt_compress_log_size, "compress_log_size=%u"}, {Opt_compress_extension, "compress_extension=%s"}, @@ -941,6 +945,12 @@ static int parse_options(struct super_block *sb, char *options, bool is_remount) case Opt_checkpoint_enable: clear_opt(sbi, DISABLE_CHECKPOINT); break; + case Opt_checkpoint_merge: + set_opt(sbi, MERGE_CHECKPOINT); + break; + case Opt_nocheckpoint_merge: + clear_opt(sbi, MERGE_CHECKPOINT); + break; #ifdef CONFIG_F2FS_FS_COMPRESSION case Opt_compress_algorithm: if (!f2fs_sb_has_compression(sbi)) { @@ -1340,6 +1350,12 @@ static void f2fs_put_super(struct super_block *sb) /* prevent remaining shrinker jobs */ mutex_lock(&sbi->umount_mutex); + /* + * flush all issued checkpoints and stop checkpoint issue thread. + * after then, all checkpoints should be done by each process context. + */ + f2fs_stop_ckpt_thread(sbi); + /* * We don't need to do checkpoint when superblock is clean. * But, the previous checkpoint was not done by umount, it needs to do @@ -1438,15 +1454,9 @@ int f2fs_sync_fs(struct super_block *sb, int sync) if (unlikely(is_sbi_flag_set(sbi, SBI_POR_DOING))) return -EAGAIN; - if (sync) { - struct cp_control cpc; - - cpc.reason = __get_cp_reason(sbi); + if (sync) + err = f2fs_issue_checkpoint(sbi); - down_write(&sbi->gc_lock); - err = f2fs_write_checkpoint(sbi, &cpc); - up_write(&sbi->gc_lock); - } return err; } @@ -1770,6 +1780,10 @@ static int f2fs_show_options(struct seq_file *seq, struct dentry *root) if (test_opt(sbi, DISABLE_CHECKPOINT)) seq_printf(seq, ",checkpoint=disable:%u", F2FS_OPTION(sbi).unusable_cap); + if (test_opt(sbi, MERGE_CHECKPOINT)) + seq_puts(seq, ",checkpoint_merge"); + else + seq_puts(seq, ",nocheckpoint_merge"); if (F2FS_OPTION(sbi).fsync_mode == FSYNC_MODE_POSIX) seq_printf(seq, ",fsync_mode=%s", "posix"); else if (F2FS_OPTION(sbi).fsync_mode == FSYNC_MODE_STRICT) @@ -2053,6 +2067,19 @@ static int f2fs_remount(struct super_block *sb, int *flags, char *data) } } + if (!test_opt(sbi, DISABLE_CHECKPOINT) && + test_opt(sbi, MERGE_CHECKPOINT)) { + err = f2fs_start_ckpt_thread(sbi); + if (err) { + f2fs_err(sbi, + "Failed to start F2FS issue_checkpoint_thread (%d)", + err); + goto restore_gc; + } + } else { + f2fs_stop_ckpt_thread(sbi); + } + /* * We stop issue flush thread if FS is mounted as RO * or if flush_merge is not passed in mount option. @@ -3804,6 +3831,19 @@ try_onemore: f2fs_init_fsync_node_info(sbi); + /* setup checkpoint request control and start checkpoint issue thread */ + f2fs_init_ckpt_req_control(sbi); + if (!test_opt(sbi, DISABLE_CHECKPOINT) && + test_opt(sbi, MERGE_CHECKPOINT)) { + err = f2fs_start_ckpt_thread(sbi); + if (err) { + f2fs_err(sbi, + "Failed to start F2FS issue_checkpoint_thread (%d)", + err); + goto stop_ckpt_thread; + } + } + /* setup f2fs internal modules */ err = f2fs_build_segment_manager(sbi); if (err) { @@ -4013,6 +4053,8 @@ free_nm: free_sm: f2fs_destroy_segment_manager(sbi); f2fs_destroy_post_read_wq(sbi); +stop_ckpt_thread: + f2fs_stop_ckpt_thread(sbi); free_devices: destroy_device_list(sbi); kvfree(sbi->ckpt); -- cgit v1.2.3 From e65920661708b7c0f3db45c9cd5d0095034ee37f Mon Sep 17 00:00:00 2001 From: Daeho Jeong Date: Thu, 21 Jan 2021 22:45:29 +0900 Subject: f2fs: add ckpt_thread_ioprio sysfs node Added "ckpt_thread_ioprio" sysfs node to give a way to change checkpoint merge daemon's io priority. Its default value is "be,3", which means "BE" I/O class and I/O priority "3". We can select the class between "rt" and "be", and set the I/O priority within valid range of it. "," delimiter is necessary in between I/O class and priority number. Signed-off-by: Daeho Jeong Reviewed-by: Chao Yu Signed-off-by: Jaegeuk Kim --- Documentation/ABI/testing/sysfs-fs-f2fs | 9 ++++++ fs/f2fs/checkpoint.c | 3 +- fs/f2fs/f2fs.h | 1 + fs/f2fs/sysfs.c | 55 +++++++++++++++++++++++++++++++++ 4 files changed, 67 insertions(+), 1 deletion(-) (limited to 'Documentation') diff --git a/Documentation/ABI/testing/sysfs-fs-f2fs b/Documentation/ABI/testing/sysfs-fs-f2fs index 362803901614..cbeac1bebe2f 100644 --- a/Documentation/ABI/testing/sysfs-fs-f2fs +++ b/Documentation/ABI/testing/sysfs-fs-f2fs @@ -400,3 +400,12 @@ Description: Show status of f2fs superblock in real time. 0x1000 SBI_QUOTA_NEED_REPAIR quota file may be corrupted 0x2000 SBI_IS_RESIZEFS resizefs is in process ====== ===================== ================================= + +What: /sys/fs/f2fs//ckpt_thread_ioprio +Date: January 2021 +Contact: "Daeho Jeong" +Description: Give a way to change checkpoint merge daemon's io priority. + Its default value is "be,3", which means "BE" I/O class and + I/O priority "3". We can select the class between "rt" and "be", + and set the I/O priority within valid range of it. "," delimiter + is necessary in between I/O class and priority number. diff --git a/fs/f2fs/checkpoint.c b/fs/f2fs/checkpoint.c index 6f6ecba8f920..579b9c3603cc 100644 --- a/fs/f2fs/checkpoint.c +++ b/fs/f2fs/checkpoint.c @@ -1851,7 +1851,7 @@ int f2fs_start_ckpt_thread(struct f2fs_sb_info *sbi) return -ENOMEM; } - set_task_ioprio(cprc->f2fs_issue_ckpt, DEFAULT_CHECKPOINT_IOPRIO); + set_task_ioprio(cprc->f2fs_issue_ckpt, cprc->ckpt_thread_ioprio); return 0; } @@ -1877,6 +1877,7 @@ void f2fs_init_ckpt_req_control(struct f2fs_sb_info *sbi) atomic_set(&cprc->issued_ckpt, 0); atomic_set(&cprc->total_ckpt, 0); atomic_set(&cprc->queued_ckpt, 0); + cprc->ckpt_thread_ioprio = DEFAULT_CHECKPOINT_IOPRIO; init_waitqueue_head(&cprc->ckpt_wait_queue); init_llist_head(&cprc->issue_list); spin_lock_init(&cprc->stat_lock); diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h index f7536aca8a31..2860003a09ed 100644 --- a/fs/f2fs/f2fs.h +++ b/fs/f2fs/f2fs.h @@ -277,6 +277,7 @@ struct ckpt_req { struct ckpt_req_control { struct task_struct *f2fs_issue_ckpt; /* checkpoint task */ + int ckpt_thread_ioprio; /* checkpoint merge thread ioprio */ wait_queue_head_t ckpt_wait_queue; /* waiting queue for wake-up */ atomic_t issued_ckpt; /* # of actually issued ckpts */ atomic_t total_ckpt; /* # of total ckpts */ diff --git a/fs/f2fs/sysfs.c b/fs/f2fs/sysfs.c index f39874d512ea..e38a7f6921dd 100644 --- a/fs/f2fs/sysfs.c +++ b/fs/f2fs/sysfs.c @@ -11,6 +11,7 @@ #include #include #include +#include #include "f2fs.h" #include "segment.h" @@ -34,6 +35,7 @@ enum { FAULT_INFO_TYPE, /* struct f2fs_fault_info */ #endif RESERVED_BLOCKS, /* struct f2fs_sb_info */ + CPRC_INFO, /* struct ckpt_req_control */ }; struct f2fs_attr { @@ -70,6 +72,8 @@ static unsigned char *__struct_ptr(struct f2fs_sb_info *sbi, int struct_type) else if (struct_type == STAT_INFO) return (unsigned char *)F2FS_STAT(sbi); #endif + else if (struct_type == CPRC_INFO) + return (unsigned char *)&sbi->cprc_info; return NULL; } @@ -261,6 +265,23 @@ static ssize_t f2fs_sbi_show(struct f2fs_attr *a, return len; } + if (!strcmp(a->attr.name, "ckpt_thread_ioprio")) { + struct ckpt_req_control *cprc = &sbi->cprc_info; + int len = 0; + int class = IOPRIO_PRIO_CLASS(cprc->ckpt_thread_ioprio); + int data = IOPRIO_PRIO_DATA(cprc->ckpt_thread_ioprio); + + if (class == IOPRIO_CLASS_RT) + len += scnprintf(buf + len, PAGE_SIZE - len, "rt,"); + else if (class == IOPRIO_CLASS_BE) + len += scnprintf(buf + len, PAGE_SIZE - len, "be,"); + else + return -EINVAL; + + len += scnprintf(buf + len, PAGE_SIZE - len, "%d\n", data); + return len; + } + ui = (unsigned int *)(ptr + a->offset); return sprintf(buf, "%u\n", *ui); @@ -314,6 +335,38 @@ out: return ret ? ret : count; } + if (!strcmp(a->attr.name, "ckpt_thread_ioprio")) { + const char *name = strim((char *)buf); + struct ckpt_req_control *cprc = &sbi->cprc_info; + int class; + long data; + int ret; + + if (!strncmp(name, "rt,", 3)) + class = IOPRIO_CLASS_RT; + else if (!strncmp(name, "be,", 3)) + class = IOPRIO_CLASS_BE; + else + return -EINVAL; + + name += 3; + ret = kstrtol(name, 10, &data); + if (ret) + return ret; + if (data >= IOPRIO_BE_NR || data < 0) + return -EINVAL; + + cprc->ckpt_thread_ioprio = IOPRIO_PRIO_VALUE(class, data); + if (test_opt(sbi, MERGE_CHECKPOINT)) { + ret = set_task_ioprio(cprc->f2fs_issue_ckpt, + cprc->ckpt_thread_ioprio); + if (ret) + return ret; + } + + return count; + } + ui = (unsigned int *)(ptr + a->offset); ret = kstrtoul(skip_spaces(buf), 0, &t); @@ -573,6 +626,7 @@ F2FS_RW_ATTR(FAULT_INFO_TYPE, f2fs_fault_info, inject_type, inject_type); #endif F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, data_io_flag, data_io_flag); F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, node_io_flag, node_io_flag); +F2FS_RW_ATTR(CPRC_INFO, ckpt_req_control, ckpt_thread_ioprio, ckpt_thread_ioprio); F2FS_GENERAL_RO_ATTR(dirty_segments); F2FS_GENERAL_RO_ATTR(free_segments); F2FS_GENERAL_RO_ATTR(lifetime_write_kbytes); @@ -658,6 +712,7 @@ static struct attribute *f2fs_attrs[] = { #endif ATTR_LIST(data_io_flag), ATTR_LIST(node_io_flag), + ATTR_LIST(ckpt_thread_ioprio), ATTR_LIST(dirty_segments), ATTR_LIST(free_segments), ATTR_LIST(unusable), -- cgit v1.2.3 From ce598680a22de43ebe0b0e86f6b45bf3a4f9cc4f Mon Sep 17 00:00:00 2001 From: Rob Herring Date: Tue, 2 Feb 2021 12:15:38 -0600 Subject: dt-bindings: thermal: sun8i: Fix misplaced schema keyword in compatible strings A compatible string 'enum' mistakenly has 'const: ' in the compatible strings. Remove these. Fixes: 0b28594d67a8 ("dt-bindings: thermal: Add YAML schema for sun8i-thermal driver bindings") Cc: Vasily Khoruzhick Cc: Yangtao Li Cc: Zhang Rui Cc: Daniel Lezcano Cc: Amit Kucheria Cc: Maxime Ripard Cc: Chen-Yu Tsai Cc: Jernej Skrabec Cc: linux-pm@vger.kernel.org Signed-off-by: Rob Herring Acked-by: Maxime Ripard Link: https://lore.kernel.org/r/20210202181538.3936235-1-robh@kernel.org --- .../bindings/thermal/allwinner,sun8i-a83t-ths.yaml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/thermal/allwinner,sun8i-a83t-ths.yaml b/Documentation/devicetree/bindings/thermal/allwinner,sun8i-a83t-ths.yaml index 31edd051295a..bf97d1fb33e7 100644 --- a/Documentation/devicetree/bindings/thermal/allwinner,sun8i-a83t-ths.yaml +++ b/Documentation/devicetree/bindings/thermal/allwinner,sun8i-a83t-ths.yaml @@ -103,12 +103,12 @@ allOf: compatible: contains: enum: - - const: allwinner,sun8i-h3-ths - - const: allwinner,sun8i-r40-ths - - const: allwinner,sun50i-a64-ths - - const: allwinner,sun50i-a100-ths - - const: allwinner,sun50i-h5-ths - - const: allwinner,sun50i-h6-ths + - allwinner,sun8i-h3-ths + - allwinner,sun8i-r40-ths + - allwinner,sun50i-a64-ths + - allwinner,sun50i-a100-ths + - allwinner,sun50i-h5-ths + - allwinner,sun50i-h6-ths then: required: -- cgit v1.2.3 From 5ae01e760d7128682f4e1b7fa2c7fc7acc254db7 Mon Sep 17 00:00:00 2001 From: Rob Herring Date: Tue, 2 Feb 2021 11:54:38 -0600 Subject: dt-bindings: usb: generic-ehci: Add missing compatible strings The generic EHCI binding needs to document all the specific compatible strings so we can track undocumented compatible strings. Add all the compatible strings from in tree users. Turns out we also have the generic 'usb-ehci' compatible which is pretty much the same binding and the correct one for the example, so let's add it. Cc: Greg Kroah-Hartman Cc: linux-usb@vger.kernel.org Signed-off-by: Rob Herring Link: https://lore.kernel.org/r/20210202175439.3904060-1-robh@kernel.org Signed-off-by: Greg Kroah-Hartman --- .../devicetree/bindings/usb/generic-ehci.yaml | 51 ++++++++++++++++++++-- 1 file changed, 48 insertions(+), 3 deletions(-) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/usb/generic-ehci.yaml b/Documentation/devicetree/bindings/usb/generic-ehci.yaml index 247ef00381ea..6816de7dfc00 100644 --- a/Documentation/devicetree/bindings/usb/generic-ehci.yaml +++ b/Documentation/devicetree/bindings/usb/generic-ehci.yaml @@ -24,8 +24,53 @@ allOf: properties: compatible: - contains: - const: generic-ehci + oneOf: + - items: + - enum: + - allwinner,sun4i-a10-ehci + - allwinner,sun50i-a64-ehci + - allwinner,sun50i-h6-ehci + - allwinner,sun5i-a13-ehci + - allwinner,sun6i-a31-ehci + - allwinner,sun7i-a20-ehci + - allwinner,sun8i-a23-ehci + - allwinner,sun8i-h3-ehci + - allwinner,sun8i-r40-ehci + - allwinner,sun9i-a80-ehci + - aspeed,ast2400-ehci + - aspeed,ast2500-ehci + - aspeed,ast2600-ehci + - brcm,bcm3384-ehci + - brcm,bcm63268-ehci + - brcm,bcm6328-ehci + - brcm,bcm6358-ehci + - brcm,bcm6362-ehci + - brcm,bcm6368-ehci + - brcm,bcm7125-ehci + - brcm,bcm7346-ehci + - brcm,bcm7358-ehci + - brcm,bcm7360-ehci + - brcm,bcm7362-ehci + - brcm,bcm7420-ehci + - brcm,bcm7425-ehci + - brcm,bcm7435-ehci + - ibm,476gtr-ehci + - nxp,lpc1850-ehci + - qca,ar7100-ehci + - snps,hsdk-v1.0-ehci + - socionext,uniphier-ehci + - const: generic-ehci + - items: + - enum: + - cavium,octeon-6335-ehci + - ibm,usb-ehci-440epx + - ibm,usb-ehci-460ex + - nintendo,hollywood-usb-ehci + - st,spear600-ehci + - const: usb-ehci + - enum: + - generic-ehci + - usb-ehci reg: minItems: 1 @@ -101,7 +146,7 @@ additionalProperties: false examples: - | usb@e0000300 { - compatible = "ibm,usb-ehci-440epx", "generic-ehci"; + compatible = "ibm,usb-ehci-440epx", "usb-ehci"; interrupt-parent = <&UIC0>; interrupts = <0x1a 4>; reg = <0xe0000300 90>, <0xe0000390 70>; -- cgit v1.2.3 From 8a61bbfe88812d1b539480fa73c0d579d70c2bb7 Mon Sep 17 00:00:00 2001 From: Rob Herring Date: Tue, 2 Feb 2021 11:54:39 -0600 Subject: dt-bindings: usb: generic-ohci: Add missing compatible strings The generic OHCI binding needs to document all the specific compatible strings so we can track undocumented compatible strings. Add all the compatible strings from in tree users. Cc: Greg Kroah-Hartman Cc: linux-usb@vger.kernel.org Acked-by: Greg Kroah-Hartman Signed-off-by: Rob Herring Link: https://lore.kernel.org/r/20210202175439.3904060-2-robh@kernel.org Signed-off-by: Greg Kroah-Hartman --- .../devicetree/bindings/usb/generic-ohci.yaml | 34 ++++++++++++++++++++-- 1 file changed, 32 insertions(+), 2 deletions(-) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/usb/generic-ohci.yaml b/Documentation/devicetree/bindings/usb/generic-ohci.yaml index 2178bcc401bc..53df281f618c 100644 --- a/Documentation/devicetree/bindings/usb/generic-ohci.yaml +++ b/Documentation/devicetree/bindings/usb/generic-ohci.yaml @@ -14,8 +14,38 @@ maintainers: properties: compatible: - contains: - const: generic-ohci + oneOf: + - items: + - enum: + - allwinner,sun4i-a10-ohci + - allwinner,sun50i-a64-ohci + - allwinner,sun50i-h6-ohci + - allwinner,sun5i-a13-ohci + - allwinner,sun6i-a31-ohci + - allwinner,sun7i-a20-ohci + - allwinner,sun8i-a23-ohci + - allwinner,sun8i-h3-ohci + - allwinner,sun8i-r40-ohci + - allwinner,sun9i-a80-ohci + - brcm,bcm3384-ohci + - brcm,bcm63268-ohci + - brcm,bcm6328-ohci + - brcm,bcm6358-ohci + - brcm,bcm6362-ohci + - brcm,bcm6368-ohci + - brcm,bcm7125-ohci + - brcm,bcm7346-ohci + - brcm,bcm7358-ohci + - brcm,bcm7360-ohci + - brcm,bcm7362-ohci + - brcm,bcm7420-ohci + - brcm,bcm7425-ohci + - brcm,bcm7435-ohci + - ibm,476gtr-ohci + - ingenic,jz4740-ohci + - snps,hsdk-v1.0-ohci + - const: generic-ohci + - const: generic-ohci reg: maxItems: 1 -- cgit v1.2.3 From d021e0694d77ee3cdc5d3fca2c8d53ae7575499a Mon Sep 17 00:00:00 2001 From: Bhaskar Chowdhury Date: Wed, 3 Feb 2021 21:04:14 +0530 Subject: doc: devicetree: bindings: usb: Change descibe to describe in usbmisc-imx.txt s/descibe/describe/ Acked-by: Randy Dunlap Signed-off-by: Bhaskar Chowdhury Link: https://lore.kernel.org/r/20210203153414.17044-1-unixbhaskar@gmail.com Signed-off-by: Greg Kroah-Hartman --- Documentation/devicetree/bindings/usb/usbmisc-imx.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/usb/usbmisc-imx.txt b/Documentation/devicetree/bindings/usb/usbmisc-imx.txt index b353b9816487..b796836d2ce7 100644 --- a/Documentation/devicetree/bindings/usb/usbmisc-imx.txt +++ b/Documentation/devicetree/bindings/usb/usbmisc-imx.txt @@ -1,7 +1,7 @@ * Freescale i.MX non-core registers Required properties: -- #index-cells: Cells used to descibe usb controller index. Should be <1> +- #index-cells: Cells used to describe usb controller index. Should be <1> - compatible: Should be one of below: "fsl,imx6q-usbmisc" for imx6q "fsl,vf610-usbmisc" for Vybrid vf610 -- cgit v1.2.3 From 012ce4dd3102a0f4d80167de343e9d44b257c1b8 Mon Sep 17 00:00:00 2001 From: Danielle Ratson Date: Tue, 2 Feb 2021 20:06:06 +0200 Subject: ethtool: Extend link modes settings uAPI with lanes Currently, when auto negotiation is on, the user can advertise all the linkmodes which correspond to a specific speed, but does not have a similar selector for the number of lanes. This is significant when a specific speed can be achieved using different number of lanes. For example, 2x50 or 4x25. Add 'ETHTOOL_A_LINKMODES_LANES' attribute and expand 'struct ethtool_link_settings' with lanes field in order to implement a new lanes-selector that will enable the user to advertise a specific number of lanes as well. When auto negotiation is off, lanes parameter can be forced only if the driver supports it. Add a capability bit in 'struct ethtool_ops' that allows ethtool know if the driver can handle the lanes parameter when auto negotiation is off, so if it does not, an error message will be returned when trying to set lanes. Example: $ ethtool -s swp1 lanes 4 $ ethtool swp1 Settings for swp1: Supported ports: [ FIBRE ] Supported link modes: 1000baseKX/Full 10000baseKR/Full 40000baseCR4/Full 40000baseSR4/Full 40000baseLR4/Full 25000baseCR/Full 25000baseSR/Full 50000baseCR2/Full 100000baseSR4/Full 100000baseCR4/Full Supported pause frame use: Symmetric Receive-only Supports auto-negotiation: Yes Supported FEC modes: Not reported Advertised link modes: 40000baseCR4/Full 40000baseSR4/Full 40000baseLR4/Full 100000baseSR4/Full 100000baseCR4/Full Advertised pause frame use: No Advertised auto-negotiation: Yes Advertised FEC modes: Not reported Speed: Unknown! Duplex: Unknown! (255) Auto-negotiation: on Port: Direct Attach Copper PHYAD: 0 Transceiver: internal Link detected: no Signed-off-by: Danielle Ratson Signed-off-by: Jakub Kicinski --- Documentation/networking/ethtool-netlink.rst | 11 ++-- include/linux/ethtool.h | 4 ++ include/uapi/linux/ethtool_netlink.h | 1 + net/ethtool/linkmodes.c | 96 +++++++++++++++++++++++----- net/ethtool/netlink.h | 2 +- 5 files changed, 93 insertions(+), 21 deletions(-) (limited to 'Documentation') diff --git a/Documentation/networking/ethtool-netlink.rst b/Documentation/networking/ethtool-netlink.rst index 30b98245979f..05073482db05 100644 --- a/Documentation/networking/ethtool-netlink.rst +++ b/Documentation/networking/ethtool-netlink.rst @@ -431,16 +431,17 @@ Request contents: ``ETHTOOL_A_LINKMODES_SPEED`` u32 link speed (Mb/s) ``ETHTOOL_A_LINKMODES_DUPLEX`` u8 duplex mode ``ETHTOOL_A_LINKMODES_MASTER_SLAVE_CFG`` u8 Master/slave port mode + ``ETHTOOL_A_LINKMODES_LANES`` u32 lanes ========================================== ====== ========================== ``ETHTOOL_A_LINKMODES_OURS`` bit set allows setting advertised link modes. If autonegotiation is on (either set now or kept from before), advertised modes are not changed (no ``ETHTOOL_A_LINKMODES_OURS`` attribute) and at least one -of speed and duplex is specified, kernel adjusts advertised modes to all -supported modes matching speed, duplex or both (whatever is specified). This -autoselection is done on ethtool side with ioctl interface, netlink interface -is supposed to allow requesting changes without knowing what exactly kernel -supports. +of speed, duplex and lanes is specified, kernel adjusts advertised modes to all +supported modes matching speed, duplex, lanes or all (whatever is specified). +This autoselection is done on ethtool side with ioctl interface, netlink +interface is supposed to allow requesting changes without knowing what exactly +kernel supports. LINKSTATE_GET diff --git a/include/linux/ethtool.h b/include/linux/ethtool.h index e3da25b51ae4..1ab13c5dfb2f 100644 --- a/include/linux/ethtool.h +++ b/include/linux/ethtool.h @@ -128,6 +128,7 @@ struct ethtool_link_ksettings { __ETHTOOL_DECLARE_LINK_MODE_MASK(advertising); __ETHTOOL_DECLARE_LINK_MODE_MASK(lp_advertising); } link_modes; + u32 lanes; }; /** @@ -265,6 +266,8 @@ struct ethtool_pause_stats { /** * struct ethtool_ops - optional netdev operations + * @cap_link_lanes_supported: indicates if the driver supports lanes + * parameter. * @supported_coalesce_params: supported types of interrupt coalescing. * @get_drvinfo: Report driver/device information. Should only set the * @driver, @version, @fw_version and @bus_info fields. If not @@ -420,6 +423,7 @@ struct ethtool_pause_stats { * of the generic netdev features interface. */ struct ethtool_ops { + u32 cap_link_lanes_supported:1; u32 supported_coalesce_params; void (*get_drvinfo)(struct net_device *, struct ethtool_drvinfo *); int (*get_regs_len)(struct net_device *); diff --git a/include/uapi/linux/ethtool_netlink.h b/include/uapi/linux/ethtool_netlink.h index e2bf36e6964b..a286635ac9b8 100644 --- a/include/uapi/linux/ethtool_netlink.h +++ b/include/uapi/linux/ethtool_netlink.h @@ -227,6 +227,7 @@ enum { ETHTOOL_A_LINKMODES_DUPLEX, /* u8 */ ETHTOOL_A_LINKMODES_MASTER_SLAVE_CFG, /* u8 */ ETHTOOL_A_LINKMODES_MASTER_SLAVE_STATE, /* u8 */ + ETHTOOL_A_LINKMODES_LANES, /* u32 */ /* add new constants above here */ __ETHTOOL_A_LINKMODES_CNT, diff --git a/net/ethtool/linkmodes.c b/net/ethtool/linkmodes.c index bb8a3351fb72..db3e31fc6709 100644 --- a/net/ethtool/linkmodes.c +++ b/net/ethtool/linkmodes.c @@ -152,12 +152,47 @@ const struct ethnl_request_ops ethnl_linkmodes_request_ops = { struct link_mode_info { int speed; + u8 lanes; u8 duplex; }; -#define __DEFINE_LINK_MODE_PARAMS(_speed, _type, _duplex) \ - [ETHTOOL_LINK_MODE(_speed, _type, _duplex)] = { \ - .speed = SPEED_ ## _speed, \ +#define __LINK_MODE_LANES_CR 1 +#define __LINK_MODE_LANES_CR2 2 +#define __LINK_MODE_LANES_CR4 4 +#define __LINK_MODE_LANES_CR8 8 +#define __LINK_MODE_LANES_DR 1 +#define __LINK_MODE_LANES_DR2 2 +#define __LINK_MODE_LANES_DR4 4 +#define __LINK_MODE_LANES_DR8 8 +#define __LINK_MODE_LANES_KR 1 +#define __LINK_MODE_LANES_KR2 2 +#define __LINK_MODE_LANES_KR4 4 +#define __LINK_MODE_LANES_KR8 8 +#define __LINK_MODE_LANES_SR 1 +#define __LINK_MODE_LANES_SR2 2 +#define __LINK_MODE_LANES_SR4 4 +#define __LINK_MODE_LANES_SR8 8 +#define __LINK_MODE_LANES_ER 1 +#define __LINK_MODE_LANES_KX 1 +#define __LINK_MODE_LANES_KX4 4 +#define __LINK_MODE_LANES_LR 1 +#define __LINK_MODE_LANES_LR4 4 +#define __LINK_MODE_LANES_LR4_ER4 4 +#define __LINK_MODE_LANES_LR_ER_FR 1 +#define __LINK_MODE_LANES_LR2_ER2_FR2 2 +#define __LINK_MODE_LANES_LR4_ER4_FR4 4 +#define __LINK_MODE_LANES_LR8_ER8_FR8 8 +#define __LINK_MODE_LANES_LRM 1 +#define __LINK_MODE_LANES_MLD2 2 +#define __LINK_MODE_LANES_T 1 +#define __LINK_MODE_LANES_T1 1 +#define __LINK_MODE_LANES_X 1 +#define __LINK_MODE_LANES_FX 1 + +#define __DEFINE_LINK_MODE_PARAMS(_speed, _type, _duplex) \ + [ETHTOOL_LINK_MODE(_speed, _type, _duplex)] = { \ + .speed = SPEED_ ## _speed, \ + .lanes = __LINK_MODE_LANES_ ## _type, \ .duplex = __DUPLEX_ ## _duplex \ } #define __DUPLEX_Half DUPLEX_HALF @@ -165,6 +200,7 @@ struct link_mode_info { #define __DEFINE_SPECIAL_MODE_PARAMS(_mode) \ [ETHTOOL_LINK_MODE_ ## _mode ## _BIT] = { \ .speed = SPEED_UNKNOWN, \ + .lanes = 0, \ .duplex = DUPLEX_UNKNOWN, \ } @@ -274,16 +310,17 @@ const struct nla_policy ethnl_linkmodes_set_policy[] = { [ETHTOOL_A_LINKMODES_SPEED] = { .type = NLA_U32 }, [ETHTOOL_A_LINKMODES_DUPLEX] = { .type = NLA_U8 }, [ETHTOOL_A_LINKMODES_MASTER_SLAVE_CFG] = { .type = NLA_U8 }, + [ETHTOOL_A_LINKMODES_LANES] = NLA_POLICY_RANGE(NLA_U32, 1, 8), }; -/* Set advertised link modes to all supported modes matching requested speed - * and duplex values. Called when autonegotiation is on, speed or duplex is - * requested but no link mode change. This is done in userspace with ioctl() - * interface, move it into kernel for netlink. +/* Set advertised link modes to all supported modes matching requested speed, + * lanes and duplex values. Called when autonegotiation is on, speed, lanes or + * duplex is requested but no link mode change. This is done in userspace with + * ioctl() interface, move it into kernel for netlink. * Returns true if advertised modes bitmap was modified. */ static bool ethnl_auto_linkmodes(struct ethtool_link_ksettings *ksettings, - bool req_speed, bool req_duplex) + bool req_speed, bool req_lanes, bool req_duplex) { unsigned long *advertising = ksettings->link_modes.advertising; unsigned long *supported = ksettings->link_modes.supported; @@ -302,6 +339,7 @@ static bool ethnl_auto_linkmodes(struct ethtool_link_ksettings *ksettings, continue; if (test_bit(i, supported) && (!req_speed || info->speed == ksettings->base.speed) && + (!req_lanes || info->lanes == ksettings->lanes) && (!req_duplex || info->duplex == ksettings->base.duplex)) set_bit(i, advertising); else @@ -327,7 +365,7 @@ static bool ethnl_validate_master_slave_cfg(u8 cfg) static int ethnl_check_linkmodes(struct genl_info *info, struct nlattr **tb) { - const struct nlattr *master_slave_cfg; + const struct nlattr *master_slave_cfg, *lanes_cfg; master_slave_cfg = tb[ETHTOOL_A_LINKMODES_MASTER_SLAVE_CFG]; if (master_slave_cfg && @@ -337,16 +375,23 @@ static int ethnl_check_linkmodes(struct genl_info *info, struct nlattr **tb) return -EOPNOTSUPP; } + lanes_cfg = tb[ETHTOOL_A_LINKMODES_LANES]; + if (lanes_cfg && !is_power_of_2(nla_get_u32(lanes_cfg))) { + NL_SET_ERR_MSG_ATTR(info->extack, lanes_cfg, + "lanes value is invalid"); + return -EINVAL; + } + return 0; } static int ethnl_update_linkmodes(struct genl_info *info, struct nlattr **tb, struct ethtool_link_ksettings *ksettings, - bool *mod) + bool *mod, const struct net_device *dev) { struct ethtool_link_settings *lsettings = &ksettings->base; - bool req_speed, req_duplex; - const struct nlattr *master_slave_cfg; + bool req_speed, req_lanes, req_duplex; + const struct nlattr *master_slave_cfg, *lanes_cfg; int ret; master_slave_cfg = tb[ETHTOOL_A_LINKMODES_MASTER_SLAVE_CFG]; @@ -360,10 +405,30 @@ static int ethnl_update_linkmodes(struct genl_info *info, struct nlattr **tb, *mod = false; req_speed = tb[ETHTOOL_A_LINKMODES_SPEED]; + req_lanes = tb[ETHTOOL_A_LINKMODES_LANES]; req_duplex = tb[ETHTOOL_A_LINKMODES_DUPLEX]; ethnl_update_u8(&lsettings->autoneg, tb[ETHTOOL_A_LINKMODES_AUTONEG], mod); + + lanes_cfg = tb[ETHTOOL_A_LINKMODES_LANES]; + if (lanes_cfg) { + /* If autoneg is off and lanes parameter is not supported by the + * driver, return an error. + */ + if (!lsettings->autoneg && + !dev->ethtool_ops->cap_link_lanes_supported) { + NL_SET_ERR_MSG_ATTR(info->extack, lanes_cfg, + "lanes configuration not supported by device"); + return -EOPNOTSUPP; + } + } else if (!lsettings->autoneg) { + /* If autoneg is off and lanes parameter is not passed from user, + * set the lanes parameter to 0. + */ + ksettings->lanes = 0; + } + ret = ethnl_update_bitset(ksettings->link_modes.advertising, __ETHTOOL_LINK_MODE_MASK_NBITS, tb[ETHTOOL_A_LINKMODES_OURS], link_mode_names, @@ -372,13 +437,14 @@ static int ethnl_update_linkmodes(struct genl_info *info, struct nlattr **tb, return ret; ethnl_update_u32(&lsettings->speed, tb[ETHTOOL_A_LINKMODES_SPEED], mod); + ethnl_update_u32(&ksettings->lanes, lanes_cfg, mod); ethnl_update_u8(&lsettings->duplex, tb[ETHTOOL_A_LINKMODES_DUPLEX], mod); ethnl_update_u8(&lsettings->master_slave_cfg, master_slave_cfg, mod); if (!tb[ETHTOOL_A_LINKMODES_OURS] && lsettings->autoneg && - (req_speed || req_duplex) && - ethnl_auto_linkmodes(ksettings, req_speed, req_duplex)) + (req_speed || req_lanes || req_duplex) && + ethnl_auto_linkmodes(ksettings, req_speed, req_lanes, req_duplex)) *mod = true; return 0; @@ -420,7 +486,7 @@ int ethnl_set_linkmodes(struct sk_buff *skb, struct genl_info *info) goto out_ops; } - ret = ethnl_update_linkmodes(info, tb, &ksettings, &mod); + ret = ethnl_update_linkmodes(info, tb, &ksettings, &mod, dev); if (ret < 0) goto out_ops; diff --git a/net/ethtool/netlink.h b/net/ethtool/netlink.h index d8efec516d86..6eabd58d81bf 100644 --- a/net/ethtool/netlink.h +++ b/net/ethtool/netlink.h @@ -351,7 +351,7 @@ extern const struct nla_policy ethnl_strset_get_policy[ETHTOOL_A_STRSET_COUNTS_O extern const struct nla_policy ethnl_linkinfo_get_policy[ETHTOOL_A_LINKINFO_HEADER + 1]; extern const struct nla_policy ethnl_linkinfo_set_policy[ETHTOOL_A_LINKINFO_TP_MDIX_CTRL + 1]; extern const struct nla_policy ethnl_linkmodes_get_policy[ETHTOOL_A_LINKMODES_HEADER + 1]; -extern const struct nla_policy ethnl_linkmodes_set_policy[ETHTOOL_A_LINKMODES_MASTER_SLAVE_CFG + 1]; +extern const struct nla_policy ethnl_linkmodes_set_policy[ETHTOOL_A_LINKMODES_LANES + 1]; extern const struct nla_policy ethnl_linkstate_get_policy[ETHTOOL_A_LINKSTATE_HEADER + 1]; extern const struct nla_policy ethnl_debug_get_policy[ETHTOOL_A_DEBUG_HEADER + 1]; extern const struct nla_policy ethnl_debug_set_policy[ETHTOOL_A_DEBUG_MSGMASK + 1]; -- cgit v1.2.3 From a618c47a816fa522fa2c8e0a17e8a291a967e44b Mon Sep 17 00:00:00 2001 From: Bjorn Andersson Date: Wed, 20 Jan 2021 14:45:30 -0800 Subject: dt-bindings: phy: qcom,qmp: Add SC8180X UFS to the QMP binding Add compatible for the SC8180x UFS PHY to the QMP binding. Signed-off-by: Bjorn Andersson Link: https://lore.kernel.org/r/20210120224531.1610709-1-bjorn.andersson@linaro.org Signed-off-by: Vinod Koul --- Documentation/devicetree/bindings/phy/qcom,qmp-phy.yaml | 1 + 1 file changed, 1 insertion(+) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/phy/qcom,qmp-phy.yaml b/Documentation/devicetree/bindings/phy/qcom,qmp-phy.yaml index f578677886c4..723194d938ba 100644 --- a/Documentation/devicetree/bindings/phy/qcom,qmp-phy.yaml +++ b/Documentation/devicetree/bindings/phy/qcom,qmp-phy.yaml @@ -25,6 +25,7 @@ properties: - qcom,msm8998-qmp-pcie-phy - qcom,msm8998-qmp-ufs-phy - qcom,msm8998-qmp-usb3-phy + - qcom,sc8180x-qmp-ufs-phy - qcom,sdm845-qhp-pcie-phy - qcom,sdm845-qmp-pcie-phy - qcom,sdm845-qmp-ufs-phy -- cgit v1.2.3 From 4dd8c1c7f2bd88a4777f87e2a12735a8404235f0 Mon Sep 17 00:00:00 2001 From: Bjorn Andersson Date: Wed, 20 Jan 2021 17:43:38 -0800 Subject: dt-bindings: phy: qcom,qmp: Add SC8180X USB phy Add compatibles for the Qualcomm QMP PHY binding for the SuperSpeed USB phys found in the SC8180x platform. Signed-off-by: Bjorn Andersson Link: https://lore.kernel.org/r/20210121014339.1612525-1-bjorn.andersson@linaro.org Signed-off-by: Vinod Koul --- Documentation/devicetree/bindings/phy/qcom,qmp-phy.yaml | 1 + 1 file changed, 1 insertion(+) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/phy/qcom,qmp-phy.yaml b/Documentation/devicetree/bindings/phy/qcom,qmp-phy.yaml index 723194d938ba..c38061de242a 100644 --- a/Documentation/devicetree/bindings/phy/qcom,qmp-phy.yaml +++ b/Documentation/devicetree/bindings/phy/qcom,qmp-phy.yaml @@ -26,6 +26,7 @@ properties: - qcom,msm8998-qmp-ufs-phy - qcom,msm8998-qmp-usb3-phy - qcom,sc8180x-qmp-ufs-phy + - qcom,sc8180x-qmp-usb3-phy - qcom,sdm845-qhp-pcie-phy - qcom,sdm845-qmp-pcie-phy - qcom,sdm845-qmp-ufs-phy -- cgit v1.2.3 From 3cd542e6e6afb6fa6c34d4094d498f42e22110f5 Mon Sep 17 00:00:00 2001 From: Mika Westerberg Date: Thu, 3 Sep 2020 13:13:21 +0300 Subject: thunderbolt: Add support for PCIe tunneling disabled (SL5) Recent Intel Thunderbolt firmware connection manager has support for another security level, SL5, that disables PCIe tunneling. This option can be turned on from the BIOS. When this is set the driver exposes a new security level "nopcie" to the userspace and hides the authorized attribute under connected devices. While there we also hide it when "dponly" security level is enabled since it is not really usable in that case anyway. Signed-off-by: Mika Westerberg Acked-by: Yehezkel Bernat --- Documentation/ABI/testing/sysfs-bus-thunderbolt | 2 ++ Documentation/admin-guide/thunderbolt.rst | 7 +++++++ drivers/thunderbolt/domain.c | 12 +++++++++++- drivers/thunderbolt/switch.c | 6 +++++- include/linux/thunderbolt.h | 3 +++ 5 files changed, 28 insertions(+), 2 deletions(-) (limited to 'Documentation') diff --git a/Documentation/ABI/testing/sysfs-bus-thunderbolt b/Documentation/ABI/testing/sysfs-bus-thunderbolt index 581dea95245b..d7f09d011b6d 100644 --- a/Documentation/ABI/testing/sysfs-bus-thunderbolt +++ b/Documentation/ABI/testing/sysfs-bus-thunderbolt @@ -85,6 +85,8 @@ Description: This attribute holds current Thunderbolt security level usbonly Automatically tunnel USB controller of the connected Thunderbolt dock (and Display Port). All PCIe links downstream of the dock are removed. + nopcie USB4 system where PCIe tunneling is disabled from + the BIOS. ======= ================================================== What: /sys/bus/thunderbolt/devices/.../authorized diff --git a/Documentation/admin-guide/thunderbolt.rst b/Documentation/admin-guide/thunderbolt.rst index 0d4348445f91..f18e881373c4 100644 --- a/Documentation/admin-guide/thunderbolt.rst +++ b/Documentation/admin-guide/thunderbolt.rst @@ -47,6 +47,9 @@ be DMA masters and thus read contents of the host memory without CPU and OS knowing about it. There are ways to prevent this by setting up an IOMMU but it is not always available for various reasons. +Some USB4 systems have a BIOS setting to disable PCIe tunneling. This is +treated as another security level (nopcie). + The security levels are as follows: none @@ -77,6 +80,10 @@ The security levels are as follows: Display Port in a dock. All PCIe links downstream of the dock are removed. + nopcie + PCIe tunneling is disabled/forbidden from the BIOS. Available in some + USB4 systems. + The current security level can be read from ``/sys/bus/thunderbolt/devices/domainX/security`` where ``domainX`` is the Thunderbolt domain the host controller manages. There is typically diff --git a/drivers/thunderbolt/domain.c b/drivers/thunderbolt/domain.c index 9ba2181464cc..a1c79c9c4f66 100644 --- a/drivers/thunderbolt/domain.c +++ b/drivers/thunderbolt/domain.c @@ -118,6 +118,7 @@ static const char * const tb_security_names[] = { [TB_SECURITY_SECURE] = "secure", [TB_SECURITY_DPONLY] = "dponly", [TB_SECURITY_USBONLY] = "usbonly", + [TB_SECURITY_NOPCIE] = "nopcie", }; static ssize_t boot_acl_show(struct device *dev, struct device_attribute *attr, @@ -243,8 +244,14 @@ static ssize_t deauthorization_show(struct device *dev, char *buf) { const struct tb *tb = container_of(dev, struct tb, dev); + bool deauthorization = false; - return sprintf(buf, "%d\n", !!tb->cm_ops->disapprove_switch); + /* Only meaningful if authorization is supported */ + if (tb->security_level == TB_SECURITY_USER || + tb->security_level == TB_SECURITY_SECURE) + deauthorization = !!tb->cm_ops->disapprove_switch; + + return sprintf(buf, "%d\n", deauthorization); } static DEVICE_ATTR_RO(deauthorization); @@ -452,6 +459,9 @@ int tb_domain_add(struct tb *tb) goto err_ctl_stop; } + tb_dbg(tb, "security level set to %s\n", + tb_security_names[tb->security_level]); + ret = device_add(&tb->dev); if (ret) goto err_ctl_stop; diff --git a/drivers/thunderbolt/switch.c b/drivers/thunderbolt/switch.c index 5377d0a3390f..b63fecca6c2a 100644 --- a/drivers/thunderbolt/switch.c +++ b/drivers/thunderbolt/switch.c @@ -1774,7 +1774,11 @@ static umode_t switch_attr_is_visible(struct kobject *kobj, struct device *dev = kobj_to_dev(kobj); struct tb_switch *sw = tb_to_switch(dev); - if (attr == &dev_attr_device.attr) { + if (attr == &dev_attr_authorized.attr) { + if (sw->tb->security_level == TB_SECURITY_NOPCIE || + sw->tb->security_level == TB_SECURITY_DPONLY) + return 0; + } else if (attr == &dev_attr_device.attr) { if (!sw->device) return 0; } else if (attr == &dev_attr_device_name.attr) { diff --git a/include/linux/thunderbolt.h b/include/linux/thunderbolt.h index 034dccf93955..659a0a810fa1 100644 --- a/include/linux/thunderbolt.h +++ b/include/linux/thunderbolt.h @@ -45,6 +45,8 @@ enum tb_cfg_pkg_type { * @TB_SECURITY_USBONLY: Only tunnel USB controller of the connected * Thunderbolt dock (and Display Port). All PCIe * links downstream of the dock are removed. + * @TB_SECURITY_NOPCIE: For USB4 systems this level is used when the + * PCIe tunneling is disabled from the BIOS. */ enum tb_security_level { TB_SECURITY_NONE, @@ -52,6 +54,7 @@ enum tb_security_level { TB_SECURITY_SECURE, TB_SECURITY_DPONLY, TB_SECURITY_USBONLY, + TB_SECURITY_NOPCIE, }; /** -- cgit v1.2.3 From 53dd01da9729a9ece9ef1e47d248b420467836ae Mon Sep 17 00:00:00 2001 From: Baruch Siach Date: Wed, 27 Jan 2021 16:20:28 +0200 Subject: dt-bindings: phy: qcom,qusb2: document ipq6018 compatible This compatible string is for the USB PHY on IPQ60xx systems. Signed-off-by: Baruch Siach Link: https://lore.kernel.org/r/7e1e7bda6ccdaab9adeeb956fac1acc39908a8dc.1611756920.git.baruch@tkos.co.il Signed-off-by: Vinod Koul --- Documentation/devicetree/bindings/phy/qcom,qusb2-phy.yaml | 1 + 1 file changed, 1 insertion(+) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/phy/qcom,qusb2-phy.yaml b/Documentation/devicetree/bindings/phy/qcom,qusb2-phy.yaml index 582abbbd8b32..9f9cf07b7d45 100644 --- a/Documentation/devicetree/bindings/phy/qcom,qusb2-phy.yaml +++ b/Documentation/devicetree/bindings/phy/qcom,qusb2-phy.yaml @@ -22,6 +22,7 @@ properties: - qcom,msm8996-qusb2-phy - qcom,msm8998-qusb2-phy - qcom,sdm660-qusb2-phy + - qcom,ipq6018-qusb2-phy - items: - enum: - qcom,sc7180-qusb2-phy -- cgit v1.2.3 From 557a28811c7e0286d3816842032db5eb7bb5f156 Mon Sep 17 00:00:00 2001 From: Konrad Dybcio Date: Sun, 31 Jan 2021 02:31:24 +0100 Subject: phy: qualcomm: usb28nm: Add MDM9607 init sequence This is required to bring up the PHY on MDM9607-based boards. Signed-off-by: Konrad Dybcio Link: https://lore.kernel.org/r/20210131013124.54484-1-konrad.dybcio@somainline.org Signed-off-by: Vinod Koul --- Documentation/devicetree/bindings/phy/qcom,usb-hs-28nm.yaml | 1 + drivers/phy/qualcomm/phy-qcom-usb-hs-28nm.c | 13 +++++++++++++ 2 files changed, 14 insertions(+) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/phy/qcom,usb-hs-28nm.yaml b/Documentation/devicetree/bindings/phy/qcom,usb-hs-28nm.yaml index ca6a0836b53c..abcc4373f39e 100644 --- a/Documentation/devicetree/bindings/phy/qcom,usb-hs-28nm.yaml +++ b/Documentation/devicetree/bindings/phy/qcom,usb-hs-28nm.yaml @@ -16,6 +16,7 @@ properties: compatible: enum: - qcom,usb-hs-28nm-femtophy + - qcom,usb-hs-28nm-mdm9607 reg: maxItems: 1 diff --git a/drivers/phy/qualcomm/phy-qcom-usb-hs-28nm.c b/drivers/phy/qualcomm/phy-qcom-usb-hs-28nm.c index a52a9bf13b75..8807e59a1162 100644 --- a/drivers/phy/qualcomm/phy-qcom-usb-hs-28nm.c +++ b/drivers/phy/qualcomm/phy-qcom-usb-hs-28nm.c @@ -401,13 +401,26 @@ static const struct hsphy_init_seq init_seq_femtophy[] = { HSPHY_INIT_CFG(0x90, 0x60, 0), }; +static const struct hsphy_init_seq init_seq_mdm9607[] = { + HSPHY_INIT_CFG(0x80, 0x44, 0), + HSPHY_INIT_CFG(0x81, 0x38, 0), + HSPHY_INIT_CFG(0x82, 0x24, 0), + HSPHY_INIT_CFG(0x83, 0x13, 0), +}; + static const struct hsphy_data hsphy_data_femtophy = { .init_seq = init_seq_femtophy, .init_seq_num = ARRAY_SIZE(init_seq_femtophy), }; +static const struct hsphy_data hsphy_data_mdm9607 = { + .init_seq = init_seq_mdm9607, + .init_seq_num = ARRAY_SIZE(init_seq_mdm9607), +}; + static const struct of_device_id qcom_snps_hsphy_match[] = { { .compatible = "qcom,usb-hs-28nm-femtophy", .data = &hsphy_data_femtophy, }, + { .compatible = "qcom,usb-hs-28nm-mdm9607", .data = &hsphy_data_mdm9607, }, { }, }; MODULE_DEVICE_TABLE(of, qcom_snps_hsphy_match); -- cgit v1.2.3 From 6b49dea4fd9c539f5fea61f6a203ec1349292a26 Mon Sep 17 00:00:00 2001 From: Barnabás Pőcze Date: Wed, 3 Feb 2021 21:57:13 +0000 Subject: platform/x86: ideapad-laptop: add "always on USB charging" control support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Certain models have a so-called "always on USB charging" feature, which enables USB charging even when the computer is turned off or suspended, and which may be controlled/queried using the SALS/HALS ACPI methods. Expose this functionality via a new device attribute (usb_charging). Tested on: Lenovo YOGA 520-14IKB 80X8 Signed-off-by: Barnabás Pőcze Link: https://lore.kernel.org/r/20210203215403.290792-28-pobrn@protonmail.com Reviewed-by: Hans de Goede Signed-off-by: Hans de Goede --- .../ABI/testing/sysfs-platform-ideapad-laptop | 9 +++ drivers/platform/x86/ideapad-laptop.c | 65 +++++++++++++++++++--- 2 files changed, 65 insertions(+), 9 deletions(-) (limited to 'Documentation') diff --git a/Documentation/ABI/testing/sysfs-platform-ideapad-laptop b/Documentation/ABI/testing/sysfs-platform-ideapad-laptop index fd2ac02bc5bd..b17688d73922 100644 --- a/Documentation/ABI/testing/sysfs-platform-ideapad-laptop +++ b/Documentation/ABI/testing/sysfs-platform-ideapad-laptop @@ -41,3 +41,12 @@ Description: # echo "0" > \ /sys/bus/pci/devices/0000:00:1f.0/PNP0C09:00/VPC2004:00/fn_lock + +What: /sys/bus/platform/devices/VPC2004:*/usb_charging +Date: Feb 2021 +KernelVersion: 5.12 +Contact: platform-driver-x86@vger.kernel.org +Description: + Controls whether the "always on USB charging" feature is + enabled or not. This feature enables charging USB devices + even if the computer is not turned on. diff --git a/drivers/platform/x86/ideapad-laptop.c b/drivers/platform/x86/ideapad-laptop.c index 24dcb4ad75ef..6cb5ad4be231 100644 --- a/drivers/platform/x86/ideapad-laptop.c +++ b/drivers/platform/x86/ideapad-laptop.c @@ -62,18 +62,22 @@ enum { }; enum { - HALS_KBD_BL_SUPPORT_BIT = 4, - HALS_KBD_BL_STATE_BIT = 5, - HALS_FNLOCK_SUPPORT_BIT = 9, - HALS_FNLOCK_STATE_BIT = 10, - HALS_HOTKEYS_PRIMARY_BIT = 11, + HALS_KBD_BL_SUPPORT_BIT = 4, + HALS_KBD_BL_STATE_BIT = 5, + HALS_USB_CHARGING_SUPPORT_BIT = 6, + HALS_USB_CHARGING_STATE_BIT = 7, + HALS_FNLOCK_SUPPORT_BIT = 9, + HALS_FNLOCK_STATE_BIT = 10, + HALS_HOTKEYS_PRIMARY_BIT = 11, }; enum { - SALS_KBD_BL_ON = 0x8, - SALS_KBD_BL_OFF = 0x9, - SALS_FNLOCK_ON = 0xe, - SALS_FNLOCK_OFF = 0xf, + SALS_KBD_BL_ON = 0x8, + SALS_KBD_BL_OFF = 0x9, + SALS_USB_CHARGING_ON = 0xa, + SALS_USB_CHARGING_OFF = 0xb, + SALS_FNLOCK_ON = 0xe, + SALS_FNLOCK_OFF = 0xf, }; enum { @@ -134,6 +138,7 @@ struct ideapad_private { bool hw_rfkill_switch : 1; bool kbd_bl : 1; bool touchpad_ctrl_via_ec : 1; + bool usb_charging : 1; } features; struct { bool initialized; @@ -592,12 +597,49 @@ static ssize_t touchpad_store(struct device *dev, static DEVICE_ATTR_RW(touchpad); +static ssize_t usb_charging_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct ideapad_private *priv = dev_get_drvdata(dev); + unsigned long hals; + int err; + + err = eval_hals(priv->adev->handle, &hals); + if (err) + return err; + + return sysfs_emit(buf, "%d\n", !!test_bit(HALS_USB_CHARGING_STATE_BIT, &hals)); +} + +static ssize_t usb_charging_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct ideapad_private *priv = dev_get_drvdata(dev); + bool state; + int err; + + err = kstrtobool(buf, &state); + if (err) + return err; + + err = exec_sals(priv->adev->handle, state ? SALS_USB_CHARGING_ON : SALS_USB_CHARGING_OFF); + if (err) + return err; + + return count; +} + +static DEVICE_ATTR_RW(usb_charging); + static struct attribute *ideapad_attributes[] = { &dev_attr_camera_power.attr, &dev_attr_conservation_mode.attr, &dev_attr_fan_mode.attr, &dev_attr_fn_lock.attr, &dev_attr_touchpad.attr, + &dev_attr_usb_charging.attr, NULL }; @@ -620,6 +662,8 @@ static umode_t ideapad_is_visible(struct kobject *kobj, else if (attr == &dev_attr_touchpad.attr) supported = priv->features.touchpad_ctrl_via_ec && test_bit(CFG_CAP_TOUCHPAD_BIT, &priv->cfg); + else if (attr == &dev_attr_usb_charging.attr) + supported = priv->features.usb_charging; return supported ? attr->mode : 0; } @@ -1459,6 +1503,9 @@ static void ideapad_check_features(struct ideapad_private *priv) if (test_bit(HALS_KBD_BL_SUPPORT_BIT, &val)) priv->features.kbd_bl = true; + + if (test_bit(HALS_USB_CHARGING_SUPPORT_BIT, &val)) + priv->features.usb_charging = true; } } } -- cgit v1.2.3 From 725f41339a70b78cd10dba71ee8ec252083b40ec Mon Sep 17 00:00:00 2001 From: Barnabás Pőcze Date: Wed, 3 Feb 2021 21:57:19 +0000 Subject: Documentation/ABI: sysfs-platform-ideapad-laptop: update device attribute paths MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The documentation referred to non-existent device attributes under a non-existent platform device. Update it with the current location of the attributes. Fixes: b5c37b798f2d ("ideapad_laptop: convert ideapad device/driver to platform bus") Signed-off-by: Barnabás Pőcze Link: https://lore.kernel.org/r/20210203215403.290792-29-pobrn@protonmail.com Reviewed-by: Hans de Goede Signed-off-by: Hans de Goede --- Documentation/ABI/testing/sysfs-platform-ideapad-laptop | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'Documentation') diff --git a/Documentation/ABI/testing/sysfs-platform-ideapad-laptop b/Documentation/ABI/testing/sysfs-platform-ideapad-laptop index b17688d73922..5ec0dee9e707 100644 --- a/Documentation/ABI/testing/sysfs-platform-ideapad-laptop +++ b/Documentation/ABI/testing/sysfs-platform-ideapad-laptop @@ -1,11 +1,11 @@ -What: /sys/devices/platform/ideapad/camera_power +What: /sys/bus/platform/devices/VPC2004:*/camera_power Date: Dec 2010 KernelVersion: 2.6.37 Contact: "Ike Panhc " Description: Control the power of camera module. 1 means on, 0 means off. -What: /sys/devices/platform/ideapad/fan_mode +What: /sys/bus/platform/devices/VPC2004:*/fan_mode Date: June 2012 KernelVersion: 3.6 Contact: "Maxim Mikityanskiy " @@ -18,7 +18,7 @@ Description: * 2 -> Dust Cleaning * 4 -> Efficient Thermal Dissipation Mode -What: /sys/devices/platform/ideapad/touchpad +What: /sys/bus/platform/devices/VPC2004:*/touchpad Date: May 2017 KernelVersion: 4.13 Contact: "Ritesh Raj Sarraf " @@ -27,7 +27,7 @@ Description: * 1 -> Switched On * 0 -> Switched Off -What: /sys/bus/pci/devices///VPC2004:00/fn_lock +What: /sys/bus/platform/devices/VPC2004:*/fn_lock Date: May 2018 KernelVersion: 4.18 Contact: "Oleg Keri " -- cgit v1.2.3 From cb3acb1564b0637beb446e6a9cf40cb40e147e1f Mon Sep 17 00:00:00 2001 From: Barnabás Pőcze Date: Wed, 3 Feb 2021 21:57:26 +0000 Subject: Documentation/ABI: sysfs-platform-ideapad-laptop: conservation_mode attribute MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Document the conservation_mode attributes provided by the ideapad-laptop module. Fixes: ade50296186a ("platform/x86: ideapad-laptop: Expose conservation mode switch") Signed-off-by: Barnabás Pőcze Link: https://lore.kernel.org/r/20210203215403.290792-30-pobrn@protonmail.com Reviewed-by: Hans de Goede Signed-off-by: Hans de Goede --- Documentation/ABI/testing/sysfs-platform-ideapad-laptop | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'Documentation') diff --git a/Documentation/ABI/testing/sysfs-platform-ideapad-laptop b/Documentation/ABI/testing/sysfs-platform-ideapad-laptop index 5ec0dee9e707..4989ab266682 100644 --- a/Documentation/ABI/testing/sysfs-platform-ideapad-laptop +++ b/Documentation/ABI/testing/sysfs-platform-ideapad-laptop @@ -27,6 +27,15 @@ Description: * 1 -> Switched On * 0 -> Switched Off +What: /sys/bus/platform/devices/VPC2004:*/conservation_mode +Date: Aug 2017 +KernelVersion: 4.14 +Contact: platform-driver-x86@vger.kernel.org +Description: + Controls whether the conservation mode is enabled or not. + This feature limits the maximum battery charge percentage to + around 50-60% in order to prolong the lifetime of the battery. + What: /sys/bus/platform/devices/VPC2004:*/fn_lock Date: May 2018 KernelVersion: 4.18 -- cgit v1.2.3 From 2c07ded06427dd3339278487a1413d5e478f05f9 Mon Sep 17 00:00:00 2001 From: Brijesh Singh Date: Mon, 4 Jan 2021 09:17:49 -0600 Subject: KVM/SVM: add support for SEV attestation command The SEV FW version >= 0.23 added a new command that can be used to query the attestation report containing the SHA-256 digest of the guest memory encrypted through the KVM_SEV_LAUNCH_UPDATE_{DATA, VMSA} commands and sign the report with the Platform Endorsement Key (PEK). See the SEV FW API spec section 6.8 for more details. Note there already exist a command (KVM_SEV_LAUNCH_MEASURE) that can be used to get the SHA-256 digest. The main difference between the KVM_SEV_LAUNCH_MEASURE and KVM_SEV_ATTESTATION_REPORT is that the latter can be called while the guest is running and the measurement value is signed with PEK. Cc: James Bottomley Cc: Tom Lendacky Cc: David Rientjes Cc: Paolo Bonzini Cc: Sean Christopherson Cc: Borislav Petkov Cc: John Allen Cc: Herbert Xu Cc: linux-crypto@vger.kernel.org Reviewed-by: Tom Lendacky Acked-by: David Rientjes Tested-by: James Bottomley Signed-off-by: Brijesh Singh Message-Id: <20210104151749.30248-1-brijesh.singh@amd.com> Signed-off-by: Paolo Bonzini --- Documentation/virt/kvm/amd-memory-encryption.rst | 21 +++++++ arch/x86/kvm/svm/sev.c | 71 ++++++++++++++++++++++++ drivers/crypto/ccp/sev-dev.c | 1 + include/linux/psp-sev.h | 17 ++++++ include/uapi/linux/kvm.h | 8 +++ 5 files changed, 118 insertions(+) (limited to 'Documentation') diff --git a/Documentation/virt/kvm/amd-memory-encryption.rst b/Documentation/virt/kvm/amd-memory-encryption.rst index 09a8f2a34e39..469a6308765b 100644 --- a/Documentation/virt/kvm/amd-memory-encryption.rst +++ b/Documentation/virt/kvm/amd-memory-encryption.rst @@ -263,6 +263,27 @@ Returns: 0 on success, -negative on error __u32 trans_len; }; +10. KVM_SEV_GET_ATTESTATION_REPORT +---------------------------------- + +The KVM_SEV_GET_ATTESTATION_REPORT command can be used by the hypervisor to query the attestation +report containing the SHA-256 digest of the guest memory and VMSA passed through the KVM_SEV_LAUNCH +commands and signed with the PEK. The digest returned by the command should match the digest +used by the guest owner with the KVM_SEV_LAUNCH_MEASURE. + +Parameters (in): struct kvm_sev_attestation + +Returns: 0 on success, -negative on error + +:: + + struct kvm_sev_attestation_report { + __u8 mnonce[16]; /* A random mnonce that will be placed in the report */ + + __u64 uaddr; /* userspace address where the report should be copied */ + __u32 len; + }; + References ========== diff --git a/arch/x86/kvm/svm/sev.c b/arch/x86/kvm/svm/sev.c index 48017fef1cd9..8dfe8988be8d 100644 --- a/arch/x86/kvm/svm/sev.c +++ b/arch/x86/kvm/svm/sev.c @@ -1041,6 +1041,74 @@ e_unpin_memory: return ret; } +static int sev_get_attestation_report(struct kvm *kvm, struct kvm_sev_cmd *argp) +{ + void __user *report = (void __user *)(uintptr_t)argp->data; + struct kvm_sev_info *sev = &to_kvm_svm(kvm)->sev_info; + struct sev_data_attestation_report *data; + struct kvm_sev_attestation_report params; + void __user *p; + void *blob = NULL; + int ret; + + if (!sev_guest(kvm)) + return -ENOTTY; + + if (copy_from_user(¶ms, (void __user *)(uintptr_t)argp->data, sizeof(params))) + return -EFAULT; + + data = kzalloc(sizeof(*data), GFP_KERNEL_ACCOUNT); + if (!data) + return -ENOMEM; + + /* User wants to query the blob length */ + if (!params.len) + goto cmd; + + p = (void __user *)(uintptr_t)params.uaddr; + if (p) { + if (params.len > SEV_FW_BLOB_MAX_SIZE) { + ret = -EINVAL; + goto e_free; + } + + ret = -ENOMEM; + blob = kmalloc(params.len, GFP_KERNEL); + if (!blob) + goto e_free; + + data->address = __psp_pa(blob); + data->len = params.len; + memcpy(data->mnonce, params.mnonce, sizeof(params.mnonce)); + } +cmd: + data->handle = sev->handle; + ret = sev_issue_cmd(kvm, SEV_CMD_ATTESTATION_REPORT, data, &argp->error); + /* + * If we query the session length, FW responded with expected data. + */ + if (!params.len) + goto done; + + if (ret) + goto e_free_blob; + + if (blob) { + if (copy_to_user(p, blob, params.len)) + ret = -EFAULT; + } + +done: + params.len = data->len; + if (copy_to_user(report, ¶ms, sizeof(params))) + ret = -EFAULT; +e_free_blob: + kfree(blob); +e_free: + kfree(data); + return ret; +} + int svm_mem_enc_op(struct kvm *kvm, void __user *argp) { struct kvm_sev_cmd sev_cmd; @@ -1091,6 +1159,9 @@ int svm_mem_enc_op(struct kvm *kvm, void __user *argp) case KVM_SEV_LAUNCH_SECRET: r = sev_launch_secret(kvm, &sev_cmd); break; + case KVM_SEV_GET_ATTESTATION_REPORT: + r = sev_get_attestation_report(kvm, &sev_cmd); + break; default: r = -EINVAL; goto out; diff --git a/drivers/crypto/ccp/sev-dev.c b/drivers/crypto/ccp/sev-dev.c index 476113e12489..cb9b4c4e371e 100644 --- a/drivers/crypto/ccp/sev-dev.c +++ b/drivers/crypto/ccp/sev-dev.c @@ -128,6 +128,7 @@ static int sev_cmd_buffer_len(int cmd) case SEV_CMD_LAUNCH_UPDATE_SECRET: return sizeof(struct sev_data_launch_secret); case SEV_CMD_DOWNLOAD_FIRMWARE: return sizeof(struct sev_data_download_firmware); case SEV_CMD_GET_ID: return sizeof(struct sev_data_get_id); + case SEV_CMD_ATTESTATION_REPORT: return sizeof(struct sev_data_attestation_report); default: return 0; } diff --git a/include/linux/psp-sev.h b/include/linux/psp-sev.h index 49d155cd2dfe..b801ead1e2bb 100644 --- a/include/linux/psp-sev.h +++ b/include/linux/psp-sev.h @@ -66,6 +66,7 @@ enum sev_cmd { SEV_CMD_LAUNCH_MEASURE = 0x033, SEV_CMD_LAUNCH_UPDATE_SECRET = 0x034, SEV_CMD_LAUNCH_FINISH = 0x035, + SEV_CMD_ATTESTATION_REPORT = 0x036, /* Guest migration commands (outgoing) */ SEV_CMD_SEND_START = 0x040, @@ -483,6 +484,22 @@ struct sev_data_dbg { u32 len; /* In */ } __packed; +/** + * struct sev_data_attestation_report - SEV_ATTESTATION_REPORT command parameters + * + * @handle: handle of the VM + * @mnonce: a random nonce that will be included in the report. + * @address: physical address where the report will be copied. + * @len: length of the physical buffer. + */ +struct sev_data_attestation_report { + u32 handle; /* In */ + u32 reserved; + u64 address; /* In */ + u8 mnonce[16]; /* In */ + u32 len; /* In/Out */ +} __packed; + #ifdef CONFIG_CRYPTO_DEV_SP_PSP /** diff --git a/include/uapi/linux/kvm.h b/include/uapi/linux/kvm.h index 374c67875cdb..07c194e2c302 100644 --- a/include/uapi/linux/kvm.h +++ b/include/uapi/linux/kvm.h @@ -1593,6 +1593,8 @@ enum sev_cmd_id { KVM_SEV_DBG_ENCRYPT, /* Guest certificates commands */ KVM_SEV_CERT_EXPORT, + /* Attestation report */ + KVM_SEV_GET_ATTESTATION_REPORT, KVM_SEV_NR_MAX, }; @@ -1645,6 +1647,12 @@ struct kvm_sev_dbg { __u32 len; }; +struct kvm_sev_attestation_report { + __u8 mnonce[16]; + __u64 uaddr; + __u32 len; +}; + #define KVM_DEV_ASSIGN_ENABLE_IOMMU (1 << 0) #define KVM_DEV_ASSIGN_PCI_2_3 (1 << 1) #define KVM_DEV_ASSIGN_MASK_INTX (1 << 2) -- cgit v1.2.3 From c32b1b896d2ab30ac30bc39194bac47a09f7f497 Mon Sep 17 00:00:00 2001 From: Chenyi Qiang Date: Fri, 6 Nov 2020 17:03:15 +0800 Subject: KVM: X86: Add the Document for KVM_CAP_X86_BUS_LOCK_EXIT Introduce a new capability named KVM_CAP_X86_BUS_LOCK_EXIT, which is used to handle bus locks detected in guest. It allows the userspace to do custom throttling policies to mitigate the 'noisy neighbour' problem. Signed-off-by: Chenyi Qiang Message-Id: <20201106090315.18606-5-chenyi.qiang@intel.com> Signed-off-by: Paolo Bonzini --- Documentation/virt/kvm/api.rst | 45 +++++++++++++++++++++++++++++++++++++++--- 1 file changed, 42 insertions(+), 3 deletions(-) (limited to 'Documentation') diff --git a/Documentation/virt/kvm/api.rst b/Documentation/virt/kvm/api.rst index 99ceb978c8b0..effcc08733fd 100644 --- a/Documentation/virt/kvm/api.rst +++ b/Documentation/virt/kvm/api.rst @@ -4893,9 +4893,11 @@ local APIC is not used. __u16 flags; More architecture-specific flags detailing state of the VCPU that may -affect the device's behavior. The only currently defined flag is -KVM_RUN_X86_SMM, which is valid on x86 machines and is set if the -VCPU is in system management mode. +affect the device's behavior. Current defined flags: + /* x86, set if the VCPU is in system management mode */ + #define KVM_RUN_X86_SMM (1 << 0) + /* x86, set if bus lock detected in VM */ + #define KVM_RUN_BUS_LOCK (1 << 1) :: @@ -6038,6 +6040,43 @@ KVM_EXIT_X86_RDMSR and KVM_EXIT_X86_WRMSR exit notifications which user space can then handle to implement model specific MSR handling and/or user notifications to inform a user that an MSR was not handled. +7.22 KVM_CAP_X86_BUS_LOCK_EXIT +------------------------------- + +:Architectures: x86 +:Target: VM +:Parameters: args[0] defines the policy used when bus locks detected in guest +:Returns: 0 on success, -EINVAL when args[0] contains invalid bits + +Valid bits in args[0] are:: + + #define KVM_BUS_LOCK_DETECTION_OFF (1 << 0) + #define KVM_BUS_LOCK_DETECTION_EXIT (1 << 1) + +Enabling this capability on a VM provides userspace with a way to select +a policy to handle the bus locks detected in guest. Userspace can obtain +the supported modes from the result of KVM_CHECK_EXTENSION and define it +through the KVM_ENABLE_CAP. + +KVM_BUS_LOCK_DETECTION_OFF and KVM_BUS_LOCK_DETECTION_EXIT are supported +currently and mutually exclusive with each other. More bits can be added in +the future. + +With KVM_BUS_LOCK_DETECTION_OFF set, bus locks in guest will not cause vm exits +so that no additional actions are needed. This is the default mode. + +With KVM_BUS_LOCK_DETECTION_EXIT set, vm exits happen when bus lock detected +in VM. KVM just exits to userspace when handling them. Userspace can enforce +its own throttling or other policy based mitigations. + +This capability is aimed to address the thread that VM can exploit bus locks to +degree the performance of the whole system. Once the userspace enable this +capability and select the KVM_BUS_LOCK_DETECTION_EXIT mode, KVM will set the +KVM_RUN_BUS_LOCK flag in vcpu-run->flags field and exit to userspace. Concerning +the bus lock vm exit can be preempted by a higher priority VM exit, the exit +notifications to userspace can be KVM_EXIT_BUS_LOCK or other reasons. +KVM_RUN_BUS_LOCK flag is used to distinguish between them. + 8. Other capabilities. ====================== -- cgit v1.2.3 From 9a77daacc87dee9fd63e31243f21894132ed8407 Mon Sep 17 00:00:00 2001 From: Ben Gardon Date: Tue, 2 Feb 2021 10:57:26 -0800 Subject: KVM: x86/mmu: Use atomic ops to set SPTEs in TDP MMU map To prepare for handling page faults in parallel, change the TDP MMU page fault handler to use atomic operations to set SPTEs so that changes are not lost if multiple threads attempt to modify the same SPTE. Reviewed-by: Peter Feiner Signed-off-by: Ben Gardon Message-Id: <20210202185734.1680553-21-bgardon@google.com> [Document new locking rules. - Paolo] Signed-off-by: Paolo Bonzini --- Documentation/virt/kvm/locking.rst | 9 ++- arch/x86/include/asm/kvm_host.h | 13 ++++ arch/x86/kvm/mmu/tdp_mmu.c | 142 ++++++++++++++++++++++++++++--------- 3 files changed, 130 insertions(+), 34 deletions(-) (limited to 'Documentation') diff --git a/Documentation/virt/kvm/locking.rst b/Documentation/virt/kvm/locking.rst index b21a34c34a21..0aa4817b466d 100644 --- a/Documentation/virt/kvm/locking.rst +++ b/Documentation/virt/kvm/locking.rst @@ -16,7 +16,14 @@ The acquisition orders for mutexes are as follows: - kvm->slots_lock is taken outside kvm->irq_lock, though acquiring them together is quite rare. -On x86, vcpu->mutex is taken outside kvm->arch.hyperv.hv_lock. +On x86: + +- vcpu->mutex is taken outside kvm->arch.hyperv.hv_lock + +- kvm->arch.mmu_lock is an rwlock. kvm->arch.tdp_mmu_pages_lock is + taken inside kvm->arch.mmu_lock, and cannot be taken without already + holding kvm->arch.mmu_lock (typically with ``read_lock``, otherwise + there's no need to take kvm->arch.tdp_mmu_pages_lock at all). Everything else is a leaf: no other lock is taken inside the critical sections. diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h index c445a51244d3..bcbb32ef9f00 100644 --- a/arch/x86/include/asm/kvm_host.h +++ b/arch/x86/include/asm/kvm_host.h @@ -1039,6 +1039,19 @@ struct kvm_arch { * tdp_mmu_page set and a root_count of 0. */ struct list_head tdp_mmu_pages; + + /* + * Protects accesses to the following fields when the MMU lock + * is held in read mode: + * - tdp_mmu_pages (above) + * - the link field of struct kvm_mmu_pages used by the TDP MMU + * - lpage_disallowed_mmu_pages + * - the lpage_disallowed_link field of struct kvm_mmu_pages used + * by the TDP MMU + * It is acceptable, but not necessary, to acquire this lock when + * the thread holds the MMU lock in write mode. + */ + spinlock_t tdp_mmu_pages_lock; }; struct kvm_vm_stat { diff --git a/arch/x86/kvm/mmu/tdp_mmu.c b/arch/x86/kvm/mmu/tdp_mmu.c index 5a9e964e0178..0b5a9339ac55 100644 --- a/arch/x86/kvm/mmu/tdp_mmu.c +++ b/arch/x86/kvm/mmu/tdp_mmu.c @@ -7,6 +7,7 @@ #include "tdp_mmu.h" #include "spte.h" +#include #include #ifdef CONFIG_X86_64 @@ -33,6 +34,7 @@ void kvm_mmu_init_tdp_mmu(struct kvm *kvm) kvm->arch.tdp_mmu_enabled = true; INIT_LIST_HEAD(&kvm->arch.tdp_mmu_roots); + spin_lock_init(&kvm->arch.tdp_mmu_pages_lock); INIT_LIST_HEAD(&kvm->arch.tdp_mmu_pages); } @@ -225,7 +227,8 @@ static void tdp_mmu_free_sp_rcu_callback(struct rcu_head *head) } static void handle_changed_spte(struct kvm *kvm, int as_id, gfn_t gfn, - u64 old_spte, u64 new_spte, int level); + u64 old_spte, u64 new_spte, int level, + bool shared); static int kvm_mmu_page_as_id(struct kvm_mmu_page *sp) { @@ -267,17 +270,26 @@ static void handle_changed_spte_dirty_log(struct kvm *kvm, int as_id, gfn_t gfn, * * @kvm: kvm instance * @sp: the new page + * @shared: This operation may not be running under the exclusive use of + * the MMU lock and the operation must synchronize with other + * threads that might be adding or removing pages. * @account_nx: This page replaces a NX large page and should be marked for * eventual reclaim. */ static void tdp_mmu_link_page(struct kvm *kvm, struct kvm_mmu_page *sp, - bool account_nx) + bool shared, bool account_nx) { - lockdep_assert_held_write(&kvm->mmu_lock); + if (shared) + spin_lock(&kvm->arch.tdp_mmu_pages_lock); + else + lockdep_assert_held_write(&kvm->mmu_lock); list_add(&sp->link, &kvm->arch.tdp_mmu_pages); if (account_nx) account_huge_nx_page(kvm, sp); + + if (shared) + spin_unlock(&kvm->arch.tdp_mmu_pages_lock); } /** @@ -285,14 +297,24 @@ static void tdp_mmu_link_page(struct kvm *kvm, struct kvm_mmu_page *sp, * * @kvm: kvm instance * @sp: the page to be removed + * @shared: This operation may not be running under the exclusive use of + * the MMU lock and the operation must synchronize with other + * threads that might be adding or removing pages. */ -static void tdp_mmu_unlink_page(struct kvm *kvm, struct kvm_mmu_page *sp) +static void tdp_mmu_unlink_page(struct kvm *kvm, struct kvm_mmu_page *sp, + bool shared) { - lockdep_assert_held_write(&kvm->mmu_lock); + if (shared) + spin_lock(&kvm->arch.tdp_mmu_pages_lock); + else + lockdep_assert_held_write(&kvm->mmu_lock); list_del(&sp->link); if (sp->lpage_disallowed) unaccount_huge_nx_page(kvm, sp); + + if (shared) + spin_unlock(&kvm->arch.tdp_mmu_pages_lock); } /** @@ -300,28 +322,39 @@ static void tdp_mmu_unlink_page(struct kvm *kvm, struct kvm_mmu_page *sp) * * @kvm: kvm instance * @pt: the page removed from the paging structure + * @shared: This operation may not be running under the exclusive use + * of the MMU lock and the operation must synchronize with other + * threads that might be modifying SPTEs. * * Given a page table that has been removed from the TDP paging structure, * iterates through the page table to clear SPTEs and free child page tables. */ -static void handle_removed_tdp_mmu_page(struct kvm *kvm, u64 *pt) +static void handle_removed_tdp_mmu_page(struct kvm *kvm, u64 *pt, + bool shared) { struct kvm_mmu_page *sp = sptep_to_sp(pt); int level = sp->role.level; gfn_t gfn = sp->gfn; u64 old_child_spte; + u64 *sptep; int i; trace_kvm_mmu_prepare_zap_page(sp); - tdp_mmu_unlink_page(kvm, sp); + tdp_mmu_unlink_page(kvm, sp, shared); for (i = 0; i < PT64_ENT_PER_PAGE; i++) { - old_child_spte = READ_ONCE(*(pt + i)); - WRITE_ONCE(*(pt + i), 0); + sptep = pt + i; + + if (shared) { + old_child_spte = xchg(sptep, 0); + } else { + old_child_spte = READ_ONCE(*sptep); + WRITE_ONCE(*sptep, 0); + } handle_changed_spte(kvm, kvm_mmu_page_as_id(sp), gfn + (i * KVM_PAGES_PER_HPAGE(level - 1)), - old_child_spte, 0, level - 1); + old_child_spte, 0, level - 1, shared); } kvm_flush_remote_tlbs_with_address(kvm, gfn, @@ -338,12 +371,16 @@ static void handle_removed_tdp_mmu_page(struct kvm *kvm, u64 *pt) * @old_spte: The value of the SPTE before the change * @new_spte: The value of the SPTE after the change * @level: the level of the PT the SPTE is part of in the paging structure + * @shared: This operation may not be running under the exclusive use of + * the MMU lock and the operation must synchronize with other + * threads that might be modifying SPTEs. * * Handle bookkeeping that might result from the modification of a SPTE. * This function must be called for all TDP SPTE modifications. */ static void __handle_changed_spte(struct kvm *kvm, int as_id, gfn_t gfn, - u64 old_spte, u64 new_spte, int level) + u64 old_spte, u64 new_spte, int level, + bool shared) { bool was_present = is_shadow_present_pte(old_spte); bool is_present = is_shadow_present_pte(new_spte); @@ -415,18 +452,51 @@ static void __handle_changed_spte(struct kvm *kvm, int as_id, gfn_t gfn, */ if (was_present && !was_leaf && (pfn_changed || !is_present)) handle_removed_tdp_mmu_page(kvm, - spte_to_child_pt(old_spte, level)); + spte_to_child_pt(old_spte, level), shared); } static void handle_changed_spte(struct kvm *kvm, int as_id, gfn_t gfn, - u64 old_spte, u64 new_spte, int level) + u64 old_spte, u64 new_spte, int level, + bool shared) { - __handle_changed_spte(kvm, as_id, gfn, old_spte, new_spte, level); + __handle_changed_spte(kvm, as_id, gfn, old_spte, new_spte, level, + shared); handle_changed_spte_acc_track(old_spte, new_spte, level); handle_changed_spte_dirty_log(kvm, as_id, gfn, old_spte, new_spte, level); } +/* + * tdp_mmu_set_spte_atomic - Set a TDP MMU SPTE atomically and handle the + * associated bookkeeping + * + * @kvm: kvm instance + * @iter: a tdp_iter instance currently on the SPTE that should be set + * @new_spte: The value the SPTE should be set to + * Returns: true if the SPTE was set, false if it was not. If false is returned, + * this function will have no side-effects. + */ +static inline bool tdp_mmu_set_spte_atomic(struct kvm *kvm, + struct tdp_iter *iter, + u64 new_spte) +{ + u64 *root_pt = tdp_iter_root_pt(iter); + struct kvm_mmu_page *root = sptep_to_sp(root_pt); + int as_id = kvm_mmu_page_as_id(root); + + lockdep_assert_held_read(&kvm->mmu_lock); + + if (cmpxchg64(rcu_dereference(iter->sptep), iter->old_spte, + new_spte) != iter->old_spte) + return false; + + handle_changed_spte(kvm, as_id, iter->gfn, iter->old_spte, new_spte, + iter->level, true); + + return true; +} + + /* * __tdp_mmu_set_spte - Set a TDP MMU SPTE and handle the associated bookkeeping * @kvm: kvm instance @@ -456,7 +526,7 @@ static inline void __tdp_mmu_set_spte(struct kvm *kvm, struct tdp_iter *iter, WRITE_ONCE(*rcu_dereference(iter->sptep), new_spte); __handle_changed_spte(kvm, as_id, iter->gfn, iter->old_spte, new_spte, - iter->level); + iter->level, false); if (record_acc_track) handle_changed_spte_acc_track(iter->old_spte, new_spte, iter->level); @@ -630,23 +700,18 @@ static int tdp_mmu_map_handle_target_level(struct kvm_vcpu *vcpu, int write, int ret = 0; int make_spte_ret = 0; - if (unlikely(is_noslot_pfn(pfn))) { + if (unlikely(is_noslot_pfn(pfn))) new_spte = make_mmio_spte(vcpu, iter->gfn, ACC_ALL); - trace_mark_mmio_spte(rcu_dereference(iter->sptep), iter->gfn, - new_spte); - } else { + else make_spte_ret = make_spte(vcpu, ACC_ALL, iter->level, iter->gfn, pfn, iter->old_spte, prefault, true, map_writable, !shadow_accessed_mask, &new_spte); - trace_kvm_mmu_set_spte(iter->level, iter->gfn, - rcu_dereference(iter->sptep)); - } if (new_spte == iter->old_spte) ret = RET_PF_SPURIOUS; - else - tdp_mmu_set_spte(vcpu->kvm, iter, new_spte); + else if (!tdp_mmu_set_spte_atomic(vcpu->kvm, iter, new_spte)) + return RET_PF_RETRY; /* * If the page fault was caused by a write but the page is write @@ -660,8 +725,13 @@ static int tdp_mmu_map_handle_target_level(struct kvm_vcpu *vcpu, int write, } /* If a MMIO SPTE is installed, the MMIO will need to be emulated. */ - if (unlikely(is_mmio_spte(new_spte))) + if (unlikely(is_mmio_spte(new_spte))) { + trace_mark_mmio_spte(rcu_dereference(iter->sptep), iter->gfn, + new_spte); ret = RET_PF_EMULATE; + } else + trace_kvm_mmu_set_spte(iter->level, iter->gfn, + rcu_dereference(iter->sptep)); trace_kvm_mmu_set_spte(iter->level, iter->gfn, rcu_dereference(iter->sptep)); @@ -720,7 +790,8 @@ int kvm_tdp_mmu_map(struct kvm_vcpu *vcpu, gpa_t gpa, u32 error_code, */ if (is_shadow_present_pte(iter.old_spte) && is_large_pte(iter.old_spte)) { - tdp_mmu_set_spte(vcpu->kvm, &iter, 0); + if (!tdp_mmu_set_spte_atomic(vcpu->kvm, &iter, 0)) + break; kvm_flush_remote_tlbs_with_address(vcpu->kvm, iter.gfn, KVM_PAGES_PER_HPAGE(iter.level)); @@ -737,19 +808,24 @@ int kvm_tdp_mmu_map(struct kvm_vcpu *vcpu, gpa_t gpa, u32 error_code, sp = alloc_tdp_mmu_page(vcpu, iter.gfn, iter.level); child_pt = sp->spt; - tdp_mmu_link_page(vcpu->kvm, sp, - huge_page_disallowed && - req_level >= iter.level); - new_spte = make_nonleaf_spte(child_pt, !shadow_accessed_mask); - trace_kvm_mmu_get_page(sp, true); - tdp_mmu_set_spte(vcpu->kvm, &iter, new_spte); + if (tdp_mmu_set_spte_atomic(vcpu->kvm, &iter, + new_spte)) { + tdp_mmu_link_page(vcpu->kvm, sp, true, + huge_page_disallowed && + req_level >= iter.level); + + trace_kvm_mmu_get_page(sp, true); + } else { + tdp_mmu_free_sp(sp); + break; + } } } - if (WARN_ON(iter.level != level)) { + if (iter.level != level) { rcu_read_unlock(); return RET_PF_RETRY; } -- cgit v1.2.3 From 4a2b92a5d3519fc2c1edda4d4aa0e05bff41e8de Mon Sep 17 00:00:00 2001 From: Bert Vermeulen Date: Fri, 22 Jan 2021 21:42:23 +0100 Subject: dt-bindings: interrupt-controller: Add Realtek RTL838x/RTL839x support Document the binding for the Realtek RTL838x/RTL839x interrupt controller. Reviewed-by: Rob Herring Signed-off-by: Bert Vermeulen [maz: Add a commit message, as the author couldn't be bothered...] Signed-off-by: Marc Zyngier Link: https://lore.kernel.org/r/20210122204224.509124-2-bert@biot.com --- .../interrupt-controller/realtek,rtl-intc.yaml | 57 ++++++++++++++++++++++ 1 file changed, 57 insertions(+) create mode 100644 Documentation/devicetree/bindings/interrupt-controller/realtek,rtl-intc.yaml (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/interrupt-controller/realtek,rtl-intc.yaml b/Documentation/devicetree/bindings/interrupt-controller/realtek,rtl-intc.yaml new file mode 100644 index 000000000000..9e76fff20323 --- /dev/null +++ b/Documentation/devicetree/bindings/interrupt-controller/realtek,rtl-intc.yaml @@ -0,0 +1,57 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/interrupt-controller/realtek,rtl-intc.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Realtek RTL SoC interrupt controller devicetree bindings + +maintainers: + - Birger Koblitz + - Bert Vermeulen + - John Crispin + +properties: + compatible: + const: realtek,rtl-intc + + "#interrupt-cells": + const: 1 + + reg: + maxItems: 1 + + interrupts: + maxItems: 1 + + interrupt-controller: true + + "#address-cells": + const: 0 + + interrupt-map: + description: Describes mapping from SoC interrupts to CPU interrupts + +required: + - compatible + - reg + - "#interrupt-cells" + - interrupt-controller + - "#address-cells" + - interrupt-map + +additionalProperties: false + +examples: + - | + intc: interrupt-controller@3000 { + compatible = "realtek,rtl-intc"; + #interrupt-cells = <1>; + interrupt-controller; + reg = <0x3000 0x20>; + #address-cells = <0>; + interrupt-map = + <31 &cpuintc 2>, + <30 &cpuintc 1>, + <29 &cpuintc 5>; + }; -- cgit v1.2.3 From e1f68169a4f89e49f33bf52df29aeb57cb8b1144 Mon Sep 17 00:00:00 2001 From: David Woodhouse Date: Fri, 4 Dec 2020 09:03:56 +0000 Subject: KVM: Add documentation for Xen hypercall and shared_info updates Signed-off-by: David Woodhouse --- Documentation/virt/kvm/api.rst | 171 +++++++++++++++++++++++++++++++++++++++-- 1 file changed, 166 insertions(+), 5 deletions(-) (limited to 'Documentation') diff --git a/Documentation/virt/kvm/api.rst b/Documentation/virt/kvm/api.rst index effcc08733fd..5919e9a94f25 100644 --- a/Documentation/virt/kvm/api.rst +++ b/Documentation/virt/kvm/api.rst @@ -960,6 +960,14 @@ memory. __u8 pad2[30]; }; +If the KVM_XEN_HVM_CONFIG_INTERCEPT_HCALL flag is returned from the +KVM_CAP_XEN_HVM check, it may be set in the flags field of this ioctl. +This requests KVM to generate the contents of the hypercall page +automatically; hypercalls will be intercepted and passed to userspace +through KVM_EXIT_XEN. In this case, all of the blob size and address +fields must be zero. + +No other flags are currently valid in the struct kvm_xen_hvm_config. 4.29 KVM_GET_CLOCK ------------------ @@ -4831,6 +4839,101 @@ into user space. If a vCPU is in running state while this ioctl is invoked, the vCPU may experience inconsistent filtering behavior on MSR accesses. +4.127 KVM_XEN_HVM_SET_ATTR +-------------------------- + +:Capability: KVM_CAP_XEN_HVM / KVM_XEN_HVM_CONFIG_SHARED_INFO +:Architectures: x86 +:Type: vm ioctl +:Parameters: struct kvm_xen_hvm_attr +:Returns: 0 on success, < 0 on error + +:: + + struct kvm_xen_hvm_attr { + __u16 type; + __u16 pad[3]; + union { + __u8 long_mode; + __u8 vector; + struct { + __u64 gfn; + } shared_info; + __u64 pad[4]; + } u; + }; + +type values: + +KVM_XEN_ATTR_TYPE_LONG_MODE + Sets the ABI mode of the VM to 32-bit or 64-bit (long mode). This + determines the layout of the shared info pages exposed to the VM. + +KVM_XEN_ATTR_TYPE_SHARED_INFO + Sets the guest physical frame number at which the Xen "shared info" + page resides. Note that although Xen places vcpu_info for the first + 32 vCPUs in the shared_info page, KVM does not automatically do so + and instead requires that KVM_XEN_VCPU_ATTR_TYPE_VCPU_INFO be used + explicitly even when the vcpu_info for a given vCPU resides at the + "default" location in the shared_info page. This is because KVM is + not aware of the Xen CPU id which is used as the index into the + vcpu_info[] array, so cannot know the correct default location. + +KVM_XEN_ATTR_TYPE_UPCALL_VECTOR + Sets the exception vector used to deliver Xen event channel upcalls. + +4.128 KVM_XEN_HVM_GET_ATTR +-------------------------- + +:Capability: KVM_CAP_XEN_HVM / KVM_XEN_HVM_CONFIG_SHARED_INFO +:Architectures: x86 +:Type: vm ioctl +:Parameters: struct kvm_xen_hvm_attr +:Returns: 0 on success, < 0 on error + +Allows Xen VM attributes to be read. For the structure and types, +see KVM_XEN_HVM_SET_ATTR above. + +4.129 KVM_XEN_VCPU_SET_ATTR +--------------------------- + +:Capability: KVM_CAP_XEN_HVM / KVM_XEN_HVM_CONFIG_SHARED_INFO +:Architectures: x86 +:Type: vcpu ioctl +:Parameters: struct kvm_xen_vcpu_attr +:Returns: 0 on success, < 0 on error + +:: + + struct kvm_xen_vcpu_attr { + __u16 type; + __u16 pad[3]; + union { + __u64 gpa; + __u64 pad[4]; + } u; + }; + +type values: + +KVM_XEN_VCPU_ATTR_TYPE_VCPU_INFO + Sets the guest physical address of the vcpu_info for a given vCPU. + +KVM_XEN_VCPU_ATTR_TYPE_VCPU_TIME_INFO + Sets the guest physical address of an additional pvclock structure + for a given vCPU. This is typically used for guest vsyscall support. + +4.130 KVM_XEN_VCPU_GET_ATTR +-------------------------- + +:Capability: KVM_CAP_XEN_HVM / KVM_XEN_HVM_CONFIG_SHARED_INFO +:Architectures: x86 +:Type: vcpu ioctl +:Parameters: struct kvm_xen_vcpu_attr +:Returns: 0 on success, < 0 on error + +Allows Xen vCPU attributes to be read. For the structure and types, +see KVM_XEN_VCPU_SET_ATTR above. 5. The kvm_run structure ======================== @@ -4998,13 +5101,18 @@ to the byte array. .. note:: - For KVM_EXIT_IO, KVM_EXIT_MMIO, KVM_EXIT_OSI, KVM_EXIT_PAPR, + For KVM_EXIT_IO, KVM_EXIT_MMIO, KVM_EXIT_OSI, KVM_EXIT_PAPR, KVM_EXIT_XEN, KVM_EXIT_EPR, KVM_EXIT_X86_RDMSR and KVM_EXIT_X86_WRMSR the corresponding operations are complete (and guest state is consistent) only after userspace has re-entered the kernel with KVM_RUN. The kernel side will first finish - incomplete operations and then check for pending signals. Userspace - can re-enter the guest with an unmasked signal pending to complete - pending operations. + incomplete operations and then check for pending signals. + + The pending state of the operation is not preserved in state which is + visible to userspace, thus userspace should ensure that the operation is + completed before performing a live migration. Userspace can re-enter the + guest with an unmasked signal pending or with the immediate_exit field set + to complete pending operations without allowing any further instructions + to be executed. :: @@ -5329,6 +5437,34 @@ wants to write. Once finished processing the event, user space must continue vCPU execution. If the MSR write was unsuccessful, user space also sets the "error" field to "1". +:: + + + struct kvm_xen_exit { + #define KVM_EXIT_XEN_HCALL 1 + __u32 type; + union { + struct { + __u32 longmode; + __u32 cpl; + __u64 input; + __u64 result; + __u64 params[6]; + } hcall; + } u; + }; + /* KVM_EXIT_XEN */ + struct kvm_hyperv_exit xen; + +Indicates that the VCPU exits into userspace to process some tasks +related to Xen emulation. + +Valid values for 'type' are: + + - KVM_EXIT_XEN_HCALL -- synchronously notify user-space about Xen hypercall. + Userspace is expected to place the hypercall result into the appropriate + field before invoking KVM_RUN again. + :: /* Fix the size of the union. */ @@ -6454,7 +6590,6 @@ guest according to the bits in the KVM_CPUID_FEATURES CPUID leaf (0x40000001). Otherwise, a guest may use the paravirtual features regardless of what has actually been exposed through the CPUID leaf. - 8.29 KVM_CAP_DIRTY_LOG_RING --------------------------- @@ -6541,3 +6676,29 @@ KVM_GET_DIRTY_LOG and KVM_CLEAR_DIRTY_LOG. After enabling KVM_CAP_DIRTY_LOG_RING with an acceptable dirty ring size, the virtual machine will switch to ring-buffer dirty page tracking and further KVM_GET_DIRTY_LOG or KVM_CLEAR_DIRTY_LOG ioctls will fail. + +8.30 KVM_CAP_XEN_HVM +-------------------- + +:Architectures: x86 + +This capability indicates the features that Xen supports for hosting Xen +PVHVM guests. Valid flags are:: + + #define KVM_XEN_HVM_CONFIG_HYPERCALL_MSR (1 << 0) + #define KVM_XEN_HVM_CONFIG_INTERCEPT_HCALL (1 << 1) + #define KVM_XEN_HVM_CONFIG_SHARED_INFO (1 << 2) + +The KVM_XEN_HVM_CONFIG_HYPERCALL_MSR flag indicates that the KVM_XEN_HVM_CONFIG +ioctl is available, for the guest to set its hypercall page. + +If KVM_XEN_HVM_CONFIG_INTERCEPT_HCALL is also set, the same flag may also be +provided in the flags to KVM_XEN_HVM_CONFIG, without providing hypercall page +contents, to request that KVM generate hypercall page content automatically +and also enable interception of guest hypercalls with KVM_EXIT_XEN. + +The KVM_XEN_HVM_CONFIG_SHARED_INFO flag indicates the availability of the +KVM_XEN_HVM_SET_ATTR, KVM_XEN_HVM_GET_ATTR, KVM_XEN_VCPU_SET_ATTR and +KVM_XEN_VCPU_GET_ATTR ioctls, as well as the delivery of exception vectors +for event channel upcalls when the evtchn_upcall_pending field of a vcpu's +vcpu_info is set. -- cgit v1.2.3 From b59fa7a060b1194fc31413507b89e30fa29aea06 Mon Sep 17 00:00:00 2001 From: Yongqiang Niu Date: Thu, 7 Jan 2021 11:11:11 +0800 Subject: dt-bindings: mediatek: add rdma-fifo-size description for mt8183 display rdma fifo size may be different even in same SOC, add this property to the corresponding rdma Signed-off-by: Yongqiang Niu Reviewed-by: Rob Herring Signed-off-by: Chun-Kuang Hu --- .../devicetree/bindings/display/mediatek/mediatek,disp.txt | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,disp.txt b/Documentation/devicetree/bindings/display/mediatek/mediatek,disp.txt index c40f900de59d..d6f03ad4b475 100644 --- a/Documentation/devicetree/bindings/display/mediatek/mediatek,disp.txt +++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,disp.txt @@ -66,6 +66,14 @@ Required properties (DMA function blocks): argument, see Documentation/devicetree/bindings/iommu/mediatek,iommu.txt for details. +Optional properties (RDMA function blocks): +- mediatek,rdma-fifo-size: rdma fifo size may be different even in same SOC, add this + property to the corresponding rdma + the value is the Max value which defined in hardware data sheet. + mediatek,rdma-fifo-size of mt8173-rdma0 is 8K + mediatek,rdma-fifo-size of mt8183-rdma0 is 5K + mediatek,rdma-fifo-size of mt8183-rdma1 is 2K + Examples: mmsys: clock-controller@14000000 { @@ -103,6 +111,7 @@ rdma0: rdma@1400e000 { clocks = <&mmsys CLK_MM_DISP_RDMA0>; iommus = <&iommu M4U_PORT_DISP_RDMA0>; mediatek,larb = <&larb0>; + mediatek,rdma-fifosize = <8192>; }; rdma1: rdma@1400f000 { -- cgit v1.2.3 From fb8b6c307c7bcfa099dedfae109b3039509f5ec8 Mon Sep 17 00:00:00 2001 From: Yongqiang Niu Date: Mon, 11 Jan 2021 15:43:37 +0800 Subject: dt-bindings: mediatek: add description for postmask add description for postmask postmask is used control round corner for display frame Signed-off-by: Yongqiang Niu Acked-by: Rob Herring Signed-off-by: Chun-Kuang Hu --- Documentation/devicetree/bindings/display/mediatek/mediatek,disp.txt | 1 + 1 file changed, 1 insertion(+) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,disp.txt b/Documentation/devicetree/bindings/display/mediatek/mediatek,disp.txt index d6f03ad4b475..b47e1a0597c2 100644 --- a/Documentation/devicetree/bindings/display/mediatek/mediatek,disp.txt +++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,disp.txt @@ -37,6 +37,7 @@ Required properties (all function blocks): "mediatek,-disp-aal" - adaptive ambient light controller "mediatek,-disp-gamma" - gamma correction "mediatek,-disp-merge" - merge streams from two RDMA sources + "mediatek,-disp-postmask" - control round corner for display frame "mediatek,-disp-split" - split stream to two encoders "mediatek,-disp-ufoe" - data compression engine "mediatek,-dsi" - DSI controller, see mediatek,dsi.txt -- cgit v1.2.3 From 91f93c3839929e44dd70aa05c4e199d89c36188f Mon Sep 17 00:00:00 2001 From: Rob Herring Date: Thu, 28 Jan 2021 18:28:43 -0600 Subject: dt-bindings: Fix undocumented compatible strings in examples Running 'dt-validate -m' will flag any compatible strings missing a schema. Fix all the errors found in DT binding examples. Most of these are just typos. Cc: Stephen Boyd Cc: Chen-Yu Tsai Cc: Herbert Xu Cc: "David S. Miller" Cc: Bartosz Golaszewski Cc: Avi Fishman Cc: Tomer Maimon Cc: Tali Perry Cc: Joerg Roedel Cc: Will Deacon Cc: Joel Stanley Cc: Wim Van Sebroeck Cc: Yoshihiro Shimoda Cc: Vincent Cheng Cc: linux-clk@vger.kernel.org Cc: linux-crypto@vger.kernel.org Cc: linux-gpio@vger.kernel.org Cc: linux-i2c@vger.kernel.org Cc: iommu@lists.linux-foundation.org Cc: linux-watchdog@vger.kernel.org Reviewed-by: Guenter Roeck Reviewed-by: Andrew Jeffery Acked-by: Maxime Ripard Reviewed-by: Linus Walleij Reviewed-by: Daniel Palmer Reviewed-by: Yoshihiro Shimoda Signed-off-by: Rob Herring Link: https://lore.kernel.org/r/20210202205544.24812-1-robh@kernel.org --- .../clock/allwinner,sun9i-a80-usb-clks.yaml | 59 ++++++++++++++++++++++ .../clock/allwinner,sun9i-a80-usb-clocks.yaml | 59 ---------------------- .../devicetree/bindings/clock/arm,syscon-icst.yaml | 4 +- .../devicetree/bindings/crypto/ti,sa2ul.yaml | 2 +- .../bindings/gpio/mstar,msc313-gpio.yaml | 2 +- .../bindings/i2c/nuvoton,npcm7xx-i2c.yaml | 2 +- .../bindings/iommu/renesas,ipmmu-vmsa.yaml | 2 +- .../bindings/pinctrl/aspeed,ast2400-pinctrl.yaml | 2 +- .../bindings/pinctrl/aspeed,ast2500-pinctrl.yaml | 2 +- .../bindings/pinctrl/aspeed,ast2600-pinctrl.yaml | 2 +- .../devicetree/bindings/ptp/ptp-idtcm.yaml | 4 +- .../devicetree/bindings/watchdog/ti,rti-wdt.yaml | 4 +- 12 files changed, 71 insertions(+), 73 deletions(-) create mode 100644 Documentation/devicetree/bindings/clock/allwinner,sun9i-a80-usb-clks.yaml delete mode 100644 Documentation/devicetree/bindings/clock/allwinner,sun9i-a80-usb-clocks.yaml (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/clock/allwinner,sun9i-a80-usb-clks.yaml b/Documentation/devicetree/bindings/clock/allwinner,sun9i-a80-usb-clks.yaml new file mode 100644 index 000000000000..6532fb6821bc --- /dev/null +++ b/Documentation/devicetree/bindings/clock/allwinner,sun9i-a80-usb-clks.yaml @@ -0,0 +1,59 @@ +# SPDX-License-Identifier: GPL-2.0+ +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/clock/allwinner,sun9i-a80-usb-clks.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Allwinner A80 USB Clock Controller Device Tree Bindings + +maintainers: + - Chen-Yu Tsai + - Maxime Ripard + +properties: + "#clock-cells": + const: 1 + + "#reset-cells": + const: 1 + + compatible: + const: allwinner,sun9i-a80-usb-clks + + reg: + maxItems: 1 + + clocks: + items: + - description: Bus Clock + - description: High Frequency Oscillator + + clock-names: + items: + - const: bus + - const: hosc + +required: + - "#clock-cells" + - "#reset-cells" + - compatible + - reg + - clocks + - clock-names + +additionalProperties: false + +examples: + - | + #include + + usb_clocks: clock@a08000 { + compatible = "allwinner,sun9i-a80-usb-clks"; + reg = <0x00a08000 0x8>; + clocks = <&ccu CLK_BUS_USB>, <&osc24M>; + clock-names = "bus", "hosc"; + #clock-cells = <1>; + #reset-cells = <1>; + }; + +... diff --git a/Documentation/devicetree/bindings/clock/allwinner,sun9i-a80-usb-clocks.yaml b/Documentation/devicetree/bindings/clock/allwinner,sun9i-a80-usb-clocks.yaml deleted file mode 100644 index fa0ee03a527f..000000000000 --- a/Documentation/devicetree/bindings/clock/allwinner,sun9i-a80-usb-clocks.yaml +++ /dev/null @@ -1,59 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0+ -%YAML 1.2 ---- -$id: http://devicetree.org/schemas/clock/allwinner,sun9i-a80-usb-clocks.yaml# -$schema: http://devicetree.org/meta-schemas/core.yaml# - -title: Allwinner A80 USB Clock Controller Device Tree Bindings - -maintainers: - - Chen-Yu Tsai - - Maxime Ripard - -properties: - "#clock-cells": - const: 1 - - "#reset-cells": - const: 1 - - compatible: - const: allwinner,sun9i-a80-usb-clocks - - reg: - maxItems: 1 - - clocks: - items: - - description: Bus Clock - - description: High Frequency Oscillator - - clock-names: - items: - - const: bus - - const: hosc - -required: - - "#clock-cells" - - "#reset-cells" - - compatible - - reg - - clocks - - clock-names - -additionalProperties: false - -examples: - - | - #include - - usb_clocks: clock@a08000 { - compatible = "allwinner,sun9i-a80-usb-clks"; - reg = <0x00a08000 0x8>; - clocks = <&ccu CLK_BUS_USB>, <&osc24M>; - clock-names = "bus", "hosc"; - #clock-cells = <1>; - #reset-cells = <1>; - }; - -... diff --git a/Documentation/devicetree/bindings/clock/arm,syscon-icst.yaml b/Documentation/devicetree/bindings/clock/arm,syscon-icst.yaml index eb241587efd1..118c5543e037 100644 --- a/Documentation/devicetree/bindings/clock/arm,syscon-icst.yaml +++ b/Documentation/devicetree/bindings/clock/arm,syscon-icst.yaml @@ -66,8 +66,8 @@ properties: - arm,syscon-icst525-integratorcp-cm-mem - arm,integrator-cm-auxosc - arm,versatile-cm-auxosc - - arm,impd-vco1 - - arm,impd-vco2 + - arm,impd1-vco1 + - arm,impd1-vco2 clocks: description: Parent clock for the ICST VCO diff --git a/Documentation/devicetree/bindings/crypto/ti,sa2ul.yaml b/Documentation/devicetree/bindings/crypto/ti,sa2ul.yaml index 1465c9ebaf93..1d48ac712b23 100644 --- a/Documentation/devicetree/bindings/crypto/ti,sa2ul.yaml +++ b/Documentation/devicetree/bindings/crypto/ti,sa2ul.yaml @@ -66,7 +66,7 @@ examples: #include main_crypto: crypto@4e00000 { - compatible = "ti,j721-sa2ul"; + compatible = "ti,j721e-sa2ul"; reg = <0x4e00000 0x1200>; power-domains = <&k3_pds 264 TI_SCI_PD_EXCLUSIVE>; dmas = <&main_udmap 0xc000>, <&main_udmap 0x4000>, diff --git a/Documentation/devicetree/bindings/gpio/mstar,msc313-gpio.yaml b/Documentation/devicetree/bindings/gpio/mstar,msc313-gpio.yaml index 1f2ef408bb43..fe1e1c63ffe3 100644 --- a/Documentation/devicetree/bindings/gpio/mstar,msc313-gpio.yaml +++ b/Documentation/devicetree/bindings/gpio/mstar,msc313-gpio.yaml @@ -46,7 +46,7 @@ examples: #include gpio: gpio@207800 { - compatible = "mstar,msc313e-gpio"; + compatible = "mstar,msc313-gpio"; #gpio-cells = <2>; reg = <0x207800 0x200>; gpio-controller; diff --git a/Documentation/devicetree/bindings/i2c/nuvoton,npcm7xx-i2c.yaml b/Documentation/devicetree/bindings/i2c/nuvoton,npcm7xx-i2c.yaml index e3ef2d36f372..128444942aec 100644 --- a/Documentation/devicetree/bindings/i2c/nuvoton,npcm7xx-i2c.yaml +++ b/Documentation/devicetree/bindings/i2c/nuvoton,npcm7xx-i2c.yaml @@ -17,7 +17,7 @@ maintainers: properties: compatible: - const: nuvoton,npcm7xx-i2c + const: nuvoton,npcm750-i2c reg: maxItems: 1 diff --git a/Documentation/devicetree/bindings/iommu/renesas,ipmmu-vmsa.yaml b/Documentation/devicetree/bindings/iommu/renesas,ipmmu-vmsa.yaml index cde1afa8dfd6..349633108bbd 100644 --- a/Documentation/devicetree/bindings/iommu/renesas,ipmmu-vmsa.yaml +++ b/Documentation/devicetree/bindings/iommu/renesas,ipmmu-vmsa.yaml @@ -93,7 +93,7 @@ examples: #include ipmmu_mx: iommu@fe951000 { - compatible = "renasas,ipmmu-r8a7791", "renasas,ipmmu-vmsa"; + compatible = "renesas,ipmmu-r8a7791", "renesas,ipmmu-vmsa"; reg = <0xfe951000 0x1000>; interrupts = , ; diff --git a/Documentation/devicetree/bindings/pinctrl/aspeed,ast2400-pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/aspeed,ast2400-pinctrl.yaml index 91be5720d094..100bb6dea3ec 100644 --- a/Documentation/devicetree/bindings/pinctrl/aspeed,ast2400-pinctrl.yaml +++ b/Documentation/devicetree/bindings/pinctrl/aspeed,ast2400-pinctrl.yaml @@ -62,7 +62,7 @@ examples: reg = <0x1e6e2000 0x1a8>; pinctrl: pinctrl { - compatible = "aspeed,g4-pinctrl"; + compatible = "aspeed,ast2400-pinctrl"; pinctrl_i2c3_default: i2c3_default { function = "I2C3"; diff --git a/Documentation/devicetree/bindings/pinctrl/aspeed,ast2500-pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/aspeed,ast2500-pinctrl.yaml index 40e9e8d4be5a..904697bc9415 100644 --- a/Documentation/devicetree/bindings/pinctrl/aspeed,ast2500-pinctrl.yaml +++ b/Documentation/devicetree/bindings/pinctrl/aspeed,ast2500-pinctrl.yaml @@ -81,7 +81,7 @@ examples: reg = <0x1e6e2000 0x1a8>; pinctrl: pinctrl { - compatible = "aspeed,g5-pinctrl"; + compatible = "aspeed,ast2500-pinctrl"; aspeed,external-nodes = <&gfx>, <&lhc>; pinctrl_i2c3_default: i2c3_default { diff --git a/Documentation/devicetree/bindings/pinctrl/aspeed,ast2600-pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/aspeed,ast2600-pinctrl.yaml index c78ab7e2eee7..ad91c0bc54da 100644 --- a/Documentation/devicetree/bindings/pinctrl/aspeed,ast2600-pinctrl.yaml +++ b/Documentation/devicetree/bindings/pinctrl/aspeed,ast2600-pinctrl.yaml @@ -95,7 +95,7 @@ examples: reg = <0x1e6e2000 0xf6c>; pinctrl: pinctrl { - compatible = "aspeed,g6-pinctrl"; + compatible = "aspeed,ast2600-pinctrl"; pinctrl_pwm10g1_default: pwm10g1_default { function = "PWM10"; diff --git a/Documentation/devicetree/bindings/ptp/ptp-idtcm.yaml b/Documentation/devicetree/bindings/ptp/ptp-idtcm.yaml index 239b49fad805..658cec67743e 100644 --- a/Documentation/devicetree/bindings/ptp/ptp-idtcm.yaml +++ b/Documentation/devicetree/bindings/ptp/ptp-idtcm.yaml @@ -59,9 +59,7 @@ additionalProperties: false examples: - | - i2c@1 { - compatible = "abc,acme-1234"; - reg = <0x01 0x400>; + i2c { #address-cells = <1>; #size-cells = <0>; phc@5b { diff --git a/Documentation/devicetree/bindings/watchdog/ti,rti-wdt.yaml b/Documentation/devicetree/bindings/watchdog/ti,rti-wdt.yaml index c1348db59374..054584d7543a 100644 --- a/Documentation/devicetree/bindings/watchdog/ti,rti-wdt.yaml +++ b/Documentation/devicetree/bindings/watchdog/ti,rti-wdt.yaml @@ -57,8 +57,8 @@ examples: */ #include - watchdog0: rti@2200000 { - compatible = "ti,rti-wdt"; + watchdog@2200000 { + compatible = "ti,j7-rti-wdt"; reg = <0x2200000 0x100>; clocks = <&k3_clks 252 1>; power-domains = <&k3_pds 252 TI_SCI_PD_EXCLUSIVE>; -- cgit v1.2.3 From 49ec0686b3e8f3afde4af9f906c672069a46c55e Mon Sep 17 00:00:00 2001 From: Rob Herring Date: Tue, 2 Feb 2021 13:49:41 -0600 Subject: dt-bindings: iommu: renesas,ipmmu-vmsa: Make 'power-domains' conditionally required Fixing the compatible string typos results in an error in the example: Documentation/devicetree/bindings/iommu/renesas,ipmmu-vmsa.example.dt.yaml: iommu@fe951000: 'power-domains' is a required property Based on the dts files, a 'power-domains' property only exists on Gen 3 which can be conditioned on !renesas,ipmmu-vmsa. Cc: Joerg Roedel Cc: Will Deacon Cc: iommu@lists.linux-foundation.org Reviewed-by: Yoshihiro Shimoda Signed-off-by: Rob Herring Link: https://lore.kernel.org/r/20210202205544.24812-2-robh@kernel.org --- .../devicetree/bindings/iommu/renesas,ipmmu-vmsa.yaml | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/iommu/renesas,ipmmu-vmsa.yaml b/Documentation/devicetree/bindings/iommu/renesas,ipmmu-vmsa.yaml index 349633108bbd..dda44976acc1 100644 --- a/Documentation/devicetree/bindings/iommu/renesas,ipmmu-vmsa.yaml +++ b/Documentation/devicetree/bindings/iommu/renesas,ipmmu-vmsa.yaml @@ -76,7 +76,6 @@ required: - compatible - reg - '#iommu-cells' - - power-domains oneOf: - required: @@ -86,6 +85,17 @@ oneOf: additionalProperties: false +allOf: + - if: + properties: + compatible: + not: + contains: + const: renesas,ipmmu-vmsa + then: + required: + - power-domains + examples: - | #include -- cgit v1.2.3 From 9183908e70e913d2db052588172968da55d82af5 Mon Sep 17 00:00:00 2001 From: Rob Herring Date: Fri, 29 Jan 2021 16:03:17 -0600 Subject: dt-bindings: Fix errors in 'if' schemas Properties in if/then schemas weren't getting checked by the meta-schemas. Enabling meta-schema checks finds several errors. The use of an 'items' schema (as opposed to the list form) is wrong in some cases as it applies to all entries. 'contains' is the correct schema to use in the case of multiple entries. Cc: Herbert Xu Cc: "David S. Miller" Cc: Chen-Yu Tsai Cc: Eric Anholt Cc: Florian Fainelli Cc: Ray Jui Cc: Scott Branden Cc: Pavel Machek Cc: Ulf Hansson Cc: Kishon Vijay Abraham I Cc: Geert Uytterhoeven Cc: Linus Walleij Cc: Daniel Lezcano Cc: linux-crypto@vger.kernel.org Cc: dri-devel@lists.freedesktop.org Cc: linux-leds@vger.kernel.org Cc: linux-mmc@vger.kernel.org Cc: linux-gpio@vger.kernel.org Acked-by: Maxime Ripard Acked-By: Vinod Koul Reviewed-by: Nicolas Saenz Julienne Acked-by: Geert Uytterhoeven Signed-off-by: Rob Herring Link: https://lore.kernel.org/r/20210202205544.24812-3-robh@kernel.org --- Documentation/devicetree/bindings/crypto/allwinner,sun8i-ce.yaml | 3 +-- Documentation/devicetree/bindings/display/brcm,bcm2835-hvs.yaml | 2 +- Documentation/devicetree/bindings/leds/ti,tca6507.yaml | 1 + Documentation/devicetree/bindings/mmc/renesas,sdhi.yaml | 2 +- Documentation/devicetree/bindings/phy/brcm,sata-phy.yaml | 3 +-- Documentation/devicetree/bindings/phy/renesas,usb2-phy.yaml | 5 ++--- Documentation/devicetree/bindings/pinctrl/renesas,pfc.yaml | 9 ++++----- .../devicetree/bindings/timer/allwinner,sun5i-a13-hstimer.yaml | 3 +-- 8 files changed, 12 insertions(+), 16 deletions(-) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/crypto/allwinner,sun8i-ce.yaml b/Documentation/devicetree/bindings/crypto/allwinner,sun8i-ce.yaml index 7a60d84289cc..6ab07eba7778 100644 --- a/Documentation/devicetree/bindings/crypto/allwinner,sun8i-ce.yaml +++ b/Documentation/devicetree/bindings/crypto/allwinner,sun8i-ce.yaml @@ -46,8 +46,7 @@ properties: if: properties: compatible: - items: - const: allwinner,sun50i-h6-crypto + const: allwinner,sun50i-h6-crypto then: properties: clocks: diff --git a/Documentation/devicetree/bindings/display/brcm,bcm2835-hvs.yaml b/Documentation/devicetree/bindings/display/brcm,bcm2835-hvs.yaml index e826ab0adb75..2e8566f47e63 100644 --- a/Documentation/devicetree/bindings/display/brcm,bcm2835-hvs.yaml +++ b/Documentation/devicetree/bindings/display/brcm,bcm2835-hvs.yaml @@ -36,7 +36,7 @@ if: properties: compatible: contains: - const: brcm,bcm2711-hvs" + const: brcm,bcm2711-hvs then: required: diff --git a/Documentation/devicetree/bindings/leds/ti,tca6507.yaml b/Documentation/devicetree/bindings/leds/ti,tca6507.yaml index 94c307c98762..32c600387895 100644 --- a/Documentation/devicetree/bindings/leds/ti,tca6507.yaml +++ b/Documentation/devicetree/bindings/leds/ti,tca6507.yaml @@ -69,6 +69,7 @@ patternProperties: if: patternProperties: "^gpio@[0-6]$": + type: object properties: compatible: contains: diff --git a/Documentation/devicetree/bindings/mmc/renesas,sdhi.yaml b/Documentation/devicetree/bindings/mmc/renesas,sdhi.yaml index 6bbf29b5c239..6c13703b31db 100644 --- a/Documentation/devicetree/bindings/mmc/renesas,sdhi.yaml +++ b/Documentation/devicetree/bindings/mmc/renesas,sdhi.yaml @@ -123,7 +123,7 @@ required: if: properties: compatible: - items: + contains: enum: - renesas,sdhi-r7s72100 - renesas,sdhi-r7s9210 diff --git a/Documentation/devicetree/bindings/phy/brcm,sata-phy.yaml b/Documentation/devicetree/bindings/phy/brcm,sata-phy.yaml index 58c3ef8004ad..04edda504ab6 100644 --- a/Documentation/devicetree/bindings/phy/brcm,sata-phy.yaml +++ b/Documentation/devicetree/bindings/phy/brcm,sata-phy.yaml @@ -99,8 +99,7 @@ patternProperties: if: properties: compatible: - items: - const: brcm,iproc-ns2-sata-phy + const: brcm,iproc-ns2-sata-phy then: properties: reg: diff --git a/Documentation/devicetree/bindings/phy/renesas,usb2-phy.yaml b/Documentation/devicetree/bindings/phy/renesas,usb2-phy.yaml index 829e8c7e467a..0f358d5b84ef 100644 --- a/Documentation/devicetree/bindings/phy/renesas,usb2-phy.yaml +++ b/Documentation/devicetree/bindings/phy/renesas,usb2-phy.yaml @@ -81,9 +81,8 @@ properties: if: properties: compatible: - items: - enum: - - renesas,usb2-phy-r7s9210 + contains: + const: renesas,usb2-phy-r7s9210 then: required: - clock-names diff --git a/Documentation/devicetree/bindings/pinctrl/renesas,pfc.yaml b/Documentation/devicetree/bindings/pinctrl/renesas,pfc.yaml index 5b5b1b9d2ec7..5d3947902f2d 100644 --- a/Documentation/devicetree/bindings/pinctrl/renesas,pfc.yaml +++ b/Documentation/devicetree/bindings/pinctrl/renesas,pfc.yaml @@ -76,11 +76,10 @@ required: if: properties: compatible: - items: - enum: - - renesas,pfc-r8a73a4 - - renesas,pfc-r8a7740 - - renesas,pfc-sh73a0 + enum: + - renesas,pfc-r8a73a4 + - renesas,pfc-r8a7740 + - renesas,pfc-sh73a0 then: required: - interrupts-extended diff --git a/Documentation/devicetree/bindings/timer/allwinner,sun5i-a13-hstimer.yaml b/Documentation/devicetree/bindings/timer/allwinner,sun5i-a13-hstimer.yaml index 40fc4bcb3145..b6a6d03a08b2 100644 --- a/Documentation/devicetree/bindings/timer/allwinner,sun5i-a13-hstimer.yaml +++ b/Documentation/devicetree/bindings/timer/allwinner,sun5i-a13-hstimer.yaml @@ -46,8 +46,7 @@ required: if: properties: compatible: - items: - const: allwinner,sun5i-a13-hstimer + const: allwinner,sun5i-a13-hstimer then: properties: -- cgit v1.2.3 From 4211bfce1eb9962f2ae1972837c032ad6d48f292 Mon Sep 17 00:00:00 2001 From: Suzuki K Poulose Date: Mon, 1 Feb 2021 11:13:42 -0700 Subject: coresight: etm4x: Expose trcdevarch via sysfs Expose the TRCDEVARCH register via the sysfs for component detection. Given that the TRCIDR1 may not completely identify the ETM component and instead need to use TRCDEVARCH, expose this via sysfs for tools to use it for identification. Link: https://lore.kernel.org/r/20210110224850.1880240-21-suzuki.poulose@arm.com Cc: Mike Leach Signed-off-by: Suzuki K Poulose Signed-off-by: Mathieu Poirier Link: https://lore.kernel.org/r/20210201181351.1475223-23-mathieu.poirier@linaro.org Signed-off-by: Greg Kroah-Hartman --- Documentation/ABI/testing/sysfs-bus-coresight-devices-etm4x | 8 ++++++++ drivers/hwtracing/coresight/coresight-etm4x-sysfs.c | 1 + 2 files changed, 9 insertions(+) (limited to 'Documentation') diff --git a/Documentation/ABI/testing/sysfs-bus-coresight-devices-etm4x b/Documentation/ABI/testing/sysfs-bus-coresight-devices-etm4x index 881f0cd99ce4..8e53a32f8150 100644 --- a/Documentation/ABI/testing/sysfs-bus-coresight-devices-etm4x +++ b/Documentation/ABI/testing/sysfs-bus-coresight-devices-etm4x @@ -371,6 +371,14 @@ Contact: Mathieu Poirier Description: (Read) Print the content of the Device ID Register (0xFC8). The value is taken directly from the HW. +What: /sys/bus/coresight/devices/etm/mgmt/trcdevarch +Date: January 2021 +KernelVersion: 5.12 +Contact: Mathieu Poirier +Description: (Read) Print the content of the Device Architecture Register + (offset 0xFBC). The value is taken directly read + from the HW. + What: /sys/bus/coresight/devices/etm/mgmt/trcdevtype Date: April 2015 KernelVersion: 4.01 diff --git a/drivers/hwtracing/coresight/coresight-etm4x-sysfs.c b/drivers/hwtracing/coresight/coresight-etm4x-sysfs.c index 45aeeac2f50e..b646d53a3133 100644 --- a/drivers/hwtracing/coresight/coresight-etm4x-sysfs.c +++ b/drivers/hwtracing/coresight/coresight-etm4x-sysfs.c @@ -2442,6 +2442,7 @@ static struct attribute *coresight_etmv4_mgmt_attrs[] = { coresight_etm4x_reg(trcoslsr, TRCOSLSR), coresight_etm4x_reg(trcconfig, TRCCONFIGR), coresight_etm4x_reg(trctraceid, TRCTRACEIDR), + coresight_etm4x_reg(trcdevarch, TRCDEVARCH), NULL, }; -- cgit v1.2.3 From 61c68c68b826182d93f5e4fe77eb92676a28d513 Mon Sep 17 00:00:00 2001 From: Suzuki K Poulose Date: Mon, 1 Feb 2021 11:13:48 -0700 Subject: dts: bindings: coresight: ETM system register access only units Document the bindings for ETMs with system register accesses. Link: https://lore.kernel.org/r/20210110224850.1880240-27-suzuki.poulose@arm.com Cc: devicetree@vger.kernel.org Cc: Mathieu Poirier Cc: Mike Leach Acked-by: Rob Herring Signed-off-by: Suzuki K Poulose Signed-off-by: Mathieu Poirier Link: https://lore.kernel.org/r/20210201181351.1475223-29-mathieu.poirier@linaro.org Signed-off-by: Greg Kroah-Hartman --- Documentation/devicetree/bindings/arm/coresight.txt | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/arm/coresight.txt b/Documentation/devicetree/bindings/arm/coresight.txt index d711676b4a51..7f9c1ca87487 100644 --- a/Documentation/devicetree/bindings/arm/coresight.txt +++ b/Documentation/devicetree/bindings/arm/coresight.txt @@ -34,9 +34,12 @@ its hardware characteristcs. Program Flow Trace Macrocell: "arm,coresight-etm3x", "arm,primecell"; - - Embedded Trace Macrocell (version 4.x): + - Embedded Trace Macrocell (version 4.x), with memory mapped access. "arm,coresight-etm4x", "arm,primecell"; + - Embedded Trace Macrocell (version 4.x), with system register access only. + "arm,coresight-etm4x-sysreg"; + - Coresight programmable Replicator : "arm,coresight-dynamic-replicator", "arm,primecell"; -- cgit v1.2.3 From f90714e56cb6c5d1e57fb4385b107932f76ef94f Mon Sep 17 00:00:00 2001 From: Nicolas Saenz Julienne Date: Fri, 29 Jan 2021 17:14:28 +0000 Subject: dt-bindings: nvmem: Add bindings for rmem driver Firmware/co-processors might use reserved memory areas in order to pass data stemming from an nvmem device otherwise non accessible to Linux. For example an EEPROM memory only physically accessible to firmware, or data only accessible early at boot time. Introduce the dt-bindings to nvmem's rmem. Reviewed-by: Rob Herring Signed-off-by: Nicolas Saenz Julienne Signed-off-by: Srinivas Kandagatla Link: https://lore.kernel.org/r/20210129171430.11328-4-srinivas.kandagatla@linaro.org Signed-off-by: Greg Kroah-Hartman --- Documentation/devicetree/bindings/nvmem/rmem.yaml | 49 +++++++++++++++++++++++ 1 file changed, 49 insertions(+) create mode 100644 Documentation/devicetree/bindings/nvmem/rmem.yaml (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/nvmem/rmem.yaml b/Documentation/devicetree/bindings/nvmem/rmem.yaml new file mode 100644 index 000000000000..1d85a0a30846 --- /dev/null +++ b/Documentation/devicetree/bindings/nvmem/rmem.yaml @@ -0,0 +1,49 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/nvmem/rmem.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Reserved Memory Based nvmem Device + +maintainers: + - Nicolas Saenz Julienne + +allOf: + - $ref: "nvmem.yaml#" + +properties: + compatible: + items: + - enum: + - raspberrypi,bootloader-config + - const: nvmem-rmem + + no-map: + $ref: /schemas/types.yaml#/definitions/flag + description: + Avoid creating a virtual mapping of the region as part of the OS' + standard mapping of system memory. + +required: + - compatible + - no-map + +unevaluatedProperties: false + +examples: + - | + reserved-memory { + #address-cells = <1>; + #size-cells = <1>; + + blconfig: nvram@10000000 { + compatible = "raspberrypi,bootloader-config", "nvmem-rmem"; + #address-cells = <1>; + #size-cells = <1>; + reg = <0x10000000 0x1000>; + no-map; + }; + }; + +... -- cgit v1.2.3 From 49f259eff82e688d83a9dd3be392fcfcc4f7cde5 Mon Sep 17 00:00:00 2001 From: Samuel Thibault Date: Thu, 28 Jan 2021 19:01:15 +0100 Subject: speakup ABI: Advertise synth parameters for all synths The parameters were advertised for the "soft" synth, but they are available for all synths. Signed-off-by: Samuel Thibault Link: https://lore.kernel.org/r/20210128180116.1848120-2-samuel.thibault@ens-lyon.org Signed-off-by: Greg Kroah-Hartman --- Documentation/ABI/stable/sysfs-driver-speakup | 30 +++++++++++++-------------- 1 file changed, 15 insertions(+), 15 deletions(-) (limited to 'Documentation') diff --git a/Documentation/ABI/stable/sysfs-driver-speakup b/Documentation/ABI/stable/sysfs-driver-speakup index 792f58ba327d..47f5c8a9843a 100644 --- a/Documentation/ABI/stable/sysfs-driver-speakup +++ b/Documentation/ABI/stable/sysfs-driver-speakup @@ -273,7 +273,7 @@ Description: In `/sys/accessibility/speakup` is a directory corresponding to Below is a description of values and parameters for soft synthesizer, which is currently the most commonly used. -What: /sys/accessibility/speakup/soft/caps_start +What: /sys/accessibility/speakup//caps_start KernelVersion: 2.6 Contact: speakup@linux-speakup.org Description: This is the string that is sent to the synthesizer to cause it @@ -281,7 +281,7 @@ Description: This is the string that is sent to the synthesizer to cause it and most others, this causes the pitch of the voice to rise above the currently set pitch. -What: /sys/accessibility/speakup/soft/caps_stop +What: /sys/accessibility/speakup//caps_stop KernelVersion: 2.6 Contact: speakup@linux-speakup.org Description: This is the string sent to the synthesizer to cause it to stop @@ -290,12 +290,12 @@ Description: This is the string sent to the synthesizer to cause it to stop down to the currently set pitch. -What: /sys/accessibility/speakup/soft/delay_time +What: /sys/accessibility/speakup//delay_time KernelVersion: 2.6 Contact: speakup@linux-speakup.org Description: TODO: -What: /sys/accessibility/speakup/soft/direct +What: /sys/accessibility/speakup//direct KernelVersion: 2.6 Contact: speakup@linux-speakup.org Description: Controls if punctuation is spoken by speakup, or by the @@ -306,36 +306,36 @@ Description: Controls if punctuation is spoken by speakup, or by the than". Zero lets speakup speak the punctuation. One lets the synthesizer itself speak punctuation. -What: /sys/accessibility/speakup/soft/freq +What: /sys/accessibility/speakup//freq KernelVersion: 2.6 Contact: speakup@linux-speakup.org Description: Gets or sets the frequency of the speech synthesizer. Range is 0-9. -What: /sys/accessibility/speakup/soft/full_time +What: /sys/accessibility/speakup//full_time KernelVersion: 2.6 Contact: speakup@linux-speakup.org Description: TODO: -What: /sys/accessibility/speakup/soft/jiffy_delta +What: /sys/accessibility/speakup//jiffy_delta KernelVersion: 2.6 Contact: speakup@linux-speakup.org Description: This controls how many jiffys the kernel gives to the synthesizer. Setting this too high can make a system unstable, or even crash it. -What: /sys/accessibility/speakup/soft/pitch +What: /sys/accessibility/speakup//pitch KernelVersion: 2.6 Contact: speakup@linux-speakup.org Description: Gets or sets the pitch of the synthesizer. The range is 0-9. -What: /sys/accessibility/speakup/soft/inflection +What: /sys/accessibility/speakup//inflection KernelVersion: 5.8 Contact: speakup@linux-speakup.org Description: Gets or sets the inflection of the synthesizer, i.e. the pitch range. The range is 0-9. -What: /sys/accessibility/speakup/soft/punct +What: /sys/accessibility/speakup//punct KernelVersion: 2.6 Contact: speakup@linux-speakup.org Description: Gets or sets the amount of punctuation spoken by the @@ -343,13 +343,13 @@ Description: Gets or sets the amount of punctuation spoken by the TODO: How is this related to speakup's punc_level, or reading_punc. -What: /sys/accessibility/speakup/soft/rate +What: /sys/accessibility/speakup//rate KernelVersion: 2.6 Contact: speakup@linux-speakup.org Description: Gets or sets the rate of the synthesizer. Range is from zero slowest, to nine fastest. -What: /sys/accessibility/speakup/soft/tone +What: /sys/accessibility/speakup//tone KernelVersion: 2.6 Contact: speakup@linux-speakup.org Description: Gets or sets the tone of the speech synthesizer. The range for @@ -357,12 +357,12 @@ Description: Gets or sets the tone of the speech synthesizer. The range for difference if using espeak and the espeakup connector. TODO: does espeakup support different tonalities? -What: /sys/accessibility/speakup/soft/trigger_time +What: /sys/accessibility/speakup//trigger_time KernelVersion: 2.6 Contact: speakup@linux-speakup.org Description: TODO: -What: /sys/accessibility/speakup/soft/voice +What: /sys/accessibility/speakup//voice KernelVersion: 2.6 Contact: speakup@linux-speakup.org Description: Gets or sets the voice used by the synthesizer if the @@ -371,7 +371,7 @@ Description: Gets or sets the voice used by the synthesizer if the voices, this parameter will not set the voice when the espeakup connector is used between speakup and espeak. -What: /sys/accessibility/speakup/soft/vol +What: /sys/accessibility/speakup//vol KernelVersion: 2.6 Contact: speakup@linux-speakup.org Description: Gets or sets the volume of the speech synthesizer. Range is 0-9, -- cgit v1.2.3 From 1f7c14afd4ad5aae5220dfc878f29770239911b1 Mon Sep 17 00:00:00 2001 From: Samuel Thibault Date: Thu, 28 Jan 2021 19:01:16 +0100 Subject: speakup: Make dectlk flush timeout configurable In case the serial port or cable got faulty, we may not be getting acknowledgements any more. The driver then currently waits for 4s to avoid jamming the device. This makes this delay configurable. Signed-off-by: Samuel Thibault Link: https://lore.kernel.org/r/20210128180116.1848120-3-samuel.thibault@ens-lyon.org Signed-off-by: Greg Kroah-Hartman --- Documentation/ABI/stable/sysfs-driver-speakup | 7 +++++++ drivers/accessibility/speakup/speakup_dectlk.c | 11 ++++++++++- drivers/accessibility/speakup/spk_types.h | 3 ++- drivers/accessibility/speakup/synth.c | 3 +++ drivers/accessibility/speakup/varhandlers.c | 1 + 5 files changed, 23 insertions(+), 2 deletions(-) (limited to 'Documentation') diff --git a/Documentation/ABI/stable/sysfs-driver-speakup b/Documentation/ABI/stable/sysfs-driver-speakup index 47f5c8a9843a..dc2a6ba1674b 100644 --- a/Documentation/ABI/stable/sysfs-driver-speakup +++ b/Documentation/ABI/stable/sysfs-driver-speakup @@ -312,6 +312,13 @@ Contact: speakup@linux-speakup.org Description: Gets or sets the frequency of the speech synthesizer. Range is 0-9. +What: /sys/accessibility/speakup//flush_time +KernelVersion: 5.12 +Contact: speakup@linux-speakup.org +Description: Gets or sets the timeout to wait for the synthesizer flush to + complete. This can be used when the cable gets faulty and flush + notifications are getting lost. + What: /sys/accessibility/speakup//full_time KernelVersion: 2.6 Contact: speakup@linux-speakup.org diff --git a/drivers/accessibility/speakup/speakup_dectlk.c b/drivers/accessibility/speakup/speakup_dectlk.c index d75de36e96c3..580ec796816b 100644 --- a/drivers/accessibility/speakup/speakup_dectlk.c +++ b/drivers/accessibility/speakup/speakup_dectlk.c @@ -78,6 +78,8 @@ static struct kobj_attribute direct_attribute = __ATTR(direct, 0644, spk_var_show, spk_var_store); static struct kobj_attribute full_time_attribute = __ATTR(full_time, 0644, spk_var_show, spk_var_store); +static struct kobj_attribute flush_time_attribute = + __ATTR(flush_time, 0644, spk_var_show, spk_var_store); static struct kobj_attribute jiffy_delta_attribute = __ATTR(jiffy_delta, 0644, spk_var_show, spk_var_store); static struct kobj_attribute trigger_time_attribute = @@ -99,6 +101,7 @@ static struct attribute *synth_attrs[] = { &delay_time_attribute.attr, &direct_attribute.attr, &full_time_attribute.attr, + &flush_time_attribute.attr, &jiffy_delta_attribute.attr, &trigger_time_attribute.attr, NULL, /* need to NULL terminate the list of attributes */ @@ -118,6 +121,7 @@ static struct spk_synth synth_dectlk = { .trigger = 50, .jiffies = 50, .full = 40000, + .flush_time = 4000, .dev_name = SYNTH_DEFAULT_DEV, .startup = SYNTH_START, .checkval = SYNTH_CHECK, @@ -200,18 +204,23 @@ static void do_catch_up(struct spk_synth *synth) static u_char last = '\0'; unsigned long flags; unsigned long jiff_max; - unsigned long timeout = msecs_to_jiffies(4000); + unsigned long timeout; DEFINE_WAIT(wait); struct var_t *jiffy_delta; struct var_t *delay_time; + struct var_t *flush_time; int jiffy_delta_val; int delay_time_val; + int timeout_val; jiffy_delta = spk_get_var(JIFFY); delay_time = spk_get_var(DELAY); + flush_time = spk_get_var(FLUSH); spin_lock_irqsave(&speakup_info.spinlock, flags); jiffy_delta_val = jiffy_delta->u.n.value; + timeout_val = flush_time->u.n.value; spin_unlock_irqrestore(&speakup_info.spinlock, flags); + timeout = msecs_to_jiffies(timeout_val); jiff_max = jiffies + jiffy_delta_val; while (!kthread_should_stop()) { diff --git a/drivers/accessibility/speakup/spk_types.h b/drivers/accessibility/speakup/spk_types.h index 7789f5dca62a..6a96ad94bc3f 100644 --- a/drivers/accessibility/speakup/spk_types.h +++ b/drivers/accessibility/speakup/spk_types.h @@ -48,7 +48,7 @@ enum var_id_t { ATTRIB_BLEEP, BLEEPS, RATE, PITCH, VOL, TONE, PUNCT, VOICE, FREQUENCY, LANG, DIRECT, PAUSE, - CAPS_START, CAPS_STOP, CHARTAB, INFLECTION, + CAPS_START, CAPS_STOP, CHARTAB, INFLECTION, FLUSH, MAXVARS }; @@ -178,6 +178,7 @@ struct spk_synth { int trigger; int jiffies; int full; + int flush_time; int ser; char *dev_name; short flags; diff --git a/drivers/accessibility/speakup/synth.c b/drivers/accessibility/speakup/synth.c index 6c14b682da13..2b8699673bac 100644 --- a/drivers/accessibility/speakup/synth.c +++ b/drivers/accessibility/speakup/synth.c @@ -348,6 +348,7 @@ struct var_t synth_time_vars[] = { { TRIGGER, .u.n = {NULL, 20, 10, 2000, 0, 0, NULL } }, { JIFFY, .u.n = {NULL, 50, 20, 200, 0, 0, NULL } }, { FULL, .u.n = {NULL, 400, 200, 60000, 0, 0, NULL } }, + { FLUSH, .u.n = {NULL, 4000, 100, 4000, 0, 0, NULL } }, V_LAST_VAR }; @@ -408,6 +409,8 @@ static int do_synth_init(struct spk_synth *in_synth) synth_time_vars[2].u.n.default_val = synth->jiffies; synth_time_vars[3].u.n.value = synth_time_vars[3].u.n.default_val = synth->full; + synth_time_vars[4].u.n.value = + synth_time_vars[4].u.n.default_val = synth->flush_time; synth_printf("%s", synth->init); for (var = synth->vars; (var->var_id >= 0) && (var->var_id < MAXVARS); var++) diff --git a/drivers/accessibility/speakup/varhandlers.c b/drivers/accessibility/speakup/varhandlers.c index d7f6bec7ff06..067c0da97dcb 100644 --- a/drivers/accessibility/speakup/varhandlers.c +++ b/drivers/accessibility/speakup/varhandlers.c @@ -23,6 +23,7 @@ static struct st_var_header var_headers[] = { { "trigger_time", TRIGGER, VAR_TIME, NULL, NULL }, { "jiffy_delta", JIFFY, VAR_TIME, NULL, NULL }, { "full_time", FULL, VAR_TIME, NULL, NULL }, + { "flush_time", FLUSH, VAR_TIME, NULL, NULL }, { "spell_delay", SPELL_DELAY, VAR_NUM, &spk_spell_delay, NULL }, { "bleeps", BLEEPS, VAR_NUM, &spk_bleeps, NULL }, { "attrib_bleep", ATTRIB_BLEEP, VAR_NUM, &spk_attrib_bleep, NULL }, -- cgit v1.2.3 From c56fd5ead29b6ad6625af632a91a231129027185 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Wed, 20 Jan 2021 19:58:18 +0100 Subject: ACPI: PM: Clean up printing messages Replace the remaining ACPI_DEBUG_PRINT() instances in device_pm.c with dev_dbg() invocations, drop the _COMPONENT and ACPI_MODULE_NAME() definitions that are not used any more, and drop the no longer needed ACPI_POWER_COMPONENT definition from the headers and documentation. Signed-off-by: Rafael J. Wysocki --- Documentation/firmware-guide/acpi/debug.rst | 1 - drivers/acpi/device_pm.c | 20 ++++++++------------ drivers/acpi/sysfs.c | 1 - include/acpi/acpi_drivers.h | 1 - 4 files changed, 8 insertions(+), 15 deletions(-) (limited to 'Documentation') diff --git a/Documentation/firmware-guide/acpi/debug.rst b/Documentation/firmware-guide/acpi/debug.rst index 1a152dd1d765..73f88a27f12b 100644 --- a/Documentation/firmware-guide/acpi/debug.rst +++ b/Documentation/firmware-guide/acpi/debug.rst @@ -59,7 +59,6 @@ shows the supported mask values, currently these:: ACPI_SBS_COMPONENT 0x00100000 ACPI_FAN_COMPONENT 0x00200000 ACPI_PCI_COMPONENT 0x00400000 - ACPI_POWER_COMPONENT 0x00800000 ACPI_CONTAINER_COMPONENT 0x01000000 ACPI_SYSTEM_COMPONENT 0x02000000 ACPI_THERMAL_COMPONENT 0x04000000 diff --git a/drivers/acpi/device_pm.c b/drivers/acpi/device_pm.c index 3586434d0ded..096153761ebc 100644 --- a/drivers/acpi/device_pm.c +++ b/drivers/acpi/device_pm.c @@ -10,6 +10,8 @@ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ +#define pr_fmt(fmt) "ACPI: PM: " fmt + #include #include #include @@ -20,9 +22,6 @@ #include "internal.h" -#define _COMPONENT ACPI_POWER_COMPONENT -ACPI_MODULE_NAME("device_pm"); - /** * acpi_power_state_string - String representation of ACPI device power state. * @state: ACPI device power state to return the string representation of. @@ -130,8 +129,8 @@ int acpi_device_get_power(struct acpi_device *device, int *state) *state = result; out: - ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device [%s] power state is %s\n", - device->pnp.bus_id, acpi_power_state_string(*state))); + dev_dbg(&device->dev, "Device power state is %s\n", + acpi_power_state_string(*state)); return 0; } @@ -174,9 +173,8 @@ int acpi_device_set_power(struct acpi_device *device, int state) /* There is a special case for D0 addressed below. */ if (state > ACPI_STATE_D0 && state == device->power.state) { - ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device [%s] already in %s\n", - device->pnp.bus_id, - acpi_power_state_string(state))); + dev_dbg(&device->dev, "Device already in %s\n", + acpi_power_state_string(state)); return 0; } @@ -276,10 +274,8 @@ int acpi_device_set_power(struct acpi_device *device, int state) acpi_power_state_string(target_state)); } else { device->power.state = target_state; - ACPI_DEBUG_PRINT((ACPI_DB_INFO, - "Device [%s] transitioned to %s\n", - device->pnp.bus_id, - acpi_power_state_string(target_state))); + dev_dbg(&device->dev, "Power state changed to %s\n", + acpi_power_state_string(target_state)); } return result; diff --git a/drivers/acpi/sysfs.c b/drivers/acpi/sysfs.c index a5cc4f3bb1e3..eeb0419d68a8 100644 --- a/drivers/acpi/sysfs.c +++ b/drivers/acpi/sysfs.c @@ -59,7 +59,6 @@ static const struct acpi_dlayer acpi_debug_layers[] = { ACPI_DEBUG_INIT(ACPI_SBS_COMPONENT), ACPI_DEBUG_INIT(ACPI_FAN_COMPONENT), ACPI_DEBUG_INIT(ACPI_PCI_COMPONENT), - ACPI_DEBUG_INIT(ACPI_POWER_COMPONENT), ACPI_DEBUG_INIT(ACPI_CONTAINER_COMPONENT), ACPI_DEBUG_INIT(ACPI_SYSTEM_COMPONENT), ACPI_DEBUG_INIT(ACPI_THERMAL_COMPONENT), diff --git a/include/acpi/acpi_drivers.h b/include/acpi/acpi_drivers.h index d4f39a20aa2a..14da491bad96 100644 --- a/include/acpi/acpi_drivers.h +++ b/include/acpi/acpi_drivers.h @@ -22,7 +22,6 @@ #define ACPI_SBS_COMPONENT 0x00100000 #define ACPI_FAN_COMPONENT 0x00200000 #define ACPI_PCI_COMPONENT 0x00400000 -#define ACPI_POWER_COMPONENT 0x00800000 #define ACPI_CONTAINER_COMPONENT 0x01000000 #define ACPI_SYSTEM_COMPONENT 0x02000000 #define ACPI_THERMAL_COMPONENT 0x04000000 -- cgit v1.2.3 From 12bfee94c23063142e8c370c651ba33482388a51 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Wed, 20 Jan 2021 20:01:18 +0100 Subject: ACPI: bus: Drop ACPI_BUS_COMPONENT which is not used any more After dropping all of the code using ACPI_BUS_COMPONENT drop it too and modify the example in the documentation using it. Signed-off-by: Rafael J. Wysocki --- Documentation/firmware-guide/acpi/debug.rst | 13 ++++++------- drivers/acpi/sysfs.c | 1 - include/acpi/acpi_drivers.h | 1 - 3 files changed, 6 insertions(+), 9 deletions(-) (limited to 'Documentation') diff --git a/Documentation/firmware-guide/acpi/debug.rst b/Documentation/firmware-guide/acpi/debug.rst index 73f88a27f12b..c7bad74c6ff7 100644 --- a/Documentation/firmware-guide/acpi/debug.rst +++ b/Documentation/firmware-guide/acpi/debug.rst @@ -52,7 +52,6 @@ shows the supported mask values, currently these:: ACPI_CA_DISASSEMBLER 0x00000800 ACPI_COMPILER 0x00001000 ACPI_TOOLS 0x00002000 - ACPI_BUS_COMPONENT 0x00010000 ACPI_AC_COMPONENT 0x00020000 ACPI_BATTERY_COMPONENT 0x00040000 ACPI_BUTTON_COMPONENT 0x00080000 @@ -117,15 +116,15 @@ currently these:: Examples ======== -For example, drivers/acpi/bus.c contains this:: +For example, drivers/acpi/acpica/evxfevnt.c contains this:: - #define _COMPONENT ACPI_BUS_COMPONENT + #define _COMPONENT ACPI_EVENTS ... - ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device insertion detected\n")); + ACPI_DEBUG_PRINT((ACPI_DB_INIT, "ACPI mode disabled\n")); -To turn on this message, set the ACPI_BUS_COMPONENT bit in acpi.debug_layer -and the ACPI_LV_INFO bit in acpi.debug_level. (The ACPI_DEBUG_PRINT -statement uses ACPI_DB_INFO, which is macro based on the ACPI_LV_INFO +To turn on this message, set the ACPI_EVENTS bit in acpi.debug_layer +and the ACPI_LV_INIT bit in acpi.debug_level. (The ACPI_DEBUG_PRINT +statement uses ACPI_DB_INIT, which is a macro based on the ACPI_LV_INIT definition.) Enable all AML "Debug" output (stores to the Debug object while interpreting diff --git a/drivers/acpi/sysfs.c b/drivers/acpi/sysfs.c index eeb0419d68a8..b065f2af8821 100644 --- a/drivers/acpi/sysfs.c +++ b/drivers/acpi/sysfs.c @@ -52,7 +52,6 @@ static const struct acpi_dlayer acpi_debug_layers[] = { ACPI_DEBUG_INIT(ACPI_COMPILER), ACPI_DEBUG_INIT(ACPI_TOOLS), - ACPI_DEBUG_INIT(ACPI_BUS_COMPONENT), ACPI_DEBUG_INIT(ACPI_AC_COMPONENT), ACPI_DEBUG_INIT(ACPI_BATTERY_COMPONENT), ACPI_DEBUG_INIT(ACPI_BUTTON_COMPONENT), diff --git a/include/acpi/acpi_drivers.h b/include/acpi/acpi_drivers.h index 14da491bad96..4baa7a7dc83a 100644 --- a/include/acpi/acpi_drivers.h +++ b/include/acpi/acpi_drivers.h @@ -15,7 +15,6 @@ * Please update drivers/acpi/debug.c and Documentation/firmware-guide/acpi/debug.rst * if you add to this list. */ -#define ACPI_BUS_COMPONENT 0x00010000 #define ACPI_AC_COMPONENT 0x00020000 #define ACPI_BATTERY_COMPONENT 0x00040000 #define ACPI_BUTTON_COMPONENT 0x00080000 -- cgit v1.2.3 From 2249ff344467b5ab4da31c1e0873c56521aa345b Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Wed, 3 Feb 2021 19:43:17 +0100 Subject: ACPI: AC: Clean up printing messages Replace the ACPI_DEBUG_PRINT() and ACPI_EXCEPTION() instances in ac.c with acpi_handle_debug() and acpi_handle_info() calls, respectively, which among other things causes the excessive log level of the messages previously printed via ACPI_EXCEPTION() to be increased. Drop the _COMPONENT and ACPI_MODULE_NAME() definitions that are not used any more, drop the no longer needed ACPI_AC_COMPONENT definition from the headers and update the documentation accordingly. While at it, replace the direct printk() invocation with pr_info(), add a pr_fmt() definition to ac.c and drop the unneeded PREFIX symbol definition from there. Signed-off-by: Rafael J. Wysocki Reviewed-by: Hanjun Guo Reviewed-by: Hans de Goede --- Documentation/firmware-guide/acpi/debug.rst | 1 - drivers/acpi/ac.c | 23 ++++++++++------------- drivers/acpi/sysfs.c | 1 - include/acpi/acpi_drivers.h | 1 - 4 files changed, 10 insertions(+), 16 deletions(-) (limited to 'Documentation') diff --git a/Documentation/firmware-guide/acpi/debug.rst b/Documentation/firmware-guide/acpi/debug.rst index c7bad74c6ff7..cb61b1ab7276 100644 --- a/Documentation/firmware-guide/acpi/debug.rst +++ b/Documentation/firmware-guide/acpi/debug.rst @@ -52,7 +52,6 @@ shows the supported mask values, currently these:: ACPI_CA_DISASSEMBLER 0x00000800 ACPI_COMPILER 0x00001000 ACPI_TOOLS 0x00002000 - ACPI_AC_COMPONENT 0x00020000 ACPI_BATTERY_COMPONENT 0x00040000 ACPI_BUTTON_COMPONENT 0x00080000 ACPI_SBS_COMPONENT 0x00100000 diff --git a/drivers/acpi/ac.c b/drivers/acpi/ac.c index 46a64e9fa716..b41180330cc1 100644 --- a/drivers/acpi/ac.c +++ b/drivers/acpi/ac.c @@ -6,6 +6,8 @@ * Copyright (C) 2001, 2002 Paul Diefenbaugh */ +#define pr_fmt(fmt) "ACPI: AC: " fmt + #include #include #include @@ -18,8 +20,6 @@ #include #include -#define PREFIX "ACPI: " - #define ACPI_AC_CLASS "ac_adapter" #define ACPI_AC_DEVICE_NAME "AC Adapter" #define ACPI_AC_FILE_STATE "state" @@ -28,9 +28,6 @@ #define ACPI_AC_STATUS_ONLINE 0x01 #define ACPI_AC_STATUS_UNKNOWN 0xFF -#define _COMPONENT ACPI_AC_COMPONENT -ACPI_MODULE_NAME("ac"); - MODULE_AUTHOR("Paul Diefenbaugh"); MODULE_DESCRIPTION("ACPI AC Adapter Driver"); MODULE_LICENSE("GPL"); @@ -102,8 +99,9 @@ static int acpi_ac_get_state(struct acpi_ac *ac) status = acpi_evaluate_integer(ac->device->handle, "_PSR", NULL, &ac->state); if (ACPI_FAILURE(status)) { - ACPI_EXCEPTION((AE_INFO, status, - "Error reading AC Adapter state")); + acpi_handle_info(ac->device->handle, + "Error reading AC Adapter state: %s\n", + acpi_format_exception(status)); ac->state = ACPI_AC_STATUS_UNKNOWN; return -ENODEV; } @@ -153,8 +151,8 @@ static void acpi_ac_notify(struct acpi_device *device, u32 event) switch (event) { default: - ACPI_DEBUG_PRINT((ACPI_DB_INFO, - "Unsupported event [0x%x]\n", event)); + acpi_handle_debug(device->handle, "Unsupported event [0x%x]\n", + event); fallthrough; case ACPI_AC_NOTIFY_STATUS: case ACPI_NOTIFY_BUS_CHECK: @@ -278,9 +276,8 @@ static int acpi_ac_add(struct acpi_device *device) goto end; } - printk(KERN_INFO PREFIX "%s [%s] (%s)\n", - acpi_device_name(device), acpi_device_bid(device), - ac->state ? "on-line" : "off-line"); + pr_info("%s [%s] (%s)\n", acpi_device_name(device), + acpi_device_bid(device), ac->state ? "on-line" : "off-line"); ac->battery_nb.notifier_call = acpi_ac_battery_notify; register_acpi_notifier(&ac->battery_nb); @@ -348,7 +345,7 @@ static int __init acpi_ac_init(void) for (i = 0; i < ARRAY_SIZE(acpi_ac_blacklist); i++) if (acpi_dev_present(acpi_ac_blacklist[i].hid, "1", acpi_ac_blacklist[i].hrv)) { - pr_info(PREFIX "AC: found native %s PMIC, not loading\n", + pr_info("found native %s PMIC, not loading\n", acpi_ac_blacklist[i].hid); return -ENODEV; } diff --git a/drivers/acpi/sysfs.c b/drivers/acpi/sysfs.c index b065f2af8821..64f7674ee498 100644 --- a/drivers/acpi/sysfs.c +++ b/drivers/acpi/sysfs.c @@ -52,7 +52,6 @@ static const struct acpi_dlayer acpi_debug_layers[] = { ACPI_DEBUG_INIT(ACPI_COMPILER), ACPI_DEBUG_INIT(ACPI_TOOLS), - ACPI_DEBUG_INIT(ACPI_AC_COMPONENT), ACPI_DEBUG_INIT(ACPI_BATTERY_COMPONENT), ACPI_DEBUG_INIT(ACPI_BUTTON_COMPONENT), ACPI_DEBUG_INIT(ACPI_SBS_COMPONENT), diff --git a/include/acpi/acpi_drivers.h b/include/acpi/acpi_drivers.h index 4baa7a7dc83a..b0d6c4cc1a39 100644 --- a/include/acpi/acpi_drivers.h +++ b/include/acpi/acpi_drivers.h @@ -15,7 +15,6 @@ * Please update drivers/acpi/debug.c and Documentation/firmware-guide/acpi/debug.rst * if you add to this list. */ -#define ACPI_AC_COMPONENT 0x00020000 #define ACPI_BATTERY_COMPONENT 0x00040000 #define ACPI_BUTTON_COMPONENT 0x00080000 #define ACPI_SBS_COMPONENT 0x00100000 -- cgit v1.2.3 From bd8c5d1ee37ff4726367128ccdfd83300ee4e3d3 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Wed, 3 Feb 2021 19:44:57 +0100 Subject: ACPI: battery: Clean up printing messages Replace the ACPI_DEBUG_PRINT() and ACPI_EXCEPTION() instances in battery.c with acpi_handle_debug() and acpi_handle_info() calls, respectively, which among other things causes the excessive log level of the messages previously printed via ACPI_EXCEPTION() to be increased. Drop the _COMPONENT and ACPI_MODULE_NAME() definitions that are not used any more, drop the no longer needed ACPI_BATTERY_COMPONENT definition from the headers and update the documentation accordingly. While at it, update the pr_fmt() definition and drop the unneeded PREFIX sybmbol definition from battery.c. Also adapt the existing pr_info() calls to the new pr_fmt() definition. Signed-off-by: Rafael J. Wysocki Reviewed-by: Hanjun Guo Reviewed-by: Hans de Goede --- Documentation/firmware-guide/acpi/debug.rst | 1 - drivers/acpi/battery.c | 33 ++++++++++++++--------------- drivers/acpi/sysfs.c | 1 - include/acpi/acpi_drivers.h | 1 - 4 files changed, 16 insertions(+), 20 deletions(-) (limited to 'Documentation') diff --git a/Documentation/firmware-guide/acpi/debug.rst b/Documentation/firmware-guide/acpi/debug.rst index cb61b1ab7276..60d877913da3 100644 --- a/Documentation/firmware-guide/acpi/debug.rst +++ b/Documentation/firmware-guide/acpi/debug.rst @@ -52,7 +52,6 @@ shows the supported mask values, currently these:: ACPI_CA_DISASSEMBLER 0x00000800 ACPI_COMPILER 0x00001000 ACPI_TOOLS 0x00002000 - ACPI_BATTERY_COMPONENT 0x00040000 ACPI_BUTTON_COMPONENT 0x00080000 ACPI_SBS_COMPONENT 0x00100000 ACPI_FAN_COMPONENT 0x00200000 diff --git a/drivers/acpi/battery.c b/drivers/acpi/battery.c index 08ee1c7b12e0..b822f77afba6 100644 --- a/drivers/acpi/battery.c +++ b/drivers/acpi/battery.c @@ -8,7 +8,7 @@ * Copyright (C) 2001, 2002 Paul Diefenbaugh */ -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt +#define pr_fmt(fmt) "ACPI: battery: " fmt #include #include @@ -29,8 +29,6 @@ #include -#define PREFIX "ACPI: " - #define ACPI_BATTERY_VALUE_UNKNOWN 0xFFFFFFFF #define ACPI_BATTERY_CAPACITY_VALID(capacity) \ ((capacity) != 0 && (capacity) != ACPI_BATTERY_VALUE_UNKNOWN) @@ -44,10 +42,6 @@ #define ACPI_BATTERY_STATE_CHARGING 0x2 #define ACPI_BATTERY_STATE_CRITICAL 0x4 -#define _COMPONENT ACPI_BATTERY_COMPONENT - -ACPI_MODULE_NAME("battery"); - MODULE_AUTHOR("Paul Diefenbaugh"); MODULE_AUTHOR("Alexey Starikovskiy "); MODULE_DESCRIPTION("ACPI Battery Driver"); @@ -466,7 +460,8 @@ static int extract_package(struct acpi_battery *battery, static int acpi_battery_get_status(struct acpi_battery *battery) { if (acpi_bus_get_status(battery->device)) { - ACPI_EXCEPTION((AE_INFO, AE_ERROR, "Evaluating _STA")); + acpi_handle_info(battery->device->handle, + "_STA evaluation failed\n"); return -ENODEV; } return 0; @@ -535,8 +530,10 @@ static int acpi_battery_get_info(struct acpi_battery *battery) mutex_unlock(&battery->lock); if (ACPI_FAILURE(status)) { - ACPI_EXCEPTION((AE_INFO, status, "Evaluating %s", - use_bix ? "_BIX":"_BIF")); + acpi_handle_info(battery->device->handle, + "%s evaluation failed: %s\n", + use_bix ?"_BIX":"_BIF", + acpi_format_exception(status)); } else { result = extract_battery_info(use_bix, battery, @@ -573,7 +570,9 @@ static int acpi_battery_get_state(struct acpi_battery *battery) mutex_unlock(&battery->lock); if (ACPI_FAILURE(status)) { - ACPI_EXCEPTION((AE_INFO, status, "Evaluating _BST")); + acpi_handle_info(battery->device->handle, + "_BST evaluation failed: %s", + acpi_format_exception(status)); return -ENODEV; } @@ -590,7 +589,7 @@ static int acpi_battery_get_state(struct acpi_battery *battery) battery->rate_now != ACPI_BATTERY_VALUE_UNKNOWN && (s16)(battery->rate_now) < 0) { battery->rate_now = abs((s16)battery->rate_now); - pr_warn_once(FW_BUG "battery: (dis)charge rate invalid.\n"); + pr_warn_once(FW_BUG "(dis)charge rate invalid.\n"); } if (test_bit(ACPI_BATTERY_QUIRK_PERCENTAGE_CAPACITY, &battery->flags) @@ -625,7 +624,9 @@ static int acpi_battery_set_alarm(struct acpi_battery *battery) if (ACPI_FAILURE(status)) return -ENODEV; - ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Alarm set to %d\n", battery->alarm)); + acpi_handle_debug(battery->device->handle, "Alarm set to %d\n", + battery->alarm); + return 0; } @@ -1201,8 +1202,7 @@ static int acpi_battery_add(struct acpi_device *device) if (result) goto fail; - pr_info(PREFIX "%s Slot [%s] (battery %s)\n", - ACPI_BATTERY_DEVICE_NAME, acpi_device_bid(device), + pr_info("Slot [%s] (battery %s)\n", acpi_device_bid(device), device->status.battery_present ? "present" : "absent"); battery->pm_nb.notifier_call = battery_notify; @@ -1282,8 +1282,7 @@ static void __init acpi_battery_init_async(void *unused, async_cookie_t cookie) if (battery_check_pmic) { for (i = 0; i < ARRAY_SIZE(acpi_battery_blacklist); i++) if (acpi_dev_present(acpi_battery_blacklist[i], "1", -1)) { - pr_info(PREFIX ACPI_BATTERY_DEVICE_NAME - ": found native %s PMIC, not loading\n", + pr_info("found native %s PMIC, not loading\n", acpi_battery_blacklist[i]); return; } diff --git a/drivers/acpi/sysfs.c b/drivers/acpi/sysfs.c index 64f7674ee498..4d3eec9dc0ee 100644 --- a/drivers/acpi/sysfs.c +++ b/drivers/acpi/sysfs.c @@ -52,7 +52,6 @@ static const struct acpi_dlayer acpi_debug_layers[] = { ACPI_DEBUG_INIT(ACPI_COMPILER), ACPI_DEBUG_INIT(ACPI_TOOLS), - ACPI_DEBUG_INIT(ACPI_BATTERY_COMPONENT), ACPI_DEBUG_INIT(ACPI_BUTTON_COMPONENT), ACPI_DEBUG_INIT(ACPI_SBS_COMPONENT), ACPI_DEBUG_INIT(ACPI_FAN_COMPONENT), diff --git a/include/acpi/acpi_drivers.h b/include/acpi/acpi_drivers.h index b0d6c4cc1a39..8fc70b273c34 100644 --- a/include/acpi/acpi_drivers.h +++ b/include/acpi/acpi_drivers.h @@ -15,7 +15,6 @@ * Please update drivers/acpi/debug.c and Documentation/firmware-guide/acpi/debug.rst * if you add to this list. */ -#define ACPI_BATTERY_COMPONENT 0x00040000 #define ACPI_BUTTON_COMPONENT 0x00080000 #define ACPI_SBS_COMPONENT 0x00100000 #define ACPI_FAN_COMPONENT 0x00200000 -- cgit v1.2.3 From 411e3216d4ee7e3c25c365b0d09e18f7798d705a Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Wed, 3 Feb 2021 19:46:14 +0100 Subject: ACPI: button: Clean up printing messages Replace the ACPI_DEBUG_PRINT() instance in button.c with an acpi_handle_debug() call, drop the _COMPONENT and ACPI_MODULE_NAME() definitions that are not used any more, drop the no longer needed ACPI_BUTTON_COMPONENT definition from the headers and update the documentation accordingly. While at it, replace the direct printk() invocations with pr_info() (that changes the excessive log level for some of them too) and drop the unneeded PREFIX sybmbol definition from battery.c. Signed-off-by: Rafael J. Wysocki Reviewed-by: Hanjun Guo Reviewed-by: Hans de Goede --- Documentation/firmware-guide/acpi/debug.rst | 1 - drivers/acpi/button.c | 15 +++++---------- drivers/acpi/sysfs.c | 1 - include/acpi/acpi_drivers.h | 1 - 4 files changed, 5 insertions(+), 13 deletions(-) (limited to 'Documentation') diff --git a/Documentation/firmware-guide/acpi/debug.rst b/Documentation/firmware-guide/acpi/debug.rst index 60d877913da3..67a5ad75a52e 100644 --- a/Documentation/firmware-guide/acpi/debug.rst +++ b/Documentation/firmware-guide/acpi/debug.rst @@ -52,7 +52,6 @@ shows the supported mask values, currently these:: ACPI_CA_DISASSEMBLER 0x00000800 ACPI_COMPILER 0x00001000 ACPI_TOOLS 0x00002000 - ACPI_BUTTON_COMPONENT 0x00080000 ACPI_SBS_COMPONENT 0x00100000 ACPI_FAN_COMPONENT 0x00200000 ACPI_PCI_COMPONENT 0x00400000 diff --git a/drivers/acpi/button.c b/drivers/acpi/button.c index 0d93a5ef4d07..85e5e0328a2e 100644 --- a/drivers/acpi/button.c +++ b/drivers/acpi/button.c @@ -21,8 +21,6 @@ #include #include -#define PREFIX "ACPI: " - #define ACPI_BUTTON_CLASS "button" #define ACPI_BUTTON_FILE_STATE "state" #define ACPI_BUTTON_TYPE_UNKNOWN 0x00 @@ -54,9 +52,6 @@ static const char * const lid_init_state_str[] = { [ACPI_BUTTON_LID_INIT_DISABLED] = "disabled", }; -#define _COMPONENT ACPI_BUTTON_COMPONENT -ACPI_MODULE_NAME("button"); - MODULE_AUTHOR("Paul Diefenbaugh"); MODULE_DESCRIPTION("ACPI Button Driver"); MODULE_LICENSE("GPL"); @@ -285,7 +280,7 @@ static int acpi_button_add_fs(struct acpi_device *device) return 0; if (acpi_button_dir || acpi_lid_dir) { - printk(KERN_ERR PREFIX "More than one Lid device found!\n"); + pr_info("More than one Lid device found!\n"); return -EEXIST; } @@ -434,8 +429,8 @@ static void acpi_button_notify(struct acpi_device *device, u32 event) } break; default: - ACPI_DEBUG_PRINT((ACPI_DB_INFO, - "Unsupported event [0x%x]\n", event)); + acpi_handle_debug(device->handle, "Unsupported event [0x%x]\n", + event); break; } } @@ -523,7 +518,7 @@ static int acpi_button_add(struct acpi_device *device) ACPI_BUTTON_CLASS, ACPI_BUTTON_SUBCLASS_LID); input->open = acpi_lid_input_open; } else { - printk(KERN_ERR PREFIX "Unsupported hid [%s]\n", hid); + pr_info("Unsupported hid [%s]\n", hid); error = -ENODEV; goto err_free_input; } @@ -567,7 +562,7 @@ static int acpi_button_add(struct acpi_device *device) } device_init_wakeup(&device->dev, true); - printk(KERN_INFO PREFIX "%s [%s]\n", name, acpi_device_bid(device)); + pr_info("%s [%s]\n", name, acpi_device_bid(device)); return 0; err_remove_fs: diff --git a/drivers/acpi/sysfs.c b/drivers/acpi/sysfs.c index 4d3eec9dc0ee..152e8eec6f13 100644 --- a/drivers/acpi/sysfs.c +++ b/drivers/acpi/sysfs.c @@ -52,7 +52,6 @@ static const struct acpi_dlayer acpi_debug_layers[] = { ACPI_DEBUG_INIT(ACPI_COMPILER), ACPI_DEBUG_INIT(ACPI_TOOLS), - ACPI_DEBUG_INIT(ACPI_BUTTON_COMPONENT), ACPI_DEBUG_INIT(ACPI_SBS_COMPONENT), ACPI_DEBUG_INIT(ACPI_FAN_COMPONENT), ACPI_DEBUG_INIT(ACPI_PCI_COMPONENT), diff --git a/include/acpi/acpi_drivers.h b/include/acpi/acpi_drivers.h index 8fc70b273c34..25df44b2ed25 100644 --- a/include/acpi/acpi_drivers.h +++ b/include/acpi/acpi_drivers.h @@ -15,7 +15,6 @@ * Please update drivers/acpi/debug.c and Documentation/firmware-guide/acpi/debug.rst * if you add to this list. */ -#define ACPI_BUTTON_COMPONENT 0x00080000 #define ACPI_SBS_COMPONENT 0x00100000 #define ACPI_FAN_COMPONENT 0x00200000 #define ACPI_PCI_COMPONENT 0x00400000 -- cgit v1.2.3 From 2924d2f837788bb0efaa79ece1e5b9e57928834b Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Wed, 3 Feb 2021 19:48:33 +0100 Subject: ACPI: video: Clean up printing messages Replace the ACPI_DEBUG_PRINT() instances in acpi_video.c with acpi_handle_debug() calls and the ACPI_EXCEPTION()/ACPI_ERROR()/ ACPI_WARNING() instances in there with acpi_handle_info() calls, which among other things causes the excessive log levels of those messages to be increased. Drop the _COMPONENT and ACPI_MODULE_NAME() definitions that are not used any more from acpi_video.c, drop the no longer needed ACPI_VIDEO_COMPONENT definition from the headers and update the documentation accordingly. While at it, add a pr_fmt() definition to acpi_video.c, replace the direct printk() invocations in there with acpi_handle_info() or pr_info() (and reduce the excessive log level where applicable) and drop the PREFIX sybmbol definition which is not necessary any more from acpi_video.c. Also make unrelated janitorial changes to fix up white space and use ACPI_FAILURE() instead of negating ACPI_SUCCESS(). Signed-off-by: Rafael J. Wysocki Reviewed-by: Hanjun Guo Reviewed-by: Hans de Goede --- Documentation/firmware-guide/acpi/debug.rst | 1 - drivers/acpi/acpi_video.c | 99 +++++++++++++++-------------- drivers/acpi/sysfs.c | 1 - include/acpi/acpi_drivers.h | 1 - 4 files changed, 51 insertions(+), 51 deletions(-) (limited to 'Documentation') diff --git a/Documentation/firmware-guide/acpi/debug.rst b/Documentation/firmware-guide/acpi/debug.rst index 67a5ad75a52e..761fae76bcce 100644 --- a/Documentation/firmware-guide/acpi/debug.rst +++ b/Documentation/firmware-guide/acpi/debug.rst @@ -59,7 +59,6 @@ shows the supported mask values, currently these:: ACPI_SYSTEM_COMPONENT 0x02000000 ACPI_THERMAL_COMPONENT 0x04000000 ACPI_MEMORY_DEVICE_COMPONENT 0x08000000 - ACPI_VIDEO_COMPONENT 0x10000000 ACPI_PROCESSOR_COMPONENT 0x20000000 debug_level diff --git a/drivers/acpi/acpi_video.c b/drivers/acpi/acpi_video.c index a322a7bd286b..2ea1781290cc 100644 --- a/drivers/acpi/acpi_video.c +++ b/drivers/acpi/acpi_video.c @@ -7,6 +7,8 @@ * Copyright (C) 2006 Thomas Tuttle */ +#define pr_fmt(fmt) "ACPI: video: " fmt + #include #include #include @@ -26,16 +28,11 @@ #include #include -#define PREFIX "ACPI: " - #define ACPI_VIDEO_BUS_NAME "Video Bus" #define ACPI_VIDEO_DEVICE_NAME "Video Device" #define MAX_NAME_LEN 20 -#define _COMPONENT ACPI_VIDEO_COMPONENT -ACPI_MODULE_NAME("video"); - MODULE_AUTHOR("Bruno Ducrot"); MODULE_DESCRIPTION("ACPI Video Driver"); MODULE_LICENSE("GPL"); @@ -326,11 +323,11 @@ acpi_video_device_lcd_query_levels(acpi_handle handle, *levels = NULL; status = acpi_evaluate_object(handle, "_BCL", NULL, &buffer); - if (!ACPI_SUCCESS(status)) + if (ACPI_FAILURE(status)) return status; obj = (union acpi_object *)buffer.pointer; if (!obj || (obj->type != ACPI_TYPE_PACKAGE)) { - printk(KERN_ERR PREFIX "Invalid _BCL data\n"); + acpi_handle_info(handle, "Invalid _BCL data\n"); status = -EFAULT; goto err; } @@ -354,7 +351,7 @@ acpi_video_device_lcd_set_level(struct acpi_video_device *device, int level) status = acpi_execute_simple_method(device->dev->handle, "_BCM", level); if (ACPI_FAILURE(status)) { - ACPI_ERROR((AE_INFO, "Evaluating _BCM failed")); + acpi_handle_info(device->dev->handle, "_BCM evaluation failed\n"); return -EIO; } @@ -368,7 +365,7 @@ acpi_video_device_lcd_set_level(struct acpi_video_device *device, int level) return 0; } - ACPI_ERROR((AE_INFO, "Current brightness invalid")); + acpi_handle_info(device->dev->handle, "Current brightness invalid\n"); return -EINVAL; } @@ -622,9 +619,8 @@ acpi_video_device_lcd_get_level_current(struct acpi_video_device *device, * BQC returned an invalid level. * Stop using it. */ - ACPI_WARNING((AE_INFO, - "%s returned an invalid level", - buf)); + acpi_handle_info(device->dev->handle, + "%s returned an invalid level", buf); device->cap._BQC = device->cap._BCQ = 0; } else { /* @@ -635,7 +631,8 @@ acpi_video_device_lcd_get_level_current(struct acpi_video_device *device, * ACPI video backlight still works w/ buggy _BQC. * http://bugzilla.kernel.org/show_bug.cgi?id=12233 */ - ACPI_WARNING((AE_INFO, "Evaluating %s failed", buf)); + acpi_handle_info(device->dev->handle, + "%s evaluation failed", buf); device->cap._BQC = device->cap._BCQ = 0; } } @@ -675,7 +672,7 @@ acpi_video_device_EDID(struct acpi_video_device *device, if (obj && obj->type == ACPI_TYPE_BUFFER) *edid = obj; else { - printk(KERN_ERR PREFIX "Invalid _DDC data\n"); + acpi_handle_info(device->dev->handle, "Invalid _DDC data\n"); status = -EFAULT; kfree(obj); } @@ -827,10 +824,9 @@ int acpi_video_get_levels(struct acpi_device *device, int result = 0; u32 value; - if (!ACPI_SUCCESS(acpi_video_device_lcd_query_levels(device->handle, - &obj))) { - ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Could not query available " - "LCD brightness level\n")); + if (ACPI_FAILURE(acpi_video_device_lcd_query_levels(device->handle, &obj))) { + acpi_handle_debug(device->handle, + "Could not query available LCD brightness level\n"); result = -ENODEV; goto out; } @@ -842,7 +838,6 @@ int acpi_video_get_levels(struct acpi_device *device, br = kzalloc(sizeof(*br), GFP_KERNEL); if (!br) { - printk(KERN_ERR "can't allocate memory\n"); result = -ENOMEM; goto out; } @@ -863,7 +858,7 @@ int acpi_video_get_levels(struct acpi_device *device, for (i = 0; i < obj->package.count; i++) { o = (union acpi_object *)&obj->package.elements[i]; if (o->type != ACPI_TYPE_INTEGER) { - printk(KERN_ERR PREFIX "Invalid data\n"); + acpi_handle_info(device->handle, "Invalid data\n"); continue; } value = (u32) o->integer.value; @@ -900,7 +895,8 @@ int acpi_video_get_levels(struct acpi_device *device, br->levels[i] = br->levels[i - level_ac_battery]; count += level_ac_battery; } else if (level_ac_battery > ACPI_VIDEO_FIRST_LEVEL) - ACPI_ERROR((AE_INFO, "Too many duplicates in _BCL package")); + acpi_handle_info(device->handle, + "Too many duplicates in _BCL package"); /* Check if the _BCL package is in a reversed order */ if (max_level == br->levels[ACPI_VIDEO_FIRST_LEVEL]) { @@ -910,8 +906,8 @@ int acpi_video_get_levels(struct acpi_device *device, sizeof(br->levels[ACPI_VIDEO_FIRST_LEVEL]), acpi_video_cmp_level, NULL); } else if (max_level != br->levels[count - 1]) - ACPI_ERROR((AE_INFO, - "Found unordered _BCL package")); + acpi_handle_info(device->handle, + "Found unordered _BCL package"); br->count = count; *dev_br = br; @@ -989,9 +985,9 @@ set_level: if (result) goto out_free_levels; - ACPI_DEBUG_PRINT((ACPI_DB_INFO, - "found %d brightness levels\n", - br->count - ACPI_VIDEO_FIRST_LEVEL)); + acpi_handle_debug(device->dev->handle, "found %d brightness levels\n", + br->count - ACPI_VIDEO_FIRST_LEVEL); + return 0; out_free_levels: @@ -1023,7 +1019,8 @@ static void acpi_video_device_find_cap(struct acpi_video_device *device) if (acpi_has_method(device->dev->handle, "_BQC")) { device->cap._BQC = 1; } else if (acpi_has_method(device->dev->handle, "_BCQ")) { - printk(KERN_WARNING FW_BUG "_BCQ is used instead of _BQC\n"); + acpi_handle_info(device->dev->handle, + "_BCQ is used instead of _BQC\n"); device->cap._BCQ = 1; } @@ -1083,8 +1080,7 @@ static int acpi_video_bus_check(struct acpi_video_bus *video) /* Does this device support video switching? */ if (video->cap._DOS || video->cap._DOD) { if (!video->cap._DOS) { - printk(KERN_WARNING FW_BUG - "ACPI(%s) defines _DOD but not _DOS\n", + pr_info(FW_BUG "ACPI(%s) defines _DOD but not _DOS\n", acpi_device_bid(video->device)); } video->flags.multihead = 1; @@ -1272,7 +1268,8 @@ acpi_video_device_bind(struct acpi_video_bus *video, ids = &video->attached_array[i]; if (device->device_id == (ids->value.int_val & 0xffff)) { ids->bind_info = device; - ACPI_DEBUG_PRINT((ACPI_DB_INFO, "device_bind %d\n", i)); + acpi_handle_debug(video->device->handle, "%s: %d\n", + __func__, i); } } } @@ -1324,20 +1321,22 @@ static int acpi_video_device_enumerate(struct acpi_video_bus *video) return AE_NOT_EXIST; status = acpi_evaluate_object(video->device->handle, "_DOD", NULL, &buffer); - if (!ACPI_SUCCESS(status)) { - ACPI_EXCEPTION((AE_INFO, status, "Evaluating _DOD")); + if (ACPI_FAILURE(status)) { + acpi_handle_info(video->device->handle, + "_DOD evaluation failed: %s\n", + acpi_format_exception(status)); return status; } dod = buffer.pointer; if (!dod || (dod->type != ACPI_TYPE_PACKAGE)) { - ACPI_EXCEPTION((AE_INFO, status, "Invalid _DOD data")); + acpi_handle_info(video->device->handle, "Invalid _DOD data\n"); status = -EFAULT; goto out; } - ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found %d video heads in _DOD\n", - dod->package.count)); + acpi_handle_debug(video->device->handle, "Found %d video heads in _DOD\n", + dod->package.count); active_list = kcalloc(1 + dod->package.count, sizeof(struct acpi_video_enumerated_device), @@ -1352,15 +1351,18 @@ static int acpi_video_device_enumerate(struct acpi_video_bus *video) obj = &dod->package.elements[i]; if (obj->type != ACPI_TYPE_INTEGER) { - printk(KERN_ERR PREFIX - "Invalid _DOD data in element %d\n", i); + acpi_handle_info(video->device->handle, + "Invalid _DOD data in element %d\n", i); continue; } active_list[count].value.int_val = obj->integer.value; active_list[count].bind_info = NULL; - ACPI_DEBUG_PRINT((ACPI_DB_INFO, "dod element[%d] = %d\n", i, - (int)obj->integer.value)); + + acpi_handle_debug(video->device->handle, + "_DOD element[%d] = %d\n", i, + (int)obj->integer.value); + count++; } @@ -1451,7 +1453,8 @@ acpi_video_switch_brightness(struct work_struct *work) out: if (result) - printk(KERN_ERR PREFIX "Failed to switch the brightness\n"); + acpi_handle_info(device->dev->handle, + "Failed to switch brightness\n"); } int acpi_video_get_edid(struct acpi_device *device, int type, int device_id, @@ -1601,8 +1604,8 @@ static void acpi_video_bus_notify(struct acpi_device *device, u32 event) break; default: - ACPI_DEBUG_PRINT((ACPI_DB_INFO, - "Unsupported event [0x%x]\n", event)); + acpi_handle_debug(device->handle, "Unsupported event [0x%x]\n", + event); break; } @@ -1675,8 +1678,7 @@ static void acpi_video_device_notify(acpi_handle handle, u32 event, void *data) keycode = KEY_DISPLAY_OFF; break; default: - ACPI_DEBUG_PRINT((ACPI_DB_INFO, - "Unsupported event [0x%x]\n", event)); + acpi_handle_debug(handle, "Unsupported event [0x%x]\n", event); break; } @@ -1812,11 +1814,12 @@ static void acpi_video_dev_register_backlight(struct acpi_video_device *device) &device->cooling_dev->device.kobj, "thermal_cooling"); if (result) - printk(KERN_ERR PREFIX "Create sysfs link\n"); + pr_info("sysfs link creation failed\n"); + result = sysfs_create_link(&device->cooling_dev->device.kobj, &device->dev->dev.kobj, "device"); if (result) - printk(KERN_ERR PREFIX "Create sysfs link\n"); + pr_info("Reverse sysfs link creation failed\n"); } static void acpi_video_run_bcl_for_osi(struct acpi_video_bus *video) @@ -2030,7 +2033,7 @@ static int acpi_video_bus_add(struct acpi_device *device) acpi_video_bus_match, NULL, device, NULL); if (status == AE_ALREADY_EXISTS) { - printk(KERN_WARNING FW_BUG + pr_info(FW_BUG "Duplicate ACPI video bus devices for the" " same VGA controller, please try module " "parameter \"video.allow_duplicates=1\"" @@ -2073,7 +2076,7 @@ static int acpi_video_bus_add(struct acpi_device *device) if (error) goto err_put_video; - printk(KERN_INFO PREFIX "%s [%s] (multi-head: %s rom: %s post: %s)\n", + pr_info("%s [%s] (multi-head: %s rom: %s post: %s)\n", ACPI_VIDEO_DEVICE_NAME, acpi_device_bid(device), video->flags.multihead ? "yes" : "no", video->flags.rom ? "yes" : "no", diff --git a/drivers/acpi/sysfs.c b/drivers/acpi/sysfs.c index 152e8eec6f13..53125f08779c 100644 --- a/drivers/acpi/sysfs.c +++ b/drivers/acpi/sysfs.c @@ -59,7 +59,6 @@ static const struct acpi_dlayer acpi_debug_layers[] = { ACPI_DEBUG_INIT(ACPI_SYSTEM_COMPONENT), ACPI_DEBUG_INIT(ACPI_THERMAL_COMPONENT), ACPI_DEBUG_INIT(ACPI_MEMORY_DEVICE_COMPONENT), - ACPI_DEBUG_INIT(ACPI_VIDEO_COMPONENT), ACPI_DEBUG_INIT(ACPI_PROCESSOR_COMPONENT), }; diff --git a/include/acpi/acpi_drivers.h b/include/acpi/acpi_drivers.h index 25df44b2ed25..fdf93f83ebaf 100644 --- a/include/acpi/acpi_drivers.h +++ b/include/acpi/acpi_drivers.h @@ -22,7 +22,6 @@ #define ACPI_SYSTEM_COMPONENT 0x02000000 #define ACPI_THERMAL_COMPONENT 0x04000000 #define ACPI_MEMORY_DEVICE_COMPONENT 0x08000000 -#define ACPI_VIDEO_COMPONENT 0x10000000 #define ACPI_PROCESSOR_COMPONENT 0x20000000 /* -- cgit v1.2.3 From f86b15a1e6541446a4a5f69bcc211348238db97f Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Wed, 3 Feb 2021 19:49:21 +0100 Subject: ACPI: thermal: Clean up printing messages Replace the ACPI_DEBUG_PRINT() instances in thermal.c with acpi_handle_debug() calls and modify the ACPI_THERMAL_TRIPS_EXCEPTION() macro in there to use acpi_handle_info() internally, which among other things causes the excessive log level of the messages printed by it to be increased. Drop the _COMPONENT and ACPI_MODULE_NAME() definitions that are not used any more from thermal.c, drop the no longer needed ACPI_THERMAL_COMPONENT definition from the headers and update the documentation accordingly. While at it, add a pr_fmt() definition to thermal.c, drop the PREFIX definition from there and replace some pr_warn() calls with pr_info() or acpi_handle_info() to reduce the excessive log level and (in the latter case) facilitate easier identification of the message source. Signed-off-by: Rafael J. Wysocki Reviewed-by: Hanjun Guo Reviewed-by: Hans de Goede --- Documentation/firmware-guide/acpi/debug.rst | 1 - drivers/acpi/sysfs.c | 1 - drivers/acpi/thermal.c | 87 ++++++++++++++--------------- include/acpi/acpi_drivers.h | 1 - 4 files changed, 43 insertions(+), 47 deletions(-) (limited to 'Documentation') diff --git a/Documentation/firmware-guide/acpi/debug.rst b/Documentation/firmware-guide/acpi/debug.rst index 761fae76bcce..03cd4e25fc45 100644 --- a/Documentation/firmware-guide/acpi/debug.rst +++ b/Documentation/firmware-guide/acpi/debug.rst @@ -57,7 +57,6 @@ shows the supported mask values, currently these:: ACPI_PCI_COMPONENT 0x00400000 ACPI_CONTAINER_COMPONENT 0x01000000 ACPI_SYSTEM_COMPONENT 0x02000000 - ACPI_THERMAL_COMPONENT 0x04000000 ACPI_MEMORY_DEVICE_COMPONENT 0x08000000 ACPI_PROCESSOR_COMPONENT 0x20000000 diff --git a/drivers/acpi/sysfs.c b/drivers/acpi/sysfs.c index 53125f08779c..8baf7644a0d0 100644 --- a/drivers/acpi/sysfs.c +++ b/drivers/acpi/sysfs.c @@ -57,7 +57,6 @@ static const struct acpi_dlayer acpi_debug_layers[] = { ACPI_DEBUG_INIT(ACPI_PCI_COMPONENT), ACPI_DEBUG_INIT(ACPI_CONTAINER_COMPONENT), ACPI_DEBUG_INIT(ACPI_SYSTEM_COMPONENT), - ACPI_DEBUG_INIT(ACPI_THERMAL_COMPONENT), ACPI_DEBUG_INIT(ACPI_MEMORY_DEVICE_COMPONENT), ACPI_DEBUG_INIT(ACPI_PROCESSOR_COMPONENT), }; diff --git a/drivers/acpi/thermal.c b/drivers/acpi/thermal.c index 859b1de31ddc..4f906380b031 100644 --- a/drivers/acpi/thermal.c +++ b/drivers/acpi/thermal.c @@ -13,6 +13,8 @@ * concepts of 'multiple limiters', upper/lower limits, etc. */ +#define pr_fmt(fmt) "ACPI: thermal: " fmt + #include #include #include @@ -29,8 +31,6 @@ #include #include -#define PREFIX "ACPI: " - #define ACPI_THERMAL_CLASS "thermal_zone" #define ACPI_THERMAL_DEVICE_NAME "Thermal Zone" #define ACPI_THERMAL_NOTIFY_TEMPERATURE 0x80 @@ -43,9 +43,6 @@ #define ACPI_THERMAL_MAX_ACTIVE 10 #define ACPI_THERMAL_MAX_LIMIT_STR_LEN 65 -#define _COMPONENT ACPI_THERMAL_COMPONENT -ACPI_MODULE_NAME("thermal"); - MODULE_AUTHOR("Paul Diefenbaugh"); MODULE_DESCRIPTION("ACPI Thermal Zone Driver"); MODULE_LICENSE("GPL"); @@ -197,8 +194,9 @@ static int acpi_thermal_get_temperature(struct acpi_thermal *tz) return -ENODEV; tz->temperature = tmp; - ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Temperature is %lu dK\n", - tz->temperature)); + + acpi_handle_debug(tz->device->handle, "Temperature is %lu dK\n", + tz->temperature); return 0; } @@ -216,8 +214,8 @@ static int acpi_thermal_get_polling_frequency(struct acpi_thermal *tz) return -ENODEV; tz->polling_frequency = tmp; - ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Polling frequency is %lu dS\n", - tz->polling_frequency)); + acpi_handle_debug(tz->device->handle, "Polling frequency is %lu dS\n", + tz->polling_frequency); return 0; } @@ -254,12 +252,12 @@ static int acpi_thermal_set_cooling_mode(struct acpi_thermal *tz, int mode) * 2.TODO: Devices listed in _PSL, _ALx, _TZD may change. * We need to re-bind the cooling devices of a thermal zone when this occurs. */ -#define ACPI_THERMAL_TRIPS_EXCEPTION(flags, str) \ +#define ACPI_THERMAL_TRIPS_EXCEPTION(flags, tz, str) \ do { \ if (flags != ACPI_TRIPS_INIT) \ - ACPI_EXCEPTION((AE_INFO, AE_ERROR, \ + acpi_handle_info(tz->device->handle, \ "ACPI thermal trip point %s changed\n" \ - "Please send acpidump to linux-acpi@vger.kernel.org", str)); \ + "Please report to linux-acpi@vger.kernel.org\n", str); \ } while (0) static int acpi_thermal_trips_update(struct acpi_thermal *tz, int flag) @@ -283,17 +281,17 @@ static int acpi_thermal_trips_update(struct acpi_thermal *tz, int flag) */ if (ACPI_FAILURE(status)) { tz->trips.critical.flags.valid = 0; - ACPI_DEBUG_PRINT((ACPI_DB_INFO, - "No critical threshold\n")); + acpi_handle_debug(tz->device->handle, + "No critical threshold\n"); } else if (tmp <= 2732) { - pr_warn(FW_BUG "Invalid critical threshold (%llu)\n", + pr_info(FW_BUG "Invalid critical threshold (%llu)\n", tmp); tz->trips.critical.flags.valid = 0; } else { tz->trips.critical.flags.valid = 1; - ACPI_DEBUG_PRINT((ACPI_DB_INFO, + acpi_handle_debug(tz->device->handle, "Found critical threshold [%lu]\n", - tz->trips.critical.temperature)); + tz->trips.critical.temperature); } if (tz->trips.critical.flags.valid == 1) { if (crt == -1) { @@ -305,8 +303,8 @@ static int acpi_thermal_trips_update(struct acpi_thermal *tz, int flag) * Allow override critical threshold */ if (crt_k > tz->trips.critical.temperature) - pr_warn(PREFIX "Critical threshold %d C\n", - crt); + pr_info("Critical threshold %d C\n", crt); + tz->trips.critical.temperature = crt_k; } } @@ -318,14 +316,14 @@ static int acpi_thermal_trips_update(struct acpi_thermal *tz, int flag) "_HOT", NULL, &tmp); if (ACPI_FAILURE(status)) { tz->trips.hot.flags.valid = 0; - ACPI_DEBUG_PRINT((ACPI_DB_INFO, - "No hot threshold\n")); + acpi_handle_debug(tz->device->handle, + "No hot threshold\n"); } else { tz->trips.hot.temperature = tmp; tz->trips.hot.flags.valid = 1; - ACPI_DEBUG_PRINT((ACPI_DB_INFO, - "Found hot threshold [%lu]\n", - tz->trips.hot.temperature)); + acpi_handle_debug(tz->device->handle, + "Found hot threshold [%lu]\n", + tz->trips.hot.temperature); } } @@ -378,7 +376,8 @@ static int acpi_thermal_trips_update(struct acpi_thermal *tz, int flag) status = acpi_evaluate_reference(tz->device->handle, "_PSL", NULL, &devices); if (ACPI_FAILURE(status)) { - pr_warn(PREFIX "Invalid passive threshold\n"); + acpi_handle_info(tz->device->handle, + "Invalid passive threshold\n"); tz->trips.passive.flags.valid = 0; } else @@ -388,12 +387,12 @@ static int acpi_thermal_trips_update(struct acpi_thermal *tz, int flag) sizeof(struct acpi_handle_list))) { memcpy(&tz->trips.passive.devices, &devices, sizeof(struct acpi_handle_list)); - ACPI_THERMAL_TRIPS_EXCEPTION(flag, "device"); + ACPI_THERMAL_TRIPS_EXCEPTION(flag, tz, "device"); } } if ((flag & ACPI_TRIPS_PASSIVE) || (flag & ACPI_TRIPS_DEVICES)) { if (valid != tz->trips.passive.flags.valid) - ACPI_THERMAL_TRIPS_EXCEPTION(flag, "state"); + ACPI_THERMAL_TRIPS_EXCEPTION(flag, tz, "state"); } /* Active (optional) */ @@ -440,8 +439,8 @@ static int acpi_thermal_trips_update(struct acpi_thermal *tz, int flag) status = acpi_evaluate_reference(tz->device->handle, name, NULL, &devices); if (ACPI_FAILURE(status)) { - pr_warn(PREFIX "Invalid active%d threshold\n", - i); + acpi_handle_info(tz->device->handle, + "Invalid active%d threshold\n", i); tz->trips.active[i].flags.valid = 0; } else @@ -451,12 +450,12 @@ static int acpi_thermal_trips_update(struct acpi_thermal *tz, int flag) sizeof(struct acpi_handle_list))) { memcpy(&tz->trips.active[i].devices, &devices, sizeof(struct acpi_handle_list)); - ACPI_THERMAL_TRIPS_EXCEPTION(flag, "device"); + ACPI_THERMAL_TRIPS_EXCEPTION(flag, tz, "device"); } } if ((flag & ACPI_TRIPS_ACTIVE) || (flag & ACPI_TRIPS_DEVICES)) if (valid != tz->trips.active[i].flags.valid) - ACPI_THERMAL_TRIPS_EXCEPTION(flag, "state"); + ACPI_THERMAL_TRIPS_EXCEPTION(flag, tz, "state"); if (!tz->trips.active[i].flags.valid) break; @@ -469,7 +468,7 @@ static int acpi_thermal_trips_update(struct acpi_thermal *tz, int flag) if (ACPI_SUCCESS(status) && memcmp(&tz->devices, &devices, sizeof(devices))) { tz->devices = devices; - ACPI_THERMAL_TRIPS_EXCEPTION(flag, "device"); + ACPI_THERMAL_TRIPS_EXCEPTION(flag, tz, "device"); } } @@ -925,8 +924,8 @@ static void acpi_thermal_notify(struct acpi_device *device, u32 event) dev_name(&device->dev), event, 0); break; default: - ACPI_DEBUG_PRINT((ACPI_DB_INFO, - "Unsupported event [0x%x]\n", event)); + acpi_handle_debug(device->handle, "Unsupported event [0x%x]\n", + event); break; } } @@ -1074,7 +1073,7 @@ static int acpi_thermal_add(struct acpi_device *device) mutex_init(&tz->thermal_check_lock); INIT_WORK(&tz->thermal_check_work, acpi_thermal_check_fn); - pr_info(PREFIX "%s [%s] (%ld C)\n", acpi_device_name(device), + pr_info("%s [%s] (%ld C)\n", acpi_device_name(device), acpi_device_bid(device), deci_kelvin_to_celsius(tz->temperature)); goto end; @@ -1146,24 +1145,24 @@ static int acpi_thermal_resume(struct device *dev) static int thermal_act(const struct dmi_system_id *d) { if (act == 0) { - pr_notice(PREFIX "%s detected: " - "disabling all active thermal trip points\n", d->ident); + pr_notice("%s detected: disabling all active thermal trip points\n", + d->ident); act = -1; } return 0; } static int thermal_nocrt(const struct dmi_system_id *d) { - pr_notice(PREFIX "%s detected: " - "disabling all critical thermal trip point actions.\n", d->ident); + pr_notice("%s detected: disabling all critical thermal trip point actions.\n", + d->ident); nocrt = 1; return 0; } static int thermal_tzp(const struct dmi_system_id *d) { if (tzp == 0) { - pr_notice(PREFIX "%s detected: " - "enabling thermal zone polling\n", d->ident); + pr_notice("%s detected: enabling thermal zone polling\n", + d->ident); tzp = 300; /* 300 dS = 30 Seconds */ } return 0; @@ -1171,8 +1170,8 @@ static int thermal_tzp(const struct dmi_system_id *d) { static int thermal_psv(const struct dmi_system_id *d) { if (psv == 0) { - pr_notice(PREFIX "%s detected: " - "disabling all passive thermal trip points\n", d->ident); + pr_notice("%s detected: disabling all passive thermal trip points\n", + d->ident); psv = -1; } return 0; @@ -1225,7 +1224,7 @@ static int __init acpi_thermal_init(void) dmi_check_system(thermal_dmi_table); if (off) { - pr_notice(PREFIX "thermal control disabled\n"); + pr_notice("thermal control disabled\n"); return -ENODEV; } diff --git a/include/acpi/acpi_drivers.h b/include/acpi/acpi_drivers.h index fdf93f83ebaf..94d356fcc483 100644 --- a/include/acpi/acpi_drivers.h +++ b/include/acpi/acpi_drivers.h @@ -20,7 +20,6 @@ #define ACPI_PCI_COMPONENT 0x00400000 #define ACPI_CONTAINER_COMPONENT 0x01000000 #define ACPI_SYSTEM_COMPONENT 0x02000000 -#define ACPI_THERMAL_COMPONENT 0x04000000 #define ACPI_MEMORY_DEVICE_COMPONENT 0x08000000 #define ACPI_PROCESSOR_COMPONENT 0x20000000 -- cgit v1.2.3 From 6acbd614c2c8d3b8de5fb7605d6e24b9b3a8a17b Mon Sep 17 00:00:00 2001 From: Bert Vermeulen Date: Wed, 20 Jan 2021 14:59:27 +0100 Subject: spi: Realtek RTL838x/RTL839x SPI controller Signed-off-by: Bert Vermeulen Link: https://lore.kernel.org/r/20210120135928.246054-2-bert@biot.com Signed-off-by: Mark Brown --- .../devicetree/bindings/spi/realtek,rtl-spi.yaml | 41 ++++++++++++++++++++++ 1 file changed, 41 insertions(+) create mode 100644 Documentation/devicetree/bindings/spi/realtek,rtl-spi.yaml (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/spi/realtek,rtl-spi.yaml b/Documentation/devicetree/bindings/spi/realtek,rtl-spi.yaml new file mode 100644 index 000000000000..30a62a211984 --- /dev/null +++ b/Documentation/devicetree/bindings/spi/realtek,rtl-spi.yaml @@ -0,0 +1,41 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/spi/realtek,rtl-spi.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Realtek RTL838x/RTL839x SPI controller + +maintainers: + - Bert Vermeulen + - Birger Koblitz + +allOf: + - $ref: "spi-controller.yaml#" + +properties: + compatible: + oneOf: + - const: realtek,rtl8380-spi + - const: realtek,rtl8382-spi + - const: realtek,rtl8391-spi + - const: realtek,rtl8392-spi + - const: realtek,rtl8393-spi + + reg: + maxItems: 1 + +required: + - compatible + - reg + +unevaluatedProperties: false + +examples: + - | + spi: spi@1200 { + compatible = "realtek,rtl8382-spi"; + reg = <0x1200 0x100>; + #address-cells = <1>; + #size-cells = <0>; + }; -- cgit v1.2.3 From 8e5cee476902ae39d90e425a6fa976e1b901544c Mon Sep 17 00:00:00 2001 From: Bert Vermeulen Date: Tue, 19 Jan 2021 10:21:05 +0100 Subject: dt-bindings: mips: Add support for RTL83xx SoC series Signed-off-by: Bert Vermeulen Signed-off-by: Thomas Bogendoerfer --- .../devicetree/bindings/mips/realtek-rtl.yaml | 24 ++++++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 Documentation/devicetree/bindings/mips/realtek-rtl.yaml (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/mips/realtek-rtl.yaml b/Documentation/devicetree/bindings/mips/realtek-rtl.yaml new file mode 100644 index 000000000000..aadff8ce0f49 --- /dev/null +++ b/Documentation/devicetree/bindings/mips/realtek-rtl.yaml @@ -0,0 +1,24 @@ +# SPDX-License-Identifier: GPL-2.0-or-later OR BSD-2-Clause +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/mips/realtek-rtl.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Realtek RTL83xx/93xx SoC series device tree bindings + +maintainers: + - Bert Vermeulen + - Sander Vanheule + +properties: + $nodename: + const: "/" + compatible: + oneOf: + # RTL8382-based boards + - items: + - enum: + - cisco,sg220-26 + - const: realtek,rtl8382-soc + +additionalProperties: true -- cgit v1.2.3 From 8310a99107b1afcf41e65fa1be21452df0cbdeff Mon Sep 17 00:00:00 2001 From: Bert Vermeulen Date: Tue, 19 Jan 2021 10:21:08 +0100 Subject: dt-bindings: Add Cisco prefix to vendor list Signed-off-by: Bert Vermeulen Acked-by: Rob Herring Signed-off-by: Thomas Bogendoerfer --- Documentation/devicetree/bindings/vendor-prefixes.yaml | 2 ++ 1 file changed, 2 insertions(+) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/vendor-prefixes.yaml b/Documentation/devicetree/bindings/vendor-prefixes.yaml index 041ae90b0d8f..e6e3a51fc2e3 100644 --- a/Documentation/devicetree/bindings/vendor-prefixes.yaml +++ b/Documentation/devicetree/bindings/vendor-prefixes.yaml @@ -229,6 +229,8 @@ patternProperties: description: Computadora Industrial Abierta Argentina "^cirrus,.*": description: Cirrus Logic, Inc. + "^cisco,.*": + description: Cisco Systems, Inc. "^cloudengines,.*": description: Cloud Engines, Inc. "^cnm,.*": -- cgit v1.2.3 From 78f101a1b25848a364c632237ee6a7a6ec468235 Mon Sep 17 00:00:00 2001 From: Borislav Petkov Date: Tue, 22 Dec 2020 14:05:55 +0100 Subject: Documentation/submitting-patches: Add blurb about backtraces in commit messages Document that backtraces in commit messages should be trimmed down to the useful information only. This has been carved out from a tip subsystem handbook patchset by Thomas Gleixner: https://lkml.kernel.org/r/20181107171010.421878737@linutronix.de and incorporates follow-on comments. Signed-off-by: Borislav Petkov Signed-off-by: Jonathan Corbet --- Documentation/process/submitting-patches.rst | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) (limited to 'Documentation') diff --git a/Documentation/process/submitting-patches.rst b/Documentation/process/submitting-patches.rst index 7f48cccc75cd..8c991c863628 100644 --- a/Documentation/process/submitting-patches.rst +++ b/Documentation/process/submitting-patches.rst @@ -684,6 +684,26 @@ generates appropriate diffstats by default.) See more details on the proper patch format in the following references. +Backtraces in commit mesages +^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Backtraces help document the call chain leading to a problem. However, +not all backtraces are helpful. For example, early boot call chains are +unique and obvious. Copying the full dmesg output verbatim, however, +adds distracting information like timestamps, module lists, register and +stack dumps. + +Therefore, the most useful backtraces should distill the relevant +information from the dump, which makes it easier to focus on the real +issue. Here is an example of a well-trimmed backtrace:: + + unchecked MSR access error: WRMSR to 0xd51 (tried to write 0x0000000000000064) + at rIP: 0xffffffffae059994 (native_write_msr+0x4/0x20) + Call Trace: + mba_wrmsr + update_domains + rdtgroup_mkdir + .. _explicit_in_reply_to: Explicit In-Reply-To headers -- cgit v1.2.3 From 4ba1d726c45d644525883565ff5850ddc7b4a718 Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Tue, 2 Feb 2021 19:32:43 -0800 Subject: Documentation: /proc/loadavg: add 3 more field descriptions Update contents of /proc/loadavg: add 3 more fields. Signed-off-by: Randy Dunlap Cc: linux-doc@vger.kernel.org Link: https://lore.kernel.org/r/fe55b139-bd03-4762-199b-83be873cf7dd@infradead.org Signed-off-by: Jonathan Corbet --- Documentation/filesystems/proc.rst | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'Documentation') diff --git a/Documentation/filesystems/proc.rst b/Documentation/filesystems/proc.rst index 2fa69f710e2a..9abdba17565e 100644 --- a/Documentation/filesystems/proc.rst +++ b/Documentation/filesystems/proc.rst @@ -687,7 +687,10 @@ files are there, and which are missing. kcore Kernel core image (can be ELF or A.OUT(deprecated in 2.4)) kmsg Kernel messages ksyms Kernel symbol table - loadavg Load average of last 1, 5 & 15 minutes + loadavg Load average of last 1, 5 & 15 minutes; + number of processes currently runnable (running or on ready queue); + total number of processes in system; + last pid created. locks Kernel locks meminfo Memory info misc Miscellaneous -- cgit v1.2.3 From 26606ce072d48ab82f640f75ab9673ee10ab4a5a Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Mon, 24 Aug 2020 21:55:58 -0700 Subject: coding-style.rst: Avoid comma statements Commas are not how statements are terminated. Always use semicolons and braces if necessary. Signed-off-by: Joe Perches Link: https://lore.kernel.org/r/2a97b738bba335434461a5a918053a49c1fb6af4.1598331148.git.joe@perches.com Signed-off-by: Jonathan Corbet --- Documentation/process/coding-style.rst | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) (limited to 'Documentation') diff --git a/Documentation/process/coding-style.rst b/Documentation/process/coding-style.rst index 98227226c4e5..a1e061149e0d 100644 --- a/Documentation/process/coding-style.rst +++ b/Documentation/process/coding-style.rst @@ -69,9 +69,26 @@ something to hide: if (condition) do_this; do_something_everytime; +Don't use commas to avoid using braces: + +.. code-block:: c + + if (condition) + do_this(), do_that(); + +Always uses braces for multiple statements: + +.. code-block:: c + + if (condition) { + do_this(); + do_that(); + } + Don't put multiple assignments on a single line either. Kernel coding style is super simple. Avoid tricky expressions. + Outside of comments, documentation and except in Kconfig, spaces are never used for indentation, and the above example is deliberately broken. -- cgit v1.2.3 From dd58e649742a5eabd327d47096f12d3302d908f1 Mon Sep 17 00:00:00 2001 From: André Almeida Date: Fri, 29 Jan 2021 22:45:46 -0300 Subject: docs: Make syscalls' helpers naming consistent MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The documentation explains the need to create internal syscalls' helpers, and that they should be called `kern_xyzzy()`. However, the comment at include/linux/syscalls.h says that they should be named as `ksys_xyzzy()`, and so are all the helpers declared bellow it. Change the documentation to reflect this. Fixes: 819671ff849b ("syscalls: define and explain goal to not call syscalls in the kernel") Signed-off-by: André Almeida Reviewed-by: Dominik Brodowski Link: https://lore.kernel.org/r/20210130014547.123006-1-andrealmeid@collabora.com Signed-off-by: Jonathan Corbet --- Documentation/process/adding-syscalls.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Documentation') diff --git a/Documentation/process/adding-syscalls.rst b/Documentation/process/adding-syscalls.rst index 02857b5ad2b5..906c47f1a9e5 100644 --- a/Documentation/process/adding-syscalls.rst +++ b/Documentation/process/adding-syscalls.rst @@ -501,7 +501,7 @@ table, but not from elsewhere in the kernel. If the syscall functionality is useful to be used within the kernel, needs to be shared between an old and a new syscall, or needs to be shared between a syscall and its compatibility variant, it should be implemented by means of a "helper" function (such as -``kern_xyzzy()``). This kernel function may then be called within the +``ksys_xyzzy()``). This kernel function may then be called within the syscall stub (``sys_xyzzy()``), the compatibility syscall stub (``compat_sys_xyzzy()``), and/or other kernel code. -- cgit v1.2.3 From 61ffd285bddc8666f23d36f78bf8e5c2e2c92c04 Mon Sep 17 00:00:00 2001 From: André Almeida Date: Fri, 29 Jan 2021 22:45:47 -0300 Subject: Documentation: admin-guide: Update kvm/xen config option MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Since commit 9bba03d4473d ("kconfig: remove 'kvmconfig' and 'xenconfig' shorthands") kvm/xen config shortcuts are not available anymore. Update the file to reflect how they should be used, with the full filename. Signed-off-by: André Almeida Link: https://lore.kernel.org/r/20210130014547.123006-2-andrealmeid@collabora.com Signed-off-by: Jonathan Corbet --- Documentation/admin-guide/README.rst | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'Documentation') diff --git a/Documentation/admin-guide/README.rst b/Documentation/admin-guide/README.rst index 261b7b4cca1f..35314b63008c 100644 --- a/Documentation/admin-guide/README.rst +++ b/Documentation/admin-guide/README.rst @@ -226,10 +226,11 @@ Configuring the kernel all module options to built in (=y) options. You can also preserve modules by LMC_KEEP. - "make kvmconfig" Enable additional options for kvm guest kernel support. + "make kvm_guest.config" Enable additional options for kvm guest kernel + support. - "make xenconfig" Enable additional options for xen dom0 guest kernel - support. + "make xen.config" Enable additional options for xen dom0 guest kernel + support. "make tinyconfig" Configure the tiniest possible kernel. -- cgit v1.2.3 From 8fa4e9388006bd2964e39cba241d8e59e5641438 Mon Sep 17 00:00:00 2001 From: Flavio Suligoi Date: Fri, 29 Jan 2021 14:20:35 +0100 Subject: docs: thermal: fix spelling mistakes Signed-off-by: Flavio Suligoi Reviewed-by: Viresh Kumar Link: https://lore.kernel.org/r/20210129132035.16967-1-f.suligoi@asem.it Signed-off-by: Jonathan Corbet --- Documentation/driver-api/thermal/sysfs-api.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'Documentation') diff --git a/Documentation/driver-api/thermal/sysfs-api.rst b/Documentation/driver-api/thermal/sysfs-api.rst index e7520cb439ac..71da7dc8c0ba 100644 --- a/Documentation/driver-api/thermal/sysfs-api.rst +++ b/Documentation/driver-api/thermal/sysfs-api.rst @@ -54,7 +54,7 @@ temperature) and throttle appropriate devices. trips: the total number of trip points this thermal zone supports. mask: - Bit string: If 'n'th bit is set, then trip point 'n' is writeable. + Bit string: If 'n'th bit is set, then trip point 'n' is writable. devdata: device private data ops: @@ -406,7 +406,7 @@ Thermal cooling device sys I/F, created once it's registered:: |---stats/reset: Writing any value resets the statistics |---stats/time_in_state_ms: Time (msec) spent in various cooling states |---stats/total_trans: Total number of times cooling state is changed - |---stats/trans_table: Cooing state transition table + |---stats/trans_table: Cooling state transition table Then next two dynamic attributes are created/removed in pairs. They represent @@ -779,5 +779,5 @@ emergency poweroff kicks in after the delay has elapsed and shuts down the system. If set to 0 emergency poweroff will not be supported. So a carefully -profiled non-zero positive value is a must for emergerncy poweroff to be +profiled non-zero positive value is a must for emergency poweroff to be triggered. -- cgit v1.2.3 From ea1d838980f4afe457a48773dfe142af58aba8bd Mon Sep 17 00:00:00 2001 From: "Nícolas F. R. A. Prado" Date: Thu, 28 Jan 2021 01:01:25 +0000 Subject: docs: Enable usage of relative paths to docs on automarkup MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Previously, a cross-reference to another document could only be created by writing the full path to the document starting from the Documentation/ directory. Extend this to also allow relative paths to be used. A relative path would be just the path, like ../filename.rst, while the absolute path still needs to start from Documentation, like Documentation/filename.rst. As part of this change, the .rst extension is now required for both types of paths, since not requiring it would cause the regex to be too generic. Suggested-by: Jonathan Corbet Signed-off-by: Nícolas F. R. A. Prado Link: https://lore.kernel.org/r/20210128010028.58541-2-nfraprado@protonmail.com [jc: Tweaked the regex to recognize .txt too] Signed-off-by: Jonathan Corbet --- Documentation/sphinx/automarkup.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'Documentation') diff --git a/Documentation/sphinx/automarkup.py b/Documentation/sphinx/automarkup.py index 953b24b6e2b4..acf5473002f3 100644 --- a/Documentation/sphinx/automarkup.py +++ b/Documentation/sphinx/automarkup.py @@ -51,7 +51,7 @@ RE_typedef = re.compile(r'\b(typedef)\s+([a-zA-Z_]\w+)', flags=ascii_p3) # Detects a reference to a documentation page of the form Documentation/... with # an optional extension # -RE_doc = re.compile(r'\bDocumentation(/[\w\-_/]+)(\.\w+)*') +RE_doc = re.compile(r'(\bDocumentation/)?((\.\./)*[\w\-/]+)\.(rst|txt)') RE_namespace = re.compile(r'^\s*..\s*c:namespace::\s*(\S+)\s*$') @@ -234,7 +234,10 @@ def markup_doc_ref(docname, app, match): # # Go through the dance of getting an xref out of the std domain # - target = match.group(1) + absolute = match.group(1) + target = match.group(2) + if absolute: + target = "/" + target xref = None pxref = addnodes.pending_xref('', refdomain = 'std', reftype = 'doc', reftarget = target, modname = None, -- cgit v1.2.3 From 1e013ff7cb54a0045c78d7426bd5369ed7f82260 Mon Sep 17 00:00:00 2001 From: "Nícolas F. R. A. Prado" Date: Thu, 28 Jan 2021 01:01:36 +0000 Subject: docs: Document cross-referencing using relative path MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Update the Cross-referencing section to explain how to create a cross-reference to a document using relative paths and with no additional syntax, by relying on automarkup.py. Signed-off-by: Nícolas F. R. A. Prado Link: https://lore.kernel.org/r/20210128010028.58541-3-nfraprado@protonmail.com Signed-off-by: Jonathan Corbet --- Documentation/doc-guide/sphinx.rst | 30 ++++++++++++++++++++---------- 1 file changed, 20 insertions(+), 10 deletions(-) (limited to 'Documentation') diff --git a/Documentation/doc-guide/sphinx.rst b/Documentation/doc-guide/sphinx.rst index 36ac2166ad67..ec3e71f56009 100644 --- a/Documentation/doc-guide/sphinx.rst +++ b/Documentation/doc-guide/sphinx.rst @@ -340,16 +340,26 @@ Rendered as: Cross-referencing ----------------- -Cross-referencing from one documentation page to another can be done by passing -the path to the file starting from the Documentation folder. -For example, to cross-reference to this page (the .rst extension is optional):: - - See Documentation/doc-guide/sphinx.rst. - -If you want to use a relative path, you need to use Sphinx's ``doc`` directive. -For example, referencing this page from the same directory would be done as:: - - See :doc:`sphinx`. +Cross-referencing from one documentation page to another can be done simply by +writing the path to the document file, no special syntax required. The path can +be either absolute or relative. For absolute paths, start it with +"Documentation/". For example, to cross-reference to this page, all the +following are valid options, depending on the current document's directory (note +that the ``.rst`` extension is required):: + + See Documentation/doc-guide/sphinx.rst. This always works. + Take a look at sphinx.rst, which is at this same directory. + Read ../sphinx.rst, which is one directory above. + +If you want the link to have a different rendered text other than the document's +title, you need to use Sphinx's ``doc`` role. For example:: + + See :doc:`my custom link text for document sphinx `. + +For most use cases, the former is preferred, as it is cleaner and more suited +for people reading the source files. If you come across a ``:doc:`` usage that +isn't adding any value, please feel free to convert it to just the document +path. For information on cross-referencing to kernel-doc functions or types, see Documentation/doc-guide/kernel-doc.rst. -- cgit v1.2.3 From df91785a22e2505d2ac668f1d3e6b6e6d8ba627a Mon Sep 17 00:00:00 2001 From: Olivier Moysan Date: Fri, 5 Feb 2021 11:44:03 +0100 Subject: ASoC: dt-bindings: add mclk provider support to stm32 i2s Add master clock provider support to STM32 I2S. Reviewed-by: Rob Herring Signed-off-by: Olivier Moysan Link: https://lore.kernel.org/r/20210205104404.18786-2-olivier.moysan@foss.st.com Signed-off-by: Mark Brown --- Documentation/devicetree/bindings/sound/st,stm32-i2s.yaml | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/sound/st,stm32-i2s.yaml b/Documentation/devicetree/bindings/sound/st,stm32-i2s.yaml index f32410890589..6feb5a09c184 100644 --- a/Documentation/devicetree/bindings/sound/st,stm32-i2s.yaml +++ b/Documentation/devicetree/bindings/sound/st,stm32-i2s.yaml @@ -54,6 +54,10 @@ properties: resets: maxItems: 1 + "#clock-cells": + description: Configure the I2S device as MCLK clock provider. + const: 0 + required: - compatible - "#sound-dai-cells" -- cgit v1.2.3 From f08c74a3b52d126d053c741b906ee1ca2a4f3568 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Thu, 4 Feb 2021 14:00:22 +0100 Subject: ASoC: dt-bindings: renesas, rsnd: Group tuples in playback/capture properties To improve human readability and enable automatic validation, the tuples in "playback" and "capture" properties in sound device nodes should be grouped using angle brackets. Signed-off-by: Geert Uytterhoeven Link: https://lore.kernel.org/r/20210204130022.1646427-1-geert+renesas@glider.be Signed-off-by: Mark Brown --- Documentation/devicetree/bindings/sound/renesas,rsnd.yaml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/sound/renesas,rsnd.yaml b/Documentation/devicetree/bindings/sound/renesas,rsnd.yaml index 0fd37aa84947..2e1046513603 100644 --- a/Documentation/devicetree/bindings/sound/renesas,rsnd.yaml +++ b/Documentation/devicetree/bindings/sound/renesas,rsnd.yaml @@ -404,7 +404,7 @@ examples: /* DAI base */ rcar_sound,dai { dai0 { - playback = <&ssi5 &src5>; + playback = <&ssi5>, <&src5>; capture = <&ssi6>; }; dai1 { @@ -430,8 +430,8 @@ examples: bitclock-master = <&rsnd_endpoint0>; frame-master = <&rsnd_endpoint0>; - playback = <&ssi0 &src0 &dvc0>; - capture = <&ssi1 &src1 &dvc1>; + playback = <&ssi0>, <&src0>, <&dvc0>; + capture = <&ssi1>, <&src1>, <&dvc1>; }; }; }; -- cgit v1.2.3 From c0133e9dbac84bc6189ef5896b937201934a4ec5 Mon Sep 17 00:00:00 2001 From: Helen Koike Date: Mon, 25 Jan 2021 15:10:29 +0100 Subject: media: doc: pixfmt-yuv: Fix 4:4:4 subsampling info YUV 4:4:4 is not subsampled, fix this in the docs. Fixes: da785536e007 ("media: doc: pixfmt-yuv: Move all semi-planar YUV formats to common file") Signed-off-by: Helen Koike Reviewed-by: Laurent Pinchart Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- Documentation/userspace-api/media/v4l/pixfmt-yuv-planar.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'Documentation') diff --git a/Documentation/userspace-api/media/v4l/pixfmt-yuv-planar.rst b/Documentation/userspace-api/media/v4l/pixfmt-yuv-planar.rst index 7d4d39201a3f..1e0db602cc1b 100644 --- a/Documentation/userspace-api/media/v4l/pixfmt-yuv-planar.rst +++ b/Documentation/userspace-api/media/v4l/pixfmt-yuv-planar.rst @@ -396,9 +396,9 @@ number of lines as the luma plane. NV24 and NV42 ------------- -Semi-planar YUV 4:4:4 formats. The chroma plane is subsampled by 2 in the -horizontal direction. Chroma lines contain half the number of pixels and the -same number of bytes as luma lines, and the chroma plane contains the same +Semi-planar YUV 4:4:4 formats. The chroma plane is not subsampled. +Chroma lines contain the same number of pixels and twice the +number of bytes as luma lines, and the chroma plane contains the same number of lines as the luma plane. .. flat-table:: Sample 4x4 NV24 Image -- cgit v1.2.3 From 08979f160eb96120354cbc6a815e8296f52cdc0d Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Sat, 30 Jan 2021 10:08:42 +0100 Subject: media: media/dvb/dvbstb.svg: Antena -> Antenna Fix typo. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- Documentation/userspace-api/media/dvb/dvbstb.svg | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Documentation') diff --git a/Documentation/userspace-api/media/dvb/dvbstb.svg b/Documentation/userspace-api/media/dvb/dvbstb.svg index 87e68baa056b..6f0ba98f9bf9 100644 --- a/Documentation/userspace-api/media/dvb/dvbstb.svg +++ b/Documentation/userspace-api/media/dvb/dvbstb.svg @@ -2,7 +2,7 @@ image/svg+xmlAntena +x="1013.1317" y="5435.1221">Antenna Frontend CA Demux -- cgit v1.2.3 From 36a6c843fd0d8e02506681577e96dabd203dd8e8 Mon Sep 17 00:00:00 2001 From: Gabriel Krisman Bertazi Date: Fri, 5 Feb 2021 13:43:21 -0500 Subject: entry: Use different define for selector variable in SUD Michael Kerrisk suggested that, from an API perspective, it is a bad idea to share the PR_SYS_DISPATCH_ defines between the prctl operation and the selector variable. Therefore, define two new constants to be used by SUD's selector variable and update the corresponding documentation and test cases. While this changes the API syscall user dispatch has never been part of a Linux release, it will show up for the first time in 5.11. Suggested-by: Michael Kerrisk (man-pages) Signed-off-by: Gabriel Krisman Bertazi Signed-off-by: Thomas Gleixner Link: https://lore.kernel.org/r/20210205184321.2062251-1-krisman@collabora.com --- Documentation/admin-guide/syscall-user-dispatch.rst | 4 ++-- include/uapi/linux/prctl.h | 3 +++ kernel/entry/syscall_user_dispatch.c | 4 ++-- .../selftests/syscall_user_dispatch/sud_benchmark.c | 8 +++++--- tools/testing/selftests/syscall_user_dispatch/sud_test.c | 14 ++++++++------ 5 files changed, 20 insertions(+), 13 deletions(-) (limited to 'Documentation') diff --git a/Documentation/admin-guide/syscall-user-dispatch.rst b/Documentation/admin-guide/syscall-user-dispatch.rst index a380d6515774..60314953c728 100644 --- a/Documentation/admin-guide/syscall-user-dispatch.rst +++ b/Documentation/admin-guide/syscall-user-dispatch.rst @@ -70,8 +70,8 @@ trampoline code on the vDSO, that trampoline is never intercepted. [selector] is a pointer to a char-sized region in the process memory region, that provides a quick way to enable disable syscall redirection thread-wide, without the need to invoke the kernel directly. selector -can be set to PR_SYS_DISPATCH_ON or PR_SYS_DISPATCH_OFF. Any other -value should terminate the program with a SIGSYS. +can be set to SYSCALL_DISPATCH_FILTER_ALLOW or SYSCALL_DISPATCH_FILTER_BLOCK. +Any other value should terminate the program with a SIGSYS. Security Notes -------------- diff --git a/include/uapi/linux/prctl.h b/include/uapi/linux/prctl.h index 90deb41c8a34..667f1aed091c 100644 --- a/include/uapi/linux/prctl.h +++ b/include/uapi/linux/prctl.h @@ -251,5 +251,8 @@ struct prctl_mm_map { #define PR_SET_SYSCALL_USER_DISPATCH 59 # define PR_SYS_DISPATCH_OFF 0 # define PR_SYS_DISPATCH_ON 1 +/* The control values for the user space selector when dispatch is enabled */ +# define SYSCALL_DISPATCH_FILTER_ALLOW 0 +# define SYSCALL_DISPATCH_FILTER_BLOCK 1 #endif /* _LINUX_PRCTL_H */ diff --git a/kernel/entry/syscall_user_dispatch.c b/kernel/entry/syscall_user_dispatch.c index b0338a5625d9..c240302f56e2 100644 --- a/kernel/entry/syscall_user_dispatch.c +++ b/kernel/entry/syscall_user_dispatch.c @@ -50,10 +50,10 @@ bool syscall_user_dispatch(struct pt_regs *regs) if (unlikely(__get_user(state, sd->selector))) do_exit(SIGSEGV); - if (likely(state == PR_SYS_DISPATCH_OFF)) + if (likely(state == SYSCALL_DISPATCH_FILTER_ALLOW)) return false; - if (state != PR_SYS_DISPATCH_ON) + if (state != SYSCALL_DISPATCH_FILTER_BLOCK) do_exit(SIGSYS); } diff --git a/tools/testing/selftests/syscall_user_dispatch/sud_benchmark.c b/tools/testing/selftests/syscall_user_dispatch/sud_benchmark.c index 6689f1183dbf..073a03702ff5 100644 --- a/tools/testing/selftests/syscall_user_dispatch/sud_benchmark.c +++ b/tools/testing/selftests/syscall_user_dispatch/sud_benchmark.c @@ -22,6 +22,8 @@ # define PR_SET_SYSCALL_USER_DISPATCH 59 # define PR_SYS_DISPATCH_OFF 0 # define PR_SYS_DISPATCH_ON 1 +# define SYSCALL_DISPATCH_FILTER_ALLOW 0 +# define SYSCALL_DISPATCH_FILTER_BLOCK 1 #endif #ifdef __NR_syscalls @@ -55,8 +57,8 @@ unsigned long trapped_call_count = 0; unsigned long native_call_count = 0; char selector; -#define SYSCALL_BLOCK (selector = PR_SYS_DISPATCH_ON) -#define SYSCALL_UNBLOCK (selector = PR_SYS_DISPATCH_OFF) +#define SYSCALL_BLOCK (selector = SYSCALL_DISPATCH_FILTER_BLOCK) +#define SYSCALL_UNBLOCK (selector = SYSCALL_DISPATCH_FILTER_ALLOW) #define CALIBRATION_STEP 100000 #define CALIBRATE_TO_SECS 5 @@ -170,7 +172,7 @@ int main(void) syscall(MAGIC_SYSCALL_1); #ifdef TEST_BLOCKED_RETURN - if (selector == PR_SYS_DISPATCH_OFF) { + if (selector == SYSCALL_DISPATCH_FILTER_ALLOW) { fprintf(stderr, "Failed to return with selector blocked.\n"); exit(-1); } diff --git a/tools/testing/selftests/syscall_user_dispatch/sud_test.c b/tools/testing/selftests/syscall_user_dispatch/sud_test.c index 6498b050ef89..b5d592d4099e 100644 --- a/tools/testing/selftests/syscall_user_dispatch/sud_test.c +++ b/tools/testing/selftests/syscall_user_dispatch/sud_test.c @@ -18,6 +18,8 @@ # define PR_SET_SYSCALL_USER_DISPATCH 59 # define PR_SYS_DISPATCH_OFF 0 # define PR_SYS_DISPATCH_ON 1 +# define SYSCALL_DISPATCH_FILTER_ALLOW 0 +# define SYSCALL_DISPATCH_FILTER_BLOCK 1 #endif #ifndef SYS_USER_DISPATCH @@ -30,8 +32,8 @@ # define MAGIC_SYSCALL_1 (0xff00) /* Bad Linux syscall number */ #endif -#define SYSCALL_DISPATCH_ON(x) ((x) = 1) -#define SYSCALL_DISPATCH_OFF(x) ((x) = 0) +#define SYSCALL_DISPATCH_ON(x) ((x) = SYSCALL_DISPATCH_FILTER_BLOCK) +#define SYSCALL_DISPATCH_OFF(x) ((x) = SYSCALL_DISPATCH_FILTER_ALLOW) /* Test Summary: * @@ -56,7 +58,7 @@ TEST_SIGNAL(dispatch_trigger_sigsys, SIGSYS) { - char sel = 0; + char sel = SYSCALL_DISPATCH_FILTER_ALLOW; struct sysinfo info; int ret; @@ -79,7 +81,7 @@ TEST_SIGNAL(dispatch_trigger_sigsys, SIGSYS) TEST(bad_prctl_param) { - char sel = 0; + char sel = SYSCALL_DISPATCH_FILTER_ALLOW; int op; /* Invalid op */ @@ -220,7 +222,7 @@ TEST_SIGNAL(bad_selector, SIGSYS) sigset_t mask; struct sysinfo info; - glob_sel = 0; + glob_sel = SYSCALL_DISPATCH_FILTER_ALLOW; nr_syscalls_emulated = 0; si_code = 0; si_errno = 0; @@ -288,7 +290,7 @@ TEST(direct_dispatch_range) { int ret = 0; struct sysinfo info; - char sel = 0; + char sel = SYSCALL_DISPATCH_FILTER_ALLOW; /* * Instead of calculating libc addresses; allow the entire -- cgit v1.2.3 From 5e4cdca887fdb445f962b3dbc2a2514d7c025d9b Mon Sep 17 00:00:00 2001 From: Miquel Raynal Date: Thu, 21 Jan 2021 11:18:03 +0100 Subject: dt-bindings: i3c: Convert the bus description to yaml Attempting a conversion of the i3c.txt file to yaml schema with minimal content changes. Signed-off-by: Miquel Raynal Reviewed-by: Rob Herring Signed-off-by: Alexandre Belloni Link: https://lore.kernel.org/r/20210121101808.14654-2-miquel.raynal@bootlin.com --- Documentation/devicetree/bindings/i3c/i3c.txt | 140 ------------------- Documentation/devicetree/bindings/i3c/i3c.yaml | 179 +++++++++++++++++++++++++ 2 files changed, 179 insertions(+), 140 deletions(-) delete mode 100644 Documentation/devicetree/bindings/i3c/i3c.txt create mode 100644 Documentation/devicetree/bindings/i3c/i3c.yaml (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/i3c/i3c.txt b/Documentation/devicetree/bindings/i3c/i3c.txt deleted file mode 100644 index 4ffe059f0fec..000000000000 --- a/Documentation/devicetree/bindings/i3c/i3c.txt +++ /dev/null @@ -1,140 +0,0 @@ -Generic device tree bindings for I3C busses -=========================================== - -This document describes generic bindings that should be used to describe I3C -busses in a device tree. - -Required properties -------------------- - -- #address-cells - should be <3>. Read more about addresses below. -- #size-cells - should be <0>. -- compatible - name of the I3C master controller driving the I3C bus - -For other required properties e.g. to describe register sets, -clocks, etc. check the binding documentation of the specific driver. -The node describing an I3C bus should be named i3c-master. - -Optional properties -------------------- - -These properties may not be supported by all I3C master drivers. Each I3C -master bindings should specify which of them are supported. - -- i3c-scl-hz: frequency of the SCL signal used for I3C transfers. - When undefined the core sets it to 12.5MHz. - -- i2c-scl-hz: frequency of the SCL signal used for I2C transfers. - When undefined, the core looks at LVR (Legacy Virtual Register) - values of I2C devices described in the device tree to determine - the maximum I2C frequency. - -I2C devices -=========== - -Each I2C device connected to the bus should be described in a subnode. All -properties described in Documentation/devicetree/bindings/i2c/i2c.txt are -valid here, but several new properties have been added. - -New constraint on existing properties: --------------------------------------- -- reg: contains 3 cells - + first cell : still encoding the I2C address. 10 bit addressing is not - supported. Devices with 10 bit address can't be properly passed through - DEFSLVS command. - - + second cell: shall be 0 - - + third cell: shall encode the I3C LVR (Legacy Virtual Register) - bit[31:8]: unused/ignored - bit[7:5]: I2C device index. Possible values - * 0: I2C device has a 50 ns spike filter - * 1: I2C device does not have a 50 ns spike filter but supports high - frequency on SCL - * 2: I2C device does not have a 50 ns spike filter and is not tolerant - to high frequencies - * 3-7: reserved - - bit[4]: tell whether the device operates in FM (Fast Mode) or FM+ mode - * 0: FM+ mode - * 1: FM mode - - bit[3:0]: device type - * 0-15: reserved - -The I2C node unit-address should always match the first cell of the reg -property: @. - -I3C devices -=========== - -All I3C devices are supposed to support DAA (Dynamic Address Assignment), and -are thus discoverable. So, by default, I3C devices do not have to be described -in the device tree. -This being said, one might want to attach extra resources to these devices, -and those resources may have to be described in the device tree, which in turn -means we have to describe I3C devices. - -Another use case for describing an I3C device in the device tree is when this -I3C device has a static I2C address and we want to assign it a specific I3C -dynamic address before the DAA takes place (so that other devices on the bus -can't take this dynamic address). - -The I3C device should be names @,, -where device-type is describing the type of device connected on the bus -(gpio-controller, sensor, ...). - -Required properties -------------------- -- reg: contains 3 cells - + first cell : encodes the static I2C address. Should be 0 if the device does - not have one (0 is not a valid I2C address). - - + second and third cells: should encode the ProvisionalID. The second cell - contains the manufacturer ID left-shifted by 1. - The third cell contains ORing of the part ID - left-shifted by 16, the instance ID left-shifted - by 12 and the extra information. This encoding is - following the PID definition provided by the I3C - specification. - -Optional properties -------------------- -- assigned-address: dynamic address to be assigned to this device. This - property is only valid if the I3C device has a static - address (first cell of the reg property != 0). - - -Example: - - i3c-master@d040000 { - compatible = "cdns,i3c-master"; - clocks = <&coreclock>, <&i3csysclock>; - clock-names = "pclk", "sysclk"; - interrupts = <3 0>; - reg = <0x0d040000 0x1000>; - #address-cells = <3>; - #size-cells = <0>; - i2c-scl-hz = <100000>; - - /* I2C device. */ - nunchuk: nunchuk@52 { - compatible = "nintendo,nunchuk"; - reg = <0x52 0x0 0x10>; - }; - - /* I3C device with a static I2C address. */ - thermal_sensor: sensor@68,39200144004 { - reg = <0x68 0x392 0x144004>; - assigned-address = <0xa>; - }; - - /* - * I3C device without a static I2C address but requiring - * resources described in the DT. - */ - sensor@0,39200154004 { - reg = <0x0 0x392 0x154004>; - clocks = <&clock_provider 0>; - }; - }; diff --git a/Documentation/devicetree/bindings/i3c/i3c.yaml b/Documentation/devicetree/bindings/i3c/i3c.yaml new file mode 100644 index 000000000000..52042aa44d19 --- /dev/null +++ b/Documentation/devicetree/bindings/i3c/i3c.yaml @@ -0,0 +1,179 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/i3c/i3c.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: I3C bus binding + +maintainers: + - Alexandre Belloni + - Miquel Raynal + +description: | + I3C busses can be described with a node for the primary I3C controller device + and a set of child nodes for each I2C or I3C slave on the bus. Each of them + may, during the life of the bus, request mastership. + +properties: + $nodename: + pattern: "^i3c-master@[0-9a-f]+$" + + "#address-cells": + const: 3 + description: | + Each I2C device connected to the bus should be described in a subnode. + + All I3C devices are supposed to support DAA (Dynamic Address Assignment), + and are thus discoverable. So, by default, I3C devices do not have to be + described in the device tree. This being said, one might want to attach + extra resources to these devices, and those resources may have to be + described in the device tree, which in turn means we have to describe + I3C devices. + + Another use case for describing an I3C device in the device tree is when + this I3C device has a static I2C address and we want to assign it a + specific I3C dynamic address before the DAA takes place (so that other + devices on the bus can't take this dynamic address). + + "#size-cells": + const: 0 + + i3c-scl-hz: + description: | + Frequency of the SCL signal used for I3C transfers. When undefined, the + default value should be 12.5MHz. + + May not be supported by all controllers. + + i2c-scl-hz: + description: | + Frequency of the SCL signal used for I2C transfers. When undefined, the + default should be to look at LVR (Legacy Virtual Register) values of + I2C devices described in the device tree to determine the maximum I2C + frequency. + + May not be supported by all controllers. + +required: + - "#address-cells" + - "#size-cells" + +patternProperties: + "@[0-9a-f]+$": + type: object + description: | + I2C child, should be named: @ + + All properties described in Documentation/devicetree/bindings/i2c/i2c.txt + are valid here, except the reg property whose content is changed. + + properties: + compatible: + description: + Compatible of the I2C device. + + reg: + items: + - items: + - description: | + I2C address. 10 bit addressing is not supported. Devices with + 10-bit address can't be properly passed through DEFSLVS + command. + minimum: 0 + maximum: 0x7f + - const: 0 + - description: | + Shall encode the I3C LVR (Legacy Virtual Register): + bit[31:8]: unused/ignored + bit[7:5]: I2C device index. Possible values: + * 0: I2C device has a 50 ns spike filter + * 1: I2C device does not have a 50 ns spike filter but + supports high frequency on SCL + * 2: I2C device does not have a 50 ns spike filter and is + not tolerant to high frequencies + * 3-7: reserved + bit[4]: tell whether the device operates in FM (Fast Mode) + or FM+ mode: + * 0: FM+ mode + * 1: FM mode + bit[3:0]: device type + * 0-15: reserved + + required: + - compatible + - reg + + "@[0-9a-f]+,[0-9a-f]+$": + type: object + description: | + I3C child, should be named: @, + + properties: + reg: + items: + - items: + - description: | + Encodes the static I2C address. Should be 0 if the device does + not have one (0 is not a valid I2C address). + minimum: 0 + maximum: 0x7f + - description: | + First half of the Provisional ID (following the PID + definition provided by the I3C specification). + + Contains the manufacturer ID left-shifted by 1. + - description: | + Second half of the Provisional ID (following the PID + definition provided by the I3C specification). + + Contains the ORing of the part ID left-shifted by 16, + the instance ID left-shifted by 12 and extra information. + + assigned-address: + $ref: /schemas/types.yaml#/definitions/uint32 + minimum: 0x1 + maximum: 0xff + description: | + Dynamic address to be assigned to this device. This property is only + valid if the I3C device has a static address (first cell of the reg + property != 0). + + required: + - reg + +additionalProperties: true + +examples: + - | + i3c-master@d040000 { + compatible = "cdns,i3c-master"; + clocks = <&coreclock>, <&i3csysclock>; + clock-names = "pclk", "sysclk"; + interrupts = <3 0>; + reg = <0x0d040000 0x1000>; + #address-cells = <3>; + #size-cells = <0>; + i2c-scl-hz = <100000>; + + /* I2C device. */ + nunchuk: nunchuk@52 { + compatible = "nintendo,nunchuk"; + reg = <0x52 0x0 0x10>; + }; + + /* I3C device with a static I2C address. */ + thermal_sensor: sensor@68,39200144004 { + reg = <0x68 0x392 0x144004>; + assigned-address = <0xa>; + }; + + /* + * I3C device without a static I2C address but requiring + * resources described in the DT. + */ + sensor@0,39200154004 { + reg = <0x0 0x392 0x154004>; + clocks = <&clock_provider 0>; + }; + }; -- cgit v1.2.3 From de67276e66fcfcd404516eebfd6436239dd9882a Mon Sep 17 00:00:00 2001 From: Miquel Raynal Date: Thu, 21 Jan 2021 11:18:04 +0100 Subject: dt-bindings: i3c: mipi-hci: Include the bus binding Update a little bit the content to match the bus binding, including: - the node title should have been named after the description done in the historical i3c.txt file, ie: i3c-master@
- child nodes should be accepted even though the drivers do not currently support it - #address-cells and #size-cells are also mandatory and have specific values Cc: Nicolas Pitre Signed-off-by: Miquel Raynal Reviewed-by: Rob Herring Signed-off-by: Alexandre Belloni Link: https://lore.kernel.org/r/20210121101808.14654-3-miquel.raynal@bootlin.com --- Documentation/devicetree/bindings/i3c/mipi-i3c-hci.yaml | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/i3c/mipi-i3c-hci.yaml b/Documentation/devicetree/bindings/i3c/mipi-i3c-hci.yaml index 07a7b10163a3..04da001fc6ec 100644 --- a/Documentation/devicetree/bindings/i3c/mipi-i3c-hci.yaml +++ b/Documentation/devicetree/bindings/i3c/mipi-i3c-hci.yaml @@ -9,6 +9,9 @@ title: MIPI I3C HCI Device Tree Bindings maintainers: - Nicolas Pitre +allOf: + - $ref: /schemas/i3c/i3c.yaml# + description: | MIPI I3C Host Controller Interface @@ -36,12 +39,14 @@ required: - reg - interrupts -additionalProperties: false +unevaluatedProperties: false examples: - | - i3c@a0000000 { + i3c-master@a0000000 { compatible = "mipi-i3c-hci"; reg = <0xa0000000 0x2000>; interrupts = <89>; + #address-cells = <3>; + #size-cells = <0>; }; -- cgit v1.2.3 From 57f7c9ff1b3fdc2cccb377207e538bf5f3ab03cf Mon Sep 17 00:00:00 2001 From: Miquel Raynal Date: Thu, 21 Jan 2021 11:18:05 +0100 Subject: dt-bindings: Add vendor prefix for Silvaco Silvaco, Inc. is an EDA provider of software tools used for process and device development and for analog/mixed-signal, power IC and memory design [1]. [1] https://www.silvaco.com/company/profile/profile.html Signed-off-by: Miquel Raynal Acked-by: Rob Herring Signed-off-by: Alexandre Belloni Link: https://lore.kernel.org/r/20210121101808.14654-4-miquel.raynal@bootlin.com --- Documentation/devicetree/bindings/vendor-prefixes.yaml | 2 ++ 1 file changed, 2 insertions(+) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/vendor-prefixes.yaml b/Documentation/devicetree/bindings/vendor-prefixes.yaml index 041ae90b0d8f..df1b7971c07e 100644 --- a/Documentation/devicetree/bindings/vendor-prefixes.yaml +++ b/Documentation/devicetree/bindings/vendor-prefixes.yaml @@ -1075,6 +1075,8 @@ patternProperties: description: Shenzhen Sunchip Technology Co., Ltd "^SUNW,.*": description: Sun Microsystems, Inc + "^silvaco,.*": + description: Silvaco, Inc. "^swir,.*": description: Sierra Wireless "^syna,.*": -- cgit v1.2.3 From b8b0446f1f1afd58e5a9ba14ab2caa08797f3bb5 Mon Sep 17 00:00:00 2001 From: Miquel Raynal Date: Thu, 21 Jan 2021 11:18:06 +0100 Subject: dt-bindings: i3c: Describe Silvaco master binding Silvaco provide a dual-role I3C master. Description is rather simple: it needs a register mapping, three clocks and an interrupt. Signed-off-by: Miquel Raynal Reviewed-by: Rob Herring Signed-off-by: Alexandre Belloni Link: https://lore.kernel.org/r/20210121101808.14654-5-miquel.raynal@bootlin.com --- .../bindings/i3c/silvaco,i3c-master.yaml | 60 ++++++++++++++++++++++ 1 file changed, 60 insertions(+) create mode 100644 Documentation/devicetree/bindings/i3c/silvaco,i3c-master.yaml (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/i3c/silvaco,i3c-master.yaml b/Documentation/devicetree/bindings/i3c/silvaco,i3c-master.yaml new file mode 100644 index 000000000000..adb5165505aa --- /dev/null +++ b/Documentation/devicetree/bindings/i3c/silvaco,i3c-master.yaml @@ -0,0 +1,60 @@ +# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/i3c/silvaco,i3c-master.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Silvaco I3C master + +maintainers: + - Conor Culhane + +allOf: + - $ref: "i3c.yaml#" + +properties: + compatible: + const: silvaco,i3c-master-v1 + + reg: + maxItems: 1 + + interrupts: + maxItems: 1 + + clocks: + items: + - description: system clock + - description: bus clock + - description: other (slower) events clock + + clock-names: + items: + - const: pclk + - const: fast_clk + - const: slow_clk + + resets: + maxItems: 1 + +required: + - compatible + - reg + - interrupts + - clock-names + - clocks + +additionalProperties: true + +examples: + - | + i3c-master@a0000000 { + compatible = "silvaco,i3c-master"; + clocks = <&zynqmp_clk 71>, <&fclk>, <&sclk>; + clock-names = "pclk", "fast_clk", "slow_clk"; + interrupt-parent = <&gic>; + interrupts = <0 89 4>; + reg = <0xa0000000 0x1000>; + #address-cells = <3>; + #size-cells = <0>; + }; -- cgit v1.2.3 From 3b8fc144d9454ec9d6ab31ae2a34d67bfc8274a1 Mon Sep 17 00:00:00 2001 From: Alexandre Belloni Date: Tue, 2 Feb 2021 01:06:34 +0100 Subject: dt-bindings: rtc: pcf2127: update bindings The NXP pcf2127 supports reset-source. Signed-off-by: Alexandre Belloni Link: https://lore.kernel.org/r/20210202000634.3438575-1-alexandre.belloni@bootlin.com --- .../devicetree/bindings/rtc/nxp,pcf2127.yaml | 51 ++++++++++++++++++++++ .../devicetree/bindings/rtc/trivial-rtc.yaml | 6 +-- 2 files changed, 52 insertions(+), 5 deletions(-) create mode 100644 Documentation/devicetree/bindings/rtc/nxp,pcf2127.yaml (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/rtc/nxp,pcf2127.yaml b/Documentation/devicetree/bindings/rtc/nxp,pcf2127.yaml new file mode 100644 index 000000000000..cde7b1675ead --- /dev/null +++ b/Documentation/devicetree/bindings/rtc/nxp,pcf2127.yaml @@ -0,0 +1,51 @@ +# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/rtc/nxp,pcf2127.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: NXP PCF2127 Real Time Clock + +allOf: + - $ref: "rtc.yaml#" + +maintainers: + - Alexandre Belloni + +properties: + compatible: + const: nxp,pcf2127 + + reg: + maxItems: 1 + + interrupts: + maxItems: 1 + + start-year: true + + reset-source: true + +required: + - compatible + - reg + +additionalProperties: false + +examples: + - | + #include + i2c { + #address-cells = <1>; + #size-cells = <0>; + + rtc@51 { + compatible = "nxp,pcf2127"; + reg = <0x51>; + pinctrl-0 = <&rtc_nint_pins>; + interrupts-extended = <&gpio1 16 IRQ_TYPE_LEVEL_HIGH>; + reset-source; + }; + }; + +... diff --git a/Documentation/devicetree/bindings/rtc/trivial-rtc.yaml b/Documentation/devicetree/bindings/rtc/trivial-rtc.yaml index c7d14de214c4..7548d8714871 100644 --- a/Documentation/devicetree/bindings/rtc/trivial-rtc.yaml +++ b/Documentation/devicetree/bindings/rtc/trivial-rtc.yaml @@ -48,12 +48,8 @@ properties: - microcrystal,rv3029 # Real Time Clock - microcrystal,rv8523 - # Real-time clock - - nxp,pcf2127 - # Real-time clock - - nxp,pcf2129 - # Real-time clock - nxp,pca2129 + - nxp,pcf2129 # Real-time Clock Module - pericom,pt7c4338 # I2C bus SERIAL INTERFACE REAL-TIME CLOCK IC -- cgit v1.2.3 From 3e90e5ad9497d993852e638f75e9e154787bdd61 Mon Sep 17 00:00:00 2001 From: Ezequiel Garcia Date: Mon, 18 Jan 2021 02:52:55 +0100 Subject: media: Clarify v4l2-async subdevice addition API Now that most users of v4l2_async_notifier_add_subdev have been converted, let's fix the documentation so it's more clear how the v4l2-async API should be used. Document functions that drivers should use, and their purpose. Signed-off-by: Ezequiel Garcia Reviewed-by: Laurent Pinchart Signed-off-by: Sakari Ailus Reviewed-by: Helen Koike Signed-off-by: Mauro Carvalho Chehab --- Documentation/driver-api/media/v4l2-subdev.rst | 48 +++++++++++++++++++++----- include/media/v4l2-async.h | 15 +++++--- 2 files changed, 50 insertions(+), 13 deletions(-) (limited to 'Documentation') diff --git a/Documentation/driver-api/media/v4l2-subdev.rst b/Documentation/driver-api/media/v4l2-subdev.rst index 0e82c77cf3e2..8b53da2f9c74 100644 --- a/Documentation/driver-api/media/v4l2-subdev.rst +++ b/Documentation/driver-api/media/v4l2-subdev.rst @@ -197,15 +197,45 @@ unregister the notifier the driver has to call takes two arguments: a pointer to struct :c:type:`v4l2_device` and a pointer to struct :c:type:`v4l2_async_notifier`. -Before registering the notifier, bridge drivers must do two things: -first, the notifier must be initialized using the -:c:func:`v4l2_async_notifier_init`. Second, bridge drivers can then -begin to form a list of subdevice descriptors that the bridge device -needs for its operation. Subdevice descriptors are added to the notifier -using the :c:func:`v4l2_async_notifier_add_subdev` call. This function -takes two arguments: a pointer to struct :c:type:`v4l2_async_notifier`, -and a pointer to the subdevice descripter, which is of type struct -:c:type:`v4l2_async_subdev`. +Before registering the notifier, bridge drivers must do two things: first, the +notifier must be initialized using the :c:func:`v4l2_async_notifier_init`. +Second, bridge drivers can then begin to form a list of subdevice descriptors +that the bridge device needs for its operation. Several functions are available +to add subdevice descriptors to a notifier, depending on the type of device and +the needs of the driver. + +:c:func:`v4l2_async_notifier_add_fwnode_remote_subdev` and +:c:func:`v4l2_async_notifier_add_i2c_subdev` are for bridge and ISP drivers for +registering their async sub-devices with the notifier. + +:c:func:`v4l2_async_register_subdev_sensor_common` is a helper function for +sensor drivers registering their own async sub-device, but it also registers a +notifier and further registers async sub-devices for lens and flash devices +found in firmware. The notifier for the sub-device is unregistered with the +async sub-device. + +These functions allocate an async sub-device descriptor which is of type struct +:c:type:`v4l2_async_subdev` embedded in a driver-specific struct. The &struct +:c:type:`v4l2_async_subdev` shall be the first member of this struct: + +.. code-block:: c + + struct my_async_subdev { + struct v4l2_async_subdev asd; + ... + }; + + struct my_async_subdev *my_asd; + struct fwnode_handle *ep; + + ... + + my_asd = v4l2_async_notifier_add_fwnode_remote_subdev(¬ifier, ep, + struct my_async_subdev); + fwnode_handle_put(ep); + + if (IS_ERR(asd)) + return PTR_ERR(asd); The V4L2 core will then use these descriptors to match asynchronously registered subdevices to them. If a match is detected the ``.bound()`` diff --git a/include/media/v4l2-async.h b/include/media/v4l2-async.h index 192a11bdc4ad..6f22daa6f067 100644 --- a/include/media/v4l2-async.h +++ b/include/media/v4l2-async.h @@ -128,7 +128,12 @@ void v4l2_async_debug_init(struct dentry *debugfs_dir); * @notifier: pointer to &struct v4l2_async_notifier * * This function initializes the notifier @asd_list. It must be called - * before the first call to @v4l2_async_notifier_add_subdev. + * before adding a subdevice to a notifier, using one of: + * @v4l2_async_notifier_add_fwnode_remote_subdev, + * @v4l2_async_notifier_add_fwnode_subdev, + * @v4l2_async_notifier_add_i2c_subdev, + * @__v4l2_async_notifier_add_subdev or + * @v4l2_async_notifier_parse_fwnode_endpoints. */ void v4l2_async_notifier_init(struct v4l2_async_notifier *notifier); @@ -262,9 +267,11 @@ void v4l2_async_notifier_unregister(struct v4l2_async_notifier *notifier); * sub-devices allocated for the purposes of the notifier but not the notifier * itself. The user is responsible for calling this function to clean up the * notifier after calling - * @v4l2_async_notifier_add_subdev, - * @v4l2_async_notifier_parse_fwnode_endpoints or - * @v4l2_fwnode_reference_parse_sensor_common. + * @v4l2_async_notifier_add_fwnode_remote_subdev, + * @v4l2_async_notifier_add_fwnode_subdev, + * @v4l2_async_notifier_add_i2c_subdev, + * @__v4l2_async_notifier_add_subdev or + * @v4l2_async_notifier_parse_fwnode_endpoints. * * There is no harm from calling v4l2_async_notifier_cleanup in other * cases as long as its memory has been zeroed after it has been -- cgit v1.2.3 From 918b866edfec39e22ccb9528bc11a0dd6ca62c2b Mon Sep 17 00:00:00 2001 From: Sakari Ailus Date: Thu, 28 Jan 2021 10:44:24 +0100 Subject: media: dt-bindings: Remove old ov5647.yaml file, update ovti,ov5647.yaml Recently ov5647.yaml got renamed as ovti,ov5647.yaml. As part of the video-interfaces DT schema conversion that was unintentionally brought back. Fix this by applying the schema changes to the new file and removing the old one. Fixes: 066a94e28a23 ("media: dt-bindings: media: Use graph and video-interfaces schemas") Signed-off-by: Sakari Ailus Signed-off-by: Mauro Carvalho Chehab --- .../devicetree/bindings/media/i2c/ov5647.yaml | 76 ---------------------- .../devicetree/bindings/media/i2c/ovti,ov5647.yaml | 20 ++---- 2 files changed, 4 insertions(+), 92 deletions(-) delete mode 100644 Documentation/devicetree/bindings/media/i2c/ov5647.yaml (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/media/i2c/ov5647.yaml b/Documentation/devicetree/bindings/media/i2c/ov5647.yaml deleted file mode 100644 index 3b1ea9da437a..000000000000 --- a/Documentation/devicetree/bindings/media/i2c/ov5647.yaml +++ /dev/null @@ -1,76 +0,0 @@ -# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) -%YAML 1.2 ---- -$id: http://devicetree.org/schemas/media/i2c/ov5647.yaml# -$schema: http://devicetree.org/meta-schemas/core.yaml# - -title: Omnivision OV5647 raw image sensor - -maintainers: - - Dave Stevenson - - Jacopo Mondi - -description: |- - The OV5647 is a raw image sensor with MIPI CSI-2 and CCP2 image data - interfaces and CCI (I2C compatible) control bus. - -properties: - compatible: - const: ovti,ov5647 - - reg: - description: I2C device address. - maxItems: 1 - - clocks: - description: Reference to the xclk clock. - maxItems: 1 - - pwdn-gpios: - description: Reference to the GPIO connected to the pwdn pin. Active high. - maxItems: 1 - - port: - $ref: /schemas/graph.yaml#/$defs/port-base - - properties: - endpoint: - $ref: /schemas/media/video-interfaces.yaml# - unevaluatedProperties: false - - properties: - clock-noncontinuous: true - - additionalProperties: false - -required: - - compatible - - reg - - clocks - - port - -additionalProperties: false - -examples: - - | - #include - - i2c { - #address-cells = <1>; - #size-cells = <0>; - - ov5647: camera@36 { - compatible = "ovti,ov5647"; - reg = <0x36>; - clocks = <&camera_clk>; - pwdn-gpios = <&pioE 29 GPIO_ACTIVE_HIGH>; - - port { - camera_out: endpoint { - remote-endpoint = <&csi1_ep1>; - }; - }; - }; - }; - -... diff --git a/Documentation/devicetree/bindings/media/i2c/ovti,ov5647.yaml b/Documentation/devicetree/bindings/media/i2c/ovti,ov5647.yaml index 429566c9ee1d..1ab22e75d3c6 100644 --- a/Documentation/devicetree/bindings/media/i2c/ovti,ov5647.yaml +++ b/Documentation/devicetree/bindings/media/i2c/ovti,ov5647.yaml @@ -31,27 +31,15 @@ properties: maxItems: 1 port: - type: object - description: |- - Should contain one endpoint sub-node used to model connection to the - video receiver according to the specification defined in - Documentation/devicetree/bindings/media/video-interfaces.txt. + $ref: /schemas/graph.yaml#/$defs/port-base properties: endpoint: - type: object + $ref: /schemas/media/video-interfaces.yaml# + unevaluatedProperties: false properties: - remote-endpoint: - description: |- - phandle to the video receiver input port. - - clock-noncontinuous: - type: boolean - description: |- - Set to true to allow MIPI CSI-2 non-continuous clock operations. - - additionalProperties: false + clock-noncontinuous: true additionalProperties: false -- cgit v1.2.3 From c00b72491366529be722de20679b169c4f479f39 Mon Sep 17 00:00:00 2001 From: Jacopo Mondi Date: Thu, 14 Jan 2021 18:04:26 +0100 Subject: media: dt-bindings: media: max9286: Document 'maxim,reverse-channel-microvolt' Document the 'maxim,reverse-channel-microvolt' vendor property in the bindings document of the max9286 driver. The newly introduced property allows to specify the initial configuration of the GMSL reverse control channel to accommodate remote serializers pre-programmed with the high threshold power supply noise immunity enabled. Reviewed-by: Rob Herring Reviewed-by: Laurent Pinchart Reviewed-by: Kieran Bingham Signed-off-by: Jacopo Mondi Signed-off-by: Sakari Ailus Signed-off-by: Mauro Carvalho Chehab --- .../bindings/media/i2c/maxim,max9286.yaml | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/media/i2c/maxim,max9286.yaml b/Documentation/devicetree/bindings/media/i2c/maxim,max9286.yaml index bf4fa56ffcc7..ee16102fdfe7 100644 --- a/Documentation/devicetree/bindings/media/i2c/maxim,max9286.yaml +++ b/Documentation/devicetree/bindings/media/i2c/maxim,max9286.yaml @@ -50,6 +50,26 @@ properties: '#gpio-cells': const: 2 + maxim,reverse-channel-microvolt: + minimum: 30000 + maximum: 200000 + default: 170000 + description: | + Initial amplitude of the reverse control channel, in micro volts. + + The initial amplitude shall be adjusted to a value compatible with the + configuration of the connected remote serializer. + + Some camera modules (for example RDACM20) include an on-board MCU that + pre-programs the embedded serializer with power supply noise immunity + (high-threshold) enabled. A typical value of the deserializer's reverse + channel amplitude to communicate with pre-programmed serializers is + 170000 micro volts. + + A typical value for the reverse channel amplitude to communicate with + a remote serializer whose high-threshold noise immunity is not enabled + is 100000 micro volts + ports: $ref: /schemas/graph.yaml#/properties/ports @@ -185,6 +205,8 @@ examples: gpio-controller; #gpio-cells = <2>; + maxim,reverse-channel-microvolt = <170000>; + ports { #address-cells = <1>; #size-cells = <0>; -- cgit v1.2.3 From d899e5f1db7aa67cad01f4835286cb985890a3da Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Wed, 27 Jan 2021 18:46:32 +0100 Subject: media: dt-bindings: media: imx258: add bindings for IMX258 sensor Add bindings for the IMX258 camera sensor. The bindings, just like the driver, are quite limited, e.g. do not support regulator supplies. Signed-off-by: Krzysztof Kozlowski Reviewed-by: Rob Herring Signed-off-by: Sakari Ailus Signed-off-by: Mauro Carvalho Chehab --- .../devicetree/bindings/media/i2c/imx258.yaml | 134 +++++++++++++++++++++ MAINTAINERS | 1 + 2 files changed, 135 insertions(+) create mode 100644 Documentation/devicetree/bindings/media/i2c/imx258.yaml (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/media/i2c/imx258.yaml b/Documentation/devicetree/bindings/media/i2c/imx258.yaml new file mode 100644 index 000000000000..eaf77866ed9b --- /dev/null +++ b/Documentation/devicetree/bindings/media/i2c/imx258.yaml @@ -0,0 +1,134 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/media/i2c/imx258.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Sony IMX258 13 Mpixel CMOS Digital Image Sensor + +maintainers: + - Krzysztof Kozlowski + +description: |- + IMX258 is a diagonal 5.867mm (Type 1/3.06) 13 Mega-pixel CMOS active pixel + type stacked image sensor with a square pixel array of size 4208 x 3120. It + is programmable through I2C interface. Image data is sent through MIPI + CSI-2. + +properties: + compatible: + const: sony,imx258 + + assigned-clocks: true + assigned-clock-parents: true + assigned-clock-rates: true + + clocks: + description: + Clock frequency from 6 to 27 MHz. + maxItems: 1 + + reg: + maxItems: 1 + + reset-gpios: + description: |- + Reference to the GPIO connected to the XCLR pin, if any. + + vana-supply: + description: + Analog voltage (VANA) supply, 2.7 V + + vdig-supply: + description: + Digital I/O voltage (VDIG) supply, 1.2 V + + vif-supply: + description: + Interface voltage (VIF) supply, 1.8 V + + # See ../video-interfaces.txt for more details + port: + type: object + properties: + endpoint: + type: object + properties: + data-lanes: + oneOf: + - items: + - const: 1 + - const: 2 + - const: 3 + - const: 4 + - items: + - const: 1 + - const: 2 + + link-frequencies: + allOf: + - $ref: /schemas/types.yaml#/definitions/uint64-array + description: + Allowed data bus frequencies. + + required: + - data-lanes + - link-frequencies + +required: + - compatible + - reg + - port + +additionalProperties: false + +examples: + - | + i2c0 { + #address-cells = <1>; + #size-cells = <0>; + + sensor@6c { + compatible = "sony,imx258"; + reg = <0x6c>; + clocks = <&imx258_clk>; + + port { + endpoint { + remote-endpoint = <&csi1_ep>; + data-lanes = <1 2 3 4>; + link-frequencies = /bits/ 64 <320000000>; + }; + }; + }; + }; + + /* Oscillator on the camera board */ + imx258_clk: clk { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <19200000>; + }; + + - | + i2c0 { + #address-cells = <1>; + #size-cells = <0>; + + sensor@6c { + compatible = "sony,imx258"; + reg = <0x6c>; + clocks = <&imx258_clk>; + + assigned-clocks = <&imx258_clk>; + assigned-clock-rates = <19200000>; + + port { + endpoint { + remote-endpoint = <&csi1_ep>; + data-lanes = <1 2 3 4>; + link-frequencies = /bits/ 64 <633600000>; + }; + }; + }; + }; diff --git a/MAINTAINERS b/MAINTAINERS index af8f06213f52..e6ebb2ff5d1c 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -16559,6 +16559,7 @@ M: Sakari Ailus L: linux-media@vger.kernel.org S: Maintained T: git git://linuxtv.org/media_tree.git +F: Documentation/devicetree/bindings/media/i2c/imx258.yaml F: drivers/media/i2c/imx258.c SONY IMX274 SENSOR DRIVER -- cgit v1.2.3 From 85db876b08f10705e992bc924530f74de3859f22 Mon Sep 17 00:00:00 2001 From: Ezequiel Garcia Date: Tue, 12 Jan 2021 20:49:19 +0100 Subject: media: Remove the legacy v4l2-clk API The V4L2 temporary clock helper API, was introduced in late 2012 and, as mentioned in the documentation, meant to be replaced by the generic clock API, once the generic clock framework became available on all relevant architectures. The generic clock API is a well-established API (since a few years now). The last few media capture drivers and sensors using v4l2-clk have been converted to the generic clock framework. We can now remove the v4l2-clk API. Signed-off-by: Ezequiel Garcia Acked-by: Petr Cvek Signed-off-by: Sakari Ailus Signed-off-by: Mauro Carvalho Chehab --- Documentation/driver-api/media/v4l2-clocks.rst | 31 --- Documentation/driver-api/media/v4l2-core.rst | 1 - drivers/media/v4l2-core/Makefile | 2 +- drivers/media/v4l2-core/v4l2-clk.c | 321 ------------------------- include/media/v4l2-clk.h | 73 ------ 5 files changed, 1 insertion(+), 427 deletions(-) delete mode 100644 Documentation/driver-api/media/v4l2-clocks.rst delete mode 100644 drivers/media/v4l2-core/v4l2-clk.c delete mode 100644 include/media/v4l2-clk.h (limited to 'Documentation') diff --git a/Documentation/driver-api/media/v4l2-clocks.rst b/Documentation/driver-api/media/v4l2-clocks.rst deleted file mode 100644 index 5c22eecab7ba..000000000000 --- a/Documentation/driver-api/media/v4l2-clocks.rst +++ /dev/null @@ -1,31 +0,0 @@ -.. SPDX-License-Identifier: GPL-2.0 - -V4L2 clocks ------------ - -.. attention:: - - This is a temporary API and it shall be replaced by the generic - clock API, when the latter becomes widely available. - -Many subdevices, like camera sensors, TV decoders and encoders, need a clock -signal to be supplied by the system. Often this clock is supplied by the -respective bridge device. The Linux kernel provides a Common Clock Framework for -this purpose. However, it is not (yet) available on all architectures. Besides, -the nature of the multi-functional (clock, data + synchronisation, I2C control) -connection of subdevices to the system might impose special requirements on the -clock API usage. E.g. V4L2 has to support clock provider driver unregistration -while a subdevice driver is holding a reference to the clock. For these reasons -a V4L2 clock helper API has been developed and is provided to bridge and -subdevice drivers. - -The API consists of two parts: two functions to register and unregister a V4L2 -clock source: v4l2_clk_register() and v4l2_clk_unregister() and calls to control -a clock object, similar to the respective generic clock API calls: -v4l2_clk_get(), v4l2_clk_put(), v4l2_clk_enable(), v4l2_clk_disable(), -v4l2_clk_get_rate(), and v4l2_clk_set_rate(). Clock suppliers have to provide -clock operations that will be called when clock users invoke respective API -methods. - -It is expected that once the CCF becomes available on all relevant -architectures this API will be removed. diff --git a/Documentation/driver-api/media/v4l2-core.rst b/Documentation/driver-api/media/v4l2-core.rst index 0dcad7a23141..1a8c4a5f256b 100644 --- a/Documentation/driver-api/media/v4l2-core.rst +++ b/Documentation/driver-api/media/v4l2-core.rst @@ -15,7 +15,6 @@ Video4Linux devices v4l2-controls v4l2-videobuf v4l2-videobuf2 - v4l2-clocks v4l2-dv-timings v4l2-flash-led-class v4l2-mc diff --git a/drivers/media/v4l2-core/Makefile b/drivers/media/v4l2-core/Makefile index 2ef0c7c958a2..e4cd589b99a5 100644 --- a/drivers/media/v4l2-core/Makefile +++ b/drivers/media/v4l2-core/Makefile @@ -6,7 +6,7 @@ tuner-objs := tuner-core.o videodev-objs := v4l2-dev.o v4l2-ioctl.o v4l2-device.o v4l2-fh.o \ - v4l2-event.o v4l2-ctrls.o v4l2-subdev.o v4l2-clk.o \ + v4l2-event.o v4l2-ctrls.o v4l2-subdev.o \ v4l2-async.o v4l2-common.o videodev-$(CONFIG_COMPAT) += v4l2-compat-ioctl32.o videodev-$(CONFIG_TRACEPOINTS) += v4l2-trace.o diff --git a/drivers/media/v4l2-core/v4l2-clk.c b/drivers/media/v4l2-core/v4l2-clk.c deleted file mode 100644 index 91274eee6977..000000000000 --- a/drivers/media/v4l2-core/v4l2-clk.c +++ /dev/null @@ -1,321 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * V4L2 clock service - * - * Copyright (C) 2012-2013, Guennadi Liakhovetski - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -static DEFINE_MUTEX(clk_lock); -static LIST_HEAD(clk_list); - -static struct v4l2_clk *v4l2_clk_find(const char *dev_id) -{ - struct v4l2_clk *clk; - - list_for_each_entry(clk, &clk_list, list) - if (!strcmp(dev_id, clk->dev_id)) - return clk; - - return ERR_PTR(-ENODEV); -} - -struct v4l2_clk *v4l2_clk_get(struct device *dev, const char *id) -{ - struct v4l2_clk *clk; - struct clk *ccf_clk = clk_get(dev, id); - char clk_name[V4L2_CLK_NAME_SIZE]; - - if (PTR_ERR(ccf_clk) == -EPROBE_DEFER) - return ERR_PTR(-EPROBE_DEFER); - - if (!IS_ERR_OR_NULL(ccf_clk)) { - clk = kzalloc(sizeof(*clk), GFP_KERNEL); - if (!clk) { - clk_put(ccf_clk); - return ERR_PTR(-ENOMEM); - } - clk->clk = ccf_clk; - - return clk; - } - - mutex_lock(&clk_lock); - clk = v4l2_clk_find(dev_name(dev)); - - /* if dev_name is not found, try use the OF name to find again */ - if (PTR_ERR(clk) == -ENODEV && dev->of_node) { - v4l2_clk_name_of(clk_name, sizeof(clk_name), dev->of_node); - clk = v4l2_clk_find(clk_name); - } - - if (!IS_ERR(clk)) - atomic_inc(&clk->use_count); - mutex_unlock(&clk_lock); - - return clk; -} -EXPORT_SYMBOL(v4l2_clk_get); - -void v4l2_clk_put(struct v4l2_clk *clk) -{ - struct v4l2_clk *tmp; - - if (IS_ERR(clk)) - return; - - if (clk->clk) { - clk_put(clk->clk); - kfree(clk); - return; - } - - mutex_lock(&clk_lock); - - list_for_each_entry(tmp, &clk_list, list) - if (tmp == clk) - atomic_dec(&clk->use_count); - - mutex_unlock(&clk_lock); -} -EXPORT_SYMBOL(v4l2_clk_put); - -static int v4l2_clk_lock_driver(struct v4l2_clk *clk) -{ - struct v4l2_clk *tmp; - int ret = -ENODEV; - - mutex_lock(&clk_lock); - - list_for_each_entry(tmp, &clk_list, list) - if (tmp == clk) { - ret = !try_module_get(clk->ops->owner); - if (ret) - ret = -EFAULT; - break; - } - - mutex_unlock(&clk_lock); - - return ret; -} - -static void v4l2_clk_unlock_driver(struct v4l2_clk *clk) -{ - module_put(clk->ops->owner); -} - -int v4l2_clk_enable(struct v4l2_clk *clk) -{ - int ret; - - if (clk->clk) - return clk_prepare_enable(clk->clk); - - ret = v4l2_clk_lock_driver(clk); - if (ret < 0) - return ret; - - mutex_lock(&clk->lock); - - if (++clk->enable == 1 && clk->ops->enable) { - ret = clk->ops->enable(clk); - if (ret < 0) - clk->enable--; - } - - mutex_unlock(&clk->lock); - - return ret; -} -EXPORT_SYMBOL(v4l2_clk_enable); - -/* - * You might Oops if you try to disabled a disabled clock, because then the - * driver isn't locked and could have been unloaded by now, so, don't do that - */ -void v4l2_clk_disable(struct v4l2_clk *clk) -{ - int enable; - - if (clk->clk) - return clk_disable_unprepare(clk->clk); - - mutex_lock(&clk->lock); - - enable = --clk->enable; - if (WARN(enable < 0, "Unbalanced %s() on %s!\n", __func__, - clk->dev_id)) - clk->enable++; - else if (!enable && clk->ops->disable) - clk->ops->disable(clk); - - mutex_unlock(&clk->lock); - - v4l2_clk_unlock_driver(clk); -} -EXPORT_SYMBOL(v4l2_clk_disable); - -unsigned long v4l2_clk_get_rate(struct v4l2_clk *clk) -{ - int ret; - - if (clk->clk) - return clk_get_rate(clk->clk); - - ret = v4l2_clk_lock_driver(clk); - if (ret < 0) - return ret; - - mutex_lock(&clk->lock); - if (!clk->ops->get_rate) - ret = -ENOSYS; - else - ret = clk->ops->get_rate(clk); - mutex_unlock(&clk->lock); - - v4l2_clk_unlock_driver(clk); - - return ret; -} -EXPORT_SYMBOL(v4l2_clk_get_rate); - -int v4l2_clk_set_rate(struct v4l2_clk *clk, unsigned long rate) -{ - int ret; - - if (clk->clk) { - long r = clk_round_rate(clk->clk, rate); - if (r < 0) - return r; - return clk_set_rate(clk->clk, r); - } - - ret = v4l2_clk_lock_driver(clk); - - if (ret < 0) - return ret; - - mutex_lock(&clk->lock); - if (!clk->ops->set_rate) - ret = -ENOSYS; - else - ret = clk->ops->set_rate(clk, rate); - mutex_unlock(&clk->lock); - - v4l2_clk_unlock_driver(clk); - - return ret; -} -EXPORT_SYMBOL(v4l2_clk_set_rate); - -struct v4l2_clk *v4l2_clk_register(const struct v4l2_clk_ops *ops, - const char *dev_id, - void *priv) -{ - struct v4l2_clk *clk; - int ret; - - if (!ops || !dev_id) - return ERR_PTR(-EINVAL); - - clk = kzalloc(sizeof(struct v4l2_clk), GFP_KERNEL); - if (!clk) - return ERR_PTR(-ENOMEM); - - clk->dev_id = kstrdup(dev_id, GFP_KERNEL); - if (!clk->dev_id) { - ret = -ENOMEM; - goto ealloc; - } - clk->ops = ops; - clk->priv = priv; - atomic_set(&clk->use_count, 0); - mutex_init(&clk->lock); - - mutex_lock(&clk_lock); - if (!IS_ERR(v4l2_clk_find(dev_id))) { - mutex_unlock(&clk_lock); - ret = -EEXIST; - goto eexist; - } - list_add_tail(&clk->list, &clk_list); - mutex_unlock(&clk_lock); - - return clk; - -eexist: -ealloc: - kfree(clk->dev_id); - kfree(clk); - return ERR_PTR(ret); -} -EXPORT_SYMBOL(v4l2_clk_register); - -void v4l2_clk_unregister(struct v4l2_clk *clk) -{ - if (WARN(atomic_read(&clk->use_count), - "%s(): Refusing to unregister ref-counted %s clock!\n", - __func__, clk->dev_id)) - return; - - mutex_lock(&clk_lock); - list_del(&clk->list); - mutex_unlock(&clk_lock); - - kfree(clk->dev_id); - kfree(clk); -} -EXPORT_SYMBOL(v4l2_clk_unregister); - -struct v4l2_clk_fixed { - unsigned long rate; - struct v4l2_clk_ops ops; -}; - -static unsigned long fixed_get_rate(struct v4l2_clk *clk) -{ - struct v4l2_clk_fixed *priv = clk->priv; - return priv->rate; -} - -struct v4l2_clk *__v4l2_clk_register_fixed(const char *dev_id, - unsigned long rate, struct module *owner) -{ - struct v4l2_clk *clk; - struct v4l2_clk_fixed *priv = kzalloc(sizeof(*priv), GFP_KERNEL); - - if (!priv) - return ERR_PTR(-ENOMEM); - - priv->rate = rate; - priv->ops.get_rate = fixed_get_rate; - priv->ops.owner = owner; - - clk = v4l2_clk_register(&priv->ops, dev_id, priv); - if (IS_ERR(clk)) - kfree(priv); - - return clk; -} -EXPORT_SYMBOL(__v4l2_clk_register_fixed); - -void v4l2_clk_unregister_fixed(struct v4l2_clk *clk) -{ - kfree(clk->priv); - v4l2_clk_unregister(clk); -} -EXPORT_SYMBOL(v4l2_clk_unregister_fixed); diff --git a/include/media/v4l2-clk.h b/include/media/v4l2-clk.h deleted file mode 100644 index d9d21a43a834..000000000000 --- a/include/media/v4l2-clk.h +++ /dev/null @@ -1,73 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ -/* - * V4L2 clock service - * - * Copyright (C) 2012-2013, Guennadi Liakhovetski - * - * ATTENTION: This is a temporary API and it shall be replaced by the generic - * clock API, when the latter becomes widely available. - */ - -#ifndef MEDIA_V4L2_CLK_H -#define MEDIA_V4L2_CLK_H - -#include -#include -#include -#include - -struct module; -struct device; - -struct clk; -struct v4l2_clk { - struct list_head list; - const struct v4l2_clk_ops *ops; - const char *dev_id; - int enable; - struct mutex lock; /* Protect the enable count */ - atomic_t use_count; - struct clk *clk; - void *priv; -}; - -struct v4l2_clk_ops { - struct module *owner; - int (*enable)(struct v4l2_clk *clk); - void (*disable)(struct v4l2_clk *clk); - unsigned long (*get_rate)(struct v4l2_clk *clk); - int (*set_rate)(struct v4l2_clk *clk, unsigned long); -}; - -struct v4l2_clk *v4l2_clk_register(const struct v4l2_clk_ops *ops, - const char *dev_name, - void *priv); -void v4l2_clk_unregister(struct v4l2_clk *clk); -struct v4l2_clk *v4l2_clk_get(struct device *dev, const char *id); -void v4l2_clk_put(struct v4l2_clk *clk); -int v4l2_clk_enable(struct v4l2_clk *clk); -void v4l2_clk_disable(struct v4l2_clk *clk); -unsigned long v4l2_clk_get_rate(struct v4l2_clk *clk); -int v4l2_clk_set_rate(struct v4l2_clk *clk, unsigned long rate); - -struct module; - -struct v4l2_clk *__v4l2_clk_register_fixed(const char *dev_id, - unsigned long rate, struct module *owner); -void v4l2_clk_unregister_fixed(struct v4l2_clk *clk); - -static inline struct v4l2_clk *v4l2_clk_register_fixed(const char *dev_id, - unsigned long rate) -{ - return __v4l2_clk_register_fixed(dev_id, rate, THIS_MODULE); -} - -#define V4L2_CLK_NAME_SIZE 64 - -#define v4l2_clk_name_i2c(name, size, adap, client) snprintf(name, size, \ - "%d-%04x", adap, client) - -#define v4l2_clk_name_of(name, size, node) snprintf(name, size, \ - "of-%pOF", node) - -#endif -- cgit v1.2.3 From 41b3e23376e9c316e6bf509ab9983fc8b0c0fc25 Mon Sep 17 00:00:00 2001 From: Martina Krasteva Date: Wed, 3 Feb 2021 14:54:40 +0100 Subject: media: dt-bindings: media: Add bindings for imx334 - Add dt-bindings documentation for Sony imx334 sensor driver. - Add MAINTAINERS entry for Sony imx334 binding documentation. Signed-off-by: Martina Krasteva Reviewed-by: Gjorgji Rosikopulos Acked-by: Daniele Alessandrelli Acked-by: Paul J. Murphy Reviewed-by: Rob Herring Signed-off-by: Sakari Ailus Signed-off-by: Mauro Carvalho Chehab --- .../devicetree/bindings/media/i2c/sony,imx334.yaml | 91 ++++++++++++++++++++++ MAINTAINERS | 8 ++ 2 files changed, 99 insertions(+) create mode 100644 Documentation/devicetree/bindings/media/i2c/sony,imx334.yaml (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/media/i2c/sony,imx334.yaml b/Documentation/devicetree/bindings/media/i2c/sony,imx334.yaml new file mode 100644 index 000000000000..24e689314bde --- /dev/null +++ b/Documentation/devicetree/bindings/media/i2c/sony,imx334.yaml @@ -0,0 +1,91 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +# Copyright (C) 2021 Intel Corporation +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/media/i2c/sony,imx334.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Sony IMX334 Sensor + +maintainers: + - Paul J. Murphy + - Daniele Alessandrelli + +description: + IMX334 sensor is a Sony CMOS active pixel digital image sensor with an active + array size of 3864H x 2202V. It is programmable through I2C interface. The + I2C client address is fixed to 0x1a as per sensor data sheet. Image data is + sent through MIPI CSI-2. + +properties: + compatible: + const: sony,imx334 + reg: + description: I2C address + maxItems: 1 + + assigned-clocks: true + assigned-clock-parents: true + assigned-clock-rates: true + + clocks: + description: Clock frequency from 6 to 27 MHz, 37.125MHz, 74.25MHz + maxItems: 1 + + reset-gpios: + description: Reference to the GPIO connected to the XCLR pin, if any. + + port: + type: object + additionalProperties: false + $ref: /schemas/graph.yaml#/properties/port + + properties: + endpoint: + type: object + properties: + data-lanes: + $ref: ../video-interfaces.yaml#/properties/data-lanes + link-frequencies: + $ref: ../video-interfaces.yaml#/properties/link-frequencies + + required: + - data-lanes + - link-frequencies + + required: + - endpoint + +required: + - compatible + - reg + - clocks + - port + +additionalProperties: false + +examples: + - | + i2c0 { + #address-cells = <1>; + #size-cells = <0>; + + camera@1a { + compatible = "sony,imx334"; + reg = <0x1a>; + clocks = <&imx334_clk>; + + assigned-clocks = <&imx334_clk>; + assigned-clock-parents = <&imx334_clk_parent>; + assigned-clock-rates = <24000000>; + + port { + imx334: endpoint { + remote-endpoint = <&cam>; + data-lanes = <1 2 3 4>; + link-frequencies = /bits/ 64 <891000000>; + }; + }; + }; + }; +... diff --git a/MAINTAINERS b/MAINTAINERS index e6ebb2ff5d1c..36be45824a43 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -16585,6 +16585,14 @@ S: Maintained T: git git://linuxtv.org/media_tree.git F: drivers/media/i2c/imx319.c +SONY IMX334 SENSOR DRIVER +M: Paul J. Murphy +M: Daniele Alessandrelli +L: linux-media@vger.kernel.org +S: Maintained +T: git git://linuxtv.org/media_tree.git +F: Documentation/devicetree/bindings/media/i2c/sony,imx334.yaml + SONY IMX355 SENSOR DRIVER M: Tianshu Qiu L: linux-media@vger.kernel.org -- cgit v1.2.3 From d0858167492b59297c5c2aac10cdc9904c5a1cc6 Mon Sep 17 00:00:00 2001 From: Vinod Koul Date: Thu, 4 Feb 2021 22:28:03 +0530 Subject: dt-bindings: phy: qcom,qmp: Add SM8350 UFS PHY bindings Add the compatible strings for the UFS PHY found on SM8350 SoC. Signed-off-by: Vinod Koul Reviewed-by: Bjorn Andersson Link: https://lore.kernel.org/r/20210204165805.62235-2-vkoul@kernel.org Signed-off-by: Vinod Koul --- Documentation/devicetree/bindings/phy/qcom,qmp-phy.yaml | 1 + 1 file changed, 1 insertion(+) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/phy/qcom,qmp-phy.yaml b/Documentation/devicetree/bindings/phy/qcom,qmp-phy.yaml index c38061de242a..626447fee092 100644 --- a/Documentation/devicetree/bindings/phy/qcom,qmp-phy.yaml +++ b/Documentation/devicetree/bindings/phy/qcom,qmp-phy.yaml @@ -40,6 +40,7 @@ properties: - qcom,sm8250-qmp-modem-pcie-phy - qcom,sm8250-qmp-usb3-phy - qcom,sm8250-qmp-usb3-uni-phy + - qcom,sm8350-qmp-ufs-phy - qcom,sm8350-qmp-usb3-phy - qcom,sm8350-qmp-usb3-uni-phy - qcom,sdx55-qmp-usb3-uni-phy -- cgit v1.2.3 From de4d9ea789530ac0ce3409878422e9389c3a7cd3 Mon Sep 17 00:00:00 2001 From: Thinh Nguyen Date: Tue, 19 Jan 2021 17:36:08 -0800 Subject: dt-binding: usb: Include USB SSP rates in GenXxY According to the USB 3.2 spec, a SuperSpeed Plus device can operate at gen2x2, gen2x1, or gen1x2. If the USB controller device supports multiple lanes at different transfer rates, the user can specify the HW capability via these new speed strings: "super-speed-plus-gen2x2" "super-speed-plus-gen2x1" "super-speed-plus-gen1x2" If the argument is simply "super-speed-plus", USB controllers should default to their maximum transfer rate and number of lanes. Reviewed-by: Rob Herring Signed-off-by: Thinh Nguyen Link: https://lore.kernel.org/r/cc7cc15f87e209c9963f19129f51398cdc374358.1611106162.git.Thinh.Nguyen@synopsys.com Signed-off-by: Greg Kroah-Hartman --- Documentation/devicetree/bindings/usb/usb.yaml | 3 +++ 1 file changed, 3 insertions(+) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/usb/usb.yaml b/Documentation/devicetree/bindings/usb/usb.yaml index ebe7f4275c59..78491e66ed24 100644 --- a/Documentation/devicetree/bindings/usb/usb.yaml +++ b/Documentation/devicetree/bindings/usb/usb.yaml @@ -54,6 +54,9 @@ properties: - high-speed - super-speed - super-speed-plus + - super-speed-plus-gen2x1 + - super-speed-plus-gen1x2 + - super-speed-plus-gen2x2 additionalProperties: true -- cgit v1.2.3 From 9d5ef190e5615a7b63af89f88c4106a5bc127974 Mon Sep 17 00:00:00 2001 From: Vladimir Oltean Date: Fri, 5 Feb 2021 15:37:10 +0200 Subject: net: dsa: automatically bring up DSA master when opening user port DSA wants the master interface to be open before the user port is due to historical reasons. The promiscuity of interfaces that are down used to have issues, as referenced Lennert Buytenhek in commit df02c6ff2e39 ("dsa: fix master interface allmulti/promisc handling"). The bugfix mentioned there, commit b6c40d68ff64 ("net: only invoke dev->change_rx_flags when device is UP"), was basically a "don't do that" approach to working around the promiscuity while down issue. Further work done by Vlad Yasevich in commit d2615bf45069 ("net: core: Always propagate flag changes to interfaces") has resolved the underlying issue, and it is strictly up to the DSA and 8021q drivers now, it is no longer mandated by the networking core that the master interface must be up when changing its promiscuity. From DSA's point of view, deciding to error out in dsa_slave_open because the master isn't up is (a) a bad user experience and (b) knocking at an open door. Even if there still was an issue with promiscuity while down, DSA could still just open the master and avoid it. Doing it this way has the additional benefit that user space can now remove DSA-specific workarounds, like systemd-networkd with BindCarrier: https://github.com/systemd/systemd/issues/7478 And we can finally remove one of the 2 bullets in the "Common pitfalls using DSA setups" chapter. Tested with two cascaded DSA switches: $ ip link set sw0p2 up fsl_enetc 0000:00:00.2 eno2: configuring for fixed/internal link mode fsl_enetc 0000:00:00.2 eno2: Link is Up - 1Gbps/Full - flow control rx/tx mscc_felix 0000:00:00.5 swp0: configuring for fixed/sgmii link mode mscc_felix 0000:00:00.5 swp0: Link is Up - 1Gbps/Full - flow control off 8021q: adding VLAN 0 to HW filter on device swp0 sja1105 spi2.0 sw0p2: configuring for phy/rgmii-id link mode IPv6: ADDRCONF(NETDEV_CHANGE): eno2: link becomes ready IPv6: ADDRCONF(NETDEV_CHANGE): swp0: link becomes ready Signed-off-by: Vladimir Oltean Reviewed-by: Andrew Lunn Reviewed-by: Florian Fainelli Signed-off-by: Jakub Kicinski --- Documentation/networking/dsa/dsa.rst | 4 ---- net/dsa/slave.c | 7 +++++-- 2 files changed, 5 insertions(+), 6 deletions(-) (limited to 'Documentation') diff --git a/Documentation/networking/dsa/dsa.rst b/Documentation/networking/dsa/dsa.rst index a8d15dd2b42b..e9517af5fe02 100644 --- a/Documentation/networking/dsa/dsa.rst +++ b/Documentation/networking/dsa/dsa.rst @@ -273,10 +273,6 @@ will not make us go through the switch tagging protocol transmit function, so the Ethernet switch on the other end, expecting a tag will typically drop this frame. -Slave network devices check that the master network device is UP before allowing -you to administratively bring UP these slave network devices. A common -configuration mistake is forgetting to bring UP the master network device first. - Interactions with other subsystems ================================== diff --git a/net/dsa/slave.c b/net/dsa/slave.c index b0571ab4e5a7..c95e3bdbe690 100644 --- a/net/dsa/slave.c +++ b/net/dsa/slave.c @@ -68,8 +68,11 @@ static int dsa_slave_open(struct net_device *dev) struct dsa_port *dp = dsa_slave_to_port(dev); int err; - if (!(master->flags & IFF_UP)) - return -ENETDOWN; + err = dev_open(master, NULL); + if (err < 0) { + netdev_err(dev, "failed to open master %s\n", master->name); + goto out; + } if (!ether_addr_equal(dev->dev_addr, master->dev_addr)) { err = dev_uc_add(master, dev->dev_addr); -- cgit v1.2.3 From d70d178726ed06094feae695658af8594c2087ad Mon Sep 17 00:00:00 2001 From: Vijayakannan Ayyathurai Date: Thu, 17 Dec 2020 02:32:47 +0800 Subject: dt-bindings: watchdog: Add bindings for Intel Keem Bay SoC Add Device Tree binding document for Watchdog IP in the Intel Keem Bay SoC. Acked-by: Mark Gross Acked-by: Andy Shevchenko Signed-off-by: Vijayakannan Ayyathurai Reviewed-by: Rob Herring Reviewed-by: Guenter Roeck Link: https://lore.kernel.org/r/8c4dad4fb8ba644607aa9379d5ec70d8707d7e75.1608141131.git.vijayakannan.ayyathurai@intel.com Signed-off-by: Guenter Roeck Signed-off-by: Wim Van Sebroeck --- .../bindings/watchdog/intel,keembay-wdt.yaml | 57 ++++++++++++++++++++++ 1 file changed, 57 insertions(+) create mode 100644 Documentation/devicetree/bindings/watchdog/intel,keembay-wdt.yaml (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/watchdog/intel,keembay-wdt.yaml b/Documentation/devicetree/bindings/watchdog/intel,keembay-wdt.yaml new file mode 100644 index 000000000000..1437ff8a122f --- /dev/null +++ b/Documentation/devicetree/bindings/watchdog/intel,keembay-wdt.yaml @@ -0,0 +1,57 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/watchdog/intel,keembay-wdt.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Intel Keem Bay SoC non-secure Watchdog Timer + +maintainers: + - Wan Ahmad Zainie + +properties: + compatible: + enum: + - intel,keembay-wdt + + reg: + maxItems: 1 + + clocks: + maxItems: 1 + + interrupts: + items: + - description: interrupt specifier for threshold interrupt line + - description: interrupt specifier for timeout interrupt line + + interrupt-names: + items: + - const: threshold + - const: timeout + +required: + - compatible + - reg + - interrupts + - interrupt-names + - clocks + +additionalProperties: false + +examples: + - | + #include + #include + #define KEEM_BAY_A53_TIM + + watchdog: watchdog@2033009c { + compatible = "intel,keembay-wdt"; + reg = <0x2033009c 0x10>; + interrupts = , + ; + interrupt-names = "threshold", "timeout"; + clocks = <&scmi_clk KEEM_BAY_A53_TIM>; + }; + +... -- cgit v1.2.3 From 1ee5981da617190c41f7a019542ed4a85041ddbd Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Fri, 18 Dec 2020 18:37:26 +0100 Subject: dt-bindings: watchdog: renesas,wdt: add r8a779a0 (V3U) support Signed-off-by: Wolfram Sang Reviewed-by: Geert Uytterhoeven Acked-by: Rob Herring Link: https://lore.kernel.org/r/20201218173731.12839-2-wsa+renesas@sang-engineering.com Signed-off-by: Guenter Roeck Signed-off-by: Wim Van Sebroeck --- Documentation/devicetree/bindings/watchdog/renesas,wdt.yaml | 1 + 1 file changed, 1 insertion(+) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/watchdog/renesas,wdt.yaml b/Documentation/devicetree/bindings/watchdog/renesas,wdt.yaml index 6933005b52bd..ab66d3f0c476 100644 --- a/Documentation/devicetree/bindings/watchdog/renesas,wdt.yaml +++ b/Documentation/devicetree/bindings/watchdog/renesas,wdt.yaml @@ -50,6 +50,7 @@ properties: - renesas,r8a77980-wdt # R-Car V3H - renesas,r8a77990-wdt # R-Car E3 - renesas,r8a77995-wdt # R-Car D3 + - renesas,r8a779a0-wdt # R-Car V3U - const: renesas,rcar-gen3-wdt # R-Car Gen3 and RZ/G2 reg: -- cgit v1.2.3 From a2fa9f574b2093a6c6312a2d0045759ea7f805ea Mon Sep 17 00:00:00 2001 From: Andre Przywara Date: Wed, 27 Jan 2021 17:24:49 +0000 Subject: dt-bindings: watchdog: sun4i: Add H616 compatible string Use enums to group all compatible devices together on the way. Signed-off-by: Andre Przywara Acked-by: Rob Herring Acked-by: Maxime Ripard Reviewed-by: Guenter Roeck Link: https://lore.kernel.org/r/20210118020848.11721-18-andre.przywara@arm.com Signed-off-by: Guenter Roeck Signed-off-by: Wim Van Sebroeck --- .../bindings/watchdog/allwinner,sun4i-a10-wdt.yaml | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/watchdog/allwinner,sun4i-a10-wdt.yaml b/Documentation/devicetree/bindings/watchdog/allwinner,sun4i-a10-wdt.yaml index 5ac607de8be4..9aa3c313c49f 100644 --- a/Documentation/devicetree/bindings/watchdog/allwinner,sun4i-a10-wdt.yaml +++ b/Documentation/devicetree/bindings/watchdog/allwinner,sun4i-a10-wdt.yaml @@ -19,13 +19,11 @@ properties: - const: allwinner,sun4i-a10-wdt - const: allwinner,sun6i-a31-wdt - items: - - const: allwinner,sun50i-a64-wdt - - const: allwinner,sun6i-a31-wdt - - items: - - const: allwinner,sun50i-a100-wdt - - const: allwinner,sun6i-a31-wdt - - items: - - const: allwinner,sun50i-h6-wdt + - enum: + - allwinner,sun50i-a64-wdt + - allwinner,sun50i-a100-wdt + - allwinner,sun50i-h6-wdt + - allwinner,sun50i-h616-wdt - const: allwinner,sun6i-a31-wdt - items: - const: allwinner,suniv-f1c100s-wdt -- cgit v1.2.3 From 1080f8a54beff856988c47f9801a326d87c9c54f Mon Sep 17 00:00:00 2001 From: Johan Jonker Date: Fri, 18 Dec 2020 13:05:27 +0100 Subject: dt-binding: watchdog: add more Rockchip compatibles to snps,dw-wdt.yaml The watchdog compatible strings are suppose to be SoC orientated. In the more recently added Rockchip SoC dtsi files only the fallback string "snps,dw-wdt" is used, so add the following compatible strings: "rockchip,px30-wdt", "snps,dw-wdt" "rockchip,rk3228-wdt", "snps,dw-wdt" "rockchip,rk3308-wdt", "snps,dw-wdt" "rockchip,rk3328-wdt", "snps,dw-wdt" "rockchip,rk3399-wdt", "snps,dw-wdt" "rockchip,rv1108-wdt", "snps,dw-wdt" make ARCH=arm dtbs_check DT_SCHEMA_FILES=Documentation/devicetree/bindings/watchdog/snps,dw-wdt.yaml make ARCH=arm64 dtbs_check DT_SCHEMA_FILES=Documentation/devicetree/bindings/watchdog/snps,dw-wdt.yaml Signed-off-by: Johan Jonker Acked-by: Rob Herring Reviewed-by: Heiko Stuebner Link: https://lore.kernel.org/r/20201218120534.13788-1-jbx6244@gmail.com Signed-off-by: Guenter Roeck Signed-off-by: Wim Van Sebroeck --- Documentation/devicetree/bindings/watchdog/snps,dw-wdt.yaml | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/watchdog/snps,dw-wdt.yaml b/Documentation/devicetree/bindings/watchdog/snps,dw-wdt.yaml index f7ee9229c29f..b58596b1831d 100644 --- a/Documentation/devicetree/bindings/watchdog/snps,dw-wdt.yaml +++ b/Documentation/devicetree/bindings/watchdog/snps,dw-wdt.yaml @@ -18,10 +18,16 @@ properties: - const: snps,dw-wdt - items: - enum: + - rockchip,px30-wdt - rockchip,rk3066-wdt - rockchip,rk3188-wdt + - rockchip,rk3228-wdt - rockchip,rk3288-wdt + - rockchip,rk3308-wdt + - rockchip,rk3328-wdt - rockchip,rk3368-wdt + - rockchip,rk3399-wdt + - rockchip,rv1108-wdt - const: snps,dw-wdt reg: -- cgit v1.2.3 From e547aa072858bd671b00528e2d1f0d7e5cab23a8 Mon Sep 17 00:00:00 2001 From: Crystal Guo Date: Wed, 14 Oct 2020 21:19:33 +0800 Subject: dt-binding: mediatek: watchdog: fix the description of compatible The watchdog driver for MT2712 and MT8183 relies on DT data, so the fallback compatible MT6589 won't work. Signed-off-by: Crystal Guo Reviewed-by: Matthias Brugger Reviewed-by: Guenter Roeck Link: https://lore.kernel.org/r/20201014131936.20584-2-crystal.guo@mediatek.com Signed-off-by: Guenter Roeck Signed-off-by: Wim Van Sebroeck --- Documentation/devicetree/bindings/watchdog/mtk-wdt.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/watchdog/mtk-wdt.txt b/Documentation/devicetree/bindings/watchdog/mtk-wdt.txt index 4dd36bd3f1ad..45eedc2c3141 100644 --- a/Documentation/devicetree/bindings/watchdog/mtk-wdt.txt +++ b/Documentation/devicetree/bindings/watchdog/mtk-wdt.txt @@ -4,13 +4,13 @@ Required properties: - compatible should contain: "mediatek,mt2701-wdt", "mediatek,mt6589-wdt": for MT2701 - "mediatek,mt2712-wdt", "mediatek,mt6589-wdt": for MT2712 + "mediatek,mt2712-wdt": for MT2712 "mediatek,mt6589-wdt": for MT6589 "mediatek,mt6797-wdt", "mediatek,mt6589-wdt": for MT6797 "mediatek,mt7622-wdt", "mediatek,mt6589-wdt": for MT7622 "mediatek,mt7623-wdt", "mediatek,mt6589-wdt": for MT7623 "mediatek,mt7629-wdt", "mediatek,mt6589-wdt": for MT7629 - "mediatek,mt8183-wdt", "mediatek,mt6589-wdt": for MT8183 + "mediatek,mt8183-wdt": for MT8183 "mediatek,mt8516-wdt", "mediatek,mt6589-wdt": for MT8516 - reg : Specifies base physical address and size of the registers. -- cgit v1.2.3 From 53526bef0a23fa748f72c5a87a7a125736948f6e Mon Sep 17 00:00:00 2001 From: Crystal Guo Date: Wed, 14 Oct 2020 21:19:34 +0800 Subject: dt-binding: mediatek: mt8192: update mtk-wdt document update mtk-wdt document for MT8192 platform Signed-off-by: Crystal Guo Reviewed-by: Guenter Roeck Link: https://lore.kernel.org/r/20201014131936.20584-3-crystal.guo@mediatek.com Signed-off-by: Guenter Roeck Signed-off-by: Wim Van Sebroeck --- Documentation/devicetree/bindings/watchdog/mtk-wdt.txt | 1 + 1 file changed, 1 insertion(+) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/watchdog/mtk-wdt.txt b/Documentation/devicetree/bindings/watchdog/mtk-wdt.txt index 45eedc2c3141..e36ba60de829 100644 --- a/Documentation/devicetree/bindings/watchdog/mtk-wdt.txt +++ b/Documentation/devicetree/bindings/watchdog/mtk-wdt.txt @@ -12,6 +12,7 @@ Required properties: "mediatek,mt7629-wdt", "mediatek,mt6589-wdt": for MT7629 "mediatek,mt8183-wdt": for MT8183 "mediatek,mt8516-wdt", "mediatek,mt6589-wdt": for MT8516 + "mediatek,mt8192-wdt": for MT8192 - reg : Specifies base physical address and size of the registers. -- cgit v1.2.3 From b4b12b48458fcec2b90ac4b3e4e017f813f22959 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Wed, 20 Jan 2021 17:27:41 +0100 Subject: watchdog: remove sirf prima driver The CSR SiRF prima2/atlas platforms are getting removed, so this driver is no longer needed. Cc: Barry Song Signed-off-by: Arnd Bergmann Reviewed-by: Guenter Roeck Acked-by: Barry Song Link: https://lore.kernel.org/r/20210120162745.61268-2-arnd@kernel.org Signed-off-by: Guenter Roeck Signed-off-by: Wim Van Sebroeck --- .../devicetree/bindings/watchdog/sirfsoc_wdt.txt | 18 -- drivers/watchdog/Kconfig | 10 - drivers/watchdog/Makefile | 1 - drivers/watchdog/sirfsoc_wdt.c | 216 --------------------- 4 files changed, 245 deletions(-) delete mode 100644 Documentation/devicetree/bindings/watchdog/sirfsoc_wdt.txt delete mode 100644 drivers/watchdog/sirfsoc_wdt.c (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/watchdog/sirfsoc_wdt.txt b/Documentation/devicetree/bindings/watchdog/sirfsoc_wdt.txt deleted file mode 100644 index 0dce5e3100b4..000000000000 --- a/Documentation/devicetree/bindings/watchdog/sirfsoc_wdt.txt +++ /dev/null @@ -1,18 +0,0 @@ -SiRFSoC Timer and Watchdog Timer(WDT) Controller - -Required properties: -- compatible: "sirf,prima2-tick" -- reg: Address range of tick timer/WDT register set -- interrupts: interrupt number to the cpu - -Optional properties: -- timeout-sec : Contains the watchdog timeout in seconds - -Example: - -timer@b0020000 { - compatible = "sirf,prima2-tick"; - reg = <0xb0020000 0x1000>; - interrupts = <0>; - timeout-sec = <30>; -}; diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig index e95827790877..081b3d9768e2 100644 --- a/drivers/watchdog/Kconfig +++ b/drivers/watchdog/Kconfig @@ -788,16 +788,6 @@ config MOXART_WDT To compile this driver as a module, choose M here: the module will be called moxart_wdt. -config SIRFSOC_WATCHDOG - tristate "SiRFSOC watchdog" - depends on HAS_IOMEM - depends on ARCH_SIRF || COMPILE_TEST - select WATCHDOG_CORE - default y - help - Support for CSR SiRFprimaII and SiRFatlasVI watchdog. When - the watchdog triggers the system will be reset. - config ST_LPC_WATCHDOG tristate "STMicroelectronics LPC Watchdog" depends on ARCH_STI || COMPILE_TEST diff --git a/drivers/watchdog/Makefile b/drivers/watchdog/Makefile index aeaa74182096..8f78458a96c0 100644 --- a/drivers/watchdog/Makefile +++ b/drivers/watchdog/Makefile @@ -73,7 +73,6 @@ obj-$(CONFIG_UX500_WATCHDOG) += ux500_wdt.o obj-$(CONFIG_RETU_WATCHDOG) += retu_wdt.o obj-$(CONFIG_BCM2835_WDT) += bcm2835_wdt.o obj-$(CONFIG_MOXART_WDT) += moxart_wdt.o -obj-$(CONFIG_SIRFSOC_WATCHDOG) += sirfsoc_wdt.o obj-$(CONFIG_ST_LPC_WATCHDOG) += st_lpc_wdt.o obj-$(CONFIG_QCOM_WDT) += qcom-wdt.o obj-$(CONFIG_BCM_KONA_WDT) += bcm_kona_wdt.o diff --git a/drivers/watchdog/sirfsoc_wdt.c b/drivers/watchdog/sirfsoc_wdt.c deleted file mode 100644 index 734cf2966ecb..000000000000 --- a/drivers/watchdog/sirfsoc_wdt.c +++ /dev/null @@ -1,216 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * Watchdog driver for CSR SiRFprimaII and SiRFatlasVI - * - * Copyright (c) 2013 Cambridge Silicon Radio Limited, a CSR plc group company. - */ - -#include -#include -#include -#include -#include -#include -#include - -#define CLOCK_FREQ 1000000 - -#define SIRFSOC_TIMER_COUNTER_LO 0x0000 -#define SIRFSOC_TIMER_MATCH_0 0x0008 -#define SIRFSOC_TIMER_INT_EN 0x0024 -#define SIRFSOC_TIMER_WATCHDOG_EN 0x0028 -#define SIRFSOC_TIMER_LATCH 0x0030 -#define SIRFSOC_TIMER_LATCHED_LO 0x0034 - -#define SIRFSOC_TIMER_WDT_INDEX 5 - -#define SIRFSOC_WDT_MIN_TIMEOUT 30 /* 30 secs */ -#define SIRFSOC_WDT_MAX_TIMEOUT (10 * 60) /* 10 mins */ -#define SIRFSOC_WDT_DEFAULT_TIMEOUT 30 /* 30 secs */ - -static unsigned int timeout; -static bool nowayout = WATCHDOG_NOWAYOUT; - -module_param(timeout, uint, 0); -module_param(nowayout, bool, 0); - -MODULE_PARM_DESC(timeout, "Default watchdog timeout (in seconds)"); -MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" - __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); - -static void __iomem *sirfsoc_wdt_base(struct watchdog_device *wdd) -{ - return (void __iomem __force *)watchdog_get_drvdata(wdd); -} - -static unsigned int sirfsoc_wdt_gettimeleft(struct watchdog_device *wdd) -{ - u32 counter, match; - void __iomem *wdt_base; - int time_left; - - wdt_base = sirfsoc_wdt_base(wdd); - counter = readl(wdt_base + SIRFSOC_TIMER_COUNTER_LO); - match = readl(wdt_base + - SIRFSOC_TIMER_MATCH_0 + (SIRFSOC_TIMER_WDT_INDEX << 2)); - - time_left = match - counter; - - return time_left / CLOCK_FREQ; -} - -static int sirfsoc_wdt_updatetimeout(struct watchdog_device *wdd) -{ - u32 counter, timeout_ticks; - void __iomem *wdt_base; - - timeout_ticks = wdd->timeout * CLOCK_FREQ; - wdt_base = sirfsoc_wdt_base(wdd); - - /* Enable the latch before reading the LATCH_LO register */ - writel(1, wdt_base + SIRFSOC_TIMER_LATCH); - - /* Set the TO value */ - counter = readl(wdt_base + SIRFSOC_TIMER_LATCHED_LO); - - counter += timeout_ticks; - - writel(counter, wdt_base + - SIRFSOC_TIMER_MATCH_0 + (SIRFSOC_TIMER_WDT_INDEX << 2)); - - return 0; -} - -static int sirfsoc_wdt_enable(struct watchdog_device *wdd) -{ - void __iomem *wdt_base = sirfsoc_wdt_base(wdd); - sirfsoc_wdt_updatetimeout(wdd); - - /* - * NOTE: If interrupt is not enabled - * then WD-Reset doesn't get generated at all. - */ - writel(readl(wdt_base + SIRFSOC_TIMER_INT_EN) - | (1 << SIRFSOC_TIMER_WDT_INDEX), - wdt_base + SIRFSOC_TIMER_INT_EN); - writel(1, wdt_base + SIRFSOC_TIMER_WATCHDOG_EN); - - return 0; -} - -static int sirfsoc_wdt_disable(struct watchdog_device *wdd) -{ - void __iomem *wdt_base = sirfsoc_wdt_base(wdd); - - writel(0, wdt_base + SIRFSOC_TIMER_WATCHDOG_EN); - writel(readl(wdt_base + SIRFSOC_TIMER_INT_EN) - & (~(1 << SIRFSOC_TIMER_WDT_INDEX)), - wdt_base + SIRFSOC_TIMER_INT_EN); - - return 0; -} - -static int sirfsoc_wdt_settimeout(struct watchdog_device *wdd, unsigned int to) -{ - wdd->timeout = to; - sirfsoc_wdt_updatetimeout(wdd); - - return 0; -} - -#define OPTIONS (WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING | WDIOF_MAGICCLOSE) - -static const struct watchdog_info sirfsoc_wdt_ident = { - .options = OPTIONS, - .firmware_version = 0, - .identity = "SiRFSOC Watchdog", -}; - -static const struct watchdog_ops sirfsoc_wdt_ops = { - .owner = THIS_MODULE, - .start = sirfsoc_wdt_enable, - .stop = sirfsoc_wdt_disable, - .get_timeleft = sirfsoc_wdt_gettimeleft, - .ping = sirfsoc_wdt_updatetimeout, - .set_timeout = sirfsoc_wdt_settimeout, -}; - -static struct watchdog_device sirfsoc_wdd = { - .info = &sirfsoc_wdt_ident, - .ops = &sirfsoc_wdt_ops, - .timeout = SIRFSOC_WDT_DEFAULT_TIMEOUT, - .min_timeout = SIRFSOC_WDT_MIN_TIMEOUT, - .max_timeout = SIRFSOC_WDT_MAX_TIMEOUT, -}; - -static int sirfsoc_wdt_probe(struct platform_device *pdev) -{ - struct device *dev = &pdev->dev; - int ret; - void __iomem *base; - - base = devm_platform_ioremap_resource(pdev, 0); - if (IS_ERR(base)) - return PTR_ERR(base); - - watchdog_set_drvdata(&sirfsoc_wdd, (__force void *)base); - - watchdog_init_timeout(&sirfsoc_wdd, timeout, dev); - watchdog_set_nowayout(&sirfsoc_wdd, nowayout); - sirfsoc_wdd.parent = dev; - - watchdog_stop_on_reboot(&sirfsoc_wdd); - watchdog_stop_on_unregister(&sirfsoc_wdd); - ret = devm_watchdog_register_device(dev, &sirfsoc_wdd); - if (ret) - return ret; - - platform_set_drvdata(pdev, &sirfsoc_wdd); - - return 0; -} - -#ifdef CONFIG_PM_SLEEP -static int sirfsoc_wdt_suspend(struct device *dev) -{ - return 0; -} - -static int sirfsoc_wdt_resume(struct device *dev) -{ - struct watchdog_device *wdd = dev_get_drvdata(dev); - - /* - * NOTE: Since timer controller registers settings are saved - * and restored back by the timer-prima2.c, so we need not - * update WD settings except refreshing timeout. - */ - sirfsoc_wdt_updatetimeout(wdd); - - return 0; -} -#endif - -static SIMPLE_DEV_PM_OPS(sirfsoc_wdt_pm_ops, - sirfsoc_wdt_suspend, sirfsoc_wdt_resume); - -static const struct of_device_id sirfsoc_wdt_of_match[] = { - { .compatible = "sirf,prima2-tick"}, - {}, -}; -MODULE_DEVICE_TABLE(of, sirfsoc_wdt_of_match); - -static struct platform_driver sirfsoc_wdt_driver = { - .driver = { - .name = "sirfsoc-wdt", - .pm = &sirfsoc_wdt_pm_ops, - .of_match_table = sirfsoc_wdt_of_match, - }, - .probe = sirfsoc_wdt_probe, -}; -module_platform_driver(sirfsoc_wdt_driver); - -MODULE_DESCRIPTION("SiRF SoC watchdog driver"); -MODULE_AUTHOR("Xianglong Du "); -MODULE_LICENSE("GPL v2"); -MODULE_ALIAS("platform:sirfsoc-wdt"); -- cgit v1.2.3 From 30f1ec70ddf5afd6a8d4c0e1ce9f21a4aea936be Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Wed, 20 Jan 2021 17:27:43 +0100 Subject: watchdog: remove zte zx driver The zte zx platform is getting removed, so this driver is no longer needed. Cc: Jun Nie Cc: Shawn Guo Signed-off-by: Arnd Bergmann Reviewed-by: Guenter Roeck Link: https://lore.kernel.org/r/20210120162745.61268-4-arnd@kernel.org Signed-off-by: Guenter Roeck Signed-off-by: Wim Van Sebroeck --- .../bindings/watchdog/zte,zx2967-wdt.txt | 32 --- drivers/watchdog/Kconfig | 10 - drivers/watchdog/Makefile | 1 - drivers/watchdog/zx2967_wdt.c | 279 --------------------- 4 files changed, 322 deletions(-) delete mode 100644 Documentation/devicetree/bindings/watchdog/zte,zx2967-wdt.txt delete mode 100644 drivers/watchdog/zx2967_wdt.c (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/watchdog/zte,zx2967-wdt.txt b/Documentation/devicetree/bindings/watchdog/zte,zx2967-wdt.txt deleted file mode 100644 index 06ce67766756..000000000000 --- a/Documentation/devicetree/bindings/watchdog/zte,zx2967-wdt.txt +++ /dev/null @@ -1,32 +0,0 @@ -ZTE zx2967 Watchdog timer - -Required properties: - -- compatible : should be one of the following. - * zte,zx296718-wdt -- reg : Specifies base physical address and size of the registers. -- clocks : Pairs of phandle and specifier referencing the controller's clocks. -- resets : Reference to the reset controller controlling the watchdog - controller. - -Optional properties: - -- timeout-sec : Contains the watchdog timeout in seconds. -- zte,wdt-reset-sysctrl : Directs how to reset system by the watchdog. - if we don't want to restart system when watchdog been triggered, - it's not required, vice versa. - It should include following fields. - * phandle of aon-sysctrl. - * offset of register that be written, should be 0xb0. - * configure value that be written to aon-sysctrl. - * bit mask, corresponding bits will be affected. - -Example: - -wdt: watchdog@1465000 { - compatible = "zte,zx296718-wdt"; - reg = <0x1465000 0x1000>; - clocks = <&topcrm WDT_WCLK>; - resets = <&toprst 35>; - zte,wdt-reset-sysctrl = <&aon_sysctrl 0xb0 1 0x115>; -}; diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig index d787138cc8fe..5d47a702f936 100644 --- a/drivers/watchdog/Kconfig +++ b/drivers/watchdog/Kconfig @@ -919,16 +919,6 @@ config ASPEED_WATCHDOG To compile this driver as a module, choose M here: the module will be called aspeed_wdt. -config ZX2967_WATCHDOG - tristate "ZTE zx2967 SoCs watchdog support" - depends on ARCH_ZX - select WATCHDOG_CORE - help - Say Y here to include support for the watchdog timer - in ZTE zx2967 SoCs. - To compile this driver as a module, choose M here: the - module will be called zx2967_wdt. - config STM32_WATCHDOG tristate "STM32 Independent WatchDoG (IWDG) support" depends on ARCH_STM32 diff --git a/drivers/watchdog/Makefile b/drivers/watchdog/Makefile index 69517fffbedb..d7678d8d9893 100644 --- a/drivers/watchdog/Makefile +++ b/drivers/watchdog/Makefile @@ -86,7 +86,6 @@ obj-$(CONFIG_BCM7038_WDT) += bcm7038_wdt.o obj-$(CONFIG_RENESAS_WDT) += renesas_wdt.o obj-$(CONFIG_RENESAS_RZAWDT) += rza_wdt.o obj-$(CONFIG_ASPEED_WATCHDOG) += aspeed_wdt.o -obj-$(CONFIG_ZX2967_WATCHDOG) += zx2967_wdt.o obj-$(CONFIG_STM32_WATCHDOG) += stm32_iwdg.o obj-$(CONFIG_UNIPHIER_WATCHDOG) += uniphier_wdt.o obj-$(CONFIG_RTD119X_WATCHDOG) += rtd119x_wdt.o diff --git a/drivers/watchdog/zx2967_wdt.c b/drivers/watchdog/zx2967_wdt.c deleted file mode 100644 index bf183e73671a..000000000000 --- a/drivers/watchdog/zx2967_wdt.c +++ /dev/null @@ -1,279 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * watchdog driver for ZTE's zx2967 family - * - * Copyright (C) 2017 ZTE Ltd. - * - * Author: Baoyou Xie - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define ZX2967_WDT_CFG_REG 0x4 -#define ZX2967_WDT_LOAD_REG 0x8 -#define ZX2967_WDT_REFRESH_REG 0x18 -#define ZX2967_WDT_START_REG 0x1c - -#define ZX2967_WDT_REFRESH_MASK GENMASK(5, 0) - -#define ZX2967_WDT_CFG_DIV(n) ((((n) & 0xff) - 1) << 8) -#define ZX2967_WDT_START_EN 0x1 - -/* - * Hardware magic number. - * When watchdog reg is written, the lowest 16 bits are valid, but - * the highest 16 bits should be always this number. - */ -#define ZX2967_WDT_WRITEKEY (0x1234 << 16) -#define ZX2967_WDT_VAL_MASK GENMASK(15, 0) - -#define ZX2967_WDT_DIV_DEFAULT 16 -#define ZX2967_WDT_DEFAULT_TIMEOUT 32 -#define ZX2967_WDT_MIN_TIMEOUT 1 -#define ZX2967_WDT_MAX_TIMEOUT 524 -#define ZX2967_WDT_MAX_COUNT 0xffff - -#define ZX2967_WDT_CLK_FREQ 0x8000 - -#define ZX2967_WDT_FLAG_REBOOT_MON BIT(0) - -struct zx2967_wdt { - struct watchdog_device wdt_device; - void __iomem *reg_base; - struct clk *clock; -}; - -static inline u32 zx2967_wdt_readl(struct zx2967_wdt *wdt, u16 reg) -{ - return readl_relaxed(wdt->reg_base + reg); -} - -static inline void zx2967_wdt_writel(struct zx2967_wdt *wdt, u16 reg, u32 val) -{ - writel_relaxed(val | ZX2967_WDT_WRITEKEY, wdt->reg_base + reg); -} - -static void zx2967_wdt_refresh(struct zx2967_wdt *wdt) -{ - u32 val; - - val = zx2967_wdt_readl(wdt, ZX2967_WDT_REFRESH_REG); - /* - * Bit 4-5, 1 and 2: refresh config info - * Bit 2-3, 1 and 2: refresh counter - * Bit 0-1, 1 and 2: refresh int-value - * we shift each group value between 1 and 2 to refresh all data. - */ - val ^= ZX2967_WDT_REFRESH_MASK; - zx2967_wdt_writel(wdt, ZX2967_WDT_REFRESH_REG, - val & ZX2967_WDT_VAL_MASK); -} - -static int -zx2967_wdt_set_timeout(struct watchdog_device *wdd, unsigned int timeout) -{ - struct zx2967_wdt *wdt = watchdog_get_drvdata(wdd); - unsigned int divisor = ZX2967_WDT_DIV_DEFAULT; - u32 count; - - count = timeout * ZX2967_WDT_CLK_FREQ; - if (count > divisor * ZX2967_WDT_MAX_COUNT) - divisor = DIV_ROUND_UP(count, ZX2967_WDT_MAX_COUNT); - count = DIV_ROUND_UP(count, divisor); - zx2967_wdt_writel(wdt, ZX2967_WDT_CFG_REG, - ZX2967_WDT_CFG_DIV(divisor) & ZX2967_WDT_VAL_MASK); - zx2967_wdt_writel(wdt, ZX2967_WDT_LOAD_REG, - count & ZX2967_WDT_VAL_MASK); - zx2967_wdt_refresh(wdt); - wdd->timeout = (count * divisor) / ZX2967_WDT_CLK_FREQ; - - return 0; -} - -static void __zx2967_wdt_start(struct zx2967_wdt *wdt) -{ - u32 val; - - val = zx2967_wdt_readl(wdt, ZX2967_WDT_START_REG); - val |= ZX2967_WDT_START_EN; - zx2967_wdt_writel(wdt, ZX2967_WDT_START_REG, - val & ZX2967_WDT_VAL_MASK); -} - -static void __zx2967_wdt_stop(struct zx2967_wdt *wdt) -{ - u32 val; - - val = zx2967_wdt_readl(wdt, ZX2967_WDT_START_REG); - val &= ~ZX2967_WDT_START_EN; - zx2967_wdt_writel(wdt, ZX2967_WDT_START_REG, - val & ZX2967_WDT_VAL_MASK); -} - -static int zx2967_wdt_start(struct watchdog_device *wdd) -{ - struct zx2967_wdt *wdt = watchdog_get_drvdata(wdd); - - zx2967_wdt_set_timeout(wdd, wdd->timeout); - __zx2967_wdt_start(wdt); - - return 0; -} - -static int zx2967_wdt_stop(struct watchdog_device *wdd) -{ - struct zx2967_wdt *wdt = watchdog_get_drvdata(wdd); - - __zx2967_wdt_stop(wdt); - - return 0; -} - -static int zx2967_wdt_keepalive(struct watchdog_device *wdd) -{ - struct zx2967_wdt *wdt = watchdog_get_drvdata(wdd); - - zx2967_wdt_refresh(wdt); - - return 0; -} - -#define ZX2967_WDT_OPTIONS \ - (WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING | WDIOF_MAGICCLOSE) -static const struct watchdog_info zx2967_wdt_ident = { - .options = ZX2967_WDT_OPTIONS, - .identity = "zx2967 watchdog", -}; - -static const struct watchdog_ops zx2967_wdt_ops = { - .owner = THIS_MODULE, - .start = zx2967_wdt_start, - .stop = zx2967_wdt_stop, - .ping = zx2967_wdt_keepalive, - .set_timeout = zx2967_wdt_set_timeout, -}; - -static void zx2967_wdt_reset_sysctrl(struct device *dev) -{ - int ret; - void __iomem *regmap; - unsigned int offset, mask, config; - struct of_phandle_args out_args; - - ret = of_parse_phandle_with_fixed_args(dev->of_node, - "zte,wdt-reset-sysctrl", 3, 0, &out_args); - if (ret) - return; - - offset = out_args.args[0]; - config = out_args.args[1]; - mask = out_args.args[2]; - - regmap = syscon_node_to_regmap(out_args.np); - if (IS_ERR(regmap)) { - of_node_put(out_args.np); - return; - } - - regmap_update_bits(regmap, offset, mask, config); - of_node_put(out_args.np); -} - -static void zx2967_clk_disable_unprepare(void *data) -{ - clk_disable_unprepare(data); -} - -static int zx2967_wdt_probe(struct platform_device *pdev) -{ - struct device *dev = &pdev->dev; - struct zx2967_wdt *wdt; - int ret; - struct reset_control *rstc; - - wdt = devm_kzalloc(dev, sizeof(*wdt), GFP_KERNEL); - if (!wdt) - return -ENOMEM; - - platform_set_drvdata(pdev, wdt); - - wdt->wdt_device.info = &zx2967_wdt_ident; - wdt->wdt_device.ops = &zx2967_wdt_ops; - wdt->wdt_device.timeout = ZX2967_WDT_DEFAULT_TIMEOUT; - wdt->wdt_device.max_timeout = ZX2967_WDT_MAX_TIMEOUT; - wdt->wdt_device.min_timeout = ZX2967_WDT_MIN_TIMEOUT; - wdt->wdt_device.parent = dev; - - wdt->reg_base = devm_platform_ioremap_resource(pdev, 0); - if (IS_ERR(wdt->reg_base)) - return PTR_ERR(wdt->reg_base); - - zx2967_wdt_reset_sysctrl(dev); - - wdt->clock = devm_clk_get(dev, NULL); - if (IS_ERR(wdt->clock)) { - dev_err(dev, "failed to find watchdog clock source\n"); - return PTR_ERR(wdt->clock); - } - - ret = clk_prepare_enable(wdt->clock); - if (ret < 0) { - dev_err(dev, "failed to enable clock\n"); - return ret; - } - ret = devm_add_action_or_reset(dev, zx2967_clk_disable_unprepare, - wdt->clock); - if (ret) - return ret; - clk_set_rate(wdt->clock, ZX2967_WDT_CLK_FREQ); - - rstc = devm_reset_control_get_exclusive(dev, NULL); - if (IS_ERR(rstc)) { - dev_err(dev, "failed to get rstc"); - return PTR_ERR(rstc); - } - - reset_control_assert(rstc); - reset_control_deassert(rstc); - - watchdog_set_drvdata(&wdt->wdt_device, wdt); - watchdog_init_timeout(&wdt->wdt_device, - ZX2967_WDT_DEFAULT_TIMEOUT, dev); - watchdog_set_nowayout(&wdt->wdt_device, WATCHDOG_NOWAYOUT); - - ret = devm_watchdog_register_device(dev, &wdt->wdt_device); - if (ret) - return ret; - - dev_info(dev, "watchdog enabled (timeout=%d sec, nowayout=%d)", - wdt->wdt_device.timeout, WATCHDOG_NOWAYOUT); - - return 0; -} - -static const struct of_device_id zx2967_wdt_match[] = { - { .compatible = "zte,zx296718-wdt", }, - {} -}; -MODULE_DEVICE_TABLE(of, zx2967_wdt_match); - -static struct platform_driver zx2967_wdt_driver = { - .probe = zx2967_wdt_probe, - .driver = { - .name = "zx2967-wdt", - .of_match_table = of_match_ptr(zx2967_wdt_match), - }, -}; -module_platform_driver(zx2967_wdt_driver); - -MODULE_AUTHOR("Baoyou Xie "); -MODULE_DESCRIPTION("ZTE zx2967 Watchdog Device Driver"); -MODULE_LICENSE("GPL v2"); -- cgit v1.2.3 From c1b50b55b00daa373379bb1062afab5ce279cad1 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Wed, 20 Jan 2021 17:27:44 +0100 Subject: watchdog: remove tango driver The tango platform is getting removed, so the driver is no longer needed. Cc: Marc Gonzalez Cc: Mans Rullgard Signed-off-by: Arnd Bergmann Reviewed-by: Guenter Roeck Acked-by: Mans Rullgard Link: https://lore.kernel.org/r/20210120162745.61268-5-arnd@kernel.org [groeck: Removed devicetree bindings] Signed-off-by: Guenter Roeck Signed-off-by: Wim Van Sebroeck --- .../bindings/watchdog/sigma,smp8642-wdt.txt | 18 -- drivers/watchdog/Kconfig | 11 -- drivers/watchdog/Makefile | 1 - drivers/watchdog/tangox_wdt.c | 209 --------------------- 4 files changed, 239 deletions(-) delete mode 100644 Documentation/devicetree/bindings/watchdog/sigma,smp8642-wdt.txt delete mode 100644 drivers/watchdog/tangox_wdt.c (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/watchdog/sigma,smp8642-wdt.txt b/Documentation/devicetree/bindings/watchdog/sigma,smp8642-wdt.txt deleted file mode 100644 index 5b7ec2c707d8..000000000000 --- a/Documentation/devicetree/bindings/watchdog/sigma,smp8642-wdt.txt +++ /dev/null @@ -1,18 +0,0 @@ -Sigma Designs SMP86xx/SMP87xx watchdog - -Required properties: -- compatible: Should be "sigma,smp8642-wdt" -- reg: Specifies the physical address region -- clocks: Should be a phandle to the clock - -Optional properties: -- timeout-sec: watchdog timeout in seconds - -Example: - -watchdog@1fd00 { - compatible = "sigma,smp8642-wdt"; - reg = <0x1fd00 8>; - clocks = <&xtal_in_clk>; - timeout-sec = <30>; -}; diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig index 5d47a702f936..dc191725b4e5 100644 --- a/drivers/watchdog/Kconfig +++ b/drivers/watchdog/Kconfig @@ -254,17 +254,6 @@ config MENZ069_WATCHDOG This driver can also be built as a module. If so the module will be called menz069_wdt. -config TANGOX_WATCHDOG - tristate "Sigma Designs SMP86xx/SMP87xx watchdog" - select WATCHDOG_CORE - depends on ARCH_TANGO || COMPILE_TEST - depends on HAS_IOMEM - help - Support for the watchdog in Sigma Designs SMP86xx (tango3) - and SMP87xx (tango4) family chips. - - This driver can be built as a module. The module name is tangox_wdt. - config WDAT_WDT tristate "ACPI Watchdog Action Table (WDAT)" depends on ACPI diff --git a/drivers/watchdog/Makefile b/drivers/watchdog/Makefile index d7678d8d9893..59ab621720ab 100644 --- a/drivers/watchdog/Makefile +++ b/drivers/watchdog/Makefile @@ -211,7 +211,6 @@ obj-$(CONFIG_DA9055_WATCHDOG) += da9055_wdt.o obj-$(CONFIG_DA9062_WATCHDOG) += da9062_wdt.o obj-$(CONFIG_DA9063_WATCHDOG) += da9063_wdt.o obj-$(CONFIG_GPIO_WATCHDOG) += gpio_wdt.o -obj-$(CONFIG_TANGOX_WATCHDOG) += tangox_wdt.o obj-$(CONFIG_WDAT_WDT) += wdat_wdt.o obj-$(CONFIG_WM831X_WATCHDOG) += wm831x_wdt.o obj-$(CONFIG_WM8350_WATCHDOG) += wm8350_wdt.o diff --git a/drivers/watchdog/tangox_wdt.c b/drivers/watchdog/tangox_wdt.c deleted file mode 100644 index 1afb0e9d808c..000000000000 --- a/drivers/watchdog/tangox_wdt.c +++ /dev/null @@ -1,209 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0+ -/* - * Copyright (C) 2015 Mans Rullgard - * SMP86xx/SMP87xx Watchdog driver - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define DEFAULT_TIMEOUT 30 - -static bool nowayout = WATCHDOG_NOWAYOUT; -module_param(nowayout, bool, 0); -MODULE_PARM_DESC(nowayout, - "Watchdog cannot be stopped once started (default=" - __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); - -static unsigned int timeout; -module_param(timeout, int, 0); -MODULE_PARM_DESC(timeout, "Watchdog timeout"); - -/* - * Counter counts down from programmed value. Reset asserts when - * the counter reaches 1. - */ -#define WD_COUNTER 0 - -#define WD_CONFIG 4 -#define WD_CONFIG_XTAL_IN BIT(0) -#define WD_CONFIG_DISABLE BIT(31) - -struct tangox_wdt_device { - struct watchdog_device wdt; - void __iomem *base; - unsigned long clk_rate; - struct clk *clk; -}; - -static int tangox_wdt_set_timeout(struct watchdog_device *wdt, - unsigned int new_timeout) -{ - wdt->timeout = new_timeout; - - return 0; -} - -static int tangox_wdt_start(struct watchdog_device *wdt) -{ - struct tangox_wdt_device *dev = watchdog_get_drvdata(wdt); - u32 ticks; - - ticks = 1 + wdt->timeout * dev->clk_rate; - writel(ticks, dev->base + WD_COUNTER); - - return 0; -} - -static int tangox_wdt_stop(struct watchdog_device *wdt) -{ - struct tangox_wdt_device *dev = watchdog_get_drvdata(wdt); - - writel(0, dev->base + WD_COUNTER); - - return 0; -} - -static unsigned int tangox_wdt_get_timeleft(struct watchdog_device *wdt) -{ - struct tangox_wdt_device *dev = watchdog_get_drvdata(wdt); - u32 count; - - count = readl(dev->base + WD_COUNTER); - - if (!count) - return 0; - - return (count - 1) / dev->clk_rate; -} - -static const struct watchdog_info tangox_wdt_info = { - .options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING | WDIOF_MAGICCLOSE, - .identity = "tangox watchdog", -}; - -static int tangox_wdt_restart(struct watchdog_device *wdt, - unsigned long action, void *data) -{ - struct tangox_wdt_device *dev = watchdog_get_drvdata(wdt); - - writel(1, dev->base + WD_COUNTER); - - return 0; -} - -static const struct watchdog_ops tangox_wdt_ops = { - .start = tangox_wdt_start, - .stop = tangox_wdt_stop, - .set_timeout = tangox_wdt_set_timeout, - .get_timeleft = tangox_wdt_get_timeleft, - .restart = tangox_wdt_restart, -}; - -static void tangox_clk_disable_unprepare(void *data) -{ - clk_disable_unprepare(data); -} - -static int tangox_wdt_probe(struct platform_device *pdev) -{ - struct tangox_wdt_device *dev; - u32 config; - int err; - - dev = devm_kzalloc(&pdev->dev, sizeof(*dev), GFP_KERNEL); - if (!dev) - return -ENOMEM; - - dev->base = devm_platform_ioremap_resource(pdev, 0); - if (IS_ERR(dev->base)) - return PTR_ERR(dev->base); - - dev->clk = devm_clk_get(&pdev->dev, NULL); - if (IS_ERR(dev->clk)) - return PTR_ERR(dev->clk); - - err = clk_prepare_enable(dev->clk); - if (err) - return err; - err = devm_add_action_or_reset(&pdev->dev, - tangox_clk_disable_unprepare, dev->clk); - if (err) - return err; - - dev->clk_rate = clk_get_rate(dev->clk); - if (!dev->clk_rate) - return -EINVAL; - - dev->wdt.parent = &pdev->dev; - dev->wdt.info = &tangox_wdt_info; - dev->wdt.ops = &tangox_wdt_ops; - dev->wdt.timeout = DEFAULT_TIMEOUT; - dev->wdt.min_timeout = 1; - dev->wdt.max_hw_heartbeat_ms = (U32_MAX - 1) / dev->clk_rate; - - watchdog_init_timeout(&dev->wdt, timeout, &pdev->dev); - watchdog_set_nowayout(&dev->wdt, nowayout); - watchdog_set_drvdata(&dev->wdt, dev); - - /* - * Deactivate counter if disable bit is set to avoid - * accidental reset. - */ - config = readl(dev->base + WD_CONFIG); - if (config & WD_CONFIG_DISABLE) - writel(0, dev->base + WD_COUNTER); - - writel(WD_CONFIG_XTAL_IN, dev->base + WD_CONFIG); - - /* - * Mark as active and restart with configured timeout if - * already running. - */ - if (readl(dev->base + WD_COUNTER)) { - set_bit(WDOG_HW_RUNNING, &dev->wdt.status); - tangox_wdt_start(&dev->wdt); - } - - watchdog_set_restart_priority(&dev->wdt, 128); - - watchdog_stop_on_unregister(&dev->wdt); - err = devm_watchdog_register_device(&pdev->dev, &dev->wdt); - if (err) - return err; - - platform_set_drvdata(pdev, dev); - - dev_info(&pdev->dev, "SMP86xx/SMP87xx watchdog registered\n"); - - return 0; -} - -static const struct of_device_id tangox_wdt_dt_ids[] = { - { .compatible = "sigma,smp8642-wdt" }, - { .compatible = "sigma,smp8759-wdt" }, - { } -}; -MODULE_DEVICE_TABLE(of, tangox_wdt_dt_ids); - -static struct platform_driver tangox_wdt_driver = { - .probe = tangox_wdt_probe, - .driver = { - .name = "tangox-wdt", - .of_match_table = tangox_wdt_dt_ids, - }, -}; - -module_platform_driver(tangox_wdt_driver); - -MODULE_AUTHOR("Mans Rullgard "); -MODULE_DESCRIPTION("SMP86xx/SMP87xx Watchdog driver"); -MODULE_LICENSE("GPL"); -- cgit v1.2.3 From 5ecd125b4b2a55a394a459df331a0b6380c773fa Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Wed, 20 Jan 2021 17:27:45 +0100 Subject: watchdog: remove coh901 driver The ST-Ericsson U300 platform is getting removed, so this driver is no longer needed. Cc: Linus Walleij Signed-off-by: Arnd Bergmann Reviewed-by: Guenter Roeck Reviewed-by: Linus Walleij Link: https://lore.kernel.org/r/20210120162745.61268-6-arnd@kernel.org Signed-off-by: Guenter Roeck Signed-off-by: Wim Van Sebroeck --- .../bindings/watchdog/stericsson-coh901327.txt | 19 - drivers/watchdog/Kconfig | 11 - drivers/watchdog/Makefile | 1 - drivers/watchdog/coh901327_wdt.c | 408 --------------------- 4 files changed, 439 deletions(-) delete mode 100644 Documentation/devicetree/bindings/watchdog/stericsson-coh901327.txt delete mode 100644 drivers/watchdog/coh901327_wdt.c (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/watchdog/stericsson-coh901327.txt b/Documentation/devicetree/bindings/watchdog/stericsson-coh901327.txt deleted file mode 100644 index 8ffb88e39e76..000000000000 --- a/Documentation/devicetree/bindings/watchdog/stericsson-coh901327.txt +++ /dev/null @@ -1,19 +0,0 @@ -ST-Ericsson COH 901 327 Watchdog timer - -Required properties: -- compatible: must be "stericsson,coh901327". -- reg: physical base address of the controller and length of memory mapped - region. -- interrupts: the interrupt used for the watchdog timeout warning. - -Optional properties: -- timeout-sec: contains the watchdog timeout in seconds. - -Example: - -watchdog: watchdog@c0012000 { - compatible = "stericsson,coh901327"; - reg = <0xc0012000 0x1000>; - interrupts = <3>; - timeout-sec = <60>; -}; diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig index dc191725b4e5..0470dc15c085 100644 --- a/drivers/watchdog/Kconfig +++ b/drivers/watchdog/Kconfig @@ -619,17 +619,6 @@ config SUNXI_WATCHDOG To compile this driver as a module, choose M here: the module will be called sunxi_wdt. -config COH901327_WATCHDOG - bool "ST-Ericsson COH 901 327 watchdog" - depends on ARCH_U300 || (ARM && COMMON_CLK && COMPILE_TEST) - default y if MACH_U300 - select WATCHDOG_CORE - help - Say Y here to include Watchdog timer support for the - watchdog embedded into the ST-Ericsson U300 series platforms. - This watchdog is used to reset the system and thus cannot be - compiled as a module. - config NPCM7XX_WATCHDOG tristate "Nuvoton NPCM750 watchdog" depends on ARCH_NPCM || COMPILE_TEST diff --git a/drivers/watchdog/Makefile b/drivers/watchdog/Makefile index 59ab621720ab..57058b81af73 100644 --- a/drivers/watchdog/Makefile +++ b/drivers/watchdog/Makefile @@ -61,7 +61,6 @@ obj-$(CONFIG_K3_RTI_WATCHDOG) += rti_wdt.o obj-$(CONFIG_ORION_WATCHDOG) += orion_wdt.o obj-$(CONFIG_SUNXI_WATCHDOG) += sunxi_wdt.o obj-$(CONFIG_RN5T618_WATCHDOG) += rn5t618_wdt.o -obj-$(CONFIG_COH901327_WATCHDOG) += coh901327_wdt.o obj-$(CONFIG_NPCM7XX_WATCHDOG) += npcm_wdt.o obj-$(CONFIG_STMP3XXX_RTC_WATCHDOG) += stmp3xxx_rtc_wdt.o obj-$(CONFIG_TS4800_WATCHDOG) += ts4800_wdt.o diff --git a/drivers/watchdog/coh901327_wdt.c b/drivers/watchdog/coh901327_wdt.c deleted file mode 100644 index 260c50b08483..000000000000 --- a/drivers/watchdog/coh901327_wdt.c +++ /dev/null @@ -1,408 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* - * coh901327_wdt.c - * - * Copyright (C) 2008-2009 ST-Ericsson AB - * Watchdog driver for the ST-Ericsson AB COH 901 327 IP core - * Author: Linus Walleij - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define DRV_NAME "WDOG COH 901 327" - -/* - * COH 901 327 register definitions - */ - -/* WDOG_FEED Register 32bit (-/W) */ -#define U300_WDOG_FR 0x00 -#define U300_WDOG_FR_FEED_RESTART_TIMER 0xFEEDU -/* WDOG_TIMEOUT Register 32bit (R/W) */ -#define U300_WDOG_TR 0x04 -#define U300_WDOG_TR_TIMEOUT_MASK 0x7FFFU -/* WDOG_DISABLE1 Register 32bit (-/W) */ -#define U300_WDOG_D1R 0x08 -#define U300_WDOG_D1R_DISABLE1_DISABLE_TIMER 0x2BADU -/* WDOG_DISABLE2 Register 32bit (R/W) */ -#define U300_WDOG_D2R 0x0C -#define U300_WDOG_D2R_DISABLE2_DISABLE_TIMER 0xCAFEU -#define U300_WDOG_D2R_DISABLE_STATUS_DISABLED 0xDABEU -#define U300_WDOG_D2R_DISABLE_STATUS_ENABLED 0x0000U -/* WDOG_STATUS Register 32bit (R/W) */ -#define U300_WDOG_SR 0x10 -#define U300_WDOG_SR_STATUS_TIMED_OUT 0xCFE8U -#define U300_WDOG_SR_STATUS_NORMAL 0x0000U -#define U300_WDOG_SR_RESET_STATUS_RESET 0xE8B4U -/* WDOG_COUNT Register 32bit (R/-) */ -#define U300_WDOG_CR 0x14 -#define U300_WDOG_CR_VALID_IND 0x8000U -#define U300_WDOG_CR_VALID_STABLE 0x0000U -#define U300_WDOG_CR_COUNT_VALUE_MASK 0x7FFFU -/* WDOG_JTAGOVR Register 32bit (R/W) */ -#define U300_WDOG_JOR 0x18 -#define U300_WDOG_JOR_JTAG_MODE_IND 0x0002U -#define U300_WDOG_JOR_JTAG_WATCHDOG_ENABLE 0x0001U -/* WDOG_RESTART Register 32bit (-/W) */ -#define U300_WDOG_RR 0x1C -#define U300_WDOG_RR_RESTART_VALUE_RESUME 0xACEDU -/* WDOG_IRQ_EVENT Register 32bit (R/W) */ -#define U300_WDOG_IER 0x20 -#define U300_WDOG_IER_WILL_BARK_IRQ_EVENT_IND 0x0001U -#define U300_WDOG_IER_WILL_BARK_IRQ_ACK_ENABLE 0x0001U -/* WDOG_IRQ_MASK Register 32bit (R/W) */ -#define U300_WDOG_IMR 0x24 -#define U300_WDOG_IMR_WILL_BARK_IRQ_ENABLE 0x0001U -/* WDOG_IRQ_FORCE Register 32bit (R/W) */ -#define U300_WDOG_IFR 0x28 -#define U300_WDOG_IFR_WILL_BARK_IRQ_FORCE_ENABLE 0x0001U - -/* Default timeout in seconds = 1 minute */ -#define U300_WDOG_DEFAULT_TIMEOUT 60 - -static unsigned int margin; -static int irq; -static void __iomem *virtbase; -static struct device *parent; - -static struct clk *clk; - -/* - * Enabling and disabling functions. - */ -static void coh901327_enable(u16 timeout) -{ - u16 val; - unsigned long freq; - unsigned long delay_ns; - - /* Restart timer if it is disabled */ - val = readw(virtbase + U300_WDOG_D2R); - if (val == U300_WDOG_D2R_DISABLE_STATUS_DISABLED) - writew(U300_WDOG_RR_RESTART_VALUE_RESUME, - virtbase + U300_WDOG_RR); - /* Acknowledge any pending interrupt so it doesn't just fire off */ - writew(U300_WDOG_IER_WILL_BARK_IRQ_ACK_ENABLE, - virtbase + U300_WDOG_IER); - /* - * The interrupt is cleared in the 32 kHz clock domain. - * Wait 3 32 kHz cycles for it to take effect - */ - freq = clk_get_rate(clk); - delay_ns = DIV_ROUND_UP(1000000000, freq); /* Freq to ns and round up */ - delay_ns = 3 * delay_ns; /* Wait 3 cycles */ - ndelay(delay_ns); - /* Enable the watchdog interrupt */ - writew(U300_WDOG_IMR_WILL_BARK_IRQ_ENABLE, virtbase + U300_WDOG_IMR); - /* Activate the watchdog timer */ - writew(timeout, virtbase + U300_WDOG_TR); - /* Start the watchdog timer */ - writew(U300_WDOG_FR_FEED_RESTART_TIMER, virtbase + U300_WDOG_FR); - /* - * Extra read so that this change propagate in the watchdog. - */ - (void) readw(virtbase + U300_WDOG_CR); - val = readw(virtbase + U300_WDOG_D2R); - if (val != U300_WDOG_D2R_DISABLE_STATUS_ENABLED) - dev_err(parent, - "%s(): watchdog not enabled! D2R value %04x\n", - __func__, val); -} - -static void coh901327_disable(void) -{ - u16 val; - - /* Disable the watchdog interrupt if it is active */ - writew(0x0000U, virtbase + U300_WDOG_IMR); - /* If the watchdog is currently enabled, attempt to disable it */ - val = readw(virtbase + U300_WDOG_D2R); - if (val != U300_WDOG_D2R_DISABLE_STATUS_DISABLED) { - writew(U300_WDOG_D1R_DISABLE1_DISABLE_TIMER, - virtbase + U300_WDOG_D1R); - writew(U300_WDOG_D2R_DISABLE2_DISABLE_TIMER, - virtbase + U300_WDOG_D2R); - /* Write this twice (else problems occur) */ - writew(U300_WDOG_D2R_DISABLE2_DISABLE_TIMER, - virtbase + U300_WDOG_D2R); - } - val = readw(virtbase + U300_WDOG_D2R); - if (val != U300_WDOG_D2R_DISABLE_STATUS_DISABLED) - dev_err(parent, - "%s(): watchdog not disabled! D2R value %04x\n", - __func__, val); -} - -static int coh901327_start(struct watchdog_device *wdt_dev) -{ - coh901327_enable(wdt_dev->timeout * 100); - return 0; -} - -static int coh901327_stop(struct watchdog_device *wdt_dev) -{ - coh901327_disable(); - return 0; -} - -static int coh901327_ping(struct watchdog_device *wdd) -{ - /* Feed the watchdog */ - writew(U300_WDOG_FR_FEED_RESTART_TIMER, - virtbase + U300_WDOG_FR); - return 0; -} - -static int coh901327_settimeout(struct watchdog_device *wdt_dev, - unsigned int time) -{ - wdt_dev->timeout = time; - /* Set new timeout value */ - writew(time * 100, virtbase + U300_WDOG_TR); - /* Feed the dog */ - writew(U300_WDOG_FR_FEED_RESTART_TIMER, - virtbase + U300_WDOG_FR); - return 0; -} - -static unsigned int coh901327_gettimeleft(struct watchdog_device *wdt_dev) -{ - u16 val; - - /* Read repeatedly until the value is stable! */ - val = readw(virtbase + U300_WDOG_CR); - while (val & U300_WDOG_CR_VALID_IND) - val = readw(virtbase + U300_WDOG_CR); - val &= U300_WDOG_CR_COUNT_VALUE_MASK; - if (val != 0) - val /= 100; - - return val; -} - -/* - * This interrupt occurs 10 ms before the watchdog WILL bark. - */ -static irqreturn_t coh901327_interrupt(int irq, void *data) -{ - u16 val; - - /* - * Ack IRQ? If this occurs we're FUBAR anyway, so - * just acknowledge, disable the interrupt and await the imminent end. - * If you at some point need a host of callbacks to be called - * when the system is about to watchdog-reset, add them here! - * - * NOTE: on future versions of this IP-block, it will be possible - * to prevent a watchdog reset by feeding the watchdog at this - * point. - */ - val = readw(virtbase + U300_WDOG_IER); - if (val == U300_WDOG_IER_WILL_BARK_IRQ_EVENT_IND) - writew(U300_WDOG_IER_WILL_BARK_IRQ_ACK_ENABLE, - virtbase + U300_WDOG_IER); - writew(0x0000U, virtbase + U300_WDOG_IMR); - dev_crit(parent, "watchdog is barking!\n"); - return IRQ_HANDLED; -} - -static const struct watchdog_info coh901327_ident = { - .options = WDIOF_CARDRESET | WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING, - .identity = DRV_NAME, -}; - -static const struct watchdog_ops coh901327_ops = { - .owner = THIS_MODULE, - .start = coh901327_start, - .stop = coh901327_stop, - .ping = coh901327_ping, - .set_timeout = coh901327_settimeout, - .get_timeleft = coh901327_gettimeleft, -}; - -static struct watchdog_device coh901327_wdt = { - .info = &coh901327_ident, - .ops = &coh901327_ops, - /* - * Max timeout is 327 since the 10ms - * timeout register is max - * 0x7FFF = 327670ms ~= 327s. - */ - .min_timeout = 1, - .max_timeout = 327, - .timeout = U300_WDOG_DEFAULT_TIMEOUT, -}; - -static int __init coh901327_probe(struct platform_device *pdev) -{ - struct device *dev = &pdev->dev; - int ret; - u16 val; - - parent = dev; - - virtbase = devm_platform_ioremap_resource(pdev, 0); - if (IS_ERR(virtbase)) - return PTR_ERR(virtbase); - - clk = clk_get(dev, NULL); - if (IS_ERR(clk)) { - ret = PTR_ERR(clk); - dev_err(dev, "could not get clock\n"); - return ret; - } - ret = clk_prepare_enable(clk); - if (ret) { - dev_err(dev, "could not prepare and enable clock\n"); - goto out_no_clk_enable; - } - - val = readw(virtbase + U300_WDOG_SR); - switch (val) { - case U300_WDOG_SR_STATUS_TIMED_OUT: - dev_info(dev, "watchdog timed out since last chip reset!\n"); - coh901327_wdt.bootstatus |= WDIOF_CARDRESET; - /* Status will be cleared below */ - break; - case U300_WDOG_SR_STATUS_NORMAL: - dev_info(dev, "in normal status, no timeouts have occurred.\n"); - break; - default: - dev_info(dev, "contains an illegal status code (%08x)\n", val); - break; - } - - val = readw(virtbase + U300_WDOG_D2R); - switch (val) { - case U300_WDOG_D2R_DISABLE_STATUS_DISABLED: - dev_info(dev, "currently disabled.\n"); - break; - case U300_WDOG_D2R_DISABLE_STATUS_ENABLED: - dev_info(dev, "currently enabled! (disabling it now)\n"); - coh901327_disable(); - break; - default: - dev_err(dev, "contains an illegal enable/disable code (%08x)\n", - val); - break; - } - - /* Reset the watchdog */ - writew(U300_WDOG_SR_RESET_STATUS_RESET, virtbase + U300_WDOG_SR); - - irq = platform_get_irq(pdev, 0); - if (request_irq(irq, coh901327_interrupt, 0, - DRV_NAME " Bark", pdev)) { - ret = -EIO; - goto out_no_irq; - } - - watchdog_init_timeout(&coh901327_wdt, margin, dev); - - coh901327_wdt.parent = dev; - ret = watchdog_register_device(&coh901327_wdt); - if (ret) - goto out_no_wdog; - - dev_info(dev, "initialized. (timeout=%d sec)\n", - coh901327_wdt.timeout); - return 0; - -out_no_wdog: - free_irq(irq, pdev); -out_no_irq: - clk_disable_unprepare(clk); -out_no_clk_enable: - clk_put(clk); - return ret; -} - -#ifdef CONFIG_PM - -static u16 wdogenablestore; -static u16 irqmaskstore; - -static int coh901327_suspend(struct platform_device *pdev, pm_message_t state) -{ - irqmaskstore = readw(virtbase + U300_WDOG_IMR) & 0x0001U; - wdogenablestore = readw(virtbase + U300_WDOG_D2R); - /* If watchdog is on, disable it here and now */ - if (wdogenablestore == U300_WDOG_D2R_DISABLE_STATUS_ENABLED) - coh901327_disable(); - return 0; -} - -static int coh901327_resume(struct platform_device *pdev) -{ - /* Restore the watchdog interrupt */ - writew(irqmaskstore, virtbase + U300_WDOG_IMR); - if (wdogenablestore == U300_WDOG_D2R_DISABLE_STATUS_ENABLED) { - /* Restart the watchdog timer */ - writew(U300_WDOG_RR_RESTART_VALUE_RESUME, - virtbase + U300_WDOG_RR); - writew(U300_WDOG_FR_FEED_RESTART_TIMER, - virtbase + U300_WDOG_FR); - } - return 0; -} -#else -#define coh901327_suspend NULL -#define coh901327_resume NULL -#endif - -/* - * Mistreating the watchdog is the only way to perform a software reset of the - * system on EMP platforms. So we implement this and export a symbol for it. - */ -void coh901327_watchdog_reset(void) -{ - /* Enable even if on JTAG too */ - writew(U300_WDOG_JOR_JTAG_WATCHDOG_ENABLE, - virtbase + U300_WDOG_JOR); - /* - * Timeout = 5s, we have to wait for the watchdog reset to - * actually take place: the watchdog will be reloaded with the - * default value immediately, so we HAVE to reboot and get back - * into the kernel in 30s, or the device will reboot again! - * The boot loader will typically deactivate the watchdog, so we - * need time enough for the boot loader to get to the point of - * deactivating the watchdog before it is shut down by it. - * - * NOTE: on future versions of the watchdog, this restriction is - * gone: the watchdog will be reloaded with a default value (1 min) - * instead of last value, and you can conveniently set the watchdog - * timeout to 10ms (value = 1) without any problems. - */ - coh901327_enable(500); - /* Return and await doom */ -} - -static const struct of_device_id coh901327_dt_match[] = { - { .compatible = "stericsson,coh901327" }, - {}, -}; - -static struct platform_driver coh901327_driver = { - .driver = { - .name = "coh901327_wdog", - .of_match_table = coh901327_dt_match, - .suppress_bind_attrs = true, - }, - .suspend = coh901327_suspend, - .resume = coh901327_resume, -}; -builtin_platform_driver_probe(coh901327_driver, coh901327_probe); - -/* not really modular, but ... */ -module_param(margin, uint, 0); -MODULE_PARM_DESC(margin, "Watchdog margin in seconds (default 60s)"); -- cgit v1.2.3 From 310680d9f508cde22bd63cd63422bb8d1c81d499 Mon Sep 17 00:00:00 2001 From: Manivannan Sadhasivam Date: Mon, 18 Jan 2021 10:40:02 +0530 Subject: dt-bindings: watchdog: Add binding for Qcom SDX55 Add devicetree binding for watchdog present in Qcom SDX55 platform. Cc: Wim Van Sebroeck Cc: Guenter Roeck Cc: Rob Herring Cc: linux-watchdog@vger.kernel.org Cc: devicetree@vger.kernel.org Signed-off-by: Manivannan Sadhasivam Reviewed-by: Guenter Roeck Link: https://lore.kernel.org/r/20210118051005.55958-5-manivannan.sadhasivam@linaro.org Signed-off-by: Guenter Roeck Signed-off-by: Wim Van Sebroeck --- Documentation/devicetree/bindings/watchdog/qcom-wdt.yaml | 1 + 1 file changed, 1 insertion(+) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/watchdog/qcom-wdt.yaml b/Documentation/devicetree/bindings/watchdog/qcom-wdt.yaml index 8e3760a3822b..b8e4118945a0 100644 --- a/Documentation/devicetree/bindings/watchdog/qcom-wdt.yaml +++ b/Documentation/devicetree/bindings/watchdog/qcom-wdt.yaml @@ -18,6 +18,7 @@ properties: - qcom,apss-wdt-qcs404 - qcom,apss-wdt-sc7180 - qcom,apss-wdt-sdm845 + - qcom,apss-wdt-sdx55 - qcom,apss-wdt-sm8150 - qcom,kpss-timer - qcom,kpss-wdt -- cgit v1.2.3 From e17fe6579de023725ec22a16965e9099e4a05ac9 Mon Sep 17 00:00:00 2001 From: Eric Biggers Date: Fri, 15 Jan 2021 10:18:16 -0800 Subject: fs-verity: add FS_IOC_READ_VERITY_METADATA ioctl Add an ioctl FS_IOC_READ_VERITY_METADATA which will allow reading verity metadata from a file that has fs-verity enabled, including: - The Merkle tree - The fsverity_descriptor (not including the signature if present) - The built-in signature, if present This ioctl has similar semantics to pread(). It is passed the type of metadata to read (one of the above three), and a buffer, offset, and size. It returns the number of bytes read or an error. Separate patches will add support for each of the above metadata types. This patch just adds the ioctl itself. This ioctl doesn't make any assumption about where the metadata is stored on-disk. It does assume the metadata is in a stable format, but that's basically already the case: - The Merkle tree and fsverity_descriptor are defined by how fs-verity file digests are computed; see the "File digest computation" section of Documentation/filesystems/fsverity.rst. Technically, the way in which the levels of the tree are ordered relative to each other wasn't previously specified, but it's logical to put the root level first. - The built-in signature is the value passed to FS_IOC_ENABLE_VERITY. This ioctl is useful because it allows writing a server program that takes a verity file and serves it to a client program, such that the client can do its own fs-verity compatible verification of the file. This only makes sense if the client doesn't trust the server and if the server needs to provide the storage for the client. More concretely, there is interest in using this ability in Android to export APK files (which are protected by fs-verity) to "protected VMs". This would use Protected KVM (https://lwn.net/Articles/836693), which provides an isolated execution environment without having to trust the traditional "host". A "guest" VM can boot from a signed image and perform specific tasks in a minimum trusted environment using files that have fs-verity enabled on the host, without trusting the host or requiring that the guest has its own trusted storage. Technically, it would be possible to duplicate the metadata and store it in separate files for serving. However, that would be less efficient and would require extra care in userspace to maintain file consistency. In addition to the above, the ability to read the built-in signatures is useful because it allows a system that is using the in-kernel signature verification to migrate to userspace signature verification. Link: https://lore.kernel.org/r/20210115181819.34732-4-ebiggers@kernel.org Reviewed-by: Victor Hsieh Acked-by: Jaegeuk Kim Reviewed-by: Chao Yu Signed-off-by: Eric Biggers --- Documentation/filesystems/fsverity.rst | 57 ++++++++++++++++++++++++++++++++++ fs/ext4/ioctl.c | 7 +++++ fs/f2fs/file.c | 11 +++++++ fs/verity/Makefile | 1 + fs/verity/read_metadata.c | 55 ++++++++++++++++++++++++++++++++ include/linux/fsverity.h | 12 +++++++ include/uapi/linux/fsverity.h | 10 ++++++ 7 files changed, 153 insertions(+) create mode 100644 fs/verity/read_metadata.c (limited to 'Documentation') diff --git a/Documentation/filesystems/fsverity.rst b/Documentation/filesystems/fsverity.rst index e0204a23e997..9ef7a7de6008 100644 --- a/Documentation/filesystems/fsverity.rst +++ b/Documentation/filesystems/fsverity.rst @@ -217,6 +217,63 @@ FS_IOC_MEASURE_VERITY can fail with the following errors: - ``EOVERFLOW``: the digest is longer than the specified ``digest_size`` bytes. Try providing a larger buffer. +FS_IOC_READ_VERITY_METADATA +--------------------------- + +The FS_IOC_READ_VERITY_METADATA ioctl reads verity metadata from a +verity file. This ioctl is available since Linux v5.12. + +This ioctl allows writing a server program that takes a verity file +and serves it to a client program, such that the client can do its own +fs-verity compatible verification of the file. This only makes sense +if the client doesn't trust the server and if the server needs to +provide the storage for the client. + +This is a fairly specialized use case, and most fs-verity users won't +need this ioctl. + +This ioctl takes in a pointer to the following structure:: + + struct fsverity_read_metadata_arg { + __u64 metadata_type; + __u64 offset; + __u64 length; + __u64 buf_ptr; + __u64 __reserved; + }; + +``metadata_type`` specifies the type of metadata to read. + +The semantics are similar to those of ``pread()``. ``offset`` +specifies the offset in bytes into the metadata item to read from, and +``length`` specifies the maximum number of bytes to read from the +metadata item. ``buf_ptr`` is the pointer to the buffer to read into, +cast to a 64-bit integer. ``__reserved`` must be 0. On success, the +number of bytes read is returned. 0 is returned at the end of the +metadata item. The returned length may be less than ``length``, for +example if the ioctl is interrupted. + +The metadata returned by FS_IOC_READ_VERITY_METADATA isn't guaranteed +to be authenticated against the file digest that would be returned by +`FS_IOC_MEASURE_VERITY`_, as the metadata is expected to be used to +implement fs-verity compatible verification anyway (though absent a +malicious disk, the metadata will indeed match). E.g. to implement +this ioctl, the filesystem is allowed to just read the Merkle tree +blocks from disk without actually verifying the path to the root node. + +FS_IOC_READ_VERITY_METADATA can fail with the following errors: + +- ``EFAULT``: the caller provided inaccessible memory +- ``EINTR``: the ioctl was interrupted before any data was read +- ``EINVAL``: reserved fields were set, or ``offset + length`` + overflowed +- ``ENODATA``: the file is not a verity file +- ``ENOTTY``: this type of filesystem does not implement fs-verity, or + this ioctl is not yet implemented on it +- ``EOPNOTSUPP``: the kernel was not configured with fs-verity + support, or the filesystem superblock has not had the 'verity' + feature enabled on it. (See `Filesystem support`_.) + FS_IOC_GETFLAGS --------------- diff --git a/fs/ext4/ioctl.c b/fs/ext4/ioctl.c index d9665d2f82db..713b1ae44c1a 100644 --- a/fs/ext4/ioctl.c +++ b/fs/ext4/ioctl.c @@ -1309,6 +1309,12 @@ out: return -EOPNOTSUPP; return fsverity_ioctl_measure(filp, (void __user *)arg); + case FS_IOC_READ_VERITY_METADATA: + if (!ext4_has_feature_verity(sb)) + return -EOPNOTSUPP; + return fsverity_ioctl_read_metadata(filp, + (const void __user *)arg); + default: return -ENOTTY; } @@ -1391,6 +1397,7 @@ long ext4_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg) case FS_IOC_GETFSMAP: case FS_IOC_ENABLE_VERITY: case FS_IOC_MEASURE_VERITY: + case FS_IOC_READ_VERITY_METADATA: case EXT4_IOC_CLEAR_ES_CACHE: case EXT4_IOC_GETSTATE: case EXT4_IOC_GET_ES_CACHE: diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c index f585545277d7..d0aefb5b97fa 100644 --- a/fs/f2fs/file.c +++ b/fs/f2fs/file.c @@ -3357,6 +3357,14 @@ static int f2fs_ioc_measure_verity(struct file *filp, unsigned long arg) return fsverity_ioctl_measure(filp, (void __user *)arg); } +static int f2fs_ioc_read_verity_metadata(struct file *filp, unsigned long arg) +{ + if (!f2fs_sb_has_verity(F2FS_I_SB(file_inode(filp)))) + return -EOPNOTSUPP; + + return fsverity_ioctl_read_metadata(filp, (const void __user *)arg); +} + static int f2fs_ioc_getfslabel(struct file *filp, unsigned long arg) { struct inode *inode = file_inode(filp); @@ -4272,6 +4280,8 @@ static long __f2fs_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) return f2fs_ioc_enable_verity(filp, arg); case FS_IOC_MEASURE_VERITY: return f2fs_ioc_measure_verity(filp, arg); + case FS_IOC_READ_VERITY_METADATA: + return f2fs_ioc_read_verity_metadata(filp, arg); case FS_IOC_GETFSLABEL: return f2fs_ioc_getfslabel(filp, arg); case FS_IOC_SETFSLABEL: @@ -4523,6 +4533,7 @@ long f2fs_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg) case F2FS_IOC_RESIZE_FS: case FS_IOC_ENABLE_VERITY: case FS_IOC_MEASURE_VERITY: + case FS_IOC_READ_VERITY_METADATA: case FS_IOC_GETFSLABEL: case FS_IOC_SETFSLABEL: case F2FS_IOC_GET_COMPRESS_BLOCKS: diff --git a/fs/verity/Makefile b/fs/verity/Makefile index 570e9136334d..435559a4fa9e 100644 --- a/fs/verity/Makefile +++ b/fs/verity/Makefile @@ -5,6 +5,7 @@ obj-$(CONFIG_FS_VERITY) += enable.o \ init.o \ measure.o \ open.o \ + read_metadata.o \ verify.o obj-$(CONFIG_FS_VERITY_BUILTIN_SIGNATURES) += signature.o diff --git a/fs/verity/read_metadata.c b/fs/verity/read_metadata.c new file mode 100644 index 000000000000..43be990fd53e --- /dev/null +++ b/fs/verity/read_metadata.c @@ -0,0 +1,55 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Ioctl to read verity metadata + * + * Copyright 2021 Google LLC + */ + +#include "fsverity_private.h" + +#include + +/** + * fsverity_ioctl_read_metadata() - read verity metadata from a file + * @filp: file to read the metadata from + * @uarg: user pointer to fsverity_read_metadata_arg + * + * Return: length read on success, 0 on EOF, -errno on failure + */ +int fsverity_ioctl_read_metadata(struct file *filp, const void __user *uarg) +{ + struct inode *inode = file_inode(filp); + const struct fsverity_info *vi; + struct fsverity_read_metadata_arg arg; + int length; + void __user *buf; + + vi = fsverity_get_info(inode); + if (!vi) + return -ENODATA; /* not a verity file */ + /* + * Note that we don't have to explicitly check that the file is open for + * reading, since verity files can only be opened for reading. + */ + + if (copy_from_user(&arg, uarg, sizeof(arg))) + return -EFAULT; + + if (arg.__reserved) + return -EINVAL; + + /* offset + length must not overflow. */ + if (arg.offset + arg.length < arg.offset) + return -EINVAL; + + /* Ensure that the return value will fit in INT_MAX. */ + length = min_t(u64, arg.length, INT_MAX); + + buf = u64_to_user_ptr(arg.buf_ptr); + + switch (arg.metadata_type) { + default: + return -EINVAL; + } +} +EXPORT_SYMBOL_GPL(fsverity_ioctl_read_metadata); diff --git a/include/linux/fsverity.h b/include/linux/fsverity.h index c1144a450392..b568b3c7d095 100644 --- a/include/linux/fsverity.h +++ b/include/linux/fsverity.h @@ -138,6 +138,10 @@ int fsverity_file_open(struct inode *inode, struct file *filp); int fsverity_prepare_setattr(struct dentry *dentry, struct iattr *attr); void fsverity_cleanup_inode(struct inode *inode); +/* read_metadata.c */ + +int fsverity_ioctl_read_metadata(struct file *filp, const void __user *uarg); + /* verify.c */ bool fsverity_verify_page(struct page *page); @@ -183,6 +187,14 @@ static inline void fsverity_cleanup_inode(struct inode *inode) { } +/* read_metadata.c */ + +static inline int fsverity_ioctl_read_metadata(struct file *filp, + const void __user *uarg) +{ + return -EOPNOTSUPP; +} + /* verify.c */ static inline bool fsverity_verify_page(struct page *page) diff --git a/include/uapi/linux/fsverity.h b/include/uapi/linux/fsverity.h index 33f44156f8ea..e062751294d0 100644 --- a/include/uapi/linux/fsverity.h +++ b/include/uapi/linux/fsverity.h @@ -83,7 +83,17 @@ struct fsverity_formatted_digest { __u8 digest[]; }; +struct fsverity_read_metadata_arg { + __u64 metadata_type; + __u64 offset; + __u64 length; + __u64 buf_ptr; + __u64 __reserved; +}; + #define FS_IOC_ENABLE_VERITY _IOW('f', 133, struct fsverity_enable_arg) #define FS_IOC_MEASURE_VERITY _IOWR('f', 134, struct fsverity_digest) +#define FS_IOC_READ_VERITY_METADATA \ + _IOWR('f', 135, struct fsverity_read_metadata_arg) #endif /* _UAPI_LINUX_FSVERITY_H */ -- cgit v1.2.3 From 622699cfe6ec5578f52727002d5717ff3f092e23 Mon Sep 17 00:00:00 2001 From: Eric Biggers Date: Fri, 15 Jan 2021 10:18:17 -0800 Subject: fs-verity: support reading Merkle tree with ioctl Add support for FS_VERITY_METADATA_TYPE_MERKLE_TREE to FS_IOC_READ_VERITY_METADATA. This allows a userspace server program to retrieve the Merkle tree of a verity file for serving to a client which implements fs-verity compatible verification. See the patch which introduced FS_IOC_READ_VERITY_METADATA for more details. This has been tested using a new xfstest which calls this ioctl via a new subcommand for the 'fsverity' program from fsverity-utils. Link: https://lore.kernel.org/r/20210115181819.34732-5-ebiggers@kernel.org Reviewed-by: Victor Hsieh Reviewed-by: Jaegeuk Kim Reviewed-by: Chao Yu Signed-off-by: Eric Biggers --- Documentation/filesystems/fsverity.rst | 10 ++++- fs/verity/read_metadata.c | 70 ++++++++++++++++++++++++++++++++++ include/uapi/linux/fsverity.h | 2 + 3 files changed, 81 insertions(+), 1 deletion(-) (limited to 'Documentation') diff --git a/Documentation/filesystems/fsverity.rst b/Documentation/filesystems/fsverity.rst index 9ef7a7de6008..50b47a6d9ea1 100644 --- a/Documentation/filesystems/fsverity.rst +++ b/Documentation/filesystems/fsverity.rst @@ -234,6 +234,8 @@ need this ioctl. This ioctl takes in a pointer to the following structure:: + #define FS_VERITY_METADATA_TYPE_MERKLE_TREE 1 + struct fsverity_read_metadata_arg { __u64 metadata_type; __u64 offset; @@ -242,7 +244,13 @@ This ioctl takes in a pointer to the following structure:: __u64 __reserved; }; -``metadata_type`` specifies the type of metadata to read. +``metadata_type`` specifies the type of metadata to read: + +- ``FS_VERITY_METADATA_TYPE_MERKLE_TREE`` reads the blocks of the + Merkle tree. The blocks are returned in order from the root level + to the leaf level. Within each level, the blocks are returned in + the same order that their hashes are themselves hashed. + See `Merkle tree`_ for more information. The semantics are similar to those of ``pread()``. ``offset`` specifies the offset in bytes into the metadata item to read from, and diff --git a/fs/verity/read_metadata.c b/fs/verity/read_metadata.c index 43be990fd53e..0f8ad2991cf9 100644 --- a/fs/verity/read_metadata.c +++ b/fs/verity/read_metadata.c @@ -7,8 +7,75 @@ #include "fsverity_private.h" +#include +#include +#include #include +static int fsverity_read_merkle_tree(struct inode *inode, + const struct fsverity_info *vi, + void __user *buf, u64 offset, int length) +{ + const struct fsverity_operations *vops = inode->i_sb->s_vop; + u64 end_offset; + unsigned int offs_in_page; + pgoff_t index, last_index; + int retval = 0; + int err = 0; + + end_offset = min(offset + length, vi->tree_params.tree_size); + if (offset >= end_offset) + return 0; + offs_in_page = offset_in_page(offset); + last_index = (end_offset - 1) >> PAGE_SHIFT; + + /* + * Iterate through each Merkle tree page in the requested range and copy + * the requested portion to userspace. Note that the Merkle tree block + * size isn't important here, as we are returning a byte stream; i.e., + * we can just work with pages even if the tree block size != PAGE_SIZE. + */ + for (index = offset >> PAGE_SHIFT; index <= last_index; index++) { + unsigned long num_ra_pages = + min_t(unsigned long, last_index - index + 1, + inode->i_sb->s_bdi->io_pages); + unsigned int bytes_to_copy = min_t(u64, end_offset - offset, + PAGE_SIZE - offs_in_page); + struct page *page; + const void *virt; + + page = vops->read_merkle_tree_page(inode, index, num_ra_pages); + if (IS_ERR(page)) { + err = PTR_ERR(page); + fsverity_err(inode, + "Error %d reading Merkle tree page %lu", + err, index); + break; + } + + virt = kmap(page); + if (copy_to_user(buf, virt + offs_in_page, bytes_to_copy)) { + kunmap(page); + put_page(page); + err = -EFAULT; + break; + } + kunmap(page); + put_page(page); + + retval += bytes_to_copy; + buf += bytes_to_copy; + offset += bytes_to_copy; + + if (fatal_signal_pending(current)) { + err = -EINTR; + break; + } + cond_resched(); + offs_in_page = 0; + } + return retval ? retval : err; +} /** * fsverity_ioctl_read_metadata() - read verity metadata from a file * @filp: file to read the metadata from @@ -48,6 +115,9 @@ int fsverity_ioctl_read_metadata(struct file *filp, const void __user *uarg) buf = u64_to_user_ptr(arg.buf_ptr); switch (arg.metadata_type) { + case FS_VERITY_METADATA_TYPE_MERKLE_TREE: + return fsverity_read_merkle_tree(inode, vi, buf, arg.offset, + length); default: return -EINVAL; } diff --git a/include/uapi/linux/fsverity.h b/include/uapi/linux/fsverity.h index e062751294d0..94003b153cb3 100644 --- a/include/uapi/linux/fsverity.h +++ b/include/uapi/linux/fsverity.h @@ -83,6 +83,8 @@ struct fsverity_formatted_digest { __u8 digest[]; }; +#define FS_VERITY_METADATA_TYPE_MERKLE_TREE 1 + struct fsverity_read_metadata_arg { __u64 metadata_type; __u64 offset; -- cgit v1.2.3 From 947191ac8caba85e25e0e036b0f097fee9e817f3 Mon Sep 17 00:00:00 2001 From: Eric Biggers Date: Fri, 15 Jan 2021 10:18:18 -0800 Subject: fs-verity: support reading descriptor with ioctl Add support for FS_VERITY_METADATA_TYPE_DESCRIPTOR to FS_IOC_READ_VERITY_METADATA. This allows a userspace server program to retrieve the fs-verity descriptor of a file for serving to a client which implements fs-verity compatible verification. See the patch which introduced FS_IOC_READ_VERITY_METADATA for more details. "fs-verity descriptor" here means only the part that userspace cares about because it is hashed to produce the file digest. It doesn't include the signature which ext4 and f2fs append to the fsverity_descriptor struct when storing it on-disk, since that way of storing the signature is an implementation detail. The next patch adds a separate metadata_type value for retrieving the signature separately. This has been tested using a new xfstest which calls this ioctl via a new subcommand for the 'fsverity' program from fsverity-utils. Link: https://lore.kernel.org/r/20210115181819.34732-6-ebiggers@kernel.org Reviewed-by: Victor Hsieh Reviewed-by: Jaegeuk Kim Reviewed-by: Chao Yu Signed-off-by: Eric Biggers --- Documentation/filesystems/fsverity.rst | 4 ++++ fs/verity/read_metadata.c | 40 ++++++++++++++++++++++++++++++++++ include/uapi/linux/fsverity.h | 1 + 3 files changed, 45 insertions(+) (limited to 'Documentation') diff --git a/Documentation/filesystems/fsverity.rst b/Documentation/filesystems/fsverity.rst index 50b47a6d9ea1..6dc5772037ef 100644 --- a/Documentation/filesystems/fsverity.rst +++ b/Documentation/filesystems/fsverity.rst @@ -235,6 +235,7 @@ need this ioctl. This ioctl takes in a pointer to the following structure:: #define FS_VERITY_METADATA_TYPE_MERKLE_TREE 1 + #define FS_VERITY_METADATA_TYPE_DESCRIPTOR 2 struct fsverity_read_metadata_arg { __u64 metadata_type; @@ -252,6 +253,9 @@ This ioctl takes in a pointer to the following structure:: the same order that their hashes are themselves hashed. See `Merkle tree`_ for more information. +- ``FS_VERITY_METADATA_TYPE_DESCRIPTOR`` reads the fs-verity + descriptor. See `fs-verity descriptor`_. + The semantics are similar to those of ``pread()``. ``offset`` specifies the offset in bytes into the metadata item to read from, and ``length`` specifies the maximum number of bytes to read from the diff --git a/fs/verity/read_metadata.c b/fs/verity/read_metadata.c index 0f8ad2991cf9..2dea6dd3bb05 100644 --- a/fs/verity/read_metadata.c +++ b/fs/verity/read_metadata.c @@ -76,6 +76,44 @@ static int fsverity_read_merkle_tree(struct inode *inode, } return retval ? retval : err; } + +/* Copy the requested portion of the buffer to userspace. */ +static int fsverity_read_buffer(void __user *dst, u64 offset, int length, + const void *src, size_t src_length) +{ + if (offset >= src_length) + return 0; + src += offset; + src_length -= offset; + + length = min_t(size_t, length, src_length); + + if (copy_to_user(dst, src, length)) + return -EFAULT; + + return length; +} + +static int fsverity_read_descriptor(struct inode *inode, + void __user *buf, u64 offset, int length) +{ + struct fsverity_descriptor *desc; + size_t desc_size; + int res; + + res = fsverity_get_descriptor(inode, &desc, &desc_size); + if (res) + return res; + + /* don't include the signature */ + desc_size = offsetof(struct fsverity_descriptor, signature); + desc->sig_size = 0; + + res = fsverity_read_buffer(buf, offset, length, desc, desc_size); + + kfree(desc); + return res; +} /** * fsverity_ioctl_read_metadata() - read verity metadata from a file * @filp: file to read the metadata from @@ -118,6 +156,8 @@ int fsverity_ioctl_read_metadata(struct file *filp, const void __user *uarg) case FS_VERITY_METADATA_TYPE_MERKLE_TREE: return fsverity_read_merkle_tree(inode, vi, buf, arg.offset, length); + case FS_VERITY_METADATA_TYPE_DESCRIPTOR: + return fsverity_read_descriptor(inode, buf, arg.offset, length); default: return -EINVAL; } diff --git a/include/uapi/linux/fsverity.h b/include/uapi/linux/fsverity.h index 94003b153cb3..41abc283dbcc 100644 --- a/include/uapi/linux/fsverity.h +++ b/include/uapi/linux/fsverity.h @@ -84,6 +84,7 @@ struct fsverity_formatted_digest { }; #define FS_VERITY_METADATA_TYPE_MERKLE_TREE 1 +#define FS_VERITY_METADATA_TYPE_DESCRIPTOR 2 struct fsverity_read_metadata_arg { __u64 metadata_type; -- cgit v1.2.3 From 07c99001312cbf90a357d4877a358f796eede65b Mon Sep 17 00:00:00 2001 From: Eric Biggers Date: Fri, 15 Jan 2021 10:18:19 -0800 Subject: fs-verity: support reading signature with ioctl Add support for FS_VERITY_METADATA_TYPE_SIGNATURE to FS_IOC_READ_VERITY_METADATA. This allows a userspace server program to retrieve the built-in signature (if present) of a verity file for serving to a client which implements fs-verity compatible verification. See the patch which introduced FS_IOC_READ_VERITY_METADATA for more details. The ability for userspace to read the built-in signatures is also useful because it allows a system that is using the in-kernel signature verification to migrate to userspace signature verification. This has been tested using a new xfstest which calls this ioctl via a new subcommand for the 'fsverity' program from fsverity-utils. Link: https://lore.kernel.org/r/20210115181819.34732-7-ebiggers@kernel.org Reviewed-by: Victor Hsieh Reviewed-by: Jaegeuk Kim Reviewed-by: Chao Yu Signed-off-by: Eric Biggers --- Documentation/filesystems/fsverity.rst | 9 ++++++++- fs/verity/read_metadata.c | 30 ++++++++++++++++++++++++++++++ include/uapi/linux/fsverity.h | 1 + 3 files changed, 39 insertions(+), 1 deletion(-) (limited to 'Documentation') diff --git a/Documentation/filesystems/fsverity.rst b/Documentation/filesystems/fsverity.rst index 6dc5772037ef..1d831e3cbcb3 100644 --- a/Documentation/filesystems/fsverity.rst +++ b/Documentation/filesystems/fsverity.rst @@ -236,6 +236,7 @@ This ioctl takes in a pointer to the following structure:: #define FS_VERITY_METADATA_TYPE_MERKLE_TREE 1 #define FS_VERITY_METADATA_TYPE_DESCRIPTOR 2 + #define FS_VERITY_METADATA_TYPE_SIGNATURE 3 struct fsverity_read_metadata_arg { __u64 metadata_type; @@ -256,6 +257,10 @@ This ioctl takes in a pointer to the following structure:: - ``FS_VERITY_METADATA_TYPE_DESCRIPTOR`` reads the fs-verity descriptor. See `fs-verity descriptor`_. +- ``FS_VERITY_METADATA_TYPE_SIGNATURE`` reads the signature which was + passed to FS_IOC_ENABLE_VERITY, if any. See `Built-in signature + verification`_. + The semantics are similar to those of ``pread()``. ``offset`` specifies the offset in bytes into the metadata item to read from, and ``length`` specifies the maximum number of bytes to read from the @@ -279,7 +284,9 @@ FS_IOC_READ_VERITY_METADATA can fail with the following errors: - ``EINTR``: the ioctl was interrupted before any data was read - ``EINVAL``: reserved fields were set, or ``offset + length`` overflowed -- ``ENODATA``: the file is not a verity file +- ``ENODATA``: the file is not a verity file, or + FS_VERITY_METADATA_TYPE_SIGNATURE was requested but the file doesn't + have a built-in signature - ``ENOTTY``: this type of filesystem does not implement fs-verity, or this ioctl is not yet implemented on it - ``EOPNOTSUPP``: the kernel was not configured with fs-verity diff --git a/fs/verity/read_metadata.c b/fs/verity/read_metadata.c index 2dea6dd3bb05..7e2d0c7bdf0d 100644 --- a/fs/verity/read_metadata.c +++ b/fs/verity/read_metadata.c @@ -114,6 +114,34 @@ static int fsverity_read_descriptor(struct inode *inode, kfree(desc); return res; } + +static int fsverity_read_signature(struct inode *inode, + void __user *buf, u64 offset, int length) +{ + struct fsverity_descriptor *desc; + size_t desc_size; + int res; + + res = fsverity_get_descriptor(inode, &desc, &desc_size); + if (res) + return res; + + if (desc->sig_size == 0) { + res = -ENODATA; + goto out; + } + + /* + * Include only the signature. Note that fsverity_get_descriptor() + * already verified that sig_size is in-bounds. + */ + res = fsverity_read_buffer(buf, offset, length, desc->signature, + le32_to_cpu(desc->sig_size)); +out: + kfree(desc); + return res; +} + /** * fsverity_ioctl_read_metadata() - read verity metadata from a file * @filp: file to read the metadata from @@ -158,6 +186,8 @@ int fsverity_ioctl_read_metadata(struct file *filp, const void __user *uarg) length); case FS_VERITY_METADATA_TYPE_DESCRIPTOR: return fsverity_read_descriptor(inode, buf, arg.offset, length); + case FS_VERITY_METADATA_TYPE_SIGNATURE: + return fsverity_read_signature(inode, buf, arg.offset, length); default: return -EINVAL; } diff --git a/include/uapi/linux/fsverity.h b/include/uapi/linux/fsverity.h index 41abc283dbcc..15384e22e331 100644 --- a/include/uapi/linux/fsverity.h +++ b/include/uapi/linux/fsverity.h @@ -85,6 +85,7 @@ struct fsverity_formatted_digest { #define FS_VERITY_METADATA_TYPE_MERKLE_TREE 1 #define FS_VERITY_METADATA_TYPE_DESCRIPTOR 2 +#define FS_VERITY_METADATA_TYPE_SIGNATURE 3 struct fsverity_read_metadata_arg { __u64 metadata_type; -- cgit v1.2.3 From d5e16dc5fdad09d7b3133b6aaea7848bfb518e04 Mon Sep 17 00:00:00 2001 From: Sia Jee Heng Date: Thu, 4 Feb 2021 09:42:57 +0800 Subject: ASoC: Intel, Keembay-i2s: Add hdmi-i2s compatible string Add intel,keembay-hdmi-i2s compatible string to support the HDMI interface. Signed-off-by: Sia Jee Heng Link: https://lore.kernel.org/r/20210204014258.10197-4-jee.heng.sia@intel.com Signed-off-by: Mark Brown --- Documentation/devicetree/bindings/sound/intel,keembay-i2s.yaml | 1 + 1 file changed, 1 insertion(+) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/sound/intel,keembay-i2s.yaml b/Documentation/devicetree/bindings/sound/intel,keembay-i2s.yaml index dba25c33f0b0..6f71294909a5 100644 --- a/Documentation/devicetree/bindings/sound/intel,keembay-i2s.yaml +++ b/Documentation/devicetree/bindings/sound/intel,keembay-i2s.yaml @@ -18,6 +18,7 @@ properties: enum: - intel,keembay-i2s - intel,keembay-tdm + - intel,keembay-hdmi-i2s "#sound-dai-cells": const: 0 -- cgit v1.2.3 From 977fb5b58469c1367aa075e7e913c03cba7d466f Mon Sep 17 00:00:00 2001 From: Hsin-Hsiung Wang Date: Sun, 7 Feb 2021 14:14:15 +0800 Subject: regulator: document binding for MT6315 regulator Add device tree binding information for MT6315 regulator driver. Example bindings for MT6315 are added. Signed-off-by: Hsin-Hsiung Wang Link: https://lore.kernel.org/r/1612678457-11548-2-git-send-email-hsin-hsiung.wang@mediatek.com Signed-off-by: Mark Brown --- .../bindings/regulator/mt6315-regulator.yaml | 69 ++++++++++++++++++++++ 1 file changed, 69 insertions(+) create mode 100644 Documentation/devicetree/bindings/regulator/mt6315-regulator.yaml (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/regulator/mt6315-regulator.yaml b/Documentation/devicetree/bindings/regulator/mt6315-regulator.yaml new file mode 100644 index 000000000000..61dd5af80db6 --- /dev/null +++ b/Documentation/devicetree/bindings/regulator/mt6315-regulator.yaml @@ -0,0 +1,69 @@ +# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/regulator/mt6315-regulator.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Mediatek MT6315 Regulator + +maintainers: + - Hsin-Hsiung Wang + +description: | + The MT6315 is a power management IC (PMIC) configurable with SPMI. + that contains 4 BUCKs output which can combine with each other + by different efuse settings. + +properties: + compatible: + const: mediatek,mt6315-regulator + + reg: + maxItems: 1 + + regulators: + type: object + description: List of regulators and its properties + + patternProperties: + "^vbuck[1-4]$": + type: object + $ref: "regulator.yaml#" + + properties: + regulator-name: + pattern: "^vbuck[1-4]$" + + additionalProperties: false + +required: + - compatible + - reg + - regulators + +additionalProperties: false + +examples: + - | + pmic@6 { + compatible = "mediatek,mt6315-regulator"; + reg = <0x6 0>; + + regulators { + vbuck1 { + regulator-compatible = "vbuck1"; + regulator-min-microvolt = <300000>; + regulator-max-microvolt = <1193750>; + regulator-enable-ramp-delay = <256>; + regulator-allowed-modes = <0 1 2 4>; + }; + + vbuck3 { + regulator-compatible = "vbuck3"; + regulator-min-microvolt = <300000>; + regulator-max-microvolt = <1193750>; + regulator-enable-ramp-delay = <256>; + regulator-allowed-modes = <0 1 2 4>; + }; + }; + }; -- cgit v1.2.3 From 951e92d141ea4ac5b68d9e6eac895e5988852d3c Mon Sep 17 00:00:00 2001 From: Zhen Lei Date: Fri, 4 Dec 2020 17:38:13 +0800 Subject: dt-bindings: mfd: Correct the node name of the panel LED According to the definition in leds-pwm.yaml, the node name of each LED must match the regular expression "^led(-[0-9a-f]+)?$". "led" or "led-" followed by a decimal or hexadecimal ID number. Signed-off-by: Zhen Lei Reviewed-by: Rob Herring Signed-off-by: Lee Jones --- Documentation/devicetree/bindings/mfd/iqs62x.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/mfd/iqs62x.yaml b/Documentation/devicetree/bindings/mfd/iqs62x.yaml index 541b06d80e73..044cd7542c2b 100644 --- a/Documentation/devicetree/bindings/mfd/iqs62x.yaml +++ b/Documentation/devicetree/bindings/mfd/iqs62x.yaml @@ -93,7 +93,7 @@ examples: pwmleds { compatible = "pwm-leds"; - panel { + led-1 { pwms = <&iqs620a_pwm 0 1000000>; max-brightness = <255>; }; -- cgit v1.2.3 From c239fea18e5763e88f3b7184a1c16b30fba57aac Mon Sep 17 00:00:00 2001 From: Tim Harvey Date: Mon, 28 Dec 2020 11:28:36 -0800 Subject: dt-bindings: mfd: gateworks-gsc: Add fan-tach mode In 7497d4a66c59 ("hwmon: (gsc-hwmon) add fan sensor") a mode was added to report RPM's from a fan tach input. Add this mode to the dt-bindings for the Gateworks System Controller. Signed-off-by: Tim Harvey Acked-by: Rob Herring Signed-off-by: Lee Jones --- Documentation/devicetree/bindings/mfd/gateworks-gsc.yaml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/mfd/gateworks-gsc.yaml b/Documentation/devicetree/bindings/mfd/gateworks-gsc.yaml index d08e8fe76446..5a1e8d21f7a0 100644 --- a/Documentation/devicetree/bindings/mfd/gateworks-gsc.yaml +++ b/Documentation/devicetree/bindings/mfd/gateworks-gsc.yaml @@ -83,8 +83,9 @@ properties: 2 - scaled voltage based on an optional resistor divider and optional offset 3 - pre-scaled 16-bit voltage value + 4 - fan tach input to report RPM's $ref: /schemas/types.yaml#/definitions/uint32 - enum: [0, 1, 2, 3] + enum: [0, 1, 2, 3, 4] gw,voltage-divider-ohms: description: Values of resistors for divider on raw ADC input -- cgit v1.2.3 From 0eee3048202acb7f109face069c840146dfa2245 Mon Sep 17 00:00:00 2001 From: Dmitry Osipenko Date: Mon, 28 Dec 2020 19:05:45 +0300 Subject: dt-bindings: mfd: Add ENE KB930 Embedded Controller binding Add binding document for the ENE KB930 Embedded Controller. Reviewed-by: Rob Herring Signed-off-by: Dmitry Osipenko Signed-off-by: Lee Jones --- .../devicetree/bindings/mfd/ene-kb930.yaml | 65 ++++++++++++++++++++++ 1 file changed, 65 insertions(+) create mode 100644 Documentation/devicetree/bindings/mfd/ene-kb930.yaml (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/mfd/ene-kb930.yaml b/Documentation/devicetree/bindings/mfd/ene-kb930.yaml new file mode 100644 index 000000000000..06ed9ec8f4bb --- /dev/null +++ b/Documentation/devicetree/bindings/mfd/ene-kb930.yaml @@ -0,0 +1,65 @@ +# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/mfd/ene-kb930.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: ENE KB930 Embedded Controller bindings + +description: | + This binding describes the ENE KB930 Embedded Controller attached to an + I2C bus. + +maintainers: + - Dmitry Osipenko + +properties: + compatible: + items: + - enum: + - acer,a500-iconia-ec # Acer A500 Iconia tablet device + - const: ene,kb930 + reg: + maxItems: 1 + + monitored-battery: true + power-supplies: true + system-power-controller: true + +required: + - compatible + - reg + +additionalProperties: false + +examples: + - | + battery: battery-cell { + compatible = "simple-battery"; + charge-full-design-microamp-hours = <3260000>; + energy-full-design-microwatt-hours = <24000000>; + operating-range-celsius = <0 40>; + }; + + mains: ac-adapter { + compatible = "gpio-charger"; + charger-type = "mains"; + gpios = <&gpio 125 0>; + }; + + i2c { + #address-cells = <1>; + #size-cells = <0>; + + embedded-controller@58 { + compatible = "acer,a500-iconia-ec", "ene,kb930"; + reg = <0x58>; + + system-power-controller; + + monitored-battery = <&battery>; + power-supplies = <&mains>; + }; + }; + +... -- cgit v1.2.3 From 296f5568c6ee906e2a8db00adc751674f1745bd8 Mon Sep 17 00:00:00 2001 From: Russ Weight Date: Thu, 14 Jan 2021 15:16:48 -0800 Subject: mfd: intel-m10-bmc: Expose MAC address and count Create two sysfs entries for exposing the MAC address and count from the MAX10 BMC register space. The MAC address is the first in a sequential block of MAC addresses reserved for the FPGA card. The MAC count is the number of MAC addresses in the reserved block. Signed-off-by: Russ Weight Signed-off-by: Xu Yilun Signed-off-by: Lee Jones --- .../ABI/testing/sysfs-driver-intel-m10-bmc | 21 +++++++++++ drivers/mfd/intel-m10-bmc.c | 43 ++++++++++++++++++++++ include/linux/mfd/intel-m10-bmc.h | 9 +++++ 3 files changed, 73 insertions(+) (limited to 'Documentation') diff --git a/Documentation/ABI/testing/sysfs-driver-intel-m10-bmc b/Documentation/ABI/testing/sysfs-driver-intel-m10-bmc index 979a2d62513f..9773925138af 100644 --- a/Documentation/ABI/testing/sysfs-driver-intel-m10-bmc +++ b/Documentation/ABI/testing/sysfs-driver-intel-m10-bmc @@ -13,3 +13,24 @@ Contact: Xu Yilun Description: Read only. Returns the firmware version of Intel MAX10 BMC chip. Format: "0x%x". + +What: /sys/bus/spi/devices/.../mac_address +Date: January 2021 +KernelVersion: 5.12 +Contact: Russ Weight +Description: Read only. Returns the first MAC address in a block + of sequential MAC addresses assigned to the board + that is managed by the Intel MAX10 BMC. It is stored in + FLASH storage and is mirrored in the MAX10 BMC register + space. + Format: "%02x:%02x:%02x:%02x:%02x:%02x". + +What: /sys/bus/spi/devices/.../mac_count +Date: January 2021 +KernelVersion: 5.12 +Contact: Russ Weight +Description: Read only. Returns the number of sequential MAC + addresses assigned to the board managed by the Intel + MAX10 BMC. This value is stored in FLASH and is mirrored + in the MAX10 BMC register space. + Format: "%u". diff --git a/drivers/mfd/intel-m10-bmc.c b/drivers/mfd/intel-m10-bmc.c index b84579b7b4f0..06c977519479 100644 --- a/drivers/mfd/intel-m10-bmc.c +++ b/drivers/mfd/intel-m10-bmc.c @@ -60,9 +60,52 @@ static ssize_t bmcfw_version_show(struct device *dev, } static DEVICE_ATTR_RO(bmcfw_version); +static ssize_t mac_address_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct intel_m10bmc *max10 = dev_get_drvdata(dev); + unsigned int macaddr_low, macaddr_high; + int ret; + + ret = m10bmc_sys_read(max10, M10BMC_MAC_LOW, &macaddr_low); + if (ret) + return ret; + + ret = m10bmc_sys_read(max10, M10BMC_MAC_HIGH, &macaddr_high); + if (ret) + return ret; + + return sysfs_emit(buf, "%02x:%02x:%02x:%02x:%02x:%02x\n", + (u8)FIELD_GET(M10BMC_MAC_BYTE1, macaddr_low), + (u8)FIELD_GET(M10BMC_MAC_BYTE2, macaddr_low), + (u8)FIELD_GET(M10BMC_MAC_BYTE3, macaddr_low), + (u8)FIELD_GET(M10BMC_MAC_BYTE4, macaddr_low), + (u8)FIELD_GET(M10BMC_MAC_BYTE5, macaddr_high), + (u8)FIELD_GET(M10BMC_MAC_BYTE6, macaddr_high)); +} +static DEVICE_ATTR_RO(mac_address); + +static ssize_t mac_count_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct intel_m10bmc *max10 = dev_get_drvdata(dev); + unsigned int macaddr_high; + int ret; + + ret = m10bmc_sys_read(max10, M10BMC_MAC_HIGH, &macaddr_high); + if (ret) + return ret; + + return sysfs_emit(buf, "%u\n", + (u8)FIELD_GET(M10BMC_MAC_COUNT, macaddr_high)); +} +static DEVICE_ATTR_RO(mac_count); + static struct attribute *m10bmc_attrs[] = { &dev_attr_bmc_version.attr, &dev_attr_bmcfw_version.attr, + &dev_attr_mac_address.attr, + &dev_attr_mac_count.attr, NULL, }; ATTRIBUTE_GROUPS(m10bmc); diff --git a/include/linux/mfd/intel-m10-bmc.h b/include/linux/mfd/intel-m10-bmc.h index c8ef2f1654a4..74d4e193966a 100644 --- a/include/linux/mfd/intel-m10-bmc.h +++ b/include/linux/mfd/intel-m10-bmc.h @@ -15,6 +15,15 @@ /* Register offset of system registers */ #define NIOS2_FW_VERSION 0x0 +#define M10BMC_MAC_LOW 0x10 +#define M10BMC_MAC_BYTE4 GENMASK(7, 0) +#define M10BMC_MAC_BYTE3 GENMASK(15, 8) +#define M10BMC_MAC_BYTE2 GENMASK(23, 16) +#define M10BMC_MAC_BYTE1 GENMASK(31, 24) +#define M10BMC_MAC_HIGH 0x14 +#define M10BMC_MAC_BYTE6 GENMASK(7, 0) +#define M10BMC_MAC_BYTE5 GENMASK(15, 8) +#define M10BMC_MAC_COUNT GENMASK(23, 16) #define M10BMC_TEST_REG 0x3c #define M10BMC_BUILD_VER 0x68 #define M10BMC_VER_MAJOR_MSK GENMASK(23, 16) -- cgit v1.2.3 From 45a90d4aba1781aa382d4aeedebcac7cc78e1927 Mon Sep 17 00:00:00 2001 From: Paul Cercueil Date: Sat, 23 Jan 2021 14:09:56 +0000 Subject: ASoC: Add compatible strings for JZ4760(B) SoC Add the ingenic,jz4760b-codec and ingenic,jz4760-codec compatible strings. In the process, convert the previous compatible strings to use an enum instead. Signed-off-by: Paul Cercueil Link: https://lore.kernel.org/r/20210123140958.12895-1-paul@crapouillou.net Signed-off-by: Mark Brown --- Documentation/devicetree/bindings/sound/ingenic,codec.yaml | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/sound/ingenic,codec.yaml b/Documentation/devicetree/bindings/sound/ingenic,codec.yaml index eb4be86464bb..97d5f3819b27 100644 --- a/Documentation/devicetree/bindings/sound/ingenic,codec.yaml +++ b/Documentation/devicetree/bindings/sound/ingenic,codec.yaml @@ -15,9 +15,14 @@ properties: compatible: oneOf: - - const: ingenic,jz4770-codec - - const: ingenic,jz4725b-codec - - const: ingenic,jz4740-codec + - enum: + - ingenic,jz4770-codec + - ingenic,jz4760-codec + - ingenic,jz4725b-codec + - ingenic,jz4740-codec + - items: + - const: ingenic,jz4760b-codec + - const: ingenic,jz4760-codec reg: maxItems: 1 -- cgit v1.2.3 From 56f45a21fc445d98219eb8863ce4e80cb97b50bc Mon Sep 17 00:00:00 2001 From: Christian Hewitt Date: Tue, 2 Feb 2021 02:10:20 +0000 Subject: dt-bindings: arm: amlogic: add ODROID-HC4 bindings Add the board bindings for the ODROID-HC4 device. Signed-off-by: Christian Hewitt Signed-off-by: Kevin Hilman Link: https://lore.kernel.org/r/20210202021021.11068-5-christianshewitt@gmail.com --- Documentation/devicetree/bindings/arm/amlogic.yaml | 1 + 1 file changed, 1 insertion(+) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/arm/amlogic.yaml b/Documentation/devicetree/bindings/arm/amlogic.yaml index b21ba8ba23dd..5f6769bf45bd 100644 --- a/Documentation/devicetree/bindings/arm/amlogic.yaml +++ b/Documentation/devicetree/bindings/arm/amlogic.yaml @@ -165,6 +165,7 @@ properties: items: - enum: - hardkernel,odroid-c4 + - hardkernel,odroid-hc4 - khadas,vim3l - seirobotics,sei610 - const: amlogic,sm1 -- cgit v1.2.3 From ee778e069dd49cf476f3939d62f31346cf730080 Mon Sep 17 00:00:00 2001 From: Manivannan Sadhasivam Date: Mon, 18 Jan 2021 09:41:54 +0530 Subject: dt-bindings: clock: Add Qualcomm A7 PLL binding Add devicetree YAML binding for Cortex A7 PLL clock in Qualcomm platforms like SDX55. Signed-off-by: Manivannan Sadhasivam Link: https://lore.kernel.org/r/20210118041156.50016-4-manivannan.sadhasivam@linaro.org Reviewed-by: Rob Herring Signed-off-by: Stephen Boyd --- .../devicetree/bindings/clock/qcom,a7pll.yaml | 51 ++++++++++++++++++++++ 1 file changed, 51 insertions(+) create mode 100644 Documentation/devicetree/bindings/clock/qcom,a7pll.yaml (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/clock/qcom,a7pll.yaml b/Documentation/devicetree/bindings/clock/qcom,a7pll.yaml new file mode 100644 index 000000000000..8666e995725f --- /dev/null +++ b/Documentation/devicetree/bindings/clock/qcom,a7pll.yaml @@ -0,0 +1,51 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/clock/qcom,a7pll.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Qualcomm A7 PLL Binding + +maintainers: + - Manivannan Sadhasivam + +description: + The A7 PLL on the Qualcomm platforms like SDX55 is used to provide high + frequency clock to the CPU. + +properties: + compatible: + enum: + - qcom,sdx55-a7pll + + reg: + maxItems: 1 + + '#clock-cells': + const: 0 + + clocks: + items: + - description: board XO clock + + clock-names: + items: + - const: bi_tcxo + +required: + - compatible + - reg + - '#clock-cells' + +additionalProperties: false + +examples: + - | + #include + a7pll: clock@17808000 { + compatible = "qcom,sdx55-a7pll"; + reg = <0x17808000 0x1000>; + clocks = <&rpmhcc RPMH_CXO_CLK>; + clock-names = "bi_tcxo"; + #clock-cells = <0>; + }; -- cgit v1.2.3 From e6c3cc63fa1a5e361b7542cca01feae2ccfe1635 Mon Sep 17 00:00:00 2001 From: Bjorn Andersson Date: Wed, 20 Jan 2021 14:37:40 -0800 Subject: dt-bindings: clock: qcom: rpmhcc: Add sc8180x rpmh clocks Add Qualcomm SC8180x to the list of compatibles for the RPMHCC binding. Signed-off-by: Bjorn Andersson Link: https://lore.kernel.org/r/20210120223741.1610344-1-bjorn.andersson@linaro.org Signed-off-by: Stephen Boyd --- Documentation/devicetree/bindings/clock/qcom,rpmhcc.yaml | 1 + 1 file changed, 1 insertion(+) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/clock/qcom,rpmhcc.yaml b/Documentation/devicetree/bindings/clock/qcom,rpmhcc.yaml index 12c9cbc0ebf9..167b018effcc 100644 --- a/Documentation/devicetree/bindings/clock/qcom,rpmhcc.yaml +++ b/Documentation/devicetree/bindings/clock/qcom,rpmhcc.yaml @@ -18,6 +18,7 @@ properties: compatible: enum: - qcom,sc7180-rpmh-clk + - qcom,sc8180x-rpmh-clk - qcom,sdm845-rpmh-clk - qcom,sdx55-rpmh-clk - qcom,sm8150-rpmh-clk -- cgit v1.2.3 From 0fadcdfdcf570c3b1db90375f4b87fbd339bde2c Mon Sep 17 00:00:00 2001 From: Bjorn Andersson Date: Mon, 25 Jan 2021 20:31:54 -0800 Subject: dt-bindings: clock: Add SC8180x GCC binding Add devicetree binding for the global clock controller found in the Qualcomm SC8180x platform. Signed-off-by: Bjorn Andersson Link: https://lore.kernel.org/r/20210126043155.1847823-1-bjorn.andersson@linaro.org Signed-off-by: Stephen Boyd --- .../bindings/clock/qcom,gcc-sc8180x.yaml | 76 +++++ include/dt-bindings/clock/qcom,gcc-sc8180x.h | 309 +++++++++++++++++++++ 2 files changed, 385 insertions(+) create mode 100644 Documentation/devicetree/bindings/clock/qcom,gcc-sc8180x.yaml create mode 100644 include/dt-bindings/clock/qcom,gcc-sc8180x.h (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/clock/qcom,gcc-sc8180x.yaml b/Documentation/devicetree/bindings/clock/qcom,gcc-sc8180x.yaml new file mode 100644 index 000000000000..f03ef96e57fa --- /dev/null +++ b/Documentation/devicetree/bindings/clock/qcom,gcc-sc8180x.yaml @@ -0,0 +1,76 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/clock/qcom,gcc-sc8180x.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Qualcomm Global Clock & Reset Controller Binding for SC8180x + +maintainers: + - Bjorn Andersson + +description: | + Qualcomm global clock control module which supports the clocks, resets and + power domains on SC8180x. + + See also: + - dt-bindings/clock/qcom,gcc-sc8180x.h + +properties: + compatible: + const: qcom,gcc-sc8180x + + clocks: + items: + - description: Board XO source + - description: Board active XO source + - description: Sleep clock source + + clock-names: + items: + - const: bi_tcxo + - const: bi_tcxo_ao + - const: sleep_clk + + '#clock-cells': + const: 1 + + '#reset-cells': + const: 1 + + '#power-domain-cells': + const: 1 + + reg: + maxItems: 1 + + protected-clocks: + description: + Protected clock specifier list as per common clock binding. + +required: + - compatible + - clocks + - clock-names + - reg + - '#clock-cells' + - '#reset-cells' + - '#power-domain-cells' + +additionalProperties: false + +examples: + - | + #include + clock-controller@100000 { + compatible = "qcom,gcc-sc8180x"; + reg = <0x00100000 0x1f0000>; + clocks = <&rpmhcc RPMH_CXO_CLK>, + <&rpmhcc RPMH_CXO_CLK_A>, + <&sleep_clk>; + clock-names = "bi_tcxo", "bi_tcxo_ao", "sleep_clk"; + #clock-cells = <1>; + #reset-cells = <1>; + #power-domain-cells = <1>; + }; +... diff --git a/include/dt-bindings/clock/qcom,gcc-sc8180x.h b/include/dt-bindings/clock/qcom,gcc-sc8180x.h new file mode 100644 index 000000000000..e893415ae13d --- /dev/null +++ b/include/dt-bindings/clock/qcom,gcc-sc8180x.h @@ -0,0 +1,309 @@ +/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */ +/* + * Copyright (c) 2018-2019, The Linux Foundation. All rights reserved. + * Copyright (c) 2021, Linaro Ltd. + */ + +#ifndef _DT_BINDINGS_CLK_QCOM_GCC_SC8180X_H +#define _DT_BINDINGS_CLK_QCOM_GCC_SC8180X_H + +#define GCC_AGGRE_NOC_PCIE_TBU_CLK 0 +#define GCC_AGGRE_UFS_CARD_AXI_CLK 1 +#define GCC_AGGRE_UFS_CARD_AXI_HW_CTL_CLK 2 +#define GCC_AGGRE_UFS_PHY_AXI_CLK 3 +#define GCC_AGGRE_UFS_PHY_AXI_HW_CTL_CLK 4 +#define GCC_AGGRE_USB3_MP_AXI_CLK 5 +#define GCC_AGGRE_USB3_PRIM_AXI_CLK 6 +#define GCC_AGGRE_USB3_SEC_AXI_CLK 7 +#define GCC_BOOT_ROM_AHB_CLK 8 +#define GCC_CAMERA_HF_AXI_CLK 9 +#define GCC_CAMERA_SF_AXI_CLK 10 +#define GCC_CFG_NOC_USB3_MP_AXI_CLK 11 +#define GCC_CFG_NOC_USB3_PRIM_AXI_CLK 12 +#define GCC_CFG_NOC_USB3_SEC_AXI_CLK 13 +#define GCC_CPUSS_AHB_CLK 14 +#define GCC_CPUSS_AHB_CLK_SRC 15 +#define GCC_CPUSS_RBCPR_CLK 16 +#define GCC_DDRSS_GPU_AXI_CLK 17 +#define GCC_DISP_HF_AXI_CLK 18 +#define GCC_DISP_SF_AXI_CLK 19 +#define GCC_EMAC_AXI_CLK 20 +#define GCC_EMAC_PTP_CLK 21 +#define GCC_EMAC_PTP_CLK_SRC 22 +#define GCC_EMAC_RGMII_CLK 23 +#define GCC_EMAC_RGMII_CLK_SRC 24 +#define GCC_EMAC_SLV_AHB_CLK 25 +#define GCC_GP1_CLK 26 +#define GCC_GP1_CLK_SRC 27 +#define GCC_GP2_CLK 28 +#define GCC_GP2_CLK_SRC 29 +#define GCC_GP3_CLK 30 +#define GCC_GP3_CLK_SRC 31 +#define GCC_GP4_CLK 32 +#define GCC_GP4_CLK_SRC 33 +#define GCC_GP5_CLK 34 +#define GCC_GP5_CLK_SRC 35 +#define GCC_GPU_GPLL0_CLK_SRC 36 +#define GCC_GPU_GPLL0_DIV_CLK_SRC 37 +#define GCC_GPU_MEMNOC_GFX_CLK 38 +#define GCC_GPU_SNOC_DVM_GFX_CLK 39 +#define GCC_NPU_AT_CLK 40 +#define GCC_NPU_AXI_CLK 41 +#define GCC_NPU_AXI_CLK_SRC 42 +#define GCC_NPU_GPLL0_CLK_SRC 43 +#define GCC_NPU_GPLL0_DIV_CLK_SRC 44 +#define GCC_NPU_TRIG_CLK 45 +#define GCC_PCIE0_PHY_REFGEN_CLK 46 +#define GCC_PCIE1_PHY_REFGEN_CLK 47 +#define GCC_PCIE2_PHY_REFGEN_CLK 48 +#define GCC_PCIE3_PHY_REFGEN_CLK 49 +#define GCC_PCIE_0_AUX_CLK 50 +#define GCC_PCIE_0_AUX_CLK_SRC 51 +#define GCC_PCIE_0_CFG_AHB_CLK 52 +#define GCC_PCIE_0_MSTR_AXI_CLK 53 +#define GCC_PCIE_0_PIPE_CLK 54 +#define GCC_PCIE_0_SLV_AXI_CLK 55 +#define GCC_PCIE_0_SLV_Q2A_AXI_CLK 56 +#define GCC_PCIE_1_AUX_CLK 57 +#define GCC_PCIE_1_AUX_CLK_SRC 58 +#define GCC_PCIE_1_CFG_AHB_CLK 59 +#define GCC_PCIE_1_MSTR_AXI_CLK 60 +#define GCC_PCIE_1_PIPE_CLK 61 +#define GCC_PCIE_1_SLV_AXI_CLK 62 +#define GCC_PCIE_1_SLV_Q2A_AXI_CLK 63 +#define GCC_PCIE_2_AUX_CLK 64 +#define GCC_PCIE_2_AUX_CLK_SRC 65 +#define GCC_PCIE_2_CFG_AHB_CLK 66 +#define GCC_PCIE_2_MSTR_AXI_CLK 67 +#define GCC_PCIE_2_PIPE_CLK 68 +#define GCC_PCIE_2_SLV_AXI_CLK 69 +#define GCC_PCIE_2_SLV_Q2A_AXI_CLK 70 +#define GCC_PCIE_3_AUX_CLK 71 +#define GCC_PCIE_3_AUX_CLK_SRC 72 +#define GCC_PCIE_3_CFG_AHB_CLK 73 +#define GCC_PCIE_3_MSTR_AXI_CLK 74 +#define GCC_PCIE_3_PIPE_CLK 75 +#define GCC_PCIE_3_SLV_AXI_CLK 76 +#define GCC_PCIE_3_SLV_Q2A_AXI_CLK 77 +#define GCC_PCIE_PHY_AUX_CLK 78 +#define GCC_PCIE_PHY_REFGEN_CLK_SRC 79 +#define GCC_PDM2_CLK 80 +#define GCC_PDM2_CLK_SRC 81 +#define GCC_PDM_AHB_CLK 82 +#define GCC_PDM_XO4_CLK 83 +#define GCC_PRNG_AHB_CLK 84 +#define GCC_QMIP_CAMERA_NRT_AHB_CLK 85 +#define GCC_QMIP_CAMERA_RT_AHB_CLK 86 +#define GCC_QMIP_DISP_AHB_CLK 87 +#define GCC_QMIP_VIDEO_CVP_AHB_CLK 88 +#define GCC_QMIP_VIDEO_VCODEC_AHB_CLK 89 +#define GCC_QSPI_1_CNOC_PERIPH_AHB_CLK 90 +#define GCC_QSPI_1_CORE_CLK 91 +#define GCC_QSPI_1_CORE_CLK_SRC 92 +#define GCC_QSPI_CNOC_PERIPH_AHB_CLK 93 +#define GCC_QSPI_CORE_CLK 94 +#define GCC_QSPI_CORE_CLK_SRC 95 +#define GCC_QUPV3_WRAP0_S0_CLK 96 +#define GCC_QUPV3_WRAP0_S0_CLK_SRC 97 +#define GCC_QUPV3_WRAP0_S1_CLK 98 +#define GCC_QUPV3_WRAP0_S1_CLK_SRC 99 +#define GCC_QUPV3_WRAP0_S2_CLK 100 +#define GCC_QUPV3_WRAP0_S2_CLK_SRC 101 +#define GCC_QUPV3_WRAP0_S3_CLK 102 +#define GCC_QUPV3_WRAP0_S3_CLK_SRC 103 +#define GCC_QUPV3_WRAP0_S4_CLK 104 +#define GCC_QUPV3_WRAP0_S4_CLK_SRC 105 +#define GCC_QUPV3_WRAP0_S5_CLK 106 +#define GCC_QUPV3_WRAP0_S5_CLK_SRC 107 +#define GCC_QUPV3_WRAP0_S6_CLK 108 +#define GCC_QUPV3_WRAP0_S6_CLK_SRC 109 +#define GCC_QUPV3_WRAP0_S7_CLK 110 +#define GCC_QUPV3_WRAP0_S7_CLK_SRC 111 +#define GCC_QUPV3_WRAP1_S0_CLK 112 +#define GCC_QUPV3_WRAP1_S0_CLK_SRC 113 +#define GCC_QUPV3_WRAP1_S1_CLK 114 +#define GCC_QUPV3_WRAP1_S1_CLK_SRC 115 +#define GCC_QUPV3_WRAP1_S2_CLK 116 +#define GCC_QUPV3_WRAP1_S2_CLK_SRC 117 +#define GCC_QUPV3_WRAP1_S3_CLK 118 +#define GCC_QUPV3_WRAP1_S3_CLK_SRC 119 +#define GCC_QUPV3_WRAP1_S4_CLK 120 +#define GCC_QUPV3_WRAP1_S4_CLK_SRC 121 +#define GCC_QUPV3_WRAP1_S5_CLK 122 +#define GCC_QUPV3_WRAP1_S5_CLK_SRC 123 +#define GCC_QUPV3_WRAP2_S0_CLK 124 +#define GCC_QUPV3_WRAP2_S0_CLK_SRC 125 +#define GCC_QUPV3_WRAP2_S1_CLK 126 +#define GCC_QUPV3_WRAP2_S1_CLK_SRC 127 +#define GCC_QUPV3_WRAP2_S2_CLK 128 +#define GCC_QUPV3_WRAP2_S2_CLK_SRC 129 +#define GCC_QUPV3_WRAP2_S3_CLK 130 +#define GCC_QUPV3_WRAP2_S3_CLK_SRC 131 +#define GCC_QUPV3_WRAP2_S4_CLK 132 +#define GCC_QUPV3_WRAP2_S4_CLK_SRC 133 +#define GCC_QUPV3_WRAP2_S5_CLK 134 +#define GCC_QUPV3_WRAP2_S5_CLK_SRC 135 +#define GCC_QUPV3_WRAP_0_M_AHB_CLK 136 +#define GCC_QUPV3_WRAP_0_S_AHB_CLK 137 +#define GCC_QUPV3_WRAP_1_M_AHB_CLK 138 +#define GCC_QUPV3_WRAP_1_S_AHB_CLK 139 +#define GCC_QUPV3_WRAP_2_M_AHB_CLK 140 +#define GCC_QUPV3_WRAP_2_S_AHB_CLK 141 +#define GCC_SDCC2_AHB_CLK 142 +#define GCC_SDCC2_APPS_CLK 143 +#define GCC_SDCC2_APPS_CLK_SRC 144 +#define GCC_SDCC4_AHB_CLK 145 +#define GCC_SDCC4_APPS_CLK 146 +#define GCC_SDCC4_APPS_CLK_SRC 147 +#define GCC_SYS_NOC_CPUSS_AHB_CLK 148 +#define GCC_TSIF_AHB_CLK 149 +#define GCC_TSIF_INACTIVITY_TIMERS_CLK 150 +#define GCC_TSIF_REF_CLK 151 +#define GCC_TSIF_REF_CLK_SRC 152 +#define GCC_UFS_CARD_2_AHB_CLK 153 +#define GCC_UFS_CARD_2_AXI_CLK 154 +#define GCC_UFS_CARD_2_AXI_CLK_SRC 155 +#define GCC_UFS_CARD_2_ICE_CORE_CLK 156 +#define GCC_UFS_CARD_2_ICE_CORE_CLK_SRC 157 +#define GCC_UFS_CARD_2_PHY_AUX_CLK 158 +#define GCC_UFS_CARD_2_PHY_AUX_CLK_SRC 159 +#define GCC_UFS_CARD_2_RX_SYMBOL_0_CLK 160 +#define GCC_UFS_CARD_2_RX_SYMBOL_1_CLK 161 +#define GCC_UFS_CARD_2_TX_SYMBOL_0_CLK 162 +#define GCC_UFS_CARD_2_UNIPRO_CORE_CLK 163 +#define GCC_UFS_CARD_2_UNIPRO_CORE_CLK_SRC 164 +#define GCC_UFS_CARD_AHB_CLK 165 +#define GCC_UFS_CARD_AXI_CLK 166 +#define GCC_UFS_CARD_AXI_CLK_SRC 167 +#define GCC_UFS_CARD_AXI_HW_CTL_CLK 168 +#define GCC_UFS_CARD_ICE_CORE_CLK 169 +#define GCC_UFS_CARD_ICE_CORE_CLK_SRC 170 +#define GCC_UFS_CARD_ICE_CORE_HW_CTL_CLK 171 +#define GCC_UFS_CARD_PHY_AUX_CLK 172 +#define GCC_UFS_CARD_PHY_AUX_CLK_SRC 173 +#define GCC_UFS_CARD_PHY_AUX_HW_CTL_CLK 174 +#define GCC_UFS_CARD_RX_SYMBOL_0_CLK 175 +#define GCC_UFS_CARD_RX_SYMBOL_1_CLK 176 +#define GCC_UFS_CARD_TX_SYMBOL_0_CLK 177 +#define GCC_UFS_CARD_UNIPRO_CORE_CLK 178 +#define GCC_UFS_CARD_UNIPRO_CORE_CLK_SRC 179 +#define GCC_UFS_CARD_UNIPRO_CORE_HW_CTL_CLK 180 +#define GCC_UFS_PHY_AHB_CLK 181 +#define GCC_UFS_PHY_AXI_CLK 182 +#define GCC_UFS_PHY_AXI_CLK_SRC 183 +#define GCC_UFS_PHY_AXI_HW_CTL_CLK 184 +#define GCC_UFS_PHY_ICE_CORE_CLK 185 +#define GCC_UFS_PHY_ICE_CORE_CLK_SRC 186 +#define GCC_UFS_PHY_ICE_CORE_HW_CTL_CLK 187 +#define GCC_UFS_PHY_PHY_AUX_CLK 188 +#define GCC_UFS_PHY_PHY_AUX_CLK_SRC 189 +#define GCC_UFS_PHY_PHY_AUX_HW_CTL_CLK 190 +#define GCC_UFS_PHY_RX_SYMBOL_0_CLK 191 +#define GCC_UFS_PHY_RX_SYMBOL_1_CLK 192 +#define GCC_UFS_PHY_TX_SYMBOL_0_CLK 193 +#define GCC_UFS_PHY_UNIPRO_CORE_CLK 194 +#define GCC_UFS_PHY_UNIPRO_CORE_CLK_SRC 195 +#define GCC_UFS_PHY_UNIPRO_CORE_HW_CTL_CLK 196 +#define GCC_USB30_MP_MASTER_CLK 197 +#define GCC_USB30_MP_MASTER_CLK_SRC 198 +#define GCC_USB30_MP_MOCK_UTMI_CLK 199 +#define GCC_USB30_MP_MOCK_UTMI_CLK_SRC 200 +#define GCC_USB30_MP_SLEEP_CLK 201 +#define GCC_USB30_PRIM_MASTER_CLK 202 +#define GCC_USB30_PRIM_MASTER_CLK_SRC 203 +#define GCC_USB30_PRIM_MOCK_UTMI_CLK 204 +#define GCC_USB30_PRIM_MOCK_UTMI_CLK_SRC 205 +#define GCC_USB30_PRIM_SLEEP_CLK 206 +#define GCC_USB30_SEC_MASTER_CLK 207 +#define GCC_USB30_SEC_MASTER_CLK_SRC 208 +#define GCC_USB30_SEC_MOCK_UTMI_CLK 209 +#define GCC_USB30_SEC_MOCK_UTMI_CLK_SRC 210 +#define GCC_USB30_SEC_SLEEP_CLK 211 +#define GCC_USB3_MP_PHY_AUX_CLK 212 +#define GCC_USB3_MP_PHY_AUX_CLK_SRC 213 +#define GCC_USB3_MP_PHY_COM_AUX_CLK 214 +#define GCC_USB3_MP_PHY_PIPE_0_CLK 215 +#define GCC_USB3_MP_PHY_PIPE_1_CLK 216 +#define GCC_USB3_PRIM_PHY_AUX_CLK 217 +#define GCC_USB3_PRIM_PHY_AUX_CLK_SRC 218 +#define GCC_USB3_PRIM_PHY_COM_AUX_CLK 219 +#define GCC_USB3_PRIM_PHY_PIPE_CLK 220 +#define GCC_USB3_SEC_PHY_AUX_CLK 221 +#define GCC_USB3_SEC_PHY_AUX_CLK_SRC 222 +#define GCC_USB3_SEC_PHY_COM_AUX_CLK 223 +#define GCC_USB3_SEC_PHY_PIPE_CLK 224 +#define GCC_VIDEO_AXI0_CLK 225 +#define GCC_VIDEO_AXI1_CLK 226 +#define GCC_VIDEO_AXIC_CLK 227 +#define GPLL0 228 +#define GPLL0_OUT_EVEN 229 +#define GPLL1 230 +#define GPLL4 231 +#define GPLL7 232 +#define GCC_PCIE_0_CLKREF_CLK 233 +#define GCC_PCIE_1_CLKREF_CLK 234 +#define GCC_PCIE_2_CLKREF_CLK 235 +#define GCC_PCIE_3_CLKREF_CLK 236 +#define GCC_USB3_PRIM_CLKREF_CLK 237 +#define GCC_USB3_SEC_CLKREF_CLK 238 + +#define GCC_EMAC_BCR 0 +#define GCC_GPU_BCR 1 +#define GCC_MMSS_BCR 2 +#define GCC_NPU_BCR 3 +#define GCC_PCIE_0_BCR 4 +#define GCC_PCIE_0_PHY_BCR 5 +#define GCC_PCIE_1_BCR 6 +#define GCC_PCIE_1_PHY_BCR 7 +#define GCC_PCIE_2_BCR 8 +#define GCC_PCIE_2_PHY_BCR 9 +#define GCC_PCIE_3_BCR 10 +#define GCC_PCIE_3_PHY_BCR 11 +#define GCC_PCIE_PHY_BCR 12 +#define GCC_PDM_BCR 13 +#define GCC_PRNG_BCR 14 +#define GCC_QSPI_1_BCR 15 +#define GCC_QSPI_BCR 16 +#define GCC_QUPV3_WRAPPER_0_BCR 17 +#define GCC_QUPV3_WRAPPER_1_BCR 18 +#define GCC_QUPV3_WRAPPER_2_BCR 19 +#define GCC_QUSB2PHY_5_BCR 20 +#define GCC_QUSB2PHY_MP0_BCR 21 +#define GCC_QUSB2PHY_MP1_BCR 22 +#define GCC_QUSB2PHY_PRIM_BCR 23 +#define GCC_QUSB2PHY_SEC_BCR 24 +#define GCC_USB3_PHY_PRIM_SP0_BCR 25 +#define GCC_USB3_PHY_PRIM_SP1_BCR 26 +#define GCC_USB3_DP_PHY_PRIM_SP0_BCR 27 +#define GCC_USB3_DP_PHY_PRIM_SP1_BCR 28 +#define GCC_USB3_PHY_SEC_BCR 29 +#define GCC_USB3PHY_PHY_SEC_BCR 30 +#define GCC_SDCC2_BCR 31 +#define GCC_SDCC4_BCR 32 +#define GCC_TSIF_BCR 33 +#define GCC_UFS_CARD_2_BCR 34 +#define GCC_UFS_CARD_BCR 35 +#define GCC_UFS_PHY_BCR 36 +#define GCC_USB30_MP_BCR 37 +#define GCC_USB30_PRIM_BCR 38 +#define GCC_USB30_SEC_BCR 39 +#define GCC_USB_PHY_CFG_AHB2PHY_BCR 40 +#define GCC_VIDEO_AXIC_CLK_BCR 41 +#define GCC_VIDEO_AXI0_CLK_BCR 42 +#define GCC_VIDEO_AXI1_CLK_BCR 43 +#define GCC_USB3_DP_PHY_SEC_BCR 44 + +/* GCC GDSCRs */ +#define EMAC_GDSC 0 +#define PCIE_0_GDSC 1 +#define PCIE_1_GDSC 2 +#define PCIE_2_GDSC 3 +#define PCIE_3_GDSC 4 +#define UFS_CARD_2_GDSC 5 +#define UFS_CARD_GDSC 6 +#define UFS_PHY_GDSC 7 +#define USB30_MP_GDSC 8 +#define USB30_PRIM_GDSC 9 +#define USB30_SEC_GDSC 10 + +#endif -- cgit v1.2.3 From a2e8c80845be43607e4957e9d10ec0c05df57a02 Mon Sep 17 00:00:00 2001 From: Vinod Koul Date: Wed, 27 Jan 2021 12:38:10 +0530 Subject: dt-bindings: clock: Add SM8350 GCC clock bindings Add device tree bindings for global clock controller on SM8350 SoCs. Reviewed-by: Rob Herring Reviewed-by: Bjorn Andersson Signed-off-by: Vinod Koul Link: https://lore.kernel.org/r/20210127070811.152690-5-vkoul@kernel.org Signed-off-by: Stephen Boyd --- .../devicetree/bindings/clock/qcom,gcc-sm8350.yaml | 96 ++++++++ include/dt-bindings/clock/qcom,gcc-sm8350.h | 254 +++++++++++++++++++++ 2 files changed, 350 insertions(+) create mode 100644 Documentation/devicetree/bindings/clock/qcom,gcc-sm8350.yaml create mode 100644 include/dt-bindings/clock/qcom,gcc-sm8350.h (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/clock/qcom,gcc-sm8350.yaml b/Documentation/devicetree/bindings/clock/qcom,gcc-sm8350.yaml new file mode 100644 index 000000000000..78f35832aa41 --- /dev/null +++ b/Documentation/devicetree/bindings/clock/qcom,gcc-sm8350.yaml @@ -0,0 +1,96 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/clock/qcom,gcc-sm8350.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Qualcomm Global Clock & Reset Controller Binding for SM8350 + +maintainers: + - Vinod Koul + +description: | + Qualcomm global clock control module which supports the clocks, resets and + power domains on SM8350. + + See also: + - dt-bindings/clock/qcom,gcc-sm8350.h + +properties: + compatible: + const: qcom,gcc-sm8350 + + clocks: + items: + - description: Board XO source + - description: Sleep clock source + - description: PLL test clock source (Optional clock) + - description: PCIE 0 Pipe clock source (Optional clock) + - description: PCIE 1 Pipe clock source (Optional clock) + - description: UFS card Rx symbol 0 clock source (Optional clock) + - description: UFS card Rx symbol 1 clock source (Optional clock) + - description: UFS card Tx symbol 0 clock source (Optional clock) + - description: UFS phy Rx symbol 0 clock source (Optional clock) + - description: UFS phy Rx symbol 1 clock source (Optional clock) + - description: UFS phy Tx symbol 0 clock source (Optional clock) + - description: USB3 phy wrapper pipe clock source (Optional clock) + - description: USB3 phy sec pipe clock source (Optional clock) + minItems: 2 + maxItems: 13 + + clock-names: + items: + - const: bi_tcxo + - const: sleep_clk + - const: core_bi_pll_test_se # Optional clock + - const: pcie_0_pipe_clk # Optional clock + - const: pcie_1_pipe_clk # Optional clock + - const: ufs_card_rx_symbol_0_clk # Optional clock + - const: ufs_card_rx_symbol_1_clk # Optional clock + - const: ufs_card_tx_symbol_0_clk # Optional clock + - const: ufs_phy_rx_symbol_0_clk # Optional clock + - const: ufs_phy_rx_symbol_1_clk # Optional clock + - const: ufs_phy_tx_symbol_0_clk # Optional clock + - const: usb3_phy_wrapper_gcc_usb30_pipe_clk # Optional clock + - const: usb3_uni_phy_sec_gcc_usb30_pipe_clk # Optional clock + minItems: 2 + maxItems: 13 + + '#clock-cells': + const: 1 + + '#reset-cells': + const: 1 + + '#power-domain-cells': + const: 1 + + reg: + maxItems: 1 + +required: + - compatible + - clocks + - clock-names + - reg + - '#clock-cells' + - '#reset-cells' + - '#power-domain-cells' + +additionalProperties: false + +examples: + - | + #include + clock-controller@100000 { + compatible = "qcom,gcc-sm8350"; + reg = <0x00100000 0x1f0000>; + clocks = <&rpmhcc RPMH_CXO_CLK>, + <&sleep_clk>; + clock-names = "bi_tcxo", "sleep_clk"; + #clock-cells = <1>; + #reset-cells = <1>; + #power-domain-cells = <1>; + }; + +... diff --git a/include/dt-bindings/clock/qcom,gcc-sm8350.h b/include/dt-bindings/clock/qcom,gcc-sm8350.h new file mode 100644 index 000000000000..1331da65f669 --- /dev/null +++ b/include/dt-bindings/clock/qcom,gcc-sm8350.h @@ -0,0 +1,254 @@ +/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */ +/* + * Copyright (c) 2019-2020, The Linux Foundation. All rights reserved. + * Copyright (c) 2020-2021, Linaro Limited + */ + +#ifndef _DT_BINDINGS_CLK_QCOM_GCC_SM8350_H +#define _DT_BINDINGS_CLK_QCOM_GCC_SM8350_H + +/* GCC HW clocks */ +#define CORE_BI_PLL_TEST_SE 0 +#define PCIE_0_PIPE_CLK 1 +#define PCIE_1_PIPE_CLK 2 +#define UFS_CARD_RX_SYMBOL_0_CLK 3 +#define UFS_CARD_RX_SYMBOL_1_CLK 4 +#define UFS_CARD_TX_SYMBOL_0_CLK 5 +#define UFS_PHY_RX_SYMBOL_0_CLK 6 +#define UFS_PHY_RX_SYMBOL_1_CLK 7 +#define UFS_PHY_TX_SYMBOL_0_CLK 8 +#define USB3_PHY_WRAPPER_GCC_USB30_PIPE_CLK 9 +#define USB3_UNI_PHY_SEC_GCC_USB30_PIPE_CLK 10 + +/* GCC clocks */ +#define GCC_AGGRE_NOC_PCIE_0_AXI_CLK 11 +#define GCC_AGGRE_NOC_PCIE_1_AXI_CLK 12 +#define GCC_AGGRE_NOC_PCIE_TBU_CLK 13 +#define GCC_AGGRE_UFS_CARD_AXI_CLK 14 +#define GCC_AGGRE_UFS_CARD_AXI_HW_CTL_CLK 15 +#define GCC_AGGRE_UFS_PHY_AXI_CLK 16 +#define GCC_AGGRE_UFS_PHY_AXI_HW_CTL_CLK 17 +#define GCC_AGGRE_USB3_PRIM_AXI_CLK 18 +#define GCC_AGGRE_USB3_SEC_AXI_CLK 19 +#define GCC_BOOT_ROM_AHB_CLK 20 +#define GCC_CAMERA_HF_AXI_CLK 21 +#define GCC_CAMERA_SF_AXI_CLK 22 +#define GCC_CFG_NOC_USB3_PRIM_AXI_CLK 23 +#define GCC_CFG_NOC_USB3_SEC_AXI_CLK 24 +#define GCC_DDRSS_GPU_AXI_CLK 25 +#define GCC_DDRSS_PCIE_SF_TBU_CLK 26 +#define GCC_DISP_HF_AXI_CLK 27 +#define GCC_DISP_SF_AXI_CLK 28 +#define GCC_GP1_CLK 29 +#define GCC_GP1_CLK_SRC 30 +#define GCC_GP2_CLK 31 +#define GCC_GP2_CLK_SRC 32 +#define GCC_GP3_CLK 33 +#define GCC_GP3_CLK_SRC 34 +#define GCC_GPLL0 35 +#define GCC_GPLL0_OUT_EVEN 36 +#define GCC_GPLL4 37 +#define GCC_GPLL9 38 +#define GCC_GPU_GPLL0_CLK_SRC 39 +#define GCC_GPU_GPLL0_DIV_CLK_SRC 40 +#define GCC_GPU_IREF_EN 41 +#define GCC_GPU_MEMNOC_GFX_CLK 42 +#define GCC_GPU_SNOC_DVM_GFX_CLK 43 +#define GCC_PCIE0_PHY_RCHNG_CLK 44 +#define GCC_PCIE1_PHY_RCHNG_CLK 45 +#define GCC_PCIE_0_AUX_CLK 46 +#define GCC_PCIE_0_AUX_CLK_SRC 47 +#define GCC_PCIE_0_CFG_AHB_CLK 48 +#define GCC_PCIE_0_CLKREF_EN 49 +#define GCC_PCIE_0_MSTR_AXI_CLK 50 +#define GCC_PCIE_0_PHY_RCHNG_CLK_SRC 51 +#define GCC_PCIE_0_PIPE_CLK 52 +#define GCC_PCIE_0_PIPE_CLK_SRC 53 +#define GCC_PCIE_0_SLV_AXI_CLK 54 +#define GCC_PCIE_0_SLV_Q2A_AXI_CLK 55 +#define GCC_PCIE_1_AUX_CLK 56 +#define GCC_PCIE_1_AUX_CLK_SRC 57 +#define GCC_PCIE_1_CFG_AHB_CLK 58 +#define GCC_PCIE_1_CLKREF_EN 59 +#define GCC_PCIE_1_MSTR_AXI_CLK 60 +#define GCC_PCIE_1_PHY_RCHNG_CLK_SRC 61 +#define GCC_PCIE_1_PIPE_CLK 62 +#define GCC_PCIE_1_PIPE_CLK_SRC 63 +#define GCC_PCIE_1_SLV_AXI_CLK 64 +#define GCC_PCIE_1_SLV_Q2A_AXI_CLK 65 +#define GCC_PDM2_CLK 66 +#define GCC_PDM2_CLK_SRC 67 +#define GCC_PDM_AHB_CLK 68 +#define GCC_PDM_XO4_CLK 69 +#define GCC_QMIP_CAMERA_NRT_AHB_CLK 70 +#define GCC_QMIP_CAMERA_RT_AHB_CLK 71 +#define GCC_QMIP_DISP_AHB_CLK 72 +#define GCC_QMIP_VIDEO_CVP_AHB_CLK 73 +#define GCC_QMIP_VIDEO_VCODEC_AHB_CLK 74 +#define GCC_QUPV3_WRAP0_CORE_2X_CLK 75 +#define GCC_QUPV3_WRAP0_CORE_CLK 76 +#define GCC_QUPV3_WRAP0_S0_CLK 77 +#define GCC_QUPV3_WRAP0_S0_CLK_SRC 78 +#define GCC_QUPV3_WRAP0_S1_CLK 79 +#define GCC_QUPV3_WRAP0_S1_CLK_SRC 80 +#define GCC_QUPV3_WRAP0_S2_CLK 81 +#define GCC_QUPV3_WRAP0_S2_CLK_SRC 82 +#define GCC_QUPV3_WRAP0_S3_CLK 83 +#define GCC_QUPV3_WRAP0_S3_CLK_SRC 84 +#define GCC_QUPV3_WRAP0_S4_CLK 85 +#define GCC_QUPV3_WRAP0_S4_CLK_SRC 86 +#define GCC_QUPV3_WRAP0_S5_CLK 87 +#define GCC_QUPV3_WRAP0_S5_CLK_SRC 88 +#define GCC_QUPV3_WRAP0_S6_CLK 89 +#define GCC_QUPV3_WRAP0_S6_CLK_SRC 90 +#define GCC_QUPV3_WRAP0_S7_CLK 91 +#define GCC_QUPV3_WRAP0_S7_CLK_SRC 92 +#define GCC_QUPV3_WRAP1_CORE_2X_CLK 93 +#define GCC_QUPV3_WRAP1_CORE_CLK 94 +#define GCC_QUPV3_WRAP1_S0_CLK 95 +#define GCC_QUPV3_WRAP1_S0_CLK_SRC 96 +#define GCC_QUPV3_WRAP1_S1_CLK 97 +#define GCC_QUPV3_WRAP1_S1_CLK_SRC 98 +#define GCC_QUPV3_WRAP1_S2_CLK 99 +#define GCC_QUPV3_WRAP1_S2_CLK_SRC 100 +#define GCC_QUPV3_WRAP1_S3_CLK 101 +#define GCC_QUPV3_WRAP1_S3_CLK_SRC 102 +#define GCC_QUPV3_WRAP1_S4_CLK 103 +#define GCC_QUPV3_WRAP1_S4_CLK_SRC 104 +#define GCC_QUPV3_WRAP1_S5_CLK 105 +#define GCC_QUPV3_WRAP1_S5_CLK_SRC 106 +#define GCC_QUPV3_WRAP2_CORE_2X_CLK 107 +#define GCC_QUPV3_WRAP2_CORE_CLK 108 +#define GCC_QUPV3_WRAP2_S0_CLK 109 +#define GCC_QUPV3_WRAP2_S0_CLK_SRC 110 +#define GCC_QUPV3_WRAP2_S1_CLK 111 +#define GCC_QUPV3_WRAP2_S1_CLK_SRC 112 +#define GCC_QUPV3_WRAP2_S2_CLK 113 +#define GCC_QUPV3_WRAP2_S2_CLK_SRC 114 +#define GCC_QUPV3_WRAP2_S3_CLK 115 +#define GCC_QUPV3_WRAP2_S3_CLK_SRC 116 +#define GCC_QUPV3_WRAP2_S4_CLK 117 +#define GCC_QUPV3_WRAP2_S4_CLK_SRC 118 +#define GCC_QUPV3_WRAP2_S5_CLK 119 +#define GCC_QUPV3_WRAP2_S5_CLK_SRC 120 +#define GCC_QUPV3_WRAP_0_M_AHB_CLK 121 +#define GCC_QUPV3_WRAP_0_S_AHB_CLK 122 +#define GCC_QUPV3_WRAP_1_M_AHB_CLK 123 +#define GCC_QUPV3_WRAP_1_S_AHB_CLK 124 +#define GCC_QUPV3_WRAP_2_M_AHB_CLK 125 +#define GCC_QUPV3_WRAP_2_S_AHB_CLK 126 +#define GCC_SDCC2_AHB_CLK 127 +#define GCC_SDCC2_APPS_CLK 128 +#define GCC_SDCC2_APPS_CLK_SRC 129 +#define GCC_SDCC4_AHB_CLK 130 +#define GCC_SDCC4_APPS_CLK 131 +#define GCC_SDCC4_APPS_CLK_SRC 132 +#define GCC_THROTTLE_PCIE_AHB_CLK 133 +#define GCC_UFS_1_CLKREF_EN 134 +#define GCC_UFS_CARD_AHB_CLK 135 +#define GCC_UFS_CARD_AXI_CLK 136 +#define GCC_UFS_CARD_AXI_CLK_SRC 137 +#define GCC_UFS_CARD_AXI_HW_CTL_CLK 138 +#define GCC_UFS_CARD_ICE_CORE_CLK 139 +#define GCC_UFS_CARD_ICE_CORE_CLK_SRC 140 +#define GCC_UFS_CARD_ICE_CORE_HW_CTL_CLK 141 +#define GCC_UFS_CARD_PHY_AUX_CLK 142 +#define GCC_UFS_CARD_PHY_AUX_CLK_SRC 143 +#define GCC_UFS_CARD_PHY_AUX_HW_CTL_CLK 144 +#define GCC_UFS_CARD_RX_SYMBOL_0_CLK 145 +#define GCC_UFS_CARD_RX_SYMBOL_0_CLK_SRC 146 +#define GCC_UFS_CARD_RX_SYMBOL_1_CLK 147 +#define GCC_UFS_CARD_RX_SYMBOL_1_CLK_SRC 148 +#define GCC_UFS_CARD_TX_SYMBOL_0_CLK 149 +#define GCC_UFS_CARD_TX_SYMBOL_0_CLK_SRC 150 +#define GCC_UFS_CARD_UNIPRO_CORE_CLK 151 +#define GCC_UFS_CARD_UNIPRO_CORE_CLK_SRC 152 +#define GCC_UFS_CARD_UNIPRO_CORE_HW_CTL_CLK 153 +#define GCC_UFS_PHY_AHB_CLK 154 +#define GCC_UFS_PHY_AXI_CLK 155 +#define GCC_UFS_PHY_AXI_CLK_SRC 156 +#define GCC_UFS_PHY_AXI_HW_CTL_CLK 157 +#define GCC_UFS_PHY_ICE_CORE_CLK 158 +#define GCC_UFS_PHY_ICE_CORE_CLK_SRC 159 +#define GCC_UFS_PHY_ICE_CORE_HW_CTL_CLK 160 +#define GCC_UFS_PHY_PHY_AUX_CLK 161 +#define GCC_UFS_PHY_PHY_AUX_CLK_SRC 162 +#define GCC_UFS_PHY_PHY_AUX_HW_CTL_CLK 163 +#define GCC_UFS_PHY_RX_SYMBOL_0_CLK 164 +#define GCC_UFS_PHY_RX_SYMBOL_0_CLK_SRC 165 +#define GCC_UFS_PHY_RX_SYMBOL_1_CLK 166 +#define GCC_UFS_PHY_RX_SYMBOL_1_CLK_SRC 167 +#define GCC_UFS_PHY_TX_SYMBOL_0_CLK 168 +#define GCC_UFS_PHY_TX_SYMBOL_0_CLK_SRC 169 +#define GCC_UFS_PHY_UNIPRO_CORE_CLK 170 +#define GCC_UFS_PHY_UNIPRO_CORE_CLK_SRC 171 +#define GCC_UFS_PHY_UNIPRO_CORE_HW_CTL_CLK 172 +#define GCC_USB30_PRIM_MASTER_CLK 173 +#define GCC_USB30_PRIM_MASTER_CLK__FORCE_MEM_CORE_ON 174 +#define GCC_USB30_PRIM_MASTER_CLK_SRC 175 +#define GCC_USB30_PRIM_MOCK_UTMI_CLK 176 +#define GCC_USB30_PRIM_MOCK_UTMI_CLK_SRC 177 +#define GCC_USB30_PRIM_MOCK_UTMI_POSTDIV_CLK_SRC 178 +#define GCC_USB30_PRIM_SLEEP_CLK 179 +#define GCC_USB30_SEC_MASTER_CLK 180 +#define GCC_USB30_SEC_MASTER_CLK__FORCE_MEM_CORE_ON 181 +#define GCC_USB30_SEC_MASTER_CLK_SRC 182 +#define GCC_USB30_SEC_MOCK_UTMI_CLK 183 +#define GCC_USB30_SEC_MOCK_UTMI_CLK_SRC 184 +#define GCC_USB30_SEC_MOCK_UTMI_POSTDIV_CLK_SRC 185 +#define GCC_USB30_SEC_SLEEP_CLK 186 +#define GCC_USB3_PRIM_PHY_AUX_CLK 187 +#define GCC_USB3_PRIM_PHY_AUX_CLK_SRC 188 +#define GCC_USB3_PRIM_PHY_COM_AUX_CLK 189 +#define GCC_USB3_PRIM_PHY_PIPE_CLK 190 +#define GCC_USB3_PRIM_PHY_PIPE_CLK_SRC 191 +#define GCC_USB3_SEC_CLKREF_EN 192 +#define GCC_USB3_SEC_PHY_AUX_CLK 193 +#define GCC_USB3_SEC_PHY_AUX_CLK_SRC 194 +#define GCC_USB3_SEC_PHY_COM_AUX_CLK 195 +#define GCC_USB3_SEC_PHY_PIPE_CLK 196 +#define GCC_USB3_SEC_PHY_PIPE_CLK_SRC 197 +#define GCC_VIDEO_AXI0_CLK 198 +#define GCC_VIDEO_AXI1_CLK 199 + +/* GCC resets */ +#define GCC_CAMERA_BCR 0 +#define GCC_DISPLAY_BCR 1 +#define GCC_GPU_BCR 2 +#define GCC_MMSS_BCR 3 +#define GCC_PCIE_0_BCR 4 +#define GCC_PCIE_0_LINK_DOWN_BCR 5 +#define GCC_PCIE_0_NOCSR_COM_PHY_BCR 6 +#define GCC_PCIE_0_PHY_BCR 7 +#define GCC_PCIE_0_PHY_NOCSR_COM_PHY_BCR 8 +#define GCC_PCIE_1_BCR 9 +#define GCC_PCIE_1_LINK_DOWN_BCR 10 +#define GCC_PCIE_1_NOCSR_COM_PHY_BCR 11 +#define GCC_PCIE_1_PHY_BCR 12 +#define GCC_PCIE_1_PHY_NOCSR_COM_PHY_BCR 13 +#define GCC_PCIE_PHY_CFG_AHB_BCR 14 +#define GCC_PCIE_PHY_COM_BCR 15 +#define GCC_PDM_BCR 16 +#define GCC_QUPV3_WRAPPER_0_BCR 17 +#define GCC_QUPV3_WRAPPER_1_BCR 18 +#define GCC_QUPV3_WRAPPER_2_BCR 19 +#define GCC_QUSB2PHY_PRIM_BCR 20 +#define GCC_QUSB2PHY_SEC_BCR 21 +#define GCC_SDCC2_BCR 22 +#define GCC_SDCC4_BCR 23 +#define GCC_UFS_CARD_BCR 24 +#define GCC_UFS_PHY_BCR 25 +#define GCC_USB30_PRIM_BCR 26 +#define GCC_USB30_SEC_BCR 27 +#define GCC_USB3_DP_PHY_PRIM_BCR 28 +#define GCC_USB3_DP_PHY_SEC_BCR 29 +#define GCC_USB3_PHY_PRIM_BCR 30 +#define GCC_USB3_PHY_SEC_BCR 31 +#define GCC_USB3PHY_PHY_PRIM_BCR 32 +#define GCC_USB3PHY_PHY_SEC_BCR 33 +#define GCC_USB_PHY_CFG_AHB2PHY_BCR 34 +#define GCC_VIDEO_AXI0_CLK_ARES 35 +#define GCC_VIDEO_AXI1_CLK_ARES 36 +#define GCC_VIDEO_BCR 37 + +#endif -- cgit v1.2.3 From c9ef2d3e3f3b3e56429f56bbea2d16882b054dbe Mon Sep 17 00:00:00 2001 From: Daniel Latypov Date: Tue, 19 Jan 2021 15:52:26 -0800 Subject: KUnit: Docs: make start.rst example Kconfig follow style.rst The primary change is that we want to encourage people to respect KUNIT_ALL_TESTS to make it easy to run all the relevant tests for a given config. Signed-off-by: Daniel Latypov Reviewed-by: Brendan Higgins Signed-off-by: Shuah Khan --- Documentation/dev-tools/kunit/start.rst | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'Documentation') diff --git a/Documentation/dev-tools/kunit/start.rst b/Documentation/dev-tools/kunit/start.rst index 454f307813ea..560f27af4619 100644 --- a/Documentation/dev-tools/kunit/start.rst +++ b/Documentation/dev-tools/kunit/start.rst @@ -196,8 +196,9 @@ Now add the following to ``drivers/misc/Kconfig``: .. code-block:: kconfig config MISC_EXAMPLE_TEST - bool "Test for my example" + tristate "Test for my example" if !KUNIT_ALL_TESTS depends on MISC_EXAMPLE && KUNIT=y + default KUNIT_ALL_TESTS and the following to ``drivers/misc/Makefile``: -- cgit v1.2.3 From 7c2b108cbe75f993d5e69d5205a01211fa33417d Mon Sep 17 00:00:00 2001 From: Daniel Latypov Date: Mon, 25 Jan 2021 10:53:33 -0800 Subject: Documentation: kunit: add tips.rst for small examples ./usage.rst contains fairly long examples and explanations of things like how to fake a class and how to use parameterized tests (and how you could do table-driven tests yourself). It's not exactly necessary information, so we add a new page with more digestible tips like "use kunit_kzalloc() instead of kzalloc() so you don't have to worry about calling kfree() yourself" and the like. Change start.rst to point users to this new page first and let them know that usage.rst is more of optional further reading. Signed-off-by: Daniel Latypov Reviewed-by: Brendan Higgins Signed-off-by: Shuah Khan --- Documentation/dev-tools/kunit/index.rst | 2 + Documentation/dev-tools/kunit/start.rst | 4 +- Documentation/dev-tools/kunit/tips.rst | 115 ++++++++++++++++++++++++++++++++ 3 files changed, 120 insertions(+), 1 deletion(-) create mode 100644 Documentation/dev-tools/kunit/tips.rst (limited to 'Documentation') diff --git a/Documentation/dev-tools/kunit/index.rst b/Documentation/dev-tools/kunit/index.rst index c234a3ab3c34..848478838347 100644 --- a/Documentation/dev-tools/kunit/index.rst +++ b/Documentation/dev-tools/kunit/index.rst @@ -13,6 +13,7 @@ KUnit - Unit Testing for the Linux Kernel api/index style faq + tips What is KUnit? ============== @@ -88,6 +89,7 @@ How do I use it? ================ * :doc:`start` - for new users of KUnit +* :doc:`tips` - for short examples of best practices * :doc:`usage` - for a more detailed explanation of KUnit features * :doc:`api/index` - for the list of KUnit APIs used for testing * :doc:`kunit-tool` - for more information on the kunit_tool helper script diff --git a/Documentation/dev-tools/kunit/start.rst b/Documentation/dev-tools/kunit/start.rst index 560f27af4619..0e65cabe08eb 100644 --- a/Documentation/dev-tools/kunit/start.rst +++ b/Documentation/dev-tools/kunit/start.rst @@ -234,5 +234,7 @@ Congrats! You just wrote your first KUnit test! Next Steps ========== -* Check out the :doc:`usage` page for a more +* Check out the :doc:`tips` page for tips on + writing idiomatic KUnit tests. +* Optional: see the :doc:`usage` page for a more in-depth explanation of KUnit. diff --git a/Documentation/dev-tools/kunit/tips.rst b/Documentation/dev-tools/kunit/tips.rst new file mode 100644 index 000000000000..a6ca0af14098 --- /dev/null +++ b/Documentation/dev-tools/kunit/tips.rst @@ -0,0 +1,115 @@ +.. SPDX-License-Identifier: GPL-2.0 + +============================ +Tips For Writing KUnit Tests +============================ + +Exiting early on failed expectations +------------------------------------ + +``KUNIT_EXPECT_EQ`` and friends will mark the test as failed and continue +execution. In some cases, it's unsafe to continue and you can use the +``KUNIT_ASSERT`` variant to exit on failure. + +.. code-block:: c + + void example_test_user_alloc_function(struct kunit *test) + { + void *object = alloc_some_object_for_me(); + + /* Make sure we got a valid pointer back. */ + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, object); + do_something_with_object(object); + } + +Allocating memory +----------------- + +Where you would use ``kzalloc``, you should prefer ``kunit_kzalloc`` instead. +KUnit will ensure the memory is freed once the test completes. + +This is particularly useful since it lets you use the ``KUNIT_ASSERT_EQ`` +macros to exit early from a test without having to worry about remembering to +call ``kfree``. + +Example: + +.. code-block:: c + + void example_test_allocation(struct kunit *test) + { + char *buffer = kunit_kzalloc(test, 16, GFP_KERNEL); + /* Ensure allocation succeeded. */ + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, buffer); + + KUNIT_ASSERT_STREQ(test, buffer, ""); + } + + +Testing static functions +------------------------ + +If you don't want to expose functions or variables just for testing, one option +is to conditionally ``#include`` the test file at the end of your .c file, e.g. + +.. code-block:: c + + /* In my_file.c */ + + static int do_interesting_thing(); + + #ifdef CONFIG_MY_KUNIT_TEST + #include "my_kunit_test.c" + #endif + +Injecting test-only code +------------------------ + +Similarly to the above, it can be useful to add test-specific logic. + +.. code-block:: c + + /* In my_file.h */ + + #ifdef CONFIG_MY_KUNIT_TEST + /* Defined in my_kunit_test.c */ + void test_only_hook(void); + #else + void test_only_hook(void) { } + #endif + +TODO(dlatypov@google.com): add an example of using ``current->kunit_test`` in +such a hook when it's not only updated for ``CONFIG_KASAN=y``. + +Customizing error messages +-------------------------- + +Each of the ``KUNIT_EXPECT`` and ``KUNIT_ASSERT`` macros have a ``_MSG`` variant. +These take a format string and arguments to provide additional context to the automatically generated error messages. + +.. code-block:: c + + char some_str[41]; + generate_sha1_hex_string(some_str); + + /* Before. Not easy to tell why the test failed. */ + KUNIT_EXPECT_EQ(test, strlen(some_str), 40); + + /* After. Now we see the offending string. */ + KUNIT_EXPECT_EQ_MSG(test, strlen(some_str), 40, "some_str='%s'", some_str); + +Alternatively, one can take full control over the error message by using ``KUNIT_FAIL()``, e.g. + +.. code-block:: c + + /* Before */ + KUNIT_EXPECT_EQ(test, some_setup_function(), 0); + + /* After: full control over the failure message. */ + if (some_setup_function()) + KUNIT_FAIL(test, "Failed to setup thing for testing"); + +Next Steps +========== +* Optional: see the :doc:`usage` page for a more + in-depth explanation of KUnit. -- cgit v1.2.3 From a851dfa8dfa72c1781667140ba1796597be27f3b Mon Sep 17 00:00:00 2001 From: Tony Nguyen Date: Fri, 20 Nov 2020 16:39:25 -0800 Subject: Documentation: ice: update documentation The ice documentation has not been updated since the initial commits of the driver. Update the documentation with features and information that are now available. Signed-off-by: Tony Nguyen --- .../device_drivers/ethernet/intel/ice.rst | 1027 +++++++++++++++++++- 1 file changed, 1006 insertions(+), 21 deletions(-) (limited to 'Documentation') diff --git a/Documentation/networking/device_drivers/ethernet/intel/ice.rst b/Documentation/networking/device_drivers/ethernet/intel/ice.rst index ee43ea57d443..e7d9cbff771b 100644 --- a/Documentation/networking/device_drivers/ethernet/intel/ice.rst +++ b/Documentation/networking/device_drivers/ethernet/intel/ice.rst @@ -1,46 +1,1031 @@ .. SPDX-License-Identifier: GPL-2.0+ -================================================================== -Linux Base Driver for the Intel(R) Ethernet Connection E800 Series -================================================================== +================================================================= +Linux Base Driver for the Intel(R) Ethernet Controller 800 Series +================================================================= Intel ice Linux driver. -Copyright(c) 2018 Intel Corporation. +Copyright(c) 2018-2021 Intel Corporation. Contents ======== -- Enabling the driver -- Support +- Overview +- Identifying Your Adapter +- Important Notes +- Additional Features & Configurations +- Performance Optimization -The driver in this release supports Intel's E800 Series of products. For -more information, visit Intel's support page at https://support.intel.com. -Enabling the driver -=================== -The driver is enabled via the standard kernel configuration system, -using the make command:: +The associated Virtual Function (VF) driver for this driver is iavf. - make oldconfig/menuconfig/etc. +Driver information can be obtained using ethtool and lspci. -The driver is located in the menu structure at: +For questions related to hardware requirements, refer to the documentation +supplied with your Intel adapter. All hardware requirements listed apply to use +with Linux. + +This driver supports XDP (Express Data Path) and AF_XDP zero-copy. Note that +XDP is blocked for frame sizes larger than 3KB. + + +Identifying Your Adapter +======================== +For information on how to identify your adapter, and for the latest Intel +network drivers, refer to the Intel Support website: +https://www.intel.com/support + + +Important Notes +=============== + +Packet drops may occur under receive stress +------------------------------------------- +Devices based on the Intel(R) Ethernet Controller 800 Series are designed to +tolerate a limited amount of system latency during PCIe and DMA transactions. +If these transactions take longer than the tolerated latency, it can impact the +length of time the packets are buffered in the device and associated memory, +which may result in dropped packets. These packets drops typically do not have +a noticeable impact on throughput and performance under standard workloads. + +If these packet drops appear to affect your workload, the following may improve +the situation: + +1) Make sure that your system's physical memory is in a high-performance + configuration, as recommended by the platform vendor. A common + recommendation is for all channels to be populated with a single DIMM + module. +2) In your system's BIOS/UEFI settings, select the "Performance" profile. +3) Your distribution may provide tools like "tuned," which can help tweak + kernel settings to achieve better standard settings for different workloads. + + +Configuring SR-IOV for improved network security +------------------------------------------------ +In a virtualized environment, on Intel(R) Ethernet Network Adapters that +support SR-IOV, the virtual function (VF) may be subject to malicious behavior. +Software-generated layer two frames, like IEEE 802.3x (link flow control), IEEE +802.1Qbb (priority based flow-control), and others of this type, are not +expected and can throttle traffic between the host and the virtual switch, +reducing performance. To resolve this issue, and to ensure isolation from +unintended traffic streams, configure all SR-IOV enabled ports for VLAN tagging +from the administrative interface on the PF. This configuration allows +unexpected, and potentially malicious, frames to be dropped. + +See "Configuring VLAN Tagging on SR-IOV Enabled Adapter Ports" later in this +README for configuration instructions. + + +Do not unload port driver if VF with active VM is bound to it +------------------------------------------------------------- +Do not unload a port's driver if a Virtual Function (VF) with an active Virtual +Machine (VM) is bound to it. Doing so will cause the port to appear to hang. +Once the VM shuts down, or otherwise releases the VF, the command will +complete. + + +Important notes for SR-IOV and Link Aggregation +----------------------------------------------- +Link Aggregation is mutually exclusive with SR-IOV. + +- If Link Aggregation is active, SR-IOV VFs cannot be created on the PF. +- If SR-IOV is active, you cannot set up Link Aggregation on the interface. + +Bridging and MACVLAN are also affected by this. If you wish to use bridging or +MACVLAN with SR-IOV, you must set up bridging or MACVLAN before enabling +SR-IOV. If you are using bridging or MACVLAN in conjunction with SR-IOV, and +you want to remove the interface from the bridge or MACVLAN, you must follow +these steps: + +1. Destroy SR-IOV VFs if they exist +2. Remove the interface from the bridge or MACVLAN +3. Recreate SRIOV VFs as needed + + +Additional Features and Configurations +====================================== + +ethtool +------- +The driver utilizes the ethtool interface for driver configuration and +diagnostics, as well as displaying statistical information. The latest ethtool +version is required for this functionality. Download it at: +https://kernel.org/pub/software/network/ethtool/ + +NOTE: The rx_bytes value of ethtool does not match the rx_bytes value of +Netdev, due to the 4-byte CRC being stripped by the device. The difference +between the two rx_bytes values will be 4 x the number of Rx packets. For +example, if Rx packets are 10 and Netdev (software statistics) displays +rx_bytes as "X", then ethtool (hardware statistics) will display rx_bytes as +"X+40" (4 bytes CRC x 10 packets). + + +Viewing Link Messages +--------------------- +Link messages will not be displayed to the console if the distribution is +restricting system messages. In order to see network driver link messages on +your console, set dmesg to eight by entering the following:: + + # dmesg -n 8 + +NOTE: This setting is not saved across reboots. + + +Dynamic Device Personalization +------------------------------ +Dynamic Device Personalization (DDP) allows you to change the packet processing +pipeline of a device by applying a profile package to the device at runtime. +Profiles can be used to, for example, add support for new protocols, change +existing protocols, or change default settings. DDP profiles can also be rolled +back without rebooting the system. + +The DDP package loads during device initialization. The driver looks for +``intel/ice/ddp/ice.pkg`` in your firmware root (typically ``/lib/firmware/`` +or ``/lib/firmware/updates/``) and checks that it contains a valid DDP package +file. + +NOTE: Your distribution should likely have provided the latest DDP file, but if +ice.pkg is missing, you can find it in the linux-firmware repository or from +intel.com. + +If the driver is unable to load the DDP package, the device will enter Safe +Mode. Safe Mode disables advanced and performance features and supports only +basic traffic and minimal functionality, such as updating the NVM or +downloading a new driver or DDP package. Safe Mode only applies to the affected +physical function and does not impact any other PFs. See the "Intel(R) Ethernet +Adapters and Devices User Guide" for more details on DDP and Safe Mode. + +NOTES: + +- If you encounter issues with the DDP package file, you may need to download + an updated driver or DDP package file. See the log messages for more + information. + +- The ice.pkg file is a symbolic link to the default DDP package file. + +- You cannot update the DDP package if any PF drivers are already loaded. To + overwrite a package, unload all PFs and then reload the driver with the new + package. + +- Only the first loaded PF per device can download a package for that device. + +You can install specific DDP package files for different physical devices in +the same system. To install a specific DDP package file: + +1. Download the DDP package file you want for your device. + +2. Rename the file ice-xxxxxxxxxxxxxxxx.pkg, where 'xxxxxxxxxxxxxxxx' is the + unique 64-bit PCI Express device serial number (in hex) of the device you + want the package downloaded on. The filename must include the complete + serial number (including leading zeros) and be all lowercase. For example, + if the 64-bit serial number is b887a3ffffca0568, then the file name would be + ice-b887a3ffffca0568.pkg. + + To find the serial number from the PCI bus address, you can use the + following command:: + + # lspci -vv -s af:00.0 | grep -i Serial + Capabilities: [150 v1] Device Serial Number b8-87-a3-ff-ff-ca-05-68 + + You can use the following command to format the serial number without the + dashes:: + + # lspci -vv -s af:00.0 | grep -i Serial | awk '{print $7}' | sed s/-//g + b887a3ffffca0568 + +3. Copy the renamed DDP package file to + ``/lib/firmware/updates/intel/ice/ddp/``. If the directory does not yet + exist, create it before copying the file. + +4. Unload all of the PFs on the device. + +5. Reload the driver with the new package. + +NOTE: The presence of a device-specific DDP package file overrides the loading +of the default DDP package file (ice.pkg). + + +Intel(R) Ethernet Flow Director +------------------------------- +The Intel Ethernet Flow Director performs the following tasks: + +- Directs receive packets according to their flows to different queues +- Enables tight control on routing a flow in the platform +- Matches flows and CPU cores for flow affinity + +NOTE: This driver supports the following flow types: + +- IPv4 +- TCPv4 +- UDPv4 +- SCTPv4 +- IPv6 +- TCPv6 +- UDPv6 +- SCTPv6 + +Each flow type supports valid combinations of IP addresses (source or +destination) and UDP/TCP/SCTP ports (source and destination). You can supply +only a source IP address, a source IP address and a destination port, or any +combination of one or more of these four parameters. + +NOTE: This driver allows you to filter traffic based on a user-defined flexible +two-byte pattern and offset by using the ethtool user-def and mask fields. Only +L3 and L4 flow types are supported for user-defined flexible filters. For a +given flow type, you must clear all Intel Ethernet Flow Director filters before +changing the input set (for that flow type). + + +Flow Director Filters +--------------------- +Flow Director filters are used to direct traffic that matches specified +characteristics. They are enabled through ethtool's ntuple interface. To enable +or disable the Intel Ethernet Flow Director and these filters:: + + # ethtool -K ntuple + +NOTE: When you disable ntuple filters, all the user programmed filters are +flushed from the driver cache and hardware. All needed filters must be re-added +when ntuple is re-enabled. + +To display all of the active filters:: + + # ethtool -u + +To add a new filter:: + + # ethtool -U flow-type src-ip [m ] dst-ip + [m ] src-port [m ] dst-port [m ] + action + + Where: + - the Ethernet device to program + - can be ip4, tcp4, udp4, sctp4, ip6, tcp6, udp6, sctp6 + - the IP address to match on + - the IPv4 address to mask on + NOTE: These filters use inverted masks. + - the port number to match on + - the 16-bit integer for masking + NOTE: These filters use inverted masks. + - the queue to direct traffic toward (-1 discards the + matched traffic) + +To delete a filter:: + + # ethtool -U delete + + Where is the filter ID displayed when printing all the active filters, + and may also have been specified using "loc " when adding the filter. + +EXAMPLES: + +To add a filter that directs packet to queue 2:: + + # ethtool -U flow-type tcp4 src-ip 192.168.10.1 dst-ip \ + 192.168.10.2 src-port 2000 dst-port 2001 action 2 [loc 1] + +To set a filter using only the source and destination IP address:: + + # ethtool -U flow-type tcp4 src-ip 192.168.10.1 dst-ip \ + 192.168.10.2 action 2 [loc 1] + +To set a filter based on a user-defined pattern and offset:: + + # ethtool -U flow-type tcp4 src-ip 192.168.10.1 dst-ip \ + 192.168.10.2 user-def 0x4FFFF action 2 [loc 1] + + where the value of the user-def field contains the offset (4 bytes) and + the pattern (0xffff). + +To match TCP traffic sent from 192.168.0.1, port 5300, directed to 192.168.0.5, +port 80, and then send it to queue 7:: + + # ethtool -U enp130s0 flow-type tcp4 src-ip 192.168.0.1 dst-ip 192.168.0.5 + src-port 5300 dst-port 80 action 7 + +To add a TCPv4 filter with a partial mask for a source IP subnet:: + + # ethtool -U flow-type tcp4 src-ip 192.168.0.0 m 0.255.255.255 dst-ip + 192.168.5.12 src-port 12600 dst-port 31 action 12 + +NOTES: + +For each flow-type, the programmed filters must all have the same matching +input set. For example, issuing the following two commands is acceptable:: + + # ethtool -U enp130s0 flow-type ip4 src-ip 192.168.0.1 src-port 5300 action 7 + # ethtool -U enp130s0 flow-type ip4 src-ip 192.168.0.5 src-port 55 action 10 + +Issuing the next two commands, however, is not acceptable, since the first +specifies src-ip and the second specifies dst-ip:: + + # ethtool -U enp130s0 flow-type ip4 src-ip 192.168.0.1 src-port 5300 action 7 + # ethtool -U enp130s0 flow-type ip4 dst-ip 192.168.0.5 src-port 55 action 10 + +The second command will fail with an error. You may program multiple filters +with the same fields, using different values, but, on one device, you may not +program two tcp4 filters with different matching fields. + +The ice driver does not support matching on a subportion of a field, thus +partial mask fields are not supported. + + +Flex Byte Flow Director Filters +------------------------------- +The driver also supports matching user-defined data within the packet payload. +This flexible data is specified using the "user-def" field of the ethtool +command in the following way: + +.. table:: + + ============================== ============================ + ``31 28 24 20 16`` ``15 12 8 4 0`` + ``offset into packet payload`` ``2 bytes of flexible data`` + ============================== ============================ + +For example, + +:: + + ... user-def 0x4FFFF ... + +tells the filter to look 4 bytes into the payload and match that value against +0xFFFF. The offset is based on the beginning of the payload, and not the +beginning of the packet. Thus + +:: + + flow-type tcp4 ... user-def 0x8BEAF ... + +would match TCP/IPv4 packets which have the value 0xBEAF 8 bytes into the +TCP/IPv4 payload. + +Note that ICMP headers are parsed as 4 bytes of header and 4 bytes of payload. +Thus to match the first byte of the payload, you must actually add 4 bytes to +the offset. Also note that ip4 filters match both ICMP frames as well as raw +(unknown) ip4 frames, where the payload will be the L3 payload of the IP4 +frame. + +The maximum offset is 64. The hardware will only read up to 64 bytes of data +from the payload. The offset must be even because the flexible data is 2 bytes +long and must be aligned to byte 0 of the packet payload. + +The user-defined flexible offset is also considered part of the input set and +cannot be programmed separately for multiple filters of the same type. However, +the flexible data is not part of the input set and multiple filters may use the +same offset but match against different data. + + +RSS Hash Flow +------------- +Allows you to set the hash bytes per flow type and any combination of one or +more options for Receive Side Scaling (RSS) hash byte configuration. + +:: + + # ethtool -N rx-flow-hash