From 993220ba6706dddbc73d9fc6bc21d371b9b4570c Mon Sep 17 00:00:00 2001 From: Corey Minyard Date: Fri, 26 Nov 2021 18:12:14 -0600 Subject: [PATCH 001/370] ipmi: Add the git repository to the MAINTAINERS file Advertise where the IPMI git repository is stored. Signed-off-by: Corey Minyard --- MAINTAINERS | 1 + 1 file changed, 1 insertion(+) diff --git a/MAINTAINERS b/MAINTAINERS index a58544f7b699..9dc675a8bddd 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -10074,6 +10074,7 @@ M: Corey Minyard L: openipmi-developer@lists.sourceforge.net (moderated for non-subscribers) S: Supported W: http://openipmi.sourceforge.net/ +T: git https://github.com/cminyard/linux-ipmi.git for-next F: Documentation/driver-api/ipmi.rst F: Documentation/devicetree/bindings/ipmi/ F: drivers/char/ipmi/ From 7281599201c3336e350406781e7d88ca92453727 Mon Sep 17 00:00:00 2001 From: Rikard Falkeborn Date: Sun, 28 Nov 2021 23:01:54 +0100 Subject: [PATCH 002/370] ipmi/watchdog: Constify ident ident is not modified and can be made const to allow the compiler to put it in read-only memory. Signed-off-by: Rikard Falkeborn Message-Id: <20211128220154.32927-1-rikard.falkeborn@gmail.com> Signed-off-by: Corey Minyard --- drivers/char/ipmi/ipmi_watchdog.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/char/ipmi/ipmi_watchdog.c b/drivers/char/ipmi/ipmi_watchdog.c index 883b4a341012..0604abdd249a 100644 --- a/drivers/char/ipmi/ipmi_watchdog.c +++ b/drivers/char/ipmi/ipmi_watchdog.c @@ -668,7 +668,7 @@ static int ipmi_heartbeat(void) return rv; } -static struct watchdog_info ident = { +static const struct watchdog_info ident = { .options = 0, /* WDIOF_SETTIMEOUT, */ .firmware_version = 1, .identity = "IPMI" From d134ad2574a1c9b5c34659709769bdb25295fd25 Mon Sep 17 00:00:00 2001 From: Jason Wang Date: Wed, 22 Dec 2021 11:27:07 +0800 Subject: [PATCH 003/370] ipmi: ssif: replace strlcpy with strscpy The strlcpy should not be used because it doesn't limit the source length. So that it will lead some potential bugs. But the strscpy doesn't require reading memory from the src string beyond the specified "count" bytes, and since the return value is easier to error-check than strlcpy()'s. In addition, the implementation is robust to the string changing out from underneath it, unlike the current strlcpy() implementation. Thus, replace strlcpy with strscpy. Signed-off-by: Jason Wang Message-Id: <20211222032707.1912186-1-wangborong@cdjrlc.com> Signed-off-by: Corey Minyard --- drivers/char/ipmi/ipmi_ssif.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/char/ipmi/ipmi_ssif.c b/drivers/char/ipmi/ipmi_ssif.c index 48aab77abebf..ba779f1abb5b 100644 --- a/drivers/char/ipmi/ipmi_ssif.c +++ b/drivers/char/ipmi/ipmi_ssif.c @@ -1354,7 +1354,7 @@ static int ssif_detect(struct i2c_client *client, struct i2c_board_info *info) if (rv) rv = -ENODEV; else - strlcpy(info->type, DEVICE_NAME, I2C_NAME_SIZE); + strscpy(info->type, DEVICE_NAME, I2C_NAME_SIZE); kfree(resp); return rv; } From 93f2ec9e401276fb4ea9903194a5bfcf175f9a2c Mon Sep 17 00:00:00 2001 From: Miquel Raynal Date: Thu, 16 Dec 2021 12:16:27 +0100 Subject: [PATCH 004/370] dt-bindings: mtd: nand-controller: Fix the reg property description The reg property of a NAND device always references the chip-selects. The ready/busy lines are described in the nand-rb property. I believe this was a harmless copy/paste error during the conversion to yaml. Fixes: 212e49693592 ("dt-bindings: mtd: Add YAML schemas for the generic NAND options") Signed-off-by: Miquel Raynal Acked-by: Rob Herring Link: https://lore.kernel.org/linux-mtd/20211216111654.238086-2-miquel.raynal@bootlin.com --- Documentation/devicetree/bindings/mtd/nand-controller.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/mtd/nand-controller.yaml b/Documentation/devicetree/bindings/mtd/nand-controller.yaml index bd217e6f5018..811f03978fc6 100644 --- a/Documentation/devicetree/bindings/mtd/nand-controller.yaml +++ b/Documentation/devicetree/bindings/mtd/nand-controller.yaml @@ -55,7 +55,7 @@ patternProperties: properties: reg: description: - Contains the native Ready/Busy IDs. + Contains the chip-select IDs. nand-ecc-engine: allOf: From 0e7f1b557974ce297e5e4c9d4245720fbb489886 Mon Sep 17 00:00:00 2001 From: Miquel Raynal Date: Thu, 16 Dec 2021 12:16:28 +0100 Subject: [PATCH 005/370] dt-bindings: mtd: nand-controller: Fix a comment in the examples The controller properties should be in the controller 'parent' node, while properties in the children nodes are specific to the NAND *chip*. This error was already present during the yaml conversion. Fixes: 2d472aba15ff ("mtd: nand: document the NAND controller/NAND chip DT representation") Signed-off-by: Miquel Raynal Acked-by: Rob Herring Link: https://lore.kernel.org/linux-mtd/20211216111654.238086-3-miquel.raynal@bootlin.com --- Documentation/devicetree/bindings/mtd/nand-controller.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/mtd/nand-controller.yaml b/Documentation/devicetree/bindings/mtd/nand-controller.yaml index 811f03978fc6..5cd144a9ec99 100644 --- a/Documentation/devicetree/bindings/mtd/nand-controller.yaml +++ b/Documentation/devicetree/bindings/mtd/nand-controller.yaml @@ -184,7 +184,7 @@ examples: nand-use-soft-ecc-engine; nand-ecc-algo = "bch"; - /* controller specific properties */ + /* NAND chip specific properties */ }; nand@1 { From f0dcb5bd56ee7cf7fcca123d5df51b201d1c9e9b Mon Sep 17 00:00:00 2001 From: Miquel Raynal Date: Thu, 16 Dec 2021 12:16:29 +0100 Subject: [PATCH 006/370] dt-bindings: mtd: nand-controller: Harmonize the property types Harmonize the different properties in this file by: * dropping the non-necessary allOf's * always defining the keywords in the following order: - first the "description" (when relevant), - then the "type"/"$ref" and the other generic keywords ("enum", "default", etc). Signed-off-by: Miquel Raynal Reviewed-by: Rob Herring Link: https://lore.kernel.org/linux-mtd/20211216111654.238086-4-miquel.raynal@bootlin.com --- .../bindings/mtd/nand-controller.yaml | 26 +++++++++---------- 1 file changed, 12 insertions(+), 14 deletions(-) diff --git a/Documentation/devicetree/bindings/mtd/nand-controller.yaml b/Documentation/devicetree/bindings/mtd/nand-controller.yaml index 5cd144a9ec99..a4fa65e872a5 100644 --- a/Documentation/devicetree/bindings/mtd/nand-controller.yaml +++ b/Documentation/devicetree/bindings/mtd/nand-controller.yaml @@ -39,8 +39,6 @@ properties: ranges: true cs-gpios: - minItems: 1 - maxItems: 8 description: Array of chip-select available to the controller. The first entries are a 1:1 mapping of the available chip-select on the @@ -48,6 +46,8 @@ properties: chip-select as needed may follow and should be phandles of GPIO lines. 'reg' entries of the NAND chip subnodes become indexes of this array when this property is present. + minItems: 1 + maxItems: 8 patternProperties: "^nand@[a-f0-9]$": @@ -58,8 +58,6 @@ patternProperties: Contains the chip-select IDs. nand-ecc-engine: - allOf: - - $ref: /schemas/types.yaml#/definitions/phandle description: | A phandle on the hardware ECC engine if any. There are basically three possibilities: @@ -69,24 +67,24 @@ patternProperties: case the phandle should reference the node itself. 3/ The ECC engine is external, in this case the phandle should reference the specific ECC engine node. + $ref: /schemas/types.yaml#/definitions/phandle nand-use-soft-ecc-engine: - type: boolean description: Use a software ECC engine. + type: boolean nand-no-ecc-engine: - type: boolean description: Do not use any ECC correction. + type: boolean nand-ecc-placement: - allOf: - - $ref: /schemas/types.yaml#/definitions/string - - enum: [ oob, interleaved ] description: Location of the ECC bytes. This location is unknown by default but can be explicitly set to "oob", if all ECC bytes are known to be stored in the OOB area, or "interleaved" if ECC bytes will be interleaved with regular data in the main area. + $ref: /schemas/types.yaml#/definitions/string + enum: [ oob, interleaved ] nand-ecc-algo: description: @@ -102,7 +100,6 @@ patternProperties: default: 8 nand-on-flash-bbt: - $ref: /schemas/types.yaml#/definitions/flag description: With this property, the OS will search the device for a Bad Block Table (BBT). If not found, it will create one, reserve @@ -111,6 +108,7 @@ patternProperties: few pages of all the blocks will be scanned at boot time to find Bad Block Markers (BBM). These markers will help to build a volatile BBT in RAM. + $ref: /schemas/types.yaml#/definitions/flag nand-ecc-strength: description: @@ -125,7 +123,6 @@ patternProperties: minimum: 1 nand-ecc-maximize: - $ref: /schemas/types.yaml#/definitions/flag description: Whether or not the ECC strength should be maximized. The maximum ECC strength is both controller and chip @@ -134,18 +131,19 @@ patternProperties: constraint into account. This is particularly useful when only the in-band area is used by the upper layers, and you want to make your NAND as reliable as possible. + $ref: /schemas/types.yaml#/definitions/flag nand-is-boot-medium: - $ref: /schemas/types.yaml#/definitions/flag description: Whether or not the NAND chip is a boot medium. Drivers might use this information to select ECC algorithms supported by the boot ROM or similar restrictions. + $ref: /schemas/types.yaml#/definitions/flag nand-rb: - $ref: /schemas/types.yaml#/definitions/uint32-array description: Contains the native Ready/Busy IDs. + $ref: /schemas/types.yaml#/definitions/uint32-array rb-gpios: description: @@ -155,11 +153,11 @@ patternProperties: should be set to GPIOD_ACTIVE_HIGH unless the signal is inverted. secure-regions: - $ref: /schemas/types.yaml#/definitions/uint64-matrix description: Regions in the NAND chip which are protected using a secure element like Trustzone. This property contains the start address and size of the secure regions present. + $ref: /schemas/types.yaml#/definitions/uint64-matrix required: - reg From 751f204a6fe6fd4a856315071c7cc9d8cf9e504d Mon Sep 17 00:00:00 2001 From: Miquel Raynal Date: Thu, 16 Dec 2021 12:16:30 +0100 Subject: [PATCH 007/370] dt-bindings: mtd: nand-chip: Create a NAND chip description Move the NAND chip description out of the NAND controller file. Indeed, a subsequent part of the properties supported by a raw NAND chip are also supported by SPI-NAND chips. So let's create a generic NAND chip description which will be pulled by nand-controller.yaml and later by spi-nand.yaml as well. Signed-off-by: Miquel Raynal Reviewed-by: Rob Herring Link: https://lore.kernel.org/linux-mtd/20211216111654.238086-5-miquel.raynal@bootlin.com --- .../devicetree/bindings/mtd/nand-chip.yaml | 70 +++++++++++++++++++ .../bindings/mtd/nand-controller.yaml | 50 +------------ 2 files changed, 72 insertions(+), 48 deletions(-) create mode 100644 Documentation/devicetree/bindings/mtd/nand-chip.yaml diff --git a/Documentation/devicetree/bindings/mtd/nand-chip.yaml b/Documentation/devicetree/bindings/mtd/nand-chip.yaml new file mode 100644 index 000000000000..97ac3a3fbb52 --- /dev/null +++ b/Documentation/devicetree/bindings/mtd/nand-chip.yaml @@ -0,0 +1,70 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/mtd/nand-chip.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: NAND Chip and NAND Controller Generic Binding + +maintainers: + - Miquel Raynal + +description: | + This file covers the generic description of a NAND chip. It implies that the + bus interface should not be taken into account: both raw NAND devices and + SPI-NAND devices are concerned by this description. + +properties: + reg: + description: + Contains the chip-select IDs. + + nand-ecc-engine: + description: | + A phandle on the hardware ECC engine if any. There are + basically three possibilities: + 1/ The ECC engine is part of the NAND controller, in this + case the phandle should reference the parent node. + 2/ The ECC engine is part of the NAND part (on-die), in this + case the phandle should reference the node itself. + 3/ The ECC engine is external, in this case the phandle should + reference the specific ECC engine node. + $ref: /schemas/types.yaml#/definitions/phandle + + nand-use-soft-ecc-engine: + description: Use a software ECC engine. + type: boolean + + nand-no-ecc-engine: + description: Do not use any ECC correction. + type: boolean + + nand-ecc-algo: + description: + Desired ECC algorithm. + $ref: /schemas/types.yaml#/definitions/string + enum: [hamming, bch, rs] + + nand-ecc-strength: + description: + Maximum number of bits that can be corrected per ECC step. + $ref: /schemas/types.yaml#/definitions/uint32 + minimum: 1 + + nand-ecc-step-size: + description: + Number of data bytes covered by a single ECC step. + $ref: /schemas/types.yaml#/definitions/uint32 + minimum: 1 + + secure-regions: + description: + Regions in the NAND chip which are protected using a secure element + like Trustzone. This property contains the start address and size of + the secure regions present. + $ref: /schemas/types.yaml#/definitions/uint64-matrix + +required: + - reg + +additionalProperties: true diff --git a/Documentation/devicetree/bindings/mtd/nand-controller.yaml b/Documentation/devicetree/bindings/mtd/nand-controller.yaml index a4fa65e872a5..33855eb48a79 100644 --- a/Documentation/devicetree/bindings/mtd/nand-controller.yaml +++ b/Documentation/devicetree/bindings/mtd/nand-controller.yaml @@ -52,31 +52,13 @@ properties: patternProperties: "^nand@[a-f0-9]$": type: object + $ref: "nand-chip.yaml#" + properties: reg: description: Contains the chip-select IDs. - nand-ecc-engine: - description: | - A phandle on the hardware ECC engine if any. There are - basically three possibilities: - 1/ The ECC engine is part of the NAND controller, in this - case the phandle should reference the parent node. - 2/ The ECC engine is part of the NAND part (on-die), in this - case the phandle should reference the node itself. - 3/ The ECC engine is external, in this case the phandle should - reference the specific ECC engine node. - $ref: /schemas/types.yaml#/definitions/phandle - - nand-use-soft-ecc-engine: - description: Use a software ECC engine. - type: boolean - - nand-no-ecc-engine: - description: Do not use any ECC correction. - type: boolean - nand-ecc-placement: description: Location of the ECC bytes. This location is unknown by default @@ -86,12 +68,6 @@ patternProperties: $ref: /schemas/types.yaml#/definitions/string enum: [ oob, interleaved ] - nand-ecc-algo: - description: - Desired ECC algorithm. - $ref: /schemas/types.yaml#/definitions/string - enum: [hamming, bch, rs] - nand-bus-width: description: Bus width to the NAND chip @@ -110,18 +86,6 @@ patternProperties: build a volatile BBT in RAM. $ref: /schemas/types.yaml#/definitions/flag - nand-ecc-strength: - description: - Maximum number of bits that can be corrected per ECC step. - $ref: /schemas/types.yaml#/definitions/uint32 - minimum: 1 - - nand-ecc-step-size: - description: - Number of data bytes covered by a single ECC step. - $ref: /schemas/types.yaml#/definitions/uint32 - minimum: 1 - nand-ecc-maximize: description: Whether or not the ECC strength should be maximized. The @@ -152,13 +116,6 @@ patternProperties: Ready/Busy pins. Active state refers to the NAND ready state and should be set to GPIOD_ACTIVE_HIGH unless the signal is inverted. - secure-regions: - description: - Regions in the NAND chip which are protected using a secure element - like Trustzone. This property contains the start address and size of - the secure regions present. - $ref: /schemas/types.yaml#/definitions/uint64-matrix - required: - reg @@ -179,9 +136,6 @@ examples: nand@0 { reg = <0>; /* Native CS */ - nand-use-soft-ecc-engine; - nand-ecc-algo = "bch"; - /* NAND chip specific properties */ }; From 3a0d6d0fb14df501c90b629c04d2c8c60615b3f3 Mon Sep 17 00:00:00 2001 From: Miquel Raynal Date: Thu, 16 Dec 2021 12:16:31 +0100 Subject: [PATCH 008/370] dt-bindings: mtd: spi-nand: Convert spi-nand description file to yaml Let's get rid of spi-nand.txt by converting it to yaml schema. While at converting this file, let's actually pull all the generic properties from nand-chip.yaml which might apply to a SPI-NAND chip. Signed-off-by: Miquel Raynal Reviewed-by: Rob Herring Link: https://lore.kernel.org/linux-mtd/20211216111654.238086-6-miquel.raynal@bootlin.com --- .../devicetree/bindings/mtd/spi-nand.txt | 5 ---- .../devicetree/bindings/mtd/spi-nand.yaml | 27 +++++++++++++++++++ 2 files changed, 27 insertions(+), 5 deletions(-) delete mode 100644 Documentation/devicetree/bindings/mtd/spi-nand.txt create mode 100644 Documentation/devicetree/bindings/mtd/spi-nand.yaml diff --git a/Documentation/devicetree/bindings/mtd/spi-nand.txt b/Documentation/devicetree/bindings/mtd/spi-nand.txt deleted file mode 100644 index 8b51f3b6d55c..000000000000 --- a/Documentation/devicetree/bindings/mtd/spi-nand.txt +++ /dev/null @@ -1,5 +0,0 @@ -SPI NAND flash - -Required properties: -- compatible: should be "spi-nand" -- reg: should encode the chip-select line used to access the NAND chip diff --git a/Documentation/devicetree/bindings/mtd/spi-nand.yaml b/Documentation/devicetree/bindings/mtd/spi-nand.yaml new file mode 100644 index 000000000000..431faac518a4 --- /dev/null +++ b/Documentation/devicetree/bindings/mtd/spi-nand.yaml @@ -0,0 +1,27 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/mtd/spi-nand.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: SPI-NAND flash device tree bindings + +maintainers: + - Miquel Raynal + +allOf: + - $ref: "nand-chip.yaml#" + +properties: + compatible: + const: spi-nand + + reg: + description: Encode the chip-select line on the SPI bus + maxItems: 1 + +required: + - compatible + - reg + +unevaluatedProperties: false From 390925f60a4bbcf32fa15f819fd6ec123dd26844 Mon Sep 17 00:00:00 2001 From: Miquel Raynal Date: Thu, 16 Dec 2021 12:16:32 +0100 Subject: [PATCH 009/370] dt-bindings: vendor-prefixes: Clarify Macronix prefix When looking at compatible prefixes, Macronix is sometimes referred as "mxicy": - mxicy,mx25r1635f - mxicy,mx25u6435f - mxicy,mx25v8035f - mxicy,mx25f0a-spi and sometimes as "mxic": - mxic,multi-itfc-v009-nand-controller - mxic,enable-randomizer-otp The oldest prefix that is also the one preferred by Macronix engineers is "mxicy", so document the other one and mark it deprecated. Signed-off-by: Miquel Raynal Reviewed-by: Rob Herring Link: https://lore.kernel.org/linux-mtd/20211216111654.238086-7-miquel.raynal@bootlin.com --- Documentation/devicetree/bindings/vendor-prefixes.yaml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Documentation/devicetree/bindings/vendor-prefixes.yaml b/Documentation/devicetree/bindings/vendor-prefixes.yaml index 294093d45a23..a8ef035152d0 100644 --- a/Documentation/devicetree/bindings/vendor-prefixes.yaml +++ b/Documentation/devicetree/bindings/vendor-prefixes.yaml @@ -802,6 +802,9 @@ patternProperties: description: Mundo Reader S.L. "^murata,.*": description: Murata Manufacturing Co., Ltd. + "^mxic,.*": + description: Macronix International Co., Ltd. + deprecated: true "^mxicy,.*": description: Macronix International Co., Ltd. "^myir,.*": From 90c204d3195a795f77f5bce767e311dd1c59ca17 Mon Sep 17 00:00:00 2001 From: Miquel Raynal Date: Thu, 16 Dec 2021 12:16:33 +0100 Subject: [PATCH 010/370] dt-bindings: spi: mxic: The interrupt property is not mandatory The interrupt property is not mandatory at all, this property should not be part of the required properties list, so move it into the optional properties list. Fixes: 326e5c8d4a87 ("dt-binding: spi: Document Macronix controller bindings") Signed-off-by: Miquel Raynal Reviewed-by: Rob Herring Reviewed-by: Mark Brown Link: https://lore.kernel.org/linux-mtd/20211216111654.238086-8-miquel.raynal@bootlin.com --- Documentation/devicetree/bindings/spi/spi-mxic.txt | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/spi/spi-mxic.txt b/Documentation/devicetree/bindings/spi/spi-mxic.txt index 529f2dab2648..7bcbb229b78b 100644 --- a/Documentation/devicetree/bindings/spi/spi-mxic.txt +++ b/Documentation/devicetree/bindings/spi/spi-mxic.txt @@ -8,11 +8,13 @@ Required properties: - reg: should contain 2 entries, one for the registers and one for the direct mapping area - reg-names: should contain "regs" and "dirmap" -- interrupts: interrupt line connected to the SPI controller - clock-names: should contain "ps_clk", "send_clk" and "send_dly_clk" - clocks: should contain 3 entries for the "ps_clk", "send_clk" and "send_dly_clk" clocks +Optional properties: +- interrupts: interrupt line connected to the SPI controller + Example: spi@43c30000 { From 295fca79a8ee8e140f61e1b00e2cd21bf0fd9464 Mon Sep 17 00:00:00 2001 From: Miquel Raynal Date: Thu, 16 Dec 2021 12:16:34 +0100 Subject: [PATCH 011/370] dt-bindings: spi: mxic: Convert to yaml Straightforward conversion from regular text to yaml schema of the Macronix SPI controller DT bindings. Signed-off-by: Miquel Raynal Reviewed-by: Rob Herring Reviewed-by: Mark Brown Link: https://lore.kernel.org/linux-mtd/20211216111654.238086-9-miquel.raynal@bootlin.com --- .../bindings/spi/mxicy,mx25f0a-spi.yaml | 60 +++++++++++++++++++ .../devicetree/bindings/spi/spi-mxic.txt | 36 ----------- 2 files changed, 60 insertions(+), 36 deletions(-) create mode 100644 Documentation/devicetree/bindings/spi/mxicy,mx25f0a-spi.yaml delete mode 100644 Documentation/devicetree/bindings/spi/spi-mxic.txt diff --git a/Documentation/devicetree/bindings/spi/mxicy,mx25f0a-spi.yaml b/Documentation/devicetree/bindings/spi/mxicy,mx25f0a-spi.yaml new file mode 100644 index 000000000000..f20d100b4a68 --- /dev/null +++ b/Documentation/devicetree/bindings/spi/mxicy,mx25f0a-spi.yaml @@ -0,0 +1,60 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/spi/mxicy,mx25f0a-spi.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Macronix SPI controller device tree bindings + +maintainers: + - Miquel Raynal + +allOf: + - $ref: "spi-controller.yaml#" + +properties: + compatible: + const: mxicy,mx25f0a-spi + + reg: + minItems: 2 + maxItems: 2 + + reg-names: + items: + - const: regs + - const: dirmap + + interrupts: + maxItems: 1 + + clocks: + minItems: 3 + maxItems: 3 + + clock-names: + items: + - const: send_clk + - const: send_dly_clk + - const: ps_clk + +required: + - compatible + - reg + - reg-names + - clocks + - clock-names + +unevaluatedProperties: false + +examples: + - | + spi@43c30000 { + compatible = "mxicy,mx25f0a-spi"; + reg = <0x43c30000 0x10000>, <0xa0000000 0x20000000>; + reg-names = "regs", "dirmap"; + clocks = <&clkwizard 0>, <&clkwizard 1>, <&clkc 18>; + clock-names = "send_clk", "send_dly_clk", "ps_clk"; + #address-cells = <1>; + #size-cells = <0>; + }; diff --git a/Documentation/devicetree/bindings/spi/spi-mxic.txt b/Documentation/devicetree/bindings/spi/spi-mxic.txt deleted file mode 100644 index 7bcbb229b78b..000000000000 --- a/Documentation/devicetree/bindings/spi/spi-mxic.txt +++ /dev/null @@ -1,36 +0,0 @@ -Macronix SPI controller Device Tree Bindings --------------------------------------------- - -Required properties: -- compatible: should be "mxicy,mx25f0a-spi" -- #address-cells: should be 1 -- #size-cells: should be 0 -- reg: should contain 2 entries, one for the registers and one for the direct - mapping area -- reg-names: should contain "regs" and "dirmap" -- clock-names: should contain "ps_clk", "send_clk" and "send_dly_clk" -- clocks: should contain 3 entries for the "ps_clk", "send_clk" and - "send_dly_clk" clocks - -Optional properties: -- interrupts: interrupt line connected to the SPI controller - -Example: - - spi@43c30000 { - compatible = "mxicy,mx25f0a-spi"; - reg = <0x43c30000 0x10000>, <0xa0000000 0x20000000>; - reg-names = "regs", "dirmap"; - clocks = <&clkwizard 0>, <&clkwizard 1>, <&clkc 18>; - clock-names = "send_clk", "send_dly_clk", "ps_clk"; - #address-cells = <1>; - #size-cells = <0>; - - flash@0 { - compatible = "jedec,spi-nor"; - reg = <0>; - spi-max-frequency = <25000000>; - spi-tx-bus-width = <4>; - spi-rx-bus-width = <4>; - }; - }; From 475e826bad8c7b65d4157259c9906fcf86834f14 Mon Sep 17 00:00:00 2001 From: Miquel Raynal Date: Thu, 16 Dec 2021 12:16:35 +0100 Subject: [PATCH 012/370] dt-bindings: spi: mxic: Document the nand-ecc-engine property This SPI controller supports interacting with an external ECC engine. The nand-ecc-engine property already exist in the NAND world but also applies to SPI controller nodes which have external correction capabilities like Macronix's. Signed-off-by: Miquel Raynal Reviewed-by: Rob Herring Reviewed-by: Mark Brown Link: https://lore.kernel.org/linux-mtd/20211216111654.238086-10-miquel.raynal@bootlin.com --- Documentation/devicetree/bindings/spi/mxicy,mx25f0a-spi.yaml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Documentation/devicetree/bindings/spi/mxicy,mx25f0a-spi.yaml b/Documentation/devicetree/bindings/spi/mxicy,mx25f0a-spi.yaml index f20d100b4a68..9202c44b4478 100644 --- a/Documentation/devicetree/bindings/spi/mxicy,mx25f0a-spi.yaml +++ b/Documentation/devicetree/bindings/spi/mxicy,mx25f0a-spi.yaml @@ -38,6 +38,11 @@ properties: - const: send_dly_clk - const: ps_clk + nand-ecc-engine: + description: NAND ECC engine used by the SPI controller in order to perform + on-the-fly correction when using a SPI-NAND memory. + $ref: /schemas/types.yaml#/definitions/phandle + required: - compatible - reg From 3e2bcda631d4e612a8cd69613a15fae2f9941857 Mon Sep 17 00:00:00 2001 From: Miquel Raynal Date: Thu, 16 Dec 2021 12:16:36 +0100 Subject: [PATCH 013/370] dt-bindings: mtd: Describe Macronix NAND ECC engine Describe Macronix NAND ECC engine. This engine may be used as an external engine or can be pipelined with either a raw NAND controller or a SPI controller. Both hardware designs with a SPI controller are shown in the examples. Signed-off-by: Miquel Raynal Reviewed-by: Rob Herring Link: https://lore.kernel.org/linux-mtd/20211216111654.238086-11-miquel.raynal@bootlin.com --- .../bindings/mtd/mxicy,nand-ecc-engine.yaml | 77 +++++++++++++++++++ 1 file changed, 77 insertions(+) create mode 100644 Documentation/devicetree/bindings/mtd/mxicy,nand-ecc-engine.yaml diff --git a/Documentation/devicetree/bindings/mtd/mxicy,nand-ecc-engine.yaml b/Documentation/devicetree/bindings/mtd/mxicy,nand-ecc-engine.yaml new file mode 100644 index 000000000000..804479999ccb --- /dev/null +++ b/Documentation/devicetree/bindings/mtd/mxicy,nand-ecc-engine.yaml @@ -0,0 +1,77 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/mtd/mxicy,nand-ecc-engine.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Macronix NAND ECC engine device tree bindings + +maintainers: + - Miquel Raynal + +properties: + compatible: + const: mxicy,nand-ecc-engine-rev3 + + reg: + maxItems: 1 + + clocks: + maxItems: 1 + + interrupts: + maxItems: 1 + +required: + - compatible + - reg + +additionalProperties: false + +examples: + - | + /* External configuration */ + spi_controller0: spi@43c30000 { + compatible = "mxicy,mx25f0a-spi"; + reg = <0x43c30000 0x10000>, <0xa0000000 0x4000000>; + reg-names = "regs", "dirmap"; + clocks = <&clkwizard 0>, <&clkwizard 1>, <&clkc 15>; + clock-names = "send_clk", "send_dly_clk", "ps_clk"; + #address-cells = <1>; + #size-cells = <0>; + + flash@0 { + compatible = "spi-nand"; + reg = <0>; + nand-ecc-engine = <&ecc_engine0>; + }; + }; + + ecc_engine0: ecc@43c40000 { + compatible = "mxicy,nand-ecc-engine-rev3"; + reg = <0x43c40000 0x10000>; + }; + + - | + /* Pipelined configuration */ + spi_controller1: spi@43c30000 { + compatible = "mxicy,mx25f0a-spi"; + reg = <0x43c30000 0x10000>, <0xa0000000 0x4000000>; + reg-names = "regs", "dirmap"; + clocks = <&clkwizard 0>, <&clkwizard 1>, <&clkc 15>; + clock-names = "send_clk", "send_dly_clk", "ps_clk"; + #address-cells = <1>; + #size-cells = <0>; + nand-ecc-engine = <&ecc_engine1>; + + flash@0 { + compatible = "spi-nand"; + reg = <0>; + nand-ecc-engine = <&spi_controller1>; + }; + }; + + ecc_engine1: ecc@43c40000 { + compatible = "mxicy,nand-ecc-engine-rev3"; + reg = <0x43c40000 0x10000>; + }; From 1d46963d453770ac68d954e61f094eba6e42744f Mon Sep 17 00:00:00 2001 From: Mason Yang Date: Thu, 16 Dec 2021 12:16:37 +0100 Subject: [PATCH 014/370] mtd: spinand: macronix: Use random program load Macronix SPI-NAND chips might benefit from an external ECC engine. Such an engine might need to access random columns, thus needing to use random commands (0x84 instead of 0x02). Signed-off-by: Mason Yang Signed-off-by: Miquel Raynal Link: https://lore.kernel.org/linux-mtd/20211216111654.238086-12-miquel.raynal@bootlin.com --- drivers/mtd/nand/spi/macronix.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/mtd/nand/spi/macronix.c b/drivers/mtd/nand/spi/macronix.c index 3f31f1381a62..dce835132a1e 100644 --- a/drivers/mtd/nand/spi/macronix.c +++ b/drivers/mtd/nand/spi/macronix.c @@ -20,7 +20,7 @@ static SPINAND_OP_VARIANTS(read_cache_variants, static SPINAND_OP_VARIANTS(write_cache_variants, SPINAND_PROG_LOAD_X4(true, 0, NULL, 0), - SPINAND_PROG_LOAD(true, 0, NULL, 0)); + SPINAND_PROG_LOAD(false, 0, NULL, 0)); static SPINAND_OP_VARIANTS(update_cache_variants, SPINAND_PROG_LOAD_X4(false, 0, NULL, 0), From 96489c1c0b53131b0e1ec33e2060538379ad6152 Mon Sep 17 00:00:00 2001 From: Miquel Raynal Date: Thu, 16 Dec 2021 12:16:38 +0100 Subject: [PATCH 015/370] mtd: nand: ecc: Add infrastructure to support hardware engines Add the necessary helpers to register/unregister hardware ECC engines that will be called from ECC engine drivers. Also add helpers to get the right engine from the user perspective. Keep a reference of the in use ECC engine in order to prevent modules to be unloaded. Put the reference when the engine gets retired. A static list of hardware (only) ECC engines is setup to keep track of the registered engines. Signed-off-by: Miquel Raynal Link: https://lore.kernel.org/linux-mtd/20211216111654.238086-13-miquel.raynal@bootlin.com --- drivers/mtd/nand/core.c | 10 +++-- drivers/mtd/nand/ecc.c | 88 ++++++++++++++++++++++++++++++++++++++++ include/linux/mtd/nand.h | 28 +++++++++++++ 3 files changed, 123 insertions(+), 3 deletions(-) diff --git a/drivers/mtd/nand/core.c b/drivers/mtd/nand/core.c index 416947f28b67..ff34e3fd84c0 100644 --- a/drivers/mtd/nand/core.c +++ b/drivers/mtd/nand/core.c @@ -235,7 +235,9 @@ static int nanddev_get_ecc_engine(struct nand_device *nand) nand->ecc.engine = nand_ecc_get_on_die_hw_engine(nand); break; case NAND_ECC_ENGINE_TYPE_ON_HOST: - pr_err("On-host hardware ECC engines not supported yet\n"); + nand->ecc.engine = nand_ecc_get_on_host_hw_engine(nand); + if (PTR_ERR(nand->ecc.engine) == -EPROBE_DEFER) + return -EPROBE_DEFER; break; default: pr_err("Missing ECC engine type\n"); @@ -255,7 +257,7 @@ static int nanddev_put_ecc_engine(struct nand_device *nand) { switch (nand->ecc.ctx.conf.engine_type) { case NAND_ECC_ENGINE_TYPE_ON_HOST: - pr_err("On-host hardware ECC engines not supported yet\n"); + nand_ecc_put_on_host_hw_engine(nand); break; case NAND_ECC_ENGINE_TYPE_NONE: case NAND_ECC_ENGINE_TYPE_SOFT: @@ -300,7 +302,9 @@ int nanddev_ecc_engine_init(struct nand_device *nand) /* Look for the ECC engine to use */ ret = nanddev_get_ecc_engine(nand); if (ret) { - pr_err("No ECC engine found\n"); + if (ret != -EPROBE_DEFER) + pr_err("No ECC engine found\n"); + return ret; } diff --git a/drivers/mtd/nand/ecc.c b/drivers/mtd/nand/ecc.c index 6c43dfda01d4..078f5ec38de3 100644 --- a/drivers/mtd/nand/ecc.c +++ b/drivers/mtd/nand/ecc.c @@ -96,6 +96,12 @@ #include #include #include +#include +#include +#include + +static LIST_HEAD(on_host_hw_engines); +static DEFINE_MUTEX(on_host_hw_engines_mutex); /** * nand_ecc_init_ctx - Init the ECC engine context @@ -611,6 +617,88 @@ struct nand_ecc_engine *nand_ecc_get_on_die_hw_engine(struct nand_device *nand) } EXPORT_SYMBOL(nand_ecc_get_on_die_hw_engine); +int nand_ecc_register_on_host_hw_engine(struct nand_ecc_engine *engine) +{ + struct nand_ecc_engine *item; + + if (!engine) + return -EINVAL; + + /* Prevent multiple registrations of one engine */ + list_for_each_entry(item, &on_host_hw_engines, node) + if (item == engine) + return 0; + + mutex_lock(&on_host_hw_engines_mutex); + list_add_tail(&engine->node, &on_host_hw_engines); + mutex_unlock(&on_host_hw_engines_mutex); + + return 0; +} +EXPORT_SYMBOL(nand_ecc_register_on_host_hw_engine); + +int nand_ecc_unregister_on_host_hw_engine(struct nand_ecc_engine *engine) +{ + if (!engine) + return -EINVAL; + + mutex_lock(&on_host_hw_engines_mutex); + list_del(&engine->node); + mutex_unlock(&on_host_hw_engines_mutex); + + return 0; +} +EXPORT_SYMBOL(nand_ecc_unregister_on_host_hw_engine); + +static struct nand_ecc_engine *nand_ecc_match_on_host_hw_engine(struct device *dev) +{ + struct nand_ecc_engine *item; + + list_for_each_entry(item, &on_host_hw_engines, node) + if (item->dev == dev) + return item; + + return NULL; +} + +struct nand_ecc_engine *nand_ecc_get_on_host_hw_engine(struct nand_device *nand) +{ + struct nand_ecc_engine *engine = NULL; + struct device *dev = &nand->mtd.dev; + struct platform_device *pdev; + struct device_node *np; + + if (list_empty(&on_host_hw_engines)) + return NULL; + + /* Check for an explicit nand-ecc-engine property */ + np = of_parse_phandle(dev->of_node, "nand-ecc-engine", 0); + if (np) { + pdev = of_find_device_by_node(np); + if (!pdev) + return ERR_PTR(-EPROBE_DEFER); + + engine = nand_ecc_match_on_host_hw_engine(&pdev->dev); + platform_device_put(pdev); + of_node_put(np); + + if (!engine) + return ERR_PTR(-EPROBE_DEFER); + } + + if (engine) + get_device(engine->dev); + + return engine; +} +EXPORT_SYMBOL(nand_ecc_get_on_host_hw_engine); + +void nand_ecc_put_on_host_hw_engine(struct nand_device *nand) +{ + put_device(nand->ecc.engine->dev); +} +EXPORT_SYMBOL(nand_ecc_put_on_host_hw_engine); + MODULE_LICENSE("GPL"); MODULE_AUTHOR("Miquel Raynal "); MODULE_DESCRIPTION("Generic ECC engine"); diff --git a/include/linux/mtd/nand.h b/include/linux/mtd/nand.h index 32fc7edf65b3..4ddd20fe9c9e 100644 --- a/include/linux/mtd/nand.h +++ b/include/linux/mtd/nand.h @@ -263,12 +263,36 @@ struct nand_ecc_engine_ops { struct nand_page_io_req *req); }; +/** + * enum nand_ecc_engine_integration - How the NAND ECC engine is integrated + * @NAND_ECC_ENGINE_INTEGRATION_INVALID: Invalid value + * @NAND_ECC_ENGINE_INTEGRATION_PIPELINED: Pipelined engine, performs on-the-fly + * correction, does not need to copy + * data around + * @NAND_ECC_ENGINE_INTEGRATION_EXTERNAL: External engine, needs to bring the + * data into its own area before use + */ +enum nand_ecc_engine_integration { + NAND_ECC_ENGINE_INTEGRATION_INVALID, + NAND_ECC_ENGINE_INTEGRATION_PIPELINED, + NAND_ECC_ENGINE_INTEGRATION_EXTERNAL, +}; + /** * struct nand_ecc_engine - ECC engine abstraction for NAND devices + * @dev: Host device + * @node: Private field for registration time * @ops: ECC engine operations + * @integration: How the engine is integrated with the host + * (only relevant on %NAND_ECC_ENGINE_TYPE_ON_HOST engines) + * @priv: Private data */ struct nand_ecc_engine { + struct device *dev; + struct list_head node; struct nand_ecc_engine_ops *ops; + enum nand_ecc_engine_integration integration; + void *priv; }; void of_get_nand_ecc_user_config(struct nand_device *nand); @@ -279,8 +303,12 @@ int nand_ecc_prepare_io_req(struct nand_device *nand, int nand_ecc_finish_io_req(struct nand_device *nand, struct nand_page_io_req *req); bool nand_ecc_is_strong_enough(struct nand_device *nand); +int nand_ecc_register_on_host_hw_engine(struct nand_ecc_engine *engine); +int nand_ecc_unregister_on_host_hw_engine(struct nand_ecc_engine *engine); struct nand_ecc_engine *nand_ecc_get_sw_engine(struct nand_device *nand); struct nand_ecc_engine *nand_ecc_get_on_die_hw_engine(struct nand_device *nand); +struct nand_ecc_engine *nand_ecc_get_on_host_hw_engine(struct nand_device *nand); +void nand_ecc_put_on_host_hw_engine(struct nand_device *nand); #if IS_ENABLED(CONFIG_MTD_NAND_ECC_SW_HAMMING) struct nand_ecc_engine *nand_ecc_sw_hamming_get_engine(void); From cda32a618debd3fad8e42757b198719ae180f8f4 Mon Sep 17 00:00:00 2001 From: Miquel Raynal Date: Thu, 16 Dec 2021 12:16:39 +0100 Subject: [PATCH 016/370] mtd: nand: Add a new helper to retrieve the ECC context Introduce nand_to_ecc_ctx() which will allow to easily jump to the private pointer of an ECC context given a NAND device. This is very handy, from the prepare or finish ECC hook, to get the internal context out of the NAND device object. Signed-off-by: Miquel Raynal Link: https://lore.kernel.org/linux-mtd/20211216111654.238086-14-miquel.raynal@bootlin.com --- include/linux/mtd/nand.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/include/linux/mtd/nand.h b/include/linux/mtd/nand.h index 4ddd20fe9c9e..b617efa0a881 100644 --- a/include/linux/mtd/nand.h +++ b/include/linux/mtd/nand.h @@ -990,6 +990,11 @@ int nanddev_markbad(struct nand_device *nand, const struct nand_pos *pos); int nanddev_ecc_engine_init(struct nand_device *nand); void nanddev_ecc_engine_cleanup(struct nand_device *nand); +static inline void *nand_to_ecc_ctx(struct nand_device *nand) +{ + return nand->ecc.ctx.priv; +} + /* BBT related functions */ enum nand_bbt_block_status { NAND_BBT_BLOCK_STATUS_UNKNOWN, From 066aef69079415b3c873c7fee1c1022c511c4045 Mon Sep 17 00:00:00 2001 From: Stanislav Jakubek Date: Sun, 9 Jan 2022 18:03:21 +0100 Subject: [PATCH 017/370] dt-bindings: serial: Convert rda,8810pl-uart to YAML Convert RDA Micro UART bindings to DT schema format. Signed-off-by: Stanislav Jakubek Signed-off-by: Rob Herring Link: https://lore.kernel.org/r/20220109170321.GA12989@standask-GA-A55M-S2HP --- .../bindings/serial/rda,8810pl-uart.txt | 17 ------- .../bindings/serial/rda,8810pl-uart.yaml | 46 +++++++++++++++++++ MAINTAINERS | 2 +- 3 files changed, 47 insertions(+), 18 deletions(-) delete mode 100644 Documentation/devicetree/bindings/serial/rda,8810pl-uart.txt create mode 100644 Documentation/devicetree/bindings/serial/rda,8810pl-uart.yaml diff --git a/Documentation/devicetree/bindings/serial/rda,8810pl-uart.txt b/Documentation/devicetree/bindings/serial/rda,8810pl-uart.txt deleted file mode 100644 index a08df97a69e6..000000000000 --- a/Documentation/devicetree/bindings/serial/rda,8810pl-uart.txt +++ /dev/null @@ -1,17 +0,0 @@ -RDA Micro UART - -Required properties: -- compatible : "rda,8810pl-uart" for RDA8810PL SoCs. -- reg : Offset and length of the register set for the device. -- interrupts : Should contain UART interrupt. -- clocks : Phandle to the input clock. - - -Example: - - uart2: serial@20a90000 { - compatible = "rda,8810pl-uart"; - reg = <0x20a90000 0x1000>; - interrupts = <11 IRQ_TYPE_LEVEL_HIGH>; - clocks = <&uart_clk>; - }; diff --git a/Documentation/devicetree/bindings/serial/rda,8810pl-uart.yaml b/Documentation/devicetree/bindings/serial/rda,8810pl-uart.yaml new file mode 100644 index 000000000000..5f4ed8221270 --- /dev/null +++ b/Documentation/devicetree/bindings/serial/rda,8810pl-uart.yaml @@ -0,0 +1,46 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/serial/rda,8810pl-uart.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: RDA Micro UART Interface + +maintainers: + - Manivannan Sadhasivam + +allOf: + - $ref: serial.yaml# + +properties: + compatible: + const: rda,8810pl-uart + + reg: + maxItems: 1 + + interrupts: + maxItems: 1 + + clocks: + maxItems: 1 + +required: + - compatible + - reg + - interrupts + - clocks + +unevaluatedProperties: false + +examples: + - | + #include + + uart3: serial@20a90000 { + compatible = "rda,8810pl-uart"; + reg = <0x20a90000 0x1000>; + interrupts = <11 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&uart_clk>; + }; +... diff --git a/MAINTAINERS b/MAINTAINERS index ea3e6c914384..1dbe55190d28 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -2503,7 +2503,7 @@ S: Maintained F: Documentation/devicetree/bindings/arm/rda.yaml F: Documentation/devicetree/bindings/gpio/gpio-rda.yaml F: Documentation/devicetree/bindings/interrupt-controller/rda,8810pl-intc.txt -F: Documentation/devicetree/bindings/serial/rda,8810pl-uart.txt +F: Documentation/devicetree/bindings/serial/rda,8810pl-uart.yaml F: Documentation/devicetree/bindings/timer/rda,8810pl-timer.txt F: arch/arm/boot/dts/rda8810pl-* F: drivers/clocksource/timer-rda.c From 92649241a25aff95d3132c2a90292c19c887071d Mon Sep 17 00:00:00 2001 From: David Heidelberg Date: Sun, 9 Jan 2022 18:18:13 +0100 Subject: [PATCH 018/370] dt-bindings: msm/mdp4: convert to yaml format Convert mdp4 binding into yaml format. Signed-off-by: David Heidelberg Signed-off-by: Rob Herring Link: https://lore.kernel.org/r/20220109171814.16103-1-david@ixit.cz --- .../devicetree/bindings/display/msm/mdp4.txt | 114 ---------------- .../devicetree/bindings/display/msm/mdp4.yaml | 124 ++++++++++++++++++ 2 files changed, 124 insertions(+), 114 deletions(-) delete mode 100644 Documentation/devicetree/bindings/display/msm/mdp4.txt create mode 100644 Documentation/devicetree/bindings/display/msm/mdp4.yaml diff --git a/Documentation/devicetree/bindings/display/msm/mdp4.txt b/Documentation/devicetree/bindings/display/msm/mdp4.txt deleted file mode 100644 index b07eeb38f709..000000000000 --- a/Documentation/devicetree/bindings/display/msm/mdp4.txt +++ /dev/null @@ -1,114 +0,0 @@ -Qualcomm adreno/snapdragon MDP4 display controller - -Description: - -This is the bindings documentation for the MDP4 display controller found in -SoCs like MSM8960, APQ8064 and MSM8660. - -Required properties: -- compatible: - * "qcom,mdp4" - mdp4 -- reg: Physical base address and length of the controller's registers. -- interrupts: The interrupt signal from the display controller. -- clocks: device clocks - See ../clocks/clock-bindings.txt for details. -- clock-names: the following clocks are required. - * "core_clk" - * "iface_clk" - * "bus_clk" - * "lut_clk" - * "hdmi_clk" - * "tv_clk" -- ports: contains the list of output ports from MDP. These connect to interfaces - that are external to the MDP hardware, such as HDMI, DSI, EDP etc (LVDS is a - special case since it is a part of the MDP block itself). - - Each output port contains an endpoint that describes how it is connected to an - external interface. These are described by the standard properties documented - here: - Documentation/devicetree/bindings/graph.txt - Documentation/devicetree/bindings/media/video-interfaces.txt - - The output port mappings are: - Port 0 -> LCDC/LVDS - Port 1 -> DSI1 Cmd/Video - Port 2 -> DSI2 Cmd/Video - Port 3 -> DTV - -Optional properties: -- clock-names: the following clocks are optional: - * "lut_clk" -- qcom,lcdc-align-lsb: Boolean value indicating that LSB alignment should be - used for LCDC. This is only valid for 18bpp panels. - -Example: - -/ { - ... - - hdmi: hdmi@4a00000 { - ... - ports { - ... - port@0 { - reg = <0>; - hdmi_in: endpoint { - remote-endpoint = <&mdp_dtv_out>; - }; - }; - ... - }; - ... - }; - - ... - - mdp: mdp@5100000 { - compatible = "qcom,mdp4"; - reg = <0x05100000 0xf0000>; - interrupts = ; - clock-names = - "core_clk", - "iface_clk", - "lut_clk", - "hdmi_clk", - "tv_clk"; - clocks = - <&mmcc MDP_CLK>, - <&mmcc MDP_AHB_CLK>, - <&mmcc MDP_AXI_CLK>, - <&mmcc MDP_LUT_CLK>, - <&mmcc HDMI_TV_CLK>, - <&mmcc MDP_TV_CLK>; - - ports { - #address-cells = <1>; - #size-cells = <0>; - - port@0 { - reg = <0>; - mdp_lvds_out: endpoint { - }; - }; - - port@1 { - reg = <1>; - mdp_dsi1_out: endpoint { - }; - }; - - port@2 { - reg = <2>; - mdp_dsi2_out: endpoint { - }; - }; - - port@3 { - reg = <3>; - mdp_dtv_out: endpoint { - remote-endpoint = <&hdmi_in>; - }; - }; - }; - }; -}; diff --git a/Documentation/devicetree/bindings/display/msm/mdp4.yaml b/Documentation/devicetree/bindings/display/msm/mdp4.yaml new file mode 100644 index 000000000000..f63f60fea27c --- /dev/null +++ b/Documentation/devicetree/bindings/display/msm/mdp4.yaml @@ -0,0 +1,124 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: "http://devicetree.org/schemas/display/msm/mdp4.yaml#" +$schema: "http://devicetree.org/meta-schemas/core.yaml#" + +title: Qualcomm Adreno/Snapdragon MDP4 display controller + +description: > + MDP4 display controller found in SoCs like MSM8960, APQ8064 and MSM8660. + +maintainers: + - Rob Clark + +properties: + compatible: + const: qcom,mdp4 + + clocks: + minItems: 6 + maxItems: 6 + + clock-names: + items: + - const: core_clk + - const: iface_clk + - const: bus_clk + - const: lut_clk + - const: hdmi_clk + - const: tv_clk + + reg: + maxItems: 1 + + interrupts: + maxItems: 1 + + iommus: + maxItems: 1 + + ports: + $ref: /schemas/graph.yaml#/properties/ports + properties: + port@0: + $ref: /schemas/graph.yaml#/properties/port + description: LCDC/LVDS + + port@1: + $ref: /schemas/graph.yaml#/properties/port + description: DSI1 Cmd / Video + + port@2: + $ref: /schemas/graph.yaml#/properties/port + description: DSI2 Cmd / Video + + port@3: + $ref: /schemas/graph.yaml#/properties/port + description: Digital TV + + qcom,lcdc-align-lsb: + type: boolean + description: > + Indication that LSB alignment should be used for LCDC. + This is only valid for 18bpp panels. + +required: + - compatible + - reg + - clocks + - ports + +additionalProperties: false + +examples: + - | + mdp: mdp@5100000 { + compatible = "qcom,mdp4"; + reg = <0x05100000 0xf0000>; + interrupts = <0 75 0>; + clock-names = + "core_clk", + "iface_clk", + "bus_clk", + "lut_clk", + "hdmi_clk", + "tv_clk"; + clocks = + <&mmcc 77>, + <&mmcc 86>, + <&mmcc 102>, + <&mmcc 75>, + <&mmcc 97>, + <&mmcc 12>; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + mdp_lvds_out: endpoint { + }; + }; + + port@1 { + reg = <1>; + mdp_dsi1_out: endpoint { + }; + }; + + port@2 { + reg = <2>; + mdp_dsi2_out: endpoint { + }; + }; + + port@3 { + reg = <3>; + mdp_dtv_out: endpoint { + remote-endpoint = <&hdmi_in>; + }; + }; + }; + }; From 5a04982df8dad24681dc5848150f507338d3e372 Mon Sep 17 00:00:00 2001 From: Michael Tretter Date: Wed, 12 Jan 2022 16:15:39 +0100 Subject: [PATCH 019/370] dt-bindings: dmaengine: zynqmp_dma: convert to yaml Convert the Xilinx ZynqMP DMA engine bindings to Yaml. Signed-off-by: Michael Tretter Signed-off-by: Rob Herring Link: https://lore.kernel.org/r/20220112151541.1328732-2-m.tretter@pengutronix.de --- .../dma/xilinx/xlnx,zynqmp-dma-1.0.yaml | 85 +++++++++++++++++++ .../bindings/dma/xilinx/zynqmp_dma.txt | 26 ------ 2 files changed, 85 insertions(+), 26 deletions(-) create mode 100644 Documentation/devicetree/bindings/dma/xilinx/xlnx,zynqmp-dma-1.0.yaml delete mode 100644 Documentation/devicetree/bindings/dma/xilinx/zynqmp_dma.txt diff --git a/Documentation/devicetree/bindings/dma/xilinx/xlnx,zynqmp-dma-1.0.yaml b/Documentation/devicetree/bindings/dma/xilinx/xlnx,zynqmp-dma-1.0.yaml new file mode 100644 index 000000000000..c0a1408b12ec --- /dev/null +++ b/Documentation/devicetree/bindings/dma/xilinx/xlnx,zynqmp-dma-1.0.yaml @@ -0,0 +1,85 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/dma/xilinx/xlnx,zynqmp-dma-1.0.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Xilinx ZynqMP DMA Engine + +description: | + The Xilinx ZynqMP DMA engine supports memory to memory transfers, + memory to device and device to memory transfers. It also has flow + control and rate control support for slave/peripheral dma access. + +maintainers: + - Michael Tretter + +allOf: + - $ref: "../dma-controller.yaml#" + +properties: + "#dma-cells": + const: 1 + + compatible: + const: xlnx,zynqmp-dma-1.0 + + reg: + description: memory map for gdma/adma module access + maxItems: 1 + + interrupts: + description: DMA channel interrupt + maxItems: 1 + + clocks: + description: input clocks + minItems: 2 + maxItems: 2 + + clock-names: + items: + - const: clk_main + - const: clk_apb + + xlnx,bus-width: + $ref: /schemas/types.yaml#/definitions/uint32 + enum: + - 64 + - 128 + description: AXI bus width in bits + + iommus: + maxItems: 1 + + power-domains: + maxItems: 1 + + dma-coherent: + description: present if dma operations are coherent + +required: + - "#dma-cells" + - compatible + - reg + - interrupts + - clocks + - clock-names + +additionalProperties: false + +examples: + - | + #include + + fpd_dma_chan1: dma-controller@fd500000 { + compatible = "xlnx,zynqmp-dma-1.0"; + reg = <0xfd500000 0x1000>; + interrupt-parent = <&gic>; + interrupts = <0 117 0x4>; + #dma-cells = <1>; + clock-names = "clk_main", "clk_apb"; + clocks = <&zynqmp_clk GDMA_REF>, <&zynqmp_clk LPD_LSBUS>; + xlnx,bus-width = <128>; + dma-coherent; + }; diff --git a/Documentation/devicetree/bindings/dma/xilinx/zynqmp_dma.txt b/Documentation/devicetree/bindings/dma/xilinx/zynqmp_dma.txt deleted file mode 100644 index 07a5a7aa9ea0..000000000000 --- a/Documentation/devicetree/bindings/dma/xilinx/zynqmp_dma.txt +++ /dev/null @@ -1,26 +0,0 @@ -Xilinx ZynqMP DMA engine, it does support memory to memory transfers, -memory to device and device to memory transfers. It also has flow -control and rate control support for slave/peripheral dma access. - -Required properties: -- compatible : Should be "xlnx,zynqmp-dma-1.0" -- reg : Memory map for gdma/adma module access. -- interrupts : Should contain DMA channel interrupt. -- xlnx,bus-width : Axi buswidth in bits. Should contain 128 or 64 -- clock-names : List of input clocks "clk_main", "clk_apb" - (see clock bindings for details) - -Optional properties: -- dma-coherent : Present if dma operations are coherent. - -Example: -++++++++ -fpd_dma_chan1: dma@fd500000 { - compatible = "xlnx,zynqmp-dma-1.0"; - reg = <0x0 0xFD500000 0x1000>; - interrupt-parent = <&gic>; - interrupts = <0 117 4>; - clock-names = "clk_main", "clk_apb"; - xlnx,bus-width = <128>; - dma-coherent; -}; From e0a9ddd5d9e1c66caefda825b3cea8ea9bd21bf0 Mon Sep 17 00:00:00 2001 From: RinHizakura Date: Sat, 25 Dec 2021 18:06:07 +0800 Subject: [PATCH 020/370] mtd: rawnand: nandsim: Replace overflow check with kzalloc to single kcalloc Instead of self-checking overflow and allocating an array of specific size by counting the total required space handy, we already have existed kernel API which responses for all these works. Signed-off-by: RinHizakura Reviewed-by: Richard Weinberger Signed-off-by: Miquel Raynal Link: https://lore.kernel.org/linux-mtd/20211225100607.118932-1-s921975628@gmail.com --- drivers/mtd/nand/raw/nandsim.c | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/drivers/mtd/nand/raw/nandsim.c b/drivers/mtd/nand/raw/nandsim.c index 0750121ac371..3698fb430f81 100644 --- a/drivers/mtd/nand/raw/nandsim.c +++ b/drivers/mtd/nand/raw/nandsim.c @@ -979,15 +979,8 @@ static int ns_read_error(unsigned int page_no) static int ns_setup_wear_reporting(struct mtd_info *mtd) { - size_t mem; - wear_eb_count = div_u64(mtd->size, mtd->erasesize); - mem = wear_eb_count * sizeof(unsigned long); - if (mem / sizeof(unsigned long) != wear_eb_count) { - NS_ERR("Too many erase blocks for wear reporting\n"); - return -ENOMEM; - } - erase_block_wear = kzalloc(mem, GFP_KERNEL); + erase_block_wear = kcalloc(wear_eb_count, sizeof(unsigned long), GFP_KERNEL); if (!erase_block_wear) { NS_ERR("Too many erase blocks for wear reporting\n"); return -ENOMEM; From db52b445793d8e4ffe9b53ff749a55470b900984 Mon Sep 17 00:00:00 2001 From: RinHizakura Date: Sat, 25 Dec 2021 18:06:48 +0800 Subject: [PATCH 021/370] mtd: rawnand: nandsim: Merge repeat codes in ns_switch_state The moving block of codes is shared between both 'if' and 'else' condition, we can move it out to reduce the duplication. Signed-off-by: RinHizakura Reviewed-by: Richard Weinberger Signed-off-by: Miquel Raynal Link: https://lore.kernel.org/linux-mtd/20211225100648.119011-1-s921975628@gmail.com --- drivers/mtd/nand/raw/nandsim.c | 19 ++++++------------- 1 file changed, 6 insertions(+), 13 deletions(-) diff --git a/drivers/mtd/nand/raw/nandsim.c b/drivers/mtd/nand/raw/nandsim.c index 3698fb430f81..2ef6bddf0ab9 100644 --- a/drivers/mtd/nand/raw/nandsim.c +++ b/drivers/mtd/nand/raw/nandsim.c @@ -1731,14 +1731,6 @@ static void ns_switch_state(struct nandsim *ns) "state: %s, nxstate: %s\n", ns_get_state_name(ns->state), ns_get_state_name(ns->nxstate)); - - /* See, whether we need to do some action */ - if ((ns->state & ACTION_MASK) && - ns_do_state_action(ns, ns->state) < 0) { - ns_switch_to_ready_state(ns, NS_STATUS_FAILED(ns)); - return; - } - } else { /* * We don't yet know which operation we perform. @@ -1755,12 +1747,13 @@ static void ns_switch_state(struct nandsim *ns) if (ns_find_operation(ns, 0)) return; + } - if ((ns->state & ACTION_MASK) && - ns_do_state_action(ns, ns->state) < 0) { - ns_switch_to_ready_state(ns, NS_STATUS_FAILED(ns)); - return; - } + /* See, whether we need to do some action */ + if ((ns->state & ACTION_MASK) && + ns_do_state_action(ns, ns->state) < 0) { + ns_switch_to_ready_state(ns, NS_STATUS_FAILED(ns)); + return; } /* For 16x devices column means the page offset in words */ From 109cf81fb573c1b685282a35e427e76f35870628 Mon Sep 17 00:00:00 2001 From: RinHizakura Date: Sat, 25 Dec 2021 18:07:13 +0800 Subject: [PATCH 022/370] mtd: rawnand: nandsim: Add NS_PAGE_BYTE_SHIFT macro to replace the repeat pattern The (ns->regs.column + ns->regs.off) pattern repeats a lot which represents the byte shift in next page to access. We can replace it with a macro to improve the readability. Signed-off-by: RinHizakura Reviewed-by: Richard Weinberger Signed-off-by: Miquel Raynal Link: https://lore.kernel.org/linux-mtd/20211225100713.119089-1-s921975628@gmail.com --- drivers/mtd/nand/raw/nandsim.c | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/drivers/mtd/nand/raw/nandsim.c b/drivers/mtd/nand/raw/nandsim.c index 2ef6bddf0ab9..24beade95c7f 100644 --- a/drivers/mtd/nand/raw/nandsim.c +++ b/drivers/mtd/nand/raw/nandsim.c @@ -201,6 +201,9 @@ MODULE_PARM_DESC(bch, "Enable BCH ecc and set how many bits should " /* Calculate the OOB offset in flash RAM image by (row, column) address */ #define NS_RAW_OFFSET_OOB(ns) (NS_RAW_OFFSET(ns) + ns->geom.pgsz) +/* Calculate the byte shift in the next page to access */ +#define NS_PAGE_BYTE_SHIFT(ns) ((ns)->regs.column + (ns)->regs.off) + /* After a command is input, the simulator goes to one of the following states */ #define STATE_CMD_READ0 0x00000001 /* read data from the beginning of page */ #define STATE_CMD_READ1 0x00000002 /* read data from the second half of page */ @@ -1382,7 +1385,7 @@ static inline union ns_mem *NS_GET_PAGE(struct nandsim *ns) */ static inline u_char *NS_PAGE_BYTE_OFF(struct nandsim *ns) { - return NS_GET_PAGE(ns)->byte + ns->regs.column + ns->regs.off; + return NS_GET_PAGE(ns)->byte + NS_PAGE_BYTE_SHIFT(ns); } static int ns_do_read_error(struct nandsim *ns, int num) @@ -1408,7 +1411,7 @@ static void ns_do_bit_flips(struct nandsim *ns, int num) ns->buf.byte[pos / 8] ^= (1 << (pos % 8)); NS_WARN("read_page: flipping bit %d in page %d " "reading from %d ecc: corrected=%u failed=%u\n", - pos, ns->regs.row, ns->regs.column + ns->regs.off, + pos, ns->regs.row, NS_PAGE_BYTE_SHIFT(ns), nsmtd->ecc_stats.corrected, nsmtd->ecc_stats.failed); } } @@ -1430,7 +1433,7 @@ static void ns_read_page(struct nandsim *ns, int num) ssize_t tx; NS_DBG("read_page: page %d written, reading from %d\n", - ns->regs.row, ns->regs.column + ns->regs.off); + ns->regs.row, NS_PAGE_BYTE_SHIFT(ns)); if (ns_do_read_error(ns, num)) return; pos = (loff_t)NS_RAW_OFFSET(ns) + ns->regs.off; @@ -1451,7 +1454,7 @@ static void ns_read_page(struct nandsim *ns, int num) memset(ns->buf.byte, 0xFF, num); } else { NS_DBG("read_page: page %d allocated, reading from %d\n", - ns->regs.row, ns->regs.column + ns->regs.off); + ns->regs.row, NS_PAGE_BYTE_SHIFT(ns)); if (ns_do_read_error(ns, num)) return; memcpy(ns->buf.byte, NS_PAGE_BYTE_OFF(ns), num); @@ -1502,7 +1505,7 @@ static int ns_prog_page(struct nandsim *ns, int num) int all; NS_DBG("prog_page: writing page %d\n", ns->regs.row); - pg_off = ns->file_buf + ns->regs.column + ns->regs.off; + pg_off = ns->file_buf + NS_PAGE_BYTE_SHIFT(ns); off = (loff_t)NS_RAW_OFFSET(ns) + ns->regs.off; if (!test_bit(ns->regs.row, ns->pages_written)) { all = 1; @@ -1591,7 +1594,7 @@ static int ns_do_state_action(struct nandsim *ns, uint32_t action) NS_ERR("do_state_action: column number is too large\n"); break; } - num = ns->geom.pgszoob - ns->regs.off - ns->regs.column; + num = ns->geom.pgszoob - NS_PAGE_BYTE_SHIFT(ns); ns_read_page(ns, num); NS_DBG("do_state_action: (ACTION_CPY:) copy %d bytes to int buf, raw offset %d\n", @@ -1659,7 +1662,7 @@ static int ns_do_state_action(struct nandsim *ns, uint32_t action) return -1; } - num = ns->geom.pgszoob - ns->regs.off - ns->regs.column; + num = ns->geom.pgszoob - NS_PAGE_BYTE_SHIFT(ns); if (num != ns->regs.count) { NS_ERR("do_state_action: too few bytes were input (%d instead of %d)\n", ns->regs.count, num); @@ -1803,7 +1806,7 @@ static void ns_switch_state(struct nandsim *ns) switch (NS_STATE(ns->state)) { case STATE_DATAIN: case STATE_DATAOUT: - ns->regs.num = ns->geom.pgszoob - ns->regs.off - ns->regs.column; + ns->regs.num = ns->geom.pgszoob - NS_PAGE_BYTE_SHIFT(ns); break; case STATE_DATAOUT_ID: From 3e68f331c8c759c0daa31cc92c3449b23119a215 Mon Sep 17 00:00:00 2001 From: Jiasheng Jiang Date: Wed, 5 Jan 2022 00:26:58 +0800 Subject: [PATCH 023/370] mtd: onenand: Check for error irq For the possible failure of the platform_get_irq(), the returned irq could be error number and will finally cause the failure of the request_irq(). Consider that platform_get_irq() can now in certain cases return -EPROBE_DEFER, and the consequences of letting request_irq() effectively convert that into -EINVAL, even at probe time rather than later on. So it might be better to check just now. Fixes: 2c22120fbd01 ("MTD: OneNAND: interrupt based wait support") Signed-off-by: Jiasheng Jiang Signed-off-by: Miquel Raynal Link: https://lore.kernel.org/linux-mtd/20220104162658.1988142-1-jiasheng@iscas.ac.cn --- drivers/mtd/nand/onenand/generic.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/drivers/mtd/nand/onenand/generic.c b/drivers/mtd/nand/onenand/generic.c index 8b6f4da5d720..a4b8b65fe15f 100644 --- a/drivers/mtd/nand/onenand/generic.c +++ b/drivers/mtd/nand/onenand/generic.c @@ -53,7 +53,12 @@ static int generic_onenand_probe(struct platform_device *pdev) } info->onenand.mmcontrol = pdata ? pdata->mmcontrol : NULL; - info->onenand.irq = platform_get_irq(pdev, 0); + + err = platform_get_irq(pdev, 0); + if (err < 0) + goto out_iounmap; + + info->onenand.irq = err; info->mtd.dev.parent = &pdev->dev; info->mtd.priv = &info->onenand; From dbfbe79dbb6339196d5a26eaed70c3a50d6d154a Mon Sep 17 00:00:00 2001 From: Tudor Ambarus Date: Thu, 6 Jan 2022 15:16:09 +0200 Subject: [PATCH 024/370] mtd: rawnand: Remove of_get_nand_on_flash_bbt() wrapper Remove the wrapper as it hides for no reason what we really want: find an of_property. Removing the wrapper makes the code easier to read. Signed-off-by: Tudor Ambarus Signed-off-by: Miquel Raynal Link: https://lore.kernel.org/linux-mtd/20220106131610.225661-1-tudor.ambarus@microchip.com --- drivers/mtd/nand/raw/nand_base.c | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/drivers/mtd/nand/raw/nand_base.c b/drivers/mtd/nand/raw/nand_base.c index e7b2ba016d8c..dd276df31ffe 100644 --- a/drivers/mtd/nand/raw/nand_base.c +++ b/drivers/mtd/nand/raw/nand_base.c @@ -5290,11 +5290,6 @@ static int of_get_nand_bus_width(struct device_node *np) } } -static bool of_get_nand_on_flash_bbt(struct device_node *np) -{ - return of_property_read_bool(np, "nand-on-flash-bbt"); -} - static int of_get_nand_secure_regions(struct nand_chip *chip) { struct device_node *dn = nand_get_flash_node(chip); @@ -5378,7 +5373,7 @@ static int rawnand_dt_init(struct nand_chip *chip) if (of_property_read_bool(dn, "nand-is-boot-medium")) chip->options |= NAND_IS_BOOT_MEDIUM; - if (of_get_nand_on_flash_bbt(dn)) + if (of_property_read_bool(dn, "nand-on-flash-bbt")) chip->bbt_options |= NAND_BBT_USE_FLASH; of_get_nand_ecc_user_config(nand); From 65a01be4f5286af4e0af83292377a5904df642d9 Mon Sep 17 00:00:00 2001 From: Tudor Ambarus Date: Thu, 6 Jan 2022 15:16:10 +0200 Subject: [PATCH 025/370] mtd: rawnand: Rework of_get_nand_bus_width() of_get_nand_bus_width() had a wrong behavior because: 1/ it ignored the -ENODATA and -EOVERFLOW return values of of_property_read_u32(). "nand-bus-width" without value was tolerated while it shouldn't have been according to the devicetree bindings. 2/ returned -EIO when the nand-bus-width was neither 8 nor 16, when it should have returned -EINVAL instead. 3/ returned the 8 or 16 bus-width integer, but it was never used it its caller. A simply return 0 on success is enough. Rework of_get_nand_bus_width() and address all the above. The execution is now stopped in case of errors. Signed-off-by: Tudor Ambarus Signed-off-by: Miquel Raynal Link: https://lore.kernel.org/linux-mtd/20220106131610.225661-2-tudor.ambarus@microchip.com --- drivers/mtd/nand/raw/nand_base.c | 30 ++++++++++++++++++------------ 1 file changed, 18 insertions(+), 12 deletions(-) diff --git a/drivers/mtd/nand/raw/nand_base.c b/drivers/mtd/nand/raw/nand_base.c index dd276df31ffe..3e4a525ac3ca 100644 --- a/drivers/mtd/nand/raw/nand_base.c +++ b/drivers/mtd/nand/raw/nand_base.c @@ -5274,20 +5274,24 @@ static void of_get_nand_ecc_legacy_user_config(struct nand_chip *chip) user_conf->placement = of_get_rawnand_ecc_placement_legacy(dn); } -static int of_get_nand_bus_width(struct device_node *np) +static int of_get_nand_bus_width(struct nand_chip *chip) { + struct device_node *dn = nand_get_flash_node(chip); u32 val; + int ret; - if (of_property_read_u32(np, "nand-bus-width", &val)) - return 8; + ret = of_property_read_u32(dn, "nand-bus-width", &val); + if (ret == -EINVAL) + /* Buswidth defaults to 8 if the property does not exist .*/ + return 0; + else if (ret) + return ret; - switch (val) { - case 8: - case 16: - return val; - default: - return -EIO; - } + if (val == 16) + chip->options |= NAND_BUSWIDTH_16; + else if (val != 8) + return -EINVAL; + return 0; } static int of_get_nand_secure_regions(struct nand_chip *chip) @@ -5363,12 +5367,14 @@ static int rawnand_dt_init(struct nand_chip *chip) { struct nand_device *nand = mtd_to_nanddev(nand_to_mtd(chip)); struct device_node *dn = nand_get_flash_node(chip); + int ret; if (!dn) return 0; - if (of_get_nand_bus_width(dn) == 16) - chip->options |= NAND_BUSWIDTH_16; + ret = of_get_nand_bus_width(chip); + if (ret) + return ret; if (of_property_read_bool(dn, "nand-is-boot-medium")) chip->options |= NAND_IS_BOOT_MEDIUM; From 9e37532b1820b4d86b17c74bf3d176d79c80974b Mon Sep 17 00:00:00 2001 From: Florian Fainelli Date: Fri, 7 Jan 2022 10:46:06 -0800 Subject: [PATCH 026/370] mtd: rawnand: brcmnand: Assign soc as early as possible In order to key off the brcmnand_probe() code in subsequent changes depending upon ctrl->soc, assign that variable as early as possible, instead of much later when we have checked that it is non-NULL. Signed-off-by: Florian Fainelli Signed-off-by: Miquel Raynal Link: https://lore.kernel.org/linux-mtd/20220107184614.2670254-2-f.fainelli@gmail.com --- drivers/mtd/nand/raw/brcmnand/brcmnand.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/mtd/nand/raw/brcmnand/brcmnand.c b/drivers/mtd/nand/raw/brcmnand/brcmnand.c index f75929783b94..63080ae3aef1 100644 --- a/drivers/mtd/nand/raw/brcmnand/brcmnand.c +++ b/drivers/mtd/nand/raw/brcmnand/brcmnand.c @@ -2998,6 +2998,7 @@ int brcmnand_probe(struct platform_device *pdev, struct brcmnand_soc *soc) dev_set_drvdata(dev, ctrl); ctrl->dev = dev; + ctrl->soc = soc; init_completion(&ctrl->done); init_completion(&ctrl->dma_done); @@ -3138,8 +3139,6 @@ int brcmnand_probe(struct platform_device *pdev, struct brcmnand_soc *soc) * interesting ways */ if (soc) { - ctrl->soc = soc; - ret = devm_request_irq(dev, ctrl->irq, brcmnand_irq, 0, DRV_NAME, ctrl); From 25f97138f8c225dbf365b428a94d7b30a6daefb3 Mon Sep 17 00:00:00 2001 From: Florian Fainelli Date: Fri, 7 Jan 2022 10:46:07 -0800 Subject: [PATCH 027/370] mtd: rawnand: brcmnand: Allow SoC to provide I/O operations Allow a brcmnand_soc instance to provide a custom set of I/O operations which we will require when using this driver on a BCMA bus which is not directly memory mapped I/O. Update the nand_{read,write}_reg accordingly to use the SoC operations if provided. To minimize the penalty on other SoCs which do support standard MMIO accesses, we use a static key which is disabled by default and gets enabled if a soc implementation does provide I/O operations. Signed-off-by: Florian Fainelli Signed-off-by: Miquel Raynal Link: https://lore.kernel.org/linux-mtd/20220107184614.2670254-3-f.fainelli@gmail.com --- drivers/mtd/nand/raw/brcmnand/brcmnand.c | 28 +++++++++++++++++++++-- drivers/mtd/nand/raw/brcmnand/brcmnand.h | 29 ++++++++++++++++++++++++ 2 files changed, 55 insertions(+), 2 deletions(-) diff --git a/drivers/mtd/nand/raw/brcmnand/brcmnand.c b/drivers/mtd/nand/raw/brcmnand/brcmnand.c index 63080ae3aef1..48d57b19c293 100644 --- a/drivers/mtd/nand/raw/brcmnand/brcmnand.c +++ b/drivers/mtd/nand/raw/brcmnand/brcmnand.c @@ -25,6 +25,7 @@ #include #include #include +#include #include #include @@ -207,6 +208,8 @@ enum { struct brcmnand_host; +static DEFINE_STATIC_KEY_FALSE(brcmnand_soc_has_ops_key); + struct brcmnand_controller { struct device *dev; struct nand_controller controller; @@ -592,15 +595,25 @@ enum { INTFC_CTLR_READY = BIT(31), }; +static inline bool brcmnand_non_mmio_ops(struct brcmnand_controller *ctrl) +{ + return static_branch_unlikely(&brcmnand_soc_has_ops_key); +} + static inline u32 nand_readreg(struct brcmnand_controller *ctrl, u32 offs) { + if (brcmnand_non_mmio_ops(ctrl)) + return brcmnand_soc_read(ctrl->soc, offs); return brcmnand_readl(ctrl->nand_base + offs); } static inline void nand_writereg(struct brcmnand_controller *ctrl, u32 offs, u32 val) { - brcmnand_writel(val, ctrl->nand_base + offs); + if (brcmnand_non_mmio_ops(ctrl)) + brcmnand_soc_write(ctrl->soc, val, offs); + else + brcmnand_writel(val, ctrl->nand_base + offs); } static int brcmnand_revision_init(struct brcmnand_controller *ctrl) @@ -766,13 +779,18 @@ static inline void brcmnand_rmw_reg(struct brcmnand_controller *ctrl, static inline u32 brcmnand_read_fc(struct brcmnand_controller *ctrl, int word) { + if (brcmnand_non_mmio_ops(ctrl)) + return brcmnand_soc_read(ctrl->soc, BRCMNAND_NON_MMIO_FC_ADDR); return __raw_readl(ctrl->nand_fc + word * 4); } static inline void brcmnand_write_fc(struct brcmnand_controller *ctrl, int word, u32 val) { - __raw_writel(val, ctrl->nand_fc + word * 4); + if (brcmnand_non_mmio_ops(ctrl)) + brcmnand_soc_write(ctrl->soc, val, BRCMNAND_NON_MMIO_FC_ADDR); + else + __raw_writel(val, ctrl->nand_fc + word * 4); } static inline void edu_writel(struct brcmnand_controller *ctrl, @@ -3000,6 +3018,12 @@ int brcmnand_probe(struct platform_device *pdev, struct brcmnand_soc *soc) ctrl->dev = dev; ctrl->soc = soc; + /* Enable the static key if the soc provides I/O operations indicating + * that a non-memory mapped IO access path must be used + */ + if (brcmnand_soc_has_ops(ctrl->soc)) + static_branch_enable(&brcmnand_soc_has_ops_key); + init_completion(&ctrl->done); init_completion(&ctrl->dma_done); init_completion(&ctrl->edu_done); diff --git a/drivers/mtd/nand/raw/brcmnand/brcmnand.h b/drivers/mtd/nand/raw/brcmnand/brcmnand.h index eb498fbe505e..f1f93d85f50d 100644 --- a/drivers/mtd/nand/raw/brcmnand/brcmnand.h +++ b/drivers/mtd/nand/raw/brcmnand/brcmnand.h @@ -11,12 +11,25 @@ struct platform_device; struct dev_pm_ops; +struct brcmnand_io_ops; + +/* Special register offset constant to intercept a non-MMIO access + * to the flash cache register space. This is intentionally large + * not to overlap with an existing offset. + */ +#define BRCMNAND_NON_MMIO_FC_ADDR 0xffffffff struct brcmnand_soc { bool (*ctlrdy_ack)(struct brcmnand_soc *soc); void (*ctlrdy_set_enabled)(struct brcmnand_soc *soc, bool en); void (*prepare_data_bus)(struct brcmnand_soc *soc, bool prepare, bool is_param); + const struct brcmnand_io_ops *ops; +}; + +struct brcmnand_io_ops { + u32 (*read_reg)(struct brcmnand_soc *soc, u32 offset); + void (*write_reg)(struct brcmnand_soc *soc, u32 val, u32 offset); }; static inline void brcmnand_soc_data_bus_prepare(struct brcmnand_soc *soc, @@ -58,6 +71,22 @@ static inline void brcmnand_writel(u32 val, void __iomem *addr) writel_relaxed(val, addr); } +static inline bool brcmnand_soc_has_ops(struct brcmnand_soc *soc) +{ + return soc && soc->ops && soc->ops->read_reg && soc->ops->write_reg; +} + +static inline u32 brcmnand_soc_read(struct brcmnand_soc *soc, u32 offset) +{ + return soc->ops->read_reg(soc, offset); +} + +static inline void brcmnand_soc_write(struct brcmnand_soc *soc, u32 val, + u32 offset) +{ + soc->ops->write_reg(soc, val, offset); +} + int brcmnand_probe(struct platform_device *pdev, struct brcmnand_soc *soc); int brcmnand_remove(struct platform_device *pdev); From c0d08a1401bbd0b8f523b431220e4b44fc4ac631 Mon Sep 17 00:00:00 2001 From: Florian Fainelli Date: Fri, 7 Jan 2022 10:46:08 -0800 Subject: [PATCH 028/370] mtd: rawnand: brcmnand: Avoid pdev in brcmnand_init_cs() In preparation for encapsulating more of what the loop calling brcmnand_init_cs() does, avoid using platform_device when it is the device behind platform_device that we are using for printing errors. No functional changes introduced. Signed-off-by: Florian Fainelli Signed-off-by: Miquel Raynal Link: https://lore.kernel.org/linux-mtd/20220107184614.2670254-4-f.fainelli@gmail.com --- drivers/mtd/nand/raw/brcmnand/brcmnand.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/mtd/nand/raw/brcmnand/brcmnand.c b/drivers/mtd/nand/raw/brcmnand/brcmnand.c index 48d57b19c293..b7b15ddf326f 100644 --- a/drivers/mtd/nand/raw/brcmnand/brcmnand.c +++ b/drivers/mtd/nand/raw/brcmnand/brcmnand.c @@ -2771,7 +2771,7 @@ static const struct nand_controller_ops brcmnand_controller_ops = { static int brcmnand_init_cs(struct brcmnand_host *host, struct device_node *dn) { struct brcmnand_controller *ctrl = host->ctrl; - struct platform_device *pdev = host->pdev; + struct device *dev = ctrl->dev; struct mtd_info *mtd; struct nand_chip *chip; int ret; @@ -2779,7 +2779,7 @@ static int brcmnand_init_cs(struct brcmnand_host *host, struct device_node *dn) ret = of_property_read_u32(dn, "reg", &host->cs); if (ret) { - dev_err(&pdev->dev, "can't get chip-select\n"); + dev_err(dev, "can't get chip-select\n"); return -ENXIO; } @@ -2788,13 +2788,13 @@ static int brcmnand_init_cs(struct brcmnand_host *host, struct device_node *dn) nand_set_flash_node(chip, dn); nand_set_controller_data(chip, host); - mtd->name = devm_kasprintf(&pdev->dev, GFP_KERNEL, "brcmnand.%d", + mtd->name = devm_kasprintf(dev, GFP_KERNEL, "brcmnand.%d", host->cs); if (!mtd->name) return -ENOMEM; mtd->owner = THIS_MODULE; - mtd->dev.parent = &pdev->dev; + mtd->dev.parent = dev; chip->legacy.cmd_ctrl = brcmnand_cmd_ctrl; chip->legacy.cmdfunc = brcmnand_cmdfunc; From 75ac944722b09faaffeb10bae355f5a1fb676107 Mon Sep 17 00:00:00 2001 From: Florian Fainelli Date: Fri, 7 Jan 2022 10:46:09 -0800 Subject: [PATCH 029/370] mtd: rawnand: brcmnand: Move OF operations out of brcmnand_init_cs() In order to initialize a given chip select object for use by the brcmnand driver, move all of the Device Tree specific routines outside of brcmnand_init_cs() in order to make it usable in a platform data configuration which will be necessary for supporting BCMA chips. No functional changes introduced. Signed-off-by: Florian Fainelli Signed-off-by: Miquel Raynal Link: https://lore.kernel.org/linux-mtd/20220107184614.2670254-5-f.fainelli@gmail.com --- drivers/mtd/nand/raw/brcmnand/brcmnand.c | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/drivers/mtd/nand/raw/brcmnand/brcmnand.c b/drivers/mtd/nand/raw/brcmnand/brcmnand.c index b7b15ddf326f..40818c881f08 100644 --- a/drivers/mtd/nand/raw/brcmnand/brcmnand.c +++ b/drivers/mtd/nand/raw/brcmnand/brcmnand.c @@ -2768,7 +2768,7 @@ static const struct nand_controller_ops brcmnand_controller_ops = { .attach_chip = brcmnand_attach_chip, }; -static int brcmnand_init_cs(struct brcmnand_host *host, struct device_node *dn) +static int brcmnand_init_cs(struct brcmnand_host *host) { struct brcmnand_controller *ctrl = host->ctrl; struct device *dev = ctrl->dev; @@ -2777,16 +2777,9 @@ static int brcmnand_init_cs(struct brcmnand_host *host, struct device_node *dn) int ret; u16 cfg_offs; - ret = of_property_read_u32(dn, "reg", &host->cs); - if (ret) { - dev_err(dev, "can't get chip-select\n"); - return -ENXIO; - } - mtd = nand_to_mtd(&host->chip); chip = &host->chip; - nand_set_flash_node(chip, dn); nand_set_controller_data(chip, host); mtd->name = devm_kasprintf(dev, GFP_KERNEL, "brcmnand.%d", host->cs); @@ -3193,7 +3186,16 @@ int brcmnand_probe(struct platform_device *pdev, struct brcmnand_soc *soc) host->pdev = pdev; host->ctrl = ctrl; - ret = brcmnand_init_cs(host, child); + ret = of_property_read_u32(child, "reg", &host->cs); + if (ret) { + dev_err(dev, "can't get chip-select\n"); + devm_kfree(dev, host); + continue; + } + + nand_set_flash_node(&host->chip, child); + + ret = brcmnand_init_cs(host); if (ret) { devm_kfree(dev, host); continue; /* Try all chip-selects */ From f5619f3774d0ef6ddbb8de4c782cc4e42966c524 Mon Sep 17 00:00:00 2001 From: Florian Fainelli Date: Fri, 7 Jan 2022 10:46:10 -0800 Subject: [PATCH 030/370] mtd: rawnand: brcmnand: Allow working without interrupts The BCMA devices include the brcmnand controller but they do not wire up any interrupt line, allow the main interrupt to be optional and update the completion path to also check for the lack of an interrupt line. Signed-off-by: Florian Fainelli Signed-off-by: Miquel Raynal Link: https://lore.kernel.org/linux-mtd/20220107184614.2670254-6-f.fainelli@gmail.com --- drivers/mtd/nand/raw/brcmnand/brcmnand.c | 52 +++++++++++------------- 1 file changed, 24 insertions(+), 28 deletions(-) diff --git a/drivers/mtd/nand/raw/brcmnand/brcmnand.c b/drivers/mtd/nand/raw/brcmnand/brcmnand.c index 40818c881f08..08e2acde5133 100644 --- a/drivers/mtd/nand/raw/brcmnand/brcmnand.c +++ b/drivers/mtd/nand/raw/brcmnand/brcmnand.c @@ -216,7 +216,7 @@ struct brcmnand_controller { void __iomem *nand_base; void __iomem *nand_fc; /* flash cache */ void __iomem *flash_dma_base; - unsigned int irq; + int irq; unsigned int dma_irq; int nand_version; @@ -1610,7 +1610,7 @@ static bool brcmstb_nand_wait_for_completion(struct nand_chip *chip) bool err = false; int sts; - if (mtd->oops_panic_write) { + if (mtd->oops_panic_write || ctrl->irq < 0) { /* switch to interrupt polling and PIO mode */ disable_ctrl_irqs(ctrl); sts = bcmnand_ctrl_poll_status(ctrl, NAND_CTRL_RDY, @@ -3144,33 +3144,29 @@ int brcmnand_probe(struct platform_device *pdev, struct brcmnand_soc *soc) } /* IRQ */ - ctrl->irq = platform_get_irq(pdev, 0); - if ((int)ctrl->irq < 0) { - dev_err(dev, "no IRQ defined\n"); - ret = -ENODEV; - goto err; - } + ctrl->irq = platform_get_irq_optional(pdev, 0); + if (ctrl->irq > 0) { + /* + * Some SoCs integrate this controller (e.g., its interrupt bits) in + * interesting ways + */ + if (soc) { + ret = devm_request_irq(dev, ctrl->irq, brcmnand_irq, 0, + DRV_NAME, ctrl); - /* - * Some SoCs integrate this controller (e.g., its interrupt bits) in - * interesting ways - */ - if (soc) { - ret = devm_request_irq(dev, ctrl->irq, brcmnand_irq, 0, - DRV_NAME, ctrl); - - /* Enable interrupt */ - ctrl->soc->ctlrdy_ack(ctrl->soc); - ctrl->soc->ctlrdy_set_enabled(ctrl->soc, true); - } else { - /* Use standard interrupt infrastructure */ - ret = devm_request_irq(dev, ctrl->irq, brcmnand_ctlrdy_irq, 0, - DRV_NAME, ctrl); - } - if (ret < 0) { - dev_err(dev, "can't allocate IRQ %d: error %d\n", - ctrl->irq, ret); - goto err; + /* Enable interrupt */ + ctrl->soc->ctlrdy_ack(ctrl->soc); + ctrl->soc->ctlrdy_set_enabled(ctrl->soc, true); + } else { + /* Use standard interrupt infrastructure */ + ret = devm_request_irq(dev, ctrl->irq, brcmnand_ctlrdy_irq, 0, + DRV_NAME, ctrl); + } + if (ret < 0) { + dev_err(dev, "can't allocate IRQ %d: error %d\n", + ctrl->irq, ret); + goto err; + } } for_each_available_child_of_node(dn, child) { From 02d1d0e4dfc3fdc5aa05b78e7def00dc1e62257e Mon Sep 17 00:00:00 2001 From: Florian Fainelli Date: Fri, 7 Jan 2022 10:46:11 -0800 Subject: [PATCH 031/370] mtd: rawnand: brcmnand: Add platform data structure for BCMA Update the BCMA's chipcommon nand flash driver to detect which chip-select is used and pass that information via platform data to the brcmnand driver. Make sure that the brcmnand platform data structure is always at the beginning of the platform data of the "nflash" device created by BCMA to allow brcmnand to safely de-reference it. Signed-off-by: Florian Fainelli Signed-off-by: Miquel Raynal Link: https://lore.kernel.org/linux-mtd/20220107184614.2670254-7-f.fainelli@gmail.com --- MAINTAINERS | 1 + drivers/bcma/driver_chipcommon_nflash.c | 20 +++++++++++++++++++- include/linux/bcma/bcma_driver_chipcommon.h | 5 +++++ include/linux/platform_data/brcmnand.h | 12 ++++++++++++ 4 files changed, 37 insertions(+), 1 deletion(-) create mode 100644 include/linux/platform_data/brcmnand.h diff --git a/MAINTAINERS b/MAINTAINERS index ea3e6c914384..8a1c1e92937f 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -4021,6 +4021,7 @@ L: linux-mtd@lists.infradead.org L: bcm-kernel-feedback-list@broadcom.com S: Maintained F: drivers/mtd/nand/raw/brcmnand/ +F: include/linux/platform_data/brcmnand.h BROADCOM STB PCIE DRIVER M: Jim Quinlan diff --git a/drivers/bcma/driver_chipcommon_nflash.c b/drivers/bcma/driver_chipcommon_nflash.c index d4f699aef8c4..a1a814750b4a 100644 --- a/drivers/bcma/driver_chipcommon_nflash.c +++ b/drivers/bcma/driver_chipcommon_nflash.c @@ -7,18 +7,28 @@ #include "bcma_private.h" +#include #include +#include #include +/* Alternate NAND controller driver name in order to allow both bcm47xxnflash + * and bcma_brcmnand to be built into the same kernel image. + */ +static const char *bcma_nflash_alt_name = "bcma_brcmnand"; + struct platform_device bcma_nflash_dev = { .name = "bcma_nflash", .num_resources = 0, }; +static const char *probes[] = { "bcm47xxpart", NULL }; + /* Initialize NAND flash access */ int bcma_nflash_init(struct bcma_drv_cc *cc) { struct bcma_bus *bus = cc->core->bus; + u32 reg; if (bus->chipinfo.id != BCMA_CHIP_ID_BCM4706 && cc->core->id.rev != 38) { @@ -33,8 +43,16 @@ int bcma_nflash_init(struct bcma_drv_cc *cc) cc->nflash.present = true; if (cc->core->id.rev == 38 && - (cc->status & BCMA_CC_CHIPST_5357_NAND_BOOT)) + (cc->status & BCMA_CC_CHIPST_5357_NAND_BOOT)) { cc->nflash.boot = true; + /* Determine the chip select that is being used */ + reg = bcma_cc_read32(cc, BCMA_CC_NAND_CS_NAND_SELECT) & 0xff; + cc->nflash.brcmnand_info.chip_select = ffs(reg) - 1; + cc->nflash.brcmnand_info.part_probe_types = probes; + cc->nflash.brcmnand_info.ecc_stepsize = 512; + cc->nflash.brcmnand_info.ecc_strength = 1; + bcma_nflash_dev.name = bcma_nflash_alt_name; + } /* Prepare platform device, but don't register it yet. It's too early, * malloc (required by device_private_init) is not available yet. */ diff --git a/include/linux/bcma/bcma_driver_chipcommon.h b/include/linux/bcma/bcma_driver_chipcommon.h index d35b9206096d..e3314f746bfa 100644 --- a/include/linux/bcma/bcma_driver_chipcommon.h +++ b/include/linux/bcma/bcma_driver_chipcommon.h @@ -3,6 +3,7 @@ #define LINUX_BCMA_DRIVER_CC_H_ #include +#include #include /** ChipCommon core registers. **/ @@ -599,6 +600,10 @@ struct bcma_sflash { #ifdef CONFIG_BCMA_NFLASH struct bcma_nflash { + /* Must be the fist member for the brcmnand driver to + * de-reference that structure. + */ + struct brcmnand_platform_data brcmnand_info; bool present; bool boot; /* This is the flash the SoC boots from */ }; diff --git a/include/linux/platform_data/brcmnand.h b/include/linux/platform_data/brcmnand.h new file mode 100644 index 000000000000..8b8777985dce --- /dev/null +++ b/include/linux/platform_data/brcmnand.h @@ -0,0 +1,12 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +#ifndef BRCMNAND_PLAT_DATA_H +#define BRCMNAND_PLAT_DATA_H + +struct brcmnand_platform_data { + int chip_select; + const char * const *part_probe_types; + unsigned int ecc_stepsize; + unsigned int ecc_strength; +}; + +#endif /* BRCMNAND_PLAT_DATA_H */ From 8e5913005f7bfcebd1c67df63fb63bcbb3bfc302 Mon Sep 17 00:00:00 2001 From: Florian Fainelli Date: Fri, 7 Jan 2022 10:46:12 -0800 Subject: [PATCH 032/370] mtd: rawnand: brcmnand: Allow platform data instantation Make use of the recently refactored code in brcmnand_init_cs() and derive the chip-select from the platform data that is supplied. Update the various code paths to avoid relying on possibly non-existent resources, too. Signed-off-by: Florian Fainelli Signed-off-by: Miquel Raynal Link: https://lore.kernel.org/linux-mtd/20220107184614.2670254-8-f.fainelli@gmail.com --- drivers/mtd/nand/raw/brcmnand/brcmnand.c | 45 ++++++++++++++++++------ 1 file changed, 35 insertions(+), 10 deletions(-) diff --git a/drivers/mtd/nand/raw/brcmnand/brcmnand.c b/drivers/mtd/nand/raw/brcmnand/brcmnand.c index 08e2acde5133..eab19df152f3 100644 --- a/drivers/mtd/nand/raw/brcmnand/brcmnand.c +++ b/drivers/mtd/nand/raw/brcmnand/brcmnand.c @@ -9,6 +9,7 @@ #include #include #include +#include #include #include #include @@ -2768,7 +2769,8 @@ static const struct nand_controller_ops brcmnand_controller_ops = { .attach_chip = brcmnand_attach_chip, }; -static int brcmnand_init_cs(struct brcmnand_host *host) +static int brcmnand_init_cs(struct brcmnand_host *host, + const char * const *part_probe_types) { struct brcmnand_controller *ctrl = host->ctrl; struct device *dev = ctrl->dev; @@ -2821,7 +2823,7 @@ static int brcmnand_init_cs(struct brcmnand_host *host) if (ret) return ret; - ret = mtd_device_register(mtd, NULL, 0); + ret = mtd_device_parse_register(mtd, part_probe_types, NULL, NULL, 0); if (ret) nand_cleanup(chip); @@ -2990,17 +2992,15 @@ static int brcmnand_edu_setup(struct platform_device *pdev) int brcmnand_probe(struct platform_device *pdev, struct brcmnand_soc *soc) { + struct brcmnand_platform_data *pd = dev_get_platdata(&pdev->dev); struct device *dev = &pdev->dev; struct device_node *dn = dev->of_node, *child; struct brcmnand_controller *ctrl; + struct brcmnand_host *host; struct resource *res; int ret; - /* We only support device-tree instantiation */ - if (!dn) - return -ENODEV; - - if (!of_match_node(brcmnand_of_match, dn)) + if (dn && !of_match_node(brcmnand_of_match, dn)) return -ENODEV; ctrl = devm_kzalloc(dev, sizeof(*ctrl), GFP_KERNEL); @@ -3027,7 +3027,7 @@ int brcmnand_probe(struct platform_device *pdev, struct brcmnand_soc *soc) /* NAND register range */ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); ctrl->nand_base = devm_ioremap_resource(dev, res); - if (IS_ERR(ctrl->nand_base)) + if (IS_ERR(ctrl->nand_base) && !brcmnand_soc_has_ops(soc)) return PTR_ERR(ctrl->nand_base); /* Enable clock before using NAND registers */ @@ -3171,7 +3171,6 @@ int brcmnand_probe(struct platform_device *pdev, struct brcmnand_soc *soc) for_each_available_child_of_node(dn, child) { if (of_device_is_compatible(child, "brcm,nandcs")) { - struct brcmnand_host *host; host = devm_kzalloc(dev, sizeof(*host), GFP_KERNEL); if (!host) { @@ -3191,7 +3190,7 @@ int brcmnand_probe(struct platform_device *pdev, struct brcmnand_soc *soc) nand_set_flash_node(&host->chip, child); - ret = brcmnand_init_cs(host); + ret = brcmnand_init_cs(host, NULL); if (ret) { devm_kfree(dev, host); continue; /* Try all chip-selects */ @@ -3201,6 +3200,32 @@ int brcmnand_probe(struct platform_device *pdev, struct brcmnand_soc *soc) } } + if (!list_empty(&ctrl->host_list)) + return 0; + + if (!pd) { + ret = -ENODEV; + goto err; + } + + /* If we got there we must have been probing via platform data */ + host = devm_kzalloc(dev, sizeof(*host), GFP_KERNEL); + if (!host) { + ret = -ENOMEM; + goto err; + } + host->pdev = pdev; + host->ctrl = ctrl; + host->cs = pd->chip_select; + host->chip.ecc.size = pd->ecc_stepsize; + host->chip.ecc.strength = pd->ecc_strength; + + ret = brcmnand_init_cs(host, pd->part_probe_types); + if (ret) + goto err; + + list_add_tail(&host->node, &ctrl->host_list); + /* No chip-selects could initialize properly */ if (list_empty(&ctrl->host_list)) { ret = -ENODEV; From 5abd37f6e9d653b748a1acad7e0abcbe540e896a Mon Sep 17 00:00:00 2001 From: Florian Fainelli Date: Fri, 7 Jan 2022 10:46:13 -0800 Subject: [PATCH 033/370] mtd: rawnand: brcmnand: BCMA controller uses command shift of 0 For some odd and unexplained reason the BCMA NAND controller, albeit revision 3.4 uses a command shift of 0 instead of 24 as it should be, quirk that. Signed-off-by: Florian Fainelli Signed-off-by: Miquel Raynal Link: https://lore.kernel.org/linux-mtd/20220107184614.2670254-9-f.fainelli@gmail.com --- drivers/mtd/nand/raw/brcmnand/brcmnand.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/mtd/nand/raw/brcmnand/brcmnand.c b/drivers/mtd/nand/raw/brcmnand/brcmnand.c index eab19df152f3..4759303ece7c 100644 --- a/drivers/mtd/nand/raw/brcmnand/brcmnand.c +++ b/drivers/mtd/nand/raw/brcmnand/brcmnand.c @@ -916,6 +916,12 @@ static void brcmnand_wr_corr_thresh(struct brcmnand_host *host, u8 val) static inline int brcmnand_cmd_shift(struct brcmnand_controller *ctrl) { + /* Kludge for the BCMA-based NAND controller which does not actually + * shift the command + */ + if (ctrl->nand_version == 0x0304 && brcmnand_non_mmio_ops(ctrl)) + return 0; + if (ctrl->nand_version < 0x0602) return 24; return 0; From feca4cc4765a67907a97bddfa94aa6901cbbce7d Mon Sep 17 00:00:00 2001 From: Florian Fainelli Date: Fri, 7 Jan 2022 10:46:14 -0800 Subject: [PATCH 034/370] mtd: rawnand: brcmnand: Add BCMA shim Add a BCMA shim to allow us to register the brcmnand driver using the BCMA bus which provides indirect memory mapped access to SoC registers. There are a number of registers that need to be byte swapped because they are natively big endian, coming directly from the NAND chip, and there is no bus interface unlike the iProc or STB platforms that performs the byte swapping for us. Signed-off-by: Florian Fainelli Signed-off-by: Miquel Raynal Link: https://lore.kernel.org/linux-mtd/20220107184614.2670254-10-f.fainelli@gmail.com --- drivers/mtd/nand/raw/Kconfig | 13 +++ drivers/mtd/nand/raw/brcmnand/Makefile | 2 + drivers/mtd/nand/raw/brcmnand/bcma_nand.c | 132 ++++++++++++++++++++++ drivers/mtd/nand/raw/brcmnand/brcmnand.c | 4 + 4 files changed, 151 insertions(+) create mode 100644 drivers/mtd/nand/raw/brcmnand/bcma_nand.c diff --git a/drivers/mtd/nand/raw/Kconfig b/drivers/mtd/nand/raw/Kconfig index 20408b7db540..99141b14b059 100644 --- a/drivers/mtd/nand/raw/Kconfig +++ b/drivers/mtd/nand/raw/Kconfig @@ -209,6 +209,19 @@ config MTD_NAND_BRCMNAND originally designed for Set-Top Box but is used on various BCM7xxx, BCM3xxx, BCM63xxx, iProc/Cygnus and more. +if MTD_NAND_BRCMNAND + +config MTD_NAND_BRCMNAND_BCMA + tristate "Broadcom BCMA NAND controller" + depends on BCMA_NFLASH + depends on BCMA + help + Enables the BRCMNAND controller over BCMA on BCM47186/BCM5358 SoCs. + The glue driver will take care of performing the low-level I/O + operations to interface the BRCMNAND controller over the BCMA bus. + +endif # MTD_NAND_BRCMNAND + config MTD_NAND_BCM47XXNFLASH tristate "BCM4706 BCMA NAND controller" depends on BCMA_NFLASH diff --git a/drivers/mtd/nand/raw/brcmnand/Makefile b/drivers/mtd/nand/raw/brcmnand/Makefile index 195b845e48b8..16dc7254200e 100644 --- a/drivers/mtd/nand/raw/brcmnand/Makefile +++ b/drivers/mtd/nand/raw/brcmnand/Makefile @@ -6,3 +6,5 @@ obj-$(CONFIG_MTD_NAND_BRCMNAND) += bcm63138_nand.o obj-$(CONFIG_MTD_NAND_BRCMNAND) += bcm6368_nand.o obj-$(CONFIG_MTD_NAND_BRCMNAND) += brcmstb_nand.o obj-$(CONFIG_MTD_NAND_BRCMNAND) += brcmnand.o + +obj-$(CONFIG_MTD_NAND_BRCMNAND_BCMA) += bcma_nand.o diff --git a/drivers/mtd/nand/raw/brcmnand/bcma_nand.c b/drivers/mtd/nand/raw/brcmnand/bcma_nand.c new file mode 100644 index 000000000000..d7c62988c452 --- /dev/null +++ b/drivers/mtd/nand/raw/brcmnand/bcma_nand.c @@ -0,0 +1,132 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright © 2021 Broadcom + */ +#include +#include +#include +#include +#include + +#include "brcmnand.h" + +struct brcmnand_bcma_soc { + struct brcmnand_soc soc; + struct bcma_drv_cc *cc; +}; + +static inline bool brcmnand_bcma_needs_swapping(u32 offset) +{ + switch (offset) { + case BCMA_CC_NAND_SPARE_RD0: + case BCMA_CC_NAND_SPARE_RD4: + case BCMA_CC_NAND_SPARE_RD8: + case BCMA_CC_NAND_SPARE_RD12: + case BCMA_CC_NAND_SPARE_WR0: + case BCMA_CC_NAND_SPARE_WR4: + case BCMA_CC_NAND_SPARE_WR8: + case BCMA_CC_NAND_SPARE_WR12: + case BCMA_CC_NAND_DEVID: + case BCMA_CC_NAND_DEVID_X: + case BCMA_CC_NAND_SPARE_RD16: + case BCMA_CC_NAND_SPARE_RD20: + case BCMA_CC_NAND_SPARE_RD24: + case BCMA_CC_NAND_SPARE_RD28: + return true; + } + + return false; +} + +static inline struct brcmnand_bcma_soc *to_bcma_soc(struct brcmnand_soc *soc) +{ + return container_of(soc, struct brcmnand_bcma_soc, soc); +} + +static u32 brcmnand_bcma_read_reg(struct brcmnand_soc *soc, u32 offset) +{ + struct brcmnand_bcma_soc *sc = to_bcma_soc(soc); + u32 val; + + /* Offset into the NAND block and deal with the flash cache separately */ + if (offset == BRCMNAND_NON_MMIO_FC_ADDR) + offset = BCMA_CC_NAND_CACHE_DATA; + else + offset += BCMA_CC_NAND_REVISION; + + val = bcma_cc_read32(sc->cc, offset); + + /* Swap if necessary */ + if (brcmnand_bcma_needs_swapping(offset)) + val = be32_to_cpu(val); + return val; +} + +static void brcmnand_bcma_write_reg(struct brcmnand_soc *soc, u32 val, + u32 offset) +{ + struct brcmnand_bcma_soc *sc = to_bcma_soc(soc); + + /* Offset into the NAND block */ + if (offset == BRCMNAND_NON_MMIO_FC_ADDR) + offset = BCMA_CC_NAND_CACHE_DATA; + else + offset += BCMA_CC_NAND_REVISION; + + /* Swap if necessary */ + if (brcmnand_bcma_needs_swapping(offset)) + val = cpu_to_be32(val); + + bcma_cc_write32(sc->cc, offset, val); +} + +static struct brcmnand_io_ops brcmnand_bcma_io_ops = { + .read_reg = brcmnand_bcma_read_reg, + .write_reg = brcmnand_bcma_write_reg, +}; + +static void brcmnand_bcma_prepare_data_bus(struct brcmnand_soc *soc, bool prepare, + bool is_param) +{ + struct brcmnand_bcma_soc *sc = to_bcma_soc(soc); + + /* Reset the cache address to ensure we are already accessing the + * beginning of a sub-page. + */ + bcma_cc_write32(sc->cc, BCMA_CC_NAND_CACHE_ADDR, 0); +} + +static int brcmnand_bcma_nand_probe(struct platform_device *pdev) +{ + struct bcma_nflash *nflash = dev_get_platdata(&pdev->dev); + struct brcmnand_bcma_soc *soc; + + soc = devm_kzalloc(&pdev->dev, sizeof(*soc), GFP_KERNEL); + if (!soc) + return -ENOMEM; + + soc->cc = container_of(nflash, struct bcma_drv_cc, nflash); + soc->soc.prepare_data_bus = brcmnand_bcma_prepare_data_bus; + soc->soc.ops = &brcmnand_bcma_io_ops; + + if (soc->cc->core->bus->chipinfo.id == BCMA_CHIP_ID_BCM4706) { + dev_err(&pdev->dev, "Use bcm47xxnflash for 4706!\n"); + return -ENODEV; + } + + return brcmnand_probe(pdev, &soc->soc); +} + +static struct platform_driver brcmnand_bcma_nand_driver = { + .probe = brcmnand_bcma_nand_probe, + .remove = brcmnand_remove, + .driver = { + .name = "bcma_brcmnand", + .pm = &brcmnand_pm_ops, + } +}; +module_platform_driver(brcmnand_bcma_nand_driver); + +MODULE_LICENSE("GPL v2"); +MODULE_AUTHOR("Broadcom"); +MODULE_DESCRIPTION("NAND controller driver glue for BCMA chips"); diff --git a/drivers/mtd/nand/raw/brcmnand/brcmnand.c b/drivers/mtd/nand/raw/brcmnand/brcmnand.c index 4759303ece7c..c412f79b81db 100644 --- a/drivers/mtd/nand/raw/brcmnand/brcmnand.c +++ b/drivers/mtd/nand/raw/brcmnand/brcmnand.c @@ -598,7 +598,11 @@ enum { static inline bool brcmnand_non_mmio_ops(struct brcmnand_controller *ctrl) { +#if IS_ENABLED(CONFIG_MTD_NAND_BRCMNAND_BCMA) return static_branch_unlikely(&brcmnand_soc_has_ops_key); +#else + return false; +#endif } static inline u32 nand_readreg(struct brcmnand_controller *ctrl, u32 offs) From 7f852ec58af6ce8d7c6fc799b82d45d76e4bd994 Mon Sep 17 00:00:00 2001 From: Patrick Williams Date: Wed, 29 Dec 2021 08:33:33 -0600 Subject: [PATCH 035/370] mtd: aspeed-smc: improve probe resilience The aspeed-smc can have multiple SPI devices attached to it in the device tree. If one of the devices is missing or failing the entire probe will fail and all MTD devices under the controller will be removed. On OpenBMC this results in a kernel panic due to missing rootfs: [ 0.538774] aspeed-smc 1e620000.spi: Using 50 MHz SPI frequency [ 0.540471] aspeed-smc 1e620000.spi: w25q01jv-iq (131072 Kbytes) [ 0.540750] aspeed-smc 1e620000.spi: CE0 window [ 0x20000000 - 0x28000000 ] 128MB [ 0.540943] aspeed-smc 1e620000.spi: CE1 window [ 0x28000000 - 0x2c000000 ] 64MB [ 0.541143] aspeed-smc 1e620000.spi: read control register: 203b0041 [ 0.581442] 5 fixed-partitions partitions found on MTD device bmc [ 0.581625] Creating 5 MTD partitions on "bmc": [ 0.581854] 0x000000000000-0x0000000e0000 : "u-boot" [ 0.584472] 0x0000000e0000-0x000000100000 : "u-boot-env" [ 0.586468] 0x000000100000-0x000000a00000 : "kernel" [ 0.588465] 0x000000a00000-0x000006000000 : "rofs" [ 0.590552] 0x000006000000-0x000008000000 : "rwfs" [ 0.592605] aspeed-smc 1e620000.spi: Using 50 MHz SPI frequency [ 0.592801] aspeed-smc 1e620000.spi: unrecognized JEDEC id bytes: 00 00 00 00 00 00 [ 0.593039] Deleting MTD partitions on "bmc": [ 0.593175] Deleting u-boot MTD partition [ 0.637929] Deleting u-boot-env MTD partition [ 0.829527] Deleting kernel MTD partition [ 0.856902] Freeing initrd memory: 1032K [ 0.866428] Deleting rofs MTD partition [ 0.906264] Deleting rwfs MTD partition [ 0.986628] aspeed-smc 1e620000.spi: Aspeed SMC probe failed -2 [ 0.986929] aspeed-smc: probe of 1e620000.spi failed with error -2 ... [ 2.936719] /dev/mtdblock: Can't open blockdev mount: mounting /dev/mtdblock on run/initramfs/ro failed: No such file or directory [ 2.963030] MTD: Couldn't look up '/dev/mtdblock': -2 mount: mounting /dev/mtdblock on run/initramfs/rw failed: No such file or directory Mounting read-write /dev/mtdblock filesystem failed. Please fix and run mount /dev/mtdblock run/initramfs/rw -t jffs2 -o rw or perform a factory reset with the clean-rwfs-filesystem option. Fatal error, triggering kernel panic! [ 3.013047] Kernel panic - not syncing: Attempted to kill init! exitcode=0x00000100 Many BMC designs have two flash chips so that they can handle a hardware failure of one of them. If one chip failed, it doesn't do any good to have redundancy if they all get removed anyhow. Improve the resilience of the probe function to handle one of the children being missing or failed. Only in the case where all children fail to probe should the controller be failed out. Signed-off-by: Patrick Williams Signed-off-by: Miquel Raynal Link: https://lore.kernel.org/linux-mtd/20211229143334.297305-1-patrick@stwcx.xyz --- drivers/mtd/spi-nor/controllers/aspeed-smc.c | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/drivers/mtd/spi-nor/controllers/aspeed-smc.c b/drivers/mtd/spi-nor/controllers/aspeed-smc.c index 7225870e8b18..acfe010f9dd7 100644 --- a/drivers/mtd/spi-nor/controllers/aspeed-smc.c +++ b/drivers/mtd/spi-nor/controllers/aspeed-smc.c @@ -769,6 +769,7 @@ static int aspeed_smc_setup_flash(struct aspeed_smc_controller *controller, struct device_node *child; unsigned int cs; int ret = -ENODEV; + bool found_one = false; for_each_available_child_of_node(np, child) { struct aspeed_smc_chip *chip; @@ -827,8 +828,17 @@ static int aspeed_smc_setup_flash(struct aspeed_smc_controller *controller, * by of property. */ ret = spi_nor_scan(nor, NULL, &hwcaps); - if (ret) - break; + /* + * If we fail to scan the device it might not be present or + * broken. Don't fail the whole controller if others work. + */ + if (ret) { + if (found_one) + ret = 0; + + devm_kfree(controller->dev, chip); + continue; + } ret = aspeed_smc_chip_setup_finish(chip); if (ret) @@ -839,6 +849,7 @@ static int aspeed_smc_setup_flash(struct aspeed_smc_controller *controller, break; controller->chips[cs] = chip; + found_one = true; } if (ret) { From 2970bf5a32f079e1e9197411db4fe9faccb1503a Mon Sep 17 00:00:00 2001 From: Dario Binacchi Date: Tue, 18 Jan 2022 10:54:32 +0100 Subject: [PATCH 036/370] mtd: rawnand: gpmi: fix controller timings setting Set the controller registers according to the real clock rate. The controller registers configuration (setup, hold, timeout, ... cycles) depends on the clock rate of the GPMI. Using the real rate instead of the ideal one, avoids that this inaccuracy (required_rate - real_rate) affects the registers setting. This patch has been tested on two custom boards with i.MX28 and i.MX6 SOCs: - i.MX28: required rate 100MHz, real rate 99.3MHz - i.MX6 required rate 100MHz, real rate 99MHz Fixes: b1206122069a ("mtd: rawnand: gpmi: use core timings instead of an empirical derivation") Co-developed-by: Michael Trimarchi Signed-off-by: Michael Trimarchi Signed-off-by: Dario Binacchi Tested-by: Sascha Hauer Reviewed-by: Sascha Hauer Signed-off-by: Miquel Raynal Link: https://lore.kernel.org/linux-mtd/20220118095434.35081-3-dario.binacchi@amarulasolutions.com --- drivers/mtd/nand/raw/gpmi-nand/gpmi-nand.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/mtd/nand/raw/gpmi-nand/gpmi-nand.c b/drivers/mtd/nand/raw/gpmi-nand/gpmi-nand.c index 1b64c5a5140d..73c3bf59b55e 100644 --- a/drivers/mtd/nand/raw/gpmi-nand/gpmi-nand.c +++ b/drivers/mtd/nand/raw/gpmi-nand/gpmi-nand.c @@ -648,6 +648,7 @@ static void gpmi_nfc_compute_timings(struct gpmi_nand_data *this, const struct nand_sdr_timings *sdr) { struct gpmi_nfc_hardware_timing *hw = &this->hw; + struct resources *r = &this->resources; unsigned int dll_threshold_ps = this->devdata->max_chain_delay; unsigned int period_ps, reference_period_ps; unsigned int data_setup_cycles, data_hold_cycles, addr_setup_cycles; @@ -671,6 +672,8 @@ static void gpmi_nfc_compute_timings(struct gpmi_nand_data *this, wrn_dly_sel = BV_GPMI_CTRL1_WRN_DLY_SEL_NO_DELAY; } + hw->clk_rate = clk_round_rate(r->clock[0], hw->clk_rate); + /* SDR core timings are given in picoseconds */ period_ps = div_u64((u64)NSEC_PER_SEC * 1000, hw->clk_rate); From 15e27d197a7ea69b4643791ca2f8467fdd998359 Mon Sep 17 00:00:00 2001 From: Dario Binacchi Date: Tue, 18 Jan 2022 10:54:33 +0100 Subject: [PATCH 037/370] mtd: rawnand: gpmi: validate controller clock rate What to do when the real rate of the gpmi clock is not equal to the required one? The solutions proposed in [1] did not lead to a conclusion on how to validate the clock rate, so, inspired by the document [2], I consider the rate correct only if not lower or equal to the rate of the previous edo mode. In fact, in chapter 4.16.2 (NV-DDR) of the document [2], it is written that "If the host selects timing mode n, then its clock period shall be faster than the clock period of timing mode n-1 and slower than or equal to the clock period of timing mode n.". I thought that it could therefore also be used in this case, without therefore having to define the valid rate ranges empirically. For example, suppose that gpmi_nfc_compute_timings() is called to set edo mode 5 (100MHz) but the rate returned by clk_round_rate() is 80MHz (edo mode 4). In this case gpmi_nfc_compute_timings() will return error, and will be called again to set edo mode 4, which this time will be successful. [1] https://lore.kernel.org/r/20210702065350.209646-5-ebiggers@kernel.org [2] http://www.onfi.org/-/media/client/onfi/specs/onfi_3_0_gold.pdf?la=en Co-developed-by: Michael Trimarchi Signed-off-by: Michael Trimarchi Signed-off-by: Dario Binacchi Tested-by: Sascha Hauer Reviewed-by: Sascha Hauer Signed-off-by: Miquel Raynal Link: https://lore.kernel.org/linux-mtd/20220118095434.35081-4-dario.binacchi@amarulasolutions.com --- drivers/mtd/nand/raw/gpmi-nand/gpmi-nand.c | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/drivers/mtd/nand/raw/gpmi-nand/gpmi-nand.c b/drivers/mtd/nand/raw/gpmi-nand/gpmi-nand.c index 73c3bf59b55e..cf35f4206030 100644 --- a/drivers/mtd/nand/raw/gpmi-nand/gpmi-nand.c +++ b/drivers/mtd/nand/raw/gpmi-nand/gpmi-nand.c @@ -644,8 +644,8 @@ err_out: * RDN_DELAY = ----------------------- {3} * RP */ -static void gpmi_nfc_compute_timings(struct gpmi_nand_data *this, - const struct nand_sdr_timings *sdr) +static int gpmi_nfc_compute_timings(struct gpmi_nand_data *this, + const struct nand_sdr_timings *sdr) { struct gpmi_nfc_hardware_timing *hw = &this->hw; struct resources *r = &this->resources; @@ -657,23 +657,33 @@ static void gpmi_nfc_compute_timings(struct gpmi_nand_data *this, int sample_delay_ps, sample_delay_factor; u16 busy_timeout_cycles; u8 wrn_dly_sel; + unsigned long clk_rate, min_rate; if (sdr->tRC_min >= 30000) { /* ONFI non-EDO modes [0-3] */ hw->clk_rate = 22000000; + min_rate = 0; wrn_dly_sel = BV_GPMI_CTRL1_WRN_DLY_SEL_4_TO_8NS; } else if (sdr->tRC_min >= 25000) { /* ONFI EDO mode 4 */ hw->clk_rate = 80000000; + min_rate = 22000000; wrn_dly_sel = BV_GPMI_CTRL1_WRN_DLY_SEL_NO_DELAY; } else { /* ONFI EDO mode 5 */ hw->clk_rate = 100000000; + min_rate = 80000000; wrn_dly_sel = BV_GPMI_CTRL1_WRN_DLY_SEL_NO_DELAY; } - hw->clk_rate = clk_round_rate(r->clock[0], hw->clk_rate); + clk_rate = clk_round_rate(r->clock[0], hw->clk_rate); + if (clk_rate <= min_rate) { + dev_err(this->dev, "clock setting: expected %ld, got %ld\n", + hw->clk_rate, clk_rate); + return -ENOTSUPP; + } + hw->clk_rate = clk_rate; /* SDR core timings are given in picoseconds */ period_ps = div_u64((u64)NSEC_PER_SEC * 1000, hw->clk_rate); @@ -714,6 +724,7 @@ static void gpmi_nfc_compute_timings(struct gpmi_nand_data *this, hw->ctrl1n |= BF_GPMI_CTRL1_RDN_DELAY(sample_delay_factor) | BM_GPMI_CTRL1_DLL_ENABLE | (use_half_period ? BM_GPMI_CTRL1_HALF_PERIOD : 0); + return 0; } static int gpmi_nfc_apply_timings(struct gpmi_nand_data *this) @@ -769,6 +780,7 @@ static int gpmi_setup_interface(struct nand_chip *chip, int chipnr, { struct gpmi_nand_data *this = nand_get_controller_data(chip); const struct nand_sdr_timings *sdr; + int ret; /* Retrieve required NAND timings */ sdr = nand_get_sdr_timings(conf); @@ -784,7 +796,9 @@ static int gpmi_setup_interface(struct nand_chip *chip, int chipnr, return 0; /* Do the actual derivation of the controller timings */ - gpmi_nfc_compute_timings(this, sdr); + ret = gpmi_nfc_compute_timings(this, sdr); + if (ret) + return ret; this->hw.must_apply_timings = true; From ac178a21754cf720b27e82965c2f11e71e9e5968 Mon Sep 17 00:00:00 2001 From: Dario Binacchi Date: Tue, 18 Jan 2022 10:54:34 +0100 Subject: [PATCH 038/370] mtd: rawnand: gpmi: support fast edo timings for mx28 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In the i.MX28 manual (MCIMX28RM, Rev. 1, 2010) you can find an example (15.2.4 High-Speed NAND Timing) of how to configure the GPMI controller to manage High-Speed ​​NAND devices, so it was wrong to assume that only i.MX6 can achieve EDO timings. This patch has been tested on a 2048/64 byte NAND (Micron MT29F2G08ABAEAH4). Kernel mtd tests: - mtd_nandbiterrs - mtd_nandecctest - mtd_oobtest - mtd_pagetest - mtd_readtest - mtd_speedtest - mtd_stresstest - mtd_subpagetest - mtd_torturetest [cycles_count = 10000000] run without errors. Before this patch (mode 0): --------------------------- eraseblock write speed is 2098 KiB/s eraseblock read speed is 2680 KiB/s page write speed is 1689 KiB/s page read speed is 2522 KiB/s 2 page write speed is 1899 KiB/s 2 page read speed is 2579 KiB/s erase speed is 128000 KiB/s 2x multi-block erase speed is 73142 KiB/s 4x multi-block erase speed is 204800 KiB/s 8x multi-block erase speed is 256000 KiB/s 16x multi-block erase speed is 256000 KiB/s 32x multi-block erase speed is 256000 KiB/s 64x multi-block erase speed is 256000 KiB/s After this patch (mode 5): ------------------------- eraseblock write speed is 3390 KiB/s eraseblock read speed is 5688 KiB/s page write speed is 2680 KiB/s page read speed is 4876 KiB/s 2 page write speed is 2909 KiB/s 2 page read speed is 5224 KiB/s erase speed is 170666 KiB/s 2x multi-block erase speed is 204800 KiB/s 4x multi-block erase speed is 256000 KiB/s 8x multi-block erase speed is 256000 KiB/s 16x multi-block erase speed is 256000 KiB/s 32x multi-block erase speed is 256000 KiB/s 64x multi-block erase speed is 256000 KiB/s Co-developed-by: Michael Trimarchi Signed-off-by: Michael Trimarchi Signed-off-by: Dario Binacchi Tested-by: Sascha Hauer Reviewed-by: Sascha Hauer Signed-off-by: Miquel Raynal Link: https://lore.kernel.org/linux-mtd/20220118095434.35081-5-dario.binacchi@amarulasolutions.com --- drivers/mtd/nand/raw/gpmi-nand/gpmi-nand.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/mtd/nand/raw/gpmi-nand/gpmi-nand.c b/drivers/mtd/nand/raw/gpmi-nand/gpmi-nand.c index cf35f4206030..d96899fa90b7 100644 --- a/drivers/mtd/nand/raw/gpmi-nand/gpmi-nand.c +++ b/drivers/mtd/nand/raw/gpmi-nand/gpmi-nand.c @@ -787,8 +787,8 @@ static int gpmi_setup_interface(struct nand_chip *chip, int chipnr, if (IS_ERR(sdr)) return PTR_ERR(sdr); - /* Only MX6 GPMI controller can reach EDO timings */ - if (sdr->tRC_min <= 25000 && !GPMI_IS_MX6(this)) + /* Only MX28/MX6 GPMI controller can reach EDO timings */ + if (sdr->tRC_min <= 25000 && !GPMI_IS_MX28(this) && !GPMI_IS_MX6(this)) return -ENOTSUPP; /* Stop here if this call was just a check */ From 2212c19e51969213924ab538396b6c1e072c41f1 Mon Sep 17 00:00:00 2001 From: Colin Ian King Date: Tue, 21 Dec 2021 18:13:40 +0000 Subject: [PATCH 039/370] mtd: rawnand: omap_elm: remove redundant variable 'errors' The variable 'errors' is being used to sum the number of errors but it is never used afterwards. This can be considered a redundant set of operations and can be removed. Signed-off-by: Colin Ian King Signed-off-by: Miquel Raynal Link: https://lore.kernel.org/linux-mtd/20211221181340.524639-1-colin.i.king@gmail.com --- drivers/mtd/nand/raw/omap_elm.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/mtd/nand/raw/omap_elm.c b/drivers/mtd/nand/raw/omap_elm.c index db105d9b560c..893e9979c4a2 100644 --- a/drivers/mtd/nand/raw/omap_elm.c +++ b/drivers/mtd/nand/raw/omap_elm.c @@ -282,7 +282,7 @@ static void elm_start_processing(struct elm_info *info, static void elm_error_correction(struct elm_info *info, struct elm_errorvec *err_vec) { - int i, j, errors = 0; + int i, j; int offset; u32 reg_val; @@ -312,8 +312,6 @@ static void elm_error_correction(struct elm_info *info, /* Update error location register */ offset += 4; } - - errors += err_vec[i].error_count; } else { err_vec[i].error_uncorrectable = true; } From d430e4acd99f3f2cd5fa30fa6e27dd39261cc967 Mon Sep 17 00:00:00 2001 From: Florian Fainelli Date: Tue, 25 Jan 2022 14:52:43 -0800 Subject: [PATCH 040/370] mtd: rawnand: brcmnand: Fix sparse warnings in bcma_nand sparse was unhappy about the way we woulc call cpu_to_be32/be32_to_cpu, apply the appropriate casting to silence the warnings. Reported-by: kernel test robot Link: https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org/thread/ZNHPJFYLO64EGI5QUT7HZ63J7O5J2G7N/ Signed-off-by: Florian Fainelli Signed-off-by: Miquel Raynal Link: https://lore.kernel.org/linux-mtd/20220125225243.15201-1-f.fainelli@gmail.com --- drivers/mtd/nand/raw/brcmnand/bcma_nand.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/mtd/nand/raw/brcmnand/bcma_nand.c b/drivers/mtd/nand/raw/brcmnand/bcma_nand.c index d7c62988c452..dd27977919fb 100644 --- a/drivers/mtd/nand/raw/brcmnand/bcma_nand.c +++ b/drivers/mtd/nand/raw/brcmnand/bcma_nand.c @@ -58,7 +58,7 @@ static u32 brcmnand_bcma_read_reg(struct brcmnand_soc *soc, u32 offset) /* Swap if necessary */ if (brcmnand_bcma_needs_swapping(offset)) - val = be32_to_cpu(val); + val = be32_to_cpu((__force __be32)val); return val; } @@ -75,7 +75,7 @@ static void brcmnand_bcma_write_reg(struct brcmnand_soc *soc, u32 val, /* Swap if necessary */ if (brcmnand_bcma_needs_swapping(offset)) - val = cpu_to_be32(val); + val = (__force u32)cpu_to_be32(val); bcma_cc_write32(sc->cc, offset, val); } From ca6263a0c9503d98b5aef04ed9b0f3971c66ec4e Mon Sep 17 00:00:00 2001 From: David Decotigny Date: Wed, 26 Jan 2022 02:11:20 -0800 Subject: [PATCH 041/370] mtd_blkdevs: avoid soft lockups with some mtd/spi devices With some spi devices, the heavy cpu usage due to polling the spi registers may lead to netdev timeouts, RCU complaints, etc. This can be acute in the absence of CONFIG_PREEMPT. This patch allows to give enough breathing room to avoid those incorrectly detected netdev timeouts for example. Example splat on 5.10.92: [ 828.399306] rcu: INFO: rcu_sched self-detected stall on CPU ... [ 828.419245] Task dump for CPU 1: [ 828.422465] task:kworker/1:1H state:R running task on cpu 1 stack: 0 pid: 76 ppid: 2 flags:0x0000002a [ 828.433132] Workqueue: kblockd blk_mq_run_work_fn [ 828.437820] Call trace: ... [ 828.512267] spi_mem_exec_op+0x4d0/0xde0 [ 828.516184] spi_mem_dirmap_read+0x180/0x39c [ 828.520443] spi_nor_read_data+0x428/0x7e8 [ 828.524523] spi_nor_read+0x154/0x214 [ 828.528172] mtd_read_oob+0x440/0x714 [ 828.531815] mtd_read+0xac/0x120 [ 828.535030] mtdblock_readsect+0x178/0x230 [ 828.539102] mtd_blktrans_work+0x9fc/0xf28 [ 828.543177] mtd_queue_rq+0x1ac/0x2e4 [ 828.546827] blk_mq_dispatch_rq_list+0x2cc/0xa44 [ 828.551419] blk_mq_do_dispatch_sched+0xb0/0x7cc [ 828.556010] __blk_mq_sched_dispatch_requests+0x350/0x494 [ 828.561372] blk_mq_sched_dispatch_requests+0xac/0xe4 [ 828.566387] __blk_mq_run_hw_queue+0x130/0x254 [ 828.570806] blk_mq_run_work_fn+0x50/0x60 [ 828.574814] process_one_work+0x578/0xf1c [ 828.578814] worker_thread+0x5dc/0xea0 [ 828.582547] kthread+0x270/0x2d4 [ 828.585765] ret_from_fork+0x10/0x30 Signed-off-by: David Decotigny Reviewed-by: Richard Weinberger Signed-off-by: Miquel Raynal Link: https://lore.kernel.org/linux-mtd/20220126101120.676021-1-decot+git@google.com --- drivers/mtd/mtd_blkdevs.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/mtd/mtd_blkdevs.c b/drivers/mtd/mtd_blkdevs.c index 243f28a3206b..64d2b093f114 100644 --- a/drivers/mtd/mtd_blkdevs.c +++ b/drivers/mtd/mtd_blkdevs.c @@ -158,6 +158,7 @@ static void mtd_blktrans_work(struct mtd_blktrans_dev *dev) } background_done = 0; + cond_resched(); spin_lock_irq(&dev->queue_lock); } } From ca0acb511c21738b32386ce0f85c284b351d919e Mon Sep 17 00:00:00 2001 From: Akhil R Date: Fri, 28 Jan 2022 17:14:25 +0530 Subject: [PATCH 042/370] device property: Add fwnode_irq_get_byname Add fwnode_irq_get_byname() to get an interrupt by name from either ACPI table or Device Tree, whichever is used for enumeration. In the ACPI case, this allow us to use 'interrupt-names' in _DSD which can be mapped to Interrupt() resource by index. The implementation is similar to 'interrupt-names' in the Device Tree. Signed-off-by: Akhil R Reviewed-by: Andy Shevchenko Acked-by: Rafael J. Wysocki Signed-off-by: Wolfram Sang --- drivers/base/property.c | 29 +++++++++++++++++++++++++++++ include/linux/property.h | 1 + 2 files changed, 30 insertions(+) diff --git a/drivers/base/property.c b/drivers/base/property.c index e6497f6877ee..fc59e0f7f9cc 100644 --- a/drivers/base/property.c +++ b/drivers/base/property.c @@ -935,6 +935,35 @@ void __iomem *fwnode_iomap(struct fwnode_handle *fwnode, int index) } EXPORT_SYMBOL(fwnode_iomap); +/** + * fwnode_irq_get_byname - Get IRQ from a fwnode using its name + * @fwnode: Pointer to the firmware node + * @name: IRQ name + * + * Description: + * Find a match to the string @name in the 'interrupt-names' string array + * in _DSD for ACPI, or of_node for Device Tree. Then get the Linux IRQ + * number of the IRQ resource corresponding to the index of the matched + * string. + * + * Return: + * Linux IRQ number on success, or negative errno otherwise. + */ +int fwnode_irq_get_byname(const struct fwnode_handle *fwnode, const char *name) +{ + int index; + + if (!name) + return -EINVAL; + + index = fwnode_property_match_string(fwnode, "interrupt-names", name); + if (index < 0) + return index; + + return fwnode_irq_get(fwnode, index); +} +EXPORT_SYMBOL(fwnode_irq_get_byname); + /** * fwnode_graph_get_next_endpoint - Get next endpoint firmware node * @fwnode: Pointer to the parent firmware node diff --git a/include/linux/property.h b/include/linux/property.h index 7399a0b45f98..95d56a562b6a 100644 --- a/include/linux/property.h +++ b/include/linux/property.h @@ -121,6 +121,7 @@ struct fwnode_handle *fwnode_handle_get(struct fwnode_handle *fwnode); void fwnode_handle_put(struct fwnode_handle *fwnode); int fwnode_irq_get(const struct fwnode_handle *fwnode, unsigned int index); +int fwnode_irq_get_byname(const struct fwnode_handle *fwnode, const char *name); void __iomem *fwnode_iomap(struct fwnode_handle *fwnode, int index); From 20e8ef5c7ffaa4c1d5f65727c536ffaf37078d5f Mon Sep 17 00:00:00 2001 From: Akhil R Date: Fri, 28 Jan 2022 17:14:26 +0530 Subject: [PATCH 043/370] docs: firmware-guide: ACPI: Add named interrupt doc Add a detailed example of the named interrupts in the ACPI table. Signed-off-by: Akhil R Reviewed-by: Andy Shevchenko Acked-by: Rafael J. Wysocki Signed-off-by: Wolfram Sang --- .../firmware-guide/acpi/enumeration.rst | 39 +++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/Documentation/firmware-guide/acpi/enumeration.rst b/Documentation/firmware-guide/acpi/enumeration.rst index 74b830b2fd59..d0022567c022 100644 --- a/Documentation/firmware-guide/acpi/enumeration.rst +++ b/Documentation/firmware-guide/acpi/enumeration.rst @@ -143,6 +143,45 @@ In robust cases the client unfortunately needs to call acpi_dma_request_slave_chan_by_index() directly and therefore choose the specific FixedDMA resource by its index. +Named Interrupts +================ + +Drivers enumerated via ACPI can have names to interrupts in the ACPI table +which can be used to get the IRQ number in the driver. + +The interrupt name can be listed in _DSD as 'interrupt-names'. The names +should be listed as an array of strings which will map to the Interrupt() +resource in the ACPI table corresponding to its index. + +The table below shows an example of its usage:: + + Device (DEV0) { + ... + Name (_CRS, ResourceTemplate() { + ... + Interrupt (ResourceConsumer, Level, ActiveHigh, Exclusive) { + 0x20, + 0x24 + } + }) + + Name (_DSD, Package () { + ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"), + Package () { + Package () {"interrupt-names", + Package (2) {"default", "alert"}}, + } + ... + }) + } + +The interrupt name 'default' will correspond to 0x20 in Interrupt() +resource and 'alert' to 0x24. Note that only the Interrupt() resource +is mapped and not GpioInt() or similar. + +The driver can call the function - fwnode_irq_get_byname() with the fwnode +and interrupt name as arguments to get the corresponding IRQ number. + SPI serial bus support ====================== From a263a84088f689bf0c1552a510b25d0bcc45fcae Mon Sep 17 00:00:00 2001 From: Akhil R Date: Fri, 28 Jan 2022 17:14:27 +0530 Subject: [PATCH 044/370] i2c: smbus: Use device_*() functions instead of of_*() Change of_*() functions to device_*() for firmware agnostic usage. This allows to have the smbus_alert interrupt without any changes in the controller drivers using the ACPI table. Signed-off-by: Akhil R Reviewed-by: Andy Shevchenko Signed-off-by: Wolfram Sang --- drivers/i2c/i2c-core-base.c | 2 +- drivers/i2c/i2c-core-smbus.c | 11 ++++++----- drivers/i2c/i2c-smbus.c | 5 +++-- include/linux/i2c-smbus.h | 6 +++--- 4 files changed, 13 insertions(+), 11 deletions(-) diff --git a/drivers/i2c/i2c-core-base.c b/drivers/i2c/i2c-core-base.c index 2c59dd748a49..32a45260c1f3 100644 --- a/drivers/i2c/i2c-core-base.c +++ b/drivers/i2c/i2c-core-base.c @@ -1479,7 +1479,7 @@ static int i2c_register_adapter(struct i2c_adapter *adap) goto out_list; } - res = of_i2c_setup_smbus_alert(adap); + res = i2c_setup_smbus_alert(adap); if (res) goto out_reg; diff --git a/drivers/i2c/i2c-core-smbus.c b/drivers/i2c/i2c-core-smbus.c index e5b2d1465e7e..304c2c8fee68 100644 --- a/drivers/i2c/i2c-core-smbus.c +++ b/drivers/i2c/i2c-core-smbus.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include "i2c-core.h" @@ -701,13 +702,13 @@ struct i2c_client *i2c_new_smbus_alert_device(struct i2c_adapter *adapter, } EXPORT_SYMBOL_GPL(i2c_new_smbus_alert_device); -#if IS_ENABLED(CONFIG_I2C_SMBUS) && IS_ENABLED(CONFIG_OF) -int of_i2c_setup_smbus_alert(struct i2c_adapter *adapter) +#if IS_ENABLED(CONFIG_I2C_SMBUS) +int i2c_setup_smbus_alert(struct i2c_adapter *adapter) { int irq; - irq = of_property_match_string(adapter->dev.of_node, "interrupt-names", - "smbus_alert"); + irq = device_property_match_string(adapter->dev.parent, "interrupt-names", + "smbus_alert"); if (irq == -EINVAL || irq == -ENODATA) return 0; else if (irq < 0) @@ -715,5 +716,5 @@ int of_i2c_setup_smbus_alert(struct i2c_adapter *adapter) return PTR_ERR_OR_ZERO(i2c_new_smbus_alert_device(adapter, NULL)); } -EXPORT_SYMBOL_GPL(of_i2c_setup_smbus_alert); +EXPORT_SYMBOL_GPL(i2c_setup_smbus_alert); #endif diff --git a/drivers/i2c/i2c-smbus.c b/drivers/i2c/i2c-smbus.c index d3d06e3b4f3b..775332945ad0 100644 --- a/drivers/i2c/i2c-smbus.c +++ b/drivers/i2c/i2c-smbus.c @@ -13,7 +13,7 @@ #include #include #include -#include +#include #include #include @@ -128,7 +128,8 @@ static int smbalert_probe(struct i2c_client *ara, if (setup) { irq = setup->irq; } else { - irq = of_irq_get_byname(adapter->dev.of_node, "smbus_alert"); + irq = fwnode_irq_get_byname(dev_fwnode(adapter->dev.parent), + "smbus_alert"); if (irq <= 0) return irq; } diff --git a/include/linux/i2c-smbus.h b/include/linux/i2c-smbus.h index 1ef421818d3a..95cf902e0bda 100644 --- a/include/linux/i2c-smbus.h +++ b/include/linux/i2c-smbus.h @@ -30,10 +30,10 @@ struct i2c_client *i2c_new_smbus_alert_device(struct i2c_adapter *adapter, struct i2c_smbus_alert_setup *setup); int i2c_handle_smbus_alert(struct i2c_client *ara); -#if IS_ENABLED(CONFIG_I2C_SMBUS) && IS_ENABLED(CONFIG_OF) -int of_i2c_setup_smbus_alert(struct i2c_adapter *adap); +#if IS_ENABLED(CONFIG_I2C_SMBUS) +int i2c_setup_smbus_alert(struct i2c_adapter *adap); #else -static inline int of_i2c_setup_smbus_alert(struct i2c_adapter *adap) +static inline int i2c_setup_smbus_alert(struct i2c_adapter *adap) { return 0; } From f244cdce52de05711d3a0e9aaa7303ef28f43f82 Mon Sep 17 00:00:00 2001 From: Kewei Xu Date: Tue, 25 Jan 2022 19:04:12 +0800 Subject: [PATCH 045/370] dt-bindings: i2c: update bindings for MT8186 SoC Add a DT binding documentation for the MT8186 soc. Signed-off-by: Kewei Xu Acked-by: Rob Herring Reviewed-by: Qii Wang Signed-off-by: Wolfram Sang --- Documentation/devicetree/bindings/i2c/i2c-mt65xx.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/Documentation/devicetree/bindings/i2c/i2c-mt65xx.txt b/Documentation/devicetree/bindings/i2c/i2c-mt65xx.txt index 5ea216ae7084..88f74a3c81ec 100644 --- a/Documentation/devicetree/bindings/i2c/i2c-mt65xx.txt +++ b/Documentation/devicetree/bindings/i2c/i2c-mt65xx.txt @@ -14,6 +14,7 @@ Required properties: "mediatek,mt7629-i2c", "mediatek,mt2712-i2c": for MediaTek MT7629 "mediatek,mt8173-i2c": for MediaTek MT8173 "mediatek,mt8183-i2c": for MediaTek MT8183 + "mediatek,mt8186-i2c": for MediaTek MT8186 "mediatek,mt8192-i2c": for MediaTek MT8192 "mediatek,mt8195-i2c", "mediatek,mt8192-i2c": for MediaTek MT8195 "mediatek,mt8516-i2c", "mediatek,mt2712-i2c": for MediaTek MT8516 From 934705316f0fce48e0a944e6efb3f8da8c616b1c Mon Sep 17 00:00:00 2001 From: Kewei Xu Date: Tue, 25 Jan 2022 19:04:13 +0800 Subject: [PATCH 046/370] i2c: mediatek: Add i2c compatible for Mediatek MT8186 Add i2c compatible for MT8186. Compare to MT8192 i2c controller, MT8186 doesn't need handshake signal witch apdma. Signed-off-by: Kewei Xu Reviewed-by: Qii Wang Signed-off-by: Wolfram Sang --- drivers/i2c/busses/i2c-mt65xx.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/drivers/i2c/busses/i2c-mt65xx.c b/drivers/i2c/busses/i2c-mt65xx.c index 9ea427f53083..aa4d21838e14 100644 --- a/drivers/i2c/busses/i2c-mt65xx.c +++ b/drivers/i2c/busses/i2c-mt65xx.c @@ -397,6 +397,19 @@ static const struct mtk_i2c_compatible mt8183_compat = { .max_dma_support = 33, }; +static const struct mtk_i2c_compatible mt8186_compat = { + .regs = mt_i2c_regs_v2, + .pmic_i2c = 0, + .dcm = 0, + .auto_restart = 1, + .aux_len_reg = 1, + .timing_adjust = 1, + .dma_sync = 0, + .ltiming_adjust = 1, + .apdma_sync = 0, + .max_dma_support = 36, +}; + static const struct mtk_i2c_compatible mt8192_compat = { .quirks = &mt8183_i2c_quirks, .regs = mt_i2c_regs_v2, @@ -418,6 +431,7 @@ static const struct of_device_id mtk_i2c_of_match[] = { { .compatible = "mediatek,mt7622-i2c", .data = &mt7622_compat }, { .compatible = "mediatek,mt8173-i2c", .data = &mt8173_compat }, { .compatible = "mediatek,mt8183-i2c", .data = &mt8183_compat }, + { .compatible = "mediatek,mt8186-i2c", .data = &mt8186_compat }, { .compatible = "mediatek,mt8192-i2c", .data = &mt8192_compat }, {} }; From 3f26d1bf90ba9bf420e49ec9cdbe13d15c0df7cd Mon Sep 17 00:00:00 2001 From: Miquel Raynal Date: Thu, 27 Jan 2022 12:06:31 +0100 Subject: [PATCH 047/370] mtd: Fix misuses of of_match_ptr() of_match_ptr() either expands to NULL if !CONFIG_OF, or is transparent otherwise. There are several drivers using this macro which keep their of_device_id array enclosed within an #ifdef CONFIG_OF check, these are considered fine. However, When misused, the of_device_id array pointed by this macro will produce a warning because it is finally unused when compiled without OF support. A number of fixes are possible: - Always depend on CONFIG_OF, but this will not always work and may break boards. - Enclose the compatible array by #ifdef's, this may save a bit of memory but will reduce build coverage. - Tell the compiler the array may be unused, if this can be avoided, let's not do this. - Just drop the macro, setting the of_device_id array for a non OF enabled platform is not an issue, it will just be unused. The latter solution seems the more appropriate, so let's use it. Reported-by: kernel test robot Signed-off-by: Miquel Raynal Acked-by: Paul Cercueil Reviewed-by: Alexandre Belloni Acked-by: Pratyush Yadav Link: https://lore.kernel.org/linux-mtd/20220127110631.1064705-1-miquel.raynal@bootlin.com --- drivers/mtd/devices/mchp23k256.c | 2 +- drivers/mtd/devices/mchp48l640.c | 2 +- drivers/mtd/nand/raw/atmel/nand-controller.c | 2 +- drivers/mtd/nand/raw/atmel/pmecc.c | 2 +- drivers/mtd/nand/raw/ingenic/ingenic_nand_drv.c | 2 +- drivers/mtd/nand/raw/ingenic/jz4780_bch.c | 2 +- drivers/mtd/nand/raw/mtk_ecc.c | 2 +- drivers/mtd/nand/raw/omap2.c | 2 +- drivers/mtd/nand/raw/renesas-nand-controller.c | 2 +- drivers/mtd/nand/raw/sh_flctl.c | 2 +- 10 files changed, 10 insertions(+), 10 deletions(-) diff --git a/drivers/mtd/devices/mchp23k256.c b/drivers/mtd/devices/mchp23k256.c index a8b31bddf14b..bf51eebf052c 100644 --- a/drivers/mtd/devices/mchp23k256.c +++ b/drivers/mtd/devices/mchp23k256.c @@ -234,7 +234,7 @@ MODULE_DEVICE_TABLE(of, mchp23k256_of_table); static struct spi_driver mchp23k256_driver = { .driver = { .name = "mchp23k256", - .of_match_table = of_match_ptr(mchp23k256_of_table), + .of_match_table = mchp23k256_of_table, }, .probe = mchp23k256_probe, .remove = mchp23k256_remove, diff --git a/drivers/mtd/devices/mchp48l640.c b/drivers/mtd/devices/mchp48l640.c index 231a10790196..4ec505b3f4a6 100644 --- a/drivers/mtd/devices/mchp48l640.c +++ b/drivers/mtd/devices/mchp48l640.c @@ -362,7 +362,7 @@ MODULE_DEVICE_TABLE(of, mchp48l640_of_table); static struct spi_driver mchp48l640_driver = { .driver = { .name = "mchp48l640", - .of_match_table = of_match_ptr(mchp48l640_of_table), + .of_match_table = mchp48l640_of_table, }, .probe = mchp48l640_probe, .remove = mchp48l640_remove, diff --git a/drivers/mtd/nand/raw/atmel/nand-controller.c b/drivers/mtd/nand/raw/atmel/nand-controller.c index f3276ee9e4fe..4ecbaccf5526 100644 --- a/drivers/mtd/nand/raw/atmel/nand-controller.c +++ b/drivers/mtd/nand/raw/atmel/nand-controller.c @@ -2648,7 +2648,7 @@ static SIMPLE_DEV_PM_OPS(atmel_nand_controller_pm_ops, NULL, static struct platform_driver atmel_nand_controller_driver = { .driver = { .name = "atmel-nand-controller", - .of_match_table = of_match_ptr(atmel_nand_controller_of_ids), + .of_match_table = atmel_nand_controller_of_ids, .pm = &atmel_nand_controller_pm_ops, }, .probe = atmel_nand_controller_probe, diff --git a/drivers/mtd/nand/raw/atmel/pmecc.c b/drivers/mtd/nand/raw/atmel/pmecc.c index 498e41ccabbd..43ebd78816c0 100644 --- a/drivers/mtd/nand/raw/atmel/pmecc.c +++ b/drivers/mtd/nand/raw/atmel/pmecc.c @@ -1003,7 +1003,7 @@ static int atmel_pmecc_probe(struct platform_device *pdev) static struct platform_driver atmel_pmecc_driver = { .driver = { .name = "atmel-pmecc", - .of_match_table = of_match_ptr(atmel_pmecc_match), + .of_match_table = atmel_pmecc_match, }, .probe = atmel_pmecc_probe, }; diff --git a/drivers/mtd/nand/raw/ingenic/ingenic_nand_drv.c b/drivers/mtd/nand/raw/ingenic/ingenic_nand_drv.c index b18861bdcdc8..ff26c10f295d 100644 --- a/drivers/mtd/nand/raw/ingenic/ingenic_nand_drv.c +++ b/drivers/mtd/nand/raw/ingenic/ingenic_nand_drv.c @@ -567,7 +567,7 @@ static struct platform_driver ingenic_nand_driver = { .remove = ingenic_nand_remove, .driver = { .name = DRV_NAME, - .of_match_table = of_match_ptr(ingenic_nand_dt_match), + .of_match_table = ingenic_nand_dt_match, }, }; module_platform_driver(ingenic_nand_driver); diff --git a/drivers/mtd/nand/raw/ingenic/jz4780_bch.c b/drivers/mtd/nand/raw/ingenic/jz4780_bch.c index d67dbfff76cc..12b5b0484fe9 100644 --- a/drivers/mtd/nand/raw/ingenic/jz4780_bch.c +++ b/drivers/mtd/nand/raw/ingenic/jz4780_bch.c @@ -260,7 +260,7 @@ static struct platform_driver jz4780_bch_driver = { .probe = jz4780_bch_probe, .driver = { .name = "jz4780-bch", - .of_match_table = of_match_ptr(jz4780_bch_dt_match), + .of_match_table = jz4780_bch_dt_match, }, }; module_platform_driver(jz4780_bch_driver); diff --git a/drivers/mtd/nand/raw/mtk_ecc.c b/drivers/mtd/nand/raw/mtk_ecc.c index 1b47964cb6da..e7df3dac705e 100644 --- a/drivers/mtd/nand/raw/mtk_ecc.c +++ b/drivers/mtd/nand/raw/mtk_ecc.c @@ -579,7 +579,7 @@ static struct platform_driver mtk_ecc_driver = { .probe = mtk_ecc_probe, .driver = { .name = "mtk-ecc", - .of_match_table = of_match_ptr(mtk_ecc_dt_match), + .of_match_table = mtk_ecc_dt_match, #ifdef CONFIG_PM_SLEEP .pm = &mtk_ecc_pm_ops, #endif diff --git a/drivers/mtd/nand/raw/omap2.c b/drivers/mtd/nand/raw/omap2.c index f0bbbe401e76..58c32a11792e 100644 --- a/drivers/mtd/nand/raw/omap2.c +++ b/drivers/mtd/nand/raw/omap2.c @@ -2298,7 +2298,7 @@ static struct platform_driver omap_nand_driver = { .remove = omap_nand_remove, .driver = { .name = DRIVER_NAME, - .of_match_table = of_match_ptr(omap_nand_ids), + .of_match_table = omap_nand_ids, }, }; diff --git a/drivers/mtd/nand/raw/renesas-nand-controller.c b/drivers/mtd/nand/raw/renesas-nand-controller.c index 428e08362956..6db063b230a9 100644 --- a/drivers/mtd/nand/raw/renesas-nand-controller.c +++ b/drivers/mtd/nand/raw/renesas-nand-controller.c @@ -1412,7 +1412,7 @@ MODULE_DEVICE_TABLE(of, rnandc_id_table); static struct platform_driver rnandc_driver = { .driver = { .name = "renesas-nandc", - .of_match_table = of_match_ptr(rnandc_id_table), + .of_match_table = rnandc_id_table, }, .probe = rnandc_probe, .remove = rnandc_remove, diff --git a/drivers/mtd/nand/raw/sh_flctl.c b/drivers/mtd/nand/raw/sh_flctl.c index 13df4bdf792a..b85b9c6fcc42 100644 --- a/drivers/mtd/nand/raw/sh_flctl.c +++ b/drivers/mtd/nand/raw/sh_flctl.c @@ -1220,7 +1220,7 @@ static struct platform_driver flctl_driver = { .remove = flctl_remove, .driver = { .name = "sh_flctl", - .of_match_table = of_match_ptr(of_flctl_match), + .of_match_table = of_flctl_match, }, }; From e02dacd3a26d5e5d3913650d3d6d939ebf77fd5c Mon Sep 17 00:00:00 2001 From: Miquel Raynal Date: Thu, 27 Jan 2022 12:08:02 +0100 Subject: [PATCH 048/370] mtd: rawnand: Fix misuses of of_match_node() On non-OF enabled platforms (CONFIG_OF is not set), of_match_node() will expand to NULL. The of_device_id array pointed by the macro will then be left unused. Let's mark the array __maybe_unused in this case to prevent compiler warnings. Signed-off-by: Miquel Raynal Acked-by: Florian Fainelli Link: https://lore.kernel.org/linux-mtd/20220127110802.1064963-1-miquel.raynal@bootlin.com --- drivers/mtd/nand/raw/atmel/nand-controller.c | 2 +- drivers/mtd/nand/raw/atmel/pmecc.c | 2 +- drivers/mtd/nand/raw/brcmnand/brcmnand.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/mtd/nand/raw/atmel/nand-controller.c b/drivers/mtd/nand/raw/atmel/nand-controller.c index 4ecbaccf5526..0209f7462635 100644 --- a/drivers/mtd/nand/raw/atmel/nand-controller.c +++ b/drivers/mtd/nand/raw/atmel/nand-controller.c @@ -1938,7 +1938,7 @@ static const struct atmel_smc_nand_ebi_csa_cfg sam9x60_ebi_csa = { .nfd0_on_d16 = AT91_SFR_CCFG_NFD0_ON_D16, }; -static const struct of_device_id atmel_ebi_csa_regmap_of_ids[] = { +static const struct of_device_id __maybe_unused atmel_ebi_csa_regmap_of_ids[] = { { .compatible = "atmel,at91sam9260-matrix", .data = &at91sam9260_ebi_csa, diff --git a/drivers/mtd/nand/raw/atmel/pmecc.c b/drivers/mtd/nand/raw/atmel/pmecc.c index 43ebd78816c0..4d7dc8a9c373 100644 --- a/drivers/mtd/nand/raw/atmel/pmecc.c +++ b/drivers/mtd/nand/raw/atmel/pmecc.c @@ -920,7 +920,7 @@ static struct atmel_pmecc_caps sama5d2_caps = { .correct_erased_chunks = true, }; -static const struct of_device_id atmel_pmecc_legacy_match[] = { +static const struct of_device_id __maybe_unused atmel_pmecc_legacy_match[] = { { .compatible = "atmel,sama5d4-nand", &sama5d4_caps }, { .compatible = "atmel,sama5d2-nand", &sama5d2_caps }, { /* sentinel */ } diff --git a/drivers/mtd/nand/raw/brcmnand/brcmnand.c b/drivers/mtd/nand/raw/brcmnand/brcmnand.c index f75929783b94..7c0f02069ea0 100644 --- a/drivers/mtd/nand/raw/brcmnand/brcmnand.c +++ b/drivers/mtd/nand/raw/brcmnand/brcmnand.c @@ -2914,7 +2914,7 @@ const struct dev_pm_ops brcmnand_pm_ops = { }; EXPORT_SYMBOL_GPL(brcmnand_pm_ops); -static const struct of_device_id brcmnand_of_match[] = { +static const struct of_device_id __maybe_unused brcmnand_of_match[] = { { .compatible = "brcm,brcmnand-v2.1" }, { .compatible = "brcm,brcmnand-v2.2" }, { .compatible = "brcm,brcmnand-v4.0" }, From 39bd2b6a3783b8990d97494ec4c8698ba5bb6740 Mon Sep 17 00:00:00 2001 From: Rob Herring Date: Tue, 18 Jan 2022 19:50:38 -0600 Subject: [PATCH 049/370] dt-bindings: Improve phandle-array schemas The 'phandle-array' type is a bit ambiguous. It can be either just an array of phandles or an array of phandles plus args. Many schemas for phandle-array properties aren't clear in the schema which case applies though the description usually describes it. The array of phandles case boils down to needing: items: maxItems: 1 The phandle plus args cases should typically take this form: items: - items: - description: A phandle - description: 1st arg cell - description: 2nd arg cell With this change, some examples need updating so that the bracketing of property values matches the schema. Signed-off-by: Rob Herring Acked-by: Viresh Kumar Acked-by: Vinod Koul Acked-by: Ulf Hansson Acked-by: Georgi Djakov Reviewed-by: Geert Uytterhoeven Acked-by: Mark Brown Acked-by: Krzysztof Kozlowski Acked-by: Stephen Boyd Acked-by: Greg Kroah-Hartman Acked-by: Marc Kleine-Budde Link: https://lore.kernel.org/r/20220119015038.2433585-1-robh@kernel.org --- .../devicetree/bindings/arm/cpus.yaml | 2 + .../devicetree/bindings/arm/idle-states.yaml | 80 +++++++++---------- .../devicetree/bindings/arm/pmu.yaml | 2 + .../bindings/ata/sata_highbank.yaml | 3 + .../bus/allwinner,sun50i-a64-de2.yaml | 5 +- .../bindings/crypto/intel,ixp4xx-crypto.yaml | 15 +++- .../allwinner,sun4i-a10-display-engine.yaml | 2 + .../display/mediatek/mediatek,hdmi.yaml | 5 +- .../devicetree/bindings/display/msm/gpu.yaml | 2 + .../bindings/display/renesas,du.yaml | 10 ++- .../display/rockchip/rockchip-drm.yaml | 2 + .../display/sprd/sprd,display-subsystem.yaml | 2 + .../bindings/display/ti/ti,am65x-dss.yaml | 3 +- .../devicetree/bindings/dma/dma-router.yaml | 2 + .../bindings/dma/st,stm32-dmamux.yaml | 2 +- .../bindings/dvfs/performance-domain.yaml | 1 - .../bindings/firmware/arm,scmi.yaml | 2 +- .../bindings/firmware/arm,scpi.yaml | 2 +- .../bindings/interconnect/qcom,rpmh.yaml | 2 + .../interrupt-controller/arm,gic-v3.yaml | 6 +- .../interrupt-controller/ti,sci-inta.yaml | 2 + .../bindings/iommu/mediatek,iommu.yaml | 6 +- .../bindings/iommu/renesas,ipmmu-vmsa.yaml | 6 ++ .../leds/backlight/led-backlight.yaml | 2 + .../allwinner,sun4i-a10-video-engine.yaml | 4 + .../bindings/media/nxp,imx8mq-mipi-csi2.yaml | 10 +-- .../devicetree/bindings/media/ti,cal.yaml | 4 + .../memory-controllers/mediatek,smi-larb.yaml | 2 +- .../samsung,exynos5422-dmc.yaml | 2 + .../net/allwinner,sun4i-a10-emac.yaml | 4 + .../bindings/net/can/bosch,c_can.yaml | 8 +- .../bindings/net/can/fsl,flexcan.yaml | 12 +-- .../devicetree/bindings/net/dsa/dsa-port.yaml | 2 + .../devicetree/bindings/net/fsl,fec.yaml | 8 +- .../bindings/net/intel,ixp4xx-ethernet.yaml | 15 +++- .../bindings/net/intel,ixp4xx-hss.yaml | 33 ++++++-- .../bindings/net/nxp,dwmac-imx.yaml | 4 + .../bindings/net/socionext,uniphier-ave4.yaml | 4 + .../devicetree/bindings/net/stm32-dwmac.yaml | 4 + .../bindings/net/ti,k3-am654-cpsw-nuss.yaml | 5 ++ .../bindings/net/wireless/mediatek,mt76.yaml | 4 + .../devicetree/bindings/opp/opp-v2-base.yaml | 2 + .../devicetree/bindings/perf/arm,dsu-pmu.yaml | 2 + .../bindings/phy/intel,combo-phy.yaml | 8 ++ .../devicetree/bindings/phy/ti,omap-usb2.yaml | 4 + .../pinctrl/aspeed,ast2500-pinctrl.yaml | 2 + .../bindings/pinctrl/canaan,k210-fpioa.yaml | 4 + .../pinctrl/mediatek,mt65xx-pinctrl.yaml | 2 + .../bindings/pinctrl/st,stm32-pinctrl.yaml | 10 ++- .../bindings/power/power-domain.yaml | 4 + .../bindings/power/renesas,apmu.yaml | 2 + .../power/rockchip,power-controller.yaml | 2 + .../bindings/power/supply/cw2015_battery.yaml | 6 +- .../bindings/power/supply/power-supply.yaml | 2 + .../bindings/regulator/regulator.yaml | 2 + .../bindings/regulator/st,stm32-booster.yaml | 2 +- .../bindings/remoteproc/qcom,adsp.yaml | 6 ++ .../bindings/remoteproc/st,stm32-rproc.yaml | 33 ++++++-- .../bindings/remoteproc/ti,k3-dsp-rproc.yaml | 2 + .../bindings/remoteproc/ti,k3-r5f-rproc.yaml | 2 + .../remoteproc/ti,omap-remoteproc.yaml | 19 +++-- .../bindings/soc/samsung/exynos-usi.yaml | 4 + .../bindings/sound/samsung,aries-wm8994.yaml | 2 + .../bindings/sound/st,stm32-sai.yaml | 8 +- .../thermal/thermal-cooling-devices.yaml | 6 +- .../bindings/thermal/thermal-idle.yaml | 8 +- .../bindings/usb/nvidia,tegra-xudc.yaml | 2 +- 67 files changed, 318 insertions(+), 119 deletions(-) diff --git a/Documentation/devicetree/bindings/arm/cpus.yaml b/Documentation/devicetree/bindings/arm/cpus.yaml index 0dcebc48ea22..916a5aebefff 100644 --- a/Documentation/devicetree/bindings/arm/cpus.yaml +++ b/Documentation/devicetree/bindings/arm/cpus.yaml @@ -243,6 +243,8 @@ properties: cpu-idle-states: $ref: '/schemas/types.yaml#/definitions/phandle-array' + items: + maxItems: 1 description: | List of phandles to idle state nodes supported by this cpu (see ./idle-states.yaml). diff --git a/Documentation/devicetree/bindings/arm/idle-states.yaml b/Documentation/devicetree/bindings/arm/idle-states.yaml index 52bce5dbb11f..4d381fa1ee57 100644 --- a/Documentation/devicetree/bindings/arm/idle-states.yaml +++ b/Documentation/devicetree/bindings/arm/idle-states.yaml @@ -337,8 +337,8 @@ examples: compatible = "arm,cortex-a57"; reg = <0x0 0x0>; enable-method = "psci"; - cpu-idle-states = <&CPU_RETENTION_0_0 &CPU_SLEEP_0_0 - &CLUSTER_RETENTION_0 &CLUSTER_SLEEP_0>; + cpu-idle-states = <&CPU_RETENTION_0_0>, <&CPU_SLEEP_0_0>, + <&CLUSTER_RETENTION_0>, <&CLUSTER_SLEEP_0>; }; cpu@1 { @@ -346,8 +346,8 @@ examples: compatible = "arm,cortex-a57"; reg = <0x0 0x1>; enable-method = "psci"; - cpu-idle-states = <&CPU_RETENTION_0_0 &CPU_SLEEP_0_0 - &CLUSTER_RETENTION_0 &CLUSTER_SLEEP_0>; + cpu-idle-states = <&CPU_RETENTION_0_0>, <&CPU_SLEEP_0_0>, + <&CLUSTER_RETENTION_0>, <&CLUSTER_SLEEP_0>; }; cpu@100 { @@ -355,8 +355,8 @@ examples: compatible = "arm,cortex-a57"; reg = <0x0 0x100>; enable-method = "psci"; - cpu-idle-states = <&CPU_RETENTION_0_0 &CPU_SLEEP_0_0 - &CLUSTER_RETENTION_0 &CLUSTER_SLEEP_0>; + cpu-idle-states = <&CPU_RETENTION_0_0>, <&CPU_SLEEP_0_0>, + <&CLUSTER_RETENTION_0>, <&CLUSTER_SLEEP_0>; }; cpu@101 { @@ -364,8 +364,8 @@ examples: compatible = "arm,cortex-a57"; reg = <0x0 0x101>; enable-method = "psci"; - cpu-idle-states = <&CPU_RETENTION_0_0 &CPU_SLEEP_0_0 - &CLUSTER_RETENTION_0 &CLUSTER_SLEEP_0>; + cpu-idle-states = <&CPU_RETENTION_0_0>, <&CPU_SLEEP_0_0>, + <&CLUSTER_RETENTION_0>, <&CLUSTER_SLEEP_0>; }; cpu@10000 { @@ -373,8 +373,8 @@ examples: compatible = "arm,cortex-a57"; reg = <0x0 0x10000>; enable-method = "psci"; - cpu-idle-states = <&CPU_RETENTION_0_0 &CPU_SLEEP_0_0 - &CLUSTER_RETENTION_0 &CLUSTER_SLEEP_0>; + cpu-idle-states = <&CPU_RETENTION_0_0>, <&CPU_SLEEP_0_0>, + <&CLUSTER_RETENTION_0>, <&CLUSTER_SLEEP_0>; }; cpu@10001 { @@ -382,8 +382,8 @@ examples: compatible = "arm,cortex-a57"; reg = <0x0 0x10001>; enable-method = "psci"; - cpu-idle-states = <&CPU_RETENTION_0_0 &CPU_SLEEP_0_0 - &CLUSTER_RETENTION_0 &CLUSTER_SLEEP_0>; + cpu-idle-states = <&CPU_RETENTION_0_0>, <&CPU_SLEEP_0_0>, + <&CLUSTER_RETENTION_0>, <&CLUSTER_SLEEP_0>; }; cpu@10100 { @@ -391,8 +391,8 @@ examples: compatible = "arm,cortex-a57"; reg = <0x0 0x10100>; enable-method = "psci"; - cpu-idle-states = <&CPU_RETENTION_0_0 &CPU_SLEEP_0_0 - &CLUSTER_RETENTION_0 &CLUSTER_SLEEP_0>; + cpu-idle-states = <&CPU_RETENTION_0_0>, <&CPU_SLEEP_0_0>, + <&CLUSTER_RETENTION_0>, <&CLUSTER_SLEEP_0>; }; cpu@10101 { @@ -400,8 +400,8 @@ examples: compatible = "arm,cortex-a57"; reg = <0x0 0x10101>; enable-method = "psci"; - cpu-idle-states = <&CPU_RETENTION_0_0 &CPU_SLEEP_0_0 - &CLUSTER_RETENTION_0 &CLUSTER_SLEEP_0>; + cpu-idle-states = <&CPU_RETENTION_0_0>, <&CPU_SLEEP_0_0>, + <&CLUSTER_RETENTION_0>, <&CLUSTER_SLEEP_0>; }; cpu@100000000 { @@ -409,8 +409,8 @@ examples: compatible = "arm,cortex-a53"; reg = <0x1 0x0>; enable-method = "psci"; - cpu-idle-states = <&CPU_RETENTION_1_0 &CPU_SLEEP_1_0 - &CLUSTER_RETENTION_1 &CLUSTER_SLEEP_1>; + cpu-idle-states = <&CPU_RETENTION_1_0>, <&CPU_SLEEP_1_0>, + <&CLUSTER_RETENTION_1>, <&CLUSTER_SLEEP_1>; }; cpu@100000001 { @@ -418,8 +418,8 @@ examples: compatible = "arm,cortex-a53"; reg = <0x1 0x1>; enable-method = "psci"; - cpu-idle-states = <&CPU_RETENTION_1_0 &CPU_SLEEP_1_0 - &CLUSTER_RETENTION_1 &CLUSTER_SLEEP_1>; + cpu-idle-states = <&CPU_RETENTION_1_0>, <&CPU_SLEEP_1_0>, + <&CLUSTER_RETENTION_1>, <&CLUSTER_SLEEP_1>; }; cpu@100000100 { @@ -427,8 +427,8 @@ examples: compatible = "arm,cortex-a53"; reg = <0x1 0x100>; enable-method = "psci"; - cpu-idle-states = <&CPU_RETENTION_1_0 &CPU_SLEEP_1_0 - &CLUSTER_RETENTION_1 &CLUSTER_SLEEP_1>; + cpu-idle-states = <&CPU_RETENTION_1_0>, <&CPU_SLEEP_1_0>, + <&CLUSTER_RETENTION_1>, <&CLUSTER_SLEEP_1>; }; cpu@100000101 { @@ -436,8 +436,8 @@ examples: compatible = "arm,cortex-a53"; reg = <0x1 0x101>; enable-method = "psci"; - cpu-idle-states = <&CPU_RETENTION_1_0 &CPU_SLEEP_1_0 - &CLUSTER_RETENTION_1 &CLUSTER_SLEEP_1>; + cpu-idle-states = <&CPU_RETENTION_1_0>, <&CPU_SLEEP_1_0>, + <&CLUSTER_RETENTION_1>, <&CLUSTER_SLEEP_1>; }; cpu@100010000 { @@ -445,8 +445,8 @@ examples: compatible = "arm,cortex-a53"; reg = <0x1 0x10000>; enable-method = "psci"; - cpu-idle-states = <&CPU_RETENTION_1_0 &CPU_SLEEP_1_0 - &CLUSTER_RETENTION_1 &CLUSTER_SLEEP_1>; + cpu-idle-states = <&CPU_RETENTION_1_0>, <&CPU_SLEEP_1_0>, + <&CLUSTER_RETENTION_1>, <&CLUSTER_SLEEP_1>; }; cpu@100010001 { @@ -454,8 +454,8 @@ examples: compatible = "arm,cortex-a53"; reg = <0x1 0x10001>; enable-method = "psci"; - cpu-idle-states = <&CPU_RETENTION_1_0 &CPU_SLEEP_1_0 - &CLUSTER_RETENTION_1 &CLUSTER_SLEEP_1>; + cpu-idle-states = <&CPU_RETENTION_1_0>, <&CPU_SLEEP_1_0>, + <&CLUSTER_RETENTION_1>, <&CLUSTER_SLEEP_1>; }; cpu@100010100 { @@ -463,8 +463,8 @@ examples: compatible = "arm,cortex-a53"; reg = <0x1 0x10100>; enable-method = "psci"; - cpu-idle-states = <&CPU_RETENTION_1_0 &CPU_SLEEP_1_0 - &CLUSTER_RETENTION_1 &CLUSTER_SLEEP_1>; + cpu-idle-states = <&CPU_RETENTION_1_0>, <&CPU_SLEEP_1_0>, + <&CLUSTER_RETENTION_1>, <&CLUSTER_SLEEP_1>; }; cpu@100010101 { @@ -472,8 +472,8 @@ examples: compatible = "arm,cortex-a53"; reg = <0x1 0x10101>; enable-method = "psci"; - cpu-idle-states = <&CPU_RETENTION_1_0 &CPU_SLEEP_1_0 - &CLUSTER_RETENTION_1 &CLUSTER_SLEEP_1>; + cpu-idle-states = <&CPU_RETENTION_1_0>, <&CPU_SLEEP_1_0>, + <&CLUSTER_RETENTION_1>, <&CLUSTER_SLEEP_1>; }; idle-states { @@ -567,56 +567,56 @@ examples: device_type = "cpu"; compatible = "arm,cortex-a15"; reg = <0x0>; - cpu-idle-states = <&cpu_sleep_0_0 &cluster_sleep_0>; + cpu-idle-states = <&cpu_sleep_0_0>, <&cluster_sleep_0>; }; cpu@1 { device_type = "cpu"; compatible = "arm,cortex-a15"; reg = <0x1>; - cpu-idle-states = <&cpu_sleep_0_0 &cluster_sleep_0>; + cpu-idle-states = <&cpu_sleep_0_0>, <&cluster_sleep_0>; }; cpu@2 { device_type = "cpu"; compatible = "arm,cortex-a15"; reg = <0x2>; - cpu-idle-states = <&cpu_sleep_0_0 &cluster_sleep_0>; + cpu-idle-states = <&cpu_sleep_0_0>, <&cluster_sleep_0>; }; cpu@3 { device_type = "cpu"; compatible = "arm,cortex-a15"; reg = <0x3>; - cpu-idle-states = <&cpu_sleep_0_0 &cluster_sleep_0>; + cpu-idle-states = <&cpu_sleep_0_0>, <&cluster_sleep_0>; }; cpu@100 { device_type = "cpu"; compatible = "arm,cortex-a7"; reg = <0x100>; - cpu-idle-states = <&cpu_sleep_1_0 &cluster_sleep_1>; + cpu-idle-states = <&cpu_sleep_1_0>, <&cluster_sleep_1>; }; cpu@101 { device_type = "cpu"; compatible = "arm,cortex-a7"; reg = <0x101>; - cpu-idle-states = <&cpu_sleep_1_0 &cluster_sleep_1>; + cpu-idle-states = <&cpu_sleep_1_0>, <&cluster_sleep_1>; }; cpu@102 { device_type = "cpu"; compatible = "arm,cortex-a7"; reg = <0x102>; - cpu-idle-states = <&cpu_sleep_1_0 &cluster_sleep_1>; + cpu-idle-states = <&cpu_sleep_1_0>, <&cluster_sleep_1>; }; cpu@103 { device_type = "cpu"; compatible = "arm,cortex-a7"; reg = <0x103>; - cpu-idle-states = <&cpu_sleep_1_0 &cluster_sleep_1>; + cpu-idle-states = <&cpu_sleep_1_0>, <&cluster_sleep_1>; }; idle-states { diff --git a/Documentation/devicetree/bindings/arm/pmu.yaml b/Documentation/devicetree/bindings/arm/pmu.yaml index 981bac451698..2e2308d73408 100644 --- a/Documentation/devicetree/bindings/arm/pmu.yaml +++ b/Documentation/devicetree/bindings/arm/pmu.yaml @@ -66,6 +66,8 @@ properties: interrupt-affinity: $ref: /schemas/types.yaml#/definitions/phandle-array + items: + maxItems: 1 description: When using SPIs, specifies a list of phandles to CPU nodes corresponding directly to the affinity of diff --git a/Documentation/devicetree/bindings/ata/sata_highbank.yaml b/Documentation/devicetree/bindings/ata/sata_highbank.yaml index ce75d77e9289..49679b58041c 100644 --- a/Documentation/devicetree/bindings/ata/sata_highbank.yaml +++ b/Documentation/devicetree/bindings/ata/sata_highbank.yaml @@ -51,6 +51,9 @@ properties: $ref: /schemas/types.yaml#/definitions/phandle-array minItems: 1 maxItems: 8 + items: + minItems: 2 + maxItems: 2 calxeda,tx-atten: description: | diff --git a/Documentation/devicetree/bindings/bus/allwinner,sun50i-a64-de2.yaml b/Documentation/devicetree/bindings/bus/allwinner,sun50i-a64-de2.yaml index 863a287ebc7e..ad313ccaaaef 100644 --- a/Documentation/devicetree/bindings/bus/allwinner,sun50i-a64-de2.yaml +++ b/Documentation/devicetree/bindings/bus/allwinner,sun50i-a64-de2.yaml @@ -35,7 +35,10 @@ properties: The SRAM that needs to be claimed to access the display engine bus. $ref: /schemas/types.yaml#/definitions/phandle-array - maxItems: 1 + items: + - items: + - description: phandle to SRAM + - description: register value for device ranges: true diff --git a/Documentation/devicetree/bindings/crypto/intel,ixp4xx-crypto.yaml b/Documentation/devicetree/bindings/crypto/intel,ixp4xx-crypto.yaml index 9c53c27bd20a..e0fe63957888 100644 --- a/Documentation/devicetree/bindings/crypto/intel,ixp4xx-crypto.yaml +++ b/Documentation/devicetree/bindings/crypto/intel,ixp4xx-crypto.yaml @@ -22,19 +22,28 @@ properties: intel,npe-handle: $ref: '/schemas/types.yaml#/definitions/phandle-array' - maxItems: 1 + items: + - items: + - description: phandle to the NPE this crypto engine + - description: the NPE instance number description: phandle to the NPE this crypto engine is using, the cell describing the NPE instance to be used. queue-rx: $ref: /schemas/types.yaml#/definitions/phandle-array - maxItems: 1 + items: + - items: + - description: phandle to the RX queue on the NPE + - description: the queue instance number description: phandle to the RX queue on the NPE, the cell describing the queue instance to be used. queue-txready: $ref: /schemas/types.yaml#/definitions/phandle-array - maxItems: 1 + items: + - items: + - description: phandle to the TX READY queue on the NPE + - description: the queue instance number description: phandle to the TX READY queue on the NPE, the cell describing the queue instance to be used. diff --git a/Documentation/devicetree/bindings/display/allwinner,sun4i-a10-display-engine.yaml b/Documentation/devicetree/bindings/display/allwinner,sun4i-a10-display-engine.yaml index e77523b02fad..d4412aea7b73 100644 --- a/Documentation/devicetree/bindings/display/allwinner,sun4i-a10-display-engine.yaml +++ b/Documentation/devicetree/bindings/display/allwinner,sun4i-a10-display-engine.yaml @@ -69,6 +69,8 @@ properties: $ref: /schemas/types.yaml#/definitions/phandle-array minItems: 1 maxItems: 2 + items: + maxItems: 1 description: | Available display engine frontends (DE 1.0) or mixers (DE 2.0/3.0) available. diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,hdmi.yaml b/Documentation/devicetree/bindings/display/mediatek/mediatek,hdmi.yaml index 111967efa999..bdaf0b51e68c 100644 --- a/Documentation/devicetree/bindings/display/mediatek/mediatek,hdmi.yaml +++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,hdmi.yaml @@ -51,7 +51,10 @@ properties: mediatek,syscon-hdmi: $ref: '/schemas/types.yaml#/definitions/phandle-array' - maxItems: 1 + items: + - items: + - description: phandle to system configuration registers + - description: register offset in the system configuration registers description: | phandle link and register offset to the system configuration registers. diff --git a/Documentation/devicetree/bindings/display/msm/gpu.yaml b/Documentation/devicetree/bindings/display/msm/gpu.yaml index 99a1ba3ada56..3397bc31d087 100644 --- a/Documentation/devicetree/bindings/display/msm/gpu.yaml +++ b/Documentation/devicetree/bindings/display/msm/gpu.yaml @@ -64,6 +64,8 @@ properties: $ref: /schemas/types.yaml#/definitions/phandle-array minItems: 1 maxItems: 4 + items: + maxItems: 1 description: | phandles to one or more reserved on-chip SRAM regions. phandle to the On Chip Memory (OCMEM) that's present on some a3xx and diff --git a/Documentation/devicetree/bindings/display/renesas,du.yaml b/Documentation/devicetree/bindings/display/renesas,du.yaml index 13efea574584..56cedcd6d576 100644 --- a/Documentation/devicetree/bindings/display/renesas,du.yaml +++ b/Documentation/devicetree/bindings/display/renesas,du.yaml @@ -76,17 +76,21 @@ properties: renesas,cmms: $ref: "/schemas/types.yaml#/definitions/phandle-array" + items: + maxItems: 1 description: A list of phandles to the CMM instances present in the SoC, one for each available DU channel. renesas,vsps: $ref: "/schemas/types.yaml#/definitions/phandle-array" + items: + items: + - description: phandle to VSP instance that serves the DU channel + - description: Channel index identifying the LIF instance in that VSP description: A list of phandle and channel index tuples to the VSPs that handle the - memory interfaces for the DU channels. The phandle identifies the VSP - instance that serves the DU channel, and the channel index identifies - the LIF instance in that VSP. + memory interfaces for the DU channels. required: - compatible diff --git a/Documentation/devicetree/bindings/display/rockchip/rockchip-drm.yaml b/Documentation/devicetree/bindings/display/rockchip/rockchip-drm.yaml index 7204da5eb4c5..a8d18a37cb23 100644 --- a/Documentation/devicetree/bindings/display/rockchip/rockchip-drm.yaml +++ b/Documentation/devicetree/bindings/display/rockchip/rockchip-drm.yaml @@ -21,6 +21,8 @@ properties: ports: $ref: /schemas/types.yaml#/definitions/phandle-array + items: + maxItems: 1 description: | Should contain a list of phandles pointing to display interface port of vop devices. vop definitions as defined in diff --git a/Documentation/devicetree/bindings/display/sprd/sprd,display-subsystem.yaml b/Documentation/devicetree/bindings/display/sprd/sprd,display-subsystem.yaml index 3d107e9434be..d0a5592bd89d 100644 --- a/Documentation/devicetree/bindings/display/sprd/sprd,display-subsystem.yaml +++ b/Documentation/devicetree/bindings/display/sprd/sprd,display-subsystem.yaml @@ -45,6 +45,8 @@ properties: ports: $ref: /schemas/types.yaml#/definitions/phandle-array + items: + maxItems: 1 description: Should contain a list of phandles pointing to display interface port of DPU devices. diff --git a/Documentation/devicetree/bindings/display/ti/ti,am65x-dss.yaml b/Documentation/devicetree/bindings/display/ti/ti,am65x-dss.yaml index 781c1868b0b8..5c7d2cbc4aac 100644 --- a/Documentation/devicetree/bindings/display/ti/ti,am65x-dss.yaml +++ b/Documentation/devicetree/bindings/display/ti/ti,am65x-dss.yaml @@ -88,8 +88,7 @@ properties: The DSS DPI output port node from video port 2 ti,am65x-oldi-io-ctrl: - $ref: "/schemas/types.yaml#/definitions/phandle-array" - maxItems: 1 + $ref: "/schemas/types.yaml#/definitions/phandle" description: phandle to syscon device node mapping OLDI IO_CTRL registers. The mapped range should point to OLDI_DAT0_IO_CTRL, map it and diff --git a/Documentation/devicetree/bindings/dma/dma-router.yaml b/Documentation/devicetree/bindings/dma/dma-router.yaml index e72748496fd9..4b817f5dc30e 100644 --- a/Documentation/devicetree/bindings/dma/dma-router.yaml +++ b/Documentation/devicetree/bindings/dma/dma-router.yaml @@ -24,6 +24,8 @@ properties: dma-masters: $ref: /schemas/types.yaml#/definitions/phandle-array + items: + maxItems: 1 description: Array of phandles to the DMA controllers the router can direct the signal to. diff --git a/Documentation/devicetree/bindings/dma/st,stm32-dmamux.yaml b/Documentation/devicetree/bindings/dma/st,stm32-dmamux.yaml index f751796531c9..7b1833d6caa2 100644 --- a/Documentation/devicetree/bindings/dma/st,stm32-dmamux.yaml +++ b/Documentation/devicetree/bindings/dma/st,stm32-dmamux.yaml @@ -46,7 +46,7 @@ examples: #dma-cells = <3>; dma-requests = <128>; dma-channels = <16>; - dma-masters = <&dma1 &dma2>; + dma-masters = <&dma1>, <&dma2>; clocks = <&timer_clk>; }; diff --git a/Documentation/devicetree/bindings/dvfs/performance-domain.yaml b/Documentation/devicetree/bindings/dvfs/performance-domain.yaml index c8b91207f34d..7959d40ded5a 100644 --- a/Documentation/devicetree/bindings/dvfs/performance-domain.yaml +++ b/Documentation/devicetree/bindings/dvfs/performance-domain.yaml @@ -43,7 +43,6 @@ properties: performance-domains: $ref: '/schemas/types.yaml#/definitions/phandle-array' - maxItems: 1 description: A phandle and performance domain specifier as defined by bindings of the performance controller/provider specified by phandle. diff --git a/Documentation/devicetree/bindings/firmware/arm,scmi.yaml b/Documentation/devicetree/bindings/firmware/arm,scmi.yaml index 5c4c6782e052..ea2f6bc9a1d6 100644 --- a/Documentation/devicetree/bindings/firmware/arm,scmi.yaml +++ b/Documentation/devicetree/bindings/firmware/arm,scmi.yaml @@ -330,7 +330,7 @@ examples: firmware { scmi { compatible = "arm,scmi-smc"; - shmem = <&cpu_scp_lpri0 &cpu_scp_lpri1>; + shmem = <&cpu_scp_lpri0>, <&cpu_scp_lpri1>; arm,smc-id = <0xc3000001>; #address-cells = <1>; diff --git a/Documentation/devicetree/bindings/firmware/arm,scpi.yaml b/Documentation/devicetree/bindings/firmware/arm,scpi.yaml index 23b346bd1252..800417a76bda 100644 --- a/Documentation/devicetree/bindings/firmware/arm,scpi.yaml +++ b/Documentation/devicetree/bindings/firmware/arm,scpi.yaml @@ -236,7 +236,7 @@ examples: scpi { compatible = "amlogic,meson-gxbb-scpi", "arm,scpi-pre-1.0"; mboxes = <&mailbox 1 &mailbox 2>; - shmem = <&cpu_scp_lpri &cpu_scp_hpri>; + shmem = <&cpu_scp_lpri>, <&cpu_scp_hpri>; scpi_sensors1: sensors { compatible = "amlogic,meson-gxbb-scpi-sensors", "arm,scpi-sensors"; diff --git a/Documentation/devicetree/bindings/interconnect/qcom,rpmh.yaml b/Documentation/devicetree/bindings/interconnect/qcom,rpmh.yaml index cbb24f9bb609..5a911be0c2ea 100644 --- a/Documentation/devicetree/bindings/interconnect/qcom,rpmh.yaml +++ b/Documentation/devicetree/bindings/interconnect/qcom,rpmh.yaml @@ -121,6 +121,8 @@ properties: qcom,bcm-voters: $ref: /schemas/types.yaml#/definitions/phandle-array + items: + maxItems: 1 description: | List of phandles to qcom,bcm-voter nodes that are required by this interconnect to send RPMh commands. diff --git a/Documentation/devicetree/bindings/interrupt-controller/arm,gic-v3.yaml b/Documentation/devicetree/bindings/interrupt-controller/arm,gic-v3.yaml index cfb3ec27bd2b..b7197f78e158 100644 --- a/Documentation/devicetree/bindings/interrupt-controller/arm,gic-v3.yaml +++ b/Documentation/devicetree/bindings/interrupt-controller/arm,gic-v3.yaml @@ -138,6 +138,8 @@ properties: properties: affinity: $ref: /schemas/types.yaml#/definitions/phandle-array + items: + maxItems: 1 description: Should be a list of phandles to CPU nodes (as described in Documentation/devicetree/bindings/arm/cpus.yaml). @@ -273,11 +275,11 @@ examples: ppi-partitions { part0: interrupt-partition-0 { - affinity = <&cpu0 &cpu2>; + affinity = <&cpu0>, <&cpu2>; }; part1: interrupt-partition-1 { - affinity = <&cpu1 &cpu3>; + affinity = <&cpu1>, <&cpu3>; }; }; }; diff --git a/Documentation/devicetree/bindings/interrupt-controller/ti,sci-inta.yaml b/Documentation/devicetree/bindings/interrupt-controller/ti,sci-inta.yaml index 3d89668573e8..88c46e61732e 100644 --- a/Documentation/devicetree/bindings/interrupt-controller/ti,sci-inta.yaml +++ b/Documentation/devicetree/bindings/interrupt-controller/ti,sci-inta.yaml @@ -77,6 +77,8 @@ properties: ti,unmapped-event-sources: $ref: /schemas/types.yaml#/definitions/phandle-array + items: + maxItems: 1 description: Array of phandles to DMA controllers where the unmapped events originate. diff --git a/Documentation/devicetree/bindings/iommu/mediatek,iommu.yaml b/Documentation/devicetree/bindings/iommu/mediatek,iommu.yaml index 0f26fe14c8e2..97e8c471a5e8 100644 --- a/Documentation/devicetree/bindings/iommu/mediatek,iommu.yaml +++ b/Documentation/devicetree/bindings/iommu/mediatek,iommu.yaml @@ -101,6 +101,8 @@ properties: $ref: /schemas/types.yaml#/definitions/phandle-array minItems: 1 maxItems: 32 + items: + maxItems: 1 description: | List of phandle to the local arbiters in the current Socs. Refer to bindings/memory-controllers/mediatek,smi-larb.yaml. It must sort @@ -167,8 +169,8 @@ examples: interrupts = ; clocks = <&infracfg CLK_INFRA_M4U>; clock-names = "bclk"; - mediatek,larbs = <&larb0 &larb1 &larb2 - &larb3 &larb4 &larb5>; + mediatek,larbs = <&larb0>, <&larb1>, <&larb2>, + <&larb3>, <&larb4>, <&larb5>; #iommu-cells = <1>; }; diff --git a/Documentation/devicetree/bindings/iommu/renesas,ipmmu-vmsa.yaml b/Documentation/devicetree/bindings/iommu/renesas,ipmmu-vmsa.yaml index ce0c715205c6..c18fe4825508 100644 --- a/Documentation/devicetree/bindings/iommu/renesas,ipmmu-vmsa.yaml +++ b/Documentation/devicetree/bindings/iommu/renesas,ipmmu-vmsa.yaml @@ -66,6 +66,12 @@ properties: renesas,ipmmu-main: $ref: /schemas/types.yaml#/definitions/phandle-array + items: + - items: + - description: phandle to main IPMMU + - description: the interrupt bit number associated with the particular + cache IPMMU device. The interrupt bit number needs to match the main + IPMMU IMSSTR register. Only used by cache IPMMU instances. description: Reference to the main IPMMU phandle plus 1 cell. The cell is the interrupt bit number associated with the particular cache IPMMU diff --git a/Documentation/devicetree/bindings/leds/backlight/led-backlight.yaml b/Documentation/devicetree/bindings/leds/backlight/led-backlight.yaml index 625082bf3892..f5822f4ea667 100644 --- a/Documentation/devicetree/bindings/leds/backlight/led-backlight.yaml +++ b/Documentation/devicetree/bindings/leds/backlight/led-backlight.yaml @@ -23,6 +23,8 @@ properties: leds: description: A list of LED nodes $ref: /schemas/types.yaml#/definitions/phandle-array + items: + maxItems: 1 brightness-levels: description: 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 c3de96d10396..ee7fc3515d89 100644 --- a/Documentation/devicetree/bindings/media/allwinner,sun4i-a10-video-engine.yaml +++ b/Documentation/devicetree/bindings/media/allwinner,sun4i-a10-video-engine.yaml @@ -48,6 +48,10 @@ properties: allwinner,sram: $ref: /schemas/types.yaml#/definitions/phandle-array + items: + - items: + - description: phandle to SRAM + - description: register value for device description: Phandle to the device SRAM iommus: diff --git a/Documentation/devicetree/bindings/media/nxp,imx8mq-mipi-csi2.yaml b/Documentation/devicetree/bindings/media/nxp,imx8mq-mipi-csi2.yaml index 1b3e1c4b99ed..2a14e3b0e004 100644 --- a/Documentation/devicetree/bindings/media/nxp,imx8mq-mipi-csi2.yaml +++ b/Documentation/devicetree/bindings/media/nxp,imx8mq-mipi-csi2.yaml @@ -58,11 +58,11 @@ properties: req_gpr is the gpr register offset of RX_ENABLE for the mipi phy. $ref: /schemas/types.yaml#/definitions/phandle-array items: - items: - - description: The 'gpr' is the phandle to general purpose register node. - - description: The 'req_gpr' is the gpr register offset containing - CSI2_1_RX_ENABLE or CSI2_2_RX_ENABLE respectively. - maximum: 0xff + - items: + - description: The 'gpr' is the phandle to general purpose register node. + - description: The 'req_gpr' is the gpr register offset containing + CSI2_1_RX_ENABLE or CSI2_2_RX_ENABLE respectively. + maximum: 0xff interconnects: maxItems: 1 diff --git a/Documentation/devicetree/bindings/media/ti,cal.yaml b/Documentation/devicetree/bindings/media/ti,cal.yaml index 66c5d392fa75..7e078424ca4d 100644 --- a/Documentation/devicetree/bindings/media/ti,cal.yaml +++ b/Documentation/devicetree/bindings/media/ti,cal.yaml @@ -48,6 +48,10 @@ properties: ti,camerrx-control: $ref: "/schemas/types.yaml#/definitions/phandle-array" + items: + - items: + - description: phandle to device control module + - description: offset to the control_camerarx_core register description: phandle to the device control module and offset to the control_camerarx_core register diff --git a/Documentation/devicetree/bindings/memory-controllers/mediatek,smi-larb.yaml b/Documentation/devicetree/bindings/memory-controllers/mediatek,smi-larb.yaml index eaeff1ada7f8..822ade9e9bab 100644 --- a/Documentation/devicetree/bindings/memory-controllers/mediatek,smi-larb.yaml +++ b/Documentation/devicetree/bindings/memory-controllers/mediatek,smi-larb.yaml @@ -52,7 +52,7 @@ properties: maxItems: 1 mediatek,smi: - $ref: /schemas/types.yaml#/definitions/phandle-array + $ref: /schemas/types.yaml#/definitions/phandle description: a phandle to the smi_common node. mediatek,larb-id: diff --git a/Documentation/devicetree/bindings/memory-controllers/samsung,exynos5422-dmc.yaml b/Documentation/devicetree/bindings/memory-controllers/samsung,exynos5422-dmc.yaml index fe8639dcffab..895c3b5c9aaa 100644 --- a/Documentation/devicetree/bindings/memory-controllers/samsung,exynos5422-dmc.yaml +++ b/Documentation/devicetree/bindings/memory-controllers/samsung,exynos5422-dmc.yaml @@ -45,6 +45,8 @@ properties: $ref: '/schemas/types.yaml#/definitions/phandle-array' minItems: 1 maxItems: 16 + items: + maxItems: 1 description: phandles of the PPMU events used by the controller. device-handle: diff --git a/Documentation/devicetree/bindings/net/allwinner,sun4i-a10-emac.yaml b/Documentation/devicetree/bindings/net/allwinner,sun4i-a10-emac.yaml index 8d8560a67abf..098b2bf7d976 100644 --- a/Documentation/devicetree/bindings/net/allwinner,sun4i-a10-emac.yaml +++ b/Documentation/devicetree/bindings/net/allwinner,sun4i-a10-emac.yaml @@ -29,6 +29,10 @@ properties: allwinner,sram: description: Phandle to the device SRAM $ref: /schemas/types.yaml#/definitions/phandle-array + items: + - items: + - description: phandle to SRAM + - description: register value for device required: - compatible diff --git a/Documentation/devicetree/bindings/net/can/bosch,c_can.yaml b/Documentation/devicetree/bindings/net/can/bosch,c_can.yaml index 2cd145a642f1..8bad328b184d 100644 --- a/Documentation/devicetree/bindings/net/can/bosch,c_can.yaml +++ b/Documentation/devicetree/bindings/net/can/bosch,c_can.yaml @@ -56,10 +56,10 @@ properties: offset). $ref: /schemas/types.yaml#/definitions/phandle-array items: - items: - - description: The phandle to the system control region. - - description: The register offset. - - description: The CAN instance number. + - items: + - description: The phandle to the system control region. + - description: The register offset. + - description: The CAN instance number. resets: maxItems: 1 diff --git a/Documentation/devicetree/bindings/net/can/fsl,flexcan.yaml b/Documentation/devicetree/bindings/net/can/fsl,flexcan.yaml index 3f0ee17c1461..e52db841bb8c 100644 --- a/Documentation/devicetree/bindings/net/can/fsl,flexcan.yaml +++ b/Documentation/devicetree/bindings/net/can/fsl,flexcan.yaml @@ -84,12 +84,12 @@ properties: req_bit is the bit offset of CAN stop request. $ref: /schemas/types.yaml#/definitions/phandle-array items: - items: - - description: The 'gpr' is the phandle to general purpose register node. - - description: The 'req_gpr' is the gpr register offset of CAN stop request. - maximum: 0xff - - description: The 'req_bit' is the bit offset of CAN stop request. - maximum: 0x1f + - items: + - description: The 'gpr' is the phandle to general purpose register node. + - description: The 'req_gpr' is the gpr register offset of CAN stop request. + maximum: 0xff + - description: The 'req_bit' is the bit offset of CAN stop request. + maximum: 0x1f fsl,clk-source: description: | diff --git a/Documentation/devicetree/bindings/net/dsa/dsa-port.yaml b/Documentation/devicetree/bindings/net/dsa/dsa-port.yaml index 702df848a71d..c504feeec6db 100644 --- a/Documentation/devicetree/bindings/net/dsa/dsa-port.yaml +++ b/Documentation/devicetree/bindings/net/dsa/dsa-port.yaml @@ -34,6 +34,8 @@ properties: full routing information must be given, not just the one hop routes to neighbouring switches $ref: /schemas/types.yaml#/definitions/phandle-array + items: + maxItems: 1 ethernet: description: diff --git a/Documentation/devicetree/bindings/net/fsl,fec.yaml b/Documentation/devicetree/bindings/net/fsl,fec.yaml index fd8371e31867..daa2f79a294f 100644 --- a/Documentation/devicetree/bindings/net/fsl,fec.yaml +++ b/Documentation/devicetree/bindings/net/fsl,fec.yaml @@ -158,11 +158,13 @@ properties: fsl,stop-mode: $ref: /schemas/types.yaml#/definitions/phandle-array + items: + - items: + - description: phandle to general purpose register node + - description: the gpr register offset for ENET stop request + - description: the gpr bit offset for ENET stop request description: Register bits of stop mode control, the format is <&gpr req_gpr req_bit>. - gpr is the phandle to general purpose register node. - req_gpr is the gpr register offset for ENET stop request. - req_bit is the gpr bit offset for ENET stop request. mdio: $ref: mdio.yaml# diff --git a/Documentation/devicetree/bindings/net/intel,ixp4xx-ethernet.yaml b/Documentation/devicetree/bindings/net/intel,ixp4xx-ethernet.yaml index 67eaf02dda80..4e1b79818aff 100644 --- a/Documentation/devicetree/bindings/net/intel,ixp4xx-ethernet.yaml +++ b/Documentation/devicetree/bindings/net/intel,ixp4xx-ethernet.yaml @@ -29,12 +29,18 @@ properties: queue-rx: $ref: '/schemas/types.yaml#/definitions/phandle-array' - maxItems: 1 + items: + - items: + - description: phandle to the RX queue node + - description: RX queue instance to use description: phandle to the RX queue on the NPE queue-txready: $ref: '/schemas/types.yaml#/definitions/phandle-array' - maxItems: 1 + items: + - items: + - description: phandle to the TX READY queue node + - description: TX READY queue instance to use description: phandle to the TX READY queue on the NPE phy-mode: true @@ -43,7 +49,10 @@ properties: intel,npe-handle: $ref: '/schemas/types.yaml#/definitions/phandle-array' - maxItems: 1 + items: + - items: + - description: phandle to the NPE this ethernet instance is using + - description: the NPE instance to use description: phandle to the NPE this ethernet instance is using and the instance to use in the second cell diff --git a/Documentation/devicetree/bindings/net/intel,ixp4xx-hss.yaml b/Documentation/devicetree/bindings/net/intel,ixp4xx-hss.yaml index 4dcd53c3e0b4..e6329febb60c 100644 --- a/Documentation/devicetree/bindings/net/intel,ixp4xx-hss.yaml +++ b/Documentation/devicetree/bindings/net/intel,ixp4xx-hss.yaml @@ -25,39 +25,62 @@ properties: intel,npe-handle: $ref: '/schemas/types.yaml#/definitions/phandle-array' - maxItems: 1 + items: + items: + - description: phandle to the NPE this HSS instance is using + - description: the NPE instance number description: phandle to the NPE this HSS instance is using and the instance to use in the second cell intel,queue-chl-rxtrig: $ref: '/schemas/types.yaml#/definitions/phandle-array' - maxItems: 1 + items: + - items: + - description: phandle to the RX trigger queue on the NPE + - description: the queue instance number description: phandle to the RX trigger queue on the NPE intel,queue-chl-txready: $ref: '/schemas/types.yaml#/definitions/phandle-array' - maxItems: 1 + items: + - items: + - description: phandle to the TX ready queue on the NPE + - description: the queue instance number description: phandle to the TX ready queue on the NPE intel,queue-pkt-rx: $ref: '/schemas/types.yaml#/definitions/phandle-array' - maxItems: 1 + items: + - items: + - description: phandle to the RX queue on the NPE + - description: the queue instance number description: phandle to the packet RX queue on the NPE intel,queue-pkt-tx: $ref: '/schemas/types.yaml#/definitions/phandle-array' maxItems: 4 + items: + items: + - description: phandle to the TX queue on the NPE + - description: the queue instance number description: phandle to the packet TX0, TX1, TX2 and TX3 queues on the NPE intel,queue-pkt-rxfree: $ref: '/schemas/types.yaml#/definitions/phandle-array' maxItems: 4 + items: + items: + - description: phandle to the RXFREE queue on the NPE + - description: the queue instance number description: phandle to the packet RXFREE0, RXFREE1, RXFREE2 and RXFREE3 queues on the NPE intel,queue-pkt-txdone: $ref: '/schemas/types.yaml#/definitions/phandle-array' - maxItems: 1 + items: + - items: + - description: phandle to the TXDONE queue on the NPE + - description: the queue instance number description: phandle to the packet TXDONE queue on the NPE cts-gpios: diff --git a/Documentation/devicetree/bindings/net/nxp,dwmac-imx.yaml b/Documentation/devicetree/bindings/net/nxp,dwmac-imx.yaml index ee4afe361fac..011363166789 100644 --- a/Documentation/devicetree/bindings/net/nxp,dwmac-imx.yaml +++ b/Documentation/devicetree/bindings/net/nxp,dwmac-imx.yaml @@ -54,6 +54,10 @@ properties: intf_mode: $ref: /schemas/types.yaml#/definitions/phandle-array + items: + - items: + - description: phandle to the GPR syscon + - description: the offset of the GPR register description: Should be phandle/offset pair. The phandle to the syscon node which encompases the GPR register, and the offset of the GPR register. diff --git a/Documentation/devicetree/bindings/net/socionext,uniphier-ave4.yaml b/Documentation/devicetree/bindings/net/socionext,uniphier-ave4.yaml index aad5a9f3f962..e602761f7b14 100644 --- a/Documentation/devicetree/bindings/net/socionext,uniphier-ave4.yaml +++ b/Documentation/devicetree/bindings/net/socionext,uniphier-ave4.yaml @@ -66,6 +66,10 @@ properties: socionext,syscon-phy-mode: $ref: /schemas/types.yaml#/definitions/phandle-array + items: + - items: + - description: phandle to syscon that configures phy mode + - description: ID of MAC instance description: A phandle to syscon with one argument that configures phy mode. The argument is the ID of MAC instance. diff --git a/Documentation/devicetree/bindings/net/stm32-dwmac.yaml b/Documentation/devicetree/bindings/net/stm32-dwmac.yaml index 3d8a3b763ae6..5c93167b3b41 100644 --- a/Documentation/devicetree/bindings/net/stm32-dwmac.yaml +++ b/Documentation/devicetree/bindings/net/stm32-dwmac.yaml @@ -74,6 +74,10 @@ properties: st,syscon: $ref: "/schemas/types.yaml#/definitions/phandle-array" + items: + - items: + - description: phandle to the syscon node which encompases the glue register + - description: offset of the control register description: Should be phandle/offset pair. The phandle to the syscon node which encompases the glue register, and the offset of the control register 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 4b97a0f1175b..b8281d8be940 100644 --- a/Documentation/devicetree/bindings/net/ti,k3-am654-cpsw-nuss.yaml +++ b/Documentation/devicetree/bindings/net/ti,k3-am654-cpsw-nuss.yaml @@ -136,6 +136,11 @@ properties: ti,syscon-efuse: $ref: /schemas/types.yaml#/definitions/phandle-array + items: + - items: + - description: Phandle to the system control device node which + provides access to efuse + - description: offset to efuse registers??? description: Phandle to the system control device node which provides access to efuse IO range with MAC addresses diff --git a/Documentation/devicetree/bindings/net/wireless/mediatek,mt76.yaml b/Documentation/devicetree/bindings/net/wireless/mediatek,mt76.yaml index 269cd63fb544..42e1f4dddca8 100644 --- a/Documentation/devicetree/bindings/net/wireless/mediatek,mt76.yaml +++ b/Documentation/devicetree/bindings/net/wireless/mediatek,mt76.yaml @@ -54,6 +54,10 @@ properties: mediatek,mtd-eeprom: $ref: /schemas/types.yaml#/definitions/phandle-array + items: + - items: + - description: phandle to MTD partition + - description: offset containing EEPROM data description: Phandle to a MTD partition + offset containing EEPROM data diff --git a/Documentation/devicetree/bindings/opp/opp-v2-base.yaml b/Documentation/devicetree/bindings/opp/opp-v2-base.yaml index 15a76bcd6d42..da0f09eedc0c 100644 --- a/Documentation/devicetree/bindings/opp/opp-v2-base.yaml +++ b/Documentation/devicetree/bindings/opp/opp-v2-base.yaml @@ -177,6 +177,8 @@ patternProperties: for the functioning of the current device at the current OPP (where this property is present). $ref: /schemas/types.yaml#/definitions/phandle-array + items: + maxItems: 1 patternProperties: '^opp-microvolt-': diff --git a/Documentation/devicetree/bindings/perf/arm,dsu-pmu.yaml b/Documentation/devicetree/bindings/perf/arm,dsu-pmu.yaml index aef63a542f34..c87821be158b 100644 --- a/Documentation/devicetree/bindings/perf/arm,dsu-pmu.yaml +++ b/Documentation/devicetree/bindings/perf/arm,dsu-pmu.yaml @@ -35,6 +35,8 @@ properties: $ref: /schemas/types.yaml#/definitions/phandle-array minItems: 1 maxItems: 12 + items: + maxItems: 1 description: List of phandles for the CPUs connected to this DSU instance. required: diff --git a/Documentation/devicetree/bindings/phy/intel,combo-phy.yaml b/Documentation/devicetree/bindings/phy/intel,combo-phy.yaml index 347d0cdfb80d..5d54b0a0e873 100644 --- a/Documentation/devicetree/bindings/phy/intel,combo-phy.yaml +++ b/Documentation/devicetree/bindings/phy/intel,combo-phy.yaml @@ -47,10 +47,18 @@ properties: intel,syscfg: $ref: /schemas/types.yaml#/definitions/phandle-array + items: + - items: + - description: phandle to Chip configuration registers + - description: ComboPhy instance id description: Chip configuration registers handle and ComboPhy instance id intel,hsio: $ref: /schemas/types.yaml#/definitions/phandle-array + items: + - items: + - description: phandle to HSIO registers + - description: ComboPhy instance id description: HSIO registers handle and ComboPhy instance id on NOC intel,aggregation: diff --git a/Documentation/devicetree/bindings/phy/ti,omap-usb2.yaml b/Documentation/devicetree/bindings/phy/ti,omap-usb2.yaml index cbbf5e8b1197..51c8a36e61f0 100644 --- a/Documentation/devicetree/bindings/phy/ti,omap-usb2.yaml +++ b/Documentation/devicetree/bindings/phy/ti,omap-usb2.yaml @@ -45,6 +45,10 @@ properties: syscon-phy-power: $ref: /schemas/types.yaml#/definitions/phandle-array + items: + - items: + - description: phandle to the system control module + - description: register offset to power on/off the PHY description: phandle/offset pair. Phandle to the system control module and register offset to power on/off the PHY. diff --git a/Documentation/devicetree/bindings/pinctrl/aspeed,ast2500-pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/aspeed,ast2500-pinctrl.yaml index d316cc082107..acd60c85b4cc 100644 --- a/Documentation/devicetree/bindings/pinctrl/aspeed,ast2500-pinctrl.yaml +++ b/Documentation/devicetree/bindings/pinctrl/aspeed,ast2500-pinctrl.yaml @@ -29,6 +29,8 @@ properties: aspeed,external-nodes: minItems: 2 maxItems: 2 + items: + maxItems: 1 $ref: /schemas/types.yaml#/definitions/phandle-array description: | A cell of phandles to external controller nodes: diff --git a/Documentation/devicetree/bindings/pinctrl/canaan,k210-fpioa.yaml b/Documentation/devicetree/bindings/pinctrl/canaan,k210-fpioa.yaml index a44691d9c57d..53e963e090f2 100644 --- a/Documentation/devicetree/bindings/pinctrl/canaan,k210-fpioa.yaml +++ b/Documentation/devicetree/bindings/pinctrl/canaan,k210-fpioa.yaml @@ -39,6 +39,10 @@ properties: canaan,k210-sysctl-power: $ref: /schemas/types.yaml#/definitions/phandle-array + items: + - items: + - description: phandle of the K210 system controller node + - description: offset of its power domain control register description: | phandle of the K210 system controller node and offset of its power domain control register. diff --git a/Documentation/devicetree/bindings/pinctrl/mediatek,mt65xx-pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/mediatek,mt65xx-pinctrl.yaml index 6953c958ff7c..161088a8be33 100644 --- a/Documentation/devicetree/bindings/pinctrl/mediatek,mt65xx-pinctrl.yaml +++ b/Documentation/devicetree/bindings/pinctrl/mediatek,mt65xx-pinctrl.yaml @@ -44,6 +44,8 @@ properties: mediatek,pctl-regmap: $ref: /schemas/types.yaml#/definitions/phandle-array + items: + maxItems: 1 minItems: 1 maxItems: 2 description: | diff --git a/Documentation/devicetree/bindings/pinctrl/st,stm32-pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/st,stm32-pinctrl.yaml index 83a18d0331b1..335ffc1353b5 100644 --- a/Documentation/devicetree/bindings/pinctrl/st,stm32-pinctrl.yaml +++ b/Documentation/devicetree/bindings/pinctrl/st,stm32-pinctrl.yaml @@ -41,11 +41,13 @@ properties: maxItems: 1 st,syscfg: - description: Should be phandle/offset/mask - - Phandle to the syscon node which includes IRQ mux selection. - - The offset of the IRQ mux selection register. - - The field mask of IRQ mux, needed if different of 0xf. + description: Phandle+args to the syscon node which includes IRQ mux selection. $ref: "/schemas/types.yaml#/definitions/phandle-array" + items: + - items: + - description: syscon node which includes IRQ mux selection + - description: The offset of the IRQ mux selection register + - description: The field mask of IRQ mux, needed if different of 0xf st,package: description: diff --git a/Documentation/devicetree/bindings/power/power-domain.yaml b/Documentation/devicetree/bindings/power/power-domain.yaml index 3143ed9a3313..889091b9814f 100644 --- a/Documentation/devicetree/bindings/power/power-domain.yaml +++ b/Documentation/devicetree/bindings/power/power-domain.yaml @@ -29,6 +29,8 @@ properties: domain-idle-states: $ref: /schemas/types.yaml#/definitions/phandle-array + items: + maxItems: 1 description: | Phandles of idle states that defines the available states for the power-domain provider. The idle state definitions are compatible with the @@ -42,6 +44,8 @@ properties: operating-points-v2: $ref: /schemas/types.yaml#/definitions/phandle-array + items: + maxItems: 1 description: Phandles to the OPP tables of power domains provided by a power domain provider. If the provider provides a single power domain only or all diff --git a/Documentation/devicetree/bindings/power/renesas,apmu.yaml b/Documentation/devicetree/bindings/power/renesas,apmu.yaml index 391897d897f2..4d293b2b2f84 100644 --- a/Documentation/devicetree/bindings/power/renesas,apmu.yaml +++ b/Documentation/devicetree/bindings/power/renesas,apmu.yaml @@ -35,6 +35,8 @@ properties: cpus: $ref: /schemas/types.yaml#/definitions/phandle-array + items: + maxItems: 1 description: | Array of phandles pointing to CPU cores, which should match the order of CPU cores used by the WUPCR and PSTR registers in the Advanced Power diff --git a/Documentation/devicetree/bindings/power/rockchip,power-controller.yaml b/Documentation/devicetree/bindings/power/rockchip,power-controller.yaml index 9b9d71087466..3deb0fc8dfd3 100644 --- a/Documentation/devicetree/bindings/power/rockchip,power-controller.yaml +++ b/Documentation/devicetree/bindings/power/rockchip,power-controller.yaml @@ -129,6 +129,8 @@ $defs: pm_qos: $ref: /schemas/types.yaml#/definitions/phandle-array + items: + maxItems: 1 description: | A number of phandles to qos blocks which need to be saved and restored while power domain switches state. diff --git a/Documentation/devicetree/bindings/power/supply/cw2015_battery.yaml b/Documentation/devicetree/bindings/power/supply/cw2015_battery.yaml index c73abb2ff513..2dda91587dc3 100644 --- a/Documentation/devicetree/bindings/power/supply/cw2015_battery.yaml +++ b/Documentation/devicetree/bindings/power/supply/cw2015_battery.yaml @@ -14,6 +14,9 @@ description: | phandle in monitored-battery. If specified the driver uses the charge-full-design-microamp-hours property of the battery. +allOf: + - $ref: power-supply.yaml# + properties: compatible: const: cellwise,cw2015 @@ -37,9 +40,6 @@ properties: minimum: 250 power-supplies: - description: - Specifies supplies used for charging the battery connected to this gauge - $ref: /schemas/types.yaml#/definitions/phandle-array minItems: 1 maxItems: 8 # Should be enough diff --git a/Documentation/devicetree/bindings/power/supply/power-supply.yaml b/Documentation/devicetree/bindings/power/supply/power-supply.yaml index 259760167759..531b67225c74 100644 --- a/Documentation/devicetree/bindings/power/supply/power-supply.yaml +++ b/Documentation/devicetree/bindings/power/supply/power-supply.yaml @@ -12,6 +12,8 @@ maintainers: properties: power-supplies: $ref: /schemas/types.yaml#/definitions/phandle-array + items: + maxItems: 1 description: This property is added to a supply in order to list the devices which supply it power, referenced by their phandles. diff --git a/Documentation/devicetree/bindings/regulator/regulator.yaml b/Documentation/devicetree/bindings/regulator/regulator.yaml index ed560ee8714e..a9b66ececccf 100644 --- a/Documentation/devicetree/bindings/regulator/regulator.yaml +++ b/Documentation/devicetree/bindings/regulator/regulator.yaml @@ -213,6 +213,8 @@ properties: is 2-way - all coupled regulators should be linked with each other. A regulator should not be coupled with its supplier. $ref: "/schemas/types.yaml#/definitions/phandle-array" + items: + maxItems: 1 regulator-coupled-max-spread: description: Array of maximum spread between voltages of coupled regulators diff --git a/Documentation/devicetree/bindings/regulator/st,stm32-booster.yaml b/Documentation/devicetree/bindings/regulator/st,stm32-booster.yaml index df0191b1ceba..38bdaef4fa39 100644 --- a/Documentation/devicetree/bindings/regulator/st,stm32-booster.yaml +++ b/Documentation/devicetree/bindings/regulator/st,stm32-booster.yaml @@ -23,7 +23,7 @@ properties: - st,stm32mp1-booster st,syscfg: - $ref: "/schemas/types.yaml#/definitions/phandle-array" + $ref: "/schemas/types.yaml#/definitions/phandle" description: phandle to system configuration controller. vdda-supply: diff --git a/Documentation/devicetree/bindings/remoteproc/qcom,adsp.yaml b/Documentation/devicetree/bindings/remoteproc/qcom,adsp.yaml index c635c181d2c2..bcad8f4080d4 100644 --- a/Documentation/devicetree/bindings/remoteproc/qcom,adsp.yaml +++ b/Documentation/devicetree/bindings/remoteproc/qcom,adsp.yaml @@ -115,6 +115,12 @@ properties: qcom,halt-regs: $ref: /schemas/types.yaml#/definitions/phandle-array + items: + - items: + - description: Phandle reference to a syscon representing TCSR + - description: offsets within syscon for q6 halt registers + - description: offsets within syscon for modem halt registers + - description: offsets within syscon for nc halt registers description: Phandle reference to a syscon representing TCSR followed by the three offsets within syscon for q6, modem and nc halt registers. diff --git a/Documentation/devicetree/bindings/remoteproc/st,stm32-rproc.yaml b/Documentation/devicetree/bindings/remoteproc/st,stm32-rproc.yaml index b587c97c282b..be3d9b0e876b 100644 --- a/Documentation/devicetree/bindings/remoteproc/st,stm32-rproc.yaml +++ b/Documentation/devicetree/bindings/remoteproc/st,stm32-rproc.yaml @@ -29,17 +29,22 @@ properties: st,syscfg-holdboot: description: remote processor reset hold boot - - Phandle of syscon block. - - The offset of the hold boot setting register. - - The field mask of the hold boot. $ref: "/schemas/types.yaml#/definitions/phandle-array" - maxItems: 1 + items: + - items: + - description: Phandle of syscon block + - description: The offset of the hold boot setting register + - description: The field mask of the hold boot st,syscfg-tz: description: Reference to the system configuration which holds the RCC trust zone mode $ref: "/schemas/types.yaml#/definitions/phandle-array" - maxItems: 1 + items: + - items: + - description: Phandle of syscon block + - description: FIXME + - description: FIXME interrupts: description: Should contain the WWDG1 watchdog reset interrupt @@ -93,20 +98,32 @@ properties: $ref: "/schemas/types.yaml#/definitions/phandle-array" description: | Reference to the system configuration which holds the remote - maxItems: 1 + items: + - items: + - description: Phandle of syscon block + - description: FIXME + - description: FIXME st,syscfg-m4-state: $ref: "/schemas/types.yaml#/definitions/phandle-array" description: | Reference to the tamp register which exposes the Cortex-M4 state. - maxItems: 1 + items: + - items: + - description: Phandle of syscon block with the tamp register + - description: FIXME + - description: FIXME st,syscfg-rsc-tbl: $ref: "/schemas/types.yaml#/definitions/phandle-array" description: | Reference to the tamp register which references the Cortex-M4 resource table address. - maxItems: 1 + items: + - items: + - description: Phandle of syscon block with the tamp register + - description: FIXME + - description: FIXME st,auto-boot: $ref: /schemas/types.yaml#/definitions/flag diff --git a/Documentation/devicetree/bindings/remoteproc/ti,k3-dsp-rproc.yaml b/Documentation/devicetree/bindings/remoteproc/ti,k3-dsp-rproc.yaml index 7b56497eec4d..4323cefdf19b 100644 --- a/Documentation/devicetree/bindings/remoteproc/ti,k3-dsp-rproc.yaml +++ b/Documentation/devicetree/bindings/remoteproc/ti,k3-dsp-rproc.yaml @@ -79,6 +79,8 @@ properties: $ref: /schemas/types.yaml#/definitions/phandle-array minItems: 1 maxItems: 4 + items: + maxItems: 1 description: | phandles to one or more reserved on-chip SRAM regions. The regions should be defined as child nodes of the respective SRAM node, and diff --git a/Documentation/devicetree/bindings/remoteproc/ti,k3-r5f-rproc.yaml b/Documentation/devicetree/bindings/remoteproc/ti,k3-r5f-rproc.yaml index d9c7e8c2b268..0f2bb06cb7b4 100644 --- a/Documentation/devicetree/bindings/remoteproc/ti,k3-r5f-rproc.yaml +++ b/Documentation/devicetree/bindings/remoteproc/ti,k3-r5f-rproc.yaml @@ -189,6 +189,8 @@ patternProperties: $ref: /schemas/types.yaml#/definitions/phandle-array minItems: 1 maxItems: 4 + items: + maxItems: 1 description: | phandles to one or more reserved on-chip SRAM regions. The regions should be defined as child nodes of the respective SRAM node, and diff --git a/Documentation/devicetree/bindings/remoteproc/ti,omap-remoteproc.yaml b/Documentation/devicetree/bindings/remoteproc/ti,omap-remoteproc.yaml index c6c12129d6b7..1fdc2741c36e 100644 --- a/Documentation/devicetree/bindings/remoteproc/ti,omap-remoteproc.yaml +++ b/Documentation/devicetree/bindings/remoteproc/ti,omap-remoteproc.yaml @@ -123,13 +123,14 @@ properties: ti,bootreg: $ref: /schemas/types.yaml#/definitions/phandle-array - description: | - Should be a triple of the phandle to the System Control - Configuration region that contains the boot address - register, the register offset of the boot address - register within the System Control module, and the bit - shift within the register. This property is required for - all the DSP instances on OMAP4, OMAP5 and DRA7xx SoCs. + items: + - items: + - description: phandle to the System Control Configuration region + - description: register offset of the boot address register + - description: the bit shift within the register + description: + This property is required for all the DSP instances on OMAP4, OMAP5 + and DRA7xx SoCs. ti,autosuspend-delay-ms: description: | @@ -140,6 +141,8 @@ properties: ti,timers: $ref: /schemas/types.yaml#/definitions/phandle-array + items: + maxItems: 1 description: | One or more phandles to OMAP DMTimer nodes, that serve as System/Tick timers for the OS running on the remote @@ -156,6 +159,8 @@ properties: ti,watchdog-timers: $ref: /schemas/types.yaml#/definitions/phandle-array + items: + maxItems: 1 description: | One or more phandles to OMAP DMTimer nodes, used to serve as Watchdog timers for the processor cores. This diff --git a/Documentation/devicetree/bindings/soc/samsung/exynos-usi.yaml b/Documentation/devicetree/bindings/soc/samsung/exynos-usi.yaml index 273f2d95a043..58f2e9d8bb0e 100644 --- a/Documentation/devicetree/bindings/soc/samsung/exynos-usi.yaml +++ b/Documentation/devicetree/bindings/soc/samsung/exynos-usi.yaml @@ -48,6 +48,10 @@ properties: samsung,sysreg: $ref: /schemas/types.yaml#/definitions/phandle-array + items: + - items: + - description: phandle to System Register syscon node + - description: offset of SW_CONF register for this USI controller description: Should be phandle/offset pair. The phandle to System Register syscon node (for the same domain where this USI controller resides) and the offset diff --git a/Documentation/devicetree/bindings/sound/samsung,aries-wm8994.yaml b/Documentation/devicetree/bindings/sound/samsung,aries-wm8994.yaml index 5fff586dc802..eb487ed3ca3b 100644 --- a/Documentation/devicetree/bindings/sound/samsung,aries-wm8994.yaml +++ b/Documentation/devicetree/bindings/sound/samsung,aries-wm8994.yaml @@ -27,6 +27,8 @@ properties: sound-dai: minItems: 2 maxItems: 2 + items: + maxItems: 1 $ref: /schemas/types.yaml#/definitions/phandle-array description: | phandles to the I2S controller and bluetooth codec, diff --git a/Documentation/devicetree/bindings/sound/st,stm32-sai.yaml b/Documentation/devicetree/bindings/sound/st,stm32-sai.yaml index 1538d11ce9a8..d4fc8fdcb72f 100644 --- a/Documentation/devicetree/bindings/sound/st,stm32-sai.yaml +++ b/Documentation/devicetree/bindings/sound/st,stm32-sai.yaml @@ -102,9 +102,11 @@ patternProperties: By default SAI sub-block is in asynchronous mode. Must contain the phandle and index of the SAI sub-block providing the synchronization. - allOf: - - $ref: /schemas/types.yaml#/definitions/phandle-array - - maxItems: 1 + $ref: /schemas/types.yaml#/definitions/phandle-array + items: + - items: + - description: phandle of the SAI sub-block + - description: index of the SAI sub-block st,iec60958: description: diff --git a/Documentation/devicetree/bindings/thermal/thermal-cooling-devices.yaml b/Documentation/devicetree/bindings/thermal/thermal-cooling-devices.yaml index f004779ba9b3..850a9841b110 100644 --- a/Documentation/devicetree/bindings/thermal/thermal-cooling-devices.yaml +++ b/Documentation/devicetree/bindings/thermal/thermal-cooling-devices.yaml @@ -66,9 +66,9 @@ examples: compatible = "qcom,kryo385"; reg = <0x0 0x0>; enable-method = "psci"; - cpu-idle-states = <&LITTLE_CPU_SLEEP_0 - &LITTLE_CPU_SLEEP_1 - &CLUSTER_SLEEP_0>; + cpu-idle-states = <&LITTLE_CPU_SLEEP_0>, + <&LITTLE_CPU_SLEEP_1>, + <&CLUSTER_SLEEP_0>; capacity-dmips-mhz = <607>; dynamic-power-coefficient = <100>; qcom,freq-domain = <&cpufreq_hw 0>; diff --git a/Documentation/devicetree/bindings/thermal/thermal-idle.yaml b/Documentation/devicetree/bindings/thermal/thermal-idle.yaml index 6278ccf16f3f..cc938d7ad1f3 100644 --- a/Documentation/devicetree/bindings/thermal/thermal-idle.yaml +++ b/Documentation/devicetree/bindings/thermal/thermal-idle.yaml @@ -37,8 +37,8 @@ properties: exit-latency-us: description: | - The exit latency constraint in microsecond for the injected idle state - for the device. It is the latency constraint to apply when selecting an + The exit latency constraint in microsecond for the injected idle state + for the device. It is the latency constraint to apply when selecting an idle state from among all the present ones. required: @@ -65,7 +65,7 @@ examples: capacity-dmips-mhz = <1024>; dynamic-power-coefficient = <436>; #cooling-cells = <2>; /* min followed by max */ - cpu-idle-states = <&CPU_SLEEP &CLUSTER_SLEEP>; + cpu-idle-states = <&CPU_SLEEP>, <&CLUSTER_SLEEP>; thermal-idle { #cooling-cells = <2>; duration-us = <10000>; @@ -81,7 +81,7 @@ examples: capacity-dmips-mhz = <1024>; dynamic-power-coefficient = <436>; #cooling-cells = <2>; /* min followed by max */ - cpu-idle-states = <&CPU_SLEEP &CLUSTER_SLEEP>; + cpu-idle-states = <&CPU_SLEEP>, <&CLUSTER_SLEEP>; thermal-idle { #cooling-cells = <2>; duration-us = <10000>; diff --git a/Documentation/devicetree/bindings/usb/nvidia,tegra-xudc.yaml b/Documentation/devicetree/bindings/usb/nvidia,tegra-xudc.yaml index a39c76b89484..fd6e7c81426e 100644 --- a/Documentation/devicetree/bindings/usb/nvidia,tegra-xudc.yaml +++ b/Documentation/devicetree/bindings/usb/nvidia,tegra-xudc.yaml @@ -83,7 +83,7 @@ properties: - const: ss nvidia,xusb-padctl: - $ref: /schemas/types.yaml#/definitions/phandle-array + $ref: /schemas/types.yaml#/definitions/phandle description: phandle to the XUSB pad controller that is used to configure the USB pads used by the XUDC controller. From 58bcfe0a082d5b3bf53135c7ee812beb9404803e Mon Sep 17 00:00:00 2001 From: Rob Herring Date: Tue, 18 Jan 2022 19:52:34 -0600 Subject: [PATCH 050/370] dt-bindings: i2c: mpc: Make each example a separate entry Each independent example should be a separate entry. This allows for 'interrupts' to have different cell sizes. Signed-off-by: Rob Herring Link: https://lore.kernel.org/r/20220119015234.2436754-1-robh@kernel.org --- Documentation/devicetree/bindings/i2c/i2c-mpc.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Documentation/devicetree/bindings/i2c/i2c-mpc.yaml b/Documentation/devicetree/bindings/i2c/i2c-mpc.yaml index 98c6fcf7bf26..018e1b944424 100644 --- a/Documentation/devicetree/bindings/i2c/i2c-mpc.yaml +++ b/Documentation/devicetree/bindings/i2c/i2c-mpc.yaml @@ -73,6 +73,7 @@ examples: clock-frequency = <100000>; }; + - | /* MPC5200B based board */ i2c@3d00 { #address-cells = <1>; @@ -84,6 +85,7 @@ examples: fsl,preserve-clocking; }; + - | /* MPC8544 base board */ i2c@3100 { #address-cells = <1>; From 8682016ca04371d13f3384b2e14de779286f8549 Mon Sep 17 00:00:00 2001 From: Rob Herring Date: Tue, 18 Jan 2022 19:52:53 -0600 Subject: [PATCH 051/370] dt-bindings: i2c: imx: Make each example a separate entry Each independent example should be a separate entry. This allows for 'interrupts' to have different cell sizes. Signed-off-by: Rob Herring Reviewed-by: Oleksij Rempel Link: https://lore.kernel.org/r/20220119015253.2437352-1-robh@kernel.org --- Documentation/devicetree/bindings/i2c/i2c-imx.yaml | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/Documentation/devicetree/bindings/i2c/i2c-imx.yaml b/Documentation/devicetree/bindings/i2c/i2c-imx.yaml index c167958ae2a9..01720e338b4c 100644 --- a/Documentation/devicetree/bindings/i2c/i2c-imx.yaml +++ b/Documentation/devicetree/bindings/i2c/i2c-imx.yaml @@ -88,9 +88,7 @@ unevaluatedProperties: false examples: - | #include - #include - #include - #include + #include i2c@83fc4000 { compatible = "fsl,imx51-i2c", "fsl,imx21-i2c"; @@ -99,6 +97,9 @@ examples: clocks = <&clks IMX5_CLK_I2C2_GATE>; }; + - | + #include + i2c@40066000 { compatible = "fsl,vf610-i2c"; reg = <0x40066000 0x1000>; From a1ba6ac48a9f707369e35b7305cf492714b7a277 Mon Sep 17 00:00:00 2001 From: Rob Herring Date: Wed, 19 Jan 2022 09:11:35 -0600 Subject: [PATCH 052/370] dt-bindings: nvmem: qcom,spmi-sdam: Drop child node schema Drop the child node schema. The schema for child nodes is already defined by nvmem.yaml and doesn't need to be duplicated in the qcom,spmi-sdam schema. Signed-off-by: Rob Herring Link: https://lore.kernel.org/r/20220119151135.3598392-1-robh@kernel.org --- .../bindings/nvmem/qcom,spmi-sdam.yaml | 28 ------------------- 1 file changed, 28 deletions(-) diff --git a/Documentation/devicetree/bindings/nvmem/qcom,spmi-sdam.yaml b/Documentation/devicetree/bindings/nvmem/qcom,spmi-sdam.yaml index a835e64bc6f5..ee79e13b5fe0 100644 --- a/Documentation/devicetree/bindings/nvmem/qcom,spmi-sdam.yaml +++ b/Documentation/devicetree/bindings/nvmem/qcom,spmi-sdam.yaml @@ -38,34 +38,6 @@ required: - reg - ranges -patternProperties: - "^.*@[0-9a-f]+$": - type: object - - properties: - reg: - maxItems: 1 - description: - Offset and size in bytes within the storage device. - - bits: - $ref: /schemas/types.yaml#/definitions/uint32-array - maxItems: 1 - items: - items: - - minimum: 0 - maximum: 7 - description: - Offset in bit within the address range specified by reg. - - minimum: 1 - description: - Size in bit within the address range specified by reg. - - required: - - reg - - additionalProperties: false - unevaluatedProperties: false examples: From b588772a9cb3c151185a7cafb8c5f38d8ebeaf50 Mon Sep 17 00:00:00 2001 From: Rob Herring Date: Wed, 19 Jan 2022 11:43:49 -0600 Subject: [PATCH 053/370] dt-bindings: ingenic,i2c: Rework interrupts in example In order to determine the number of interrupt cells in examples, the examples will require all 'interrupts' properties to use the same number of cells or have explicit interrupt provider node(s). As the former is simpler, update the Ingenic example to use 2 interrupt cells everywhere. Signed-off-by: Rob Herring Link: https://lore.kernel.org/r/20220119174349.3809513-1-robh@kernel.org --- Documentation/devicetree/bindings/i2c/ingenic,i2c.yaml | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/Documentation/devicetree/bindings/i2c/ingenic,i2c.yaml b/Documentation/devicetree/bindings/i2c/ingenic,i2c.yaml index febde6cc5f69..af6d64a6da6e 100644 --- a/Documentation/devicetree/bindings/i2c/ingenic,i2c.yaml +++ b/Documentation/devicetree/bindings/i2c/ingenic,i2c.yaml @@ -69,8 +69,7 @@ examples: #size-cells = <0>; reg = <0x10054000 0x1000>; - interrupt-parent = <&intc>; - interrupts = <56>; + interrupts = <56 IRQ_TYPE_LEVEL_LOW>; clocks = <&cgu JZ4780_CLK_SMB4>; pinctrl-names = "default"; @@ -86,7 +85,6 @@ examples: compatible = "nxp,pcf8563"; reg = <0x51>; - interrupt-parent = <&gpf>; interrupts = <30 IRQ_TYPE_LEVEL_LOW>; }; }; From b1809ee932101dbf1b29e860b06d1c26310f2f91 Mon Sep 17 00:00:00 2001 From: Rob Herring Date: Wed, 19 Jan 2022 11:44:07 -0600 Subject: [PATCH 054/370] dt-bindings: i2c: stm32-i2c: Move st,syscfg-fmp definition to top level It is preferred to define all properties in the main schema and leave if/then/else schemas to just be further constraints on properties. Rework the schema to use be more specific for each cell. Previously, multiple entries of 3 cells each was allowed. Signed-off-by: Rob Herring Link: https://lore.kernel.org/r/20220119174407.3810088-1-robh@kernel.org --- .../devicetree/bindings/i2c/st,stm32-i2c.yaml | 24 ++++++++++--------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/Documentation/devicetree/bindings/i2c/st,stm32-i2c.yaml b/Documentation/devicetree/bindings/i2c/st,stm32-i2c.yaml index 46b62e1c9273..dccbb18b6dc0 100644 --- a/Documentation/devicetree/bindings/i2c/st,stm32-i2c.yaml +++ b/Documentation/devicetree/bindings/i2c/st,stm32-i2c.yaml @@ -25,16 +25,9 @@ allOf: i2c-scl-falling-time-ns: default: 10 - - st,syscfg-fmp: - description: Use to set Fast Mode Plus bit within SYSCFG when - Fast Mode Plus speed is selected by slave. - Format is phandle to syscfg / register offset within - syscfg / register bitmask for FMP bit. - $ref: "/schemas/types.yaml#/definitions/phandle-array" - items: - minItems: 3 - maxItems: 3 + else: + properties: + st,syscfg-fmp: false - if: properties: @@ -87,6 +80,16 @@ properties: minimum: 1 maximum: 1000000 + st,syscfg-fmp: + description: Use to set Fast Mode Plus bit within SYSCFG when Fast Mode + Plus speed is selected by slave. + $ref: "/schemas/types.yaml#/definitions/phandle-array" + items: + - items: + - description: phandle to syscfg + - description: register offset within syscfg + - description: register bitmask for FMP bit + required: - compatible - reg @@ -147,4 +150,3 @@ examples: i2c-scl-falling-time-ns = <20>; st,syscfg-fmp = <&syscfg 0x4 0x2>; }; -... From d7b0c4aae17100f5ab7d67a361d79165cb983f18 Mon Sep 17 00:00:00 2001 From: Rob Herring Date: Thu, 20 Jan 2022 11:23:18 -0600 Subject: [PATCH 055/370] dt-bindings: net: ti,k3-am654-cpts: Fix assigned-clock-parents The schema has a typo with 'assigned-clocks-parents'. As it is not required to list assigned clocks in bindings, just drop the assigned-clocks property definitions to fix this Signed-off-by: Rob Herring Link: https://lore.kernel.org/r/20220120172319.1628500-1-robh@kernel.org --- Documentation/devicetree/bindings/net/ti,k3-am654-cpts.yaml | 6 ------ 1 file changed, 6 deletions(-) diff --git a/Documentation/devicetree/bindings/net/ti,k3-am654-cpts.yaml b/Documentation/devicetree/bindings/net/ti,k3-am654-cpts.yaml index 1a81bf70c88c..a30419ef550a 100644 --- a/Documentation/devicetree/bindings/net/ti,k3-am654-cpts.yaml +++ b/Documentation/devicetree/bindings/net/ti,k3-am654-cpts.yaml @@ -103,12 +103,6 @@ properties: clocks: maxItems: 8 - assigned-clocks: - maxItems: 1 - - assigned-clocks-parents: - maxItems: 1 - required: - clocks From b85c7d88ed87dcc86981118876160fc74ab2d1fb Mon Sep 17 00:00:00 2001 From: Rob Herring Date: Thu, 20 Jan 2022 11:23:32 -0600 Subject: [PATCH 056/370] dt-bindings: watchdog: fsl-imx7ulp-wdt: Fix assigned-clock-parents The schema has a typo with 'assigned-clocks-parents'. As it is not required to list assigned clocks in bindings, just drop the assigned-clocks property definitions to fix this. Signed-off-by: Rob Herring Acked-by: Guenter Roeck Link: https://lore.kernel.org/r/20220120172333.1628990-1-robh@kernel.org --- .../devicetree/bindings/watchdog/fsl-imx7ulp-wdt.yaml | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/Documentation/devicetree/bindings/watchdog/fsl-imx7ulp-wdt.yaml b/Documentation/devicetree/bindings/watchdog/fsl-imx7ulp-wdt.yaml index fb603a20e396..4ca8a31359a5 100644 --- a/Documentation/devicetree/bindings/watchdog/fsl-imx7ulp-wdt.yaml +++ b/Documentation/devicetree/bindings/watchdog/fsl-imx7ulp-wdt.yaml @@ -29,12 +29,6 @@ properties: clocks: maxItems: 1 - assigned-clocks: - maxItems: 1 - - assigned-clocks-parents: - maxItems: 1 - timeout-sec: true required: @@ -56,7 +50,7 @@ examples: interrupts = ; clocks = <&pcc2 IMX7ULP_CLK_WDG1>; assigned-clocks = <&pcc2 IMX7ULP_CLK_WDG1>; - assigned-clocks-parents = <&scg1 IMX7ULP_CLK_FIRC_BUS_CLK>; + assigned-clock-parents = <&scg1 IMX7ULP_CLK_FIRC_BUS_CLK>; timeout-sec = <40>; }; From 24a4b57a3d014751ec8ba8b33f38390d5bda94c2 Mon Sep 17 00:00:00 2001 From: Rob Herring Date: Wed, 19 Jan 2022 12:10:54 -0600 Subject: [PATCH 057/370] dt-bindings: remoteproc: ti: Add mailbox provider nodes to example In order to make the 'mboxes' property in the TI remoteproc examples parseable, mailbox provider nodes are needed. Normally, the examples have a __fixup__ node which can be used for determining each phandle+arg entry. However, for this binding the arg cells contain a phandle, and the __fixups__ information can't be used. Signed-off-by: Rob Herring Link: https://lore.kernel.org/r/20220119181053.3846613-1-robh@kernel.org --- .../devicetree/bindings/remoteproc/ti,k3-dsp-rproc.yaml | 8 ++++++++ .../devicetree/bindings/remoteproc/ti,k3-r5f-rproc.yaml | 8 ++++++++ 2 files changed, 16 insertions(+) diff --git a/Documentation/devicetree/bindings/remoteproc/ti,k3-dsp-rproc.yaml b/Documentation/devicetree/bindings/remoteproc/ti,k3-dsp-rproc.yaml index 4323cefdf19b..cedbc5efdc56 100644 --- a/Documentation/devicetree/bindings/remoteproc/ti,k3-dsp-rproc.yaml +++ b/Documentation/devicetree/bindings/remoteproc/ti,k3-dsp-rproc.yaml @@ -142,6 +142,14 @@ examples: #address-cells = <2>; #size-cells = <2>; + mailbox0_cluster3: mailbox-0 { + #mbox-cells = <1>; + }; + + mailbox0_cluster4: mailbox-1 { + #mbox-cells = <1>; + }; + bus@100000 { compatible = "simple-bus"; #address-cells = <2>; diff --git a/Documentation/devicetree/bindings/remoteproc/ti,k3-r5f-rproc.yaml b/Documentation/devicetree/bindings/remoteproc/ti,k3-r5f-rproc.yaml index 0f2bb06cb7b4..0868154a0364 100644 --- a/Documentation/devicetree/bindings/remoteproc/ti,k3-r5f-rproc.yaml +++ b/Documentation/devicetree/bindings/remoteproc/ti,k3-r5f-rproc.yaml @@ -238,6 +238,14 @@ examples: #address-cells = <2>; #size-cells = <2>; + mailbox0: mailbox-0 { + #mbox-cells = <1>; + }; + + mailbox1: mailbox-1 { + #mbox-cells = <1>; + }; + bus@100000 { compatible = "simple-bus"; #address-cells = <2>; From d7f17b661fe947719500f8b3296f7f02113e8951 Mon Sep 17 00:00:00 2001 From: Rob Herring Date: Wed, 26 Jan 2022 17:11:46 -0600 Subject: [PATCH 058/370] dt-bindings: arm,cci-400: Add interrupt controller to example In order to parse the 'interrupts' an interrupt provider node is needed. That is because the example is a full example (starting with root node) and on those we don't guess and generate a fake provider. Signed-off-by: Rob Herring Link: https://lore.kernel.org/r/20220126231146.1632819-1-robh@kernel.org --- Documentation/devicetree/bindings/arm/arm,cci-400.yaml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Documentation/devicetree/bindings/arm/arm,cci-400.yaml b/Documentation/devicetree/bindings/arm/arm,cci-400.yaml index f8530a50863a..1706134b75a3 100644 --- a/Documentation/devicetree/bindings/arm/arm,cci-400.yaml +++ b/Documentation/devicetree/bindings/arm/arm,cci-400.yaml @@ -119,6 +119,11 @@ examples: arm,hbi = <0x249>; interrupt-parent = <&gic>; + gic: interrupt-controller { + interrupt-controller; + #interrupt-cells = <3>; + }; + /* * This CCI node corresponds to a CCI component whose control * registers sits at address 0x000000002c090000. From 97709d365bbd68056ace43ef47ad8aaf40f44855 Mon Sep 17 00:00:00 2001 From: Rob Herring Date: Wed, 26 Jan 2022 17:14:27 -0600 Subject: [PATCH 059/370] ASoC: dt-bindings: Centralize the 'sound-dai' definition 'sound-dai' is a common property, but has duplicate type definitions. Create a new common definition to define the type and then update all the other occurrences to just define how many entries there are just like other phandle+arg properties. The constraints on the number of entries is based on the examples and could be wrong. Cc: Krzysztof Kozlowski Signed-off-by: Rob Herring Acked-by: Jerome Brunet Acked-by: Krzysztof Kozlowski Acked-by: Mark Brown Link: https://lore.kernel.org/r/20220126231427.1638089-1-robh@kernel.org --- .../bindings/sound/amlogic,gx-sound-card.yaml | 4 ++-- .../bindings/sound/google,sc7180-trogdor.yaml | 6 ++++-- .../bindings/sound/imx-audio-card.yaml | 7 +++++-- .../bindings/sound/qcom,sm8250.yaml | 10 +++++++--- .../bindings/sound/samsung,aries-wm8994.yaml | 5 +---- .../bindings/sound/samsung,midas-audio.yaml | 2 -- .../bindings/sound/samsung,odroid.yaml | 9 +++------ .../devicetree/bindings/sound/sound-dai.yaml | 20 +++++++++++++++++++ 8 files changed, 42 insertions(+), 21 deletions(-) create mode 100644 Documentation/devicetree/bindings/sound/sound-dai.yaml diff --git a/Documentation/devicetree/bindings/sound/amlogic,gx-sound-card.yaml b/Documentation/devicetree/bindings/sound/amlogic,gx-sound-card.yaml index 2e35aeaa8781..8b5be4b92f35 100644 --- a/Documentation/devicetree/bindings/sound/amlogic,gx-sound-card.yaml +++ b/Documentation/devicetree/bindings/sound/amlogic,gx-sound-card.yaml @@ -57,7 +57,7 @@ patternProperties: rate sound-dai: - $ref: /schemas/types.yaml#/definitions/phandle-array + maxItems: 1 description: phandle of the CPU DAI patternProperties: @@ -71,7 +71,7 @@ patternProperties: properties: sound-dai: - $ref: /schemas/types.yaml#/definitions/phandle-array + maxItems: 1 description: phandle of the codec DAI required: diff --git a/Documentation/devicetree/bindings/sound/google,sc7180-trogdor.yaml b/Documentation/devicetree/bindings/sound/google,sc7180-trogdor.yaml index 837e3faa63a9..233caa0ade87 100644 --- a/Documentation/devicetree/bindings/sound/google,sc7180-trogdor.yaml +++ b/Documentation/devicetree/bindings/sound/google,sc7180-trogdor.yaml @@ -62,13 +62,15 @@ patternProperties: description: Holds subnode which indicates cpu dai. type: object properties: - sound-dai: true + sound-dai: + maxItems: 1 codec: description: Holds subnode which indicates codec dai. type: object properties: - sound-dai: true + sound-dai: + maxItems: 1 required: - link-name diff --git a/Documentation/devicetree/bindings/sound/imx-audio-card.yaml b/Documentation/devicetree/bindings/sound/imx-audio-card.yaml index d1816dd061cf..bb3a435722c7 100644 --- a/Documentation/devicetree/bindings/sound/imx-audio-card.yaml +++ b/Documentation/devicetree/bindings/sound/imx-audio-card.yaml @@ -59,13 +59,16 @@ patternProperties: description: Holds subnode which indicates cpu dai. type: object properties: - sound-dai: true + sound-dai: + maxItems: 1 codec: description: Holds subnode which indicates codec dai. type: object properties: - sound-dai: true + sound-dai: + minItems: 1 + maxItems: 2 fsl,mclk-equal-bclk: description: Indicates mclk can be equal to bclk, especially for sai interface diff --git a/Documentation/devicetree/bindings/sound/qcom,sm8250.yaml b/Documentation/devicetree/bindings/sound/qcom,sm8250.yaml index 4bfda04b4608..4ecd4080bb96 100644 --- a/Documentation/devicetree/bindings/sound/qcom,sm8250.yaml +++ b/Documentation/devicetree/bindings/sound/qcom,sm8250.yaml @@ -69,19 +69,23 @@ patternProperties: description: Holds subnode which indicates cpu dai. type: object properties: - sound-dai: true + sound-dai: + maxItems: 1 platform: description: Holds subnode which indicates platform dai. type: object properties: - sound-dai: true + sound-dai: + maxItems: 1 codec: description: Holds subnode which indicates codec dai. type: object properties: - sound-dai: true + sound-dai: + minItems: 1 + maxItems: 4 required: - link-name diff --git a/Documentation/devicetree/bindings/sound/samsung,aries-wm8994.yaml b/Documentation/devicetree/bindings/sound/samsung,aries-wm8994.yaml index eb487ed3ca3b..4ffa275b3c49 100644 --- a/Documentation/devicetree/bindings/sound/samsung,aries-wm8994.yaml +++ b/Documentation/devicetree/bindings/sound/samsung,aries-wm8994.yaml @@ -27,9 +27,6 @@ properties: sound-dai: minItems: 2 maxItems: 2 - items: - maxItems: 1 - $ref: /schemas/types.yaml#/definitions/phandle-array description: | phandles to the I2S controller and bluetooth codec, in that order @@ -38,7 +35,7 @@ properties: type: object properties: sound-dai: - $ref: /schemas/types.yaml#/definitions/phandle-array + maxItems: 1 description: phandle to the WM8994 CODEC samsung,audio-routing: diff --git a/Documentation/devicetree/bindings/sound/samsung,midas-audio.yaml b/Documentation/devicetree/bindings/sound/samsung,midas-audio.yaml index 095775c598fa..ec50bcb4af5f 100644 --- a/Documentation/devicetree/bindings/sound/samsung,midas-audio.yaml +++ b/Documentation/devicetree/bindings/sound/samsung,midas-audio.yaml @@ -21,7 +21,6 @@ properties: type: object properties: sound-dai: - $ref: /schemas/types.yaml#/definitions/phandle-array maxItems: 1 description: phandle to the I2S controller required: @@ -31,7 +30,6 @@ properties: type: object properties: sound-dai: - $ref: /schemas/types.yaml#/definitions/phandle-array maxItems: 1 description: phandle to the WM1811 CODEC required: diff --git a/Documentation/devicetree/bindings/sound/samsung,odroid.yaml b/Documentation/devicetree/bindings/sound/samsung,odroid.yaml index e8122bc87362..db2513f3e168 100644 --- a/Documentation/devicetree/bindings/sound/samsung,odroid.yaml +++ b/Documentation/devicetree/bindings/sound/samsung,odroid.yaml @@ -37,18 +37,15 @@ properties: type: object properties: sound-dai: - $ref: /schemas/types.yaml#/definitions/phandle-array description: phandles to the I2S controllers codec: type: object properties: sound-dai: - $ref: /schemas/types.yaml#/definitions/phandle-array - description: | - List of phandles to the CODEC nodes, - first entry must be corresponding to the MAX98090 CODEC and - the second entry must be the phandle of the HDMI IP block node. + items: + - description: phandle of the MAX98090 CODEC + - description: phandle of the HDMI IP block node samsung,audio-routing: $ref: /schemas/types.yaml#/definitions/non-unique-string-array diff --git a/Documentation/devicetree/bindings/sound/sound-dai.yaml b/Documentation/devicetree/bindings/sound/sound-dai.yaml new file mode 100644 index 000000000000..61c6f7abc4e7 --- /dev/null +++ b/Documentation/devicetree/bindings/sound/sound-dai.yaml @@ -0,0 +1,20 @@ +# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/sound/sound-dai.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Digital Audio Interface consumer Device Tree Bindings + +maintainers: + - Rob Herring + +select: true + +properties: + sound-dai: + $ref: /schemas/types.yaml#/definitions/phandle-array + description: A phandle plus args to digital audio interface provider(s) + +additionalProperties: true +... From a8b309ce9760943486e0585285e0125588a31650 Mon Sep 17 00:00:00 2001 From: Thomas Bracht Laumann Jespersen Date: Mon, 31 Jan 2022 12:20:28 +0100 Subject: [PATCH 060/370] scripts/dtc: Call pkg-config POSIXly correct Running with POSIXLY_CORRECT=1 in the environment the scripts/dtc build fails, because pkg-config doesn't output anything when the flags come after the arguments. Fixes: 067c650c456e ("dtc: Use pkg-config to locate libyaml") Signed-off-by: Thomas Bracht Laumann Jespersen Signed-off-by: Rob Herring Link: https://lore.kernel.org/r/20220131112028.7907-1-t@laumann.xyz --- scripts/dtc/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/dtc/Makefile b/scripts/dtc/Makefile index 95aaf7431bff..1cba78e1dce6 100644 --- a/scripts/dtc/Makefile +++ b/scripts/dtc/Makefile @@ -29,7 +29,7 @@ dtc-objs += yamltree.o # To include installed in a non-default path HOSTCFLAGS_yamltree.o := $(shell pkg-config --cflags yaml-0.1) # To link libyaml installed in a non-default path -HOSTLDLIBS_dtc := $(shell pkg-config yaml-0.1 --libs) +HOSTLDLIBS_dtc := $(shell pkg-config --libs yaml-0.1) endif # Generated files need one more search path to include headers in source tree From d029175f1420931e8d855868d264c4685687f3fd Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Fri, 4 Feb 2022 17:18:51 +0100 Subject: [PATCH 061/370] MAINTAINERS: dt-bindings: Add Krzysztof Kozlowski Add Krzysztof Kozlowski as a second maintainer for the Devicetree bindings, to share the Rob's workload and help in review. Cc: devicetree@vger.kernel.org Signed-off-by: Krzysztof Kozlowski Signed-off-by: Rob Herring Link: https://lore.kernel.org/r/20220204161851.138874-1-krzysztof.kozlowski@canonical.com --- MAINTAINERS | 1 + 1 file changed, 1 insertion(+) diff --git a/MAINTAINERS b/MAINTAINERS index 1dbe55190d28..e8a05c7aca40 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -14388,6 +14388,7 @@ F: scripts/dtc/ OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS M: Rob Herring +M: Krzysztof Kozlowski L: devicetree@vger.kernel.org S: Maintained Q: http://patchwork.ozlabs.org/project/devicetree-bindings/list/ From 951285e59e8ac1d056780b3b5f024cdbdc9846d8 Mon Sep 17 00:00:00 2001 From: Christophe JAILLET Date: Sun, 9 Jan 2022 13:34:18 +0100 Subject: [PATCH 062/370] i2c: amd-mp2: Remove useless DMA-32 fallback configuration As stated in [1], dma_set_mask() with a 64-bit mask never fails if dev->dma_mask is non-NULL. So, if it fails, the 32 bits case will also fail for the same reason. Simplify code and remove some dead code accordingly. [1]: https://lkml.org/lkml/2021/6/7/398 Signed-off-by: Christophe JAILLET Acked-by: Nehal Bakulchandra Shah Signed-off-by: Wolfram Sang --- drivers/i2c/busses/i2c-amd-mp2-pci.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/drivers/i2c/busses/i2c-amd-mp2-pci.c b/drivers/i2c/busses/i2c-amd-mp2-pci.c index adf0e8c1ec01..f57077a7448d 100644 --- a/drivers/i2c/busses/i2c-amd-mp2-pci.c +++ b/drivers/i2c/busses/i2c-amd-mp2-pci.c @@ -308,11 +308,8 @@ static int amd_mp2_pci_init(struct amd_mp2_dev *privdata, pci_set_master(pci_dev); rc = dma_set_mask(&pci_dev->dev, DMA_BIT_MASK(64)); - if (rc) { - rc = dma_set_mask(&pci_dev->dev, DMA_BIT_MASK(32)); - if (rc) - goto err_dma_mask; - } + if (rc) + goto err_dma_mask; /* Set up intx irq */ writel(0, privdata->mmio + AMD_P2C_MSG_INTEN); From b205f5850263632b6897d8f0bfaeeea4955f8663 Mon Sep 17 00:00:00 2001 From: Christophe JAILLET Date: Fri, 20 Aug 2021 20:43:33 +0200 Subject: [PATCH 063/370] i2c: bcm2835: Fix the error handling in 'bcm2835_i2c_probe()' Some resource should be released if an error occurs in 'bcm2835_i2c_probe()'. Add an error handling path and the needed 'clk_disable_unprepare()' and 'clk_rate_exclusive_put()' calls. While at it, rework the bottom of the function to use this newly added error handling path and have an explicit and more standard "return 0;" at the end of the normal path. Fixes: bebff81fb8b9 ("i2c: bcm2835: Model Divider in CCF") Signed-off-by: Christophe JAILLET [wsa: rebased] Signed-off-by: Wolfram Sang --- drivers/i2c/busses/i2c-bcm2835.c | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/drivers/i2c/busses/i2c-bcm2835.c b/drivers/i2c/busses/i2c-bcm2835.c index dfc534065595..f2dc6616afdd 100644 --- a/drivers/i2c/busses/i2c-bcm2835.c +++ b/drivers/i2c/busses/i2c-bcm2835.c @@ -449,18 +449,20 @@ static int bcm2835_i2c_probe(struct platform_device *pdev) ret = clk_prepare_enable(i2c_dev->bus_clk); if (ret) { dev_err(&pdev->dev, "Couldn't prepare clock"); - return ret; + goto err_put_exclusive_rate; } i2c_dev->irq = platform_get_irq(pdev, 0); - if (i2c_dev->irq < 0) - return i2c_dev->irq; + if (i2c_dev->irq < 0) { + ret = i2c_dev->irq; + goto err_disable_unprepare_clk; + } ret = request_irq(i2c_dev->irq, bcm2835_i2c_isr, IRQF_SHARED, dev_name(&pdev->dev), i2c_dev); if (ret) { dev_err(&pdev->dev, "Could not request IRQ\n"); - return -ENODEV; + goto err_disable_unprepare_clk; } adap = &i2c_dev->adapter; @@ -478,7 +480,16 @@ static int bcm2835_i2c_probe(struct platform_device *pdev) ret = i2c_add_adapter(adap); if (ret) - free_irq(i2c_dev->irq, i2c_dev); + goto err_free_irq; + + return 0; + +err_free_irq: + free_irq(i2c_dev->irq, i2c_dev); +err_disable_unprepare_clk: + clk_disable_unprepare(i2c_dev->bus_clk); +err_put_exclusive_rate: + clk_rate_exclusive_put(i2c_dev->bus_clk); return ret; } From bc7ee2e34b219da6813c17a1680dd20766648883 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Wed, 2 Feb 2022 14:34:03 +0000 Subject: [PATCH 064/370] mtd: mchp23k256: Add SPI ID table Currently autoloading for SPI devices does not use the DT ID table, it uses SPI modalises. Supporting OF modalises is going to be difficult if not impractical, an attempt was made but has been reverted, so ensure that module autoloading works for this driver by adding an id_table listing the SPI IDs for everything. Fixes: 96c8395e2166 ("spi: Revert modalias changes") Signed-off-by: Mark Brown Reviewed-by: Michael Walle Signed-off-by: Miquel Raynal Link: https://lore.kernel.org/linux-mtd/20220202143404.16070-3-broonie@kernel.org --- drivers/mtd/devices/mchp23k256.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/drivers/mtd/devices/mchp23k256.c b/drivers/mtd/devices/mchp23k256.c index bf51eebf052c..fa35320bff62 100644 --- a/drivers/mtd/devices/mchp23k256.c +++ b/drivers/mtd/devices/mchp23k256.c @@ -231,6 +231,19 @@ static const struct of_device_id mchp23k256_of_table[] = { }; MODULE_DEVICE_TABLE(of, mchp23k256_of_table); +static const struct spi_device_id mchp23k256_spi_ids[] = { + { + .name = "mchp23k256", + .driver_data = (kernel_ulong_t)&mchp23k256_caps, + }, + { + .name = "mchp23lcv1024", + .driver_data = (kernel_ulong_t)&mchp23lcv1024_caps, + }, + {} +}; +MODULE_DEVICE_TABLE(spi, mchp23k256_spi_ids); + static struct spi_driver mchp23k256_driver = { .driver = { .name = "mchp23k256", @@ -238,6 +251,7 @@ static struct spi_driver mchp23k256_driver = { }, .probe = mchp23k256_probe, .remove = mchp23k256_remove, + .id_table = mchp23k256_spi_ids, }; module_spi_driver(mchp23k256_driver); From 69a6d06878f05d63673b0dcdc3c3ef1af2996d46 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Wed, 2 Feb 2022 14:34:04 +0000 Subject: [PATCH 065/370] mtd: mchp48l640: Add SPI ID table Currently autoloading for SPI devices does not use the DT ID table, it uses SPI modalises. Supporting OF modalises is going to be difficult if not impractical, an attempt was made but has been reverted, so ensure that module autoloading works for this driver by adding an id_table listing the SPI IDs for everything. Fixes: 96c8395e2166 ("spi: Revert modalias changes") Signed-off-by: Mark Brown Reviewed-by: Michael Walle Signed-off-by: Miquel Raynal Link: https://lore.kernel.org/linux-mtd/20220202143404.16070-4-broonie@kernel.org --- drivers/mtd/devices/mchp48l640.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/drivers/mtd/devices/mchp48l640.c b/drivers/mtd/devices/mchp48l640.c index 4ec505b3f4a6..7ed32509b41a 100644 --- a/drivers/mtd/devices/mchp48l640.c +++ b/drivers/mtd/devices/mchp48l640.c @@ -359,6 +359,15 @@ static const struct of_device_id mchp48l640_of_table[] = { }; MODULE_DEVICE_TABLE(of, mchp48l640_of_table); +static const struct spi_device_id mchp48l640_spi_ids[] = { + { + .name = "48l640", + .driver_data = (kernel_ulong_t)&mchp48l640_caps, + }, + {} +}; +MODULE_DEVICE_TABLE(spi, mchp48l640_spi_ids); + static struct spi_driver mchp48l640_driver = { .driver = { .name = "mchp48l640", @@ -366,6 +375,7 @@ static struct spi_driver mchp48l640_driver = { }, .probe = mchp48l640_probe, .remove = mchp48l640_remove, + .id_table = mchp48l640_spi_ids, }; module_spi_driver(mchp48l640_driver); From ad5e35f58384179bbd3cdb349904e150f364c4f3 Mon Sep 17 00:00:00 2001 From: Miquel Raynal Date: Fri, 28 Jan 2022 12:34:14 +0100 Subject: [PATCH 066/370] mtd: Replace the expert mode symbols with a single helper Reduce the number of exported symbols by replacing: - mtd_expert_analysis_warning (the error string) - mtd_expert_analysis_mode (the boolean) with a single helper: - mtd_check_expert_analysis_mode Calling this helper will both check/return the content of the internal boolean -which is not exported anymore- and as well conditionally WARN_ONCE() the user, like it was done before. While on this function, make the error string local to the helper and set it const. Only export this helper when CONFIG_DEBUG_FS is defined to limit the growth of the Linux kernel size only for a debug feature on production kernels. Mechanically update all the consumers. Suggested-by: Geert Uytterhoeven Signed-off-by: Miquel Raynal Link: https://lore.kernel.org/linux-mtd/20220128113414.1121924-1-miquel.raynal@bootlin.com --- drivers/mtd/mtdcore.c | 23 +++++++++++++++-------- drivers/mtd/nand/core.c | 2 +- drivers/mtd/nand/raw/nand_base.c | 2 +- drivers/mtd/nand/raw/nand_bbt.c | 2 +- include/linux/mtd/mtd.h | 8 ++++++-- 5 files changed, 24 insertions(+), 13 deletions(-) diff --git a/drivers/mtd/mtdcore.c b/drivers/mtd/mtdcore.c index 70f492dce158..1e7f3bbf847e 100644 --- a/drivers/mtd/mtdcore.c +++ b/drivers/mtd/mtdcore.c @@ -358,6 +358,21 @@ static int mtd_partname_debug_show(struct seq_file *s, void *p) DEFINE_SHOW_ATTRIBUTE(mtd_partname_debug); +static bool mtd_expert_analysis_mode; + +#ifdef CONFIG_DEBUG_FS +bool mtd_check_expert_analysis_mode(void) +{ + const char *mtd_expert_analysis_warning = + "Bad block checks have been entirely disabled.\n" + "This is only reserved for post-mortem forensics and debug purposes.\n" + "Never enable this mode if you do not know what you are doing!\n"; + + return WARN_ONCE(mtd_expert_analysis_mode, mtd_expert_analysis_warning); +} +EXPORT_SYMBOL_GPL(mtd_check_expert_analysis_mode); +#endif + static struct dentry *dfs_dir_mtd; static void mtd_debugfs_populate(struct mtd_info *mtd) @@ -2370,14 +2385,6 @@ static struct backing_dev_info * __init mtd_bdi_init(const char *name) return ret ? ERR_PTR(ret) : bdi; } -char *mtd_expert_analysis_warning = - "Bad block checks have been entirely disabled.\n" - "This is only reserved for post-mortem forensics and debug purposes.\n" - "Never enable this mode if you do not know what you are doing!\n"; -EXPORT_SYMBOL_GPL(mtd_expert_analysis_warning); -bool mtd_expert_analysis_mode; -EXPORT_SYMBOL_GPL(mtd_expert_analysis_mode); - static struct proc_dir_entry *proc_mtd; static int __init init_mtd(void) diff --git a/drivers/mtd/nand/core.c b/drivers/mtd/nand/core.c index 416947f28b67..3ff99a42a63f 100644 --- a/drivers/mtd/nand/core.c +++ b/drivers/mtd/nand/core.c @@ -21,7 +21,7 @@ */ bool nanddev_isbad(struct nand_device *nand, const struct nand_pos *pos) { - if (WARN_ONCE(mtd_expert_analysis_mode, mtd_expert_analysis_warning)) + if (mtd_check_expert_analysis_mode()) return false; if (nanddev_bbt_is_initialized(nand)) { diff --git a/drivers/mtd/nand/raw/nand_base.c b/drivers/mtd/nand/raw/nand_base.c index e7b2ba016d8c..068ecf979033 100644 --- a/drivers/mtd/nand/raw/nand_base.c +++ b/drivers/mtd/nand/raw/nand_base.c @@ -321,7 +321,7 @@ static int nand_isbad_bbm(struct nand_chip *chip, loff_t ofs) if (nand_region_is_secured(chip, ofs, mtd->erasesize)) return -EIO; - if (WARN_ONCE(mtd_expert_analysis_mode, mtd_expert_analysis_warning)) + if (mtd_check_expert_analysis_mode()) return 0; if (chip->legacy.block_bad) diff --git a/drivers/mtd/nand/raw/nand_bbt.c b/drivers/mtd/nand/raw/nand_bbt.c index ab630af3a309..a3723da2e0a0 100644 --- a/drivers/mtd/nand/raw/nand_bbt.c +++ b/drivers/mtd/nand/raw/nand_bbt.c @@ -1455,7 +1455,7 @@ int nand_isbad_bbt(struct nand_chip *this, loff_t offs, int allowbbt) pr_debug("nand_isbad_bbt(): bbt info for offs 0x%08x: (block %d) 0x%02x\n", (unsigned int)offs, block, res); - if (WARN_ONCE(mtd_expert_analysis_mode, mtd_expert_analysis_warning)) + if (mtd_check_expert_analysis_mode()) return 0; switch (res) { diff --git a/include/linux/mtd/mtd.h b/include/linux/mtd/mtd.h index 1ffa933121f6..1b3fc8c71ab3 100644 --- a/include/linux/mtd/mtd.h +++ b/include/linux/mtd/mtd.h @@ -711,7 +711,11 @@ static inline int mtd_is_bitflip_or_eccerr(int err) { unsigned mtd_mmap_capabilities(struct mtd_info *mtd); -extern char *mtd_expert_analysis_warning; -extern bool mtd_expert_analysis_mode; +#ifdef CONFIG_DEBUG_FS +bool mtd_check_expert_analysis_mode(void); +#else +static inline bool mtd_check_expert_analysis_mode(void) { return false; } +#endif + #endif /* __MTD_MTD_H__ */ From 0bc4978a679c4efe37c6919cb2082dc123d40120 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Tue, 1 Feb 2022 19:00:42 +0100 Subject: [PATCH 067/370] i2c: ACPI: Replace acpi_bus_get_device() Replace acpi_bus_get_device() that is going to be dropped with acpi_fetch_acpi_dev(). No intentional functional impact. Signed-off-by: Rafael J. Wysocki Reviewed-by: Andy Shevchenko Acked-by: Mika Westerberg Signed-off-by: Wolfram Sang --- drivers/i2c/i2c-core-acpi.c | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) diff --git a/drivers/i2c/i2c-core-acpi.c b/drivers/i2c/i2c-core-acpi.c index 85ed4c1d4924..08b561f0709d 100644 --- a/drivers/i2c/i2c-core-acpi.c +++ b/drivers/i2c/i2c-core-acpi.c @@ -236,7 +236,8 @@ static int i2c_acpi_get_info(struct acpi_device *adev, struct acpi_device *adapter_adev; /* The adapter must be present */ - if (acpi_bus_get_device(lookup.adapter_handle, &adapter_adev)) + adapter_adev = acpi_fetch_acpi_dev(lookup.adapter_handle); + if (!adapter_adev) return -ENODEV; if (acpi_bus_get_status(adapter_adev) || !adapter_adev->status.present) @@ -275,13 +276,10 @@ static acpi_status i2c_acpi_add_device(acpi_handle handle, u32 level, void *data, void **return_value) { struct i2c_adapter *adapter = data; - struct acpi_device *adev; + struct acpi_device *adev = acpi_fetch_acpi_dev(handle); struct i2c_board_info info; - if (acpi_bus_get_device(handle, &adev)) - return AE_OK; - - if (i2c_acpi_get_info(adev, &info, adapter, NULL)) + if (!adev || i2c_acpi_get_info(adev, &info, adapter, NULL)) return AE_OK; i2c_acpi_register_device(adapter, adev, &info); @@ -341,12 +339,9 @@ static acpi_status i2c_acpi_lookup_speed(acpi_handle handle, u32 level, void *data, void **return_value) { struct i2c_acpi_lookup *lookup = data; - struct acpi_device *adev; + struct acpi_device *adev = acpi_fetch_acpi_dev(handle); - if (acpi_bus_get_device(handle, &adev)) - return AE_OK; - - if (i2c_acpi_do_lookup(adev, lookup)) + if (!adev || i2c_acpi_do_lookup(adev, lookup)) return AE_OK; if (lookup->search_handle != lookup->adapter_handle) From 0c47dd7d09bb5de5a8e5de24c7e04d66e42a727e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonathan=20Neusch=C3=A4fer?= Date: Sat, 29 Jan 2022 10:39:07 +0100 Subject: [PATCH 068/370] i2c: npcm7xx: Fix typos MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The comments in this driver have a few typos. Let's fix them. Signed-off-by: Jonathan Neuschäfer Reviewed-by: Randy Dunlap Reviewed-by: tali.perry@nuvoton.com Signed-off-by: Wolfram Sang --- drivers/i2c/busses/i2c-npcm7xx.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/drivers/i2c/busses/i2c-npcm7xx.c b/drivers/i2c/busses/i2c-npcm7xx.c index 2ad166355ec9..71aad029425d 100644 --- a/drivers/i2c/busses/i2c-npcm7xx.c +++ b/drivers/i2c/busses/i2c-npcm7xx.c @@ -781,7 +781,7 @@ static void npcm_i2c_set_fifo(struct npcm_i2c *bus, int nread, int nwrite) /* * if we are about to read the first byte in blk rd mode, * don't NACK it. If slave returns zero size HW can't NACK - * it immidiattly, it will read extra byte and then NACK. + * it immediately, it will read extra byte and then NACK. */ if (bus->rd_ind == 0 && bus->read_block_use) { /* set fifo to read one byte, no last: */ @@ -981,7 +981,7 @@ static void npcm_i2c_slave_xmit(struct npcm_i2c *bus, u16 nwrite, /* * npcm_i2c_slave_wr_buf_sync: * currently slave IF only supports single byte operations. - * in order to utilyze the npcm HW FIFO, the driver will ask for 16 bytes + * in order to utilize the npcm HW FIFO, the driver will ask for 16 bytes * at a time, pack them in buffer, and then transmit them all together * to the FIFO and onward to the bus. * NACK on read will be once reached to bus->adap->quirks->max_read_len. @@ -1175,7 +1175,7 @@ static irqreturn_t npcm_i2c_int_slave_handler(struct npcm_i2c *bus) /* * the i2c module can response to 10 own SA. * check which one was addressed by the master. - * repond to the first one. + * respond to the first one. */ addr = ((i2ccst3 & 0x07) << 7) | (i2ccst2 & 0x7F); @@ -1753,8 +1753,8 @@ static void npcm_i2c_recovery_init(struct i2c_adapter *_adap) /* * npcm i2c HW allows direct reading of SCL and SDA. * However, it does not support setting SCL and SDA directly. - * The recovery function can togle SCL when SDA is low (but not set) - * Getter functions used internally, and can be used externaly. + * The recovery function can toggle SCL when SDA is low (but not set) + * Getter functions used internally, and can be used externally. */ rinfo->get_scl = npcm_i2c_get_SCL; rinfo->get_sda = npcm_i2c_get_SDA; @@ -1768,10 +1768,10 @@ static void npcm_i2c_recovery_init(struct i2c_adapter *_adap) /* * npcm_i2c_init_clk: init HW timing parameters. - * NPCM7XX i2c module timing parameters are depenent on module core clk (APB) + * NPCM7XX i2c module timing parameters are dependent on module core clk (APB) * and bus frequency. - * 100kHz bus requires tSCL = 4 * SCLFRQ * tCLK. LT and HT are simetric. - * 400kHz bus requires assymetric HT and LT. A different equation is recomended + * 100kHz bus requires tSCL = 4 * SCLFRQ * tCLK. LT and HT are symmetric. + * 400kHz bus requires asymmetric HT and LT. A different equation is recommended * by the HW designer, given core clock range (equations in comments below). * */ From 056d38576abec08b6b2d3b2507d8f28b22aaa284 Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Mon, 31 Jan 2022 18:27:13 +0100 Subject: [PATCH 069/370] dt-bindings: i2c: samsung,s3c2410-i2c: convert to dtschema Convert the Samsung S3C24xx/S3C64xx/S5PV210/Exynos SoC I2C Controller bindings to DT schema format. The conversion includes also changes/fixes to the bindings, matching the real hardware and existing Linux driver: 1. Do not require interrupts on samsung,exynos5-sata-phy-i2c, because there is no such. 2. Do not allow gpios on samsung,exynos5-sata-phy-i2c, because they are hard-wired just like for HDMI phy. 3. Do not require samsung,i2c-sda-delay and use default of 0. 4. Require clock, which was always required but missing in bindings. Signed-off-by: Krzysztof Kozlowski Signed-off-by: Rob Herring Link: https://lore.kernel.org/r/20220131172713.208976-1-krzysztof.kozlowski@canonical.com --- .../devicetree/bindings/i2c/i2c-s3c2410.txt | 58 ------- .../bindings/i2c/samsung,s3c2410-i2c.yaml | 164 ++++++++++++++++++ 2 files changed, 164 insertions(+), 58 deletions(-) delete mode 100644 Documentation/devicetree/bindings/i2c/i2c-s3c2410.txt create mode 100644 Documentation/devicetree/bindings/i2c/samsung,s3c2410-i2c.yaml diff --git a/Documentation/devicetree/bindings/i2c/i2c-s3c2410.txt b/Documentation/devicetree/bindings/i2c/i2c-s3c2410.txt deleted file mode 100644 index 66ae46d3bc2f..000000000000 --- a/Documentation/devicetree/bindings/i2c/i2c-s3c2410.txt +++ /dev/null @@ -1,58 +0,0 @@ -* Samsung's I2C controller - -The Samsung's I2C controller is used to interface with I2C devices. - -Required properties: - - compatible: value should be either of the following. - (a) "samsung, s3c2410-i2c", for i2c compatible with s3c2410 i2c. - (b) "samsung, s3c2440-i2c", for i2c compatible with s3c2440 i2c. - (c) "samsung, s3c2440-hdmiphy-i2c", for s3c2440-like i2c used - inside HDMIPHY block found on several samsung SoCs - (d) "samsung, exynos5-sata-phy-i2c", for s3c2440-like i2c used as - a host to SATA PHY controller on an internal bus. - - reg: physical base address of the controller and length of memory mapped - region. - - interrupts: interrupt number to the cpu. - - samsung,i2c-sda-delay: Delay (in ns) applied to data line (SDA) edges. - -Required for all cases except "samsung,s3c2440-hdmiphy-i2c": - - Samsung GPIO variant (deprecated): - - gpios: The order of the gpios should be the following: . - The gpio specifier depends on the gpio controller. Required in all - cases except for "samsung,s3c2440-hdmiphy-i2c" whose input/output - lines are permanently wired to the respective clienta - - Pinctrl variant (preferred, if available): - - pinctrl-0: Pin control group to be used for this controller. - - pinctrl-names: Should contain only one value - "default". - -Optional properties: - - samsung,i2c-slave-addr: Slave address in multi-master environment. If not - specified, default value is 0. - - samsung,i2c-max-bus-freq: Desired frequency in Hz of the bus. If not - specified, the default value in Hz is 100000. - - samsung,sysreg-phandle - handle to syscon used to control the system registers - -Example: - - i2c@13870000 { - compatible = "samsung,s3c2440-i2c"; - reg = <0x13870000 0x100>; - interrupts = <345>; - samsung,i2c-sda-delay = <100>; - samsung,i2c-max-bus-freq = <100000>; - /* Samsung GPIO variant begins here */ - gpios = <&gpd1 2 0 /* SDA */ - &gpd1 3 0 /* SCL */>; - /* Samsung GPIO variant ends here */ - /* Pinctrl variant begins here */ - pinctrl-0 = <&i2c3_bus>; - pinctrl-names = "default"; - /* Pinctrl variant ends here */ - #address-cells = <1>; - #size-cells = <0>; - - wm8994@1a { - compatible = "wlf,wm8994"; - reg = <0x1a>; - }; - }; diff --git a/Documentation/devicetree/bindings/i2c/samsung,s3c2410-i2c.yaml b/Documentation/devicetree/bindings/i2c/samsung,s3c2410-i2c.yaml new file mode 100644 index 000000000000..84051b0129c2 --- /dev/null +++ b/Documentation/devicetree/bindings/i2c/samsung,s3c2410-i2c.yaml @@ -0,0 +1,164 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/i2c/samsung,s3c2410-i2c.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Samsung S3C/S5P/Exynos SoC I2C Controller + +maintainers: + - Krzysztof Kozlowski + +properties: + compatible: + enum: + - samsung,s3c2410-i2c + - samsung,s3c2440-i2c + # For s3c2440-like I2C used inside HDMIPHY block found on several SoCs: + - samsung,s3c2440-hdmiphy-i2c + # For s3c2440-like I2C used as a host to SATA PHY controller on an + # internal bus: + - samsung,exynos5-sata-phy-i2c + + '#address-cells': + const: 1 + + clocks: + maxItems: 1 + + clock-names: + items: + - const: i2c + + gpios: + description: | + The order of the GPIOs should be the following:: . The GPIO + specifier depends on the gpio controller. Required in all cases except + for "samsung,s3c2440-hdmiphy-i2c" whose input/output lines are + permanently wired to the respective client. + This property is deprecated. Use "pinctrl-0" and "pinctrl-names" instead. + deprecated: yes + + interrupts: + maxItems: 1 + + reg: + maxItems: 1 + + samsung,i2c-max-bus-freq: + $ref: /schemas/types.yaml#/definitions/uint32 + description: + Desired frequency in Hz of the bus. + default: 100000 + + samsung,i2c-sda-delay: + $ref: /schemas/types.yaml#/definitions/uint32 + description: + Delay (in ns) applied to data line (SDA) edges. + default: 0 + + samsung,i2c-slave-addr: + $ref: /schemas/types.yaml#/definitions/uint32 + description: + Slave address in multi-master environment. + default: 0 + + samsung,sysreg-phandle: + $ref: /schemas/types.yaml#/definitions/phandle + description: Pandle to syscon used to control the system registers. + + '#size-cells': + const: 0 + +required: + - compatible + - reg + +allOf: + - $ref: /schemas/i2c/i2c-controller.yaml# + - if: + properties: + compatible: + contains: + enum: + - samsung,s3c2440-hdmiphy-i2c + - samsung,exynos5-sata-phy-i2c + then: + properties: + gpios: false + + - if: + properties: + compatible: + contains: + enum: + - samsung,s3c2410-i2c + - samsung,s3c2440-i2c + - samsung,s3c2440-hdmiphy-i2c + then: + required: + - interrupts + +unevaluatedProperties: false + +examples: + - | + #include + #include + + i2c@12c60000 { + compatible = "samsung,s3c2440-i2c"; + reg = <0x12C60000 0x100>; + interrupts = ; + #address-cells = <1>; + #size-cells = <0>; + clocks = <&clock CLK_I2C0>; + clock-names = "i2c"; + pinctrl-names = "default"; + pinctrl-0 = <&i2c0_bus>; + + samsung,sysreg-phandle = <&sysreg_system_controller>; + samsung,i2c-sda-delay = <100>; + samsung,i2c-max-bus-freq = <20000>; + samsung,i2c-slave-addr = <0x66>; + + eeprom@50 { + compatible = "samsung,s524ad0xd1"; + reg = <0x50>; + }; + }; + + i2c@12ce0000 { + compatible = "samsung,s3c2440-hdmiphy-i2c"; + reg = <0x12CE0000 0x1000>; + interrupts = ; + #address-cells = <1>; + #size-cells = <0>; + clocks = <&clock CLK_I2C_HDMI>; + clock-names = "i2c"; + + samsung,i2c-sda-delay = <100>; + samsung,i2c-max-bus-freq = <66000>; + + phy-i2c@38 { + compatible = "samsung,exynos4212-hdmiphy"; + reg = <0x38>; + }; + }; + + i2c@121d0000 { + compatible = "samsung,exynos5-sata-phy-i2c"; + reg = <0x121D0000 0x100>; + #address-cells = <1>; + #size-cells = <0>; + clocks = <&clock CLK_SATA_PHYI2C>; + clock-names = "i2c"; + + samsung,i2c-sda-delay = <100>; + samsung,i2c-max-bus-freq = <40000>; + + phy-i2c@38 { + compatible = "samsung,exynos-sataphy-i2c"; + reg = <0x38>; + }; + }; From ba9897a0e0cefcff0108d856aa754b953997d920 Mon Sep 17 00:00:00 2001 From: Christophe JAILLET Date: Sat, 5 Feb 2022 08:40:48 +0100 Subject: [PATCH 070/370] backlight: pwm_bl: Avoid open coded arithmetic in memory allocation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit kmalloc_array()/kcalloc() should be used to avoid potential overflow when a multiplication is needed to compute the size of the requested memory. So turn a kzalloc()+explicit size computation into an equivalent kcalloc(). Signed-off-by: Christophe JAILLET Acked-by: Uwe Kleine-König Reviewed-by: Daniel Thompson Signed-off-by: Lee Jones Link: https://lore.kernel.org/r/bd3d74acfa58d59f6f5f81fc5a9fb409edb8d747.1644046817.git.christophe.jaillet@wanadoo.fr --- drivers/video/backlight/pwm_bl.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/drivers/video/backlight/pwm_bl.c b/drivers/video/backlight/pwm_bl.c index 8d8959a70e44..c0523a0269ee 100644 --- a/drivers/video/backlight/pwm_bl.c +++ b/drivers/video/backlight/pwm_bl.c @@ -263,9 +263,8 @@ static int pwm_backlight_parse_dt(struct device *dev, /* read brightness levels from DT property */ if (num_levels > 0) { - size_t size = sizeof(*data->levels) * num_levels; - - data->levels = devm_kzalloc(dev, size, GFP_KERNEL); + data->levels = devm_kcalloc(dev, num_levels, + sizeof(*data->levels), GFP_KERNEL); if (!data->levels) return -ENOMEM; @@ -320,8 +319,8 @@ static int pwm_backlight_parse_dt(struct device *dev, * Create a new table of brightness levels with all the * interpolated steps. */ - size = sizeof(*table) * num_levels; - table = devm_kzalloc(dev, size, GFP_KERNEL); + table = devm_kcalloc(dev, num_levels, sizeof(*table), + GFP_KERNEL); if (!table) return -ENOMEM; /* From cec6647a00e25105ade1a4574d8c3a657acddf57 Mon Sep 17 00:00:00 2001 From: Luca Weiss Date: Wed, 29 Dec 2021 18:03:55 +0100 Subject: [PATCH 071/370] dt-bindings: backlight: qcom-wled: Add PM6150L compatible Document the compatible for the wled block found in PM6150L. Signed-off-by: Luca Weiss Acked-by: Rob Herring Signed-off-by: Lee Jones Link: https://lore.kernel.org/r/20211229170358.2457006-2-luca.weiss@fairphone.com --- Documentation/devicetree/bindings/leds/backlight/qcom-wled.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/Documentation/devicetree/bindings/leds/backlight/qcom-wled.yaml b/Documentation/devicetree/bindings/leds/backlight/qcom-wled.yaml index d839e75d9788..1c24b333c6e2 100644 --- a/Documentation/devicetree/bindings/leds/backlight/qcom-wled.yaml +++ b/Documentation/devicetree/bindings/leds/backlight/qcom-wled.yaml @@ -22,6 +22,7 @@ properties: - qcom,pmi8994-wled - qcom,pmi8998-wled - qcom,pm660l-wled + - qcom,pm6150l-wled - qcom,pm8150l-wled reg: From d4294e4fc7f0feeb877ae0aa58cea4f4328f8974 Mon Sep 17 00:00:00 2001 From: Luca Weiss Date: Wed, 29 Dec 2021 18:03:56 +0100 Subject: [PATCH 072/370] backlight: qcom-wled: Add PM6150L compatible PM6150L contains WLED of version 5. Add support ofr it to the driver. Signed-off-by: Luca Weiss Reviewed-by: Daniel Thompson Signed-off-by: Lee Jones Link: https://lore.kernel.org/r/20211229170358.2457006-3-luca.weiss@fairphone.com --- drivers/video/backlight/qcom-wled.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/video/backlight/qcom-wled.c b/drivers/video/backlight/qcom-wled.c index 306bcc6ccb92..527210e85795 100644 --- a/drivers/video/backlight/qcom-wled.c +++ b/drivers/video/backlight/qcom-wled.c @@ -1734,6 +1734,7 @@ static const struct of_device_id wled_match_table[] = { { .compatible = "qcom,pmi8994-wled", .data = (void *)4 }, { .compatible = "qcom,pmi8998-wled", .data = (void *)4 }, { .compatible = "qcom,pm660l-wled", .data = (void *)4 }, + { .compatible = "qcom,pm6150l-wled", .data = (void *)5 }, { .compatible = "qcom,pm8150l-wled", .data = (void *)5 }, {} }; From 90c3e3b8140d833a737085abd1ac133d14a32390 Mon Sep 17 00:00:00 2001 From: Alistair Francis Date: Mon, 24 Jan 2022 22:10:02 +1000 Subject: [PATCH 073/370] dt-bindings: mfd: Initial commit of silergy,sy7636a.yaml Initial support for the Silergy SY7636A Power Management chip and regulator. Signed-off-by: Alistair Francis Reviewed-by: Rob Herring Signed-off-by: Lee Jones --- .../bindings/mfd/silergy,sy7636a.yaml | 82 +++++++++++++++++++ 1 file changed, 82 insertions(+) create mode 100644 Documentation/devicetree/bindings/mfd/silergy,sy7636a.yaml diff --git a/Documentation/devicetree/bindings/mfd/silergy,sy7636a.yaml b/Documentation/devicetree/bindings/mfd/silergy,sy7636a.yaml new file mode 100644 index 000000000000..6de74c701635 --- /dev/null +++ b/Documentation/devicetree/bindings/mfd/silergy,sy7636a.yaml @@ -0,0 +1,82 @@ +# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/mfd/silergy,sy7636a.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: silergy sy7636a PMIC + +maintainers: + - Alistair Francis + +properties: + compatible: + const: silergy,sy7636a + + reg: + description: + I2C device address. + maxItems: 1 + + "#address-cells": + const: 1 + + "#size-cells": + const: 0 + + '#thermal-sensor-cells': + const: 0 + + epd-pwr-good-gpios: + description: + Specifying the power good GPIOs. + maxItems: 1 + + regulators: + type: object + + properties: + compatible: + const: silergy,sy7636a-regulator + + vcom: + type: object + $ref: /schemas/regulator/regulator.yaml# + description: + The regulator for the compenstation voltage. Enabling/disabling this + enables/disables the entire device. + properties: + regulator-name: + const: vcom + + additionalProperties: false + +required: + - compatible + - reg + - '#thermal-sensor-cells' + +additionalProperties: false + +examples: + - | + i2c { + #address-cells = <1>; + #size-cells = <0>; + + pmic@62 { + compatible = "silergy,sy7636a"; + reg = <0x62>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_epdpmic>; + #thermal-sensor-cells = <0>; + + regulators { + reg_epdpmic: vcom { + regulator-name = "vcom"; + regulator-boot-on; + }; + }; + }; + }; +... From bae5a4acef67db8870e33d9258223c9dcd64b5d1 Mon Sep 17 00:00:00 2001 From: Alistair Francis Date: Mon, 24 Jan 2022 22:10:03 +1000 Subject: [PATCH 074/370] mfd: simple-mfd-i2c: Add a Kconfig name Add a Kconfig name to the "Simple Multi-Functional Device support (I2C)" device so that it can be enabled via menuconfig. Signed-off-by: Alistair Francis Signed-off-by: Lee Jones --- drivers/mfd/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig index ba0b3eb131f1..e0d2fcb10a0c 100644 --- a/drivers/mfd/Kconfig +++ b/drivers/mfd/Kconfig @@ -1188,7 +1188,7 @@ config MFD_SI476X_CORE module will be called si476x-core. config MFD_SIMPLE_MFD_I2C - tristate + tristate "Simple Multi-Functional Device support (I2C)" depends on I2C select MFD_CORE select REGMAP_I2C From 5913eb45d036288babb67e97b210233537ef7b90 Mon Sep 17 00:00:00 2001 From: Alistair Francis Date: Mon, 24 Jan 2022 22:10:04 +1000 Subject: [PATCH 075/370] mfd: simple-mfd-i2c: Enable support for the silergy,sy7636a Signed-off-by: Alistair Francis Signed-off-by: Lee Jones --- drivers/mfd/simple-mfd-i2c.c | 11 +++++++++++ include/linux/mfd/sy7636a.h | 34 ++++++++++++++++++++++++++++++++++ 2 files changed, 45 insertions(+) create mode 100644 include/linux/mfd/sy7636a.h diff --git a/drivers/mfd/simple-mfd-i2c.c b/drivers/mfd/simple-mfd-i2c.c index 51536691ad9d..f4c8fc3ee463 100644 --- a/drivers/mfd/simple-mfd-i2c.c +++ b/drivers/mfd/simple-mfd-i2c.c @@ -62,8 +62,19 @@ static int simple_mfd_i2c_probe(struct i2c_client *i2c) return ret; } +static const struct mfd_cell sy7636a_cells[] = { + { .name = "sy7636a-regulator", }, + { .name = "sy7636a-temperature", }, +}; + +static const struct simple_mfd_data silergy_sy7636a = { + .mfd_cell = sy7636a_cells, + .mfd_cell_size = ARRAY_SIZE(sy7636a_cells), +}; + static const struct of_device_id simple_mfd_i2c_of_match[] = { { .compatible = "kontron,sl28cpld" }, + { .compatible = "silergy,sy7636a", .data = &silergy_sy7636a}, {} }; MODULE_DEVICE_TABLE(of, simple_mfd_i2c_of_match); diff --git a/include/linux/mfd/sy7636a.h b/include/linux/mfd/sy7636a.h new file mode 100644 index 000000000000..22f03b2f851e --- /dev/null +++ b/include/linux/mfd/sy7636a.h @@ -0,0 +1,34 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Functions to access SY3686A power management chip. + * + * Copyright (C) 2021 reMarkable AS - http://www.remarkable.com/ + */ + +#ifndef __MFD_SY7636A_H +#define __MFD_SY7636A_H + +#define SY7636A_REG_OPERATION_MODE_CRL 0x00 +/* It is set if a gpio is used to control the regulator */ +#define SY7636A_OPERATION_MODE_CRL_VCOMCTL BIT(6) +#define SY7636A_OPERATION_MODE_CRL_ONOFF BIT(7) +#define SY7636A_REG_VCOM_ADJUST_CTRL_L 0x01 +#define SY7636A_REG_VCOM_ADJUST_CTRL_H 0x02 +#define SY7636A_REG_VCOM_ADJUST_CTRL_MASK 0x01ff +#define SY7636A_REG_VLDO_VOLTAGE_ADJULST_CTRL 0x03 +#define SY7636A_REG_POWER_ON_DELAY_TIME 0x06 +#define SY7636A_REG_FAULT_FLAG 0x07 +#define SY7636A_FAULT_FLAG_PG BIT(0) +#define SY7636A_REG_TERMISTOR_READOUT 0x08 + +#define SY7636A_REG_MAX 0x08 + +#define VCOM_ADJUST_CTRL_MASK 0x1ff +// Used to shift the high byte +#define VCOM_ADJUST_CTRL_SHIFT 8 +// Used to scale from VCOM_ADJUST_CTRL to mv +#define VCOM_ADJUST_CTRL_SCAL 10000 + +#define FAULT_FLAG_SHIFT 1 + +#endif /* __LINUX_MFD_SY7636A_H */ From 947d0cce70ae37b89295040165404b1da3994c10 Mon Sep 17 00:00:00 2001 From: Alistair Francis Date: Mon, 24 Jan 2022 22:10:05 +1000 Subject: [PATCH 076/370] regulator: sy7636a: Remove requirement on sy7636a mfd Signed-off-by: Alistair Francis Acked-by: Mark Brown Signed-off-by: Lee Jones --- drivers/regulator/Kconfig | 1 - drivers/regulator/sy7636a-regulator.c | 7 +++++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig index 1c35fed20d34..25ae5f087ff9 100644 --- a/drivers/regulator/Kconfig +++ b/drivers/regulator/Kconfig @@ -1208,7 +1208,6 @@ config REGULATOR_STW481X_VMMC config REGULATOR_SY7636A tristate "Silergy SY7636A voltage regulator" - depends on MFD_SY7636A help This driver supports Silergy SY3686A voltage regulator. diff --git a/drivers/regulator/sy7636a-regulator.c b/drivers/regulator/sy7636a-regulator.c index 22fddf868e4c..29fc27c2cda0 100644 --- a/drivers/regulator/sy7636a-regulator.c +++ b/drivers/regulator/sy7636a-regulator.c @@ -7,11 +7,14 @@ // Authors: Lars Ivar Miljeteig // Alistair Francis +#include +#include +#include #include #include +#include +#include #include -#include -#include struct sy7636a_data { struct regmap *regmap; From de34a4053250781404779b567b58dd97af689ce0 Mon Sep 17 00:00:00 2001 From: Alistair Francis Date: Mon, 24 Jan 2022 22:10:06 +1000 Subject: [PATCH 077/370] hwmon: sy7636a: Add temperature driver for sy7636a This is a multi-function device to interface with the sy7636a EPD PMIC chip from Silergy. Signed-off-by: Alistair Francis Acked-by: Guenter Roeck Signed-off-by: Lee Jones --- Documentation/hwmon/index.rst | 1 + Documentation/hwmon/sy7636a-hwmon.rst | 26 +++++++ drivers/hwmon/Kconfig | 9 +++ drivers/hwmon/Makefile | 1 + drivers/hwmon/sy7636a-hwmon.c | 106 ++++++++++++++++++++++++++ 5 files changed, 143 insertions(+) create mode 100644 Documentation/hwmon/sy7636a-hwmon.rst create mode 100644 drivers/hwmon/sy7636a-hwmon.c diff --git a/Documentation/hwmon/index.rst b/Documentation/hwmon/index.rst index df20022c741f..6e0906ef5d25 100644 --- a/Documentation/hwmon/index.rst +++ b/Documentation/hwmon/index.rst @@ -185,6 +185,7 @@ Hardware Monitoring Kernel Drivers smsc47m1 sparx5-temp stpddc60 + sy7636a-hwmon tc654 tc74 thmc50 diff --git a/Documentation/hwmon/sy7636a-hwmon.rst b/Documentation/hwmon/sy7636a-hwmon.rst new file mode 100644 index 000000000000..5612079397d5 --- /dev/null +++ b/Documentation/hwmon/sy7636a-hwmon.rst @@ -0,0 +1,26 @@ +.. SPDX-License-Identifier: GPL-2.0-or-later + +Kernel driver sy7636a-hwmon +========================= + +Supported chips: + + * Silergy SY7636A PMIC + + +Description +----------- + +This driver adds hardware temperature reading support for +the Silergy SY7636A PMIC. + +The following sensors are supported + + * Temperature + - SoC on-die temperature in milli-degree C + +sysfs-Interface +--------------- + +temp0_input + - SoC on-die temperature (milli-degree C) diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig index 8df25f1079ba..aa5785e657a4 100644 --- a/drivers/hwmon/Kconfig +++ b/drivers/hwmon/Kconfig @@ -1672,6 +1672,15 @@ config SENSORS_SIS5595 This driver can also be built as a module. If so, the module will be called sis5595. +config SENSORS_SY7636A + tristate "Silergy SY7636A" + help + If you say yes here you get support for the thermistor readout of + the Silergy SY7636A PMIC. + + This driver can also be built as a module. If so, the module + will be called sy7636a-hwmon. + config SENSORS_DME1737 tristate "SMSC DME1737, SCH311x and compatibles" depends on I2C && !PPC diff --git a/drivers/hwmon/Makefile b/drivers/hwmon/Makefile index 185f946d698b..fe54a3dfdb03 100644 --- a/drivers/hwmon/Makefile +++ b/drivers/hwmon/Makefile @@ -186,6 +186,7 @@ obj-$(CONFIG_SENSORS_SMSC47M1) += smsc47m1.o obj-$(CONFIG_SENSORS_SMSC47M192)+= smsc47m192.o obj-$(CONFIG_SENSORS_SPARX5) += sparx5-temp.o obj-$(CONFIG_SENSORS_STTS751) += stts751.o +obj-$(CONFIG_SENSORS_SY7636A) += sy7636a-hwmon.o obj-$(CONFIG_SENSORS_AMC6821) += amc6821.o obj-$(CONFIG_SENSORS_TC74) += tc74.o obj-$(CONFIG_SENSORS_THMC50) += thmc50.o diff --git a/drivers/hwmon/sy7636a-hwmon.c b/drivers/hwmon/sy7636a-hwmon.c new file mode 100644 index 000000000000..6dd9c2a0f0e0 --- /dev/null +++ b/drivers/hwmon/sy7636a-hwmon.c @@ -0,0 +1,106 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Functions to access SY3686A power management chip temperature + * + * Copyright (C) 2021 reMarkable AS - http://www.remarkable.com/ + * + * Authors: Lars Ivar Miljeteig + * Alistair Francis + */ + +#include +#include +#include +#include +#include +#include +#include + +#include + +static int sy7636a_read(struct device *dev, enum hwmon_sensor_types type, + u32 attr, int channel, long *temp) +{ + struct regmap *regmap = dev_get_drvdata(dev); + int ret, reg_val; + + ret = regmap_read(regmap, + SY7636A_REG_TERMISTOR_READOUT, ®_val); + if (ret) + return ret; + + *temp = reg_val * 1000; + + return 0; +} + +static umode_t sy7636a_is_visible(const void *data, + enum hwmon_sensor_types type, + u32 attr, int channel) +{ + if (type != hwmon_temp) + return 0; + + if (attr != hwmon_temp_input) + return 0; + + return 0444; +} + +static const struct hwmon_ops sy7636a_hwmon_ops = { + .is_visible = sy7636a_is_visible, + .read = sy7636a_read, +}; + +static const struct hwmon_channel_info *sy7636a_info[] = { + HWMON_CHANNEL_INFO(chip, HWMON_C_REGISTER_TZ), + HWMON_CHANNEL_INFO(temp, HWMON_T_INPUT), + NULL +}; + +static const struct hwmon_chip_info sy7636a_chip_info = { + .ops = &sy7636a_hwmon_ops, + .info = sy7636a_info, +}; + +static int sy7636a_sensor_probe(struct platform_device *pdev) +{ + struct regmap *regmap = dev_get_regmap(pdev->dev.parent, NULL); + struct regulator *regulator; + struct device *hwmon_dev; + int err; + + if (!regmap) + return -EPROBE_DEFER; + + regulator = devm_regulator_get(&pdev->dev, "vcom"); + if (IS_ERR(regulator)) + return PTR_ERR(regulator); + + err = regulator_enable(regulator); + if (err) + return err; + + hwmon_dev = devm_hwmon_device_register_with_info(&pdev->dev, + "sy7636a_temperature", regmap, + &sy7636a_chip_info, NULL); + + if (IS_ERR(hwmon_dev)) { + err = PTR_ERR(hwmon_dev); + dev_err(&pdev->dev, "Unable to register hwmon device, returned %d\n", err); + return err; + } + + return 0; +} + +static struct platform_driver sy7636a_sensor_driver = { + .probe = sy7636a_sensor_probe, + .driver = { + .name = "sy7636a-temperature", + }, +}; +module_platform_driver(sy7636a_sensor_driver); + +MODULE_DESCRIPTION("SY7636A sensor driver"); +MODULE_LICENSE("GPL"); From e84d3a45cce1a3653230955562828c998db9e765 Mon Sep 17 00:00:00 2001 From: Stanislav Jakubek Date: Fri, 14 Jan 2022 18:21:55 +0100 Subject: [PATCH 078/370] dt-bindings: trivial-devices: make comment indentation consistent Makes the comment indentation consistent across the board. Signed-off-by: Stanislav Jakubek Signed-off-by: Rob Herring Link: https://lore.kernel.org/r/20220114172155.GA3677@standask-GA-A55M-S2HP --- Documentation/devicetree/bindings/trivial-devices.yaml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Documentation/devicetree/bindings/trivial-devices.yaml b/Documentation/devicetree/bindings/trivial-devices.yaml index 091792ba993e..2855581eef40 100644 --- a/Documentation/devicetree/bindings/trivial-devices.yaml +++ b/Documentation/devicetree/bindings/trivial-devices.yaml @@ -77,7 +77,7 @@ properties: - delta,ahe50dc-fan # Delta Electronics DPS-650-AB power supply - delta,dps650ab - # Delta Electronics DPS920AB 920W 54V Power Supply + # Delta Electronics DPS920AB 920W 54V Power Supply - delta,dps920ab # 1/4 Brick DC/DC Regulated Power Module - delta,q54sj108a2 @@ -123,13 +123,13 @@ properties: - ibm,cffps2 # Infineon IR36021 digital POL buck controller - infineon,ir36021 - # Infineon IR38060 Voltage Regulator + # Infineon IR38060 Voltage Regulator - infineon,ir38060 # Infineon IR38064 Voltage Regulator - infineon,ir38064 - # Infineon IR38164 Voltage Regulator + # Infineon IR38164 Voltage Regulator - infineon,ir38164 - # Infineon IR38263 Voltage Regulator + # Infineon IR38263 Voltage Regulator - infineon,ir38263 # Infineon SLB9635 (Soft-) I2C TPM (old protocol, max 100khz) - infineon,slb9635tt From d71ea591223e0ffc39ebca4a0f98244fc208a267 Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Thu, 27 Jan 2022 08:52:29 +0100 Subject: [PATCH 079/370] dt-bindings: vendor-prefixes: clarify HP prefix There are two independent companies: "HP Inc." and "Hewlett Packard Enterprise". Clarify that "hp" prefix is about the first one. Signed-off-by: Krzysztof Kozlowski Signed-off-by: Rob Herring Link: https://lore.kernel.org/r/20220127075229.10299-1-krzysztof.kozlowski@canonical.com --- Documentation/devicetree/bindings/vendor-prefixes.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/vendor-prefixes.yaml b/Documentation/devicetree/bindings/vendor-prefixes.yaml index 294093d45a23..6136dafe4853 100644 --- a/Documentation/devicetree/bindings/vendor-prefixes.yaml +++ b/Documentation/devicetree/bindings/vendor-prefixes.yaml @@ -514,7 +514,7 @@ patternProperties: "^hoperun,.*": description: Jiangsu HopeRun Software Co., Ltd. "^hp,.*": - description: Hewlett Packard + description: Hewlett Packard Inc. "^hsg,.*": description: HannStar Display Co. "^holtek,.*": From 8cba323437a49a45756d661f500b324fc2d486fe Mon Sep 17 00:00:00 2001 From: Sean Nyekjaer Date: Tue, 8 Feb 2022 09:52:13 +0100 Subject: [PATCH 080/370] mtd: rawnand: protect access to rawnand devices while in suspend Prevent rawnand access while in a suspended state. Commit 013e6292aaf5 ("mtd: rawnand: Simplify the locking") allows the rawnand layer to return errors rather than waiting in a blocking wait. Tested on a iMX6ULL. Fixes: 013e6292aaf5 ("mtd: rawnand: Simplify the locking") Signed-off-by: Sean Nyekjaer Reviewed-by: Boris Brezillon Cc: stable@vger.kernel.org Signed-off-by: Miquel Raynal Link: https://lore.kernel.org/linux-mtd/20220208085213.1838273-1-sean@geanix.com --- drivers/mtd/nand/raw/nand_base.c | 44 +++++++++++++++----------------- include/linux/mtd/rawnand.h | 2 ++ 2 files changed, 22 insertions(+), 24 deletions(-) diff --git a/drivers/mtd/nand/raw/nand_base.c b/drivers/mtd/nand/raw/nand_base.c index 3e4a525ac3ca..612ae60e9763 100644 --- a/drivers/mtd/nand/raw/nand_base.c +++ b/drivers/mtd/nand/raw/nand_base.c @@ -338,16 +338,19 @@ static int nand_isbad_bbm(struct nand_chip *chip, loff_t ofs) * * Return: -EBUSY if the chip has been suspended, 0 otherwise */ -static int nand_get_device(struct nand_chip *chip) +static void nand_get_device(struct nand_chip *chip) { - mutex_lock(&chip->lock); - if (chip->suspended) { + /* Wait until the device is resumed. */ + while (1) { + mutex_lock(&chip->lock); + if (!chip->suspended) { + mutex_lock(&chip->controller->lock); + return; + } mutex_unlock(&chip->lock); - return -EBUSY; - } - mutex_lock(&chip->controller->lock); - return 0; + wait_event(chip->resume_wq, !chip->suspended); + } } /** @@ -576,9 +579,7 @@ static int nand_block_markbad_lowlevel(struct nand_chip *chip, loff_t ofs) nand_erase_nand(chip, &einfo, 0); /* Write bad block marker to OOB */ - ret = nand_get_device(chip); - if (ret) - return ret; + nand_get_device(chip); ret = nand_markbad_bbm(chip, ofs); nand_release_device(chip); @@ -3826,9 +3827,7 @@ static int nand_read_oob(struct mtd_info *mtd, loff_t from, ops->mode != MTD_OPS_RAW) return -ENOTSUPP; - ret = nand_get_device(chip); - if (ret) - return ret; + nand_get_device(chip); if (!ops->datbuf) ret = nand_do_read_oob(chip, from, ops); @@ -4415,13 +4414,11 @@ static int nand_write_oob(struct mtd_info *mtd, loff_t to, struct mtd_oob_ops *ops) { struct nand_chip *chip = mtd_to_nand(mtd); - int ret; + int ret = 0; ops->retlen = 0; - ret = nand_get_device(chip); - if (ret) - return ret; + nand_get_device(chip); switch (ops->mode) { case MTD_OPS_PLACE_OOB: @@ -4481,9 +4478,7 @@ int nand_erase_nand(struct nand_chip *chip, struct erase_info *instr, return -EIO; /* Grab the lock and see if the device is available */ - ret = nand_get_device(chip); - if (ret) - return ret; + nand_get_device(chip); /* Shift to get first page */ page = (int)(instr->addr >> chip->page_shift); @@ -4570,7 +4565,7 @@ static void nand_sync(struct mtd_info *mtd) pr_debug("%s: called\n", __func__); /* Grab the lock and see if the device is available */ - WARN_ON(nand_get_device(chip)); + nand_get_device(chip); /* Release it and go back */ nand_release_device(chip); } @@ -4587,9 +4582,7 @@ static int nand_block_isbad(struct mtd_info *mtd, loff_t offs) int ret; /* Select the NAND device */ - ret = nand_get_device(chip); - if (ret) - return ret; + nand_get_device(chip); nand_select_target(chip, chipnr); @@ -4660,6 +4653,8 @@ static void nand_resume(struct mtd_info *mtd) __func__); } mutex_unlock(&chip->lock); + + wake_up_all(&chip->resume_wq); } /** @@ -5438,6 +5433,7 @@ static int nand_scan_ident(struct nand_chip *chip, unsigned int maxchips, chip->cur_cs = -1; mutex_init(&chip->lock); + init_waitqueue_head(&chip->resume_wq); /* Enforce the right timings for reset/detection */ chip->current_interface_config = nand_get_reset_interface_config(); diff --git a/include/linux/mtd/rawnand.h b/include/linux/mtd/rawnand.h index 5b88cd51fadb..dcf90144d70b 100644 --- a/include/linux/mtd/rawnand.h +++ b/include/linux/mtd/rawnand.h @@ -1240,6 +1240,7 @@ struct nand_secure_region { * @lock: Lock protecting the suspended field. Also used to serialize accesses * to the NAND device * @suspended: Set to 1 when the device is suspended, 0 when it's not + * @resume_wq: wait queue to sleep if rawnand is in suspended state. * @cur_cs: Currently selected target. -1 means no target selected, otherwise we * should always have cur_cs >= 0 && cur_cs < nanddev_ntargets(). * NAND Controller drivers should not modify this value, but they're @@ -1294,6 +1295,7 @@ struct nand_chip { /* Internals */ struct mutex lock; unsigned int suspended : 1; + wait_queue_head_t resume_wq; int cur_cs; int read_retries; struct nand_secure_region *secure_regions; From 48e6633a9fa2400b53a964358753769f291a7eb0 Mon Sep 17 00:00:00 2001 From: Miquel Raynal Date: Thu, 16 Dec 2021 12:16:40 +0100 Subject: [PATCH 081/370] mtd: nand: mxic-ecc: Add Macronix external ECC engine support Some SPI-NAND chips do not support on-die ECC. For these chips, correction must apply on the SPI controller end. In order to avoid doing all the calculations by software, Macronix provides a specific engine that can offload the intensive work. Add Macronix ECC engine support, this engine can work in conjunction with a SPI controller and a raw NAND controller, it can be pipelined or external and supports linear and syndrome layouts. Right now the simplest configuration is supported: SPI controller external and linear ECC engine. Signed-off-by: Miquel Raynal Link: https://lore.kernel.org/linux-mtd/20211216111654.238086-15-miquel.raynal@bootlin.com --- drivers/mtd/nand/Kconfig | 6 + drivers/mtd/nand/Makefile | 1 + drivers/mtd/nand/ecc-mxic.c | 695 ++++++++++++++++++++++++++++++++++++ 3 files changed, 702 insertions(+) create mode 100644 drivers/mtd/nand/ecc-mxic.c diff --git a/drivers/mtd/nand/Kconfig b/drivers/mtd/nand/Kconfig index b40455234cbd..8431292ff49d 100644 --- a/drivers/mtd/nand/Kconfig +++ b/drivers/mtd/nand/Kconfig @@ -46,6 +46,12 @@ config MTD_NAND_ECC_SW_BCH ECC codes. They are used with NAND devices requiring more than 1 bit of error correction. +config MTD_NAND_ECC_MXIC + bool "Macronix external hardware ECC engine" + select MTD_NAND_ECC + help + This enables support for the hardware ECC engine from Macronix. + endmenu endmenu diff --git a/drivers/mtd/nand/Makefile b/drivers/mtd/nand/Makefile index 1c0b46960eb1..a4e6b7ae0614 100644 --- a/drivers/mtd/nand/Makefile +++ b/drivers/mtd/nand/Makefile @@ -10,3 +10,4 @@ obj-y += spi/ nandcore-$(CONFIG_MTD_NAND_ECC) += ecc.o nandcore-$(CONFIG_MTD_NAND_ECC_SW_HAMMING) += ecc-sw-hamming.o nandcore-$(CONFIG_MTD_NAND_ECC_SW_BCH) += ecc-sw-bch.o +nandcore-$(CONFIG_MTD_NAND_ECC_MXIC) += ecc-mxic.o diff --git a/drivers/mtd/nand/ecc-mxic.c b/drivers/mtd/nand/ecc-mxic.c new file mode 100644 index 000000000000..3e8fbe62547e --- /dev/null +++ b/drivers/mtd/nand/ecc-mxic.c @@ -0,0 +1,695 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Support for Macronix external hardware ECC engine for NAND devices, also + * called DPE for Data Processing Engine. + * + * Copyright © 2019 Macronix + * Author: Miquel Raynal + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* DPE Configuration */ +#define DP_CONFIG 0x00 +#define ECC_EN BIT(0) +#define ECC_TYP(idx) (((idx) << 3) & GENMASK(6, 3)) +/* DPE Interrupt Status */ +#define INTRPT_STS 0x04 +#define TRANS_CMPLT BIT(0) +#define SDMA_MAIN BIT(1) +#define SDMA_SPARE BIT(2) +#define ECC_ERR BIT(3) +#define TO_SPARE BIT(4) +#define TO_MAIN BIT(5) +/* DPE Interrupt Status Enable */ +#define INTRPT_STS_EN 0x08 +/* DPE Interrupt Signal Enable */ +#define INTRPT_SIG_EN 0x0C +/* Host Controller Configuration */ +#define HC_CONFIG 0x10 +#define MEM2MEM BIT(4) /* TRANS_TYP_IO in the spec */ +#define ECC_PACKED 0 /* LAYOUT_TYP_INTEGRATED in the spec */ +#define ECC_INTERLEAVED BIT(2) /* LAYOUT_TYP_DISTRIBUTED in the spec */ +#define BURST_TYP_FIXED 0 +#define BURST_TYP_INCREASING BIT(0) +/* Host Controller Slave Address */ +#define HC_SLV_ADDR 0x14 +/* ECC Chunk Size */ +#define CHUNK_SIZE 0x20 +/* Main Data Size */ +#define MAIN_SIZE 0x24 +/* Spare Data Size */ +#define SPARE_SIZE 0x28 +#define META_SZ(reg) ((reg) & GENMASK(7, 0)) +#define PARITY_SZ(reg) (((reg) & GENMASK(15, 8)) >> 8) +#define RSV_SZ(reg) (((reg) & GENMASK(23, 16)) >> 16) +#define SPARE_SZ(reg) ((reg) >> 24) +/* ECC Chunk Count */ +#define CHUNK_CNT 0x30 +/* SDMA Control */ +#define SDMA_CTRL 0x40 +#define WRITE_NAND 0 +#define READ_NAND BIT(1) +#define CONT_NAND BIT(29) +#define CONT_SYSM BIT(30) /* Continue System Memory? */ +#define SDMA_STRT BIT(31) +/* SDMA Address of Main Data */ +#define SDMA_MAIN_ADDR 0x44 +/* SDMA Address of Spare Data */ +#define SDMA_SPARE_ADDR 0x48 +/* DPE Version Number */ +#define DP_VER 0xD0 +#define DP_VER_OFFSET 16 + +/* Status bytes between each chunk of spare data */ +#define STAT_BYTES 4 +#define NO_ERR 0x00 +#define MAX_CORR_ERR 0x28 +#define UNCORR_ERR 0xFE +#define ERASED_CHUNK 0xFF + +struct mxic_ecc_engine { + struct device *dev; + void __iomem *regs; + int irq; + struct completion complete; + struct nand_ecc_engine external_engine; + struct mutex lock; +}; + +struct mxic_ecc_ctx { + /* ECC machinery */ + unsigned int data_step_sz; + unsigned int oob_step_sz; + unsigned int parity_sz; + unsigned int meta_sz; + u8 *status; + int steps; + + /* DMA boilerplate */ + struct nand_ecc_req_tweak_ctx req_ctx; + u8 *oobwithstat; + struct scatterlist sg[2]; + struct nand_page_io_req *req; +}; + +static struct mxic_ecc_engine *ext_ecc_eng_to_mxic(struct nand_ecc_engine *eng) +{ + return container_of(eng, struct mxic_ecc_engine, external_engine); +} + +static struct mxic_ecc_engine *nand_to_mxic(struct nand_device *nand) +{ + struct nand_ecc_engine *eng = nand->ecc.engine; + + return ext_ecc_eng_to_mxic(eng); +} + +static int mxic_ecc_ooblayout_ecc(struct mtd_info *mtd, int section, + struct mtd_oob_region *oobregion) +{ + struct nand_device *nand = mtd_to_nanddev(mtd); + struct mxic_ecc_ctx *ctx = nand_to_ecc_ctx(nand); + + if (section < 0 || section >= ctx->steps) + return -ERANGE; + + oobregion->offset = (section * ctx->oob_step_sz) + ctx->meta_sz; + oobregion->length = ctx->parity_sz; + + return 0; +} + +static int mxic_ecc_ooblayout_free(struct mtd_info *mtd, int section, + struct mtd_oob_region *oobregion) +{ + struct nand_device *nand = mtd_to_nanddev(mtd); + struct mxic_ecc_ctx *ctx = nand_to_ecc_ctx(nand); + + if (section < 0 || section >= ctx->steps) + return -ERANGE; + + if (!section) { + oobregion->offset = 2; + oobregion->length = ctx->meta_sz - 2; + } else { + oobregion->offset = section * ctx->oob_step_sz; + oobregion->length = ctx->meta_sz; + } + + return 0; +} + +static const struct mtd_ooblayout_ops mxic_ecc_ooblayout_ops = { + .ecc = mxic_ecc_ooblayout_ecc, + .free = mxic_ecc_ooblayout_free, +}; + +static void mxic_ecc_disable_engine(struct mxic_ecc_engine *mxic) +{ + u32 reg; + + reg = readl(mxic->regs + DP_CONFIG); + reg &= ~ECC_EN; + writel(reg, mxic->regs + DP_CONFIG); +} + +static void mxic_ecc_enable_engine(struct mxic_ecc_engine *mxic) +{ + u32 reg; + + reg = readl(mxic->regs + DP_CONFIG); + reg |= ECC_EN; + writel(reg, mxic->regs + DP_CONFIG); +} + +static void mxic_ecc_disable_int(struct mxic_ecc_engine *mxic) +{ + writel(0, mxic->regs + INTRPT_SIG_EN); +} + +static void mxic_ecc_enable_int(struct mxic_ecc_engine *mxic) +{ + writel(TRANS_CMPLT, mxic->regs + INTRPT_SIG_EN); +} + +static irqreturn_t mxic_ecc_isr(int irq, void *dev_id) +{ + struct mxic_ecc_engine *mxic = dev_id; + u32 sts; + + sts = readl(mxic->regs + INTRPT_STS); + if (!sts) + return IRQ_NONE; + + if (sts & TRANS_CMPLT) + complete(&mxic->complete); + + writel(sts, mxic->regs + INTRPT_STS); + + return IRQ_HANDLED; +} + +static int mxic_ecc_init_ctx(struct nand_device *nand, struct device *dev) +{ + struct mxic_ecc_engine *mxic = nand_to_mxic(nand); + struct nand_ecc_props *conf = &nand->ecc.ctx.conf; + struct nand_ecc_props *reqs = &nand->ecc.requirements; + struct nand_ecc_props *user = &nand->ecc.user_conf; + struct mtd_info *mtd = nanddev_to_mtd(nand); + int step_size = 0, strength = 0, desired_correction = 0, steps, idx; + int possible_strength[] = {4, 8, 40, 48}; + int spare_size[] = {32, 32, 96, 96}; + struct mxic_ecc_ctx *ctx; + u32 spare_reg; + int ret; + + ctx = devm_kzalloc(dev, sizeof(*ctx), GFP_KERNEL); + if (!ctx) + return -ENOMEM; + + nand->ecc.ctx.priv = ctx; + + /* Only large page NAND chips may use BCH */ + if (mtd->oobsize < 64) { + pr_err("BCH cannot be used with small page NAND chips\n"); + return -EINVAL; + } + + mtd_set_ooblayout(mtd, &mxic_ecc_ooblayout_ops); + + /* Enable all status bits */ + writel(TRANS_CMPLT | SDMA_MAIN | SDMA_SPARE | ECC_ERR | + TO_SPARE | TO_MAIN, mxic->regs + INTRPT_STS_EN); + + /* Configure the correction depending on the NAND device topology */ + if (user->step_size && user->strength) { + step_size = user->step_size; + strength = user->strength; + } else if (reqs->step_size && reqs->strength) { + step_size = reqs->step_size; + strength = reqs->strength; + } + + if (step_size && strength) { + steps = mtd->writesize / step_size; + desired_correction = steps * strength; + } + + /* Step size is fixed to 1kiB, strength may vary (4 possible values) */ + conf->step_size = SZ_1K; + steps = mtd->writesize / conf->step_size; + + ctx->status = devm_kzalloc(dev, steps * sizeof(u8), GFP_KERNEL); + if (!ctx->status) + return -ENOMEM; + + if (desired_correction) { + strength = desired_correction / steps; + + for (idx = 0; idx < ARRAY_SIZE(possible_strength); idx++) + if (possible_strength[idx] >= strength) + break; + + idx = min_t(unsigned int, idx, + ARRAY_SIZE(possible_strength) - 1); + } else { + /* Missing data, maximize the correction */ + idx = ARRAY_SIZE(possible_strength) - 1; + } + + /* Tune the selected strength until it fits in the OOB area */ + for (; idx >= 0; idx--) { + if (spare_size[idx] * steps <= mtd->oobsize) + break; + } + + /* This engine cannot be used with this NAND device */ + if (idx < 0) + return -EINVAL; + + /* Configure the engine for the desired strength */ + writel(ECC_TYP(idx), mxic->regs + DP_CONFIG); + conf->strength = possible_strength[idx]; + spare_reg = readl(mxic->regs + SPARE_SIZE); + + ctx->steps = steps; + ctx->data_step_sz = mtd->writesize / steps; + ctx->oob_step_sz = mtd->oobsize / steps; + ctx->parity_sz = PARITY_SZ(spare_reg); + ctx->meta_sz = META_SZ(spare_reg); + + /* Ensure buffers will contain enough bytes to store the STAT_BYTES */ + ctx->req_ctx.oob_buffer_size = nanddev_per_page_oobsize(nand) + + (ctx->steps * STAT_BYTES); + ret = nand_ecc_init_req_tweaking(&ctx->req_ctx, nand); + if (ret) + return ret; + + ctx->oobwithstat = kmalloc(mtd->oobsize + (ctx->steps * STAT_BYTES), + GFP_KERNEL); + if (!ctx->oobwithstat) { + ret = -ENOMEM; + goto cleanup_req_tweak; + } + + sg_init_table(ctx->sg, 2); + + /* Configuration dump and sanity checks */ + dev_err(dev, "DPE version number: %d\n", + readl(mxic->regs + DP_VER) >> DP_VER_OFFSET); + dev_err(dev, "Chunk size: %d\n", readl(mxic->regs + CHUNK_SIZE)); + dev_err(dev, "Main size: %d\n", readl(mxic->regs + MAIN_SIZE)); + dev_err(dev, "Spare size: %d\n", SPARE_SZ(spare_reg)); + dev_err(dev, "Rsv size: %ld\n", RSV_SZ(spare_reg)); + dev_err(dev, "Parity size: %d\n", ctx->parity_sz); + dev_err(dev, "Meta size: %d\n", ctx->meta_sz); + + if ((ctx->meta_sz + ctx->parity_sz + RSV_SZ(spare_reg)) != + SPARE_SZ(spare_reg)) { + dev_err(dev, "Wrong OOB configuration: %d + %d + %ld != %d\n", + ctx->meta_sz, ctx->parity_sz, RSV_SZ(spare_reg), + SPARE_SZ(spare_reg)); + ret = -EINVAL; + goto free_oobwithstat; + } + + if (ctx->oob_step_sz != SPARE_SZ(spare_reg)) { + dev_err(dev, "Wrong OOB configuration: %d != %d\n", + ctx->oob_step_sz, SPARE_SZ(spare_reg)); + ret = -EINVAL; + goto free_oobwithstat; + } + + return 0; + +free_oobwithstat: + kfree(ctx->oobwithstat); +cleanup_req_tweak: + nand_ecc_cleanup_req_tweaking(&ctx->req_ctx); + + return ret; +} + +static int mxic_ecc_init_ctx_external(struct nand_device *nand) +{ + struct mxic_ecc_engine *mxic = nand_to_mxic(nand); + struct device *dev = nand->ecc.engine->dev; + int ret; + + dev_info(dev, "Macronix ECC engine in external mode\n"); + + ret = mxic_ecc_init_ctx(nand, dev); + if (ret) + return ret; + + /* Trigger each step manually */ + writel(1, mxic->regs + CHUNK_CNT); + writel(BURST_TYP_INCREASING | ECC_PACKED | MEM2MEM, + mxic->regs + HC_CONFIG); + + return 0; +} + +static void mxic_ecc_cleanup_ctx(struct nand_device *nand) +{ + struct mxic_ecc_ctx *ctx = nand_to_ecc_ctx(nand); + + if (ctx) { + nand_ecc_cleanup_req_tweaking(&ctx->req_ctx); + kfree(ctx->oobwithstat); + } +} + +static int mxic_ecc_data_xfer_wait_for_completion(struct mxic_ecc_engine *mxic) +{ + u32 val; + int ret; + + if (mxic->irq) { + reinit_completion(&mxic->complete); + mxic_ecc_enable_int(mxic); + ret = wait_for_completion_timeout(&mxic->complete, + msecs_to_jiffies(1000)); + mxic_ecc_disable_int(mxic); + } else { + ret = readl_poll_timeout(mxic->regs + INTRPT_STS, val, + val & TRANS_CMPLT, 10, USEC_PER_SEC); + writel(val, mxic->regs + INTRPT_STS); + } + + if (ret) { + dev_err(mxic->dev, "Timeout on data xfer completion\n"); + return -ETIMEDOUT; + } + + return 0; +} + +static int mxic_ecc_process_data(struct mxic_ecc_engine *mxic, + unsigned int direction) +{ + unsigned int dir = (direction == NAND_PAGE_READ) ? + READ_NAND : WRITE_NAND; + int ret; + + mxic_ecc_enable_engine(mxic); + + /* Trigger processing */ + writel(SDMA_STRT | dir, mxic->regs + SDMA_CTRL); + + /* Wait for completion */ + ret = mxic_ecc_data_xfer_wait_for_completion(mxic); + + mxic_ecc_disable_engine(mxic); + + return ret; +} + +static void mxic_ecc_extract_status_bytes(struct mxic_ecc_ctx *ctx) +{ + u8 *buf = ctx->oobwithstat; + int next_stat_pos; + int step; + + /* Extract the ECC status */ + for (step = 0; step < ctx->steps; step++) { + next_stat_pos = ctx->oob_step_sz + + ((STAT_BYTES + ctx->oob_step_sz) * step); + + ctx->status[step] = buf[next_stat_pos]; + } +} + +static void mxic_ecc_reconstruct_oobbuf(struct mxic_ecc_ctx *ctx, + u8 *dst, const u8 *src) +{ + int step; + + /* Reconstruct the OOB buffer linearly (without the ECC status bytes) */ + for (step = 0; step < ctx->steps; step++) + memcpy(dst + (step * ctx->oob_step_sz), + src + (step * (ctx->oob_step_sz + STAT_BYTES)), + ctx->oob_step_sz); +} + +static void mxic_ecc_add_room_in_oobbuf(struct mxic_ecc_ctx *ctx, + u8 *dst, const u8 *src) +{ + int step; + + /* Add some space in the OOB buffer for the status bytes */ + for (step = 0; step < ctx->steps; step++) + memcpy(dst + (step * (ctx->oob_step_sz + STAT_BYTES)), + src + (step * ctx->oob_step_sz), + ctx->oob_step_sz); +} + +static int mxic_ecc_count_biterrs(struct mxic_ecc_engine *mxic, + struct nand_device *nand) +{ + struct mxic_ecc_ctx *ctx = nand_to_ecc_ctx(nand); + struct mtd_info *mtd = nanddev_to_mtd(nand); + struct device *dev = mxic->dev; + unsigned int max_bf = 0; + bool failure = false; + int step; + + for (step = 0; step < ctx->steps; step++) { + u8 stat = ctx->status[step]; + + if (stat == NO_ERR) { + dev_dbg(dev, "ECC step %d: no error\n", step); + } else if (stat == ERASED_CHUNK) { + dev_dbg(dev, "ECC step %d: erased\n", step); + } else if (stat == UNCORR_ERR || stat > MAX_CORR_ERR) { + dev_dbg(dev, "ECC step %d: uncorrectable\n", step); + mtd->ecc_stats.failed++; + failure = true; + } else { + dev_dbg(dev, "ECC step %d: %d bits corrected\n", + step, stat); + max_bf = max_t(unsigned int, max_bf, stat); + mtd->ecc_stats.corrected += stat; + } + } + + return failure ? -EBADMSG : max_bf; +} + +/* External ECC engine helpers */ +static int mxic_ecc_prepare_io_req_external(struct nand_device *nand, + struct nand_page_io_req *req) +{ + struct mxic_ecc_engine *mxic = nand_to_mxic(nand); + struct mxic_ecc_ctx *ctx = nand_to_ecc_ctx(nand); + struct mtd_info *mtd = nanddev_to_mtd(nand); + int offset, nents, step, ret; + + if (req->mode == MTD_OPS_RAW) + return 0; + + nand_ecc_tweak_req(&ctx->req_ctx, req); + ctx->req = req; + + if (req->type == NAND_PAGE_READ) + return 0; + + mxic_ecc_add_room_in_oobbuf(ctx, ctx->oobwithstat, + ctx->req->oobbuf.out); + + sg_set_buf(&ctx->sg[0], req->databuf.out, req->datalen); + sg_set_buf(&ctx->sg[1], ctx->oobwithstat, + req->ooblen + (ctx->steps * STAT_BYTES)); + + nents = dma_map_sg(mxic->dev, ctx->sg, 2, DMA_BIDIRECTIONAL); + if (!nents) + return -EINVAL; + + mutex_lock(&mxic->lock); + + for (step = 0; step < ctx->steps; step++) { + writel(sg_dma_address(&ctx->sg[0]) + (step * ctx->data_step_sz), + mxic->regs + SDMA_MAIN_ADDR); + writel(sg_dma_address(&ctx->sg[1]) + (step * (ctx->oob_step_sz + STAT_BYTES)), + mxic->regs + SDMA_SPARE_ADDR); + ret = mxic_ecc_process_data(mxic, ctx->req->type); + if (ret) + break; + } + + mutex_unlock(&mxic->lock); + + dma_unmap_sg(mxic->dev, ctx->sg, 2, DMA_BIDIRECTIONAL); + + if (ret) + return ret; + + /* Retrieve the calculated ECC bytes */ + for (step = 0; step < ctx->steps; step++) { + offset = ctx->meta_sz + (step * ctx->oob_step_sz); + mtd_ooblayout_get_eccbytes(mtd, + (u8 *)ctx->req->oobbuf.out + offset, + ctx->oobwithstat + (step * STAT_BYTES), + step * ctx->parity_sz, + ctx->parity_sz); + } + + return 0; +} + +static int mxic_ecc_finish_io_req_external(struct nand_device *nand, + struct nand_page_io_req *req) +{ + struct mxic_ecc_engine *mxic = nand_to_mxic(nand); + struct mxic_ecc_ctx *ctx = nand_to_ecc_ctx(nand); + int nents, step, ret; + + if (req->mode == MTD_OPS_RAW) + return 0; + + if (req->type == NAND_PAGE_WRITE) { + nand_ecc_restore_req(&ctx->req_ctx, req); + return 0; + } + + /* Copy the OOB buffer and add room for the ECC engine status bytes */ + mxic_ecc_add_room_in_oobbuf(ctx, ctx->oobwithstat, ctx->req->oobbuf.in); + + sg_set_buf(&ctx->sg[0], req->databuf.in, req->datalen); + sg_set_buf(&ctx->sg[1], ctx->oobwithstat, + req->ooblen + (ctx->steps * STAT_BYTES)); + nents = dma_map_sg(mxic->dev, ctx->sg, 2, DMA_BIDIRECTIONAL); + if (!nents) + return -EINVAL; + + mutex_lock(&mxic->lock); + + for (step = 0; step < ctx->steps; step++) { + writel(sg_dma_address(&ctx->sg[0]) + (step * ctx->data_step_sz), + mxic->regs + SDMA_MAIN_ADDR); + writel(sg_dma_address(&ctx->sg[1]) + (step * (ctx->oob_step_sz + STAT_BYTES)), + mxic->regs + SDMA_SPARE_ADDR); + ret = mxic_ecc_process_data(mxic, ctx->req->type); + if (ret) + break; + } + + mutex_unlock(&mxic->lock); + + dma_unmap_sg(mxic->dev, ctx->sg, 2, DMA_BIDIRECTIONAL); + + /* Extract the status bytes and reconstruct the buffer */ + mxic_ecc_extract_status_bytes(ctx); + mxic_ecc_reconstruct_oobbuf(ctx, ctx->req->oobbuf.in, ctx->oobwithstat); + + nand_ecc_restore_req(&ctx->req_ctx, req); + + return mxic_ecc_count_biterrs(mxic, nand); +} + +static struct nand_ecc_engine_ops mxic_ecc_engine_external_ops = { + .init_ctx = mxic_ecc_init_ctx_external, + .cleanup_ctx = mxic_ecc_cleanup_ctx, + .prepare_io_req = mxic_ecc_prepare_io_req_external, + .finish_io_req = mxic_ecc_finish_io_req_external, +}; + +static int mxic_ecc_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct mxic_ecc_engine *mxic; + int ret; + + mxic = devm_kzalloc(&pdev->dev, sizeof(*mxic), GFP_KERNEL); + if (!mxic) + return -ENOMEM; + + mxic->dev = &pdev->dev; + + /* + * Both memory regions for the ECC engine itself and the AXI slave + * address are mandatory. + */ + mxic->regs = devm_platform_ioremap_resource(pdev, 0); + if (IS_ERR(mxic->regs)) { + dev_err(&pdev->dev, "Missing memory region\n"); + return PTR_ERR(mxic->regs); + } + + mxic_ecc_disable_engine(mxic); + mxic_ecc_disable_int(mxic); + + /* IRQ is optional yet much more efficient */ + mxic->irq = platform_get_irq_byname_optional(pdev, "ecc-engine"); + if (mxic->irq > 0) { + ret = devm_request_irq(&pdev->dev, mxic->irq, mxic_ecc_isr, 0, + "mxic-ecc", mxic); + if (ret) + return ret; + } else { + dev_info(dev, "Invalid or missing IRQ, fallback to polling\n"); + mxic->irq = 0; + } + + mutex_init(&mxic->lock); + + /* + * In external mode, the device is the ECC engine. In pipelined mode, + * the device is the host controller. The device is used to match the + * right ECC engine based on the DT properties. + */ + mxic->external_engine.dev = &pdev->dev; + mxic->external_engine.integration = NAND_ECC_ENGINE_INTEGRATION_EXTERNAL; + mxic->external_engine.ops = &mxic_ecc_engine_external_ops; + + nand_ecc_register_on_host_hw_engine(&mxic->external_engine); + + platform_set_drvdata(pdev, mxic); + + return 0; +} + +static int mxic_ecc_remove(struct platform_device *pdev) +{ + struct mxic_ecc_engine *mxic = platform_get_drvdata(pdev); + + nand_ecc_unregister_on_host_hw_engine(&mxic->external_engine); + + return 0; +} + +static const struct of_device_id mxic_ecc_of_ids[] = { + { + .compatible = "mxicy,nand-ecc-engine-rev3", + }, + { /* sentinel */ }, +}; +MODULE_DEVICE_TABLE(of, mxic_ecc_of_ids); + +static struct platform_driver mxic_ecc_driver = { + .driver = { + .name = "mxic-nand-ecc-engine", + .of_match_table = mxic_ecc_of_ids, + }, + .probe = mxic_ecc_probe, + .remove = mxic_ecc_remove, +}; +module_platform_driver(mxic_ecc_driver); + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Miquel Raynal "); +MODULE_DESCRIPTION("Macronix NAND hardware ECC controller"); From 5145abeb0649acf810a32e63bd762e617a9b3309 Mon Sep 17 00:00:00 2001 From: Miquel Raynal Date: Thu, 16 Dec 2021 12:16:41 +0100 Subject: [PATCH 082/370] mtd: nand: ecc: Provide a helper to retrieve a pilelined engine device In a pipelined engine situation, we might either have the host which internally has support for error correction, or have it using an external hardware block for this purpose. In the former case, the host is also the ECC engine. In the latter case, it is not. In order to get the right pointers on the right devices (for example: in order to devm_* allocate variables), let's introduce this helper which can safely be called by pipelined ECC engines in order to retrieve the right device structure. Signed-off-by: Miquel Raynal Link: https://lore.kernel.org/linux-mtd/20211216111654.238086-16-miquel.raynal@bootlin.com --- drivers/mtd/nand/ecc.c | 31 +++++++++++++++++++++++++++++++ include/linux/mtd/nand.h | 1 + 2 files changed, 32 insertions(+) diff --git a/drivers/mtd/nand/ecc.c b/drivers/mtd/nand/ecc.c index 078f5ec38de3..5250764cedee 100644 --- a/drivers/mtd/nand/ecc.c +++ b/drivers/mtd/nand/ecc.c @@ -699,6 +699,37 @@ void nand_ecc_put_on_host_hw_engine(struct nand_device *nand) } EXPORT_SYMBOL(nand_ecc_put_on_host_hw_engine); +/* + * In the case of a pipelined engine, the device registering the ECC + * engine is not necessarily the ECC engine itself but may be a host controller. + * It is then useful to provide a helper to retrieve the right device object + * which actually represents the ECC engine. + */ +struct device *nand_ecc_get_engine_dev(struct device *host) +{ + struct platform_device *ecc_pdev; + struct device_node *np; + + /* + * If the device node contains this property, it means we need to follow + * it in order to get the right ECC engine device we are looking for. + */ + np = of_parse_phandle(host->of_node, "nand-ecc-engine", 0); + if (!np) + return host; + + ecc_pdev = of_find_device_by_node(np); + if (!ecc_pdev) { + of_node_put(np); + return NULL; + } + + platform_device_put(ecc_pdev); + of_node_put(np); + + return &ecc_pdev->dev; +} + MODULE_LICENSE("GPL"); MODULE_AUTHOR("Miquel Raynal "); MODULE_DESCRIPTION("Generic ECC engine"); diff --git a/include/linux/mtd/nand.h b/include/linux/mtd/nand.h index b617efa0a881..615b3e3a3920 100644 --- a/include/linux/mtd/nand.h +++ b/include/linux/mtd/nand.h @@ -309,6 +309,7 @@ struct nand_ecc_engine *nand_ecc_get_sw_engine(struct nand_device *nand); struct nand_ecc_engine *nand_ecc_get_on_die_hw_engine(struct nand_device *nand); struct nand_ecc_engine *nand_ecc_get_on_host_hw_engine(struct nand_device *nand); void nand_ecc_put_on_host_hw_engine(struct nand_device *nand); +struct device *nand_ecc_get_engine_dev(struct device *host); #if IS_ENABLED(CONFIG_MTD_NAND_ECC_SW_HAMMING) struct nand_ecc_engine *nand_ecc_sw_hamming_get_engine(void); From f4e82f190e793ed882b028044e90769acc4e55d7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonathan=20Neusch=C3=A4fer?= Date: Sun, 30 Jan 2022 11:27:02 +0100 Subject: [PATCH 083/370] dt-bindings: timer: nuvoton,npcm7xx-timer: Convert to YAML MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Let's convert this devicetree binding to YAML, to make it easier to extend later. Signed-off-by: Jonathan Neuschäfer Signed-off-by: Rob Herring Link: https://lore.kernel.org/r/20220130102704.2892072-1-j.neuschaefer@gmx.net --- .../bindings/timer/nuvoton,npcm7xx-timer.txt | 21 --------- .../bindings/timer/nuvoton,npcm7xx-timer.yaml | 46 +++++++++++++++++++ 2 files changed, 46 insertions(+), 21 deletions(-) delete mode 100644 Documentation/devicetree/bindings/timer/nuvoton,npcm7xx-timer.txt create mode 100644 Documentation/devicetree/bindings/timer/nuvoton,npcm7xx-timer.yaml diff --git a/Documentation/devicetree/bindings/timer/nuvoton,npcm7xx-timer.txt b/Documentation/devicetree/bindings/timer/nuvoton,npcm7xx-timer.txt deleted file mode 100644 index ac3a5e887455..000000000000 --- a/Documentation/devicetree/bindings/timer/nuvoton,npcm7xx-timer.txt +++ /dev/null @@ -1,21 +0,0 @@ -Nuvoton NPCM7xx timer - -Nuvoton NPCM7xx have three timer modules, each timer module provides five 24-bit -timer counters. - -Required properties: -- compatible : "nuvoton,npcm750-timer" for Poleg NPCM750, or - "nuvoton,wpcm450-timer" for Hermon WPCM450. -- reg : Offset and length of the register set for the device. -- interrupts : Contain the timer interrupt of timer 0. -- clocks : phandle of timer reference clock (usually a 25 MHz clock). - -Example: - -timer@f0008000 { - compatible = "nuvoton,npcm750-timer"; - interrupts = ; - reg = <0xf0008000 0x50>; - clocks = <&clk NPCM7XX_CLK_TIMER>; -}; - diff --git a/Documentation/devicetree/bindings/timer/nuvoton,npcm7xx-timer.yaml b/Documentation/devicetree/bindings/timer/nuvoton,npcm7xx-timer.yaml new file mode 100644 index 000000000000..0cbc26a72151 --- /dev/null +++ b/Documentation/devicetree/bindings/timer/nuvoton,npcm7xx-timer.yaml @@ -0,0 +1,46 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/timer/nuvoton,npcm7xx-timer.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Nuvoton NPCM7xx timer + +maintainers: + - Jonathan Neuschäfer + +properties: + compatible: + enum: + - nuvoton,wpcm450-timer # for Hermon WPCM450 + - nuvoton,npcm750-timer # for Poleg NPCM750 + + reg: + maxItems: 1 + + interrupts: + items: + - description: The timer interrupt of timer 0 + + clocks: + maxItems: 1 + +required: + - compatible + - reg + - interrupts + - clocks + +additionalProperties: false + +examples: + - | + #include + #include + #include + timer@f0008000 { + compatible = "nuvoton,npcm750-timer"; + interrupts = ; + reg = <0xf0008000 0x50>; + clocks = <&clk NPCM7XX_CLK_TIMER>; + }; From 208b65f7b5cccb7185ec7c1b11e788eddf9e075a Mon Sep 17 00:00:00 2001 From: Corentin Labbe Date: Tue, 1 Feb 2022 14:49:40 +0000 Subject: [PATCH 084/370] dt-bindings: net: convert net/cortina,gemini-ethernet to yaml Converts net/cortina,gemini-ethernet.txt to yaml This permits to detect some missing properties like interrupts Signed-off-by: Corentin Labbe Reviewed-by: Linus Walleij Signed-off-by: Rob Herring Link: https://lore.kernel.org/r/20220201144940.2488782-1-clabbe@baylibre.com --- .../bindings/net/cortina,gemini-ethernet.txt | 92 ------------ .../bindings/net/cortina,gemini-ethernet.yaml | 137 ++++++++++++++++++ 2 files changed, 137 insertions(+), 92 deletions(-) delete mode 100644 Documentation/devicetree/bindings/net/cortina,gemini-ethernet.txt create mode 100644 Documentation/devicetree/bindings/net/cortina,gemini-ethernet.yaml diff --git a/Documentation/devicetree/bindings/net/cortina,gemini-ethernet.txt b/Documentation/devicetree/bindings/net/cortina,gemini-ethernet.txt deleted file mode 100644 index 6c559981d110..000000000000 --- a/Documentation/devicetree/bindings/net/cortina,gemini-ethernet.txt +++ /dev/null @@ -1,92 +0,0 @@ -Cortina Systems Gemini Ethernet Controller -========================================== - -This ethernet controller is found in the Gemini SoC family: -StorLink SL3512 and SL3516, also known as Cortina Systems -CS3512 and CS3516. - -Required properties: -- compatible: must be "cortina,gemini-ethernet" -- reg: must contain the global registers and the V-bit and A-bit - memory areas, in total three register sets. -- syscon: a phandle to the system controller -- #address-cells: must be specified, must be <1> -- #size-cells: must be specified, must be <1> -- ranges: should be state like this giving a 1:1 address translation - for the subnodes - -The subnodes represents the two ethernet ports in this device. -They are not independent of each other since they share resources -in the parent node, and are thus children. - -Required subnodes: -- port0: contains the resources for ethernet port 0 -- port1: contains the resources for ethernet port 1 - -Required subnode properties: -- compatible: must be "cortina,gemini-ethernet-port" -- reg: must contain two register areas: the DMA/TOE memory and - the GMAC memory area of the port -- interrupts: should contain the interrupt line of the port. - this is nominally a level interrupt active high. -- resets: this must provide an SoC-integrated reset line for - the port. -- clocks: this should contain a handle to the PCLK clock for - clocking the silicon in this port -- clock-names: must be "PCLK" - -Optional subnode properties: -- phy-mode: see ethernet.txt -- phy-handle: see ethernet.txt - -Example: - -mdio-bus { - (...) - phy0: ethernet-phy@1 { - reg = <1>; - device_type = "ethernet-phy"; - }; - phy1: ethernet-phy@3 { - reg = <3>; - device_type = "ethernet-phy"; - }; -}; - - -ethernet@60000000 { - compatible = "cortina,gemini-ethernet"; - reg = <0x60000000 0x4000>, /* Global registers, queue */ - <0x60004000 0x2000>, /* V-bit */ - <0x60006000 0x2000>; /* A-bit */ - syscon = <&syscon>; - #address-cells = <1>; - #size-cells = <1>; - ranges; - - gmac0: ethernet-port@0 { - compatible = "cortina,gemini-ethernet-port"; - reg = <0x60008000 0x2000>, /* Port 0 DMA/TOE */ - <0x6000a000 0x2000>; /* Port 0 GMAC */ - interrupt-parent = <&intcon>; - interrupts = <1 IRQ_TYPE_LEVEL_HIGH>; - resets = <&syscon GEMINI_RESET_GMAC0>; - clocks = <&syscon GEMINI_CLK_GATE_GMAC0>; - clock-names = "PCLK"; - phy-mode = "rgmii"; - phy-handle = <&phy0>; - }; - - gmac1: ethernet-port@1 { - compatible = "cortina,gemini-ethernet-port"; - reg = <0x6000c000 0x2000>, /* Port 1 DMA/TOE */ - <0x6000e000 0x2000>; /* Port 1 GMAC */ - interrupt-parent = <&intcon>; - interrupts = <2 IRQ_TYPE_LEVEL_HIGH>; - resets = <&syscon GEMINI_RESET_GMAC1>; - clocks = <&syscon GEMINI_CLK_GATE_GMAC1>; - clock-names = "PCLK"; - phy-mode = "rgmii"; - phy-handle = <&phy1>; - }; -}; diff --git a/Documentation/devicetree/bindings/net/cortina,gemini-ethernet.yaml b/Documentation/devicetree/bindings/net/cortina,gemini-ethernet.yaml new file mode 100644 index 000000000000..cc01b9b5752a --- /dev/null +++ b/Documentation/devicetree/bindings/net/cortina,gemini-ethernet.yaml @@ -0,0 +1,137 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/net/cortina,gemini-ethernet.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Cortina Systems Gemini Ethernet Controller + +maintainers: + - Linus Walleij + +description: | + This ethernet controller is found in the Gemini SoC family: + StorLink SL3512 and SL3516, also known as Cortina Systems + CS3512 and CS3516. + +properties: + compatible: + const: cortina,gemini-ethernet + + reg: + minItems: 3 + description: must contain the global registers and the V-bit and A-bit + memory areas, in total three register sets. + + "#address-cells": + const: 1 + + "#size-cells": + const: 1 + + ranges: true + +#The subnodes represents the two ethernet ports in this device. +#They are not independent of each other since they share resources +#in the parent node, and are thus children. +patternProperties: + "^ethernet-port@[0-9]+$": + type: object + description: contains the resources for ethernet port + allOf: + - $ref: ethernet-controller.yaml# + properties: + compatible: + const: cortina,gemini-ethernet-port + + reg: + items: + - description: DMA/TOE memory + - description: GMAC memory area of the port + + interrupts: + maxItems: 1 + description: should contain the interrupt line of the port. + this is nominally a level interrupt active high. + + resets: + maxItems: 1 + description: this must provide an SoC-integrated reset line for the port. + + clocks: + maxItems: 1 + description: this should contain a handle to the PCLK clock for + clocking the silicon in this port + + clock-names: + const: PCLK + + required: + - reg + - compatible + - interrupts + - resets + - clocks + - clock-names + +required: + - compatible + - reg + - ranges + +additionalProperties: false + +examples: + - | + #include + #include + #include + mdio0: mdio { + #address-cells = <1>; + #size-cells = <0>; + phy0: ethernet-phy@1 { + reg = <1>; + device_type = "ethernet-phy"; + }; + phy1: ethernet-phy@3 { + reg = <3>; + device_type = "ethernet-phy"; + }; + }; + + + ethernet@60000000 { + compatible = "cortina,gemini-ethernet"; + reg = <0x60000000 0x4000>, /* Global registers, queue */ + <0x60004000 0x2000>, /* V-bit */ + <0x60006000 0x2000>; /* A-bit */ + #address-cells = <1>; + #size-cells = <1>; + ranges; + + gmac0: ethernet-port@0 { + compatible = "cortina,gemini-ethernet-port"; + reg = <0x60008000 0x2000>, /* Port 0 DMA/TOE */ + <0x6000a000 0x2000>; /* Port 0 GMAC */ + interrupt-parent = <&intcon>; + interrupts = <1 IRQ_TYPE_LEVEL_HIGH>; + resets = <&syscon GEMINI_RESET_GMAC0>; + clocks = <&syscon GEMINI_CLK_GATE_GMAC0>; + clock-names = "PCLK"; + phy-mode = "rgmii"; + phy-handle = <&phy0>; + }; + + gmac1: ethernet-port@1 { + compatible = "cortina,gemini-ethernet-port"; + reg = <0x6000c000 0x2000>, /* Port 1 DMA/TOE */ + <0x6000e000 0x2000>; /* Port 1 GMAC */ + interrupt-parent = <&intcon>; + interrupts = <2 IRQ_TYPE_LEVEL_HIGH>; + resets = <&syscon GEMINI_RESET_GMAC1>; + clocks = <&syscon GEMINI_CLK_GATE_GMAC1>; + clock-names = "PCLK"; + phy-mode = "rgmii"; + phy-handle = <&phy1>; + }; + }; From 31fc1c63c2ae4a542e3c7ac572a10a59ece45c24 Mon Sep 17 00:00:00 2001 From: Tony Lindgren Date: Thu, 3 Feb 2022 09:39:29 +0200 Subject: [PATCH 085/370] dt-bindings: clock: Add binding for TI clksel In order to prepare for fixing lots of devicetree unique_unit_address warnings for the TI clock nodes, let's add a binding for the TI clksel clocks. This allows us to move the overlapping reg properties for the component clocks to be children of the related clksel nodes. And with that we need the reg property only for the parent clksel node making the reg property unique like it should be. We want to set #clock-cells = <2> in case we ever start parsing ranges of clkcsel instances directly using a clksel driver rather than using the existing component clock drivers and child nodes. And before the devicetree files can be updated, we need to update the TI clock drivers to get the IO address from the parent clksel node. Cc: Tero Kristo Signed-off-by: Tony Lindgren Signed-off-by: Rob Herring Link: https://lore.kernel.org/r/20220203073929.59296-1-tony@atomide.com --- .../bindings/clock/ti/ti,clksel.yaml | 51 +++++++++++++++++++ 1 file changed, 51 insertions(+) create mode 100644 Documentation/devicetree/bindings/clock/ti/ti,clksel.yaml diff --git a/Documentation/devicetree/bindings/clock/ti/ti,clksel.yaml b/Documentation/devicetree/bindings/clock/ti/ti,clksel.yaml new file mode 100644 index 000000000000..c56f911fff47 --- /dev/null +++ b/Documentation/devicetree/bindings/clock/ti/ti,clksel.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/ti/ti,clksel.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Binding for TI clksel clock + +maintainers: + - Tony Lindgren + +description: | + The TI CLKSEL clocks consist of consist of input clock mux bits, and in some + cases also has divider, multiplier and gate bits. + +properties: + compatible: + const: ti,clksel + + reg: + maxItems: 1 + description: The CLKSEL register range + + '#address-cells': + enum: [ 0, 1, 2 ] + + '#size-cells': + enum: [ 0, 1, 2 ] + + ranges: true + + "#clock-cells": + const: 2 + description: The CLKSEL register and bit offset + +required: + - compatible + - reg + - "#clock-cells" + +additionalProperties: + type: object + +examples: + - | + clksel_gfx_fclk: clock@52c { + compatible = "ti,clksel"; + reg = <0x25c 0x4>; + #clock-cells = <2>; + }; +... From e87d05d85a149fce4ea7564525efbd2e66438036 Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Tue, 8 Feb 2022 18:18:16 +0100 Subject: [PATCH 086/370] dt-bindings: phy: samsung,exynos-hdmi-phy: convert to dtschema Convert the Exynos HDMI PHY bindings to DT schema format and put them next to other PHYs. Signed-off-by: Krzysztof Kozlowski Signed-off-by: Rob Herring Link: https://lore.kernel.org/r/20220208171823.226211-4-krzysztof.kozlowski@canonical.com --- .../display/exynos/exynos_hdmiphy.txt | 15 ------- .../bindings/phy/samsung,exynos-hdmi-phy.yaml | 44 +++++++++++++++++++ 2 files changed, 44 insertions(+), 15 deletions(-) delete mode 100644 Documentation/devicetree/bindings/display/exynos/exynos_hdmiphy.txt create mode 100644 Documentation/devicetree/bindings/phy/samsung,exynos-hdmi-phy.yaml diff --git a/Documentation/devicetree/bindings/display/exynos/exynos_hdmiphy.txt b/Documentation/devicetree/bindings/display/exynos/exynos_hdmiphy.txt deleted file mode 100644 index 162f641f7639..000000000000 --- a/Documentation/devicetree/bindings/display/exynos/exynos_hdmiphy.txt +++ /dev/null @@ -1,15 +0,0 @@ -Device-Tree bindings for hdmiphy driver - -Required properties: -- compatible: value should be one of the following: - 1) "samsung,exynos5-hdmiphy" - 2) "samsung,exynos4210-hdmiphy". - 3) "samsung,exynos4212-hdmiphy". -- reg: I2C address of the hdmiphy device. - -Example: - - hdmiphy { - compatible = "samsung,exynos4210-hdmiphy"; - reg = <0x38>; - }; diff --git a/Documentation/devicetree/bindings/phy/samsung,exynos-hdmi-phy.yaml b/Documentation/devicetree/bindings/phy/samsung,exynos-hdmi-phy.yaml new file mode 100644 index 000000000000..c61574e10b2a --- /dev/null +++ b/Documentation/devicetree/bindings/phy/samsung,exynos-hdmi-phy.yaml @@ -0,0 +1,44 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/phy/samsung,exynos-hdmi-phy.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Samsung Exynos SoC HDMI PHY + +maintainers: + - Inki Dae + - Joonyoung Shim + - Seung-Woo Kim + - Kyungmin Park + - Krzysztof Kozlowski + +properties: + compatible: + oneOf: + - enum: + - samsung,exynos4210-hdmiphy + - samsung,exynos4212-hdmiphy + - const: samsung,exynos5-hdmiphy + deprecated: true + + reg: + maxItems: 1 + +required: + - compatible + - reg + +additionalProperties: false + +examples: + - | + i2c { + #address-cells = <1>; + #size-cells = <0>; + + hdmi-phy@38 { + compatible = "samsung,exynos4210-hdmiphy"; + reg = <0x38>; + }; + }; From f16fe2d3b41fe284a06fe568beaab6a6a5bf7894 Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Tue, 8 Feb 2022 18:18:17 +0100 Subject: [PATCH 087/370] dt-bindings: display: samsung,exynos5433-decon: convert to dtschema Convert the Exynos5433 DECON display controller bindings to DT schema format. The conversion includes also updates to the bindings, matching the current DTS and Linux driver: 1. Require "fifo" interrupt. 2. Add "dsd" as a last clock. 3. Document "power-domains" and "iommus" properties. Signed-off-by: Krzysztof Kozlowski Signed-off-by: Rob Herring Link: https://lore.kernel.org/r/20220208171823.226211-5-krzysztof.kozlowski@canonical.com --- .../display/exynos/exynos5433-decon.txt | 60 ------- .../samsung/samsung,exynos5433-decon.yaml | 148 ++++++++++++++++++ MAINTAINERS | 1 + 3 files changed, 149 insertions(+), 60 deletions(-) delete mode 100644 Documentation/devicetree/bindings/display/exynos/exynos5433-decon.txt create mode 100644 Documentation/devicetree/bindings/display/samsung/samsung,exynos5433-decon.yaml diff --git a/Documentation/devicetree/bindings/display/exynos/exynos5433-decon.txt b/Documentation/devicetree/bindings/display/exynos/exynos5433-decon.txt deleted file mode 100644 index 775193e1c641..000000000000 --- a/Documentation/devicetree/bindings/display/exynos/exynos5433-decon.txt +++ /dev/null @@ -1,60 +0,0 @@ -Device-Tree bindings for Samsung Exynos SoC display controller (DECON) - -DECON (Display and Enhancement Controller) is the Display Controller for the -Exynos series of SoCs which transfers the image data from a video memory -buffer to an external LCD interface. - -Required properties: -- compatible: value should be one of: - "samsung,exynos5433-decon", "samsung,exynos5433-decon-tv"; -- reg: physical base address and length of the DECON registers set. -- interrupt-names: should contain the interrupt names depending on mode of work: - video mode: "vsync", - command mode: "lcd_sys", - command mode with software trigger: "lcd_sys", "te". -- interrupts or interrupts-extended: list of interrupt specifiers corresponding - to names privided in interrupt-names, as described in - interrupt-controller/interrupts.txt -- clocks: must include clock specifiers corresponding to entries in the - clock-names property. -- clock-names: list of clock names sorted in the same order as the clocks - property. Must contain "pclk", "aclk_decon", "aclk_smmu_decon0x", - "aclk_xiu_decon0x", "pclk_smmu_decon0x", "aclk_smmu_decon1x", - "aclk_xiu_decon1x", "pclk_smmu_decon1x", clk_decon_vclk", - "sclk_decon_eclk" -- ports: contains a port which is connected to mic node. address-cells and - size-cells must 1 and 0, respectively. -- port: contains an endpoint node which is connected to the endpoint in the mic - node. The reg value muset be 0. - -Example: -SoC specific DT entry: -decon: decon@13800000 { - compatible = "samsung,exynos5433-decon"; - reg = <0x13800000 0x2104>; - clocks = <&cmu_disp CLK_ACLK_DECON>, <&cmu_disp CLK_ACLK_SMMU_DECON0X>, - <&cmu_disp CLK_ACLK_XIU_DECON0X>, - <&cmu_disp CLK_PCLK_SMMU_DECON0X>, - <&cmu_disp CLK_ACLK_SMMU_DECON1X>, - <&cmu_disp CLK_ACLK_XIU_DECON1X>, - <&cmu_disp CLK_PCLK_SMMU_DECON1X>, - <&cmu_disp CLK_SCLK_DECON_VCLK>, - <&cmu_disp CLK_SCLK_DECON_ECLK>; - clock-names = "aclk_decon", "aclk_smmu_decon0x", "aclk_xiu_decon0x", - "pclk_smmu_decon0x", "aclk_smmu_decon1x", "aclk_xiu_decon1x", - "pclk_smmu_decon1x", "sclk_decon_vclk", "sclk_decon_eclk"; - interrupt-names = "vsync", "lcd_sys"; - interrupts = <0 202 0>, <0 203 0>; - - ports { - #address-cells = <1>; - #size-cells = <0>; - - port@0 { - reg = <0>; - decon_to_mic: endpoint { - remote-endpoint = <&mic_to_decon>; - }; - }; - }; -}; diff --git a/Documentation/devicetree/bindings/display/samsung/samsung,exynos5433-decon.yaml b/Documentation/devicetree/bindings/display/samsung/samsung,exynos5433-decon.yaml new file mode 100644 index 000000000000..6f796835ea03 --- /dev/null +++ b/Documentation/devicetree/bindings/display/samsung/samsung,exynos5433-decon.yaml @@ -0,0 +1,148 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/display/samsung/samsung,exynos5433-decon.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Samsung Exynos5433 SoC Display and Enhancement Controller (DECON) + +maintainers: + - Inki Dae + - Joonyoung Shim + - Seung-Woo Kim + - Kyungmin Park + - Krzysztof Kozlowski + +description: | + DECON (Display and Enhancement Controller) is the Display Controller for the + Exynos5433 series of SoCs which transfers the image data from a video memory + buffer to an external LCD interface. + +properties: + compatible: + enum: + - samsung,exynos5433-decon + - samsung,exynos5433-decon-tv + + clocks: + minItems: 11 + maxItems: 11 + + clock-names: + items: + - const: pclk + - const: aclk_decon + - const: aclk_smmu_decon0x + - const: aclk_xiu_decon0x + - const: pclk_smmu_decon0x + - const: aclk_smmu_decon1x + - const: aclk_xiu_decon1x + - const: pclk_smmu_decon1x + - const: sclk_decon_vclk + - const: sclk_decon_eclk + - const: dsd + + interrupts: + minItems: 3 + maxItems: 4 + description: | + Interrupts depend on mode of work: + - video mode: vsync + - command mode: lcd_sys + - command mode with software trigger: lcd_sys, te + + interrupt-names: + minItems: 3 + items: + - const: fifo + - const: vsync + - const: lcd_sys + - const: te + + iommus: + minItems: 2 + maxItems: 2 + + iommu-names: + items: + - const: m0 + - const: m1 + + ports: + $ref: /schemas/graph.yaml#/properties/ports + description: + Contains a port which is connected to mic node. + + power-domains: + maxItems: 1 + + reg: + maxItems: 1 + + samsung,disp-sysreg: + $ref: /schemas/types.yaml#/definitions/phandle + description: + Phandle to DISP system controller interface. + +required: + - compatible + - clocks + - clock-names + - interrupts + - interrupt-names + - ports + - reg + +additionalProperties: false + +examples: + - | + #include + #include + + display-controller@13800000 { + compatible = "samsung,exynos5433-decon"; + reg = <0x13800000 0x2104>; + clocks = <&cmu_disp CLK_PCLK_DECON>, + <&cmu_disp CLK_ACLK_DECON>, + <&cmu_disp CLK_ACLK_SMMU_DECON0X>, + <&cmu_disp CLK_ACLK_XIU_DECON0X>, + <&cmu_disp CLK_PCLK_SMMU_DECON0X>, + <&cmu_disp CLK_ACLK_SMMU_DECON1X>, + <&cmu_disp CLK_ACLK_XIU_DECON1X>, + <&cmu_disp CLK_PCLK_SMMU_DECON1X>, + <&cmu_disp CLK_SCLK_DECON_VCLK>, + <&cmu_disp CLK_SCLK_DECON_ECLK>, + <&cmu_disp CLK_SCLK_DSD>; + clock-names = "pclk", + "aclk_decon", + "aclk_smmu_decon0x", + "aclk_xiu_decon0x", + "pclk_smmu_decon0x", + "aclk_smmu_decon1x", + "aclk_xiu_decon1x", + "pclk_smmu_decon1x", + "sclk_decon_vclk", + "sclk_decon_eclk", + "dsd"; + power-domains = <&pd_disp>; + interrupt-names = "fifo", "vsync", "lcd_sys"; + interrupts = , + , + ; + samsung,disp-sysreg = <&syscon_disp>; + iommus = <&sysmmu_decon0x>, <&sysmmu_decon1x>; + iommu-names = "m0", "m1"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + decon_to_mic: endpoint { + remote-endpoint = <&mic_to_decon>; + }; + }; + }; + }; diff --git a/MAINTAINERS b/MAINTAINERS index e8a05c7aca40..f1f083955329 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -6396,6 +6396,7 @@ L: dri-devel@lists.freedesktop.org S: Supported T: git git://git.kernel.org/pub/scm/linux/kernel/git/daeinki/drm-exynos.git F: Documentation/devicetree/bindings/display/exynos/ +F: Documentation/devicetree/bindings/display/samsung/ F: drivers/gpu/drm/exynos/ F: include/uapi/drm/exynos_drm.h From 5c45a11b618eb58993930e69da9153e7ce5cd630 Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Tue, 8 Feb 2022 18:18:18 +0100 Subject: [PATCH 088/370] dt-bindings: display: samsung,exynos7-decon: convert to dtschema Convert the Exynos7 DECON display controller bindings to DT schema format. Signed-off-by: Krzysztof Kozlowski Signed-off-by: Rob Herring Link: https://lore.kernel.org/r/20220208171823.226211-6-krzysztof.kozlowski@canonical.com --- .../bindings/display/exynos/exynos7-decon.txt | 65 ---------- .../samsung/samsung,exynos7-decon.yaml | 120 ++++++++++++++++++ 2 files changed, 120 insertions(+), 65 deletions(-) delete mode 100644 Documentation/devicetree/bindings/display/exynos/exynos7-decon.txt create mode 100644 Documentation/devicetree/bindings/display/samsung/samsung,exynos7-decon.yaml diff --git a/Documentation/devicetree/bindings/display/exynos/exynos7-decon.txt b/Documentation/devicetree/bindings/display/exynos/exynos7-decon.txt deleted file mode 100644 index 53912c99ec38..000000000000 --- a/Documentation/devicetree/bindings/display/exynos/exynos7-decon.txt +++ /dev/null @@ -1,65 +0,0 @@ -Device-Tree bindings for Samsung Exynos7 SoC display controller (DECON) - -DECON (Display and Enhancement Controller) is the Display Controller for the -Exynos7 series of SoCs which transfers the image data from a video memory -buffer to an external LCD interface. - -Required properties: -- compatible: value should be "samsung,exynos7-decon"; - -- reg: physical base address and length of the DECON registers set. - -- interrupts: should contain a list of all DECON IP block interrupts in the - order: FIFO Level, VSYNC, LCD_SYSTEM. The interrupt specifier - format depends on the interrupt controller used. - -- interrupt-names: should contain the interrupt names: "fifo", "vsync", - "lcd_sys", in the same order as they were listed in the interrupts - property. - -- pinctrl-0: pin control group to be used for this controller. - -- pinctrl-names: must contain a "default" entry. - -- clocks: must include clock specifiers corresponding to entries in the - clock-names property. - -- clock-names: list of clock names sorted in the same order as the clocks - property. Must contain "pclk_decon0", "aclk_decon0", - "decon0_eclk", "decon0_vclk". -- i80-if-timings: timing configuration for lcd i80 interface support. - -Optional Properties: -- power-domains: a phandle to DECON power domain node. -- display-timings: timing settings for DECON, as described in document [1]. - Can be used in case timings cannot be provided otherwise - or to override timings provided by the panel. - -[1]: Documentation/devicetree/bindings/display/panel/display-timing.txt - -Example: - -SoC specific DT entry: - - decon@13930000 { - compatible = "samsung,exynos7-decon"; - interrupt-parent = <&combiner>; - reg = <0x13930000 0x1000>; - interrupt-names = "lcd_sys", "vsync", "fifo"; - interrupts = <0 188 0>, <0 189 0>, <0 190 0>; - clocks = <&clock_disp PCLK_DECON_INT>, - <&clock_disp ACLK_DECON_INT>, - <&clock_disp SCLK_DECON_INT_ECLK>, - <&clock_disp SCLK_DECON_INT_EXTCLKPLL>; - clock-names = "pclk_decon0", "aclk_decon0", "decon0_eclk", - "decon0_vclk"; - status = "disabled"; - }; - -Board specific DT entry: - - decon@13930000 { - pinctrl-0 = <&lcd_clk &pwm1_out>; - pinctrl-names = "default"; - status = "okay"; - }; diff --git a/Documentation/devicetree/bindings/display/samsung/samsung,exynos7-decon.yaml b/Documentation/devicetree/bindings/display/samsung/samsung,exynos7-decon.yaml new file mode 100644 index 000000000000..afa137d47922 --- /dev/null +++ b/Documentation/devicetree/bindings/display/samsung/samsung,exynos7-decon.yaml @@ -0,0 +1,120 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/display/samsung/samsung,exynos7-decon.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Samsung Exynos7 SoC Display and Enhancement Controller (DECON) + +maintainers: + - Inki Dae + - Joonyoung Shim + - Seung-Woo Kim + - Kyungmin Park + - Krzysztof Kozlowski + +description: | + DECON (Display and Enhancement Controller) is the Display Controller for the + Exynos7 series of SoCs which transfers the image data from a video memory + buffer to an external LCD interface. + +properties: + compatible: + const: samsung,exynos7-decon + + clocks: + minItems: 4 + maxItems: 4 + + clock-names: + items: + - const: pclk_decon0 + - const: aclk_decon0 + - const: decon0_eclk + - const: decon0_vclk + + display-timings: + $ref: ../panel/display-timings.yaml# + + i80-if-timings: + type: object + description: timing configuration for lcd i80 interface support + properties: + cs-setup: + $ref: /schemas/types.yaml#/definitions/uint32 + description: + Clock cycles for the active period of address signal is enabled until + chip select is enabled. + default: 0 + + wr-active: + $ref: /schemas/types.yaml#/definitions/uint32 + description: + Clock cycles for the active period of CS is enabled. + default: 1 + + wr-hold: + $ref: /schemas/types.yaml#/definitions/uint32 + description: + Clock cycles for the active period of CS is disabled until write + signal is disabled. + default: 0 + + wr-setup: + $ref: /schemas/types.yaml#/definitions/uint32 + description: + Clock cycles for the active period of CS signal is enabled until + write signal is enabled. + default: 0 + + interrupts: + items: + - description: FIFO level + - description: VSYNC + - description: LCD system + + interrupt-names: + items: + - const: fifo + - const: vsync + - const: lcd_sys + + power-domains: + maxItems: 1 + + reg: + maxItems: 1 + +required: + - compatible + - clocks + - clock-names + - interrupts + - interrupt-names + - reg + +additionalProperties: false + +examples: + - | + #include + #include + + display-controller@13930000 { + compatible = "samsung,exynos7-decon"; + reg = <0x13930000 0x1000>; + interrupt-names = "fifo", "vsync", "lcd_sys"; + interrupts = , + , + ; + clocks = <&clock_disp 100>, /* PCLK_DECON_INT */ + <&clock_disp 101>, /* ACLK_DECON_INT */ + <&clock_disp 102>, /* SCLK_DECON_INT_ECLK */ + <&clock_disp 103>; /* SCLK_DECON_INT_EXTCLKPLL */ + clock-names = "pclk_decon0", + "aclk_decon0", + "decon0_eclk", + "decon0_vclk"; + pinctrl-0 = <&lcd_clk &pwm1_out>; + pinctrl-names = "default"; + }; From 6b15415e0303ad9647c9b882d2ebd18142504cbd Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Tue, 8 Feb 2022 18:18:19 +0100 Subject: [PATCH 089/370] dt-bindings: display: samsung,exynos-hdmi-ddc: convert to dtschema Convert the Exynos HDMI DDC bindings to DT schema format. Signed-off-by: Krzysztof Kozlowski Signed-off-by: Rob Herring Link: https://lore.kernel.org/r/20220208171823.226211-7-krzysztof.kozlowski@canonical.com --- .../display/exynos/exynos_hdmiddc.txt | 15 ------- .../samsung/samsung,exynos-hdmi-ddc.yaml | 42 +++++++++++++++++++ 2 files changed, 42 insertions(+), 15 deletions(-) delete mode 100644 Documentation/devicetree/bindings/display/exynos/exynos_hdmiddc.txt create mode 100644 Documentation/devicetree/bindings/display/samsung/samsung,exynos-hdmi-ddc.yaml diff --git a/Documentation/devicetree/bindings/display/exynos/exynos_hdmiddc.txt b/Documentation/devicetree/bindings/display/exynos/exynos_hdmiddc.txt deleted file mode 100644 index 41eee971562b..000000000000 --- a/Documentation/devicetree/bindings/display/exynos/exynos_hdmiddc.txt +++ /dev/null @@ -1,15 +0,0 @@ -Device-Tree bindings for hdmiddc driver - -Required properties: -- compatible: value should be one of the following - 1) "samsung,exynos5-hdmiddc" - 2) "samsung,exynos4210-hdmiddc" - -- reg: I2C address of the hdmiddc device. - -Example: - - hdmiddc { - compatible = "samsung,exynos4210-hdmiddc"; - reg = <0x50>; - }; diff --git a/Documentation/devicetree/bindings/display/samsung/samsung,exynos-hdmi-ddc.yaml b/Documentation/devicetree/bindings/display/samsung/samsung,exynos-hdmi-ddc.yaml new file mode 100644 index 000000000000..f998a3a5b71f --- /dev/null +++ b/Documentation/devicetree/bindings/display/samsung/samsung,exynos-hdmi-ddc.yaml @@ -0,0 +1,42 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/display/samsung/samsung,exynos-hdmi-ddc.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Samsung Exynos SoC HDMI DDC + +maintainers: + - Inki Dae + - Joonyoung Shim + - Seung-Woo Kim + - Kyungmin Park + - Krzysztof Kozlowski + +properties: + compatible: + oneOf: + - const: samsung,exynos4210-hdmiddc + - const: samsung,exynos5-hdmiddc + deprecated: true + + reg: + maxItems: 1 + +required: + - compatible + - reg + +additionalProperties: false + +examples: + - | + i2c { + #address-cells = <1>; + #size-cells = <0>; + + ddc@50 { + compatible = "samsung,exynos4210-hdmiddc"; + reg = <0x50>; + }; + }; From 68e89bb36d583ab06f2e21341dd99e57a88c7e81 Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Tue, 8 Feb 2022 18:18:20 +0100 Subject: [PATCH 090/370] dt-bindings: display: samsung,exynos-mixer: convert to dtschema Convert the Exynos Mixer bindings to DT schema format. The conversion includes also updates to the bindings, matching the current DTS and Linux driver: 1. Add clocks required on Exynos4210 and Exynos4212 types of Mixer. 2. Add second memory range on Exynos4210 and Exynos4212. 3. Add interconnects, iommus and power-domains. Signed-off-by: Krzysztof Kozlowski Signed-off-by: Rob Herring Link: https://lore.kernel.org/r/20220208171823.226211-8-krzysztof.kozlowski@canonical.com --- .../bindings/display/exynos/exynos_mixer.txt | 26 ---- .../display/samsung/samsung,exynos-mixer.yaml | 143 ++++++++++++++++++ 2 files changed, 143 insertions(+), 26 deletions(-) delete mode 100644 Documentation/devicetree/bindings/display/exynos/exynos_mixer.txt create mode 100644 Documentation/devicetree/bindings/display/samsung/samsung,exynos-mixer.yaml diff --git a/Documentation/devicetree/bindings/display/exynos/exynos_mixer.txt b/Documentation/devicetree/bindings/display/exynos/exynos_mixer.txt deleted file mode 100644 index 3e38128f866b..000000000000 --- a/Documentation/devicetree/bindings/display/exynos/exynos_mixer.txt +++ /dev/null @@ -1,26 +0,0 @@ -Device-Tree bindings for mixer driver - -Required properties: -- compatible: value should be one of the following: - 1) "samsung,exynos5-mixer" - 2) "samsung,exynos4210-mixer" - 3) "samsung,exynos4212-mixer" - 4) "samsung,exynos5250-mixer" - 5) "samsung,exynos5420-mixer" - -- reg: physical base address of the mixer and length of memory mapped - region. -- interrupts: interrupt number to the cpu. -- clocks: list of clock IDs from SoC clock driver. - a) mixer: Gate of Mixer IP bus clock. - b) sclk_hdmi: HDMI Special clock, one of the two possible inputs of - mixer mux. - c) hdmi: Gate of HDMI IP bus clock, needed together with sclk_hdmi. - -Example: - - mixer { - compatible = "samsung,exynos5250-mixer"; - reg = <0x14450000 0x10000>; - interrupts = <0 94 0>; - }; diff --git a/Documentation/devicetree/bindings/display/samsung/samsung,exynos-mixer.yaml b/Documentation/devicetree/bindings/display/samsung/samsung,exynos-mixer.yaml new file mode 100644 index 000000000000..ba40284ac66f --- /dev/null +++ b/Documentation/devicetree/bindings/display/samsung/samsung,exynos-mixer.yaml @@ -0,0 +1,143 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/display/samsung/samsung,exynos-mixer.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Samsung Exynos SoC Mixer + +maintainers: + - Inki Dae + - Joonyoung Shim + - Seung-Woo Kim + - Kyungmin Park + - Krzysztof Kozlowski + +description: + Samsung Exynos SoC Mixer is responsible for mixing and blending multiple data + inputs before passing it to an output device. The output is passed to HDMI. + +properties: + compatible: + oneOf: + - enum: + - samsung,exynos4210-mixer + - samsung,exynos4212-mixer + - samsung,exynos5250-mixer + - samsung,exynos5420-mixer + - const: samsung,exynos5-mixer + deprecated: true + + clocks: + minItems: 3 + items: + - description: Gate of Mixer IP bus clock. + - description: Gate of HDMI IP bus clock, needed together with sclk_hdmi. + - description: HDMI Special clock, one of the two possible inputs of + mixer mux. + - description: Video Processor clock. + - description: Mixer mux clock. + - description: Mixer Special clock. + + clock-names: + minItems: 3 + items: + - const: mixer + - const: hdmi + - const: sclk_hdmi + - const: vp + - const: mout_mixer + - const: sclk_mixer + + interconnects: + maxItems: 1 + + interrupts: + maxItems: 1 + + iommus: + maxItems: 1 + + power-domains: + maxItems: 1 + + reg: + minItems: 1 + items: + - description: Mixer memory region. + - description: Video Processor memory region. + +required: + - compatible + - clocks + - clock-names + - interrupts + - reg + +allOf: + - if: + properties: + compatible: + contains: + const: samsung,exynos4210-mixer + - samsung,exynos4212-mixer + then: + properties: + clocks: + minItems: 6 + maxItems: 6 + regs: + minItems: 2 + maxItems: 2 + + - if: + properties: + compatible: + contains: + const: samsung,exynos4212-mixer + then: + properties: + clocks: + minItems: 4 + maxItems: 4 + regs: + minItems: 2 + maxItems: 2 + + - if: + properties: + compatible: + contains: + enum: + - samsung,exynos5-mixer + - samsung,exynos5250-mixer + - samsung,exynos5420-mixer + then: + properties: + clocks: + minItems: 3 + maxItems: 3 + regs: + minItems: 1 + maxItems: 1 + +additionalProperties: false + +examples: + - | + #include + #include + + mixer@14450000 { + compatible = "samsung,exynos5250-mixer"; + reg = <0x14450000 0x10000>; + interrupts = ; + clocks = <&clock CLK_MIXER>, + <&clock CLK_HDMI>, + <&clock CLK_SCLK_HDMI>; + clock-names = "mixer", + "hdmi", + "sclk_hdmi"; + iommus = <&sysmmu_tv>; + power-domains = <&pd_disp1>; + }; From a5032991e108f88ac8a69452b24fa9c8b4621352 Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Tue, 8 Feb 2022 18:18:21 +0100 Subject: [PATCH 091/370] dt-bindings: display: samsung,exynos-hdmi: convert to dtschema Convert the Exynos HDMI bindings to DT schema format. The conversion includes also updates to the bindings, matching the current DTS and Linux driver: 1. Add required properties: VDD supplies, power-domains. 2. Add optional properties: HDMI-EN supply, ports. Signed-off-by: Krzysztof Kozlowski Signed-off-by: Rob Herring Link: https://lore.kernel.org/r/20220208171823.226211-9-krzysztof.kozlowski@canonical.com --- .../bindings/display/exynos/exynos_hdmi.txt | 64 ----- .../display/samsung/samsung,exynos-hdmi.yaml | 227 ++++++++++++++++++ 2 files changed, 227 insertions(+), 64 deletions(-) delete mode 100644 Documentation/devicetree/bindings/display/exynos/exynos_hdmi.txt create mode 100644 Documentation/devicetree/bindings/display/samsung/samsung,exynos-hdmi.yaml diff --git a/Documentation/devicetree/bindings/display/exynos/exynos_hdmi.txt b/Documentation/devicetree/bindings/display/exynos/exynos_hdmi.txt deleted file mode 100644 index 58b12e25bbb1..000000000000 --- a/Documentation/devicetree/bindings/display/exynos/exynos_hdmi.txt +++ /dev/null @@ -1,64 +0,0 @@ -Device-Tree bindings for drm hdmi driver - -Required properties: -- compatible: value should be one among the following: - 1) "samsung,exynos4210-hdmi" - 2) "samsung,exynos4212-hdmi" - 3) "samsung,exynos5420-hdmi" - 4) "samsung,exynos5433-hdmi" -- reg: physical base address of the hdmi and length of memory mapped - region. -- interrupts: interrupt number to the cpu. -- hpd-gpios: following information about the hotplug gpio pin. - a) phandle of the gpio controller node. - b) pin number within the gpio controller. - c) optional flags and pull up/down. -- ddc: phandle to the hdmi ddc node -- phy: phandle to the hdmi phy node -- samsung,syscon-phandle: phandle for system controller node for PMU. -- #sound-dai-cells: should be 0. - -Required properties for Exynos 4210, 4212, 5420 and 5433: -- clocks: list of clock IDs from SoC clock driver. - a) hdmi: Gate of HDMI IP bus clock. - b) sclk_hdmi: Gate of HDMI special clock. - c) sclk_pixel: Pixel special clock, one of the two possible inputs of - HDMI clock mux. - d) sclk_hdmiphy: HDMI PHY clock output, one of two possible inputs of - HDMI clock mux. - e) mout_hdmi: It is required by the driver to switch between the 2 - parents i.e. sclk_pixel and sclk_hdmiphy. If hdmiphy is stable - after configuration, parent is set to sclk_hdmiphy else - sclk_pixel. -- clock-names: aliases as per driver requirements for above clock IDs: - "hdmi", "sclk_hdmi", "sclk_pixel", "sclk_hdmiphy" and "mout_hdmi". - -Required properties for Exynos 5433: -- clocks: list of clock specifiers according to common clock bindings. - a) hdmi_pclk: Gate of HDMI IP APB bus. - b) hdmi_i_pclk: Gate of HDMI-PHY IP APB bus. - d) i_tmds_clk: Gate of HDMI TMDS clock. - e) i_pixel_clk: Gate of HDMI pixel clock. - f) i_spdif_clk: Gate of HDMI SPDIF clock. - g) oscclk: Oscillator clock, used as parent of following *_user clocks - in case HDMI-PHY is not operational. - h) tmds_clko: TMDS clock generated by HDMI-PHY. - i) tmds_clko_user: MUX used to switch between oscclk and tmds_clko, - respectively if HDMI-PHY is off and operational. - j) pixel_clko: Pixel clock generated by HDMI-PHY. - k) pixel_clko_user: MUX used to switch between oscclk and pixel_clko, - respectively if HDMI-PHY is off and operational. -- clock-names: aliases for above clock specfiers. -- samsung,sysreg: handle to syscon used to control the system registers. - -Example: - - hdmi { - compatible = "samsung,exynos4212-hdmi"; - reg = <0x14530000 0x100000>; - interrupts = <0 95 0>; - hpd-gpios = <&gpx3 7 1>; - ddc = <&hdmi_ddc_node>; - phy = <&hdmi_phy_node>; - samsung,syscon-phandle = <&pmu_system_controller>; - }; diff --git a/Documentation/devicetree/bindings/display/samsung/samsung,exynos-hdmi.yaml b/Documentation/devicetree/bindings/display/samsung/samsung,exynos-hdmi.yaml new file mode 100644 index 000000000000..cb8e735ce3bd --- /dev/null +++ b/Documentation/devicetree/bindings/display/samsung/samsung,exynos-hdmi.yaml @@ -0,0 +1,227 @@ +# SPDX-License-Identifier: GPL-2.0-only +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/display/samsung/samsung,exynos-hdmi.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Samsung Exynos SoC HDMI + +maintainers: + - Inki Dae + - Joonyoung Shim + - Seung-Woo Kim + - Kyungmin Park + - Krzysztof Kozlowski + +properties: + compatible: + enum: + - samsung,exynos4210-hdmi + - samsung,exynos4212-hdmi + - samsung,exynos5420-hdmi + - samsung,exynos5433-hdmi + + clocks: + minItems: 5 + maxItems: 10 + + clock-names: + minItems: 5 + maxItems: 10 + + ddc: + $ref: /schemas/types.yaml#/definitions/phandle + description: + Phandle to the HDMI DDC node. + + hdmi-en-supply: + description: + Provides voltage source for DCC lines available on HDMI connector. When + there is no power provided for DDC epprom, some TV-sets do not pulls up + HPD (hot plug detect) line, what causes HDMI block to stay turned off. + When provided, the regulator allows TV-set correctly signal HPD event. + + hpd-gpios: + maxItems: 1 + description: + A GPIO line connected to HPD + + interrupts: + maxItems: 1 + + phy: + $ref: /schemas/types.yaml#/definitions/phandle + description: Phandle to the HDMI PHY node. + + ports: + $ref: /schemas/graph.yaml#/properties/ports + description: + Contains a port which is connected to mic node. + + power-domains: + maxItems: 1 + + reg: + maxItems: 1 + + samsung,syscon-phandle: + $ref: /schemas/types.yaml#/definitions/phandle + description: + Phandle to the PMU system controller node. + + samsung,sysreg-phandle: + $ref: /schemas/types.yaml#/definitions/phandle + description: + Phandle to DISP system controller interface. + + '#sound-dai-cells': + const: 0 + + vdd-supply: + description: + VDD 1.0V HDMI TX. + + vdd_osc-supply: + description: + VDD 1.8V HDMI OSC. + + vdd_pll-supply: + description: + VDD 1.0V HDMI PLL. + +required: + - compatible + - clocks + - clock-names + - ddc + - hpd-gpios + - interrupts + - phy + - reg + - samsung,syscon-phandle + - '#sound-dai-cells' + - vdd-supply + - vdd_osc-supply + - vdd_pll-supply + +allOf: + - if: + properties: + compatible: + contains: + const: samsung,exynos5433-hdmi + then: + properties: + clocks: + items: + - description: Gate of HDMI IP APB bus. + - description: Gate of HDMI-PHY IP APB bus. + - description: Gate of HDMI TMDS clock. + - description: Gate of HDMI pixel clock. + - description: TMDS clock generated by HDMI-PHY. + - description: MUX used to switch between oscclk and tmds_clko, + respectively if HDMI-PHY is off and operational. + - description: Pixel clock generated by HDMI-PHY. + - description: MUX used to switch between oscclk and pixel_clko, + respectively if HDMI-PHY is off and operational. + - description: Oscillator clock, used as parent of following *_user + clocks in case HDMI-PHY is not operational. + - description: Gate of HDMI SPDIF clock. + clock-names: + items: + - const: hdmi_pclk + - const: hdmi_i_pclk + - const: i_tmds_clk + - const: i_pixel_clk + - const: tmds_clko + - const: tmds_clko_user + - const: pixel_clko + - const: pixel_clko_user + - const: oscclk + - const: i_spdif_clk + required: + - samsung,sysreg-phandle + else: + properties: + clocks: + items: + - description: Gate of HDMI IP bus clock. + - description: Gate of HDMI special clock. + - description: Pixel special clock, one of the two possible inputs + of HDMI clock mux. + - description: HDMI PHY clock output, one of two possible inputs of + HDMI clock mux. + - description: It is required by the driver to switch between the 2 + parents i.e. sclk_pixel and sclk_hdmiphy. If hdmiphy is stable + after configuration, parent is set to sclk_hdmiphy else + sclk_pixel. + clock-names: + items: + - const: hdmi + - const: sclk_hdmi + - const: sclk_pixel + - const: sclk_hdmiphy + - const: mout_hdmi + +additionalProperties: false + +examples: + - | + #include + #include + #include + + hdmi@13970000 { + compatible = "samsung,exynos5433-hdmi"; + reg = <0x13970000 0x70000>; + interrupts = ; + clocks = <&cmu_disp CLK_PCLK_HDMI>, + <&cmu_disp CLK_PCLK_HDMIPHY>, + <&cmu_disp CLK_PHYCLK_HDMIPHY_TMDS_CLKO>, + <&cmu_disp CLK_PHYCLK_HDMI_PIXEL>, + <&cmu_disp CLK_PHYCLK_HDMIPHY_TMDS_CLKO_PHY>, + <&cmu_disp CLK_MOUT_PHYCLK_HDMIPHY_TMDS_CLKO_USER>, + <&cmu_disp CLK_PHYCLK_HDMIPHY_PIXEL_CLKO_PHY>, + <&cmu_disp CLK_MOUT_PHYCLK_HDMIPHY_PIXEL_CLKO_USER>, + <&xxti>, + <&cmu_disp CLK_SCLK_HDMI_SPDIF>; + clock-names = "hdmi_pclk", + "hdmi_i_pclk", + "i_tmds_clk", + "i_pixel_clk", + "tmds_clko", + "tmds_clko_user", + "pixel_clko", + "pixel_clko_user", + "oscclk", + "i_spdif_clk"; + phy = <&hdmiphy>; + ddc = <&hsi2c_11>; + samsung,syscon-phandle = <&pmu_system_controller>; + samsung,sysreg-phandle = <&syscon_disp>; + #sound-dai-cells = <0>; + + hpd-gpios = <&gpa3 0 GPIO_ACTIVE_HIGH>; + vdd-supply = <&ldo6_reg>; + vdd_osc-supply = <&ldo7_reg>; + vdd_pll-supply = <&ldo6_reg>; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + hdmi_to_tv: endpoint { + remote-endpoint = <&tv_to_hdmi>; + }; + }; + + port@1 { + reg = <1>; + hdmi_to_mhl: endpoint { + remote-endpoint = <&mhl_to_hdmi>; + }; + }; + }; + }; From 4c5e180b83edbd1199e948050fe8f5fc17fc26d5 Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Tue, 8 Feb 2022 18:18:22 +0100 Subject: [PATCH 092/370] dt-bindings: display: samsung,exynos5433-mic: convert to dtschema Convert the Exynos5433 MIC bindings to DT schema format. The conversion includes also updates to the bindings, matching the current DTS and Linux driver: adding optional power-domains. Signed-off-by: Krzysztof Kozlowski Signed-off-by: Rob Herring Link: https://lore.kernel.org/r/20220208171823.226211-10-krzysztof.kozlowski@canonical.com --- .../bindings/display/exynos/exynos-mic.txt | 51 ---------- .../samsung/samsung,exynos5433-mic.yaml | 95 +++++++++++++++++++ 2 files changed, 95 insertions(+), 51 deletions(-) delete mode 100644 Documentation/devicetree/bindings/display/exynos/exynos-mic.txt create mode 100644 Documentation/devicetree/bindings/display/samsung/samsung,exynos5433-mic.yaml diff --git a/Documentation/devicetree/bindings/display/exynos/exynos-mic.txt b/Documentation/devicetree/bindings/display/exynos/exynos-mic.txt deleted file mode 100644 index 0fba2ee6440a..000000000000 --- a/Documentation/devicetree/bindings/display/exynos/exynos-mic.txt +++ /dev/null @@ -1,51 +0,0 @@ -Device-Tree bindings for Samsung Exynos SoC mobile image compressor (MIC) - -MIC (mobile image compressor) resides between decon and mipi dsi. Mipi dsi is -not capable to transfer high resoltuion frame data as decon can send. MIC -solves this problem by compressing the frame data by 1/2 before it is -transferred through mipi dsi. The compressed frame data must be uncompressed in -the panel PCB. - -Required properties: -- compatible: value should be "samsung,exynos5433-mic". -- reg: physical base address and length of the MIC registers set and system - register of mic. -- clocks: must include clock specifiers corresponding to entries in the - clock-names property. -- clock-names: list of clock names sorted in the same order as the clocks - property. Must contain "pclk_mic0", "sclk_rgb_vclk_to_mic0". -- samsung,disp-syscon: the reference node for syscon for DISP block. -- ports: contains a port which is connected to decon node and dsi node. - address-cells and size-cells must 1 and 0, respectively. -- port: contains an endpoint node which is connected to the endpoint in the - decon node or dsi node. The reg value must be 0 and 1 respectively. - -Example: -SoC specific DT entry: -mic: mic@13930000 { - compatible = "samsung,exynos5433-mic"; - reg = <0x13930000 0x48>; - clocks = <&cmu_disp CLK_PCLK_MIC0>, - <&cmu_disp CLK_SCLK_RGB_VCLK_TO_MIC0>; - clock-names = "pclk_mic0", "sclk_rgb_vclk_to_mic0"; - samsung,disp-syscon = <&syscon_disp>; - - ports { - #address-cells = <1>; - #size-cells = <0>; - - port@0 { - reg = <0>; - mic_to_decon: endpoint { - remote-endpoint = <&decon_to_mic>; - }; - }; - - port@1 { - reg = <1>; - mic_to_dsi: endpoint { - remote-endpoint = <&dsi_to_mic>; - }; - }; - }; -}; diff --git a/Documentation/devicetree/bindings/display/samsung/samsung,exynos5433-mic.yaml b/Documentation/devicetree/bindings/display/samsung/samsung,exynos5433-mic.yaml new file mode 100644 index 000000000000..01fccb138ebd --- /dev/null +++ b/Documentation/devicetree/bindings/display/samsung/samsung,exynos5433-mic.yaml @@ -0,0 +1,95 @@ +# SPDX-License-Identifier: GPL-2.0-only +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/display/samsung/samsung,exynos5433-mic.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Samsung Exynos5433 SoC Mobile Image Compressor (MIC) + +maintainers: + - Inki Dae + - Joonyoung Shim + - Seung-Woo Kim + - Kyungmin Park + - Krzysztof Kozlowski + +description: | + MIC (Mobile Image Compressor) resides between DECON and MIPI DSI. MIPI DSI is + not capable of transferring high resoltuion frame data as DECON can send. MIC + solves this problem by compressing the frame data by 1/2 before it is + transferred through MIPI DSI. The compressed frame data must be uncompressed + in the panel PCB. + +properties: + compatible: + const: samsung,exynos5433-mic + + clocks: + minItems: 2 + maxItems: 2 + + clock-names: + items: + - const: pclk_mic0 + - const: sclk_rgb_vclk_to_mic0 + + ports: + $ref: /schemas/graph.yaml#/properties/ports + description: + Contains a port which is connected to mic node. + + power-domains: + maxItems: 1 + + reg: + maxItems: 1 + + samsung,disp-syscon: + $ref: /schemas/types.yaml#/definitions/phandle + description: + Phandle to DISP system controller interface. + +required: + - compatible + - clocks + - clock-names + - ports + - reg + - samsung,disp-syscon + +additionalProperties: false + +examples: + - | + #include + #include + + image-processor@13930000 { + compatible = "samsung,exynos5433-mic"; + reg = <0x13930000 0x48>; + clocks = <&cmu_disp CLK_PCLK_MIC0>, + <&cmu_disp CLK_SCLK_RGB_VCLK_TO_MIC0>; + clock-names = "pclk_mic0", + "sclk_rgb_vclk_to_mic0"; + power-domains = <&pd_disp>; + samsung,disp-syscon = <&syscon_disp>; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + mic_to_decon: endpoint { + remote-endpoint = <&decon_to_mic>; + }; + }; + + port@1 { + reg = <1>; + mic_to_dsi: endpoint { + remote-endpoint = <&dsi_to_mic>; + }; + }; + }; + }; From e4fc20d74a1809067304556bc2ba860683bbf4a6 Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Tue, 8 Feb 2022 18:18:23 +0100 Subject: [PATCH 093/370] dt-bindings: display: samsung,exynos-fimd: convert to dtschema Convert the S3C/S5P/Exynos FIMD bindings to DT schema format. The conversion includes also updates to the bindings, matching the current DTS and Linux driver: adding optional iommus and power-domains. Signed-off-by: Krzysztof Kozlowski Signed-off-by: Rob Herring Link: https://lore.kernel.org/r/20220208171823.226211-11-krzysztof.kozlowski@canonical.com --- .../bindings/display/exynos/samsung-fimd.txt | 107 ---------- .../display/samsung/samsung,fimd.yaml | 198 ++++++++++++++++++ 2 files changed, 198 insertions(+), 107 deletions(-) delete mode 100644 Documentation/devicetree/bindings/display/exynos/samsung-fimd.txt create mode 100644 Documentation/devicetree/bindings/display/samsung/samsung,fimd.yaml diff --git a/Documentation/devicetree/bindings/display/exynos/samsung-fimd.txt b/Documentation/devicetree/bindings/display/exynos/samsung-fimd.txt deleted file mode 100644 index b3096421d42b..000000000000 --- a/Documentation/devicetree/bindings/display/exynos/samsung-fimd.txt +++ /dev/null @@ -1,107 +0,0 @@ -Device-Tree bindings for Samsung SoC display controller (FIMD) - -FIMD (Fully Interactive Mobile Display) is the Display Controller for the -Samsung series of SoCs which transfers the image data from a video memory -buffer to an external LCD interface. - -Required properties: -- compatible: value should be one of the following - "samsung,s3c2443-fimd"; /* for S3C24XX SoCs */ - "samsung,s3c6400-fimd"; /* for S3C64XX SoCs */ - "samsung,s5pv210-fimd"; /* for S5PV210 SoC */ - "samsung,exynos3250-fimd"; /* for Exynos3250/3472 SoCs */ - "samsung,exynos4210-fimd"; /* for Exynos4 SoCs */ - "samsung,exynos5250-fimd"; /* for Exynos5250 SoCs */ - "samsung,exynos5420-fimd"; /* for Exynos5420/5422/5800 SoCs */ - -- reg: physical base address and length of the FIMD registers set. - -- interrupts: should contain a list of all FIMD IP block interrupts in the - order: FIFO Level, VSYNC, LCD_SYSTEM. The interrupt specifier - format depends on the interrupt controller used. - -- interrupt-names: should contain the interrupt names: "fifo", "vsync", - "lcd_sys", in the same order as they were listed in the interrupts - property. - -- pinctrl-0: pin control group to be used for this controller. - -- pinctrl-names: must contain a "default" entry. - -- clocks: must include clock specifiers corresponding to entries in the - clock-names property. - -- clock-names: list of clock names sorted in the same order as the clocks - property. Must contain "sclk_fimd" and "fimd". - -Optional Properties: -- power-domains: a phandle to FIMD power domain node. -- samsung,invert-vden: video enable signal is inverted -- samsung,invert-vclk: video clock signal is inverted -- display-timings: timing settings for FIMD, as described in document [1]. - Can be used in case timings cannot be provided otherwise - or to override timings provided by the panel. -- samsung,sysreg: handle to syscon used to control the system registers -- i80-if-timings: timing configuration for lcd i80 interface support. - - cs-setup: clock cycles for the active period of address signal is enabled - until chip select is enabled. - If not specified, the default value(0) will be used. - - wr-setup: clock cycles for the active period of CS signal is enabled until - write signal is enabled. - If not specified, the default value(0) will be used. - - wr-active: clock cycles for the active period of CS is enabled. - If not specified, the default value(1) will be used. - - wr-hold: clock cycles for the active period of CS is disabled until write - signal is disabled. - If not specified, the default value(0) will be used. - - The parameters are defined as: - - VCLK(internal) __|??????|_____|??????|_____|??????|_____|??????|_____|?? - : : : : : - Address Output --:| : : : - Chip Select ???????????????|____________:____________:____________|?? - | wr-setup+1 | | wr-hold+1 | - |<---------->| |<---------->| - Write Enable ????????????????????????????|____________|??????????????? - | wr-active+1| - |<---------->| - Video Data ------------------------------ - -The device node can contain 'port' child nodes according to the bindings defined -in [2]. The following are properties specific to those nodes: -- reg: (required) port index, can be: - 0 - for CAMIF0 input, - 1 - for CAMIF1 input, - 2 - for CAMIF2 input, - 3 - for parallel output, - 4 - for write-back interface - -[1]: Documentation/devicetree/bindings/display/panel/display-timing.txt -[2]: Documentation/devicetree/bindings/media/video-interfaces.txt - -Example: - -SoC specific DT entry: - - fimd@11c00000 { - compatible = "samsung,exynos4210-fimd"; - interrupt-parent = <&combiner>; - reg = <0x11c00000 0x20000>; - interrupt-names = "fifo", "vsync", "lcd_sys"; - interrupts = <11 0>, <11 1>, <11 2>; - clocks = <&clock 140>, <&clock 283>; - clock-names = "sclk_fimd", "fimd"; - power-domains = <&pd_lcd0>; - status = "disabled"; - }; - -Board specific DT entry: - - fimd@11c00000 { - pinctrl-0 = <&lcd_clk &lcd_data24 &pwm1_out>; - pinctrl-names = "default"; - status = "okay"; - }; diff --git a/Documentation/devicetree/bindings/display/samsung/samsung,fimd.yaml b/Documentation/devicetree/bindings/display/samsung/samsung,fimd.yaml new file mode 100644 index 000000000000..9cf5f120d516 --- /dev/null +++ b/Documentation/devicetree/bindings/display/samsung/samsung,fimd.yaml @@ -0,0 +1,198 @@ +# SPDX-License-Identifier: GPL-2.0-only +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/display/samsung/samsung,fimd.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Samsung S3C/S5P/Exynos SoC Fully Interactive Mobile Display (FIMD) + +maintainers: + - Inki Dae + - Joonyoung Shim + - Seung-Woo Kim + - Kyungmin Park + - Krzysztof Kozlowski + +properties: + compatible: + enum: + - samsung,s3c2443-fimd + - samsung,s3c6400-fimd + - samsung,s5pv210-fimd + - samsung,exynos3250-fimd + - samsung,exynos4210-fimd + - samsung,exynos5250-fimd + - samsung,exynos5420-fimd + + '#address-cells': + const: 1 + + clocks: + minItems: 2 + maxItems: 2 + + clock-names: + items: + - const: sclk_fimd + - const: fimd + + display-timings: + $ref: ../panel/display-timings.yaml# + + i80-if-timings: + type: object + description: | + Timing configuration for lcd i80 interface support. + The parameters are defined as:: + VCLK(internal) __|??????|_____|??????|_____|??????|_____|??????|_____|?? + : : : : : + Address Output --:| : : : + Chip Select ???????????????|____________:____________:____________|?? + | wr-setup+1 | | wr-hold+1 | + |<---------->| |<---------->| + Write Enable ????????????????????????????|____________|??????????????? + | wr-active+1| + |<---------->| + Video Data ------------------------------ + + properties: + cs-setup: + $ref: /schemas/types.yaml#/definitions/uint32 + description: + Clock cycles for the active period of address signal is enabled until + chip select is enabled. + default: 0 + + wr-active: + $ref: /schemas/types.yaml#/definitions/uint32 + description: + Clock cycles for the active period of CS is enabled. + default: 1 + + wr-hold: + $ref: /schemas/types.yaml#/definitions/uint32 + description: + Clock cycles for the active period of CS is disabled until write + signal is disabled. + default: 0 + + wr-setup: + $ref: /schemas/types.yaml#/definitions/uint32 + description: + Clock cycles for the active period of CS signal is enabled until + write signal is enabled. + default: 0 + + iommus: + minItems: 1 + maxItems: 2 + + iommu-names: + items: + - const: m0 + - const: m1 + + interrupts: + items: + - description: FIFO level + - description: VSYNC + - description: LCD system + + interrupt-names: + items: + - const: fifo + - const: vsync + - const: lcd_sys + + power-domains: + maxItems: 1 + + reg: + maxItems: 1 + + samsung,invert-vden: + type: boolean + description: + Video enable signal is inverted. + + samsung,invert-vclk: + type: boolean + description: + Video clock signal is inverted. + + samsung,sysreg: + $ref: /schemas/types.yaml#/definitions/phandle + description: + Phandle to System Register syscon. + + '#size-cells': + const: 0 + +patternProperties: + "^port@[0-4]+$": + $ref: /schemas/graph.yaml#/properties/port + description: | + Contains ports with port with index:: + 0 - for CAMIF0 input, + 1 - for CAMIF1 input, + 2 - for CAMIF2 input, + 3 - for parallel output, + 4 - for write-back interface + +required: + - compatible + - clocks + - clock-names + - interrupts + - interrupt-names + - reg + +allOf: + - if: + properties: + compatible: + contains: + const: samsung,exynos5420-fimd + then: + properties: + iommus: + minItems: 2 + maxItems: 2 + +additionalProperties: false + +examples: + - | + #include + + fimd@11c00000 { + compatible = "samsung,exynos4210-fimd"; + interrupt-parent = <&combiner>; + reg = <0x11c00000 0x20000>; + interrupt-names = "fifo", "vsync", "lcd_sys"; + interrupts = <11 0>, <11 1>, <11 2>; + clocks = <&clock CLK_SCLK_FIMD0>, <&clock CLK_FIMD0>; + clock-names = "sclk_fimd", "fimd"; + power-domains = <&pd_lcd0>; + iommus = <&sysmmu_fimd0>; + samsung,sysreg = <&sys_reg>; + + #address-cells = <1>; + #size-cells = <0>; + + samsung,invert-vden; + samsung,invert-vclk; + + pinctrl-0 = <&lcd_clk>, <&lcd_data24>; + pinctrl-names = "default"; + + port@3 { + reg = <3>; + + fimd_dpi_ep: endpoint { + remote-endpoint = <&lcd_ep>; + }; + }; + }; From 59dfdc13ca226682f927f9c1f8ed888450a4e8b3 Mon Sep 17 00:00:00 2001 From: Dinh Nguyen Date: Fri, 28 Jan 2022 07:31:42 -0600 Subject: [PATCH 094/370] dt-bindings: net: can: fix dtbs warning Mute the warning from "make dtbs_check": Documentation/devicetree/bindings/net/can/bosch,m_can.example.dt.yaml: can@20e8000: bosch,mram-cfg: [[0, 0, 0, 32, 0, 0, 0, 1]] is too short Signed-off-by: Dinh Nguyen Signed-off-by: Rob Herring Link: https://lore.kernel.org/r/20220128133142.2135718-1-dinguyen@kernel.org --- Documentation/devicetree/bindings/net/can/bosch,m_can.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/Documentation/devicetree/bindings/net/can/bosch,m_can.yaml b/Documentation/devicetree/bindings/net/can/bosch,m_can.yaml index 401ab7cdb379..035964a8609c 100644 --- a/Documentation/devicetree/bindings/net/can/bosch,m_can.yaml +++ b/Documentation/devicetree/bindings/net/can/bosch,m_can.yaml @@ -101,6 +101,7 @@ properties: - description: Tx Buffers 0-32 elements / 0-576 words minimum: 0 maximum: 32 + minItems: 1 power-domains: description: From 3a36eb031b6fe8e134d3f706f90211331e950951 Mon Sep 17 00:00:00 2001 From: Nicolas Ferre Date: Sun, 30 Jan 2022 15:47:08 +0100 Subject: [PATCH 095/370] dt-bindings: rng: atmel,at91-trng: update maintainers entry Update according to new MAINTAINERS entry. Signed-off-by: Nicolas Ferre Acked-by: Ludovic Desroches Acked-by: Claudiu Beznea Signed-off-by: Rob Herring Link: https://lore.kernel.org/r/d84760e0b81c338e01f7856e1ce3c5b600b08f23.1643553619.git.nicolas.ferre@microchip.com --- Documentation/devicetree/bindings/rng/atmel,at91-trng.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/rng/atmel,at91-trng.yaml b/Documentation/devicetree/bindings/rng/atmel,at91-trng.yaml index c1527637eb74..3ce45456d867 100644 --- a/Documentation/devicetree/bindings/rng/atmel,at91-trng.yaml +++ b/Documentation/devicetree/bindings/rng/atmel,at91-trng.yaml @@ -9,7 +9,7 @@ title: Atmel AT91 True Random Number Generator maintainers: - Nicolas Ferre - Alexandre Belloni - - Ludovic Desroches + - Claudiu Beznea properties: compatible: From b4ba994f2622b6a261a6b30933f32893d2d78294 Mon Sep 17 00:00:00 2001 From: Quentin Schulz Date: Mon, 31 Jan 2022 17:54:39 +0100 Subject: [PATCH 096/370] dt-bindings: ltk050h3146w: replace Heiko Stuebner by myself as maintainer Heiko does not work at Theobroma Systems anymore and the boards using those panels are downstream, maintained internally by the company, so let's relieve Heiko of maintainership duties. Cc: Heiko Stuebner Cc: Quentin Schulz Signed-off-by: Quentin Schulz Acked-by: Heiko Stuebner Signed-off-by: Rob Herring Link: https://lore.kernel.org/r/20220131165439.717713-1-quentin.schulz@theobroma-systems.com --- .../devicetree/bindings/display/panel/leadtek,ltk050h3146w.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/display/panel/leadtek,ltk050h3146w.yaml b/Documentation/devicetree/bindings/display/panel/leadtek,ltk050h3146w.yaml index 3715882b63b6..3f6efbb942da 100644 --- a/Documentation/devicetree/bindings/display/panel/leadtek,ltk050h3146w.yaml +++ b/Documentation/devicetree/bindings/display/panel/leadtek,ltk050h3146w.yaml @@ -7,7 +7,7 @@ $schema: http://devicetree.org/meta-schemas/core.yaml# title: Leadtek LTK050H3146W 5.0in 720x1280 DSI panel maintainers: - - Heiko Stuebner + - Quentin Schulz allOf: - $ref: panel-common.yaml# From 70e038f89b467995708207fb57bbf46aec32dc2c Mon Sep 17 00:00:00 2001 From: Miquel Raynal Date: Thu, 16 Dec 2021 12:16:42 +0100 Subject: [PATCH 097/370] mtd: nand: mxic-ecc: Support SPI pipelined mode Introduce the support for another possible configuration: the ECC engine may work as DMA master (pipelined) and move itself the data to/from the NAND chip into the buffer, applying the necessary corrections/computations on the fly. This driver offers an ECC engine implementation that must be instatiated from a SPI controller driver. Signed-off-by: Miquel Raynal Link: https://lore.kernel.org/linux-mtd/20211216111654.238086-17-miquel.raynal@bootlin.com --- drivers/mtd/nand/ecc-mxic.c | 186 +++++++++++++++++++++++++++++- include/linux/mtd/nand-ecc-mxic.h | 49 ++++++++ 2 files changed, 234 insertions(+), 1 deletion(-) create mode 100644 include/linux/mtd/nand-ecc-mxic.h diff --git a/drivers/mtd/nand/ecc-mxic.c b/drivers/mtd/nand/ecc-mxic.c index 3e8fbe62547e..c122139255e5 100644 --- a/drivers/mtd/nand/ecc-mxic.c +++ b/drivers/mtd/nand/ecc-mxic.c @@ -16,6 +16,7 @@ #include #include #include +#include #include #include #include @@ -40,7 +41,9 @@ #define INTRPT_SIG_EN 0x0C /* Host Controller Configuration */ #define HC_CONFIG 0x10 +#define DEV2MEM 0 /* TRANS_TYP_DMA in the spec */ #define MEM2MEM BIT(4) /* TRANS_TYP_IO in the spec */ +#define MAPPING BIT(5) /* TRANS_TYP_MAPPING in the spec */ #define ECC_PACKED 0 /* LAYOUT_TYP_INTEGRATED in the spec */ #define ECC_INTERLEAVED BIT(2) /* LAYOUT_TYP_DISTRIBUTED in the spec */ #define BURST_TYP_FIXED 0 @@ -87,6 +90,7 @@ struct mxic_ecc_engine { int irq; struct completion complete; struct nand_ecc_engine external_engine; + struct nand_ecc_engine pipelined_engine; struct mutex lock; }; @@ -104,6 +108,7 @@ struct mxic_ecc_ctx { u8 *oobwithstat; struct scatterlist sg[2]; struct nand_page_io_req *req; + unsigned int pageoffs; }; static struct mxic_ecc_engine *ext_ecc_eng_to_mxic(struct nand_ecc_engine *eng) @@ -111,11 +116,19 @@ static struct mxic_ecc_engine *ext_ecc_eng_to_mxic(struct nand_ecc_engine *eng) return container_of(eng, struct mxic_ecc_engine, external_engine); } +static struct mxic_ecc_engine *pip_ecc_eng_to_mxic(struct nand_ecc_engine *eng) +{ + return container_of(eng, struct mxic_ecc_engine, pipelined_engine); +} + static struct mxic_ecc_engine *nand_to_mxic(struct nand_device *nand) { struct nand_ecc_engine *eng = nand->ecc.engine; - return ext_ecc_eng_to_mxic(eng); + if (eng->integration == NAND_ECC_ENGINE_INTEGRATION_EXTERNAL) + return ext_ecc_eng_to_mxic(eng); + else + return pip_ecc_eng_to_mxic(eng); } static int mxic_ecc_ooblayout_ecc(struct mtd_info *mtd, int section, @@ -364,6 +377,38 @@ static int mxic_ecc_init_ctx_external(struct nand_device *nand) return 0; } +static int mxic_ecc_init_ctx_pipelined(struct nand_device *nand) +{ + struct mxic_ecc_engine *mxic = nand_to_mxic(nand); + struct mxic_ecc_ctx *ctx; + struct device *dev; + int ret; + + dev = nand_ecc_get_engine_dev(nand->ecc.engine->dev); + if (!dev) + return -EINVAL; + + dev_info(dev, "Macronix ECC engine in pipelined/mapping mode\n"); + + ret = mxic_ecc_init_ctx(nand, dev); + if (ret) + return ret; + + ctx = nand_to_ecc_ctx(nand); + + /* All steps should be handled in one go directly by the internal DMA */ + writel(ctx->steps, mxic->regs + CHUNK_CNT); + + /* + * Interleaved ECC scheme cannot be used otherwise factory bad block + * markers would be lost. A packed layout is mandatory. + */ + writel(BURST_TYP_INCREASING | ECC_PACKED | MAPPING, + mxic->regs + HC_CONFIG); + + return 0; +} + static void mxic_ecc_cleanup_ctx(struct nand_device *nand) { struct mxic_ecc_ctx *ctx = nand_to_ecc_ctx(nand); @@ -419,6 +464,18 @@ static int mxic_ecc_process_data(struct mxic_ecc_engine *mxic, return ret; } +int mxic_ecc_process_data_pipelined(struct nand_ecc_engine *eng, + unsigned int direction, dma_addr_t dirmap) +{ + struct mxic_ecc_engine *mxic = pip_ecc_eng_to_mxic(eng); + + if (dirmap) + writel(dirmap, mxic->regs + HC_SLV_ADDR); + + return mxic_ecc_process_data(mxic, direction); +} +EXPORT_SYMBOL_GPL(mxic_ecc_process_data_pipelined); + static void mxic_ecc_extract_status_bytes(struct mxic_ecc_ctx *ctx) { u8 *buf = ctx->oobwithstat; @@ -592,6 +649,11 @@ static int mxic_ecc_finish_io_req_external(struct nand_device *nand, dma_unmap_sg(mxic->dev, ctx->sg, 2, DMA_BIDIRECTIONAL); + if (ret) { + nand_ecc_restore_req(&ctx->req_ctx, req); + return ret; + } + /* Extract the status bytes and reconstruct the buffer */ mxic_ecc_extract_status_bytes(ctx); mxic_ecc_reconstruct_oobbuf(ctx, ctx->req->oobbuf.in, ctx->oobwithstat); @@ -601,6 +663,65 @@ static int mxic_ecc_finish_io_req_external(struct nand_device *nand, return mxic_ecc_count_biterrs(mxic, nand); } +/* Pipelined ECC engine helpers */ +static int mxic_ecc_prepare_io_req_pipelined(struct nand_device *nand, + struct nand_page_io_req *req) +{ + struct mxic_ecc_engine *mxic = nand_to_mxic(nand); + struct mxic_ecc_ctx *ctx = nand_to_ecc_ctx(nand); + int nents; + + if (req->mode == MTD_OPS_RAW) + return 0; + + nand_ecc_tweak_req(&ctx->req_ctx, req); + ctx->req = req; + + /* Copy the OOB buffer and add room for the ECC engine status bytes */ + mxic_ecc_add_room_in_oobbuf(ctx, ctx->oobwithstat, ctx->req->oobbuf.in); + + sg_set_buf(&ctx->sg[0], req->databuf.in, req->datalen); + sg_set_buf(&ctx->sg[1], ctx->oobwithstat, + req->ooblen + (ctx->steps * STAT_BYTES)); + + nents = dma_map_sg(mxic->dev, ctx->sg, 2, DMA_BIDIRECTIONAL); + if (!nents) + return -EINVAL; + + mutex_lock(&mxic->lock); + + writel(sg_dma_address(&ctx->sg[0]), mxic->regs + SDMA_MAIN_ADDR); + writel(sg_dma_address(&ctx->sg[1]), mxic->regs + SDMA_SPARE_ADDR); + + return 0; +} + +static int mxic_ecc_finish_io_req_pipelined(struct nand_device *nand, + struct nand_page_io_req *req) +{ + struct mxic_ecc_engine *mxic = nand_to_mxic(nand); + struct mxic_ecc_ctx *ctx = nand_to_ecc_ctx(nand); + int ret = 0; + + if (req->mode == MTD_OPS_RAW) + return 0; + + mutex_unlock(&mxic->lock); + + dma_unmap_sg(mxic->dev, ctx->sg, 2, DMA_BIDIRECTIONAL); + + if (req->type == NAND_PAGE_READ) { + mxic_ecc_extract_status_bytes(ctx); + mxic_ecc_reconstruct_oobbuf(ctx, ctx->req->oobbuf.in, + ctx->oobwithstat); + ret = mxic_ecc_count_biterrs(mxic, nand); + } + + nand_ecc_restore_req(&ctx->req_ctx, req); + + return ret; +} + static struct nand_ecc_engine_ops mxic_ecc_engine_external_ops = { .init_ctx = mxic_ecc_init_ctx_external, .cleanup_ctx = mxic_ecc_cleanup_ctx, @@ -608,6 +729,69 @@ static struct nand_ecc_engine_ops mxic_ecc_engine_external_ops = { .finish_io_req = mxic_ecc_finish_io_req_external, }; +static struct nand_ecc_engine_ops mxic_ecc_engine_pipelined_ops = { + .init_ctx = mxic_ecc_init_ctx_pipelined, + .cleanup_ctx = mxic_ecc_cleanup_ctx, + .prepare_io_req = mxic_ecc_prepare_io_req_pipelined, + .finish_io_req = mxic_ecc_finish_io_req_pipelined, +}; + +struct nand_ecc_engine_ops *mxic_ecc_get_pipelined_ops(void) +{ + return &mxic_ecc_engine_pipelined_ops; +} +EXPORT_SYMBOL_GPL(mxic_ecc_get_pipelined_ops); + +static struct platform_device * +mxic_ecc_get_pdev(struct platform_device *spi_pdev) +{ + struct platform_device *eng_pdev; + struct device_node *np; + + /* Retrieve the nand-ecc-engine phandle */ + np = of_parse_phandle(spi_pdev->dev.of_node, "nand-ecc-engine", 0); + if (!np) + return NULL; + + /* Jump to the engine's device node */ + eng_pdev = of_find_device_by_node(np); + of_node_put(np); + + return eng_pdev; +} + +void mxic_ecc_put_pipelined_engine(struct nand_ecc_engine *eng) +{ + struct mxic_ecc_engine *mxic = pip_ecc_eng_to_mxic(eng); + + platform_device_put(to_platform_device(mxic->dev)); +} +EXPORT_SYMBOL_GPL(mxic_ecc_put_pipelined_engine); + +struct nand_ecc_engine * +mxic_ecc_get_pipelined_engine(struct platform_device *spi_pdev) +{ + struct platform_device *eng_pdev; + struct mxic_ecc_engine *mxic; + + eng_pdev = mxic_ecc_get_pdev(spi_pdev); + if (!eng_pdev) + return ERR_PTR(-ENODEV); + + mxic = platform_get_drvdata(eng_pdev); + if (!mxic) { + platform_device_put(eng_pdev); + return ERR_PTR(-EPROBE_DEFER); + } + + return &mxic->pipelined_engine; +} +EXPORT_SYMBOL_GPL(mxic_ecc_get_pipelined_engine); + +/* + * Only the external ECC engine is exported as the pipelined is SoC specific, so + * it is registered directly by the drivers that wrap it. + */ static int mxic_ecc_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; diff --git a/include/linux/mtd/nand-ecc-mxic.h b/include/linux/mtd/nand-ecc-mxic.h new file mode 100644 index 000000000000..f3aa1ac82aed --- /dev/null +++ b/include/linux/mtd/nand-ecc-mxic.h @@ -0,0 +1,49 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright © 2019 Macronix + * Author: Miquèl Raynal + * + * Header for the Macronix external ECC engine. + */ + +#ifndef __MTD_NAND_ECC_MXIC_H__ +#define __MTD_NAND_ECC_MXIC_H__ + +#include +#include + +struct mxic_ecc_engine; + +#if IS_ENABLED(CONFIG_MTD_NAND_ECC_MXIC) + +struct nand_ecc_engine_ops *mxic_ecc_get_pipelined_ops(void); +struct nand_ecc_engine *mxic_ecc_get_pipelined_engine(struct platform_device *spi_pdev); +void mxic_ecc_put_pipelined_engine(struct nand_ecc_engine *eng); +int mxic_ecc_process_data_pipelined(struct nand_ecc_engine *eng, + unsigned int direction, dma_addr_t dirmap); + +#else /* !CONFIG_MTD_NAND_ECC_MXIC */ + +static inline struct nand_ecc_engine_ops *mxic_ecc_get_pipelined_ops(void) +{ + return NULL; +} + +static inline struct nand_ecc_engine * +mxic_ecc_get_pipelined_engine(struct platform_device *spi_pdev) +{ + return ERR_PTR(-EOPNOTSUPP); +} + +static inline void mxic_ecc_put_pipelined_engine(struct nand_ecc_engine *eng) {} + +static inline int mxic_ecc_process_data_pipelined(struct nand_ecc_engine *eng, + unsigned int direction, + dma_addr_t dirmap) +{ + return -EOPNOTSUPP; +} + +#endif /* CONFIG_MTD_NAND_ECC_MXIC */ + +#endif /* __MTD_NAND_ECC_MXIC_H__ */ From 4a3cc7fb6e63bcfdedec25364738f1493345bd20 Mon Sep 17 00:00:00 2001 From: Miquel Raynal Date: Thu, 27 Jan 2022 10:17:56 +0100 Subject: [PATCH 098/370] spi: spi-mem: Introduce a capability structure Create a spi_controller_mem_caps structure and put it within the spi_controller structure close to the spi_controller_mem_ops strucure. So far the only field in this structure is the support for dtr operations, but soon we will add another parameter. Also create a helper to parse the capabilities and check if the requested capability has been set or not. Signed-off-by: Miquel Raynal Reviewed-by: Pratyush Yadav Reviewed-by: Boris Brezillon Reviewed-by: Tudor Ambarus Reviewed-by: Mark Brown Link: https://lore.kernel.org/linux-mtd/20220127091808.1043392-2-miquel.raynal@bootlin.com --- include/linux/spi/spi-mem.h | 11 +++++++++++ include/linux/spi/spi.h | 3 +++ 2 files changed, 14 insertions(+) diff --git a/include/linux/spi/spi-mem.h b/include/linux/spi/spi-mem.h index 85e2ff7b840d..38e5d45c9842 100644 --- a/include/linux/spi/spi-mem.h +++ b/include/linux/spi/spi-mem.h @@ -285,6 +285,17 @@ struct spi_controller_mem_ops { unsigned long timeout_ms); }; +/** + * struct spi_controller_mem_caps - SPI memory controller capabilities + * @dtr: Supports DTR operations + */ +struct spi_controller_mem_caps { + bool dtr; +}; + +#define spi_mem_controller_is_capable(ctlr, cap) \ + ((ctlr)->mem_caps && (ctlr)->mem_caps->cap) + /** * struct spi_mem_driver - SPI memory driver * @spidrv: inherit from a SPI driver diff --git a/include/linux/spi/spi.h b/include/linux/spi/spi.h index 7ab3fed7b804..cf99a1ee0e74 100644 --- a/include/linux/spi/spi.h +++ b/include/linux/spi/spi.h @@ -23,6 +23,7 @@ struct ptp_system_timestamp; struct spi_controller; struct spi_transfer; struct spi_controller_mem_ops; +struct spi_controller_mem_caps; /* * INTERFACES between SPI master-side drivers and SPI slave protocol handlers, @@ -415,6 +416,7 @@ extern struct spi_device *spi_new_ancillary_device(struct spi_device *spi, u8 ch * @mem_ops: optimized/dedicated operations for interactions with SPI memory. * This field is optional and should only be implemented if the * controller has native support for memory like operations. + * @mem_caps: controller capabilities for the handling of memory operations. * @unprepare_message: undo any work done by prepare_message(). * @slave_abort: abort the ongoing transfer request on an SPI slave controller * @cs_gpios: LEGACY: array of GPIO descs to use as chip select lines; one per @@ -639,6 +641,7 @@ struct spi_controller { /* Optimized handlers for SPI memory-like operations. */ const struct spi_controller_mem_ops *mem_ops; + const struct spi_controller_mem_caps *mem_caps; /* gpio chip select */ int *cs_gpios; From cb7e96ee81edaa48c67d84c14df2cbe464391c37 Mon Sep 17 00:00:00 2001 From: Miquel Raynal Date: Thu, 27 Jan 2022 10:17:57 +0100 Subject: [PATCH 099/370] spi: spi-mem: Check the controller extra capabilities Controllers can now provide a spi-mem capabilities structure. Let's make use of it in spi_mem_controller_default_supports_op(). As we want to check for DTR operations as well as normal operations in a single helper, let's pull the necessary checks from spi_mem_dtr_supports_op() for now. However, because no controller provide these extra capabilities, this change has no effect so far. Signed-off-by: Miquel Raynal Reviewed-by: Pratyush Yadav Reviewed-by: Boris Brezillon Reviewed-by: Tudor Ambarus Link: https://lore.kernel.org/linux-mtd/20220127091808.1043392-3-miquel.raynal@bootlin.com --- drivers/spi/spi-mem.c | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/drivers/spi/spi-mem.c b/drivers/spi/spi-mem.c index 37f4443ce9a0..86e6597bc3dc 100644 --- a/drivers/spi/spi-mem.c +++ b/drivers/spi/spi-mem.c @@ -173,11 +173,20 @@ EXPORT_SYMBOL_GPL(spi_mem_dtr_supports_op); bool spi_mem_default_supports_op(struct spi_mem *mem, const struct spi_mem_op *op) { - if (op->cmd.dtr || op->addr.dtr || op->dummy.dtr || op->data.dtr) - return false; + struct spi_controller *ctlr = mem->spi->controller; + bool op_is_dtr = + op->cmd.dtr || op->addr.dtr || op->dummy.dtr || op->data.dtr; - if (op->cmd.nbytes != 1) - return false; + if (op_is_dtr) { + if (!spi_mem_controller_is_capable(ctlr, dtr)) + return false; + + if (op->cmd.nbytes != 2) + return false; + } else { + if (op->cmd.nbytes != 1) + return false; + } return spi_mem_check_buswidth(mem, op); } From a9be454927de3b6df8ca4cbd88e019e52b73d4b4 Mon Sep 17 00:00:00 2001 From: Miquel Raynal Date: Thu, 27 Jan 2022 10:17:58 +0100 Subject: [PATCH 100/370] spi: cadence-quadspi: Provide a capability structure This controller has DTR support, so advertize it with a capability now that the spi-controller structure contains this new field. This will later be used by the core to discriminate whether an operation is supported or not, in a more generic way than having different helpers. Signed-off-by: Miquel Raynal Reviewed-by: Pratyush Yadav Reviewed-by: Boris Brezillon Reviewed-by: Tudor Ambarus Reviewed-by: Mark Brown Link: https://lore.kernel.org/linux-mtd/20220127091808.1043392-4-miquel.raynal@bootlin.com --- drivers/spi/spi-cadence-quadspi.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/spi/spi-cadence-quadspi.c b/drivers/spi/spi-cadence-quadspi.c index b808c94641fa..455b90d1feed 100644 --- a/drivers/spi/spi-cadence-quadspi.c +++ b/drivers/spi/spi-cadence-quadspi.c @@ -1595,6 +1595,10 @@ static const struct spi_controller_mem_ops cqspi_mem_ops = { .supports_op = cqspi_supports_mem_op, }; +static const struct spi_controller_mem_caps cqspi_mem_caps = { + .dtr = true, +}; + static int cqspi_setup_flash(struct cqspi_st *cqspi) { struct platform_device *pdev = cqspi->pdev; @@ -1652,6 +1656,7 @@ static int cqspi_probe(struct platform_device *pdev) } master->mode_bits = SPI_RX_QUAD | SPI_RX_DUAL; master->mem_ops = &cqspi_mem_ops; + master->mem_caps = &cqspi_mem_caps; master->dev.of_node = pdev->dev.of_node; cqspi = spi_master_get_devdata(master); From 0e450c7ce7d170a78adaeaa9a430e4184f191c15 Mon Sep 17 00:00:00 2001 From: Miquel Raynal Date: Thu, 27 Jan 2022 10:17:59 +0100 Subject: [PATCH 101/370] spi: mxic: Provide a capability structure This controller has DTR support, so advertize it with a capability now that the spi-controller structure contains this new field. This will later be used by the core to discriminate whether an operation is supported or not, in a more generic way than having different helpers. Signed-off-by: Miquel Raynal Reviewed-by: Boris Brezillon Reviewed-by: Tudor Ambarus Reviewed-by: Mark Brown Link: https://lore.kernel.org/linux-mtd/20220127091808.1043392-5-miquel.raynal@bootlin.com --- drivers/spi/spi-mxic.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/spi/spi-mxic.c b/drivers/spi/spi-mxic.c index 45889947afed..9952fcdf3627 100644 --- a/drivers/spi/spi-mxic.c +++ b/drivers/spi/spi-mxic.c @@ -448,6 +448,10 @@ static const struct spi_controller_mem_ops mxic_spi_mem_ops = { .exec_op = mxic_spi_mem_exec_op, }; +static const struct spi_controller_mem_caps mxic_spi_mem_caps = { + .dtr = true, +}; + static void mxic_spi_set_cs(struct spi_device *spi, bool lvl) { struct mxic_spi *mxic = spi_master_get_devdata(spi->master); @@ -580,6 +584,7 @@ static int mxic_spi_probe(struct platform_device *pdev) master->num_chipselect = 1; master->mem_ops = &mxic_spi_mem_ops; + master->mem_caps = &mxic_spi_mem_caps; master->set_cs = mxic_spi_set_cs; master->transfer_one = mxic_spi_transfer_one; From 9a15efc5d5e6b5beaed0883e5bdcd0b1384c1b20 Mon Sep 17 00:00:00 2001 From: Miquel Raynal Date: Thu, 27 Jan 2022 10:18:00 +0100 Subject: [PATCH 102/370] spi: spi-mem: Kill the spi_mem_dtr_supports_op() helper Now that spi_mem_default_supports_op() has access to the static controller capabilities (relating to memory operations), and now that these capabilities have been filled by the relevant controllers, there is no need for a specific helper checking only DTR operations, so let's just kill spi_mem_dtr_supports_op() and simply use spi_mem_default_supports_op() instead. Signed-off-by: Miquel Raynal Reviewed-by: Pratyush Yadav Reviewed-by: Boris Brezillon Reviewed-by: Tudor Ambarus Link: https://lore.kernel.org/linux-mtd/20220127091808.1043392-6-miquel.raynal@bootlin.com --- drivers/spi/spi-cadence-quadspi.c | 5 +---- drivers/spi/spi-mem.c | 10 ---------- drivers/spi/spi-mxic.c | 10 +--------- include/linux/spi/spi-mem.h | 11 ----------- 4 files changed, 2 insertions(+), 34 deletions(-) diff --git a/drivers/spi/spi-cadence-quadspi.c b/drivers/spi/spi-cadence-quadspi.c index 455b90d1feed..b0c9f62ccefb 100644 --- a/drivers/spi/spi-cadence-quadspi.c +++ b/drivers/spi/spi-cadence-quadspi.c @@ -1441,10 +1441,7 @@ static bool cqspi_supports_mem_op(struct spi_mem *mem, if (!(all_true || all_false)) return false; - if (all_true) - return spi_mem_dtr_supports_op(mem, op); - else - return spi_mem_default_supports_op(mem, op); + return spi_mem_default_supports_op(mem, op); } static int cqspi_of_get_flash_pdata(struct platform_device *pdev, diff --git a/drivers/spi/spi-mem.c b/drivers/spi/spi-mem.c index 86e6597bc3dc..ed966d8129eb 100644 --- a/drivers/spi/spi-mem.c +++ b/drivers/spi/spi-mem.c @@ -160,16 +160,6 @@ static bool spi_mem_check_buswidth(struct spi_mem *mem, return true; } -bool spi_mem_dtr_supports_op(struct spi_mem *mem, - const struct spi_mem_op *op) -{ - if (op->cmd.nbytes != 2) - return false; - - return spi_mem_check_buswidth(mem, op); -} -EXPORT_SYMBOL_GPL(spi_mem_dtr_supports_op); - bool spi_mem_default_supports_op(struct spi_mem *mem, const struct spi_mem_op *op) { diff --git a/drivers/spi/spi-mxic.c b/drivers/spi/spi-mxic.c index 9952fcdf3627..6bec0a7c77d3 100644 --- a/drivers/spi/spi-mxic.c +++ b/drivers/spi/spi-mxic.c @@ -335,8 +335,6 @@ static int mxic_spi_data_xfer(struct mxic_spi *mxic, const void *txbuf, static bool mxic_spi_mem_supports_op(struct spi_mem *mem, const struct spi_mem_op *op) { - bool all_false; - if (op->data.buswidth > 8 || op->addr.buswidth > 8 || op->dummy.buswidth > 8 || op->cmd.buswidth > 8) return false; @@ -348,13 +346,7 @@ static bool mxic_spi_mem_supports_op(struct spi_mem *mem, if (op->addr.nbytes > 7) return false; - all_false = !op->cmd.dtr && !op->addr.dtr && !op->dummy.dtr && - !op->data.dtr; - - if (all_false) - return spi_mem_default_supports_op(mem, op); - else - return spi_mem_dtr_supports_op(mem, op); + return spi_mem_default_supports_op(mem, op); } static int mxic_spi_mem_exec_op(struct spi_mem *mem, diff --git a/include/linux/spi/spi-mem.h b/include/linux/spi/spi-mem.h index 38e5d45c9842..4a1bfe689872 100644 --- a/include/linux/spi/spi-mem.h +++ b/include/linux/spi/spi-mem.h @@ -330,10 +330,6 @@ void spi_controller_dma_unmap_mem_op_data(struct spi_controller *ctlr, bool spi_mem_default_supports_op(struct spi_mem *mem, const struct spi_mem_op *op); - -bool spi_mem_dtr_supports_op(struct spi_mem *mem, - const struct spi_mem_op *op); - #else static inline int spi_controller_dma_map_mem_op_data(struct spi_controller *ctlr, @@ -356,13 +352,6 @@ bool spi_mem_default_supports_op(struct spi_mem *mem, { return false; } - -static inline -bool spi_mem_dtr_supports_op(struct spi_mem *mem, - const struct spi_mem_op *op) -{ - return false; -} #endif /* CONFIG_SPI_MEM */ int spi_mem_adjust_op_size(struct spi_mem *mem, struct spi_mem_op *op); From a433c2cbd75ab76f277364f44e76f32c7df306e7 Mon Sep 17 00:00:00 2001 From: Miquel Raynal Date: Thu, 27 Jan 2022 10:18:01 +0100 Subject: [PATCH 103/370] spi: spi-mem: Add an ecc parameter to the spi_mem_op structure Soon the SPI-NAND core will need a way to request a SPI controller to enable ECC support for a given operation. This is because of the pipelined integration of certain ECC engines, which are directly managed by the SPI controller itself. Introduce a spi_mem_op additional field for this purpose: ecc. So far this field is left unset and checked to be false by all the SPI controller drivers in their ->supports_op() hook, as they all call spi_mem_default_supports_op(). Signed-off-by: Miquel Raynal Acked-by: Pratyush Yadav Reviewed-by: Boris Brezillon Reviewed-by: Tudor Ambarus Link: https://lore.kernel.org/linux-mtd/20220127091808.1043392-7-miquel.raynal@bootlin.com --- drivers/spi/spi-mem.c | 5 +++++ include/linux/spi/spi-mem.h | 4 ++++ 2 files changed, 9 insertions(+) diff --git a/drivers/spi/spi-mem.c b/drivers/spi/spi-mem.c index ed966d8129eb..f38ac31961c9 100644 --- a/drivers/spi/spi-mem.c +++ b/drivers/spi/spi-mem.c @@ -178,6 +178,11 @@ bool spi_mem_default_supports_op(struct spi_mem *mem, return false; } + if (op->data.ecc) { + if (!spi_mem_controller_is_capable(ctlr, ecc)) + return false; + } + return spi_mem_check_buswidth(mem, op); } EXPORT_SYMBOL_GPL(spi_mem_default_supports_op); diff --git a/include/linux/spi/spi-mem.h b/include/linux/spi/spi-mem.h index 4a1bfe689872..2ba044d0d5e5 100644 --- a/include/linux/spi/spi-mem.h +++ b/include/linux/spi/spi-mem.h @@ -89,6 +89,7 @@ enum spi_mem_data_dir { * @dummy.dtr: whether the dummy bytes should be sent in DTR mode or not * @data.buswidth: number of IO lanes used to send/receive the data * @data.dtr: whether the data should be sent in DTR mode or not + * @data.ecc: whether error correction is required or not * @data.dir: direction of the transfer * @data.nbytes: number of data bytes to send/receive. Can be zero if the * operation does not involve transferring data @@ -119,6 +120,7 @@ struct spi_mem_op { struct { u8 buswidth; u8 dtr : 1; + u8 ecc : 1; enum spi_mem_data_dir dir; unsigned int nbytes; union { @@ -288,9 +290,11 @@ struct spi_controller_mem_ops { /** * struct spi_controller_mem_caps - SPI memory controller capabilities * @dtr: Supports DTR operations + * @ecc: Supports operations with error correction */ struct spi_controller_mem_caps { bool dtr; + bool ecc; }; #define spi_mem_controller_is_capable(ctlr, cap) \ From dc4c2cbf0be2d4a8e2a65013ea2815bb2c8ba949 Mon Sep 17 00:00:00 2001 From: Miquel Raynal Date: Thu, 27 Jan 2022 10:18:02 +0100 Subject: [PATCH 104/370] mtd: spinand: Delay a little bit the dirmap creation As we will soon tweak the dirmap creation to act a little bit differently depending on the picked ECC engine, we need to initialize dirmaps after ECC engines. This should not have any effect as dirmaps are not yet used at this point. Signed-off-by: Miquel Raynal Reviewed-by: Boris Brezillon Link: https://lore.kernel.org/linux-mtd/20220127091808.1043392-8-miquel.raynal@bootlin.com --- drivers/mtd/nand/spi/core.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/drivers/mtd/nand/spi/core.c b/drivers/mtd/nand/spi/core.c index 2c8685f1f2fa..bb6b026b558b 100644 --- a/drivers/mtd/nand/spi/core.c +++ b/drivers/mtd/nand/spi/core.c @@ -1208,14 +1208,6 @@ static int spinand_init(struct spinand_device *spinand) if (ret) goto err_free_bufs; - ret = spinand_create_dirmaps(spinand); - if (ret) { - dev_err(dev, - "Failed to create direct mappings for read/write operations (err = %d)\n", - ret); - goto err_manuf_cleanup; - } - ret = nanddev_init(nand, &spinand_ops, THIS_MODULE); if (ret) goto err_manuf_cleanup; @@ -1250,6 +1242,14 @@ static int spinand_init(struct spinand_device *spinand) mtd->ecc_strength = nanddev_get_ecc_conf(nand)->strength; mtd->ecc_step_size = nanddev_get_ecc_conf(nand)->step_size; + ret = spinand_create_dirmaps(spinand); + if (ret) { + dev_err(dev, + "Failed to create direct mappings for read/write operations (err = %d)\n", + ret); + goto err_cleanup_ecc_engine; + } + return 0; err_cleanup_ecc_engine: From f9d7c7265bcff7d9a17425a8cddf702e8fe159c2 Mon Sep 17 00:00:00 2001 From: Miquel Raynal Date: Thu, 27 Jan 2022 10:18:03 +0100 Subject: [PATCH 105/370] mtd: spinand: Create direct mapping descriptors for ECC operations In order for pipelined ECC engines to be able to enable/disable the ECC engine only when needed and avoid races when future parallel-operations will be supported, we need to provide the information about the use of the ECC engine in the direct mapping hooks. As direct mapping configurations are meant to be static, it is best to create two new mappings: one for regular 'raw' accesses and one for accesses involving correction. It is up to the driver to use or not the new ECC enable boolean contained in the spi-mem operation. As dirmaps are not free (they consume a few pages of MMIO address space) and because these extra entries are only meant to be used by pipelined engines, let's limit their use to this specific type of engine and save a bit of memory with all the other setups. Signed-off-by: Miquel Raynal Reviewed-by: Boris Brezillon Link: https://lore.kernel.org/linux-mtd/20220127091808.1043392-9-miquel.raynal@bootlin.com --- drivers/mtd/nand/spi/core.c | 35 +++++++++++++++++++++++++++++++++-- include/linux/mtd/spinand.h | 2 ++ 2 files changed, 35 insertions(+), 2 deletions(-) diff --git a/drivers/mtd/nand/spi/core.c b/drivers/mtd/nand/spi/core.c index bb6b026b558b..ff8336870bc0 100644 --- a/drivers/mtd/nand/spi/core.c +++ b/drivers/mtd/nand/spi/core.c @@ -381,7 +381,10 @@ static int spinand_read_from_cache_op(struct spinand_device *spinand, } } - rdesc = spinand->dirmaps[req->pos.plane].rdesc; + if (req->mode == MTD_OPS_RAW) + rdesc = spinand->dirmaps[req->pos.plane].rdesc; + else + rdesc = spinand->dirmaps[req->pos.plane].rdesc_ecc; while (nbytes) { ret = spi_mem_dirmap_read(rdesc, column, nbytes, buf); @@ -452,7 +455,10 @@ static int spinand_write_to_cache_op(struct spinand_device *spinand, req->ooblen); } - wdesc = spinand->dirmaps[req->pos.plane].wdesc; + if (req->mode == MTD_OPS_RAW) + wdesc = spinand->dirmaps[req->pos.plane].wdesc; + else + wdesc = spinand->dirmaps[req->pos.plane].wdesc_ecc; while (nbytes) { ret = spi_mem_dirmap_write(wdesc, column, nbytes, buf); @@ -865,6 +871,31 @@ static int spinand_create_dirmap(struct spinand_device *spinand, spinand->dirmaps[plane].rdesc = desc; + if (nand->ecc.engine->integration != NAND_ECC_ENGINE_INTEGRATION_PIPELINED) { + spinand->dirmaps[plane].wdesc_ecc = spinand->dirmaps[plane].wdesc; + spinand->dirmaps[plane].rdesc_ecc = spinand->dirmaps[plane].rdesc; + + return 0; + } + + info.op_tmpl = *spinand->op_templates.update_cache; + info.op_tmpl.data.ecc = true; + desc = devm_spi_mem_dirmap_create(&spinand->spimem->spi->dev, + spinand->spimem, &info); + if (IS_ERR(desc)) + return PTR_ERR(desc); + + spinand->dirmaps[plane].wdesc_ecc = desc; + + info.op_tmpl = *spinand->op_templates.read_cache; + info.op_tmpl.data.ecc = true; + desc = devm_spi_mem_dirmap_create(&spinand->spimem->spi->dev, + spinand->spimem, &info); + if (IS_ERR(desc)) + return PTR_ERR(desc); + + spinand->dirmaps[plane].rdesc_ecc = desc; + return 0; } diff --git a/include/linux/mtd/spinand.h b/include/linux/mtd/spinand.h index 6988956b8492..3aa28240a77f 100644 --- a/include/linux/mtd/spinand.h +++ b/include/linux/mtd/spinand.h @@ -389,6 +389,8 @@ struct spinand_info { struct spinand_dirmap { struct spi_mem_dirmap_desc *wdesc; struct spi_mem_dirmap_desc *rdesc; + struct spi_mem_dirmap_desc *wdesc_ecc; + struct spi_mem_dirmap_desc *rdesc_ecc; }; /** From 5fd6739e0df7e320bcac103dfb95fe75941fea17 Mon Sep 17 00:00:00 2001 From: Miquel Raynal Date: Thu, 27 Jan 2022 10:18:04 +0100 Subject: [PATCH 106/370] spi: mxic: Fix the transmit path By working with external hardware ECC engines, we figured out that Under certain circumstances, it is needed for the SPI controller to check INT_TX_EMPTY and INT_RX_NOT_EMPTY in both receive and transmit path (not only in the receive path). The delay penalty being negligible, move this code in the common path. Fixes: b942d80b0a39 ("spi: Add MXIC controller driver") Cc: stable@vger.kernel.org Suggested-by: Mason Yang Signed-off-by: Miquel Raynal Reviewed-by: Zhengxun Li Reviewed-by: Mark Brown Link: https://lore.kernel.org/linux-mtd/20220127091808.1043392-10-miquel.raynal@bootlin.com --- drivers/spi/spi-mxic.c | 28 ++++++++++++---------------- 1 file changed, 12 insertions(+), 16 deletions(-) diff --git a/drivers/spi/spi-mxic.c b/drivers/spi/spi-mxic.c index 6bec0a7c77d3..22a82f5f74b5 100644 --- a/drivers/spi/spi-mxic.c +++ b/drivers/spi/spi-mxic.c @@ -304,25 +304,21 @@ static int mxic_spi_data_xfer(struct mxic_spi *mxic, const void *txbuf, writel(data, mxic->regs + TXD(nbytes % 4)); + ret = readl_poll_timeout(mxic->regs + INT_STS, sts, + sts & INT_TX_EMPTY, 0, USEC_PER_SEC); + if (ret) + return ret; + + ret = readl_poll_timeout(mxic->regs + INT_STS, sts, + sts & INT_RX_NOT_EMPTY, 0, + USEC_PER_SEC); + if (ret) + return ret; + + data = readl(mxic->regs + RXD); if (rxbuf) { - ret = readl_poll_timeout(mxic->regs + INT_STS, sts, - sts & INT_TX_EMPTY, 0, - USEC_PER_SEC); - if (ret) - return ret; - - ret = readl_poll_timeout(mxic->regs + INT_STS, sts, - sts & INT_RX_NOT_EMPTY, 0, - USEC_PER_SEC); - if (ret) - return ret; - - data = readl(mxic->regs + RXD); data >>= (8 * (4 - nbytes)); memcpy(rxbuf + pos, &data, nbytes); - WARN_ON(readl(mxic->regs + INT_STS) & INT_RX_NOT_EMPTY); - } else { - readl(mxic->regs + RXD); } WARN_ON(readl(mxic->regs + INT_STS) & INT_RX_NOT_EMPTY); From b7b64db74ea53f51d316077c1267bb4d0792ef4b Mon Sep 17 00:00:00 2001 From: Miquel Raynal Date: Thu, 27 Jan 2022 10:18:05 +0100 Subject: [PATCH 107/370] spi: mxic: Create a helper to configure the controller before an operation Create the mxic_spi_set_hc_cfg() helper to configure the HC_CFG register. This helper will soon be used by the dirmap implementation and having this code factorized out earlier will clarify this addition. Signed-off-by: Miquel Raynal Reviewed-by: Mark Brown Link: https://lore.kernel.org/linux-mtd/20220127091808.1043392-11-miquel.raynal@bootlin.com --- drivers/spi/spi-mxic.c | 31 +++++++++++++++++++------------ 1 file changed, 19 insertions(+), 12 deletions(-) diff --git a/drivers/spi/spi-mxic.c b/drivers/spi/spi-mxic.c index 22a82f5f74b5..c45f949a864d 100644 --- a/drivers/spi/spi-mxic.c +++ b/drivers/spi/spi-mxic.c @@ -280,6 +280,22 @@ static void mxic_spi_hw_init(struct mxic_spi *mxic) mxic->regs + HC_CFG); } +static u32 mxic_spi_prep_hc_cfg(struct spi_device *spi, u32 flags) +{ + int nio = 1; + + if (spi->mode & (SPI_TX_OCTAL | SPI_RX_OCTAL)) + nio = 8; + else if (spi->mode & (SPI_TX_QUAD | SPI_RX_QUAD)) + nio = 4; + else if (spi->mode & (SPI_TX_DUAL | SPI_RX_DUAL)) + nio = 2; + + return flags | HC_CFG_NIO(nio) | + HC_CFG_TYPE(spi->chip_select, HC_CFG_TYPE_SPI_NOR) | + HC_CFG_SLV_ACT(spi->chip_select) | HC_CFG_IDLE_SIO_LVL(1); +} + static int mxic_spi_data_xfer(struct mxic_spi *mxic, const void *txbuf, void *rxbuf, unsigned int len) { @@ -349,7 +365,7 @@ static int mxic_spi_mem_exec_op(struct spi_mem *mem, const struct spi_mem_op *op) { struct mxic_spi *mxic = spi_master_get_devdata(mem->spi->master); - int nio = 1, i, ret; + int i, ret; u32 ss_ctrl; u8 addr[8], cmd[2]; @@ -357,18 +373,9 @@ static int mxic_spi_mem_exec_op(struct spi_mem *mem, if (ret) return ret; - if (mem->spi->mode & (SPI_TX_OCTAL | SPI_RX_OCTAL)) - nio = 8; - else if (mem->spi->mode & (SPI_TX_QUAD | SPI_RX_QUAD)) - nio = 4; - else if (mem->spi->mode & (SPI_TX_DUAL | SPI_RX_DUAL)) - nio = 2; - - writel(HC_CFG_NIO(nio) | - HC_CFG_TYPE(mem->spi->chip_select, HC_CFG_TYPE_SPI_NOR) | - HC_CFG_SLV_ACT(mem->spi->chip_select) | HC_CFG_IDLE_SIO_LVL(1) | - HC_CFG_MAN_CS_EN, + writel(mxic_spi_prep_hc_cfg(mem->spi, HC_CFG_MAN_CS_EN), mxic->regs + HC_CFG); + writel(HC_EN_BIT, mxic->regs + HC_EN); ss_ctrl = OP_CMD_BYTES(op->cmd.nbytes) | From d1b64bb28907b0ae4eff6befd6a1a476fbb68424 Mon Sep 17 00:00:00 2001 From: Miquel Raynal Date: Thu, 27 Jan 2022 10:18:06 +0100 Subject: [PATCH 108/370] spi: mxic: Create a helper to ease the start of an operation Create the mxic_spi_mem_prep_op_cfg() helper to provide the content to write to the register controlling the next IO command. This helper will soon be used by the dirmap implementation and having this code factorized out earlier will clarify this addition. Signed-off-by: Miquel Raynal Reviewed-by: Mark Brown Link: https://lore.kernel.org/linux-mtd/20220127091808.1043392-12-miquel.raynal@bootlin.com --- drivers/spi/spi-mxic.c | 53 +++++++++++++++++++++++------------------- 1 file changed, 29 insertions(+), 24 deletions(-) diff --git a/drivers/spi/spi-mxic.c b/drivers/spi/spi-mxic.c index c45f949a864d..ba9cda4bf161 100644 --- a/drivers/spi/spi-mxic.c +++ b/drivers/spi/spi-mxic.c @@ -296,6 +296,33 @@ static u32 mxic_spi_prep_hc_cfg(struct spi_device *spi, u32 flags) HC_CFG_SLV_ACT(spi->chip_select) | HC_CFG_IDLE_SIO_LVL(1); } +static u32 mxic_spi_mem_prep_op_cfg(const struct spi_mem_op *op) +{ + u32 cfg = OP_CMD_BYTES(op->cmd.nbytes) | + OP_CMD_BUSW(fls(op->cmd.buswidth) - 1) | + (op->cmd.dtr ? OP_CMD_DDR : 0); + + if (op->addr.nbytes) + cfg |= OP_ADDR_BYTES(op->addr.nbytes) | + OP_ADDR_BUSW(fls(op->addr.buswidth) - 1) | + (op->addr.dtr ? OP_ADDR_DDR : 0); + + if (op->dummy.nbytes) + cfg |= OP_DUMMY_CYC(op->dummy.nbytes); + + if (op->data.nbytes) { + cfg |= OP_DATA_BUSW(fls(op->data.buswidth) - 1) | + (op->data.dtr ? OP_DATA_DDR : 0); + if (op->data.dir == SPI_MEM_DATA_IN) { + cfg |= OP_READ; + if (op->data.dtr) + cfg |= OP_DQS_EN; + } + } + + return cfg; +} + static int mxic_spi_data_xfer(struct mxic_spi *mxic, const void *txbuf, void *rxbuf, unsigned int len) { @@ -366,7 +393,6 @@ static int mxic_spi_mem_exec_op(struct spi_mem *mem, { struct mxic_spi *mxic = spi_master_get_devdata(mem->spi->master); int i, ret; - u32 ss_ctrl; u8 addr[8], cmd[2]; ret = mxic_spi_set_freq(mxic, mem->spi->max_speed_hz); @@ -378,29 +404,8 @@ static int mxic_spi_mem_exec_op(struct spi_mem *mem, writel(HC_EN_BIT, mxic->regs + HC_EN); - ss_ctrl = OP_CMD_BYTES(op->cmd.nbytes) | - OP_CMD_BUSW(fls(op->cmd.buswidth) - 1) | - (op->cmd.dtr ? OP_CMD_DDR : 0); - - if (op->addr.nbytes) - ss_ctrl |= OP_ADDR_BYTES(op->addr.nbytes) | - OP_ADDR_BUSW(fls(op->addr.buswidth) - 1) | - (op->addr.dtr ? OP_ADDR_DDR : 0); - - if (op->dummy.nbytes) - ss_ctrl |= OP_DUMMY_CYC(op->dummy.nbytes); - - if (op->data.nbytes) { - ss_ctrl |= OP_DATA_BUSW(fls(op->data.buswidth) - 1) | - (op->data.dtr ? OP_DATA_DDR : 0); - if (op->data.dir == SPI_MEM_DATA_IN) { - ss_ctrl |= OP_READ; - if (op->data.dtr) - ss_ctrl |= OP_DQS_EN; - } - } - - writel(ss_ctrl, mxic->regs + SS_CTRL(mem->spi->chip_select)); + writel(mxic_spi_mem_prep_op_cfg(op), + mxic->regs + SS_CTRL(mem->spi->chip_select)); writel(readl(mxic->regs + HC_CFG) | HC_CFG_MAN_CS_ASSERT, mxic->regs + HC_CFG); From 33fce1d8bfa8220eb3edf5b3691a411a9191d0b1 Mon Sep 17 00:00:00 2001 From: Miquel Raynal Date: Thu, 27 Jan 2022 10:18:07 +0100 Subject: [PATCH 109/370] spi: mxic: Add support for direct mapping Implement the ->dirmap_create() and ->dirmap_read/write() hooks to provide a fast path for read and write accesses. Signed-off-by: Miquel Raynal Tested-by: Zhengxun Li Reviewed-by: Zhengxun Li Reviewed-by: Mark Brown Link: https://lore.kernel.org/linux-mtd/20220127091808.1043392-13-miquel.raynal@bootlin.com --- drivers/spi/spi-mxic.c | 112 +++++++++++++++++++++++++++++++++++++++-- 1 file changed, 109 insertions(+), 3 deletions(-) diff --git a/drivers/spi/spi-mxic.c b/drivers/spi/spi-mxic.c index ba9cda4bf161..0d3390964c6f 100644 --- a/drivers/spi/spi-mxic.c +++ b/drivers/spi/spi-mxic.c @@ -172,6 +172,11 @@ struct mxic_spi { struct clk *send_dly_clk; void __iomem *regs; u32 cur_speed_hz; + struct { + void __iomem *map; + dma_addr_t dma; + size_t size; + } linear; }; static int mxic_spi_clk_enable(struct mxic_spi *mxic) @@ -296,7 +301,8 @@ static u32 mxic_spi_prep_hc_cfg(struct spi_device *spi, u32 flags) HC_CFG_SLV_ACT(spi->chip_select) | HC_CFG_IDLE_SIO_LVL(1); } -static u32 mxic_spi_mem_prep_op_cfg(const struct spi_mem_op *op) +static u32 mxic_spi_mem_prep_op_cfg(const struct spi_mem_op *op, + unsigned int data_len) { u32 cfg = OP_CMD_BYTES(op->cmd.nbytes) | OP_CMD_BUSW(fls(op->cmd.buswidth) - 1) | @@ -310,7 +316,8 @@ static u32 mxic_spi_mem_prep_op_cfg(const struct spi_mem_op *op) if (op->dummy.nbytes) cfg |= OP_DUMMY_CYC(op->dummy.nbytes); - if (op->data.nbytes) { + /* Direct mapping data.nbytes field is not populated */ + if (data_len) { cfg |= OP_DATA_BUSW(fls(op->data.buswidth) - 1) | (op->data.dtr ? OP_DATA_DDR : 0); if (op->data.dir == SPI_MEM_DATA_IN) { @@ -371,6 +378,77 @@ static int mxic_spi_data_xfer(struct mxic_spi *mxic, const void *txbuf, return 0; } +static ssize_t mxic_spi_mem_dirmap_read(struct spi_mem_dirmap_desc *desc, + u64 offs, size_t len, void *buf) +{ + struct mxic_spi *mxic = spi_master_get_devdata(desc->mem->spi->master); + int ret; + u32 sts; + + if (WARN_ON(offs + desc->info.offset + len > U32_MAX)) + return -EINVAL; + + writel(mxic_spi_prep_hc_cfg(desc->mem->spi, 0), mxic->regs + HC_CFG); + + writel(mxic_spi_mem_prep_op_cfg(&desc->info.op_tmpl, len), + mxic->regs + LRD_CFG); + writel(desc->info.offset + offs, mxic->regs + LRD_ADDR); + len = min_t(size_t, len, mxic->linear.size); + writel(len, mxic->regs + LRD_RANGE); + writel(LMODE_CMD0(desc->info.op_tmpl.cmd.opcode) | + LMODE_SLV_ACT(desc->mem->spi->chip_select) | + LMODE_EN, + mxic->regs + LRD_CTRL); + + memcpy_fromio(buf, mxic->linear.map, len); + + writel(INT_LRD_DIS, mxic->regs + INT_STS); + writel(0, mxic->regs + LRD_CTRL); + + ret = readl_poll_timeout(mxic->regs + INT_STS, sts, + sts & INT_LRD_DIS, 0, USEC_PER_SEC); + if (ret) + return ret; + + return len; +} + +static ssize_t mxic_spi_mem_dirmap_write(struct spi_mem_dirmap_desc *desc, + u64 offs, size_t len, + const void *buf) +{ + struct mxic_spi *mxic = spi_master_get_devdata(desc->mem->spi->master); + u32 sts; + int ret; + + if (WARN_ON(offs + desc->info.offset + len > U32_MAX)) + return -EINVAL; + + writel(mxic_spi_prep_hc_cfg(desc->mem->spi, 0), mxic->regs + HC_CFG); + + writel(mxic_spi_mem_prep_op_cfg(&desc->info.op_tmpl, len), + mxic->regs + LWR_CFG); + writel(desc->info.offset + offs, mxic->regs + LWR_ADDR); + len = min_t(size_t, len, mxic->linear.size); + writel(len, mxic->regs + LWR_RANGE); + writel(LMODE_CMD0(desc->info.op_tmpl.cmd.opcode) | + LMODE_SLV_ACT(desc->mem->spi->chip_select) | + LMODE_EN, + mxic->regs + LWR_CTRL); + + memcpy_toio(mxic->linear.map, buf, len); + + writel(INT_LWR_DIS, mxic->regs + INT_STS); + writel(0, mxic->regs + LWR_CTRL); + + ret = readl_poll_timeout(mxic->regs + INT_STS, sts, + sts & INT_LWR_DIS, 0, USEC_PER_SEC); + if (ret) + return ret; + + return len; +} + static bool mxic_spi_mem_supports_op(struct spi_mem *mem, const struct spi_mem_op *op) { @@ -388,6 +466,22 @@ static bool mxic_spi_mem_supports_op(struct spi_mem *mem, return spi_mem_default_supports_op(mem, op); } +static int mxic_spi_mem_dirmap_create(struct spi_mem_dirmap_desc *desc) +{ + struct mxic_spi *mxic = spi_master_get_devdata(desc->mem->spi->master); + + if (!mxic->linear.map) + return -EINVAL; + + if (desc->info.offset + desc->info.length > U32_MAX) + return -EINVAL; + + if (!mxic_spi_mem_supports_op(desc->mem, &desc->info.op_tmpl)) + return -EOPNOTSUPP; + + return 0; +} + static int mxic_spi_mem_exec_op(struct spi_mem *mem, const struct spi_mem_op *op) { @@ -404,7 +498,7 @@ static int mxic_spi_mem_exec_op(struct spi_mem *mem, writel(HC_EN_BIT, mxic->regs + HC_EN); - writel(mxic_spi_mem_prep_op_cfg(op), + writel(mxic_spi_mem_prep_op_cfg(op, op->data.nbytes), mxic->regs + SS_CTRL(mem->spi->chip_select)); writel(readl(mxic->regs + HC_CFG) | HC_CFG_MAN_CS_ASSERT, @@ -446,6 +540,9 @@ out: static const struct spi_controller_mem_ops mxic_spi_mem_ops = { .supports_op = mxic_spi_mem_supports_op, .exec_op = mxic_spi_mem_exec_op, + .dirmap_create = mxic_spi_mem_dirmap_create, + .dirmap_read = mxic_spi_mem_dirmap_read, + .dirmap_write = mxic_spi_mem_dirmap_write, }; static const struct spi_controller_mem_caps mxic_spi_mem_caps = { @@ -579,6 +676,15 @@ static int mxic_spi_probe(struct platform_device *pdev) if (IS_ERR(mxic->regs)) return PTR_ERR(mxic->regs); + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "dirmap"); + mxic->linear.map = devm_ioremap_resource(&pdev->dev, res); + if (!IS_ERR(mxic->linear.map)) { + mxic->linear.dma = res->start; + mxic->linear.size = resource_size(res); + } else { + mxic->linear.map = NULL; + } + pm_runtime_enable(&pdev->dev); master->auto_runtime_pm = true; From 00360ebae483e603d55ec9a7231b787cb80ffe13 Mon Sep 17 00:00:00 2001 From: Miquel Raynal Date: Wed, 2 Feb 2022 15:45:36 +0100 Subject: [PATCH 110/370] spi: mxic: Add support for pipelined ECC operations Some SPI-NAND chips do not have a proper on-die ECC engine providing error correction/detection. This is particularly an issue on embedded devices with limited resources because all the computations must happen in software, unless an external hardware engine is provided. These external engines are new and can be of two categories: external or pipelined. Macronix is providing both, the former being already supported. The second, however, is very SoC implementation dependent and must be instantiated by the SPI host controller directly. An entire subsystem has been contributed to support these engines which makes the insertion into another subsystem such as SPI quite straightforward without the need for a lot of specific functions. Signed-off-by: Miquel Raynal Reviewed-by: Mark Brown Link: https://lore.kernel.org/linux-mtd/20220202144536.393792-1-miquel.raynal@bootlin.com --- drivers/spi/Kconfig | 1 + drivers/spi/spi-mxic.c | 113 +++++++++++++++++++++++++++++- include/linux/mtd/nand-ecc-mxic.h | 2 +- include/linux/mtd/nand.h | 15 ++++ 4 files changed, 128 insertions(+), 3 deletions(-) diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig index b2a8821971e1..269613b03e40 100644 --- a/drivers/spi/Kconfig +++ b/drivers/spi/Kconfig @@ -879,6 +879,7 @@ config SPI_SYNQUACER config SPI_MXIC tristate "Macronix MX25F0A SPI controller" depends on SPI_MASTER + imply MTD_NAND_ECC_MXIC help This selects the Macronix MX25F0A SPI controller driver. diff --git a/drivers/spi/spi-mxic.c b/drivers/spi/spi-mxic.c index 0d3390964c6f..55c092069301 100644 --- a/drivers/spi/spi-mxic.c +++ b/drivers/spi/spi-mxic.c @@ -12,6 +12,8 @@ #include #include #include +#include +#include #include #include #include @@ -167,6 +169,7 @@ #define HW_TEST(x) (0xe0 + ((x) * 4)) struct mxic_spi { + struct device *dev; struct clk *ps_clk; struct clk *send_clk; struct clk *send_dly_clk; @@ -177,6 +180,12 @@ struct mxic_spi { dma_addr_t dma; size_t size; } linear; + + struct { + bool use_pipelined_conf; + struct nand_ecc_engine *pipelined_engine; + void *ctx; + } ecc; }; static int mxic_spi_clk_enable(struct mxic_spi *mxic) @@ -400,7 +409,15 @@ static ssize_t mxic_spi_mem_dirmap_read(struct spi_mem_dirmap_desc *desc, LMODE_EN, mxic->regs + LRD_CTRL); - memcpy_fromio(buf, mxic->linear.map, len); + if (mxic->ecc.use_pipelined_conf && desc->info.op_tmpl.data.ecc) { + ret = mxic_ecc_process_data_pipelined(mxic->ecc.pipelined_engine, + NAND_PAGE_READ, + mxic->linear.dma + offs); + if (ret) + return ret; + } else { + memcpy_fromio(buf, mxic->linear.map, len); + } writel(INT_LRD_DIS, mxic->regs + INT_STS); writel(0, mxic->regs + LRD_CTRL); @@ -436,7 +453,15 @@ static ssize_t mxic_spi_mem_dirmap_write(struct spi_mem_dirmap_desc *desc, LMODE_EN, mxic->regs + LWR_CTRL); - memcpy_toio(mxic->linear.map, buf, len); + if (mxic->ecc.use_pipelined_conf && desc->info.op_tmpl.data.ecc) { + ret = mxic_ecc_process_data_pipelined(mxic->ecc.pipelined_engine, + NAND_PAGE_WRITE, + mxic->linear.dma + offs); + if (ret) + return ret; + } else { + memcpy_toio(mxic->linear.map, buf, len); + } writel(INT_LWR_DIS, mxic->regs + INT_STS); writel(0, mxic->regs + LWR_CTRL); @@ -547,6 +572,7 @@ static const struct spi_controller_mem_ops mxic_spi_mem_ops = { static const struct spi_controller_mem_caps mxic_spi_mem_caps = { .dtr = true, + .ecc = true, }; static void mxic_spi_set_cs(struct spi_device *spi, bool lvl) @@ -611,6 +637,80 @@ static int mxic_spi_transfer_one(struct spi_master *master, return 0; } +/* ECC wrapper */ +static int mxic_spi_mem_ecc_init_ctx(struct nand_device *nand) +{ + struct nand_ecc_engine_ops *ops = mxic_ecc_get_pipelined_ops(); + struct mxic_spi *mxic = nand->ecc.engine->priv; + + mxic->ecc.use_pipelined_conf = true; + + return ops->init_ctx(nand); +} + +static void mxic_spi_mem_ecc_cleanup_ctx(struct nand_device *nand) +{ + struct nand_ecc_engine_ops *ops = mxic_ecc_get_pipelined_ops(); + struct mxic_spi *mxic = nand->ecc.engine->priv; + + mxic->ecc.use_pipelined_conf = false; + + ops->cleanup_ctx(nand); +} + +static int mxic_spi_mem_ecc_prepare_io_req(struct nand_device *nand, + struct nand_page_io_req *req) +{ + struct nand_ecc_engine_ops *ops = mxic_ecc_get_pipelined_ops(); + + return ops->prepare_io_req(nand, req); +} + +static int mxic_spi_mem_ecc_finish_io_req(struct nand_device *nand, + struct nand_page_io_req *req) +{ + struct nand_ecc_engine_ops *ops = mxic_ecc_get_pipelined_ops(); + + return ops->finish_io_req(nand, req); +} + +static struct nand_ecc_engine_ops mxic_spi_mem_ecc_engine_pipelined_ops = { + .init_ctx = mxic_spi_mem_ecc_init_ctx, + .cleanup_ctx = mxic_spi_mem_ecc_cleanup_ctx, + .prepare_io_req = mxic_spi_mem_ecc_prepare_io_req, + .finish_io_req = mxic_spi_mem_ecc_finish_io_req, +}; + +static void mxic_spi_mem_ecc_remove(struct mxic_spi *mxic) +{ + if (mxic->ecc.pipelined_engine) { + mxic_ecc_put_pipelined_engine(mxic->ecc.pipelined_engine); + nand_ecc_unregister_on_host_hw_engine(mxic->ecc.pipelined_engine); + } +} + +static int mxic_spi_mem_ecc_probe(struct platform_device *pdev, + struct mxic_spi *mxic) +{ + struct nand_ecc_engine *eng; + + if (!mxic_ecc_get_pipelined_ops()) + return -EOPNOTSUPP; + + eng = mxic_ecc_get_pipelined_engine(pdev); + if (IS_ERR(eng)) + return PTR_ERR(eng); + + eng->dev = &pdev->dev; + eng->integration = NAND_ECC_ENGINE_INTEGRATION_PIPELINED; + eng->ops = &mxic_spi_mem_ecc_engine_pipelined_ops; + eng->priv = mxic; + mxic->ecc.pipelined_engine = eng; + nand_ecc_register_on_host_hw_engine(eng); + + return 0; +} + static int __maybe_unused mxic_spi_runtime_suspend(struct device *dev) { struct spi_master *master = dev_get_drvdata(dev); @@ -656,6 +756,7 @@ static int mxic_spi_probe(struct platform_device *pdev) platform_set_drvdata(pdev, master); mxic = spi_master_get_devdata(master); + mxic->dev = &pdev->dev; master->dev.of_node = pdev->dev.of_node; @@ -702,6 +803,12 @@ static int mxic_spi_probe(struct platform_device *pdev) mxic_spi_hw_init(mxic); + ret = mxic_spi_mem_ecc_probe(pdev, mxic); + if (ret == -EPROBE_DEFER) { + pm_runtime_disable(&pdev->dev); + return ret; + } + ret = spi_register_master(master); if (ret) { dev_err(&pdev->dev, "spi_register_master failed\n"); @@ -714,8 +821,10 @@ static int mxic_spi_probe(struct platform_device *pdev) static int mxic_spi_remove(struct platform_device *pdev) { struct spi_master *master = platform_get_drvdata(pdev); + struct mxic_spi *mxic = spi_master_get_devdata(master); pm_runtime_disable(&pdev->dev); + mxic_spi_mem_ecc_remove(mxic); spi_unregister_master(master); return 0; diff --git a/include/linux/mtd/nand-ecc-mxic.h b/include/linux/mtd/nand-ecc-mxic.h index f3aa1ac82aed..b125926e458c 100644 --- a/include/linux/mtd/nand-ecc-mxic.h +++ b/include/linux/mtd/nand-ecc-mxic.h @@ -14,7 +14,7 @@ struct mxic_ecc_engine; -#if IS_ENABLED(CONFIG_MTD_NAND_ECC_MXIC) +#if IS_ENABLED(CONFIG_MTD_NAND_ECC_MXIC) && IS_REACHABLE(CONFIG_MTD_NAND_CORE) struct nand_ecc_engine_ops *mxic_ecc_get_pipelined_ops(void); struct nand_ecc_engine *mxic_ecc_get_pipelined_engine(struct platform_device *spi_pdev); diff --git a/include/linux/mtd/nand.h b/include/linux/mtd/nand.h index 615b3e3a3920..c3693bb87b4c 100644 --- a/include/linux/mtd/nand.h +++ b/include/linux/mtd/nand.h @@ -303,8 +303,23 @@ int nand_ecc_prepare_io_req(struct nand_device *nand, int nand_ecc_finish_io_req(struct nand_device *nand, struct nand_page_io_req *req); bool nand_ecc_is_strong_enough(struct nand_device *nand); + +#if IS_REACHABLE(CONFIG_MTD_NAND_CORE) int nand_ecc_register_on_host_hw_engine(struct nand_ecc_engine *engine); int nand_ecc_unregister_on_host_hw_engine(struct nand_ecc_engine *engine); +#else +static inline int +nand_ecc_register_on_host_hw_engine(struct nand_ecc_engine *engine) +{ + return -ENOTSUPP; +} +static inline int +nand_ecc_unregister_on_host_hw_engine(struct nand_ecc_engine *engine) +{ + return -ENOTSUPP; +} +#endif + struct nand_ecc_engine *nand_ecc_get_sw_engine(struct nand_device *nand); struct nand_ecc_engine *nand_ecc_get_on_die_hw_engine(struct nand_device *nand); struct nand_ecc_engine *nand_ecc_get_on_host_hw_engine(struct nand_device *nand); From 27c196c7b73cb70bbed3a9df46563bab60e63415 Mon Sep 17 00:00:00 2001 From: Terry Bowman Date: Wed, 9 Feb 2022 11:27:09 -0600 Subject: [PATCH 111/370] kernel/resource: Introduce request_mem_region_muxed() Support for requesting muxed memory region is implemented but not currently callable as a macro. Add the request muxed memory region macro. MMIO memory accesses can be synchronized using request_mem_region() which is already available. This call will return failure if the resource is busy. The 'muxed' version of this macro will handle a busy resource by using a wait queue to retry until the resource is available. Signed-off-by: Terry Bowman Reviewed-by: Andy Shevchenko Signed-off-by: Wolfram Sang --- include/linux/ioport.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/include/linux/ioport.h b/include/linux/ioport.h index 8359c50f9988..ec5f71f7135b 100644 --- a/include/linux/ioport.h +++ b/include/linux/ioport.h @@ -262,6 +262,8 @@ resource_union(struct resource *r1, struct resource *r2, struct resource *r) #define request_muxed_region(start,n,name) __request_region(&ioport_resource, (start), (n), (name), IORESOURCE_MUXED) #define __request_mem_region(start,n,name, excl) __request_region(&iomem_resource, (start), (n), (name), excl) #define request_mem_region(start,n,name) __request_region(&iomem_resource, (start), (n), (name), 0) +#define request_mem_region_muxed(start, n, name) \ + __request_region(&iomem_resource, (start), (n), (name), IORESOURCE_MUXED) #define request_mem_region_exclusive(start,n,name) \ __request_region(&iomem_resource, (start), (n), (name), IORESOURCE_EXCLUSIVE) #define rename_region(region, newname) do { (region)->name = (newname); } while (0) From 93102cb449780f7b4eecf713451627b78373ce49 Mon Sep 17 00:00:00 2001 From: Terry Bowman Date: Wed, 9 Feb 2022 11:27:10 -0600 Subject: [PATCH 112/370] i2c: piix4: Replace hardcoded memory map size with a #define Replace number constant with #define to improve readability and maintainability. Signed-off-by: Terry Bowman Reviewed-by: Andy Shevchenko Reviewed-by: Jean Delvare Signed-off-by: Wolfram Sang --- drivers/i2c/busses/i2c-piix4.c | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/drivers/i2c/busses/i2c-piix4.c b/drivers/i2c/busses/i2c-piix4.c index 8c1b31ed0c42..3ff68967034e 100644 --- a/drivers/i2c/busses/i2c-piix4.c +++ b/drivers/i2c/busses/i2c-piix4.c @@ -77,6 +77,7 @@ /* SB800 constants */ #define SB800_PIIX4_SMB_IDX 0xcd6 +#define SB800_PIIX4_SMB_MAP_SIZE 2 #define KERNCZ_IMC_IDX 0x3e #define KERNCZ_IMC_DATA 0x3f @@ -290,7 +291,8 @@ static int piix4_setup_sb800(struct pci_dev *PIIX4_dev, else smb_en = (aux) ? 0x28 : 0x2c; - if (!request_muxed_region(SB800_PIIX4_SMB_IDX, 2, "sb800_piix4_smb")) { + if (!request_muxed_region(SB800_PIIX4_SMB_IDX, SB800_PIIX4_SMB_MAP_SIZE, + "sb800_piix4_smb")) { dev_err(&PIIX4_dev->dev, "SMB base address index region 0x%x already in use.\n", SB800_PIIX4_SMB_IDX); @@ -302,7 +304,7 @@ static int piix4_setup_sb800(struct pci_dev *PIIX4_dev, outb_p(smb_en + 1, SB800_PIIX4_SMB_IDX); smba_en_hi = inb_p(SB800_PIIX4_SMB_IDX + 1); - release_region(SB800_PIIX4_SMB_IDX, 2); + release_region(SB800_PIIX4_SMB_IDX, SB800_PIIX4_SMB_MAP_SIZE); if (!smb_en) { smb_en_status = smba_en_lo & 0x10; @@ -371,7 +373,8 @@ static int piix4_setup_sb800(struct pci_dev *PIIX4_dev, piix4_port_shift_sb800 = SB800_PIIX4_PORT_IDX_SHIFT; } } else { - if (!request_muxed_region(SB800_PIIX4_SMB_IDX, 2, + if (!request_muxed_region(SB800_PIIX4_SMB_IDX, + SB800_PIIX4_SMB_MAP_SIZE, "sb800_piix4_smb")) { release_region(piix4_smba, SMBIOSIZE); return -EBUSY; @@ -384,7 +387,7 @@ static int piix4_setup_sb800(struct pci_dev *PIIX4_dev, SB800_PIIX4_PORT_IDX; piix4_port_mask_sb800 = SB800_PIIX4_PORT_IDX_MASK; piix4_port_shift_sb800 = SB800_PIIX4_PORT_IDX_SHIFT; - release_region(SB800_PIIX4_SMB_IDX, 2); + release_region(SB800_PIIX4_SMB_IDX, SB800_PIIX4_SMB_MAP_SIZE); } dev_info(&PIIX4_dev->dev, @@ -682,7 +685,8 @@ static s32 piix4_access_sb800(struct i2c_adapter *adap, u16 addr, u8 port; int retval; - if (!request_muxed_region(SB800_PIIX4_SMB_IDX, 2, "sb800_piix4_smb")) + if (!request_muxed_region(SB800_PIIX4_SMB_IDX, SB800_PIIX4_SMB_MAP_SIZE, + "sb800_piix4_smb")) return -EBUSY; /* Request the SMBUS semaphore, avoid conflicts with the IMC */ @@ -758,7 +762,7 @@ static s32 piix4_access_sb800(struct i2c_adapter *adap, u16 addr, piix4_imc_wakeup(); release: - release_region(SB800_PIIX4_SMB_IDX, 2); + release_region(SB800_PIIX4_SMB_IDX, SB800_PIIX4_SMB_MAP_SIZE); return retval; } From a3325d225b00889f4b7fdb25d83033cae1048a92 Mon Sep 17 00:00:00 2001 From: Terry Bowman Date: Wed, 9 Feb 2022 11:27:11 -0600 Subject: [PATCH 113/370] i2c: piix4: Move port I/O region request/release code into functions Move duplicated region request and release code into a function. Move is in preparation for following MMIO changes. Signed-off-by: Terry Bowman Reviewed-by: Andy Shevchenko Reviewed-by: Jean Delvare [wsa: added missing curly brace] Signed-off-by: Wolfram Sang --- drivers/i2c/busses/i2c-piix4.c | 48 ++++++++++++++++++++++------------ 1 file changed, 31 insertions(+), 17 deletions(-) diff --git a/drivers/i2c/busses/i2c-piix4.c b/drivers/i2c/busses/i2c-piix4.c index 3ff68967034e..39c4f5ce0cd9 100644 --- a/drivers/i2c/busses/i2c-piix4.c +++ b/drivers/i2c/busses/i2c-piix4.c @@ -165,6 +165,24 @@ struct i2c_piix4_adapdata { u8 port; /* Port number, shifted */ }; +static int piix4_sb800_region_request(struct device *dev) +{ + if (!request_muxed_region(SB800_PIIX4_SMB_IDX, SB800_PIIX4_SMB_MAP_SIZE, + "sb800_piix4_smb")) { + dev_err(dev, + "SMBus base address index region 0x%x already in use.\n", + SB800_PIIX4_SMB_IDX); + return -EBUSY; + } + + return 0; +} + +static void piix4_sb800_region_release(struct device *dev) +{ + release_region(SB800_PIIX4_SMB_IDX, SB800_PIIX4_SMB_MAP_SIZE); +} + static int piix4_setup(struct pci_dev *PIIX4_dev, const struct pci_device_id *id) { @@ -270,6 +288,7 @@ static int piix4_setup_sb800(struct pci_dev *PIIX4_dev, unsigned short piix4_smba; u8 smba_en_lo, smba_en_hi, smb_en, smb_en_status, port_sel; u8 i2ccfg, i2ccfg_offset = 0x10; + int retval; /* SB800 and later SMBus does not support forcing address */ if (force || force_addr) { @@ -291,20 +310,16 @@ static int piix4_setup_sb800(struct pci_dev *PIIX4_dev, else smb_en = (aux) ? 0x28 : 0x2c; - if (!request_muxed_region(SB800_PIIX4_SMB_IDX, SB800_PIIX4_SMB_MAP_SIZE, - "sb800_piix4_smb")) { - dev_err(&PIIX4_dev->dev, - "SMB base address index region 0x%x already in use.\n", - SB800_PIIX4_SMB_IDX); - return -EBUSY; - } + retval = piix4_sb800_region_request(&PIIX4_dev->dev); + if (retval) + return retval; outb_p(smb_en, SB800_PIIX4_SMB_IDX); smba_en_lo = inb_p(SB800_PIIX4_SMB_IDX + 1); outb_p(smb_en + 1, SB800_PIIX4_SMB_IDX); smba_en_hi = inb_p(SB800_PIIX4_SMB_IDX + 1); - release_region(SB800_PIIX4_SMB_IDX, SB800_PIIX4_SMB_MAP_SIZE); + piix4_sb800_region_release(&PIIX4_dev->dev); if (!smb_en) { smb_en_status = smba_en_lo & 0x10; @@ -373,11 +388,10 @@ static int piix4_setup_sb800(struct pci_dev *PIIX4_dev, piix4_port_shift_sb800 = SB800_PIIX4_PORT_IDX_SHIFT; } } else { - if (!request_muxed_region(SB800_PIIX4_SMB_IDX, - SB800_PIIX4_SMB_MAP_SIZE, - "sb800_piix4_smb")) { + retval = piix4_sb800_region_request(&PIIX4_dev->dev); + if (retval) { release_region(piix4_smba, SMBIOSIZE); - return -EBUSY; + return retval; } outb_p(SB800_PIIX4_PORT_IDX_SEL, SB800_PIIX4_SMB_IDX); @@ -387,7 +401,7 @@ static int piix4_setup_sb800(struct pci_dev *PIIX4_dev, SB800_PIIX4_PORT_IDX; piix4_port_mask_sb800 = SB800_PIIX4_PORT_IDX_MASK; piix4_port_shift_sb800 = SB800_PIIX4_PORT_IDX_SHIFT; - release_region(SB800_PIIX4_SMB_IDX, SB800_PIIX4_SMB_MAP_SIZE); + piix4_sb800_region_release(&PIIX4_dev->dev); } dev_info(&PIIX4_dev->dev, @@ -685,9 +699,9 @@ static s32 piix4_access_sb800(struct i2c_adapter *adap, u16 addr, u8 port; int retval; - if (!request_muxed_region(SB800_PIIX4_SMB_IDX, SB800_PIIX4_SMB_MAP_SIZE, - "sb800_piix4_smb")) - return -EBUSY; + retval = piix4_sb800_region_request(&adap->dev); + if (retval) + return retval; /* Request the SMBUS semaphore, avoid conflicts with the IMC */ smbslvcnt = inb_p(SMBSLVCNT); @@ -762,7 +776,7 @@ static s32 piix4_access_sb800(struct i2c_adapter *adap, u16 addr, piix4_imc_wakeup(); release: - release_region(SB800_PIIX4_SMB_IDX, SB800_PIIX4_SMB_MAP_SIZE); + piix4_sb800_region_release(&adap->dev); return retval; } From 0a59a24e14e9b21dcbb6b8ea41422e2fdfa437fd Mon Sep 17 00:00:00 2001 From: Terry Bowman Date: Wed, 9 Feb 2022 11:27:12 -0600 Subject: [PATCH 114/370] i2c: piix4: Move SMBus controller base address detect into function Move SMBus controller base address detection into function. Refactor is in preparation for following MMIO changes. Signed-off-by: Terry Bowman Reviewed-by: Andy Shevchenko Reviewed-by: Jean Delvare Signed-off-by: Wolfram Sang --- drivers/i2c/busses/i2c-piix4.c | 69 ++++++++++++++++++++++------------ 1 file changed, 44 insertions(+), 25 deletions(-) diff --git a/drivers/i2c/busses/i2c-piix4.c b/drivers/i2c/busses/i2c-piix4.c index 39c4f5ce0cd9..132ded733781 100644 --- a/drivers/i2c/busses/i2c-piix4.c +++ b/drivers/i2c/busses/i2c-piix4.c @@ -282,11 +282,51 @@ static int piix4_setup(struct pci_dev *PIIX4_dev, return piix4_smba; } +static int piix4_setup_sb800_smba(struct pci_dev *PIIX4_dev, + u8 smb_en, + u8 aux, + u8 *smb_en_status, + unsigned short *piix4_smba) +{ + u8 smba_en_lo; + u8 smba_en_hi; + int retval; + + retval = piix4_sb800_region_request(&PIIX4_dev->dev); + if (retval) + return retval; + + outb_p(smb_en, SB800_PIIX4_SMB_IDX); + smba_en_lo = inb_p(SB800_PIIX4_SMB_IDX + 1); + outb_p(smb_en + 1, SB800_PIIX4_SMB_IDX); + smba_en_hi = inb_p(SB800_PIIX4_SMB_IDX + 1); + + piix4_sb800_region_release(&PIIX4_dev->dev); + + if (!smb_en) { + *smb_en_status = smba_en_lo & 0x10; + *piix4_smba = smba_en_hi << 8; + if (aux) + *piix4_smba |= 0x20; + } else { + *smb_en_status = smba_en_lo & 0x01; + *piix4_smba = ((smba_en_hi << 8) | smba_en_lo) & 0xffe0; + } + + if (!*smb_en_status) { + dev_err(&PIIX4_dev->dev, + "SMBus Host Controller not enabled!\n"); + return -ENODEV; + } + + return 0; +} + static int piix4_setup_sb800(struct pci_dev *PIIX4_dev, const struct pci_device_id *id, u8 aux) { unsigned short piix4_smba; - u8 smba_en_lo, smba_en_hi, smb_en, smb_en_status, port_sel; + u8 smb_en, smb_en_status, port_sel; u8 i2ccfg, i2ccfg_offset = 0x10; int retval; @@ -310,33 +350,12 @@ static int piix4_setup_sb800(struct pci_dev *PIIX4_dev, else smb_en = (aux) ? 0x28 : 0x2c; - retval = piix4_sb800_region_request(&PIIX4_dev->dev); + retval = piix4_setup_sb800_smba(PIIX4_dev, smb_en, aux, &smb_en_status, + &piix4_smba); + if (retval) return retval; - outb_p(smb_en, SB800_PIIX4_SMB_IDX); - smba_en_lo = inb_p(SB800_PIIX4_SMB_IDX + 1); - outb_p(smb_en + 1, SB800_PIIX4_SMB_IDX); - smba_en_hi = inb_p(SB800_PIIX4_SMB_IDX + 1); - - piix4_sb800_region_release(&PIIX4_dev->dev); - - if (!smb_en) { - smb_en_status = smba_en_lo & 0x10; - piix4_smba = smba_en_hi << 8; - if (aux) - piix4_smba |= 0x20; - } else { - smb_en_status = smba_en_lo & 0x01; - piix4_smba = ((smba_en_hi << 8) | smba_en_lo) & 0xffe0; - } - - if (!smb_en_status) { - dev_err(&PIIX4_dev->dev, - "SMBus Host Controller not enabled!\n"); - return -ENODEV; - } - if (acpi_check_region(piix4_smba, SMBIOSIZE, piix4_driver.name)) return -ENODEV; From fbafbd51bff52cb3a920fd98d4dae2a78dd433d0 Mon Sep 17 00:00:00 2001 From: Terry Bowman Date: Wed, 9 Feb 2022 11:27:13 -0600 Subject: [PATCH 115/370] i2c: piix4: Move SMBus port selection into function Move port selection code into a separate function. Refactor is in preparation for following MMIO changes. Signed-off-by: Terry Bowman Reviewed-by: Andy Shevchenko Reviewed-by: Jean Delvare Signed-off-by: Wolfram Sang --- drivers/i2c/busses/i2c-piix4.c | 27 +++++++++++++++++---------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/drivers/i2c/busses/i2c-piix4.c b/drivers/i2c/busses/i2c-piix4.c index 132ded733781..efe51f67fdd6 100644 --- a/drivers/i2c/busses/i2c-piix4.c +++ b/drivers/i2c/busses/i2c-piix4.c @@ -698,6 +698,20 @@ static void piix4_imc_wakeup(void) release_region(KERNCZ_IMC_IDX, 2); } +static int piix4_sb800_port_sel(u8 port) +{ + u8 smba_en_lo, val; + + outb_p(piix4_port_sel_sb800, SB800_PIIX4_SMB_IDX); + smba_en_lo = inb_p(SB800_PIIX4_SMB_IDX + 1); + + val = (smba_en_lo & ~piix4_port_mask_sb800) | port; + if (smba_en_lo != val) + outb_p(val, SB800_PIIX4_SMB_IDX + 1); + + return (smba_en_lo & piix4_port_mask_sb800); +} + /* * Handles access to multiple SMBus ports on the SB800. * The port is selected by bits 2:1 of the smb_en register (0x2c). @@ -714,8 +728,7 @@ static s32 piix4_access_sb800(struct i2c_adapter *adap, u16 addr, unsigned short piix4_smba = adapdata->smba; int retries = MAX_TIMEOUT; int smbslvcnt; - u8 smba_en_lo; - u8 port; + u8 prev_port; int retval; retval = piix4_sb800_region_request(&adap->dev); @@ -775,18 +788,12 @@ static s32 piix4_access_sb800(struct i2c_adapter *adap, u16 addr, } } - outb_p(piix4_port_sel_sb800, SB800_PIIX4_SMB_IDX); - smba_en_lo = inb_p(SB800_PIIX4_SMB_IDX + 1); - - port = adapdata->port; - if ((smba_en_lo & piix4_port_mask_sb800) != port) - outb_p((smba_en_lo & ~piix4_port_mask_sb800) | port, - SB800_PIIX4_SMB_IDX + 1); + prev_port = piix4_sb800_port_sel(adapdata->port); retval = piix4_access(adap, addr, flags, read_write, command, size, data); - outb_p(smba_en_lo, SB800_PIIX4_SMB_IDX + 1); + piix4_sb800_port_sel(prev_port); /* Release the semaphore */ outb_p(smbslvcnt | 0x20, SMBSLVCNT); From 7c148722d074c29fb998578eea5de3c14b9608c9 Mon Sep 17 00:00:00 2001 From: Terry Bowman Date: Wed, 9 Feb 2022 11:27:14 -0600 Subject: [PATCH 116/370] i2c: piix4: Add EFCH MMIO support to region request and release EFCH cd6h/cd7h port I/O may no longer be available on later AMD processors and it is recommended to use MMIO instead. Update the request and release functions to support MMIO. MMIO request/release and mmapping require details during cleanup. Add a MMIO configuration structure containing resource and vaddress details for mapping the region, accessing the region, and releasing the region. Signed-off-by: Terry Bowman Reviewed-by: Andy Shevchenko Reviewed-by: Jean Delvare [wsa: rebased after fixup in previous patch] Signed-off-by: Wolfram Sang --- drivers/i2c/busses/i2c-piix4.c | 66 +++++++++++++++++++++++++++++----- 1 file changed, 58 insertions(+), 8 deletions(-) diff --git a/drivers/i2c/busses/i2c-piix4.c b/drivers/i2c/busses/i2c-piix4.c index efe51f67fdd6..d06998f7b031 100644 --- a/drivers/i2c/busses/i2c-piix4.c +++ b/drivers/i2c/busses/i2c-piix4.c @@ -98,6 +98,9 @@ #define SB800_PIIX4_PORT_IDX_MASK_KERNCZ 0x18 #define SB800_PIIX4_PORT_IDX_SHIFT_KERNCZ 3 +#define SB800_PIIX4_FCH_PM_ADDR 0xFED80300 +#define SB800_PIIX4_FCH_PM_SIZE 8 + /* insmod parameters */ /* If force is set to anything different from 0, we forcibly enable the @@ -156,6 +159,12 @@ static const char *piix4_main_port_names_sb800[PIIX4_MAX_ADAPTERS] = { }; static const char *piix4_aux_port_name_sb800 = " port 1"; +struct sb800_mmio_cfg { + void __iomem *addr; + struct resource *res; + bool use_mmio; +}; + struct i2c_piix4_adapdata { unsigned short smba; @@ -163,10 +172,40 @@ struct i2c_piix4_adapdata { bool sb800_main; bool notify_imc; u8 port; /* Port number, shifted */ + struct sb800_mmio_cfg mmio_cfg; }; -static int piix4_sb800_region_request(struct device *dev) +static int piix4_sb800_region_request(struct device *dev, + struct sb800_mmio_cfg *mmio_cfg) { + if (mmio_cfg->use_mmio) { + struct resource *res; + void __iomem *addr; + + res = request_mem_region_muxed(SB800_PIIX4_FCH_PM_ADDR, + SB800_PIIX4_FCH_PM_SIZE, + "sb800_piix4_smb"); + if (!res) { + dev_err(dev, + "SMBus base address memory region 0x%x already in use.\n", + SB800_PIIX4_FCH_PM_ADDR); + return -EBUSY; + } + + addr = ioremap(SB800_PIIX4_FCH_PM_ADDR, + SB800_PIIX4_FCH_PM_SIZE); + if (!addr) { + release_resource(res); + dev_err(dev, "SMBus base address mapping failed.\n"); + return -ENOMEM; + } + + mmio_cfg->res = res; + mmio_cfg->addr = addr; + + return 0; + } + if (!request_muxed_region(SB800_PIIX4_SMB_IDX, SB800_PIIX4_SMB_MAP_SIZE, "sb800_piix4_smb")) { dev_err(dev, @@ -178,8 +217,15 @@ static int piix4_sb800_region_request(struct device *dev) return 0; } -static void piix4_sb800_region_release(struct device *dev) +static void piix4_sb800_region_release(struct device *dev, + struct sb800_mmio_cfg *mmio_cfg) { + if (mmio_cfg->use_mmio) { + iounmap(mmio_cfg->addr); + release_resource(mmio_cfg->res); + return; + } + release_region(SB800_PIIX4_SMB_IDX, SB800_PIIX4_SMB_MAP_SIZE); } @@ -288,11 +334,13 @@ static int piix4_setup_sb800_smba(struct pci_dev *PIIX4_dev, u8 *smb_en_status, unsigned short *piix4_smba) { + struct sb800_mmio_cfg mmio_cfg; u8 smba_en_lo; u8 smba_en_hi; int retval; - retval = piix4_sb800_region_request(&PIIX4_dev->dev); + mmio_cfg.use_mmio = 0; + retval = piix4_sb800_region_request(&PIIX4_dev->dev, &mmio_cfg); if (retval) return retval; @@ -301,7 +349,7 @@ static int piix4_setup_sb800_smba(struct pci_dev *PIIX4_dev, outb_p(smb_en + 1, SB800_PIIX4_SMB_IDX); smba_en_hi = inb_p(SB800_PIIX4_SMB_IDX + 1); - piix4_sb800_region_release(&PIIX4_dev->dev); + piix4_sb800_region_release(&PIIX4_dev->dev, &mmio_cfg); if (!smb_en) { *smb_en_status = smba_en_lo & 0x10; @@ -328,6 +376,7 @@ static int piix4_setup_sb800(struct pci_dev *PIIX4_dev, unsigned short piix4_smba; u8 smb_en, smb_en_status, port_sel; u8 i2ccfg, i2ccfg_offset = 0x10; + struct sb800_mmio_cfg mmio_cfg; int retval; /* SB800 and later SMBus does not support forcing address */ @@ -407,7 +456,8 @@ static int piix4_setup_sb800(struct pci_dev *PIIX4_dev, piix4_port_shift_sb800 = SB800_PIIX4_PORT_IDX_SHIFT; } } else { - retval = piix4_sb800_region_request(&PIIX4_dev->dev); + mmio_cfg.use_mmio = 0; + retval = piix4_sb800_region_request(&PIIX4_dev->dev, &mmio_cfg); if (retval) { release_region(piix4_smba, SMBIOSIZE); return retval; @@ -420,7 +470,7 @@ static int piix4_setup_sb800(struct pci_dev *PIIX4_dev, SB800_PIIX4_PORT_IDX; piix4_port_mask_sb800 = SB800_PIIX4_PORT_IDX_MASK; piix4_port_shift_sb800 = SB800_PIIX4_PORT_IDX_SHIFT; - piix4_sb800_region_release(&PIIX4_dev->dev); + piix4_sb800_region_release(&PIIX4_dev->dev, &mmio_cfg); } dev_info(&PIIX4_dev->dev, @@ -731,7 +781,7 @@ static s32 piix4_access_sb800(struct i2c_adapter *adap, u16 addr, u8 prev_port; int retval; - retval = piix4_sb800_region_request(&adap->dev); + retval = piix4_sb800_region_request(&adap->dev, &adapdata->mmio_cfg); if (retval) return retval; @@ -802,7 +852,7 @@ static s32 piix4_access_sb800(struct i2c_adapter *adap, u16 addr, piix4_imc_wakeup(); release: - piix4_sb800_region_release(&adap->dev); + piix4_sb800_region_release(&adap->dev, &adapdata->mmio_cfg); return retval; } From 46967bc1ee93acd1d8953c87dc16f43de4076f93 Mon Sep 17 00:00:00 2001 From: Terry Bowman Date: Wed, 9 Feb 2022 11:27:15 -0600 Subject: [PATCH 117/370] i2c: piix4: Add EFCH MMIO support to SMBus base address detect The EFCH SMBus controller's base address is determined using details in FCH::PM::DECODEEN[smbusasfiobase] and FCH::PM::DECODEEN[smbusasfioen].These register fields were accessed using cd6h/cd7h port I/O. cd6h/cd7h port I/O is no longer available in later AMD processors. Change base address detection to use MMIO instead of port I/O cd6h/cd7h. Signed-off-by: Terry Bowman Reviewed-by: Andy Shevchenko Reviewed-by: Jean Delvare Signed-off-by: Wolfram Sang --- drivers/i2c/busses/i2c-piix4.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/drivers/i2c/busses/i2c-piix4.c b/drivers/i2c/busses/i2c-piix4.c index d06998f7b031..7f312177eb27 100644 --- a/drivers/i2c/busses/i2c-piix4.c +++ b/drivers/i2c/busses/i2c-piix4.c @@ -344,10 +344,15 @@ static int piix4_setup_sb800_smba(struct pci_dev *PIIX4_dev, if (retval) return retval; - outb_p(smb_en, SB800_PIIX4_SMB_IDX); - smba_en_lo = inb_p(SB800_PIIX4_SMB_IDX + 1); - outb_p(smb_en + 1, SB800_PIIX4_SMB_IDX); - smba_en_hi = inb_p(SB800_PIIX4_SMB_IDX + 1); + if (mmio_cfg.use_mmio) { + smba_en_lo = ioread8(mmio_cfg.addr); + smba_en_hi = ioread8(mmio_cfg.addr + 1); + } else { + outb_p(smb_en, SB800_PIIX4_SMB_IDX); + smba_en_lo = inb_p(SB800_PIIX4_SMB_IDX + 1); + outb_p(smb_en + 1, SB800_PIIX4_SMB_IDX); + smba_en_hi = inb_p(SB800_PIIX4_SMB_IDX + 1); + } piix4_sb800_region_release(&PIIX4_dev->dev, &mmio_cfg); From 381a3083c6747ae5cdbef9b176d57d1b966db49f Mon Sep 17 00:00:00 2001 From: Terry Bowman Date: Wed, 9 Feb 2022 11:27:16 -0600 Subject: [PATCH 118/370] i2c: piix4: Add EFCH MMIO support for SMBus port select AMD processors include registers capable of selecting between 2 SMBus ports. Port selection is made during each user access by writing to FCH::PM::DECODEEN[smbus0sel]. Change the driver to use MMIO during SMBus port selection because cd6h/cd7h port I/O is not available on later AMD processors. Signed-off-by: Terry Bowman Reviewed-by: Andy Shevchenko Reviewed-by: Jean Delvare Signed-off-by: Wolfram Sang --- drivers/i2c/busses/i2c-piix4.c | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/drivers/i2c/busses/i2c-piix4.c b/drivers/i2c/busses/i2c-piix4.c index 7f312177eb27..4789fc9ad270 100644 --- a/drivers/i2c/busses/i2c-piix4.c +++ b/drivers/i2c/busses/i2c-piix4.c @@ -753,10 +753,19 @@ static void piix4_imc_wakeup(void) release_region(KERNCZ_IMC_IDX, 2); } -static int piix4_sb800_port_sel(u8 port) +static int piix4_sb800_port_sel(u8 port, struct sb800_mmio_cfg *mmio_cfg) { u8 smba_en_lo, val; + if (mmio_cfg->use_mmio) { + smba_en_lo = ioread8(mmio_cfg->addr + piix4_port_sel_sb800); + val = (smba_en_lo & ~piix4_port_mask_sb800) | port; + if (smba_en_lo != val) + iowrite8(val, mmio_cfg->addr + piix4_port_sel_sb800); + + return (smba_en_lo & piix4_port_mask_sb800); + } + outb_p(piix4_port_sel_sb800, SB800_PIIX4_SMB_IDX); smba_en_lo = inb_p(SB800_PIIX4_SMB_IDX + 1); @@ -843,12 +852,12 @@ static s32 piix4_access_sb800(struct i2c_adapter *adap, u16 addr, } } - prev_port = piix4_sb800_port_sel(adapdata->port); + prev_port = piix4_sb800_port_sel(adapdata->port, &adapdata->mmio_cfg); retval = piix4_access(adap, addr, flags, read_write, command, size, data); - piix4_sb800_port_sel(prev_port); + piix4_sb800_port_sel(prev_port, &adapdata->mmio_cfg); /* Release the semaphore */ outb_p(smbslvcnt | 0x20, SMBSLVCNT); From 6cf72f41808ab5db1d7718b999b3ff0166e67e45 Mon Sep 17 00:00:00 2001 From: Terry Bowman Date: Wed, 9 Feb 2022 11:27:17 -0600 Subject: [PATCH 119/370] i2c: piix4: Enable EFCH MMIO for Family 17h+ Enable EFCH MMIO using check for SMBus PCI revision ID value 0x51 or greater. This PCI revision ID check will enable family 17h and future AMD processors with the same EFCH SMBus controller HW. Signed-off-by: Terry Bowman Reviewed-by: Andy Shevchenko Reviewed-by: Jean Delvare Signed-off-by: Wolfram Sang --- drivers/i2c/busses/i2c-piix4.c | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/drivers/i2c/busses/i2c-piix4.c b/drivers/i2c/busses/i2c-piix4.c index 4789fc9ad270..ac8e7d60672a 100644 --- a/drivers/i2c/busses/i2c-piix4.c +++ b/drivers/i2c/busses/i2c-piix4.c @@ -229,6 +229,18 @@ static void piix4_sb800_region_release(struct device *dev, release_region(SB800_PIIX4_SMB_IDX, SB800_PIIX4_SMB_MAP_SIZE); } +static bool piix4_sb800_use_mmio(struct pci_dev *PIIX4_dev) +{ + /* + * cd6h/cd7h port I/O accesses can be disabled on AMD processors + * w/ SMBus PCI revision ID 0x51 or greater. MMIO is supported on + * the same processors and is the recommended access method. + */ + return (PIIX4_dev->vendor == PCI_VENDOR_ID_AMD && + PIIX4_dev->device == PCI_DEVICE_ID_AMD_KERNCZ_SMBUS && + PIIX4_dev->revision >= 0x51); +} + static int piix4_setup(struct pci_dev *PIIX4_dev, const struct pci_device_id *id) { @@ -339,7 +351,7 @@ static int piix4_setup_sb800_smba(struct pci_dev *PIIX4_dev, u8 smba_en_hi; int retval; - mmio_cfg.use_mmio = 0; + mmio_cfg.use_mmio = piix4_sb800_use_mmio(PIIX4_dev); retval = piix4_sb800_region_request(&PIIX4_dev->dev, &mmio_cfg); if (retval) return retval; @@ -461,7 +473,7 @@ static int piix4_setup_sb800(struct pci_dev *PIIX4_dev, piix4_port_shift_sb800 = SB800_PIIX4_PORT_IDX_SHIFT; } } else { - mmio_cfg.use_mmio = 0; + mmio_cfg.use_mmio = piix4_sb800_use_mmio(PIIX4_dev); retval = piix4_sb800_region_request(&PIIX4_dev->dev, &mmio_cfg); if (retval) { release_region(piix4_smba, SMBIOSIZE); @@ -944,6 +956,7 @@ static int piix4_add_adapter(struct pci_dev *dev, unsigned short smba, return -ENOMEM; } + adapdata->mmio_cfg.use_mmio = piix4_sb800_use_mmio(dev); adapdata->smba = smba; adapdata->sb800_main = sb800_main; adapdata->port = port << piix4_port_shift_sb800; From 6960331dee17ee54d1b6188f0f4fc9537279d514 Mon Sep 17 00:00:00 2001 From: Jan Dabros Date: Tue, 8 Feb 2022 15:12:17 +0100 Subject: [PATCH 120/370] i2c: designware: Add missing locks All accesses to controller's registers should be protected on probe, disable and xfer paths. This is needed for i2c bus controllers that are shared with but not controller by kernel. Signed-off-by: Jan Dabros Reviewed-by: Hans de Goede Acked-by: Jarkko Nikula Tested-by: Jarkko Nikula Reviewed-by: Andy Shevchenko Signed-off-by: Wolfram Sang --- drivers/i2c/busses/i2c-designware-common.c | 12 ++++++++++++ drivers/i2c/busses/i2c-designware-master.c | 6 ++++++ 2 files changed, 18 insertions(+) diff --git a/drivers/i2c/busses/i2c-designware-common.c b/drivers/i2c/busses/i2c-designware-common.c index bf2a4920638a..9f8574320eb2 100644 --- a/drivers/i2c/busses/i2c-designware-common.c +++ b/drivers/i2c/busses/i2c-designware-common.c @@ -578,7 +578,12 @@ int i2c_dw_set_fifo_size(struct dw_i2c_dev *dev) * Try to detect the FIFO depth if not set by interface driver, * the depth could be from 2 to 256 from HW spec. */ + ret = i2c_dw_acquire_lock(dev); + if (ret) + return ret; + ret = regmap_read(dev->map, DW_IC_COMP_PARAM_1, ¶m); + i2c_dw_release_lock(dev); if (ret) return ret; @@ -607,6 +612,11 @@ u32 i2c_dw_func(struct i2c_adapter *adap) void i2c_dw_disable(struct dw_i2c_dev *dev) { u32 dummy; + int ret; + + ret = i2c_dw_acquire_lock(dev); + if (ret) + return; /* Disable controller */ __i2c_dw_disable(dev); @@ -614,6 +624,8 @@ void i2c_dw_disable(struct dw_i2c_dev *dev) /* Disable all interrupts */ regmap_write(dev->map, DW_IC_INTR_MASK, 0); regmap_read(dev->map, DW_IC_CLR_INTR, &dummy); + + i2c_dw_release_lock(dev); } void i2c_dw_disable_int(struct dw_i2c_dev *dev) diff --git a/drivers/i2c/busses/i2c-designware-master.c b/drivers/i2c/busses/i2c-designware-master.c index 9177463c2cbb..1a4b23556db3 100644 --- a/drivers/i2c/busses/i2c-designware-master.c +++ b/drivers/i2c/busses/i2c-designware-master.c @@ -905,7 +905,13 @@ int i2c_dw_probe_master(struct dw_i2c_dev *dev) irq_flags = IRQF_SHARED | IRQF_COND_SUSPEND; } + ret = i2c_dw_acquire_lock(dev); + if (ret) + return ret; + i2c_dw_disable_int(dev); + i2c_dw_release_lock(dev); + ret = devm_request_irq(dev->dev, dev->irq, i2c_dw_isr, irq_flags, dev_name(dev->dev), dev); if (ret) { From 78d5e9e299e31bc2deaaa94a45bf8ea024f27e8c Mon Sep 17 00:00:00 2001 From: Jan Dabros Date: Tue, 8 Feb 2022 15:12:18 +0100 Subject: [PATCH 121/370] i2c: designware: Add AMD PSP I2C bus support Implement an I2C controller sharing mechanism between the host (kernel) and PSP co-processor on some platforms equipped with AMD Cezanne SoC. On these platforms we need to implement "software" i2c arbitration. Default arbitration owner is PSP and kernel asks for acquire as well as inform about release of the i2c bus via mailbox mechanism. +---------+ <- ACQUIRE | | +---------| CPU |\ | | | \ +----------+ SDA | +---------+ \ | |------- MAILBOX +--> | I2C-DW | SCL | +---------+ | |------- | | | +----------+ +---------| PSP | <- ACK | | +---------+ +---------+ <- RELEASE | | +---------| CPU | | | | +----------+ SDA | +---------+ | |------- MAILBOX +--> | I2C-DW | SCL | +---------+ / | |------- | | | / +----------+ +---------| PSP |/ <- ACK | | +---------+ The solution is similar to i2c-designware-baytrail.c implementation, where we are using a generic i2c-designware-* driver with a small "wrapper". In contrary to baytrail semaphore implementation, beside internal acquire_lock() and release_lock() methods we are also applying quirks to lock_bus() and unlock_bus() global adapter methods. With this in place all i2c clients drivers may lock i2c bus for a desired number of i2c transactions (e.g. write-wait-read) without being aware of that such bus is shared with another entity. Modify i2c_dw_probe_lock_support() to select correct semaphore implementation at runtime, since now we have more than one available. Configure new matching ACPI ID "AMDI0019" and register ARBITRATION_SEMAPHORE flag in order to distinguish setup with PSP arbitration. Add myself as a reviewer for I2C DesignWare in order to help with reviewing and testing possible changes touching new i2c-designware-amdpsp.c module. Signed-off-by: Jan Dabros Reviewed-by: Andy Shevchenko Acked-by: Jarkko Nikula Tested-by: Jarkko Nikula [wsa: removed unneeded blank line and curly braces] Signed-off-by: Wolfram Sang --- MAINTAINERS | 1 + drivers/acpi/acpi_apd.c | 7 +- drivers/i2c/busses/Kconfig | 11 + drivers/i2c/busses/Makefile | 1 + drivers/i2c/busses/i2c-designware-amdpsp.c | 392 +++++++++++++++++++ drivers/i2c/busses/i2c-designware-baytrail.c | 12 +- drivers/i2c/busses/i2c-designware-core.h | 18 +- drivers/i2c/busses/i2c-designware-platdrv.c | 60 +++ 8 files changed, 490 insertions(+), 12 deletions(-) create mode 100644 drivers/i2c/busses/i2c-designware-amdpsp.c diff --git a/MAINTAINERS b/MAINTAINERS index ea3e6c914384..c2e76d94cc18 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -18660,6 +18660,7 @@ SYNOPSYS DESIGNWARE I2C DRIVER M: Jarkko Nikula R: Andy Shevchenko R: Mika Westerberg +R: Jan Dabros L: linux-i2c@vger.kernel.org S: Maintained F: drivers/i2c/busses/i2c-designware-* diff --git a/drivers/acpi/acpi_apd.c b/drivers/acpi/acpi_apd.c index e7934ba79b02..ad245bbd965e 100644 --- a/drivers/acpi/acpi_apd.c +++ b/drivers/acpi/acpi_apd.c @@ -232,12 +232,13 @@ static const struct acpi_device_id acpi_apd_device_ids[] = { /* Generic apd devices */ #ifdef CONFIG_X86_AMD_PLATFORM_DEVICE { "AMD0010", APD_ADDR(cz_i2c_desc) }, - { "AMDI0010", APD_ADDR(wt_i2c_desc) }, { "AMD0020", APD_ADDR(cz_uart_desc) }, - { "AMDI0020", APD_ADDR(cz_uart_desc) }, - { "AMDI0022", APD_ADDR(cz_uart_desc) }, { "AMD0030", }, { "AMD0040", APD_ADDR(fch_misc_desc)}, + { "AMDI0010", APD_ADDR(wt_i2c_desc) }, + { "AMDI0019", APD_ADDR(wt_i2c_desc) }, + { "AMDI0020", APD_ADDR(cz_uart_desc) }, + { "AMDI0022", APD_ADDR(cz_uart_desc) }, { "HYGO0010", APD_ADDR(wt_i2c_desc) }, #endif #ifdef CONFIG_ARM64 diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig index 42da31c1ab70..5ea26a7aa1d5 100644 --- a/drivers/i2c/busses/Kconfig +++ b/drivers/i2c/busses/Kconfig @@ -553,6 +553,17 @@ config I2C_DESIGNWARE_PLATFORM This driver can also be built as a module. If so, the module will be called i2c-designware-platform. +config I2C_DESIGNWARE_AMDPSP + bool "AMD PSP I2C semaphore support" + depends on X86_MSR + depends on ACPI + depends on I2C_DESIGNWARE_PLATFORM + help + This driver enables managed host access to the selected I2C bus shared + between AMD CPU and AMD PSP. + + You should say Y if running on an AMD system equipped with the PSP. + config I2C_DESIGNWARE_BAYTRAIL bool "Intel Baytrail I2C semaphore support" depends on ACPI diff --git a/drivers/i2c/busses/Makefile b/drivers/i2c/busses/Makefile index 1d00dce77098..752f47be3fc1 100644 --- a/drivers/i2c/busses/Makefile +++ b/drivers/i2c/busses/Makefile @@ -54,6 +54,7 @@ i2c-designware-core-y += i2c-designware-master.o i2c-designware-core-$(CONFIG_I2C_DESIGNWARE_SLAVE) += i2c-designware-slave.o obj-$(CONFIG_I2C_DESIGNWARE_PLATFORM) += i2c-designware-platform.o i2c-designware-platform-y := i2c-designware-platdrv.o +i2c-designware-platform-$(CONFIG_I2C_DESIGNWARE_AMDPSP) += i2c-designware-amdpsp.o i2c-designware-platform-$(CONFIG_I2C_DESIGNWARE_BAYTRAIL) += i2c-designware-baytrail.o obj-$(CONFIG_I2C_DESIGNWARE_PCI) += i2c-designware-pci.o i2c-designware-pci-y := i2c-designware-pcidrv.o diff --git a/drivers/i2c/busses/i2c-designware-amdpsp.c b/drivers/i2c/busses/i2c-designware-amdpsp.c new file mode 100644 index 000000000000..752e0024db03 --- /dev/null +++ b/drivers/i2c/busses/i2c-designware-amdpsp.c @@ -0,0 +1,392 @@ +// SPDX-License-Identifier: GPL-2.0 + +#include +#include +#include +#include +#include +#include + +#include + +#include "i2c-designware-core.h" + +#define MSR_AMD_PSP_ADDR 0xc00110a2 +#define PSP_MBOX_OFFSET 0x10570 +#define PSP_CMD_TIMEOUT_US (500 * USEC_PER_MSEC) + +#define PSP_I2C_REQ_BUS_CMD 0x64 +#define PSP_I2C_REQ_RETRY_CNT 10 +#define PSP_I2C_REQ_RETRY_DELAY_US (50 * USEC_PER_MSEC) +#define PSP_I2C_REQ_STS_OK 0x0 +#define PSP_I2C_REQ_STS_BUS_BUSY 0x1 +#define PSP_I2C_REQ_STS_INV_PARAM 0x3 + +#define PSP_MBOX_FIELDS_STS GENMASK(15, 0) +#define PSP_MBOX_FIELDS_CMD GENMASK(23, 16) +#define PSP_MBOX_FIELDS_RESERVED GENMASK(29, 24) +#define PSP_MBOX_FIELDS_RECOVERY BIT(30) +#define PSP_MBOX_FIELDS_READY BIT(31) + +struct psp_req_buffer_hdr { + u32 total_size; + u32 status; +}; + +enum psp_i2c_req_type { + PSP_I2C_REQ_ACQUIRE, + PSP_I2C_REQ_RELEASE, + PSP_I2C_REQ_MAX +}; + +struct psp_i2c_req { + struct psp_req_buffer_hdr hdr; + enum psp_i2c_req_type type; +}; + +struct psp_mbox { + u32 cmd_fields; + u64 i2c_req_addr; +} __packed; + +static DEFINE_MUTEX(psp_i2c_access_mutex); +static unsigned long psp_i2c_sem_acquired; +static void __iomem *mbox_iomem; +static u32 psp_i2c_access_count; +static bool psp_i2c_mbox_fail; +static struct device *psp_i2c_dev; + +/* + * Implementation of PSP-x86 i2c-arbitration mailbox introduced for AMD Cezanne + * family of SoCs. + */ + +static int psp_get_mbox_addr(unsigned long *mbox_addr) +{ + unsigned long long psp_mmio; + + if (rdmsrl_safe(MSR_AMD_PSP_ADDR, &psp_mmio)) + return -EIO; + + *mbox_addr = (unsigned long)(psp_mmio + PSP_MBOX_OFFSET); + + return 0; +} + +static int psp_mbox_probe(void) +{ + unsigned long mbox_addr; + int ret; + + ret = psp_get_mbox_addr(&mbox_addr); + if (ret) + return ret; + + mbox_iomem = ioremap(mbox_addr, sizeof(struct psp_mbox)); + if (!mbox_iomem) + return -ENOMEM; + + return 0; +} + +/* Recovery field should be equal 0 to start sending commands */ +static int psp_check_mbox_recovery(struct psp_mbox __iomem *mbox) +{ + u32 tmp; + + tmp = readl(&mbox->cmd_fields); + + return FIELD_GET(PSP_MBOX_FIELDS_RECOVERY, tmp); +} + +static int psp_wait_cmd(struct psp_mbox __iomem *mbox) +{ + u32 tmp, expected; + + /* Expect mbox_cmd to be cleared and ready bit to be set by PSP */ + expected = FIELD_PREP(PSP_MBOX_FIELDS_READY, 1); + + /* + * Check for readiness of PSP mailbox in a tight loop in order to + * process further as soon as command was consumed. + */ + return readl_poll_timeout(&mbox->cmd_fields, tmp, (tmp == expected), + 0, PSP_CMD_TIMEOUT_US); +} + +/* Status equal to 0 means that PSP succeed processing command */ +static u32 psp_check_mbox_sts(struct psp_mbox __iomem *mbox) +{ + u32 cmd_reg; + + cmd_reg = readl(&mbox->cmd_fields); + + return FIELD_GET(PSP_MBOX_FIELDS_STS, cmd_reg); +} + +static int psp_send_cmd(struct psp_i2c_req *req) +{ + struct psp_mbox __iomem *mbox = mbox_iomem; + phys_addr_t req_addr; + u32 cmd_reg; + + if (psp_check_mbox_recovery(mbox)) + return -EIO; + + if (psp_wait_cmd(mbox)) + return -EBUSY; + + /* + * Fill mailbox with address of command-response buffer, which will be + * used for sending i2c requests as well as reading status returned by + * PSP. Use physical address of buffer, since PSP will map this region. + */ + req_addr = __psp_pa((void *)req); + writeq(req_addr, &mbox->i2c_req_addr); + + /* Write command register to trigger processing */ + cmd_reg = FIELD_PREP(PSP_MBOX_FIELDS_CMD, PSP_I2C_REQ_BUS_CMD); + writel(cmd_reg, &mbox->cmd_fields); + + if (psp_wait_cmd(mbox)) + return -ETIMEDOUT; + + if (psp_check_mbox_sts(mbox)) + return -EIO; + + return 0; +} + +/* Helper to verify status returned by PSP */ +static int check_i2c_req_sts(struct psp_i2c_req *req) +{ + int status; + + status = readl(&req->hdr.status); + + switch (status) { + case PSP_I2C_REQ_STS_OK: + return 0; + case PSP_I2C_REQ_STS_BUS_BUSY: + return -EBUSY; + case PSP_I2C_REQ_STS_INV_PARAM: + default: + return -EIO; + }; +} + +static int psp_send_check_i2c_req(struct psp_i2c_req *req) +{ + /* + * Errors in x86-PSP i2c-arbitration protocol may occur at two levels: + * 1. mailbox communication - PSP is not operational or some IO errors + * with basic communication had happened; + * 2. i2c-requests - PSP refuses to grant i2c arbitration to x86 for too + * long. + * In order to distinguish between these two in error handling code, all + * errors on the first level (returned by psp_send_cmd) are shadowed by + * -EIO. + */ + if (psp_send_cmd(req)) + return -EIO; + + return check_i2c_req_sts(req); +} + +static int psp_send_i2c_req(enum psp_i2c_req_type i2c_req_type) +{ + struct psp_i2c_req *req; + unsigned long start; + int status, ret; + + /* Allocate command-response buffer */ + req = kzalloc(sizeof(*req), GFP_KERNEL); + if (!req) + return -ENOMEM; + + req->hdr.total_size = sizeof(*req); + req->type = i2c_req_type; + + start = jiffies; + ret = read_poll_timeout(psp_send_check_i2c_req, status, + (status != -EBUSY), + PSP_I2C_REQ_RETRY_DELAY_US, + PSP_I2C_REQ_RETRY_CNT * PSP_I2C_REQ_RETRY_DELAY_US, + 0, req); + if (ret) + goto cleanup; + + ret = status; + if (ret) + goto cleanup; + + dev_dbg(psp_i2c_dev, "Request accepted by PSP after %ums\n", + jiffies_to_msecs(jiffies - start)); + +cleanup: + kfree(req); + return ret; +} + +static int psp_acquire_i2c_bus(void) +{ + int status; + + mutex_lock(&psp_i2c_access_mutex); + + /* Return early if mailbox malfunctioned */ + if (psp_i2c_mbox_fail) + goto cleanup; + + /* + * Simply increment usage counter and return if PSP semaphore was + * already taken by kernel. + */ + if (psp_i2c_access_count) { + psp_i2c_access_count++; + goto cleanup; + }; + + status = psp_send_i2c_req(PSP_I2C_REQ_ACQUIRE); + if (status) { + if (status == -ETIMEDOUT) + dev_err(psp_i2c_dev, "Timed out waiting for PSP to release I2C bus\n"); + else + dev_err(psp_i2c_dev, "PSP communication error\n"); + + dev_err(psp_i2c_dev, "Assume i2c bus is for exclusive host usage\n"); + psp_i2c_mbox_fail = true; + goto cleanup; + } + + psp_i2c_sem_acquired = jiffies; + psp_i2c_access_count++; + + /* + * In case of errors with PSP arbitrator psp_i2c_mbox_fail variable is + * set above. As a consequence consecutive calls to acquire will bypass + * communication with PSP. At any case i2c bus is granted to the caller, + * thus always return success. + */ +cleanup: + mutex_unlock(&psp_i2c_access_mutex); + return 0; +} + +static void psp_release_i2c_bus(void) +{ + int status; + + mutex_lock(&psp_i2c_access_mutex); + + /* Return early if mailbox was malfunctional */ + if (psp_i2c_mbox_fail) + goto cleanup; + + /* + * If we are last owner of PSP semaphore, need to release aribtration + * via mailbox. + */ + psp_i2c_access_count--; + if (psp_i2c_access_count) + goto cleanup; + + /* Send a release command to PSP */ + status = psp_send_i2c_req(PSP_I2C_REQ_RELEASE); + if (status) { + if (status == -ETIMEDOUT) + dev_err(psp_i2c_dev, "Timed out waiting for PSP to acquire I2C bus\n"); + else + dev_err(psp_i2c_dev, "PSP communication error\n"); + + dev_err(psp_i2c_dev, "Assume i2c bus is for exclusive host usage\n"); + psp_i2c_mbox_fail = true; + goto cleanup; + } + + dev_dbg(psp_i2c_dev, "PSP semaphore held for %ums\n", + jiffies_to_msecs(jiffies - psp_i2c_sem_acquired)); + +cleanup: + mutex_unlock(&psp_i2c_access_mutex); +} + +/* + * Locking methods are based on the default implementation from + * drivers/i2c/i2c-core-base.c, but with psp acquire and release operations + * added. With this in place we can ensure that i2c clients on the bus shared + * with psp are able to lock HW access to the bus for arbitrary number of + * operations - that is e.g. write-wait-read. + */ +static void i2c_adapter_dw_psp_lock_bus(struct i2c_adapter *adapter, + unsigned int flags) +{ + psp_acquire_i2c_bus(); + rt_mutex_lock_nested(&adapter->bus_lock, i2c_adapter_depth(adapter)); +} + +static int i2c_adapter_dw_psp_trylock_bus(struct i2c_adapter *adapter, + unsigned int flags) +{ + int ret; + + ret = rt_mutex_trylock(&adapter->bus_lock); + if (ret) + return ret; + + psp_acquire_i2c_bus(); + + return ret; +} + +static void i2c_adapter_dw_psp_unlock_bus(struct i2c_adapter *adapter, + unsigned int flags) +{ + psp_release_i2c_bus(); + rt_mutex_unlock(&adapter->bus_lock); +} + +static const struct i2c_lock_operations i2c_dw_psp_lock_ops = { + .lock_bus = i2c_adapter_dw_psp_lock_bus, + .trylock_bus = i2c_adapter_dw_psp_trylock_bus, + .unlock_bus = i2c_adapter_dw_psp_unlock_bus, +}; + +int i2c_dw_amdpsp_probe_lock_support(struct dw_i2c_dev *dev) +{ + int ret; + + if (!dev) + return -ENODEV; + + if (!(dev->flags & ARBITRATION_SEMAPHORE)) + return -ENODEV; + + /* Allow to bind only one instance of a driver */ + if (psp_i2c_dev) + return -EEXIST; + + psp_i2c_dev = dev->dev; + + ret = psp_mbox_probe(); + if (ret) + return ret; + + dev_info(psp_i2c_dev, "I2C bus managed by AMD PSP\n"); + + /* + * Install global locking callbacks for adapter as well as internal i2c + * controller locks. + */ + dev->adapter.lock_ops = &i2c_dw_psp_lock_ops; + dev->acquire_lock = psp_acquire_i2c_bus; + dev->release_lock = psp_release_i2c_bus; + + return 0; +} + +/* Unmap area used as a mailbox with PSP */ +void i2c_dw_amdpsp_remove_lock_support(struct dw_i2c_dev *dev) +{ + iounmap(mbox_iomem); +} diff --git a/drivers/i2c/busses/i2c-designware-baytrail.c b/drivers/i2c/busses/i2c-designware-baytrail.c index c6a7a00e1d52..45774aa47c28 100644 --- a/drivers/i2c/busses/i2c-designware-baytrail.c +++ b/drivers/i2c/busses/i2c-designware-baytrail.c @@ -12,25 +12,25 @@ #include "i2c-designware-core.h" -int i2c_dw_probe_lock_support(struct dw_i2c_dev *dev) +int i2c_dw_baytrail_probe_lock_support(struct dw_i2c_dev *dev) { acpi_status status; unsigned long long shared_host = 0; acpi_handle handle; - if (!dev || !dev->dev) - return 0; + if (!dev) + return -ENODEV; handle = ACPI_HANDLE(dev->dev); if (!handle) - return 0; + return -ENODEV; status = acpi_evaluate_integer(handle, "_SEM", NULL, &shared_host); if (ACPI_FAILURE(status)) - return 0; + return -ENODEV; if (!shared_host) - return 0; + return -ENODEV; if (!iosf_mbi_available()) return -EPROBE_DEFER; diff --git a/drivers/i2c/busses/i2c-designware-core.h b/drivers/i2c/busses/i2c-designware-core.h index 4b26cba40139..1d65212fddbd 100644 --- a/drivers/i2c/busses/i2c-designware-core.h +++ b/drivers/i2c/busses/i2c-designware-core.h @@ -227,6 +227,8 @@ struct reset_control; * @hs_lcnt: high speed LCNT value * @acquire_lock: function to acquire a hardware lock on the bus * @release_lock: function to release a hardware lock on the bus + * @semaphore_idx: Index of table with semaphore type attached to the bus. It's + * -1 if there is no semaphore. * @shared_with_punit: true if this bus is shared with the SoCs PUNIT * @disable: function to disable the controller * @disable_int: function to disable all interrupts @@ -285,6 +287,7 @@ struct dw_i2c_dev { u16 hs_lcnt; int (*acquire_lock)(void); void (*release_lock)(void); + int semaphore_idx; bool shared_with_punit; void (*disable)(struct dw_i2c_dev *dev); void (*disable_int)(struct dw_i2c_dev *dev); @@ -297,6 +300,7 @@ struct dw_i2c_dev { #define ACCESS_INTR_MASK BIT(0) #define ACCESS_NO_IRQ_SUSPEND BIT(1) +#define ARBITRATION_SEMAPHORE BIT(2) #define MODEL_MSCC_OCELOT BIT(8) #define MODEL_BAIKAL_BT1 BIT(9) @@ -310,6 +314,11 @@ struct dw_i2c_dev { #define AMD_UCSI_INTR_REG 0x474 #define AMD_UCSI_INTR_EN 0xd +struct i2c_dw_semaphore_callbacks { + int (*probe)(struct dw_i2c_dev *dev); + void (*remove)(struct dw_i2c_dev *dev); +}; + int i2c_dw_init_regmap(struct dw_i2c_dev *dev); u32 i2c_dw_scl_hcnt(u32 ic_clk, u32 tSYMBOL, u32 tf, int cond, int offset); u32 i2c_dw_scl_lcnt(u32 ic_clk, u32 tLOW, u32 tf, int offset); @@ -370,9 +379,12 @@ static inline void i2c_dw_configure(struct dw_i2c_dev *dev) } #if IS_ENABLED(CONFIG_I2C_DESIGNWARE_BAYTRAIL) -extern int i2c_dw_probe_lock_support(struct dw_i2c_dev *dev); -#else -static inline int i2c_dw_probe_lock_support(struct dw_i2c_dev *dev) { return 0; } +int i2c_dw_baytrail_probe_lock_support(struct dw_i2c_dev *dev); +#endif + +#if IS_ENABLED(CONFIG_I2C_DESIGNWARE_AMDPSP) +int i2c_dw_amdpsp_probe_lock_support(struct dw_i2c_dev *dev); +void i2c_dw_amdpsp_remove_lock_support(struct dw_i2c_dev *dev); #endif int i2c_dw_validate_speed(struct dw_i2c_dev *dev); diff --git a/drivers/i2c/busses/i2c-designware-platdrv.c b/drivers/i2c/busses/i2c-designware-platdrv.c index 2bd81abc86f6..9973ac894a51 100644 --- a/drivers/i2c/busses/i2c-designware-platdrv.c +++ b/drivers/i2c/busses/i2c-designware-platdrv.c @@ -50,6 +50,7 @@ static const struct acpi_device_id dw_i2c_acpi_match[] = { { "808622C1", ACCESS_NO_IRQ_SUSPEND }, { "AMD0010", ACCESS_INTR_MASK }, { "AMDI0010", ACCESS_INTR_MASK }, + { "AMDI0019", ACCESS_INTR_MASK | ARBITRATION_SEMAPHORE }, { "AMDI0510", 0 }, { "APMC0D0F", 0 }, { "HISI02A1", 0 }, @@ -204,6 +205,63 @@ static const struct dmi_system_id dw_i2c_hwmon_class_dmi[] = { { } /* terminate list */ }; +static const struct i2c_dw_semaphore_callbacks i2c_dw_semaphore_cb_table[] = { +#ifdef CONFIG_I2C_DESIGNWARE_BAYTRAIL + { + .probe = i2c_dw_baytrail_probe_lock_support, + }, +#endif +#ifdef CONFIG_I2C_DESIGNWARE_AMDPSP + { + .probe = i2c_dw_amdpsp_probe_lock_support, + .remove = i2c_dw_amdpsp_remove_lock_support, + }, +#endif + {} +}; + +static int i2c_dw_probe_lock_support(struct dw_i2c_dev *dev) +{ + const struct i2c_dw_semaphore_callbacks *ptr; + int i = 0; + int ret; + + ptr = i2c_dw_semaphore_cb_table; + + dev->semaphore_idx = -1; + + while (ptr->probe) { + ret = ptr->probe(dev); + if (ret) { + /* + * If there is no semaphore device attached to this + * controller, we shouldn't abort general i2c_controller + * probe. + */ + if (ret != -ENODEV) + return ret; + + i++; + ptr++; + continue; + } + + dev->semaphore_idx = i; + break; + } + + return 0; +} + +static void i2c_dw_remove_lock_support(struct dw_i2c_dev *dev) +{ + if (dev->semaphore_idx < 0) + return; + + if (i2c_dw_semaphore_cb_table[dev->semaphore_idx].remove) + i2c_dw_semaphore_cb_table[dev->semaphore_idx].remove(dev); +} + static int dw_i2c_plat_probe(struct platform_device *pdev) { struct i2c_adapter *adap; @@ -334,6 +392,8 @@ static int dw_i2c_plat_remove(struct platform_device *pdev) pm_runtime_put_sync(&pdev->dev); dw_i2c_plat_pm_cleanup(dev); + i2c_dw_remove_lock_support(dev); + reset_control_assert(dev->rst); return 0; From e044e3e696b1c6b3bbb1ea536c590af169d3267b Mon Sep 17 00:00:00 2001 From: David Heidelberg Date: Mon, 7 Feb 2022 23:39:11 +0100 Subject: [PATCH 122/370] dt-bindings: display: bridge: document Toshiba TC358768 cells and panel node Inherit valid properties from the dsi-controller. Reviewed-by: Dmitry Osipenko Signed-off-by: David Heidelberg Signed-off-by: Rob Herring Link: https://lore.kernel.org/r/20220207223911.97180-1-david@ixit.cz --- .../bindings/display/bridge/toshiba,tc358768.yaml | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/Documentation/devicetree/bindings/display/bridge/toshiba,tc358768.yaml b/Documentation/devicetree/bindings/display/bridge/toshiba,tc358768.yaml index eacfe7165083..3bd670b8e5cd 100644 --- a/Documentation/devicetree/bindings/display/bridge/toshiba,tc358768.yaml +++ b/Documentation/devicetree/bindings/display/bridge/toshiba,tc358768.yaml @@ -77,7 +77,10 @@ required: - vddio-supply - ports -additionalProperties: false +allOf: + - $ref: ../dsi-controller.yaml# + +unevaluatedProperties: false examples: - | @@ -87,7 +90,7 @@ examples: #address-cells = <1>; #size-cells = <0>; - dsi_bridge: dsi-bridge@e { + dsi_bridge: dsi@e { compatible = "toshiba,tc358768"; reg = <0xe>; From c2687295df00ec7baf6a8c59b340264474e98183 Mon Sep 17 00:00:00 2001 From: Zenghui Yu Date: Tue, 8 Feb 2022 15:03:00 +0800 Subject: [PATCH 123/370] dt-bindings: arm: Trivial typo fixes in cpu-capacity.txt Correct the spelling of 'cluster1@max-freq' and fix the wrong capacity-dmips-mhz value 576 (which should be 578 instead). Signed-off-by: Zenghui Yu Signed-off-by: Rob Herring Link: https://lore.kernel.org/r/20220208070300.1610-1-yuzenghui@huawei.com --- Documentation/devicetree/bindings/arm/cpu-capacity.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Documentation/devicetree/bindings/arm/cpu-capacity.txt b/Documentation/devicetree/bindings/arm/cpu-capacity.txt index 380e21c5fc7e..cc5e190390b7 100644 --- a/Documentation/devicetree/bindings/arm/cpu-capacity.txt +++ b/Documentation/devicetree/bindings/arm/cpu-capacity.txt @@ -62,8 +62,8 @@ Example 1 (ARM 64-bit, 6-cpu system, two clusters): The capacities-dmips-mhz or DMIPS/MHz values (scaled to 1024) are 1024 and 578 for cluster0 and cluster1. Further normalization is done by the operating system based on cluster0@max-freq=1100 and -custer1@max-freq=850, final capacities are 1024 for cluster0 and -446 for cluster1 (576*850/1100). +cluster1@max-freq=850, final capacities are 1024 for cluster0 and +446 for cluster1 (578*850/1100). cpus { #address-cells = <2>; From bd79e84c6500db6ce069472e51c979764d88a024 Mon Sep 17 00:00:00 2001 From: Oleksij Rempel Date: Wed, 9 Feb 2022 09:28:20 +0100 Subject: [PATCH 124/370] dt-bindings: net: ethernet-controller: document label property "label" provides human readable name used on a box, board or schematic to identify Ethernet port. Signed-off-by: Oleksij Rempel Signed-off-by: Rob Herring Link: https://lore.kernel.org/r/20220209082820.2210753-1-o.rempel@pengutronix.de --- .../devicetree/bindings/net/ethernet-controller.yaml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Documentation/devicetree/bindings/net/ethernet-controller.yaml b/Documentation/devicetree/bindings/net/ethernet-controller.yaml index 34c5463abcec..817794e56227 100644 --- a/Documentation/devicetree/bindings/net/ethernet-controller.yaml +++ b/Documentation/devicetree/bindings/net/ethernet-controller.yaml @@ -13,6 +13,10 @@ properties: $nodename: pattern: "^ethernet(@.*)?$" + label: + $ref: /schemas/types.yaml#/definitions/string + description: Human readable label on a port of a box. + local-mac-address: description: Specifies the MAC address that was assigned to the network device. From 49364138080efb54434de086aef49353068285ef Mon Sep 17 00:00:00 2001 From: Fabrice Gasnier Date: Wed, 9 Feb 2022 14:52:27 +0100 Subject: [PATCH 125/370] dt-bindings: timer: armv7m-systick: convert to dtschema Convert the ARMv7-M system timer bindings to DT schema format. Signed-off-by: Fabrice Gasnier Cc: Alexandre Torgue Signed-off-by: Rob Herring Link: https://lore.kernel.org/r/1644414747-22159-1-git-send-email-fabrice.gasnier@foss.st.com --- .../bindings/timer/arm,armv7m-systick.txt | 26 --------- .../bindings/timer/arm,armv7m-systick.yaml | 54 +++++++++++++++++++ 2 files changed, 54 insertions(+), 26 deletions(-) delete mode 100644 Documentation/devicetree/bindings/timer/arm,armv7m-systick.txt create mode 100644 Documentation/devicetree/bindings/timer/arm,armv7m-systick.yaml diff --git a/Documentation/devicetree/bindings/timer/arm,armv7m-systick.txt b/Documentation/devicetree/bindings/timer/arm,armv7m-systick.txt deleted file mode 100644 index 7cf4a24601eb..000000000000 --- a/Documentation/devicetree/bindings/timer/arm,armv7m-systick.txt +++ /dev/null @@ -1,26 +0,0 @@ -* ARMv7M System Timer - -ARMv7-M includes a system timer, known as SysTick. Current driver only -implements the clocksource feature. - -Required properties: -- compatible : Should be "arm,armv7m-systick" -- reg : The address range of the timer - -Required clocking property, have to be one of: -- clocks : The input clock of the timer -- clock-frequency : The rate in HZ in input of the ARM SysTick - -Examples: - -systick: timer@e000e010 { - compatible = "arm,armv7m-systick"; - reg = <0xe000e010 0x10>; - clocks = <&clk_systick>; -}; - -systick: timer@e000e010 { - compatible = "arm,armv7m-systick"; - reg = <0xe000e010 0x10>; - clock-frequency = <90000000>; -}; diff --git a/Documentation/devicetree/bindings/timer/arm,armv7m-systick.yaml b/Documentation/devicetree/bindings/timer/arm,armv7m-systick.yaml new file mode 100644 index 000000000000..2bcade5d8ac6 --- /dev/null +++ b/Documentation/devicetree/bindings/timer/arm,armv7m-systick.yaml @@ -0,0 +1,54 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/timer/arm,armv7m-systick.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: ARMv7M System Timer + +maintainers: + - Alexandre Torgue + - Fabrice Gasnier + +description: ARMv7-M includes a system timer, known as SysTick. + +properties: + compatible: + const: arm,armv7m-systick + + reg: + maxItems: 1 + + clocks: + maxItems: 1 + + clock-frequency: true + +oneOf: + - required: + - clocks + - required: + - clock-frequency + +required: + - compatible + - reg + +additionalProperties: false + +examples: + - | + timer@e000e010 { + compatible = "arm,armv7m-systick"; + reg = <0xe000e010 0x10>; + clocks = <&clk_systick>; + }; + + - | + timer@e000e010 { + compatible = "arm,armv7m-systick"; + reg = <0xe000e010 0x10>; + clock-frequency = <90000000>; + }; + +... From b36fc8181e3b31ba9e11c6a1938aa5bede10206f Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Thu, 3 Feb 2022 15:33:16 +0100 Subject: [PATCH 126/370] dt-bindings: i2c: renesas,rcar-i2c: Add r8a779f0 support Document support for the I2C Bus Interfaces in the Renesas R-Car S4-8 (R8A779F0) SoC, including a new family-specific compatible value for the R-Car Gen4 family. Signed-off-by: Geert Uytterhoeven Reviewed-by: Wolfram Sang Acked-by: Rob Herring Signed-off-by: Wolfram Sang --- Documentation/devicetree/bindings/i2c/renesas,rcar-i2c.yaml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/Documentation/devicetree/bindings/i2c/renesas,rcar-i2c.yaml b/Documentation/devicetree/bindings/i2c/renesas,rcar-i2c.yaml index 052aad44e781..c30107833a51 100644 --- a/Documentation/devicetree/bindings/i2c/renesas,rcar-i2c.yaml +++ b/Documentation/devicetree/bindings/i2c/renesas,rcar-i2c.yaml @@ -49,6 +49,11 @@ properties: - renesas,i2c-r8a779a0 # R-Car V3U - const: renesas,rcar-gen3-i2c # R-Car Gen3 and RZ/G2 + - items: + - enum: + - renesas,i2c-r8a779f0 # R-Car S4-8 + - const: renesas,rcar-gen4-i2c # R-Car Gen4 + reg: maxItems: 1 @@ -132,6 +137,7 @@ allOf: enum: - renesas,rcar-gen2-i2c - renesas,rcar-gen3-i2c + - renesas,rcar-gen4-i2c then: required: - resets From ea01b71b07993d5c518496692f476a3c6b5d9786 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Thu, 3 Feb 2022 15:33:17 +0100 Subject: [PATCH 127/370] i2c: rcar: Add R-Car Gen4 support Add support for the I2C Bus Interface on R-Car Gen4 SoCs (e.g. R-Car S4-8) by matching on a family-specific compatible value. While I2C on R-Car Gen4 does support some extra features (Slave Clock Stretch Select), for now it is treated the same as I2C on R-Car Gen3. Signed-off-by: Geert Uytterhoeven Reviewed-by: Wolfram Sang [wsa: removed incorrect "FM+" from commit message] Signed-off-by: Wolfram Sang --- drivers/i2c/busses/i2c-rcar.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/i2c/busses/i2c-rcar.c b/drivers/i2c/busses/i2c-rcar.c index f71c730f9838..0db3d7559066 100644 --- a/drivers/i2c/busses/i2c-rcar.c +++ b/drivers/i2c/busses/i2c-rcar.c @@ -1008,6 +1008,7 @@ static const struct of_device_id rcar_i2c_dt_ids[] = { { .compatible = "renesas,rcar-gen1-i2c", .data = (void *)I2C_RCAR_GEN1 }, { .compatible = "renesas,rcar-gen2-i2c", .data = (void *)I2C_RCAR_GEN2 }, { .compatible = "renesas,rcar-gen3-i2c", .data = (void *)I2C_RCAR_GEN3 }, + { .compatible = "renesas,rcar-gen4-i2c", .data = (void *)I2C_RCAR_GEN3 }, {}, }; MODULE_DEVICE_TABLE(of, rcar_i2c_dt_ids); From d0aee048d648ec2d9aa7af43b127ebf847d497d5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= Date: Fri, 11 Feb 2022 11:58:06 +0100 Subject: [PATCH 128/370] i2c: brcmstb: allow compiling on BCM4908 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BCM4908 SoCs use the same I2C hardware block as STB and BCM63xx devices. Signed-off-by: Rafał Miłecki Acked-by: Florian Fainelli Signed-off-by: Wolfram Sang --- drivers/i2c/busses/Kconfig | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig index 5ea26a7aa1d5..1fbb5f1fa7b1 100644 --- a/drivers/i2c/busses/Kconfig +++ b/drivers/i2c/busses/Kconfig @@ -477,8 +477,8 @@ config I2C_BCM_KONA config I2C_BRCMSTB tristate "BRCM Settop/DSL I2C controller" - depends on ARCH_BCM2835 || ARCH_BRCMSTB || BMIPS_GENERIC || \ - ARCH_BCM_63XX || COMPILE_TEST + depends on ARCH_BCM2835 || ARCH_BCM4908 || ARCH_BCM_63XX || \ + ARCH_BRCMSTB || BMIPS_GENERIC || COMPILE_TEST default y help If you say yes to this option, support will be included for the From f1bd6661946b20d1ea07de84a3c9a550e0367476 Mon Sep 17 00:00:00 2001 From: Conor Dooley Date: Mon, 7 Feb 2022 16:26:29 +0000 Subject: [PATCH 129/370] dt-bindings: i2c: add bindings for microchip mpfs i2c Add device tree bindings for the i2c controller on the Microchip PolarFire SoC. Signed-off-by: Daire McNamara Reviewed-by: Rob Herring Signed-off-by: Conor Dooley Acked-by: Palmer Dabbelt Signed-off-by: Wolfram Sang --- .../bindings/i2c/microchip,corei2c.yaml | 56 +++++++++++++++++++ 1 file changed, 56 insertions(+) create mode 100644 Documentation/devicetree/bindings/i2c/microchip,corei2c.yaml diff --git a/Documentation/devicetree/bindings/i2c/microchip,corei2c.yaml b/Documentation/devicetree/bindings/i2c/microchip,corei2c.yaml new file mode 100644 index 000000000000..c8e605fbb8a6 --- /dev/null +++ b/Documentation/devicetree/bindings/i2c/microchip,corei2c.yaml @@ -0,0 +1,56 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/i2c/microchip,corei2c.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Microchip MPFS I2C Controller Device Tree Bindings + +maintainers: + - Daire McNamara + +allOf: + - $ref: /schemas/i2c/i2c-controller.yaml# + +properties: + compatible: + oneOf: + - items: + - const: microchip,mpfs-i2c # Microchip PolarFire SoC compatible SoCs + - const: microchip,corei2c-rtl-v7 # Microchip Fabric based i2c IP core + - const: microchip,corei2c-rtl-v7 # Microchip Fabric based i2c IP core + + reg: + maxItems: 1 + + interrupts: + maxItems: 1 + + clocks: + maxItems: 1 + + clock-frequency: + description: | + Desired I2C bus clock frequency in Hz. As only Standard and Fast + modes are supported, possible values are 100000 and 400000. + enum: [100000, 400000] + +required: + - compatible + - reg + - interrupts + - clocks + +unevaluatedProperties: false + +examples: + - | + i2c@2010a000 { + compatible = "microchip,mpfs-i2c", "microchip,corei2c-rtl-v7"; + reg = <0x2010a000 0x1000>; + clocks = <&clkcfg 15>; + interrupt-parent = <&plic>; + interrupts = <58>; + clock-frequency = <100000>; + }; +... From e6148767825ce345338328a29030a182e3b22d10 Mon Sep 17 00:00:00 2001 From: Kees Cook Date: Fri, 18 Jun 2021 23:30:07 -0700 Subject: [PATCH 130/370] Makefile: Enable -Warray-bounds With the recent fixes for flexible arrays and expanded FORTIFY_SOURCE coverage, it is now possible to enable -Warray-bounds. Since both GCC and Clang include -Warray-bounds in -Wall, adjust the Makefile to just stop disabling it. Note that this option can be conservative in its warnings (which is done at casting time rather than access time), but this is reasonable since the cast variables may be accessed out of a scope where the true size of the original object can't be evaluated. These handful of false positives (which are arguably bad casts and can be easily avoided), are worth dealing with because of the many places where this option has helped identify missed bounds checks and even accesses done against cases where a NULL pointer could be reached. https://github.com/KSPP/linux/issues/109 https://github.com/KSPP/linux/issues/151 Cc: Arnd Bergmann Cc: Masahiro Yamada Cc: linux-kbuild@vger.kernel.org Co-developed-by: Gustavo A. R. Silva Signed-off-by: Gustavo A. R. Silva Signed-off-by: Kees Cook --- Makefile | 1 - 1 file changed, 1 deletion(-) diff --git a/Makefile b/Makefile index ceb987e5c87b..d66b61691e8c 100644 --- a/Makefile +++ b/Makefile @@ -952,7 +952,6 @@ KBUILD_CFLAGS += $(call cc-disable-warning, stringop-truncation) # We'll want to enable this eventually, but it's not going away for 5.7 at least KBUILD_CFLAGS += $(call cc-disable-warning, zero-length-bounds) -KBUILD_CFLAGS += -Wno-array-bounds KBUILD_CFLAGS += $(call cc-disable-warning, stringop-overflow) # Another good warning that we'll want to enable eventually From 00a4f836eb369723b148e3f250c850a028778832 Mon Sep 17 00:00:00 2001 From: Kees Cook Date: Tue, 17 Aug 2021 11:56:36 -0700 Subject: [PATCH 131/370] Makefile: Enable -Wzero-length-bounds With all known internal zero-length accesses fixed, it is possible to enable -Wzero-length-bounds globally. Since this is included by default in -Warray-bounds, we just need to stop disabling it. Cc: "Gustavo A. R. Silva" Cc: Arnd Bergmann Cc: Masahiro Yamada Cc: linux-kbuild@vger.kernel.org Signed-off-by: Kees Cook Reviewed-by: Nick Desaulniers Link: https://lore.kernel.org/lkml/CAKwvOd=bcs5W6eEDXGn5ROR2EuMiSp_2e6sLFxak=KK6yLWcvA@mail.gmail.com --- Makefile | 1 - 1 file changed, 1 deletion(-) diff --git a/Makefile b/Makefile index d66b61691e8c..8e2e4edf7e71 100644 --- a/Makefile +++ b/Makefile @@ -951,7 +951,6 @@ KBUILD_CFLAGS += $(call cc-option, -Wcast-function-type) KBUILD_CFLAGS += $(call cc-disable-warning, stringop-truncation) # We'll want to enable this eventually, but it's not going away for 5.7 at least -KBUILD_CFLAGS += $(call cc-disable-warning, zero-length-bounds) KBUILD_CFLAGS += $(call cc-disable-warning, stringop-overflow) # Another good warning that we'll want to enable eventually From f68f2ff91512c199ec24883001245912afc17873 Mon Sep 17 00:00:00 2001 From: Kees Cook Date: Tue, 20 Apr 2021 23:22:52 -0700 Subject: [PATCH 132/370] fortify: Detect struct member overflows in memcpy() at compile-time memcpy() is dead; long live memcpy() tl;dr: In order to eliminate a large class of common buffer overflow flaws that continue to persist in the kernel, have memcpy() (under CONFIG_FORTIFY_SOURCE) perform bounds checking of the destination struct member when they have a known size. This would have caught all of the memcpy()-related buffer write overflow flaws identified in at least the last three years. Background and analysis: While stack-based buffer overflow flaws are largely mitigated by stack canaries (and similar) features, heap-based buffer overflow flaws continue to regularly appear in the kernel. Many classes of heap buffer overflows are mitigated by FORTIFY_SOURCE when using the strcpy() family of functions, but a significant number remain exposed through the memcpy() family of functions. At its core, FORTIFY_SOURCE uses the compiler's __builtin_object_size() internal[0] to determine the available size at a target address based on the compile-time known structure layout details. It operates in two modes: outer bounds (0) and inner bounds (1). In mode 0, the size of the enclosing structure is used. In mode 1, the size of the specific field is used. For example: struct object { u16 scalar1; /* 2 bytes */ char array[6]; /* 6 bytes */ u64 scalar2; /* 8 bytes */ u32 scalar3; /* 4 bytes */ u32 scalar4; /* 4 bytes */ } instance; __builtin_object_size(instance.array, 0) == 22, since the remaining size of the enclosing structure starting from "array" is 22 bytes (6 + 8 + 4 + 4). __builtin_object_size(instance.array, 1) == 6, since the remaining size of the specific field "array" is 6 bytes. The initial implementation of FORTIFY_SOURCE used mode 0 because there were many cases of both strcpy() and memcpy() functions being used to write (or read) across multiple fields in a structure. For example, it would catch this, which is writing 2 bytes beyond the end of "instance": memcpy(&instance.array, data, 25); While this didn't protect against overwriting adjacent fields in a given structure, it would at least stop overflows from reaching beyond the end of the structure into neighboring memory, and provided a meaningful mitigation of a subset of buffer overflow flaws. However, many desirable targets remain within the enclosing structure (for example function pointers). As it happened, there were very few cases of strcpy() family functions intentionally writing beyond the end of a string buffer. Once all known cases were removed from the kernel, the strcpy() family was tightened[1] to use mode 1, providing greater mitigation coverage. What remains is switching memcpy() to mode 1 as well, but making the switch is much more difficult because of how frustrating it can be to find existing "normal" uses of memcpy() that expect to write (or read) across multiple fields. The root cause of the problem is that the C language lacks a common pattern to indicate the intent of an author's use of memcpy(), and is further complicated by the available compile-time and run-time mitigation behaviors. The FORTIFY_SOURCE mitigation comes in two halves: the compile-time half, when both the buffer size _and_ the length of the copy is known, and the run-time half, when only the buffer size is known. If neither size is known, there is no bounds checking possible. At compile-time when the compiler sees that a length will always exceed a known buffer size, a warning can be deterministically emitted. For the run-time half, the length is tested against the known size of the buffer, and the overflowing operation is detected. (The performance overhead for these tests is virtually zero.) It is relatively easy to find compile-time false-positives since a warning is always generated. Fixing the false positives, however, can be very time-consuming as there are hundreds of instances. While it's possible some over-read conditions could lead to kernel memory exposures, the bulk of the risk comes from the run-time flaws where the length of a write may end up being attacker-controlled and lead to an overflow. Many of the compile-time false-positives take a form similar to this: memcpy(&instance.scalar2, data, sizeof(instance.scalar2) + sizeof(instance.scalar3)); and the run-time ones are similar, but lack a constant expression for the size of the copy: memcpy(instance.array, data, length); The former is meant to cover multiple fields (though its style has been frowned upon more recently), but has been technically legal. Both lack any expressivity in the C language about the author's _intent_ in a way that a compiler can check when the length isn't known at compile time. A comment doesn't work well because what's needed is something a compiler can directly reason about. Is a given memcpy() call expected to overflow into neighbors? Is it not? By using the new struct_group() macro, this intent can be much more easily encoded. It is not as easy to find the run-time false-positives since the code path to exercise a seemingly out-of-bounds condition that is actually expected may not be trivially reachable. Tightening the restrictions to block an operation for a false positive will either potentially create a greater flaw (if a copy is truncated by the mitigation), or destabilize the kernel (e.g. with a BUG()), making things completely useless for the end user. As a result, tightening the memcpy() restriction (when there is a reasonable level of uncertainty of the number of false positives), needs to first WARN() with no truncation. (Though any sufficiently paranoid end-user can always opt to set the panic_on_warn=1 sysctl.) Once enough development time has passed, the mitigation can be further intensified. (Note that this patch is only the compile-time checking step, which is a prerequisite to doing run-time checking, which will come in future patches.) Given the potential frustrations of weeding out all the false positives when tightening the run-time checks, it is reasonable to wonder if these changes would actually add meaningful protection. Looking at just the last three years, there are 23 identified flaws with a CVE that mention "buffer overflow", and 11 are memcpy()-related buffer overflows. (For the remaining 12: 7 are array index overflows that would be mitigated by systems built with CONFIG_UBSAN_BOUNDS=y: CVE-2019-0145, CVE-2019-14835, CVE-2019-14896, CVE-2019-14897, CVE-2019-14901, CVE-2019-17666, CVE-2021-28952. 2 are miscalculated allocation sizes which could be mitigated with memory tagging: CVE-2019-16746, CVE-2019-2181. 1 is an iovec buffer bug maybe mitigated by memory tagging: CVE-2020-10742. 1 is a type confusion bug mitigated by stack canaries: CVE-2020-10942. 1 is a string handling logic bug with no mitigation I'm aware of: CVE-2021-28972.) At my last count on an x86_64 allmodconfig build, there are 35,294 calls to memcpy(). With callers instrumented to report all places where the buffer size is known but the length remains unknown (i.e. a run-time bounds check is added), we can count how many new run-time bounds checks are added when the destination and source arguments of memcpy() are changed to use "mode 1" bounds checking: 1,276. This means for the future run-time checking, there is a worst-case upper bounds of 3.6% false positives to fix. In addition, there were around 150 new compile-time warnings to evaluate and fix (which have now been fixed). With this instrumentation it's also possible to compare the places where the known 11 memcpy() flaw overflows manifested against the resulting list of potential new run-time bounds checks, as a measure of potential efficacy of the tightened mitigation. Much to my surprise, horror, and delight, all 11 flaws would have been detected by the newly added run-time bounds checks, making this a distinctly clear mitigation improvement: 100% coverage for known memcpy() flaws, with a possible 2 orders of magnitude gain in coverage over existing but undiscovered run-time dynamic length flaws (i.e. 1265 newly covered sites in addition to the 11 known), against only <4% of all memcpy() callers maybe gaining a false positive run-time check, with only about 150 new compile-time instances needing evaluation. Specifically these would have been mitigated: CVE-2020-24490 https://git.kernel.org/linus/a2ec905d1e160a33b2e210e45ad30445ef26ce0e CVE-2020-12654 https://git.kernel.org/linus/3a9b153c5591548612c3955c9600a98150c81875 CVE-2020-12653 https://git.kernel.org/linus/b70261a288ea4d2f4ac7cd04be08a9f0f2de4f4d CVE-2019-14895 https://git.kernel.org/linus/3d94a4a8373bf5f45cf5f939e88b8354dbf2311b CVE-2019-14816 https://git.kernel.org/linus/7caac62ed598a196d6ddf8d9c121e12e082cac3a CVE-2019-14815 https://git.kernel.org/linus/7caac62ed598a196d6ddf8d9c121e12e082cac3a CVE-2019-14814 https://git.kernel.org/linus/7caac62ed598a196d6ddf8d9c121e12e082cac3a CVE-2019-10126 https://git.kernel.org/linus/69ae4f6aac1578575126319d3f55550e7e440449 CVE-2019-9500 https://git.kernel.org/linus/1b5e2423164b3670e8bc9174e4762d297990deff no-CVE-yet https://git.kernel.org/linus/130f634da1af649205f4a3dd86cbe5c126b57914 no-CVE-yet https://git.kernel.org/linus/d10a87a3535cce2b890897914f5d0d83df669c63 To accelerate the review of potential run-time false positives, it's also worth noting that it is possible to partially automate checking by examining the memcpy() buffer argument to check for the destination struct member having a neighboring array member. It is reasonable to expect that the vast majority of run-time false positives would look like the already evaluated and fixed compile-time false positives, where the most common pattern is neighboring arrays. (And, FWIW, many of the compile-time fixes were actual bugs, so it is reasonable to assume we'll have similar cases of actual bugs getting fixed for run-time checks.) Implementation: Tighten the memcpy() destination buffer size checking to use the actual ("mode 1") target buffer size as the bounds check instead of their enclosing structure's ("mode 0") size. Use a common inline for memcpy() (and memmove() in a following patch), since all the tests are the same. All new cross-field memcpy() uses must use the struct_group() macro or similar to target a specific range of fields, so that FORTIFY_SOURCE can reason about the size and safety of the copy. For now, cross-member "mode 1" _read_ detection at compile-time will be limited to W=1 builds, since it is, unfortunately, very common. As the priority is solving write overflows, read overflows will be part of a future phase (and can be fixed in parallel, for anyone wanting to look at W=1 build output). For run-time, the "mode 0" size checking and mitigation is left unchanged, with "mode 1" to be added in stages. In this patch, no new run-time checks are added. Future patches will first bounds-check writes, and only perform a WARN() for now. This way any missed run-time false positives can be flushed out over the coming several development cycles, but system builders who have tested their workloads to be WARN()-free can enable the panic_on_warn=1 sysctl to immediately gain a mitigation against this class of buffer overflows. Once that is under way, run-time bounds-checking of reads can be similarly enabled. Related classes of flaws that will remain unmitigated: - memcpy() with flexible array structures, as the compiler does not currently have visibility into the size of the trailing flexible array. These can be fixed in the future by refactoring such cases to use a new set of flexible array structure helpers to perform the common serialization/deserialization code patterns doing allocation and/or copying. - memcpy() with raw pointers (e.g. void *, char *, etc), or otherwise having their buffer size unknown at compile time, have no good mitigation beyond memory tagging (and even that would only protect against inter-object overflow, not intra-object neighboring field overflows), or refactoring. Some kind of "fat pointer" solution is likely needed to gain proper size-of-buffer awareness. (e.g. see struct membuf) - type confusion where a higher level type's allocation size does not match the resulting cast type eventually passed to a deeper memcpy() call where the compiler cannot see the true type. In theory, greater static analysis could catch these, and the use of -Warray-bounds will help find some of these. [0] https://gcc.gnu.org/onlinedocs/gcc/Object-Size-Checking.html [1] https://git.kernel.org/linus/6a39e62abbafd1d58d1722f40c7d26ef379c6a2f Signed-off-by: Kees Cook --- include/linux/fortify-string.h | 109 ++++++++++++++++-- lib/Makefile | 3 +- lib/string_helpers.c | 6 + .../read_overflow2_field-memcpy.c | 5 + .../write_overflow_field-memcpy.c | 5 + 5 files changed, 115 insertions(+), 13 deletions(-) create mode 100644 lib/test_fortify/read_overflow2_field-memcpy.c create mode 100644 lib/test_fortify/write_overflow_field-memcpy.c diff --git a/include/linux/fortify-string.h b/include/linux/fortify-string.h index a6cd6815f249..f578d00403ad 100644 --- a/include/linux/fortify-string.h +++ b/include/linux/fortify-string.h @@ -8,7 +8,9 @@ void fortify_panic(const char *name) __noreturn __cold; void __read_overflow(void) __compiletime_error("detected read beyond size of object (1st parameter)"); void __read_overflow2(void) __compiletime_error("detected read beyond size of object (2nd parameter)"); +void __read_overflow2_field(size_t avail, size_t wanted) __compiletime_warning("detected read beyond size of field (2nd parameter); maybe use struct_group()?"); void __write_overflow(void) __compiletime_error("detected write beyond size of object (1st parameter)"); +void __write_overflow_field(size_t avail, size_t wanted) __compiletime_warning("detected write beyond size of field (1st parameter); maybe use struct_group()?"); #define __compiletime_strlen(p) \ ({ \ @@ -209,22 +211,105 @@ __FORTIFY_INLINE void *memset(void *p, int c, __kernel_size_t size) return __underlying_memset(p, c, size); } -__FORTIFY_INLINE void *memcpy(void *p, const void *q, __kernel_size_t size) +/* + * To make sure the compiler can enforce protection against buffer overflows, + * memcpy(), memmove(), and memset() must not be used beyond individual + * struct members. If you need to copy across multiple members, please use + * struct_group() to create a named mirror of an anonymous struct union. + * (e.g. see struct sk_buff.) Read overflow checking is currently only + * done when a write overflow is also present, or when building with W=1. + * + * Mitigation coverage matrix + * Bounds checking at: + * +-------+-------+-------+-------+ + * | Compile time | Run time | + * memcpy() argument sizes: | write | read | write | read | + * dest source length +-------+-------+-------+-------+ + * memcpy(known, known, constant) | y | y | n/a | n/a | + * memcpy(known, unknown, constant) | y | n | n/a | V | + * memcpy(known, known, dynamic) | n | n | B | B | + * memcpy(known, unknown, dynamic) | n | n | B | V | + * memcpy(unknown, known, constant) | n | y | V | n/a | + * memcpy(unknown, unknown, constant) | n | n | V | V | + * memcpy(unknown, known, dynamic) | n | n | V | B | + * memcpy(unknown, unknown, dynamic) | n | n | V | V | + * +-------+-------+-------+-------+ + * + * y = perform deterministic compile-time bounds checking + * n = cannot perform deterministic compile-time bounds checking + * n/a = no run-time bounds checking needed since compile-time deterministic + * B = can perform run-time bounds checking (currently unimplemented) + * V = vulnerable to run-time overflow (will need refactoring to solve) + * + */ +__FORTIFY_INLINE void fortify_memcpy_chk(__kernel_size_t size, + const size_t p_size, + const size_t q_size, + const size_t p_size_field, + const size_t q_size_field, + const char *func) { - size_t p_size = __builtin_object_size(p, 0); - size_t q_size = __builtin_object_size(q, 0); - if (__builtin_constant_p(size)) { - if (p_size < size) + /* + * Length argument is a constant expression, so we + * can perform compile-time bounds checking where + * buffer sizes are known. + */ + + /* Error when size is larger than enclosing struct. */ + if (p_size > p_size_field && p_size < size) __write_overflow(); - if (q_size < size) + if (q_size > q_size_field && q_size < size) __read_overflow2(); + + /* Warn when write size argument larger than dest field. */ + if (p_size_field < size) + __write_overflow_field(p_size_field, size); + /* + * Warn for source field over-read when building with W=1 + * or when an over-write happened, so both can be fixed at + * the same time. + */ + if ((IS_ENABLED(KBUILD_EXTRA_WARN1) || p_size_field < size) && + q_size_field < size) + __read_overflow2_field(q_size_field, size); } - if (p_size < size || q_size < size) - fortify_panic(__func__); - return __underlying_memcpy(p, q, size); + /* + * At this point, length argument may not be a constant expression, + * so run-time bounds checking can be done where buffer sizes are + * known. (This is not an "else" because the above checks may only + * be compile-time warnings, and we want to still warn for run-time + * overflows.) + */ + + /* + * Always stop accesses beyond the struct that contains the + * field, when the buffer's remaining size is known. + * (The -1 test is to optimize away checks where the buffer + * lengths are unknown.) + */ + if ((p_size != (size_t)(-1) && p_size < size) || + (q_size != (size_t)(-1) && q_size < size)) + fortify_panic(func); } +#define __fortify_memcpy_chk(p, q, size, p_size, q_size, \ + p_size_field, q_size_field, op) ({ \ + size_t __fortify_size = (size_t)(size); \ + fortify_memcpy_chk(__fortify_size, p_size, q_size, \ + p_size_field, q_size_field, #op); \ + __underlying_##op(p, q, __fortify_size); \ +}) + +/* + * __builtin_object_size() must be captured here to avoid evaluating argument + * side-effects further into the macro layers. + */ +#define memcpy(p, q, s) __fortify_memcpy_chk(p, q, s, \ + __builtin_object_size(p, 0), __builtin_object_size(q, 0), \ + __builtin_object_size(p, 1), __builtin_object_size(q, 1), \ + memcpy) + __FORTIFY_INLINE void *memmove(void *p, const void *q, __kernel_size_t size) { size_t p_size = __builtin_object_size(p, 0); @@ -304,13 +389,14 @@ __FORTIFY_INLINE void *kmemdup(const void *p, size_t size, gfp_t gfp) return __real_kmemdup(p, size, gfp); } -/* defined after fortified strlen and memcpy to reuse them */ +/* Defined after fortified strlen to reuse it. */ __FORTIFY_INLINE char *strcpy(char *p, const char *q) { size_t p_size = __builtin_object_size(p, 1); size_t q_size = __builtin_object_size(q, 1); size_t size; + /* If neither buffer size is known, immediately give up. */ if (p_size == (size_t)-1 && q_size == (size_t)-1) return __underlying_strcpy(p, q); size = strlen(q) + 1; @@ -320,14 +406,13 @@ __FORTIFY_INLINE char *strcpy(char *p, const char *q) /* Run-time check for dynamic size overflow. */ if (p_size < size) fortify_panic(__func__); - memcpy(p, q, size); + __underlying_memcpy(p, q, size); return p; } /* Don't use these outside the FORITFY_SOURCE implementation */ #undef __underlying_memchr #undef __underlying_memcmp -#undef __underlying_memcpy #undef __underlying_memmove #undef __underlying_memset #undef __underlying_strcat diff --git a/lib/Makefile b/lib/Makefile index 300f569c626b..a99ce004812a 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -374,7 +374,8 @@ TEST_FORTIFY_LOG = test_fortify.log quiet_cmd_test_fortify = TEST $@ cmd_test_fortify = $(CONFIG_SHELL) $(srctree)/scripts/test_fortify.sh \ $< $@ "$(NM)" $(CC) $(c_flags) \ - $(call cc-disable-warning,fortify-source) + $(call cc-disable-warning,fortify-source) \ + -DKBUILD_EXTRA_WARN1 targets += $(TEST_FORTIFY_LOGS) clean-files += $(TEST_FORTIFY_LOGS) diff --git a/lib/string_helpers.c b/lib/string_helpers.c index 90f9f1b7afec..4f877e9551d5 100644 --- a/lib/string_helpers.c +++ b/lib/string_helpers.c @@ -968,6 +968,12 @@ void memcpy_and_pad(void *dest, size_t dest_len, const void *src, size_t count, EXPORT_SYMBOL(memcpy_and_pad); #ifdef CONFIG_FORTIFY_SOURCE +/* These are placeholders for fortify compile-time warnings. */ +void __read_overflow2_field(size_t avail, size_t wanted) { } +EXPORT_SYMBOL(__read_overflow2_field); +void __write_overflow_field(size_t avail, size_t wanted) { } +EXPORT_SYMBOL(__write_overflow_field); + void fortify_panic(const char *name) { pr_emerg("detected buffer overflow in %s\n", name); diff --git a/lib/test_fortify/read_overflow2_field-memcpy.c b/lib/test_fortify/read_overflow2_field-memcpy.c new file mode 100644 index 000000000000..de9569266223 --- /dev/null +++ b/lib/test_fortify/read_overflow2_field-memcpy.c @@ -0,0 +1,5 @@ +// SPDX-License-Identifier: GPL-2.0-only +#define TEST \ + memcpy(large, instance.buf, sizeof(instance.buf) + 1) + +#include "test_fortify.h" diff --git a/lib/test_fortify/write_overflow_field-memcpy.c b/lib/test_fortify/write_overflow_field-memcpy.c new file mode 100644 index 000000000000..28cc81058dd3 --- /dev/null +++ b/lib/test_fortify/write_overflow_field-memcpy.c @@ -0,0 +1,5 @@ +// SPDX-License-Identifier: GPL-2.0-only +#define TEST \ + memcpy(instance.buf, large, sizeof(instance.buf) + 1) + +#include "test_fortify.h" From 938a000e3f9bead24ea753286b3e4d2423275c9e Mon Sep 17 00:00:00 2001 From: Kees Cook Date: Wed, 16 Jun 2021 14:48:19 -0700 Subject: [PATCH 133/370] fortify: Detect struct member overflows in memmove() at compile-time As done for memcpy(), also update memmove() to use the same tightened compile-time checks under CONFIG_FORTIFY_SOURCE. Signed-off-by: Kees Cook --- arch/x86/boot/compressed/misc.c | 3 ++- arch/x86/lib/memcpy_32.c | 1 + include/linux/fortify-string.h | 21 ++++--------------- .../read_overflow2_field-memmove.c | 5 +++++ .../write_overflow_field-memmove.c | 5 +++++ 5 files changed, 17 insertions(+), 18 deletions(-) create mode 100644 lib/test_fortify/read_overflow2_field-memmove.c create mode 100644 lib/test_fortify/write_overflow_field-memmove.c diff --git a/arch/x86/boot/compressed/misc.c b/arch/x86/boot/compressed/misc.c index a4339cb2d247..1cdcaf34ee36 100644 --- a/arch/x86/boot/compressed/misc.c +++ b/arch/x86/boot/compressed/misc.c @@ -37,10 +37,11 @@ * try to define their own functions if these are not defined as macros. */ #define memzero(s, n) memset((s), 0, (n)) +#ifndef memmove #define memmove memmove - /* Functions used by the included decompressor code below. */ void *memmove(void *dest, const void *src, size_t n); +#endif /* * This is set up by the setup-routine at boot-time diff --git a/arch/x86/lib/memcpy_32.c b/arch/x86/lib/memcpy_32.c index 3a6e6cfe8c35..ef3af7ff2c8a 100644 --- a/arch/x86/lib/memcpy_32.c +++ b/arch/x86/lib/memcpy_32.c @@ -4,6 +4,7 @@ #undef memcpy #undef memset +#undef memmove __visible void *memcpy(void *to, const void *from, size_t n) { diff --git a/include/linux/fortify-string.h b/include/linux/fortify-string.h index f578d00403ad..098d8a322a7a 100644 --- a/include/linux/fortify-string.h +++ b/include/linux/fortify-string.h @@ -309,22 +309,10 @@ __FORTIFY_INLINE void fortify_memcpy_chk(__kernel_size_t size, __builtin_object_size(p, 0), __builtin_object_size(q, 0), \ __builtin_object_size(p, 1), __builtin_object_size(q, 1), \ memcpy) - -__FORTIFY_INLINE void *memmove(void *p, const void *q, __kernel_size_t size) -{ - size_t p_size = __builtin_object_size(p, 0); - size_t q_size = __builtin_object_size(q, 0); - - if (__builtin_constant_p(size)) { - if (p_size < size) - __write_overflow(); - if (q_size < size) - __read_overflow2(); - } - if (p_size < size || q_size < size) - fortify_panic(__func__); - return __underlying_memmove(p, q, size); -} +#define memmove(p, q, s) __fortify_memcpy_chk(p, q, s, \ + __builtin_object_size(p, 0), __builtin_object_size(q, 0), \ + __builtin_object_size(p, 1), __builtin_object_size(q, 1), \ + memmove) extern void *__real_memscan(void *, int, __kernel_size_t) __RENAME(memscan); __FORTIFY_INLINE void *memscan(void *p, int c, __kernel_size_t size) @@ -413,7 +401,6 @@ __FORTIFY_INLINE char *strcpy(char *p, const char *q) /* Don't use these outside the FORITFY_SOURCE implementation */ #undef __underlying_memchr #undef __underlying_memcmp -#undef __underlying_memmove #undef __underlying_memset #undef __underlying_strcat #undef __underlying_strcpy diff --git a/lib/test_fortify/read_overflow2_field-memmove.c b/lib/test_fortify/read_overflow2_field-memmove.c new file mode 100644 index 000000000000..6cc2724c8f62 --- /dev/null +++ b/lib/test_fortify/read_overflow2_field-memmove.c @@ -0,0 +1,5 @@ +// SPDX-License-Identifier: GPL-2.0-only +#define TEST \ + memmove(large, instance.buf, sizeof(instance.buf) + 1) + +#include "test_fortify.h" diff --git a/lib/test_fortify/write_overflow_field-memmove.c b/lib/test_fortify/write_overflow_field-memmove.c new file mode 100644 index 000000000000..377fcf9bb2fd --- /dev/null +++ b/lib/test_fortify/write_overflow_field-memmove.c @@ -0,0 +1,5 @@ +// SPDX-License-Identifier: GPL-2.0-only +#define TEST \ + memmove(instance.buf, large, sizeof(instance.buf) + 1) + +#include "test_fortify.h" From 28e77cc1c0686621a4d416f599cee5ab369daa0a Mon Sep 17 00:00:00 2001 From: Kees Cook Date: Wed, 16 Jun 2021 14:42:23 -0700 Subject: [PATCH 134/370] fortify: Detect struct member overflows in memset() at compile-time As done for memcpy(), also update memset() to use the same tightened compile-time bounds checking under CONFIG_FORTIFY_SOURCE. Signed-off-by: Kees Cook --- include/linux/fortify-string.h | 54 ++++++++++++++++--- .../write_overflow_field-memset.c | 5 ++ 2 files changed, 51 insertions(+), 8 deletions(-) create mode 100644 lib/test_fortify/write_overflow_field-memset.c diff --git a/include/linux/fortify-string.h b/include/linux/fortify-string.h index 098d8a322a7a..53123712bb3b 100644 --- a/include/linux/fortify-string.h +++ b/include/linux/fortify-string.h @@ -200,17 +200,56 @@ __FORTIFY_INLINE char *strncat(char *p, const char *q, __kernel_size_t count) return p; } -__FORTIFY_INLINE void *memset(void *p, int c, __kernel_size_t size) +__FORTIFY_INLINE void fortify_memset_chk(__kernel_size_t size, + const size_t p_size, + const size_t p_size_field) { - size_t p_size = __builtin_object_size(p, 0); + if (__builtin_constant_p(size)) { + /* + * Length argument is a constant expression, so we + * can perform compile-time bounds checking where + * buffer sizes are known. + */ - if (__builtin_constant_p(size) && p_size < size) - __write_overflow(); - if (p_size < size) - fortify_panic(__func__); - return __underlying_memset(p, c, size); + /* Error when size is larger than enclosing struct. */ + if (p_size > p_size_field && p_size < size) + __write_overflow(); + + /* Warn when write size is larger than dest field. */ + if (p_size_field < size) + __write_overflow_field(p_size_field, size); + } + /* + * At this point, length argument may not be a constant expression, + * so run-time bounds checking can be done where buffer sizes are + * known. (This is not an "else" because the above checks may only + * be compile-time warnings, and we want to still warn for run-time + * overflows.) + */ + + /* + * Always stop accesses beyond the struct that contains the + * field, when the buffer's remaining size is known. + * (The -1 test is to optimize away checks where the buffer + * lengths are unknown.) + */ + if (p_size != (size_t)(-1) && p_size < size) + fortify_panic("memset"); } +#define __fortify_memset_chk(p, c, size, p_size, p_size_field) ({ \ + size_t __fortify_size = (size_t)(size); \ + fortify_memset_chk(__fortify_size, p_size, p_size_field), \ + __underlying_memset(p, c, __fortify_size); \ +}) + +/* + * __builtin_object_size() must be captured here to avoid evaluating argument + * side-effects further into the macro layers. + */ +#define memset(p, c, s) __fortify_memset_chk(p, c, s, \ + __builtin_object_size(p, 0), __builtin_object_size(p, 1)) + /* * To make sure the compiler can enforce protection against buffer overflows, * memcpy(), memmove(), and memset() must not be used beyond individual @@ -401,7 +440,6 @@ __FORTIFY_INLINE char *strcpy(char *p, const char *q) /* Don't use these outside the FORITFY_SOURCE implementation */ #undef __underlying_memchr #undef __underlying_memcmp -#undef __underlying_memset #undef __underlying_strcat #undef __underlying_strcpy #undef __underlying_strlen diff --git a/lib/test_fortify/write_overflow_field-memset.c b/lib/test_fortify/write_overflow_field-memset.c new file mode 100644 index 000000000000..2331da26909e --- /dev/null +++ b/lib/test_fortify/write_overflow_field-memset.c @@ -0,0 +1,5 @@ +// SPDX-License-Identifier: GPL-2.0-only +#define TEST \ + memset(instance.buf, 0x42, sizeof(instance.buf) + 1) + +#include "test_fortify.h" From 818ab43fc56ad978cbb7c0ffdc9a332fd2f23a23 Mon Sep 17 00:00:00 2001 From: Kees Cook Date: Sun, 30 Jan 2022 09:59:29 -0800 Subject: [PATCH 135/370] fortify: Update compile-time tests for Clang 14 Clang 14 introduces support for compiletime_assert(). Update the compile-time warning regex to catch Clang's variant of the warning text in preparation for Clang supporting CONFIG_FORTIFY_SOURCE. Cc: Nick Desaulniers Cc: linux-hardening@vger.kernel.org Cc: llvm@lists.linux.dev Reviewed-by: Nathan Chancellor Link: https://lore.kernel.org/lkml/YfbtQKtpyAM1hHiC@dev-arch.archlinux-ax161 Signed-off-by: Kees Cook --- scripts/test_fortify.sh | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/scripts/test_fortify.sh b/scripts/test_fortify.sh index a4da365508f0..c2688ab8281d 100644 --- a/scripts/test_fortify.sh +++ b/scripts/test_fortify.sh @@ -46,8 +46,12 @@ if "$@" -Werror -c "$IN" -o "$OUT".o 2> "$TMP" ; then status="warning: unsafe ${FUNC}() usage lacked '$WANT' symbol in $IN" fi else - # If the build failed, check for the warning in the stderr (gcc). - if ! grep -q -m1 "error: call to .\b${WANT}\b." "$TMP" ; then + # If the build failed, check for the warning in the stderr. + # GCC: + # ./include/linux/fortify-string.h:316:25: error: call to '__write_overflow_field' declared with attribute warning: detected write beyond size of field (1st parameter); maybe use struct_group()? [-Werror=attribute-warning] + # Clang 14: + # ./include/linux/fortify-string.h:316:4: error: call to __write_overflow_field declared with 'warning' attribute: detected write beyond size of field (1st parameter); maybe use struct_group()? [-Werror,-Wattribute-warning] + if ! grep -Eq -m1 "error: call to .?\b${WANT}\b.?" "$TMP" ; then status="warning: unsafe ${FUNC}() usage lacked '$WANT' warning in $IN" fi fi From f361143141362485b39eb40bb4910e3f4219180f Mon Sep 17 00:00:00 2001 From: Kees Cook Date: Tue, 8 Feb 2022 14:53:43 -0800 Subject: [PATCH 136/370] fortify: Replace open-coded __gnu_inline attribute Replace open-coded gnu_inline attribute with the normal kernel convention for attributes: __gnu_inline Signed-off-by: Kees Cook Reviewed-by: Nick Desaulniers Link: https://lore.kernel.org/r/20220208225350.1331628-2-keescook@chromium.org --- include/linux/fortify-string.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/linux/fortify-string.h b/include/linux/fortify-string.h index 53123712bb3b..439aad24ab3b 100644 --- a/include/linux/fortify-string.h +++ b/include/linux/fortify-string.h @@ -2,7 +2,7 @@ #ifndef _LINUX_FORTIFY_STRING_H_ #define _LINUX_FORTIFY_STRING_H_ -#define __FORTIFY_INLINE extern __always_inline __attribute__((gnu_inline)) +#define __FORTIFY_INLINE extern __always_inline __gnu_inline #define __RENAME(x) __asm__(#x) void fortify_panic(const char *name) __noreturn __cold; From f0202b8ca48cef152d4cdf775f39be6d3b372e1e Mon Sep 17 00:00:00 2001 From: Kees Cook Date: Tue, 8 Feb 2022 14:53:44 -0800 Subject: [PATCH 137/370] Compiler Attributes: Add __pass_object_size for Clang In order to gain greater visibility to type information when using __builtin_object_size(), Clang has a function attribute "pass_object_size" that will make size information available for marked arguments in a function by way of implicit additional function arguments that are then wired up the __builtin_object_size(). This is needed to implement FORTIFY_SOURCE in Clang, as a workaround to Clang's __builtin_object_size() having limited visibility[1] into types across function calls (even inlines). This attribute has an additional benefit that it can be used even on non-inline functions to gain argument size information. [1] https://github.com/llvm/llvm-project/issues/53516 Cc: Nick Desaulniers Cc: Nathan Chancellor Cc: llvm@lists.linux.dev Reviewed-by: Miguel Ojeda Signed-off-by: Kees Cook Reviewed-by: Nick Desaulniers Link: https://lore.kernel.org/r/20220208225350.1331628-3-keescook@chromium.org --- include/linux/compiler_attributes.h | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/include/linux/compiler_attributes.h b/include/linux/compiler_attributes.h index 37e260020221..d0c503772061 100644 --- a/include/linux/compiler_attributes.h +++ b/include/linux/compiler_attributes.h @@ -263,6 +263,20 @@ */ #define __packed __attribute__((__packed__)) +/* + * Note: the "type" argument should match any __builtin_object_size(p, type) usage. + * + * Optional: not supported by gcc. + * Optional: not supported by icc. + * + * clang: https://clang.llvm.org/docs/AttributeReference.html#pass-object-size-pass-dynamic-object-size + */ +#if __has_attribute(__pass_object_size__) +# define __pass_object_size(type) __attribute__((__pass_object_size__(type))) +#else +# define __pass_object_size(type) +#endif + /* * gcc: https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#index-pure-function-attribute */ From d694dbaefd6fa6bdde84b704779eab53942753a5 Mon Sep 17 00:00:00 2001 From: Kees Cook Date: Tue, 8 Feb 2022 14:53:45 -0800 Subject: [PATCH 138/370] Compiler Attributes: Add __overloadable for Clang In order for FORTIFY_SOURCE to use __pass_object_size on an "extern inline" function, as all the fortified string functions are, the functions must be marked as being overloadable (i.e. different prototypes due to the implicitly injected object size arguments). This allows the __pass_object_size versions to take precedence. Cc: Nathan Chancellor Cc: llvm@lists.linux.dev Reviewed-by: Miguel Ojeda Reviewed-by: Nick Desaulniers Signed-off-by: Kees Cook Link: https://lore.kernel.org/r/20220208225350.1331628-4-keescook@chromium.org --- include/linux/compiler_attributes.h | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/include/linux/compiler_attributes.h b/include/linux/compiler_attributes.h index d0c503772061..dcaf55f5d1ae 100644 --- a/include/linux/compiler_attributes.h +++ b/include/linux/compiler_attributes.h @@ -257,6 +257,18 @@ */ #define __noreturn __attribute__((__noreturn__)) +/* + * Optional: not supported by gcc. + * Optional: not supported by icc. + * + * clang: https://clang.llvm.org/docs/AttributeReference.html#overloadable + */ +#if __has_attribute(__overloadable__) +# define __overloadable __attribute__((__overloadable__)) +#else +# define __overloadable +#endif + /* * gcc: https://gcc.gnu.org/onlinedocs/gcc/Common-Type-Attributes.html#index-packed-type-attribute * clang: https://gcc.gnu.org/onlinedocs/gcc/Common-Variable-Attributes.html#index-packed-variable-attribute From 1c7f4e5c1b6c9d9b508007c141dca77cab9434b4 Mon Sep 17 00:00:00 2001 From: Kees Cook Date: Tue, 8 Feb 2022 14:53:46 -0800 Subject: [PATCH 139/370] Compiler Attributes: Add __diagnose_as for Clang Clang will perform various compile-time diagnostics on uses of various functions (e.g. simple bounds-checking on strcpy(), etc). These diagnostics can be assigned to other functions (for example, new implementations of the string functions under CONFIG_FORTIFY_SOURCE) using the "diagnose_as_builtin" attribute. This allows those functions to retain their compile-time diagnostic warnings. Cc: Nathan Chancellor Cc: llvm@lists.linux.dev Reviewed-by: Miguel Ojeda Reviewed-by: Nick Desaulniers Signed-off-by: Kees Cook Link: https://lore.kernel.org/r/20220208225350.1331628-5-keescook@chromium.org --- include/linux/compiler_attributes.h | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/include/linux/compiler_attributes.h b/include/linux/compiler_attributes.h index dcaf55f5d1ae..445e80517cab 100644 --- a/include/linux/compiler_attributes.h +++ b/include/linux/compiler_attributes.h @@ -100,6 +100,19 @@ # define __copy(symbol) #endif +/* + * Optional: not supported by gcc + * Optional: only supported since clang >= 14.0 + * Optional: not supported by icc + * + * clang: https://clang.llvm.org/docs/AttributeReference.html#diagnose_as_builtin + */ +#if __has_attribute(__diagnose_as_builtin__) +# define __diagnose_as(builtin...) __attribute__((__diagnose_as_builtin__(builtin))) +#else +# define __diagnose_as(builtin...) +#endif + /* * Don't. Just don't. See commit 771c035372a0 ("deprecate the '__deprecated' * attribute warnings entirely and for good") for more information. From 0a2b782a00f33e7d06dc43d099fa071ae97bee77 Mon Sep 17 00:00:00 2001 From: Kees Cook Date: Tue, 8 Feb 2022 14:53:47 -0800 Subject: [PATCH 140/370] fortify: Make pointer arguments const In preparation for using Clang's __pass_object_size attribute, make all the pointer arguments to the fortified string functions const. Nothing was changing their values anyway, so this added requirement (needed by __pass_object_size) requires no code changes and has no impact on the binary instruction output. Signed-off-by: Kees Cook Reviewed-by: Nick Desaulniers Link: https://lore.kernel.org/r/20220208225350.1331628-6-keescook@chromium.org --- include/linux/fortify-string.h | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/include/linux/fortify-string.h b/include/linux/fortify-string.h index 439aad24ab3b..f874ada4b9af 100644 --- a/include/linux/fortify-string.h +++ b/include/linux/fortify-string.h @@ -50,7 +50,7 @@ extern char *__underlying_strncpy(char *p, const char *q, __kernel_size_t size) #define __underlying_strncpy __builtin_strncpy #endif -__FORTIFY_INLINE char *strncpy(char *p, const char *q, __kernel_size_t size) +__FORTIFY_INLINE char *strncpy(char * const p, const char *q, __kernel_size_t size) { size_t p_size = __builtin_object_size(p, 1); @@ -61,7 +61,7 @@ __FORTIFY_INLINE char *strncpy(char *p, const char *q, __kernel_size_t size) return __underlying_strncpy(p, q, size); } -__FORTIFY_INLINE char *strcat(char *p, const char *q) +__FORTIFY_INLINE char *strcat(char * const p, const char *q) { size_t p_size = __builtin_object_size(p, 1); @@ -73,7 +73,7 @@ __FORTIFY_INLINE char *strcat(char *p, const char *q) } extern __kernel_size_t __real_strnlen(const char *, __kernel_size_t) __RENAME(strnlen); -__FORTIFY_INLINE __kernel_size_t strnlen(const char *p, __kernel_size_t maxlen) +__FORTIFY_INLINE __kernel_size_t strnlen(const char * const p, __kernel_size_t maxlen) { size_t p_size = __builtin_object_size(p, 1); size_t p_len = __compiletime_strlen(p); @@ -94,7 +94,7 @@ __FORTIFY_INLINE __kernel_size_t strnlen(const char *p, __kernel_size_t maxlen) } /* defined after fortified strnlen to reuse it. */ -__FORTIFY_INLINE __kernel_size_t strlen(const char *p) +__FORTIFY_INLINE __kernel_size_t strlen(const char * const p) { __kernel_size_t ret; size_t p_size = __builtin_object_size(p, 1); @@ -110,7 +110,7 @@ __FORTIFY_INLINE __kernel_size_t strlen(const char *p) /* defined after fortified strlen to reuse it */ extern size_t __real_strlcpy(char *, const char *, size_t) __RENAME(strlcpy); -__FORTIFY_INLINE size_t strlcpy(char *p, const char *q, size_t size) +__FORTIFY_INLINE size_t strlcpy(char * const p, const char * const q, size_t size) { size_t p_size = __builtin_object_size(p, 1); size_t q_size = __builtin_object_size(q, 1); @@ -137,7 +137,7 @@ __FORTIFY_INLINE size_t strlcpy(char *p, const char *q, size_t size) /* defined after fortified strnlen to reuse it */ extern ssize_t __real_strscpy(char *, const char *, size_t) __RENAME(strscpy); -__FORTIFY_INLINE ssize_t strscpy(char *p, const char *q, size_t size) +__FORTIFY_INLINE ssize_t strscpy(char * const p, const char * const q, size_t size) { size_t len; /* Use string size rather than possible enclosing struct size. */ @@ -183,7 +183,7 @@ __FORTIFY_INLINE ssize_t strscpy(char *p, const char *q, size_t size) } /* defined after fortified strlen and strnlen to reuse them */ -__FORTIFY_INLINE char *strncat(char *p, const char *q, __kernel_size_t count) +__FORTIFY_INLINE char *strncat(char * const p, const char * const q, __kernel_size_t count) { size_t p_len, copy_len; size_t p_size = __builtin_object_size(p, 1); @@ -354,7 +354,7 @@ __FORTIFY_INLINE void fortify_memcpy_chk(__kernel_size_t size, memmove) extern void *__real_memscan(void *, int, __kernel_size_t) __RENAME(memscan); -__FORTIFY_INLINE void *memscan(void *p, int c, __kernel_size_t size) +__FORTIFY_INLINE void *memscan(void * const p, int c, __kernel_size_t size) { size_t p_size = __builtin_object_size(p, 0); @@ -365,7 +365,7 @@ __FORTIFY_INLINE void *memscan(void *p, int c, __kernel_size_t size) return __real_memscan(p, c, size); } -__FORTIFY_INLINE int memcmp(const void *p, const void *q, __kernel_size_t size) +__FORTIFY_INLINE int memcmp(const void * const p, const void * const q, __kernel_size_t size) { size_t p_size = __builtin_object_size(p, 0); size_t q_size = __builtin_object_size(q, 0); @@ -381,7 +381,7 @@ __FORTIFY_INLINE int memcmp(const void *p, const void *q, __kernel_size_t size) return __underlying_memcmp(p, q, size); } -__FORTIFY_INLINE void *memchr(const void *p, int c, __kernel_size_t size) +__FORTIFY_INLINE void *memchr(const void * const p, int c, __kernel_size_t size) { size_t p_size = __builtin_object_size(p, 0); @@ -393,7 +393,7 @@ __FORTIFY_INLINE void *memchr(const void *p, int c, __kernel_size_t size) } void *__real_memchr_inv(const void *s, int c, size_t n) __RENAME(memchr_inv); -__FORTIFY_INLINE void *memchr_inv(const void *p, int c, size_t size) +__FORTIFY_INLINE void *memchr_inv(const void * const p, int c, size_t size) { size_t p_size = __builtin_object_size(p, 0); @@ -405,7 +405,7 @@ __FORTIFY_INLINE void *memchr_inv(const void *p, int c, size_t size) } extern void *__real_kmemdup(const void *src, size_t len, gfp_t gfp) __RENAME(kmemdup); -__FORTIFY_INLINE void *kmemdup(const void *p, size_t size, gfp_t gfp) +__FORTIFY_INLINE void *kmemdup(const void * const p, size_t size, gfp_t gfp) { size_t p_size = __builtin_object_size(p, 0); @@ -417,7 +417,7 @@ __FORTIFY_INLINE void *kmemdup(const void *p, size_t size, gfp_t gfp) } /* Defined after fortified strlen to reuse it. */ -__FORTIFY_INLINE char *strcpy(char *p, const char *q) +__FORTIFY_INLINE char *strcpy(char * const p, const char * const q) { size_t p_size = __builtin_object_size(p, 1); size_t q_size = __builtin_object_size(q, 1); From 92df138a8d663cefebc3124041253677a53c92cf Mon Sep 17 00:00:00 2001 From: Kees Cook Date: Tue, 8 Feb 2022 14:53:48 -0800 Subject: [PATCH 141/370] fortify: Use __diagnose_as() for better diagnostic coverage In preparation for using Clang's __pass_object_size, add __diagnose_as() attributes to mark the functions as being the same as the indicated builtins. When __daignose_as() is available, Clang will have a more complete ability to apply its own diagnostic analysis to callers of these functions, as if they were the builtins themselves. Without __diagnose_as, Clang's compile time diagnostic messages won't be as precise as they could be, but at least users of older toolchains will still benefit from having fortified routines. Signed-off-by: Kees Cook Reviewed-by: Nick Desaulniers Link: https://lore.kernel.org/r/20220208225350.1331628-7-keescook@chromium.org --- include/linux/fortify-string.h | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/include/linux/fortify-string.h b/include/linux/fortify-string.h index f874ada4b9af..db1ad1c1c79a 100644 --- a/include/linux/fortify-string.h +++ b/include/linux/fortify-string.h @@ -50,7 +50,8 @@ extern char *__underlying_strncpy(char *p, const char *q, __kernel_size_t size) #define __underlying_strncpy __builtin_strncpy #endif -__FORTIFY_INLINE char *strncpy(char * const p, const char *q, __kernel_size_t size) +__FORTIFY_INLINE __diagnose_as(__builtin_strncpy, 1, 2, 3) +char *strncpy(char * const p, const char *q, __kernel_size_t size) { size_t p_size = __builtin_object_size(p, 1); @@ -61,7 +62,8 @@ __FORTIFY_INLINE char *strncpy(char * const p, const char *q, __kernel_size_t si return __underlying_strncpy(p, q, size); } -__FORTIFY_INLINE char *strcat(char * const p, const char *q) +__FORTIFY_INLINE __diagnose_as(__builtin_strcat, 1, 2) +char *strcat(char * const p, const char *q) { size_t p_size = __builtin_object_size(p, 1); @@ -94,7 +96,8 @@ __FORTIFY_INLINE __kernel_size_t strnlen(const char * const p, __kernel_size_t m } /* defined after fortified strnlen to reuse it. */ -__FORTIFY_INLINE __kernel_size_t strlen(const char * const p) +__FORTIFY_INLINE __diagnose_as(__builtin_strlen, 1) +__kernel_size_t strlen(const char * const p) { __kernel_size_t ret; size_t p_size = __builtin_object_size(p, 1); @@ -183,7 +186,8 @@ __FORTIFY_INLINE ssize_t strscpy(char * const p, const char * const q, size_t si } /* defined after fortified strlen and strnlen to reuse them */ -__FORTIFY_INLINE char *strncat(char * const p, const char * const q, __kernel_size_t count) +__FORTIFY_INLINE __diagnose_as(__builtin_strncat, 1, 2, 3) +char *strncat(char * const p, const char * const q, __kernel_size_t count) { size_t p_len, copy_len; size_t p_size = __builtin_object_size(p, 1); @@ -365,7 +369,8 @@ __FORTIFY_INLINE void *memscan(void * const p, int c, __kernel_size_t size) return __real_memscan(p, c, size); } -__FORTIFY_INLINE int memcmp(const void * const p, const void * const q, __kernel_size_t size) +__FORTIFY_INLINE __diagnose_as(__builtin_memcmp, 1, 2, 3) +int memcmp(const void * const p, const void * const q, __kernel_size_t size) { size_t p_size = __builtin_object_size(p, 0); size_t q_size = __builtin_object_size(q, 0); @@ -381,7 +386,8 @@ __FORTIFY_INLINE int memcmp(const void * const p, const void * const q, __kernel return __underlying_memcmp(p, q, size); } -__FORTIFY_INLINE void *memchr(const void * const p, int c, __kernel_size_t size) +__FORTIFY_INLINE __diagnose_as(__builtin_memchr, 1, 2, 3) +void *memchr(const void * const p, int c, __kernel_size_t size) { size_t p_size = __builtin_object_size(p, 0); @@ -417,7 +423,8 @@ __FORTIFY_INLINE void *kmemdup(const void * const p, size_t size, gfp_t gfp) } /* Defined after fortified strlen to reuse it. */ -__FORTIFY_INLINE char *strcpy(char * const p, const char * const q) +__FORTIFY_INLINE __diagnose_as(__builtin_strcpy, 1, 2) +char *strcpy(char * const p, const char * const q) { size_t p_size = __builtin_object_size(p, 1); size_t q_size = __builtin_object_size(q, 1); From 67ebc3ab446230c77fe3b545a9d8a11cac1cfb6e Mon Sep 17 00:00:00 2001 From: Kees Cook Date: Tue, 8 Feb 2022 14:53:49 -0800 Subject: [PATCH 142/370] fortify: Make sure strlen() may still be used as a constant expression In preparation for enabling Clang FORTIFY_SOURCE support, redefine strlen() as a macro that tests for being a constant expression so that strlen() can still be used in static initializers, which is lost when adding __pass_object_size and __overloadable. An example of this usage can be seen here: https://lore.kernel.org/all/202201252321.dRmWZ8wW-lkp@intel.com/ Notably, this constant expression feature of strlen() is not available for architectures that build with -ffreestanding. This means the kernel currently does not universally expect strlen() to be used this way, but since there _are_ some build configurations that depend on it, retain the characteristic for Clang FORTIFY_SOURCE builds too. Signed-off-by: Kees Cook Reviewed-by: Nick Desaulniers Link: https://lore.kernel.org/r/20220208225350.1331628-8-keescook@chromium.org --- include/linux/fortify-string.h | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/include/linux/fortify-string.h b/include/linux/fortify-string.h index db1ad1c1c79a..f77cf22e2d60 100644 --- a/include/linux/fortify-string.h +++ b/include/linux/fortify-string.h @@ -2,6 +2,8 @@ #ifndef _LINUX_FORTIFY_STRING_H_ #define _LINUX_FORTIFY_STRING_H_ +#include + #define __FORTIFY_INLINE extern __always_inline __gnu_inline #define __RENAME(x) __asm__(#x) @@ -95,9 +97,16 @@ __FORTIFY_INLINE __kernel_size_t strnlen(const char * const p, __kernel_size_t m return ret; } -/* defined after fortified strnlen to reuse it. */ +/* + * Defined after fortified strnlen to reuse it. However, it must still be + * possible for strlen() to be used on compile-time strings for use in + * static initializers (i.e. as a constant expression). + */ +#define strlen(p) \ + __builtin_choose_expr(__is_constexpr(__builtin_strlen(p)), \ + __builtin_strlen(p), __fortify_strlen(p)) __FORTIFY_INLINE __diagnose_as(__builtin_strlen, 1) -__kernel_size_t strlen(const char * const p) +__kernel_size_t __fortify_strlen(const char * const p) { __kernel_size_t ret; size_t p_size = __builtin_object_size(p, 1); From 281d0c962752fb40866dd8d4cade68656f34bd1f Mon Sep 17 00:00:00 2001 From: Kees Cook Date: Tue, 8 Feb 2022 14:53:50 -0800 Subject: [PATCH 143/370] fortify: Add Clang support Enable FORTIFY_SOURCE support for Clang: Use the new __pass_object_size and __overloadable attributes so that Clang will have appropriate visibility into argument sizes such that __builtin_object_size(p, 1) will behave correctly. Additional details available here: https://github.com/llvm/llvm-project/issues/53516 https://github.com/ClangBuiltLinux/linux/issues/1401 A bug with __builtin_constant_p() of globally defined variables was fixed in Clang 13 (and backported to 12.0.1), so FORTIFY support must depend on that version or later. Additional details here: https://bugs.llvm.org/show_bug.cgi?id=41459 commit a52f8a59aef4 ("fortify: Explicitly disable Clang support") A bug with Clang's -mregparm=3 and -m32 makes some builtins unusable, so removing -ffreestanding (to gain the needed libcall optimizations with Clang) cannot be done. Without the libcall optimizations, Clang cannot provide appropriate FORTIFY coverage, so it must be disabled for CONFIG_X86_32. Additional details here; https://github.com/llvm/llvm-project/issues/53645 Cc: Miguel Ojeda Cc: Nick Desaulniers Cc: Nathan Chancellor Cc: George Burgess IV Cc: llvm@lists.linux.dev Signed-off-by: Kees Cook Reviewed-by: Nick Desaulniers Link: https://lore.kernel.org/r/20220208225350.1331628-9-keescook@chromium.org --- include/linux/fortify-string.h | 40 ++++++++++++++++++++++------------ security/Kconfig | 5 +++-- 2 files changed, 29 insertions(+), 16 deletions(-) diff --git a/include/linux/fortify-string.h b/include/linux/fortify-string.h index f77cf22e2d60..295637a66c46 100644 --- a/include/linux/fortify-string.h +++ b/include/linux/fortify-string.h @@ -4,7 +4,7 @@ #include -#define __FORTIFY_INLINE extern __always_inline __gnu_inline +#define __FORTIFY_INLINE extern __always_inline __gnu_inline __overloadable #define __RENAME(x) __asm__(#x) void fortify_panic(const char *name) __noreturn __cold; @@ -52,8 +52,17 @@ extern char *__underlying_strncpy(char *p, const char *q, __kernel_size_t size) #define __underlying_strncpy __builtin_strncpy #endif +/* + * Clang's use of __builtin_object_size() within inlines needs hinting via + * __pass_object_size(). The preference is to only ever use type 1 (member + * size, rather than struct size), but there remain some stragglers using + * type 0 that will be converted in the future. + */ +#define POS __pass_object_size(1) +#define POS0 __pass_object_size(0) + __FORTIFY_INLINE __diagnose_as(__builtin_strncpy, 1, 2, 3) -char *strncpy(char * const p, const char *q, __kernel_size_t size) +char *strncpy(char * const POS p, const char *q, __kernel_size_t size) { size_t p_size = __builtin_object_size(p, 1); @@ -65,7 +74,7 @@ char *strncpy(char * const p, const char *q, __kernel_size_t size) } __FORTIFY_INLINE __diagnose_as(__builtin_strcat, 1, 2) -char *strcat(char * const p, const char *q) +char *strcat(char * const POS p, const char *q) { size_t p_size = __builtin_object_size(p, 1); @@ -77,7 +86,7 @@ char *strcat(char * const p, const char *q) } extern __kernel_size_t __real_strnlen(const char *, __kernel_size_t) __RENAME(strnlen); -__FORTIFY_INLINE __kernel_size_t strnlen(const char * const p, __kernel_size_t maxlen) +__FORTIFY_INLINE __kernel_size_t strnlen(const char * const POS p, __kernel_size_t maxlen) { size_t p_size = __builtin_object_size(p, 1); size_t p_len = __compiletime_strlen(p); @@ -106,7 +115,7 @@ __FORTIFY_INLINE __kernel_size_t strnlen(const char * const p, __kernel_size_t m __builtin_choose_expr(__is_constexpr(__builtin_strlen(p)), \ __builtin_strlen(p), __fortify_strlen(p)) __FORTIFY_INLINE __diagnose_as(__builtin_strlen, 1) -__kernel_size_t __fortify_strlen(const char * const p) +__kernel_size_t __fortify_strlen(const char * const POS p) { __kernel_size_t ret; size_t p_size = __builtin_object_size(p, 1); @@ -122,7 +131,7 @@ __kernel_size_t __fortify_strlen(const char * const p) /* defined after fortified strlen to reuse it */ extern size_t __real_strlcpy(char *, const char *, size_t) __RENAME(strlcpy); -__FORTIFY_INLINE size_t strlcpy(char * const p, const char * const q, size_t size) +__FORTIFY_INLINE size_t strlcpy(char * const POS p, const char * const POS q, size_t size) { size_t p_size = __builtin_object_size(p, 1); size_t q_size = __builtin_object_size(q, 1); @@ -149,7 +158,7 @@ __FORTIFY_INLINE size_t strlcpy(char * const p, const char * const q, size_t siz /* defined after fortified strnlen to reuse it */ extern ssize_t __real_strscpy(char *, const char *, size_t) __RENAME(strscpy); -__FORTIFY_INLINE ssize_t strscpy(char * const p, const char * const q, size_t size) +__FORTIFY_INLINE ssize_t strscpy(char * const POS p, const char * const POS q, size_t size) { size_t len; /* Use string size rather than possible enclosing struct size. */ @@ -196,7 +205,7 @@ __FORTIFY_INLINE ssize_t strscpy(char * const p, const char * const q, size_t si /* defined after fortified strlen and strnlen to reuse them */ __FORTIFY_INLINE __diagnose_as(__builtin_strncat, 1, 2, 3) -char *strncat(char * const p, const char * const q, __kernel_size_t count) +char *strncat(char * const POS p, const char * const POS q, __kernel_size_t count) { size_t p_len, copy_len; size_t p_size = __builtin_object_size(p, 1); @@ -367,7 +376,7 @@ __FORTIFY_INLINE void fortify_memcpy_chk(__kernel_size_t size, memmove) extern void *__real_memscan(void *, int, __kernel_size_t) __RENAME(memscan); -__FORTIFY_INLINE void *memscan(void * const p, int c, __kernel_size_t size) +__FORTIFY_INLINE void *memscan(void * const POS0 p, int c, __kernel_size_t size) { size_t p_size = __builtin_object_size(p, 0); @@ -379,7 +388,7 @@ __FORTIFY_INLINE void *memscan(void * const p, int c, __kernel_size_t size) } __FORTIFY_INLINE __diagnose_as(__builtin_memcmp, 1, 2, 3) -int memcmp(const void * const p, const void * const q, __kernel_size_t size) +int memcmp(const void * const POS0 p, const void * const POS0 q, __kernel_size_t size) { size_t p_size = __builtin_object_size(p, 0); size_t q_size = __builtin_object_size(q, 0); @@ -396,7 +405,7 @@ int memcmp(const void * const p, const void * const q, __kernel_size_t size) } __FORTIFY_INLINE __diagnose_as(__builtin_memchr, 1, 2, 3) -void *memchr(const void * const p, int c, __kernel_size_t size) +void *memchr(const void * const POS0 p, int c, __kernel_size_t size) { size_t p_size = __builtin_object_size(p, 0); @@ -408,7 +417,7 @@ void *memchr(const void * const p, int c, __kernel_size_t size) } void *__real_memchr_inv(const void *s, int c, size_t n) __RENAME(memchr_inv); -__FORTIFY_INLINE void *memchr_inv(const void * const p, int c, size_t size) +__FORTIFY_INLINE void *memchr_inv(const void * const POS0 p, int c, size_t size) { size_t p_size = __builtin_object_size(p, 0); @@ -420,7 +429,7 @@ __FORTIFY_INLINE void *memchr_inv(const void * const p, int c, size_t size) } extern void *__real_kmemdup(const void *src, size_t len, gfp_t gfp) __RENAME(kmemdup); -__FORTIFY_INLINE void *kmemdup(const void * const p, size_t size, gfp_t gfp) +__FORTIFY_INLINE void *kmemdup(const void * const POS0 p, size_t size, gfp_t gfp) { size_t p_size = __builtin_object_size(p, 0); @@ -433,7 +442,7 @@ __FORTIFY_INLINE void *kmemdup(const void * const p, size_t size, gfp_t gfp) /* Defined after fortified strlen to reuse it. */ __FORTIFY_INLINE __diagnose_as(__builtin_strcpy, 1, 2) -char *strcpy(char * const p, const char * const q) +char *strcpy(char * const POS p, const char * const POS q) { size_t p_size = __builtin_object_size(p, 1); size_t q_size = __builtin_object_size(q, 1); @@ -462,4 +471,7 @@ char *strcpy(char * const p, const char * const q) #undef __underlying_strncat #undef __underlying_strncpy +#undef POS +#undef POS0 + #endif /* _LINUX_FORTIFY_STRING_H_ */ diff --git a/security/Kconfig b/security/Kconfig index 0b847f435beb..1d2d71cc1f36 100644 --- a/security/Kconfig +++ b/security/Kconfig @@ -177,9 +177,10 @@ config HARDENED_USERCOPY_PAGESPAN config FORTIFY_SOURCE bool "Harden common str/mem functions against buffer overflows" depends on ARCH_HAS_FORTIFY_SOURCE - # https://bugs.llvm.org/show_bug.cgi?id=50322 # https://bugs.llvm.org/show_bug.cgi?id=41459 - depends on !CC_IS_CLANG + depends on !CC_IS_CLANG || CLANG_VERSION >= 120001 + # https://github.com/llvm/llvm-project/issues/53645 + depends on !CC_IS_CLANG || !X86_32 help Detect overflows of buffers in common string and memory functions where the compiler can determine and validate the buffer sizes. From 1de785a58035031f81a43c42f355fa1db510dc36 Mon Sep 17 00:00:00 2001 From: Jeff LaBundy Date: Sun, 23 Jan 2022 13:01:05 -0600 Subject: [PATCH 144/370] mfd: iqs62x: Provide device revision to sub-devices Individual sub-devices may elect to make decisions based on the specific revision of silicon encountered at probe. This data is already read from the device, but is not retained. Pass this data on to the sub-devices by adding the software and hardware numbers (registers 0x01 and 0x02, respectively) to the iqs62x_core struct. Signed-off-by: Jeff LaBundy Signed-off-by: Lee Jones --- drivers/mfd/iqs62x.c | 6 +++--- include/linux/mfd/iqs62x.h | 7 +++++++ 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/drivers/mfd/iqs62x.c b/drivers/mfd/iqs62x.c index 9805cf191245..575ab67e243d 100644 --- a/drivers/mfd/iqs62x.c +++ b/drivers/mfd/iqs62x.c @@ -898,7 +898,6 @@ static int iqs62x_probe(struct i2c_client *client) struct iqs62x_info info; unsigned int val; int ret, i, j; - u8 sw_num = 0; const char *fw_name = NULL; iqs62x = devm_kzalloc(&client->dev, sizeof(*iqs62x), GFP_KERNEL); @@ -949,7 +948,8 @@ static int iqs62x_probe(struct i2c_client *client) if (info.sw_num < iqs62x->dev_desc->sw_num) continue; - sw_num = info.sw_num; + iqs62x->sw_num = info.sw_num; + iqs62x->hw_num = info.hw_num; /* * Read each of the device's designated calibration registers, @@ -985,7 +985,7 @@ static int iqs62x_probe(struct i2c_client *client) return -EINVAL; } - if (!sw_num) { + if (!iqs62x->sw_num) { dev_err(&client->dev, "Unrecognized software number: 0x%02X\n", info.sw_num); return -EINVAL; diff --git a/include/linux/mfd/iqs62x.h b/include/linux/mfd/iqs62x.h index 5ced55eae11b..ffc86010af74 100644 --- a/include/linux/mfd/iqs62x.h +++ b/include/linux/mfd/iqs62x.h @@ -14,6 +14,11 @@ #define IQS624_PROD_NUM 0x43 #define IQS625_PROD_NUM 0x4E +#define IQS620_HW_NUM_V0 0x82 +#define IQS620_HW_NUM_V1 IQS620_HW_NUM_V0 +#define IQS620_HW_NUM_V2 IQS620_HW_NUM_V0 +#define IQS620_HW_NUM_V3 0x92 + #define IQS621_ALS_FLAGS 0x16 #define IQS622_ALS_FLAGS 0x14 @@ -129,6 +134,8 @@ struct iqs62x_core { struct completion fw_done; enum iqs62x_ui_sel ui_sel; unsigned long event_cache; + u8 sw_num; + u8 hw_num; }; extern const struct iqs62x_event_desc iqs62x_events[IQS62X_NUM_EVENTS]; From 9e444dbf278c604110762b25d8e0b4e9f1d27dbc Mon Sep 17 00:00:00 2001 From: Jeff LaBundy Date: Sun, 23 Jan 2022 13:01:06 -0600 Subject: [PATCH 145/370] iio: temperature: iqs620at-temp: Add support for V3 silicon The vendor introduced an updated revision of IQS620A(T) silicon which is backwards-compatible with previous revisions, the only exception being the offset used to derive temperature. Enable this new revision by returning the appropriate offset as a function of the hardware number provided by the parent MFD. Signed-off-by: Jeff LaBundy Signed-off-by: Lee Jones --- drivers/iio/temperature/iqs620at-temp.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/iio/temperature/iqs620at-temp.c b/drivers/iio/temperature/iqs620at-temp.c index fe126e1fb783..e2f878d57af7 100644 --- a/drivers/iio/temperature/iqs620at-temp.c +++ b/drivers/iio/temperature/iqs620at-temp.c @@ -17,6 +17,7 @@ #define IQS620_TEMP_SCALE 1000 #define IQS620_TEMP_OFFSET (-100) +#define IQS620_TEMP_OFFSET_V3 (-40) static int iqs620_temp_read_raw(struct iio_dev *indio_dev, struct iio_chan_spec const *chan, @@ -41,7 +42,8 @@ static int iqs620_temp_read_raw(struct iio_dev *indio_dev, return IIO_VAL_INT; case IIO_CHAN_INFO_OFFSET: - *val = IQS620_TEMP_OFFSET; + *val = iqs62x->hw_num < IQS620_HW_NUM_V3 ? IQS620_TEMP_OFFSET + : IQS620_TEMP_OFFSET_V3; return IIO_VAL_INT; default: From af31e2b729a215a1a1d40939bcfccdbab9971deb Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Tue, 11 Jan 2022 18:50:14 +0100 Subject: [PATCH 146/370] dt-bindings: leds: maxim,max77693: Convert to dtschema Convert the LEDs bindings of Maxim MAX77693 MUIC to DT schema format. The existing bindings were defined in ../bindings/mfd/max77693.txt. Signed-off-by: Krzysztof Kozlowski Reviewed-by: Rob Herring Signed-off-by: Lee Jones --- .../bindings/leds/maxim,max77693.yaml | 105 ++++++++++++++++++ 1 file changed, 105 insertions(+) create mode 100644 Documentation/devicetree/bindings/leds/maxim,max77693.yaml diff --git a/Documentation/devicetree/bindings/leds/maxim,max77693.yaml b/Documentation/devicetree/bindings/leds/maxim,max77693.yaml new file mode 100644 index 000000000000..86a0005cf156 --- /dev/null +++ b/Documentation/devicetree/bindings/leds/maxim,max77693.yaml @@ -0,0 +1,105 @@ +# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/leds/maxim,max77693.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Maxim MAX77693 MicroUSB and Companion Power Management IC LEDs + +maintainers: + - Krzysztof Kozlowski + +description: | + This is a part of device tree bindings for Maxim MAX77693 MicroUSB Integrated + Circuit (MUIC). + + There are two LED outputs available - FLED1 and FLED2. Each of them can + control a separate LED or they can be connected together to double the + maximum current for a single connected LED. One LED is represented by one + child node. + + See also Documentation/devicetree/bindings/mfd/maxim,max77693.yaml for + additional information and example. + +properties: + compatible: + const: maxim,max77693-led + + maxim,boost-mode: + description: + In boost mode the device can produce up to 1.2A of total current on both + outputs. The maximum current on each output is reduced to 625mA then. If + not enabled explicitly, boost setting defaults to LEDS_BOOST_FIXED in + case both current sources are used. + See LEDS_BOOST_* in include/dt-bindings/leds/common.h. + $ref: /schemas/types.yaml#/definitions/uint32 + enum: [0, 1, 2] + + maxim,boost-mvout: + description: | + Output voltage of the boost module in millivolts. + Valid values: 3300 - 5500, step by 25 (rounded down) + $ref: /schemas/types.yaml#/definitions/uint32 + minimum: 3300 + maximum: 5500 + default: 3300 + + maxim,mvsys-min: + description: | + Low input voltage level in millivolts. Flash is not fired if chip + estimates that system voltage could drop below this level due to flash + power consumption. + Valid values: 2400 - 3400, step by 33 (rounded down) + $ref: /schemas/types.yaml#/definitions/uint32 + minimum: 2400 + maximum: 3400 + default: 2400 + +patternProperties: + "^([a-z]+-)?led[01]?$": + type: object + $ref: common.yaml# + unevaluatedProperties: false + + properties: + led-sources: + allOf: + - minItems: 1 + maxItems: 2 + items: + minimum: 0 + maximum: 1 + + led-max-microamp: + description: | + Valid values for a LED connected to one FLED output: + 15625 - 250000, step by 15625 (rounded down) + Valid values for a LED connected to both FLED outputs: + 15625 - 500000, step by 15625 (rounded down) + + flash-max-microamp: + description: | + Valid values for a single LED connected to one FLED output + (boost mode must be turned off): + 15625 - 1000000, step by 15625 (rounded down) + Valid values for a single LED connected to both FLED outputs: + 15625 - 1250000, step by 15625 (rounded down) + Valid values for two LEDs case: + 15625 - 625000, step by 15625 (rounded down) + + flash-max-timeout-us: + description: | + Valid values: 62500 - 1000000, step by 62500 (rounded down) + minimum: 62500 + maximum: 1000000 + + required: + - flash-max-microamp + - flash-max-timeout-us + - led-max-microamp + - led-sources + +required: + - compatible + +additionalProperties: false From a400122b2a9685f6758be817f2a9043bd641af7b Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Tue, 11 Jan 2022 18:50:15 +0100 Subject: [PATCH 147/370] dt-bindings: power: supply: maxim,max77693: Convert to dtschema Convert the Charger bindings of Maxim MAX77693 MUIC to DT schema format. The existing bindings were defined in ../bindings/mfd/max77693.txt. Signed-off-by: Krzysztof Kozlowski Reviewed-by: Rob Herring Signed-off-by: Lee Jones --- .../bindings/power/supply/maxim,max77693.yaml | 70 +++++++++++++++++++ MAINTAINERS | 1 + 2 files changed, 71 insertions(+) create mode 100644 Documentation/devicetree/bindings/power/supply/maxim,max77693.yaml diff --git a/Documentation/devicetree/bindings/power/supply/maxim,max77693.yaml b/Documentation/devicetree/bindings/power/supply/maxim,max77693.yaml new file mode 100644 index 000000000000..a21dc1a8890f --- /dev/null +++ b/Documentation/devicetree/bindings/power/supply/maxim,max77693.yaml @@ -0,0 +1,70 @@ +# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/power/supply/maxim,max77693.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Maxim MAX77693 MicroUSB and Companion Power Management IC Charger + +maintainers: + - Krzysztof Kozlowski + +description: | + This is a part of device tree bindings for Maxim MAX77693 MicroUSB Integrated + Circuit (MUIC). + + See also Documentation/devicetree/bindings/mfd/maxim,max77693.yaml for + additional information and example. + +properties: + compatible: + const: maxim,max77693-charger + + maxim,constant-microvolt: + description: | + Battery constant voltage in uV. The charger will operate in fast + charge constant current mode till battery voltage reaches this level. + Then the charger will switch to fast charge constant voltage mode. + Also vsys (system voltage) will be set to this value when DC power is + supplied but charger is not enabled. + Valid values: 3650000 - 4400000, step by 25000 (rounded down) + minimum: 3650000 + maximum: 4400000 + default: 4200000 + + maxim,min-system-microvolt: + description: | + Minimal system voltage in uV. + enum: [3000000, 3100000, 3200000, 3300000, 3400000, 3500000, + 3600000, 3700000] + default: 3600000 + + maxim,thermal-regulation-celsius: + description: | + Temperature in Celsius for entering high temperature charging mode. + If die temperature exceeds this value the charging current will be + reduced by 105 mA/Celsius. + enum: [70, 85, 100, 115] + default: 100 + + maxim,battery-overcurrent-microamp: + description: | + Overcurrent protection threshold in uA (current from battery to + system). + Valid values: 2000000 - 3500000, step by 250000 (rounded down) + minimum: 2000000 + maximum: 3500000 + default: 3500000 + + maxim,charge-input-threshold-microvolt: + description: | + Threshold voltage in uV for triggering input voltage regulation loop. + If input voltage decreases below this value, the input current will + be reduced to reach the threshold voltage. + enum: [4300000, 4700000, 4800000, 4900000] + default: 4300000 + +required: + - compatible + +additionalProperties: false diff --git a/MAINTAINERS b/MAINTAINERS index ea3e6c914384..7e3a45578747 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -11710,6 +11710,7 @@ M: Krzysztof Kozlowski M: Bartlomiej Zolnierkiewicz L: linux-pm@vger.kernel.org S: Supported +F: Documentation/devicetree/bindings/power/supply/maxim,max77693.yaml F: drivers/power/supply/max14577_charger.c F: drivers/power/supply/max77693_charger.c From 1a2c2cac2cae13cfd78904923eff0356f2d3f071 Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Tue, 11 Jan 2022 18:50:16 +0100 Subject: [PATCH 148/370] regulator: dt-bindings: maxim,max77693: Convert to dtschema Convert the regulator bindings of Maxim MAX77693 MUIC to DT schema format. The existing bindings were defined in ../bindings/mfd/max77693.txt. Signed-off-by: Krzysztof Kozlowski Reviewed-by: Rob Herring Signed-off-by: Lee Jones --- .../bindings/regulator/maxim,max77693.yaml | 60 +++++++++++++++++++ 1 file changed, 60 insertions(+) create mode 100644 Documentation/devicetree/bindings/regulator/maxim,max77693.yaml diff --git a/Documentation/devicetree/bindings/regulator/maxim,max77693.yaml b/Documentation/devicetree/bindings/regulator/maxim,max77693.yaml new file mode 100644 index 000000000000..20d8559bdc2b --- /dev/null +++ b/Documentation/devicetree/bindings/regulator/maxim,max77693.yaml @@ -0,0 +1,60 @@ +# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/regulator/maxim,max77693.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Maxim MAX77693 MicroUSB and Companion Power Management IC regulators + +maintainers: + - Chanwoo Choi + - Krzysztof Kozlowski + +description: | + This is a part of device tree bindings for Maxim MAX77693 MicroUSB Integrated + Circuit (MUIC). + + See also Documentation/devicetree/bindings/mfd/maxim,max77693.yaml for + additional information and example. + +properties: + CHARGER: + type: object + $ref: regulator.yaml# + additionalProperties: false + description: | + Current regulator. + + properties: + regulator-name: true + regulator-always-on: true + regulator-boot-on: true + regulator-min-microamp: + minimum: 60000 + regulator-max-microamp: + maximum: 2580000 + + required: + - regulator-name + +patternProperties: + "^ESAFEOUT[12]$": + type: object + $ref: regulator.yaml# + additionalProperties: false + description: | + Safeout LDO regulator. + + properties: + regulator-name: true + regulator-always-on: true + regulator-boot-on: true + regulator-min-microvolt: + minimum: 3300000 + regulator-max-microvolt: + maximum: 4950000 + + required: + - regulator-name + +additionalProperties: false From b38213c6118b6b3fe163bd9acb7f723c379dd833 Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Tue, 11 Jan 2022 18:50:17 +0100 Subject: [PATCH 149/370] dt-bindings: mfd: maxim,max77693: Convert to dtschema Convert the MFD part of Maxim MAX77693 MUIC to DT schema format. The example DTS was copied from existing DTS (exynos4412-midas.dtsi), so keep the license as GPL-2.0-only. Signed-off-by: Krzysztof Kozlowski Reviewed-by: Rob Herring Signed-off-by: Lee Jones --- .../devicetree/bindings/mfd/max77693.txt | 194 ------------------ .../bindings/mfd/maxim,max77693.yaml | 143 +++++++++++++ MAINTAINERS | 2 +- 3 files changed, 144 insertions(+), 195 deletions(-) delete mode 100644 Documentation/devicetree/bindings/mfd/max77693.txt create mode 100644 Documentation/devicetree/bindings/mfd/maxim,max77693.yaml diff --git a/Documentation/devicetree/bindings/mfd/max77693.txt b/Documentation/devicetree/bindings/mfd/max77693.txt deleted file mode 100644 index 1032df14498b..000000000000 --- a/Documentation/devicetree/bindings/mfd/max77693.txt +++ /dev/null @@ -1,194 +0,0 @@ -Maxim MAX77693 multi-function device - -MAX77693 is a Multifunction device with the following submodules: -- PMIC, -- CHARGER, -- LED, -- MUIC, -- HAPTIC - -It is interfaced to host controller using i2c. -This document describes the bindings for the mfd device. - -Required properties: -- compatible : Must be "maxim,max77693". -- reg : Specifies the i2c slave address of PMIC block. -- interrupts : This i2c device has an IRQ line connected to the main SoC. - -Optional properties: -- regulators : The regulators of max77693 have to be instantiated under subnode - named "regulators" using the following format. - - regulators { - regulator-compatible = ESAFEOUT1/ESAFEOUT2/CHARGER - standard regulator constraints[*]. - }; - - [*] refer Documentation/devicetree/bindings/regulator/regulator.txt - -- haptic : The MAX77693 haptic device utilises a PWM controlled motor to provide - users with tactile feedback. PWM period and duty-cycle are varied in - order to provide the appropriate level of feedback. - - Required properties: - - compatible : Must be "maxim,max77693-haptic" - - haptic-supply : power supply for the haptic motor - [*] refer Documentation/devicetree/bindings/regulator/regulator.txt - - pwms : phandle to the physical PWM(Pulse Width Modulation) device. - PWM properties should be named "pwms". And number of cell is different - for each pwm device. - To get more information, please refer to documentation. - [*] refer Documentation/devicetree/bindings/pwm/pwm.txt - -- charger : Node configuring the charger driver. - If present, required properties: - - compatible : Must be "maxim,max77693-charger". - - Optional properties (if not set, defaults will be used): - - maxim,constant-microvolt : Battery constant voltage in uV. The charger - will operate in fast charge constant current mode till battery voltage - reaches this level. Then the charger will switch to fast charge constant - voltage mode. Also vsys (system voltage) will be set to this value when - DC power is supplied but charger is not enabled. - Valid values: 3650000 - 4400000, step by 25000 (rounded down) - Default: 4200000 - - - maxim,min-system-microvolt : Minimal system voltage in uV. - Valid values: 3000000 - 3700000, step by 100000 (rounded down) - Default: 3600000 - - - maxim,thermal-regulation-celsius : Temperature in Celsius for entering - high temperature charging mode. If die temperature exceeds this value - the charging current will be reduced by 105 mA/Celsius. - Valid values: 70, 85, 100, 115 - Default: 100 - - - maxim,battery-overcurrent-microamp : Overcurrent protection threshold - in uA (current from battery to system). - Valid values: 2000000 - 3500000, step by 250000 (rounded down) - Default: 3500000 - - - maxim,charge-input-threshold-microvolt : Threshold voltage in uV for - triggering input voltage regulation loop. If input voltage decreases - below this value, the input current will be reduced to reach the - threshold voltage. - Valid values: 4300000, 4700000, 4800000, 4900000 - Default: 4300000 - -- led : the LED submodule device node - -There are two LED outputs available - FLED1 and FLED2. Each of them can -control a separate LED or they can be connected together to double -the maximum current for a single connected LED. One LED is represented -by one child node. - -Required properties: -- compatible : Must be "maxim,max77693-led". - -Optional properties: -- maxim,boost-mode : - In boost mode the device can produce up to 1.2A of total current - on both outputs. The maximum current on each output is reduced - to 625mA then. If not enabled explicitly, boost setting defaults to - LEDS_BOOST_FIXED in case both current sources are used. - Possible values: - LEDS_BOOST_OFF (0) - no boost, - LEDS_BOOST_ADAPTIVE (1) - adaptive mode, - LEDS_BOOST_FIXED (2) - fixed mode. -- maxim,boost-mvout : Output voltage of the boost module in millivolts. - Valid values: 3300 - 5500, step by 25 (rounded down) - Default: 3300 -- maxim,mvsys-min : Low input voltage level in millivolts. Flash is not fired - if chip estimates that system voltage could drop below this level due - to flash power consumption. - Valid values: 2400 - 3400, step by 33 (rounded down) - Default: 2400 - -Required properties for the LED child node: -- led-sources : see Documentation/devicetree/bindings/leds/common.txt; - device current output identifiers: 0 - FLED1, 1 - FLED2 -- led-max-microamp : see Documentation/devicetree/bindings/leds/common.txt - Valid values for a LED connected to one FLED output: - 15625 - 250000, step by 15625 (rounded down) - Valid values for a LED connected to both FLED outputs: - 15625 - 500000, step by 15625 (rounded down) -- flash-max-microamp : see Documentation/devicetree/bindings/leds/common.txt - Valid values for a single LED connected to one FLED output - (boost mode must be turned off): - 15625 - 1000000, step by 15625 (rounded down) - Valid values for a single LED connected to both FLED outputs: - 15625 - 1250000, step by 15625 (rounded down) - Valid values for two LEDs case: - 15625 - 625000, step by 15625 (rounded down) -- flash-max-timeout-us : see Documentation/devicetree/bindings/leds/common.txt - Valid values: 62500 - 1000000, step by 62500 (rounded down) - -Optional properties for the LED child node: -- label : see Documentation/devicetree/bindings/leds/common.txt - -Optional nodes: -- max77693-muic : - Node used only by extcon consumers. - Required properties: - - compatible : "maxim,max77693-muic" - -Example: -#include - - max77693@66 { - compatible = "maxim,max77693"; - reg = <0x66>; - interrupt-parent = <&gpx1>; - interrupts = <5 IRQ_TYPE_LEVEL_LOW>; - - regulators { - esafeout@1 { - regulator-compatible = "ESAFEOUT1"; - regulator-name = "ESAFEOUT1"; - regulator-boot-on; - }; - esafeout@2 { - regulator-compatible = "ESAFEOUT2"; - regulator-name = "ESAFEOUT2"; - }; - charger@0 { - regulator-compatible = "CHARGER"; - regulator-name = "CHARGER"; - regulator-min-microamp = <60000>; - regulator-max-microamp = <2580000>; - regulator-boot-on; - }; - }; - - haptic { - compatible = "maxim,max77693-haptic"; - haptic-supply = <&haptic_supply>; - pwms = <&pwm 0 40000 0>; - pwm-names = "haptic"; - }; - - charger { - compatible = "maxim,max77693-charger"; - - maxim,constant-microvolt = <4200000>; - maxim,min-system-microvolt = <3600000>; - maxim,thermal-regulation-celsius = <75>; - maxim,battery-overcurrent-microamp = <3000000>; - maxim,charge-input-threshold-microvolt = <4300000>; - }; - - led { - compatible = "maxim,max77693-led"; - maxim,boost-mode = ; - maxim,boost-mvout = <5000>; - maxim,mvsys-min = <2400>; - - camera_flash: flash-led { - label = "max77693-flash"; - led-sources = <0>, <1>; - led-max-microamp = <500000>; - flash-max-microamp = <1250000>; - flash-max-timeout-us = <1000000>; - }; - }; - }; diff --git a/Documentation/devicetree/bindings/mfd/maxim,max77693.yaml b/Documentation/devicetree/bindings/mfd/maxim,max77693.yaml new file mode 100644 index 000000000000..906101197e11 --- /dev/null +++ b/Documentation/devicetree/bindings/mfd/maxim,max77693.yaml @@ -0,0 +1,143 @@ +# SPDX-License-Identifier: GPL-2.0-only +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/mfd/maxim,max77693.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Maxim MAX77693 MicroUSB and Companion Power Management IC + +maintainers: + - Chanwoo Choi + - Krzysztof Kozlowski + +description: | + This is a part of device tree bindings for Maxim MAX77693 MicroUSB + Integrated Circuit (MUIC). + + The Maxim MAX77693 is a MicroUSB and Companion Power Management IC which + includes voltage current regulators, charger, LED/flash, haptic motor driver + and MicroUSB management IC. + +properties: + compatible: + const: maxim,max77693 + + interrupts: + maxItems: 1 + + reg: + maxItems: 1 + + charger: + $ref: /schemas/power/supply/maxim,max77693.yaml + + led: + $ref: /schemas/leds/maxim,max77693.yaml + + max77693-muic: + type: object + additionalProperties: false + + properties: + compatible: + const: maxim,max77693-muic + + required: + - compatible + + motor-driver: + type: object + additionalProperties: false + + properties: + compatible: + const: maxim,max77693-haptic + + haptic-supply: + description: Power supply to the haptic motor + + pwms: + maxItems: 1 + + required: + - compatible + - haptic-supply + - pwms + + regulators: + $ref: ../regulator/maxim,max77693.yaml + description: + List of child nodes that specify the regulators. + +required: + - compatible + - interrupts + - reg + +additionalProperties: false + +examples: + - | + #include + #include + + i2c { + #address-cells = <1>; + #size-cells = <0>; + + pmic@66 { + compatible = "maxim,max77693"; + reg = <0x66>; + interrupt-parent = <&gpx1>; + interrupts = <5 IRQ_TYPE_LEVEL_LOW>; + + regulators { + ESAFEOUT1 { + regulator-name = "ESAFEOUT1"; + }; + + ESAFEOUT2 { + regulator-name = "ESAFEOUT2"; + }; + + CHARGER { + regulator-name = "CHARGER"; + regulator-min-microamp = <60000>; + regulator-max-microamp = <2580000>; + }; + }; + + motor-driver { + compatible = "maxim,max77693-haptic"; + haptic-supply = <&ldo26_reg>; + pwms = <&pwm 0 38022 0>; + }; + + charger { + compatible = "maxim,max77693-charger"; + + maxim,constant-microvolt = <4350000>; + maxim,min-system-microvolt = <3600000>; + maxim,thermal-regulation-celsius = <100>; + maxim,battery-overcurrent-microamp = <3500000>; + maxim,charge-input-threshold-microvolt = <4300000>; + }; + + led { + compatible = "maxim,max77693-led"; + maxim,boost-mode = ; + maxim,boost-mvout = <5000>; + maxim,mvsys-min = <2400>; + + flash-led { + label = "max77693-flash"; + function = LED_FUNCTION_FLASH; + color = ; + led-sources = <0>, <1>; + led-max-microamp = <500000>; + flash-max-microamp = <1250000>; + flash-max-timeout-us = <1000000>; + }; + }; + }; + }; diff --git a/MAINTAINERS b/MAINTAINERS index 7e3a45578747..c336d0252370 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -11721,9 +11721,9 @@ M: Bartlomiej Zolnierkiewicz L: linux-kernel@vger.kernel.org S: Supported F: Documentation/devicetree/bindings/*/maxim,max77686.yaml +F: Documentation/devicetree/bindings/*/maxim,max77693.yaml F: Documentation/devicetree/bindings/clock/maxim,max77686.txt F: Documentation/devicetree/bindings/mfd/max14577.txt -F: Documentation/devicetree/bindings/mfd/max77693.txt F: drivers/*/max14577*.c F: drivers/*/max77686*.c F: drivers/*/max77693*.c From 481153991c410e322383490527c20b0c41dbf652 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Thu, 10 Feb 2022 22:33:41 +0100 Subject: [PATCH 150/370] i2c: don't expose function which is only used internally MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit i2c_setup_smbus_alert() is only needed within the I2C core, so no need to expose it to other modules. Signed-off-by: Wolfram Sang Reviewed-by: Niklas Söderlund Signed-off-by: Wolfram Sang --- drivers/i2c/i2c-core-smbus.c | 1 - drivers/i2c/i2c-core.h | 9 +++++++++ include/linux/i2c-smbus.h | 8 -------- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/drivers/i2c/i2c-core-smbus.c b/drivers/i2c/i2c-core-smbus.c index 304c2c8fee68..053b215308c4 100644 --- a/drivers/i2c/i2c-core-smbus.c +++ b/drivers/i2c/i2c-core-smbus.c @@ -716,5 +716,4 @@ int i2c_setup_smbus_alert(struct i2c_adapter *adapter) return PTR_ERR_OR_ZERO(i2c_new_smbus_alert_device(adapter, NULL)); } -EXPORT_SYMBOL_GPL(i2c_setup_smbus_alert); #endif diff --git a/drivers/i2c/i2c-core.h b/drivers/i2c/i2c-core.h index 8ce261167a2d..87e2c914f1c5 100644 --- a/drivers/i2c/i2c-core.h +++ b/drivers/i2c/i2c-core.h @@ -86,3 +86,12 @@ void of_i2c_register_devices(struct i2c_adapter *adap); static inline void of_i2c_register_devices(struct i2c_adapter *adap) { } #endif extern struct notifier_block i2c_of_notifier; + +#if IS_ENABLED(CONFIG_I2C_SMBUS) +int i2c_setup_smbus_alert(struct i2c_adapter *adap); +#else +static inline int i2c_setup_smbus_alert(struct i2c_adapter *adap) +{ + return 0; +} +#endif diff --git a/include/linux/i2c-smbus.h b/include/linux/i2c-smbus.h index 95cf902e0bda..ced1c6ead52a 100644 --- a/include/linux/i2c-smbus.h +++ b/include/linux/i2c-smbus.h @@ -30,14 +30,6 @@ struct i2c_client *i2c_new_smbus_alert_device(struct i2c_adapter *adapter, struct i2c_smbus_alert_setup *setup); int i2c_handle_smbus_alert(struct i2c_client *ara); -#if IS_ENABLED(CONFIG_I2C_SMBUS) -int i2c_setup_smbus_alert(struct i2c_adapter *adap); -#else -static inline int i2c_setup_smbus_alert(struct i2c_adapter *adap) -{ - return 0; -} -#endif #if IS_ENABLED(CONFIG_I2C_SMBUS) && IS_ENABLED(CONFIG_I2C_SLAVE) struct i2c_client *i2c_new_slave_host_notify_device(struct i2c_adapter *adapter); void i2c_free_slave_host_notify_device(struct i2c_client *client); From 9c02d4011e92b92aa008d6907216a8e501b0443a Mon Sep 17 00:00:00 2001 From: Jarkko Nikula Date: Fri, 11 Feb 2022 17:00:01 +0200 Subject: [PATCH 151/370] i2c: i801: Add support for Intel Raptor Lake PCH-S Add SMBus PCI ID on Intel Raptor Lake PCH-S. Signed-off-by: Jarkko Nikula Reviewed-by: Jean Delvare Signed-off-by: Wolfram Sang --- Documentation/i2c/busses/i2c-i801.rst | 1 + drivers/i2c/busses/Kconfig | 1 + drivers/i2c/busses/i2c-i801.c | 3 +++ 3 files changed, 5 insertions(+) diff --git a/Documentation/i2c/busses/i2c-i801.rst b/Documentation/i2c/busses/i2c-i801.rst index 42bbdd6e7fd8..cad59170b2ad 100644 --- a/Documentation/i2c/busses/i2c-i801.rst +++ b/Documentation/i2c/busses/i2c-i801.rst @@ -45,6 +45,7 @@ Supported adapters: * Intel Jasper Lake (SOC) * Intel Emmitsburg (PCH) * Intel Alder Lake (PCH) + * Intel Raptor Lake (PCH) Datasheets: Publicly available at the Intel website diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig index 1fbb5f1fa7b1..bfe17c42e11d 100644 --- a/drivers/i2c/busses/Kconfig +++ b/drivers/i2c/busses/Kconfig @@ -148,6 +148,7 @@ config I2C_I801 Jasper Lake (SOC) Emmitsburg (PCH) Alder Lake (PCH) + Raptor Lake (PCH) This driver can also be built as a module. If so, the module will be called i2c-i801. diff --git a/drivers/i2c/busses/i2c-i801.c b/drivers/i2c/busses/i2c-i801.c index 7428cc6af5cc..36b086ef1378 100644 --- a/drivers/i2c/busses/i2c-i801.c +++ b/drivers/i2c/busses/i2c-i801.c @@ -75,6 +75,7 @@ * Alder Lake-S (PCH) 0x7aa3 32 hard yes yes yes * Alder Lake-P (PCH) 0x51a3 32 hard yes yes yes * Alder Lake-M (PCH) 0x54a3 32 hard yes yes yes + * Raptor Lake-S (PCH) 0x7a23 32 hard yes yes yes * * Features supported by this driver: * Software PEC no @@ -228,6 +229,7 @@ #define PCI_DEVICE_ID_INTEL_ALDER_LAKE_P_SMBUS 0x51a3 #define PCI_DEVICE_ID_INTEL_ALDER_LAKE_M_SMBUS 0x54a3 #define PCI_DEVICE_ID_INTEL_BROXTON_SMBUS 0x5ad4 +#define PCI_DEVICE_ID_INTEL_RAPTOR_LAKE_S_SMBUS 0x7a23 #define PCI_DEVICE_ID_INTEL_ALDER_LAKE_S_SMBUS 0x7aa3 #define PCI_DEVICE_ID_INTEL_LYNXPOINT_SMBUS 0x8c22 #define PCI_DEVICE_ID_INTEL_WILDCATPOINT_SMBUS 0x8ca2 @@ -1041,6 +1043,7 @@ static const struct pci_device_id i801_ids[] = { { PCI_DEVICE_DATA(INTEL, ALDER_LAKE_S_SMBUS, FEATURES_ICH5 | FEATURE_TCO_CNL) }, { PCI_DEVICE_DATA(INTEL, ALDER_LAKE_P_SMBUS, FEATURES_ICH5 | FEATURE_TCO_CNL) }, { PCI_DEVICE_DATA(INTEL, ALDER_LAKE_M_SMBUS, FEATURES_ICH5 | FEATURE_TCO_CNL) }, + { PCI_DEVICE_DATA(INTEL, RAPTOR_LAKE_S_SMBUS, FEATURES_ICH5 | FEATURE_TCO_CNL) }, { 0, } }; From 4ebf4987c0918ec6a08ece8ee745af44af02dee0 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Wed, 5 Jan 2022 16:19:31 +0200 Subject: [PATCH 152/370] i2c: Introduce common module to instantiate CCGx UCSI Introduce a common module to provide an API to instantiate UCSI device for Cypress CCGx Type-C controller. Individual bus drivers need to select this one on demand. Signed-off-by: Andy Shevchenko Signed-off-by: Wolfram Sang --- drivers/i2c/busses/Kconfig | 7 +++++++ drivers/i2c/busses/Makefile | 3 +++ drivers/i2c/busses/i2c-ccgx-ucsi.c | 30 ++++++++++++++++++++++++++++++ drivers/i2c/busses/i2c-ccgx-ucsi.h | 11 +++++++++++ 4 files changed, 51 insertions(+) create mode 100644 drivers/i2c/busses/i2c-ccgx-ucsi.c create mode 100644 drivers/i2c/busses/i2c-ccgx-ucsi.h diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig index bfe17c42e11d..6df1bd150233 100644 --- a/drivers/i2c/busses/Kconfig +++ b/drivers/i2c/busses/Kconfig @@ -9,6 +9,13 @@ menu "I2C Hardware Bus support" comment "PC SMBus host controller drivers" depends on PCI +config I2C_CCGX_UCSI + tristate + help + A common module to provide an API to instantiate UCSI device + for Cypress CCGx Type-C controller. Individual bus drivers + need to select this one on demand. + config I2C_ALI1535 tristate "ALI 1535" depends on PCI diff --git a/drivers/i2c/busses/Makefile b/drivers/i2c/busses/Makefile index 752f47be3fc1..479f60e4ee3d 100644 --- a/drivers/i2c/busses/Makefile +++ b/drivers/i2c/busses/Makefile @@ -6,6 +6,9 @@ # ACPI drivers obj-$(CONFIG_I2C_SCMI) += i2c-scmi.o +# Auxiliary I2C/SMBus modules +obj-$(CONFIG_I2C_CCGX_UCSI) += i2c-ccgx-ucsi.o + # PC SMBus host controller drivers obj-$(CONFIG_I2C_ALI1535) += i2c-ali1535.o obj-$(CONFIG_I2C_ALI1563) += i2c-ali1563.o diff --git a/drivers/i2c/busses/i2c-ccgx-ucsi.c b/drivers/i2c/busses/i2c-ccgx-ucsi.c new file mode 100644 index 000000000000..092dc92dea9f --- /dev/null +++ b/drivers/i2c/busses/i2c-ccgx-ucsi.c @@ -0,0 +1,30 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Instantiate UCSI device for Cypress CCGx Type-C controller. + * Derived from i2c-designware-pcidrv.c and i2c-nvidia-gpu.c. + */ + +#include +#include +#include +#include + +#include "i2c-ccgx-ucsi.h" + +struct software_node; + +struct i2c_client *i2c_new_ccgx_ucsi(struct i2c_adapter *adapter, int irq, + const struct software_node *swnode) +{ + struct i2c_board_info info = {}; + + strscpy(info.type, "ccgx-ucsi", sizeof(info.type)); + info.addr = 0x08; + info.irq = irq; + info.swnode = swnode; + + return i2c_new_client_device(adapter, &info); +} +EXPORT_SYMBOL_GPL(i2c_new_ccgx_ucsi); + +MODULE_LICENSE("GPL"); diff --git a/drivers/i2c/busses/i2c-ccgx-ucsi.h b/drivers/i2c/busses/i2c-ccgx-ucsi.h new file mode 100644 index 000000000000..739ac7a4b117 --- /dev/null +++ b/drivers/i2c/busses/i2c-ccgx-ucsi.h @@ -0,0 +1,11 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +#ifndef __I2C_CCGX_UCSI_H_ +#define __I2C_CCGX_UCSI_H_ + +struct i2c_adapter; +struct i2c_client; +struct software_node; + +struct i2c_client *i2c_new_ccgx_ucsi(struct i2c_adapter *adapter, int irq, + const struct software_node *swnode); +#endif /* __I2C_CCGX_UCSI_H_ */ From 2079563d6f60e63f7fc5d1b0b7a48dbb93c209d1 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Wed, 5 Jan 2022 16:19:32 +0200 Subject: [PATCH 153/370] i2c: nvidia-gpu: Switch to use i2c_new_ccgx_ucsi() Instead of open coded variant switch to use i2c_new_ccgx_ucsi(). Signed-off-by: Andy Shevchenko Signed-off-by: Wolfram Sang --- drivers/i2c/busses/Kconfig | 1 + drivers/i2c/busses/i2c-nvidia-gpu.c | 26 ++++++-------------------- 2 files changed, 7 insertions(+), 20 deletions(-) diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig index 6df1bd150233..df3ecbe8ff25 100644 --- a/drivers/i2c/busses/Kconfig +++ b/drivers/i2c/busses/Kconfig @@ -253,6 +253,7 @@ config I2C_NFORCE2_S4985 config I2C_NVIDIA_GPU tristate "NVIDIA GPU I2C controller" depends on PCI + select I2C_CCGX_UCSI help If you say yes to this option, support will be included for the NVIDIA GPU I2C controller which is used to communicate with the GPU's diff --git a/drivers/i2c/busses/i2c-nvidia-gpu.c b/drivers/i2c/busses/i2c-nvidia-gpu.c index b5055a3cbd93..8117c3674209 100644 --- a/drivers/i2c/busses/i2c-nvidia-gpu.c +++ b/drivers/i2c/busses/i2c-nvidia-gpu.c @@ -17,6 +17,8 @@ #include +#include "i2c-ccgx-ucsi.h" + /* I2C definitions */ #define I2C_MST_CNTL 0x00 #define I2C_MST_CNTL_GEN_START BIT(0) @@ -266,23 +268,6 @@ static const struct software_node ccgx_node = { .properties = ccgx_props, }; -static int gpu_populate_client(struct gpu_i2c_dev *i2cd, int irq) -{ - i2cd->gpu_ccgx_ucsi = devm_kzalloc(i2cd->dev, - sizeof(*i2cd->gpu_ccgx_ucsi), - GFP_KERNEL); - if (!i2cd->gpu_ccgx_ucsi) - return -ENOMEM; - - strlcpy(i2cd->gpu_ccgx_ucsi->type, "ccgx-ucsi", - sizeof(i2cd->gpu_ccgx_ucsi->type)); - i2cd->gpu_ccgx_ucsi->addr = 0x8; - i2cd->gpu_ccgx_ucsi->irq = irq; - i2cd->gpu_ccgx_ucsi->swnode = &ccgx_node; - i2cd->ccgx_client = i2c_new_client_device(&i2cd->adapter, i2cd->gpu_ccgx_ucsi); - return PTR_ERR_OR_ZERO(i2cd->ccgx_client); -} - static int gpu_i2c_probe(struct pci_dev *pdev, const struct pci_device_id *id) { struct gpu_i2c_dev *i2cd; @@ -328,9 +313,10 @@ static int gpu_i2c_probe(struct pci_dev *pdev, const struct pci_device_id *id) if (status < 0) goto free_irq_vectors; - status = gpu_populate_client(i2cd, pdev->irq); - if (status < 0) { - dev_err(&pdev->dev, "gpu_populate_client failed %d\n", status); + i2cd->ccgx_client = i2c_new_ccgx_ucsi(&i2cd->adapter, pdev->irq, &ccgx_node); + if (IS_ERR(i2cd->ccgx_client)) { + status = dev_err_probe(&pdev->dev, PTR_ERR(i2cd->ccgx_client), + "register UCSI failed\n"); goto del_adapter; } From c2c25be6dc94132bca85f5b2c6ee9f6d7ab0173f Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Wed, 5 Jan 2022 16:19:33 +0200 Subject: [PATCH 154/370] i2c: nvidia-gpu: Use temporary variable for struct device Use temporary variable for struct device to make code neater. Signed-off-by: Andy Shevchenko Signed-off-by: Wolfram Sang --- drivers/i2c/busses/i2c-nvidia-gpu.c | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/drivers/i2c/busses/i2c-nvidia-gpu.c b/drivers/i2c/busses/i2c-nvidia-gpu.c index 8117c3674209..a82be377146e 100644 --- a/drivers/i2c/busses/i2c-nvidia-gpu.c +++ b/drivers/i2c/busses/i2c-nvidia-gpu.c @@ -270,19 +270,20 @@ static const struct software_node ccgx_node = { static int gpu_i2c_probe(struct pci_dev *pdev, const struct pci_device_id *id) { + struct device *dev = &pdev->dev; struct gpu_i2c_dev *i2cd; int status; - i2cd = devm_kzalloc(&pdev->dev, sizeof(*i2cd), GFP_KERNEL); + i2cd = devm_kzalloc(dev, sizeof(*i2cd), GFP_KERNEL); if (!i2cd) return -ENOMEM; - i2cd->dev = &pdev->dev; - dev_set_drvdata(&pdev->dev, i2cd); + i2cd->dev = dev; + dev_set_drvdata(dev, i2cd); status = pcim_enable_device(pdev); if (status < 0) { - dev_err(&pdev->dev, "pcim_enable_device failed %d\n", status); + dev_err(dev, "pcim_enable_device failed %d\n", status); return status; } @@ -290,13 +291,13 @@ static int gpu_i2c_probe(struct pci_dev *pdev, const struct pci_device_id *id) i2cd->regs = pcim_iomap(pdev, 0, 0); if (!i2cd->regs) { - dev_err(&pdev->dev, "pcim_iomap failed\n"); + dev_err(dev, "pcim_iomap failed\n"); return -ENOMEM; } status = pci_alloc_irq_vectors(pdev, 1, 1, PCI_IRQ_MSI); if (status < 0) { - dev_err(&pdev->dev, "pci_alloc_irq_vectors err %d\n", status); + dev_err(dev, "pci_alloc_irq_vectors err %d\n", status); return status; } @@ -308,22 +309,21 @@ static int gpu_i2c_probe(struct pci_dev *pdev, const struct pci_device_id *id) sizeof(i2cd->adapter.name)); i2cd->adapter.algo = &gpu_i2c_algorithm; i2cd->adapter.quirks = &gpu_i2c_quirks; - i2cd->adapter.dev.parent = &pdev->dev; + i2cd->adapter.dev.parent = dev; status = i2c_add_adapter(&i2cd->adapter); if (status < 0) goto free_irq_vectors; i2cd->ccgx_client = i2c_new_ccgx_ucsi(&i2cd->adapter, pdev->irq, &ccgx_node); if (IS_ERR(i2cd->ccgx_client)) { - status = dev_err_probe(&pdev->dev, PTR_ERR(i2cd->ccgx_client), - "register UCSI failed\n"); + status = dev_err_probe(dev, PTR_ERR(i2cd->ccgx_client), "register UCSI failed\n"); goto del_adapter; } - pm_runtime_set_autosuspend_delay(&pdev->dev, 3000); - pm_runtime_use_autosuspend(&pdev->dev); - pm_runtime_put_autosuspend(&pdev->dev); - pm_runtime_allow(&pdev->dev); + pm_runtime_set_autosuspend_delay(dev, 3000); + pm_runtime_use_autosuspend(dev); + pm_runtime_put_autosuspend(dev); + pm_runtime_allow(dev); return 0; @@ -336,7 +336,7 @@ free_irq_vectors: static void gpu_i2c_remove(struct pci_dev *pdev) { - struct gpu_i2c_dev *i2cd = dev_get_drvdata(&pdev->dev); + struct gpu_i2c_dev *i2cd = pci_get_drvdata(pdev); pm_runtime_get_noresume(i2cd->dev); i2c_del_adapter(&i2cd->adapter); From c74a30ce137636d1a12abde357718e45524c2b71 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Wed, 5 Jan 2022 16:19:34 +0200 Subject: [PATCH 155/370] i2c: nvidia-gpu: Convert to use dev_err_probe() It's fine to call dev_err_probe() in ->probe() when error code is known. Convert the driver to use dev_err_probe(). Signed-off-by: Andy Shevchenko Signed-off-by: Wolfram Sang --- drivers/i2c/busses/i2c-nvidia-gpu.c | 18 ++++++------------ 1 file changed, 6 insertions(+), 12 deletions(-) diff --git a/drivers/i2c/busses/i2c-nvidia-gpu.c b/drivers/i2c/busses/i2c-nvidia-gpu.c index a82be377146e..6920c1b9a126 100644 --- a/drivers/i2c/busses/i2c-nvidia-gpu.c +++ b/drivers/i2c/busses/i2c-nvidia-gpu.c @@ -282,24 +282,18 @@ static int gpu_i2c_probe(struct pci_dev *pdev, const struct pci_device_id *id) dev_set_drvdata(dev, i2cd); status = pcim_enable_device(pdev); - if (status < 0) { - dev_err(dev, "pcim_enable_device failed %d\n", status); - return status; - } + if (status < 0) + return dev_err_probe(dev, status, "pcim_enable_device failed\n"); pci_set_master(pdev); i2cd->regs = pcim_iomap(pdev, 0, 0); - if (!i2cd->regs) { - dev_err(dev, "pcim_iomap failed\n"); - return -ENOMEM; - } + if (!i2cd->regs) + return dev_err_probe(dev, -ENOMEM, "pcim_iomap failed\n"); status = pci_alloc_irq_vectors(pdev, 1, 1, PCI_IRQ_MSI); - if (status < 0) { - dev_err(dev, "pci_alloc_irq_vectors err %d\n", status); - return status; - } + if (status < 0) + return dev_err_probe(dev, status, "pci_alloc_irq_vectors err\n"); gpu_enable_i2c_bus(i2cd); From 531310dd5d9f78b5d9e28e742d55c775f114ad5a Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Wed, 5 Jan 2022 16:19:35 +0200 Subject: [PATCH 156/370] i2c: designware-pci: Switch to use i2c_new_ccgx_ucsi() Instead of open coded variant switch to use i2c_new_ccgx_ucsi(). Signed-off-by: Andy Shevchenko Acked-by: Jarkko Nikula Signed-off-by: Wolfram Sang --- drivers/i2c/busses/Kconfig | 1 + drivers/i2c/busses/i2c-designware-pcidrv.c | 30 ++++------------------ 2 files changed, 6 insertions(+), 25 deletions(-) diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig index df3ecbe8ff25..0e6070bcf241 100644 --- a/drivers/i2c/busses/Kconfig +++ b/drivers/i2c/busses/Kconfig @@ -590,6 +590,7 @@ config I2C_DESIGNWARE_PCI tristate "Synopsys DesignWare PCI" depends on PCI select I2C_DESIGNWARE_CORE + select I2C_CCGX_UCSI help If you say yes to this option, support will be included for the Synopsys DesignWare I2C adapter. Only master mode is supported. diff --git a/drivers/i2c/busses/i2c-designware-pcidrv.c b/drivers/i2c/busses/i2c-designware-pcidrv.c index ef4250f8852b..2782dddfb087 100644 --- a/drivers/i2c/busses/i2c-designware-pcidrv.c +++ b/drivers/i2c/busses/i2c-designware-pcidrv.c @@ -24,6 +24,7 @@ #include #include "i2c-designware-core.h" +#include "i2c-ccgx-ucsi.h" #define DRIVER_NAME "i2c-designware-pci" #define AMD_CLK_RATE_HZ 100000 @@ -125,26 +126,6 @@ static int mfld_setup(struct pci_dev *pdev, struct dw_pci_controller *c) return -ENODEV; } - /* - * TODO find a better way how to deduplicate instantiation - * of USB PD slave device from nVidia GPU driver. - */ -static int navi_amd_register_client(struct dw_i2c_dev *dev) -{ - struct i2c_board_info info; - - memset(&info, 0, sizeof(struct i2c_board_info)); - strscpy(info.type, "ccgx-ucsi", I2C_NAME_SIZE); - info.addr = 0x08; - info.irq = dev->irq; - - dev->slave = i2c_new_client_device(&dev->adapter, &info); - if (IS_ERR(dev->slave)) - return PTR_ERR(dev->slave); - - return 0; -} - static int navi_amd_setup(struct pci_dev *pdev, struct dw_pci_controller *c) { struct dw_i2c_dev *dev = dev_get_drvdata(&pdev->dev); @@ -325,11 +306,10 @@ static int i2c_dw_pci_probe(struct pci_dev *pdev, } if ((dev->flags & MODEL_MASK) == MODEL_AMD_NAVI_GPU) { - r = navi_amd_register_client(dev); - if (r) { - dev_err(dev->dev, "register client failed with %d\n", r); - return r; - } + dev->slave = i2c_new_ccgx_ucsi(&dev->adapter, dev->irq, NULL); + if (IS_ERR(dev->slave)) + return dev_err_probe(dev->dev, PTR_ERR(dev->slave), + "register UCSI failed\n"); } pm_runtime_set_autosuspend_delay(&pdev->dev, 1000); From 1e4fe5430bd791fb2a2d7b41ac25d1aaa5d0726a Mon Sep 17 00:00:00 2001 From: Yang Li Date: Mon, 14 Feb 2022 20:47:01 +0800 Subject: [PATCH 157/370] i2c: designware: remove unneeded semicolon Eliminate the following coccicheck warnings: ./drivers/i2c/busses/i2c-designware-amdpsp.c:172:2-3: Unneeded semicolon ./drivers/i2c/busses/i2c-designware-amdpsp.c:245:2-3: Unneeded semicolon Reported-by: Abaci Robot Signed-off-by: Yang Li Acked-by: Jarkko Nikula Reviewed-by: Jan Dabros Signed-off-by: Wolfram Sang --- drivers/i2c/busses/i2c-designware-amdpsp.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/i2c/busses/i2c-designware-amdpsp.c b/drivers/i2c/busses/i2c-designware-amdpsp.c index 752e0024db03..9d37becbd846 100644 --- a/drivers/i2c/busses/i2c-designware-amdpsp.c +++ b/drivers/i2c/busses/i2c-designware-amdpsp.c @@ -172,7 +172,7 @@ static int check_i2c_req_sts(struct psp_i2c_req *req) case PSP_I2C_REQ_STS_INV_PARAM: default: return -EIO; - }; + } } static int psp_send_check_i2c_req(struct psp_i2c_req *req) @@ -245,7 +245,7 @@ static int psp_acquire_i2c_bus(void) if (psp_i2c_access_count) { psp_i2c_access_count++; goto cleanup; - }; + } status = psp_send_i2c_req(PSP_I2C_REQ_ACQUIRE); if (status) { From 19e138e43a0820bb4dbf8fb5c7691f82e9221f2b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Povi=C5=A1er?= Date: Fri, 4 Feb 2022 10:59:14 +0100 Subject: [PATCH 158/370] i2c: pasemi: Drop I2C classes from platform driver variant MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Drop I2C device-probing classes from platform variant of the PASemi controller as it is only used on platforms where I2C devices should be instantiated in devicetree. (The I2C_CLASS_DEPRECATED flag is not raised as up to this point no devices relied on the old behavior.) Fixes: d88ae2932df0 ("i2c: pasemi: Add Apple platform driver") Signed-off-by: Martin Povišer Reviewed-by: Sven Peter Acked-by: Hector Martin Signed-off-by: Wolfram Sang --- drivers/i2c/busses/i2c-pasemi-core.c | 1 - drivers/i2c/busses/i2c-pasemi-pci.c | 1 + 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/i2c/busses/i2c-pasemi-core.c b/drivers/i2c/busses/i2c-pasemi-core.c index 4e161a4089d8..7728c8460dc0 100644 --- a/drivers/i2c/busses/i2c-pasemi-core.c +++ b/drivers/i2c/busses/i2c-pasemi-core.c @@ -333,7 +333,6 @@ int pasemi_i2c_common_probe(struct pasemi_smbus *smbus) smbus->adapter.owner = THIS_MODULE; snprintf(smbus->adapter.name, sizeof(smbus->adapter.name), "PA Semi SMBus adapter (%s)", dev_name(smbus->dev)); - smbus->adapter.class = I2C_CLASS_HWMON | I2C_CLASS_SPD; smbus->adapter.algo = &smbus_algorithm; smbus->adapter.algo_data = smbus; diff --git a/drivers/i2c/busses/i2c-pasemi-pci.c b/drivers/i2c/busses/i2c-pasemi-pci.c index 1ab1f28744fb..cfc89e04eb94 100644 --- a/drivers/i2c/busses/i2c-pasemi-pci.c +++ b/drivers/i2c/busses/i2c-pasemi-pci.c @@ -56,6 +56,7 @@ static int pasemi_smb_pci_probe(struct pci_dev *dev, if (!smbus->ioaddr) return -EBUSY; + smbus->adapter.class = I2C_CLASS_HWMON | I2C_CLASS_SPD; error = pasemi_i2c_common_probe(smbus); if (error) return error; From 54eb8dc8f338962e12760fb718f4ca39a8cf3aa9 Mon Sep 17 00:00:00 2001 From: Frank Rowand Date: Thu, 10 Feb 2022 17:08:19 -0600 Subject: [PATCH 159/370] of: unittest: print pass messages at PR_INFO level Printing the devicetree unittest pass message for each passed test creates much console verbosity. The existing pass messages are printed at loglevel KERN_DEBUG so they will not print by default. Change default to print the pass messages at loglevel PR_INFO so they will print with the default console loglevel. The test community expects either a pass or a fail message for each test in a test suite. The messages are typically post-processed to report pass/fail results. Signed-off-by: Frank Rowand Tested-by: Linux Kernel Functional Testing Signed-off-by: Rob Herring Link: https://lore.kernel.org/r/20220210230819.3303212-1-frowand.list@gmail.com --- drivers/of/unittest.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/of/unittest.c b/drivers/of/unittest.c index 70992103c07d..9012e6900965 100644 --- a/drivers/of/unittest.c +++ b/drivers/of/unittest.c @@ -44,7 +44,7 @@ static struct unittest_results { pr_err("FAIL %s():%i " fmt, __func__, __LINE__, ##__VA_ARGS__); \ } else { \ unittest_results.passed++; \ - pr_debug("pass %s():%i\n", __func__, __LINE__); \ + pr_info("pass %s():%i\n", __func__, __LINE__); \ } \ failed; \ }) From 2e8185fccd63f008987d55d1b4d69bf1e050bc02 Mon Sep 17 00:00:00 2001 From: Nick Hawkins Date: Thu, 10 Feb 2022 11:59:11 -0600 Subject: [PATCH 160/370] dt-bindings: vendor-prefixes: add HPE Prefix Description: This patch adds the Hewlett Packard Enterprise prefix that will be used for upcoming support in the HPE BMC GXP. Signed-off-by: Nick Hawkins Reviewed-by: Krzysztof Kozlowski Signed-off-by: Rob Herring Link: https://lore.kernel.org/r/20220210175912.102159-1-nick.hawkins@hpe.com --- Documentation/devicetree/bindings/vendor-prefixes.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Documentation/devicetree/bindings/vendor-prefixes.yaml b/Documentation/devicetree/bindings/vendor-prefixes.yaml index 6136dafe4853..913f722a6b8d 100644 --- a/Documentation/devicetree/bindings/vendor-prefixes.yaml +++ b/Documentation/devicetree/bindings/vendor-prefixes.yaml @@ -515,6 +515,8 @@ patternProperties: description: Jiangsu HopeRun Software Co., Ltd. "^hp,.*": description: Hewlett Packard Inc. + "^hpe,.*": + description: Hewlett Packard Enterprise "^hsg,.*": description: HannStar Display Co. "^holtek,.*": From c8f2ad6869b56233ba4d00dc090e11bb41a55205 Mon Sep 17 00:00:00 2001 From: Tudor Ambarus Date: Fri, 11 Feb 2022 11:39:20 +0200 Subject: [PATCH 161/370] dt-bindings: crypto: Convert Atmel AES to yaml Convert Atmel AES documentation to yaml format. With the conversion the clock and clock-names properties are made mandatory. The driver returns -EINVAL if "aes_clk" is not found, reflect that in the bindings and make the clock and clock-names properties mandatory. Update the example to better describe how one should define the dt node. Signed-off-by: Tudor Ambarus Reviewed-by: Krzysztof Kozlowski Signed-off-by: Rob Herring Link: https://lore.kernel.org/r/20220211093922.456634-2-tudor.ambarus@microchip.com --- .../crypto/atmel,at91sam9g46-aes.yaml | 66 +++++++++++++++++++ .../bindings/crypto/atmel-crypto.txt | 20 ------ 2 files changed, 66 insertions(+), 20 deletions(-) create mode 100644 Documentation/devicetree/bindings/crypto/atmel,at91sam9g46-aes.yaml diff --git a/Documentation/devicetree/bindings/crypto/atmel,at91sam9g46-aes.yaml b/Documentation/devicetree/bindings/crypto/atmel,at91sam9g46-aes.yaml new file mode 100644 index 000000000000..0ccaab16dc61 --- /dev/null +++ b/Documentation/devicetree/bindings/crypto/atmel,at91sam9g46-aes.yaml @@ -0,0 +1,66 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +# Copyright (C) 2022 Microchip Technology, Inc. and its subsidiaries +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/crypto/atmel,at91sam9g46-aes.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Atmel Advanced Encryption Standard (AES) HW cryptographic accelerator + +maintainers: + - Tudor Ambarus + +properties: + compatible: + const: atmel,at91sam9g46-aes + + reg: + maxItems: 1 + + interrupts: + maxItems: 1 + + clocks: + maxItems: 1 + + clock-names: + const: aes_clk + + dmas: + items: + - description: TX DMA Channel + - description: RX DMA Channel + + dma-names: + items: + - const: tx + - const: rx + +required: + - compatible + - reg + - interrupts + - clocks + - clock-names + - dmas + - dma-names + +additionalProperties: false + +examples: + - | + #include + #include + #include + #include + + aes: crypto@e1810000 { + compatible = "atmel,at91sam9g46-aes"; + reg = <0xe1810000 0x100>; + interrupts = ; + clocks = <&pmc PMC_TYPE_PERIPHERAL 27>; + clock-names = "aes_clk"; + dmas = <&dma0 AT91_XDMAC_DT_PERID(1)>, + <&dma0 AT91_XDMAC_DT_PERID(2)>; + dma-names = "tx", "rx"; + }; diff --git a/Documentation/devicetree/bindings/crypto/atmel-crypto.txt b/Documentation/devicetree/bindings/crypto/atmel-crypto.txt index f2aab3dc2b52..1353ebd0dcaa 100644 --- a/Documentation/devicetree/bindings/crypto/atmel-crypto.txt +++ b/Documentation/devicetree/bindings/crypto/atmel-crypto.txt @@ -2,26 +2,6 @@ These are the HW cryptographic accelerators found on some Atmel products. -* Advanced Encryption Standard (AES) - -Required properties: -- compatible : Should be "atmel,at91sam9g46-aes". -- reg: Should contain AES registers location and length. -- interrupts: Should contain the IRQ line for the AES. -- dmas: List of two DMA specifiers as described in - atmel-dma.txt and dma.txt files. -- dma-names: Contains one identifier string for each DMA specifier - in the dmas property. - -Example: -aes@f8038000 { - compatible = "atmel,at91sam9g46-aes"; - reg = <0xf8038000 0x100>; - interrupts = <43 4 0>; - dmas = <&dma1 2 18>, - <&dma1 2 19>; - dma-names = "tx", "rx"; - * Triple Data Encryption Standard (Triple DES) Required properties: From d63b583f681e7999fde293142f6cbc0f2a766b64 Mon Sep 17 00:00:00 2001 From: Tudor Ambarus Date: Fri, 11 Feb 2022 11:39:21 +0200 Subject: [PATCH 162/370] dt-bindings: crypto: Convert Atmel TDES to yaml Convert Atmel TDES documentation to yaml format. With the conversion the clock and clock-names properties are made mandatory. The driver returns -EINVAL if "tdes_clk" is not found, reflect that in the bindings and make the clock and clock-names properties mandatory. Update the example to better describe how one should define the dt node. Signed-off-by: Tudor Ambarus Reviewed-by: Krzysztof Kozlowski Signed-off-by: Rob Herring Link: https://lore.kernel.org/r/20220211093922.456634-3-tudor.ambarus@microchip.com --- .../crypto/atmel,at91sam9g46-tdes.yaml | 64 +++++++++++++++++++ .../bindings/crypto/atmel-crypto.txt | 23 ------- 2 files changed, 64 insertions(+), 23 deletions(-) create mode 100644 Documentation/devicetree/bindings/crypto/atmel,at91sam9g46-tdes.yaml diff --git a/Documentation/devicetree/bindings/crypto/atmel,at91sam9g46-tdes.yaml b/Documentation/devicetree/bindings/crypto/atmel,at91sam9g46-tdes.yaml new file mode 100644 index 000000000000..fcc5adf03cad --- /dev/null +++ b/Documentation/devicetree/bindings/crypto/atmel,at91sam9g46-tdes.yaml @@ -0,0 +1,64 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +# Copyright (C) 2022 Microchip Technology, Inc. and its subsidiaries +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/crypto/atmel,at91sam9g46-tdes.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Atmel Triple Data Encryption Standard (TDES) HW cryptographic accelerator + +maintainers: + - Tudor Ambarus + +properties: + compatible: + const: atmel,at91sam9g46-tdes + + reg: + maxItems: 1 + + interrupts: + maxItems: 1 + + clocks: + maxItems: 1 + + clock-names: + const: tdes_clk + + dmas: + items: + - description: TX DMA Channel + - description: RX DMA Channel + + dma-names: + items: + - const: tx + - const: rx + +required: + - compatible + - reg + - interrupts + - clocks + - clock-names + +additionalProperties: false + +examples: + - | + #include + #include + #include + #include + + tdes: crypto@e2014000 { + compatible = "atmel,at91sam9g46-tdes"; + reg = <0xe2014000 0x100>; + interrupts = ; + clocks = <&pmc PMC_TYPE_PERIPHERAL 96>; + clock-names = "tdes_clk"; + dmas = <&dma0 AT91_XDMAC_DT_PERID(54)>, + <&dma0 AT91_XDMAC_DT_PERID(53)>; + dma-names = "tx", "rx"; + }; diff --git a/Documentation/devicetree/bindings/crypto/atmel-crypto.txt b/Documentation/devicetree/bindings/crypto/atmel-crypto.txt index 1353ebd0dcaa..5c6541cfcc4a 100644 --- a/Documentation/devicetree/bindings/crypto/atmel-crypto.txt +++ b/Documentation/devicetree/bindings/crypto/atmel-crypto.txt @@ -2,29 +2,6 @@ These are the HW cryptographic accelerators found on some Atmel products. -* Triple Data Encryption Standard (Triple DES) - -Required properties: -- compatible : Should be "atmel,at91sam9g46-tdes". -- reg: Should contain TDES registers location and length. -- interrupts: Should contain the IRQ line for the TDES. - -Optional properties: -- dmas: List of two DMA specifiers as described in - atmel-dma.txt and dma.txt files. -- dma-names: Contains one identifier string for each DMA specifier - in the dmas property. - -Example: -tdes@f803c000 { - compatible = "atmel,at91sam9g46-tdes"; - reg = <0xf803c000 0x100>; - interrupts = <44 4 0>; - dmas = <&dma1 2 20>, - <&dma1 2 21>; - dma-names = "tx", "rx"; -}; - * Secure Hash Algorithm (SHA) Required properties: From 44c75c9e3d08b430a9f002a087f2da255909b8ff Mon Sep 17 00:00:00 2001 From: Tudor Ambarus Date: Fri, 11 Feb 2022 11:39:22 +0200 Subject: [PATCH 163/370] dt-bindings: crypto: Convert Atmel SHA to yaml Convert Atmel SHA documentation to yaml format. With the conversion the clock and clock-names properties are made mandatory. The driver returns -EINVAL if "sha_clk" is not found, reflect that in the bindings and make the clock and clock-names properties mandatory. Update the example to better describe how one should define the dt node. Signed-off-by: Tudor Ambarus Reviewed-by: Krzysztof Kozlowski Signed-off-by: Rob Herring Link: https://lore.kernel.org/r/20220211093922.456634-4-tudor.ambarus@microchip.com --- .../crypto/atmel,at91sam9g46-sha.yaml | 60 +++++++++++++++++++ .../bindings/crypto/atmel-crypto.txt | 25 -------- 2 files changed, 60 insertions(+), 25 deletions(-) create mode 100644 Documentation/devicetree/bindings/crypto/atmel,at91sam9g46-sha.yaml delete mode 100644 Documentation/devicetree/bindings/crypto/atmel-crypto.txt diff --git a/Documentation/devicetree/bindings/crypto/atmel,at91sam9g46-sha.yaml b/Documentation/devicetree/bindings/crypto/atmel,at91sam9g46-sha.yaml new file mode 100644 index 000000000000..5163c51b4547 --- /dev/null +++ b/Documentation/devicetree/bindings/crypto/atmel,at91sam9g46-sha.yaml @@ -0,0 +1,60 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +# Copyright (C) 2022 Microchip Technology, Inc. and its subsidiaries +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/crypto/atmel,at91sam9g46-sha.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Atmel Secure Hash Algorithm (SHA) HW cryptographic accelerator + +maintainers: + - Tudor Ambarus + +properties: + compatible: + const: atmel,at91sam9g46-sha + + reg: + maxItems: 1 + + interrupts: + maxItems: 1 + + clocks: + maxItems: 1 + + clock-names: + const: sha_clk + + dmas: + maxItems: 1 + description: TX DMA Channel + + dma-names: + const: tx + +required: + - compatible + - reg + - interrupts + - clocks + - clock-names + +additionalProperties: false + +examples: + - | + #include + #include + #include + #include + + sha: crypto@e1814000 { + compatible = "atmel,at91sam9g46-sha"; + reg = <0xe1814000 0x100>; + interrupts = ; + clocks = <&pmc PMC_TYPE_PERIPHERAL 83>; + clock-names = "sha_clk"; + dmas = <&dma0 AT91_XDMAC_DT_PERID(48)>; + dma-names = "tx"; + }; diff --git a/Documentation/devicetree/bindings/crypto/atmel-crypto.txt b/Documentation/devicetree/bindings/crypto/atmel-crypto.txt deleted file mode 100644 index 5c6541cfcc4a..000000000000 --- a/Documentation/devicetree/bindings/crypto/atmel-crypto.txt +++ /dev/null @@ -1,25 +0,0 @@ -* Atmel HW cryptographic accelerators - -These are the HW cryptographic accelerators found on some Atmel products. - -* Secure Hash Algorithm (SHA) - -Required properties: -- compatible : Should be "atmel,at91sam9g46-sha". -- reg: Should contain SHA registers location and length. -- interrupts: Should contain the IRQ line for the SHA. - -Optional properties: -- dmas: One DMA specifiers as described in - atmel-dma.txt and dma.txt files. -- dma-names: Contains one identifier string for each DMA specifier - in the dmas property. Only one "tx" string needed. - -Example: -sha@f8034000 { - compatible = "atmel,at91sam9g46-sha"; - reg = <0xf8034000 0x100>; - interrupts = <42 4 0>; - dmas = <&dma1 2 17>; - dma-names = "tx"; -}; From 5d16dcd252fd3f77d1579342b78d947033065d64 Mon Sep 17 00:00:00 2001 From: Corentin Labbe Date: Fri, 11 Feb 2022 12:01:57 +0000 Subject: [PATCH 164/370] dt-bindings: convert ata/cortina,gemini-sata-bridge to yaml This patch converts ata/cortina,gemini-sata-bridge binding to yaml Reviewed-by: Krzysztof Kozlowski Reviewed-by: Linus Walleij Acked-by: Damien Le Moal Signed-off-by: Corentin Labbe Signed-off-by: Rob Herring Link: https://lore.kernel.org/r/20220211120157.3385145-1-clabbe@baylibre.com --- .../ata/cortina,gemini-sata-bridge.txt | 55 --------- .../ata/cortina,gemini-sata-bridge.yaml | 109 ++++++++++++++++++ 2 files changed, 109 insertions(+), 55 deletions(-) delete mode 100644 Documentation/devicetree/bindings/ata/cortina,gemini-sata-bridge.txt create mode 100644 Documentation/devicetree/bindings/ata/cortina,gemini-sata-bridge.yaml diff --git a/Documentation/devicetree/bindings/ata/cortina,gemini-sata-bridge.txt b/Documentation/devicetree/bindings/ata/cortina,gemini-sata-bridge.txt deleted file mode 100644 index 1c3d3cc70051..000000000000 --- a/Documentation/devicetree/bindings/ata/cortina,gemini-sata-bridge.txt +++ /dev/null @@ -1,55 +0,0 @@ -* Cortina Systems Gemini SATA Bridge - -The Gemini SATA bridge in a SoC-internal PATA to SATA bridge that -takes two Faraday Technology FTIDE010 PATA controllers and bridges -them in different configurations to two SATA ports. - -Required properties: -- compatible: should be - "cortina,gemini-sata-bridge" -- reg: registers and size for the block -- resets: phandles to the reset lines for both SATA bridges -- reset-names: must be "sata0", "sata1" -- clocks: phandles to the compulsory peripheral clocks -- clock-names: must be "SATA0_PCLK", "SATA1_PCLK" -- syscon: a phandle to the global Gemini system controller -- cortina,gemini-ata-muxmode: tell the desired multiplexing mode for - the ATA controller and SATA bridges. Values 0..3: - Mode 0: ata0 master <-> sata0 - ata1 master <-> sata1 - ata0 slave interface brought out on IDE pads - Mode 1: ata0 master <-> sata0 - ata1 master <-> sata1 - ata1 slave interface brought out on IDE pads - Mode 2: ata1 master <-> sata1 - ata1 slave <-> sata0 - ata0 master and slave interfaces brought out - on IDE pads - Mode 3: ata0 master <-> sata0 - ata0 slave <-> sata1 - ata1 master and slave interfaces brought out - on IDE pads - -Optional boolean properties: -- cortina,gemini-enable-ide-pins: enables the PATA to IDE connection. - The muxmode setting decides whether ATA0 or ATA1 is brought out, - and whether master, slave or both interfaces get brought out. -- cortina,gemini-enable-sata-bridge: enables the PATA to SATA bridge - inside the Gemnini SoC. The Muxmode decides what PATA blocks will - be muxed out and how. - -Example: - -sata: sata@46000000 { - compatible = "cortina,gemini-sata-bridge"; - reg = <0x46000000 0x100>; - resets = <&rcon 26>, <&rcon 27>; - reset-names = "sata0", "sata1"; - clocks = <&gcc GEMINI_CLK_GATE_SATA0>, - <&gcc GEMINI_CLK_GATE_SATA1>; - clock-names = "SATA0_PCLK", "SATA1_PCLK"; - syscon = <&syscon>; - cortina,gemini-ata-muxmode = <3>; - cortina,gemini-enable-ide-pins; - cortina,gemini-enable-sata-bridge; -}; diff --git a/Documentation/devicetree/bindings/ata/cortina,gemini-sata-bridge.yaml b/Documentation/devicetree/bindings/ata/cortina,gemini-sata-bridge.yaml new file mode 100644 index 000000000000..21a90975593b --- /dev/null +++ b/Documentation/devicetree/bindings/ata/cortina,gemini-sata-bridge.yaml @@ -0,0 +1,109 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/ata/cortina,gemini-sata-bridge.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Cortina Systems Gemini SATA Bridge + +maintainers: + - Linus Walleij + +description: | + The Gemini SATA bridge in a SoC-internal PATA to SATA bridge that + takes two Faraday Technology FTIDE010 PATA controllers and bridges + them in different configurations to two SATA ports. + +properties: + compatible: + const: cortina,gemini-sata-bridge + + reg: + maxItems: 1 + + resets: + minItems: 2 + maxItems: 2 + description: phandles to the reset lines for both SATA bridges + + reset-names: + items: + - const: sata0 + - const: sata1 + + clocks: + minItems: 2 + maxItems: 2 + description: phandles to the compulsory peripheral clocks + + clock-names: + items: + - const: SATA0_PCLK + - const: SATA1_PCLK + + syscon: + $ref: /schemas/types.yaml#/definitions/phandle + description: a phandle to the global Gemini system controller + + cortina,gemini-ata-muxmode: + $ref: /schemas/types.yaml#/definitions/uint32 + enum: + - 0 + - 1 + - 2 + - 3 + description: | + Tell the desired multiplexing mode for the ATA controller and SATA + bridges. + Mode 0: ata0 master <-> sata0 + ata1 master <-> sata1 + ata0 slave interface brought out on IDE pads + Mode 1: ata0 master <-> sata0 + ata1 master <-> sata1 + ata1 slave interface brought out on IDE pads + Mode 2: ata1 master <-> sata1 + ata1 slave <-> sata0 + ata0 master and slave interfaces brought out on IDE pads + Mode 3: ata0 master <-> sata0 + ata0 slave <-> sata1 + ata1 master and slave interfaces brought out on IDE pads + + cortina,gemini-enable-ide-pins: + type: boolean + description: Enables the PATA to IDE connection. + The muxmode setting decides whether ATA0 or ATA1 is brought out, + and whether master, slave or both interfaces get brought out. + + cortina,gemini-enable-sata-bridge: + type: boolean + description: Enables the PATA to SATA bridge inside the Gemnini SoC. + The Muxmode decides what PATA blocks will be muxed out and how. + +required: + - clocks + - clock-names + - cortina,gemini-ata-muxmode + - resets + - reset-names + - compatible + - reg + - syscon + +additionalProperties: false + +examples: + - | + #include + sata@46000000 { + compatible = "cortina,gemini-sata-bridge"; + reg = <0x46000000 0x100>; + resets = <&rcon 26>, <&rcon 27>; + reset-names = "sata0", "sata1"; + clocks = <&gcc GEMINI_CLK_GATE_SATA0>, + <&gcc GEMINI_CLK_GATE_SATA1>; + clock-names = "SATA0_PCLK", "SATA1_PCLK"; + syscon = <&syscon>; + cortina,gemini-ata-muxmode = <3>; + cortina,gemini-enable-ide-pins; + cortina,gemini-enable-sata-bridge; + }; From 9036ff626579b1d92edfd0881d6b283e9995c16d Mon Sep 17 00:00:00 2001 From: Vladimir Zapolskiy Date: Thu, 3 Feb 2022 18:46:28 +0200 Subject: [PATCH 165/370] dt-bindings: i2c: qcom-cci: add QCOM SM8450 compatible The change adds QCOM SM8450 compatible value to the list of QCOM CCI controller compatibles, the controller found on the SoC is equal to the ones found on previous SoC generations. Signed-off-by: Vladimir Zapolskiy Reviewed-by: Robert Foss Acked-by: Rob Herring Signed-off-by: Wolfram Sang --- Documentation/devicetree/bindings/i2c/i2c-qcom-cci.txt | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/i2c/i2c-qcom-cci.txt b/Documentation/devicetree/bindings/i2c/i2c-qcom-cci.txt index 7b9fc0c22eaf..924ad8c03464 100644 --- a/Documentation/devicetree/bindings/i2c/i2c-qcom-cci.txt +++ b/Documentation/devicetree/bindings/i2c/i2c-qcom-cci.txt @@ -10,6 +10,7 @@ PROPERTIES: "qcom,msm8996-cci" "qcom,sdm845-cci" "qcom,sm8250-cci" + "qcom,sm8450-cci" - reg Usage: required @@ -43,7 +44,8 @@ PROPERTIES: SUBNODES: The CCI provides I2C masters for one (msm8916) or two i2c busses (msm8996, -sdm845 and sm8250), described as subdevices named "i2c-bus@0" and "i2c-bus@1". +sdm845, sm8250 and sm8450), described as subdevices named "i2c-bus@0" and +"i2c-bus@1". PROPERTIES: From 017b32e6da8d4a9673bf68ab4ac1260ef74e9695 Mon Sep 17 00:00:00 2001 From: Vladimir Zapolskiy Date: Thu, 3 Feb 2022 18:47:13 +0200 Subject: [PATCH 166/370] i2c: qcom-cci: add sm8450 compatible Add QCOM SM8450 specific compatible for CCI controller, which is equal to CCI controllers found on QCOM SDM845 and QCOM SM8250 SoCs. Signed-off-by: Vladimir Zapolskiy Reviewed-by: Robert Foss Signed-off-by: Wolfram Sang --- drivers/i2c/busses/i2c-qcom-cci.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/i2c/busses/i2c-qcom-cci.c b/drivers/i2c/busses/i2c-qcom-cci.c index c1de8eb66169..649c91993744 100644 --- a/drivers/i2c/busses/i2c-qcom-cci.c +++ b/drivers/i2c/busses/i2c-qcom-cci.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0 // Copyright (c) 2012-2016, The Linux Foundation. All rights reserved. -// Copyright (c) 2017-20 Linaro Limited. +// Copyright (c) 2017-2022 Linaro Limited. #include #include @@ -770,6 +770,7 @@ static const struct of_device_id cci_dt_match[] = { { .compatible = "qcom,msm8996-cci", .data = &cci_v2_data}, { .compatible = "qcom,sdm845-cci", .data = &cci_v2_data}, { .compatible = "qcom,sm8250-cci", .data = &cci_v2_data}, + { .compatible = "qcom,sm8450-cci", .data = &cci_v2_data}, {} }; MODULE_DEVICE_TABLE(of, cci_dt_match); From ccb7bc50177c5e94e0609126654abeb4f3b67819 Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Thu, 10 Feb 2022 21:42:21 +0100 Subject: [PATCH 167/370] mtd: spear_smi: use GFP_KERNEL Platform_driver probe functions aren't called with locks held and thus don't need GFP_ATOMIC. Use GFP_KERNEL instead. Problem found with Coccinelle. Signed-off-by: Julia Lawall Signed-off-by: Miquel Raynal Link: https://lore.kernel.org/linux-mtd/20220210204223.104181-8-Julia.Lawall@inria.fr --- drivers/mtd/devices/spear_smi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/mtd/devices/spear_smi.c b/drivers/mtd/devices/spear_smi.c index 2e00862389dd..24073518587f 100644 --- a/drivers/mtd/devices/spear_smi.c +++ b/drivers/mtd/devices/spear_smi.c @@ -969,7 +969,7 @@ static int spear_smi_probe(struct platform_device *pdev) goto err; } - dev = devm_kzalloc(&pdev->dev, sizeof(*dev), GFP_ATOMIC); + dev = devm_kzalloc(&pdev->dev, sizeof(*dev), GFP_KERNEL); if (!dev) { ret = -ENOMEM; goto err; From 438356e5151b929af90e501b9c6dd1f3ea2fc7c4 Mon Sep 17 00:00:00 2001 From: Corentin Labbe Date: Fri, 11 Feb 2022 12:08:42 +0000 Subject: [PATCH 168/370] dt-bindings: mtd: drop mtd/cortina,gemini-flash.txt Drop mtd/cortina,gemini-flash.txt since it is nearly already handled by Documentation/devicetree/bindings/mtd/mtd-physmap.yaml. We add jedec-flash to list of compatible because one board (gemini-dlink-dns-313.dts) needs it. See commit a10d862e585e ("ARM: dts: Fix the DNS-313 flash compatible") The flash on the DNS-313 needs to be probed as JEDEC, it does not conform to the common CFI standard. Reviewed-by: Linus Walleij Signed-off-by: Corentin Labbe Reviewed-by: Rob Herring Signed-off-by: Miquel Raynal Link: https://lore.kernel.org/linux-mtd/20220211120842.3388592-1-clabbe@baylibre.com --- .../bindings/mtd/cortina,gemini-flash.txt | 24 ------------------- .../devicetree/bindings/mtd/mtd-physmap.yaml | 18 +++++++++++++- 2 files changed, 17 insertions(+), 25 deletions(-) delete mode 100644 Documentation/devicetree/bindings/mtd/cortina,gemini-flash.txt diff --git a/Documentation/devicetree/bindings/mtd/cortina,gemini-flash.txt b/Documentation/devicetree/bindings/mtd/cortina,gemini-flash.txt deleted file mode 100644 index efa5b2aba829..000000000000 --- a/Documentation/devicetree/bindings/mtd/cortina,gemini-flash.txt +++ /dev/null @@ -1,24 +0,0 @@ -Flash device on Cortina Systems Gemini SoC - -This flash is regular CFI compatible (Intel or AMD extended) flash chips with -some special bits that can be controlled by the machine's system controller. - -Required properties: -- compatible : must be "cortina,gemini-flash", "cfi-flash"; -- reg : memory address for the flash chip -- syscon : must be a phandle to the system controller -- bank-width : width in bytes of flash interface, should be <2> - -For the rest of the properties, see mtd-physmap.yaml. - -The device tree may optionally contain sub-nodes describing partitions of the -address space. See partition.txt for more detail. - -Example: - -flash@30000000 { - compatible = "cortina,gemini-flash", "cfi-flash"; - reg = <0x30000000 0x01000000>; - syscon = <&syscon>; - bank-width = <2>; -}; diff --git a/Documentation/devicetree/bindings/mtd/mtd-physmap.yaml b/Documentation/devicetree/bindings/mtd/mtd-physmap.yaml index f827984936f6..82eb4e0f453b 100644 --- a/Documentation/devicetree/bindings/mtd/mtd-physmap.yaml +++ b/Documentation/devicetree/bindings/mtd/mtd-physmap.yaml @@ -44,7 +44,9 @@ properties: - numonyx,js28f128 - sst,sst39vf320 - xlnx,xps-mch-emc-2.00.a - - const: cfi-flash + - enum: + - cfi-flash + - jedec-flash - items: - enum: - cypress,cy7c1019dv33-10zsxi @@ -127,6 +129,20 @@ required: - compatible - reg +if: + properties: + compatible: + contains: + const: cortina,gemini-flash +then: + properties: + syscon: + $ref: /schemas/types.yaml#/definitions/phandle + description: + Phandle to the syscon controller + required: + - syscon + # FIXME: A parent bus may define timing properties additionalProperties: true From 2365f91c861cbfeef7141c69842848c7b2d3c2db Mon Sep 17 00:00:00 2001 From: INAGAKI Hiroshi Date: Sun, 13 Feb 2022 15:40:44 +0900 Subject: [PATCH 169/370] mtd: parsers: trx: allow to use on MediaTek MIPS SoCs Buffalo sells some router devices which have trx-formatted firmware, based on MediaTek MIPS SoCs. To use parser_trx on those devices, add "RALINK" to dependency and allow to compile for MediaTek MIPS SoCs. examples: - WCR-1166DS (MT7628) - WSR-1166DHP (MT7621) - WSR-2533DHP (MT7621) Signed-off-by: INAGAKI Hiroshi Signed-off-by: Miquel Raynal Link: https://lore.kernel.org/linux-mtd/20220213064045.1781-1-musashino.open@gmail.com --- drivers/mtd/parsers/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/mtd/parsers/Kconfig b/drivers/mtd/parsers/Kconfig index 337ea8b9a4c3..23763d16e4f9 100644 --- a/drivers/mtd/parsers/Kconfig +++ b/drivers/mtd/parsers/Kconfig @@ -115,7 +115,7 @@ config MTD_AFS_PARTS config MTD_PARSER_TRX tristate "Parser for TRX format partitions" - depends on MTD && (BCM47XX || ARCH_BCM_5301X || ARCH_MEDIATEK || COMPILE_TEST) + depends on MTD && (BCM47XX || ARCH_BCM_5301X || ARCH_MEDIATEK || RALINK || COMPILE_TEST) help TRX is a firmware format used by Broadcom on their devices. It may contain up to 3/4 partitions (depending on the version). From a1fe2ace2c39dcdc7c053705459a73b7598b1e4f Mon Sep 17 00:00:00 2001 From: Amit Kumar Mahapatra Date: Wed, 9 Feb 2022 11:04:27 +0530 Subject: [PATCH 170/370] mtd: rawnand: pl353: Set the nand chip node as the flash node In devicetree the flash information is embedded within nand chip node, so during nand chip initialization the nand chip node should be passed to nand_set_flash_node() api, instead of nand controller node. Fixes: 08d8c62164a3 ("mtd: rawnand: pl353: Add support for the ARM PL353 SMC NAND controller") Signed-off-by: Amit Kumar Mahapatra Signed-off-by: Miquel Raynal Link: https://lore.kernel.org/linux-mtd/20220209053427.27676-1-amit.kumar-mahapatra@xilinx.com --- drivers/mtd/nand/raw/pl35x-nand-controller.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/mtd/nand/raw/pl35x-nand-controller.c b/drivers/mtd/nand/raw/pl35x-nand-controller.c index 8a91e069ee2e..3c6f6aff649f 100644 --- a/drivers/mtd/nand/raw/pl35x-nand-controller.c +++ b/drivers/mtd/nand/raw/pl35x-nand-controller.c @@ -1062,7 +1062,7 @@ static int pl35x_nand_chip_init(struct pl35x_nandc *nfc, chip->controller = &nfc->controller; mtd = nand_to_mtd(chip); mtd->dev.parent = nfc->dev; - nand_set_flash_node(chip, nfc->dev->of_node); + nand_set_flash_node(chip, np); if (!mtd->name) { mtd->name = devm_kasprintf(nfc->dev, GFP_KERNEL, "%s", PL35X_NANDC_DRIVER_NAME); From cb57fae479be41d1233f5a49d4760de9a5692b6e Mon Sep 17 00:00:00 2001 From: Christophe Kerello Date: Thu, 17 Feb 2022 15:47:52 +0100 Subject: [PATCH 171/370] dt-binding: mtd: nand: Document the wp-gpios property A few drivers use this property to describe the GPIO pin used to protect the NAND during program/erase operations. Signed-off-by: Christophe Kerello Acked-by: Rob Herring Signed-off-by: Miquel Raynal Link: https://lore.kernel.org/linux-mtd/20220217144755.270679-2-christophe.kerello@foss.st.com --- Documentation/devicetree/bindings/mtd/nand-controller.yaml | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/Documentation/devicetree/bindings/mtd/nand-controller.yaml b/Documentation/devicetree/bindings/mtd/nand-controller.yaml index bd217e6f5018..53b21aed0ac5 100644 --- a/Documentation/devicetree/bindings/mtd/nand-controller.yaml +++ b/Documentation/devicetree/bindings/mtd/nand-controller.yaml @@ -154,6 +154,13 @@ patternProperties: Ready/Busy pins. Active state refers to the NAND ready state and should be set to GPIOD_ACTIVE_HIGH unless the signal is inverted. + wp-gpios: + description: + Contains one GPIO descriptor for the Write Protect pin. + Active state refers to the NAND Write Protect state and should be + set to GPIOD_ACTIVE_LOW unless the signal is inverted. + maxItems: 1 + secure-regions: $ref: /schemas/types.yaml#/definitions/uint64-matrix description: From ffb16c1c42670356c579926aabdac0ac7bbc16d8 Mon Sep 17 00:00:00 2001 From: Christophe Kerello Date: Thu, 17 Feb 2022 15:47:53 +0100 Subject: [PATCH 172/370] mtd: rawnand: stm32_fmc2: Add NAND Write Protect support This patch adds the support of the WP# signal. WP will be disabled in probe/resume callbacks and will be enabled in remove/suspend callbacks. Signed-off-by: Christophe Kerello Signed-off-by: Miquel Raynal Link: https://lore.kernel.org/linux-mtd/20220217144755.270679-3-christophe.kerello@foss.st.com --- drivers/mtd/nand/raw/stm32_fmc2_nand.c | 40 +++++++++++++++++++++++++- 1 file changed, 39 insertions(+), 1 deletion(-) diff --git a/drivers/mtd/nand/raw/stm32_fmc2_nand.c b/drivers/mtd/nand/raw/stm32_fmc2_nand.c index 97b4e02e43e4..87c1c7dd97eb 100644 --- a/drivers/mtd/nand/raw/stm32_fmc2_nand.c +++ b/drivers/mtd/nand/raw/stm32_fmc2_nand.c @@ -9,6 +9,7 @@ #include #include #include +#include #include #include #include @@ -231,6 +232,7 @@ struct stm32_fmc2_timings { struct stm32_fmc2_nand { struct nand_chip chip; + struct gpio_desc *wp_gpio; struct stm32_fmc2_timings timings; int ncs; int cs_used[FMC2_MAX_CE]; @@ -1747,6 +1749,18 @@ static const struct nand_controller_ops stm32_fmc2_nfc_controller_ops = { .setup_interface = stm32_fmc2_nfc_setup_interface, }; +static void stm32_fmc2_nfc_wp_enable(struct stm32_fmc2_nand *nand) +{ + if (nand->wp_gpio) + gpiod_set_value(nand->wp_gpio, 1); +} + +static void stm32_fmc2_nfc_wp_disable(struct stm32_fmc2_nand *nand) +{ + if (nand->wp_gpio) + gpiod_set_value(nand->wp_gpio, 0); +} + static int stm32_fmc2_nfc_parse_child(struct stm32_fmc2_nfc *nfc, struct device_node *dn) { @@ -1785,6 +1799,18 @@ static int stm32_fmc2_nfc_parse_child(struct stm32_fmc2_nfc *nfc, nand->cs_used[i] = cs; } + nand->wp_gpio = devm_gpiod_get_from_of_node(nfc->dev, dn, + "wp-gpios", 0, + GPIOD_OUT_HIGH, "wp"); + if (IS_ERR(nand->wp_gpio)) { + ret = PTR_ERR(nand->wp_gpio); + if (ret != -ENOENT) + return dev_err_probe(nfc->dev, ret, + "failed to request WP GPIO\n"); + + nand->wp_gpio = NULL; + } + nand_set_flash_node(&nand->chip, dn); return 0; @@ -1956,10 +1982,12 @@ static int stm32_fmc2_nfc_probe(struct platform_device *pdev) chip->options |= NAND_BUSWIDTH_AUTO | NAND_NO_SUBPAGE_WRITE | NAND_USES_DMA; + stm32_fmc2_nfc_wp_disable(nand); + /* Scan to find existence of the device */ ret = nand_scan(chip, nand->ncs); if (ret) - goto err_release_dma; + goto err_wp_enable; ret = mtd_device_register(mtd, NULL, 0); if (ret) @@ -1972,6 +2000,9 @@ static int stm32_fmc2_nfc_probe(struct platform_device *pdev) err_nand_cleanup: nand_cleanup(chip); +err_wp_enable: + stm32_fmc2_nfc_wp_enable(nand); + err_release_dma: if (nfc->dma_ecc_ch) dma_release_channel(nfc->dma_ecc_ch); @@ -2012,15 +2043,20 @@ static int stm32_fmc2_nfc_remove(struct platform_device *pdev) clk_disable_unprepare(nfc->clk); + stm32_fmc2_nfc_wp_enable(nand); + return 0; } static int __maybe_unused stm32_fmc2_nfc_suspend(struct device *dev) { struct stm32_fmc2_nfc *nfc = dev_get_drvdata(dev); + struct stm32_fmc2_nand *nand = &nfc->nand; clk_disable_unprepare(nfc->clk); + stm32_fmc2_nfc_wp_enable(nand); + pinctrl_pm_select_sleep_state(dev); return 0; @@ -2042,6 +2078,8 @@ static int __maybe_unused stm32_fmc2_nfc_resume(struct device *dev) stm32_fmc2_nfc_init(nfc); + stm32_fmc2_nfc_wp_disable(nand); + for (chip_cs = 0; chip_cs < FMC2_MAX_CE; chip_cs++) { if (!(nfc->cs_assigned & BIT(chip_cs))) continue; From 8302532f47bb6c3aa1ed2043d30187ca307f176a Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Fri, 4 Feb 2022 17:59:20 +0200 Subject: [PATCH 173/370] i2c: smbus: Check for parent device before dereference MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit An I²C adapter might be instantiated without parent. In such case there is no property can be retrieved. Skip SMBus alert setup when this happens. Fixes: a263a84088f6 ("i2c: smbus: Use device_*() functions instead of of_*()") Reported-by: syzbot+0591ccf54ee05344e4eb@syzkaller.appspotmail.com Signed-off-by: Andy Shevchenko Signed-off-by: Wolfram Sang --- drivers/i2c/i2c-core-smbus.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/drivers/i2c/i2c-core-smbus.c b/drivers/i2c/i2c-core-smbus.c index 053b215308c4..e3b96fc53b5c 100644 --- a/drivers/i2c/i2c-core-smbus.c +++ b/drivers/i2c/i2c-core-smbus.c @@ -705,10 +705,14 @@ EXPORT_SYMBOL_GPL(i2c_new_smbus_alert_device); #if IS_ENABLED(CONFIG_I2C_SMBUS) int i2c_setup_smbus_alert(struct i2c_adapter *adapter) { + struct device *parent = adapter->dev.parent; int irq; - irq = device_property_match_string(adapter->dev.parent, "interrupt-names", - "smbus_alert"); + /* Adapter instantiated without parent, skip the SMBus alert setup */ + if (!parent) + return 0; + + irq = device_property_match_string(parent, "interrupt-names", "smbus_alert"); if (irq == -EINVAL || irq == -ENODATA) return 0; else if (irq < 0) From 48b0e01109f5fb91eabb6f7c4a487b76942061cc Mon Sep 17 00:00:00 2001 From: Edward Shishkin Date: Mon, 21 Feb 2022 00:22:19 +0100 Subject: [PATCH 174/370] reiserfs: get rid of AOP_FLAG_CONT_EXPAND flag Remove usage of AOP_FLAG_CONT_EXPAND flag. Reiserfs is the only user of it and it is easy to avoid. Link: https://lore.kernel.org/r/20220220232219.1235-1-edward.shishkin@gmail.com Signed-off-by: Edward Shishkin Signed-off-by: Jan Kara --- fs/reiserfs/inode.c | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) diff --git a/fs/reiserfs/inode.c b/fs/reiserfs/inode.c index f49b72ccac4c..e943930939f5 100644 --- a/fs/reiserfs/inode.c +++ b/fs/reiserfs/inode.c @@ -2763,13 +2763,6 @@ static int reiserfs_write_begin(struct file *file, int old_ref = 0; inode = mapping->host; - *fsdata = NULL; - if (flags & AOP_FLAG_CONT_EXPAND && - (pos & (inode->i_sb->s_blocksize - 1)) == 0) { - pos ++; - *fsdata = (void *)(unsigned long)flags; - } - index = pos >> PAGE_SHIFT; page = grab_cache_page_write_begin(mapping, index, flags); if (!page) @@ -2896,9 +2889,6 @@ static int reiserfs_write_end(struct file *file, struct address_space *mapping, unsigned start; bool locked = false; - if ((unsigned long)fsdata & AOP_FLAG_CONT_EXPAND) - pos ++; - reiserfs_wait_on_write_block(inode->i_sb); if (reiserfs_transaction_running(inode->i_sb)) th = current->journal_info; @@ -3316,7 +3306,11 @@ int reiserfs_setattr(struct user_namespace *mnt_userns, struct dentry *dentry, /* fill in hole pointers in the expanding truncate case. */ if (attr->ia_size > inode->i_size) { - error = generic_cont_expand_simple(inode, attr->ia_size); + loff_t pos = attr->ia_size; + + if ((pos & (inode->i_sb->s_blocksize - 1)) == 0) + pos++; + error = generic_cont_expand_simple(inode, pos); if (REISERFS_I(inode)->i_prealloc_count > 0) { int err; struct reiserfs_transaction_handle th; From 2596f6b93a606332c0e5759991e880fbe76e6c8d Mon Sep 17 00:00:00 2001 From: Joel Stanley Date: Mon, 21 Feb 2022 17:33:51 +1030 Subject: [PATCH 175/370] ipmi: kcs: aspeed: Add AST2600 compatible string The AST2600 is already described in the bindings, but the driver never gained a compatible string. Signed-off-by: Joel Stanley Message-Id: <20220221070351.121905-1-joel@jms.id.au> Signed-off-by: Corey Minyard --- drivers/char/ipmi/kcs_bmc_aspeed.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/char/ipmi/kcs_bmc_aspeed.c b/drivers/char/ipmi/kcs_bmc_aspeed.c index 92a37b33494c..b555286016b1 100644 --- a/drivers/char/ipmi/kcs_bmc_aspeed.c +++ b/drivers/char/ipmi/kcs_bmc_aspeed.c @@ -693,6 +693,7 @@ static const struct of_device_id ast_kcs_bmc_match[] = { { .compatible = "aspeed,ast2500-kcs-bmc", .data = &of_v1_ops }, { .compatible = "aspeed,ast2400-kcs-bmc-v2", .data = &of_v2_ops }, { .compatible = "aspeed,ast2500-kcs-bmc-v2", .data = &of_v2_ops }, + { .compatible = "aspeed,ast2600-kcs-bmc", .data = &of_v2_ops }, { } }; MODULE_DEVICE_TABLE(of, ast_kcs_bmc_match); From 5dad90f360579534cf19444a7db8532258f811e9 Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Mon, 21 Feb 2022 09:22:26 +0100 Subject: [PATCH 176/370] dt-bindings: vendor-prefixes: add second HiSilicon prefix There are few boards DTS using "hisi,rst-syscon" property - undocumented "hisi" prefix. The property will not be changed in DTS to non-deprecated one, because of compatibility reasons. Add deprecated "hisi" prefix to silence DT schema warnings. Cc: Wei Xu Cc: David Heidelberg Signed-off-by: Krzysztof Kozlowski Reviewed-by: David Heidelberg Reviewed-by: Wei Xu Signed-off-by: Rob Herring Link: https://lore.kernel.org/r/20220221082228.34407-1-krzysztof.kozlowski@canonical.com --- Documentation/devicetree/bindings/vendor-prefixes.yaml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Documentation/devicetree/bindings/vendor-prefixes.yaml b/Documentation/devicetree/bindings/vendor-prefixes.yaml index 913f722a6b8d..fc2838960323 100644 --- a/Documentation/devicetree/bindings/vendor-prefixes.yaml +++ b/Documentation/devicetree/bindings/vendor-prefixes.yaml @@ -499,6 +499,9 @@ patternProperties: description: Himax Technologies, Inc. "^hirschmann,.*": description: Hirschmann Automation and Control GmbH + "^hisi,.*": + description: HiSilicon Limited (deprecated, use hisilicon) + deprecated: true "^hisilicon,.*": description: HiSilicon Limited. "^hit,.*": From aaffb26991bca8cae5f00bb65f0b5a190ca71929 Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Mon, 21 Feb 2022 09:22:27 +0100 Subject: [PATCH 177/370] dt-bindings: vendor-prefixes: add second Synopsys prefix There are few bindings with compatibles starting with a "synopsys" prefix. Document it as deprecated, to be sure no new usages will appear. Signed-off-by: Krzysztof Kozlowski Signed-off-by: Rob Herring Link: https://lore.kernel.org/r/20220221082228.34407-2-krzysztof.kozlowski@canonical.com --- Documentation/devicetree/bindings/vendor-prefixes.yaml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Documentation/devicetree/bindings/vendor-prefixes.yaml b/Documentation/devicetree/bindings/vendor-prefixes.yaml index fc2838960323..3da2b08429e1 100644 --- a/Documentation/devicetree/bindings/vendor-prefixes.yaml +++ b/Documentation/devicetree/bindings/vendor-prefixes.yaml @@ -1186,6 +1186,9 @@ patternProperties: description: Synaptics Inc. "^synology,.*": description: Synology, Inc. + "^synopsys,.*": + description: Synopsys, Inc. (deprecated, use snps) + deprecated: true "^tbs,.*": description: TBS Technologies "^tbs-biometrics,.*": From 16234ef1d2aa170e37c27734ab6544633707ba19 Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Mon, 21 Feb 2022 09:22:28 +0100 Subject: [PATCH 178/370] dt-bindings: usb: do not use deprecated synopsys prefix The "synopsys" prefix and "synopsys,dwc3" compatible are deprecated. Signed-off-by: Krzysztof Kozlowski Signed-off-by: Rob Herring Link: https://lore.kernel.org/r/20220221082228.34407-3-krzysztof.kozlowski@canonical.com --- Documentation/devicetree/bindings/usb/dwc3-cavium.txt | 2 +- Documentation/devicetree/bindings/usb/ti,keystone-dwc3.yaml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Documentation/devicetree/bindings/usb/dwc3-cavium.txt b/Documentation/devicetree/bindings/usb/dwc3-cavium.txt index 710b782ccf65..171df79360ff 100644 --- a/Documentation/devicetree/bindings/usb/dwc3-cavium.txt +++ b/Documentation/devicetree/bindings/usb/dwc3-cavium.txt @@ -20,7 +20,7 @@ Example device node: refclk-type-hs = "dlmc_ref_clk0"; power = <0x00000002 0x00000002 0x00000001>; xhci@1690000000000 { - compatible = "cavium,octeon-7130-xhci", "synopsys,dwc3"; + compatible = "cavium,octeon-7130-xhci", "snps,dwc3"; reg = <0x00016900 0x00000000 0x00000010 0x00000000>; interrupt-parent = <0x00000010>; interrupts = <0x00000009 0x00000004>; diff --git a/Documentation/devicetree/bindings/usb/ti,keystone-dwc3.yaml b/Documentation/devicetree/bindings/usb/ti,keystone-dwc3.yaml index f6e91a5fd8fe..b1f65a656528 100644 --- a/Documentation/devicetree/bindings/usb/ti,keystone-dwc3.yaml +++ b/Documentation/devicetree/bindings/usb/ti,keystone-dwc3.yaml @@ -92,7 +92,7 @@ examples: ranges; usb@2690000 { - compatible = "synopsys,dwc3"; + compatible = "snps,dwc3"; reg = <0x2690000 0x70000>; interrupts = ; usb-phy = <&usb_phy>, <&usb_phy>; From 57c9e3c9a374ff1419e5559f8979c0b43a0bffbd Mon Sep 17 00:00:00 2001 From: Corey Minyard Date: Wed, 23 Feb 2022 07:38:12 -0600 Subject: [PATCH 179/370] ipmi:ipmi_ipmb: Unregister the SMI on remove Otherwise it will continue to be hooked into the IPMI framework. Signed-off-by: Corey Minyard --- drivers/char/ipmi/ipmi_ipmb.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/char/ipmi/ipmi_ipmb.c b/drivers/char/ipmi/ipmi_ipmb.c index ba0c2d2c6bbe..88d7316b3bab 100644 --- a/drivers/char/ipmi/ipmi_ipmb.c +++ b/drivers/char/ipmi/ipmi_ipmb.c @@ -433,6 +433,8 @@ static int ipmi_ipmb_remove(struct i2c_client *client) } ipmi_ipmb_stop_thread(iidev); + ipmi_unregister_smi(iidev->intf); + return 0; } From 00d93611f00219bd142aa119c5121793cac30ff0 Mon Sep 17 00:00:00 2001 From: Corey Minyard Date: Sun, 20 Feb 2022 14:38:39 -0600 Subject: [PATCH 180/370] ipmi:ipmb: Add the ability to have a separate slave and master device A situation has come up where there is a slave-only device for the slave and a separate master device on the same bug. Allow a separate slave device to be registered. Signed-off-by: Corey Minyard --- .../devicetree/bindings/ipmi/ipmi-ipmb.yaml | 8 +++ drivers/char/ipmi/ipmi_ipmb.c | 60 +++++++++++++++---- 2 files changed, 58 insertions(+), 10 deletions(-) diff --git a/Documentation/devicetree/bindings/ipmi/ipmi-ipmb.yaml b/Documentation/devicetree/bindings/ipmi/ipmi-ipmb.yaml index 93d8f8e88cf5..71bc031c4fde 100644 --- a/Documentation/devicetree/bindings/ipmi/ipmi-ipmb.yaml +++ b/Documentation/devicetree/bindings/ipmi/ipmi-ipmb.yaml @@ -36,6 +36,14 @@ properties: $ref: /schemas/types.yaml#/definitions/uint32 description: Number of retries before a failure is declared. Defaults to 1. + slave-dev: + $ref: /schemas/types.yaml#/definitions/phandle + description: | + The slave i2c device. If not present, the main device is used. This + lets you use two devices on the IPMB, one for master and one for slave, + in case you have a slave device that can only be a slave. The slave + will receive messages and the master will transmit. + required: - compatible - reg diff --git a/drivers/char/ipmi/ipmi_ipmb.c b/drivers/char/ipmi/ipmi_ipmb.c index 88d7316b3bab..b81b862532fb 100644 --- a/drivers/char/ipmi/ipmi_ipmb.c +++ b/drivers/char/ipmi/ipmi_ipmb.c @@ -39,6 +39,7 @@ MODULE_PARM_DESC(max_retries, "Max resends of a command before timing out."); struct ipmi_ipmb_dev { struct ipmi_smi *intf; struct i2c_client *client; + struct i2c_client *slave; struct ipmi_smi_handlers handlers; @@ -257,7 +258,7 @@ static void ipmi_ipmb_format_for_xmit(struct ipmi_ipmb_dev *iidev, memcpy(iidev->xmitmsg + 5, msg->data + 1, msg->data_size - 1); iidev->xmitlen = msg->data_size + 4; } - iidev->xmitmsg[3] = iidev->client->addr << 1; + iidev->xmitmsg[3] = iidev->slave->addr << 1; if (((msg->data[0] >> 2) & 1) == 0) /* If it's a command, put in our own sequence number. */ iidev->xmitmsg[4] = ((iidev->xmitmsg[4] & 0x03) | @@ -427,10 +428,13 @@ static int ipmi_ipmb_remove(struct i2c_client *client) { struct ipmi_ipmb_dev *iidev = i2c_get_clientdata(client); - if (iidev->client) { - iidev->client = NULL; - i2c_slave_unregister(client); + if (iidev->slave) { + i2c_slave_unregister(iidev->slave); + if (iidev->slave != iidev->client) + i2c_unregister_device(iidev->slave); } + iidev->slave = NULL; + iidev->client = NULL; ipmi_ipmb_stop_thread(iidev); ipmi_unregister_smi(iidev->intf); @@ -443,6 +447,9 @@ static int ipmi_ipmb_probe(struct i2c_client *client, { struct device *dev = &client->dev; struct ipmi_ipmb_dev *iidev; + struct device_node *slave_np; + struct i2c_adapter *slave_adap = NULL; + struct i2c_client *slave = NULL; int rv; iidev = devm_kzalloc(&client->dev, sizeof(*iidev), GFP_KERNEL); @@ -466,15 +473,46 @@ static int ipmi_ipmb_probe(struct i2c_client *client, &iidev->max_retries) != 0) iidev->max_retries = max_retries; - i2c_set_clientdata(client, iidev); - client->flags |= I2C_CLIENT_SLAVE; - - rv = i2c_slave_register(client, ipmi_ipmb_slave_cb); - if (rv) - return rv; + slave_np = of_parse_phandle(dev->of_node, "slave-dev", 0); + if (slave_np) { + slave_adap = of_get_i2c_adapter_by_node(slave_np); + if (!slave_adap) { + dev_notice(&client->dev, + "Could not find slave adapter\n"); + return -EINVAL; + } + } iidev->client = client; + if (slave_adap) { + struct i2c_board_info binfo; + + memset(&binfo, 0, sizeof(binfo)); + strscpy(binfo.type, "ipmb-slave", I2C_NAME_SIZE); + binfo.addr = client->addr; + binfo.flags = I2C_CLIENT_SLAVE; + slave = i2c_new_client_device(slave_adap, &binfo); + i2c_put_adapter(slave_adap); + if (IS_ERR(slave)) { + rv = PTR_ERR(slave); + dev_notice(&client->dev, + "Could not allocate slave device: %d\n", rv); + return rv; + } + i2c_set_clientdata(slave, iidev); + } else { + slave = client; + } + i2c_set_clientdata(client, iidev); + slave->flags |= I2C_CLIENT_SLAVE; + + rv = i2c_slave_register(slave, ipmi_ipmb_slave_cb); + if (rv) + goto out_err; + iidev->slave = slave; + slave = NULL; + iidev->handlers.flags = IPMI_SMI_CAN_HANDLE_IPMB_DIRECT; iidev->handlers.start_processing = ipmi_ipmb_start_processing; iidev->handlers.shutdown = ipmi_ipmb_shutdown; @@ -504,6 +542,8 @@ static int ipmi_ipmb_probe(struct i2c_client *client, return 0; out_err: + if (slave && slave != client) + i2c_unregister_device(slave); ipmi_ipmb_remove(client); return rv; } From 4f0b903ded728c505850daf2914bfc08841f0ae6 Mon Sep 17 00:00:00 2001 From: Amir Goldstein Date: Wed, 23 Feb 2022 17:14:37 +0200 Subject: [PATCH 181/370] fsnotify: fix merge with parent's ignored mask fsnotify_parent() does not consider the parent's mark at all unless the parent inode shows interest in events on children and in the specific event. So unless parent added an event to both its mark mask and ignored mask, the event will not be ignored. Fix this by declaring the interest of an object in an event when the event is in either a mark mask or ignored mask. Link: https://lore.kernel.org/r/20220223151438.790268-2-amir73il@gmail.com Signed-off-by: Amir Goldstein Signed-off-by: Jan Kara --- fs/notify/fanotify/fanotify_user.c | 17 +++++++++-------- fs/notify/mark.c | 4 ++-- include/linux/fsnotify_backend.h | 15 +++++++++++++++ 3 files changed, 26 insertions(+), 10 deletions(-) diff --git a/fs/notify/fanotify/fanotify_user.c b/fs/notify/fanotify/fanotify_user.c index 2ff6bd85ba8f..bd99430a128d 100644 --- a/fs/notify/fanotify/fanotify_user.c +++ b/fs/notify/fanotify/fanotify_user.c @@ -1003,17 +1003,18 @@ static __u32 fanotify_mark_remove_from_mask(struct fsnotify_mark *fsn_mark, __u32 mask, unsigned int flags, __u32 umask, int *destroy) { - __u32 oldmask = 0; + __u32 oldmask, newmask; /* umask bits cannot be removed by user */ mask &= ~umask; spin_lock(&fsn_mark->lock); + oldmask = fsnotify_calc_mask(fsn_mark); if (!(flags & FAN_MARK_IGNORED_MASK)) { - oldmask = fsn_mark->mask; fsn_mark->mask &= ~mask; } else { fsn_mark->ignored_mask &= ~mask; } + newmask = fsnotify_calc_mask(fsn_mark); /* * We need to keep the mark around even if remaining mask cannot * result in any events (e.g. mask == FAN_ONDIR) to support incremenal @@ -1023,7 +1024,7 @@ static __u32 fanotify_mark_remove_from_mask(struct fsnotify_mark *fsn_mark, *destroy = !((fsn_mark->mask | fsn_mark->ignored_mask) & ~umask); spin_unlock(&fsn_mark->lock); - return mask & oldmask; + return oldmask & ~newmask; } static int fanotify_remove_mark(struct fsnotify_group *group, @@ -1081,23 +1082,23 @@ static int fanotify_remove_inode_mark(struct fsnotify_group *group, } static __u32 fanotify_mark_add_to_mask(struct fsnotify_mark *fsn_mark, - __u32 mask, - unsigned int flags) + __u32 mask, unsigned int flags) { - __u32 oldmask = -1; + __u32 oldmask, newmask; spin_lock(&fsn_mark->lock); + oldmask = fsnotify_calc_mask(fsn_mark); if (!(flags & FAN_MARK_IGNORED_MASK)) { - oldmask = fsn_mark->mask; fsn_mark->mask |= mask; } else { fsn_mark->ignored_mask |= mask; if (flags & FAN_MARK_IGNORED_SURV_MODIFY) fsn_mark->flags |= FSNOTIFY_MARK_FLAG_IGNORED_SURV_MODIFY; } + newmask = fsnotify_calc_mask(fsn_mark); spin_unlock(&fsn_mark->lock); - return mask & ~oldmask; + return newmask & ~oldmask; } static struct fsnotify_mark *fanotify_add_new_mark(struct fsnotify_group *group, diff --git a/fs/notify/mark.c b/fs/notify/mark.c index 9007d6affff3..4853184f7dde 100644 --- a/fs/notify/mark.c +++ b/fs/notify/mark.c @@ -127,7 +127,7 @@ static void __fsnotify_recalc_mask(struct fsnotify_mark_connector *conn) return; hlist_for_each_entry(mark, &conn->list, obj_list) { if (mark->flags & FSNOTIFY_MARK_FLAG_ATTACHED) - new_mask |= mark->mask; + new_mask |= fsnotify_calc_mask(mark); } *fsnotify_conn_mask_p(conn) = new_mask; } @@ -692,7 +692,7 @@ int fsnotify_add_mark_locked(struct fsnotify_mark *mark, if (ret) goto err; - if (mark->mask) + if (mark->mask || mark->ignored_mask) fsnotify_recalc_mask(mark->connector); return ret; diff --git a/include/linux/fsnotify_backend.h b/include/linux/fsnotify_backend.h index 790c31844db5..5f9c960049b0 100644 --- a/include/linux/fsnotify_backend.h +++ b/include/linux/fsnotify_backend.h @@ -601,6 +601,21 @@ extern void fsnotify_remove_queued_event(struct fsnotify_group *group, /* functions used to manipulate the marks attached to inodes */ +/* Get mask for calculating object interest taking ignored mask into account */ +static inline __u32 fsnotify_calc_mask(struct fsnotify_mark *mark) +{ + __u32 mask = mark->mask; + + if (!mark->ignored_mask) + return mask; + + /* + * If mark is interested in ignoring events on children, the object must + * show interest in those events for fsnotify_parent() to notice it. + */ + return mask | (mark->ignored_mask & ALL_FSNOTIFY_EVENTS); +} + /* Get mask of events for a list of marks */ extern __u32 fsnotify_conn_mask(struct fsnotify_mark_connector *conn); /* Calculate mask of events for a list of marks */ From 04e317ba72d07901b03399b3d1525e83424df5b3 Mon Sep 17 00:00:00 2001 From: Amir Goldstein Date: Wed, 23 Feb 2022 17:14:38 +0200 Subject: [PATCH 182/370] fsnotify: optimize FS_MODIFY events with no ignored masks fsnotify() treats FS_MODIFY events specially - it does not skip them even if the FS_MODIFY event does not apear in the object's fsnotify mask. This is because send_to_group() checks if FS_MODIFY needs to clear ignored mask of marks. The common case is that an object does not have any mark with ignored mask and in particular, that it does not have a mark with ignored mask and without the FSNOTIFY_MARK_FLAG_IGNORED_SURV_MODIFY flag. Set FS_MODIFY in object's fsnotify mask during fsnotify_recalc_mask() if object has a mark with an ignored mask and without the FSNOTIFY_MARK_FLAG_IGNORED_SURV_MODIFY flag and remove the special treatment of FS_MODIFY in fsnotify(), so that FS_MODIFY events could be optimized in the common case. Call fsnotify_recalc_mask() from fanotify after adding or removing an ignored mask from a mark without FSNOTIFY_MARK_FLAG_IGNORED_SURV_MODIFY or when adding the FSNOTIFY_MARK_FLAG_IGNORED_SURV_MODIFY flag to a mark with ignored mask (the flag cannot be removed by fanotify uapi). Performance results for doing 10000000 write(2)s to tmpfs: vanilla patched without notification mark 25.486+-1.054 24.965+-0.244 with notification mark 30.111+-0.139 26.891+-1.355 So we can see the overhead of notification subsystem has been drastically reduced. Link: https://lore.kernel.org/r/20220223151438.790268-3-amir73il@gmail.com Suggested-by: Jan Kara Signed-off-by: Amir Goldstein Signed-off-by: Jan Kara --- fs/notify/fanotify/fanotify_user.c | 32 +++++++++++++++++++++++------- fs/notify/fsnotify.c | 8 +++++--- include/linux/fsnotify_backend.h | 4 ++++ 3 files changed, 34 insertions(+), 10 deletions(-) diff --git a/fs/notify/fanotify/fanotify_user.c b/fs/notify/fanotify/fanotify_user.c index bd99430a128d..9b32b76a9c30 100644 --- a/fs/notify/fanotify/fanotify_user.c +++ b/fs/notify/fanotify/fanotify_user.c @@ -1081,8 +1081,28 @@ static int fanotify_remove_inode_mark(struct fsnotify_group *group, flags, umask); } +static void fanotify_mark_add_ignored_mask(struct fsnotify_mark *fsn_mark, + __u32 mask, unsigned int flags, + __u32 *removed) +{ + fsn_mark->ignored_mask |= mask; + + /* + * Setting FAN_MARK_IGNORED_SURV_MODIFY for the first time may lead to + * the removal of the FS_MODIFY bit in calculated mask if it was set + * because of an ignored mask that is now going to survive FS_MODIFY. + */ + if ((flags & FAN_MARK_IGNORED_SURV_MODIFY) && + !(fsn_mark->flags & FSNOTIFY_MARK_FLAG_IGNORED_SURV_MODIFY)) { + fsn_mark->flags |= FSNOTIFY_MARK_FLAG_IGNORED_SURV_MODIFY; + if (!(fsn_mark->mask & FS_MODIFY)) + *removed = FS_MODIFY; + } +} + static __u32 fanotify_mark_add_to_mask(struct fsnotify_mark *fsn_mark, - __u32 mask, unsigned int flags) + __u32 mask, unsigned int flags, + __u32 *removed) { __u32 oldmask, newmask; @@ -1091,9 +1111,7 @@ static __u32 fanotify_mark_add_to_mask(struct fsnotify_mark *fsn_mark, if (!(flags & FAN_MARK_IGNORED_MASK)) { fsn_mark->mask |= mask; } else { - fsn_mark->ignored_mask |= mask; - if (flags & FAN_MARK_IGNORED_SURV_MODIFY) - fsn_mark->flags |= FSNOTIFY_MARK_FLAG_IGNORED_SURV_MODIFY; + fanotify_mark_add_ignored_mask(fsn_mark, mask, flags, removed); } newmask = fsnotify_calc_mask(fsn_mark); spin_unlock(&fsn_mark->lock); @@ -1156,7 +1174,7 @@ static int fanotify_add_mark(struct fsnotify_group *group, __kernel_fsid_t *fsid) { struct fsnotify_mark *fsn_mark; - __u32 added; + __u32 added, removed = 0; int ret = 0; mutex_lock(&group->mark_mutex); @@ -1179,8 +1197,8 @@ static int fanotify_add_mark(struct fsnotify_group *group, goto out; } - added = fanotify_mark_add_to_mask(fsn_mark, mask, flags); - if (added & ~fsnotify_conn_mask(fsn_mark->connector)) + added = fanotify_mark_add_to_mask(fsn_mark, mask, flags, &removed); + if (removed || (added & ~fsnotify_conn_mask(fsn_mark->connector))) fsnotify_recalc_mask(fsn_mark->connector); out: diff --git a/fs/notify/fsnotify.c b/fs/notify/fsnotify.c index ab81a0776ece..494f653efbc6 100644 --- a/fs/notify/fsnotify.c +++ b/fs/notify/fsnotify.c @@ -531,11 +531,13 @@ int fsnotify(__u32 mask, const void *data, int data_type, struct inode *dir, /* - * if this is a modify event we may need to clear the ignored masks - * otherwise return if none of the marks care about this type of event. + * If this is a modify event we may need to clear some ignored masks. + * In that case, the object with ignored masks will have the FS_MODIFY + * event in its mask. + * Otherwise, return if none of the marks care about this type of event. */ test_mask = (mask & ALL_FSNOTIFY_EVENTS); - if (!(mask & FS_MODIFY) && !(test_mask & marks_mask)) + if (!(test_mask & marks_mask)) return 0; iter_info.srcu_idx = srcu_read_lock(&fsnotify_mark_srcu); diff --git a/include/linux/fsnotify_backend.h b/include/linux/fsnotify_backend.h index 5f9c960049b0..0805b74cae44 100644 --- a/include/linux/fsnotify_backend.h +++ b/include/linux/fsnotify_backend.h @@ -609,6 +609,10 @@ static inline __u32 fsnotify_calc_mask(struct fsnotify_mark *mark) if (!mark->ignored_mask) return mask; + /* Interest in FS_MODIFY may be needed for clearing ignored mask */ + if (!(mark->flags & FSNOTIFY_MARK_FLAG_IGNORED_SURV_MODIFY)) + mask |= FS_MODIFY; + /* * If mark is interested in ignoring events on children, the object must * show interest in those events for fsnotify_parent() to notice it. From 2b709a7209ef43f02607815a2ab8027e5593ed1a Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Wed, 23 Feb 2022 08:35:46 +0100 Subject: [PATCH 183/370] dt-bindings: writing-schema: Install from PyPI repository Installing dtschema from github.com/devicetree-org is not needed anymore because dtschema is now part of regular PyPI repository. In certain cases it might cause some troubles as it brings latest master version, not the stable release: $ pip3 show dtschema Version: 2020.8.2.dev4+g341f3e3 $ make dt_binding_check dtschema minimum version is v2020.8.1 Reported-by: Marek Szyprowski Signed-off-by: Krzysztof Kozlowski Signed-off-by: Rob Herring Link: https://lore.kernel.org/r/20220223073547.8746-1-krzysztof.kozlowski@canonical.com --- Documentation/devicetree/bindings/writing-schema.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/writing-schema.rst b/Documentation/devicetree/bindings/writing-schema.rst index ea21c72aeb37..4004dd9209a6 100644 --- a/Documentation/devicetree/bindings/writing-schema.rst +++ b/Documentation/devicetree/bindings/writing-schema.rst @@ -118,7 +118,7 @@ The DT schema project must be installed in order to validate the DT schema binding documents and validate DTS files using the DT schema. The DT schema project can be installed with pip:: - pip3 install git+https://github.com/devicetree-org/dt-schema.git@master + pip3 install dtschema Several executables (dt-doc-validate, dt-mk-schema, dt-validate) will be installed. Ensure they are in your PATH (~/.local/bin by default). From 418adabeb3d048a4fd2575b8b96d0769c2fcd1c1 Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Wed, 23 Feb 2022 08:35:47 +0100 Subject: [PATCH 184/370] dt-bindings: example: Extend with typical case (int-array and disallowed prop) Extend the example with: - an array where each element has constraints (min/max value), - property not allowed in case of different compatible. Signed-off-by: Krzysztof Kozlowski Signed-off-by: Rob Herring Link: https://lore.kernel.org/r/20220223073547.8746-2-krzysztof.kozlowski@canonical.com --- .../devicetree/bindings/example-schema.yaml | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/Documentation/devicetree/bindings/example-schema.yaml b/Documentation/devicetree/bindings/example-schema.yaml index c078796ae1b5..80a28781845d 100644 --- a/Documentation/devicetree/bindings/example-schema.yaml +++ b/Documentation/devicetree/bindings/example-schema.yaml @@ -162,6 +162,16 @@ properties: don't need a type. enum: [ 100, 200, 300 ] + vendor,int-array-variable-length-and-constrained-values: + description: Array might define what type of elements might be used (e.g. + their range). + $ref: /schemas/types.yaml#/definitions/uint32-array + minItems: 2 + maxItems: 3 + items: + minimum: 0 + maximum: 8 + child-node: description: Child nodes are just another property from a json-schema perspective. @@ -207,6 +217,10 @@ allOf: then: required: - foo-supply + else: + # If otherwise the property is not allowed: + properties: + foo-supply: false # Altering schema depending on presence of properties is usually done by # dependencies (see above), however some adjustments might require if: - if: From 10d7e312497f13419e1f99d903961c7ec0739da3 Mon Sep 17 00:00:00 2001 From: Robin Murphy Date: Thu, 17 Feb 2022 17:47:14 +0000 Subject: [PATCH 185/370] dt-bindings: reserved-memory: Add restricted-dma-pool constraints The "restricted-dma-pool" definition prohibits combination with either of the "no-map" and "reusable" properties, but this is only stated in the description text. Add those constraints to the schema so we can properly validate them. Signed-off-by: Robin Murphy Acked-by: Florian Fainelli Signed-off-by: Rob Herring Link: https://lore.kernel.org/r/a4f3d4e2feef008d1236ebc3f5f0c46360f20c60.1645119806.git.robin.murphy@arm.com --- .../bindings/reserved-memory/shared-dma-pool.yaml | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/Documentation/devicetree/bindings/reserved-memory/shared-dma-pool.yaml b/Documentation/devicetree/bindings/reserved-memory/shared-dma-pool.yaml index a4bf757d6881..618105f079be 100644 --- a/Documentation/devicetree/bindings/reserved-memory/shared-dma-pool.yaml +++ b/Documentation/devicetree/bindings/reserved-memory/shared-dma-pool.yaml @@ -56,6 +56,16 @@ properties: If this property is present, then Linux will use the region for the default pool of the consistent DMA allocator. +if: + properties: + compatible: + contains: + const: restricted-dma-pool +then: + properties: + no-map: false + reusable: false + unevaluatedProperties: false examples: From 2394770bd6bb6639f5d571d7b7ac08dc7660bca1 Mon Sep 17 00:00:00 2001 From: Michael Walle Date: Wed, 23 Feb 2022 14:43:27 +0100 Subject: [PATCH 186/370] mtd: spi-nor: atmel: unify function names To avoid name clashes unify all the function and static object names and use one of the following prefixes which should be sufficiently unique: - _nor_ - _nor_ - _ There are no functional changes. Signed-off-by: Michael Walle Signed-off-by: Tudor Ambarus Acked-by: Pratyush Yadav Link: https://lore.kernel.org/r/20220223134358.1914798-2-michael@walle.cc --- drivers/mtd/spi-nor/atmel.c | 81 +++++++++++++++++++------------------ 1 file changed, 42 insertions(+), 39 deletions(-) diff --git a/drivers/mtd/spi-nor/atmel.c b/drivers/mtd/spi-nor/atmel.c index d6d889ce8876..656dd80a0be7 100644 --- a/drivers/mtd/spi-nor/atmel.c +++ b/drivers/mtd/spi-nor/atmel.c @@ -16,12 +16,12 @@ * is to unlock the whole flash array on startup. Therefore, we have to support * exactly this operation. */ -static int atmel_at25fs_lock(struct spi_nor *nor, loff_t ofs, uint64_t len) +static int at25fs_nor_lock(struct spi_nor *nor, loff_t ofs, uint64_t len) { return -EOPNOTSUPP; } -static int atmel_at25fs_unlock(struct spi_nor *nor, loff_t ofs, uint64_t len) +static int at25fs_nor_unlock(struct spi_nor *nor, loff_t ofs, uint64_t len) { int ret; @@ -37,28 +37,28 @@ static int atmel_at25fs_unlock(struct spi_nor *nor, loff_t ofs, uint64_t len) return ret; } -static int atmel_at25fs_is_locked(struct spi_nor *nor, loff_t ofs, uint64_t len) +static int at25fs_nor_is_locked(struct spi_nor *nor, loff_t ofs, uint64_t len) { return -EOPNOTSUPP; } -static const struct spi_nor_locking_ops atmel_at25fs_locking_ops = { - .lock = atmel_at25fs_lock, - .unlock = atmel_at25fs_unlock, - .is_locked = atmel_at25fs_is_locked, +static const struct spi_nor_locking_ops at25fs_nor_locking_ops = { + .lock = at25fs_nor_lock, + .unlock = at25fs_nor_unlock, + .is_locked = at25fs_nor_is_locked, }; -static void atmel_at25fs_late_init(struct spi_nor *nor) +static void at25fs_nor_late_init(struct spi_nor *nor) { - nor->params->locking_ops = &atmel_at25fs_locking_ops; + nor->params->locking_ops = &at25fs_nor_locking_ops; } -static const struct spi_nor_fixups atmel_at25fs_fixups = { - .late_init = atmel_at25fs_late_init, +static const struct spi_nor_fixups at25fs_nor_fixups = { + .late_init = at25fs_nor_late_init, }; /** - * atmel_set_global_protection - Do a Global Protect or Unprotect command + * atmel_nor_set_global_protection - Do a Global Protect or Unprotect command * @nor: pointer to 'struct spi_nor' * @ofs: offset in bytes * @len: len in bytes @@ -66,8 +66,8 @@ static const struct spi_nor_fixups atmel_at25fs_fixups = { * * Return: 0 on success, -error otherwise. */ -static int atmel_set_global_protection(struct spi_nor *nor, loff_t ofs, - uint64_t len, bool is_protect) +static int atmel_nor_set_global_protection(struct spi_nor *nor, loff_t ofs, + uint64_t len, bool is_protect) { int ret; u8 sr; @@ -116,17 +116,20 @@ static int atmel_set_global_protection(struct spi_nor *nor, loff_t ofs, return spi_nor_write_sr(nor, nor->bouncebuf, 1); } -static int atmel_global_protect(struct spi_nor *nor, loff_t ofs, uint64_t len) +static int atmel_nor_global_protect(struct spi_nor *nor, loff_t ofs, + uint64_t len) { - return atmel_set_global_protection(nor, ofs, len, true); + return atmel_nor_set_global_protection(nor, ofs, len, true); } -static int atmel_global_unprotect(struct spi_nor *nor, loff_t ofs, uint64_t len) +static int atmel_nor_global_unprotect(struct spi_nor *nor, loff_t ofs, + uint64_t len) { - return atmel_set_global_protection(nor, ofs, len, false); + return atmel_nor_set_global_protection(nor, ofs, len, false); } -static int atmel_is_global_protected(struct spi_nor *nor, loff_t ofs, uint64_t len) +static int atmel_nor_is_global_protected(struct spi_nor *nor, loff_t ofs, + uint64_t len) { int ret; @@ -140,47 +143,47 @@ static int atmel_is_global_protected(struct spi_nor *nor, loff_t ofs, uint64_t l return ((nor->bouncebuf[0] & ATMEL_SR_GLOBAL_PROTECT_MASK) == ATMEL_SR_GLOBAL_PROTECT_MASK); } -static const struct spi_nor_locking_ops atmel_global_protection_ops = { - .lock = atmel_global_protect, - .unlock = atmel_global_unprotect, - .is_locked = atmel_is_global_protected, +static const struct spi_nor_locking_ops atmel_nor_global_protection_ops = { + .lock = atmel_nor_global_protect, + .unlock = atmel_nor_global_unprotect, + .is_locked = atmel_nor_is_global_protected, }; -static void atmel_global_protection_late_init(struct spi_nor *nor) +static void atmel_nor_global_protection_late_init(struct spi_nor *nor) { - nor->params->locking_ops = &atmel_global_protection_ops; + nor->params->locking_ops = &atmel_nor_global_protection_ops; } -static const struct spi_nor_fixups atmel_global_protection_fixups = { - .late_init = atmel_global_protection_late_init, +static const struct spi_nor_fixups atmel_nor_global_protection_fixups = { + .late_init = atmel_nor_global_protection_late_init, }; -static const struct flash_info atmel_parts[] = { +static const struct flash_info atmel_nor_parts[] = { /* Atmel -- some are (confusingly) marketed as "DataFlash" */ { "at25fs010", INFO(0x1f6601, 0, 32 * 1024, 4) FLAGS(SPI_NOR_HAS_LOCK) NO_SFDP_FLAGS(SECT_4K) - .fixups = &atmel_at25fs_fixups }, + .fixups = &at25fs_nor_fixups }, { "at25fs040", INFO(0x1f6604, 0, 64 * 1024, 8) FLAGS(SPI_NOR_HAS_LOCK) NO_SFDP_FLAGS(SECT_4K) - .fixups = &atmel_at25fs_fixups }, + .fixups = &at25fs_nor_fixups }, { "at25df041a", INFO(0x1f4401, 0, 64 * 1024, 8) FLAGS(SPI_NOR_HAS_LOCK | SPI_NOR_SWP_IS_VOLATILE) NO_SFDP_FLAGS(SECT_4K) - .fixups = &atmel_global_protection_fixups }, + .fixups = &atmel_nor_global_protection_fixups }, { "at25df321", INFO(0x1f4700, 0, 64 * 1024, 64) FLAGS(SPI_NOR_HAS_LOCK | SPI_NOR_SWP_IS_VOLATILE) NO_SFDP_FLAGS(SECT_4K) - .fixups = &atmel_global_protection_fixups }, + .fixups = &atmel_nor_global_protection_fixups }, { "at25df321a", INFO(0x1f4701, 0, 64 * 1024, 64) FLAGS(SPI_NOR_HAS_LOCK | SPI_NOR_SWP_IS_VOLATILE) NO_SFDP_FLAGS(SECT_4K) - .fixups = &atmel_global_protection_fixups }, + .fixups = &atmel_nor_global_protection_fixups }, { "at25df641", INFO(0x1f4800, 0, 64 * 1024, 128) FLAGS(SPI_NOR_HAS_LOCK | SPI_NOR_SWP_IS_VOLATILE) NO_SFDP_FLAGS(SECT_4K) - .fixups = &atmel_global_protection_fixups }, + .fixups = &atmel_nor_global_protection_fixups }, { "at25sl321", INFO(0x1f4216, 0, 64 * 1024, 64) NO_SFDP_FLAGS(SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, { "at26f004", INFO(0x1f0400, 0, 64 * 1024, 8) @@ -188,21 +191,21 @@ static const struct flash_info atmel_parts[] = { { "at26df081a", INFO(0x1f4501, 0, 64 * 1024, 16) FLAGS(SPI_NOR_HAS_LOCK | SPI_NOR_SWP_IS_VOLATILE) NO_SFDP_FLAGS(SECT_4K) - .fixups = &atmel_global_protection_fixups }, + .fixups = &atmel_nor_global_protection_fixups }, { "at26df161a", INFO(0x1f4601, 0, 64 * 1024, 32) FLAGS(SPI_NOR_HAS_LOCK | SPI_NOR_SWP_IS_VOLATILE) NO_SFDP_FLAGS(SECT_4K) - .fixups = &atmel_global_protection_fixups }, + .fixups = &atmel_nor_global_protection_fixups }, { "at26df321", INFO(0x1f4700, 0, 64 * 1024, 64) FLAGS(SPI_NOR_HAS_LOCK | SPI_NOR_SWP_IS_VOLATILE) NO_SFDP_FLAGS(SECT_4K) - .fixups = &atmel_global_protection_fixups }, + .fixups = &atmel_nor_global_protection_fixups }, { "at45db081d", INFO(0x1f2500, 0, 64 * 1024, 16) NO_SFDP_FLAGS(SECT_4K) }, }; const struct spi_nor_manufacturer spi_nor_atmel = { .name = "atmel", - .parts = atmel_parts, - .nparts = ARRAY_SIZE(atmel_parts), + .parts = atmel_nor_parts, + .nparts = ARRAY_SIZE(atmel_nor_parts), }; From 9eb916e2523e65381e15bd12ef9b182dcbd8ca67 Mon Sep 17 00:00:00 2001 From: Michael Walle Date: Wed, 23 Feb 2022 14:43:28 +0100 Subject: [PATCH 187/370] mtd: spi-nor: catalyst: unify function names To avoid name clashes unify all the function and static object names and use one of the following prefixes which should be sufficiently unique: - _nor_ - _nor_ - _ There are no functional changes. Signed-off-by: Michael Walle Signed-off-by: Tudor Ambarus Acked-by: Pratyush Yadav Link: https://lore.kernel.org/r/20220223134358.1914798-3-michael@walle.cc --- drivers/mtd/spi-nor/catalyst.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/mtd/spi-nor/catalyst.c b/drivers/mtd/spi-nor/catalyst.c index ae4d67e01bb3..6d310815fb12 100644 --- a/drivers/mtd/spi-nor/catalyst.c +++ b/drivers/mtd/spi-nor/catalyst.c @@ -8,7 +8,7 @@ #include "core.h" -static const struct flash_info catalyst_parts[] = { +static const struct flash_info catalyst_nor_parts[] = { /* Catalyst / On Semiconductor -- non-JEDEC */ { "cat25c11", CAT25_INFO(16, 8, 16, 1) }, { "cat25c03", CAT25_INFO(32, 8, 16, 2) }, @@ -19,6 +19,6 @@ static const struct flash_info catalyst_parts[] = { const struct spi_nor_manufacturer spi_nor_catalyst = { .name = "catalyst", - .parts = catalyst_parts, - .nparts = ARRAY_SIZE(catalyst_parts), + .parts = catalyst_nor_parts, + .nparts = ARRAY_SIZE(catalyst_nor_parts), }; From f5e7bd2768d7a43bbe7305fa348110d61564b527 Mon Sep 17 00:00:00 2001 From: Michael Walle Date: Wed, 23 Feb 2022 14:43:29 +0100 Subject: [PATCH 188/370] mtd: spi-nor: eon: unify function names To avoid name clashes unify all the function and static object names and use one of the following prefixes which should be sufficiently unique: - _nor_ - _nor_ - _ There are no functional changes. Signed-off-by: Michael Walle Signed-off-by: Tudor Ambarus Acked-by: Pratyush Yadav Link: https://lore.kernel.org/r/20220223134358.1914798-4-michael@walle.cc --- drivers/mtd/spi-nor/eon.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/mtd/spi-nor/eon.c b/drivers/mtd/spi-nor/eon.c index 4f3ee6331f37..8c1c57530281 100644 --- a/drivers/mtd/spi-nor/eon.c +++ b/drivers/mtd/spi-nor/eon.c @@ -8,7 +8,7 @@ #include "core.h" -static const struct flash_info eon_parts[] = { +static const struct flash_info eon_nor_parts[] = { /* EON -- en25xxx */ { "en25f32", INFO(0x1c3116, 0, 64 * 1024, 64) NO_SFDP_FLAGS(SECT_4K) }, @@ -32,6 +32,6 @@ static const struct flash_info eon_parts[] = { const struct spi_nor_manufacturer spi_nor_eon = { .name = "eon", - .parts = eon_parts, - .nparts = ARRAY_SIZE(eon_parts), + .parts = eon_nor_parts, + .nparts = ARRAY_SIZE(eon_nor_parts), }; From a7a3f09024b6a4d974ca6e8408b1bdee038584a6 Mon Sep 17 00:00:00 2001 From: Michael Walle Date: Wed, 23 Feb 2022 14:43:30 +0100 Subject: [PATCH 189/370] mtd: spi-nor: esmt: unify function names To avoid name clashes unify all the function and static object names and use one of the following prefixes which should be sufficiently unique: - _nor_ - _nor_ - _ There are no functional changes. Signed-off-by: Michael Walle Signed-off-by: Tudor Ambarus Acked-by: Pratyush Yadav Link: https://lore.kernel.org/r/20220223134358.1914798-5-michael@walle.cc --- drivers/mtd/spi-nor/esmt.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/mtd/spi-nor/esmt.c b/drivers/mtd/spi-nor/esmt.c index ace1da221566..79e2408f4998 100644 --- a/drivers/mtd/spi-nor/esmt.c +++ b/drivers/mtd/spi-nor/esmt.c @@ -8,7 +8,7 @@ #include "core.h" -static const struct flash_info esmt_parts[] = { +static const struct flash_info esmt_nor_parts[] = { /* ESMT */ { "f25l32pa", INFO(0x8c2016, 0, 64 * 1024, 64) FLAGS(SPI_NOR_HAS_LOCK | SPI_NOR_SWP_IS_VOLATILE) @@ -23,6 +23,6 @@ static const struct flash_info esmt_parts[] = { const struct spi_nor_manufacturer spi_nor_esmt = { .name = "esmt", - .parts = esmt_parts, - .nparts = ARRAY_SIZE(esmt_parts), + .parts = esmt_nor_parts, + .nparts = ARRAY_SIZE(esmt_nor_parts), }; From 09ae8354c31d184b4dd8c66cbee49decb2dcc439 Mon Sep 17 00:00:00 2001 From: Michael Walle Date: Wed, 23 Feb 2022 14:43:31 +0100 Subject: [PATCH 190/370] mtd: spi-nor: everspin: unify function names To avoid name clashes unify all the function and static object names and use one of the following prefixes which should be sufficiently unique: - _nor_ - _nor_ - _ There are no functional changes. Signed-off-by: Michael Walle Signed-off-by: Tudor Ambarus Acked-by: Pratyush Yadav Link: https://lore.kernel.org/r/20220223134358.1914798-6-michael@walle.cc --- drivers/mtd/spi-nor/everspin.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/mtd/spi-nor/everspin.c b/drivers/mtd/spi-nor/everspin.c index f6c6fb36a428..84a07c2e0536 100644 --- a/drivers/mtd/spi-nor/everspin.c +++ b/drivers/mtd/spi-nor/everspin.c @@ -8,7 +8,7 @@ #include "core.h" -static const struct flash_info everspin_parts[] = { +static const struct flash_info everspin_nor_parts[] = { /* Everspin */ { "mr25h128", CAT25_INFO(16 * 1024, 1, 256, 2) }, { "mr25h256", CAT25_INFO(32 * 1024, 1, 256, 2) }, @@ -18,6 +18,6 @@ static const struct flash_info everspin_parts[] = { const struct spi_nor_manufacturer spi_nor_everspin = { .name = "everspin", - .parts = everspin_parts, - .nparts = ARRAY_SIZE(everspin_parts), + .parts = everspin_nor_parts, + .nparts = ARRAY_SIZE(everspin_nor_parts), }; From 5410151931fa83b7c2199810ff93111f89813f4d Mon Sep 17 00:00:00 2001 From: Michael Walle Date: Wed, 23 Feb 2022 14:43:32 +0100 Subject: [PATCH 191/370] mtd: spi-nor: fujitsu: unify function names To avoid name clashes unify all the function and static object names and use one of the following prefixes which should be sufficiently unique: - _nor_ - _nor_ - _ There are no functional changes. Signed-off-by: Michael Walle Signed-off-by: Tudor Ambarus Acked-by: Pratyush Yadav Link: https://lore.kernel.org/r/20220223134358.1914798-7-michael@walle.cc --- drivers/mtd/spi-nor/fujitsu.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/mtd/spi-nor/fujitsu.c b/drivers/mtd/spi-nor/fujitsu.c index 5fa8f04f2e35..69cffc5c73ef 100644 --- a/drivers/mtd/spi-nor/fujitsu.c +++ b/drivers/mtd/spi-nor/fujitsu.c @@ -8,7 +8,7 @@ #include "core.h" -static const struct flash_info fujitsu_parts[] = { +static const struct flash_info fujitsu_nor_parts[] = { /* Fujitsu */ { "mb85rs1mt", INFO(0x047f27, 0, 128 * 1024, 1) FLAGS(SPI_NOR_NO_ERASE) }, @@ -16,6 +16,6 @@ static const struct flash_info fujitsu_parts[] = { const struct spi_nor_manufacturer spi_nor_fujitsu = { .name = "fujitsu", - .parts = fujitsu_parts, - .nparts = ARRAY_SIZE(fujitsu_parts), + .parts = fujitsu_nor_parts, + .nparts = ARRAY_SIZE(fujitsu_nor_parts), }; From 0ab828613c5af6c8562961c8ed07781aea7caa5d Mon Sep 17 00:00:00 2001 From: Michael Walle Date: Wed, 23 Feb 2022 14:43:33 +0100 Subject: [PATCH 192/370] mtd: spi-nor: gigadevice: unify function names To avoid name clashes unify all the function and static object names and use one of the following prefixes which should be sufficiently unique: - _nor_ - _nor_ - _ There are no functional changes. Signed-off-by: Michael Walle Signed-off-by: Tudor Ambarus Acked-by: Pratyush Yadav Link: https://lore.kernel.org/r/20220223134358.1914798-8-michael@walle.cc --- drivers/mtd/spi-nor/gigadevice.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/mtd/spi-nor/gigadevice.c b/drivers/mtd/spi-nor/gigadevice.c index 0807d0263808..119b38e6fc2a 100644 --- a/drivers/mtd/spi-nor/gigadevice.c +++ b/drivers/mtd/spi-nor/gigadevice.c @@ -23,7 +23,7 @@ static const struct spi_nor_fixups gd25q256_fixups = { .default_init = gd25q256_default_init, }; -static const struct flash_info gigadevice_parts[] = { +static const struct flash_info gigadevice_nor_parts[] = { { "gd25q16", INFO(0xc84015, 0, 64 * 1024, 32) FLAGS(SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB) NO_SFDP_FLAGS(SECT_4K | SPI_NOR_DUAL_READ | @@ -61,6 +61,6 @@ static const struct flash_info gigadevice_parts[] = { const struct spi_nor_manufacturer spi_nor_gigadevice = { .name = "gigadevice", - .parts = gigadevice_parts, - .nparts = ARRAY_SIZE(gigadevice_parts), + .parts = gigadevice_nor_parts, + .nparts = ARRAY_SIZE(gigadevice_nor_parts), }; From 536437aabb7a55c60c28c7a753a9e2d875757938 Mon Sep 17 00:00:00 2001 From: Michael Walle Date: Wed, 23 Feb 2022 14:43:34 +0100 Subject: [PATCH 193/370] mtd: spi-nor: intel: unify function names To avoid name clashes unify all the function and static object names and use one of the following prefixes which should be sufficiently unique: - _nor_ - _nor_ - _ There are no functional changes. Signed-off-by: Michael Walle Signed-off-by: Tudor Ambarus Acked-by: Pratyush Yadav Link: https://lore.kernel.org/r/20220223134358.1914798-9-michael@walle.cc --- drivers/mtd/spi-nor/intel.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/mtd/spi-nor/intel.c b/drivers/mtd/spi-nor/intel.c index d64e114e9fb4..9179f2d09cba 100644 --- a/drivers/mtd/spi-nor/intel.c +++ b/drivers/mtd/spi-nor/intel.c @@ -8,7 +8,7 @@ #include "core.h" -static const struct flash_info intel_parts[] = { +static const struct flash_info intel_nor_parts[] = { /* Intel/Numonyx -- xxxs33b */ { "160s33b", INFO(0x898911, 0, 64 * 1024, 32) FLAGS(SPI_NOR_HAS_LOCK | SPI_NOR_SWP_IS_VOLATILE) }, @@ -20,6 +20,6 @@ static const struct flash_info intel_parts[] = { const struct spi_nor_manufacturer spi_nor_intel = { .name = "intel", - .parts = intel_parts, - .nparts = ARRAY_SIZE(intel_parts), + .parts = intel_nor_parts, + .nparts = ARRAY_SIZE(intel_nor_parts), }; From cc5af02f6008409b453e21ad6911047b84da6dc3 Mon Sep 17 00:00:00 2001 From: Michael Walle Date: Wed, 23 Feb 2022 14:43:35 +0100 Subject: [PATCH 194/370] mtd: spi-nor: issi: unify function names To avoid name clashes unify all the function and static object names and use one of the following prefixes which should be sufficiently unique: - _nor_ - _nor_ - _ There are no functional changes. Signed-off-by: Michael Walle Signed-off-by: Tudor Ambarus Acked-by: Pratyush Yadav Link: https://lore.kernel.org/r/20220223134358.1914798-10-michael@walle.cc --- drivers/mtd/spi-nor/issi.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/mtd/spi-nor/issi.c b/drivers/mtd/spi-nor/issi.c index 23629b919ade..c012bc2486e1 100644 --- a/drivers/mtd/spi-nor/issi.c +++ b/drivers/mtd/spi-nor/issi.c @@ -29,7 +29,7 @@ static const struct spi_nor_fixups is25lp256_fixups = { .post_bfpt = is25lp256_post_bfpt_fixups, }; -static const struct flash_info issi_parts[] = { +static const struct flash_info issi_nor_parts[] = { /* ISSI */ { "is25cd512", INFO(0x7f9d20, 0, 32 * 1024, 2) NO_SFDP_FLAGS(SECT_4K) }, @@ -69,18 +69,18 @@ static const struct flash_info issi_parts[] = { NO_SFDP_FLAGS(SECT_4K) }, }; -static void issi_default_init(struct spi_nor *nor) +static void issi_nor_default_init(struct spi_nor *nor) { nor->params->quad_enable = spi_nor_sr1_bit6_quad_enable; } static const struct spi_nor_fixups issi_fixups = { - .default_init = issi_default_init, + .default_init = issi_nor_default_init, }; const struct spi_nor_manufacturer spi_nor_issi = { .name = "issi", - .parts = issi_parts, - .nparts = ARRAY_SIZE(issi_parts), + .parts = issi_nor_parts, + .nparts = ARRAY_SIZE(issi_nor_parts), .fixups = &issi_fixups, }; From 0757201a1daae58e9cd6b9ac3ca5c9e6ddbcf5b8 Mon Sep 17 00:00:00 2001 From: Michael Walle Date: Wed, 23 Feb 2022 14:43:36 +0100 Subject: [PATCH 195/370] mtd: spi-nor: macronix: unify function names To avoid name clashes unify all the function and static object names and use one of the following prefixes which should be sufficiently unique: - _nor_ - _nor_ - _ There are no functional changes. Signed-off-by: Michael Walle Signed-off-by: Tudor Ambarus Acked-by: Pratyush Yadav Link: https://lore.kernel.org/r/20220223134358.1914798-11-michael@walle.cc --- drivers/mtd/spi-nor/macronix.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/drivers/mtd/spi-nor/macronix.c b/drivers/mtd/spi-nor/macronix.c index 97dba1ae7fb1..d81a4cb2812b 100644 --- a/drivers/mtd/spi-nor/macronix.c +++ b/drivers/mtd/spi-nor/macronix.c @@ -32,7 +32,7 @@ static const struct spi_nor_fixups mx25l25635_fixups = { .post_bfpt = mx25l25635_post_bfpt_fixups, }; -static const struct flash_info macronix_parts[] = { +static const struct flash_info macronix_nor_parts[] = { /* Macronix */ { "mx25l512e", INFO(0xc22010, 0, 64 * 1024, 1) NO_SFDP_FLAGS(SECT_4K) }, @@ -102,19 +102,19 @@ static const struct flash_info macronix_parts[] = { FIXUP_FLAGS(SPI_NOR_4B_OPCODES) }, }; -static void macronix_default_init(struct spi_nor *nor) +static void macronix_nor_default_init(struct spi_nor *nor) { nor->params->quad_enable = spi_nor_sr1_bit6_quad_enable; nor->params->set_4byte_addr_mode = spi_nor_set_4byte_addr_mode; } -static const struct spi_nor_fixups macronix_fixups = { - .default_init = macronix_default_init, +static const struct spi_nor_fixups macronix_nor_fixups = { + .default_init = macronix_nor_default_init, }; const struct spi_nor_manufacturer spi_nor_macronix = { .name = "macronix", - .parts = macronix_parts, - .nparts = ARRAY_SIZE(macronix_parts), - .fixups = ¯onix_fixups, + .parts = macronix_nor_parts, + .nparts = ARRAY_SIZE(macronix_nor_parts), + .fixups = ¯onix_nor_fixups, }; From c9d5cdf4bf9cd4e0e96f8e2ead053869df9e2459 Mon Sep 17 00:00:00 2001 From: Michael Walle Date: Wed, 23 Feb 2022 14:43:37 +0100 Subject: [PATCH 196/370] mtd: spi-nor: micron-st: unify function names To avoid name clashes unify all the function and static object names and use one of the following prefixes which should be sufficiently unique: - _nor_ - _nor_ - _ There are no functional changes. Signed-off-by: Michael Walle Signed-off-by: Tudor Ambarus Acked-by: Pratyush Yadav Link: https://lore.kernel.org/r/20220223134358.1914798-12-michael@walle.cc --- drivers/mtd/spi-nor/micron-st.c | 34 ++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/drivers/mtd/spi-nor/micron-st.c b/drivers/mtd/spi-nor/micron-st.c index bb95b1aabf74..7a68f2ad3ea1 100644 --- a/drivers/mtd/spi-nor/micron-st.c +++ b/drivers/mtd/spi-nor/micron-st.c @@ -17,7 +17,7 @@ #define SPINOR_MT_OCT_DTR 0xe7 /* Enable Octal DTR. */ #define SPINOR_MT_EXSPI 0xff /* Enable Extended SPI (default) */ -static int spi_nor_micron_octal_dtr_enable(struct spi_nor *nor, bool enable) +static int micron_st_nor_octal_dtr_enable(struct spi_nor *nor, bool enable) { struct spi_mem_op op; u8 *buf = nor->bouncebuf; @@ -102,7 +102,7 @@ static int spi_nor_micron_octal_dtr_enable(struct spi_nor *nor, bool enable) static void mt35xu512aba_default_init(struct spi_nor *nor) { - nor->params->octal_dtr_enable = spi_nor_micron_octal_dtr_enable; + nor->params->octal_dtr_enable = micron_st_nor_octal_dtr_enable; } static void mt35xu512aba_post_sfdp_fixup(struct spi_nor *nor) @@ -130,7 +130,7 @@ static const struct spi_nor_fixups mt35xu512aba_fixups = { .post_sfdp = mt35xu512aba_post_sfdp_fixup, }; -static const struct flash_info micron_parts[] = { +static const struct flash_info micron_nor_parts[] = { { "mt35xu512aba", INFO(0x2c5b1a, 0, 128 * 1024, 512) FLAGS(USE_FSR) NO_SFDP_FLAGS(SECT_4K | SPI_NOR_OCTAL_READ | @@ -143,7 +143,7 @@ static const struct flash_info micron_parts[] = { FIXUP_FLAGS(SPI_NOR_4B_OPCODES) }, }; -static const struct flash_info st_parts[] = { +static const struct flash_info st_nor_parts[] = { { "n25q016a", INFO(0x20bb15, 0, 64 * 1024, 32) NO_SFDP_FLAGS(SECT_4K | SPI_NOR_QUAD_READ) }, { "n25q032", INFO(0x20ba16, 0, 64 * 1024, 64) @@ -250,15 +250,15 @@ static const struct flash_info st_parts[] = { }; /** - * st_micron_set_4byte_addr_mode() - Set 4-byte address mode for ST and Micron - * flashes. + * micron_st_nor_set_4byte_addr_mode() - Set 4-byte address mode for ST and + * Micron flashes. * @nor: pointer to 'struct spi_nor'. * @enable: true to enter the 4-byte address mode, false to exit the 4-byte * address mode. * * Return: 0 on success, -errno otherwise. */ -static int st_micron_set_4byte_addr_mode(struct spi_nor *nor, bool enable) +static int micron_st_nor_set_4byte_addr_mode(struct spi_nor *nor, bool enable) { int ret; @@ -273,28 +273,28 @@ static int st_micron_set_4byte_addr_mode(struct spi_nor *nor, bool enable) return spi_nor_write_disable(nor); } -static void micron_st_default_init(struct spi_nor *nor) +static void micron_st_nor_default_init(struct spi_nor *nor) { nor->flags |= SNOR_F_HAS_LOCK; nor->flags &= ~SNOR_F_HAS_16BIT_SR; nor->params->quad_enable = NULL; - nor->params->set_4byte_addr_mode = st_micron_set_4byte_addr_mode; + nor->params->set_4byte_addr_mode = micron_st_nor_set_4byte_addr_mode; } -static const struct spi_nor_fixups micron_st_fixups = { - .default_init = micron_st_default_init, +static const struct spi_nor_fixups micron_st_nor_fixups = { + .default_init = micron_st_nor_default_init, }; const struct spi_nor_manufacturer spi_nor_micron = { .name = "micron", - .parts = micron_parts, - .nparts = ARRAY_SIZE(micron_parts), - .fixups = µn_st_fixups, + .parts = micron_nor_parts, + .nparts = ARRAY_SIZE(micron_nor_parts), + .fixups = µn_st_nor_fixups, }; const struct spi_nor_manufacturer spi_nor_st = { .name = "st", - .parts = st_parts, - .nparts = ARRAY_SIZE(st_parts), - .fixups = µn_st_fixups, + .parts = st_nor_parts, + .nparts = ARRAY_SIZE(st_nor_parts), + .fixups = µn_st_nor_fixups, }; From fedd0cbf3e932cf4659957a7038a0f9a81028900 Mon Sep 17 00:00:00 2001 From: Michael Walle Date: Wed, 23 Feb 2022 14:43:38 +0100 Subject: [PATCH 197/370] mtd: spi-nor: spansion: unify function names To avoid name clashes unify all the function and static object names and use one of the following prefixes which should be sufficiently unique: - _nor_ - _nor_ - _ There are no functional changes. Signed-off-by: Michael Walle Signed-off-by: Tudor Ambarus Acked-by: Pratyush Yadav Link: https://lore.kernel.org/r/20220223134358.1914798-13-michael@walle.cc --- drivers/mtd/spi-nor/spansion.c | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/drivers/mtd/spi-nor/spansion.c b/drivers/mtd/spi-nor/spansion.c index 534196b1d3e7..5affa8ae43a7 100644 --- a/drivers/mtd/spi-nor/spansion.c +++ b/drivers/mtd/spi-nor/spansion.c @@ -20,7 +20,7 @@ #define SPINOR_OP_CYPRESS_RD_FAST 0xee /** - * spi_nor_cypress_octal_dtr_enable() - Enable octal DTR on Cypress flashes. + * cypress_nor_octal_dtr_enable() - Enable octal DTR on Cypress flashes. * @nor: pointer to a 'struct spi_nor' * @enable: whether to enable or disable Octal DTR * @@ -29,7 +29,7 @@ * * Return: 0 on success, -errno otherwise. */ -static int spi_nor_cypress_octal_dtr_enable(struct spi_nor *nor, bool enable) +static int cypress_nor_octal_dtr_enable(struct spi_nor *nor, bool enable) { struct spi_mem_op op; u8 *buf = nor->bouncebuf; @@ -116,7 +116,7 @@ static int spi_nor_cypress_octal_dtr_enable(struct spi_nor *nor, bool enable) static void s28hs512t_default_init(struct spi_nor *nor) { - nor->params->octal_dtr_enable = spi_nor_cypress_octal_dtr_enable; + nor->params->octal_dtr_enable = cypress_nor_octal_dtr_enable; nor->params->writesize = 16; } @@ -183,9 +183,9 @@ static const struct spi_nor_fixups s28hs512t_fixups = { }; static int -s25fs_s_post_bfpt_fixups(struct spi_nor *nor, - const struct sfdp_parameter_header *bfpt_header, - const struct sfdp_bfpt *bfpt) +s25fs_s_nor_post_bfpt_fixups(struct spi_nor *nor, + const struct sfdp_parameter_header *bfpt_header, + const struct sfdp_bfpt *bfpt) { /* * The S25FS-S chip family reports 512-byte pages in BFPT but @@ -198,11 +198,11 @@ s25fs_s_post_bfpt_fixups(struct spi_nor *nor, return 0; } -static const struct spi_nor_fixups s25fs_s_fixups = { - .post_bfpt = s25fs_s_post_bfpt_fixups, +static const struct spi_nor_fixups s25fs_s_nor_fixups = { + .post_bfpt = s25fs_s_nor_post_bfpt_fixups, }; -static const struct flash_info spansion_parts[] = { +static const struct flash_info spansion_nor_parts[] = { /* Spansion/Cypress -- single (large) sector size only, at least * for the chips listed here (without boot sectors). */ @@ -229,7 +229,7 @@ static const struct flash_info spansion_parts[] = { { "s25fs128s1", INFO6(0x012018, 0x4d0181, 64 * 1024, 256) FLAGS(USE_CLSR) NO_SFDP_FLAGS(SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) - .fixups = &s25fs_s_fixups, }, + .fixups = &s25fs_s_nor_fixups, }, { "s25fs256s0", INFO6(0x010219, 0x4d0081, 256 * 1024, 128) FLAGS(USE_CLSR) NO_SFDP_FLAGS(SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, @@ -239,7 +239,7 @@ static const struct flash_info spansion_parts[] = { { "s25fs512s", INFO6(0x010220, 0x4d0081, 256 * 1024, 256) FLAGS(USE_CLSR) NO_SFDP_FLAGS(SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) - .fixups = &s25fs_s_fixups, }, + .fixups = &s25fs_s_nor_fixups, }, { "s25sl12800", INFO(0x012018, 0x0300, 256 * 1024, 64) }, { "s25sl12801", INFO(0x012018, 0x0301, 64 * 1024, 256) }, { "s25fl129p0", INFO(0x012018, 0x4d00, 256 * 1024, 64) @@ -294,7 +294,7 @@ static const struct flash_info spansion_parts[] = { }, }; -static void spansion_late_init(struct spi_nor *nor) +static void spansion_nor_late_init(struct spi_nor *nor) { if (nor->params->size <= SZ_16M) return; @@ -305,13 +305,13 @@ static void spansion_late_init(struct spi_nor *nor) nor->mtd.erasesize = nor->info->sector_size; } -static const struct spi_nor_fixups spansion_fixups = { - .late_init = spansion_late_init, +static const struct spi_nor_fixups spansion_nor_fixups = { + .late_init = spansion_nor_late_init, }; const struct spi_nor_manufacturer spi_nor_spansion = { .name = "spansion", - .parts = spansion_parts, - .nparts = ARRAY_SIZE(spansion_parts), - .fixups = &spansion_fixups, + .parts = spansion_nor_parts, + .nparts = ARRAY_SIZE(spansion_nor_parts), + .fixups = &spansion_nor_fixups, }; From 7e5b38ae4f23487eeeff9dbcbea38f1e0c504522 Mon Sep 17 00:00:00 2001 From: Michael Walle Date: Wed, 23 Feb 2022 14:43:39 +0100 Subject: [PATCH 198/370] mtd: spi-nor: sst: unify function names To avoid name clashes unify all the function and static object names and use one of the following prefixes which should be sufficiently unique: - _nor_ - _nor_ - _ There are no functional changes. Signed-off-by: Michael Walle Signed-off-by: Tudor Ambarus Acked-by: Pratyush Yadav Link: https://lore.kernel.org/r/20220223134358.1914798-14-michael@walle.cc --- drivers/mtd/spi-nor/sst.c | 44 +++++++++++++++++++-------------------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/drivers/mtd/spi-nor/sst.c b/drivers/mtd/spi-nor/sst.c index 30183e9189b9..63bcc97bf978 100644 --- a/drivers/mtd/spi-nor/sst.c +++ b/drivers/mtd/spi-nor/sst.c @@ -13,12 +13,12 @@ #define SST26VF_CR_BPNV BIT(3) -static int sst26vf_lock(struct spi_nor *nor, loff_t ofs, uint64_t len) +static int sst26vf_nor_lock(struct spi_nor *nor, loff_t ofs, uint64_t len) { return -EOPNOTSUPP; } -static int sst26vf_unlock(struct spi_nor *nor, loff_t ofs, uint64_t len) +static int sst26vf_nor_unlock(struct spi_nor *nor, loff_t ofs, uint64_t len) { int ret; @@ -38,27 +38,27 @@ static int sst26vf_unlock(struct spi_nor *nor, loff_t ofs, uint64_t len) return spi_nor_global_block_unlock(nor); } -static int sst26vf_is_locked(struct spi_nor *nor, loff_t ofs, uint64_t len) +static int sst26vf_nor_is_locked(struct spi_nor *nor, loff_t ofs, uint64_t len) { return -EOPNOTSUPP; } -static const struct spi_nor_locking_ops sst26vf_locking_ops = { - .lock = sst26vf_lock, - .unlock = sst26vf_unlock, - .is_locked = sst26vf_is_locked, +static const struct spi_nor_locking_ops sst26vf_nor_locking_ops = { + .lock = sst26vf_nor_lock, + .unlock = sst26vf_nor_unlock, + .is_locked = sst26vf_nor_is_locked, }; -static void sst26vf_late_init(struct spi_nor *nor) +static void sst26vf_nor_late_init(struct spi_nor *nor) { - nor->params->locking_ops = &sst26vf_locking_ops; + nor->params->locking_ops = &sst26vf_nor_locking_ops; } -static const struct spi_nor_fixups sst26vf_fixups = { - .late_init = sst26vf_late_init, +static const struct spi_nor_fixups sst26vf_nor_fixups = { + .late_init = sst26vf_nor_late_init, }; -static const struct flash_info sst_parts[] = { +static const struct flash_info sst_nor_parts[] = { /* SST -- large erase sizes are "overlays", "sectors" are 4K */ { "sst25vf040b", INFO(0xbf258d, 0, 64 * 1024, 8) FLAGS(SPI_NOR_HAS_LOCK | SPI_NOR_SWP_IS_VOLATILE) @@ -114,11 +114,11 @@ static const struct flash_info sst_parts[] = { { "sst26vf064b", INFO(0xbf2643, 0, 64 * 1024, 128) FLAGS(SPI_NOR_HAS_LOCK | SPI_NOR_SWP_IS_VOLATILE) NO_SFDP_FLAGS(SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) - .fixups = &sst26vf_fixups }, + .fixups = &sst26vf_nor_fixups }, }; -static int sst_write(struct mtd_info *mtd, loff_t to, size_t len, - size_t *retlen, const u_char *buf) +static int sst_nor_write(struct mtd_info *mtd, loff_t to, size_t len, + size_t *retlen, const u_char *buf) { struct spi_nor *nor = mtd_to_spi_nor(mtd); size_t actual = 0; @@ -203,19 +203,19 @@ out: return ret; } -static void sst_late_init(struct spi_nor *nor) +static void sst_nor_late_init(struct spi_nor *nor) { if (nor->info->mfr_flags & SST_WRITE) - nor->mtd._write = sst_write; + nor->mtd._write = sst_nor_write; } -static const struct spi_nor_fixups sst_fixups = { - .late_init = sst_late_init, +static const struct spi_nor_fixups sst_nor_fixups = { + .late_init = sst_nor_late_init, }; const struct spi_nor_manufacturer spi_nor_sst = { .name = "sst", - .parts = sst_parts, - .nparts = ARRAY_SIZE(sst_parts), - .fixups = &sst_fixups, + .parts = sst_nor_parts, + .nparts = ARRAY_SIZE(sst_nor_parts), + .fixups = &sst_nor_fixups, }; From a7a0466f582f82a94d32273c287b35658484880a Mon Sep 17 00:00:00 2001 From: Michael Walle Date: Wed, 23 Feb 2022 14:43:40 +0100 Subject: [PATCH 199/370] mtd: spi-nor: winbond: unify function names To avoid name clashes unify all the function and static object names and use one of the following prefixes which should be sufficiently unique: - _nor_ - _nor_ - _ There are no functional changes. Signed-off-by: Michael Walle Signed-off-by: Tudor Ambarus Acked-by: Pratyush Yadav Link: https://lore.kernel.org/r/20220223134358.1914798-15-michael@walle.cc --- drivers/mtd/spi-nor/winbond.c | 29 +++++++++++++++-------------- 1 file changed, 15 insertions(+), 14 deletions(-) diff --git a/drivers/mtd/spi-nor/winbond.c b/drivers/mtd/spi-nor/winbond.c index 675f32c136b3..fe80dffc2e70 100644 --- a/drivers/mtd/spi-nor/winbond.c +++ b/drivers/mtd/spi-nor/winbond.c @@ -32,7 +32,7 @@ static const struct spi_nor_fixups w25q256_fixups = { .post_bfpt = w25q256_post_bfpt_fixups, }; -static const struct flash_info winbond_parts[] = { +static const struct flash_info winbond_nor_parts[] = { /* Winbond -- w25x "blocks" are 64K, "sectors" are 4KiB */ { "w25x05", INFO(0xef3010, 0, 64 * 1024, 1) NO_SFDP_FLAGS(SECT_4K) }, @@ -130,14 +130,15 @@ static const struct flash_info winbond_parts[] = { }; /** - * winbond_set_4byte_addr_mode() - Set 4-byte address mode for Winbond flashes. + * winbond_nor_set_4byte_addr_mode() - Set 4-byte address mode for Winbond + * flashes. * @nor: pointer to 'struct spi_nor'. * @enable: true to enter the 4-byte address mode, false to exit the 4-byte * address mode. * * Return: 0 on success, -errno otherwise. */ -static int winbond_set_4byte_addr_mode(struct spi_nor *nor, bool enable) +static int winbond_nor_set_4byte_addr_mode(struct spi_nor *nor, bool enable) { int ret; @@ -161,7 +162,7 @@ static int winbond_set_4byte_addr_mode(struct spi_nor *nor, bool enable) return spi_nor_write_disable(nor); } -static const struct spi_nor_otp_ops winbond_otp_ops = { +static const struct spi_nor_otp_ops winbond_nor_otp_ops = { .read = spi_nor_otp_read_secr, .write = spi_nor_otp_write_secr, .erase = spi_nor_otp_erase_secr, @@ -169,25 +170,25 @@ static const struct spi_nor_otp_ops winbond_otp_ops = { .is_locked = spi_nor_otp_is_locked_sr2, }; -static void winbond_default_init(struct spi_nor *nor) +static void winbond_nor_default_init(struct spi_nor *nor) { - nor->params->set_4byte_addr_mode = winbond_set_4byte_addr_mode; + nor->params->set_4byte_addr_mode = winbond_nor_set_4byte_addr_mode; } -static void winbond_late_init(struct spi_nor *nor) +static void winbond_nor_late_init(struct spi_nor *nor) { if (nor->params->otp.org->n_regions) - nor->params->otp.ops = &winbond_otp_ops; + nor->params->otp.ops = &winbond_nor_otp_ops; } -static const struct spi_nor_fixups winbond_fixups = { - .default_init = winbond_default_init, - .late_init = winbond_late_init, +static const struct spi_nor_fixups winbond_nor_fixups = { + .default_init = winbond_nor_default_init, + .late_init = winbond_nor_late_init, }; const struct spi_nor_manufacturer spi_nor_winbond = { .name = "winbond", - .parts = winbond_parts, - .nparts = ARRAY_SIZE(winbond_parts), - .fixups = &winbond_fixups, + .parts = winbond_nor_parts, + .nparts = ARRAY_SIZE(winbond_nor_parts), + .fixups = &winbond_nor_fixups, }; From 45acce2099c5984f09cbf549e97b1536322e4052 Mon Sep 17 00:00:00 2001 From: Michael Walle Date: Wed, 23 Feb 2022 14:43:41 +0100 Subject: [PATCH 200/370] mtd: spi-nor: xilinx: unify function names To avoid name clashes unify all the function and static object names and use one of the following prefixes which should be sufficiently unique: - _nor_ - _nor_ - _ There are no functional changes. Signed-off-by: Michael Walle Signed-off-by: Tudor Ambarus Acked-by: Pratyush Yadav Link: https://lore.kernel.org/r/20220223134358.1914798-16-michael@walle.cc --- drivers/mtd/spi-nor/xilinx.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/drivers/mtd/spi-nor/xilinx.c b/drivers/mtd/spi-nor/xilinx.c index 580562bc1e45..07dd11788df5 100644 --- a/drivers/mtd/spi-nor/xilinx.c +++ b/drivers/mtd/spi-nor/xilinx.c @@ -8,7 +8,7 @@ #include "core.h" -static const struct flash_info xilinx_parts[] = { +static const struct flash_info xilinx_nor_parts[] = { /* Xilinx S3AN Internal Flash */ { "3S50AN", S3AN_INFO(0x1f2200, 64, 264) }, { "3S200AN", S3AN_INFO(0x1f2400, 256, 264) }, @@ -26,7 +26,7 @@ static const struct flash_info xilinx_parts[] = { * Addr can safely be unsigned int, the biggest S3AN device is smaller than * 4 MiB. */ -static u32 s3an_convert_addr(struct spi_nor *nor, u32 addr) +static u32 s3an_nor_convert_addr(struct spi_nor *nor, u32 addr) { u32 page_size = nor->params->page_size; u32 offset, page; @@ -73,25 +73,25 @@ static int xilinx_nor_setup(struct spi_nor *nor, nor->mtd.erasesize = 8 * page_size; } else { /* Flash in Default addressing mode */ - nor->params->convert_addr = s3an_convert_addr; + nor->params->convert_addr = s3an_nor_convert_addr; nor->mtd.erasesize = nor->info->sector_size; } return 0; } -static void xilinx_late_init(struct spi_nor *nor) +static void xilinx_nor_late_init(struct spi_nor *nor) { nor->params->setup = xilinx_nor_setup; } -static const struct spi_nor_fixups xilinx_fixups = { - .late_init = xilinx_late_init, +static const struct spi_nor_fixups xilinx_nor_fixups = { + .late_init = xilinx_nor_late_init, }; const struct spi_nor_manufacturer spi_nor_xilinx = { .name = "xilinx", - .parts = xilinx_parts, - .nparts = ARRAY_SIZE(xilinx_parts), - .fixups = &xilinx_fixups, + .parts = xilinx_nor_parts, + .nparts = ARRAY_SIZE(xilinx_nor_parts), + .fixups = &xilinx_nor_fixups, }; From 232e2830f525a804fc852c3a6a1df69f252a4f23 Mon Sep 17 00:00:00 2001 From: Michael Walle Date: Wed, 23 Feb 2022 14:43:42 +0100 Subject: [PATCH 201/370] mtd: spi-nor: xmc: unify function names To avoid name clashes unify all the function and static object names and use one of the following prefixes which should be sufficiently unique: - _nor_ - _nor_ - _ There are no functional changes. Signed-off-by: Michael Walle Signed-off-by: Tudor Ambarus Acked-by: Pratyush Yadav Link: https://lore.kernel.org/r/20220223134358.1914798-17-michael@walle.cc --- drivers/mtd/spi-nor/xmc.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/mtd/spi-nor/xmc.c b/drivers/mtd/spi-nor/xmc.c index 2992af03cb0a..051411e86339 100644 --- a/drivers/mtd/spi-nor/xmc.c +++ b/drivers/mtd/spi-nor/xmc.c @@ -8,7 +8,7 @@ #include "core.h" -static const struct flash_info xmc_parts[] = { +static const struct flash_info xmc_nor_parts[] = { /* XMC (Wuhan Xinxin Semiconductor Manufacturing Corp.) */ { "XM25QH64A", INFO(0x207017, 0, 64 * 1024, 128) NO_SFDP_FLAGS(SECT_4K | SPI_NOR_DUAL_READ | @@ -20,6 +20,6 @@ static const struct flash_info xmc_parts[] = { const struct spi_nor_manufacturer spi_nor_xmc = { .name = "xmc", - .parts = xmc_parts, - .nparts = ARRAY_SIZE(xmc_parts), + .parts = xmc_nor_parts, + .nparts = ARRAY_SIZE(xmc_nor_parts), }; From 50b3a818991074177a56c87124c7a7bdf5fa4f67 Mon Sep 17 00:00:00 2001 From: Zhang Yi Date: Sat, 12 Feb 2022 13:05:32 +0800 Subject: [PATCH 202/370] ext2: correct max file size computing We need to calculate the max file size accurately if the total blocks that can address by block tree exceed the upper_limit. But this check is not correct now, it only compute the total data blocks but missing metadata blocks are needed. So in the case of "data blocks < upper_limit && total blocks > upper_limit", we will get wrong result. Fortunately, this case could not happen in reality, but it's confused and better to correct the computing. bits data blocks metadatablocks upper_limit 10 16843020 66051 2147483647 11 134480396 263171 1073741823 12 1074791436 1050627 536870911 (*) 13 8594130956 4198403 268435455 (*) 14 68736258060 16785411 134217727 (*) 15 549822930956 67125251 67108863 (*) 16 4398314962956 268468227 33554431 (*) [*] Need to calculate in depth. Fixes: 1c2d14212b15 ("ext2: Fix underflow in ext2_max_size()") Link: https://lore.kernel.org/r/20220212050532.179055-1-yi.zhang@huawei.com Signed-off-by: Zhang Yi Signed-off-by: Jan Kara --- fs/ext2/super.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/fs/ext2/super.c b/fs/ext2/super.c index 94f1fbd7d3ac..6d4f5ef74766 100644 --- a/fs/ext2/super.c +++ b/fs/ext2/super.c @@ -753,8 +753,12 @@ static loff_t ext2_max_size(int bits) res += 1LL << (bits-2); res += 1LL << (2*(bits-2)); res += 1LL << (3*(bits-2)); + /* Compute how many metadata blocks are needed */ + meta_blocks = 1; + meta_blocks += 1 + ppb; + meta_blocks += 1 + ppb + ppb * ppb; /* Does block tree limit file size? */ - if (res < upper_limit) + if (res + meta_blocks <= upper_limit) goto check_lfs; res = upper_limit; From b44aa9ac6bb4a305ceb2ed224781bc10abc03b12 Mon Sep 17 00:00:00 2001 From: Michael Walle Date: Wed, 23 Feb 2022 14:43:43 +0100 Subject: [PATCH 203/370] mtd: spi-nor: slightly refactor the spi_nor_setup() Instead of always using a function pointer (and initializing it to our default), just call the default function if the flash didn't set its own one. That will make the call flow easier to follow. Also mark the parameter as optional now. Signed-off-by: Michael Walle Signed-off-by: Tudor Ambarus Reviewed-by: Pratyush Yadav Link: https://lore.kernel.org/r/20220223134358.1914798-18-michael@walle.cc --- drivers/mtd/spi-nor/core.c | 10 +++++----- drivers/mtd/spi-nor/core.h | 8 ++++---- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/drivers/mtd/spi-nor/core.c b/drivers/mtd/spi-nor/core.c index 04ea180118e3..4d2036cdce42 100644 --- a/drivers/mtd/spi-nor/core.c +++ b/drivers/mtd/spi-nor/core.c @@ -2532,11 +2532,12 @@ static int spi_nor_setup(struct spi_nor *nor, { int ret; - if (nor->params->setup) { + if (nor->params->setup) ret = nor->params->setup(nor, hwcaps); - if (ret) - return ret; - } + else + ret = spi_nor_default_setup(nor, hwcaps); + if (ret) + return ret; return spi_nor_set_addr_width(nor); } @@ -2786,7 +2787,6 @@ static void spi_nor_init_default_params(struct spi_nor *nor) params->quad_enable = spi_nor_sr2_bit1_quad_enable; params->set_4byte_addr_mode = spansion_set_4byte_addr_mode; - params->setup = spi_nor_default_setup; params->otp.org = &info->otp_org; /* Default to 16-bit Write Status (01h) Command */ diff --git a/drivers/mtd/spi-nor/core.h b/drivers/mtd/spi-nor/core.h index 2afb610853a9..4fe16b5aa3f5 100644 --- a/drivers/mtd/spi-nor/core.h +++ b/drivers/mtd/spi-nor/core.h @@ -257,10 +257,10 @@ struct spi_nor_otp { * @convert_addr: converts an absolute address into something the flash * will understand. Particularly useful when pagesize is * not a power-of-2. - * @setup: configures the SPI NOR memory. Useful for SPI NOR - * flashes that have peculiarities to the SPI NOR standard - * e.g. different opcodes, specific address calculation, - * page size, etc. + * @setup: (optional) configures the SPI NOR memory. Useful for + * SPI NOR flashes that have peculiarities to the SPI NOR + * standard e.g. different opcodes, specific address + * calculation, page size, etc. * @locking_ops: SPI NOR locking methods. */ struct spi_nor_flash_parameter { From 4cf1c7bdc55c8af3a2fbc028e21918630d081f12 Mon Sep 17 00:00:00 2001 From: Michael Walle Date: Wed, 23 Feb 2022 14:43:44 +0100 Subject: [PATCH 204/370] mtd: spi-nor: allow a flash to define its own ready() function Xilinx and Micron flashes have their own implementation of the spi_nor_ready() function. At the moment, the core will figure out which one to call according to some flags. Lay the foundation to make it possible that a flash can register its own ready() function. Signed-off-by: Michael Walle Signed-off-by: Tudor Ambarus Reviewed-by: Pratyush Yadav Link: https://lore.kernel.org/r/20220223134358.1914798-19-michael@walle.cc --- drivers/mtd/spi-nor/core.c | 4 ++++ drivers/mtd/spi-nor/core.h | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/drivers/mtd/spi-nor/core.c b/drivers/mtd/spi-nor/core.c index 4d2036cdce42..390a9ab413b7 100644 --- a/drivers/mtd/spi-nor/core.c +++ b/drivers/mtd/spi-nor/core.c @@ -794,6 +794,10 @@ static int spi_nor_ready(struct spi_nor *nor) { int sr, fsr; + /* Flashes might override the standard routine. */ + if (nor->params->ready) + return nor->params->ready(nor); + if (nor->flags & SNOR_F_READY_XSR_RDY) sr = spi_nor_xsr_ready(nor); else diff --git a/drivers/mtd/spi-nor/core.h b/drivers/mtd/spi-nor/core.h index 4fe16b5aa3f5..fdc8c0f31f5c 100644 --- a/drivers/mtd/spi-nor/core.h +++ b/drivers/mtd/spi-nor/core.h @@ -261,6 +261,9 @@ struct spi_nor_otp { * SPI NOR flashes that have peculiarities to the SPI NOR * standard e.g. different opcodes, specific address * calculation, page size, etc. + * @ready: (optional) flashes might use a different mechanism + * than reading the status register to indicate they + * are ready for a new command * @locking_ops: SPI NOR locking methods. */ struct spi_nor_flash_parameter { @@ -282,6 +285,7 @@ struct spi_nor_flash_parameter { int (*set_4byte_addr_mode)(struct spi_nor *nor, bool enable); u32 (*convert_addr)(struct spi_nor *nor, u32 addr); int (*setup)(struct spi_nor *nor, const struct spi_nor_hwcaps *hwcaps); + int (*ready)(struct spi_nor *nor); const struct spi_nor_locking_ops *locking_ops; }; From 66cf87c60014a34c67bd2e70614fd4c4aea51202 Mon Sep 17 00:00:00 2001 From: Michael Walle Date: Wed, 23 Feb 2022 14:43:45 +0100 Subject: [PATCH 205/370] mtd: spi-nor: export more functions to be used in vendor modules We will move vendor specific code into the vendor modules and thus we will have to export these functions so they can be called. Signed-off-by: Michael Walle Signed-off-by: Tudor Ambarus Reviewed-by: Pratyush Yadav Link: https://lore.kernel.org/r/20220223134358.1914798-20-michael@walle.cc --- drivers/mtd/spi-nor/core.c | 10 +++++----- drivers/mtd/spi-nor/core.h | 6 ++++++ 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/drivers/mtd/spi-nor/core.c b/drivers/mtd/spi-nor/core.c index 390a9ab413b7..8481272533a3 100644 --- a/drivers/mtd/spi-nor/core.c +++ b/drivers/mtd/spi-nor/core.c @@ -157,8 +157,8 @@ static int spi_nor_spimem_exec_op(struct spi_nor *nor, struct spi_mem_op *op) return spi_mem_exec_op(nor->spimem, op); } -static int spi_nor_controller_ops_read_reg(struct spi_nor *nor, u8 opcode, - u8 *buf, size_t len) +int spi_nor_controller_ops_read_reg(struct spi_nor *nor, u8 opcode, + u8 *buf, size_t len) { if (spi_nor_protocol_is_dtr(nor->reg_proto)) return -EOPNOTSUPP; @@ -166,8 +166,8 @@ static int spi_nor_controller_ops_read_reg(struct spi_nor *nor, u8 opcode, return nor->controller_ops->read_reg(nor, opcode, buf, len); } -static int spi_nor_controller_ops_write_reg(struct spi_nor *nor, u8 opcode, - const u8 *buf, size_t len) +int spi_nor_controller_ops_write_reg(struct spi_nor *nor, u8 opcode, + const u8 *buf, size_t len) { if (spi_nor_protocol_is_dtr(nor->reg_proto)) return -EOPNOTSUPP; @@ -683,7 +683,7 @@ static void spi_nor_clear_sr(struct spi_nor *nor) * * Return: 1 if ready, 0 if not ready, -errno on errors. */ -static int spi_nor_sr_ready(struct spi_nor *nor) +int spi_nor_sr_ready(struct spi_nor *nor) { int ret = spi_nor_read_sr(nor, nor->bouncebuf); diff --git a/drivers/mtd/spi-nor/core.h b/drivers/mtd/spi-nor/core.h index fdc8c0f31f5c..446218b0e017 100644 --- a/drivers/mtd/spi-nor/core.h +++ b/drivers/mtd/spi-nor/core.h @@ -558,6 +558,7 @@ int spi_nor_sr1_bit6_quad_enable(struct spi_nor *nor); int spi_nor_sr2_bit1_quad_enable(struct spi_nor *nor); int spi_nor_sr2_bit7_quad_enable(struct spi_nor *nor); int spi_nor_read_sr(struct spi_nor *nor, u8 *sr); +int spi_nor_sr_ready(struct spi_nor *nor); int spi_nor_read_cr(struct spi_nor *nor, u8 *cr); int spi_nor_write_sr(struct spi_nor *nor, const u8 *sr, size_t len); int spi_nor_write_sr_and_check(struct spi_nor *nor, u8 sr1); @@ -603,6 +604,11 @@ void spi_nor_try_unlock_all(struct spi_nor *nor); void spi_nor_set_mtd_locking_ops(struct spi_nor *nor); void spi_nor_set_mtd_otp_ops(struct spi_nor *nor); +int spi_nor_controller_ops_read_reg(struct spi_nor *nor, u8 opcode, + u8 *buf, size_t len); +int spi_nor_controller_ops_write_reg(struct spi_nor *nor, u8 opcode, + const u8 *buf, size_t len); + static inline struct spi_nor *mtd_to_spi_nor(struct mtd_info *mtd) { return container_of(mtd, struct spi_nor, mtd); From 9fb4beb1b0510398c8202c6db04f29b3f22d53a7 Mon Sep 17 00:00:00 2001 From: Michael Walle Date: Wed, 23 Feb 2022 14:43:46 +0100 Subject: [PATCH 206/370] mtd: spi-nor: guard _page_size parameter in S3AN_INFO() The _page_size marco parameter was missing parentheses around it. Add them. Signed-off-by: Michael Walle Signed-off-by: Tudor Ambarus Reviewed-by: Pratyush Yadav Link: https://lore.kernel.org/r/20220223134358.1914798-21-michael@walle.cc --- drivers/mtd/spi-nor/core.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/mtd/spi-nor/core.h b/drivers/mtd/spi-nor/core.h index 446218b0e017..3c37b46d60d5 100644 --- a/drivers/mtd/spi-nor/core.h +++ b/drivers/mtd/spi-nor/core.h @@ -469,9 +469,9 @@ struct flash_info { (_jedec_id) & 0xff \ }, \ .id_len = 3, \ - .sector_size = (8*_page_size), \ + .sector_size = (8 * (_page_size)), \ .n_sectors = (_n_sectors), \ - .page_size = _page_size, \ + .page_size = (_page_size), \ .addr_width = 3, \ .flags = SPI_NOR_NO_FR | SPI_NOR_XSR_RDY, From 8b4195cd6dc3f1f0ab457d23d21e9f72fde0760a Mon Sep 17 00:00:00 2001 From: Michael Walle Date: Wed, 23 Feb 2022 14:43:47 +0100 Subject: [PATCH 207/370] mtd: spi-nor: move all xilinx specifics into xilinx.c Mechanically move all the xilinx functions to its own module. Then register the new flash specific ready() function. Signed-off-by: Michael Walle Signed-off-by: Tudor Ambarus Reviewed-by: Pratyush Yadav Link: https://lore.kernel.org/r/20220223134358.1914798-22-michael@walle.cc --- drivers/mtd/spi-nor/core.c | 64 +------------------------------ drivers/mtd/spi-nor/core.h | 18 --------- drivers/mtd/spi-nor/xilinx.c | 73 ++++++++++++++++++++++++++++++++++++ include/linux/mtd/spi-nor.h | 9 ----- 4 files changed, 74 insertions(+), 90 deletions(-) diff --git a/drivers/mtd/spi-nor/core.c b/drivers/mtd/spi-nor/core.c index 8481272533a3..ae1560250c48 100644 --- a/drivers/mtd/spi-nor/core.c +++ b/drivers/mtd/spi-nor/core.c @@ -598,57 +598,6 @@ int spi_nor_write_ear(struct spi_nor *nor, u8 ear) return ret; } -/** - * spi_nor_xread_sr() - Read the Status Register on S3AN flashes. - * @nor: pointer to 'struct spi_nor'. - * @sr: pointer to a DMA-able buffer where the value of the - * Status Register will be written. - * - * Return: 0 on success, -errno otherwise. - */ -int spi_nor_xread_sr(struct spi_nor *nor, u8 *sr) -{ - int ret; - - if (nor->spimem) { - struct spi_mem_op op = - SPI_MEM_OP(SPI_MEM_OP_CMD(SPINOR_OP_XRDSR, 0), - SPI_MEM_OP_NO_ADDR, - SPI_MEM_OP_NO_DUMMY, - SPI_MEM_OP_DATA_IN(1, sr, 0)); - - spi_nor_spimem_setup_op(nor, &op, nor->reg_proto); - - ret = spi_mem_exec_op(nor->spimem, &op); - } else { - ret = spi_nor_controller_ops_read_reg(nor, SPINOR_OP_XRDSR, sr, - 1); - } - - if (ret) - dev_dbg(nor->dev, "error %d reading XRDSR\n", ret); - - return ret; -} - -/** - * spi_nor_xsr_ready() - Query the Status Register of the S3AN flash to see if - * the flash is ready for new commands. - * @nor: pointer to 'struct spi_nor'. - * - * Return: 1 if ready, 0 if not ready, -errno on errors. - */ -static int spi_nor_xsr_ready(struct spi_nor *nor) -{ - int ret; - - ret = spi_nor_xread_sr(nor, nor->bouncebuf); - if (ret) - return ret; - - return !!(nor->bouncebuf[0] & XSR_RDY); -} - /** * spi_nor_clear_sr() - Clear the Status Register. * @nor: pointer to 'struct spi_nor'. @@ -798,10 +747,7 @@ static int spi_nor_ready(struct spi_nor *nor) if (nor->params->ready) return nor->params->ready(nor); - if (nor->flags & SNOR_F_READY_XSR_RDY) - sr = spi_nor_xsr_ready(nor); - else - sr = spi_nor_sr_ready(nor); + sr = spi_nor_sr_ready(nor); if (sr < 0) return sr; fsr = nor->flags & SNOR_F_USE_FSR ? spi_nor_fsr_ready(nor) : 1; @@ -2677,14 +2623,6 @@ static void spi_nor_init_flags(struct spi_nor *nor) if (flags & USE_FSR) nor->flags |= SNOR_F_USE_FSR; - - /* - * Make sure the XSR_RDY flag is set before calling - * spi_nor_wait_till_ready(). Xilinx S3AN share MFR - * with Atmel SPI NOR. - */ - if (flags & SPI_NOR_XSR_RDY) - nor->flags |= SNOR_F_READY_XSR_RDY; } /** diff --git a/drivers/mtd/spi-nor/core.h b/drivers/mtd/spi-nor/core.h index 3c37b46d60d5..fabc01ae9a81 100644 --- a/drivers/mtd/spi-nor/core.h +++ b/drivers/mtd/spi-nor/core.h @@ -15,7 +15,6 @@ enum spi_nor_option_flags { SNOR_F_USE_FSR = BIT(0), SNOR_F_HAS_SR_TB = BIT(1), SNOR_F_NO_OP_CHIP_ERASE = BIT(2), - SNOR_F_READY_XSR_RDY = BIT(3), SNOR_F_USE_CLSR = BIT(4), SNOR_F_BROKEN_RESET = BIT(5), SNOR_F_4B_OPCODES = BIT(6), @@ -351,8 +350,6 @@ struct spi_nor_fixups { * SPI_NOR_NO_FR: can't do fastread. * USE_CLSR: use CLSR command. * USE_FSR: use flag status register - * SPI_NOR_XSR_RDY: S3AN flashes have specific opcode to read the - * status register. * * @no_sfdp_flags: flags that indicate support that can be discovered via SFDP. * Used when SFDP tables are not defined in the flash. These @@ -405,7 +402,6 @@ struct flash_info { #define SPI_NOR_NO_FR BIT(8) #define USE_CLSR BIT(9) #define USE_FSR BIT(10) -#define SPI_NOR_XSR_RDY BIT(11) u8 no_sfdp_flags; #define SPI_NOR_SKIP_SFDP BIT(0) @@ -462,19 +458,6 @@ struct flash_info { .addr_width = (_addr_width), \ .flags = SPI_NOR_NO_ERASE | SPI_NOR_NO_FR, \ -#define S3AN_INFO(_jedec_id, _n_sectors, _page_size) \ - .id = { \ - ((_jedec_id) >> 16) & 0xff, \ - ((_jedec_id) >> 8) & 0xff, \ - (_jedec_id) & 0xff \ - }, \ - .id_len = 3, \ - .sector_size = (8 * (_page_size)), \ - .n_sectors = (_n_sectors), \ - .page_size = (_page_size), \ - .addr_width = 3, \ - .flags = SPI_NOR_NO_FR | SPI_NOR_XSR_RDY, - #define OTP_INFO(_len, _n_regions, _base, _offset) \ .otp_org = { \ .len = (_len), \ @@ -564,7 +547,6 @@ int spi_nor_write_sr(struct spi_nor *nor, const u8 *sr, size_t len); int spi_nor_write_sr_and_check(struct spi_nor *nor, u8 sr1); int spi_nor_write_16bit_cr_and_check(struct spi_nor *nor, u8 cr); -int spi_nor_xread_sr(struct spi_nor *nor, u8 *sr); ssize_t spi_nor_read_data(struct spi_nor *nor, loff_t from, size_t len, u8 *buf); ssize_t spi_nor_write_data(struct spi_nor *nor, loff_t to, size_t len, diff --git a/drivers/mtd/spi-nor/xilinx.c b/drivers/mtd/spi-nor/xilinx.c index 07dd11788df5..05c7fe843a7d 100644 --- a/drivers/mtd/spi-nor/xilinx.c +++ b/drivers/mtd/spi-nor/xilinx.c @@ -8,6 +8,27 @@ #include "core.h" +#define SPINOR_OP_XSE 0x50 /* Sector erase */ +#define SPINOR_OP_XPP 0x82 /* Page program */ +#define SPINOR_OP_XRDSR 0xd7 /* Read status register */ + +#define XSR_PAGESIZE BIT(0) /* Page size in Po2 or Linear */ +#define XSR_RDY BIT(7) /* Ready */ + +#define S3AN_INFO(_jedec_id, _n_sectors, _page_size) \ + .id = { \ + ((_jedec_id) >> 16) & 0xff, \ + ((_jedec_id) >> 8) & 0xff, \ + (_jedec_id) & 0xff \ + }, \ + .id_len = 3, \ + .sector_size = (8 * (_page_size)), \ + .n_sectors = (_n_sectors), \ + .page_size = (_page_size), \ + .addr_width = 3, \ + .flags = SPI_NOR_NO_FR + +/* Xilinx S3AN share MFR with Atmel SPI NOR */ static const struct flash_info xilinx_nor_parts[] = { /* Xilinx S3AN Internal Flash */ { "3S50AN", S3AN_INFO(0x1f2200, 64, 264) }, @@ -38,6 +59,57 @@ static u32 s3an_nor_convert_addr(struct spi_nor *nor, u32 addr) return page | offset; } +/** + * spi_nor_xread_sr() - Read the Status Register on S3AN flashes. + * @nor: pointer to 'struct spi_nor'. + * @sr: pointer to a DMA-able buffer where the value of the + * Status Register will be written. + * + * Return: 0 on success, -errno otherwise. + */ +static int spi_nor_xread_sr(struct spi_nor *nor, u8 *sr) +{ + int ret; + + if (nor->spimem) { + struct spi_mem_op op = + SPI_MEM_OP(SPI_MEM_OP_CMD(SPINOR_OP_XRDSR, 0), + SPI_MEM_OP_NO_ADDR, + SPI_MEM_OP_NO_DUMMY, + SPI_MEM_OP_DATA_IN(1, sr, 0)); + + spi_nor_spimem_setup_op(nor, &op, nor->reg_proto); + + ret = spi_mem_exec_op(nor->spimem, &op); + } else { + ret = spi_nor_controller_ops_read_reg(nor, SPINOR_OP_XRDSR, sr, + 1); + } + + if (ret) + dev_dbg(nor->dev, "error %d reading XRDSR\n", ret); + + return ret; +} + +/** + * spi_nor_xsr_ready() - Query the Status Register of the S3AN flash to see if + * the flash is ready for new commands. + * @nor: pointer to 'struct spi_nor'. + * + * Return: 1 if ready, 0 if not ready, -errno on errors. + */ +static int spi_nor_xsr_ready(struct spi_nor *nor) +{ + int ret; + + ret = spi_nor_xread_sr(nor, nor->bouncebuf); + if (ret) + return ret; + + return !!(nor->bouncebuf[0] & XSR_RDY); +} + static int xilinx_nor_setup(struct spi_nor *nor, const struct spi_nor_hwcaps *hwcaps) { @@ -83,6 +155,7 @@ static int xilinx_nor_setup(struct spi_nor *nor, static void xilinx_nor_late_init(struct spi_nor *nor) { nor->params->setup = xilinx_nor_setup; + nor->params->ready = spi_nor_xsr_ready; } static const struct spi_nor_fixups xilinx_nor_fixups = { diff --git a/include/linux/mtd/spi-nor.h b/include/linux/mtd/spi-nor.h index fc90fce26e33..b44b05a6f934 100644 --- a/include/linux/mtd/spi-nor.h +++ b/include/linux/mtd/spi-nor.h @@ -86,15 +86,6 @@ #define SPINOR_OP_BP 0x02 /* Byte program */ #define SPINOR_OP_AAI_WP 0xad /* Auto address increment word program */ -/* Used for S3AN flashes only */ -#define SPINOR_OP_XSE 0x50 /* Sector erase */ -#define SPINOR_OP_XPP 0x82 /* Page program */ -#define SPINOR_OP_XRDSR 0xd7 /* Read status register */ - -#define XSR_PAGESIZE BIT(0) /* Page size in Po2 or Linear */ -#define XSR_RDY BIT(7) /* Ready */ - - /* Used for Macronix and Winbond flashes. */ #define SPINOR_OP_EN4B 0xb7 /* Enter 4-byte mode */ #define SPINOR_OP_EX4B 0xe9 /* Exit 4-byte mode */ From 8b7a2e00d1172d8cc2a2869e3508f1e7abd26e7b Mon Sep 17 00:00:00 2001 From: Michael Walle Date: Wed, 23 Feb 2022 14:43:48 +0100 Subject: [PATCH 208/370] mtd: spi-nor: xilinx: rename vendor specific functions and defines Drop the generic spi_nor prefix for all the xilinx functions. Signed-off-by: Michael Walle Signed-off-by: Tudor Ambarus Reviewed-by: Pratyush Yadav Link: https://lore.kernel.org/r/20220223134358.1914798-23-michael@walle.cc --- drivers/mtd/spi-nor/xilinx.c | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/drivers/mtd/spi-nor/xilinx.c b/drivers/mtd/spi-nor/xilinx.c index 05c7fe843a7d..ffd5579d45cb 100644 --- a/drivers/mtd/spi-nor/xilinx.c +++ b/drivers/mtd/spi-nor/xilinx.c @@ -8,9 +8,9 @@ #include "core.h" -#define SPINOR_OP_XSE 0x50 /* Sector erase */ -#define SPINOR_OP_XPP 0x82 /* Page program */ -#define SPINOR_OP_XRDSR 0xd7 /* Read status register */ +#define XILINX_OP_SE 0x50 /* Sector erase */ +#define XILINX_OP_PP 0x82 /* Page program */ +#define XILINX_OP_RDSR 0xd7 /* Read status register */ #define XSR_PAGESIZE BIT(0) /* Page size in Po2 or Linear */ #define XSR_RDY BIT(7) /* Ready */ @@ -60,20 +60,20 @@ static u32 s3an_nor_convert_addr(struct spi_nor *nor, u32 addr) } /** - * spi_nor_xread_sr() - Read the Status Register on S3AN flashes. + * xilinx_nor_read_sr() - Read the Status Register on S3AN flashes. * @nor: pointer to 'struct spi_nor'. * @sr: pointer to a DMA-able buffer where the value of the * Status Register will be written. * * Return: 0 on success, -errno otherwise. */ -static int spi_nor_xread_sr(struct spi_nor *nor, u8 *sr) +static int xilinx_nor_read_sr(struct spi_nor *nor, u8 *sr) { int ret; if (nor->spimem) { struct spi_mem_op op = - SPI_MEM_OP(SPI_MEM_OP_CMD(SPINOR_OP_XRDSR, 0), + SPI_MEM_OP(SPI_MEM_OP_CMD(XILINX_OP_RDSR, 0), SPI_MEM_OP_NO_ADDR, SPI_MEM_OP_NO_DUMMY, SPI_MEM_OP_DATA_IN(1, sr, 0)); @@ -82,7 +82,7 @@ static int spi_nor_xread_sr(struct spi_nor *nor, u8 *sr) ret = spi_mem_exec_op(nor->spimem, &op); } else { - ret = spi_nor_controller_ops_read_reg(nor, SPINOR_OP_XRDSR, sr, + ret = spi_nor_controller_ops_read_reg(nor, XILINX_OP_RDSR, sr, 1); } @@ -93,17 +93,17 @@ static int spi_nor_xread_sr(struct spi_nor *nor, u8 *sr) } /** - * spi_nor_xsr_ready() - Query the Status Register of the S3AN flash to see if - * the flash is ready for new commands. + * xilinx_nor_sr_ready() - Query the Status Register of the S3AN flash to see + * if the flash is ready for new commands. * @nor: pointer to 'struct spi_nor'. * * Return: 1 if ready, 0 if not ready, -errno on errors. */ -static int spi_nor_xsr_ready(struct spi_nor *nor) +static int xilinx_nor_sr_ready(struct spi_nor *nor) { int ret; - ret = spi_nor_xread_sr(nor, nor->bouncebuf); + ret = xilinx_nor_read_sr(nor, nor->bouncebuf); if (ret) return ret; @@ -116,12 +116,12 @@ static int xilinx_nor_setup(struct spi_nor *nor, u32 page_size; int ret; - ret = spi_nor_xread_sr(nor, nor->bouncebuf); + ret = xilinx_nor_read_sr(nor, nor->bouncebuf); if (ret) return ret; - nor->erase_opcode = SPINOR_OP_XSE; - nor->program_opcode = SPINOR_OP_XPP; + nor->erase_opcode = XILINX_OP_SE; + nor->program_opcode = XILINX_OP_PP; nor->read_opcode = SPINOR_OP_READ; nor->flags |= SNOR_F_NO_OP_CHIP_ERASE; @@ -155,7 +155,7 @@ static int xilinx_nor_setup(struct spi_nor *nor, static void xilinx_nor_late_init(struct spi_nor *nor) { nor->params->setup = xilinx_nor_setup; - nor->params->ready = spi_nor_xsr_ready; + nor->params->ready = xilinx_nor_sr_ready; } static const struct spi_nor_fixups xilinx_nor_fixups = { From 56b852e8635ba83ecd47ad5f6ad269e8ab782ec8 Mon Sep 17 00:00:00 2001 From: Michael Walle Date: Wed, 23 Feb 2022 14:43:49 +0100 Subject: [PATCH 209/370] mtd: spi-nor: xilinx: correct the debug message XRDSR is a combination of xilinx and the RDSR opcode, but the register is just the status register. Correct the debug message. Signed-off-by: Michael Walle Signed-off-by: Tudor Ambarus Reviewed-by: Pratyush Yadav Link: https://lore.kernel.org/r/20220223134358.1914798-24-michael@walle.cc --- drivers/mtd/spi-nor/xilinx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/mtd/spi-nor/xilinx.c b/drivers/mtd/spi-nor/xilinx.c index ffd5579d45cb..9459ac2609dc 100644 --- a/drivers/mtd/spi-nor/xilinx.c +++ b/drivers/mtd/spi-nor/xilinx.c @@ -87,7 +87,7 @@ static int xilinx_nor_read_sr(struct spi_nor *nor, u8 *sr) } if (ret) - dev_dbg(nor->dev, "error %d reading XRDSR\n", ret); + dev_dbg(nor->dev, "error %d reading SR\n", ret); return ret; } From c770abe52d81089a8b8ecd1fe42722e29bbab5f5 Mon Sep 17 00:00:00 2001 From: Michael Walle Date: Wed, 23 Feb 2022 14:43:50 +0100 Subject: [PATCH 210/370] mtd: spi-nor: move all micron-st specifics into micron-st.c The flag status register is only available on micron flashes. Move all the functions around that into the micron module. This is almost a mechanical move except for the spi_nor_fsr_ready() which now also checks the normal status register. Previously, this was done in spi_nor_ready(). Signed-off-by: Michael Walle Signed-off-by: Tudor Ambarus Tested-by: Pratyush Yadav # on mt35xu512aba, s28hs512t Reviewed-by: Pratyush Yadav Link: https://lore.kernel.org/r/20220223134358.1914798-25-michael@walle.cc --- drivers/mtd/spi-nor/core.c | 123 +---------------------------- drivers/mtd/spi-nor/micron-st.c | 134 ++++++++++++++++++++++++++++++++ include/linux/mtd/spi-nor.h | 8 -- 3 files changed, 135 insertions(+), 130 deletions(-) diff --git a/drivers/mtd/spi-nor/core.c b/drivers/mtd/spi-nor/core.c index ae1560250c48..5b56d718692b 100644 --- a/drivers/mtd/spi-nor/core.c +++ b/drivers/mtd/spi-nor/core.c @@ -412,50 +412,6 @@ int spi_nor_read_sr(struct spi_nor *nor, u8 *sr) return ret; } -/** - * spi_nor_read_fsr() - Read the Flag Status Register. - * @nor: pointer to 'struct spi_nor' - * @fsr: pointer to a DMA-able buffer where the value of the - * Flag Status Register will be written. Should be at least 2 - * bytes. - * - * Return: 0 on success, -errno otherwise. - */ -static int spi_nor_read_fsr(struct spi_nor *nor, u8 *fsr) -{ - int ret; - - if (nor->spimem) { - struct spi_mem_op op = - SPI_MEM_OP(SPI_MEM_OP_CMD(SPINOR_OP_RDFSR, 0), - SPI_MEM_OP_NO_ADDR, - SPI_MEM_OP_NO_DUMMY, - SPI_MEM_OP_DATA_IN(1, fsr, 0)); - - if (nor->reg_proto == SNOR_PROTO_8_8_8_DTR) { - op.addr.nbytes = nor->params->rdsr_addr_nbytes; - op.dummy.nbytes = nor->params->rdsr_dummy; - /* - * We don't want to read only one byte in DTR mode. So, - * read 2 and then discard the second byte. - */ - op.data.nbytes = 2; - } - - spi_nor_spimem_setup_op(nor, &op, nor->reg_proto); - - ret = spi_mem_exec_op(nor->spimem, &op); - } else { - ret = spi_nor_controller_ops_read_reg(nor, SPINOR_OP_RDFSR, fsr, - 1); - } - - if (ret) - dev_dbg(nor->dev, "error %d reading FSR\n", ret); - - return ret; -} - /** * spi_nor_read_cr() - Read the Configuration Register using the * SPINOR_OP_RDCR (35h) command. @@ -664,75 +620,6 @@ int spi_nor_sr_ready(struct spi_nor *nor) return !(nor->bouncebuf[0] & SR_WIP); } -/** - * spi_nor_clear_fsr() - Clear the Flag Status Register. - * @nor: pointer to 'struct spi_nor'. - */ -static void spi_nor_clear_fsr(struct spi_nor *nor) -{ - int ret; - - if (nor->spimem) { - struct spi_mem_op op = - SPI_MEM_OP(SPI_MEM_OP_CMD(SPINOR_OP_CLFSR, 0), - SPI_MEM_OP_NO_ADDR, - SPI_MEM_OP_NO_DUMMY, - SPI_MEM_OP_NO_DATA); - - spi_nor_spimem_setup_op(nor, &op, nor->reg_proto); - - ret = spi_mem_exec_op(nor->spimem, &op); - } else { - ret = spi_nor_controller_ops_write_reg(nor, SPINOR_OP_CLFSR, - NULL, 0); - } - - if (ret) - dev_dbg(nor->dev, "error %d clearing FSR\n", ret); -} - -/** - * spi_nor_fsr_ready() - Query the Flag Status Register to see if the flash is - * ready for new commands. - * @nor: pointer to 'struct spi_nor'. - * - * Return: 1 if ready, 0 if not ready, -errno on errors. - */ -static int spi_nor_fsr_ready(struct spi_nor *nor) -{ - int ret = spi_nor_read_fsr(nor, nor->bouncebuf); - - if (ret) - return ret; - - if (nor->bouncebuf[0] & (FSR_E_ERR | FSR_P_ERR)) { - if (nor->bouncebuf[0] & FSR_E_ERR) - dev_err(nor->dev, "Erase operation failed.\n"); - else - dev_err(nor->dev, "Program operation failed.\n"); - - if (nor->bouncebuf[0] & FSR_PT_ERR) - dev_err(nor->dev, - "Attempted to modify a protected sector.\n"); - - spi_nor_clear_fsr(nor); - - /* - * WEL bit remains set to one when an erase or page program - * error occurs. Issue a Write Disable command to protect - * against inadvertent writes that can possibly corrupt the - * contents of the memory. - */ - ret = spi_nor_write_disable(nor); - if (ret) - return ret; - - return -EIO; - } - - return !!(nor->bouncebuf[0] & FSR_READY); -} - /** * spi_nor_ready() - Query the flash to see if it is ready for new commands. * @nor: pointer to 'struct spi_nor'. @@ -741,19 +628,11 @@ static int spi_nor_fsr_ready(struct spi_nor *nor) */ static int spi_nor_ready(struct spi_nor *nor) { - int sr, fsr; - /* Flashes might override the standard routine. */ if (nor->params->ready) return nor->params->ready(nor); - sr = spi_nor_sr_ready(nor); - if (sr < 0) - return sr; - fsr = nor->flags & SNOR_F_USE_FSR ? spi_nor_fsr_ready(nor) : 1; - if (fsr < 0) - return fsr; - return sr && fsr; + return spi_nor_sr_ready(nor); } /** diff --git a/drivers/mtd/spi-nor/micron-st.c b/drivers/mtd/spi-nor/micron-st.c index 7a68f2ad3ea1..e580830ed70f 100644 --- a/drivers/mtd/spi-nor/micron-st.c +++ b/drivers/mtd/spi-nor/micron-st.c @@ -8,6 +8,8 @@ #include "core.h" +#define SPINOR_OP_RDFSR 0x70 /* Read flag status register */ +#define SPINOR_OP_CLFSR 0x50 /* Clear flag status register */ #define SPINOR_OP_MT_DTR_RD 0xfd /* Fast Read opcode in DTR mode */ #define SPINOR_OP_MT_RD_ANY_REG 0x85 /* Read volatile register */ #define SPINOR_OP_MT_WR_ANY_REG 0x81 /* Write volatile register */ @@ -17,6 +19,12 @@ #define SPINOR_MT_OCT_DTR 0xe7 /* Enable Octal DTR. */ #define SPINOR_MT_EXSPI 0xff /* Enable Extended SPI (default) */ +/* Flag Status Register bits */ +#define FSR_READY BIT(7) /* Device status, 0 = Busy, 1 = Ready */ +#define FSR_E_ERR BIT(5) /* Erase operation status */ +#define FSR_P_ERR BIT(4) /* Program operation status */ +#define FSR_PT_ERR BIT(1) /* Protection error bit */ + static int micron_st_nor_octal_dtr_enable(struct spi_nor *nor, bool enable) { struct spi_mem_op op; @@ -273,6 +281,125 @@ static int micron_st_nor_set_4byte_addr_mode(struct spi_nor *nor, bool enable) return spi_nor_write_disable(nor); } +/** + * spi_nor_read_fsr() - Read the Flag Status Register. + * @nor: pointer to 'struct spi_nor' + * @fsr: pointer to a DMA-able buffer where the value of the + * Flag Status Register will be written. Should be at least 2 + * bytes. + * + * Return: 0 on success, -errno otherwise. + */ +static int spi_nor_read_fsr(struct spi_nor *nor, u8 *fsr) +{ + int ret; + + if (nor->spimem) { + struct spi_mem_op op = + SPI_MEM_OP(SPI_MEM_OP_CMD(SPINOR_OP_RDFSR, 0), + SPI_MEM_OP_NO_ADDR, + SPI_MEM_OP_NO_DUMMY, + SPI_MEM_OP_DATA_IN(1, fsr, 0)); + + if (nor->reg_proto == SNOR_PROTO_8_8_8_DTR) { + op.addr.nbytes = nor->params->rdsr_addr_nbytes; + op.dummy.nbytes = nor->params->rdsr_dummy; + /* + * We don't want to read only one byte in DTR mode. So, + * read 2 and then discard the second byte. + */ + op.data.nbytes = 2; + } + + spi_nor_spimem_setup_op(nor, &op, nor->reg_proto); + + ret = spi_mem_exec_op(nor->spimem, &op); + } else { + ret = spi_nor_controller_ops_read_reg(nor, SPINOR_OP_RDFSR, fsr, + 1); + } + + if (ret) + dev_dbg(nor->dev, "error %d reading FSR\n", ret); + + return ret; +} + +/** + * spi_nor_clear_fsr() - Clear the Flag Status Register. + * @nor: pointer to 'struct spi_nor'. + */ +static void spi_nor_clear_fsr(struct spi_nor *nor) +{ + int ret; + + if (nor->spimem) { + struct spi_mem_op op = + SPI_MEM_OP(SPI_MEM_OP_CMD(SPINOR_OP_CLFSR, 0), + SPI_MEM_OP_NO_ADDR, + SPI_MEM_OP_NO_DUMMY, + SPI_MEM_OP_NO_DATA); + + spi_nor_spimem_setup_op(nor, &op, nor->reg_proto); + + ret = spi_mem_exec_op(nor->spimem, &op); + } else { + ret = spi_nor_controller_ops_write_reg(nor, SPINOR_OP_CLFSR, + NULL, 0); + } + + if (ret) + dev_dbg(nor->dev, "error %d clearing FSR\n", ret); +} + +/** + * spi_nor_fsr_ready() - Query the Status Register as well as the Flag Status + * Register to see if the flash is ready for new commands. If there are any + * errors in the FSR clear them. + * @nor: pointer to 'struct spi_nor'. + * + * Return: 1 if ready, 0 if not ready, -errno on errors. + */ +static int spi_nor_fsr_ready(struct spi_nor *nor) +{ + int sr_ready, ret; + + sr_ready = spi_nor_sr_ready(nor); + if (sr_ready < 0) + return sr_ready; + + ret = spi_nor_read_fsr(nor, nor->bouncebuf); + if (ret) + return ret; + + if (nor->bouncebuf[0] & (FSR_E_ERR | FSR_P_ERR)) { + if (nor->bouncebuf[0] & FSR_E_ERR) + dev_err(nor->dev, "Erase operation failed.\n"); + else + dev_err(nor->dev, "Program operation failed.\n"); + + if (nor->bouncebuf[0] & FSR_PT_ERR) + dev_err(nor->dev, + "Attempted to modify a protected sector.\n"); + + spi_nor_clear_fsr(nor); + + /* + * WEL bit remains set to one when an erase or page program + * error occurs. Issue a Write Disable command to protect + * against inadvertent writes that can possibly corrupt the + * contents of the memory. + */ + ret = spi_nor_write_disable(nor); + if (ret) + return ret; + + return -EIO; + } + + return sr_ready && !!(nor->bouncebuf[0] & FSR_READY); +} + static void micron_st_nor_default_init(struct spi_nor *nor) { nor->flags |= SNOR_F_HAS_LOCK; @@ -281,8 +408,15 @@ static void micron_st_nor_default_init(struct spi_nor *nor) nor->params->set_4byte_addr_mode = micron_st_nor_set_4byte_addr_mode; } +static void micron_st_nor_late_init(struct spi_nor *nor) +{ + if (nor->flags & SNOR_F_USE_FSR) + nor->params->ready = spi_nor_fsr_ready; +} + static const struct spi_nor_fixups micron_st_nor_fixups = { .default_init = micron_st_nor_default_init, + .late_init = micron_st_nor_late_init, }; const struct spi_nor_manufacturer spi_nor_micron = { diff --git a/include/linux/mtd/spi-nor.h b/include/linux/mtd/spi-nor.h index b44b05a6f934..4622251a79ff 100644 --- a/include/linux/mtd/spi-nor.h +++ b/include/linux/mtd/spi-nor.h @@ -47,8 +47,6 @@ #define SPINOR_OP_RDID 0x9f /* Read JEDEC ID */ #define SPINOR_OP_RDSFDP 0x5a /* Read SFDP */ #define SPINOR_OP_RDCR 0x35 /* Read configuration register */ -#define SPINOR_OP_RDFSR 0x70 /* Read flag status register */ -#define SPINOR_OP_CLFSR 0x50 /* Clear flag status register */ #define SPINOR_OP_RDEAR 0xc8 /* Read Extended Address Register */ #define SPINOR_OP_WREAR 0xc5 /* Write Extended Address Register */ #define SPINOR_OP_SRSTEN 0x66 /* Software Reset Enable */ @@ -126,12 +124,6 @@ /* Enhanced Volatile Configuration Register bits */ #define EVCR_QUAD_EN_MICRON BIT(7) /* Micron Quad I/O */ -/* Flag Status Register bits */ -#define FSR_READY BIT(7) /* Device status, 0 = Busy, 1 = Ready */ -#define FSR_E_ERR BIT(5) /* Erase operation status */ -#define FSR_P_ERR BIT(4) /* Program operation status */ -#define FSR_PT_ERR BIT(1) /* Protection error bit */ - /* Status Register 2 bits. */ #define SR2_QUAD_EN_BIT1 BIT(1) #define SR2_LB1 BIT(3) /* Security Register Lock Bit 1 */ From 8f938262a6f37c4ca5e5f9552411877df2f93aab Mon Sep 17 00:00:00 2001 From: Michael Walle Date: Wed, 23 Feb 2022 14:43:51 +0100 Subject: [PATCH 211/370] mtd: spi-nor: micron-st: convert USE_FSR to a manufacturer flag Now that all functions using that flag are local to the micron module, we can convert the flag to a manufacturer one. Signed-off-by: Michael Walle Signed-off-by: Tudor Ambarus Tested-by: Pratyush Yadav # on mt35xu512aba, s28hs512t Reviewed-by: Pratyush Yadav Link: https://lore.kernel.org/r/20220223134358.1914798-26-michael@walle.cc --- drivers/mtd/spi-nor/core.c | 3 -- drivers/mtd/spi-nor/core.h | 3 -- drivers/mtd/spi-nor/micron-st.c | 93 +++++++++++++++++++++------------ 3 files changed, 60 insertions(+), 39 deletions(-) diff --git a/drivers/mtd/spi-nor/core.c b/drivers/mtd/spi-nor/core.c index 5b56d718692b..ac0faedebafe 100644 --- a/drivers/mtd/spi-nor/core.c +++ b/drivers/mtd/spi-nor/core.c @@ -2499,9 +2499,6 @@ static void spi_nor_init_flags(struct spi_nor *nor) if (flags & USE_CLSR) nor->flags |= SNOR_F_USE_CLSR; - - if (flags & USE_FSR) - nor->flags |= SNOR_F_USE_FSR; } /** diff --git a/drivers/mtd/spi-nor/core.h b/drivers/mtd/spi-nor/core.h index fabc01ae9a81..a02bf54289fb 100644 --- a/drivers/mtd/spi-nor/core.h +++ b/drivers/mtd/spi-nor/core.h @@ -12,7 +12,6 @@ #define SPI_NOR_MAX_ID_LEN 6 enum spi_nor_option_flags { - SNOR_F_USE_FSR = BIT(0), SNOR_F_HAS_SR_TB = BIT(1), SNOR_F_NO_OP_CHIP_ERASE = BIT(2), SNOR_F_USE_CLSR = BIT(4), @@ -349,7 +348,6 @@ struct spi_nor_fixups { * NO_CHIP_ERASE: chip does not support chip erase. * SPI_NOR_NO_FR: can't do fastread. * USE_CLSR: use CLSR command. - * USE_FSR: use flag status register * * @no_sfdp_flags: flags that indicate support that can be discovered via SFDP. * Used when SFDP tables are not defined in the flash. These @@ -401,7 +399,6 @@ struct flash_info { #define NO_CHIP_ERASE BIT(7) #define SPI_NOR_NO_FR BIT(8) #define USE_CLSR BIT(9) -#define USE_FSR BIT(10) u8 no_sfdp_flags; #define SPI_NOR_SKIP_SFDP BIT(0) diff --git a/drivers/mtd/spi-nor/micron-st.c b/drivers/mtd/spi-nor/micron-st.c index e580830ed70f..1a7227594bf0 100644 --- a/drivers/mtd/spi-nor/micron-st.c +++ b/drivers/mtd/spi-nor/micron-st.c @@ -8,6 +8,9 @@ #include "core.h" +/* flash_info mfr_flag. Used to read proprietary FSR register. */ +#define USE_FSR BIT(0) + #define SPINOR_OP_RDFSR 0x70 /* Read flag status register */ #define SPINOR_OP_CLFSR 0x50 /* Clear flag status register */ #define SPINOR_OP_MT_DTR_RD 0xfd /* Fast Read opcode in DTR mode */ @@ -140,15 +143,17 @@ static const struct spi_nor_fixups mt35xu512aba_fixups = { static const struct flash_info micron_nor_parts[] = { { "mt35xu512aba", INFO(0x2c5b1a, 0, 128 * 1024, 512) - FLAGS(USE_FSR) NO_SFDP_FLAGS(SECT_4K | SPI_NOR_OCTAL_READ | SPI_NOR_OCTAL_DTR_READ | SPI_NOR_OCTAL_DTR_PP) FIXUP_FLAGS(SPI_NOR_4B_OPCODES | SPI_NOR_IO_MODE_EN_VOLATILE) - .fixups = &mt35xu512aba_fixups}, + MFR_FLAGS(USE_FSR) + .fixups = &mt35xu512aba_fixups + }, { "mt35xu02g", INFO(0x2c5b1c, 0, 128 * 1024, 2048) - FLAGS(USE_FSR) NO_SFDP_FLAGS(SECT_4K | SPI_NOR_OCTAL_READ) - FIXUP_FLAGS(SPI_NOR_4B_OPCODES) }, + FIXUP_FLAGS(SPI_NOR_4B_OPCODES) + MFR_FLAGS(USE_FSR) + }, }; static const struct flash_info st_nor_parts[] = { @@ -164,57 +169,79 @@ static const struct flash_info st_nor_parts[] = { NO_SFDP_FLAGS(SECT_4K | SPI_NOR_QUAD_READ) }, { "n25q128a11", INFO(0x20bb18, 0, 64 * 1024, 256) FLAGS(SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB | SPI_NOR_4BIT_BP | - SPI_NOR_BP3_SR_BIT6 | USE_FSR) - NO_SFDP_FLAGS(SECT_4K | SPI_NOR_QUAD_READ) }, + SPI_NOR_BP3_SR_BIT6) + NO_SFDP_FLAGS(SECT_4K | SPI_NOR_QUAD_READ) + MFR_FLAGS(USE_FSR) + }, { "n25q128a13", INFO(0x20ba18, 0, 64 * 1024, 256) FLAGS(SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB | SPI_NOR_4BIT_BP | - SPI_NOR_BP3_SR_BIT6 | USE_FSR) - NO_SFDP_FLAGS(SECT_4K | SPI_NOR_QUAD_READ) }, + SPI_NOR_BP3_SR_BIT6) + NO_SFDP_FLAGS(SECT_4K | SPI_NOR_QUAD_READ) + MFR_FLAGS(USE_FSR) + }, { "mt25ql256a", INFO6(0x20ba19, 0x104400, 64 * 1024, 512) - FLAGS(USE_FSR) NO_SFDP_FLAGS(SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) - FIXUP_FLAGS(SPI_NOR_4B_OPCODES) }, + FIXUP_FLAGS(SPI_NOR_4B_OPCODES) + MFR_FLAGS(USE_FSR) + }, { "n25q256a", INFO(0x20ba19, 0, 64 * 1024, 512) - FLAGS(USE_FSR) NO_SFDP_FLAGS(SECT_4K | SPI_NOR_DUAL_READ | - SPI_NOR_QUAD_READ) }, + SPI_NOR_QUAD_READ) + MFR_FLAGS(USE_FSR) + }, { "mt25qu256a", INFO6(0x20bb19, 0x104400, 64 * 1024, 512) - FLAGS(USE_FSR) NO_SFDP_FLAGS(SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) - FIXUP_FLAGS(SPI_NOR_4B_OPCODES) }, + FIXUP_FLAGS(SPI_NOR_4B_OPCODES) + MFR_FLAGS(USE_FSR) + }, { "n25q256ax1", INFO(0x20bb19, 0, 64 * 1024, 512) - FLAGS(USE_FSR) - NO_SFDP_FLAGS(SECT_4K | SPI_NOR_QUAD_READ) }, + NO_SFDP_FLAGS(SECT_4K | SPI_NOR_QUAD_READ) + MFR_FLAGS(USE_FSR) + }, { "mt25ql512a", INFO6(0x20ba20, 0x104400, 64 * 1024, 1024) - FLAGS(USE_FSR) NO_SFDP_FLAGS(SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) - FIXUP_FLAGS(SPI_NOR_4B_OPCODES) }, + FIXUP_FLAGS(SPI_NOR_4B_OPCODES) + MFR_FLAGS(USE_FSR) + }, { "n25q512ax3", INFO(0x20ba20, 0, 64 * 1024, 1024) FLAGS(SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB | SPI_NOR_4BIT_BP | - SPI_NOR_BP3_SR_BIT6 | USE_FSR) - NO_SFDP_FLAGS(SECT_4K | SPI_NOR_QUAD_READ) }, + SPI_NOR_BP3_SR_BIT6) + NO_SFDP_FLAGS(SECT_4K | SPI_NOR_QUAD_READ) + MFR_FLAGS(USE_FSR) + }, { "mt25qu512a", INFO6(0x20bb20, 0x104400, 64 * 1024, 1024) - FLAGS(USE_FSR) NO_SFDP_FLAGS(SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) - FIXUP_FLAGS(SPI_NOR_4B_OPCODES) }, + FIXUP_FLAGS(SPI_NOR_4B_OPCODES) + MFR_FLAGS(USE_FSR) + }, { "n25q512a", INFO(0x20bb20, 0, 64 * 1024, 1024) FLAGS(SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB | SPI_NOR_4BIT_BP | - SPI_NOR_BP3_SR_BIT6 | USE_FSR) - NO_SFDP_FLAGS(SECT_4K | SPI_NOR_QUAD_READ) }, + SPI_NOR_BP3_SR_BIT6) + NO_SFDP_FLAGS(SECT_4K | SPI_NOR_QUAD_READ) + MFR_FLAGS(USE_FSR) + }, { "n25q00", INFO(0x20ba21, 0, 64 * 1024, 2048) FLAGS(SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB | SPI_NOR_4BIT_BP | - SPI_NOR_BP3_SR_BIT6 | NO_CHIP_ERASE | USE_FSR) - NO_SFDP_FLAGS(SECT_4K | SPI_NOR_QUAD_READ) }, + SPI_NOR_BP3_SR_BIT6 | NO_CHIP_ERASE) + NO_SFDP_FLAGS(SECT_4K | SPI_NOR_QUAD_READ) + MFR_FLAGS(USE_FSR) + }, { "n25q00a", INFO(0x20bb21, 0, 64 * 1024, 2048) - FLAGS(NO_CHIP_ERASE | USE_FSR) - NO_SFDP_FLAGS(SECT_4K | SPI_NOR_QUAD_READ) }, + FLAGS(NO_CHIP_ERASE) + NO_SFDP_FLAGS(SECT_4K | SPI_NOR_QUAD_READ) + MFR_FLAGS(USE_FSR) + }, { "mt25ql02g", INFO(0x20ba22, 0, 64 * 1024, 4096) - FLAGS(NO_CHIP_ERASE | USE_FSR) - NO_SFDP_FLAGS(SECT_4K | SPI_NOR_QUAD_READ) }, + FLAGS(NO_CHIP_ERASE) + NO_SFDP_FLAGS(SECT_4K | SPI_NOR_QUAD_READ) + MFR_FLAGS(USE_FSR) + }, { "mt25qu02g", INFO(0x20bb22, 0, 64 * 1024, 4096) - FLAGS(NO_CHIP_ERASE | USE_FSR) + FLAGS(NO_CHIP_ERASE) NO_SFDP_FLAGS(SECT_4K | SPI_NOR_DUAL_READ | - SPI_NOR_QUAD_READ) }, + SPI_NOR_QUAD_READ) + MFR_FLAGS(USE_FSR) + }, { "m25p05", INFO(0x202010, 0, 32 * 1024, 2) }, { "m25p10", INFO(0x202011, 0, 32 * 1024, 4) }, @@ -410,7 +437,7 @@ static void micron_st_nor_default_init(struct spi_nor *nor) static void micron_st_nor_late_init(struct spi_nor *nor) { - if (nor->flags & SNOR_F_USE_FSR) + if (nor->info->mfr_flags & USE_FSR) nor->params->ready = spi_nor_fsr_ready; } From 2b18a18ea7f8e234e66046f64787efd21c290538 Mon Sep 17 00:00:00 2001 From: Michael Walle Date: Wed, 23 Feb 2022 14:43:52 +0100 Subject: [PATCH 212/370] mtd: spi-nor: micron-st: rename vendor specific functions and defines Drop the generic spi_nor prefix for all the micron-st functions. Signed-off-by: Michael Walle Signed-off-by: Tudor Ambarus Tested-by: Pratyush Yadav # on mt35xu512aba, s28hs512t Reviewed-by: Pratyush Yadav Link: https://lore.kernel.org/r/20220223134358.1914798-27-michael@walle.cc --- drivers/mtd/spi-nor/micron-st.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/drivers/mtd/spi-nor/micron-st.c b/drivers/mtd/spi-nor/micron-st.c index 1a7227594bf0..8a20475ce77a 100644 --- a/drivers/mtd/spi-nor/micron-st.c +++ b/drivers/mtd/spi-nor/micron-st.c @@ -309,7 +309,7 @@ static int micron_st_nor_set_4byte_addr_mode(struct spi_nor *nor, bool enable) } /** - * spi_nor_read_fsr() - Read the Flag Status Register. + * micron_st_nor_read_fsr() - Read the Flag Status Register. * @nor: pointer to 'struct spi_nor' * @fsr: pointer to a DMA-able buffer where the value of the * Flag Status Register will be written. Should be at least 2 @@ -317,7 +317,7 @@ static int micron_st_nor_set_4byte_addr_mode(struct spi_nor *nor, bool enable) * * Return: 0 on success, -errno otherwise. */ -static int spi_nor_read_fsr(struct spi_nor *nor, u8 *fsr) +static int micron_st_nor_read_fsr(struct spi_nor *nor, u8 *fsr) { int ret; @@ -353,10 +353,10 @@ static int spi_nor_read_fsr(struct spi_nor *nor, u8 *fsr) } /** - * spi_nor_clear_fsr() - Clear the Flag Status Register. + * micron_st_nor_clear_fsr() - Clear the Flag Status Register. * @nor: pointer to 'struct spi_nor'. */ -static void spi_nor_clear_fsr(struct spi_nor *nor) +static void micron_st_nor_clear_fsr(struct spi_nor *nor) { int ret; @@ -380,14 +380,14 @@ static void spi_nor_clear_fsr(struct spi_nor *nor) } /** - * spi_nor_fsr_ready() - Query the Status Register as well as the Flag Status + * micron_st_nor_ready() - Query the Status Register as well as the Flag Status * Register to see if the flash is ready for new commands. If there are any * errors in the FSR clear them. * @nor: pointer to 'struct spi_nor'. * * Return: 1 if ready, 0 if not ready, -errno on errors. */ -static int spi_nor_fsr_ready(struct spi_nor *nor) +static int micron_st_nor_ready(struct spi_nor *nor) { int sr_ready, ret; @@ -395,7 +395,7 @@ static int spi_nor_fsr_ready(struct spi_nor *nor) if (sr_ready < 0) return sr_ready; - ret = spi_nor_read_fsr(nor, nor->bouncebuf); + ret = micron_st_nor_read_fsr(nor, nor->bouncebuf); if (ret) return ret; @@ -409,7 +409,7 @@ static int spi_nor_fsr_ready(struct spi_nor *nor) dev_err(nor->dev, "Attempted to modify a protected sector.\n"); - spi_nor_clear_fsr(nor); + micron_st_nor_clear_fsr(nor); /* * WEL bit remains set to one when an erase or page program @@ -438,7 +438,7 @@ static void micron_st_nor_default_init(struct spi_nor *nor) static void micron_st_nor_late_init(struct spi_nor *nor) { if (nor->info->mfr_flags & USE_FSR) - nor->params->ready = spi_nor_fsr_ready; + nor->params->ready = micron_st_nor_ready; } static const struct spi_nor_fixups micron_st_nor_fixups = { From 6235ff040c1372acab928c308f43908840e991d3 Mon Sep 17 00:00:00 2001 From: Michael Walle Date: Wed, 23 Feb 2022 14:43:53 +0100 Subject: [PATCH 213/370] mtd: spi-nor: spansion: slightly rework control flow in late_init() Don't return early when the flash is smaller than or equal to 16MiB. We need to be able to register hooks for all sizes of flashes. This also has the benefit that it increases the readability of the code because the action, i.e. registering the fixups, is connected to the condition, i.e. flashes larger than 16MiB. Signed-off-by: Michael Walle Signed-off-by: Tudor Ambarus Tested-by: Pratyush Yadav # on mt35xu512aba, s28hs512t Reviewed-by: Pratyush Yadav Link: https://lore.kernel.org/r/20220223134358.1914798-28-michael@walle.cc --- drivers/mtd/spi-nor/spansion.c | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/drivers/mtd/spi-nor/spansion.c b/drivers/mtd/spi-nor/spansion.c index 5affa8ae43a7..1a0e7214d9e5 100644 --- a/drivers/mtd/spi-nor/spansion.c +++ b/drivers/mtd/spi-nor/spansion.c @@ -296,13 +296,12 @@ static const struct flash_info spansion_nor_parts[] = { static void spansion_nor_late_init(struct spi_nor *nor) { - if (nor->params->size <= SZ_16M) - return; - - nor->flags |= SNOR_F_4B_OPCODES; - /* No small sector erase for 4-byte command set */ - nor->erase_opcode = SPINOR_OP_SE; - nor->mtd.erasesize = nor->info->sector_size; + if (nor->params->size > SZ_16M) { + nor->flags |= SNOR_F_4B_OPCODES; + /* No small sector erase for 4-byte command set */ + nor->erase_opcode = SPINOR_OP_SE; + nor->mtd.erasesize = nor->info->sector_size; + } } static const struct spi_nor_fixups spansion_nor_fixups = { From 837d5181beef068c16bb8424c2c1571a7d5d7966 Mon Sep 17 00:00:00 2001 From: Michael Walle Date: Wed, 23 Feb 2022 14:43:54 +0100 Subject: [PATCH 214/370] mtd: spi-nor: move all spansion specifics into spansion.c The clear status register flags is only available on spansion flashes. Move all the functions around that into the spanion module. Signed-off-by: Michael Walle Signed-off-by: Tudor Ambarus Tested-by: Pratyush Yadav # on mt35xu512aba, s28hs512t Reviewed-by: Pratyush Yadav Link: https://lore.kernel.org/r/20220223134358.1914798-29-michael@walle.cc --- drivers/mtd/spi-nor/core.c | 49 ------------------------ drivers/mtd/spi-nor/spansion.c | 70 ++++++++++++++++++++++++++++++++++ include/linux/mtd/spi-nor.h | 1 - 3 files changed, 70 insertions(+), 50 deletions(-) diff --git a/drivers/mtd/spi-nor/core.c b/drivers/mtd/spi-nor/core.c index ac0faedebafe..e2b8b0a438ce 100644 --- a/drivers/mtd/spi-nor/core.c +++ b/drivers/mtd/spi-nor/core.c @@ -554,33 +554,6 @@ int spi_nor_write_ear(struct spi_nor *nor, u8 ear) return ret; } -/** - * spi_nor_clear_sr() - Clear the Status Register. - * @nor: pointer to 'struct spi_nor'. - */ -static void spi_nor_clear_sr(struct spi_nor *nor) -{ - int ret; - - if (nor->spimem) { - struct spi_mem_op op = - SPI_MEM_OP(SPI_MEM_OP_CMD(SPINOR_OP_CLSR, 0), - SPI_MEM_OP_NO_ADDR, - SPI_MEM_OP_NO_DUMMY, - SPI_MEM_OP_NO_DATA); - - spi_nor_spimem_setup_op(nor, &op, nor->reg_proto); - - ret = spi_mem_exec_op(nor->spimem, &op); - } else { - ret = spi_nor_controller_ops_write_reg(nor, SPINOR_OP_CLSR, - NULL, 0); - } - - if (ret) - dev_dbg(nor->dev, "error %d clearing SR\n", ret); -} - /** * spi_nor_sr_ready() - Query the Status Register to see if the flash is ready * for new commands. @@ -595,28 +568,6 @@ int spi_nor_sr_ready(struct spi_nor *nor) if (ret) return ret; - if (nor->flags & SNOR_F_USE_CLSR && - nor->bouncebuf[0] & (SR_E_ERR | SR_P_ERR)) { - if (nor->bouncebuf[0] & SR_E_ERR) - dev_err(nor->dev, "Erase Error occurred\n"); - else - dev_err(nor->dev, "Programming Error occurred\n"); - - spi_nor_clear_sr(nor); - - /* - * WEL bit remains set to one when an erase or page program - * error occurs. Issue a Write Disable command to protect - * against inadvertent writes that can possibly corrupt the - * contents of the memory. - */ - ret = spi_nor_write_disable(nor); - if (ret) - return ret; - - return -EIO; - } - return !(nor->bouncebuf[0] & SR_WIP); } diff --git a/drivers/mtd/spi-nor/spansion.c b/drivers/mtd/spi-nor/spansion.c index 1a0e7214d9e5..dbafe97c2636 100644 --- a/drivers/mtd/spi-nor/spansion.c +++ b/drivers/mtd/spi-nor/spansion.c @@ -8,6 +8,7 @@ #include "core.h" +#define SPINOR_OP_CLSR 0x30 /* Clear status register 1 */ #define SPINOR_OP_RD_ANY_REG 0x65 /* Read any register */ #define SPINOR_OP_WR_ANY_REG 0x71 /* Write any register */ #define SPINOR_REG_CYPRESS_CFR2V 0x00800003 @@ -294,6 +295,72 @@ static const struct flash_info spansion_nor_parts[] = { }, }; +/** + * spi_nor_clear_sr() - Clear the Status Register. + * @nor: pointer to 'struct spi_nor'. + */ +static void spi_nor_clear_sr(struct spi_nor *nor) +{ + int ret; + + if (nor->spimem) { + struct spi_mem_op op = + SPI_MEM_OP(SPI_MEM_OP_CMD(SPINOR_OP_CLSR, 0), + SPI_MEM_OP_NO_ADDR, + SPI_MEM_OP_NO_DUMMY, + SPI_MEM_OP_NO_DATA); + + spi_nor_spimem_setup_op(nor, &op, nor->reg_proto); + + ret = spi_mem_exec_op(nor->spimem, &op); + } else { + ret = spi_nor_controller_ops_write_reg(nor, SPINOR_OP_CLSR, + NULL, 0); + } + + if (ret) + dev_dbg(nor->dev, "error %d clearing SR\n", ret); +} + +/** + * spi_nor_sr_ready_and_clear() - Query the Status Register to see if the flash + * is ready for new commands and clear it if there are any errors. + * @nor: pointer to 'struct spi_nor'. + * + * Return: 1 if ready, 0 if not ready, -errno on errors. + */ +static int spi_nor_sr_ready_and_clear(struct spi_nor *nor) +{ + int ret; + + ret = spi_nor_read_sr(nor, nor->bouncebuf); + if (ret) + return ret; + + if (nor->bouncebuf[0] & (SR_E_ERR | SR_P_ERR)) { + if (nor->bouncebuf[0] & SR_E_ERR) + dev_err(nor->dev, "Erase Error occurred\n"); + else + dev_err(nor->dev, "Programming Error occurred\n"); + + spi_nor_clear_sr(nor); + + /* + * WEL bit remains set to one when an erase or page program + * error occurs. Issue a Write Disable command to protect + * against inadvertent writes that can possibly corrupt the + * contents of the memory. + */ + ret = spi_nor_write_disable(nor); + if (ret) + return ret; + + return -EIO; + } + + return !(nor->bouncebuf[0] & SR_WIP); +} + static void spansion_nor_late_init(struct spi_nor *nor) { if (nor->params->size > SZ_16M) { @@ -302,6 +369,9 @@ static void spansion_nor_late_init(struct spi_nor *nor) nor->erase_opcode = SPINOR_OP_SE; nor->mtd.erasesize = nor->info->sector_size; } + + if (nor->flags & SNOR_F_USE_CLSR) + nor->params->ready = spi_nor_sr_ready_and_clear; } static const struct spi_nor_fixups spansion_nor_fixups = { diff --git a/include/linux/mtd/spi-nor.h b/include/linux/mtd/spi-nor.h index 4622251a79ff..5e25a7b75ae2 100644 --- a/include/linux/mtd/spi-nor.h +++ b/include/linux/mtd/spi-nor.h @@ -90,7 +90,6 @@ /* Used for Spansion flashes only. */ #define SPINOR_OP_BRWR 0x17 /* Bank register write */ -#define SPINOR_OP_CLSR 0x30 /* Clear status register 1 */ /* Used for Micron flashes only. */ #define SPINOR_OP_RD_EVCR 0x65 /* Read EVCR register */ From 51c55506a7b1e6017dd6602ad14266ee551aa2d2 Mon Sep 17 00:00:00 2001 From: Michael Walle Date: Wed, 23 Feb 2022 14:43:55 +0100 Subject: [PATCH 215/370] mtd: spi-nor: spansion: convert USE_CLSR to a manufacturer flag Now that all functions using that flag are local to the spansion module, we can convert the flag to a manufacturer one. Signed-off-by: Michael Walle Signed-off-by: Tudor Ambarus Tested-by: Pratyush Yadav # on mt35xu512aba, s28hs512t Reviewed-by: Pratyush Yadav Link: https://lore.kernel.org/r/20220223134358.1914798-30-michael@walle.cc --- drivers/mtd/spi-nor/core.c | 3 -- drivers/mtd/spi-nor/core.h | 3 -- drivers/mtd/spi-nor/spansion.c | 71 ++++++++++++++++++++-------------- 3 files changed, 42 insertions(+), 35 deletions(-) diff --git a/drivers/mtd/spi-nor/core.c b/drivers/mtd/spi-nor/core.c index e2b8b0a438ce..f5a2f37d140e 100644 --- a/drivers/mtd/spi-nor/core.c +++ b/drivers/mtd/spi-nor/core.c @@ -2447,9 +2447,6 @@ static void spi_nor_init_flags(struct spi_nor *nor) if (flags & NO_CHIP_ERASE) nor->flags |= SNOR_F_NO_OP_CHIP_ERASE; - - if (flags & USE_CLSR) - nor->flags |= SNOR_F_USE_CLSR; } /** diff --git a/drivers/mtd/spi-nor/core.h b/drivers/mtd/spi-nor/core.h index a02bf54289fb..2130a96e2044 100644 --- a/drivers/mtd/spi-nor/core.h +++ b/drivers/mtd/spi-nor/core.h @@ -14,7 +14,6 @@ enum spi_nor_option_flags { SNOR_F_HAS_SR_TB = BIT(1), SNOR_F_NO_OP_CHIP_ERASE = BIT(2), - SNOR_F_USE_CLSR = BIT(4), SNOR_F_BROKEN_RESET = BIT(5), SNOR_F_4B_OPCODES = BIT(6), SNOR_F_HAS_4BAIT = BIT(7), @@ -347,7 +346,6 @@ struct spi_nor_fixups { * SPI_NOR_NO_ERASE: no erase command needed. * NO_CHIP_ERASE: chip does not support chip erase. * SPI_NOR_NO_FR: can't do fastread. - * USE_CLSR: use CLSR command. * * @no_sfdp_flags: flags that indicate support that can be discovered via SFDP. * Used when SFDP tables are not defined in the flash. These @@ -398,7 +396,6 @@ struct flash_info { #define SPI_NOR_NO_ERASE BIT(6) #define NO_CHIP_ERASE BIT(7) #define SPI_NOR_NO_FR BIT(8) -#define USE_CLSR BIT(9) u8 no_sfdp_flags; #define SPI_NOR_SKIP_SFDP BIT(0) diff --git a/drivers/mtd/spi-nor/spansion.c b/drivers/mtd/spi-nor/spansion.c index dbafe97c2636..32d3301ce385 100644 --- a/drivers/mtd/spi-nor/spansion.c +++ b/drivers/mtd/spi-nor/spansion.c @@ -8,6 +8,9 @@ #include "core.h" +/* flash_info mfr_flag. Used to clear sticky prorietary SR bits. */ +#define USE_CLSR BIT(0) + #define SPINOR_OP_CLSR 0x30 /* Clear status register 1 */ #define SPINOR_OP_RD_ANY_REG 0x65 /* Read any register */ #define SPINOR_OP_WR_ANY_REG 0x71 /* Write any register */ @@ -212,43 +215,53 @@ static const struct flash_info spansion_nor_parts[] = { { "s25sl064p", INFO(0x010216, 0x4d00, 64 * 1024, 128) NO_SFDP_FLAGS(SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, { "s25fl128s0", INFO6(0x012018, 0x4d0080, 256 * 1024, 64) - FLAGS(USE_CLSR) - NO_SFDP_FLAGS(SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, - { "s25fl128s1", INFO6(0x012018, 0x4d0180, 64 * 1024, 256) - FLAGS(USE_CLSR) - NO_SFDP_FLAGS(SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, - { "s25fl256s0", INFO6(0x010219, 0x4d0080, 256 * 1024, 128) - FLAGS(USE_CLSR) - NO_SFDP_FLAGS(SPI_NOR_SKIP_SFDP | SPI_NOR_DUAL_READ | - SPI_NOR_QUAD_READ) }, - { "s25fl256s1", INFO6(0x010219, 0x4d0180, 64 * 1024, 512) - FLAGS(USE_CLSR) - NO_SFDP_FLAGS(SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, - { "s25fl512s", INFO6(0x010220, 0x4d0080, 256 * 1024, 256) - FLAGS(SPI_NOR_HAS_LOCK | USE_CLSR) - NO_SFDP_FLAGS(SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, - { "s25fs128s1", INFO6(0x012018, 0x4d0181, 64 * 1024, 256) - FLAGS(USE_CLSR) NO_SFDP_FLAGS(SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) + MFR_FLAGS(USE_CLSR) + }, + { "s25fl128s1", INFO6(0x012018, 0x4d0180, 64 * 1024, 256) + NO_SFDP_FLAGS(SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) + MFR_FLAGS(USE_CLSR) + }, + { "s25fl256s0", INFO6(0x010219, 0x4d0080, 256 * 1024, 128) + NO_SFDP_FLAGS(SPI_NOR_SKIP_SFDP | SPI_NOR_DUAL_READ | + SPI_NOR_QUAD_READ) + MFR_FLAGS(USE_CLSR) + }, + { "s25fl256s1", INFO6(0x010219, 0x4d0180, 64 * 1024, 512) + NO_SFDP_FLAGS(SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) + MFR_FLAGS(USE_CLSR) + }, + { "s25fl512s", INFO6(0x010220, 0x4d0080, 256 * 1024, 256) + FLAGS(SPI_NOR_HAS_LOCK) + NO_SFDP_FLAGS(SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) + MFR_FLAGS(USE_CLSR) + }, + { "s25fs128s1", INFO6(0x012018, 0x4d0181, 64 * 1024, 256) + NO_SFDP_FLAGS(SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) + MFR_FLAGS(USE_CLSR) .fixups = &s25fs_s_nor_fixups, }, { "s25fs256s0", INFO6(0x010219, 0x4d0081, 256 * 1024, 128) - FLAGS(USE_CLSR) - NO_SFDP_FLAGS(SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, - { "s25fs256s1", INFO6(0x010219, 0x4d0181, 64 * 1024, 512) - FLAGS(USE_CLSR) - NO_SFDP_FLAGS(SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, - { "s25fs512s", INFO6(0x010220, 0x4d0081, 256 * 1024, 256) - FLAGS(USE_CLSR) NO_SFDP_FLAGS(SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) + MFR_FLAGS(USE_CLSR) + }, + { "s25fs256s1", INFO6(0x010219, 0x4d0181, 64 * 1024, 512) + NO_SFDP_FLAGS(SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) + MFR_FLAGS(USE_CLSR) + }, + { "s25fs512s", INFO6(0x010220, 0x4d0081, 256 * 1024, 256) + NO_SFDP_FLAGS(SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) + MFR_FLAGS(USE_CLSR) .fixups = &s25fs_s_nor_fixups, }, { "s25sl12800", INFO(0x012018, 0x0300, 256 * 1024, 64) }, { "s25sl12801", INFO(0x012018, 0x0301, 64 * 1024, 256) }, { "s25fl129p0", INFO(0x012018, 0x4d00, 256 * 1024, 64) - FLAGS(USE_CLSR) - NO_SFDP_FLAGS(SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, + NO_SFDP_FLAGS(SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) + MFR_FLAGS(USE_CLSR) + }, { "s25fl129p1", INFO(0x012018, 0x4d01, 64 * 1024, 256) - FLAGS(USE_CLSR) - NO_SFDP_FLAGS(SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, + NO_SFDP_FLAGS(SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) + MFR_FLAGS(USE_CLSR) + }, { "s25sl004a", INFO(0x010212, 0, 64 * 1024, 8) }, { "s25sl008a", INFO(0x010213, 0, 64 * 1024, 16) }, { "s25sl016a", INFO(0x010214, 0, 64 * 1024, 32) }, @@ -370,7 +383,7 @@ static void spansion_nor_late_init(struct spi_nor *nor) nor->mtd.erasesize = nor->info->sector_size; } - if (nor->flags & SNOR_F_USE_CLSR) + if (nor->info->mfr_flags & USE_CLSR) nor->params->ready = spi_nor_sr_ready_and_clear; } From e8fd3b4b266b44df207af253d0c8de68c5a09ca9 Mon Sep 17 00:00:00 2001 From: Michael Walle Date: Wed, 23 Feb 2022 14:43:56 +0100 Subject: [PATCH 216/370] mtd: spi-nor: spansion: rename vendor specific functions and defines Drop the generic spi_nor prefix for all the spansion functions. Signed-off-by: Michael Walle Signed-off-by: Tudor Ambarus Tested-by: Pratyush Yadav # on mt35xu512aba, s28hs512t Reviewed-by: Pratyush Yadav Link: https://lore.kernel.org/r/20220223134358.1914798-31-michael@walle.cc --- drivers/mtd/spi-nor/spansion.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/drivers/mtd/spi-nor/spansion.c b/drivers/mtd/spi-nor/spansion.c index 32d3301ce385..f24e546e04a5 100644 --- a/drivers/mtd/spi-nor/spansion.c +++ b/drivers/mtd/spi-nor/spansion.c @@ -309,10 +309,10 @@ static const struct flash_info spansion_nor_parts[] = { }; /** - * spi_nor_clear_sr() - Clear the Status Register. + * spansion_nor_clear_sr() - Clear the Status Register. * @nor: pointer to 'struct spi_nor'. */ -static void spi_nor_clear_sr(struct spi_nor *nor) +static void spansion_nor_clear_sr(struct spi_nor *nor) { int ret; @@ -336,13 +336,13 @@ static void spi_nor_clear_sr(struct spi_nor *nor) } /** - * spi_nor_sr_ready_and_clear() - Query the Status Register to see if the flash - * is ready for new commands and clear it if there are any errors. + * spansion_nor_sr_ready_and_clear() - Query the Status Register to see if the + * flash is ready for new commands and clear it if there are any errors. * @nor: pointer to 'struct spi_nor'. * * Return: 1 if ready, 0 if not ready, -errno on errors. */ -static int spi_nor_sr_ready_and_clear(struct spi_nor *nor) +static int spansion_nor_sr_ready_and_clear(struct spi_nor *nor) { int ret; @@ -356,7 +356,7 @@ static int spi_nor_sr_ready_and_clear(struct spi_nor *nor) else dev_err(nor->dev, "Programming Error occurred\n"); - spi_nor_clear_sr(nor); + spansion_nor_clear_sr(nor); /* * WEL bit remains set to one when an erase or page program @@ -384,7 +384,7 @@ static void spansion_nor_late_init(struct spi_nor *nor) } if (nor->info->mfr_flags & USE_CLSR) - nor->params->ready = spi_nor_sr_ready_and_clear; + nor->params->ready = spansion_nor_sr_ready_and_clear; } static const struct spi_nor_fixups spansion_nor_fixups = { From e9d663a2a0193c82e4b4ffe066317ce16fc345e8 Mon Sep 17 00:00:00 2001 From: Michael Walle Date: Wed, 23 Feb 2022 14:43:57 +0100 Subject: [PATCH 217/370] mtd: spi-nor: slightly change code style in spi_nor_sr_ready() Now that there is almost no special case code left in spi_nor_sr_ready(), the return check looks odd. Move the function call closer to the return code checking. Signed-off-by: Michael Walle Signed-off-by: Tudor Ambarus Reviewed-by: Pratyush Yadav Link: https://lore.kernel.org/r/20220223134358.1914798-32-michael@walle.cc --- drivers/mtd/spi-nor/core.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/mtd/spi-nor/core.c b/drivers/mtd/spi-nor/core.c index f5a2f37d140e..9014008e60b3 100644 --- a/drivers/mtd/spi-nor/core.c +++ b/drivers/mtd/spi-nor/core.c @@ -563,8 +563,9 @@ int spi_nor_write_ear(struct spi_nor *nor, u8 ear) */ int spi_nor_sr_ready(struct spi_nor *nor) { - int ret = spi_nor_read_sr(nor, nor->bouncebuf); + int ret; + ret = spi_nor_read_sr(nor, nor->bouncebuf); if (ret) return ret; From 3c552889e431cf5c9680bb7de1c5d16bcc90b033 Mon Sep 17 00:00:00 2001 From: Michael Walle Date: Wed, 23 Feb 2022 14:43:58 +0100 Subject: [PATCH 218/370] mtd: spi-nor: renumber flags As we have deleted some flag, lets renumber them so there are no holes. Signed-off-by: Michael Walle Signed-off-by: Tudor Ambarus Reviewed-by: Pratyush Yadav Link: https://lore.kernel.org/r/20220223134358.1914798-33-michael@walle.cc --- drivers/mtd/spi-nor/core.h | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/drivers/mtd/spi-nor/core.h b/drivers/mtd/spi-nor/core.h index 2130a96e2044..b7fd760e3b47 100644 --- a/drivers/mtd/spi-nor/core.h +++ b/drivers/mtd/spi-nor/core.h @@ -12,20 +12,20 @@ #define SPI_NOR_MAX_ID_LEN 6 enum spi_nor_option_flags { - SNOR_F_HAS_SR_TB = BIT(1), - SNOR_F_NO_OP_CHIP_ERASE = BIT(2), - SNOR_F_BROKEN_RESET = BIT(5), - SNOR_F_4B_OPCODES = BIT(6), - SNOR_F_HAS_4BAIT = BIT(7), - SNOR_F_HAS_LOCK = BIT(8), - SNOR_F_HAS_16BIT_SR = BIT(9), - SNOR_F_NO_READ_CR = BIT(10), - SNOR_F_HAS_SR_TB_BIT6 = BIT(11), - SNOR_F_HAS_4BIT_BP = BIT(12), - SNOR_F_HAS_SR_BP3_BIT6 = BIT(13), - SNOR_F_IO_MODE_EN_VOLATILE = BIT(14), - SNOR_F_SOFT_RESET = BIT(15), - SNOR_F_SWP_IS_VOLATILE = BIT(16), + SNOR_F_HAS_SR_TB = BIT(0), + SNOR_F_NO_OP_CHIP_ERASE = BIT(1), + SNOR_F_BROKEN_RESET = BIT(2), + SNOR_F_4B_OPCODES = BIT(3), + SNOR_F_HAS_4BAIT = BIT(4), + SNOR_F_HAS_LOCK = BIT(5), + SNOR_F_HAS_16BIT_SR = BIT(6), + SNOR_F_NO_READ_CR = BIT(7), + SNOR_F_HAS_SR_TB_BIT6 = BIT(8), + SNOR_F_HAS_4BIT_BP = BIT(9), + SNOR_F_HAS_SR_BP3_BIT6 = BIT(10), + SNOR_F_IO_MODE_EN_VOLATILE = BIT(11), + SNOR_F_SOFT_RESET = BIT(12), + SNOR_F_SWP_IS_VOLATILE = BIT(13), }; struct spi_nor_read_command { From f4676c8ec39689c6370bd58f4266c5c613de2a28 Mon Sep 17 00:00:00 2001 From: Joel Stanley Date: Mon, 28 Feb 2022 16:58:40 +1030 Subject: [PATCH 219/370] ipmi: kcs: aspeed: Remove old bindings support It's been a few releases since we depreciated the "v1" bindings. Remove support from the driver as all known device trees have been updated to use the new bindings. Signed-off-by: Joel Stanley Message-Id: <20220228062840.449215-1-joel@jms.id.au> Signed-off-by: Corey Minyard --- drivers/char/ipmi/kcs_bmc_aspeed.c | 68 +++--------------------------- 1 file changed, 7 insertions(+), 61 deletions(-) diff --git a/drivers/char/ipmi/kcs_bmc_aspeed.c b/drivers/char/ipmi/kcs_bmc_aspeed.c index b555286016b1..cdc88cde1e9a 100644 --- a/drivers/char/ipmi/kcs_bmc_aspeed.c +++ b/drivers/char/ipmi/kcs_bmc_aspeed.c @@ -128,11 +128,6 @@ struct aspeed_kcs_bmc { } obe; }; -struct aspeed_kcs_of_ops { - int (*get_channel)(struct platform_device *pdev); - int (*get_io_address)(struct platform_device *pdev, u32 addrs[2]); -}; - static inline struct aspeed_kcs_bmc *to_aspeed_kcs_bmc(struct kcs_bmc_device *kcs_bmc) { return container_of(kcs_bmc, struct aspeed_kcs_bmc, kcs_bmc); @@ -475,38 +470,7 @@ static const struct kcs_ioreg ast_kcs_bmc_ioregs[KCS_CHANNEL_MAX] = { { .idr = LPC_IDR4, .odr = LPC_ODR4, .str = LPC_STR4 }, }; -static int aspeed_kcs_of_v1_get_channel(struct platform_device *pdev) -{ - struct device_node *np; - u32 channel; - int rc; - - np = pdev->dev.of_node; - - rc = of_property_read_u32(np, "kcs_chan", &channel); - if ((rc != 0) || (channel == 0 || channel > KCS_CHANNEL_MAX)) { - dev_err(&pdev->dev, "no valid 'kcs_chan' configured\n"); - return -EINVAL; - } - - return channel; -} - -static int -aspeed_kcs_of_v1_get_io_address(struct platform_device *pdev, u32 addrs[2]) -{ - int rc; - - rc = of_property_read_u32(pdev->dev.of_node, "kcs_addr", addrs); - if (rc || addrs[0] > 0xffff) { - dev_err(&pdev->dev, "no valid 'kcs_addr' configured\n"); - return -EINVAL; - } - - return 1; -} - -static int aspeed_kcs_of_v2_get_channel(struct platform_device *pdev) +static int aspeed_kcs_of_get_channel(struct platform_device *pdev) { struct device_node *np; struct kcs_ioreg ioreg; @@ -535,12 +499,11 @@ static int aspeed_kcs_of_v2_get_channel(struct platform_device *pdev) if (!memcmp(&ast_kcs_bmc_ioregs[i], &ioreg, sizeof(ioreg))) return i + 1; } - return -EINVAL; } static int -aspeed_kcs_of_v2_get_io_address(struct platform_device *pdev, u32 addrs[2]) +aspeed_kcs_of_get_io_address(struct platform_device *pdev, u32 addrs[2]) { int rc; @@ -567,7 +530,6 @@ aspeed_kcs_of_v2_get_io_address(struct platform_device *pdev, u32 addrs[2]) static int aspeed_kcs_probe(struct platform_device *pdev) { - const struct aspeed_kcs_of_ops *ops; struct kcs_bmc_device *kcs_bmc; struct aspeed_kcs_bmc *priv; struct device_node *np; @@ -585,15 +547,11 @@ static int aspeed_kcs_probe(struct platform_device *pdev) return -ENODEV; } - ops = of_device_get_match_data(&pdev->dev); - if (!ops) - return -EINVAL; - - channel = ops->get_channel(pdev); + channel = aspeed_kcs_of_get_channel(pdev); if (channel < 0) return channel; - nr_addrs = ops->get_io_address(pdev, addrs); + nr_addrs = aspeed_kcs_of_get_io_address(pdev, addrs); if (nr_addrs < 0) return nr_addrs; @@ -678,22 +636,10 @@ static int aspeed_kcs_remove(struct platform_device *pdev) return 0; } -static const struct aspeed_kcs_of_ops of_v1_ops = { - .get_channel = aspeed_kcs_of_v1_get_channel, - .get_io_address = aspeed_kcs_of_v1_get_io_address, -}; - -static const struct aspeed_kcs_of_ops of_v2_ops = { - .get_channel = aspeed_kcs_of_v2_get_channel, - .get_io_address = aspeed_kcs_of_v2_get_io_address, -}; - static const struct of_device_id ast_kcs_bmc_match[] = { - { .compatible = "aspeed,ast2400-kcs-bmc", .data = &of_v1_ops }, - { .compatible = "aspeed,ast2500-kcs-bmc", .data = &of_v1_ops }, - { .compatible = "aspeed,ast2400-kcs-bmc-v2", .data = &of_v2_ops }, - { .compatible = "aspeed,ast2500-kcs-bmc-v2", .data = &of_v2_ops }, - { .compatible = "aspeed,ast2600-kcs-bmc", .data = &of_v2_ops }, + { .compatible = "aspeed,ast2400-kcs-bmc-v2" }, + { .compatible = "aspeed,ast2500-kcs-bmc-v2" }, + { .compatible = "aspeed,ast2600-kcs-bmc" }, { } }; MODULE_DEVICE_TABLE(of, ast_kcs_bmc_match); From 73b9f6389e5cc2980ca892b9cf048659e6a98d28 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Fri, 28 Jan 2022 10:07:35 +0100 Subject: [PATCH 220/370] dt-bindings: timer: sifive,clint: Fix number of interrupts The number of interrupts lacks an upper bound, thus assuming one, causing properly grouped "interrupts-extended" properties to be flagged as an error by "make dtbs_check". Fix this by adding the missing "maxItems", using the architectural maximum of 4095 interrupts. Signed-off-by: Geert Uytterhoeven Acked-by: Rob Herring Reviewed-by: Anup Patel Signed-off-by: Rob Herring Link: https://lore.kernel.org/r/e6a4c5b20d2acb52125d7d6e6c7e3694d7cb182c.1643360652.git.geert@linux-m68k.org --- Documentation/devicetree/bindings/timer/sifive,clint.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/Documentation/devicetree/bindings/timer/sifive,clint.yaml b/Documentation/devicetree/bindings/timer/sifive,clint.yaml index 8d5f4687add9..fe4b73c3f269 100644 --- a/Documentation/devicetree/bindings/timer/sifive,clint.yaml +++ b/Documentation/devicetree/bindings/timer/sifive,clint.yaml @@ -44,6 +44,7 @@ properties: interrupts-extended: minItems: 1 + maxItems: 4095 additionalProperties: false From 4eb7b1339c23517922b4e3710abadb153f75336f Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Fri, 28 Jan 2022 10:07:36 +0100 Subject: [PATCH 221/370] dt-bindings: timer: sifive,clint: Group interrupt tuples To improve human readability and enable automatic validation, the tuples in "interrupts-extended" properties should be grouped using angle brackets. Signed-off-by: Geert Uytterhoeven Reviewed-by: Rob Herring Reviewed-by: Anup Patel Signed-off-by: Rob Herring Link: https://lore.kernel.org/r/62bf4ee6613550c07a99d4bd226ab0d33acae4c4.1643360652.git.geert@linux-m68k.org --- Documentation/devicetree/bindings/timer/sifive,clint.yaml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Documentation/devicetree/bindings/timer/sifive,clint.yaml b/Documentation/devicetree/bindings/timer/sifive,clint.yaml index fe4b73c3f269..e64f46339079 100644 --- a/Documentation/devicetree/bindings/timer/sifive,clint.yaml +++ b/Documentation/devicetree/bindings/timer/sifive,clint.yaml @@ -57,10 +57,10 @@ examples: - | timer@2000000 { compatible = "sifive,fu540-c000-clint", "sifive,clint0"; - interrupts-extended = <&cpu1intc 3 &cpu1intc 7 - &cpu2intc 3 &cpu2intc 7 - &cpu3intc 3 &cpu3intc 7 - &cpu4intc 3 &cpu4intc 7>; + interrupts-extended = <&cpu1intc 3>, <&cpu1intc 7>, + <&cpu2intc 3>, <&cpu2intc 7>, + <&cpu3intc 3>, <&cpu3intc 7>, + <&cpu4intc 3>, <&cpu4intc 7>; reg = <0x2000000 0x10000>; }; ... From 8e4296c286ed7a3b69e619d5069493bdcc9a2b25 Mon Sep 17 00:00:00 2001 From: Frank Rowand Date: Tue, 1 Feb 2022 12:14:13 -0600 Subject: [PATCH 222/370] of: unittest: add program to process EXPECT messages If unittest detects a problem it will print a warning or error message to the console. Unittest also triggers warning and error messages from other kernel code as a result of intentionally bad unittest data. This has led to confusion as to whether the triggered messages are an expected result of a test or whether there is a real problem that is independent of unittest. EXPECT messages were added to unittest to report each triggered message that is expected, resulting in verbose console output. scripts/dtc/of_unittest is a new program that processes the EXPECT messages to determine whether the triggered messages occurred and also removes the excess verbosity of the EXPECT messages. More information is available from 'scripts/dtc/of_unittest_expect --help'. Signed-off-by: Frank Rowand Signed-off-by: Rob Herring Link: https://lore.kernel.org/r/20220201181413.2719955-1-frowand.list@gmail.com --- Documentation/devicetree/of_unittest.rst | 27 +- scripts/dtc/of_unittest_expect | 408 +++++++++++++++++++++++ 2 files changed, 432 insertions(+), 3 deletions(-) create mode 100755 scripts/dtc/of_unittest_expect diff --git a/Documentation/devicetree/of_unittest.rst b/Documentation/devicetree/of_unittest.rst index 2afe41a37148..8864b52d1195 100644 --- a/Documentation/devicetree/of_unittest.rst +++ b/Documentation/devicetree/of_unittest.rst @@ -24,7 +24,28 @@ from the unflattened device tree data structure. This interface is used by most of the device drivers in various use cases. -2. Test-data +2. Verbose Output (EXPECT) +========================== + +If unittest detects a problem it will print a warning or error message to +the console. Unittest also triggers warning and error messages from other +kernel code as a result of intentionally bad unittest data. This has led +to confusion as to whether the triggered messages are an expected result +of a test or whether there is a real problem that is independent of unittest. + +'EXPECT \ : text' (begin) and 'EXPECT / : text' (end) messages have been +added to unittest to report that a warning or error is expected. The +begin is printed before triggering the warning or error, and the end is +printed after triggering the warning or error. + +The EXPECT messages result in very noisy console messages that are difficult +to read. The script scripts/dtc/of_unittest_expect was created to filter +this verbosity and highlight mismatches between triggered warnings and +errors vs expected warnings and errors. More information is available +from 'scripts/dtc/of_unittest_expect --help'. + + +3. Test-data ============ The Device Tree Source file (drivers/of/unittest-data/testcases.dts) contains @@ -56,7 +77,7 @@ The assembly file is compiled into an object file (testcases.dtb.o), and is linked into the kernel image. -2.1. Adding the test data +3.1. Adding the test data ------------------------- Un-flattened device tree structure: @@ -191,7 +212,7 @@ properties are updated to the live tree's node by calling the function update_node_properties(). -2.2. Removing the test data +3.2. Removing the test data --------------------------- Once the test case execution is complete, selftest_data_remove is called in diff --git a/scripts/dtc/of_unittest_expect b/scripts/dtc/of_unittest_expect new file mode 100755 index 000000000000..96b12d9ea606 --- /dev/null +++ b/scripts/dtc/of_unittest_expect @@ -0,0 +1,408 @@ +#!/usr/bin/perl +# SPDX-License-Identifier: GPL-2.0 +# +# Copyright 2020, 2022 Sony Corporation +# +# Author: Frank Rowand + +# This program is meant to be an aid to reading the verbose output of +# on the console log that results from executing the Linux kernel +# devicetree unittest (drivers/of/unitest.c). + +$VUFX = "220201a"; + +use strict 'refs'; +use strict subs; + +use Getopt::Long; +use Text::Wrap; + +# strip off everything before final "/" +(undef, $script_name) = split(/^.*\//, $0); + +# following /usr/include/sysexits.h +$EX_OK=0; +$EX_USAGE=64; + + +#______________________________________________________________________________ +sub compare { + my ($expect, $got) = @_; + my $expect_next; + my $expect_next_lit; + my $got_next; + my $type; + + while ($expect) { + + ($expect_next, $type) = split(/<>/, $type); + $expect =~ s/^.*?>>//; # '?' is non-greedy, minimal match + + # literal, ignore all metacharacters when used in a regex + $expect_next_lit = quotemeta($expect_next); + + $got_next = $got; + $got_next =~ s/^($expect_next_lit).*/\1/; + $got =~ s/^$expect_next_lit//; + + if ($expect_next ne $got_next) { + return 0; + } + + if ($type eq "int") { + if ($got =~ /^[+-]*[0-9]+/) { + $got =~ s/^[+-]*[0-9]+//; + } else { + return 0; + } + } elsif ($type eq "hex") { + if ($got =~ /^(0x)*[0-9a-f]+/) { + $got =~ s/^(0x)*[0-9a-f]+//; + } else { + return 0; + } + } elsif ($type eq "") { + if ($expect_next ne $got_next) { + return 0; + } else { + return 1; + } + } else { + $internal_err++; + print "** ERROR: special pattern not recognized: <<$type>>, CONSOLE_LOG line: $.\n"; + return 0; + } + + } + + # should not get here + $internal_err++; + print "** ERROR: $script_name internal error, at end of compare(), CONSOLE_LOG line: $.\n"; + + return 0; +} + + +#______________________________________________________________________________ +sub usage { + +# ***** when editing, be careful to not put tabs in the string printed: + + print STDERR +" +usage: + + $script_name CONSOLE_LOG + + -h print program usage + --help print program usage + --hide-expect suppress output of EXPECTed lines + --line-num report line number of CONSOLE_LOG + --no-expect-stats do not report EXPECT statistics + --no-strip-ts do not strip leading console timestamps + --verbose do not suppress EXPECT begin and end lines + --version print program version and exit + + + Process a console log for EXPECTed test related messages to either + highlight expected devicetree unittest related messages or suppress + the messages. Leading console timestamps will be stripped. + + Various unittests may trigger kernel messages from outside the + unittest code. The unittest annotates that it expects the message + to occur with an 'EXPECT \\ : text' (begin) before triggering the + message, and an 'EXPECT / : text' (end) after triggering the message. + + If an expected message does not occur, that will be reported. + + For each expected message, the 'EXPECT \\ : text' (begin) and + 'EXPECT / : text' (end), 'text' will contain the message text. + + If 'EXPECT \\' (begin) and 'EXPECT /' (end) lines do not contain + matching 'text', that will be reported. + + If EXPECT lines are nested, 'EXPECT /' (end) lines must be in the + reverse order of the corresponding 'EXPECT \\' (begin) lines. + + 'EXPECT \\ : text' (begin) and 'EXPECT / : text' (end) lines can + contain special patterns in 'text': + + <> matches: [+-]*[0-9]+ + <> matches: (0x)*[0-9a-f]+ + + 'EXPECT \\' (begin) and 'EXPECT /' (end) lines are suppressed. + + A prefix is added to every line of output: + + 'ok ' Line matches an enclosing EXPECT begin/end pair + + '** ' Line reports $script_name warning or error + + '-> ' Line reports start or end of the unittests + + '>> ' Line reports a unittest test FAIL + + ' ' Lines that are not otherwise prefixed + + Issues detected in CONSOLE_LOG are reported to STDOUT, not to STDERR. + + Known Issues: + + --line-num causes the CONSOLE_LOG line number to be printed in 4 columns. + If CONSOLE_LOG contains more than 9999 lines then more columns will be + used to report the line number for lines greater than 9999 (eg for + lines 10000 - 99999, 5 columns will be used). +"; + + return {}; +} + +#______________________________________________________________________________ +#______________________________________________________________________________ + +if (!GetOptions( + "h" => \$help, + "help" => \$help, + "hide-expect" => \$hide_expect, + "line-num" => \$print_line_num, + "no-expect-stats" => \$no_expect_stats, + "no-strip-ts" => \$no_strip_ts, + "verbose" => \$verbose, + "version" => \$version, + )) { + print STDERR "\n"; + print STDERR "ERROR processing command line options\n"; + print STDERR "\n"; + print STDERR "For help, type '$script_name --help'\n"; + print STDERR "\n"; + + exit $EX_OK; +} + + +if ($no_strip_ts) { + $strip_ts = 1; + $no_strip_ts = 0; +} else { + $strip_ts = 0; + $no_strip_ts = 1; +} + + +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +if ($help){ + + &usage; + + exit $EX_OK; +} + + +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +if ($version) { + print STDERR "\n$script_name $VUFX\n\n"; + print STDERR "\n"; + + exit $EX_OK; +} + + +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +if ($#ARGV != 0) { + + # Limit input files to exactly one. + # + # 'while ($line = ) {' in the code below supports multiple file + # names on the command line, but the EXPECT statistics are reported + # once for all input - it is not an expected use case to generate one + # set of statistics for multiple input files. + + print STDERR "\n"; + print STDERR "Required arguments: CONSOLE_LOG\n"; + print STDERR "\n"; + + exit $EX_USAGE; +} + + +#______________________________________________________________________________ + +# Patterns to match 'EXPECT \ : ' (begin) and 'EXPECT / : ' (end) +# +# $exp_* are used as regex match patterns, +# so '\\\\' in $exp_begin matches a single '\' +# quotemeta() does not do the right thing in this case +# +# $pr_fmt is the prefix that unittest prints for every message + +$pr_fmt = "### dt-test ### "; +$exp_begin = "${pr_fmt}EXPECT \\\\ : "; +$exp_end = "${pr_fmt}EXPECT / : "; + + +$line_num = ""; +$timestamp = ""; + +LINE: +while ($line = ) { + + chomp $line; + + $prefix = " "; ## 2 characters + + + if ($strip_ts) { + + $timestamp = $line; + + if ($timestamp =~ /^\[\s*[0-9]+\.[0-9]*\] /) { + ($timestamp, $null) = split(/]/, $line); + $timestamp = $timestamp . "] "; + + } else { + $timestamp = ""; + } + } + + $line =~ s/^\[\s*[0-9]+\.[0-9]*\] //; + + + # ----- find EXPECT begin + + if ($line =~ /^\s*$exp_begin/) { + $data = $line; + $data =~ s/^\s*$exp_begin//; + push @begin, $data; + + if ($verbose) { + if ($print_line_num) { + $line_num = sprintf("%4s ", $.); + } + printf "%s %s%s%s\n", $prefix, $line_num, $timestamp, $line; + } + + next LINE; + } + + + # ----- find EXPECT end + + if ($line =~ /^\s*$exp_end/) { + $data = $line; + $data =~ s/^\s*$exp_end//; + + if ($verbose) { + if ($print_line_num) { + $line_num = sprintf("%4s ", $.); + } + printf "%s %s%s%s\n", $prefix, $line_num, $timestamp, $line; + } + + $found = 0; + $no_begin = 0; + if (@found_or_begin > 0) { + $begin = pop @found_or_begin; + if (compare($data, $begin)) { + $found = 1; + } + } elsif (@begin > 0) { + $begin = pop @begin; + } else { + $no_begin = 1; + } + + if ($no_begin) { + + $expect_missing_begin++; + print "** ERROR: EXPECT end without any EXPECT begin:\n"; + print " end ---> $line\n"; + + } elsif (! $found) { + + if ($print_line_num) { + $line_num = sprintf("%4s ", $.); + } + + $expect_not_found++; + printf "** %s%s$script_name WARNING - not found ---> %s\n", + $line_num, $timestamp, $data; + + } elsif (! compare($data, $begin)) { + + $expect_missing_end++; + print "** ERROR: EXPECT end does not match EXPECT begin:\n"; + print " begin -> $begin\n"; + print " end ---> $line\n"; + + } else { + + $expect_found++; + + } + + next LINE; + } + + + # ----- not an EXPECT line + + if (($line =~ /^${pr_fmt}start of unittest - you will see error messages$/) || + ($line =~ /^${pr_fmt}end of unittest - [0-9]+ passed, [0-9]+ failed$/ ) ) { + $prefix = "->"; # 2 characters + } elsif ($line =~ /^${pr_fmt}FAIL /) { + $unittest_fail++; + $prefix = ">>"; # 2 characters + } + + $found = 0; + foreach $begin (@begin) { + if (compare($begin, $line)) { + $found = 1; + last; + } + } + + if ($found) { + $begin = shift @begin; + while (! compare($begin, $line)) { + push @found_or_begin, $begin; + $begin = shift @begin; + } + push @found_or_begin, $line; + + if ($hide_expect) { + $suppress_line = 1; + next LINE; + } + $prefix = "ok"; # 2 characters + } + + + if ($print_line_num) { + $line_num = sprintf("%4s ", $.); + } + + printf "%s %s%s%s\n", $prefix, $line_num, $timestamp, $line; +} + +if (! $no_expect_stats) { + print "\n"; + print "** EXPECT statistics:\n"; + print "**\n"; + printf "** EXPECT found : %4i\n", $expect_found; + printf "** EXPECT not found : %4i\n", $expect_not_found; + printf "** missing EXPECT begin : %4i\n", $expect_missing_begin; + printf "** missing EXPECT end : %4i\n", $expect_missing_end; + printf "** unittest FAIL : %4i\n", $unittest_fail; + printf "** internal error : %4i\n", $internal_err; +} + +if (@begin) { + print "** ERROR: EXPECT begin without any EXPECT end:\n"; + print " This list may be misleading.\n"; + foreach $begin (@begin) { + print " begin ---> $begin\n"; + } +} From 68ea1b2c3386ad484b7daa4a64fa7b3be661607f Mon Sep 17 00:00:00 2001 From: Sebastian Andrzej Siewior Date: Fri, 11 Feb 2022 19:14:55 +0100 Subject: [PATCH 223/370] i2c: core: Use generic_handle_irq_safe() in i2c_handle_smbus_host_notify(). The i2c-i801 driver invokes i2c_handle_smbus_host_notify() from his interrupt service routine. On PREEMPT_RT i2c-i801's handler is forced threaded with enabled interrupts which leads to a warning by handle_irq_event_percpu() assuming that irq_default_primary_handler() enabled interrupts. i2c-i801's interrupt handler can't be made non-threaded because the interrupt line is shared with other devices. Use generic_handle_irq_safe() which can invoked with disabled and enabled interrupts. Reported-by: Michael Below Link: https://bugs.debian.org/1002537 Signed-off-by: Sebastian Andrzej Siewior Reviewed-by: Oleksandr Natalenko Signed-off-by: Wolfram Sang --- drivers/i2c/i2c-core-base.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/i2c/i2c-core-base.c b/drivers/i2c/i2c-core-base.c index 32a45260c1f3..d43db2c3876e 100644 --- a/drivers/i2c/i2c-core-base.c +++ b/drivers/i2c/i2c-core-base.c @@ -1424,7 +1424,7 @@ int i2c_handle_smbus_host_notify(struct i2c_adapter *adap, unsigned short addr) if (irq <= 0) return -ENXIO; - generic_handle_irq(irq); + generic_handle_irq_safe(irq); return 0; } From a5ea32579f08b9f612e3091467d01b6503ba24dd Mon Sep 17 00:00:00 2001 From: Sebastian Andrzej Siewior Date: Fri, 11 Feb 2022 19:14:56 +0100 Subject: [PATCH 224/370] i2c: cht-wc: Use generic_handle_irq_safe(). Instead of manually disabling interrupts before invoking use generic_handle_irq_safe() which can be invoked with enabled and disabled interrupts. Signed-off-by: Sebastian Andrzej Siewior Reviewed-by: Hans de Goede Acked-by: Wolfram Sang Signed-off-by: Wolfram Sang --- drivers/i2c/busses/i2c-cht-wc.c | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/drivers/i2c/busses/i2c-cht-wc.c b/drivers/i2c/busses/i2c-cht-wc.c index 1cf68f85b2e1..8ccf0c928bb4 100644 --- a/drivers/i2c/busses/i2c-cht-wc.c +++ b/drivers/i2c/busses/i2c-cht-wc.c @@ -99,15 +99,8 @@ static irqreturn_t cht_wc_i2c_adap_thread_handler(int id, void *data) * interrupt handler as well, so running the client irq handler from * this thread will cause things to lock up. */ - if (reg & CHT_WC_EXTCHGRIRQ_CLIENT_IRQ) { - /* - * generic_handle_irq expects local IRQs to be disabled - * as normally it is called from interrupt context. - */ - local_irq_disable(); - generic_handle_irq(adap->client_irq); - local_irq_enable(); - } + if (reg & CHT_WC_EXTCHGRIRQ_CLIENT_IRQ) + generic_handle_irq_safe(adap->client_irq); return IRQ_HANDLED; } From 36c11fee4fb5e5b4bf320d65957bbc21da9cd6d3 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Thu, 24 Feb 2022 13:31:21 +0100 Subject: [PATCH 225/370] dt-bindings: i2c: microchip,corei2c: Fix indentation of compatible items make dt_binding_check: Documentation/devicetree/bindings/i2c/microchip,corei2c.yaml:19:9: [warning] wrong indentation: expected 10 but found 8 (indentation) Fixes: f1bd6661946b20d1 ("dt-bindings: i2c: add bindings for microchip mpfs i2c") Signed-off-by: Geert Uytterhoeven Acked-by: Rob Herring Acked-by: Conor Dooley Signed-off-by: Wolfram Sang --- Documentation/devicetree/bindings/i2c/microchip,corei2c.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Documentation/devicetree/bindings/i2c/microchip,corei2c.yaml b/Documentation/devicetree/bindings/i2c/microchip,corei2c.yaml index c8e605fbb8a6..7bad4b946a34 100644 --- a/Documentation/devicetree/bindings/i2c/microchip,corei2c.yaml +++ b/Documentation/devicetree/bindings/i2c/microchip,corei2c.yaml @@ -16,8 +16,8 @@ properties: compatible: oneOf: - items: - - const: microchip,mpfs-i2c # Microchip PolarFire SoC compatible SoCs - - const: microchip,corei2c-rtl-v7 # Microchip Fabric based i2c IP core + - const: microchip,mpfs-i2c # Microchip PolarFire SoC compatible SoCs + - const: microchip,corei2c-rtl-v7 # Microchip Fabric based i2c IP core - const: microchip,corei2c-rtl-v7 # Microchip Fabric based i2c IP core reg: From da2e86c0bd7bc6fdb116dd03c041cf816205cbdc Mon Sep 17 00:00:00 2001 From: Lad Prabhakar Date: Wed, 9 Feb 2022 23:22:32 +0000 Subject: [PATCH 226/370] i2c: riic: Simplify reset handling Read reset phandle as optional instead of exclusive so that all the DT's passing the reset phandle can be used to assert/deassert the reset line. With this change we don't have to differentiate the RZ/G2L SoC. With the above changes we no longer need the "renesas,riic-r9a07g044" compatible string, so drop it from riic_i2c_dt_ids[]. No changes are required to the r9a07g044.dtsi as we already have "renesas,riic-rz" as a fallback compatible string. While at it, check the return code of reset_control_deassert() as it might fail and also add a devres action to assert the reset line. Signed-off-by: Lad Prabhakar Reviewed-by: Geert Uytterhoeven Signed-off-by: Wolfram Sang --- drivers/i2c/busses/i2c-riic.c | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/drivers/i2c/busses/i2c-riic.c b/drivers/i2c/busses/i2c-riic.c index 8dfd27dc6149..cded77e06670 100644 --- a/drivers/i2c/busses/i2c-riic.c +++ b/drivers/i2c/busses/i2c-riic.c @@ -88,11 +88,6 @@ #define RIIC_INIT_MSG -1 -enum riic_type { - RIIC_RZ_A, - RIIC_RZ_G2L, -}; - struct riic_dev { void __iomem *base; u8 *buf; @@ -396,6 +391,11 @@ static struct riic_irq_desc riic_irqs[] = { { .res_num = 5, .isr = riic_tend_isr, .name = "riic-nack" }, }; +static void riic_reset_control_assert(void *data) +{ + reset_control_assert(data); +} + static int riic_i2c_probe(struct platform_device *pdev) { struct riic_dev *riic; @@ -404,7 +404,6 @@ static int riic_i2c_probe(struct platform_device *pdev) struct i2c_timings i2c_t; struct reset_control *rstc; int i, ret; - enum riic_type type; riic = devm_kzalloc(&pdev->dev, sizeof(*riic), GFP_KERNEL); if (!riic) @@ -421,16 +420,18 @@ static int riic_i2c_probe(struct platform_device *pdev) return PTR_ERR(riic->clk); } - type = (enum riic_type)of_device_get_match_data(&pdev->dev); - if (type == RIIC_RZ_G2L) { - rstc = devm_reset_control_get_exclusive(&pdev->dev, NULL); - if (IS_ERR(rstc)) { - dev_err(&pdev->dev, "Error: missing reset ctrl\n"); - return PTR_ERR(rstc); - } + rstc = devm_reset_control_get_optional_exclusive(&pdev->dev, NULL); + if (IS_ERR(rstc)) + return dev_err_probe(&pdev->dev, PTR_ERR(rstc), + "Error: missing reset ctrl\n"); - reset_control_deassert(rstc); - } + ret = reset_control_deassert(rstc); + if (ret) + return ret; + + ret = devm_add_action_or_reset(&pdev->dev, riic_reset_control_assert, rstc); + if (ret) + return ret; for (i = 0; i < ARRAY_SIZE(riic_irqs); i++) { ret = platform_get_irq(pdev, riic_irqs[i].res_num); @@ -492,8 +493,7 @@ static int riic_i2c_remove(struct platform_device *pdev) } static const struct of_device_id riic_i2c_dt_ids[] = { - { .compatible = "renesas,riic-r9a07g044", .data = (void *)RIIC_RZ_G2L }, - { .compatible = "renesas,riic-rz", .data = (void *)RIIC_RZ_A }, + { .compatible = "renesas,riic-rz", }, { /* Sentinel */ }, }; From d8703554f4dea9775417525b22b3d65ed1c6b16e Mon Sep 17 00:00:00 2001 From: Vinod Koul Date: Mon, 21 Feb 2022 15:57:16 +0530 Subject: [PATCH 227/370] i2c: qcom-geni: Add support for GPI DMA QUP Serial engines supports data transfers thru FIFO mode, SE DMA mode and lastly GPI DMA mode. Former two are already supported and this adds supports for the last mode. In GPI DMA mode, the firmware is issued commands by driver to perform DMA and setup the serial port. Signed-off-by: Vinod Koul Reviewed-by: Bjorn Andersson Signed-off-by: Wolfram Sang --- drivers/i2c/busses/i2c-qcom-geni.c | 308 ++++++++++++++++++++++++++--- 1 file changed, 280 insertions(+), 28 deletions(-) diff --git a/drivers/i2c/busses/i2c-qcom-geni.c b/drivers/i2c/busses/i2c-qcom-geni.c index 6d635a7c104c..fc1dcc19f2a1 100644 --- a/drivers/i2c/busses/i2c-qcom-geni.c +++ b/drivers/i2c/busses/i2c-qcom-geni.c @@ -3,7 +3,9 @@ #include #include +#include #include +#include #include #include #include @@ -48,6 +50,9 @@ #define LOW_COUNTER_SHFT 10 #define CYCLE_COUNTER_MSK GENMASK(9, 0) +#define I2C_PACK_TX BIT(0) +#define I2C_PACK_RX BIT(1) + enum geni_i2c_err_code { GP_IRQ0, NACK, @@ -89,6 +94,9 @@ struct geni_i2c_dev { void *dma_buf; size_t xfer_len; dma_addr_t dma_addr; + struct dma_chan *tx_c; + struct dma_chan *rx_c; + bool gpi_mode; }; struct geni_i2c_err_log { @@ -456,12 +464,207 @@ static int geni_i2c_tx_one_msg(struct geni_i2c_dev *gi2c, struct i2c_msg *msg, return gi2c->err; } +static void i2c_gpi_cb_result(void *cb, const struct dmaengine_result *result) +{ + struct geni_i2c_dev *gi2c = cb; + + if (result->result != DMA_TRANS_NOERROR) { + dev_err(gi2c->se.dev, "DMA txn failed:%d\n", result->result); + gi2c->err = -EIO; + } else if (result->residue) { + dev_dbg(gi2c->se.dev, "DMA xfer has pending: %d\n", result->residue); + } + + complete(&gi2c->done); +} + +static void geni_i2c_gpi_unmap(struct geni_i2c_dev *gi2c, struct i2c_msg *msg, + void *tx_buf, dma_addr_t tx_addr, + void *rx_buf, dma_addr_t rx_addr) +{ + if (tx_buf) { + dma_unmap_single(gi2c->se.dev->parent, tx_addr, msg->len, DMA_TO_DEVICE); + i2c_put_dma_safe_msg_buf(tx_buf, msg, false); + } + + if (rx_buf) { + dma_unmap_single(gi2c->se.dev->parent, rx_addr, msg->len, DMA_FROM_DEVICE); + i2c_put_dma_safe_msg_buf(rx_buf, msg, false); + } +} + +static int geni_i2c_gpi(struct geni_i2c_dev *gi2c, struct i2c_msg *msg, + struct dma_slave_config *config, dma_addr_t *dma_addr_p, + void **buf, unsigned int op, struct dma_chan *dma_chan) +{ + struct gpi_i2c_config *peripheral; + unsigned int flags; + void *dma_buf; + dma_addr_t addr; + enum dma_data_direction map_dirn; + enum dma_transfer_direction dma_dirn; + struct dma_async_tx_descriptor *desc; + int ret; + + peripheral = config->peripheral_config; + + dma_buf = i2c_get_dma_safe_msg_buf(msg, 1); + if (!dma_buf) + return -ENOMEM; + + if (op == I2C_WRITE) + map_dirn = DMA_TO_DEVICE; + else + map_dirn = DMA_FROM_DEVICE; + + addr = dma_map_single(gi2c->se.dev->parent, dma_buf, msg->len, map_dirn); + if (dma_mapping_error(gi2c->se.dev->parent, addr)) { + i2c_put_dma_safe_msg_buf(dma_buf, msg, false); + return -ENOMEM; + } + + /* set the length as message for rx txn */ + peripheral->rx_len = msg->len; + peripheral->op = op; + + ret = dmaengine_slave_config(dma_chan, config); + if (ret) { + dev_err(gi2c->se.dev, "dma config error: %d for op:%d\n", ret, op); + goto err_config; + } + + peripheral->set_config = 0; + peripheral->multi_msg = true; + flags = DMA_PREP_INTERRUPT | DMA_CTRL_ACK; + + if (op == I2C_WRITE) + dma_dirn = DMA_MEM_TO_DEV; + else + dma_dirn = DMA_DEV_TO_MEM; + + desc = dmaengine_prep_slave_single(dma_chan, addr, msg->len, dma_dirn, flags); + if (!desc) { + dev_err(gi2c->se.dev, "prep_slave_sg failed\n"); + ret = -EIO; + goto err_config; + } + + desc->callback_result = i2c_gpi_cb_result; + desc->callback_param = gi2c; + + dmaengine_submit(desc); + *dma_addr_p = addr; + + return 0; + +err_config: + dma_unmap_single(gi2c->se.dev->parent, addr, msg->len, map_dirn); + i2c_put_dma_safe_msg_buf(dma_buf, msg, false); + return ret; +} + +static int geni_i2c_gpi_xfer(struct geni_i2c_dev *gi2c, struct i2c_msg msgs[], int num) +{ + struct dma_slave_config config = {}; + struct gpi_i2c_config peripheral = {}; + int i, ret = 0, timeout; + dma_addr_t tx_addr, rx_addr; + void *tx_buf = NULL, *rx_buf = NULL; + const struct geni_i2c_clk_fld *itr = gi2c->clk_fld; + + config.peripheral_config = &peripheral; + config.peripheral_size = sizeof(peripheral); + + peripheral.pack_enable = I2C_PACK_TX | I2C_PACK_RX; + peripheral.cycle_count = itr->t_cycle_cnt; + peripheral.high_count = itr->t_high_cnt; + peripheral.low_count = itr->t_low_cnt; + peripheral.clk_div = itr->clk_div; + peripheral.set_config = 1; + peripheral.multi_msg = false; + + for (i = 0; i < num; i++) { + gi2c->cur = &msgs[i]; + gi2c->err = 0; + dev_dbg(gi2c->se.dev, "msg[%d].len:%d\n", i, gi2c->cur->len); + + peripheral.stretch = 0; + if (i < num - 1) + peripheral.stretch = 1; + + peripheral.addr = msgs[i].addr; + + if (msgs[i].flags & I2C_M_RD) { + ret = geni_i2c_gpi(gi2c, &msgs[i], &config, + &rx_addr, &rx_buf, I2C_READ, gi2c->rx_c); + if (ret) + goto err; + } + + ret = geni_i2c_gpi(gi2c, &msgs[i], &config, + &tx_addr, &tx_buf, I2C_WRITE, gi2c->tx_c); + if (ret) + goto err; + + if (msgs[i].flags & I2C_M_RD) + dma_async_issue_pending(gi2c->rx_c); + dma_async_issue_pending(gi2c->tx_c); + + timeout = wait_for_completion_timeout(&gi2c->done, XFER_TIMEOUT); + if (!timeout) { + dev_err(gi2c->se.dev, "I2C timeout gpi flags:%d addr:0x%x\n", + gi2c->cur->flags, gi2c->cur->addr); + gi2c->err = -ETIMEDOUT; + goto err; + } + + if (gi2c->err) { + ret = gi2c->err; + goto err; + } + + geni_i2c_gpi_unmap(gi2c, &msgs[i], tx_buf, tx_addr, rx_buf, rx_addr); + } + + return num; + +err: + dev_err(gi2c->se.dev, "GPI transfer failed: %d\n", ret); + dmaengine_terminate_sync(gi2c->rx_c); + dmaengine_terminate_sync(gi2c->tx_c); + geni_i2c_gpi_unmap(gi2c, &msgs[i], tx_buf, tx_addr, rx_buf, rx_addr); + return ret; +} + +static int geni_i2c_fifo_xfer(struct geni_i2c_dev *gi2c, + struct i2c_msg msgs[], int num) +{ + int i, ret = 0; + + for (i = 0; i < num; i++) { + u32 m_param = i < (num - 1) ? STOP_STRETCH : 0; + + m_param |= ((msgs[i].addr << SLV_ADDR_SHFT) & SLV_ADDR_MSK); + + gi2c->cur = &msgs[i]; + if (msgs[i].flags & I2C_M_RD) + ret = geni_i2c_rx_one_msg(gi2c, &msgs[i], m_param); + else + ret = geni_i2c_tx_one_msg(gi2c, &msgs[i], m_param); + + if (ret) + return ret; + } + + return num; +} + static int geni_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num) { struct geni_i2c_dev *gi2c = i2c_get_adapdata(adap); - int i, ret; + int ret; gi2c->err = 0; reinit_completion(&gi2c->done); @@ -475,28 +678,17 @@ static int geni_i2c_xfer(struct i2c_adapter *adap, } qcom_geni_i2c_conf(gi2c); - for (i = 0; i < num; i++) { - u32 m_param = i < (num - 1) ? STOP_STRETCH : 0; - m_param |= ((msgs[i].addr << SLV_ADDR_SHFT) & SLV_ADDR_MSK); - - gi2c->cur = &msgs[i]; - if (msgs[i].flags & I2C_M_RD) - ret = geni_i2c_rx_one_msg(gi2c, &msgs[i], m_param); - else - ret = geni_i2c_tx_one_msg(gi2c, &msgs[i], m_param); - - if (ret) - break; - } - if (ret == 0) - ret = num; + if (gi2c->gpi_mode) + ret = geni_i2c_gpi_xfer(gi2c, msgs, num); + else + ret = geni_i2c_fifo_xfer(gi2c, msgs, num); pm_runtime_mark_last_busy(gi2c->se.dev); pm_runtime_put_autosuspend(gi2c->se.dev); gi2c->cur = NULL; gi2c->err = 0; - return ret; + return num; } static u32 geni_i2c_func(struct i2c_adapter *adap) @@ -517,11 +709,50 @@ static const struct acpi_device_id geni_i2c_acpi_match[] = { MODULE_DEVICE_TABLE(acpi, geni_i2c_acpi_match); #endif +static void release_gpi_dma(struct geni_i2c_dev *gi2c) +{ + if (gi2c->rx_c) + dma_release_channel(gi2c->rx_c); + + if (gi2c->tx_c) + dma_release_channel(gi2c->tx_c); +} + +static int setup_gpi_dma(struct geni_i2c_dev *gi2c) +{ + int ret; + + geni_se_select_mode(&gi2c->se, GENI_GPI_DMA); + gi2c->tx_c = dma_request_chan(gi2c->se.dev, "tx"); + if (IS_ERR(gi2c->tx_c)) { + ret = dev_err_probe(gi2c->se.dev, PTR_ERR(gi2c->tx_c), + "Failed to get tx DMA ch\n"); + if (ret < 0) + goto err_tx; + } + + gi2c->rx_c = dma_request_chan(gi2c->se.dev, "rx"); + if (IS_ERR(gi2c->rx_c)) { + ret = dev_err_probe(gi2c->se.dev, PTR_ERR(gi2c->rx_c), + "Failed to get rx DMA ch\n"); + if (ret < 0) + goto err_rx; + } + + dev_dbg(gi2c->se.dev, "Grabbed GPI dma channels\n"); + return 0; + +err_rx: + dma_release_channel(gi2c->tx_c); +err_tx: + return ret; +} + static int geni_i2c_probe(struct platform_device *pdev) { struct geni_i2c_dev *gi2c; struct resource *res; - u32 proto, tx_depth; + u32 proto, tx_depth, fifo_disable; int ret; struct device *dev = &pdev->dev; @@ -601,27 +832,43 @@ static int geni_i2c_probe(struct platform_device *pdev) return ret; } proto = geni_se_read_proto(&gi2c->se); - tx_depth = geni_se_get_tx_fifo_depth(&gi2c->se); if (proto != GENI_SE_I2C) { dev_err(dev, "Invalid proto %d\n", proto); geni_se_resources_off(&gi2c->se); return -ENXIO; } - gi2c->tx_wm = tx_depth - 1; - geni_se_init(&gi2c->se, gi2c->tx_wm, tx_depth); - geni_se_config_packing(&gi2c->se, BITS_PER_BYTE, PACKING_BYTES_PW, - true, true, true); + + fifo_disable = readl_relaxed(gi2c->se.base + GENI_IF_DISABLE_RO) & FIFO_IF_DISABLE; + if (fifo_disable) { + /* FIFO is disabled, so we can only use GPI DMA */ + gi2c->gpi_mode = true; + ret = setup_gpi_dma(gi2c); + if (ret) { + dev_err(dev, "Failed to setup GPI DMA mode:%d ret\n", ret); + return ret; + } + + dev_dbg(dev, "Using GPI DMA mode for I2C\n"); + } else { + gi2c->gpi_mode = false; + tx_depth = geni_se_get_tx_fifo_depth(&gi2c->se); + gi2c->tx_wm = tx_depth - 1; + geni_se_init(&gi2c->se, gi2c->tx_wm, tx_depth); + geni_se_config_packing(&gi2c->se, BITS_PER_BYTE, + PACKING_BYTES_PW, true, true, true); + + dev_dbg(dev, "i2c fifo/se-dma mode. fifo depth:%d\n", tx_depth); + } + ret = geni_se_resources_off(&gi2c->se); if (ret) { dev_err(dev, "Error turning off resources %d\n", ret); - return ret; + goto err_dma; } ret = geni_icc_disable(&gi2c->se); if (ret) - return ret; - - dev_dbg(dev, "i2c fifo/se-dma mode. fifo depth:%d\n", tx_depth); + goto err_dma; gi2c->suspended = 1; pm_runtime_set_suspended(gi2c->se.dev); @@ -633,12 +880,16 @@ static int geni_i2c_probe(struct platform_device *pdev) if (ret) { dev_err(dev, "Error adding i2c adapter %d\n", ret); pm_runtime_disable(gi2c->se.dev); - return ret; + goto err_dma; } dev_dbg(dev, "Geni-I2C adaptor successfully added\n"); return 0; + +err_dma: + release_gpi_dma(gi2c); + return ret; } static int geni_i2c_remove(struct platform_device *pdev) @@ -646,6 +897,7 @@ static int geni_i2c_remove(struct platform_device *pdev) struct geni_i2c_dev *gi2c = platform_get_drvdata(pdev); i2c_del_adapter(&gi2c->adap); + release_gpi_dma(gi2c); pm_runtime_disable(gi2c->se.dev); return 0; } From 17ba1e87fca9e6bad7eacbb1ef042c83358d245e Mon Sep 17 00:00:00 2001 From: Jan Dabros Date: Fri, 18 Feb 2022 14:33:48 +0100 Subject: [PATCH 228/370] i2c: designware: Fix improper usage of readl Kernel test robot reported incorrect type in argument 1 of readl(), but more importantly it brought attention that MMIO accessor shouldn't be used in this case, since req->hdr.status is part of a command-response buffer in system memory. Since its value may be altered by PSP outside of the scope of current thread (somehow similar to IRQ handler case), we need to use READ_ONCE() to ensure compiler won't optimize this call. Fix also 'status' variable type to reflect that corresponding field in command-response buffer is platform-independent u32. Fixes: 78d5e9e299e3 ("i2c: designware: Add AMD PSP I2C bus support") Signed-off-by: Jan Dabros Reported-by: kernel test robot Reviewed-by: Andy Shevchenko Acked-by: Jarkko Nikula Signed-off-by: Wolfram Sang --- drivers/i2c/busses/i2c-designware-amdpsp.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/i2c/busses/i2c-designware-amdpsp.c b/drivers/i2c/busses/i2c-designware-amdpsp.c index 9d37becbd846..3844695e6bf3 100644 --- a/drivers/i2c/busses/i2c-designware-amdpsp.c +++ b/drivers/i2c/busses/i2c-designware-amdpsp.c @@ -160,9 +160,10 @@ static int psp_send_cmd(struct psp_i2c_req *req) /* Helper to verify status returned by PSP */ static int check_i2c_req_sts(struct psp_i2c_req *req) { - int status; + u32 status; - status = readl(&req->hdr.status); + /* Status field in command-response buffer is updated by PSP */ + status = READ_ONCE(req->hdr.status); switch (status) { case PSP_I2C_REQ_STS_OK: From b5a796c6a8091b636f12cd9df12ccb2eed1b7f6c Mon Sep 17 00:00:00 2001 From: Kewei Xu Date: Thu, 17 Feb 2022 20:22:43 +0800 Subject: [PATCH 229/370] i2c: mediatek: modify bus speed calculation formula When clock-div is 0 or greater than 1, the bus speed calculated by the old speed calculation formula will be larger than the target speed. So we update the formula. Signed-off-by: Kewei Xu Reviewed-by: AngeloGioacchino Del Regno Reviewed-by: Qii Wang Signed-off-by: Wolfram Sang --- drivers/i2c/busses/i2c-mt65xx.c | 51 ++++++++++++++++++++++++++------- 1 file changed, 41 insertions(+), 10 deletions(-) diff --git a/drivers/i2c/busses/i2c-mt65xx.c b/drivers/i2c/busses/i2c-mt65xx.c index aa4d21838e14..682293ec9825 100644 --- a/drivers/i2c/busses/i2c-mt65xx.c +++ b/drivers/i2c/busses/i2c-mt65xx.c @@ -67,11 +67,12 @@ #define MAX_SAMPLE_CNT_DIV 8 #define MAX_STEP_CNT_DIV 64 -#define MAX_CLOCK_DIV 256 +#define MAX_CLOCK_DIV_8BITS 256 +#define MAX_CLOCK_DIV_5BITS 32 #define MAX_HS_STEP_CNT_DIV 8 -#define I2C_STANDARD_MODE_BUFFER (1000 / 2) -#define I2C_FAST_MODE_BUFFER (300 / 2) -#define I2C_FAST_MODE_PLUS_BUFFER (20 / 2) +#define I2C_STANDARD_MODE_BUFFER (1000 / 3) +#define I2C_FAST_MODE_BUFFER (300 / 3) +#define I2C_FAST_MODE_PLUS_BUFFER (20 / 3) #define I2C_CONTROL_RS (0x1 << 1) #define I2C_CONTROL_DMA_EN (0x1 << 2) @@ -604,6 +605,31 @@ static int mtk_i2c_max_step_cnt(unsigned int target_speed) return MAX_STEP_CNT_DIV; } +static int mtk_i2c_get_clk_div_restri(struct mtk_i2c *i2c, + unsigned int sample_cnt) +{ + int clk_div_restri = 0; + + if (i2c->dev_comp->ltiming_adjust == 0) + return 0; + + if (sample_cnt == 1) { + if (i2c->ac_timing.inter_clk_div == 0) + clk_div_restri = 0; + else + clk_div_restri = 1; + } else { + if (i2c->ac_timing.inter_clk_div == 0) + clk_div_restri = -1; + else if (i2c->ac_timing.inter_clk_div == 1) + clk_div_restri = 0; + else + clk_div_restri = 1; + } + + return clk_div_restri; +} + /* * Check and Calculate i2c ac-timing * @@ -732,6 +758,7 @@ static int mtk_i2c_calculate_speed(struct mtk_i2c *i2c, unsigned int clk_src, unsigned int best_mul; unsigned int cnt_mul; int ret = -EINVAL; + int clk_div_restri = 0; if (target_speed > I2C_MAX_HIGH_SPEED_MODE_FREQ) target_speed = I2C_MAX_HIGH_SPEED_MODE_FREQ; @@ -749,7 +776,8 @@ static int mtk_i2c_calculate_speed(struct mtk_i2c *i2c, unsigned int clk_src, * optimizing for sample_cnt * step_cnt being minimal */ for (sample_cnt = 1; sample_cnt <= MAX_SAMPLE_CNT_DIV; sample_cnt++) { - step_cnt = DIV_ROUND_UP(opt_div, sample_cnt); + clk_div_restri = mtk_i2c_get_clk_div_restri(i2c, sample_cnt); + step_cnt = DIV_ROUND_UP(opt_div + clk_div_restri, sample_cnt); cnt_mul = step_cnt * sample_cnt; if (step_cnt > max_step_cnt) continue; @@ -763,7 +791,7 @@ static int mtk_i2c_calculate_speed(struct mtk_i2c *i2c, unsigned int clk_src, best_mul = cnt_mul; base_sample_cnt = sample_cnt; base_step_cnt = step_cnt; - if (best_mul == opt_div) + if (best_mul == (opt_div + clk_div_restri)) break; } } @@ -774,7 +802,8 @@ static int mtk_i2c_calculate_speed(struct mtk_i2c *i2c, unsigned int clk_src, sample_cnt = base_sample_cnt; step_cnt = base_step_cnt; - if ((clk_src / (2 * sample_cnt * step_cnt)) > target_speed) { + if ((clk_src / (2 * (sample_cnt * step_cnt - clk_div_restri))) > + target_speed) { /* In this case, hardware can't support such * low i2c_bus_freq */ @@ -803,13 +832,16 @@ static int mtk_i2c_set_speed(struct mtk_i2c *i2c, unsigned int parent_clk) target_speed = i2c->speed_hz; parent_clk /= i2c->clk_src_div; - if (i2c->dev_comp->timing_adjust) - max_clk_div = MAX_CLOCK_DIV; + if (i2c->dev_comp->timing_adjust && i2c->dev_comp->ltiming_adjust) + max_clk_div = MAX_CLOCK_DIV_5BITS; + else if (i2c->dev_comp->timing_adjust) + max_clk_div = MAX_CLOCK_DIV_8BITS; else max_clk_div = 1; for (clk_div = 1; clk_div <= max_clk_div; clk_div++) { clk_src = parent_clk / clk_div; + i2c->ac_timing.inter_clk_div = clk_div - 1; if (target_speed > I2C_MAX_FAST_MODE_PLUS_FREQ) { /* Set master code speed register */ @@ -856,7 +888,6 @@ static int mtk_i2c_set_speed(struct mtk_i2c *i2c, unsigned int parent_clk) break; } - i2c->ac_timing.inter_clk_div = clk_div - 1; return 0; } From 5b9df0acd22a0bcd4e0e97e6f8368c31843ceb95 Mon Sep 17 00:00:00 2001 From: Xu Wang Date: Wed, 30 Sep 2020 08:42:33 +0000 Subject: [PATCH 230/370] i2c: mediatek: remove redundant null check Because clk_disable_unprepare already checked NULL clock parameter, so the additional checks are unnecessary, just remove it Signed-off-by: Xu Wang Reviewed-by: Qii Wang Signed-off-by: Wolfram Sang --- drivers/i2c/busses/i2c-mt65xx.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/drivers/i2c/busses/i2c-mt65xx.c b/drivers/i2c/busses/i2c-mt65xx.c index 682293ec9825..5bf7f965800d 100644 --- a/drivers/i2c/busses/i2c-mt65xx.c +++ b/drivers/i2c/busses/i2c-mt65xx.c @@ -476,8 +476,7 @@ static int mtk_i2c_clock_enable(struct mtk_i2c *i2c) return 0; err_arb: - if (i2c->have_pmic) - clk_disable_unprepare(i2c->clk_pmic); + clk_disable_unprepare(i2c->clk_pmic); err_pmic: clk_disable_unprepare(i2c->clk_main); err_main: @@ -488,11 +487,9 @@ err_main: static void mtk_i2c_clock_disable(struct mtk_i2c *i2c) { - if (i2c->clk_arb) - clk_disable_unprepare(i2c->clk_arb); + clk_disable_unprepare(i2c->clk_arb); - if (i2c->have_pmic) - clk_disable_unprepare(i2c->clk_pmic); + clk_disable_unprepare(i2c->clk_pmic); clk_disable_unprepare(i2c->clk_main); clk_disable_unprepare(i2c->clk_dma); From c205cac49e09deac8f91462138136d22a3161571 Mon Sep 17 00:00:00 2001 From: Lad Prabhakar Date: Sun, 27 Feb 2022 21:32:50 +0000 Subject: [PATCH 231/370] dt-bindings: net: can: renesas,rcar-canfd: Document RZ/V2L SoC Document RZ/V2L CANFD bindings. RZ/V2L CANFD is identical to one found on the RZ/G2L SoC. No driver changes are required as generic compatible string "renesas,rzg2l-canfd" will be used as a fallback. Signed-off-by: Lad Prabhakar Reviewed-by: Biju Das Reviewed-by: Geert Uytterhoeven Acked-by: Krzysztof Kozlowski Signed-off-by: Rob Herring Link: https://lore.kernel.org/r/20220227213250.23637-1-prabhakar.mahadev-lad.rj@bp.renesas.com --- .../devicetree/bindings/net/can/renesas,rcar-canfd.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/Documentation/devicetree/bindings/net/can/renesas,rcar-canfd.yaml b/Documentation/devicetree/bindings/net/can/renesas,rcar-canfd.yaml index 546c6e6d2fb0..720130bda6a6 100644 --- a/Documentation/devicetree/bindings/net/can/renesas,rcar-canfd.yaml +++ b/Documentation/devicetree/bindings/net/can/renesas,rcar-canfd.yaml @@ -33,6 +33,7 @@ properties: - items: - enum: - renesas,r9a07g044-canfd # RZ/G2{L,LC} + - renesas,r9a07g054-canfd # RZ/V2L - const: renesas,rzg2l-canfd # RZ/G2L family reg: From c57813b8b288dcb5e158993cfdff31a60bc24955 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Wed, 23 Feb 2022 14:48:38 +0100 Subject: [PATCH 232/370] i2c: designware: Lock the adapter while setting the suspended flag Lock the adapter while setting the suspended flag, to ensure that other locked code always sees the change immediately, rather then possibly using a stale value. This involves splitting the suspend/resume callbacks into separate runtime and normal suspend/resume calls. This is necessary because i2c_dw_xfer() will get called by the i2c-core with the adapter locked and it in turn calls the runtime-resume callback through pm_runtime_get_sync(). So the runtime versions of the suspend/resume callbacks cannot take the adapter-lock. Note this patch simply makes the runtime suspend/resume callbacks not deal with the suspended flag at all. During runtime the pm_runtime_get_sync() from i2c_dw_xfer() will always ensure that the adapter is resumed when necessary. The suspended flag check is only necessary to check proper suspend/resume ordering during normal suspend/resume which makes the pm_runtime_get_sync() call a no-op. Signed-off-by: Hans de Goede Reviewed-by: Andy Shevchenko Acked-by: Jarkko Nikula Signed-off-by: Wolfram Sang --- drivers/i2c/busses/i2c-designware-pcidrv.c | 31 +++++++++++++++++---- drivers/i2c/busses/i2c-designware-platdrv.c | 31 +++++++++++++++++---- 2 files changed, 52 insertions(+), 10 deletions(-) diff --git a/drivers/i2c/busses/i2c-designware-pcidrv.c b/drivers/i2c/busses/i2c-designware-pcidrv.c index 2782dddfb087..a736a2aaa66e 100644 --- a/drivers/i2c/busses/i2c-designware-pcidrv.c +++ b/drivers/i2c/busses/i2c-designware-pcidrv.c @@ -194,14 +194,30 @@ static struct dw_pci_controller dw_pci_controllers[] = { }, }; +static int __maybe_unused i2c_dw_pci_runtime_suspend(struct device *dev) +{ + struct dw_i2c_dev *i_dev = dev_get_drvdata(dev); + + i_dev->disable(i_dev); + return 0; +} + static int __maybe_unused i2c_dw_pci_suspend(struct device *dev) { struct dw_i2c_dev *i_dev = dev_get_drvdata(dev); + i2c_lock_bus(&i_dev->adapter, I2C_LOCK_ROOT_ADAPTER); i_dev->suspended = true; - i_dev->disable(i_dev); + i2c_unlock_bus(&i_dev->adapter, I2C_LOCK_ROOT_ADAPTER); - return 0; + return i2c_dw_pci_runtime_suspend(dev); +} + +static int __maybe_unused i2c_dw_pci_runtime_resume(struct device *dev) +{ + struct dw_i2c_dev *i_dev = dev_get_drvdata(dev); + + return i_dev->init(i_dev); } static int __maybe_unused i2c_dw_pci_resume(struct device *dev) @@ -209,14 +225,19 @@ static int __maybe_unused i2c_dw_pci_resume(struct device *dev) struct dw_i2c_dev *i_dev = dev_get_drvdata(dev); int ret; - ret = i_dev->init(i_dev); + ret = i2c_dw_pci_runtime_resume(dev); + + i2c_lock_bus(&i_dev->adapter, I2C_LOCK_ROOT_ADAPTER); i_dev->suspended = false; + i2c_unlock_bus(&i_dev->adapter, I2C_LOCK_ROOT_ADAPTER); return ret; } -static UNIVERSAL_DEV_PM_OPS(i2c_dw_pm_ops, i2c_dw_pci_suspend, - i2c_dw_pci_resume, NULL); +static const struct dev_pm_ops i2c_dw_pm_ops = { + SET_SYSTEM_SLEEP_PM_OPS(i2c_dw_pci_suspend, i2c_dw_pci_resume) + SET_RUNTIME_PM_OPS(i2c_dw_pci_runtime_suspend, i2c_dw_pci_runtime_resume, NULL) +}; static int i2c_dw_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) diff --git a/drivers/i2c/busses/i2c-designware-platdrv.c b/drivers/i2c/busses/i2c-designware-platdrv.c index 9973ac894a51..f0703286d93b 100644 --- a/drivers/i2c/busses/i2c-designware-platdrv.c +++ b/drivers/i2c/busses/i2c-designware-platdrv.c @@ -428,12 +428,10 @@ static void dw_i2c_plat_complete(struct device *dev) #endif #ifdef CONFIG_PM -static int dw_i2c_plat_suspend(struct device *dev) +static int dw_i2c_plat_runtime_suspend(struct device *dev) { struct dw_i2c_dev *i_dev = dev_get_drvdata(dev); - i_dev->suspended = true; - if (i_dev->shared_with_punit) return 0; @@ -443,7 +441,18 @@ static int dw_i2c_plat_suspend(struct device *dev) return 0; } -static int dw_i2c_plat_resume(struct device *dev) +static int dw_i2c_plat_suspend(struct device *dev) +{ + struct dw_i2c_dev *i_dev = dev_get_drvdata(dev); + + i2c_lock_bus(&i_dev->adapter, I2C_LOCK_ROOT_ADAPTER); + i_dev->suspended = true; + i2c_unlock_bus(&i_dev->adapter, I2C_LOCK_ROOT_ADAPTER); + + return dw_i2c_plat_runtime_suspend(dev); +} + +static int dw_i2c_plat_runtime_resume(struct device *dev) { struct dw_i2c_dev *i_dev = dev_get_drvdata(dev); @@ -451,7 +460,19 @@ static int dw_i2c_plat_resume(struct device *dev) i2c_dw_prepare_clk(i_dev, true); i_dev->init(i_dev); + + return 0; +} + +static int dw_i2c_plat_resume(struct device *dev) +{ + struct dw_i2c_dev *i_dev = dev_get_drvdata(dev); + + dw_i2c_plat_runtime_resume(dev); + + i2c_lock_bus(&i_dev->adapter, I2C_LOCK_ROOT_ADAPTER); i_dev->suspended = false; + i2c_unlock_bus(&i_dev->adapter, I2C_LOCK_ROOT_ADAPTER); return 0; } @@ -460,7 +481,7 @@ static const struct dev_pm_ops dw_i2c_dev_pm_ops = { .prepare = dw_i2c_plat_prepare, .complete = dw_i2c_plat_complete, SET_LATE_SYSTEM_SLEEP_PM_OPS(dw_i2c_plat_suspend, dw_i2c_plat_resume) - SET_RUNTIME_PM_OPS(dw_i2c_plat_suspend, dw_i2c_plat_resume, NULL) + SET_RUNTIME_PM_OPS(dw_i2c_plat_runtime_suspend, dw_i2c_plat_runtime_resume, NULL) }; #define DW_I2C_DEV_PMOPS (&dw_i2c_dev_pm_ops) From 80704a84a9f8276337a83c0c3ce641af3b27c79c Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Wed, 23 Feb 2022 14:48:39 +0100 Subject: [PATCH 233/370] i2c: designware: Use the i2c_mark_adapter_suspended/resumed() helpers Use the i2c_mark_adapter_suspended/resumed() i2c-core helpers and rely on the i2c-core's suspended checking instead of using DIY code. Signed-off-by: Hans de Goede Acked-by: Jarkko Nikula Reviewed-by: Andy Shevchenko Signed-off-by: Wolfram Sang --- drivers/i2c/busses/i2c-designware-core.h | 2 -- drivers/i2c/busses/i2c-designware-master.c | 5 ----- drivers/i2c/busses/i2c-designware-pcidrv.c | 8 ++------ drivers/i2c/busses/i2c-designware-platdrv.c | 9 ++------- 4 files changed, 4 insertions(+), 20 deletions(-) diff --git a/drivers/i2c/busses/i2c-designware-core.h b/drivers/i2c/busses/i2c-designware-core.h index 1d65212fddbd..70b80e710990 100644 --- a/drivers/i2c/busses/i2c-designware-core.h +++ b/drivers/i2c/busses/i2c-designware-core.h @@ -236,7 +236,6 @@ struct reset_control; * @set_sda_hold_time: callback to retrieve IP specific SDA hold timing * @mode: operation mode - DW_IC_MASTER or DW_IC_SLAVE * @rinfo: I²C GPIO recovery information - * @suspended: set to true if the controller is suspended * * HCNT and LCNT parameters can be used if the platform knows more accurate * values than the one computed based only on the input clock frequency. @@ -295,7 +294,6 @@ struct dw_i2c_dev { int (*set_sda_hold_time)(struct dw_i2c_dev *dev); int mode; struct i2c_bus_recovery_info rinfo; - bool suspended; }; #define ACCESS_INTR_MASK BIT(0) diff --git a/drivers/i2c/busses/i2c-designware-master.c b/drivers/i2c/busses/i2c-designware-master.c index 1a4b23556db3..44a94b225ed8 100644 --- a/drivers/i2c/busses/i2c-designware-master.c +++ b/drivers/i2c/busses/i2c-designware-master.c @@ -567,11 +567,6 @@ i2c_dw_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num) goto done_nolock; } - if (dev_WARN_ONCE(dev->dev, dev->suspended, "Transfer while suspended\n")) { - ret = -ESHUTDOWN; - goto done_nolock; - } - reinit_completion(&dev->cmd_complete); dev->msgs = msgs; dev->msgs_num = num; diff --git a/drivers/i2c/busses/i2c-designware-pcidrv.c b/drivers/i2c/busses/i2c-designware-pcidrv.c index a736a2aaa66e..608e61209455 100644 --- a/drivers/i2c/busses/i2c-designware-pcidrv.c +++ b/drivers/i2c/busses/i2c-designware-pcidrv.c @@ -206,9 +206,7 @@ static int __maybe_unused i2c_dw_pci_suspend(struct device *dev) { struct dw_i2c_dev *i_dev = dev_get_drvdata(dev); - i2c_lock_bus(&i_dev->adapter, I2C_LOCK_ROOT_ADAPTER); - i_dev->suspended = true; - i2c_unlock_bus(&i_dev->adapter, I2C_LOCK_ROOT_ADAPTER); + i2c_mark_adapter_suspended(&i_dev->adapter); return i2c_dw_pci_runtime_suspend(dev); } @@ -227,9 +225,7 @@ static int __maybe_unused i2c_dw_pci_resume(struct device *dev) ret = i2c_dw_pci_runtime_resume(dev); - i2c_lock_bus(&i_dev->adapter, I2C_LOCK_ROOT_ADAPTER); - i_dev->suspended = false; - i2c_unlock_bus(&i_dev->adapter, I2C_LOCK_ROOT_ADAPTER); + i2c_mark_adapter_resumed(&i_dev->adapter); return ret; } diff --git a/drivers/i2c/busses/i2c-designware-platdrv.c b/drivers/i2c/busses/i2c-designware-platdrv.c index f0703286d93b..116a297d1f6b 100644 --- a/drivers/i2c/busses/i2c-designware-platdrv.c +++ b/drivers/i2c/busses/i2c-designware-platdrv.c @@ -445,9 +445,7 @@ static int dw_i2c_plat_suspend(struct device *dev) { struct dw_i2c_dev *i_dev = dev_get_drvdata(dev); - i2c_lock_bus(&i_dev->adapter, I2C_LOCK_ROOT_ADAPTER); - i_dev->suspended = true; - i2c_unlock_bus(&i_dev->adapter, I2C_LOCK_ROOT_ADAPTER); + i2c_mark_adapter_suspended(&i_dev->adapter); return dw_i2c_plat_runtime_suspend(dev); } @@ -469,10 +467,7 @@ static int dw_i2c_plat_resume(struct device *dev) struct dw_i2c_dev *i_dev = dev_get_drvdata(dev); dw_i2c_plat_runtime_resume(dev); - - i2c_lock_bus(&i_dev->adapter, I2C_LOCK_ROOT_ADAPTER); - i_dev->suspended = false; - i2c_unlock_bus(&i_dev->adapter, I2C_LOCK_ROOT_ADAPTER); + i2c_mark_adapter_resumed(&i_dev->adapter); return 0; } From eb1e49e04ab9863f5e9a73ebadaae15aef2fce35 Mon Sep 17 00:00:00 2001 From: Lad Prabhakar Date: Sun, 27 Feb 2022 21:47:47 +0000 Subject: [PATCH 234/370] dt-bindings: i2c: renesas,riic: Document RZ/V2L SoC Document RZ/V2L I2C bindings. RZ/V2L I2C is identical to one found on the RZ/G2L SoC. No driver changes are required as RZ/G2L compatible string "renesas,riic-rz" will be used as a fallback. Signed-off-by: Lad Prabhakar Reviewed-by: Biju Das Reviewed-by: Geert Uytterhoeven Acked-by: Krzysztof Kozlowski Signed-off-by: Rob Herring Link: https://lore.kernel.org/r/20220227214747.24819-1-prabhakar.mahadev-lad.rj@bp.renesas.com --- Documentation/devicetree/bindings/i2c/renesas,riic.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Documentation/devicetree/bindings/i2c/renesas,riic.yaml b/Documentation/devicetree/bindings/i2c/renesas,riic.yaml index 402fd125e010..f4b235a87ac6 100644 --- a/Documentation/devicetree/bindings/i2c/renesas,riic.yaml +++ b/Documentation/devicetree/bindings/i2c/renesas,riic.yaml @@ -20,6 +20,7 @@ properties: - renesas,riic-r7s72100 # RZ/A1H - renesas,riic-r7s9210 # RZ/A2M - renesas,riic-r9a07g044 # RZ/G2{L,LC} + - renesas,riic-r9a07g054 # RZ/V2L - const: renesas,riic-rz # RZ/A or RZ/G2L reg: @@ -75,6 +76,7 @@ if: contains: enum: - renesas,riic-r9a07g044 + - renesas,riic-r9a07g054 then: required: - resets From 7419553d03ffff648be0aba03f2f762212fc013b Mon Sep 17 00:00:00 2001 From: Lad Prabhakar Date: Sun, 27 Feb 2022 22:48:44 +0000 Subject: [PATCH 235/370] dt-bindings: timer: renesas: ostm: Document Renesas RZ/V2L OSTM Document the General Timer Module(a.k.a OSTM) found on the RZ/V2L SoC. OSTM module is identical to one found RZ/G2L SoC. No driver changes are required as generic compatible string "renesas,ostm" will be used as a fallback. Signed-off-by: Lad Prabhakar Reviewed-by: Biju Das Acked-by: Krzysztof Kozlowski Reviewed-by: Geert Uytterhoeven Signed-off-by: Rob Herring Link: https://lore.kernel.org/r/20220227224845.27348-1-prabhakar.mahadev-lad.rj@bp.renesas.com --- Documentation/devicetree/bindings/timer/renesas,ostm.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Documentation/devicetree/bindings/timer/renesas,ostm.yaml b/Documentation/devicetree/bindings/timer/renesas,ostm.yaml index 7fa7f977b44c..c399a019dde7 100644 --- a/Documentation/devicetree/bindings/timer/renesas,ostm.yaml +++ b/Documentation/devicetree/bindings/timer/renesas,ostm.yaml @@ -24,6 +24,7 @@ properties: - renesas,r7s72100-ostm # RZ/A1H - renesas,r7s9210-ostm # RZ/A2M - renesas,r9a07g044-ostm # RZ/G2{L,LC} + - renesas,r9a07g054-ostm # RZ/V2L - const: renesas,ostm # Generic reg: @@ -54,6 +55,7 @@ if: contains: enum: - renesas,r9a07g044-ostm + - renesas,r9a07g054-ostm then: required: - resets From f866a7ae1265960af80e555a0f0e1d22c72476eb Mon Sep 17 00:00:00 2001 From: Lad Prabhakar Date: Sun, 27 Feb 2022 23:03:01 +0000 Subject: [PATCH 236/370] dt-bindings: reset: renesas,rzg2l-usbphy-ctrl: Document RZ/V2L USBPHY Control bindings Add device tree binding document for RZ/V2L USBPHY Control Device. RZ/V2L USBPHY Control Device is identical to one found on the RZ/G2L SoC. No driver changes are required as generic compatible string "renesas,rzg2l-usbphy-ctrl" will be used as a fallback. Signed-off-by: Lad Prabhakar Reviewed-by: Biju Das Reviewed-by: Geert Uytterhoeven Acked-by: Krzysztof Kozlowski Signed-off-by: Rob Herring Link: https://lore.kernel.org/r/20220227230302.30388-1-prabhakar.mahadev-lad.rj@bp.renesas.com --- .../devicetree/bindings/reset/renesas,rzg2l-usbphy-ctrl.yaml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/reset/renesas,rzg2l-usbphy-ctrl.yaml b/Documentation/devicetree/bindings/reset/renesas,rzg2l-usbphy-ctrl.yaml index b13514e6783d..86c2569ced97 100644 --- a/Documentation/devicetree/bindings/reset/renesas,rzg2l-usbphy-ctrl.yaml +++ b/Documentation/devicetree/bindings/reset/renesas,rzg2l-usbphy-ctrl.yaml @@ -4,7 +4,7 @@ $id: http://devicetree.org/schemas/reset/renesas,rzg2l-usbphy-ctrl.yaml# $schema: http://devicetree.org/meta-schemas/core.yaml# -title: Renesas RZ/G2L USBPHY Control +title: Renesas RZ/{G2L,V2L} USBPHY Control maintainers: - Biju Das @@ -18,6 +18,7 @@ properties: items: - enum: - renesas,r9a07g044-usbphy-ctrl # RZ/G2{L,LC} + - renesas,r9a07g054-usbphy-ctrl # RZ/V2L - const: renesas,rzg2l-usbphy-ctrl reg: From 53157759f56bae8aa6ad2912378f7e75e218e779 Mon Sep 17 00:00:00 2001 From: Lad Prabhakar Date: Sun, 27 Feb 2022 23:15:31 +0000 Subject: [PATCH 237/370] dt-bindings: usb: renesas,usbhs: Document RZ/V2L bindings Document RZ/V2L (R9A07G054) SoC bindings. USBHS block is identical to one found on RZ/A2 SoC. No driver changes are required as generic compatible string "renesas,rza2-usbhs" will be used as a fallback. Signed-off-by: Lad Prabhakar Reviewed-by: Biju Das Reviewed-by: Geert Uytterhoeven Acked-by: Krzysztof Kozlowski Acked-by: Yoshihiro Shimoda Signed-off-by: Rob Herring Link: https://lore.kernel.org/r/20220227231531.32279-1-prabhakar.mahadev-lad.rj@bp.renesas.com --- Documentation/devicetree/bindings/usb/renesas,usbhs.yaml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/usb/renesas,usbhs.yaml b/Documentation/devicetree/bindings/usb/renesas,usbhs.yaml index 012fe80a7611..0bb841b28003 100644 --- a/Documentation/devicetree/bindings/usb/renesas,usbhs.yaml +++ b/Documentation/devicetree/bindings/usb/renesas,usbhs.yaml @@ -20,6 +20,7 @@ properties: - enum: - renesas,usbhs-r7s9210 # RZ/A2 - renesas,usbhs-r9a07g044 # RZ/G2{L,LC} + - renesas,usbhs-r9a07g054 # RZ/V2L - const: renesas,rza2-usbhs - items: @@ -116,7 +117,9 @@ allOf: properties: compatible: contains: - const: renesas,usbhs-r9a07g044 + enum: + - renesas,usbhs-r9a07g044 + - renesas,usbhs-r9a07g054 then: properties: interrupts: From d7583c8a57485da19feb6dd85573763a8c5ec1d1 Mon Sep 17 00:00:00 2001 From: Akhil R Date: Thu, 10 Feb 2022 21:06:03 +0530 Subject: [PATCH 238/370] i2c: tegra: Add SMBus block read function Emulate SMBus block read using ContinueXfer to read the length byte Signed-off-by: Akhil R Reviewed-by: Dmitry Osipenko Acked-by: Thierry Reding Signed-off-by: Wolfram Sang --- drivers/i2c/busses/i2c-tegra.c | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/drivers/i2c/busses/i2c-tegra.c b/drivers/i2c/busses/i2c-tegra.c index 03cea102ab76..2941e42aa6a0 100644 --- a/drivers/i2c/busses/i2c-tegra.c +++ b/drivers/i2c/busses/i2c-tegra.c @@ -1233,6 +1233,11 @@ static int tegra_i2c_xfer_msg(struct tegra_i2c_dev *i2c_dev, return err; i2c_dev->msg_buf = msg->buf; + + /* The condition true implies smbus block read and len is already read */ + if (msg->flags & I2C_M_RECV_LEN && end_state != MSG_END_CONTINUE) + i2c_dev->msg_buf = msg->buf + 1; + i2c_dev->msg_buf_remaining = msg->len; i2c_dev->msg_err = I2C_ERR_NONE; i2c_dev->msg_read = !!(msg->flags & I2C_M_RD); @@ -1389,6 +1394,15 @@ static int tegra_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], else end_type = MSG_END_REPEAT_START; } + /* If M_RECV_LEN use ContinueXfer to read the first byte */ + if (msgs[i].flags & I2C_M_RECV_LEN) { + ret = tegra_i2c_xfer_msg(i2c_dev, &msgs[i], MSG_END_CONTINUE); + if (ret) + break; + /* Set the read byte as msg len */ + msgs[i].len = msgs[i].buf[0]; + dev_dbg(i2c_dev->dev, "reading %d bytes\n", msgs[i].len); + } ret = tegra_i2c_xfer_msg(i2c_dev, &msgs[i], end_type); if (ret) break; @@ -1416,10 +1430,10 @@ static u32 tegra_i2c_func(struct i2c_adapter *adap) { struct tegra_i2c_dev *i2c_dev = i2c_get_adapdata(adap); u32 ret = I2C_FUNC_I2C | (I2C_FUNC_SMBUS_EMUL & ~I2C_FUNC_SMBUS_QUICK) | - I2C_FUNC_10BIT_ADDR | I2C_FUNC_PROTOCOL_MANGLING; + I2C_FUNC_10BIT_ADDR | I2C_FUNC_PROTOCOL_MANGLING; if (i2c_dev->hw->has_continue_xfer_support) - ret |= I2C_FUNC_NOSTART; + ret |= I2C_FUNC_NOSTART | I2C_FUNC_SMBUS_READ_BLOCK_DATA; return ret; } From eb103a51640ee32ab01c51e13bf8fca211f25f61 Mon Sep 17 00:00:00 2001 From: Jan Kara Date: Fri, 25 Feb 2022 13:54:45 +0100 Subject: [PATCH 239/370] reiserfs: Deprecate reiserfs Reiserfs is relatively old filesystem and its development has ceased quite some years ago. Linux distributions moved away from it towards other filesystems such as btrfs, xfs, or ext4. To reduce maintenance burden on cross filesystem changes (such as new mount API, iomap, folios ...) let's add a deprecation notice when the filesystem is mounted and schedule its removal to 2025. Link: https://lore.kernel.org/r/20220225125445.29942-1-jack@suse.cz Signed-off-by: Jan Kara --- fs/reiserfs/Kconfig | 10 +++++++--- fs/reiserfs/super.c | 2 ++ 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/fs/reiserfs/Kconfig b/fs/reiserfs/Kconfig index 8fd54ed8f844..33c8b0dd07a2 100644 --- a/fs/reiserfs/Kconfig +++ b/fs/reiserfs/Kconfig @@ -1,10 +1,14 @@ # SPDX-License-Identifier: GPL-2.0-only config REISERFS_FS - tristate "Reiserfs support" + tristate "Reiserfs support (deprecated)" select CRC32 help - Stores not just filenames but the files themselves in a balanced - tree. Uses journalling. + Reiserfs is deprecated and scheduled to be removed from the kernel + in 2025. If you are still using it, please migrate to another + filesystem or tell us your usecase for reiserfs. + + Reiserfs stores not just filenames but the files themselves in a + balanced tree. Uses journalling. Balanced trees are more efficient than traditional file system architectural foundations. diff --git a/fs/reiserfs/super.c b/fs/reiserfs/super.c index 82e09901462e..a18be1a18f84 100644 --- a/fs/reiserfs/super.c +++ b/fs/reiserfs/super.c @@ -1652,6 +1652,8 @@ static int read_super_block(struct super_block *s, int offset) return 1; } + reiserfs_warning(NULL, "", "reiserfs filesystem is deprecated and " + "scheduled to be removed from the kernel in 2025"); SB_BUFFER_WITH_SB(s) = bh; SB_DISK_SUPER_BLOCK(s) = rs; From dca669354e6ff494222dfc461bed1087264f3755 Mon Sep 17 00:00:00 2001 From: Rob Herring Date: Mon, 28 Feb 2022 15:38:02 -0600 Subject: [PATCH 240/370] dt-bindings: Another pass removing cases of 'allOf' containing a '$ref' MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Another pass at removing unnecessary use of 'allOf' with a '$ref'. json-schema versions draft7 and earlier have a weird behavior in that any keywords combined with a '$ref' are ignored (silently). The correct form was to put a '$ref' under an 'allOf'. This behavior is now changed in the 2019-09 json-schema spec and '$ref' can be mixed with other keywords. Cc: Krzysztof Kozlowski Cc: Thierry Reding Cc: Sam Ravnborg Cc: Dmitry Torokhov Cc: Pavel Machek Cc: Guenter Roeck Cc: Richard Weinberger Cc: Vignesh Raghavendra Cc: "David S. Miller" Cc: Kishon Vijay Abraham I Cc: Sebastian Reichel Cc: Mathieu Poirier Signed-off-by: Rob Herring Acked-by: Mark Brown Reviewed-by: Greg Kroah-Hartman Acked-By: Vinod Koul Acked-by: Lee Jones Acked-by: Marek Behún Acked-by: Miquel Raynal Reviewed-by: Laurent Pinchart Acked-by: Jakub Kicinski Acked-by: Bjorn Andersson Link: https://lore.kernel.org/r/20220228213802.1639658-1-robh@kernel.org --- .../bindings/connector/usb-connector.yaml | 3 +-- .../bindings/display/brcm,bcm2711-hdmi.yaml | 3 +-- .../bindings/display/bridge/adi,adv7511.yaml | 5 ++--- .../bindings/display/bridge/synopsys,dw-hdmi.yaml | 5 ++--- .../bindings/display/panel/display-timings.yaml | 3 +-- .../devicetree/bindings/display/ste,mcde.yaml | 4 ++-- .../devicetree/bindings/input/adc-joystick.yaml | 9 ++++----- .../bindings/leds/cznic,turris-omnia-leds.yaml | 3 +-- .../devicetree/bindings/leds/leds-lp50xx.yaml | 3 +-- .../devicetree/bindings/mfd/google,cros-ec.yaml | 12 ++++-------- .../bindings/mtd/rockchip,nand-controller.yaml | 3 +-- .../devicetree/bindings/net/ti,cpsw-switch.yaml | 3 +-- .../bindings/phy/phy-stm32-usbphyc.yaml | 3 +-- .../bindings/power/supply/sbs,sbs-manager.yaml | 4 +--- .../bindings/remoteproc/ti,k3-r5f-rproc.yaml | 3 +-- .../devicetree/bindings/soc/ti/ti,pruss.yaml | 15 +++------------ .../devicetree/bindings/sound/st,stm32-sai.yaml | 3 +-- .../devicetree/bindings/sound/tlv320adcx140.yaml | 13 ++++++------- .../devicetree/bindings/spi/spi-controller.yaml | 4 +--- .../devicetree/bindings/usb/st,stusb160x.yaml | 4 +--- 20 files changed, 36 insertions(+), 69 deletions(-) diff --git a/Documentation/devicetree/bindings/connector/usb-connector.yaml b/Documentation/devicetree/bindings/connector/usb-connector.yaml index 7eb8659fa610..0420fa563532 100644 --- a/Documentation/devicetree/bindings/connector/usb-connector.yaml +++ b/Documentation/devicetree/bindings/connector/usb-connector.yaml @@ -104,8 +104,7 @@ properties: - "1.5A" and "3.0A", 5V 1.5A and 5V 3.0A respectively, as defined in USB Type-C Cable and Connector specification, when Power Delivery is not supported. - allOf: - - $ref: /schemas/types.yaml#/definitions/string + $ref: /schemas/types.yaml#/definitions/string enum: - default - 1.5A diff --git a/Documentation/devicetree/bindings/display/brcm,bcm2711-hdmi.yaml b/Documentation/devicetree/bindings/display/brcm,bcm2711-hdmi.yaml index a1d5a32660e0..a9d34dd7bbc5 100644 --- a/Documentation/devicetree/bindings/display/brcm,bcm2711-hdmi.yaml +++ b/Documentation/devicetree/bindings/display/brcm,bcm2711-hdmi.yaml @@ -72,8 +72,7 @@ properties: - const: hpd-removed ddc: - allOf: - - $ref: /schemas/types.yaml#/definitions/phandle + $ref: /schemas/types.yaml#/definitions/phandle description: > Phandle of the I2C controller used for DDC EDID probing diff --git a/Documentation/devicetree/bindings/display/bridge/adi,adv7511.yaml b/Documentation/devicetree/bindings/display/bridge/adi,adv7511.yaml index d3dd7a79b909..f08a01dfedf3 100644 --- a/Documentation/devicetree/bindings/display/bridge/adi,adv7511.yaml +++ b/Documentation/devicetree/bindings/display/bridge/adi,adv7511.yaml @@ -76,9 +76,8 @@ properties: adi,input-depth: description: Number of bits per color component at the input. - allOf: - - $ref: /schemas/types.yaml#/definitions/uint32 - - enum: [ 8, 10, 12 ] + $ref: /schemas/types.yaml#/definitions/uint32 + enum: [ 8, 10, 12 ] adi,input-colorspace: description: Input color space. diff --git a/Documentation/devicetree/bindings/display/bridge/synopsys,dw-hdmi.yaml b/Documentation/devicetree/bindings/display/bridge/synopsys,dw-hdmi.yaml index 9be44a682e67..b00246faea57 100644 --- a/Documentation/devicetree/bindings/display/bridge/synopsys,dw-hdmi.yaml +++ b/Documentation/devicetree/bindings/display/bridge/synopsys,dw-hdmi.yaml @@ -26,9 +26,8 @@ properties: reg-io-width: description: Width (in bytes) of the registers specified by the reg property. - allOf: - - $ref: /schemas/types.yaml#/definitions/uint32 - - enum: [1, 4] + $ref: /schemas/types.yaml#/definitions/uint32 + enum: [1, 4] default: 1 clocks: diff --git a/Documentation/devicetree/bindings/display/panel/display-timings.yaml b/Documentation/devicetree/bindings/display/panel/display-timings.yaml index 56903ded005e..6d30575819d3 100644 --- a/Documentation/devicetree/bindings/display/panel/display-timings.yaml +++ b/Documentation/devicetree/bindings/display/panel/display-timings.yaml @@ -31,8 +31,7 @@ properties: patternProperties: "^timing": type: object - allOf: - - $ref: panel-timing.yaml# + $ref: panel-timing.yaml# additionalProperties: false diff --git a/Documentation/devicetree/bindings/display/ste,mcde.yaml b/Documentation/devicetree/bindings/display/ste,mcde.yaml index de0c678b3c29..564ea845c82e 100644 --- a/Documentation/devicetree/bindings/display/ste,mcde.yaml +++ b/Documentation/devicetree/bindings/display/ste,mcde.yaml @@ -58,8 +58,8 @@ patternProperties: "^dsi@[0-9a-f]+$": description: subnodes for the three DSI host adapters type: object - allOf: - - $ref: dsi-controller.yaml# + $ref: dsi-controller.yaml# + properties: compatible: const: ste,mcde-dsi diff --git a/Documentation/devicetree/bindings/input/adc-joystick.yaml b/Documentation/devicetree/bindings/input/adc-joystick.yaml index 721878d5b7af..2ee04e03bc22 100644 --- a/Documentation/devicetree/bindings/input/adc-joystick.yaml +++ b/Documentation/devicetree/bindings/input/adc-joystick.yaml @@ -61,11 +61,10 @@ patternProperties: description: EV_ABS specific event code generated by the axis. abs-range: - allOf: - - $ref: /schemas/types.yaml#/definitions/uint32-array - - items: - - description: minimum value - - description: maximum value + $ref: /schemas/types.yaml#/definitions/uint32-array + items: + - description: minimum value + - description: maximum value description: > Minimum and maximum values produced by the axis. For an ABS_X axis this will be the left-most and right-most diff --git a/Documentation/devicetree/bindings/leds/cznic,turris-omnia-leds.yaml b/Documentation/devicetree/bindings/leds/cznic,turris-omnia-leds.yaml index c7ed2871da06..9362b1ef9e88 100644 --- a/Documentation/devicetree/bindings/leds/cznic,turris-omnia-leds.yaml +++ b/Documentation/devicetree/bindings/leds/cznic,turris-omnia-leds.yaml @@ -32,8 +32,7 @@ properties: patternProperties: "^multi-led@[0-9a-b]$": type: object - allOf: - - $ref: leds-class-multicolor.yaml# + $ref: leds-class-multicolor.yaml# description: This node represents one of the RGB LED devices on Turris Omnia. No subnodes need to be added for subchannels since this controller only diff --git a/Documentation/devicetree/bindings/leds/leds-lp50xx.yaml b/Documentation/devicetree/bindings/leds/leds-lp50xx.yaml index c192b5feadc7..f12fe5b53f30 100644 --- a/Documentation/devicetree/bindings/leds/leds-lp50xx.yaml +++ b/Documentation/devicetree/bindings/leds/leds-lp50xx.yaml @@ -55,8 +55,7 @@ properties: patternProperties: '^multi-led@[0-9a-f]$': type: object - allOf: - - $ref: leds-class-multicolor.yaml# + $ref: leds-class-multicolor.yaml# properties: reg: minItems: 1 diff --git a/Documentation/devicetree/bindings/mfd/google,cros-ec.yaml b/Documentation/devicetree/bindings/mfd/google,cros-ec.yaml index d1f53bd449f7..a52f3a82283c 100644 --- a/Documentation/devicetree/bindings/mfd/google,cros-ec.yaml +++ b/Documentation/devicetree/bindings/mfd/google,cros-ec.yaml @@ -38,18 +38,14 @@ properties: description: This property specifies the delay in usecs between the assertion of the CS and the first clock pulse. - allOf: - - $ref: /schemas/types.yaml#/definitions/uint32 - - default: 0 - - minimum: 0 + $ref: /schemas/types.yaml#/definitions/uint32 + default: 0 google,cros-ec-spi-msg-delay: description: This property specifies the delay in usecs between messages. - allOf: - - $ref: /schemas/types.yaml#/definitions/uint32 - - default: 0 - - minimum: 0 + $ref: /schemas/types.yaml#/definitions/uint32 + default: 0 google,has-vbc-nvram: description: diff --git a/Documentation/devicetree/bindings/mtd/rockchip,nand-controller.yaml b/Documentation/devicetree/bindings/mtd/rockchip,nand-controller.yaml index 0922536b1811..d681a4676f06 100644 --- a/Documentation/devicetree/bindings/mtd/rockchip,nand-controller.yaml +++ b/Documentation/devicetree/bindings/mtd/rockchip,nand-controller.yaml @@ -96,8 +96,7 @@ patternProperties: rockchip,boot-ecc-strength: enum: [16, 24, 40, 60, 70] - allOf: - - $ref: /schemas/types.yaml#/definitions/uint32 + $ref: /schemas/types.yaml#/definitions/uint32 description: | If specified it indicates that a different BCH/ECC setting is supported by the boot ROM. diff --git a/Documentation/devicetree/bindings/net/ti,cpsw-switch.yaml b/Documentation/devicetree/bindings/net/ti,cpsw-switch.yaml index 07a00f53adbf..31bf825c6598 100644 --- a/Documentation/devicetree/bindings/net/ti,cpsw-switch.yaml +++ b/Documentation/devicetree/bindings/net/ti,cpsw-switch.yaml @@ -88,8 +88,7 @@ properties: type: object description: CPSW external ports - allOf: - - $ref: ethernet-controller.yaml# + $ref: ethernet-controller.yaml# properties: reg: diff --git a/Documentation/devicetree/bindings/phy/phy-stm32-usbphyc.yaml b/Documentation/devicetree/bindings/phy/phy-stm32-usbphyc.yaml index 267b695215b6..dc287d428e49 100644 --- a/Documentation/devicetree/bindings/phy/phy-stm32-usbphyc.yaml +++ b/Documentation/devicetree/bindings/phy/phy-stm32-usbphyc.yaml @@ -76,8 +76,7 @@ patternProperties: connector: type: object - allOf: - - $ref: ../connector/usb-connector.yaml + $ref: /schemas/connector/usb-connector.yaml properties: vbus-supply: true diff --git a/Documentation/devicetree/bindings/power/supply/sbs,sbs-manager.yaml b/Documentation/devicetree/bindings/power/supply/sbs,sbs-manager.yaml index 72e8f274c791..99f506d6b0a0 100644 --- a/Documentation/devicetree/bindings/power/supply/sbs,sbs-manager.yaml +++ b/Documentation/devicetree/bindings/power/supply/sbs,sbs-manager.yaml @@ -46,9 +46,7 @@ additionalProperties: false patternProperties: "^i2c@[1-4]$": type: object - - allOf: - - $ref: /schemas/i2c/i2c-controller.yaml# + $ref: /schemas/i2c/i2c-controller.yaml# examples: - | diff --git a/Documentation/devicetree/bindings/remoteproc/ti,k3-r5f-rproc.yaml b/Documentation/devicetree/bindings/remoteproc/ti,k3-r5f-rproc.yaml index 0868154a0364..fb9605f0655b 100644 --- a/Documentation/devicetree/bindings/remoteproc/ti,k3-r5f-rproc.yaml +++ b/Documentation/devicetree/bindings/remoteproc/ti,k3-r5f-rproc.yaml @@ -95,8 +95,7 @@ patternProperties: addresses. Cache and memory access settings are provided through a Memory Protection Unit (MPU), programmable only from the R5Fs. - allOf: - - $ref: /schemas/arm/keystone/ti,k3-sci-common.yaml# + $ref: /schemas/arm/keystone/ti,k3-sci-common.yaml# properties: compatible: diff --git a/Documentation/devicetree/bindings/soc/ti/ti,pruss.yaml b/Documentation/devicetree/bindings/soc/ti/ti,pruss.yaml index 9d128b9e7deb..64461d432004 100644 --- a/Documentation/devicetree/bindings/soc/ti/ti,pruss.yaml +++ b/Documentation/devicetree/bindings/soc/ti/ti,pruss.yaml @@ -281,10 +281,7 @@ patternProperties: PRUSS INTC Node. Each PRUSS has a single interrupt controller instance 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# - + $ref: /schemas/interrupt-controller/ti,pruss-intc.yaml# type: object mdio@[a-f0-9]+$: @@ -292,10 +289,7 @@ patternProperties: MDIO Node. Each PRUSS has an MDIO module that can be used to control external PHYs. The MDIO module used within the PRU-ICSS is an instance of the MDIO Controller used in TI Davinci SoCs. - - allOf: - - $ref: /schemas/net/ti,davinci-mdio.yaml# - + $ref: /schemas/net/ti,davinci-mdio.yaml# type: object "^(pru|rtu|txpru)@[0-9a-f]+$": @@ -305,10 +299,7 @@ patternProperties: inactive by using the standard DT string property, "status". The ICSSG IP present on K3 SoCs have additional auxiliary PRU cores with slightly different IP integration. - - allOf: - - $ref: /schemas/remoteproc/ti,pru-rproc.yaml# - + $ref: /schemas/remoteproc/ti,pru-rproc.yaml# type: object required: diff --git a/Documentation/devicetree/bindings/sound/st,stm32-sai.yaml b/Documentation/devicetree/bindings/sound/st,stm32-sai.yaml index d4fc8fdcb72f..b3dbcba33e41 100644 --- a/Documentation/devicetree/bindings/sound/st,stm32-sai.yaml +++ b/Documentation/devicetree/bindings/sound/st,stm32-sai.yaml @@ -115,8 +115,7 @@ patternProperties: By default, custom protocol is assumed, meaning that protocol is configured according to protocol defined in related DAI link node, such as i2s, left justified, right justified, dsp and pdm protocols. - allOf: - - $ref: /schemas/types.yaml#/definitions/flag + $ref: /schemas/types.yaml#/definitions/flag "#clock-cells": description: Configure the SAI device as master clock provider. diff --git a/Documentation/devicetree/bindings/sound/tlv320adcx140.yaml b/Documentation/devicetree/bindings/sound/tlv320adcx140.yaml index d77c8283526d..2ad17b361db0 100644 --- a/Documentation/devicetree/bindings/sound/tlv320adcx140.yaml +++ b/Documentation/devicetree/bindings/sound/tlv320adcx140.yaml @@ -176,13 +176,12 @@ patternProperties: 4 - Drive weak low and active high 5 - Drive Hi-Z and active high - allOf: - - $ref: /schemas/types.yaml#/definitions/uint32-array - - minItems: 2 - maxItems: 2 - items: - maximum: 15 - default: [2, 2] + $ref: /schemas/types.yaml#/definitions/uint32-array + minItems: 2 + maxItems: 2 + items: + maximum: 15 + default: [2, 2] required: - compatible diff --git a/Documentation/devicetree/bindings/spi/spi-controller.yaml b/Documentation/devicetree/bindings/spi/spi-controller.yaml index 36b72518f565..6d0511a8727f 100644 --- a/Documentation/devicetree/bindings/spi/spi-controller.yaml +++ b/Documentation/devicetree/bindings/spi/spi-controller.yaml @@ -93,9 +93,7 @@ properties: patternProperties: "^.*@[0-9a-f]+$": type: object - - allOf: - - $ref: spi-peripheral-props.yaml + $ref: spi-peripheral-props.yaml required: - compatible diff --git a/Documentation/devicetree/bindings/usb/st,stusb160x.yaml b/Documentation/devicetree/bindings/usb/st,stusb160x.yaml index ead1571e0e43..b5a8c9814dd3 100644 --- a/Documentation/devicetree/bindings/usb/st,stusb160x.yaml +++ b/Documentation/devicetree/bindings/usb/st,stusb160x.yaml @@ -32,9 +32,7 @@ properties: connector: type: object - - allOf: - - $ref: ../connector/usb-connector.yaml + $ref: /schemas/connector/usb-connector.yaml# properties: compatible: From 9c02c6391c88a9d2669c2ff8da92cf6efd7f760b Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Tue, 1 Mar 2022 17:28:59 +0100 Subject: [PATCH 241/370] i2c: i801: Drop useless masking in i801_access I went all the way back to kernel 2.6.12 and that masking was never needed. I suppose it was there in anticipation of software PEC support, but that was never added to the driver (and never will be, as this is made obsolete by hardware PEC). I'm also removing initialization to 0, which is not needed either, and would prevent the compiler from reporting an actual usage of uninitialized variables. Signed-off-by: Jean Delvare Reviewed-by: Jarkko Nikula Signed-off-by: Wolfram Sang --- drivers/i2c/busses/i2c-i801.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/i2c/busses/i2c-i801.c b/drivers/i2c/busses/i2c-i801.c index 36b086ef1378..715f6d51d09c 100644 --- a/drivers/i2c/busses/i2c-i801.c +++ b/drivers/i2c/busses/i2c-i801.c @@ -792,7 +792,7 @@ static s32 i801_access(struct i2c_adapter *adap, u16 addr, { int hwpec; int block = 0; - int ret = 0, xact = 0; + int ret, xact; struct i801_priv *priv = i2c_get_adapdata(adap); mutex_lock(&priv->acpi_lock); @@ -904,7 +904,7 @@ static s32 i801_access(struct i2c_adapter *adap, u16 addr, if ((read_write == I2C_SMBUS_WRITE) || (xact == I801_QUICK)) goto out; - switch (xact & 0x7f) { + switch (xact) { case I801_BYTE: /* Result put in SMBHSTDAT0 */ case I801_BYTE_DATA: data->byte = inb_p(SMBHSTDAT0(priv)); From 55b6f82e9443aaf0c6c3a27c394481555ed0da50 Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Tue, 1 Mar 2022 17:39:37 +0100 Subject: [PATCH 242/370] i2c: i801: Add support for the Process Call command The Process Call command is implemented by the hardware since the very first Intel 82801 chipset, and trivial to support. Oscar Romero Matamala from the Georgia Institute of Technology told me it is needed for an experiment his team is working on at the moment, so let's just add support for it. Signed-off-by: Jean Delvare Reviewed-by: Jarkko Nikula Signed-off-by: Wolfram Sang --- drivers/i2c/busses/i2c-i801.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/drivers/i2c/busses/i2c-i801.c b/drivers/i2c/busses/i2c-i801.c index 715f6d51d09c..1fc006a1d532 100644 --- a/drivers/i2c/busses/i2c-i801.c +++ b/drivers/i2c/busses/i2c-i801.c @@ -166,7 +166,7 @@ #define I801_BYTE 0x04 #define I801_BYTE_DATA 0x08 #define I801_WORD_DATA 0x0C -#define I801_PROC_CALL 0x10 /* unimplemented */ +#define I801_PROC_CALL 0x10 #define I801_BLOCK_DATA 0x14 #define I801_I2C_BLOCK_DATA 0x18 /* ICH5 and later */ #define I801_BLOCK_PROC_CALL 0x1C @@ -838,6 +838,14 @@ static s32 i801_access(struct i2c_adapter *adap, u16 addr, } xact = I801_WORD_DATA; break; + case I2C_SMBUS_PROC_CALL: + outb_p((addr & 0x7f) << 1, SMBHSTADD(priv)); + outb_p(command, SMBHSTCMD(priv)); + outb_p(data->word & 0xff, SMBHSTDAT0(priv)); + outb_p((data->word & 0xff00) >> 8, SMBHSTDAT1(priv)); + xact = I801_PROC_CALL; + read_write = I2C_SMBUS_READ; + break; case I2C_SMBUS_BLOCK_DATA: outb_p(((addr & 0x7f) << 1) | (read_write & 0x01), SMBHSTADD(priv)); @@ -910,6 +918,7 @@ static s32 i801_access(struct i2c_adapter *adap, u16 addr, data->byte = inb_p(SMBHSTDAT0(priv)); break; case I801_WORD_DATA: + case I801_PROC_CALL: data->word = inb_p(SMBHSTDAT0(priv)) + (inb_p(SMBHSTDAT1(priv)) << 8); break; @@ -935,6 +944,7 @@ static u32 i801_func(struct i2c_adapter *adapter) return I2C_FUNC_SMBUS_QUICK | I2C_FUNC_SMBUS_BYTE | I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA | + I2C_FUNC_SMBUS_PROC_CALL | I2C_FUNC_SMBUS_BLOCK_DATA | I2C_FUNC_SMBUS_WRITE_I2C_BLOCK | ((priv->features & FEATURE_SMBUS_PEC) ? I2C_FUNC_SMBUS_PEC : 0) | ((priv->features & FEATURE_BLOCK_PROC) ? From 1d366c2f9df8279df2adbb60471f86fc40a1c39e Mon Sep 17 00:00:00 2001 From: Robert Hancock Date: Thu, 27 Jan 2022 11:50:13 -0600 Subject: [PATCH 243/370] i2c: xiic: Make bus names unique This driver is for an FPGA logic core, so there can be arbitrarily many instances of the bus on a given system. Previously all of the I2C bus names were "xiic-i2c" which caused issues with lm_sensors when trying to map human-readable names to sensor inputs because it could not properly distinguish the busses, for example. Append the platform device name to the I2C bus name so it is unique between different instances. Fixes: e1d5b6598cdc ("i2c: Add support for Xilinx XPS IIC Bus Interface") Signed-off-by: Robert Hancock Tested-by: Michal Simek Signed-off-by: Wolfram Sang --- drivers/i2c/busses/i2c-xiic.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/i2c/busses/i2c-xiic.c b/drivers/i2c/busses/i2c-xiic.c index eb789cfb9973..ffefe3c482e9 100644 --- a/drivers/i2c/busses/i2c-xiic.c +++ b/drivers/i2c/busses/i2c-xiic.c @@ -734,7 +734,6 @@ static const struct i2c_adapter_quirks xiic_quirks = { static const struct i2c_adapter xiic_adapter = { .owner = THIS_MODULE, - .name = DRIVER_NAME, .class = I2C_CLASS_DEPRECATED, .algo = &xiic_algorithm, .quirks = &xiic_quirks, @@ -771,6 +770,8 @@ static int xiic_i2c_probe(struct platform_device *pdev) i2c_set_adapdata(&i2c->adap, i2c); i2c->adap.dev.parent = &pdev->dev; i2c->adap.dev.of_node = pdev->dev.of_node; + snprintf(i2c->adap.name, sizeof(i2c->adap.name), + DRIVER_NAME " %s", pdev->name); mutex_init(&i2c->lock); From 309d955985ee9e94697c197b7b489555f1ac7259 Mon Sep 17 00:00:00 2001 From: Rob Herring Date: Mon, 28 Feb 2022 14:10:05 -0600 Subject: [PATCH 244/370] dt-bindings: kbuild: Support partial matches with DT_SCHEMA_FILES DT_SCHEMA_FILES is currently restricted to a list of exact files with the full source tree path (i.e. Documentation/devicetree/bindings/...). Loosen this requirement and let DT_SCHEMA_FILES be a partial match. With this, checking all schema files in a directory is possible: $ make DT_SCHEMA_FILES=/gpio/ dt_binding_check Or all schema files with 'qcom' in the path or filename: $ make DT_SCHEMA_FILES=qcom dt_binding_check Cc: Masahiro Yamada Signed-off-by: Rob Herring Reviewed-by: Krzysztof Kozlowski Link: https://lore.kernel.org/r/20220228201006.1484903-1-robh@kernel.org --- Documentation/devicetree/bindings/Makefile | 15 +++++---------- .../devicetree/bindings/writing-schema.rst | 9 +++++---- 2 files changed, 10 insertions(+), 14 deletions(-) diff --git a/Documentation/devicetree/bindings/Makefile b/Documentation/devicetree/bindings/Makefile index 41c555181b6f..5138d10e0601 100644 --- a/Documentation/devicetree/bindings/Makefile +++ b/Documentation/devicetree/bindings/Makefile @@ -31,11 +31,8 @@ find_all_cmd = find $(srctree)/$(src) \( -name '*.yaml' ! \ -name 'processed-schema*' ! \ -name '*.example.dt.yaml' \) -ifeq ($(DT_SCHEMA_FILES),) -find_cmd = $(find_all_cmd) -else -find_cmd = echo $(addprefix $(srctree)/, $(DT_SCHEMA_FILES)) -endif +find_cmd = $(find_all_cmd) | grep -F "$(DT_SCHEMA_FILES)" +CHK_DT_DOCS := $(shell $(find_cmd)) quiet_cmd_yamllint = LINT $(src) cmd_yamllint = ($(find_cmd) | \ @@ -83,22 +80,20 @@ ifeq ($(DT_SCHEMA_FILES),) $(obj)/processed-schema.json: $(obj)/processed-schema-examples.json FORCE $(call if_changed,copy) -DT_SCHEMA_FILES = $(DT_DOCS) - else # If DT_SCHEMA_FILES is specified, use it for processed-schema.json $(obj)/processed-schema.json: DT_MK_SCHEMA_FLAGS := -u -$(obj)/processed-schema.json: $(DT_SCHEMA_FILES) check_dtschema_version FORCE +$(obj)/processed-schema.json: $(CHK_DT_DOCS) check_dtschema_version FORCE $(call if_changed,mk_schema) endif always-$(CHECK_DT_BINDING) += processed-schema-examples.json always-$(CHECK_DTBS) += processed-schema.json -always-$(CHECK_DT_BINDING) += $(patsubst $(src)/%.yaml,%.example.dts, $(DT_SCHEMA_FILES)) -always-$(CHECK_DT_BINDING) += $(patsubst $(src)/%.yaml,%.example.dt.yaml, $(DT_SCHEMA_FILES)) +always-$(CHECK_DT_BINDING) += $(patsubst $(srctree)/$(src)/%.yaml,%.example.dts, $(CHK_DT_DOCS)) +always-$(CHECK_DT_BINDING) += $(patsubst $(srctree)/$(src)/%.yaml,%.example.dt.yaml, $(CHK_DT_DOCS)) # Hack: avoid 'Argument list too long' error for 'make clean'. Remove most of # build artifacts here before they are processed by scripts/Makefile.clean diff --git a/Documentation/devicetree/bindings/writing-schema.rst b/Documentation/devicetree/bindings/writing-schema.rst index 4004dd9209a6..3b00fe981494 100644 --- a/Documentation/devicetree/bindings/writing-schema.rst +++ b/Documentation/devicetree/bindings/writing-schema.rst @@ -157,13 +157,14 @@ It is possible to run both in a single command:: make dt_binding_check dtbs_check -It is also possible to run checks with a single schema file by setting the -``DT_SCHEMA_FILES`` variable to a specific schema file. +It is also possible to run checks with a subset of matching schema files by +setting the ``DT_SCHEMA_FILES`` variable to a specific schema file or pattern. :: - make dt_binding_check DT_SCHEMA_FILES=Documentation/devicetree/bindings/trivial-devices.yaml - make dtbs_check DT_SCHEMA_FILES=Documentation/devicetree/bindings/trivial-devices.yaml + make dt_binding_check DT_SCHEMA_FILES=trivial-devices.yaml + make dt_binding_check DT_SCHEMA_FILES=/gpio/ + make dtbs_check DT_SCHEMA_FILES=trivial-devices.yaml json-schema Resources From ea87f1eb4fd81375a3abf564f6f2999561985831 Mon Sep 17 00:00:00 2001 From: Rob Herring Date: Thu, 3 Mar 2022 10:57:09 -0600 Subject: [PATCH 245/370] dt-bindings: arm: Allow 32-bit 'cpu-release-addr' values While the DT Spec says 'cpu-release-addr' is always 64-bit, some 32-bit Arm DTs used a 32-bit value. We're now stuck with those cases, so add uint32 as a valid type. Signed-off-by: Rob Herring Acked-by: Krzysztof Kozlowski Link: https://lore.kernel.org/r/20220303165710.1859862-1-robh@kernel.org --- Documentation/devicetree/bindings/arm/cpus.yaml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Documentation/devicetree/bindings/arm/cpus.yaml b/Documentation/devicetree/bindings/arm/cpus.yaml index 916a5aebefff..cddc3f63c9fd 100644 --- a/Documentation/devicetree/bindings/arm/cpus.yaml +++ b/Documentation/devicetree/bindings/arm/cpus.yaml @@ -232,14 +232,14 @@ properties: - ti,am4372 cpu-release-addr: - $ref: '/schemas/types.yaml#/definitions/uint64' - + oneOf: + - $ref: '/schemas/types.yaml#/definitions/uint32' + - $ref: '/schemas/types.yaml#/definitions/uint64' description: + The DT specification defines this as 64-bit always, but some 32-bit Arm + systems have used a 32-bit value which must be supported. Required for systems that have an "enable-method" property value of "spin-table". - On ARM v8 64-bit systems must be a two cell - property identifying a 64-bit zero-initialised - memory location. cpu-idle-states: $ref: '/schemas/types.yaml#/definitions/phandle-array' From 72c356c2cf4066c355cc69ca7127ba70df717d93 Mon Sep 17 00:00:00 2001 From: Luca Ceresoli Date: Wed, 23 Feb 2022 18:59:01 +0100 Subject: [PATCH 246/370] rtc: max77686: Convert comments to kernel-doc format Convert the comments documenting this struct to kernel-doc format for standardization and readability. Signed-off-by: Luca Ceresoli Reviewed-by: Krzysztof Kozlowski Acked-by: Alexandre Belloni Reviewed-by: Randy Dunlap Signed-off-by: Lee Jones --- drivers/rtc/rtc-max77686.c | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/drivers/rtc/rtc-max77686.c b/drivers/rtc/rtc-max77686.c index eae7cb9faf1e..bac52cdea97d 100644 --- a/drivers/rtc/rtc-max77686.c +++ b/drivers/rtc/rtc-max77686.c @@ -61,24 +61,27 @@ enum { RTC_NR_TIME }; +/** + * struct max77686_rtc_driver_data - model-specific configuration + * @delay: Minimum usecs needed for a RTC update + * @mask: Mask used to read RTC registers value + * @map: Registers offset to I2C addresses map + * @alarm_enable_reg: Has a separate alarm enable register? + * @rtc_i2c_addr: I2C address for RTC block + * @rtc_irq_from_platform: RTC interrupt via platform resource + * @alarm_pending_status_reg: Pending alarm status register + * @rtc_irq_chip: RTC IRQ CHIP for regmap + * @regmap_config: regmap configuration for the chip + */ struct max77686_rtc_driver_data { - /* Minimum usecs needed for a RTC update */ unsigned long delay; - /* Mask used to read RTC registers value */ u8 mask; - /* Registers offset to I2C addresses map */ const unsigned int *map; - /* Has a separate alarm enable register? */ bool alarm_enable_reg; - /* I2C address for RTC block */ int rtc_i2c_addr; - /* RTC interrupt via platform resource */ bool rtc_irq_from_platform; - /* Pending alarm status register */ int alarm_pending_status_reg; - /* RTC IRQ CHIP for regmap */ const struct regmap_irq_chip *rtc_irq_chip; - /* regmap configuration for the chip */ const struct regmap_config *regmap_config; }; From a26d84633c2ba3c41fd7692986fb2231c9228c4e Mon Sep 17 00:00:00 2001 From: Luca Ceresoli Date: Wed, 23 Feb 2022 18:59:02 +0100 Subject: [PATCH 247/370] rtc: max77686: Rename day-of-month defines RTC_DATE and REG_RTC_DATE are used for the registers holding the day of month. Rename these constants to mean what they mean. Signed-off-by: Luca Ceresoli Reviewed-by: Krzysztof Kozlowski Acked-by: Alexandre Belloni Signed-off-by: Lee Jones --- drivers/mfd/max77686.c | 2 +- drivers/rtc/rtc-max77686.c | 16 ++++++++-------- include/linux/mfd/max77686-private.h | 4 ++-- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/drivers/mfd/max77686.c b/drivers/mfd/max77686.c index f9e12ab2bc75..2ac64277fb84 100644 --- a/drivers/mfd/max77686.c +++ b/drivers/mfd/max77686.c @@ -87,7 +87,7 @@ static bool max77802_rtc_is_volatile_reg(struct device *dev, unsigned int reg) reg == MAX77802_RTC_WEEKDAY || reg == MAX77802_RTC_MONTH || reg == MAX77802_RTC_YEAR || - reg == MAX77802_RTC_DATE); + reg == MAX77802_RTC_MONTHDAY); } static bool max77802_is_volatile_reg(struct device *dev, unsigned int reg) diff --git a/drivers/rtc/rtc-max77686.c b/drivers/rtc/rtc-max77686.c index bac52cdea97d..7e765207f28e 100644 --- a/drivers/rtc/rtc-max77686.c +++ b/drivers/rtc/rtc-max77686.c @@ -57,7 +57,7 @@ enum { RTC_WEEKDAY, RTC_MONTH, RTC_YEAR, - RTC_DATE, + RTC_MONTHDAY, RTC_NR_TIME }; @@ -119,7 +119,7 @@ enum max77686_rtc_reg_offset { REG_RTC_WEEKDAY, REG_RTC_MONTH, REG_RTC_YEAR, - REG_RTC_DATE, + REG_RTC_MONTHDAY, REG_ALARM1_SEC, REG_ALARM1_MIN, REG_ALARM1_HOUR, @@ -150,7 +150,7 @@ static const unsigned int max77686_map[REG_RTC_END] = { [REG_RTC_WEEKDAY] = MAX77686_RTC_WEEKDAY, [REG_RTC_MONTH] = MAX77686_RTC_MONTH, [REG_RTC_YEAR] = MAX77686_RTC_YEAR, - [REG_RTC_DATE] = MAX77686_RTC_DATE, + [REG_RTC_MONTHDAY] = MAX77686_RTC_MONTHDAY, [REG_ALARM1_SEC] = MAX77686_ALARM1_SEC, [REG_ALARM1_MIN] = MAX77686_ALARM1_MIN, [REG_ALARM1_HOUR] = MAX77686_ALARM1_HOUR, @@ -233,7 +233,7 @@ static const unsigned int max77802_map[REG_RTC_END] = { [REG_RTC_WEEKDAY] = MAX77802_RTC_WEEKDAY, [REG_RTC_MONTH] = MAX77802_RTC_MONTH, [REG_RTC_YEAR] = MAX77802_RTC_YEAR, - [REG_RTC_DATE] = MAX77802_RTC_DATE, + [REG_RTC_MONTHDAY] = MAX77802_RTC_MONTHDAY, [REG_ALARM1_SEC] = MAX77802_ALARM1_SEC, [REG_ALARM1_MIN] = MAX77802_ALARM1_MIN, [REG_ALARM1_HOUR] = MAX77802_ALARM1_HOUR, @@ -288,7 +288,7 @@ static void max77686_rtc_data_to_tm(u8 *data, struct rtc_time *tm, /* Only a single bit is set in data[], so fls() would be equivalent */ tm->tm_wday = ffs(data[RTC_WEEKDAY] & mask) - 1; - tm->tm_mday = data[RTC_DATE] & 0x1f; + tm->tm_mday = data[RTC_MONTHDAY] & 0x1f; tm->tm_mon = (data[RTC_MONTH] & 0x0f) - 1; tm->tm_year = data[RTC_YEAR] & mask; tm->tm_yday = 0; @@ -309,7 +309,7 @@ static int max77686_rtc_tm_to_data(struct rtc_time *tm, u8 *data, data[RTC_MIN] = tm->tm_min; data[RTC_HOUR] = tm->tm_hour; data[RTC_WEEKDAY] = 1 << tm->tm_wday; - data[RTC_DATE] = tm->tm_mday; + data[RTC_MONTHDAY] = tm->tm_mday; data[RTC_MONTH] = tm->tm_mon + 1; if (info->drv_data->alarm_enable_reg) { @@ -565,8 +565,8 @@ static int max77686_rtc_start_alarm(struct max77686_rtc_info *info) data[RTC_MONTH] |= (1 << ALARM_ENABLE_SHIFT); if (data[RTC_YEAR] & info->drv_data->mask) data[RTC_YEAR] |= (1 << ALARM_ENABLE_SHIFT); - if (data[RTC_DATE] & 0x1f) - data[RTC_DATE] |= (1 << ALARM_ENABLE_SHIFT); + if (data[RTC_MONTHDAY] & 0x1f) + data[RTC_MONTHDAY] |= (1 << ALARM_ENABLE_SHIFT); ret = regmap_bulk_write(info->rtc_regmap, map[REG_ALARM1_SEC], data, ARRAY_SIZE(data)); diff --git a/include/linux/mfd/max77686-private.h b/include/linux/mfd/max77686-private.h index b1482b3cf353..3acceeedbaba 100644 --- a/include/linux/mfd/max77686-private.h +++ b/include/linux/mfd/max77686-private.h @@ -152,7 +152,7 @@ enum max77686_rtc_reg { MAX77686_RTC_WEEKDAY = 0x0A, MAX77686_RTC_MONTH = 0x0B, MAX77686_RTC_YEAR = 0x0C, - MAX77686_RTC_DATE = 0x0D, + MAX77686_RTC_MONTHDAY = 0x0D, MAX77686_ALARM1_SEC = 0x0E, MAX77686_ALARM1_MIN = 0x0F, MAX77686_ALARM1_HOUR = 0x10, @@ -352,7 +352,7 @@ enum max77802_rtc_reg { MAX77802_RTC_WEEKDAY = 0xCA, MAX77802_RTC_MONTH = 0xCB, MAX77802_RTC_YEAR = 0xCC, - MAX77802_RTC_DATE = 0xCD, + MAX77802_RTC_MONTHDAY = 0xCD, MAX77802_RTC_AE1 = 0xCE, MAX77802_ALARM1_SEC = 0xCF, MAX77802_ALARM1_MIN = 0xD0, From 3e2e90fefc9bc6f81a477d35db5e3be1bcb9e62d Mon Sep 17 00:00:00 2001 From: Luca Ceresoli Date: Wed, 23 Feb 2022 18:59:03 +0100 Subject: [PATCH 248/370] rtc: max77686: Remove unused code to read in 12-hour mode The MAX77714 RTC chip is explicitly set to 24-hour mode in max77686_rtc_probe() -> max77686_rtc_init_reg() and never changed back to 12-hour mode. Accordingly info->rtc_24hr_mode is set to 1 in the same place and never modified later, so it is de facto a constant. Yet there is code to read 12-hour time, which is unreachable. Remove the unused variable, the unreachable code to manage 12-hour mode and the defines that become unused due to the above changes. Signed-off-by: Luca Ceresoli Reviewed-by: Krzysztof Kozlowski Acked-by: Alexandre Belloni Signed-off-by: Lee Jones --- drivers/rtc/rtc-max77686.c | 14 +------------- 1 file changed, 1 insertion(+), 13 deletions(-) diff --git a/drivers/rtc/rtc-max77686.c b/drivers/rtc/rtc-max77686.c index 7e765207f28e..5c64d08c0732 100644 --- a/drivers/rtc/rtc-max77686.c +++ b/drivers/rtc/rtc-max77686.c @@ -34,9 +34,6 @@ #define RTC_UDR_MASK BIT(RTC_UDR_SHIFT) #define RTC_RBUDR_SHIFT 4 #define RTC_RBUDR_MASK BIT(RTC_RBUDR_SHIFT) -/* RTC Hour register */ -#define HOUR_PM_SHIFT 6 -#define HOUR_PM_MASK BIT(HOUR_PM_SHIFT) /* RTC Alarm Enable */ #define ALARM_ENABLE_SHIFT 7 #define ALARM_ENABLE_MASK BIT(ALARM_ENABLE_SHIFT) @@ -99,7 +96,6 @@ struct max77686_rtc_info { int rtc_irq; int virq; - int rtc_24hr_mode; }; enum MAX77686_RTC_OP { @@ -278,13 +274,7 @@ static void max77686_rtc_data_to_tm(u8 *data, struct rtc_time *tm, tm->tm_sec = data[RTC_SEC] & mask; tm->tm_min = data[RTC_MIN] & mask; - if (info->rtc_24hr_mode) { - tm->tm_hour = data[RTC_HOUR] & 0x1f; - } else { - tm->tm_hour = data[RTC_HOUR] & 0x0f; - if (data[RTC_HOUR] & HOUR_PM_MASK) - tm->tm_hour += 12; - } + tm->tm_hour = data[RTC_HOUR] & 0x1f; /* Only a single bit is set in data[], so fls() would be equivalent */ tm->tm_wday = ffs(data[RTC_WEEKDAY] & mask) - 1; @@ -662,8 +652,6 @@ static int max77686_rtc_init_reg(struct max77686_rtc_info *info) data[0] = (1 << BCD_EN_SHIFT) | (1 << MODEL24_SHIFT); data[1] = (0 << BCD_EN_SHIFT) | (1 << MODEL24_SHIFT); - info->rtc_24hr_mode = 1; - ret = regmap_bulk_write(info->rtc_regmap, info->drv_data->map[REG_RTC_CONTROLM], data, ARRAY_SIZE(data)); From d1f3188478743ee302c8b0c1f6d17a82c517fa9d Mon Sep 17 00:00:00 2001 From: Luca Ceresoli Date: Wed, 23 Feb 2022 18:59:04 +0100 Subject: [PATCH 249/370] dt-bindings: mfd: Add Maxim MAX77714 PMIC Add bindings for the MAX77714 PMIC with GPIO, RTC and watchdog. Signed-off-by: Luca Ceresoli Reviewed-by: Rob Herring Reviewed-by: Krzysztof Kozlowski Signed-off-by: Lee Jones --- .../bindings/mfd/maxim,max77714.yaml | 68 +++++++++++++++++++ MAINTAINERS | 5 ++ 2 files changed, 73 insertions(+) create mode 100644 Documentation/devicetree/bindings/mfd/maxim,max77714.yaml diff --git a/Documentation/devicetree/bindings/mfd/maxim,max77714.yaml b/Documentation/devicetree/bindings/mfd/maxim,max77714.yaml new file mode 100644 index 000000000000..74a6867d3c82 --- /dev/null +++ b/Documentation/devicetree/bindings/mfd/maxim,max77714.yaml @@ -0,0 +1,68 @@ +# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/mfd/maxim,max77714.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: MAX77714 PMIC with GPIO, RTC and watchdog from Maxim Integrated. + +maintainers: + - Luca Ceresoli + +description: | + MAX77714 is a Power Management IC with 4 buck regulators, 9 + low-dropout regulators, 8 GPIOs, RTC and watchdog. + +properties: + compatible: + const: maxim,max77714 + + reg: + maxItems: 1 + + interrupts: + maxItems: 1 + + interrupt-controller: true + + "#interrupt-cells": + const: 2 + description: + The first cell is the IRQ number, the second cell is the trigger type. + + regulators: + type: object + additionalProperties: false + + patternProperties: + '^(buck[0-3]|ldo[0-8])$': + type: object + unevaluatedProperties: false + $ref: /schemas/regulator/regulator.yaml# + +required: + - compatible + - reg + - interrupts + - interrupt-controller + - "#interrupt-cells" + +additionalProperties: false + +examples: + - | + #include + i2c { + #address-cells = <1>; + #size-cells = <0>; + + pmic@1c { + compatible = "maxim,max77714"; + reg = <0x1c>; + interrupt-parent = <&gpio2>; + interrupts = <3 IRQ_TYPE_LEVEL_LOW>; + + interrupt-controller; + #interrupt-cells = <2>; + }; + }; diff --git a/MAINTAINERS b/MAINTAINERS index ea3e6c914384..4cb0e77b47ef 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -11691,6 +11691,11 @@ F: drivers/power/supply/max77650-charger.c F: drivers/regulator/max77650-regulator.c F: include/linux/mfd/max77650.h +MAXIM MAX77714 PMIC MFD DRIVER +M: Luca Ceresoli +S: Maintained +F: Documentation/devicetree/bindings/mfd/maxim,max77714.yaml + MAXIM MAX77802 PMIC REGULATOR DEVICE DRIVER M: Javier Martinez Canillas L: linux-kernel@vger.kernel.org From 60b050ff3a60273d56b4017d0f45d5ca71aae5ad Mon Sep 17 00:00:00 2001 From: Luca Ceresoli Date: Wed, 23 Feb 2022 18:59:05 +0100 Subject: [PATCH 250/370] mfd: max77714: Add driver for Maxim MAX77714 PMIC Add a simple driver for the Maxim MAX77714 PMIC, supporting RTC and watchdog only. Signed-off-by: Luca Ceresoli Reviewed-by: Krzysztof Kozlowski Signed-off-by: Lee Jones --- MAINTAINERS | 2 + drivers/mfd/Kconfig | 14 ++++ drivers/mfd/Makefile | 1 + drivers/mfd/max77714.c | 152 +++++++++++++++++++++++++++++++++++ include/linux/mfd/max77714.h | 60 ++++++++++++++ 5 files changed, 229 insertions(+) create mode 100644 drivers/mfd/max77714.c create mode 100644 include/linux/mfd/max77714.h diff --git a/MAINTAINERS b/MAINTAINERS index 4cb0e77b47ef..6b7c58e7ce84 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -11695,6 +11695,8 @@ MAXIM MAX77714 PMIC MFD DRIVER M: Luca Ceresoli S: Maintained F: Documentation/devicetree/bindings/mfd/maxim,max77714.yaml +F: drivers/mfd/max77714.c +F: include/linux/mfd/max77714.h MAXIM MAX77802 PMIC REGULATOR DEVICE DRIVER M: Javier Martinez Canillas diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig index ba0b3eb131f1..036ddf68c814 100644 --- a/drivers/mfd/Kconfig +++ b/drivers/mfd/Kconfig @@ -849,6 +849,20 @@ config MFD_MAX77693 additional drivers must be enabled in order to use the functionality of the device. +config MFD_MAX77714 + tristate "Maxim Semiconductor MAX77714 PMIC Support" + depends on I2C + depends on OF || COMPILE_TEST + select MFD_CORE + select REGMAP_I2C + help + Say yes here to add support for Maxim Semiconductor MAX77714. + This is a Power Management IC with 4 buck regulators, 9 + low-dropout regulators, 8 GPIOs, RTC, watchdog etc. This driver + provides common support for accessing the device; additional + drivers must be enabled in order to use each functionality of the + device. + config MFD_MAX77843 bool "Maxim Semiconductor MAX77843 PMIC Support" depends on I2C=y diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile index df1ecc4a4c95..eea70cb9f9b9 100644 --- a/drivers/mfd/Makefile +++ b/drivers/mfd/Makefile @@ -162,6 +162,7 @@ obj-$(CONFIG_MFD_MAX77620) += max77620.o obj-$(CONFIG_MFD_MAX77650) += max77650.o obj-$(CONFIG_MFD_MAX77686) += max77686.o obj-$(CONFIG_MFD_MAX77693) += max77693.o +obj-$(CONFIG_MFD_MAX77714) += max77714.o obj-$(CONFIG_MFD_MAX77843) += max77843.o obj-$(CONFIG_MFD_MAX8907) += max8907.o max8925-objs := max8925-core.o max8925-i2c.o diff --git a/drivers/mfd/max77714.c b/drivers/mfd/max77714.c new file mode 100644 index 000000000000..d1e4247800d2 --- /dev/null +++ b/drivers/mfd/max77714.c @@ -0,0 +1,152 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Maxim MAX77714 Core Driver + * + * Copyright (C) 2022 Luca Ceresoli + * Author: Luca Ceresoli + */ + +#include +#include +#include +#include +#include +#include +#include + +static const struct mfd_cell max77714_cells[] = { + { .name = "max77714-watchdog" }, + { .name = "max77714-rtc" }, +}; + +static const struct regmap_range max77714_readable_ranges[] = { + regmap_reg_range(MAX77714_INT_TOP, MAX77714_INT_TOP), + regmap_reg_range(MAX77714_INT_TOPM, MAX77714_INT_TOPM), + regmap_reg_range(MAX77714_32K_STATUS, MAX77714_32K_CONFIG), + regmap_reg_range(MAX77714_CNFG_GLBL2, MAX77714_CNFG2_ONOFF), +}; + +static const struct regmap_range max77714_writable_ranges[] = { + regmap_reg_range(MAX77714_INT_TOPM, MAX77714_INT_TOPM), + regmap_reg_range(MAX77714_32K_CONFIG, MAX77714_32K_CONFIG), + regmap_reg_range(MAX77714_CNFG_GLBL2, MAX77714_CNFG2_ONOFF), +}; + +static const struct regmap_access_table max77714_readable_table = { + .yes_ranges = max77714_readable_ranges, + .n_yes_ranges = ARRAY_SIZE(max77714_readable_ranges), +}; + +static const struct regmap_access_table max77714_writable_table = { + .yes_ranges = max77714_writable_ranges, + .n_yes_ranges = ARRAY_SIZE(max77714_writable_ranges), +}; + +static const struct regmap_config max77714_regmap_config = { + .reg_bits = 8, + .val_bits = 8, + .max_register = MAX77714_CNFG2_ONOFF, + .rd_table = &max77714_readable_table, + .wr_table = &max77714_writable_table, +}; + +static const struct regmap_irq max77714_top_irqs[] = { + REGMAP_IRQ_REG(MAX77714_IRQ_TOP_ONOFF, 0, MAX77714_INT_TOP_ONOFF), + REGMAP_IRQ_REG(MAX77714_IRQ_TOP_RTC, 0, MAX77714_INT_TOP_RTC), + REGMAP_IRQ_REG(MAX77714_IRQ_TOP_GPIO, 0, MAX77714_INT_TOP_GPIO), + REGMAP_IRQ_REG(MAX77714_IRQ_TOP_LDO, 0, MAX77714_INT_TOP_LDO), + REGMAP_IRQ_REG(MAX77714_IRQ_TOP_SD, 0, MAX77714_INT_TOP_SD), + REGMAP_IRQ_REG(MAX77714_IRQ_TOP_GLBL, 0, MAX77714_INT_TOP_GLBL), +}; + +static const struct regmap_irq_chip max77714_irq_chip = { + .name = "max77714-pmic", + .status_base = MAX77714_INT_TOP, + .mask_base = MAX77714_INT_TOPM, + .num_regs = 1, + .irqs = max77714_top_irqs, + .num_irqs = ARRAY_SIZE(max77714_top_irqs), +}; + +/* + * MAX77714 initially uses the internal, low precision oscillator. Enable + * the external oscillator by setting the XOSC_RETRY bit. If the external + * oscillator is not OK (probably not installed) this has no effect. + */ +static int max77714_setup_xosc(struct device *dev, struct regmap *regmap) +{ + /* Internal Crystal Load Capacitance, indexed by value of 32KLOAD bits */ + static const unsigned int load_cap[4] = {0, 10, 12, 22}; /* pF */ + unsigned int load_cap_idx; + unsigned int status; + int err; + + err = regmap_update_bits(regmap, MAX77714_32K_CONFIG, + MAX77714_32K_CONFIG_XOSC_RETRY, + MAX77714_32K_CONFIG_XOSC_RETRY); + if (err) + return dev_err_probe(dev, err, "Failed to configure the external oscillator\n"); + + err = regmap_read(regmap, MAX77714_32K_STATUS, &status); + if (err) + return dev_err_probe(dev, err, "Failed to read external oscillator status\n"); + + load_cap_idx = (status >> MAX77714_32K_STATUS_32KLOAD_SHF) + & MAX77714_32K_STATUS_32KLOAD_MSK; + + dev_info(dev, "Using %s oscillator, %d pF load cap\n", + status & MAX77714_32K_STATUS_32KSOURCE ? "internal" : "external", + load_cap[load_cap_idx]); + + return 0; +} + +static int max77714_probe(struct i2c_client *client) +{ + struct device *dev = &client->dev; + struct regmap *regmap; + struct regmap_irq_chip_data *irq_data; + int err; + + regmap = devm_regmap_init_i2c(client, &max77714_regmap_config); + if (IS_ERR(regmap)) + return dev_err_probe(dev, PTR_ERR(regmap), + "Failed to initialise regmap\n"); + + err = max77714_setup_xosc(dev, regmap); + if (err) + return err; + + err = devm_regmap_add_irq_chip(dev, regmap, client->irq, + IRQF_ONESHOT | IRQF_SHARED, 0, + &max77714_irq_chip, &irq_data); + if (err) + return dev_err_probe(dev, err, "Failed to add PMIC IRQ chip\n"); + + err = devm_mfd_add_devices(dev, PLATFORM_DEVID_NONE, + max77714_cells, ARRAY_SIZE(max77714_cells), + NULL, 0, NULL); + if (err) + return dev_err_probe(dev, err, "Failed to register child devices\n"); + + return 0; +} + +static const struct of_device_id max77714_dt_match[] = { + { .compatible = "maxim,max77714" }, + {}, +}; +MODULE_DEVICE_TABLE(of, max77714_dt_match); + +static struct i2c_driver max77714_driver = { + .driver = { + .name = "max77714", + .of_match_table = max77714_dt_match, + }, + .probe_new = max77714_probe, +}; +module_i2c_driver(max77714_driver); + +MODULE_DESCRIPTION("Maxim MAX77714 MFD core driver"); +MODULE_AUTHOR("Luca Ceresoli "); +MODULE_LICENSE("GPL"); diff --git a/include/linux/mfd/max77714.h b/include/linux/mfd/max77714.h new file mode 100644 index 000000000000..a970dc455426 --- /dev/null +++ b/include/linux/mfd/max77714.h @@ -0,0 +1,60 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Maxim MAX77714 Register and data structures definition. + * + * Copyright (C) 2022 Luca Ceresoli + * Author: Luca Ceresoli + */ + +#ifndef __LINUX_MFD_MAX77714_H_ +#define __LINUX_MFD_MAX77714_H_ + +#include + +#define MAX77714_INT_TOP 0x00 +#define MAX77714_INT_TOPM 0x07 /* Datasheet says "read only", but it is RW */ + +#define MAX77714_INT_TOP_ONOFF BIT(1) +#define MAX77714_INT_TOP_RTC BIT(3) +#define MAX77714_INT_TOP_GPIO BIT(4) +#define MAX77714_INT_TOP_LDO BIT(5) +#define MAX77714_INT_TOP_SD BIT(6) +#define MAX77714_INT_TOP_GLBL BIT(7) + +#define MAX77714_32K_STATUS 0x30 +#define MAX77714_32K_STATUS_SIOSCOK BIT(5) +#define MAX77714_32K_STATUS_XOSCOK BIT(4) +#define MAX77714_32K_STATUS_32KSOURCE BIT(3) +#define MAX77714_32K_STATUS_32KLOAD_MSK 0x3 +#define MAX77714_32K_STATUS_32KLOAD_SHF 1 +#define MAX77714_32K_STATUS_CRYSTAL_CFG BIT(0) + +#define MAX77714_32K_CONFIG 0x31 +#define MAX77714_32K_CONFIG_XOSC_RETRY BIT(4) + +#define MAX77714_CNFG_GLBL2 0x91 +#define MAX77714_WDTEN BIT(2) +#define MAX77714_WDTSLPC BIT(3) +#define MAX77714_TWD_MASK 0x3 +#define MAX77714_TWD_2s 0x0 +#define MAX77714_TWD_16s 0x1 +#define MAX77714_TWD_64s 0x2 +#define MAX77714_TWD_128s 0x3 + +#define MAX77714_CNFG_GLBL3 0x92 +#define MAX77714_WDTC BIT(0) + +#define MAX77714_CNFG2_ONOFF 0x94 +#define MAX77714_WD_RST_WK BIT(5) + +/* Interrupts */ +enum { + MAX77714_IRQ_TOP_ONOFF, + MAX77714_IRQ_TOP_RTC, /* Real-time clock */ + MAX77714_IRQ_TOP_GPIO, /* GPIOs */ + MAX77714_IRQ_TOP_LDO, /* Low-dropout regulators */ + MAX77714_IRQ_TOP_SD, /* Step-down regulators */ + MAX77714_IRQ_TOP_GLBL, /* "Global resources": Low-Battery, overtemp... */ +}; + +#endif /* __LINUX_MFD_MAX77714_H_ */ From 254099d8fafcd80e11a3246f6ff62af816a2b566 Mon Sep 17 00:00:00 2001 From: Luca Ceresoli Date: Wed, 23 Feb 2022 18:59:06 +0100 Subject: [PATCH 251/370] watchdog: max77620: Add support for the max77714 variant The MAX77714 is a MFD chip whose watchdog has the same programming procedures as the MAX77620 watchdog, but most register offsets and bit masks are different, as well as some features. Support the MAX77714 watchdog by adding a variant description table holding the differences. All the features implemented by this driver are available on the MAX77714 except for the lack of a WDTOFFC bit. Instead of using a "HAS_*" flag we handle this by holding in the cnfg_glbl2_cfg_bits struct field the bits (i.e. the features) to enable in the CNFG_GLBL2 register. These bits differ among the two models. This implementation allows to avoid any conditional code, keeping the execution flow unchanged. Signed-off-by: Luca Ceresoli Reviewed-by: Guenter Roeck Signed-off-by: Lee Jones --- drivers/watchdog/Kconfig | 2 +- drivers/watchdog/max77620_wdt.c | 80 ++++++++++++++++++++++++++------- 2 files changed, 65 insertions(+), 17 deletions(-) diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig index c8fa79da23b3..5373ecdec58e 100644 --- a/drivers/watchdog/Kconfig +++ b/drivers/watchdog/Kconfig @@ -678,7 +678,7 @@ config MAX63XX_WATCHDOG config MAX77620_WATCHDOG tristate "Maxim Max77620 Watchdog Timer" - depends on MFD_MAX77620 || COMPILE_TEST + depends on MFD_MAX77620 || MFD_MAX77714 || COMPILE_TEST select WATCHDOG_CORE help This is the driver for the Max77620 watchdog timer. diff --git a/drivers/watchdog/max77620_wdt.c b/drivers/watchdog/max77620_wdt.c index be6a53c30002..cd321c7e0d59 100644 --- a/drivers/watchdog/max77620_wdt.c +++ b/drivers/watchdog/max77620_wdt.c @@ -3,8 +3,10 @@ * Maxim MAX77620 Watchdog Driver * * Copyright (C) 2016 NVIDIA CORPORATION. All rights reserved. + * Copyright (C) 2022 Luca Ceresoli * * Author: Laxman Dewangan + * Author: Luca Ceresoli */ #include @@ -13,6 +15,7 @@ #include #include #include +#include #include #include #include @@ -20,17 +23,57 @@ static bool nowayout = WATCHDOG_NOWAYOUT; +/** + * struct max77620_variant - Data specific to a chip variant + * @wdt_info: watchdog descriptor + * @reg_onoff_cnfg2: ONOFF_CNFG2 register offset + * @reg_cnfg_glbl2: CNFG_GLBL2 register offset + * @reg_cnfg_glbl3: CNFG_GLBL3 register offset + * @wdtc_mask: WDTC bit mask in CNFG_GLBL3 (=bits to update to ping the watchdog) + * @bit_wd_rst_wk: WD_RST_WK bit offset within ONOFF_CNFG2 + * @cnfg_glbl2_cfg_bits: configuration bits to enable in CNFG_GLBL2 register + */ +struct max77620_variant { + u8 reg_onoff_cnfg2; + u8 reg_cnfg_glbl2; + u8 reg_cnfg_glbl3; + u8 wdtc_mask; + u8 bit_wd_rst_wk; + u8 cnfg_glbl2_cfg_bits; +}; + struct max77620_wdt { struct device *dev; struct regmap *rmap; + const struct max77620_variant *drv_data; struct watchdog_device wdt_dev; }; +static const struct max77620_variant max77620_wdt_data = { + .reg_onoff_cnfg2 = MAX77620_REG_ONOFFCNFG2, + .reg_cnfg_glbl2 = MAX77620_REG_CNFGGLBL2, + .reg_cnfg_glbl3 = MAX77620_REG_CNFGGLBL3, + .wdtc_mask = MAX77620_WDTC_MASK, + .bit_wd_rst_wk = MAX77620_ONOFFCNFG2_WD_RST_WK, + /* Set WDT clear in OFF and sleep mode */ + .cnfg_glbl2_cfg_bits = MAX77620_WDTSLPC | MAX77620_WDTOFFC, +}; + +static const struct max77620_variant max77714_wdt_data = { + .reg_onoff_cnfg2 = MAX77714_CNFG2_ONOFF, + .reg_cnfg_glbl2 = MAX77714_CNFG_GLBL2, + .reg_cnfg_glbl3 = MAX77714_CNFG_GLBL3, + .wdtc_mask = MAX77714_WDTC, + .bit_wd_rst_wk = MAX77714_WD_RST_WK, + /* Set WDT clear in sleep mode (there is no WDTOFFC on MAX77714) */ + .cnfg_glbl2_cfg_bits = MAX77714_WDTSLPC, +}; + static int max77620_wdt_start(struct watchdog_device *wdt_dev) { struct max77620_wdt *wdt = watchdog_get_drvdata(wdt_dev); - return regmap_update_bits(wdt->rmap, MAX77620_REG_CNFGGLBL2, + return regmap_update_bits(wdt->rmap, wdt->drv_data->reg_cnfg_glbl2, MAX77620_WDTEN, MAX77620_WDTEN); } @@ -38,7 +81,7 @@ static int max77620_wdt_stop(struct watchdog_device *wdt_dev) { struct max77620_wdt *wdt = watchdog_get_drvdata(wdt_dev); - return regmap_update_bits(wdt->rmap, MAX77620_REG_CNFGGLBL2, + return regmap_update_bits(wdt->rmap, wdt->drv_data->reg_cnfg_glbl2, MAX77620_WDTEN, 0); } @@ -46,8 +89,8 @@ static int max77620_wdt_ping(struct watchdog_device *wdt_dev) { struct max77620_wdt *wdt = watchdog_get_drvdata(wdt_dev); - return regmap_update_bits(wdt->rmap, MAX77620_REG_CNFGGLBL3, - MAX77620_WDTC_MASK, 0x1); + return regmap_update_bits(wdt->rmap, wdt->drv_data->reg_cnfg_glbl3, + wdt->drv_data->wdtc_mask, 0x1); } static int max77620_wdt_set_timeout(struct watchdog_device *wdt_dev, @@ -80,12 +123,12 @@ static int max77620_wdt_set_timeout(struct watchdog_device *wdt_dev, break; } - ret = regmap_update_bits(wdt->rmap, MAX77620_REG_CNFGGLBL3, - MAX77620_WDTC_MASK, 0x1); + ret = regmap_update_bits(wdt->rmap, wdt->drv_data->reg_cnfg_glbl3, + wdt->drv_data->wdtc_mask, 0x1); if (ret < 0) return ret; - ret = regmap_update_bits(wdt->rmap, MAX77620_REG_CNFGGLBL2, + ret = regmap_update_bits(wdt->rmap, wdt->drv_data->reg_cnfg_glbl2, MAX77620_TWD_MASK, regval); if (ret < 0) return ret; @@ -109,6 +152,7 @@ static const struct watchdog_ops max77620_wdt_ops = { static int max77620_wdt_probe(struct platform_device *pdev) { + const struct platform_device_id *id = platform_get_device_id(pdev); struct device *dev = &pdev->dev; struct max77620_wdt *wdt; struct watchdog_device *wdt_dev; @@ -120,6 +164,8 @@ static int max77620_wdt_probe(struct platform_device *pdev) return -ENOMEM; wdt->dev = dev; + wdt->drv_data = (const struct max77620_variant *) id->driver_data; + wdt->rmap = dev_get_regmap(dev->parent, NULL); if (!wdt->rmap) { dev_err(wdt->dev, "Failed to get parent regmap\n"); @@ -136,25 +182,25 @@ static int max77620_wdt_probe(struct platform_device *pdev) platform_set_drvdata(pdev, wdt); /* Enable WD_RST_WK - WDT expire results in a restart */ - ret = regmap_update_bits(wdt->rmap, MAX77620_REG_ONOFFCNFG2, - MAX77620_ONOFFCNFG2_WD_RST_WK, - MAX77620_ONOFFCNFG2_WD_RST_WK); + ret = regmap_update_bits(wdt->rmap, wdt->drv_data->reg_onoff_cnfg2, + wdt->drv_data->bit_wd_rst_wk, + wdt->drv_data->bit_wd_rst_wk); if (ret < 0) { dev_err(wdt->dev, "Failed to set WD_RST_WK: %d\n", ret); return ret; } - /* Set WDT clear in OFF and sleep mode */ - ret = regmap_update_bits(wdt->rmap, MAX77620_REG_CNFGGLBL2, - MAX77620_WDTOFFC | MAX77620_WDTSLPC, - MAX77620_WDTOFFC | MAX77620_WDTSLPC); + /* Set the "auto WDT clear" bits available on the chip */ + ret = regmap_update_bits(wdt->rmap, wdt->drv_data->reg_cnfg_glbl2, + wdt->drv_data->cnfg_glbl2_cfg_bits, + wdt->drv_data->cnfg_glbl2_cfg_bits); if (ret < 0) { dev_err(wdt->dev, "Failed to set WDT OFF mode: %d\n", ret); return ret; } /* Check if WDT running and if yes then set flags properly */ - ret = regmap_read(wdt->rmap, MAX77620_REG_CNFGGLBL2, ®val); + ret = regmap_read(wdt->rmap, wdt->drv_data->reg_cnfg_glbl2, ®val); if (ret < 0) { dev_err(wdt->dev, "Failed to read WDT CFG register: %d\n", ret); return ret; @@ -186,7 +232,8 @@ static int max77620_wdt_probe(struct platform_device *pdev) } static const struct platform_device_id max77620_wdt_devtype[] = { - { .name = "max77620-watchdog", }, + { "max77620-watchdog", (kernel_ulong_t)&max77620_wdt_data }, + { "max77714-watchdog", (kernel_ulong_t)&max77714_wdt_data }, { }, }; MODULE_DEVICE_TABLE(platform, max77620_wdt_devtype); @@ -208,4 +255,5 @@ MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started " "(default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); MODULE_AUTHOR("Laxman Dewangan "); +MODULE_AUTHOR("Luca Ceresoli "); MODULE_LICENSE("GPL v2"); From 3f6f1f1f9f12c16934304ceca342b7ba83639da9 Mon Sep 17 00:00:00 2001 From: Luca Ceresoli Date: Wed, 23 Feb 2022 18:59:07 +0100 Subject: [PATCH 252/370] watchdog: max77620: Add comment to clarify set_timeout procedure Clarify why we need to ping the watchdog before changing the timeout by quoting the MAX77714 datasheet. Signed-off-by: Luca Ceresoli Reviewed-by: Guenter Roeck Signed-off-by: Lee Jones --- drivers/watchdog/max77620_wdt.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/watchdog/max77620_wdt.c b/drivers/watchdog/max77620_wdt.c index cd321c7e0d59..b76ad6ba0915 100644 --- a/drivers/watchdog/max77620_wdt.c +++ b/drivers/watchdog/max77620_wdt.c @@ -123,6 +123,11 @@ static int max77620_wdt_set_timeout(struct watchdog_device *wdt_dev, break; } + /* + * "If the value of TWD needs to be changed, clear the system + * watchdog timer first [...], then change the value of TWD." + * (MAX77714 datasheet but applies to MAX77620 too) + */ ret = regmap_update_bits(wdt->rmap, wdt->drv_data->reg_cnfg_glbl3, wdt->drv_data->wdtc_mask, 0x1); if (ret < 0) From c58e496311a50c087eeeaaae81083cd643fe5128 Mon Sep 17 00:00:00 2001 From: Luca Ceresoli Date: Wed, 23 Feb 2022 18:59:08 +0100 Subject: [PATCH 253/370] rtc: max77686: Add MAX77714 support The RTC included in the MAX77714 PMIC is very similar to the one in the MAX77686. Reuse the rtc-max77686.c driver with the minimum required changes for the MAX77714 RTC. Signed-off-by: Luca Ceresoli Reviewed-by: Krzysztof Kozlowski Acked-by: Alexandre Belloni Signed-off-by: Lee Jones --- drivers/rtc/Kconfig | 2 +- drivers/rtc/rtc-max77686.c | 24 ++++++++++++++++++++++++ 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig index d85a3c31347c..f6d6d4c26361 100644 --- a/drivers/rtc/Kconfig +++ b/drivers/rtc/Kconfig @@ -375,7 +375,7 @@ config RTC_DRV_MAX8997 config RTC_DRV_MAX77686 tristate "Maxim MAX77686" - depends on MFD_MAX77686 || MFD_MAX77620 || COMPILE_TEST + depends on MFD_MAX77686 || MFD_MAX77620 || MFD_MAX77714 || COMPILE_TEST help If you say yes here you will get support for the RTC of Maxim MAX77686/MAX77620/MAX77802 PMIC. diff --git a/drivers/rtc/rtc-max77686.c b/drivers/rtc/rtc-max77686.c index 5c64d08c0732..b0250d91fb00 100644 --- a/drivers/rtc/rtc-max77686.c +++ b/drivers/rtc/rtc-max77686.c @@ -19,6 +19,7 @@ #define MAX77686_I2C_ADDR_RTC (0x0C >> 1) #define MAX77620_I2C_ADDR_RTC 0x68 +#define MAX77714_I2C_ADDR_RTC 0x48 #define MAX77686_INVALID_I2C_ADDR (-1) /* Define non existing register */ @@ -200,6 +201,28 @@ static const struct max77686_rtc_driver_data max77686_drv_data = { .regmap_config = &max77686_rtc_regmap_config, }; +static const struct regmap_irq_chip max77714_rtc_irq_chip = { + .name = "max77714-rtc", + .status_base = MAX77686_RTC_INT, + .mask_base = MAX77686_RTC_INTM, + .num_regs = 1, + .irqs = max77686_rtc_irqs, + .num_irqs = ARRAY_SIZE(max77686_rtc_irqs) - 1, /* no WTSR on 77714 */ +}; + +static const struct max77686_rtc_driver_data max77714_drv_data = { + .delay = 16000, + .mask = 0x7f, + .map = max77686_map, + .alarm_enable_reg = false, + .rtc_irq_from_platform = false, + /* On MAX77714 RTCA1 is BIT 1 of RTCINT (0x00). Not supported by this driver. */ + .alarm_pending_status_reg = MAX77686_INVALID_REG, + .rtc_i2c_addr = MAX77714_I2C_ADDR_RTC, + .rtc_irq_chip = &max77714_rtc_irq_chip, + .regmap_config = &max77686_rtc_regmap_config, +}; + static const struct regmap_config max77620_rtc_regmap_config = { .reg_bits = 8, .val_bits = 8, @@ -843,6 +866,7 @@ static const struct platform_device_id rtc_id[] = { { "max77686-rtc", .driver_data = (kernel_ulong_t)&max77686_drv_data, }, { "max77802-rtc", .driver_data = (kernel_ulong_t)&max77802_drv_data, }, { "max77620-rtc", .driver_data = (kernel_ulong_t)&max77620_drv_data, }, + { "max77714-rtc", .driver_data = (kernel_ulong_t)&max77714_drv_data, }, {}, }; MODULE_DEVICE_TABLE(platform, rtc_id); From e477e51a41cb5d6034f3c5ea85a71ad4613996b9 Mon Sep 17 00:00:00 2001 From: Jiasheng Jiang Date: Thu, 24 Feb 2022 10:23:31 +0800 Subject: [PATCH 254/370] mfd: mc13xxx: Add check for mc13xxx_irq_request As the potential failure of the devm_request_threaded_irq(), it should be better to check the return value of the mc13xxx_irq_request() and return error if fails. Fixes: 8e00593557c3 ("mfd: Add mc13892 support to mc13xxx") Signed-off-by: Jiasheng Jiang Signed-off-by: Lee Jones Link: https://lore.kernel.org/r/20220224022331.3208275-1-jiasheng@iscas.ac.cn --- drivers/mfd/mc13xxx-core.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/mfd/mc13xxx-core.c b/drivers/mfd/mc13xxx-core.c index 8a4f1d90dcfd..1000572761a8 100644 --- a/drivers/mfd/mc13xxx-core.c +++ b/drivers/mfd/mc13xxx-core.c @@ -323,8 +323,10 @@ int mc13xxx_adc_do_conversion(struct mc13xxx *mc13xxx, unsigned int mode, adc1 |= MC13783_ADC1_ATOX; dev_dbg(mc13xxx->dev, "%s: request irq\n", __func__); - mc13xxx_irq_request(mc13xxx, MC13XXX_IRQ_ADCDONE, + ret = mc13xxx_irq_request(mc13xxx, MC13XXX_IRQ_ADCDONE, mc13xxx_handler_adcdone, __func__, &adcdone_data); + if (ret) + goto out; mc13xxx_reg_write(mc13xxx, MC13XXX_ADC0, adc0); mc13xxx_reg_write(mc13xxx, MC13XXX_ADC1, adc1); From c47383f849097c2b3547e28365578cd9e5811378 Mon Sep 17 00:00:00 2001 From: Johnson Wang Date: Thu, 6 Jan 2022 14:54:04 +0800 Subject: [PATCH 255/370] mfd: Add support for the MediaTek MT6366 PMIC This adds support for the MediaTek MT6366 PMIC. This is a multifunction device with the following sub modules: - Regulator - RTC - Codec - Interrupt It is interfaced to the host controller using SPI interface by a proprietary hardware called PMIC wrapper or pwrap. MT6366 MFD is a child device of the pwrap. Signed-off-by: Johnson Wang Signed-off-by: Lee Jones Link: https://lore.kernel.org/r/20220106065407.16036-2-johnson.wang@mediatek.com --- drivers/mfd/mt6358-irq.c | 1 + include/linux/mfd/mt6358/registers.h | 7 +++++++ include/linux/mfd/mt6397/core.h | 1 + 3 files changed, 9 insertions(+) diff --git a/drivers/mfd/mt6358-irq.c b/drivers/mfd/mt6358-irq.c index 83f3ffbdbb4c..ea5e452510eb 100644 --- a/drivers/mfd/mt6358-irq.c +++ b/drivers/mfd/mt6358-irq.c @@ -212,6 +212,7 @@ int mt6358_irq_init(struct mt6397_chip *chip) switch (chip->chip_id) { case MT6358_CHIP_ID: + case MT6366_CHIP_ID: chip->irq_data = &mt6358_irqd; break; diff --git a/include/linux/mfd/mt6358/registers.h b/include/linux/mfd/mt6358/registers.h index 201139b12140..3d33517f178c 100644 --- a/include/linux/mfd/mt6358/registers.h +++ b/include/linux/mfd/mt6358/registers.h @@ -94,6 +94,10 @@ #define MT6358_BUCK_VCORE_CON0 0x1488 #define MT6358_BUCK_VCORE_DBG0 0x149e #define MT6358_BUCK_VCORE_DBG1 0x14a0 +#define MT6358_BUCK_VCORE_SSHUB_CON0 0x14a4 +#define MT6358_BUCK_VCORE_SSHUB_CON1 0x14a6 +#define MT6358_BUCK_VCORE_SSHUB_ELR0 MT6358_BUCK_VCORE_SSHUB_CON1 +#define MT6358_BUCK_VCORE_SSHUB_DBG1 MT6358_BUCK_VCORE_DBG1 #define MT6358_BUCK_VCORE_ELR0 0x14aa #define MT6358_BUCK_VGPU_CON0 0x1508 #define MT6358_BUCK_VGPU_DBG0 0x151e @@ -169,6 +173,9 @@ #define MT6358_LDO_VSRAM_OTHERS_CON0 0x1ba6 #define MT6358_LDO_VSRAM_OTHERS_DBG0 0x1bc0 #define MT6358_LDO_VSRAM_OTHERS_DBG1 0x1bc2 +#define MT6358_LDO_VSRAM_OTHERS_SSHUB_CON0 0x1bc4 +#define MT6358_LDO_VSRAM_OTHERS_SSHUB_CON1 0x1bc6 +#define MT6358_LDO_VSRAM_OTHERS_SSHUB_DBG1 MT6358_LDO_VSRAM_OTHERS_DBG1 #define MT6358_LDO_VSRAM_GPU_CON0 0x1bc8 #define MT6358_LDO_VSRAM_GPU_DBG0 0x1be2 #define MT6358_LDO_VSRAM_GPU_DBG1 0x1be4 diff --git a/include/linux/mfd/mt6397/core.h b/include/linux/mfd/mt6397/core.h index 56f210eebc54..1cf78726503b 100644 --- a/include/linux/mfd/mt6397/core.h +++ b/include/linux/mfd/mt6397/core.h @@ -14,6 +14,7 @@ enum chip_id { MT6323_CHIP_ID = 0x23, MT6358_CHIP_ID = 0x58, MT6359_CHIP_ID = 0x59, + MT6366_CHIP_ID = 0x66, MT6391_CHIP_ID = 0x91, MT6397_CHIP_ID = 0x97, }; From 85e6c775762aa4067d2c2b8121e59a06564d0dc4 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Fri, 4 Mar 2022 18:55:55 +0100 Subject: [PATCH 256/370] nvme: remove support or stream based temperature hint This support was added for RocksDB, but RocksDB ended up not using it. At the same time drives on the open marked (vs those build for OEMs for non-Linux support) that actually support streams are extremly rare. Don't bloat the nvme driver for it. Signed-off-by: Christoph Hellwig Acked-by: Jens Axboe Reviewed-by: Keith Busch Link: https://lore.kernel.org/r/20220304175556.407719-1-hch@lst.de [axboe: fold in ctrl->nr_streams removal from Keith] Signed-off-by: Jens Axboe --- drivers/nvme/host/core.c | 143 --------------------------------------- drivers/nvme/host/nvme.h | 1 - 2 files changed, 144 deletions(-) diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c index ace8c61850b1..bcbe12fd4984 100644 --- a/drivers/nvme/host/core.c +++ b/drivers/nvme/host/core.c @@ -77,10 +77,6 @@ module_param(apst_secondary_latency_tol_us, ulong, 0644); MODULE_PARM_DESC(apst_secondary_latency_tol_us, "secondary APST latency tolerance in us"); -static bool streams; -module_param(streams, bool, 0644); -MODULE_PARM_DESC(streams, "turn on support for Streams write directives"); - /* * nvme_wq - hosts nvme related works that are not reset or delete * nvme_reset_wq - hosts nvme reset works @@ -748,108 +744,6 @@ bool __nvme_check_ready(struct nvme_ctrl *ctrl, struct request *rq, } EXPORT_SYMBOL_GPL(__nvme_check_ready); -static int nvme_toggle_streams(struct nvme_ctrl *ctrl, bool enable) -{ - struct nvme_command c = { }; - - c.directive.opcode = nvme_admin_directive_send; - c.directive.nsid = cpu_to_le32(NVME_NSID_ALL); - c.directive.doper = NVME_DIR_SND_ID_OP_ENABLE; - c.directive.dtype = NVME_DIR_IDENTIFY; - c.directive.tdtype = NVME_DIR_STREAMS; - c.directive.endir = enable ? NVME_DIR_ENDIR : 0; - - return nvme_submit_sync_cmd(ctrl->admin_q, &c, NULL, 0); -} - -static int nvme_disable_streams(struct nvme_ctrl *ctrl) -{ - return nvme_toggle_streams(ctrl, false); -} - -static int nvme_enable_streams(struct nvme_ctrl *ctrl) -{ - return nvme_toggle_streams(ctrl, true); -} - -static int nvme_get_stream_params(struct nvme_ctrl *ctrl, - struct streams_directive_params *s, u32 nsid) -{ - struct nvme_command c = { }; - - memset(s, 0, sizeof(*s)); - - c.directive.opcode = nvme_admin_directive_recv; - c.directive.nsid = cpu_to_le32(nsid); - c.directive.numd = cpu_to_le32(nvme_bytes_to_numd(sizeof(*s))); - c.directive.doper = NVME_DIR_RCV_ST_OP_PARAM; - c.directive.dtype = NVME_DIR_STREAMS; - - return nvme_submit_sync_cmd(ctrl->admin_q, &c, s, sizeof(*s)); -} - -static int nvme_configure_directives(struct nvme_ctrl *ctrl) -{ - struct streams_directive_params s; - u16 nssa; - int ret; - - if (!(ctrl->oacs & NVME_CTRL_OACS_DIRECTIVES)) - return 0; - if (!streams) - return 0; - - ret = nvme_enable_streams(ctrl); - if (ret) - return ret; - - ret = nvme_get_stream_params(ctrl, &s, NVME_NSID_ALL); - if (ret) - goto out_disable_stream; - - nssa = le16_to_cpu(s.nssa); - if (nssa < BLK_MAX_WRITE_HINTS - 1) { - dev_info(ctrl->device, "too few streams (%u) available\n", - nssa); - /* this condition is not an error: streams are optional */ - ret = 0; - goto out_disable_stream; - } - - ctrl->nr_streams = min_t(u16, nssa, BLK_MAX_WRITE_HINTS - 1); - dev_info(ctrl->device, "Using %u streams\n", ctrl->nr_streams); - return 0; - -out_disable_stream: - nvme_disable_streams(ctrl); - return ret; -} - -/* - * Check if 'req' has a write hint associated with it. If it does, assign - * a valid namespace stream to the write. - */ -static void nvme_assign_write_stream(struct nvme_ctrl *ctrl, - struct request *req, u16 *control, - u32 *dsmgmt) -{ - enum rw_hint streamid = req->write_hint; - - if (streamid == WRITE_LIFE_NOT_SET || streamid == WRITE_LIFE_NONE) - streamid = 0; - else { - streamid--; - if (WARN_ON_ONCE(streamid > ctrl->nr_streams)) - return; - - *control |= NVME_RW_DTYPE_STREAMS; - *dsmgmt |= streamid << 16; - } - - if (streamid < ARRAY_SIZE(req->q->write_hints)) - req->q->write_hints[streamid] += blk_rq_bytes(req) >> 9; -} - static inline void nvme_setup_flush(struct nvme_ns *ns, struct nvme_command *cmnd) { @@ -953,7 +847,6 @@ static inline blk_status_t nvme_setup_rw(struct nvme_ns *ns, struct request *req, struct nvme_command *cmnd, enum nvme_opcode op) { - struct nvme_ctrl *ctrl = ns->ctrl; u16 control = 0; u32 dsmgmt = 0; @@ -976,9 +869,6 @@ static inline blk_status_t nvme_setup_rw(struct nvme_ns *ns, cmnd->rw.apptag = 0; cmnd->rw.appmask = 0; - if (req_op(req) == REQ_OP_WRITE && ctrl->nr_streams) - nvme_assign_write_stream(ctrl, req, &control, &dsmgmt); - if (ns->ms) { /* * If formated with metadata, the block layer always provides a @@ -1697,9 +1587,6 @@ static void nvme_config_discard(struct gendisk *disk, struct nvme_ns *ns) return; } - if (ctrl->nr_streams && ns->sws && ns->sgs) - size *= ns->sws * ns->sgs; - BUILD_BUG_ON(PAGE_SIZE / sizeof(struct nvme_dsm_range) < NVME_DSM_MAX_RANGES); @@ -1725,31 +1612,6 @@ static bool nvme_ns_ids_equal(struct nvme_ns_ids *a, struct nvme_ns_ids *b) a->csi == b->csi; } -static int nvme_setup_streams_ns(struct nvme_ctrl *ctrl, struct nvme_ns *ns, - u32 *phys_bs, u32 *io_opt) -{ - struct streams_directive_params s; - int ret; - - if (!ctrl->nr_streams) - return 0; - - ret = nvme_get_stream_params(ctrl, &s, ns->head->ns_id); - if (ret) - return ret; - - ns->sws = le32_to_cpu(s.sws); - ns->sgs = le16_to_cpu(s.sgs); - - if (ns->sws) { - *phys_bs = ns->sws * (1 << ns->lba_shift); - if (ns->sgs) - *io_opt = *phys_bs * ns->sgs; - } - - return 0; -} - static void nvme_configure_metadata(struct nvme_ns *ns, struct nvme_id_ns *id) { struct nvme_ctrl *ctrl = ns->ctrl; @@ -1841,7 +1703,6 @@ static void nvme_update_disk_info(struct gendisk *disk, blk_integrity_unregister(disk); atomic_bs = phys_bs = bs; - nvme_setup_streams_ns(ns->ctrl, ns, &phys_bs, &io_opt); if (id->nabo == 0) { /* * Bit 1 indicates whether NAWUPF is defined for this namespace @@ -3131,10 +2992,6 @@ int nvme_init_ctrl_finish(struct nvme_ctrl *ctrl) if (ret < 0) return ret; - ret = nvme_configure_directives(ctrl); - if (ret < 0) - return ret; - ret = nvme_configure_acre(ctrl); if (ret < 0) return ret; diff --git a/drivers/nvme/host/nvme.h b/drivers/nvme/host/nvme.h index 587d92df118b..1bed663322ee 100644 --- a/drivers/nvme/host/nvme.h +++ b/drivers/nvme/host/nvme.h @@ -280,7 +280,6 @@ struct nvme_ctrl { u16 crdt[3]; u16 oncs; u16 oacs; - u16 nr_streams; u16 sqsize; u32 max_namespaces; atomic_t abort_limit; From c75e707fe1aab32f1dc8e09845533b6542d9aaa9 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Fri, 4 Mar 2022 18:55:56 +0100 Subject: [PATCH 257/370] block: remove the per-bio/request write hint With the NVMe support for this gone, there are no consumers of these hints left, so remove them. Signed-off-by: Christoph Hellwig Link: https://lore.kernel.org/r/20220304175556.407719-2-hch@lst.de Signed-off-by: Jens Axboe --- block/bio.c | 2 -- block/blk-crypto-fallback.c | 1 - block/blk-merge.c | 14 -------------- block/blk-mq-debugfs.c | 24 ------------------------ block/blk-mq.c | 1 - block/bounce.c | 1 - block/fops.c | 3 --- drivers/md/raid1.c | 2 -- drivers/md/raid5-ppl.c | 28 +++------------------------- drivers/md/raid5.c | 6 ------ fs/btrfs/extent_io.c | 1 - fs/buffer.c | 13 +++++-------- fs/direct-io.c | 3 --- fs/ext4/page-io.c | 5 +---- fs/f2fs/data.c | 2 -- fs/gfs2/lops.c | 1 - fs/iomap/buffered-io.c | 2 -- fs/iomap/direct-io.c | 1 - fs/mpage.c | 1 - fs/zonefs/super.c | 1 - include/linux/blk_types.h | 1 - include/linux/blkdev.h | 3 --- 22 files changed, 9 insertions(+), 107 deletions(-) diff --git a/block/bio.c b/block/bio.c index 151cace2dbe1..3c57b3ba727d 100644 --- a/block/bio.c +++ b/block/bio.c @@ -257,7 +257,6 @@ void bio_init(struct bio *bio, struct block_device *bdev, struct bio_vec *table, bio->bi_opf = opf; bio->bi_flags = 0; bio->bi_ioprio = 0; - bio->bi_write_hint = 0; bio->bi_status = 0; bio->bi_iter.bi_sector = 0; bio->bi_iter.bi_size = 0; @@ -737,7 +736,6 @@ static int __bio_clone(struct bio *bio, struct bio *bio_src, gfp_t gfp) bio_flagged(bio_src, BIO_REMAPPED)) bio_set_flag(bio, BIO_REMAPPED); bio->bi_ioprio = bio_src->bi_ioprio; - bio->bi_write_hint = bio_src->bi_write_hint; bio->bi_iter = bio_src->bi_iter; bio_clone_blkg_association(bio, bio_src); diff --git a/block/blk-crypto-fallback.c b/block/blk-crypto-fallback.c index 18c8eafe20b9..7c854584b52b 100644 --- a/block/blk-crypto-fallback.c +++ b/block/blk-crypto-fallback.c @@ -170,7 +170,6 @@ static struct bio *blk_crypto_fallback_clone_bio(struct bio *bio_src) bio_set_flag(bio, BIO_REMAPPED); bio->bi_opf = bio_src->bi_opf; bio->bi_ioprio = bio_src->bi_ioprio; - bio->bi_write_hint = bio_src->bi_write_hint; bio->bi_iter.bi_sector = bio_src->bi_iter.bi_sector; bio->bi_iter.bi_size = bio_src->bi_iter.bi_size; diff --git a/block/blk-merge.c b/block/blk-merge.c index f5255991b773..0e871d4e7cb8 100644 --- a/block/blk-merge.c +++ b/block/blk-merge.c @@ -782,13 +782,6 @@ static struct request *attempt_merge(struct request_queue *q, !blk_write_same_mergeable(req->bio, next->bio)) return NULL; - /* - * Don't allow merge of different write hints, or for a hint with - * non-hint IO. - */ - if (req->write_hint != next->write_hint) - return NULL; - if (req->ioprio != next->ioprio) return NULL; @@ -915,13 +908,6 @@ bool blk_rq_merge_ok(struct request *rq, struct bio *bio) !blk_write_same_mergeable(rq->bio, bio)) return false; - /* - * Don't allow merge of different write hints, or for a hint with - * non-hint IO. - */ - if (rq->write_hint != bio->bi_write_hint) - return false; - if (rq->ioprio != bio_prio(bio)) return false; diff --git a/block/blk-mq-debugfs.c b/block/blk-mq-debugfs.c index 3a790eb4995c..c2904c75c160 100644 --- a/block/blk-mq-debugfs.c +++ b/block/blk-mq-debugfs.c @@ -183,35 +183,11 @@ inval: return count; } -static int queue_write_hint_show(void *data, struct seq_file *m) -{ - struct request_queue *q = data; - int i; - - for (i = 0; i < BLK_MAX_WRITE_HINTS; i++) - seq_printf(m, "hint%d: %llu\n", i, q->write_hints[i]); - - return 0; -} - -static ssize_t queue_write_hint_store(void *data, const char __user *buf, - size_t count, loff_t *ppos) -{ - struct request_queue *q = data; - int i; - - for (i = 0; i < BLK_MAX_WRITE_HINTS; i++) - q->write_hints[i] = 0; - - return count; -} - static const struct blk_mq_debugfs_attr blk_mq_debugfs_queue_attrs[] = { { "poll_stat", 0400, queue_poll_stat_show }, { "requeue_list", 0400, .seq_ops = &queue_requeue_list_seq_ops }, { "pm_only", 0600, queue_pm_only_show, NULL }, { "state", 0600, queue_state_show, queue_state_write }, - { "write_hints", 0600, queue_write_hint_show, queue_write_hint_store }, { "zone_wlock", 0400, queue_zone_wlock_show, NULL }, { }, }; diff --git a/block/blk-mq.c b/block/blk-mq.c index f1b067d06ab5..64d5c2edb817 100644 --- a/block/blk-mq.c +++ b/block/blk-mq.c @@ -2406,7 +2406,6 @@ static void blk_mq_bio_to_request(struct request *rq, struct bio *bio, rq->cmd_flags |= REQ_FAILFAST_MASK; rq->__sector = bio->bi_iter.bi_sector; - rq->write_hint = bio->bi_write_hint; blk_rq_bio_prep(rq, bio, nr_segs); /* This can't fail, since GFP_NOIO includes __GFP_DIRECT_RECLAIM. */ diff --git a/block/bounce.c b/block/bounce.c index 3d50d19cde72..9db1256d57d5 100644 --- a/block/bounce.c +++ b/block/bounce.c @@ -169,7 +169,6 @@ static struct bio *bounce_clone_bio(struct bio *bio_src) if (bio_flagged(bio_src, BIO_REMAPPED)) bio_set_flag(bio, BIO_REMAPPED); bio->bi_ioprio = bio_src->bi_ioprio; - bio->bi_write_hint = bio_src->bi_write_hint; bio->bi_iter.bi_sector = bio_src->bi_iter.bi_sector; bio->bi_iter.bi_size = bio_src->bi_iter.bi_size; diff --git a/block/fops.c b/block/fops.c index 7ccc4ff109ce..1c732b72de72 100644 --- a/block/fops.c +++ b/block/fops.c @@ -83,7 +83,6 @@ static ssize_t __blkdev_direct_IO_simple(struct kiocb *iocb, bio_init(&bio, bdev, vecs, nr_pages, dio_bio_write_op(iocb)); } bio.bi_iter.bi_sector = pos >> SECTOR_SHIFT; - bio.bi_write_hint = iocb->ki_hint; bio.bi_private = current; bio.bi_end_io = blkdev_bio_end_io_simple; bio.bi_ioprio = iocb->ki_ioprio; @@ -225,7 +224,6 @@ static ssize_t __blkdev_direct_IO(struct kiocb *iocb, struct iov_iter *iter, for (;;) { bio->bi_iter.bi_sector = pos >> SECTOR_SHIFT; - bio->bi_write_hint = iocb->ki_hint; bio->bi_private = dio; bio->bi_end_io = blkdev_bio_end_io; bio->bi_ioprio = iocb->ki_ioprio; @@ -327,7 +325,6 @@ static ssize_t __blkdev_direct_IO_async(struct kiocb *iocb, dio->flags = 0; dio->iocb = iocb; bio->bi_iter.bi_sector = pos >> SECTOR_SHIFT; - bio->bi_write_hint = iocb->ki_hint; bio->bi_end_io = blkdev_bio_end_io_async; bio->bi_ioprio = iocb->ki_ioprio; diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c index 03477e971699..370ab3218534 100644 --- a/drivers/md/raid1.c +++ b/drivers/md/raid1.c @@ -1137,8 +1137,6 @@ static void alloc_behind_master_bio(struct r1bio *r1_bio, goto skip_copy; } - behind_bio->bi_write_hint = bio->bi_write_hint; - while (i < vcnt && size) { struct page *page; int len = min_t(int, PAGE_SIZE, size); diff --git a/drivers/md/raid5-ppl.c b/drivers/md/raid5-ppl.c index bbb5673104ec..388ab41d1a11 100644 --- a/drivers/md/raid5-ppl.c +++ b/drivers/md/raid5-ppl.c @@ -467,7 +467,6 @@ static void ppl_submit_iounit(struct ppl_io_unit *io) bio_set_dev(bio, log->rdev->bdev); bio->bi_iter.bi_sector = log->next_io_sector; bio_add_page(bio, io->header_page, PAGE_SIZE, 0); - bio->bi_write_hint = ppl_conf->write_hint; pr_debug("%s: log->current_io_sector: %llu\n", __func__, (unsigned long long)log->next_io_sector); @@ -497,7 +496,6 @@ static void ppl_submit_iounit(struct ppl_io_unit *io) bio = bio_alloc_bioset(prev->bi_bdev, BIO_MAX_VECS, prev->bi_opf, GFP_NOIO, &ppl_conf->bs); - bio->bi_write_hint = prev->bi_write_hint; bio->bi_iter.bi_sector = bio_end_sector(prev); bio_add_page(bio, sh->ppl_page, PAGE_SIZE, 0); @@ -1397,7 +1395,6 @@ int ppl_init_log(struct r5conf *conf) atomic64_set(&ppl_conf->seq, 0); INIT_LIST_HEAD(&ppl_conf->no_mem_stripes); spin_lock_init(&ppl_conf->no_mem_stripes_lock); - ppl_conf->write_hint = RWH_WRITE_LIFE_NOT_SET; if (!mddev->external) { ppl_conf->signature = ~crc32c_le(~0, mddev->uuid, sizeof(mddev->uuid)); @@ -1496,25 +1493,13 @@ int ppl_modify_log(struct r5conf *conf, struct md_rdev *rdev, bool add) static ssize_t ppl_write_hint_show(struct mddev *mddev, char *buf) { - size_t ret = 0; - struct r5conf *conf; - struct ppl_conf *ppl_conf = NULL; - - spin_lock(&mddev->lock); - conf = mddev->private; - if (conf && raid5_has_ppl(conf)) - ppl_conf = conf->log_private; - ret = sprintf(buf, "%d\n", ppl_conf ? ppl_conf->write_hint : 0); - spin_unlock(&mddev->lock); - - return ret; + return sprintf(buf, "%d\n", 0); } static ssize_t ppl_write_hint_store(struct mddev *mddev, const char *page, size_t len) { struct r5conf *conf; - struct ppl_conf *ppl_conf; int err = 0; unsigned short new; @@ -1528,17 +1513,10 @@ ppl_write_hint_store(struct mddev *mddev, const char *page, size_t len) return err; conf = mddev->private; - if (!conf) { + if (!conf) err = -ENODEV; - } else if (raid5_has_ppl(conf)) { - ppl_conf = conf->log_private; - if (!ppl_conf) - err = -EINVAL; - else - ppl_conf->write_hint = new; - } else { + else if (!raid5_has_ppl(conf) || !conf->log_private) err = -EINVAL; - } mddev_unlock(mddev); diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c index 8891aaba6596..78503db55ca4 100644 --- a/drivers/md/raid5.c +++ b/drivers/md/raid5.c @@ -1210,9 +1210,6 @@ again: bi->bi_io_vec[0].bv_len = RAID5_STRIPE_SIZE(conf); bi->bi_io_vec[0].bv_offset = sh->dev[i].offset; bi->bi_iter.bi_size = RAID5_STRIPE_SIZE(conf); - bi->bi_write_hint = sh->dev[i].write_hint; - if (!rrdev) - sh->dev[i].write_hint = RWH_WRITE_LIFE_NOT_SET; /* * If this is discard request, set bi_vcnt 0. We don't * want to confuse SCSI because SCSI will replace payload @@ -1264,8 +1261,6 @@ again: rbi->bi_io_vec[0].bv_len = RAID5_STRIPE_SIZE(conf); rbi->bi_io_vec[0].bv_offset = sh->dev[i].offset; rbi->bi_iter.bi_size = RAID5_STRIPE_SIZE(conf); - rbi->bi_write_hint = sh->dev[i].write_hint; - sh->dev[i].write_hint = RWH_WRITE_LIFE_NOT_SET; /* * If this is discard request, set bi_vcnt 0. We don't * want to confuse SCSI because SCSI will replace payload @@ -3416,7 +3411,6 @@ static int add_stripe_bio(struct stripe_head *sh, struct bio *bi, int dd_idx, (unsigned long long)sh->sector); spin_lock_irq(&sh->stripe_lock); - sh->dev[dd_idx].write_hint = bi->bi_write_hint; /* Don't allow new IO added to stripes in batch list */ if (sh->batch_head) goto overlap; diff --git a/fs/btrfs/extent_io.c b/fs/btrfs/extent_io.c index 5923eec8caa8..3b386bbb85a7 100644 --- a/fs/btrfs/extent_io.c +++ b/fs/btrfs/extent_io.c @@ -3321,7 +3321,6 @@ static int alloc_new_bio(struct btrfs_inode *inode, bio_ctrl->bio_flags = bio_flags; bio->bi_end_io = end_io_func; bio->bi_private = &inode->io_tree; - bio->bi_write_hint = inode->vfs_inode.i_write_hint; bio->bi_opf = opf; ret = calc_bio_boundaries(bio_ctrl, inode, file_offset); if (ret < 0) diff --git a/fs/buffer.c b/fs/buffer.c index a17c386a142c..29c6c60660f6 100644 --- a/fs/buffer.c +++ b/fs/buffer.c @@ -53,7 +53,7 @@ static int fsync_buffers_list(spinlock_t *lock, struct list_head *list); static int submit_bh_wbc(int op, int op_flags, struct buffer_head *bh, - enum rw_hint hint, struct writeback_control *wbc); + struct writeback_control *wbc); #define BH_ENTRY(list) list_entry((list), struct buffer_head, b_assoc_buffers) @@ -1806,8 +1806,7 @@ int __block_write_full_page(struct inode *inode, struct page *page, do { struct buffer_head *next = bh->b_this_page; if (buffer_async_write(bh)) { - submit_bh_wbc(REQ_OP_WRITE, write_flags, bh, - inode->i_write_hint, wbc); + submit_bh_wbc(REQ_OP_WRITE, write_flags, bh, wbc); nr_underway++; } bh = next; @@ -1861,8 +1860,7 @@ recover: struct buffer_head *next = bh->b_this_page; if (buffer_async_write(bh)) { clear_buffer_dirty(bh); - submit_bh_wbc(REQ_OP_WRITE, write_flags, bh, - inode->i_write_hint, wbc); + submit_bh_wbc(REQ_OP_WRITE, write_flags, bh, wbc); nr_underway++; } bh = next; @@ -3008,7 +3006,7 @@ static void end_bio_bh_io_sync(struct bio *bio) } static int submit_bh_wbc(int op, int op_flags, struct buffer_head *bh, - enum rw_hint write_hint, struct writeback_control *wbc) + struct writeback_control *wbc) { struct bio *bio; @@ -3034,7 +3032,6 @@ static int submit_bh_wbc(int op, int op_flags, struct buffer_head *bh, fscrypt_set_bio_crypt_ctx_bh(bio, bh, GFP_NOIO); bio->bi_iter.bi_sector = bh->b_blocknr * (bh->b_size >> 9); - bio->bi_write_hint = write_hint; bio_add_page(bio, bh->b_page, bh->b_size, bh_offset(bh)); BUG_ON(bio->bi_iter.bi_size != bh->b_size); @@ -3056,7 +3053,7 @@ static int submit_bh_wbc(int op, int op_flags, struct buffer_head *bh, int submit_bh(int op, int op_flags, struct buffer_head *bh) { - return submit_bh_wbc(op, op_flags, bh, 0, NULL); + return submit_bh_wbc(op, op_flags, bh, NULL); } EXPORT_SYMBOL(submit_bh); diff --git a/fs/direct-io.c b/fs/direct-io.c index 38bca4980a1c..aef06e607b40 100644 --- a/fs/direct-io.c +++ b/fs/direct-io.c @@ -402,9 +402,6 @@ dio_bio_alloc(struct dio *dio, struct dio_submit *sdio, bio->bi_end_io = dio_bio_end_aio; else bio->bi_end_io = dio_bio_end_io; - - bio->bi_write_hint = dio->iocb->ki_hint; - sdio->bio = bio; sdio->logical_offset_in_bio = sdio->cur_page_fs_offset; } diff --git a/fs/ext4/page-io.c b/fs/ext4/page-io.c index 17bb78ebd784..495ce59fb4ad 100644 --- a/fs/ext4/page-io.c +++ b/fs/ext4/page-io.c @@ -373,7 +373,6 @@ void ext4_io_submit(struct ext4_io_submit *io) if (bio) { if (io->io_wbc->sync_mode == WB_SYNC_ALL) io->io_bio->bi_opf |= REQ_SYNC; - io->io_bio->bi_write_hint = io->io_end->inode->i_write_hint; submit_bio(io->io_bio); } io->io_bio = NULL; @@ -418,10 +417,8 @@ static void io_submit_add_bh(struct ext4_io_submit *io, submit_and_retry: ext4_io_submit(io); } - if (io->io_bio == NULL) { + if (io->io_bio == NULL) io_submit_init_bio(io, bh); - io->io_bio->bi_write_hint = inode->i_write_hint; - } ret = bio_add_page(io->io_bio, page, bh->b_size, bh_offset(bh)); if (ret != bh->b_size) goto submit_and_retry; diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c index e71dde8de0db..20d65aa6243a 100644 --- a/fs/f2fs/data.c +++ b/fs/f2fs/data.c @@ -403,8 +403,6 @@ static struct bio *__bio_alloc(struct f2fs_io_info *fio, int npages) } else { bio->bi_end_io = f2fs_write_end_io; bio->bi_private = sbi; - bio->bi_write_hint = f2fs_io_type_to_rw_hint(sbi, - fio->type, fio->temp); } iostat_alloc_and_bind_ctx(sbi, bio, NULL); diff --git a/fs/gfs2/lops.c b/fs/gfs2/lops.c index 4ae1eefae616..6ba51cbb94cf 100644 --- a/fs/gfs2/lops.c +++ b/fs/gfs2/lops.c @@ -491,7 +491,6 @@ static struct bio *gfs2_chain_bio(struct bio *prev, unsigned int nr_iovecs) new = bio_alloc(prev->bi_bdev, nr_iovecs, prev->bi_opf, GFP_NOIO); bio_clone_blkg_association(new, prev); new->bi_iter.bi_sector = bio_end_sector(prev); - new->bi_write_hint = prev->bi_write_hint; bio_chain(new, prev); submit_bio(prev); return new; diff --git a/fs/iomap/buffered-io.c b/fs/iomap/buffered-io.c index 4653f3d07a1d..d0bf43f37a64 100644 --- a/fs/iomap/buffered-io.c +++ b/fs/iomap/buffered-io.c @@ -1232,7 +1232,6 @@ iomap_alloc_ioend(struct inode *inode, struct iomap_writepage_ctx *wpc, REQ_OP_WRITE | wbc_to_write_flags(wbc), GFP_NOFS, &iomap_ioend_bioset); bio->bi_iter.bi_sector = sector; - bio->bi_write_hint = inode->i_write_hint; wbc_init_bio(wbc, bio); ioend = container_of(bio, struct iomap_ioend, io_inline_bio); @@ -1263,7 +1262,6 @@ iomap_chain_bio(struct bio *prev) new = bio_alloc(prev->bi_bdev, BIO_MAX_VECS, prev->bi_opf, GFP_NOFS); bio_clone_blkg_association(new, prev); new->bi_iter.bi_sector = bio_end_sector(prev); - new->bi_write_hint = prev->bi_write_hint; bio_chain(prev, new); bio_get(prev); /* for iomap_finish_ioend */ diff --git a/fs/iomap/direct-io.c b/fs/iomap/direct-io.c index e2ba13645ef2..a434b1829545 100644 --- a/fs/iomap/direct-io.c +++ b/fs/iomap/direct-io.c @@ -309,7 +309,6 @@ static loff_t iomap_dio_bio_iter(const struct iomap_iter *iter, bio = bio_alloc(iomap->bdev, nr_pages, bio_opf, GFP_KERNEL); bio->bi_iter.bi_sector = iomap_sector(iomap, pos); - bio->bi_write_hint = dio->iocb->ki_hint; bio->bi_ioprio = dio->iocb->ki_ioprio; bio->bi_private = dio; bio->bi_end_io = iomap_dio_bio_end_io; diff --git a/fs/mpage.c b/fs/mpage.c index 6c4b810a21d0..c6379a81f90f 100644 --- a/fs/mpage.c +++ b/fs/mpage.c @@ -588,7 +588,6 @@ alloc_new: GFP_NOFS); bio->bi_iter.bi_sector = blocks[0] << (blkbits - 9); wbc_init_bio(wbc, bio); - bio->bi_write_hint = inode->i_write_hint; } /* diff --git a/fs/zonefs/super.c b/fs/zonefs/super.c index d331b52592a0..b71a23dd1255 100644 --- a/fs/zonefs/super.c +++ b/fs/zonefs/super.c @@ -695,7 +695,6 @@ static ssize_t zonefs_file_dio_append(struct kiocb *iocb, struct iov_iter *from) bio = bio_alloc(bdev, nr_pages, REQ_OP_ZONE_APPEND | REQ_SYNC | REQ_IDLE, GFP_NOFS); bio->bi_iter.bi_sector = zi->i_zsector; - bio->bi_write_hint = iocb->ki_hint; bio->bi_ioprio = iocb->ki_ioprio; if (iocb->ki_flags & IOCB_DSYNC) bio->bi_opf |= REQ_FUA; diff --git a/include/linux/blk_types.h b/include/linux/blk_types.h index 5561e58d158a..ba8cfa57255f 100644 --- a/include/linux/blk_types.h +++ b/include/linux/blk_types.h @@ -250,7 +250,6 @@ struct bio { */ unsigned short bi_flags; /* BIO_* below */ unsigned short bi_ioprio; - unsigned short bi_write_hint; blk_status_t bi_status; atomic_t __bi_remaining; diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h index a12c031af887..226836ccd060 100644 --- a/include/linux/blkdev.h +++ b/include/linux/blkdev.h @@ -518,9 +518,6 @@ struct request_queue { bool mq_sysfs_init_done; -#define BLK_MAX_WRITE_HINTS 5 - u64 write_hints[BLK_MAX_WRITE_HINTS]; - /* * Independent sector access ranges. This is always NULL for * devices that do not have multiple independent access ranges. From c340b990d58c856c1636e0c10abb9e4351ad852a Mon Sep 17 00:00:00 2001 From: Keith Busch Date: Thu, 3 Mar 2022 12:13:05 -0800 Subject: [PATCH 258/370] block: support pi with extended metadata The nvme spec allows protection information formats with metadata extending beyond the pi field. Use the actual size of the metadata field for incrementing the buffer. Reviewed-by: Christoph Hellwig Reviewed-by: Hannes Reinecke Reviewed-by: Martin K. Petersen Signed-off-by: Keith Busch Link: https://lore.kernel.org/r/20220303201312.3255347-2-kbusch@kernel.org Signed-off-by: Jens Axboe --- block/bio-integrity.c | 1 + block/t10-pi.c | 4 ++-- include/linux/blk-integrity.h | 1 + 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/block/bio-integrity.c b/block/bio-integrity.c index 6996e7bd66e9..32929c89ba8a 100644 --- a/block/bio-integrity.c +++ b/block/bio-integrity.c @@ -165,6 +165,7 @@ static blk_status_t bio_integrity_process(struct bio *bio, iter.disk_name = bio->bi_bdev->bd_disk->disk_name; iter.interval = 1 << bi->interval_exp; + iter.tuple_size = bi->tuple_size; iter.seed = proc_iter->bi_sector; iter.prot_buf = bvec_virt(bip->bip_vec); diff --git a/block/t10-pi.c b/block/t10-pi.c index 25a52a2a09a8..758a76518854 100644 --- a/block/t10-pi.c +++ b/block/t10-pi.c @@ -44,7 +44,7 @@ static blk_status_t t10_pi_generate(struct blk_integrity_iter *iter, pi->ref_tag = 0; iter->data_buf += iter->interval; - iter->prot_buf += sizeof(struct t10_pi_tuple); + iter->prot_buf += iter->tuple_size; iter->seed++; } @@ -93,7 +93,7 @@ static blk_status_t t10_pi_verify(struct blk_integrity_iter *iter, next: iter->data_buf += iter->interval; - iter->prot_buf += sizeof(struct t10_pi_tuple); + iter->prot_buf += iter->tuple_size; iter->seed++; } diff --git a/include/linux/blk-integrity.h b/include/linux/blk-integrity.h index 8a038ea0717e..378b2459efe2 100644 --- a/include/linux/blk-integrity.h +++ b/include/linux/blk-integrity.h @@ -19,6 +19,7 @@ struct blk_integrity_iter { sector_t seed; unsigned int data_size; unsigned short interval; + unsigned char tuple_size; const char *disk_name; }; From 84b735429f5fe6f57fc0b3fff3932dce1471e668 Mon Sep 17 00:00:00 2001 From: Keith Busch Date: Thu, 3 Mar 2022 12:13:06 -0800 Subject: [PATCH 259/370] nvme: allow integrity on extended metadata formats The block integrity subsystem knows how to construct protection information buffers with metadata beyond the protection information fields. Remove the driver restriction. Note, this can only work if the PI field appears first in the metadata, as the integrity subsystem doesn't calculate guard tags on preceding metadata. Reviewed-by: Christoph Hellwig Reviewed-by: Hannes Reinecke Reviewed-by: Martin K. Petersen Signed-off-by: Keith Busch Link: https://lore.kernel.org/r/20220303201312.3255347-3-kbusch@kernel.org Signed-off-by: Jens Axboe --- drivers/nvme/host/core.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c index bcbe12fd4984..cd13b7dcd18f 100644 --- a/drivers/nvme/host/core.c +++ b/drivers/nvme/host/core.c @@ -1616,12 +1616,9 @@ static void nvme_configure_metadata(struct nvme_ns *ns, struct nvme_id_ns *id) { struct nvme_ctrl *ctrl = ns->ctrl; - /* - * The PI implementation requires the metadata size to be equal to the - * t10 pi tuple size. - */ ns->ms = le16_to_cpu(id->lbaf[id->flbas & NVME_NS_FLBAS_LBA_MASK].ms); - if (ns->ms == sizeof(struct t10_pi_tuple)) + if (id->dps & NVME_NS_DPS_PI_FIRST || + ns->ms == sizeof(struct t10_pi_tuple)) ns->pi_type = id->dps & NVME_NS_DPS_PI_MASK; else ns->pi_type = 0; From c2ea5fcf53d5f21e6aff0de11d55bc202822df6a Mon Sep 17 00:00:00 2001 From: Keith Busch Date: Thu, 3 Mar 2022 12:13:07 -0800 Subject: [PATCH 260/370] asm-generic: introduce be48 unaligned accessors The NVMe protocol extended the data integrity fields with unaligned 48-bit reference tags. Provide some helper accessors in preparation for these. Reviewed-by: Christoph Hellwig Reviewed-by: Martin K. Petersen Reviewed-by: Hannes Reinecke Reviewed-by: Chaitanya Kulkarni Acked-by: Arnd Bergmann Signed-off-by: Keith Busch Reviewed-by: Bart Van Assche Link: https://lore.kernel.org/r/20220303201312.3255347-4-kbusch@kernel.org Signed-off-by: Jens Axboe --- include/asm-generic/unaligned.h | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/include/asm-generic/unaligned.h b/include/asm-generic/unaligned.h index 1c4242416c9f..8fc637379899 100644 --- a/include/asm-generic/unaligned.h +++ b/include/asm-generic/unaligned.h @@ -126,4 +126,30 @@ static inline void put_unaligned_le24(const u32 val, void *p) __put_unaligned_le24(val, p); } +static inline void __put_unaligned_be48(const u64 val, __u8 *p) +{ + *p++ = val >> 40; + *p++ = val >> 32; + *p++ = val >> 24; + *p++ = val >> 16; + *p++ = val >> 8; + *p++ = val; +} + +static inline void put_unaligned_be48(const u64 val, void *p) +{ + __put_unaligned_be48(val, p); +} + +static inline u64 __get_unaligned_be48(const u8 *p) +{ + return (u64)p[0] << 40 | (u64)p[1] << 32 | p[2] << 24 | + p[3] << 16 | p[4] << 8 | p[5]; +} + +static inline u64 get_unaligned_be48(const void *p) +{ + return __get_unaligned_be48(p); +} + #endif /* __ASM_GENERIC_UNALIGNED_H */ From 7ee8809df990d1de379002973baee1681e8d7dd3 Mon Sep 17 00:00:00 2001 From: Keith Busch Date: Thu, 3 Mar 2022 12:13:08 -0800 Subject: [PATCH 261/370] linux/kernel: introduce lower_48_bits function Recent data integrity field enhancements allow reference tags to be up to 48 bits. Introduce an inline helper function since this will be a repeated operation. Suggested-by: Bart Van Assche Signed-off-by: Keith Busch Reviewed-by: Bart Van Assche Link: https://lore.kernel.org/r/20220303201312.3255347-5-kbusch@kernel.org Signed-off-by: Jens Axboe --- include/linux/kernel.h | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/include/linux/kernel.h b/include/linux/kernel.h index 33f47a996513..3877478681b9 100644 --- a/include/linux/kernel.h +++ b/include/linux/kernel.h @@ -63,6 +63,15 @@ } \ ) +/** + * lower_48_bits() - return bits 0-47 of a number + * @n: the number we're accessing + */ +static inline u64 lower_48_bits(u64 n) +{ + return n & ((1ull << 48) - 1); +} + /** * upper_32_bits - return bits 32-63 of a number * @n: the number we're accessing From cbc0a40e17da361a2ada8d669413ccfbd2028f2d Mon Sep 17 00:00:00 2001 From: Keith Busch Date: Thu, 3 Mar 2022 12:13:09 -0800 Subject: [PATCH 262/370] lib: add rocksoft model crc64 The NVM Express specification extended data integrity fields to 64 bits using the Rocksoft parameters. Add the poly to the crc64 table generation, and provide a generic library routine implementing the algorithm. The Rocksoft 64-bit CRC model parameters are as follows: Poly: 0xAD93D23594C93659 Initial value: 0xFFFFFFFFFFFFFFFF Reflected Input: True Reflected Output: True Xor Final: 0xFFFFFFFFFFFFFFFF Since this model used reflected bits, the implementation generates the reflected table so the result is ordered consistently. Cc: Christoph Hellwig Cc: Hannes Reinecke Cc: Martin K. Petersen Signed-off-by: Keith Busch Reviewed-by: Martin K. Petersen Link: https://lore.kernel.org/r/20220303201312.3255347-6-kbusch@kernel.org Signed-off-by: Jens Axboe --- include/linux/crc64.h | 2 ++ lib/crc64.c | 28 ++++++++++++++++++++++++ lib/gen_crc64table.c | 51 +++++++++++++++++++++++++++++++++---------- 3 files changed, 70 insertions(+), 11 deletions(-) diff --git a/include/linux/crc64.h b/include/linux/crc64.h index c756e65a1b58..9480f38cc7cf 100644 --- a/include/linux/crc64.h +++ b/include/linux/crc64.h @@ -8,4 +8,6 @@ #include u64 __pure crc64_be(u64 crc, const void *p, size_t len); +u64 __pure crc64_rocksoft_generic(u64 crc, const void *p, size_t len); + #endif /* _LINUX_CRC64_H */ diff --git a/lib/crc64.c b/lib/crc64.c index 9f852a89ee2a..61ae8dfb6a1c 100644 --- a/lib/crc64.c +++ b/lib/crc64.c @@ -22,6 +22,13 @@ * x^24 + x^23 + x^22 + x^21 + x^19 + x^17 + x^13 + x^12 + x^10 + x^9 + * x^7 + x^4 + x + 1 * + * crc64rocksoft[256] table is from the Rocksoft specification polynomial + * defined as, + * + * x^64 + x^63 + x^61 + x^59 + x^58 + x^56 + x^55 + x^52 + x^49 + x^48 + x^47 + + * x^46 + x^44 + x^41 + x^37 + x^36 + x^34 + x^32 + x^31 + x^28 + x^26 + x^23 + + * x^22 + x^19 + x^16 + x^13 + x^12 + x^10 + x^9 + x^6 + x^4 + x^3 + 1 + * * Copyright 2018 SUSE Linux. * Author: Coly Li */ @@ -55,3 +62,24 @@ u64 __pure crc64_be(u64 crc, const void *p, size_t len) return crc; } EXPORT_SYMBOL_GPL(crc64_be); + +/** + * crc64_rocksoft_generic - Calculate bitwise Rocksoft CRC64 + * @crc: seed value for computation. 0 for a new CRC calculation, or the + * previous crc64 value if computing incrementally. + * @p: pointer to buffer over which CRC64 is run + * @len: length of buffer @p + */ +u64 __pure crc64_rocksoft_generic(u64 crc, const void *p, size_t len) +{ + const unsigned char *_p = p; + size_t i; + + crc = ~crc; + + for (i = 0; i < len; i++) + crc = (crc >> 8) ^ crc64rocksofttable[(crc & 0xff) ^ *_p++]; + + return ~crc; +} +EXPORT_SYMBOL_GPL(crc64_rocksoft_generic); diff --git a/lib/gen_crc64table.c b/lib/gen_crc64table.c index 094b43aef8db..55e222acd0b8 100644 --- a/lib/gen_crc64table.c +++ b/lib/gen_crc64table.c @@ -17,10 +17,30 @@ #include #define CRC64_ECMA182_POLY 0x42F0E1EBA9EA3693ULL +#define CRC64_ROCKSOFT_POLY 0x9A6C9329AC4BC9B5ULL static uint64_t crc64_table[256] = {0}; +static uint64_t crc64_rocksoft_table[256] = {0}; -static void generate_crc64_table(void) +static void generate_reflected_crc64_table(uint64_t table[256], uint64_t poly) +{ + uint64_t i, j, c, crc; + + for (i = 0; i < 256; i++) { + crc = 0ULL; + c = i; + + for (j = 0; j < 8; j++) { + if ((crc ^ (c >> j)) & 1) + crc = (crc >> 1) ^ poly; + else + crc >>= 1; + } + table[i] = crc; + } +} + +static void generate_crc64_table(uint64_t table[256], uint64_t poly) { uint64_t i, j, c, crc; @@ -30,26 +50,22 @@ static void generate_crc64_table(void) for (j = 0; j < 8; j++) { if ((crc ^ c) & 0x8000000000000000ULL) - crc = (crc << 1) ^ CRC64_ECMA182_POLY; + crc = (crc << 1) ^ poly; else crc <<= 1; c <<= 1; } - crc64_table[i] = crc; + table[i] = crc; } } -static void print_crc64_table(void) +static void output_table(uint64_t table[256]) { int i; - printf("/* this file is generated - do not edit */\n\n"); - printf("#include \n"); - printf("#include \n\n"); - printf("static const u64 ____cacheline_aligned crc64table[256] = {\n"); for (i = 0; i < 256; i++) { - printf("\t0x%016" PRIx64 "ULL", crc64_table[i]); + printf("\t0x%016" PRIx64 "ULL", table[i]); if (i & 0x1) printf(",\n"); else @@ -58,9 +74,22 @@ static void print_crc64_table(void) printf("};\n"); } +static void print_crc64_tables(void) +{ + printf("/* this file is generated - do not edit */\n\n"); + printf("#include \n"); + printf("#include \n\n"); + printf("static const u64 ____cacheline_aligned crc64table[256] = {\n"); + output_table(crc64_table); + + printf("\nstatic const u64 ____cacheline_aligned crc64rocksofttable[256] = {\n"); + output_table(crc64_rocksoft_table); +} + int main(int argc, char *argv[]) { - generate_crc64_table(); - print_crc64_table(); + generate_crc64_table(crc64_table, CRC64_ECMA182_POLY); + generate_reflected_crc64_table(crc64_rocksoft_table, CRC64_ROCKSOFT_POLY); + print_crc64_tables(); return 0; } From f3813f4b287e480b1fcd62ca798d8556644b8278 Mon Sep 17 00:00:00 2001 From: Keith Busch Date: Thu, 3 Mar 2022 12:13:10 -0800 Subject: [PATCH 263/370] crypto: add rocksoft 64b crc guard tag framework Hardware specific features may be able to calculate a crc64, so provide a framework for drivers to register their implementation. If nothing is registered, fallback to the generic table lookup implementation. The implementation is modeled after the crct10dif equivalent. Signed-off-by: Keith Busch Link: https://lore.kernel.org/r/20220303201312.3255347-7-kbusch@kernel.org Signed-off-by: Jens Axboe --- crypto/Kconfig | 5 ++ crypto/Makefile | 1 + crypto/crc64_rocksoft_generic.c | 89 ++++++++++++++++++++++ crypto/testmgr.c | 7 ++ crypto/testmgr.h | 15 ++++ include/linux/crc64.h | 5 ++ lib/Kconfig | 9 +++ lib/Makefile | 1 + lib/crc64-rocksoft.c | 126 ++++++++++++++++++++++++++++++++ 9 files changed, 258 insertions(+) create mode 100644 crypto/crc64_rocksoft_generic.c create mode 100644 lib/crc64-rocksoft.c diff --git a/crypto/Kconfig b/crypto/Kconfig index 442765219c37..e88e2d00e33d 100644 --- a/crypto/Kconfig +++ b/crypto/Kconfig @@ -735,6 +735,11 @@ config CRYPTO_CRCT10DIF_VPMSUM multiply-sum (vpmsum) instructions, introduced in POWER8. Enable on POWER8 and newer processors for improved performance. +config CRYPTO_CRC64_ROCKSOFT + tristate "Rocksoft Model CRC64 algorithm" + depends on CRC64 + select CRYPTO_HASH + config CRYPTO_VPMSUM_TESTER tristate "Powerpc64 vpmsum hardware acceleration tester" depends on CRYPTO_CRCT10DIF_VPMSUM && CRYPTO_CRC32C_VPMSUM diff --git a/crypto/Makefile b/crypto/Makefile index d76bff8d0ffd..f754c4d17d6b 100644 --- a/crypto/Makefile +++ b/crypto/Makefile @@ -152,6 +152,7 @@ obj-$(CONFIG_CRYPTO_MICHAEL_MIC) += michael_mic.o obj-$(CONFIG_CRYPTO_CRC32C) += crc32c_generic.o obj-$(CONFIG_CRYPTO_CRC32) += crc32_generic.o obj-$(CONFIG_CRYPTO_CRCT10DIF) += crct10dif_common.o crct10dif_generic.o +obj-$(CONFIG_CRYPTO_CRC64_ROCKSOFT) += crc64_rocksoft_generic.o obj-$(CONFIG_CRYPTO_AUTHENC) += authenc.o authencesn.o obj-$(CONFIG_CRYPTO_LZO) += lzo.o lzo-rle.o obj-$(CONFIG_CRYPTO_LZ4) += lz4.o diff --git a/crypto/crc64_rocksoft_generic.c b/crypto/crc64_rocksoft_generic.c new file mode 100644 index 000000000000..9e812bb26dba --- /dev/null +++ b/crypto/crc64_rocksoft_generic.c @@ -0,0 +1,89 @@ +// SPDX-License-Identifier: GPL-2.0-only + +#include +#include +#include +#include + +static int chksum_init(struct shash_desc *desc) +{ + u64 *crc = shash_desc_ctx(desc); + + *crc = 0; + + return 0; +} + +static int chksum_update(struct shash_desc *desc, const u8 *data, + unsigned int length) +{ + u64 *crc = shash_desc_ctx(desc); + + *crc = crc64_rocksoft_generic(*crc, data, length); + + return 0; +} + +static int chksum_final(struct shash_desc *desc, u8 *out) +{ + u64 *crc = shash_desc_ctx(desc); + + put_unaligned_le64(*crc, out); + return 0; +} + +static int __chksum_finup(u64 crc, const u8 *data, unsigned int len, u8 *out) +{ + crc = crc64_rocksoft_generic(crc, data, len); + put_unaligned_le64(crc, out); + return 0; +} + +static int chksum_finup(struct shash_desc *desc, const u8 *data, + unsigned int len, u8 *out) +{ + u64 *crc = shash_desc_ctx(desc); + + return __chksum_finup(*crc, data, len, out); +} + +static int chksum_digest(struct shash_desc *desc, const u8 *data, + unsigned int length, u8 *out) +{ + return __chksum_finup(0, data, length, out); +} + +static struct shash_alg alg = { + .digestsize = sizeof(u64), + .init = chksum_init, + .update = chksum_update, + .final = chksum_final, + .finup = chksum_finup, + .digest = chksum_digest, + .descsize = sizeof(u64), + .base = { + .cra_name = CRC64_ROCKSOFT_STRING, + .cra_driver_name = "crc64-rocksoft-generic", + .cra_priority = 200, + .cra_blocksize = 1, + .cra_module = THIS_MODULE, + } +}; + +static int __init crc64_rocksoft_init(void) +{ + return crypto_register_shash(&alg); +} + +static void __exit crc64_rocksoft_exit(void) +{ + crypto_unregister_shash(&alg); +} + +module_init(crc64_rocksoft_init); +module_exit(crc64_rocksoft_exit); + +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("Rocksoft model CRC64 calculation."); +MODULE_ALIAS_CRYPTO("crc64-rocksoft"); +MODULE_ALIAS_CRYPTO("crc64-rocksoft-generic"); diff --git a/crypto/testmgr.c b/crypto/testmgr.c index 5831d4bbc64f..2e120eea10b1 100644 --- a/crypto/testmgr.c +++ b/crypto/testmgr.c @@ -4526,6 +4526,13 @@ static const struct alg_test_desc alg_test_descs[] = { .suite = { .hash = __VECS(crc32c_tv_template) } + }, { + .alg = "crc64-rocksoft", + .test = alg_test_hash, + .fips_allowed = 1, + .suite = { + .hash = __VECS(crc64_rocksoft_tv_template) + } }, { .alg = "crct10dif", .test = alg_test_hash, diff --git a/crypto/testmgr.h b/crypto/testmgr.h index a253d66ba1c1..f1a22794c404 100644 --- a/crypto/testmgr.h +++ b/crypto/testmgr.h @@ -3679,6 +3679,21 @@ static const struct hash_testvec rmd160_tv_template[] = { } }; +static const u8 zeroes[4096] = { [0 ... 4095] = 0 }; +static const u8 ones[4096] = { [0 ... 4095] = 0xff }; + +static const struct hash_testvec crc64_rocksoft_tv_template[] = { + { + .plaintext = zeroes, + .psize = 4096, + .digest = (u8 *)(u64[]){ 0x6482d367eb22b64eull }, + }, { + .plaintext = ones, + .psize = 4096, + .digest = (u8 *)(u64[]){ 0xc0ddba7302eca3acull }, + } +}; + static const struct hash_testvec crct10dif_tv_template[] = { { .plaintext = "abc", diff --git a/include/linux/crc64.h b/include/linux/crc64.h index 9480f38cc7cf..e044c60d1e61 100644 --- a/include/linux/crc64.h +++ b/include/linux/crc64.h @@ -7,7 +7,12 @@ #include +#define CRC64_ROCKSOFT_STRING "crc64-rocksoft" + u64 __pure crc64_be(u64 crc, const void *p, size_t len); u64 __pure crc64_rocksoft_generic(u64 crc, const void *p, size_t len); +u64 crc64_rocksoft(const unsigned char *buffer, size_t len); +u64 crc64_rocksoft_update(u64 crc, const unsigned char *buffer, size_t len); + #endif /* _LINUX_CRC64_H */ diff --git a/lib/Kconfig b/lib/Kconfig index 9b5a692ce00c..087e06b4cdfd 100644 --- a/lib/Kconfig +++ b/lib/Kconfig @@ -145,6 +145,15 @@ config CRC_T10DIF kernel tree needs to calculate CRC checks for use with the SCSI data integrity subsystem. +config CRC64_ROCKSOFT + tristate "CRC calculation for the Rocksoft model CRC64" + select CRC64 + select CRYPTO + select CRYPTO_CRC64_ROCKSOFT + help + This option provides a CRC64 API to a registered crypto driver. + This is used with the block layer's data integrity subsystem. + config CRC_ITU_T tristate "CRC ITU-T V.41 functions" help diff --git a/lib/Makefile b/lib/Makefile index 300f569c626b..7f7ae7458b6c 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -175,6 +175,7 @@ obj-$(CONFIG_CRC4) += crc4.o obj-$(CONFIG_CRC7) += crc7.o obj-$(CONFIG_LIBCRC32C) += libcrc32c.o obj-$(CONFIG_CRC8) += crc8.o +obj-$(CONFIG_CRC64_ROCKSOFT) += crc64-rocksoft.o obj-$(CONFIG_XXHASH) += xxhash.o obj-$(CONFIG_GENERIC_ALLOCATOR) += genalloc.o diff --git a/lib/crc64-rocksoft.c b/lib/crc64-rocksoft.c new file mode 100644 index 000000000000..fc9ae0da5df7 --- /dev/null +++ b/lib/crc64-rocksoft.c @@ -0,0 +1,126 @@ +// SPDX-License-Identifier: GPL-2.0-only + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static struct crypto_shash __rcu *crc64_rocksoft_tfm; +static DEFINE_STATIC_KEY_TRUE(crc64_rocksoft_fallback); +static DEFINE_MUTEX(crc64_rocksoft_mutex); +static struct work_struct crc64_rocksoft_rehash_work; + +static int crc64_rocksoft_notify(struct notifier_block *self, unsigned long val, void *data) +{ + struct crypto_alg *alg = data; + + if (val != CRYPTO_MSG_ALG_LOADED || + strcmp(alg->cra_name, CRC64_ROCKSOFT_STRING)) + return NOTIFY_DONE; + + schedule_work(&crc64_rocksoft_rehash_work); + return NOTIFY_OK; +} + +static void crc64_rocksoft_rehash(struct work_struct *work) +{ + struct crypto_shash *new, *old; + + mutex_lock(&crc64_rocksoft_mutex); + old = rcu_dereference_protected(crc64_rocksoft_tfm, + lockdep_is_held(&crc64_rocksoft_mutex)); + new = crypto_alloc_shash(CRC64_ROCKSOFT_STRING, 0, 0); + if (IS_ERR(new)) { + mutex_unlock(&crc64_rocksoft_mutex); + return; + } + rcu_assign_pointer(crc64_rocksoft_tfm, new); + mutex_unlock(&crc64_rocksoft_mutex); + + if (old) { + synchronize_rcu(); + crypto_free_shash(old); + } else { + static_branch_disable(&crc64_rocksoft_fallback); + } +} + +static struct notifier_block crc64_rocksoft_nb = { + .notifier_call = crc64_rocksoft_notify, +}; + +u64 crc64_rocksoft_update(u64 crc, const unsigned char *buffer, size_t len) +{ + struct { + struct shash_desc shash; + u64 crc; + } desc; + int err; + + if (static_branch_unlikely(&crc64_rocksoft_fallback)) + return crc64_rocksoft_generic(crc, buffer, len); + + rcu_read_lock(); + desc.shash.tfm = rcu_dereference(crc64_rocksoft_tfm); + desc.crc = crc; + err = crypto_shash_update(&desc.shash, buffer, len); + rcu_read_unlock(); + + BUG_ON(err); + + return desc.crc; +} +EXPORT_SYMBOL_GPL(crc64_rocksoft_update); + +u64 crc64_rocksoft(const unsigned char *buffer, size_t len) +{ + return crc64_rocksoft_update(0, buffer, len); +} +EXPORT_SYMBOL_GPL(crc64_rocksoft); + +static int __init crc64_rocksoft_mod_init(void) +{ + INIT_WORK(&crc64_rocksoft_rehash_work, crc64_rocksoft_rehash); + crypto_register_notifier(&crc64_rocksoft_nb); + crc64_rocksoft_rehash(&crc64_rocksoft_rehash_work); + return 0; +} + +static void __exit crc64_rocksoft_mod_fini(void) +{ + crypto_unregister_notifier(&crc64_rocksoft_nb); + cancel_work_sync(&crc64_rocksoft_rehash_work); + crypto_free_shash(rcu_dereference_protected(crc64_rocksoft_tfm, 1)); +} + +module_init(crc64_rocksoft_mod_init); +module_exit(crc64_rocksoft_mod_fini); + +static int crc64_rocksoft_transform_show(char *buffer, const struct kernel_param *kp) +{ + struct crypto_shash *tfm; + int len; + + if (static_branch_unlikely(&crc64_rocksoft_fallback)) + return sprintf(buffer, "fallback\n"); + + rcu_read_lock(); + tfm = rcu_dereference(crc64_rocksoft_tfm); + len = snprintf(buffer, PAGE_SIZE, "%s\n", + crypto_shash_driver_name(tfm)); + rcu_read_unlock(); + + return len; +} + +module_param_call(transform, NULL, crc64_rocksoft_transform_show, NULL, 0444); + +MODULE_AUTHOR("Keith Busch "); +MODULE_DESCRIPTION("Rocksoft model CRC64 calculation (library API)"); +MODULE_LICENSE("GPL"); +MODULE_SOFTDEP("pre: crc64"); From a7d4383f17e10f338ea757a849f02298790d24fb Mon Sep 17 00:00:00 2001 From: Keith Busch Date: Thu, 3 Mar 2022 12:13:11 -0800 Subject: [PATCH 264/370] block: add pi for extended integrity The NVMe specification defines new data integrity formats beyond the t10 tuple. Add support for the specification defined CRC64 formats, assuming the reference tag does not need to be split with the "storage tag". Cc: Hannes Reinecke Cc: "Martin K. Petersen" Signed-off-by: Keith Busch Reviewed-by: Martin K. Petersen Link: https://lore.kernel.org/r/20220303201312.3255347-8-kbusch@kernel.org Signed-off-by: Jens Axboe --- block/Kconfig | 1 + block/t10-pi.c | 194 +++++++++++++++++++++++++++++++++++++++++ include/linux/t10-pi.h | 20 +++++ 3 files changed, 215 insertions(+) diff --git a/block/Kconfig b/block/Kconfig index 7eb5d6d53b3f..50b17e260fa2 100644 --- a/block/Kconfig +++ b/block/Kconfig @@ -73,6 +73,7 @@ config BLK_DEV_INTEGRITY_T10 tristate depends on BLK_DEV_INTEGRITY select CRC_T10DIF + select CRC64_ROCKSOFT config BLK_DEV_ZONED bool "Zoned block device support" diff --git a/block/t10-pi.c b/block/t10-pi.c index 758a76518854..914d8cddd43a 100644 --- a/block/t10-pi.c +++ b/block/t10-pi.c @@ -7,8 +7,10 @@ #include #include #include +#include #include #include +#include typedef __be16 (csum_fn) (void *, unsigned int); @@ -278,4 +280,196 @@ const struct blk_integrity_profile t10_pi_type3_ip = { }; EXPORT_SYMBOL(t10_pi_type3_ip); +static __be64 ext_pi_crc64(void *data, unsigned int len) +{ + return cpu_to_be64(crc64_rocksoft(data, len)); +} + +static blk_status_t ext_pi_crc64_generate(struct blk_integrity_iter *iter, + enum t10_dif_type type) +{ + unsigned int i; + + for (i = 0 ; i < iter->data_size ; i += iter->interval) { + struct crc64_pi_tuple *pi = iter->prot_buf; + + pi->guard_tag = ext_pi_crc64(iter->data_buf, iter->interval); + pi->app_tag = 0; + + if (type == T10_PI_TYPE1_PROTECTION) + put_unaligned_be48(iter->seed, pi->ref_tag); + else + put_unaligned_be48(0ULL, pi->ref_tag); + + iter->data_buf += iter->interval; + iter->prot_buf += iter->tuple_size; + iter->seed++; + } + + return BLK_STS_OK; +} + +static bool ext_pi_ref_escape(u8 *ref_tag) +{ + static u8 ref_escape[6] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; + + return memcmp(ref_tag, ref_escape, sizeof(ref_escape)) == 0; +} + +static blk_status_t ext_pi_crc64_verify(struct blk_integrity_iter *iter, + enum t10_dif_type type) +{ + unsigned int i; + + for (i = 0; i < iter->data_size; i += iter->interval) { + struct crc64_pi_tuple *pi = iter->prot_buf; + u64 ref, seed; + __be64 csum; + + if (type == T10_PI_TYPE1_PROTECTION) { + if (pi->app_tag == T10_PI_APP_ESCAPE) + goto next; + + ref = get_unaligned_be48(pi->ref_tag); + seed = lower_48_bits(iter->seed); + if (ref != seed) { + pr_err("%s: ref tag error at location %llu (rcvd %llu)\n", + iter->disk_name, seed, ref); + return BLK_STS_PROTECTION; + } + } else if (type == T10_PI_TYPE3_PROTECTION) { + if (pi->app_tag == T10_PI_APP_ESCAPE && + ext_pi_ref_escape(pi->ref_tag)) + goto next; + } + + csum = ext_pi_crc64(iter->data_buf, iter->interval); + if (pi->guard_tag != csum) { + pr_err("%s: guard tag error at sector %llu " \ + "(rcvd %016llx, want %016llx)\n", + iter->disk_name, (unsigned long long)iter->seed, + be64_to_cpu(pi->guard_tag), be64_to_cpu(csum)); + return BLK_STS_PROTECTION; + } + +next: + iter->data_buf += iter->interval; + iter->prot_buf += iter->tuple_size; + iter->seed++; + } + + return BLK_STS_OK; +} + +static blk_status_t ext_pi_type1_verify_crc64(struct blk_integrity_iter *iter) +{ + return ext_pi_crc64_verify(iter, T10_PI_TYPE1_PROTECTION); +} + +static blk_status_t ext_pi_type1_generate_crc64(struct blk_integrity_iter *iter) +{ + return ext_pi_crc64_generate(iter, T10_PI_TYPE1_PROTECTION); +} + +static void ext_pi_type1_prepare(struct request *rq) +{ + const int tuple_sz = rq->q->integrity.tuple_size; + u64 ref_tag = ext_pi_ref_tag(rq); + struct bio *bio; + + __rq_for_each_bio(bio, rq) { + struct bio_integrity_payload *bip = bio_integrity(bio); + u64 virt = lower_48_bits(bip_get_seed(bip)); + struct bio_vec iv; + struct bvec_iter iter; + + /* Already remapped? */ + if (bip->bip_flags & BIP_MAPPED_INTEGRITY) + break; + + bip_for_each_vec(iv, bip, iter) { + unsigned int j; + void *p; + + p = bvec_kmap_local(&iv); + for (j = 0; j < iv.bv_len; j += tuple_sz) { + struct crc64_pi_tuple *pi = p; + u64 ref = get_unaligned_be48(pi->ref_tag); + + if (ref == virt) + put_unaligned_be48(ref_tag, pi->ref_tag); + virt++; + ref_tag++; + p += tuple_sz; + } + kunmap_local(p); + } + + bip->bip_flags |= BIP_MAPPED_INTEGRITY; + } +} + +static void ext_pi_type1_complete(struct request *rq, unsigned int nr_bytes) +{ + unsigned intervals = nr_bytes >> rq->q->integrity.interval_exp; + const int tuple_sz = rq->q->integrity.tuple_size; + u64 ref_tag = ext_pi_ref_tag(rq); + struct bio *bio; + + __rq_for_each_bio(bio, rq) { + struct bio_integrity_payload *bip = bio_integrity(bio); + u64 virt = lower_48_bits(bip_get_seed(bip)); + struct bio_vec iv; + struct bvec_iter iter; + + bip_for_each_vec(iv, bip, iter) { + unsigned int j; + void *p; + + p = bvec_kmap_local(&iv); + for (j = 0; j < iv.bv_len && intervals; j += tuple_sz) { + struct crc64_pi_tuple *pi = p; + u64 ref = get_unaligned_be48(pi->ref_tag); + + if (ref == ref_tag) + put_unaligned_be48(virt, pi->ref_tag); + virt++; + ref_tag++; + intervals--; + p += tuple_sz; + } + kunmap_local(p); + } + } +} + +static blk_status_t ext_pi_type3_verify_crc64(struct blk_integrity_iter *iter) +{ + return ext_pi_crc64_verify(iter, T10_PI_TYPE3_PROTECTION); +} + +static blk_status_t ext_pi_type3_generate_crc64(struct blk_integrity_iter *iter) +{ + return ext_pi_crc64_generate(iter, T10_PI_TYPE3_PROTECTION); +} + +const struct blk_integrity_profile ext_pi_type1_crc64 = { + .name = "EXT-DIF-TYPE1-CRC64", + .generate_fn = ext_pi_type1_generate_crc64, + .verify_fn = ext_pi_type1_verify_crc64, + .prepare_fn = ext_pi_type1_prepare, + .complete_fn = ext_pi_type1_complete, +}; +EXPORT_SYMBOL_GPL(ext_pi_type1_crc64); + +const struct blk_integrity_profile ext_pi_type3_crc64 = { + .name = "EXT-DIF-TYPE3-CRC64", + .generate_fn = ext_pi_type3_generate_crc64, + .verify_fn = ext_pi_type3_verify_crc64, + .prepare_fn = t10_pi_type3_prepare, + .complete_fn = t10_pi_type3_complete, +}; +EXPORT_SYMBOL_GPL(ext_pi_type3_crc64); + +MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL"); diff --git a/include/linux/t10-pi.h b/include/linux/t10-pi.h index c635c2e014e3..a4b1af581f69 100644 --- a/include/linux/t10-pi.h +++ b/include/linux/t10-pi.h @@ -53,4 +53,24 @@ extern const struct blk_integrity_profile t10_pi_type1_ip; extern const struct blk_integrity_profile t10_pi_type3_crc; extern const struct blk_integrity_profile t10_pi_type3_ip; +struct crc64_pi_tuple { + __be64 guard_tag; + __be16 app_tag; + __u8 ref_tag[6]; +}; + +static inline u64 ext_pi_ref_tag(struct request *rq) +{ + unsigned int shift = ilog2(queue_logical_block_size(rq->q)); + +#ifdef CONFIG_BLK_DEV_INTEGRITY + if (rq->q->integrity.interval_exp) + shift = rq->q->integrity.interval_exp; +#endif + return lower_48_bits(blk_rq_pos(rq) >> (shift - SECTOR_SHIFT)); +} + +extern const struct blk_integrity_profile ext_pi_type1_crc64; +extern const struct blk_integrity_profile ext_pi_type3_crc64; + #endif From 4020aad85c6785ddac8d51f345ff9e3328ce773a Mon Sep 17 00:00:00 2001 From: Keith Busch Date: Thu, 3 Mar 2022 12:13:12 -0800 Subject: [PATCH 265/370] nvme: add support for enhanced metadata NVM Express ratified TP 4068 defines new protection information formats. Implement support for the CRC64 guard tags. Since the block layer doesn't support variable length reference tags, driver support for the Storage Tag space is not supported at this time. Cc: Hannes Reinecke Cc: "Martin K. Petersen" Cc: Klaus Jensen Signed-off-by: Keith Busch Reviewed-by: Martin K. Petersen Link: https://lore.kernel.org/r/20220303201312.3255347-9-kbusch@kernel.org Signed-off-by: Jens Axboe --- drivers/nvme/host/core.c | 166 +++++++++++++++++++++++++++++++++------ drivers/nvme/host/nvme.h | 4 +- include/linux/nvme.h | 53 +++++++++++-- 3 files changed, 190 insertions(+), 33 deletions(-) diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c index cd13b7dcd18f..51c08f206cbf 100644 --- a/drivers/nvme/host/core.c +++ b/drivers/nvme/host/core.c @@ -813,6 +813,30 @@ static blk_status_t nvme_setup_discard(struct nvme_ns *ns, struct request *req, return BLK_STS_OK; } +static void nvme_set_ref_tag(struct nvme_ns *ns, struct nvme_command *cmnd, + struct request *req) +{ + u32 upper, lower; + u64 ref48; + + /* both rw and write zeroes share the same reftag format */ + switch (ns->guard_type) { + case NVME_NVM_NS_16B_GUARD: + cmnd->rw.reftag = cpu_to_le32(t10_pi_ref_tag(req)); + break; + case NVME_NVM_NS_64B_GUARD: + ref48 = ext_pi_ref_tag(req); + lower = lower_32_bits(ref48); + upper = upper_32_bits(ref48); + + cmnd->rw.reftag = cpu_to_le32(lower); + cmnd->rw.cdw3 = cpu_to_le32(upper); + break; + default: + break; + } +} + static inline blk_status_t nvme_setup_write_zeroes(struct nvme_ns *ns, struct request *req, struct nvme_command *cmnd) { @@ -834,8 +858,7 @@ static inline blk_status_t nvme_setup_write_zeroes(struct nvme_ns *ns, switch (ns->pi_type) { case NVME_NS_DPS_PI_TYPE1: case NVME_NS_DPS_PI_TYPE2: - cmnd->write_zeroes.reftag = - cpu_to_le32(t10_pi_ref_tag(req)); + nvme_set_ref_tag(ns, cmnd, req); break; } } @@ -861,7 +884,8 @@ static inline blk_status_t nvme_setup_rw(struct nvme_ns *ns, cmnd->rw.opcode = op; cmnd->rw.flags = 0; cmnd->rw.nsid = cpu_to_le32(ns->head->ns_id); - cmnd->rw.rsvd2 = 0; + cmnd->rw.cdw2 = 0; + cmnd->rw.cdw3 = 0; cmnd->rw.metadata = 0; cmnd->rw.slba = cpu_to_le64(nvme_sect_to_lba(ns, blk_rq_pos(req))); cmnd->rw.length = cpu_to_le16((blk_rq_bytes(req) >> ns->lba_shift) - 1); @@ -892,7 +916,7 @@ static inline blk_status_t nvme_setup_rw(struct nvme_ns *ns, NVME_RW_PRINFO_PRCHK_REF; if (op == nvme_cmd_zone_append) control |= NVME_RW_APPEND_PIREMAP; - cmnd->rw.reftag = cpu_to_le32(t10_pi_ref_tag(req)); + nvme_set_ref_tag(ns, cmnd, req); break; } } @@ -1544,33 +1568,58 @@ int nvme_getgeo(struct block_device *bdev, struct hd_geometry *geo) } #ifdef CONFIG_BLK_DEV_INTEGRITY -static void nvme_init_integrity(struct gendisk *disk, u16 ms, u8 pi_type, +static void nvme_init_integrity(struct gendisk *disk, struct nvme_ns *ns, u32 max_integrity_segments) { struct blk_integrity integrity = { }; - switch (pi_type) { + switch (ns->pi_type) { case NVME_NS_DPS_PI_TYPE3: - integrity.profile = &t10_pi_type3_crc; - integrity.tag_size = sizeof(u16) + sizeof(u32); - integrity.flags |= BLK_INTEGRITY_DEVICE_CAPABLE; + switch (ns->guard_type) { + case NVME_NVM_NS_16B_GUARD: + integrity.profile = &t10_pi_type3_crc; + integrity.tag_size = sizeof(u16) + sizeof(u32); + integrity.flags |= BLK_INTEGRITY_DEVICE_CAPABLE; + break; + case NVME_NVM_NS_64B_GUARD: + integrity.profile = &ext_pi_type3_crc64; + integrity.tag_size = sizeof(u16) + 6; + integrity.flags |= BLK_INTEGRITY_DEVICE_CAPABLE; + break; + default: + integrity.profile = NULL; + break; + } break; case NVME_NS_DPS_PI_TYPE1: case NVME_NS_DPS_PI_TYPE2: - integrity.profile = &t10_pi_type1_crc; - integrity.tag_size = sizeof(u16); - integrity.flags |= BLK_INTEGRITY_DEVICE_CAPABLE; + switch (ns->guard_type) { + case NVME_NVM_NS_16B_GUARD: + integrity.profile = &t10_pi_type1_crc; + integrity.tag_size = sizeof(u16); + integrity.flags |= BLK_INTEGRITY_DEVICE_CAPABLE; + break; + case NVME_NVM_NS_64B_GUARD: + integrity.profile = &ext_pi_type1_crc64; + integrity.tag_size = sizeof(u16); + integrity.flags |= BLK_INTEGRITY_DEVICE_CAPABLE; + break; + default: + integrity.profile = NULL; + break; + } break; default: integrity.profile = NULL; break; } - integrity.tuple_size = ms; + + integrity.tuple_size = ns->ms; blk_integrity_register(disk, &integrity); blk_queue_max_integrity_segments(disk->queue, max_integrity_segments); } #else -static void nvme_init_integrity(struct gendisk *disk, u16 ms, u8 pi_type, +static void nvme_init_integrity(struct gendisk *disk, struct nvme_ns *ns, u32 max_integrity_segments) { } @@ -1612,16 +1661,72 @@ static bool nvme_ns_ids_equal(struct nvme_ns_ids *a, struct nvme_ns_ids *b) a->csi == b->csi; } +static int nvme_init_ms(struct nvme_ns *ns, struct nvme_id_ns *id) +{ + bool first = id->dps & NVME_NS_DPS_PI_FIRST; + unsigned lbaf = nvme_lbaf_index(id->flbas); + struct nvme_ctrl *ctrl = ns->ctrl; + struct nvme_command c = { }; + struct nvme_id_ns_nvm *nvm; + int ret = 0; + u32 elbaf; + + ns->pi_size = 0; + ns->ms = le16_to_cpu(id->lbaf[lbaf].ms); + if (!(ctrl->ctratt & NVME_CTRL_ATTR_ELBAS)) { + ns->pi_size = sizeof(struct t10_pi_tuple); + ns->guard_type = NVME_NVM_NS_16B_GUARD; + goto set_pi; + } + + nvm = kzalloc(sizeof(*nvm), GFP_KERNEL); + if (!nvm) + return -ENOMEM; + + c.identify.opcode = nvme_admin_identify; + c.identify.nsid = cpu_to_le32(ns->head->ns_id); + c.identify.cns = NVME_ID_CNS_CS_NS; + c.identify.csi = NVME_CSI_NVM; + + ret = nvme_submit_sync_cmd(ns->ctrl->admin_q, &c, nvm, sizeof(*nvm)); + if (ret) + goto free_data; + + elbaf = le32_to_cpu(nvm->elbaf[lbaf]); + + /* no support for storage tag formats right now */ + if (nvme_elbaf_sts(elbaf)) + goto free_data; + + ns->guard_type = nvme_elbaf_guard_type(elbaf); + switch (ns->guard_type) { + case NVME_NVM_NS_64B_GUARD: + ns->pi_size = sizeof(struct crc64_pi_tuple); + break; + case NVME_NVM_NS_16B_GUARD: + ns->pi_size = sizeof(struct t10_pi_tuple); + break; + default: + break; + } + +free_data: + kfree(nvm); +set_pi: + if (ns->pi_size && (first || ns->ms == ns->pi_size)) + ns->pi_type = id->dps & NVME_NS_DPS_PI_MASK; + else + ns->pi_type = 0; + + return ret; +} + static void nvme_configure_metadata(struct nvme_ns *ns, struct nvme_id_ns *id) { struct nvme_ctrl *ctrl = ns->ctrl; - ns->ms = le16_to_cpu(id->lbaf[id->flbas & NVME_NS_FLBAS_LBA_MASK].ms); - if (id->dps & NVME_NS_DPS_PI_FIRST || - ns->ms == sizeof(struct t10_pi_tuple)) - ns->pi_type = id->dps & NVME_NS_DPS_PI_MASK; - else - ns->pi_type = 0; + if (nvme_init_ms(ns, id)) + return; ns->features &= ~(NVME_NS_METADATA_SUPPORTED | NVME_NS_EXT_LBAS); if (!ns->ms || !(ctrl->ops->flags & NVME_F_METADATA_SUPPORTED)) @@ -1738,7 +1843,7 @@ static void nvme_update_disk_info(struct gendisk *disk, if (ns->ms) { if (IS_ENABLED(CONFIG_BLK_DEV_INTEGRITY) && (ns->features & NVME_NS_METADATA_SUPPORTED)) - nvme_init_integrity(disk, ns->ms, ns->pi_type, + nvme_init_integrity(disk, ns, ns->ctrl->max_integrity_segments); else if (!nvme_ns_has_pi(ns)) capacity = 0; @@ -1793,7 +1898,7 @@ static void nvme_set_chunk_sectors(struct nvme_ns *ns, struct nvme_id_ns *id) static int nvme_update_ns_info(struct nvme_ns *ns, struct nvme_id_ns *id) { - unsigned lbaf = id->flbas & NVME_NS_FLBAS_LBA_MASK; + unsigned lbaf = nvme_lbaf_index(id->flbas); int ret; blk_mq_freeze_queue(ns->disk->queue); @@ -2138,20 +2243,27 @@ static int nvme_configure_timestamp(struct nvme_ctrl *ctrl) return ret; } -static int nvme_configure_acre(struct nvme_ctrl *ctrl) +static int nvme_configure_host_options(struct nvme_ctrl *ctrl) { struct nvme_feat_host_behavior *host; + u8 acre = 0, lbafee = 0; int ret; /* Don't bother enabling the feature if retry delay is not reported */ - if (!ctrl->crdt[0]) + if (ctrl->crdt[0]) + acre = NVME_ENABLE_ACRE; + if (ctrl->ctratt & NVME_CTRL_ATTR_ELBAS) + lbafee = NVME_ENABLE_LBAFEE; + + if (!acre && !lbafee) return 0; host = kzalloc(sizeof(*host), GFP_KERNEL); if (!host) return 0; - host->acre = NVME_ENABLE_ACRE; + host->acre = acre; + host->lbafee = lbafee; ret = nvme_set_features(ctrl, NVME_FEAT_HOST_BEHAVIOR, 0, host, sizeof(*host), NULL); kfree(host); @@ -2989,7 +3101,7 @@ int nvme_init_ctrl_finish(struct nvme_ctrl *ctrl) if (ret < 0) return ret; - ret = nvme_configure_acre(ctrl); + ret = nvme_configure_host_options(ctrl); if (ret < 0) return ret; @@ -4703,12 +4815,14 @@ static inline void _nvme_check_size(void) BUILD_BUG_ON(sizeof(struct nvme_id_ctrl) != NVME_IDENTIFY_DATA_SIZE); BUILD_BUG_ON(sizeof(struct nvme_id_ns) != NVME_IDENTIFY_DATA_SIZE); BUILD_BUG_ON(sizeof(struct nvme_id_ns_zns) != NVME_IDENTIFY_DATA_SIZE); + BUILD_BUG_ON(sizeof(struct nvme_id_ns_nvm) != NVME_IDENTIFY_DATA_SIZE); BUILD_BUG_ON(sizeof(struct nvme_id_ctrl_zns) != NVME_IDENTIFY_DATA_SIZE); BUILD_BUG_ON(sizeof(struct nvme_id_ctrl_nvm) != NVME_IDENTIFY_DATA_SIZE); BUILD_BUG_ON(sizeof(struct nvme_lba_range_type) != 64); BUILD_BUG_ON(sizeof(struct nvme_smart_log) != 512); BUILD_BUG_ON(sizeof(struct nvme_dbbuf) != 64); BUILD_BUG_ON(sizeof(struct nvme_directive_cmd) != 64); + BUILD_BUG_ON(sizeof(struct nvme_feat_host_behavior) != 512); } diff --git a/drivers/nvme/host/nvme.h b/drivers/nvme/host/nvme.h index 1bed663322ee..e7ccdb119ede 100644 --- a/drivers/nvme/host/nvme.h +++ b/drivers/nvme/host/nvme.h @@ -453,9 +453,11 @@ struct nvme_ns { int lba_shift; u16 ms; + u16 pi_size; u16 sgs; u32 sws; u8 pi_type; + u8 guard_type; #ifdef CONFIG_BLK_DEV_ZONED u64 zsze; #endif @@ -478,7 +480,7 @@ struct nvme_ns { /* NVMe ns supports metadata actions by the controller (generate/strip) */ static inline bool nvme_ns_has_pi(struct nvme_ns *ns) { - return ns->pi_type && ns->ms == sizeof(struct t10_pi_tuple); + return ns->pi_type && ns->ms == ns->pi_size; } struct nvme_ctrl_ops { diff --git a/include/linux/nvme.h b/include/linux/nvme.h index 9dbc3ef4daf7..4f44f83817a9 100644 --- a/include/linux/nvme.h +++ b/include/linux/nvme.h @@ -244,6 +244,7 @@ enum { enum nvme_ctrl_attr { NVME_CTRL_ATTR_HID_128_BIT = (1 << 0), NVME_CTRL_ATTR_TBKAS = (1 << 6), + NVME_CTRL_ATTR_ELBAS = (1 << 15), }; struct nvme_id_ctrl { @@ -399,8 +400,7 @@ struct nvme_id_ns { __le16 endgid; __u8 nguid[16]; __u8 eui64[8]; - struct nvme_lbaf lbaf[16]; - __u8 rsvd192[192]; + struct nvme_lbaf lbaf[64]; __u8 vs[3712]; }; @@ -418,8 +418,7 @@ struct nvme_id_ns_zns { __le32 rrl; __le32 frl; __u8 rsvd20[2796]; - struct nvme_zns_lbafe lbafe[16]; - __u8 rsvd3072[768]; + struct nvme_zns_lbafe lbafe[64]; __u8 vs[256]; }; @@ -428,6 +427,30 @@ struct nvme_id_ctrl_zns { __u8 rsvd1[4095]; }; +struct nvme_id_ns_nvm { + __le64 lbstm; + __u8 pic; + __u8 rsvd9[3]; + __le32 elbaf[64]; + __u8 rsvd268[3828]; +}; + +enum { + NVME_ID_NS_NVM_STS_MASK = 0x3f, + NVME_ID_NS_NVM_GUARD_SHIFT = 7, + NVME_ID_NS_NVM_GUARD_MASK = 0x3, +}; + +static inline __u8 nvme_elbaf_sts(__u32 elbaf) +{ + return elbaf & NVME_ID_NS_NVM_STS_MASK; +} + +static inline __u8 nvme_elbaf_guard_type(__u32 elbaf) +{ + return (elbaf >> NVME_ID_NS_NVM_GUARD_SHIFT) & NVME_ID_NS_NVM_GUARD_MASK; +} + struct nvme_id_ctrl_nvm { __u8 vsl; __u8 wzsl; @@ -478,6 +501,8 @@ enum { NVME_NS_FEAT_IO_OPT = 1 << 4, NVME_NS_ATTR_RO = 1 << 0, NVME_NS_FLBAS_LBA_MASK = 0xf, + NVME_NS_FLBAS_LBA_UMASK = 0x60, + NVME_NS_FLBAS_LBA_SHIFT = 1, NVME_NS_FLBAS_META_EXT = 0x10, NVME_NS_NMIC_SHARED = 1 << 0, NVME_LBAF_RP_BEST = 0, @@ -496,6 +521,18 @@ enum { NVME_NS_DPS_PI_TYPE3 = 3, }; +enum { + NVME_NVM_NS_16B_GUARD = 0, + NVME_NVM_NS_32B_GUARD = 1, + NVME_NVM_NS_64B_GUARD = 2, +}; + +static inline __u8 nvme_lbaf_index(__u8 flbas) +{ + return (flbas & NVME_NS_FLBAS_LBA_MASK) | + ((flbas & NVME_NS_FLBAS_LBA_UMASK) >> NVME_NS_FLBAS_LBA_SHIFT); +} + /* Identify Namespace Metadata Capabilities (MC): */ enum { NVME_MC_EXTENDED_LBA = (1 << 0), @@ -842,7 +879,8 @@ struct nvme_rw_command { __u8 flags; __u16 command_id; __le32 nsid; - __u64 rsvd2; + __le32 cdw2; + __le32 cdw3; __le64 metadata; union nvme_data_ptr dptr; __le64 slba; @@ -996,11 +1034,14 @@ enum { struct nvme_feat_host_behavior { __u8 acre; - __u8 resv1[511]; + __u8 etdas; + __u8 lbafee; + __u8 resv1[509]; }; enum { NVME_ENABLE_ACRE = 1, + NVME_ENABLE_LBAFEE = 1, }; /* Admin commands */ From a45194b9de18671adf4acb1741c64298bf32006b Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Mon, 7 Mar 2022 18:29:01 +0100 Subject: [PATCH 266/370] MAINTAINERS: dt-bindings: update Krzysztof Kozlowski's email Use Krzysztof Kozlowski's @kernel.org account in dt-bindings maintainer entry. Signed-off-by: Krzysztof Kozlowski Signed-off-by: Rob Herring Link: https://lore.kernel.org/r/20220307172901.156929-1-krzysztof.kozlowski@canonical.com --- MAINTAINERS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MAINTAINERS b/MAINTAINERS index f1f083955329..922f11c190b9 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -14389,7 +14389,7 @@ F: scripts/dtc/ OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS M: Rob Herring -M: Krzysztof Kozlowski +M: Krzysztof Kozlowski L: devicetree@vger.kernel.org S: Maintained Q: http://patchwork.ozlabs.org/project/devicetree-bindings/list/ From 31e9dc49c2c03c3f166248f16dbe1248ffb5c6a9 Mon Sep 17 00:00:00 2001 From: Colin Ian King Date: Mon, 7 Mar 2022 15:21:49 +0000 Subject: [PATCH 267/370] udf: remove redundant assignment of variable etype Variable etype is being assigned a value that is never read. The variable and assignment are redundant and can be removed. Cleans up clang scan build warning: fs/udf/super.c:2485:10: warning: Although the value stored to 'etype' is used in the enclosing expression, the value is never actually read from 'etype' [deadcode.DeadStores] Link: https://lore.kernel.org/r/20220307152149.139045-1-colin.i.king@gmail.com Signed-off-by: Colin Ian King Signed-off-by: Jan Kara --- fs/udf/super.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/fs/udf/super.c b/fs/udf/super.c index f26b5e0b84b6..8871cc43b272 100644 --- a/fs/udf/super.c +++ b/fs/udf/super.c @@ -2474,7 +2474,6 @@ static unsigned int udf_count_free_table(struct super_block *sb, unsigned int accum = 0; uint32_t elen; struct kernel_lb_addr eloc; - int8_t etype; struct extent_position epos; mutex_lock(&UDF_SB(sb)->s_alloc_mutex); @@ -2482,7 +2481,7 @@ static unsigned int udf_count_free_table(struct super_block *sb, epos.offset = sizeof(struct unallocSpaceEntry); epos.bh = NULL; - while ((etype = udf_next_aext(table, &epos, &eloc, &elen, 1)) != -1) + while (udf_next_aext(table, &epos, &eloc, &elen, 1) != -1) accum += (elen >> table->i_sb->s_blocksize_bits); brelse(epos.bh); From 151c6b49d679872d6fc0b50e0ad96303091694a2 Mon Sep 17 00:00:00 2001 From: Tudor Ambarus Date: Mon, 28 Feb 2022 18:33:34 +0200 Subject: [PATCH 268/370] mtd: spi-nor: Skip erase logic when SPI_NOR_NO_ERASE is set Even if SPI_NOR_NO_ERASE was set, one could still send erase opcodes to the flash. It is not recommended to send unsupported opcodes to flashes. Fix the logic and do not set mtd->_erase when SPI_NOR_NO_ERASE is specified. With this users will not be able to issue erase opcodes to flashes and instead they will recive an -ENOTSUPP error. Fixes: b199489d37b2 ("mtd: spi-nor: add the framework for SPI NOR") Signed-off-by: Tudor Ambarus Reviewed-by: Michael Walle Cc: stable@vger.kernel.org Link: https://lore.kernel.org/r/20220228163334.277730-1-tudor.ambarus@microchip.com --- drivers/mtd/spi-nor/core.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/mtd/spi-nor/core.c b/drivers/mtd/spi-nor/core.c index 9014008e60b3..b4f141ad9c9c 100644 --- a/drivers/mtd/spi-nor/core.c +++ b/drivers/mtd/spi-nor/core.c @@ -2948,10 +2948,11 @@ static void spi_nor_set_mtd_info(struct spi_nor *nor) mtd->flags = MTD_CAP_NORFLASH; if (nor->info->flags & SPI_NOR_NO_ERASE) mtd->flags |= MTD_NO_ERASE; + else + mtd->_erase = spi_nor_erase; mtd->writesize = nor->params->writesize; mtd->writebufsize = nor->params->page_size; mtd->size = nor->params->size; - mtd->_erase = spi_nor_erase; mtd->_read = spi_nor_read; /* Might be already set by some SST flashes. */ if (!mtd->_write) From 4946d58dbb3b35c239881eaedc236b8214bc254b Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Sat, 25 Dec 2021 12:55:06 +0100 Subject: [PATCH 269/370] mfd: intel_soc_pmic_crc: Sort cells by IRQ order The cells for the Crystal Cove PMIC are already mostly sorted by function / IRQ order. Move the ADC cell so that they are fully sorted. Also move some of the resource definitions so that their order matches the (new) order of the cells. Signed-off-by: Hans de Goede Signed-off-by: Lee Jones Link: https://lore.kernel.org/r/20211225115509.94891-2-hdegoede@redhat.com --- drivers/mfd/intel_soc_pmic_crc.c | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/drivers/mfd/intel_soc_pmic_crc.c b/drivers/mfd/intel_soc_pmic_crc.c index 38acb20e2d60..574cb8f9c70d 100644 --- a/drivers/mfd/intel_soc_pmic_crc.c +++ b/drivers/mfd/intel_soc_pmic_crc.c @@ -28,18 +28,10 @@ #define CRYSTAL_COVE_IRQ_GPIO 5 #define CRYSTAL_COVE_IRQ_VHDMIOCP 6 -static const struct resource gpio_resources[] = { - DEFINE_RES_IRQ_NAMED(CRYSTAL_COVE_IRQ_GPIO, "GPIO"), -}; - static const struct resource pwrsrc_resources[] = { DEFINE_RES_IRQ_NAMED(CRYSTAL_COVE_IRQ_PWRSRC, "PWRSRC"), }; -static const struct resource adc_resources[] = { - DEFINE_RES_IRQ_NAMED(CRYSTAL_COVE_IRQ_ADC, "ADC"), -}; - static const struct resource thermal_resources[] = { DEFINE_RES_IRQ_NAMED(CRYSTAL_COVE_IRQ_THRM, "THERMAL"), }; @@ -48,17 +40,20 @@ static const struct resource bcu_resources[] = { DEFINE_RES_IRQ_NAMED(CRYSTAL_COVE_IRQ_BCU, "BCU"), }; +static const struct resource adc_resources[] = { + DEFINE_RES_IRQ_NAMED(CRYSTAL_COVE_IRQ_ADC, "ADC"), +}; + +static const struct resource gpio_resources[] = { + DEFINE_RES_IRQ_NAMED(CRYSTAL_COVE_IRQ_GPIO, "GPIO"), +}; + static struct mfd_cell crystal_cove_byt_dev[] = { { .name = "crystal_cove_pwrsrc", .num_resources = ARRAY_SIZE(pwrsrc_resources), .resources = pwrsrc_resources, }, - { - .name = "crystal_cove_adc", - .num_resources = ARRAY_SIZE(adc_resources), - .resources = adc_resources, - }, { .name = "crystal_cove_thermal", .num_resources = ARRAY_SIZE(thermal_resources), @@ -69,6 +64,11 @@ static struct mfd_cell crystal_cove_byt_dev[] = { .num_resources = ARRAY_SIZE(bcu_resources), .resources = bcu_resources, }, + { + .name = "crystal_cove_adc", + .num_resources = ARRAY_SIZE(adc_resources), + .resources = adc_resources, + }, { .name = "crystal_cove_gpio", .num_resources = ARRAY_SIZE(gpio_resources), From 50904e9bd686a2b1fe4c98273a57ba048bd0f1c4 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Sat, 25 Dec 2021 12:55:07 +0100 Subject: [PATCH 270/370] mfd: intel_soc_pmic_crc: Add crystal_cove_charger cell to BYT cells The Crystal Cove PMIC has a pin which can be used to connect the IRQ of an external charger IC. On some boards this is used and we need to have a cell for this, with a driver which creates its own irqchip with a single IRQ for the charger driver to consume. The charger driver cannot directly consume the IRQ from the MFD level irqchip because the PMIC has 2 levels of interrupts and the second level interrupt status register, which is handled by the cell drivers, needs to have the IRQ acked to avoid an IRQ storm. Signed-off-by: Hans de Goede Signed-off-by: Lee Jones Link: https://lore.kernel.org/r/20211225115509.94891-3-hdegoede@redhat.com --- drivers/mfd/intel_soc_pmic_crc.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/drivers/mfd/intel_soc_pmic_crc.c b/drivers/mfd/intel_soc_pmic_crc.c index 574cb8f9c70d..5bb0367bd974 100644 --- a/drivers/mfd/intel_soc_pmic_crc.c +++ b/drivers/mfd/intel_soc_pmic_crc.c @@ -44,6 +44,10 @@ static const struct resource adc_resources[] = { DEFINE_RES_IRQ_NAMED(CRYSTAL_COVE_IRQ_ADC, "ADC"), }; +static const struct resource charger_resources[] = { + DEFINE_RES_IRQ_NAMED(CRYSTAL_COVE_IRQ_CHGR, "CHGR"), +}; + static const struct resource gpio_resources[] = { DEFINE_RES_IRQ_NAMED(CRYSTAL_COVE_IRQ_GPIO, "GPIO"), }; @@ -69,6 +73,11 @@ static struct mfd_cell crystal_cove_byt_dev[] = { .num_resources = ARRAY_SIZE(adc_resources), .resources = adc_resources, }, + { + .name = "crystal_cove_charger", + .num_resources = ARRAY_SIZE(charger_resources), + .resources = charger_resources, + }, { .name = "crystal_cove_gpio", .num_resources = ARRAY_SIZE(gpio_resources), From f49f43371b8a680c5972d052598d7c120f1a05d3 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Sat, 25 Dec 2021 12:55:08 +0100 Subject: [PATCH 271/370] mfd: intel_soc_pmic_crc: Set main IRQ domain bus token to DOMAIN_BUS_NEXUS For the CRC PMIC we end up with multiple IRQ domains with the same fwnode. One for the irqchip which demultiplexes the actual PMIC interrupt into interrupts for the various cells (known as the level 1 interrupts); And 2 more for the irqchips which are part of the crystal_cove_gpio and crystal_cove_charger cells. This leads to the following error being printed when CONFIG_GENERIC_IRQ_DEBUGFS is enabled: debugfs: File '\_SB.I2C7.PMIC' in directory 'domains' already present! Set the bus token of the main IRQ domain to DOMAIN_BUS_NEXUS to avoid this error, this also allows irq_find_matching_fwspec() to find the right domain if necessary. Note all 3 domain registering drivers need to set the IRQ domain bus token. This is necessary because the IRQ domain code defaults to creating the debugfs dir with just the fwnode name and then renames it when the bus token is set. So each one starts with the same default name and all 3 must be given a different name to avoid problems when one of the other drivers loads and starts with the same default name. Signed-off-by: Hans de Goede Signed-off-by: Lee Jones Link: https://lore.kernel.org/r/20211225115509.94891-4-hdegoede@redhat.com --- drivers/mfd/intel_soc_pmic_core.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/mfd/intel_soc_pmic_core.c b/drivers/mfd/intel_soc_pmic_core.c index 47cb7f00dfcf..5e8c94e008ed 100644 --- a/drivers/mfd/intel_soc_pmic_core.c +++ b/drivers/mfd/intel_soc_pmic_core.c @@ -64,6 +64,10 @@ static int intel_soc_pmic_i2c_probe(struct i2c_client *i2c, /* Add lookup table for crc-pwm */ pwm_add_table(crc_pwm_lookup, ARRAY_SIZE(crc_pwm_lookup)); + /* To distuingish this domain from the GPIO/charger's irqchip domains */ + irq_domain_update_bus_token(regmap_irq_get_domain(pmic->irq_chip_data), + DOMAIN_BUS_NEXUS); + ret = mfd_add_devices(dev, -1, config->cell_dev, config->n_cell_devs, NULL, 0, regmap_irq_get_domain(pmic->irq_chip_data)); From b0e846248de5bd57e4b785791f359ecb8f2d7311 Mon Sep 17 00:00:00 2001 From: Lukas Bulwahn Date: Mon, 27 Dec 2021 07:48:39 +0100 Subject: [PATCH 272/370] mfd: db8500-prcmu: Remove dead code for a non-existing config The config DBX500_PRCMU_QOS_POWER was never introduced in the kernel repository. So, the ifdef in ./include/linux/mfd/dbx500-prcmu.h was never effective. Remove these dead function prototypes. Signed-off-by: Lukas Bulwahn Reviewed-by: Linus Walleij Signed-off-by: Lee Jones Link: https://lore.kernel.org/r/20211227064839.21405-1-lukas.bulwahn@gmail.com --- include/linux/mfd/dbx500-prcmu.h | 18 ------------------ 1 file changed, 18 deletions(-) diff --git a/include/linux/mfd/dbx500-prcmu.h b/include/linux/mfd/dbx500-prcmu.h index cbf9d7619493..2a255362b5ac 100644 --- a/include/linux/mfd/dbx500-prcmu.h +++ b/include/linux/mfd/dbx500-prcmu.h @@ -556,22 +556,6 @@ static inline void prcmu_clear(unsigned int reg, u32 bits) #define PRCMU_QOS_ARM_OPP 3 #define PRCMU_QOS_DEFAULT_VALUE -1 -#ifdef CONFIG_DBX500_PRCMU_QOS_POWER - -unsigned long prcmu_qos_get_cpufreq_opp_delay(void); -void prcmu_qos_set_cpufreq_opp_delay(unsigned long); -void prcmu_qos_force_opp(int, s32); -int prcmu_qos_requirement(int pm_qos_class); -int prcmu_qos_add_requirement(int pm_qos_class, char *name, s32 value); -int prcmu_qos_update_requirement(int pm_qos_class, char *name, s32 new_value); -void prcmu_qos_remove_requirement(int pm_qos_class, char *name); -int prcmu_qos_add_notifier(int prcmu_qos_class, - struct notifier_block *notifier); -int prcmu_qos_remove_notifier(int prcmu_qos_class, - struct notifier_block *notifier); - -#else - static inline unsigned long prcmu_qos_get_cpufreq_opp_delay(void) { return 0; @@ -613,6 +597,4 @@ static inline int prcmu_qos_remove_notifier(int prcmu_qos_class, return 0; } -#endif - #endif /* __MACH_PRCMU_H */ From 10377bb293358c4fe06204ed596264f69f85102a Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Tue, 4 Jan 2022 16:54:35 +0000 Subject: [PATCH 273/370] mfd: arizona: Add missing statics to the of_match_tables When the match tables were split for I2C and SPI a static should have been added since the tables are no longer exported. Fixes: 3f65555c417c ("mfd: arizona: Split of_match table into I2C and SPI versions") Reported-by: kernel test robot Signed-off-by: Charles Keepax Signed-off-by: Lee Jones Link: https://lore.kernel.org/r/20220104165435.26782-1-ckeepax@opensource.cirrus.com --- drivers/mfd/arizona-i2c.c | 2 +- drivers/mfd/arizona-spi.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/mfd/arizona-i2c.c b/drivers/mfd/arizona-i2c.c index 3ed810e81f63..6d83e6b9a692 100644 --- a/drivers/mfd/arizona-i2c.c +++ b/drivers/mfd/arizona-i2c.c @@ -105,7 +105,7 @@ static const struct i2c_device_id arizona_i2c_id[] = { MODULE_DEVICE_TABLE(i2c, arizona_i2c_id); #ifdef CONFIG_OF -const struct of_device_id arizona_i2c_of_match[] = { +static const struct of_device_id arizona_i2c_of_match[] = { { .compatible = "wlf,wm5102", .data = (void *)WM5102 }, { .compatible = "wlf,wm5110", .data = (void *)WM5110 }, { .compatible = "wlf,wm8280", .data = (void *)WM8280 }, diff --git a/drivers/mfd/arizona-spi.c b/drivers/mfd/arizona-spi.c index 9fe06dda3782..98c87d3bd00f 100644 --- a/drivers/mfd/arizona-spi.c +++ b/drivers/mfd/arizona-spi.c @@ -226,7 +226,7 @@ static const struct spi_device_id arizona_spi_ids[] = { MODULE_DEVICE_TABLE(spi, arizona_spi_ids); #ifdef CONFIG_OF -const struct of_device_id arizona_spi_of_match[] = { +static const struct of_device_id arizona_spi_of_match[] = { { .compatible = "wlf,wm5102", .data = (void *)WM5102 }, { .compatible = "wlf,wm5110", .data = (void *)WM5110 }, { .compatible = "wlf,wm8280", .data = (void *)WM8280 }, From a96f688b4e4466da39385368f47fc02a0409a367 Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Thu, 10 Feb 2022 08:44:44 +0000 Subject: [PATCH 274/370] hwmon: sy7636a: Fix trivial 'underline too short' warning Documentation/hwmon/sy7636a-hwmon.rst:4: WARNING: Title underline too short. Kernel driver sy7636a-hwmon ========================= Acked-by: Guenter Roeck Signed-off-by: Lee Jones Link: https://lore.kernel.org/all/YgTRu7iLgJMymeT5@google.com/ --- Documentation/hwmon/sy7636a-hwmon.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Documentation/hwmon/sy7636a-hwmon.rst b/Documentation/hwmon/sy7636a-hwmon.rst index 5612079397d5..c85db7b32941 100644 --- a/Documentation/hwmon/sy7636a-hwmon.rst +++ b/Documentation/hwmon/sy7636a-hwmon.rst @@ -1,7 +1,7 @@ .. SPDX-License-Identifier: GPL-2.0-or-later Kernel driver sy7636a-hwmon -========================= +=========================== Supported chips: From 56f216d8efbc1212bf5ff8a6ff5e29927965e8db Mon Sep 17 00:00:00 2001 From: Peter Geis Date: Tue, 8 Feb 2022 14:40:23 -0500 Subject: [PATCH 275/370] mfd: rk808: Add reboot support to rk808.c This adds reboot support to the rk808 pmic driver and enables it for the rk809 and rk817 devices. This only enables if the rockchip,system-power-controller flag is set. Signed-off-by: Peter Geis Signed-off-by: Frank Wunderlich Reviewed-by: Dmitry Osipenko Signed-off-by: Lee Jones Link: https://lore.kernel.org/r/20220208194023.929720-1-pgwipeout@gmail.com --- drivers/mfd/rk808.c | 44 +++++++++++++++++++++++++++++++++++++++ include/linux/mfd/rk808.h | 1 + 2 files changed, 45 insertions(+) diff --git a/drivers/mfd/rk808.c b/drivers/mfd/rk808.c index b181fe401330..4142b638e5fa 100644 --- a/drivers/mfd/rk808.c +++ b/drivers/mfd/rk808.c @@ -19,6 +19,7 @@ #include #include #include +#include struct rk808_reg_data { int addr; @@ -543,6 +544,7 @@ static void rk808_pm_power_off(void) reg = RK808_DEVCTRL_REG, bit = DEV_OFF_RST; break; + case RK809_ID: case RK817_ID: reg = RK817_SYS_CFG(3); bit = DEV_OFF; @@ -559,6 +561,34 @@ static void rk808_pm_power_off(void) dev_err(&rk808_i2c_client->dev, "Failed to shutdown device!\n"); } +static int rk808_restart_notify(struct notifier_block *this, unsigned long mode, void *cmd) +{ + struct rk808 *rk808 = i2c_get_clientdata(rk808_i2c_client); + unsigned int reg, bit; + int ret; + + switch (rk808->variant) { + case RK809_ID: + case RK817_ID: + reg = RK817_SYS_CFG(3); + bit = DEV_RST; + break; + + default: + return NOTIFY_DONE; + } + ret = regmap_update_bits(rk808->regmap, reg, bit, bit); + if (ret) + dev_err(&rk808_i2c_client->dev, "Failed to restart device!\n"); + + return NOTIFY_DONE; +} + +static struct notifier_block rk808_restart_handler = { + .notifier_call = rk808_restart_notify, + .priority = 192, +}; + static void rk8xx_shutdown(struct i2c_client *client) { struct rk808 *rk808 = i2c_get_clientdata(client); @@ -727,6 +757,18 @@ static int rk808_probe(struct i2c_client *client, if (of_property_read_bool(np, "rockchip,system-power-controller")) { rk808_i2c_client = client; pm_power_off = rk808_pm_power_off; + + switch (rk808->variant) { + case RK809_ID: + case RK817_ID: + ret = register_restart_handler(&rk808_restart_handler); + if (ret) + dev_warn(&client->dev, "failed to register rst handler, %d\n", ret); + break; + default: + dev_dbg(&client->dev, "pmic controlled board reset not supported\n"); + break; + } } return 0; @@ -749,6 +791,8 @@ static int rk808_remove(struct i2c_client *client) if (pm_power_off == rk808_pm_power_off) pm_power_off = NULL; + unregister_restart_handler(&rk808_restart_handler); + return 0; } diff --git a/include/linux/mfd/rk808.h b/include/linux/mfd/rk808.h index a96e6d43ca06..58602032e642 100644 --- a/include/linux/mfd/rk808.h +++ b/include/linux/mfd/rk808.h @@ -373,6 +373,7 @@ enum rk805_reg { #define SWITCH2_EN BIT(6) #define SWITCH1_EN BIT(5) #define DEV_OFF_RST BIT(3) +#define DEV_RST BIT(2) #define DEV_OFF BIT(0) #define RTC_STOP BIT(0) From 2a6bacf79b3ae3616393e4b9a0fc623e269e506f Mon Sep 17 00:00:00 2001 From: Luca Weiss Date: Wed, 12 Jan 2022 20:40:52 +0100 Subject: [PATCH 276/370] dt-bindings: mfd: qcom,tcsr: Document msm8953 compatible Document the compatible for tcsr found in msm8953. Signed-off-by: Luca Weiss Acked-by: Konrad Dybcio Acked-by: Rob Herring Signed-off-by: Lee Jones Link: https://lore.kernel.org/r/20220112194118.178026-4-luca@z3ntu.xyz --- Documentation/devicetree/bindings/mfd/qcom,tcsr.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/Documentation/devicetree/bindings/mfd/qcom,tcsr.txt b/Documentation/devicetree/bindings/mfd/qcom,tcsr.txt index c5f4f0ddfcc3..add61bcc3c74 100644 --- a/Documentation/devicetree/bindings/mfd/qcom,tcsr.txt +++ b/Documentation/devicetree/bindings/mfd/qcom,tcsr.txt @@ -10,6 +10,7 @@ Required properties: "qcom,tcsr-ipq8064", "syscon" for IPQ8064 "qcom,tcsr-apq8064", "syscon" for APQ8064 "qcom,tcsr-msm8660", "syscon" for MSM8660 + "qcom,tcsr-msm8953", "syscon" for MSM8953 "qcom,tcsr-msm8960", "syscon" for MSM8960 "qcom,tcsr-msm8974", "syscon" for MSM8974 "qcom,tcsr-apq8084", "syscon" for APQ8084 From c788f6e6aa112bf516d0f3f85ae6cc4e6c103239 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Mon, 14 Feb 2022 16:07:10 +0100 Subject: [PATCH 277/370] mfd: stmfx: Improve error message triggered by regulator fault in .remove() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Returning a non-zero value in an i2c remove callback results in the i2c core emitting a very generic error message ("remove failed (-ESOMETHING), will be ignored") and as the message indicates not further error handling is done. Instead emit a more specific error message and then return zero in .remove(). The long-term goal is to make the i2c remove prototype return void, making all implementations return 0 is preparatory work for this change. Signed-off-by: Uwe Kleine-König Signed-off-by: Lee Jones Link: https://lore.kernel.org/r/20220214150710.312269-1-u.kleine-koenig@pengutronix.de --- drivers/mfd/stmfx.c | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/drivers/mfd/stmfx.c b/drivers/mfd/stmfx.c index e095a3930142..122f96094410 100644 --- a/drivers/mfd/stmfx.c +++ b/drivers/mfd/stmfx.c @@ -392,17 +392,22 @@ err: return ret; } -static int stmfx_chip_exit(struct i2c_client *client) +static void stmfx_chip_exit(struct i2c_client *client) { struct stmfx *stmfx = i2c_get_clientdata(client); regmap_write(stmfx->map, STMFX_REG_IRQ_SRC_EN, 0); regmap_write(stmfx->map, STMFX_REG_SYS_CTRL, 0); - if (stmfx->vdd) - return regulator_disable(stmfx->vdd); + if (stmfx->vdd) { + int ret; - return 0; + ret = regulator_disable(stmfx->vdd); + if (ret) + dev_err(&client->dev, + "Failed to disable vdd regulator: %pe\n", + ERR_PTR(ret)); + } } static int stmfx_probe(struct i2c_client *client, @@ -466,7 +471,9 @@ static int stmfx_remove(struct i2c_client *client) { stmfx_irq_exit(client); - return stmfx_chip_exit(client); + stmfx_chip_exit(client); + + return 0; } #ifdef CONFIG_PM_SLEEP From c3a0dcd8f5668e45a9e8a91b80f4ab99bbe21e78 Mon Sep 17 00:00:00 2001 From: Luca Weiss Date: Wed, 12 Jan 2022 20:40:53 +0100 Subject: [PATCH 278/370] mfd: qcom-spmi-pmic: Add pm8953 compatible Document the compatible for pm8953 as found in msm8953. Signed-off-by: Luca Weiss Acked-by: Konrad Dybcio Acked-by: Rob Herring Signed-off-by: Lee Jones Link: https://lore.kernel.org/r/20220112194118.178026-5-luca@z3ntu.xyz --- Documentation/devicetree/bindings/mfd/qcom,spmi-pmic.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/Documentation/devicetree/bindings/mfd/qcom,spmi-pmic.txt b/Documentation/devicetree/bindings/mfd/qcom,spmi-pmic.txt index 7a27c500ff63..a461ec2f758f 100644 --- a/Documentation/devicetree/bindings/mfd/qcom,spmi-pmic.txt +++ b/Documentation/devicetree/bindings/mfd/qcom,spmi-pmic.txt @@ -35,6 +35,7 @@ Required properties: "qcom,pm8916", "qcom,pm8941", "qcom,pm8950", + "qcom,pm8953", "qcom,pm8994", "qcom,pm8998", "qcom,pma8084", From a002f65ab409608b643c79bf6417bd453b64a55f Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Sat, 15 Jan 2022 01:26:49 +0100 Subject: [PATCH 279/370] mfd: ab8500: Rewrite bindings in YAML This rewrites the former text based AB8500 bindings in YAML. When the AB8500 bindings were first written (in 2012) we were not strict on some things and node names were definitely not standardized. This patch uses standard node names to most of the subnodes on the AB8500 and is accompanied by another patch fixing all the DTS files to conform to this. The bindings are not as perfect as newly written bindings would be, it is a best effort to deal with the legacy. Cc: devicetree@vger.kernel.org Signed-off-by: Linus Walleij Reviewed-by: Rob Herring Signed-off-by: Lee Jones Link: https://lore.kernel.org/r/20220115002649.1526163-1-linus.walleij@linaro.org --- .../devicetree/bindings/mfd/ab8500.txt | 282 ---------- .../bindings/mfd/stericsson,ab8500.yaml | 500 ++++++++++++++++++ .../bindings/mfd/stericsson,db8500-prcmu.yaml | 1 + 3 files changed, 501 insertions(+), 282 deletions(-) delete mode 100644 Documentation/devicetree/bindings/mfd/ab8500.txt create mode 100644 Documentation/devicetree/bindings/mfd/stericsson,ab8500.yaml diff --git a/Documentation/devicetree/bindings/mfd/ab8500.txt b/Documentation/devicetree/bindings/mfd/ab8500.txt deleted file mode 100644 index 937b3e5505e0..000000000000 --- a/Documentation/devicetree/bindings/mfd/ab8500.txt +++ /dev/null @@ -1,282 +0,0 @@ -* AB8500 Multi-Functional Device (MFD) - -Required parent device properties: -- compatible : contains "stericsson,ab8500" or "stericsson,ab8505"; -- interrupts : contains the IRQ line for the AB8500 -- interrupt-controller : describes the AB8500 as an Interrupt Controller (has its own domain) -- #interrupt-cells : should be 2, for 2-cell format - - The first cell is the AB8500 local IRQ number - - The second cell is used to specify optional parameters - - bits[3:0] trigger type and level flags: - 1 = low-to-high edge triggered - 2 = high-to-low edge triggered - 4 = active high level-sensitive - 8 = active low level-sensitive - -The AB8500 consists of a large and varied group of sub-devices: - -Device IRQ Names Supply Names Description ------- --------- ------------ ----------- -ab8500-bm : : : Battery Manager -ab8500-btemp : : : Battery Temperature -ab8500-charger : : : Battery Charger -ab8500-codec : : : Audio Codec -ab8500-fg : : vddadc : Fuel Gauge - : NCONV_ACCU : : Accumulate N Sample Conversion - : BATT_OVV : : Battery Over Voltage - : LOW_BAT_F : : LOW threshold battery voltage - : CC_INT_CALIB : : Coulomb Counter Internal Calibration - : CCEOC : : Coulomb Counter End of Conversion -ab8500-btemp : : vtvout : Battery Temperature - : BAT_CTRL_INDB : : Battery Removal Indicator - : BTEMP_LOW : : Btemp < BtempLow, if battery temperature is lower than -10°C - : BTEMP_LOW_MEDIUM : : BtempLow < Btemp < BtempMedium,if battery temperature is between -10 and 0°C - : BTEMP_MEDIUM_HIGH : : BtempMedium < Btemp < BtempHigh,if battery temperature is between 0°C and MaxTemp - : BTEMP_HIGH : : Btemp > BtempHigh, if battery temperature is higher than MaxTemp -ab8500-charger : : vddadc : Charger interface - : MAIN_CH_UNPLUG_DET : : main charger unplug detection management (not in 8505) - : MAIN_CHARGE_PLUG_DET : : main charger plug detection management (not in 8505) - : MAIN_EXT_CH_NOT_OK : : main charger not OK - : MAIN_CH_TH_PROT_R : : Die temp is above main charger - : MAIN_CH_TH_PROT_F : : Die temp is below main charger - : VBUS_DET_F : : VBUS falling detected - : VBUS_DET_R : : VBUS rising detected - : USB_LINK_STATUS : : USB link status has changed - : USB_CH_TH_PROT_R : : Die temp is above usb charger - : USB_CH_TH_PROT_F : : Die temp is below usb charger - : USB_CHARGER_NOT_OKR : : allowed USB charger not ok detection - : VBUS_OVV : : Overvoltage on Vbus ball detected (USB charge is stopped) - : CH_WD_EXP : : Charger watchdog detected -ab8500-gpadc : HW_CONV_END : vddadc : Analogue to Digital Converter - SW_CONV_END : : -ab8500-gpio : : : GPIO Controller (AB8500) -ab8505-gpio : : : GPIO Controller (AB8505) -ab8500-ponkey : ONKEY_DBF : : Power-on Key - ONKEY_DBR : : -ab8500-pwm : : : Pulse Width Modulator -ab8500-regulator : : : Regulators (AB8500) -ab8505-regulator : : : Regulators (AB8505) -ab8500-rtc : 60S : : Real Time Clock - : ALARM : : -ab8500-sysctrl : : : System Control -ab8500-usb : ID_WAKEUP_R : vddulpivio18 : Universal Serial Bus - : ID_WAKEUP_F : v-ape : - : VBUS_DET_F : musb_1v8 : - : VBUS_DET_R : : - : USB_LINK_STATUS : : - : USB_ADP_PROBE_PLUG : : - : USB_ADP_PROBE_UNPLUG : : - -Required child device properties: -- compatible : "stericsson,ab8500-[bm|btemp|charger|fg|gpadc|gpio|ponkey| - pwm|regulator|rtc|sysctrl|usb]"; - - A few child devices require ADC channels from the GPADC node. Those follow the - standard bindings from - https://github.com/devicetree-org/dt-schema/blob/master/schemas/iio/iio-consumer.yaml - and Documentation/devicetree/bindings/iio/adc/adc.yaml - - abx500-temp : io-channels "aux1" and "aux2" for measuring external - temperatures. - ab8500-fg : io-channel "main_bat_v" for measuring main battery voltage, - ab8500-btemp : io-channels "btemp_ball" and "bat_ctrl" for measuring the - battery voltage. - ab8500-charger : io-channels "main_charger_v", "main_charger_c", "vbus_v", - "usb_charger_c" for measuring voltage and current of the - different charging supplies. - -Optional child device properties: -- interrupts : contains the device IRQ(s) using the 2-cell format (see above) -- interrupt-names : contains names of IRQ resource in the order in which they were - supplied in the interrupts property -- -supply : contains a phandle to the regulator supply node in Device Tree - -Non-standard child device properties: - - Audio CODEC: - - stericsson,amic[1|2]-type-single-ended : Single-ended Analoge Mic (default: differential) - - stericsson,amic1a-bias-vamic2 : Analoge Mic wishes to use a non-standard Vamic - - stericsson,amic1b-bias-vamic2 : Analoge Mic wishes to use a non-standard Vamic - - stericsson,amic2-bias-vamic1 : Analoge Mic wishes to use a non-standard Vamic - - stericsson,earpeice-cmv : Earpeice voltage (only: 950 | 1100 | 1270 | 1580) - -ab8500 { - compatible = "stericsson,ab8500"; - interrupts = <0 40 0x4>; - interrupt-controller; - #interrupt-cells = <2>; - - ab8500-rtc { - compatible = "stericsson,ab8500-rtc"; - interrupts = <17 0x4 - 18 0x4>; - interrupt-names = "60S", "ALARM"; - }; - - ab8500-gpadc { - compatible = "stericsson,ab8500-gpadc"; - interrupts = <32 0x4 - 39 0x4>; - interrupt-names = "HW_CONV_END", "SW_CONV_END"; - vddadc-supply = <&ab8500_ldo_tvout_reg>; - #address-cells = <1>; - #size-cells = <0>; - #io-channel-cells = <1>; - - /* GPADC channels */ - bat_ctrl: channel@1 { - reg = <0x01>; - }; - btemp_ball: channel@2 { - reg = <0x02>; - }; - main_charger_v: channel@3 { - reg = <0x03>; - }; - acc_detect1: channel@4 { - reg = <0x04>; - }; - acc_detect2: channel@5 { - reg = <0x05>; - }; - adc_aux1: channel@6 { - reg = <0x06>; - }; - adc_aux2: channel@7 { - reg = <0x07>; - }; - main_batt_v: channel@8 { - reg = <0x08>; - }; - vbus_v: channel@9 { - reg = <0x09>; - }; - main_charger_c: channel@a { - reg = <0x0a>; - }; - usb_charger_c: channel@b { - reg = <0x0b>; - }; - bk_bat_v: channel@c { - reg = <0x0c>; - }; - die_temp: channel@d { - reg = <0x0d>; - }; - usb_id: channel@e { - reg = <0x0e>; - }; - xtal_temp: channel@12 { - reg = <0x12>; - }; - vbat_true_meas: channel@13 { - reg = <0x13>; - }; - bat_ctrl_and_ibat: channel@1c { - reg = <0x1c>; - }; - vbat_meas_and_ibat: channel@1d { - reg = <0x1d>; - }; - vbat_true_meas_and_ibat: channel@1e { - reg = <0x1e>; - }; - bat_temp_and_ibat: channel@1f { - reg = <0x1f>; - }; - }; - - ab8500_temp { - compatible = "stericsson,abx500-temp"; - io-channels = <&gpadc 0x06>, - <&gpadc 0x07>; - io-channel-name = "aux1", "aux2"; - }; - - ab8500_battery: ab8500_battery { - stericsson,battery-type = "LIPO"; - thermistor-on-batctrl; - }; - - ab8500_fg { - compatible = "stericsson,ab8500-fg"; - battery = <&ab8500_battery>; - io-channels = <&gpadc 0x08>; - io-channel-name = "main_bat_v"; - }; - - ab8500_btemp { - compatible = "stericsson,ab8500-btemp"; - battery = <&ab8500_battery>; - io-channels = <&gpadc 0x02>, - <&gpadc 0x01>; - io-channel-name = "btemp_ball", - "bat_ctrl"; - }; - - ab8500_charger { - compatible = "stericsson,ab8500-charger"; - battery = <&ab8500_battery>; - vddadc-supply = <&ab8500_ldo_tvout_reg>; - io-channels = <&gpadc 0x03>, - <&gpadc 0x0a>, - <&gpadc 0x09>, - <&gpadc 0x0b>; - io-channel-name = "main_charger_v", - "main_charger_c", - "vbus_v", - "usb_charger_c"; - }; - - ab8500-usb { - compatible = "stericsson,ab8500-usb"; - interrupts = < 90 0x4 - 96 0x4 - 14 0x4 - 15 0x4 - 79 0x4 - 74 0x4 - 75 0x4>; - interrupt-names = "ID_WAKEUP_R", - "ID_WAKEUP_F", - "VBUS_DET_F", - "VBUS_DET_R", - "USB_LINK_STATUS", - "USB_ADP_PROBE_PLUG", - "USB_ADP_PROBE_UNPLUG"; - vddulpivio18-supply = <&ab8500_ldo_intcore_reg>; - v-ape-supply = <&db8500_vape_reg>; - musb_1v8-supply = <&db8500_vsmps2_reg>; - }; - - ab8500-ponkey { - compatible = "stericsson,ab8500-ponkey"; - interrupts = <6 0x4 - 7 0x4>; - interrupt-names = "ONKEY_DBF", "ONKEY_DBR"; - }; - - ab8500-sysctrl { - compatible = "stericsson,ab8500-sysctrl"; - }; - - ab8500-pwm { - compatible = "stericsson,ab8500-pwm"; - }; - - codec: ab8500-codec { - compatible = "stericsson,ab8500-codec"; - - stericsson,earpeice-cmv = <950>; /* Units in mV. */ - }; - - ab8500-regulators { - compatible = "stericsson,ab8500-regulator"; - - ab8500_ldo_aux1_reg: ab8500_ldo_aux1 { - /* - * See: Documentation/devicetree/bindings/regulator/regulator.txt - * for more information on regulators - */ - }; - }; -}; diff --git a/Documentation/devicetree/bindings/mfd/stericsson,ab8500.yaml b/Documentation/devicetree/bindings/mfd/stericsson,ab8500.yaml new file mode 100644 index 000000000000..623a4b5cd27a --- /dev/null +++ b/Documentation/devicetree/bindings/mfd/stericsson,ab8500.yaml @@ -0,0 +1,500 @@ +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/mfd/stericsson,ab8500.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: ST-Ericsson Analog Baseband AB8500 and AB8505 + +maintainers: + - Linus Walleij + +description: + the AB8500 "Analog Baseband" is the mixed-signals integrated circuit + handling power management (regulators), analog-to-digital conversion + (ADC), battery charging, fuel gauging of the battery, battery-backed + RTC, PWM, USB PHY and some GPIO lines in the ST-Ericsson U8500 platforms + in connection with the DB8500 digital baseband. The DB8500 PRCMU + communicates directly and autonomously with the AB8500 and thus it + appears as a subnode of the DB8500 PRCMU. An altered version called + AB8505 also exist, the difference in AB8505 is that some of the USB and + USB charging handling has changed, and it has an embedded USB-to-serial + converter. Most subblocks takes their interrupts directly from the + AB8500 embedded interrupt controller. + +properties: + $nodename: + pattern: '^ab850[05]$' + + compatible: + enum: + - stericsson,ab8500 + - stericsson,ab8505 + + interrupts: + maxItems: 1 + + interrupt-controller: true + + '#interrupt-cells': + const: 2 + + # Some subnodes use a reg, some don't. Those that do use a single cell. + '#address-cells': + const: 1 + + '#size-cells': + const: 0 + + clock-controller: + description: Node describing the AB8500 clock controller. This + provides the reference clock for the entire U8500 system and + the DB8500 counterpart. + type: object + + properties: + compatible: + const: stericsson,ab8500-clk + + '#clock-cells': + const: 1 + + gpio: + description: Node describing the AB8500 GPIO controller. A few + GPIO pins available for misc usage. + type: object + + properties: + compatible: + enum: + - stericsson,ab8500-gpio + - stericsson,ab8505-gpio + + gpio-controller: true + + '#gpio-cells': + const: 2 + + rtc: + description: Node describing the AB8500 battery-backed RTC. + type: object + + properties: + compatible: + const: stericsson,ab8500-rtc + + interrupts: + items: + - description: 60 second interval alarm interrupt + - description: RTC alarm + + interrupt-names: + items: + - const: 60S + - const: ALARM + + adc: + description: Node describing the AB8500 general purpose analog to digital + converter, GPADC. + type: object + + properties: + compatible: + const: stericsson,ab8500-gpadc + + # AB8505 only supports one (software) EOC interrupt + interrupts: + minItems: 1 + maxItems: 2 + + interrupt-names: true + + vddadc-supply: true + + '#address-cells': + const: 1 + + '#size-cells': + const: 0 + + '#io-channel-cells': + const: 1 + + patternProperties: + "^channel@[0-9a-f]+$": + type: object + $ref: ../iio/adc/adc.yaml# + description: Represents each of the external channels which are + connected to the ADC. + + properties: + reg: + items: + minimum: 1 + maximum: 31 + + required: + - reg + + additionalProperties: false + + required: + - compatible + - interrupts + - interrupt-names + - vddadc-supply + - '#address-cells' + - '#size-cells' + - '#io-channel-cells' + + additionalProperties: false + + thermal: + description: Node describing the AB8500 thermal control block. All this block + really does is to fire an interrupt when the die becomes 130 degrees Celsius + in temperature. + type: object + + properties: + compatible: + const: stericsson,abx500-temp + + interrupts: + items: + - description: Thermal warm warning interrupt + + interrupt-names: + items: + - const: ABX500_TEMP_WARM + + required: + - compatible + - interrupts + - interrupt-names + + additionalProperties: false + + ab8500_fg: + description: Node describing the AB8500 fuel gauge control block. + type: object + $ref: ../power/supply/stericsson,ab8500-fg.yaml + + ab8500_btemp: + description: Node describing the AB8500 battery temperature control block. + type: object + $ref: ../power/supply/stericsson,ab8500-btemp.yaml + + ab8500_charger: + description: Node describing the AB8500 battery charger control block. + type: object + $ref: ../power/supply/stericsson,ab8500-charger.yaml + + ab8500_chargalg: + description: Node describing the AB8500 battery charger algorithm. + type: object + $ref: ../power/supply/stericsson,ab8500-chargalg.yaml + + phy: + description: Node describing the AB8500 USB PHY control block. + type: object + + properties: + compatible: + const: stericsson,ab8500-usb + + interrupts: + items: + - description: ID wakeup rising IRQ + - description: ID wakeup falling IRQ + - description: VBUS detection falling IRQ + - description: VBUS detection rising IRQ + - description: USB link status change IRQ + - description: ADP probe plug IRQ + - description: ADP probe unplug IRQ + + interrupt-names: + items: + - const: ID_WAKEUP_R + - const: ID_WAKEUP_F + - const: VBUS_DET_F + - const: VBUS_DET_R + - const: USB_LINK_STATUS + - const: USB_ADP_PROBE_PLUG + - const: USB_ADP_PROBE_UNPLUG + + vddulpivio18-supply: true + v-ape-supply: true + musb_1v8-supply: true + + clocks: + items: + - description: PRCMY system clock + + clock-names: + items: + - const: sysclk + + '#phy-cells': + const: 0 + + required: + - compatible + - interrupts + - interrupt-names + - vddulpivio18-supply + - v-ape-supply + - musb_1v8-supply + - clocks + - clock-names + - '#phy-cells' + + additionalProperties: false + + key: + description: Node describing the AB8500 power-on key control block. + type: object + + properties: + compatible: + const: stericsson,ab8500-poweron-key + + interrupts: + items: + - description: ON key falling IRQ + - description: ON key rising IRQ + + interrupt-names: + items: + - const: ONKEY_DBF + - const: ONKEY_DBR + + required: + - compatible + - interrupts + - interrupt-names + + additionalProperties: false + + ab8500-sysctrl: + description: Node describing the AB8500 system control block. + type: object + + properties: + compatible: + const: stericsson,ab8500-sysctrl + + required: + - compatible + + additionalProperties: false + + codec: + description: Node describing the AB8500 audio codec block. + type: object + + properties: + compatible: + const: stericsson,ab8500-codec + + V-AUD-supply: true + V-AMIC1-supply: true + V-AMIC2-supply: true + V-DMIC-supply: true + + clocks: + items: + - description: Audio system clock + + clock-names: + items: + - const: audioclk + + stericsson,earpeice-cmv: + description: Earpeice voltage + $ref: /schemas/types.yaml#/definitions/uint32 + enum: [ 950, 1100, 1270, 1580 ] + + required: + - compatible + + additionalProperties: false + + regulator: + description: Node describing the AB8500 internal regulators. + type: object + + properties: + compatible: + enum: + - stericsson,ab8500-regulator + - stericsson,ab8505-regulator + + vin-supply: + description: The regulator supplying all of the internal regulators + with power. + + ab8500_ldo_aux1: + description: The voltage for the auxilary LDO regulator 1 + type: object + $ref: ../regulator/regulator.yaml# + + ab8500_ldo_aux2: + description: The voltage for the auxilary LDO regulator 2 + type: object + $ref: ../regulator/regulator.yaml# + + ab8500_ldo_aux3: + description: The voltage for the auxilary LDO regulator 3 + type: object + $ref: ../regulator/regulator.yaml# + + ab8500_ldo_aux4: + description: The voltage for the auxilary LDO regulator 4 + only present on AB8505 + type: object + $ref: ../regulator/regulator.yaml# + + ab8500_ldo_aux5: + description: The voltage for the auxilary LDO regulator 5 + only present on AB8505 + type: object + $ref: ../regulator/regulator.yaml# + + ab8500_ldo_aux6: + description: The voltage for the auxilary LDO regulator 6 + only present on AB8505 + type: object + $ref: ../regulator/regulator.yaml# + + # There is never any AUX7 regulator which is confusing + + ab8500_ldo_aux8: + description: The voltage for the auxilary LDO regulator 8 + only present on AB8505 + type: object + $ref: ../regulator/regulator.yaml# + + ab8500_ldo_intcore: + description: The LDO regulator for the internal core voltage + of the AB8500 + type: object + $ref: ../regulator/regulator.yaml# + + ab8500_ldo_adc: + description: Analog power regulator for the analog to digital converter + ADC, only present on AB8505 + type: object + $ref: ../regulator/regulator.yaml# + + ab8500_ldo_tvout: + description: The voltage for the TV output regulator, incidentally + this voltage is also used for other purposes such as measuring + the temperature of the NTC thermistor on the battery. + Only present on AB8500. + type: object + $ref: ../regulator/regulator.yaml# + + ab8500_ldo_audio: + description: The LDO regulator for the audio codec output + type: object + $ref: ../regulator/regulator.yaml# + + ab8500_ldo_anamic1: + description: The LDO regulator for the analog microphone 1 + type: object + $ref: ../regulator/regulator.yaml# + + ab8500_ldo_anamic2: + description: The LDO regulator for the analog microphone 2 + type: object + $ref: ../regulator/regulator.yaml# + + ab8500_ldo_dmic: + description: The LDO regulator for the digital microphone + only present on AB8500 + type: object + $ref: ../regulator/regulator.yaml# + + ab8500_ldo_ana: + description: Analog power regulator for CSI and DSI interfaces, + Camera Serial Interface CSI and Display Serial Interface DSI. + type: object + $ref: ../regulator/regulator.yaml# + + required: + - compatible + + additionalProperties: false + + + regulator-external: + description: Node describing the AB8500 external regulators. This + concerns the autonomous regulators VSMPS1, VSMPS2 and VSMPS3 + that are normally controlled by external electronics but also + sometimes need to be explicitly controlled by software. + type: object + + properties: + compatible: + const: stericsson,ab8500-ext-regulator + + ab8500_ext1: + description: The voltage for the VSMPS1 external regulator + type: object + $ref: ../regulator/regulator.yaml# + + ab8500_ext2: + description: The voltage for the VSMPS2 external regulator + type: object + $ref: ../regulator/regulator.yaml# + + ab8500_ext3: + description: The voltage for the VSMPS3 external regulator + type: object + $ref: ../regulator/regulator.yaml# + + required: + - compatible + + additionalProperties: false + +patternProperties: + "^pwm@[1-9]+?$": + type: object + $ref: ../pwm/pwm.yaml# + description: Represents each of the PWM blocks in the AB8500 + + properties: + compatible: + const: stericsson,ab8500-pwm + + reg: true + + clocks: + items: + - description: internal clock + + clock-names: + items: + - const: intclk + + required: + - compatible + - reg + +required: + - compatible + - clock-controller + - gpio + - rtc + - adc + - thermal + - ab8500_fg + - ab8500_btemp + - ab8500_charger + - ab8500_chargalg + - phy + - key + - regulator + +additionalProperties: false diff --git a/Documentation/devicetree/bindings/mfd/stericsson,db8500-prcmu.yaml b/Documentation/devicetree/bindings/mfd/stericsson,db8500-prcmu.yaml index a0d4bad5dc81..1d4d88f7e82d 100644 --- a/Documentation/devicetree/bindings/mfd/stericsson,db8500-prcmu.yaml +++ b/Documentation/devicetree/bindings/mfd/stericsson,db8500-prcmu.yaml @@ -263,6 +263,7 @@ patternProperties: set of devicetree bindings. The AB8505 is a newer version of the same ASIC. type: object + $ref: stericsson,ab8500.yaml# required: - compatible From 6ceb5f173ff15136f3d76e8d22aa8c6e784ea126 Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Thu, 10 Feb 2022 21:42:23 +0100 Subject: [PATCH 280/370] mfd: sta2x11: Use GFP_KERNEL instead of GFP_ATOMIC pci_driver probe functions aren't called with locks held and thus don't need GFP_ATOMIC. Use GFP_KERNEL instead. Problem found with Coccinelle. Signed-off-by: Julia Lawall Signed-off-by: Lee Jones Link: https://lore.kernel.org/r/20220210204223.104181-10-Julia.Lawall@inria.fr --- drivers/mfd/sta2x11-mfd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/mfd/sta2x11-mfd.c b/drivers/mfd/sta2x11-mfd.c index 1819c8fe4d8f..02cc49daf2e3 100644 --- a/drivers/mfd/sta2x11-mfd.c +++ b/drivers/mfd/sta2x11-mfd.c @@ -590,7 +590,7 @@ static int sta2x11_mfd_probe(struct pci_dev *pdev, /* Record this pdev before mfd_add_devices: their probe looks for it */ if (!sta2x11_mfd_find(pdev)) - sta2x11_mfd_add(pdev, GFP_ATOMIC); + sta2x11_mfd_add(pdev, GFP_KERNEL); /* Just 2 bars for all mfd's at present */ for (i = 0; i < 2; i++) { From 3d4d1266597c0206f85c42c387eb942716dfad45 Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Sat, 12 Feb 2022 22:47:24 +0100 Subject: [PATCH 281/370] mfd: ab8500: Drop debugfs module This debugfs isn't used by anyone, if we want to dump the contents of registers we should just convert the driver to regmap instead. I'm also excluding this from the device tree bindings when converting to YAML because it is not a real device, and device trees should only contain real physical devices. Delete it. Signed-off-by: Linus Walleij Signed-off-by: Lee Jones Link: https://lore.kernel.org/r/20220212214724.681530-1-linus.walleij@linaro.org --- drivers/mfd/Kconfig | 8 - drivers/mfd/Makefile | 1 - drivers/mfd/ab8500-core.c | 20 - drivers/mfd/ab8500-debugfs.c | 2096 ---------------------------------- 4 files changed, 2125 deletions(-) delete mode 100644 drivers/mfd/ab8500-debugfs.c diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig index f6678c07dc5e..3b59456f5545 100644 --- a/drivers/mfd/Kconfig +++ b/drivers/mfd/Kconfig @@ -1297,14 +1297,6 @@ config AB8500_CORE the irq_chip parts for handling the Mixed Signal chip events. This chip embeds various other multimedia functionalities as well. -config AB8500_DEBUG - bool "Enable debug info via debugfs" - depends on AB8500_GPADC && DEBUG_FS - default y if DEBUG_FS - help - Select this option if you want debug information using the debug - filesystem, debugfs. - config MFD_DB8500_PRCMU bool "ST-Ericsson DB8500 Power Reset Control Management Unit" depends on UX500_SOC_DB8500 diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile index eea70cb9f9b9..858cacf659d6 100644 --- a/drivers/mfd/Makefile +++ b/drivers/mfd/Makefile @@ -177,7 +177,6 @@ obj-$(CONFIG_MFD_PCF50633) += pcf50633.o obj-$(CONFIG_PCF50633_ADC) += pcf50633-adc.o obj-$(CONFIG_PCF50633_GPIO) += pcf50633-gpio.o obj-$(CONFIG_ABX500_CORE) += abx500-core.o -obj-$(CONFIG_AB8500_DEBUG) += ab8500-debugfs.o obj-$(CONFIG_MFD_DB8500_PRCMU) += db8500-prcmu.o # ab8500-core need to come after db8500-prcmu (which provides the channel) obj-$(CONFIG_AB8500_CORE) += ab8500-core.o ab8500-sysctrl.o diff --git a/drivers/mfd/ab8500-core.c b/drivers/mfd/ab8500-core.c index cca0aac26148..6a059270acdc 100644 --- a/drivers/mfd/ab8500-core.c +++ b/drivers/mfd/ab8500-core.c @@ -613,10 +613,6 @@ static const struct mfd_cell ab8500_bm_devs[] = { }; static const struct mfd_cell ab8500_devs[] = { -#ifdef CONFIG_DEBUG_FS - MFD_CELL_OF("ab8500-debug", - NULL, NULL, 0, 0, "stericsson,ab8500-debug"), -#endif MFD_CELL_OF("ab8500-sysctrl", NULL, NULL, 0, 0, "stericsson,ab8500-sysctrl"), MFD_CELL_OF("ab8500-ext-regulator", @@ -652,11 +648,6 @@ static const struct mfd_cell ab8500_devs[] = { }; static const struct mfd_cell ab9540_devs[] = { -#ifdef CONFIG_DEBUG_FS - { - .name = "ab8500-debug", - }, -#endif { .name = "ab8500-sysctrl", }, @@ -707,12 +698,6 @@ static const struct mfd_cell ab9540_devs[] = { /* Device list for ab8505 */ static const struct mfd_cell ab8505_devs[] = { -#ifdef CONFIG_DEBUG_FS - { - .name = "ab8500-debug", - .of_compatible = "stericsson,ab8500-debug", - }, -#endif { .name = "ab8500-sysctrl", .of_compatible = "stericsson,ab8500-sysctrl", @@ -764,11 +749,6 @@ static const struct mfd_cell ab8505_devs[] = { }; static const struct mfd_cell ab8540_devs[] = { -#ifdef CONFIG_DEBUG_FS - { - .name = "ab8500-debug", - }, -#endif { .name = "ab8500-sysctrl", }, diff --git a/drivers/mfd/ab8500-debugfs.c b/drivers/mfd/ab8500-debugfs.c deleted file mode 100644 index e43dea89b094..000000000000 --- a/drivers/mfd/ab8500-debugfs.c +++ /dev/null @@ -1,2096 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Copyright (C) ST-Ericsson SA 2010 - * - * Author: Mattias Wallin for ST-Ericsson. - */ -/* - * AB8500 register access - * ====================== - * - * read: - * # echo BANK > /ab8500/register-bank - * # echo ADDR > /ab8500/register-address - * # cat /ab8500/register-value - * - * write: - * # echo BANK > /ab8500/register-bank - * # echo ADDR > /ab8500/register-address - * # echo VALUE > /ab8500/register-value - * - * read all registers from a bank: - * # echo BANK > /ab8500/register-bank - * # cat /ab8500/all-bank-register - * - * BANK target AB8500 register bank - * ADDR target AB8500 register address - * VALUE decimal or 0x-prefixed hexadecimal - * - * - * User Space notification on AB8500 IRQ - * ===================================== - * - * Allows user space entity to be notified when target AB8500 IRQ occurs. - * When subscribed, a sysfs entry is created in ab8500.i2c platform device. - * One can pool this file to get target IRQ occurence information. - * - * subscribe to an AB8500 IRQ: - * # echo IRQ > /ab8500/irq-subscribe - * - * unsubscribe from an AB8500 IRQ: - * # echo IRQ > /ab8500/irq-unsubscribe - * - * - * AB8500 register formated read/write access - * ========================================== - * - * Read: read data, data>>SHIFT, data&=MASK, output data - * [0xABCDEF98] shift=12 mask=0xFFF => 0x00000CDE - * Write: read data, data &= ~(MASK< [0xAB123F98] - * - * Usage: - * # echo "CMD [OPTIONS] BANK ADRESS [VALUE]" > $debugfs/ab8500/hwreg - * - * CMD read read access - * write write access - * - * BANK target reg bank - * ADDRESS target reg address - * VALUE (write) value to be updated - * - * OPTIONS - * -d|-dec (read) output in decimal - * -h|-hexa (read) output in 0x-hexa (default) - * -l|-w|-b 32bit (default), 16bit or 8bit reg access - * -m|-mask MASK 0x-hexa mask (default 0xFFFFFFFF) - * -s|-shift SHIFT bit shift value (read:left, write:right) - * -o|-offset OFFSET address offset to add to ADDRESS value - * - * Warning: bit shift operation is applied to bit-mask. - * Warning: bit shift direction depends on read or right command. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#ifdef CONFIG_DEBUG_FS -#include -#include -#endif - -static u32 debug_bank; -static u32 debug_address; - -static int irq_ab8500; -static int irq_first; -static int irq_last; -static u32 *irq_count; -static int num_irqs; - -static struct device_attribute **dev_attr; -static char **event_name; - -/** - * struct ab8500_reg_range - * @first: the first address of the range - * @last: the last address of the range - * @perm: access permissions for the range - */ -struct ab8500_reg_range { - u8 first; - u8 last; - u8 perm; -}; - -/** - * struct ab8500_prcmu_ranges - * @num_ranges: the number of ranges in the list - * @bankid: bank identifier - * @range: the list of register ranges - */ -struct ab8500_prcmu_ranges { - u8 num_ranges; - u8 bankid; - const struct ab8500_reg_range *range; -}; - -/* hwreg- "mask" and "shift" entries ressources */ -struct hwreg_cfg { - u32 bank; /* target bank */ - unsigned long addr; /* target address */ - uint fmt; /* format */ - unsigned long mask; /* read/write mask, applied before any bit shift */ - long shift; /* bit shift (read:right shift, write:left shift */ -}; -/* fmt bit #0: 0=hexa, 1=dec */ -#define REG_FMT_DEC(c) ((c)->fmt & 0x1) -#define REG_FMT_HEX(c) (!REG_FMT_DEC(c)) - -static struct hwreg_cfg hwreg_cfg = { - .addr = 0, /* default: invalid phys addr */ - .fmt = 0, /* default: 32bit access, hex output */ - .mask = 0xFFFFFFFF, /* default: no mask */ - .shift = 0, /* default: no bit shift */ -}; - -#define AB8500_NAME_STRING "ab8500" -#define AB8500_NUM_BANKS AB8500_DEBUG_FIELD_LAST - -#define AB8500_REV_REG 0x80 - -static struct ab8500_prcmu_ranges *debug_ranges; - -static struct ab8500_prcmu_ranges ab8500_debug_ranges[AB8500_NUM_BANKS] = { - [AB8500_M_FSM_RANK] = { - .num_ranges = 0, - .range = NULL, - }, - [AB8500_SYS_CTRL1_BLOCK] = { - .num_ranges = 3, - .range = (struct ab8500_reg_range[]) { - { - .first = 0x00, - .last = 0x02, - }, - { - .first = 0x42, - .last = 0x42, - }, - { - .first = 0x80, - .last = 0x81, - }, - }, - }, - [AB8500_SYS_CTRL2_BLOCK] = { - .num_ranges = 4, - .range = (struct ab8500_reg_range[]) { - { - .first = 0x00, - .last = 0x0D, - }, - { - .first = 0x0F, - .last = 0x17, - }, - { - .first = 0x30, - .last = 0x30, - }, - { - .first = 0x32, - .last = 0x33, - }, - }, - }, - [AB8500_REGU_CTRL1] = { - .num_ranges = 3, - .range = (struct ab8500_reg_range[]) { - { - .first = 0x00, - .last = 0x00, - }, - { - .first = 0x03, - .last = 0x10, - }, - { - .first = 0x80, - .last = 0x84, - }, - }, - }, - [AB8500_REGU_CTRL2] = { - .num_ranges = 5, - .range = (struct ab8500_reg_range[]) { - { - .first = 0x00, - .last = 0x15, - }, - { - .first = 0x17, - .last = 0x19, - }, - { - .first = 0x1B, - .last = 0x1D, - }, - { - .first = 0x1F, - .last = 0x22, - }, - { - .first = 0x40, - .last = 0x44, - }, - /* - * 0x80-0x8B are SIM registers and should - * not be accessed from here - */ - }, - }, - [AB8500_USB] = { - .num_ranges = 2, - .range = (struct ab8500_reg_range[]) { - { - .first = 0x80, - .last = 0x83, - }, - { - .first = 0x87, - .last = 0x8A, - }, - }, - }, - [AB8500_TVOUT] = { - .num_ranges = 9, - .range = (struct ab8500_reg_range[]) { - { - .first = 0x00, - .last = 0x12, - }, - { - .first = 0x15, - .last = 0x17, - }, - { - .first = 0x19, - .last = 0x21, - }, - { - .first = 0x27, - .last = 0x2C, - }, - { - .first = 0x41, - .last = 0x41, - }, - { - .first = 0x45, - .last = 0x5B, - }, - { - .first = 0x5D, - .last = 0x5D, - }, - { - .first = 0x69, - .last = 0x69, - }, - { - .first = 0x80, - .last = 0x81, - }, - }, - }, - [AB8500_DBI] = { - .num_ranges = 0, - .range = NULL, - }, - [AB8500_ECI_AV_ACC] = { - .num_ranges = 1, - .range = (struct ab8500_reg_range[]) { - { - .first = 0x80, - .last = 0x82, - }, - }, - }, - [AB8500_RESERVED] = { - .num_ranges = 0, - .range = NULL, - }, - [AB8500_GPADC] = { - .num_ranges = 1, - .range = (struct ab8500_reg_range[]) { - { - .first = 0x00, - .last = 0x08, - }, - }, - }, - [AB8500_CHARGER] = { - .num_ranges = 9, - .range = (struct ab8500_reg_range[]) { - { - .first = 0x00, - .last = 0x03, - }, - { - .first = 0x05, - .last = 0x05, - }, - { - .first = 0x40, - .last = 0x40, - }, - { - .first = 0x42, - .last = 0x42, - }, - { - .first = 0x44, - .last = 0x44, - }, - { - .first = 0x50, - .last = 0x55, - }, - { - .first = 0x80, - .last = 0x82, - }, - { - .first = 0xC0, - .last = 0xC2, - }, - { - .first = 0xf5, - .last = 0xf6, - }, - }, - }, - [AB8500_GAS_GAUGE] = { - .num_ranges = 3, - .range = (struct ab8500_reg_range[]) { - { - .first = 0x00, - .last = 0x00, - }, - { - .first = 0x07, - .last = 0x0A, - }, - { - .first = 0x10, - .last = 0x14, - }, - }, - }, - [AB8500_AUDIO] = { - .num_ranges = 1, - .range = (struct ab8500_reg_range[]) { - { - .first = 0x00, - .last = 0x6F, - }, - }, - }, - [AB8500_INTERRUPT] = { - .num_ranges = 0, - .range = NULL, - }, - [AB8500_RTC] = { - .num_ranges = 1, - .range = (struct ab8500_reg_range[]) { - { - .first = 0x00, - .last = 0x0F, - }, - }, - }, - [AB8500_MISC] = { - .num_ranges = 8, - .range = (struct ab8500_reg_range[]) { - { - .first = 0x00, - .last = 0x05, - }, - { - .first = 0x10, - .last = 0x15, - }, - { - .first = 0x20, - .last = 0x25, - }, - { - .first = 0x30, - .last = 0x35, - }, - { - .first = 0x40, - .last = 0x45, - }, - { - .first = 0x50, - .last = 0x50, - }, - { - .first = 0x60, - .last = 0x67, - }, - { - .first = 0x80, - .last = 0x80, - }, - }, - }, - [AB8500_DEVELOPMENT] = { - .num_ranges = 1, - .range = (struct ab8500_reg_range[]) { - { - .first = 0x00, - .last = 0x00, - }, - }, - }, - [AB8500_DEBUG] = { - .num_ranges = 1, - .range = (struct ab8500_reg_range[]) { - { - .first = 0x05, - .last = 0x07, - }, - }, - }, - [AB8500_PROD_TEST] = { - .num_ranges = 0, - .range = NULL, - }, - [AB8500_STE_TEST] = { - .num_ranges = 0, - .range = NULL, - }, - [AB8500_OTP_EMUL] = { - .num_ranges = 1, - .range = (struct ab8500_reg_range[]) { - { - .first = 0x01, - .last = 0x0F, - }, - }, - }, -}; - -static struct ab8500_prcmu_ranges ab8505_debug_ranges[AB8500_NUM_BANKS] = { - [0x0] = { - .num_ranges = 0, - .range = NULL, - }, - [AB8500_SYS_CTRL1_BLOCK] = { - .num_ranges = 5, - .range = (struct ab8500_reg_range[]) { - { - .first = 0x00, - .last = 0x04, - }, - { - .first = 0x42, - .last = 0x42, - }, - { - .first = 0x52, - .last = 0x52, - }, - { - .first = 0x54, - .last = 0x57, - }, - { - .first = 0x80, - .last = 0x83, - }, - }, - }, - [AB8500_SYS_CTRL2_BLOCK] = { - .num_ranges = 5, - .range = (struct ab8500_reg_range[]) { - { - .first = 0x00, - .last = 0x0D, - }, - { - .first = 0x0F, - .last = 0x17, - }, - { - .first = 0x20, - .last = 0x20, - }, - { - .first = 0x30, - .last = 0x30, - }, - { - .first = 0x32, - .last = 0x3A, - }, - }, - }, - [AB8500_REGU_CTRL1] = { - .num_ranges = 3, - .range = (struct ab8500_reg_range[]) { - { - .first = 0x00, - .last = 0x00, - }, - { - .first = 0x03, - .last = 0x11, - }, - { - .first = 0x80, - .last = 0x86, - }, - }, - }, - [AB8500_REGU_CTRL2] = { - .num_ranges = 6, - .range = (struct ab8500_reg_range[]) { - { - .first = 0x00, - .last = 0x06, - }, - { - .first = 0x08, - .last = 0x15, - }, - { - .first = 0x17, - .last = 0x19, - }, - { - .first = 0x1B, - .last = 0x1D, - }, - { - .first = 0x1F, - .last = 0x30, - }, - { - .first = 0x40, - .last = 0x48, - }, - /* - * 0x80-0x8B are SIM registers and should - * not be accessed from here - */ - }, - }, - [AB8500_USB] = { - .num_ranges = 3, - .range = (struct ab8500_reg_range[]) { - { - .first = 0x80, - .last = 0x83, - }, - { - .first = 0x87, - .last = 0x8A, - }, - { - .first = 0x91, - .last = 0x94, - }, - }, - }, - [AB8500_TVOUT] = { - .num_ranges = 0, - .range = NULL, - }, - [AB8500_DBI] = { - .num_ranges = 0, - .range = NULL, - }, - [AB8500_ECI_AV_ACC] = { - .num_ranges = 1, - .range = (struct ab8500_reg_range[]) { - { - .first = 0x80, - .last = 0x82, - }, - }, - }, - [AB8500_RESERVED] = { - .num_ranges = 0, - .range = NULL, - }, - [AB8500_GPADC] = { - .num_ranges = 1, - .range = (struct ab8500_reg_range[]) { - { - .first = 0x00, - .last = 0x08, - }, - }, - }, - [AB8500_CHARGER] = { - .num_ranges = 9, - .range = (struct ab8500_reg_range[]) { - { - .first = 0x02, - .last = 0x03, - }, - { - .first = 0x05, - .last = 0x05, - }, - { - .first = 0x40, - .last = 0x44, - }, - { - .first = 0x50, - .last = 0x57, - }, - { - .first = 0x60, - .last = 0x60, - }, - { - .first = 0xA0, - .last = 0xA7, - }, - { - .first = 0xAF, - .last = 0xB2, - }, - { - .first = 0xC0, - .last = 0xC2, - }, - { - .first = 0xF5, - .last = 0xF5, - }, - }, - }, - [AB8500_GAS_GAUGE] = { - .num_ranges = 3, - .range = (struct ab8500_reg_range[]) { - { - .first = 0x00, - .last = 0x00, - }, - { - .first = 0x07, - .last = 0x0A, - }, - { - .first = 0x10, - .last = 0x14, - }, - }, - }, - [AB8500_AUDIO] = { - .num_ranges = 1, - .range = (struct ab8500_reg_range[]) { - { - .first = 0x00, - .last = 0x83, - }, - }, - }, - [AB8500_INTERRUPT] = { - .num_ranges = 11, - .range = (struct ab8500_reg_range[]) { - { - .first = 0x00, - .last = 0x04, - }, - { - .first = 0x06, - .last = 0x07, - }, - { - .first = 0x09, - .last = 0x09, - }, - { - .first = 0x0B, - .last = 0x0C, - }, - { - .first = 0x12, - .last = 0x15, - }, - { - .first = 0x18, - .last = 0x18, - }, - /* Latch registers should not be read here */ - { - .first = 0x40, - .last = 0x44, - }, - { - .first = 0x46, - .last = 0x49, - }, - { - .first = 0x4B, - .last = 0x4D, - }, - { - .first = 0x52, - .last = 0x55, - }, - { - .first = 0x58, - .last = 0x58, - }, - /* LatchHier registers should not be read here */ - }, - }, - [AB8500_RTC] = { - .num_ranges = 2, - .range = (struct ab8500_reg_range[]) { - { - .first = 0x00, - .last = 0x14, - }, - { - .first = 0x16, - .last = 0x17, - }, - }, - }, - [AB8500_MISC] = { - .num_ranges = 8, - .range = (struct ab8500_reg_range[]) { - { - .first = 0x00, - .last = 0x06, - }, - { - .first = 0x10, - .last = 0x16, - }, - { - .first = 0x20, - .last = 0x26, - }, - { - .first = 0x30, - .last = 0x36, - }, - { - .first = 0x40, - .last = 0x46, - }, - { - .first = 0x50, - .last = 0x50, - }, - { - .first = 0x60, - .last = 0x6B, - }, - { - .first = 0x80, - .last = 0x82, - }, - }, - }, - [AB8500_DEVELOPMENT] = { - .num_ranges = 2, - .range = (struct ab8500_reg_range[]) { - { - .first = 0x00, - .last = 0x00, - }, - { - .first = 0x05, - .last = 0x05, - }, - }, - }, - [AB8500_DEBUG] = { - .num_ranges = 1, - .range = (struct ab8500_reg_range[]) { - { - .first = 0x05, - .last = 0x07, - }, - }, - }, - [AB8500_PROD_TEST] = { - .num_ranges = 0, - .range = NULL, - }, - [AB8500_STE_TEST] = { - .num_ranges = 0, - .range = NULL, - }, - [AB8500_OTP_EMUL] = { - .num_ranges = 1, - .range = (struct ab8500_reg_range[]) { - { - .first = 0x01, - .last = 0x15, - }, - }, - }, -}; - -static struct ab8500_prcmu_ranges ab8540_debug_ranges[AB8500_NUM_BANKS] = { - [AB8500_M_FSM_RANK] = { - .num_ranges = 1, - .range = (struct ab8500_reg_range[]) { - { - .first = 0x00, - .last = 0x0B, - }, - }, - }, - [AB8500_SYS_CTRL1_BLOCK] = { - .num_ranges = 6, - .range = (struct ab8500_reg_range[]) { - { - .first = 0x00, - .last = 0x04, - }, - { - .first = 0x42, - .last = 0x42, - }, - { - .first = 0x50, - .last = 0x54, - }, - { - .first = 0x57, - .last = 0x57, - }, - { - .first = 0x80, - .last = 0x83, - }, - { - .first = 0x90, - .last = 0x90, - }, - }, - }, - [AB8500_SYS_CTRL2_BLOCK] = { - .num_ranges = 5, - .range = (struct ab8500_reg_range[]) { - { - .first = 0x00, - .last = 0x0D, - }, - { - .first = 0x0F, - .last = 0x10, - }, - { - .first = 0x20, - .last = 0x21, - }, - { - .first = 0x32, - .last = 0x3C, - }, - { - .first = 0x40, - .last = 0x42, - }, - }, - }, - [AB8500_REGU_CTRL1] = { - .num_ranges = 4, - .range = (struct ab8500_reg_range[]) { - { - .first = 0x03, - .last = 0x15, - }, - { - .first = 0x20, - .last = 0x20, - }, - { - .first = 0x80, - .last = 0x85, - }, - { - .first = 0x87, - .last = 0x88, - }, - }, - }, - [AB8500_REGU_CTRL2] = { - .num_ranges = 8, - .range = (struct ab8500_reg_range[]) { - { - .first = 0x00, - .last = 0x06, - }, - { - .first = 0x08, - .last = 0x15, - }, - { - .first = 0x17, - .last = 0x19, - }, - { - .first = 0x1B, - .last = 0x1D, - }, - { - .first = 0x1F, - .last = 0x2F, - }, - { - .first = 0x31, - .last = 0x3A, - }, - { - .first = 0x43, - .last = 0x44, - }, - { - .first = 0x48, - .last = 0x49, - }, - }, - }, - [AB8500_USB] = { - .num_ranges = 3, - .range = (struct ab8500_reg_range[]) { - { - .first = 0x80, - .last = 0x83, - }, - { - .first = 0x87, - .last = 0x8A, - }, - { - .first = 0x91, - .last = 0x94, - }, - }, - }, - [AB8500_TVOUT] = { - .num_ranges = 0, - .range = NULL - }, - [AB8500_DBI] = { - .num_ranges = 4, - .range = (struct ab8500_reg_range[]) { - { - .first = 0x00, - .last = 0x07, - }, - { - .first = 0x10, - .last = 0x11, - }, - { - .first = 0x20, - .last = 0x21, - }, - { - .first = 0x30, - .last = 0x43, - }, - }, - }, - [AB8500_ECI_AV_ACC] = { - .num_ranges = 2, - .range = (struct ab8500_reg_range[]) { - { - .first = 0x00, - .last = 0x03, - }, - { - .first = 0x80, - .last = 0x82, - }, - }, - }, - [AB8500_RESERVED] = { - .num_ranges = 0, - .range = NULL, - }, - [AB8500_GPADC] = { - .num_ranges = 4, - .range = (struct ab8500_reg_range[]) { - { - .first = 0x00, - .last = 0x01, - }, - { - .first = 0x04, - .last = 0x06, - }, - { - .first = 0x09, - .last = 0x0A, - }, - { - .first = 0x10, - .last = 0x14, - }, - }, - }, - [AB8500_CHARGER] = { - .num_ranges = 10, - .range = (struct ab8500_reg_range[]) { - { - .first = 0x00, - .last = 0x00, - }, - { - .first = 0x02, - .last = 0x05, - }, - { - .first = 0x40, - .last = 0x44, - }, - { - .first = 0x50, - .last = 0x57, - }, - { - .first = 0x60, - .last = 0x60, - }, - { - .first = 0x70, - .last = 0x70, - }, - { - .first = 0xA0, - .last = 0xA9, - }, - { - .first = 0xAF, - .last = 0xB2, - }, - { - .first = 0xC0, - .last = 0xC6, - }, - { - .first = 0xF5, - .last = 0xF5, - }, - }, - }, - [AB8500_GAS_GAUGE] = { - .num_ranges = 3, - .range = (struct ab8500_reg_range[]) { - { - .first = 0x00, - .last = 0x00, - }, - { - .first = 0x07, - .last = 0x0A, - }, - { - .first = 0x10, - .last = 0x14, - }, - }, - }, - [AB8500_AUDIO] = { - .num_ranges = 1, - .range = (struct ab8500_reg_range[]) { - { - .first = 0x00, - .last = 0x9f, - }, - }, - }, - [AB8500_INTERRUPT] = { - .num_ranges = 6, - .range = (struct ab8500_reg_range[]) { - { - .first = 0x00, - .last = 0x05, - }, - { - .first = 0x0B, - .last = 0x0D, - }, - { - .first = 0x12, - .last = 0x20, - }, - /* Latch registers should not be read here */ - { - .first = 0x40, - .last = 0x45, - }, - { - .first = 0x4B, - .last = 0x4D, - }, - { - .first = 0x52, - .last = 0x60, - }, - /* LatchHier registers should not be read here */ - }, - }, - [AB8500_RTC] = { - .num_ranges = 3, - .range = (struct ab8500_reg_range[]) { - { - .first = 0x00, - .last = 0x07, - }, - { - .first = 0x0B, - .last = 0x18, - }, - { - .first = 0x20, - .last = 0x25, - }, - }, - }, - [AB8500_MISC] = { - .num_ranges = 9, - .range = (struct ab8500_reg_range[]) { - { - .first = 0x00, - .last = 0x06, - }, - { - .first = 0x10, - .last = 0x16, - }, - { - .first = 0x20, - .last = 0x26, - }, - { - .first = 0x30, - .last = 0x36, - }, - { - .first = 0x40, - .last = 0x49, - }, - { - .first = 0x50, - .last = 0x50, - }, - { - .first = 0x60, - .last = 0x6B, - }, - { - .first = 0x70, - .last = 0x74, - }, - { - .first = 0x80, - .last = 0x82, - }, - }, - }, - [AB8500_DEVELOPMENT] = { - .num_ranges = 3, - .range = (struct ab8500_reg_range[]) { - { - .first = 0x00, - .last = 0x01, - }, - { - .first = 0x06, - .last = 0x06, - }, - { - .first = 0x10, - .last = 0x21, - }, - }, - }, - [AB8500_DEBUG] = { - .num_ranges = 3, - .range = (struct ab8500_reg_range[]) { - { - .first = 0x01, - .last = 0x0C, - }, - { - .first = 0x0E, - .last = 0x11, - }, - { - .first = 0x80, - .last = 0x81, - }, - }, - }, - [AB8500_PROD_TEST] = { - .num_ranges = 0, - .range = NULL, - }, - [AB8500_STE_TEST] = { - .num_ranges = 0, - .range = NULL, - }, - [AB8500_OTP_EMUL] = { - .num_ranges = 1, - .range = (struct ab8500_reg_range[]) { - { - .first = 0x00, - .last = 0x3F, - }, - }, - }, -}; - -static irqreturn_t ab8500_debug_handler(int irq, void *data) -{ - char buf[16]; - struct kobject *kobj = (struct kobject *)data; - unsigned int irq_abb = irq - irq_first; - - if (irq_abb < num_irqs) - irq_count[irq_abb]++; - /* - * This makes it possible to use poll for events (EPOLLPRI | EPOLLERR) - * from userspace on sysfs file named - */ - sprintf(buf, "%d", irq); - sysfs_notify(kobj, NULL, buf); - - return IRQ_HANDLED; -} - -/* Prints to seq_file or log_buf */ -static int ab8500_registers_print(struct device *dev, u32 bank, - struct seq_file *s) -{ - unsigned int i; - - for (i = 0; i < debug_ranges[bank].num_ranges; i++) { - u32 reg; - - for (reg = debug_ranges[bank].range[i].first; - reg <= debug_ranges[bank].range[i].last; - reg++) { - u8 value; - int err; - - err = abx500_get_register_interruptible(dev, - (u8)bank, (u8)reg, &value); - if (err < 0) { - dev_err(dev, "ab->read fail %d\n", err); - return err; - } - - if (s) { - seq_printf(s, " [0x%02X/0x%02X]: 0x%02X\n", - bank, reg, value); - /* - * Error is not returned here since - * the output is wanted in any case - */ - if (seq_has_overflowed(s)) - return 0; - } else { - dev_info(dev, " [0x%02X/0x%02X]: 0x%02X\n", - bank, reg, value); - } - } - } - - return 0; -} - -static int ab8500_bank_registers_show(struct seq_file *s, void *p) -{ - struct device *dev = s->private; - u32 bank = debug_bank; - - seq_puts(s, AB8500_NAME_STRING " register values:\n"); - - seq_printf(s, " bank 0x%02X:\n", bank); - - return ab8500_registers_print(dev, bank, s); -} - -DEFINE_SHOW_ATTRIBUTE(ab8500_bank_registers); - -static int ab8500_print_all_banks(struct seq_file *s, void *p) -{ - struct device *dev = s->private; - unsigned int i; - - seq_puts(s, AB8500_NAME_STRING " register values:\n"); - - for (i = 0; i < AB8500_NUM_BANKS; i++) { - int err; - - seq_printf(s, " bank 0x%02X:\n", i); - err = ab8500_registers_print(dev, i, s); - if (err) - return err; - } - return 0; -} - -/* Dump registers to kernel log */ -void ab8500_dump_all_banks(struct device *dev) -{ - unsigned int i; - - dev_info(dev, "ab8500 register values:\n"); - - for (i = 1; i < AB8500_NUM_BANKS; i++) { - dev_info(dev, " bank 0x%02X:\n", i); - ab8500_registers_print(dev, i, NULL); - } -} - -static int ab8500_all_banks_open(struct inode *inode, struct file *file) -{ - struct seq_file *s; - int err; - - err = single_open(file, ab8500_print_all_banks, inode->i_private); - if (!err) { - /* Default buf size in seq_read is not enough */ - s = (struct seq_file *)file->private_data; - s->size = (PAGE_SIZE * 2); - s->buf = kmalloc(s->size, GFP_KERNEL); - if (!s->buf) { - single_release(inode, file); - err = -ENOMEM; - } - } - return err; -} - -static const struct file_operations ab8500_all_banks_fops = { - .open = ab8500_all_banks_open, - .read = seq_read, - .llseek = seq_lseek, - .release = single_release, - .owner = THIS_MODULE, -}; - -static int ab8500_bank_print(struct seq_file *s, void *p) -{ - seq_printf(s, "0x%02X\n", debug_bank); - return 0; -} - -static int ab8500_bank_open(struct inode *inode, struct file *file) -{ - return single_open(file, ab8500_bank_print, inode->i_private); -} - -static ssize_t ab8500_bank_write(struct file *file, - const char __user *user_buf, - size_t count, loff_t *ppos) -{ - struct device *dev = ((struct seq_file *)(file->private_data))->private; - unsigned long user_bank; - int err; - - err = kstrtoul_from_user(user_buf, count, 0, &user_bank); - if (err) - return err; - - if (user_bank >= AB8500_NUM_BANKS) { - dev_err(dev, "debugfs error input > number of banks\n"); - return -EINVAL; - } - - debug_bank = user_bank; - - return count; -} - -static int ab8500_address_print(struct seq_file *s, void *p) -{ - seq_printf(s, "0x%02X\n", debug_address); - return 0; -} - -static int ab8500_address_open(struct inode *inode, struct file *file) -{ - return single_open(file, ab8500_address_print, inode->i_private); -} - -static ssize_t ab8500_address_write(struct file *file, - const char __user *user_buf, - size_t count, loff_t *ppos) -{ - struct device *dev = ((struct seq_file *)(file->private_data))->private; - unsigned long user_address; - int err; - - err = kstrtoul_from_user(user_buf, count, 0, &user_address); - if (err) - return err; - - if (user_address > 0xff) { - dev_err(dev, "debugfs error input > 0xff\n"); - return -EINVAL; - } - debug_address = user_address; - - return count; -} - -static int ab8500_val_print(struct seq_file *s, void *p) -{ - struct device *dev = s->private; - int ret; - u8 regvalue; - - ret = abx500_get_register_interruptible(dev, - (u8)debug_bank, (u8)debug_address, ®value); - if (ret < 0) { - dev_err(dev, "abx500_get_reg fail %d, %d\n", - ret, __LINE__); - return -EINVAL; - } - seq_printf(s, "0x%02X\n", regvalue); - - return 0; -} - -static int ab8500_val_open(struct inode *inode, struct file *file) -{ - return single_open(file, ab8500_val_print, inode->i_private); -} - -static ssize_t ab8500_val_write(struct file *file, - const char __user *user_buf, - size_t count, loff_t *ppos) -{ - struct device *dev = ((struct seq_file *)(file->private_data))->private; - unsigned long user_val; - int err; - - err = kstrtoul_from_user(user_buf, count, 0, &user_val); - if (err) - return err; - - if (user_val > 0xff) { - dev_err(dev, "debugfs error input > 0xff\n"); - return -EINVAL; - } - err = abx500_set_register_interruptible(dev, - (u8)debug_bank, debug_address, (u8)user_val); - if (err < 0) { - pr_err("abx500_set_reg failed %d, %d", err, __LINE__); - return -EINVAL; - } - - return count; -} - -/* - * Interrupt status - */ -static u32 num_interrupts[AB8500_MAX_NR_IRQS]; -static u32 num_wake_interrupts[AB8500_MAX_NR_IRQS]; -static int num_interrupt_lines; - -void ab8500_debug_register_interrupt(int line) -{ - if (line < num_interrupt_lines) - num_interrupts[line]++; -} - -static int ab8500_interrupts_show(struct seq_file *s, void *p) -{ - int line; - - seq_puts(s, "name: number: irq: number of: wake:\n"); - - for (line = 0; line < num_interrupt_lines; line++) { - seq_printf(s, "%3i: %4i %6i %4i\n", - line, - line + irq_first, - num_interrupts[line], - num_wake_interrupts[line]); - } - - return 0; -} - -DEFINE_SHOW_ATTRIBUTE(ab8500_interrupts); - -/* - * - HWREG DB8500 formated routines - */ -static int ab8500_hwreg_print(struct seq_file *s, void *d) -{ - struct device *dev = s->private; - int ret; - u8 regvalue; - - ret = abx500_get_register_interruptible(dev, - (u8)hwreg_cfg.bank, (u8)hwreg_cfg.addr, ®value); - if (ret < 0) { - dev_err(dev, "abx500_get_reg fail %d, %d\n", - ret, __LINE__); - return -EINVAL; - } - - if (hwreg_cfg.shift >= 0) - regvalue >>= hwreg_cfg.shift; - else - regvalue <<= -hwreg_cfg.shift; - regvalue &= hwreg_cfg.mask; - - if (REG_FMT_DEC(&hwreg_cfg)) - seq_printf(s, "%d\n", regvalue); - else - seq_printf(s, "0x%02X\n", regvalue); - return 0; -} - -static int ab8500_hwreg_open(struct inode *inode, struct file *file) -{ - return single_open(file, ab8500_hwreg_print, inode->i_private); -} - -#define AB8500_SUPPLY_CONTROL_CONFIG_1 0x01 -#define AB8500_SUPPLY_CONTROL_REG 0x00 -#define AB8500_FIRST_SIM_REG 0x80 -#define AB8500_LAST_SIM_REG 0x8B -#define AB8505_LAST_SIM_REG 0x8C - -static int ab8500_modem_show(struct seq_file *s, void *p) -{ - struct device *dev = s->private; - struct ab8500 *ab8500; - int err; - u8 value; - u8 orig_value; - u32 bank = AB8500_REGU_CTRL2; - u32 last_sim_reg = AB8500_LAST_SIM_REG; - u32 reg; - - ab8500 = dev_get_drvdata(dev->parent); - dev_warn(dev, "WARNING! This operation can interfer with modem side\n" - "and should only be done with care\n"); - - err = abx500_get_register_interruptible(dev, - AB8500_REGU_CTRL1, AB8500_SUPPLY_CONTROL_REG, &orig_value); - if (err < 0) - goto report_read_failure; - - /* Config 1 will allow APE side to read SIM registers */ - err = abx500_set_register_interruptible(dev, - AB8500_REGU_CTRL1, AB8500_SUPPLY_CONTROL_REG, - AB8500_SUPPLY_CONTROL_CONFIG_1); - if (err < 0) - goto report_write_failure; - - seq_printf(s, " bank 0x%02X:\n", bank); - - if (is_ab9540(ab8500) || is_ab8505(ab8500)) - last_sim_reg = AB8505_LAST_SIM_REG; - - for (reg = AB8500_FIRST_SIM_REG; reg <= last_sim_reg; reg++) { - err = abx500_get_register_interruptible(dev, - bank, reg, &value); - if (err < 0) - goto report_read_failure; - - seq_printf(s, " [0x%02X/0x%02X]: 0x%02X\n", bank, reg, value); - } - err = abx500_set_register_interruptible(dev, - AB8500_REGU_CTRL1, AB8500_SUPPLY_CONTROL_REG, orig_value); - if (err < 0) - goto report_write_failure; - - return 0; - -report_read_failure: - dev_err(dev, "ab->read fail %d\n", err); - return err; - -report_write_failure: - dev_err(dev, "ab->write fail %d\n", err); - return err; -} - -DEFINE_SHOW_ATTRIBUTE(ab8500_modem); - -/* - * return length of an ASCII numerical value, 0 is string is not a - * numerical value. - * string shall start at value 1st char. - * string can be tailed with \0 or space or newline chars only. - * value can be decimal or hexadecimal (prefixed 0x or 0X). - */ -static int strval_len(char *b) -{ - char *s = b; - - if ((*s == '0') && ((*(s+1) == 'x') || (*(s+1) == 'X'))) { - s += 2; - for (; *s && (*s != ' ') && (*s != '\n'); s++) { - if (!isxdigit(*s)) - return 0; - } - } else { - if (*s == '-') - s++; - for (; *s && (*s != ' ') && (*s != '\n'); s++) { - if (!isdigit(*s)) - return 0; - } - } - return (int) (s-b); -} - -/* - * parse hwreg input data. - * update global hwreg_cfg only if input data syntax is ok. - */ -static ssize_t hwreg_common_write(char *b, struct hwreg_cfg *cfg, - struct device *dev) -{ - uint write, val = 0; - u8 regvalue; - int ret; - struct hwreg_cfg loc = { - .bank = 0, /* default: invalid phys addr */ - .addr = 0, /* default: invalid phys addr */ - .fmt = 0, /* default: 32bit access, hex output */ - .mask = 0xFFFFFFFF, /* default: no mask */ - .shift = 0, /* default: no bit shift */ - }; - - /* read or write ? */ - if (!strncmp(b, "read ", 5)) { - write = 0; - b += 5; - } else if (!strncmp(b, "write ", 6)) { - write = 1; - b += 6; - } else - return -EINVAL; - - /* OPTIONS -l|-w|-b -s -m -o */ - while ((*b == ' ') || (*b == '-')) { - if (*(b-1) != ' ') { - b++; - continue; - } - if ((!strncmp(b, "-d ", 3)) || - (!strncmp(b, "-dec ", 5))) { - b += (*(b+2) == ' ') ? 3 : 5; - loc.fmt |= (1<<0); - } else if ((!strncmp(b, "-h ", 3)) || - (!strncmp(b, "-hex ", 5))) { - b += (*(b+2) == ' ') ? 3 : 5; - loc.fmt &= ~(1<<0); - } else if ((!strncmp(b, "-m ", 3)) || - (!strncmp(b, "-mask ", 6))) { - b += (*(b+2) == ' ') ? 3 : 6; - if (strval_len(b) == 0) - return -EINVAL; - ret = kstrtoul(b, 0, &loc.mask); - if (ret) - return ret; - } else if ((!strncmp(b, "-s ", 3)) || - (!strncmp(b, "-shift ", 7))) { - b += (*(b+2) == ' ') ? 3 : 7; - if (strval_len(b) == 0) - return -EINVAL; - ret = kstrtol(b, 0, &loc.shift); - if (ret) - return ret; - } else { - return -EINVAL; - } - } - /* get arg BANK and ADDRESS */ - if (strval_len(b) == 0) - return -EINVAL; - ret = kstrtouint(b, 0, &loc.bank); - if (ret) - return ret; - while (*b == ' ') - b++; - if (strval_len(b) == 0) - return -EINVAL; - ret = kstrtoul(b, 0, &loc.addr); - if (ret) - return ret; - - if (write) { - while (*b == ' ') - b++; - if (strval_len(b) == 0) - return -EINVAL; - ret = kstrtouint(b, 0, &val); - if (ret) - return ret; - } - - /* args are ok, update target cfg (mainly for read) */ - *cfg = loc; - -#ifdef ABB_HWREG_DEBUG - pr_warn("HWREG request: %s, %s,\n", (write) ? "write" : "read", - REG_FMT_DEC(cfg) ? "decimal" : "hexa"); - pr_warn(" addr=0x%08X, mask=0x%X, shift=%d" "value=0x%X\n", - cfg->addr, cfg->mask, cfg->shift, val); -#endif - - if (!write) - return 0; - - ret = abx500_get_register_interruptible(dev, - (u8)cfg->bank, (u8)cfg->addr, ®value); - if (ret < 0) { - dev_err(dev, "abx500_get_reg fail %d, %d\n", - ret, __LINE__); - return -EINVAL; - } - - if (cfg->shift >= 0) { - regvalue &= ~(cfg->mask << (cfg->shift)); - val = (val & cfg->mask) << (cfg->shift); - } else { - regvalue &= ~(cfg->mask >> (-cfg->shift)); - val = (val & cfg->mask) >> (-cfg->shift); - } - val = val | regvalue; - - ret = abx500_set_register_interruptible(dev, - (u8)cfg->bank, (u8)cfg->addr, (u8)val); - if (ret < 0) { - pr_err("abx500_set_reg failed %d, %d", ret, __LINE__); - return -EINVAL; - } - - return 0; -} - -static ssize_t ab8500_hwreg_write(struct file *file, - const char __user *user_buf, size_t count, loff_t *ppos) -{ - struct device *dev = ((struct seq_file *)(file->private_data))->private; - char buf[128]; - int buf_size, ret; - - /* Get userspace string and assure termination */ - buf_size = min((int)count, (int)(sizeof(buf)-1)); - if (copy_from_user(buf, user_buf, buf_size)) - return -EFAULT; - buf[buf_size] = 0; - - /* get args and process */ - ret = hwreg_common_write(buf, &hwreg_cfg, dev); - return (ret) ? ret : buf_size; -} - -/* - * - irq subscribe/unsubscribe stuff - */ -static int ab8500_subscribe_unsubscribe_print(struct seq_file *s, void *p) -{ - seq_printf(s, "%d\n", irq_first); - - return 0; -} - -static int ab8500_subscribe_unsubscribe_open(struct inode *inode, - struct file *file) -{ - return single_open(file, ab8500_subscribe_unsubscribe_print, - inode->i_private); -} - -/* - * Userspace should use poll() on this file. When an event occur - * the blocking poll will be released. - */ -static ssize_t show_irq(struct device *dev, - struct device_attribute *attr, char *buf) -{ - unsigned long name; - unsigned int irq_index; - int err; - - err = kstrtoul(attr->attr.name, 0, &name); - if (err) - return err; - - irq_index = name - irq_first; - if (irq_index >= num_irqs) - return -EINVAL; - - return sprintf(buf, "%u\n", irq_count[irq_index]); -} - -static ssize_t ab8500_subscribe_write(struct file *file, - const char __user *user_buf, - size_t count, loff_t *ppos) -{ - struct device *dev = ((struct seq_file *)(file->private_data))->private; - unsigned long user_val; - int err; - unsigned int irq_index; - - err = kstrtoul_from_user(user_buf, count, 0, &user_val); - if (err) - return err; - - if (user_val < irq_first) { - dev_err(dev, "debugfs error input < %d\n", irq_first); - return -EINVAL; - } - if (user_val > irq_last) { - dev_err(dev, "debugfs error input > %d\n", irq_last); - return -EINVAL; - } - - irq_index = user_val - irq_first; - if (irq_index >= num_irqs) - return -EINVAL; - - /* - * This will create a sysfs file named which userspace can - * use to select or poll and get the AB8500 events - */ - dev_attr[irq_index] = kmalloc(sizeof(struct device_attribute), - GFP_KERNEL); - if (!dev_attr[irq_index]) - return -ENOMEM; - - event_name[irq_index] = kasprintf(GFP_KERNEL, "%lu", user_val); - if (!event_name[irq_index]) - return -ENOMEM; - - dev_attr[irq_index]->show = show_irq; - dev_attr[irq_index]->store = NULL; - dev_attr[irq_index]->attr.name = event_name[irq_index]; - dev_attr[irq_index]->attr.mode = S_IRUGO; - err = sysfs_create_file(&dev->kobj, &dev_attr[irq_index]->attr); - if (err < 0) { - pr_info("sysfs_create_file failed %d\n", err); - return err; - } - - err = request_threaded_irq(user_val, NULL, ab8500_debug_handler, - IRQF_SHARED | IRQF_NO_SUSPEND | IRQF_ONESHOT, - "ab8500-debug", &dev->kobj); - if (err < 0) { - pr_info("request_threaded_irq failed %d, %lu\n", - err, user_val); - sysfs_remove_file(&dev->kobj, &dev_attr[irq_index]->attr); - return err; - } - - return count; -} - -static ssize_t ab8500_unsubscribe_write(struct file *file, - const char __user *user_buf, - size_t count, loff_t *ppos) -{ - struct device *dev = ((struct seq_file *)(file->private_data))->private; - unsigned long user_val; - int err; - unsigned int irq_index; - - err = kstrtoul_from_user(user_buf, count, 0, &user_val); - if (err) - return err; - - if (user_val < irq_first) { - dev_err(dev, "debugfs error input < %d\n", irq_first); - return -EINVAL; - } - if (user_val > irq_last) { - dev_err(dev, "debugfs error input > %d\n", irq_last); - return -EINVAL; - } - - irq_index = user_val - irq_first; - if (irq_index >= num_irqs) - return -EINVAL; - - /* Set irq count to 0 when unsubscribe */ - irq_count[irq_index] = 0; - - if (dev_attr[irq_index]) - sysfs_remove_file(&dev->kobj, &dev_attr[irq_index]->attr); - - - free_irq(user_val, &dev->kobj); - kfree(event_name[irq_index]); - kfree(dev_attr[irq_index]); - - return count; -} - -/* - * - several debugfs nodes fops - */ - -static const struct file_operations ab8500_bank_fops = { - .open = ab8500_bank_open, - .write = ab8500_bank_write, - .read = seq_read, - .llseek = seq_lseek, - .release = single_release, - .owner = THIS_MODULE, -}; - -static const struct file_operations ab8500_address_fops = { - .open = ab8500_address_open, - .write = ab8500_address_write, - .read = seq_read, - .llseek = seq_lseek, - .release = single_release, - .owner = THIS_MODULE, -}; - -static const struct file_operations ab8500_val_fops = { - .open = ab8500_val_open, - .write = ab8500_val_write, - .read = seq_read, - .llseek = seq_lseek, - .release = single_release, - .owner = THIS_MODULE, -}; - -static const struct file_operations ab8500_subscribe_fops = { - .open = ab8500_subscribe_unsubscribe_open, - .write = ab8500_subscribe_write, - .read = seq_read, - .llseek = seq_lseek, - .release = single_release, - .owner = THIS_MODULE, -}; - -static const struct file_operations ab8500_unsubscribe_fops = { - .open = ab8500_subscribe_unsubscribe_open, - .write = ab8500_unsubscribe_write, - .read = seq_read, - .llseek = seq_lseek, - .release = single_release, - .owner = THIS_MODULE, -}; - -static const struct file_operations ab8500_hwreg_fops = { - .open = ab8500_hwreg_open, - .write = ab8500_hwreg_write, - .read = seq_read, - .llseek = seq_lseek, - .release = single_release, - .owner = THIS_MODULE, -}; - -static int ab8500_debug_probe(struct platform_device *plf) -{ - struct dentry *ab8500_dir; - struct ab8500 *ab8500; - struct resource *res; - - debug_bank = AB8500_MISC; - debug_address = AB8500_REV_REG & 0x00FF; - - ab8500 = dev_get_drvdata(plf->dev.parent); - num_irqs = ab8500->mask_size; - - irq_count = devm_kcalloc(&plf->dev, - num_irqs, sizeof(*irq_count), GFP_KERNEL); - if (!irq_count) - return -ENOMEM; - - dev_attr = devm_kcalloc(&plf->dev, - num_irqs, sizeof(*dev_attr), GFP_KERNEL); - if (!dev_attr) - return -ENOMEM; - - event_name = devm_kcalloc(&plf->dev, - num_irqs, sizeof(*event_name), GFP_KERNEL); - if (!event_name) - return -ENOMEM; - - res = platform_get_resource_byname(plf, 0, "IRQ_AB8500"); - if (!res) { - dev_err(&plf->dev, "AB8500 irq not found, err %d\n", irq_first); - return -ENXIO; - } - irq_ab8500 = res->start; - - irq_first = platform_get_irq_byname(plf, "IRQ_FIRST"); - if (irq_first < 0) - return irq_first; - - irq_last = platform_get_irq_byname(plf, "IRQ_LAST"); - if (irq_last < 0) - return irq_last; - - ab8500_dir = debugfs_create_dir(AB8500_NAME_STRING, NULL); - - debugfs_create_file("all-bank-registers", S_IRUGO, ab8500_dir, - &plf->dev, &ab8500_bank_registers_fops); - debugfs_create_file("all-banks", S_IRUGO, ab8500_dir, - &plf->dev, &ab8500_all_banks_fops); - debugfs_create_file("register-bank", (S_IRUGO | S_IWUSR | S_IWGRP), - ab8500_dir, &plf->dev, &ab8500_bank_fops); - debugfs_create_file("register-address", (S_IRUGO | S_IWUSR | S_IWGRP), - ab8500_dir, &plf->dev, &ab8500_address_fops); - debugfs_create_file("register-value", (S_IRUGO | S_IWUSR | S_IWGRP), - ab8500_dir, &plf->dev, &ab8500_val_fops); - debugfs_create_file("irq-subscribe", (S_IRUGO | S_IWUSR | S_IWGRP), - ab8500_dir, &plf->dev, &ab8500_subscribe_fops); - - if (is_ab8500(ab8500)) { - debug_ranges = ab8500_debug_ranges; - num_interrupt_lines = AB8500_NR_IRQS; - } else if (is_ab8505(ab8500)) { - debug_ranges = ab8505_debug_ranges; - num_interrupt_lines = AB8505_NR_IRQS; - } else if (is_ab9540(ab8500)) { - debug_ranges = ab8505_debug_ranges; - num_interrupt_lines = AB9540_NR_IRQS; - } else if (is_ab8540(ab8500)) { - debug_ranges = ab8540_debug_ranges; - num_interrupt_lines = AB8540_NR_IRQS; - } - - debugfs_create_file("interrupts", (S_IRUGO), ab8500_dir, &plf->dev, - &ab8500_interrupts_fops); - debugfs_create_file("irq-unsubscribe", (S_IRUGO | S_IWUSR | S_IWGRP), - ab8500_dir, &plf->dev, &ab8500_unsubscribe_fops); - debugfs_create_file("hwreg", (S_IRUGO | S_IWUSR | S_IWGRP), ab8500_dir, - &plf->dev, &ab8500_hwreg_fops); - debugfs_create_file("all-modem-registers", (S_IRUGO | S_IWUSR | S_IWGRP), - ab8500_dir, &plf->dev, &ab8500_modem_fops); - - return 0; -} - -static struct platform_driver ab8500_debug_driver = { - .driver = { - .name = "ab8500-debug", - .suppress_bind_attrs = true, - }, - .probe = ab8500_debug_probe, -}; - -static int __init ab8500_debug_init(void) -{ - return platform_driver_register(&ab8500_debug_driver); -} -subsys_initcall(ab8500_debug_init); From 8c70bd5802f4f51979f3b8a887088837edd56341 Mon Sep 17 00:00:00 2001 From: Jarkko Nikula Date: Fri, 11 Feb 2022 16:50:55 +0200 Subject: [PATCH 282/370] mfd: intel-lpss: Add Intel Raptor Lake PCH-S PCI IDs Add Intel Raptor Lake PCH-S LPSS PCI IDs. Signed-off-by: Jarkko Nikula Reviewed-by: Andy Shevchenko Signed-off-by: Lee Jones Link: https://lore.kernel.org/r/20220211145055.992179-1-jarkko.nikula@linux.intel.com --- drivers/mfd/intel-lpss-pci.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/drivers/mfd/intel-lpss-pci.c b/drivers/mfd/intel-lpss-pci.c index 5513fae6be92..962ee14c62dd 100644 --- a/drivers/mfd/intel-lpss-pci.c +++ b/drivers/mfd/intel-lpss-pci.c @@ -353,6 +353,21 @@ static const struct pci_device_id intel_lpss_pci_ids[] = { { PCI_VDEVICE(INTEL, 0x5ac4), (kernel_ulong_t)&bxt_info }, { PCI_VDEVICE(INTEL, 0x5ac6), (kernel_ulong_t)&bxt_info }, { PCI_VDEVICE(INTEL, 0x5aee), (kernel_ulong_t)&bxt_uart_info }, + /* RPL-S */ + { PCI_VDEVICE(INTEL, 0x7a28), (kernel_ulong_t)&bxt_uart_info }, + { PCI_VDEVICE(INTEL, 0x7a29), (kernel_ulong_t)&bxt_uart_info }, + { PCI_VDEVICE(INTEL, 0x7a2a), (kernel_ulong_t)&bxt_info }, + { PCI_VDEVICE(INTEL, 0x7a2b), (kernel_ulong_t)&bxt_info }, + { PCI_VDEVICE(INTEL, 0x7a4c), (kernel_ulong_t)&bxt_i2c_info }, + { PCI_VDEVICE(INTEL, 0x7a4d), (kernel_ulong_t)&bxt_i2c_info }, + { PCI_VDEVICE(INTEL, 0x7a4e), (kernel_ulong_t)&bxt_i2c_info }, + { PCI_VDEVICE(INTEL, 0x7a4f), (kernel_ulong_t)&bxt_i2c_info }, + { PCI_VDEVICE(INTEL, 0x7a5c), (kernel_ulong_t)&bxt_uart_info }, + { PCI_VDEVICE(INTEL, 0x7a79), (kernel_ulong_t)&bxt_info }, + { PCI_VDEVICE(INTEL, 0x7a7b), (kernel_ulong_t)&bxt_info }, + { PCI_VDEVICE(INTEL, 0x7a7c), (kernel_ulong_t)&bxt_i2c_info }, + { PCI_VDEVICE(INTEL, 0x7a7d), (kernel_ulong_t)&bxt_i2c_info }, + { PCI_VDEVICE(INTEL, 0x7a7e), (kernel_ulong_t)&bxt_uart_info }, /* ADL-S */ { PCI_VDEVICE(INTEL, 0x7aa8), (kernel_ulong_t)&bxt_uart_info }, { PCI_VDEVICE(INTEL, 0x7aa9), (kernel_ulong_t)&bxt_uart_info }, From 8d73aa0e6b75761f1cd32d58aa115bf5382c567e Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Wed, 2 Feb 2022 16:13:09 +0100 Subject: [PATCH 283/370] mfd: exynos-lpass: Drop unneeded syscon.h include syscon regmap is not used since commit addebf1588ab ("mfd: exynos-lpass: Remove pad retention control"). Fixes: addebf1588ab ("mfd: exynos-lpass: Remove pad retention control") Signed-off-by: Krzysztof Kozlowski Reviewed-by: Alim Akhtar Signed-off-by: Lee Jones Link: https://lore.kernel.org/r/20220202151310.285561-3-krzysztof.kozlowski@canonical.com --- drivers/mfd/exynos-lpass.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/mfd/exynos-lpass.c b/drivers/mfd/exynos-lpass.c index 99bd0e73c19c..166cd21088cd 100644 --- a/drivers/mfd/exynos-lpass.c +++ b/drivers/mfd/exynos-lpass.c @@ -15,7 +15,6 @@ #include #include #include -#include #include #include #include From dab18d3be1bf8da00bad9a567cf5b91eb16bcb2c Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Wed, 2 Feb 2022 16:13:10 +0100 Subject: [PATCH 284/370] dt-bindings: mfd: samsung,exynos5433-lpass: Convert to dtschema Convert the Exynos5433 LPASS bindings to DT schema format. Signed-off-by: Krzysztof Kozlowski Reviewed-by: Rob Herring Signed-off-by: Lee Jones Link: https://lore.kernel.org/r/20220202151310.285561-4-krzysztof.kozlowski@canonical.com --- .../bindings/mfd/samsung,exynos5433-lpass.txt | 72 ----------- .../mfd/samsung,exynos5433-lpass.yaml | 117 ++++++++++++++++++ 2 files changed, 117 insertions(+), 72 deletions(-) delete mode 100644 Documentation/devicetree/bindings/mfd/samsung,exynos5433-lpass.txt create mode 100644 Documentation/devicetree/bindings/mfd/samsung,exynos5433-lpass.yaml diff --git a/Documentation/devicetree/bindings/mfd/samsung,exynos5433-lpass.txt b/Documentation/devicetree/bindings/mfd/samsung,exynos5433-lpass.txt deleted file mode 100644 index 30ea27c3936d..000000000000 --- a/Documentation/devicetree/bindings/mfd/samsung,exynos5433-lpass.txt +++ /dev/null @@ -1,72 +0,0 @@ -Samsung Exynos SoC Low Power Audio Subsystem (LPASS) - -Required properties: - - - compatible : "samsung,exynos5433-lpass" - - reg : should contain the LPASS top SFR region location - and size - - clock-names : should contain following required clocks: "sfr0_ctrl" - - clocks : should contain clock specifiers of all clocks, which - input names have been specified in clock-names - property, in same order. - - #address-cells : should be 1 - - #size-cells : should be 1 - - ranges : must be present - -Each IP block of the Low Power Audio Subsystem should be specified as -an optional sub-node. For "samsung,exynos5433-lpass" compatible this includes: -UART, SLIMBUS, PCM, I2S, DMAC, Timers 0...4, VIC, WDT 0...1 devices. - -Bindings of the sub-nodes are described in: - ../serial/samsung_uart.yaml - ../sound/samsung-i2s.txt - ../dma/arm-pl330.txt - - -Example: - -audio-subsystem { - compatible = "samsung,exynos5433-lpass"; - reg = <0x11400000 0x100>, <0x11500000 0x08>; - clocks = <&cmu_aud CLK_PCLK_SFR0_CTRL>; - clock-names = "sfr0_ctrl"; - #address-cells = <1>; - #size-cells = <1>; - ranges; - - adma: adma@11420000 { - compatible = "arm,pl330", "arm,primecell"; - reg = <0x11420000 0x1000>; - interrupts = <0 73 0>; - clocks = <&cmu_aud CLK_ACLK_DMAC>; - clock-names = "apb_pclk"; - #dma-cells = <1>; - #dma-channels = <8>; - #dma-requests = <32>; - }; - - i2s0: i2s0@11440000 { - compatible = "samsung,exynos7-i2s"; - reg = <0x11440000 0x100>; - dmas = <&adma 0 &adma 2>; - dma-names = "tx", "rx"; - interrupts = <0 70 0>; - clocks = <&cmu_aud CLK_PCLK_AUD_I2S>, - <&cmu_aud CLK_SCLK_AUD_I2S>, - <&cmu_aud CLK_SCLK_I2S_BCLK>; - clock-names = "iis", "i2s_opclk0", "i2s_opclk1"; - pinctrl-names = "default"; - pinctrl-0 = <&i2s0_bus>; - }; - - serial_3: serial@11460000 { - compatible = "samsung,exynos5433-uart"; - reg = <0x11460000 0x100>; - interrupts = <0 67 0>; - clocks = <&cmu_aud CLK_PCLK_AUD_UART>, - <&cmu_aud CLK_SCLK_AUD_UART>; - clock-names = "uart", "clk_uart_baud0"; - pinctrl-names = "default"; - pinctrl-0 = <&uart_aud_bus>; - }; - }; diff --git a/Documentation/devicetree/bindings/mfd/samsung,exynos5433-lpass.yaml b/Documentation/devicetree/bindings/mfd/samsung,exynos5433-lpass.yaml new file mode 100644 index 000000000000..bae55c98961c --- /dev/null +++ b/Documentation/devicetree/bindings/mfd/samsung,exynos5433-lpass.yaml @@ -0,0 +1,117 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/mfd/samsung,exynos5433-lpass.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Samsung Exynos SoC Low Power Audio Subsystem (LPASS) + +maintainers: + - Krzysztof Kozlowski + - Sylwester Nawrocki + +properties: + compatible: + const: samsung,exynos5433-lpass + + '#address-cells': + const: 1 + + clocks: + maxItems: 1 + + clock-names: + items: + - const: sfr0_ctrl + + power-domains: + maxItems: 1 + + ranges: true + + reg: + minItems: 2 + maxItems: 2 + + '#size-cells': + const: 1 + +patternProperties: + "^dma-controller@[0-9a-f]+$": + $ref: /schemas/dma/arm,pl330.yaml + + "^i2s@[0-9a-f]+$": + $ref: /schemas/sound/samsung-i2s.yaml + + "^serial@[0-9a-f]+$": + $ref: /schemas/serial/samsung_uart.yaml + +required: + - compatible + - '#address-cells' + - clocks + - clock-names + - ranges + - reg + - '#size-cells' + +additionalProperties: false + +examples: + - | + #include + #include + + audio-subsystem@11400000 { + compatible = "samsung,exynos5433-lpass"; + reg = <0x11400000 0x100>, <0x11500000 0x08>; + clocks = <&cmu_aud CLK_PCLK_SFR0_CTRL>; + clock-names = "sfr0_ctrl"; + power-domains = <&pd_aud>; + #address-cells = <1>; + #size-cells = <1>; + ranges; + + dma-controller@11420000 { + compatible = "arm,pl330", "arm,primecell"; + reg = <0x11420000 0x1000>; + interrupts = ; + clocks = <&cmu_aud CLK_ACLK_DMAC>; + clock-names = "apb_pclk"; + #dma-cells = <1>; + #dma-channels = <8>; + #dma-requests = <32>; + power-domains = <&pd_aud>; + }; + + i2s@11440000 { + compatible = "samsung,exynos7-i2s"; + reg = <0x11440000 0x100>; + dmas = <&adma 0>, <&adma 2>; + dma-names = "tx", "rx"; + interrupts = ; + #address-cells = <1>; + #size-cells = <0>; + clocks = <&cmu_aud CLK_PCLK_AUD_I2S>, + <&cmu_aud CLK_SCLK_AUD_I2S>, + <&cmu_aud CLK_SCLK_I2S_BCLK>; + clock-names = "iis", "i2s_opclk0", "i2s_opclk1"; + #clock-cells = <1>; + pinctrl-names = "default"; + pinctrl-0 = <&i2s0_bus>; + power-domains = <&pd_aud>; + #sound-dai-cells = <1>; + }; + + serial@11460000 { + compatible = "samsung,exynos5433-uart"; + reg = <0x11460000 0x100>; + interrupts = ; + clocks = <&cmu_aud CLK_PCLK_AUD_UART>, + <&cmu_aud CLK_SCLK_AUD_UART>; + clock-names = "uart", "clk_uart_baud0"; + pinctrl-names = "default"; + pinctrl-0 = <&uart_aud_bus>; + power-domains = <&pd_aud>; + }; + }; From 49be1630558751186ffe612c3e111a8699ce6b53 Mon Sep 17 00:00:00 2001 From: Johnson Wang Date: Thu, 6 Jan 2022 14:54:06 +0800 Subject: [PATCH 285/370] dt-bindings: mfd: Add compatible for the MediaTek MT6366 PMIC This adds compatible for the MediaTek MT6366 PMIC. Signed-off-by: Johnson Wang Acked-by: Rob Herring Signed-off-by: Lee Jones Link: https://lore.kernel.org/r/20220106065407.16036-4-johnson.wang@mediatek.com --- Documentation/devicetree/bindings/mfd/mt6397.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/mfd/mt6397.txt b/Documentation/devicetree/bindings/mfd/mt6397.txt index 99a84b69a29f..293db2a71ef2 100644 --- a/Documentation/devicetree/bindings/mfd/mt6397.txt +++ b/Documentation/devicetree/bindings/mfd/mt6397.txt @@ -20,7 +20,7 @@ This document describes the binding for MFD device and its sub module. Required properties: compatible: "mediatek,mt6323" for PMIC MT6323 - "mediatek,mt6358" for PMIC MT6358 + "mediatek,mt6358" for PMIC MT6358 and MT6366 "mediatek,mt6359" for PMIC MT6359 "mediatek,mt6397" for PMIC MT6397 From 023a8830a62846e1cecc8da07e00c801dd0d7598 Mon Sep 17 00:00:00 2001 From: Christophe JAILLET Date: Sun, 13 Feb 2022 08:41:39 +0100 Subject: [PATCH 286/370] backlight: backlight: Slighly simplify devm_of_find_backlight() Use devm_add_action_or_reset() instead of devm_add_action()+hand writing what is done in the release function, should an error occur. This is more straightforward and saves a few lines of code. While at it, remove a useless test in devm_backlight_release(). 'data' is known to be not NULL when this function is called. Signed-off-by: Christophe JAILLET Reviewed-by: Daniel Thompson Signed-off-by: Lee Jones Link: https://lore.kernel.org/r/f998a4291d865273afa0d1f85764a9ac7fbc1b64.1644738084.git.christophe.jaillet@wanadoo.fr --- drivers/video/backlight/backlight.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/drivers/video/backlight/backlight.c b/drivers/video/backlight/backlight.c index 4ae6fae94ac2..b788ff3d0f45 100644 --- a/drivers/video/backlight/backlight.c +++ b/drivers/video/backlight/backlight.c @@ -710,8 +710,7 @@ static void devm_backlight_release(void *data) { struct backlight_device *bd = data; - if (bd) - put_device(&bd->dev); + put_device(&bd->dev); } /** @@ -737,11 +736,10 @@ struct backlight_device *devm_of_find_backlight(struct device *dev) bd = of_find_backlight(dev); if (IS_ERR_OR_NULL(bd)) return bd; - ret = devm_add_action(dev, devm_backlight_release, bd); - if (ret) { - put_device(&bd->dev); + ret = devm_add_action_or_reset(dev, devm_backlight_release, bd); + if (ret) return ERR_PTR(ret); - } + return bd; } EXPORT_SYMBOL(devm_of_find_backlight); From 8544073271d1cb8664d191a8e87dafb7e0407189 Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Sun, 6 Mar 2022 12:11:14 +0100 Subject: [PATCH 287/370] dt-bindings: ufs: add common platform bindings Add bindings for common parts (platform) of Universal Flash Storage (UFS) Host Controllers in dtschema format. Include also the bindings directory in the UFS maintainers entry. Signed-off-by: Krzysztof Kozlowski Reviewed-by: Alim Akhtar Signed-off-by: Rob Herring Link: https://lore.kernel.org/r/20220306111125.116455-2-krzysztof.kozlowski@canonical.com --- .../devicetree/bindings/ufs/ufs-common.yaml | 82 +++++++++++++++++++ MAINTAINERS | 1 + 2 files changed, 83 insertions(+) create mode 100644 Documentation/devicetree/bindings/ufs/ufs-common.yaml diff --git a/Documentation/devicetree/bindings/ufs/ufs-common.yaml b/Documentation/devicetree/bindings/ufs/ufs-common.yaml new file mode 100644 index 000000000000..47a4e9e1a775 --- /dev/null +++ b/Documentation/devicetree/bindings/ufs/ufs-common.yaml @@ -0,0 +1,82 @@ +# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/ufs/ufs-common.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Common properties for Universal Flash Storage (UFS) Host Controllers + +maintainers: + - Alim Akhtar + - Avri Altman + +properties: + clocks: true + + clock-names: true + + freq-table-hz: + items: + items: + - description: Minimum frequency for given clock in Hz + - description: Maximum frequency for given clock in Hz + description: | + Array of operating frequencies in Hz stored in the same order + as the clocks property. If this property is not defined or a value in the + array is "0" then it is assumed that the frequency is set by the parent + clock or a fixed rate clock source. + + interrupts: + maxItems: 1 + + lanes-per-direction: + $ref: /schemas/types.yaml#/definitions/uint32 + enum: [1, 2] + default: 2 + description: + Number of lanes available per direction. Note that it is assume same + number of lanes is used both directions at once. + + vdd-hba-supply: + description: + Phandle to UFS host controller supply regulator node. + + vcc-supply: + description: + Phandle to VCC supply regulator node. + + vccq-supply: + description: + Phandle to VCCQ supply regulator node. + + vccq2-supply: + description: + Phandle to VCCQ2 supply regulator node. + + vcc-supply-1p8: + type: boolean + description: + For embedded UFS devices, valid VCC range is 1.7-1.95V or 2.7-3.6V. This + boolean property when set, specifies to use low voltage range of + 1.7-1.95V. Note for external UFS cards this property is invalid and valid + VCC range is always 2.7-3.6V. + + vcc-max-microamp: + description: + Specifies max. load that can be drawn from VCC supply. + + vccq-max-microamp: + description: + Specifies max. load that can be drawn from VCCQ supply. + + vccq2-max-microamp: + description: + Specifies max. load that can be drawn from VCCQ2 supply. + +dependencies: + freq-table-hz: [ 'clocks' ] + +required: + - interrupts + +additionalProperties: true diff --git a/MAINTAINERS b/MAINTAINERS index 922f11c190b9..3620cae28fdd 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -19773,6 +19773,7 @@ R: Alim Akhtar R: Avri Altman L: linux-scsi@vger.kernel.org S: Supported +F: Documentation/devicetree/bindings/ufs/ F: Documentation/scsi/ufs.rst F: drivers/scsi/ufs/ From cebe22345fb8f92cd1ca4b5aafe63d77722e4a37 Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Sun, 6 Mar 2022 12:11:15 +0100 Subject: [PATCH 288/370] dt-bindings: ufs: samsung,exynos-ufs: use common bindings Use common UFS bindings in Samsung Exynos UFS to cover generic/common properties in DTS. Signed-off-by: Krzysztof Kozlowski Reviewed-by: Rob Herring Reviewed-by: Alim Akhtar Signed-off-by: Rob Herring Link: https://lore.kernel.org/r/20220306111125.116455-3-krzysztof.kozlowski@canonical.com --- .../devicetree/bindings/ufs/samsung,exynos-ufs.yaml | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/Documentation/devicetree/bindings/ufs/samsung,exynos-ufs.yaml b/Documentation/devicetree/bindings/ufs/samsung,exynos-ufs.yaml index 95ac1c18334d..c949eb617313 100644 --- a/Documentation/devicetree/bindings/ufs/samsung,exynos-ufs.yaml +++ b/Documentation/devicetree/bindings/ufs/samsung,exynos-ufs.yaml @@ -11,12 +11,11 @@ maintainers: description: | Each Samsung UFS host controller instance should have its own node. - This binding define Samsung specific binding other then what is used - in the common ufshcd bindings - [1] Documentation/devicetree/bindings/ufs/ufshcd-pltfrm.txt + +allOf: + - $ref: ufs-common.yaml properties: - compatible: enum: - samsung,exynos7-ufs @@ -47,9 +46,6 @@ properties: - const: core_clk - const: sclk_unipro_main - interrupts: - maxItems: 1 - phys: maxItems: 1 @@ -67,13 +63,12 @@ properties: required: - compatible - reg - - interrupts - phys - phy-names - clocks - clock-names -additionalProperties: false +unevaluatedProperties: false examples: - | From 1581355bd0edca670011ef15364cfa5326da36cd Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Sun, 6 Mar 2022 12:11:16 +0100 Subject: [PATCH 289/370] dt-bindings: ufs: cdns,ufshc: convert to dtschema Convert the Cadence Universal Flash Storage (UFS) Controlle to DT schema format. Signed-off-by: Krzysztof Kozlowski Reviewed-by: Rob Herring Signed-off-by: Rob Herring Link: https://lore.kernel.org/r/20220306111125.116455-4-krzysztof.kozlowski@canonical.com --- .../devicetree/bindings/ufs/cdns,ufshc.txt | 32 --------- .../devicetree/bindings/ufs/cdns,ufshc.yaml | 68 +++++++++++++++++++ .../devicetree/bindings/ufs/ti,j721e-ufs.yaml | 7 +- 3 files changed, 71 insertions(+), 36 deletions(-) delete mode 100644 Documentation/devicetree/bindings/ufs/cdns,ufshc.txt create mode 100644 Documentation/devicetree/bindings/ufs/cdns,ufshc.yaml diff --git a/Documentation/devicetree/bindings/ufs/cdns,ufshc.txt b/Documentation/devicetree/bindings/ufs/cdns,ufshc.txt deleted file mode 100644 index 02347b017abd..000000000000 --- a/Documentation/devicetree/bindings/ufs/cdns,ufshc.txt +++ /dev/null @@ -1,32 +0,0 @@ -* Cadence Universal Flash Storage (UFS) Controller - -UFS nodes are defined to describe on-chip UFS host controllers. -Each UFS controller instance should have its own node. -Please see the ufshcd-pltfrm.txt for a list of all available properties. - -Required properties: -- compatible : Compatible list, contains one of the following controllers: - "cdns,ufshc" - Generic CDNS HCI, - "cdns,ufshc-m31-16nm" - CDNS UFS HC + M31 16nm PHY - complemented with the JEDEC version: - "jedec,ufs-2.0" - -- reg : Address and length of the UFS register set. -- interrupts : One interrupt mapping. -- freq-table-hz : Clock frequency table. - See the ufshcd-pltfrm.txt for details. -- 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. "core_clk" is mandatory. - Depending on a type of a PHY, - the "phy_clk" clock can also be added, if needed. - -Example: - ufs@fd030000 { - compatible = "cdns,ufshc", "jedec,ufs-2.0"; - reg = <0xfd030000 0x10000>; - interrupts = <0 1 IRQ_TYPE_LEVEL_HIGH>; - freq-table-hz = <0 0>, <0 0>; - clocks = <&ufs_core_clk>, <&ufs_phy_clk>; - clock-names = "core_clk", "phy_clk"; - }; diff --git a/Documentation/devicetree/bindings/ufs/cdns,ufshc.yaml b/Documentation/devicetree/bindings/ufs/cdns,ufshc.yaml new file mode 100644 index 000000000000..d227dea368be --- /dev/null +++ b/Documentation/devicetree/bindings/ufs/cdns,ufshc.yaml @@ -0,0 +1,68 @@ +# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/ufs/cdns,ufshc.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Cadence Universal Flash Storage (UFS) Controller + +maintainers: + - Jan Kotas + +# Select only our matches, not all jedec,ufs-2.0 +select: + properties: + compatible: + contains: + enum: + - cdns,ufshc + - cdns,ufshc-m31-16nm + required: + - compatible + +allOf: + - $ref: ufs-common.yaml + +properties: + compatible: + items: + - enum: + - cdns,ufshc + # CDNS UFS HC + M31 16nm PHY + - cdns,ufshc-m31-16nm + - const: jedec,ufs-2.0 + + clocks: + minItems: 1 + maxItems: 3 + + clock-names: + minItems: 1 + items: + - const: core_clk + - const: phy_clk + - const: ref_clk + + reg: + maxItems: 1 + +required: + - compatible + - clocks + - clock-names + - reg + +unevaluatedProperties: false + +examples: + - | + #include + + ufs@fd030000 { + compatible = "cdns,ufshc", "jedec,ufs-2.0"; + reg = <0xfd030000 0x10000>; + interrupts = ; + freq-table-hz = <0 0>, <0 0>; + clocks = <&ufs_core_clk>, <&ufs_phy_clk>; + clock-names = "core_clk", "phy_clk"; + }; diff --git a/Documentation/devicetree/bindings/ufs/ti,j721e-ufs.yaml b/Documentation/devicetree/bindings/ufs/ti,j721e-ufs.yaml index 4d13e6bc1c50..c5eca7735f76 100644 --- a/Documentation/devicetree/bindings/ufs/ti,j721e-ufs.yaml +++ b/Documentation/devicetree/bindings/ufs/ti,j721e-ufs.yaml @@ -47,11 +47,10 @@ required: patternProperties: "^ufs@[0-9a-f]+$": - type: object + $ref: cdns,ufshc.yaml description: | - Cadence UFS controller node must be the child node. Refer - Documentation/devicetree/bindings/ufs/cdns,ufshc.txt for binding - documentation of child node + Cadence UFS controller node must be the child node. + unevaluatedProperties: false additionalProperties: false From 578f116b7ad62c44306a1cde27cd0bc7873161f2 Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Sun, 6 Mar 2022 12:11:17 +0100 Subject: [PATCH 290/370] dt-bindings: ufs: drop unused/old ufs-qcom PHY bindings The Qualcomm UFS PHY bindings are documented in bindings/phy/qcom,qmp-phy.yaml and the compatibles from separate file bindings/ufs/ufs-qcom.txt are not used at all. Signed-off-by: Krzysztof Kozlowski Reviewed-by: Bjorn Andersson Reviewed-by: Rob Herring Signed-off-by: Rob Herring Link: https://lore.kernel.org/r/20220306111125.116455-5-krzysztof.kozlowski@canonical.com --- .../devicetree/bindings/ufs/ufs-qcom.txt | 63 ------------------- 1 file changed, 63 deletions(-) delete mode 100644 Documentation/devicetree/bindings/ufs/ufs-qcom.txt diff --git a/Documentation/devicetree/bindings/ufs/ufs-qcom.txt b/Documentation/devicetree/bindings/ufs/ufs-qcom.txt deleted file mode 100644 index fd59f93e9556..000000000000 --- a/Documentation/devicetree/bindings/ufs/ufs-qcom.txt +++ /dev/null @@ -1,63 +0,0 @@ -* Qualcomm Technologies Inc Universal Flash Storage (UFS) PHY - -UFSPHY nodes are defined to describe on-chip UFS PHY hardware macro. -Each UFS PHY node should have its own node. - -To bind UFS PHY with UFS host controller, the controller node should -contain a phandle reference to UFS PHY node. - -Required properties: -- compatible : compatible list, contains one of the following - - "qcom,ufs-phy-qmp-20nm" for 20nm ufs phy, - "qcom,ufs-phy-qmp-14nm" for legacy 14nm ufs phy, - "qcom,msm8996-ufs-phy-qmp-14nm" for 14nm ufs phy - present on MSM8996 chipset. -- reg : should contain PHY register address space (mandatory), -- reg-names : indicates various resources passed to driver (via reg proptery) by name. - Required "reg-names" is "phy_mem". -- #phy-cells : This property shall be set to 0 -- vdda-phy-supply : phandle to main PHY supply for analog domain -- vdda-pll-supply : phandle to PHY PLL and Power-Gen block power supply -- 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. "ref_clk_src", "ref_clk", - "tx_iface_clk" & "rx_iface_clk" are mandatory but - "ref_clk_parent" is optional - -Optional properties: -- vdda-phy-max-microamp : specifies max. load that can be drawn from phy supply -- vdda-pll-max-microamp : specifies max. load that can be drawn from pll supply -- vddp-ref-clk-supply : phandle to UFS device ref_clk pad power supply -- vddp-ref-clk-max-microamp : specifies max. load that can be drawn from this supply -- resets : specifies the PHY reset in the UFS controller - -Example: - - ufsphy1: ufsphy@fc597000 { - compatible = "qcom,ufs-phy-qmp-20nm"; - reg = <0xfc597000 0x800>; - reg-names = "phy_mem"; - #phy-cells = <0>; - vdda-phy-supply = <&pma8084_l4>; - vdda-pll-supply = <&pma8084_l12>; - vdda-phy-max-microamp = <50000>; - vdda-pll-max-microamp = <1000>; - clock-names = "ref_clk_src", - "ref_clk_parent", - "ref_clk", - "tx_iface_clk", - "rx_iface_clk"; - clocks = <&clock_rpm clk_ln_bb_clk>, - <&clock_gcc clk_pcie_1_phy_ldo >, - <&clock_gcc clk_ufs_phy_ldo>, - <&clock_gcc clk_gcc_ufs_tx_cfg_clk>, - <&clock_gcc clk_gcc_ufs_rx_cfg_clk>; - resets = <&ufshc 0>; - }; - - ufshc: ufshc@fc598000 { - #reset-cells = <1>; - ... - phys = <&ufsphy1>; - phy-names = "ufsphy"; - }; From 462c5c0aa7989ea33fb4167daad0c0354b066f6b Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Sun, 6 Mar 2022 12:11:18 +0100 Subject: [PATCH 291/370] dt-bindings: ufs: qcom,ufs: convert to dtschema Convert the Qualcomm Universal Flash Storage (UFS) Controller to DT schema format. Except the conversion, add also properties already present in DTS: iommus, interconnects and power-domains. Signed-off-by: Krzysztof Kozlowski Reviewed-by: Rob Herring Signed-off-by: Rob Herring Link: https://lore.kernel.org/r/20220306111125.116455-6-krzysztof.kozlowski@canonical.com --- .../devicetree/bindings/ufs/qcom,ufs.yaml | 242 ++++++++++++++++++ .../devicetree/bindings/ufs/ufshcd-pltfrm.txt | 90 ------- 2 files changed, 242 insertions(+), 90 deletions(-) create mode 100644 Documentation/devicetree/bindings/ufs/qcom,ufs.yaml delete mode 100644 Documentation/devicetree/bindings/ufs/ufshcd-pltfrm.txt diff --git a/Documentation/devicetree/bindings/ufs/qcom,ufs.yaml b/Documentation/devicetree/bindings/ufs/qcom,ufs.yaml new file mode 100644 index 000000000000..5b3a2157f7e5 --- /dev/null +++ b/Documentation/devicetree/bindings/ufs/qcom,ufs.yaml @@ -0,0 +1,242 @@ +# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/ufs/qcom,ufs.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Qualcomm Universal Flash Storage (UFS) Controller + +maintainers: + - Bjorn Andersson + - Andy Gross + +# Select only our matches, not all jedec,ufs-2.0 +select: + properties: + compatible: + contains: + const: qcom,ufshc + required: + - compatible + +properties: + compatible: + items: + - enum: + - qcom,msm8994-ufshc + - qcom,msm8996-ufshc + - qcom,msm8998-ufshc + - qcom,sdm845-ufshc + - qcom,sm8150-ufshc + - qcom,sm8250-ufshc + - qcom,sm8350-ufshc + - qcom,sm8450-ufshc + - const: qcom,ufshc + - const: jedec,ufs-2.0 + + clocks: + minItems: 8 + maxItems: 11 + + clock-names: + minItems: 8 + maxItems: 11 + + interconnects: + minItems: 2 + maxItems: 2 + + interconnect-names: + items: + - const: ufs-ddr + - const: cpu-ufs + + iommus: + minItems: 1 + maxItems: 2 + + phys: + maxItems: 1 + + phy-names: + items: + - const: ufsphy + + power-domains: + maxItems: 1 + + reg: + minItems: 1 + maxItems: 2 + + resets: + maxItems: 1 + + '#reset-cells': + const: 1 + + reset-names: + items: + - const: rst + + reset-gpios: + maxItems: 1 + description: + GPIO connected to the RESET pin of the UFS memory device. + +required: + - compatible + - reg + +allOf: + - $ref: ufs-common.yaml + + - if: + properties: + compatible: + contains: + enum: + - qcom,msm8998-ufshc + - qcom,sm8250-ufshc + - qcom,sm8350-ufshc + - qcom,sm8450-ufshc + then: + properties: + clocks: + minItems: 8 + maxItems: 8 + clock-names: + items: + - const: core_clk + - const: bus_aggr_clk + - const: iface_clk + - const: core_clk_unipro + - const: ref_clk + - const: tx_lane0_sync_clk + - const: rx_lane0_sync_clk + - const: rx_lane1_sync_clk + reg: + minItems: 1 + maxItems: 1 + + - if: + properties: + compatible: + contains: + enum: + - qcom,sdm845-ufshc + - qcom,sm8150-ufshc + then: + properties: + clocks: + minItems: 9 + maxItems: 9 + clock-names: + items: + - const: core_clk + - const: bus_aggr_clk + - const: iface_clk + - const: core_clk_unipro + - const: ref_clk + - const: tx_lane0_sync_clk + - const: rx_lane0_sync_clk + - const: rx_lane1_sync_clk + - const: ice_core_clk + reg: + minItems: 2 + maxItems: 2 + + - if: + properties: + compatible: + contains: + enum: + - qcom,msm8996-ufshc + then: + properties: + clocks: + minItems: 11 + maxItems: 11 + clock-names: + items: + - const: core_clk_src + - const: core_clk + - const: bus_clk + - const: bus_aggr_clk + - const: iface_clk + - const: core_clk_unipro_src + - const: core_clk_unipro + - const: core_clk_ice + - const: ref_clk + - const: tx_lane0_sync_clk + - const: rx_lane0_sync_clk + reg: + minItems: 1 + maxItems: 1 + + # TODO: define clock bindings for qcom,msm8994-ufshc + +unevaluatedProperties: false + +examples: + - | + #include + #include + #include + #include + #include + + soc { + #address-cells = <2>; + #size-cells = <2>; + + ufs@1d84000 { + compatible = "qcom,sm8450-ufshc", "qcom,ufshc", + "jedec,ufs-2.0"; + reg = <0 0x01d84000 0 0x3000>; + interrupts = ; + phys = <&ufs_mem_phy_lanes>; + phy-names = "ufsphy"; + lanes-per-direction = <2>; + #reset-cells = <1>; + resets = <&gcc GCC_UFS_PHY_BCR>; + reset-names = "rst"; + reset-gpios = <&tlmm 210 GPIO_ACTIVE_LOW>; + + vcc-supply = <&vreg_l7b_2p5>; + vcc-max-microamp = <1100000>; + vccq-supply = <&vreg_l9b_1p2>; + vccq-max-microamp = <1200000>; + + power-domains = <&gcc UFS_PHY_GDSC>; + iommus = <&apps_smmu 0xe0 0x0>; + interconnects = <&aggre1_noc MASTER_UFS_MEM &mc_virt SLAVE_EBI1>, + <&gem_noc MASTER_APPSS_PROC &config_noc SLAVE_UFS_MEM_CFG>; + interconnect-names = "ufs-ddr", "cpu-ufs"; + + clock-names = "core_clk", + "bus_aggr_clk", + "iface_clk", + "core_clk_unipro", + "ref_clk", + "tx_lane0_sync_clk", + "rx_lane0_sync_clk", + "rx_lane1_sync_clk"; + clocks = <&gcc GCC_UFS_PHY_AXI_CLK>, + <&gcc GCC_AGGRE_UFS_PHY_AXI_CLK>, + <&gcc GCC_UFS_PHY_AHB_CLK>, + <&gcc GCC_UFS_PHY_UNIPRO_CORE_CLK>, + <&rpmhcc RPMH_CXO_CLK>, + <&gcc GCC_UFS_PHY_TX_SYMBOL_0_CLK>, + <&gcc GCC_UFS_PHY_RX_SYMBOL_0_CLK>, + <&gcc GCC_UFS_PHY_RX_SYMBOL_1_CLK>; + freq-table-hz = <75000000 300000000>, + <0 0>, + <0 0>, + <75000000 300000000>, + <75000000 300000000>, + <0 0>, + <0 0>, + <0 0>; + }; + }; diff --git a/Documentation/devicetree/bindings/ufs/ufshcd-pltfrm.txt b/Documentation/devicetree/bindings/ufs/ufshcd-pltfrm.txt deleted file mode 100644 index d0fee78e6203..000000000000 --- a/Documentation/devicetree/bindings/ufs/ufshcd-pltfrm.txt +++ /dev/null @@ -1,90 +0,0 @@ -* Universal Flash Storage (UFS) Host Controller - -UFSHC nodes are defined to describe on-chip UFS host controllers. -Each UFS controller instance should have its own node. - -Required properties: -- compatible : must contain "jedec,ufs-1.1" or "jedec,ufs-2.0" - - For Qualcomm SoCs must contain, as below, an - SoC-specific compatible along with "qcom,ufshc" and - the appropriate jedec string: - "qcom,msm8994-ufshc", "qcom,ufshc", "jedec,ufs-2.0" - "qcom,msm8996-ufshc", "qcom,ufshc", "jedec,ufs-2.0" - "qcom,msm8998-ufshc", "qcom,ufshc", "jedec,ufs-2.0" - "qcom,sdm845-ufshc", "qcom,ufshc", "jedec,ufs-2.0" - "qcom,sm8150-ufshc", "qcom,ufshc", "jedec,ufs-2.0" - "qcom,sm8250-ufshc", "qcom,ufshc", "jedec,ufs-2.0" - "qcom,sm8350-ufshc", "qcom,ufshc", "jedec,ufs-2.0" - "qcom,sm8450-ufshc", "qcom,ufshc", "jedec,ufs-2.0" -- interrupts : -- reg : - -Optional properties: -- phys : phandle to UFS PHY node -- phy-names : the string "ufsphy" when is found in a node, along - with "phys" attribute, provides phandle to UFS PHY node -- vdd-hba-supply : phandle to UFS host controller supply regulator node -- vcc-supply : phandle to VCC supply regulator node -- vccq-supply : phandle to VCCQ supply regulator node -- vccq2-supply : phandle to VCCQ2 supply regulator node -- vcc-supply-1p8 : For embedded UFS devices, valid VCC range is 1.7-1.95V - or 2.7-3.6V. This boolean property when set, specifies - to use low voltage range of 1.7-1.95V. Note for external - UFS cards this property is invalid and valid VCC range is - always 2.7-3.6V. -- vcc-max-microamp : specifies max. load that can be drawn from vcc supply -- vccq-max-microamp : specifies max. load that can be drawn from vccq supply -- vccq2-max-microamp : specifies max. load that can be drawn from vccq2 supply - -- 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. - "ref_clk" indicates reference clock frequency. - UFS host supplies reference clock to UFS device and UFS device - specification allows host to provide one of the 4 frequencies (19.2 MHz, - 26 MHz, 38.4 MHz, 52MHz) for reference clock. This "ref_clk" entry is - parsed and used to update the reference clock setting in device. - Defaults to 26 MHz(as per specification) if not specified by host. -- freq-table-hz : Array of operating frequencies stored in the same - order as the clocks property. If this property is not - defined or a value in the array is "0" then it is assumed - that the frequency is set by the parent clock or a - fixed rate clock source. --lanes-per-direction : number of lanes available per direction - either 1 or 2. - Note that it is assume same number of lanes is used both - directions at once. If not specified, default is 2 lanes per direction. -- #reset-cells : Must be <1> for Qualcomm UFS controllers that expose - PHY reset from the UFS controller. -- resets : reset node register -- reset-names : describe reset node register, the "rst" corresponds to reset the whole UFS IP. -- reset-gpios : A phandle and gpio specifier denoting the GPIO connected - to the RESET pin of the UFS memory device. - -Note: If above properties are not defined it can be assumed that the supply -regulators or clocks are always on. - -Example: - ufshc@fc598000 { - compatible = "jedec,ufs-1.1"; - reg = <0xfc598000 0x800>; - interrupts = <0 28 0>; - - vdd-hba-supply = <&xxx_reg0>; - vcc-supply = <&xxx_reg1>; - vcc-supply-1p8; - vccq-supply = <&xxx_reg2>; - vccq2-supply = <&xxx_reg3>; - vcc-max-microamp = 500000; - vccq-max-microamp = 200000; - vccq2-max-microamp = 200000; - - clocks = <&core 0>, <&ref 0>, <&phy 0>, <&iface 0>; - clock-names = "core_clk", "ref_clk", "phy_clk", "iface_clk"; - freq-table-hz = <100000000 200000000>, <0 0>, <0 0>, <0 0>; - resets = <&reset 0 1>; - reset-names = "rst"; - phys = <&ufsphy1>; - phy-names = "ufsphy"; - #reset-cells = <1>; - }; From 516075a230d4801222cf0d1b8c8534e73c81c16a Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Sun, 6 Mar 2022 12:11:19 +0100 Subject: [PATCH 292/370] dt-bindings: ufs: hisilicon,ufs: convert to dtschema Convert the HiSilicon Universal Flash Storage (UFS) Controller to DT schema format. Signed-off-by: Krzysztof Kozlowski Reviewed-by: Rob Herring Signed-off-by: Rob Herring Link: https://lore.kernel.org/r/20220306111125.116455-7-krzysztof.kozlowski@canonical.com --- .../bindings/ufs/hisilicon,ufs.yaml | 90 +++++++++++++++++++ .../devicetree/bindings/ufs/ufs-hisi.txt | 42 --------- 2 files changed, 90 insertions(+), 42 deletions(-) create mode 100644 Documentation/devicetree/bindings/ufs/hisilicon,ufs.yaml delete mode 100644 Documentation/devicetree/bindings/ufs/ufs-hisi.txt diff --git a/Documentation/devicetree/bindings/ufs/hisilicon,ufs.yaml b/Documentation/devicetree/bindings/ufs/hisilicon,ufs.yaml new file mode 100644 index 000000000000..4432bfa0cbc7 --- /dev/null +++ b/Documentation/devicetree/bindings/ufs/hisilicon,ufs.yaml @@ -0,0 +1,90 @@ +# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/ufs/hisilicon,ufs.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: HiSilicon Universal Flash Storage (UFS) Controller + +maintainers: + - Li Wei + +# Select only our matches, not all jedec,ufs +select: + properties: + compatible: + contains: + enum: + - hisilicon,hi3660-ufs + - hisilicon,hi3670-ufs + required: + - compatible + +allOf: + - $ref: ufs-common.yaml + +properties: + compatible: + oneOf: + - items: + - const: hisilicon,hi3660-ufs + - const: jedec,ufs-1.1 + - items: + - enum: + - hisilicon,hi3670-ufs + - const: jedec,ufs-2.1 + + clocks: + minItems: 2 + maxItems: 2 + + clock-names: + items: + - const: ref_clk + - const: phy_clk + + reg: + items: + - description: UFS register address space + - description: UFS SYS CTRL register address space + + resets: + maxItems: 1 + + reset-names: + items: + - const: rst + +required: + - compatible + - reg + - resets + - reset-names + +unevaluatedProperties: false + +examples: + - | + #include + #include + + soc { + #address-cells = <2>; + #size-cells = <2>; + + ufs@ff3c0000 { + compatible = "hisilicon,hi3670-ufs", "jedec,ufs-2.1"; + reg = <0x0 0xff3c0000 0x0 0x1000>, + <0x0 0xff3e0000 0x0 0x1000>; + interrupt-parent = <&gic>; + interrupts = ; + clocks = <&crg_ctrl HI3670_CLK_GATE_UFSIO_REF>, + <&crg_ctrl HI3670_CLK_GATE_UFS_SUBSYS>; + clock-names = "ref_clk", "phy_clk"; + freq-table-hz = <0 0>, + <0 0>; + + resets = <&crg_rst 0x84 12>; + reset-names = "rst"; + }; + }; diff --git a/Documentation/devicetree/bindings/ufs/ufs-hisi.txt b/Documentation/devicetree/bindings/ufs/ufs-hisi.txt deleted file mode 100644 index 0b83df1a5418..000000000000 --- a/Documentation/devicetree/bindings/ufs/ufs-hisi.txt +++ /dev/null @@ -1,42 +0,0 @@ -* Hisilicon Universal Flash Storage (UFS) Host Controller - -UFS nodes are defined to describe on-chip UFS hardware macro. -Each UFS Host Controller should have its own node. - -Required properties: -- compatible : compatible list, contains one of the following - - "hisilicon,hi3660-ufs", "jedec,ufs-1.1" for hisi ufs - host controller present on Hi3660 chipset. - "hisilicon,hi3670-ufs", "jedec,ufs-2.1" for hisi ufs - host controller present on Hi3670 chipset. -- reg : should contain UFS register address space & UFS SYS CTRL register address, -- interrupts : interrupt number -- 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. "ref_clk", "phy_clk" is optional -- freq-table-hz : Array of operating frequencies stored in the same - order as the clocks property. If this property is not - defined or a value in the array is "0" then it is assumed - that the frequency is set by the parent clock or a - fixed rate clock source. -- resets : describe reset node register -- reset-names : reset node register, the "rst" corresponds to reset the whole UFS IP. - -Example: - - ufs: ufs@ff3b0000 { - compatible = "hisilicon,hi3660-ufs", "jedec,ufs-1.1"; - /* 0: HCI standard */ - /* 1: UFS SYS CTRL */ - reg = <0x0 0xff3b0000 0x0 0x1000>, - <0x0 0xff3b1000 0x0 0x1000>; - interrupt-parent = <&gic>; - interrupts = ; - clocks = <&crg_ctrl HI3660_CLK_GATE_UFSIO_REF>, - <&crg_ctrl HI3660_CLK_GATE_UFSPHY_CFG>; - clock-names = "ref_clk", "phy_clk"; - freq-table-hz = <0 0>, <0 0>; - /* offset: 0x84; bit: 12 */ - resets = <&crg_rst 0x84 12>; - reset-names = "rst"; - }; From 954c6010053ce387d50bed8fcd55cda701728f5e Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Sun, 6 Mar 2022 12:11:20 +0100 Subject: [PATCH 293/370] dt-bindings: ufs: mediatek,ufs: convert to dtschema Convert the Mediatek Universal Flash Storage (UFS) Controller to DT schema format. Signed-off-by: Krzysztof Kozlowski Reviewed-by: Rob Herring Signed-off-by: Rob Herring Link: https://lore.kernel.org/r/20220306111125.116455-8-krzysztof.kozlowski@canonical.com --- .../devicetree/bindings/ufs/mediatek,ufs.yaml | 67 +++++++++++++++++++ .../devicetree/bindings/ufs/ufs-mediatek.txt | 45 ------------- 2 files changed, 67 insertions(+), 45 deletions(-) create mode 100644 Documentation/devicetree/bindings/ufs/mediatek,ufs.yaml delete mode 100644 Documentation/devicetree/bindings/ufs/ufs-mediatek.txt diff --git a/Documentation/devicetree/bindings/ufs/mediatek,ufs.yaml b/Documentation/devicetree/bindings/ufs/mediatek,ufs.yaml new file mode 100644 index 000000000000..32fd535a514a --- /dev/null +++ b/Documentation/devicetree/bindings/ufs/mediatek,ufs.yaml @@ -0,0 +1,67 @@ +# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/ufs/mediatek,ufs.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Mediatek Universal Flash Storage (UFS) Controller + +maintainers: + - Stanley Chu + +allOf: + - $ref: ufs-common.yaml + +properties: + compatible: + enum: + - mediatek,mt8183-ufshci + - mediatek,mt8192-ufshci + + clocks: + maxItems: 1 + + clock-names: + items: + - const: ufs + + phys: + maxItems: 1 + + reg: + maxItems: 1 + + vcc-supply: true + +required: + - compatible + - clocks + - clock-names + - phys + - reg + - vcc-supply + +unevaluatedProperties: false + +examples: + - | + #include + #include + + soc { + #address-cells = <2>; + #size-cells = <2>; + + ufs@ff3c0000 { + compatible = "mediatek,mt8183-ufshci"; + reg = <0 0x11270000 0 0x2300>; + interrupts = ; + phys = <&ufsphy>; + + clocks = <&infracfg_ao CLK_INFRA_UFS>; + clock-names = "ufs"; + freq-table-hz = <0 0>; + + vcc-supply = <&mt_pmic_vemc_ldo_reg>; + }; + }; diff --git a/Documentation/devicetree/bindings/ufs/ufs-mediatek.txt b/Documentation/devicetree/bindings/ufs/ufs-mediatek.txt deleted file mode 100644 index 63a953b672d2..000000000000 --- a/Documentation/devicetree/bindings/ufs/ufs-mediatek.txt +++ /dev/null @@ -1,45 +0,0 @@ -* Mediatek Universal Flash Storage (UFS) Host Controller - -UFS nodes are defined to describe on-chip UFS hardware macro. -Each UFS Host Controller should have its own node. - -To bind UFS PHY with UFS host controller, the controller node should -contain a phandle reference to UFS M-PHY node. - -Required properties for UFS nodes: -- compatible : Compatible list, contains the following controller: - "mediatek,mt8183-ufshci" for MediaTek UFS host controller - present on MT8183 chipsets. - "mediatek,mt8192-ufshci" for MediaTek UFS host controller - present on MT8192 chipsets. -- reg : Address and length of the UFS register set. -- phys : phandle to m-phy. -- 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. "ufs" is mandatory. - "ufs": ufshci core control clock. -- freq-table-hz : Array of operating frequencies stored in the same - order as the clocks property. If this property is not - defined or a value in the array is "0" then it is assumed - that the frequency is set by the parent clock or a - fixed rate clock source. -- vcc-supply : phandle to VCC supply regulator node. - -Example: - - ufsphy: phy@11fa0000 { - ... - }; - - ufshci@11270000 { - compatible = "mediatek,mt8183-ufshci"; - reg = <0 0x11270000 0 0x2300>; - interrupts = ; - phys = <&ufsphy>; - - clocks = <&infracfg_ao INFRACFG_AO_UFS_CG>; - clock-names = "ufs"; - freq-table-hz = <0 0>; - - vcc-supply = <&mt_pmic_vemc_ldo_reg>; - }; From f3e00820f51952bb75c4c2fd722d56e844e17c15 Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Sun, 6 Mar 2022 12:11:21 +0100 Subject: [PATCH 294/370] dt-bindings: ufs: snps,tc-dwc-g210: convert to dtschema Convert the Synopsys Universal Flash Storage (UFS) Controller to DT schema format. Signed-off-by: Krzysztof Kozlowski Reviewed-by: Rob Herring Signed-off-by: Rob Herring Link: https://lore.kernel.org/r/20220306111125.116455-9-krzysztof.kozlowski@canonical.com --- .../bindings/ufs/snps,tc-dwc-g210.yaml | 51 +++++++++++++++++++ .../bindings/ufs/tc-dwc-g210-pltfrm.txt | 26 ---------- 2 files changed, 51 insertions(+), 26 deletions(-) create mode 100644 Documentation/devicetree/bindings/ufs/snps,tc-dwc-g210.yaml delete mode 100644 Documentation/devicetree/bindings/ufs/tc-dwc-g210-pltfrm.txt diff --git a/Documentation/devicetree/bindings/ufs/snps,tc-dwc-g210.yaml b/Documentation/devicetree/bindings/ufs/snps,tc-dwc-g210.yaml new file mode 100644 index 000000000000..671a70d95138 --- /dev/null +++ b/Documentation/devicetree/bindings/ufs/snps,tc-dwc-g210.yaml @@ -0,0 +1,51 @@ +# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/ufs/snps,tc-dwc-g210.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Synopsys DesignWare Universal Flash Storage (UFS) Controller + +maintainers: + - Li Wei + +# Select only our matches, not all jedec,ufs +select: + properties: + compatible: + contains: + enum: + - snps,dwc-ufshcd-1.40a + required: + - compatible + +allOf: + - $ref: ufs-common.yaml + +properties: + compatible: + items: + - enum: + - snps,g210-tc-6.00-20bit + - snps,g210-tc-6.00-40bit + - const: snps,dwc-ufshcd-1.40a + - const: jedec,ufs-2.0 + + reg: + maxItems: 1 + +required: + - compatible + - reg + +unevaluatedProperties: false + +examples: + - | + ufs@d0000000 { + compatible = "snps,g210-tc-6.00-40bit", + "snps,dwc-ufshcd-1.40a", + "jedec,ufs-2.0"; + reg = <0xd0000000 0x10000>; + interrupts = <24>; + }; diff --git a/Documentation/devicetree/bindings/ufs/tc-dwc-g210-pltfrm.txt b/Documentation/devicetree/bindings/ufs/tc-dwc-g210-pltfrm.txt deleted file mode 100644 index 71c0777960e9..000000000000 --- a/Documentation/devicetree/bindings/ufs/tc-dwc-g210-pltfrm.txt +++ /dev/null @@ -1,26 +0,0 @@ -* Universal Flash Storage (UFS) DesignWare Host Controller - -DWC_UFS nodes are defined to describe on-chip UFS host controllers and MPHY. -Each UFS controller instance should have its own node. - -Required properties: -- compatible : compatible list must contain the PHY type & version: - "snps,g210-tc-6.00-20bit" - "snps,g210-tc-6.00-40bit" - complemented with the Controller IP version: - "snps,dwc-ufshcd-1.40a" - complemented with the JEDEC version: - "jedec,ufs-1.1" - "jedec,ufs-2.0" - -- reg : -- interrupts : - -Example for a setup using a 1.40a DWC Controller with a 6.00 G210 40-bit TC: - dwc-ufs@d0000000 { - compatible = "snps,g210-tc-6.00-40bit", - "snps,dwc-ufshcd-1.40a", - "jedec,ufs-2.0"; - reg = < 0xd0000000 0x10000 >; - interrupts = < 24 >; - }; From 17bf6b7c7835841f77adda76802ac2e6c11ec65e Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Tue, 8 Mar 2022 18:49:02 +0100 Subject: [PATCH 295/370] dt-bindings: firmware: arm,scpi: Add missing maxItems to mboxes/shmem "make dt_binding_check": Documentation/devicetree/bindings/firmware/arm,scpi.example.dt.yaml: scpi: shmem: [[2], [1]] is too long Fix this by adding a proper maxItems value to the shmem property, and to the related mboxes property. Fix the grouping of the "mboxes" property in the example. Signed-off-by: Geert Uytterhoeven Acked-by: Sudeep Holla Signed-off-by: Rob Herring Link: https://lore.kernel.org/r/58b7c706f259f88a61bfe82d9106fe0a93a9838d.1646761693.git.geert+renesas@glider.be --- Documentation/devicetree/bindings/firmware/arm,scpi.yaml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/firmware/arm,scpi.yaml b/Documentation/devicetree/bindings/firmware/arm,scpi.yaml index 800417a76bda..1f9322925e7c 100644 --- a/Documentation/devicetree/bindings/firmware/arm,scpi.yaml +++ b/Documentation/devicetree/bindings/firmware/arm,scpi.yaml @@ -43,6 +43,7 @@ properties: by remote SCP firmware for use by SCPI message protocol should be specified in any order. minItems: 1 + maxItems: 4 shmem: description: @@ -51,6 +52,7 @@ properties: be any memory reserved for the purpose of this communication between the processors. minItems: 1 + maxItems: 4 power-controller: type: object @@ -235,7 +237,7 @@ examples: firmware { scpi { compatible = "amlogic,meson-gxbb-scpi", "arm,scpi-pre-1.0"; - mboxes = <&mailbox 1 &mailbox 2>; + mboxes = <&mailbox 1>, <&mailbox 2>; shmem = <&cpu_scp_lpri>, <&cpu_scp_hpri>; scpi_sensors1: sensors { From 16d1f0a7938568e32fafaedfeb45dd661e9880ee Mon Sep 17 00:00:00 2001 From: Oleksii Moisieiev Date: Mon, 7 Mar 2022 08:17:43 +0000 Subject: [PATCH 296/370] dt-bindings: Add vendor prefix for Xen hypervisor Xen is an open source type-1 hypervisor. Signed-off-by: Oleksii Moisieiev Reviewed-by: Stefano Stabellini Signed-off-by: Rob Herring Link: https://lore.kernel.org/r/aece6fd976980131120456800de3558e1e2308a0.1646639462.git.oleksii_moisieiev@epam.com --- Documentation/devicetree/bindings/vendor-prefixes.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Documentation/devicetree/bindings/vendor-prefixes.yaml b/Documentation/devicetree/bindings/vendor-prefixes.yaml index 3da2b08429e1..bf7a4a09aa71 100644 --- a/Documentation/devicetree/bindings/vendor-prefixes.yaml +++ b/Documentation/devicetree/bindings/vendor-prefixes.yaml @@ -1368,6 +1368,8 @@ patternProperties: description: Wanchanglong Electronics Technology(SHENZHEN)Co.,Ltd. "^x-powers,.*": description: X-Powers + "^xen,.*": + description: Xen Hypervisor "^xes,.*": description: Extreme Engineering Solutions (X-ES) "^xiaomi,.*": From 41d36a9f3e5336f5b48c3adba0777b8e217020d7 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Tue, 8 Mar 2022 07:05:28 +0100 Subject: [PATCH 297/370] fs: remove kiocb.ki_hint This field is entirely unused now except for a tracepoint in f2fs, so remove it. Signed-off-by: Christoph Hellwig Reviewed-by: Dave Chinner Reviewed-by: Chaitanya Kulkarni Link: https://lore.kernel.org/r/20220308060529.736277-2-hch@lst.de Signed-off-by: Jens Axboe --- fs/aio.c | 1 - fs/cachefiles/io.c | 2 -- fs/f2fs/file.c | 6 ------ fs/io_uring.c | 1 - include/linux/fs.h | 12 ------------ include/trace/events/f2fs.h | 3 +-- 6 files changed, 1 insertion(+), 24 deletions(-) diff --git a/fs/aio.c b/fs/aio.c index 4ceba13a7db0..eb0948bb74f1 100644 --- a/fs/aio.c +++ b/fs/aio.c @@ -1478,7 +1478,6 @@ static int aio_prep_rw(struct kiocb *req, const struct iocb *iocb) req->ki_flags = iocb_flags(req->ki_filp); if (iocb->aio_flags & IOCB_FLAG_RESFD) req->ki_flags |= IOCB_EVENTFD; - req->ki_hint = ki_hint_validate(file_write_hint(req->ki_filp)); if (iocb->aio_flags & IOCB_FLAG_IOPRIO) { /* * If the IOCB_FLAG_IOPRIO flag of aio_flags is set, then diff --git a/fs/cachefiles/io.c b/fs/cachefiles/io.c index 753986ea1583..bc7c7a7d9260 100644 --- a/fs/cachefiles/io.c +++ b/fs/cachefiles/io.c @@ -138,7 +138,6 @@ static int cachefiles_read(struct netfs_cache_resources *cres, ki->iocb.ki_filp = file; ki->iocb.ki_pos = start_pos + skipped; ki->iocb.ki_flags = IOCB_DIRECT; - ki->iocb.ki_hint = ki_hint_validate(file_write_hint(file)); ki->iocb.ki_ioprio = get_current_ioprio(); ki->skipped = skipped; ki->object = object; @@ -313,7 +312,6 @@ static int cachefiles_write(struct netfs_cache_resources *cres, ki->iocb.ki_filp = file; ki->iocb.ki_pos = start_pos; ki->iocb.ki_flags = IOCB_DIRECT | IOCB_WRITE; - ki->iocb.ki_hint = ki_hint_validate(file_write_hint(file)); ki->iocb.ki_ioprio = get_current_ioprio(); ki->object = object; ki->inval_counter = cres->inval_counter; diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c index 3c98ef6af97d..45076c01a2ba 100644 --- a/fs/f2fs/file.c +++ b/fs/f2fs/file.c @@ -4479,10 +4479,8 @@ static ssize_t f2fs_dio_write_iter(struct kiocb *iocb, struct iov_iter *from, struct f2fs_inode_info *fi = F2FS_I(inode); struct f2fs_sb_info *sbi = F2FS_I_SB(inode); const bool do_opu = f2fs_lfs_mode(sbi); - const int whint_mode = F2FS_OPTION(sbi).whint_mode; const loff_t pos = iocb->ki_pos; const ssize_t count = iov_iter_count(from); - const enum rw_hint hint = iocb->ki_hint; unsigned int dio_flags; struct iomap_dio *dio; ssize_t ret; @@ -4515,8 +4513,6 @@ static ssize_t f2fs_dio_write_iter(struct kiocb *iocb, struct iov_iter *from, if (do_opu) down_read(&fi->i_gc_rwsem[READ]); } - if (whint_mode == WHINT_MODE_OFF) - iocb->ki_hint = WRITE_LIFE_NOT_SET; /* * We have to use __iomap_dio_rw() and iomap_dio_complete() instead of @@ -4539,8 +4535,6 @@ static ssize_t f2fs_dio_write_iter(struct kiocb *iocb, struct iov_iter *from, ret = iomap_dio_complete(dio); } - if (whint_mode == WHINT_MODE_OFF) - iocb->ki_hint = hint; if (do_opu) up_read(&fi->i_gc_rwsem[READ]); up_read(&fi->i_gc_rwsem[WRITE]); diff --git a/fs/io_uring.c b/fs/io_uring.c index 4715980e9015..36e09169ff93 100644 --- a/fs/io_uring.c +++ b/fs/io_uring.c @@ -3747,7 +3747,6 @@ static int io_write_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe) { if (unlikely(!(req->file->f_mode & FMODE_WRITE))) return -EBADF; - req->rw.kiocb.ki_hint = ki_hint_validate(file_write_hint(req->file)); return io_prep_rw(req, sqe); } diff --git a/include/linux/fs.h b/include/linux/fs.h index e2d892b201b0..d5658ac5d8c6 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -327,7 +327,6 @@ struct kiocb { void (*ki_complete)(struct kiocb *iocb, long ret); void *private; int ki_flags; - u16 ki_hint; u16 ki_ioprio; /* See linux/ioprio.h */ struct wait_page_queue *ki_waitq; /* for async buffered IO */ randomized_struct_fields_end @@ -2225,21 +2224,11 @@ static inline enum rw_hint file_write_hint(struct file *file) static inline int iocb_flags(struct file *file); -static inline u16 ki_hint_validate(enum rw_hint hint) -{ - typeof(((struct kiocb *)0)->ki_hint) max_hint = -1; - - if (hint <= max_hint) - return hint; - return 0; -} - static inline void init_sync_kiocb(struct kiocb *kiocb, struct file *filp) { *kiocb = (struct kiocb) { .ki_filp = filp, .ki_flags = iocb_flags(filp), - .ki_hint = ki_hint_validate(file_write_hint(filp)), .ki_ioprio = get_current_ioprio(), }; } @@ -2250,7 +2239,6 @@ static inline void kiocb_clone(struct kiocb *kiocb, struct kiocb *kiocb_src, *kiocb = (struct kiocb) { .ki_filp = filp, .ki_flags = kiocb_src->ki_flags, - .ki_hint = kiocb_src->ki_hint, .ki_ioprio = kiocb_src->ki_ioprio, .ki_pos = kiocb_src->ki_pos, }; diff --git a/include/trace/events/f2fs.h b/include/trace/events/f2fs.h index f701bb23f83c..1779e133cea0 100644 --- a/include/trace/events/f2fs.h +++ b/include/trace/events/f2fs.h @@ -956,12 +956,11 @@ TRACE_EVENT(f2fs_direct_IO_enter, __entry->rw = rw; ), - TP_printk("dev = (%d,%d), ino = %lu pos = %lld len = %lu ki_flags = %x ki_hint = %x ki_ioprio = %x rw = %d", + TP_printk("dev = (%d,%d), ino = %lu pos = %lld len = %lu ki_flags = %x ki_ioprio = %x rw = %d", show_dev_ino(__entry), __entry->iocb->ki_pos, __entry->len, __entry->iocb->ki_flags, - __entry->iocb->ki_hint, __entry->iocb->ki_ioprio, __entry->rw) ); From 7b12e49669c99f63bc12351c57e581f1f14d4adf Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Tue, 8 Mar 2022 07:05:29 +0100 Subject: [PATCH 298/370] fs: remove fs.f_write_hint The value is now completely unused except for reporting it back through the F_GET_FILE_RW_HINT ioctl, so remove the value and the two ioctls for it. Trying to use the F_SET_FILE_RW_HINT and F_GET_FILE_RW_HINT fcntls will now return EINVAL, just like it would on a kernel that never supported this functionality in the first place. Signed-off-by: Christoph Hellwig Reviewed-by: Dave Chinner Reviewed-by: Chaitanya Kulkarni Link: https://lore.kernel.org/r/20220308060529.736277-3-hch@lst.de Signed-off-by: Jens Axboe --- fs/fcntl.c | 18 ------------------ fs/open.c | 1 - include/linux/fs.h | 9 --------- 3 files changed, 28 deletions(-) diff --git a/fs/fcntl.c b/fs/fcntl.c index 9c6c6a3e2de5..f15d885b9796 100644 --- a/fs/fcntl.c +++ b/fs/fcntl.c @@ -291,22 +291,6 @@ static long fcntl_rw_hint(struct file *file, unsigned int cmd, u64 h; switch (cmd) { - case F_GET_FILE_RW_HINT: - h = file_write_hint(file); - if (copy_to_user(argp, &h, sizeof(*argp))) - return -EFAULT; - return 0; - case F_SET_FILE_RW_HINT: - if (copy_from_user(&h, argp, sizeof(h))) - return -EFAULT; - hint = (enum rw_hint) h; - if (!rw_hint_valid(hint)) - return -EINVAL; - - spin_lock(&file->f_lock); - file->f_write_hint = hint; - spin_unlock(&file->f_lock); - return 0; case F_GET_RW_HINT: h = inode->i_write_hint; if (copy_to_user(argp, &h, sizeof(*argp))) @@ -431,8 +415,6 @@ static long do_fcntl(int fd, unsigned int cmd, unsigned long arg, break; case F_GET_RW_HINT: case F_SET_RW_HINT: - case F_GET_FILE_RW_HINT: - case F_SET_FILE_RW_HINT: err = fcntl_rw_hint(filp, cmd, arg); break; default: diff --git a/fs/open.c b/fs/open.c index 9ff2f621b760..1315253e0247 100644 --- a/fs/open.c +++ b/fs/open.c @@ -835,7 +835,6 @@ static int do_dentry_open(struct file *f, likely(f->f_op->write || f->f_op->write_iter)) f->f_mode |= FMODE_CAN_WRITE; - f->f_write_hint = WRITE_LIFE_NOT_SET; f->f_flags &= ~(O_CREAT | O_EXCL | O_NOCTTY | O_TRUNC); file_ra_state_init(&f->f_ra, f->f_mapping->host->i_mapping); diff --git a/include/linux/fs.h b/include/linux/fs.h index d5658ac5d8c6..a1fc3b41cd82 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -966,7 +966,6 @@ struct file { * Must not be taken from IRQ context. */ spinlock_t f_lock; - enum rw_hint f_write_hint; atomic_long_t f_count; unsigned int f_flags; fmode_t f_mode; @@ -2214,14 +2213,6 @@ static inline bool HAS_UNMAPPED_ID(struct user_namespace *mnt_userns, !gid_valid(i_gid_into_mnt(mnt_userns, inode)); } -static inline enum rw_hint file_write_hint(struct file *file) -{ - if (file->f_write_hint != WRITE_LIFE_NOT_SET) - return file->f_write_hint; - - return file_inode(file)->i_write_hint; -} - static inline int iocb_flags(struct file *file); static inline void init_sync_kiocb(struct kiocb *kiocb, struct file *filp) From b3e664a7f449805aea492713223d7a5578325136 Mon Sep 17 00:00:00 2001 From: Rob Herring Date: Thu, 3 Mar 2022 11:45:14 -0600 Subject: [PATCH 299/370] dt-bindings: kbuild: Print a warning if yamllint is not found Running yamllint is effectively required for binding schemas, so print a warning if not found rather than silently skipping running it. Signed-off-by: Rob Herring Reviewed-by: Krzysztof Kozlowski Link: https://lore.kernel.org/r/20220303221417.2486268-1-robh@kernel.org --- Documentation/devicetree/bindings/Makefile | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/Makefile b/Documentation/devicetree/bindings/Makefile index 5138d10e0601..29b5dbd0807e 100644 --- a/Documentation/devicetree/bindings/Makefile +++ b/Documentation/devicetree/bindings/Makefile @@ -3,7 +3,8 @@ DT_DOC_CHECKER ?= dt-doc-validate DT_EXTRACT_EX ?= dt-extract-example DT_MK_SCHEMA ?= dt-mk-schema -DT_SCHEMA_LINT = $(shell which yamllint) +DT_SCHEMA_LINT := $(shell which yamllint || \ + echo "warning: python package 'yamllint' not installed, skipping" >&2) DT_SCHEMA_MIN_VERSION = 2021.2.1 From 21d5929ff230635400d138df66b0b8dd38893c25 Mon Sep 17 00:00:00 2001 From: Richard Zhu Date: Thu, 3 Mar 2022 15:50:05 +0800 Subject: [PATCH 300/370] dt-bindings: imx6q-pcie: Add iMX8MM PCIe compatible string Add the i.MX8MM PCIe compatible string. Signed-off-by: Richard Zhu Reviewed-by: Lucas Stach Signed-off-by: Rob Herring Link: https://lore.kernel.org/r/1646293805-18248-1-git-send-email-hongxing.zhu@nxp.com --- Documentation/devicetree/bindings/pci/fsl,imx6q-pcie.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/Documentation/devicetree/bindings/pci/fsl,imx6q-pcie.yaml b/Documentation/devicetree/bindings/pci/fsl,imx6q-pcie.yaml index 643a6333b07b..36c8a06d17a0 100644 --- a/Documentation/devicetree/bindings/pci/fsl,imx6q-pcie.yaml +++ b/Documentation/devicetree/bindings/pci/fsl,imx6q-pcie.yaml @@ -25,6 +25,7 @@ properties: - fsl,imx6qp-pcie - fsl,imx7d-pcie - fsl,imx8mq-pcie + - fsl,imx8mm-pcie reg: items: From 9be01ee2289bb3e8c8d17844076705b0b14b7164 Mon Sep 17 00:00:00 2001 From: Richard Zhu Date: Mon, 7 Mar 2022 17:07:31 +0800 Subject: [PATCH 301/370] dt-bindings: imx6q-pcie: Add iMX8MP PCIe compatible string Add i.MX8MP PCIe compatible string. Signed-off-by: Richard Zhu Signed-off-by: Rob Herring Link: https://lore.kernel.org/r/1646644054-24421-5-git-send-email-hongxing.zhu@nxp.com --- Documentation/devicetree/bindings/pci/fsl,imx6q-pcie.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/Documentation/devicetree/bindings/pci/fsl,imx6q-pcie.yaml b/Documentation/devicetree/bindings/pci/fsl,imx6q-pcie.yaml index 36c8a06d17a0..252e5b72aee0 100644 --- a/Documentation/devicetree/bindings/pci/fsl,imx6q-pcie.yaml +++ b/Documentation/devicetree/bindings/pci/fsl,imx6q-pcie.yaml @@ -26,6 +26,7 @@ properties: - fsl,imx7d-pcie - fsl,imx8mq-pcie - fsl,imx8mm-pcie + - fsl,imx8mp-pcie reg: items: From b48b563626655fe1d43a79e5ceb9d6367f851edc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20L=C3=A9ger?= Date: Fri, 4 Mar 2022 11:32:25 +0100 Subject: [PATCH 302/370] dt-bindings: net: mscc,vsc7514-switch: convert txt bindings to yaml MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Convert existing txt bindings to yaml format. Signed-off-by: Clément Léger Signed-off-by: Rob Herring Link: https://lore.kernel.org/r/20220304103225.111428-1-clement.leger@bootlin.com --- .../bindings/net/mscc,vsc7514-switch.yaml | 191 ++++++++++++++++++ .../devicetree/bindings/net/mscc-ocelot.txt | 83 -------- 2 files changed, 191 insertions(+), 83 deletions(-) create mode 100644 Documentation/devicetree/bindings/net/mscc,vsc7514-switch.yaml delete mode 100644 Documentation/devicetree/bindings/net/mscc-ocelot.txt diff --git a/Documentation/devicetree/bindings/net/mscc,vsc7514-switch.yaml b/Documentation/devicetree/bindings/net/mscc,vsc7514-switch.yaml new file mode 100644 index 000000000000..ee0a504bdb24 --- /dev/null +++ b/Documentation/devicetree/bindings/net/mscc,vsc7514-switch.yaml @@ -0,0 +1,191 @@ +# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/net/mscc,vsc7514-switch.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Microchip VSC7514 Ethernet switch controller + +maintainers: + - Vladimir Oltean + - Claudiu Manoil + - Alexandre Belloni + +description: | + Bindings for the Microchip VSC7514 switch driver + + The VSC7514 switch driver handles up to 11 ports and can inject/extract + packets using CPU. Additionally, PTP is supported as well as FDMA for faster + packet extraction/injection. + +properties: + $nodename: + pattern: "^switch@[0-9a-f]+$" + + compatible: + const: mscc,vsc7514-switch + + reg: + items: + - description: system target + - description: rewriter target + - description: qs target + - description: PTP target + - description: Port0 target + - description: Port1 target + - description: Port2 target + - description: Port3 target + - description: Port4 target + - description: Port5 target + - description: Port6 target + - description: Port7 target + - description: Port8 target + - description: Port9 target + - description: Port10 target + - description: QSystem target + - description: Analyzer target + - description: S0 target + - description: S1 target + - description: S2 target + - description: fdma target + + reg-names: + items: + - const: sys + - const: rew + - const: qs + - const: ptp + - const: port0 + - const: port1 + - const: port2 + - const: port3 + - const: port4 + - const: port5 + - const: port6 + - const: port7 + - const: port8 + - const: port9 + - const: port10 + - const: qsys + - const: ana + - const: s0 + - const: s1 + - const: s2 + - const: fdma + + interrupts: + minItems: 1 + items: + - description: PTP ready + - description: register based extraction + - description: frame dma based extraction + + interrupt-names: + minItems: 1 + items: + - const: ptp_rdy + - const: xtr + - const: fdma + + ethernet-ports: + type: object + + properties: + '#address-cells': + const: 1 + '#size-cells': + const: 0 + + additionalProperties: false + + patternProperties: + "^port@[0-9a-f]+$": + type: object + description: Ethernet ports handled by the switch + + $ref: ethernet-controller.yaml# + + unevaluatedProperties: false + + properties: + reg: + description: Switch port number + + phy-handle: true + + phy-mode: true + + fixed-link: true + + mac-address: true + + required: + - reg + - phy-mode + + oneOf: + - required: + - phy-handle + - required: + - fixed-link + +required: + - compatible + - reg + - reg-names + - interrupts + - interrupt-names + - ethernet-ports + +additionalProperties: false + +examples: + - | + switch@1010000 { + compatible = "mscc,vsc7514-switch"; + reg = <0x1010000 0x10000>, + <0x1030000 0x10000>, + <0x1080000 0x100>, + <0x10e0000 0x10000>, + <0x11e0000 0x100>, + <0x11f0000 0x100>, + <0x1200000 0x100>, + <0x1210000 0x100>, + <0x1220000 0x100>, + <0x1230000 0x100>, + <0x1240000 0x100>, + <0x1250000 0x100>, + <0x1260000 0x100>, + <0x1270000 0x100>, + <0x1280000 0x100>, + <0x1800000 0x80000>, + <0x1880000 0x10000>, + <0x1040000 0x10000>, + <0x1050000 0x10000>, + <0x1060000 0x10000>, + <0x1a0 0x1c4>; + reg-names = "sys", "rew", "qs", "ptp", "port0", "port1", + "port2", "port3", "port4", "port5", "port6", + "port7", "port8", "port9", "port10", "qsys", + "ana", "s0", "s1", "s2", "fdma"; + interrupts = <18 21 16>; + interrupt-names = "ptp_rdy", "xtr", "fdma"; + + ethernet-ports { + #address-cells = <1>; + #size-cells = <0>; + + port0: port@0 { + reg = <0>; + phy-handle = <&phy0>; + phy-mode = "internal"; + }; + port1: port@1 { + reg = <1>; + phy-handle = <&phy1>; + phy-mode = "internal"; + }; + }; + }; + +... diff --git a/Documentation/devicetree/bindings/net/mscc-ocelot.txt b/Documentation/devicetree/bindings/net/mscc-ocelot.txt deleted file mode 100644 index 3b6290b45ce5..000000000000 --- a/Documentation/devicetree/bindings/net/mscc-ocelot.txt +++ /dev/null @@ -1,83 +0,0 @@ -Microsemi Ocelot network Switch -=============================== - -The Microsemi Ocelot network switch can be found on Microsemi SoCs (VSC7513, -VSC7514) - -Required properties: -- compatible: Should be "mscc,vsc7514-switch" -- reg: Must contain an (offset, length) pair of the register set for each - entry in reg-names. -- reg-names: Must include the following entries: - - "sys" - - "rew" - - "qs" - - "ptp" (optional due to backward compatibility) - - "qsys" - - "ana" - - "portX" with X from 0 to the number of last port index available on that - switch -- interrupts: Should contain the switch interrupts for frame extraction, - frame injection and PTP ready. -- interrupt-names: should contain the interrupt names: "xtr", "inj". Can contain - "ptp_rdy" which is optional due to backward compatibility. -- ethernet-ports: A container for child nodes representing switch ports. - -The ethernet-ports container has the following properties - -Required properties: - -- #address-cells: Must be 1 -- #size-cells: Must be 0 - -Each port node must have the following mandatory properties: -- reg: Describes the port address in the switch - -Port nodes may also contain the following optional standardised -properties, described in binding documents: - -- phy-handle: Phandle to a PHY on an MDIO bus. See - Documentation/devicetree/bindings/net/ethernet.txt for details. - -Example: - - switch@1010000 { - compatible = "mscc,vsc7514-switch"; - reg = <0x1010000 0x10000>, - <0x1030000 0x10000>, - <0x1080000 0x100>, - <0x10e0000 0x10000>, - <0x11e0000 0x100>, - <0x11f0000 0x100>, - <0x1200000 0x100>, - <0x1210000 0x100>, - <0x1220000 0x100>, - <0x1230000 0x100>, - <0x1240000 0x100>, - <0x1250000 0x100>, - <0x1260000 0x100>, - <0x1270000 0x100>, - <0x1280000 0x100>, - <0x1800000 0x80000>, - <0x1880000 0x10000>; - reg-names = "sys", "rew", "qs", "ptp", "port0", "port1", - "port2", "port3", "port4", "port5", "port6", - "port7", "port8", "port9", "port10", "qsys", - "ana"; - interrupts = <18 21 22>; - interrupt-names = "ptp_rdy", "xtr", "inj"; - - ethernet-ports { - #address-cells = <1>; - #size-cells = <0>; - - port0: port@0 { - reg = <0>; - phy-handle = <&phy0>; - }; - port1: port@1 { - reg = <1>; - phy-handle = <&phy1>; - }; - }; - }; From 6853fece628c5a968e4c264d26a4f7750de42199 Mon Sep 17 00:00:00 2001 From: Tom Rix Date: Wed, 9 Mar 2022 14:23:02 -0800 Subject: [PATCH 303/370] dt-bindings: clk: cleanup comments For spdx, first line /* */ for *.h, change tab to space Replacements devider to divider Comunications to Communications periphrals to peripherals supportted to supported wich to which Documentatoin to Documentation Signed-off-by: Tom Rix Signed-off-by: Rob Herring Link: https://lore.kernel.org/r/20220309222302.1114561-1-trix@redhat.com --- include/dt-bindings/clock/alphascale,asm9260.h | 2 +- include/dt-bindings/clock/axis,artpec6-clkctrl.h | 2 +- include/dt-bindings/clock/boston-clock.h | 3 +-- include/dt-bindings/clock/marvell,mmp2.h | 4 ++-- include/dt-bindings/clock/marvell,pxa168.h | 4 ++-- include/dt-bindings/clock/marvell,pxa910.h | 4 ++-- include/dt-bindings/clock/nuvoton,npcm7xx-clock.h | 2 +- include/dt-bindings/clock/stm32fx-clock.h | 4 ++-- include/dt-bindings/clock/stratix10-clock.h | 2 +- 9 files changed, 13 insertions(+), 14 deletions(-) diff --git a/include/dt-bindings/clock/alphascale,asm9260.h b/include/dt-bindings/clock/alphascale,asm9260.h index d3871c63308b..f53f8b16883d 100644 --- a/include/dt-bindings/clock/alphascale,asm9260.h +++ b/include/dt-bindings/clock/alphascale,asm9260.h @@ -55,7 +55,7 @@ #define CLKID_AHB_I2S1 45 #define CLKID_AHB_MAC1 46 -/* devider */ +/* divider */ #define CLKID_SYS_CPU 47 #define CLKID_SYS_AHB 48 #define CLKID_SYS_I2S0M 49 diff --git a/include/dt-bindings/clock/axis,artpec6-clkctrl.h b/include/dt-bindings/clock/axis,artpec6-clkctrl.h index b1f4971642e6..14e424a7c08c 100644 --- a/include/dt-bindings/clock/axis,artpec6-clkctrl.h +++ b/include/dt-bindings/clock/axis,artpec6-clkctrl.h @@ -2,7 +2,7 @@ /* * ARTPEC-6 clock controller indexes * - * Copyright 2016 Axis Comunications AB. + * Copyright 2016 Axis Communications AB. */ #ifndef DT_BINDINGS_CLK_ARTPEC6_CLKCTRL_H diff --git a/include/dt-bindings/clock/boston-clock.h b/include/dt-bindings/clock/boston-clock.h index a6f009821137..38140fa87b09 100644 --- a/include/dt-bindings/clock/boston-clock.h +++ b/include/dt-bindings/clock/boston-clock.h @@ -1,7 +1,6 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Copyright (C) 2016 Imagination Technologies - * - * SPDX-License-Identifier: GPL-2.0 */ #ifndef __DT_BINDINGS_CLOCK_BOSTON_CLOCK_H__ diff --git a/include/dt-bindings/clock/marvell,mmp2.h b/include/dt-bindings/clock/marvell,mmp2.h index 87f5ad5df72f..f0819d66b230 100644 --- a/include/dt-bindings/clock/marvell,mmp2.h +++ b/include/dt-bindings/clock/marvell,mmp2.h @@ -32,7 +32,7 @@ #define MMP2_CLK_I2S0 31 #define MMP2_CLK_I2S1 32 -/* apb periphrals */ +/* apb peripherals */ #define MMP2_CLK_TWSI0 60 #define MMP2_CLK_TWSI1 61 #define MMP2_CLK_TWSI2 62 @@ -60,7 +60,7 @@ #define MMP3_CLK_THERMAL2 84 #define MMP3_CLK_THERMAL3 85 -/* axi periphrals */ +/* axi peripherals */ #define MMP2_CLK_SDH0 101 #define MMP2_CLK_SDH1 102 #define MMP2_CLK_SDH2 103 diff --git a/include/dt-bindings/clock/marvell,pxa168.h b/include/dt-bindings/clock/marvell,pxa168.h index caf90436b848..db2b41f1b127 100644 --- a/include/dt-bindings/clock/marvell,pxa168.h +++ b/include/dt-bindings/clock/marvell,pxa168.h @@ -23,7 +23,7 @@ #define PXA168_CLK_UART_PLL 27 #define PXA168_CLK_USB_PLL 28 -/* apb periphrals */ +/* apb peripherals */ #define PXA168_CLK_TWSI0 60 #define PXA168_CLK_TWSI1 61 #define PXA168_CLK_TWSI2 62 @@ -45,7 +45,7 @@ #define PXA168_CLK_SSP4 78 #define PXA168_CLK_TIMER 79 -/* axi periphrals */ +/* axi peripherals */ #define PXA168_CLK_DFC 100 #define PXA168_CLK_SDH0 101 #define PXA168_CLK_SDH1 102 diff --git a/include/dt-bindings/clock/marvell,pxa910.h b/include/dt-bindings/clock/marvell,pxa910.h index 7bf46238946e..c9018ab354d0 100644 --- a/include/dt-bindings/clock/marvell,pxa910.h +++ b/include/dt-bindings/clock/marvell,pxa910.h @@ -23,7 +23,7 @@ #define PXA910_CLK_UART_PLL 27 #define PXA910_CLK_USB_PLL 28 -/* apb periphrals */ +/* apb peripherals */ #define PXA910_CLK_TWSI0 60 #define PXA910_CLK_TWSI1 61 #define PXA910_CLK_TWSI2 62 @@ -43,7 +43,7 @@ #define PXA910_CLK_TIMER0 76 #define PXA910_CLK_TIMER1 77 -/* axi periphrals */ +/* axi peripherals */ #define PXA910_CLK_DFC 100 #define PXA910_CLK_SDH0 101 #define PXA910_CLK_SDH1 102 diff --git a/include/dt-bindings/clock/nuvoton,npcm7xx-clock.h b/include/dt-bindings/clock/nuvoton,npcm7xx-clock.h index f21522605b94..3e0a9b68933d 100644 --- a/include/dt-bindings/clock/nuvoton,npcm7xx-clock.h +++ b/include/dt-bindings/clock/nuvoton,npcm7xx-clock.h @@ -1,7 +1,7 @@ /* SPDX-License-Identifier: GPL-2.0 */ /* * Nuvoton NPCM7xx Clock Generator binding - * clock binding number for all clocks supportted by nuvoton,npcm7xx-clk + * clock binding number for all clocks supported by nuvoton,npcm7xx-clk * * Copyright (C) 2018 Nuvoton Technologies tali.perry@nuvoton.com * diff --git a/include/dt-bindings/clock/stm32fx-clock.h b/include/dt-bindings/clock/stm32fx-clock.h index 1cc89c548578..e5dad050d518 100644 --- a/include/dt-bindings/clock/stm32fx-clock.h +++ b/include/dt-bindings/clock/stm32fx-clock.h @@ -7,10 +7,10 @@ */ /* - * List of clocks wich are not derived from system clock (SYSCLOCK) + * List of clocks which are not derived from system clock (SYSCLOCK) * * The index of these clocks is the secondary index of DT bindings - * (see Documentatoin/devicetree/bindings/clock/st,stm32-rcc.txt) + * (see Documentation/devicetree/bindings/clock/st,stm32-rcc.txt) * * e.g: ; diff --git a/include/dt-bindings/clock/stratix10-clock.h b/include/dt-bindings/clock/stratix10-clock.h index 08b98e20b7cc..636498f9e08e 100644 --- a/include/dt-bindings/clock/stratix10-clock.h +++ b/include/dt-bindings/clock/stratix10-clock.h @@ -1,4 +1,4 @@ -/* SPDX-License-Identifier: GPL-2.0 */ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Copyright (C) 2017, Intel Corporation */ From 7ea75dd386be6fc15763c4adba67b35e5f051b70 Mon Sep 17 00:00:00 2001 From: Sergiu Moga Date: Thu, 10 Mar 2022 13:45:52 +0200 Subject: [PATCH 304/370] dt-bindings: i2c: convert i2c-at91 to json-schema Convert I2C binding for Atmel/Microchip SoCs to Device Tree Schema format. Signed-off-by: Sergiu Moga Signed-off-by: Rob Herring Link: https://lore.kernel.org/r/20220310114553.184763-3-sergiu.moga@microchip.com --- .../bindings/i2c/atmel,at91sam-i2c.yaml | 140 ++++++++++++++++++ .../devicetree/bindings/i2c/i2c-at91.txt | 82 ---------- 2 files changed, 140 insertions(+), 82 deletions(-) create mode 100644 Documentation/devicetree/bindings/i2c/atmel,at91sam-i2c.yaml delete mode 100644 Documentation/devicetree/bindings/i2c/i2c-at91.txt diff --git a/Documentation/devicetree/bindings/i2c/atmel,at91sam-i2c.yaml b/Documentation/devicetree/bindings/i2c/atmel,at91sam-i2c.yaml new file mode 100644 index 000000000000..a64b7d0ce6bf --- /dev/null +++ b/Documentation/devicetree/bindings/i2c/atmel,at91sam-i2c.yaml @@ -0,0 +1,140 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +# Copyright (C) 2022 Microchip Technology, Inc. and its subsidiaries +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/i2c/atmel,at91sam-i2c.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: I2C for Atmel/Microchip platforms + +maintainers: + - Alexandre Belloni + +properties: + compatible: + enum: + - atmel,at91rm9200-i2c + - atmel,at91sam9261-i2c + - atmel,at91sam9260-i2c + - atmel,at91sam9g20-i2c + - atmel,at91sam9g10-i2c + - atmel,at91sam9x5-i2c + - atmel,sama5d4-i2c + - atmel,sama5d2-i2c + - microchip,sam9x60-i2c + + reg: + maxItems: 1 + + interrupts: + maxItems: 1 + + "#address-cells": + const: 1 + + "#size-cells": + const: 0 + + clocks: + maxItems: 1 + + clock-frequency: + default: 100000 + + dmas: + items: + - description: TX DMA Channel Specifier + - description: RX DMA Channel Specifier + + dma-names: + items: + - const: tx + - const: rx + + atmel,fifo-size: + $ref: /schemas/types.yaml#/definitions/uint32 + description: | + Maximum number of data the RX and TX FIFOs can store for + FIFO capable I2C controllers. + + scl-gpios: true + + sda-gpios: true + +required: + - compatible + - reg + - interrupts + - "#address-cells" + - "#size-cells" + - clocks + +allOf: + - $ref: "i2c-controller.yaml" + - if: + properties: + compatible: + contains: + enum: + - atmel,sama5d4-i2c + - atmel,sama5d2-i2c + - microchip,sam9x60-i2c + then: + properties: + i2c-sda-hold-time-ns: + description: + TWD hold time + maxItems: 1 + +unevaluatedProperties: false + +examples: + - | + #include + #include + #include + + i2c0: i2c@fff84000 { + compatible = "atmel,at91sam9g20-i2c"; + reg = <0xfff84000 0x100>; + interrupts = <12 IRQ_TYPE_LEVEL_HIGH 6>; + #address-cells = <1>; + #size-cells = <0>; + clocks = <&twi0_clk>; + clock-frequency = <400000>; + + eeprom@50 { + compatible = "atmel,24c512"; + reg = <0x50>; + pagesize = <128>; + }; + }; + + i2c1: i2c@f8034600 { + compatible = "atmel,sama5d2-i2c"; + reg = <0xf8034600 0x100>; + interrupts = <19 IRQ_TYPE_LEVEL_HIGH 7>; + dmas = <&dma0 + (AT91_XDMAC_DT_MEM_IF(0) | AT91_XDMAC_DT_PER_IF(1)) + AT91_XDMAC_DT_PERID(11)>, + <&dma0 + (AT91_XDMAC_DT_MEM_IF(0) | AT91_XDMAC_DT_PER_IF(1)) + AT91_XDMAC_DT_PERID(12)>; + dma-names = "tx", "rx"; + #address-cells = <1>; + #size-cells = <0>; + clocks = <&flx0>; + atmel,fifo-size = <16>; + i2c-sda-hold-time-ns = <336>; + pinctrl-names = "default", "gpio"; + pinctrl-0 = <&pinctrl_i2c0>; + pinctrl-1 = <&pinctrl_i2c0_gpio>; + sda-gpios = <&pioA 30 GPIO_ACTIVE_HIGH>; + scl-gpios = <&pioA 31 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>; + + eeprom@54 { + compatible = "atmel,24c02"; + reg = <0x54>; + pagesize = <16>; + }; + }; diff --git a/Documentation/devicetree/bindings/i2c/i2c-at91.txt b/Documentation/devicetree/bindings/i2c/i2c-at91.txt deleted file mode 100644 index 2015f50aed0f..000000000000 --- a/Documentation/devicetree/bindings/i2c/i2c-at91.txt +++ /dev/null @@ -1,82 +0,0 @@ -I2C for Atmel platforms - -Required properties : -- compatible : Must be one of: - "atmel,at91rm9200-i2c", - "atmel,at91sam9261-i2c", - "atmel,at91sam9260-i2c", - "atmel,at91sam9g20-i2c", - "atmel,at91sam9g10-i2c", - "atmel,at91sam9x5-i2c", - "atmel,sama5d4-i2c", - "atmel,sama5d2-i2c", - "microchip,sam9x60-i2c". -- 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>; -- clocks: phandles to input clocks. - -Optional properties: -- clock-frequency: Desired I2C bus frequency in Hz, otherwise defaults to 100000 -- dmas: A list of two dma specifiers, one for each entry in dma-names. -- dma-names: should contain "tx" and "rx". -- atmel,fifo-size: maximum number of data the RX and TX FIFOs can store for FIFO - capable I2C controllers. -- i2c-sda-hold-time-ns: TWD hold time, only available for: - "atmel,sama5d4-i2c", - "atmel,sama5d2-i2c", - "microchip,sam9x60-i2c". -- scl-gpios: specify the gpio related to SCL pin -- sda-gpios: specify the gpio related to SDA pin -- pinctrl: add extra pinctrl to configure i2c pins to gpio function for i2c - bus recovery, call it "gpio" state -- Child nodes conforming to i2c bus binding - - -Examples : - -i2c0: i2c@fff84000 { - compatible = "atmel,at91sam9g20-i2c"; - reg = <0xfff84000 0x100>; - interrupts = <12 4 6>; - #address-cells = <1>; - #size-cells = <0>; - clocks = <&twi0_clk>; - clock-frequency = <400000>; - - 24c512@50 { - compatible = "atmel,24c512"; - reg = <0x50>; - pagesize = <128>; - } -} - -i2c0: i2c@f8034600 { - compatible = "atmel,sama5d2-i2c"; - reg = <0xf8034600 0x100>; - interrupts = <19 IRQ_TYPE_LEVEL_HIGH 7>; - dmas = <&dma0 - (AT91_XDMAC_DT_MEM_IF(0) | AT91_XDMAC_DT_PER_IF(1)) - AT91_XDMAC_DT_PERID(11)>, - <&dma0 - (AT91_XDMAC_DT_MEM_IF(0) | AT91_XDMAC_DT_PER_IF(1)) - AT91_XDMAC_DT_PERID(12)>; - dma-names = "tx", "rx"; - #address-cells = <1>; - #size-cells = <0>; - clocks = <&flx0>; - atmel,fifo-size = <16>; - i2c-sda-hold-time-ns = <336>; - pinctrl-names = "default", "gpio"; - pinctrl-0 = <&pinctrl_i2c0>; - pinctrl-1 = <&pinctrl_i2c0_gpio>; - sda-gpios = <&pioA 30 GPIO_ACTIVE_HIGH>; - scl-gpios = <&pioA 31 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>; - - wm8731: wm8731@1a { - compatible = "wm8731"; - reg = <0x1a>; - }; -}; From 2a4013c0cc29929d957119972c36b0368a3b4023 Mon Sep 17 00:00:00 2001 From: Sergiu Moga Date: Thu, 10 Mar 2022 13:45:53 +0200 Subject: [PATCH 305/370] dt-bindings: i2c: at91: Add SAMA7G5 compatible strings list Add compatible strings list for SAMA7G5. Signed-off-by: Sergiu Moga Signed-off-by: Rob Herring Link: https://lore.kernel.org/r/20220310114553.184763-4-sergiu.moga@microchip.com --- .../bindings/i2c/atmel,at91sam-i2c.yaml | 26 ++++++++++++------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/Documentation/devicetree/bindings/i2c/atmel,at91sam-i2c.yaml b/Documentation/devicetree/bindings/i2c/atmel,at91sam-i2c.yaml index a64b7d0ce6bf..ea2303c0e143 100644 --- a/Documentation/devicetree/bindings/i2c/atmel,at91sam-i2c.yaml +++ b/Documentation/devicetree/bindings/i2c/atmel,at91sam-i2c.yaml @@ -12,16 +12,21 @@ maintainers: properties: compatible: - enum: - - atmel,at91rm9200-i2c - - atmel,at91sam9261-i2c - - atmel,at91sam9260-i2c - - atmel,at91sam9g20-i2c - - atmel,at91sam9g10-i2c - - atmel,at91sam9x5-i2c - - atmel,sama5d4-i2c - - atmel,sama5d2-i2c - - microchip,sam9x60-i2c + oneOf: + - items: + - enum: + - atmel,at91rm9200-i2c + - atmel,at91sam9261-i2c + - atmel,at91sam9260-i2c + - atmel,at91sam9g20-i2c + - atmel,at91sam9g10-i2c + - atmel,at91sam9x5-i2c + - atmel,sama5d4-i2c + - atmel,sama5d2-i2c + - microchip,sam9x60-i2c + - items: + - const: microchip,sama7g5-i2c + - const: microchip,sam9x60-i2c reg: maxItems: 1 @@ -79,6 +84,7 @@ allOf: - atmel,sama5d4-i2c - atmel,sama5d2-i2c - microchip,sam9x60-i2c + - microchip,sama7g5-i2c then: properties: i2c-sda-hold-time-ns: From 1d9a770bc8f080267bba6b2169c87efb61f245c1 Mon Sep 17 00:00:00 2001 From: Rob Herring Date: Wed, 9 Mar 2022 19:35:52 -0600 Subject: [PATCH 306/370] dt-bindings: arm: Convert QEMU fw-cfg to DT schema Convert the QEMU fw-cfg binding to DT schema format. As this binding is also used on Risc-V now, drop any architecture references and move to a common location. The fw-cfg interface has also gained some DMA support which is coherent, so add the missing 'dma-coherent'. Signed-off-by: Rob Herring Reviewed-by: Krzysztof Kozlowski Acked-by: Laszlo Ersek Link: https://lore.kernel.org/r/20220310013552.549590-1-robh@kernel.org --- .../devicetree/bindings/arm/fw-cfg.txt | 38 ------------- .../bindings/firmware/qemu,fw-cfg-mmio.yaml | 54 +++++++++++++++++++ 2 files changed, 54 insertions(+), 38 deletions(-) delete mode 100644 Documentation/devicetree/bindings/arm/fw-cfg.txt create mode 100644 Documentation/devicetree/bindings/firmware/qemu,fw-cfg-mmio.yaml diff --git a/Documentation/devicetree/bindings/arm/fw-cfg.txt b/Documentation/devicetree/bindings/arm/fw-cfg.txt deleted file mode 100644 index fd54e1db2156..000000000000 --- a/Documentation/devicetree/bindings/arm/fw-cfg.txt +++ /dev/null @@ -1,38 +0,0 @@ -* QEMU Firmware Configuration bindings for ARM - -QEMU's arm-softmmu and aarch64-softmmu emulation / virtualization targets -provide the following Firmware Configuration interface on the "virt" machine -type: - -- A write-only, 16-bit wide selector (or control) register, -- a read-write, 64-bit wide data register. - -QEMU exposes the control and data register to ARM guests as memory mapped -registers; their location is communicated to the guest's UEFI firmware in the -DTB that QEMU places at the bottom of the guest's DRAM. - -The authoritative guest-side hardware interface documentation to the fw_cfg -device can be found in "docs/specs/fw_cfg.txt" in the QEMU source tree. - - -Required properties: - -- compatible: "qemu,fw-cfg-mmio". - -- reg: the MMIO region used by the device. - * Bytes 0x0 to 0x7 cover the data register. - * Bytes 0x8 to 0x9 cover the selector register. - * Further registers may be appended to the region in case of future interface - revisions / feature bits. - -Example: - -/ { - #size-cells = <0x2>; - #address-cells = <0x2>; - - fw-cfg@9020000 { - compatible = "qemu,fw-cfg-mmio"; - reg = <0x0 0x9020000 0x0 0xa>; - }; -}; diff --git a/Documentation/devicetree/bindings/firmware/qemu,fw-cfg-mmio.yaml b/Documentation/devicetree/bindings/firmware/qemu,fw-cfg-mmio.yaml new file mode 100644 index 000000000000..fcf0011b8e6d --- /dev/null +++ b/Documentation/devicetree/bindings/firmware/qemu,fw-cfg-mmio.yaml @@ -0,0 +1,54 @@ +# SPDX-License-Identifier: GPL-2.0 +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/firmware/qemu,fw-cfg-mmio.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: QEMU Firmware Configuration bindings + +maintainers: + - Rob Herring + +description: | + Various QEMU emulation / virtualization targets provide the following + Firmware Configuration interface on the "virt" machine type: + + - A write-only, 16-bit wide selector (or control) register, + - a read-write, 64-bit wide data register. + + QEMU exposes the control and data register to guests as memory mapped + registers; their location is communicated to the guest's UEFI firmware in the + DTB that QEMU places at the bottom of the guest's DRAM. + + The authoritative guest-side hardware interface documentation to the fw_cfg + device can be found in "docs/specs/fw_cfg.txt" in the QEMU source tree. + + +properties: + compatible: + const: qemu,fw-cfg-mmio + + reg: + maxItems: 1 + description: | + * Bytes 0x0 to 0x7 cover the data register. + * Bytes 0x8 to 0x9 cover the selector register. + * Further registers may be appended to the region in case of future interface + revisions / feature bits. + + dma-coherent: true + +required: + - compatible + - reg + +additionalProperties: false + +examples: + - | + + fw-cfg@9020000 { + compatible = "qemu,fw-cfg-mmio"; + reg = <0x9020000 0xa>; + }; +... From 37de81210f74c909e3d42c90fea3497a00ac618b Mon Sep 17 00:00:00 2001 From: Rob Herring Date: Wed, 9 Mar 2022 20:12:24 -0600 Subject: [PATCH 307/370] dt-bindings: Add QEMU virt machine compatible The top level QEMU virt machine compatible, linux,dummy-virt, has been in use for a long time, but never documented. Add a schema for it. Signed-off-by: Rob Herring Reviewed-by: Krzysztof Kozlowski Link: https://lore.kernel.org/r/20220310021224.599398-1-robh@kernel.org --- .../bindings/arm/linux,dummy-virt.yaml | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 Documentation/devicetree/bindings/arm/linux,dummy-virt.yaml diff --git a/Documentation/devicetree/bindings/arm/linux,dummy-virt.yaml b/Documentation/devicetree/bindings/arm/linux,dummy-virt.yaml new file mode 100644 index 000000000000..c7c5eb48fc7e --- /dev/null +++ b/Documentation/devicetree/bindings/arm/linux,dummy-virt.yaml @@ -0,0 +1,20 @@ +# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/arm/linux,dummy-virt.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: QEMU virt machine + +maintainers: + - Rob Herring + +properties: + $nodename: + const: "/" + compatible: + const: linux,dummy-virt + +additionalProperties: true + +... From 2783a7f56f9980f61ca809b826bcd14dc77eb7b9 Mon Sep 17 00:00:00 2001 From: Rob Herring Date: Thu, 10 Mar 2022 10:05:12 -0600 Subject: [PATCH 308/370] dt-bindings: kbuild: Pass DT_SCHEMA_FILES to dt-validate In preparation for supporting validation of DTB files, the full processed schema will always be needed in order to extract type information from it. Therefore, the processed schema containing only what DT_SCHEMA_FILES specifies won't work. Instead, dt-validate has gained an option, -l or --limit, to specify which schema(s) to use for validation. As the command line option is new, we the minimum dtschema version must be updated. Cc: Masahiro Yamada Signed-off-by: Rob Herring Link: https://lore.kernel.org/r/20220310160513.1708182-2-robh@kernel.org --- Documentation/devicetree/bindings/Makefile | 28 +++------------------- scripts/Makefile.lib | 5 ++-- 2 files changed, 5 insertions(+), 28 deletions(-) diff --git a/Documentation/devicetree/bindings/Makefile b/Documentation/devicetree/bindings/Makefile index 29b5dbd0807e..2716f7b9e25e 100644 --- a/Documentation/devicetree/bindings/Makefile +++ b/Documentation/devicetree/bindings/Makefile @@ -6,7 +6,7 @@ DT_MK_SCHEMA ?= dt-mk-schema DT_SCHEMA_LINT := $(shell which yamllint || \ echo "warning: python package 'yamllint' not installed, skipping" >&2) -DT_SCHEMA_MIN_VERSION = 2021.2.1 +DT_SCHEMA_MIN_VERSION = 2022.3 PHONY += check_dtschema_version check_dtschema_version: @@ -25,9 +25,6 @@ quiet_cmd_extract_ex = DTEX $@ $(obj)/%.example.dts: $(src)/%.yaml check_dtschema_version FORCE $(call if_changed,extract_ex) -# Use full schemas when checking %.example.dts -DT_TMP_SCHEMA := $(obj)/processed-schema-examples.json - find_all_cmd = find $(srctree)/$(src) \( -name '*.yaml' ! \ -name 'processed-schema*' ! \ -name '*.example.dt.yaml' \) @@ -70,29 +67,10 @@ override DTC_FLAGS := \ # Disable undocumented compatible checks until warning free override DT_CHECKER_FLAGS ?= -$(obj)/processed-schema-examples.json: $(DT_DOCS) $(src)/.yamllint check_dtschema_version FORCE +$(obj)/processed-schema.json: $(DT_DOCS) $(src)/.yamllint check_dtschema_version FORCE $(call if_changed_rule,chkdt) -ifeq ($(DT_SCHEMA_FILES),) - -# Unless DT_SCHEMA_FILES is specified, use the full schema for dtbs_check too. -# Just copy processed-schema-examples.json - -$(obj)/processed-schema.json: $(obj)/processed-schema-examples.json FORCE - $(call if_changed,copy) - -else - -# If DT_SCHEMA_FILES is specified, use it for processed-schema.json - -$(obj)/processed-schema.json: DT_MK_SCHEMA_FLAGS := -u -$(obj)/processed-schema.json: $(CHK_DT_DOCS) check_dtschema_version FORCE - $(call if_changed,mk_schema) - -endif - -always-$(CHECK_DT_BINDING) += processed-schema-examples.json -always-$(CHECK_DTBS) += processed-schema.json +always-y += processed-schema.json always-$(CHECK_DT_BINDING) += $(patsubst $(srctree)/$(src)/%.yaml,%.example.dts, $(CHK_DT_DOCS)) always-$(CHECK_DT_BINDING) += $(patsubst $(srctree)/$(src)/%.yaml,%.example.dt.yaml, $(CHK_DT_DOCS)) diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib index 79be57fdd32a..c8c6f1745d03 100644 --- a/scripts/Makefile.lib +++ b/scripts/Makefile.lib @@ -361,10 +361,9 @@ $(multi-dtb-y): FORCE $(call multi_depend, $(multi-dtb-y), .dtb, -dtbs) DT_CHECKER ?= dt-validate -DT_CHECKER_FLAGS ?= $(if $(DT_SCHEMA_FILES),,-m) +DT_CHECKER_FLAGS ?= $(if $(DT_SCHEMA_FILES),-l $(DT_SCHEMA_FILES),-m) DT_BINDING_DIR := Documentation/devicetree/bindings -# DT_TMP_SCHEMA may be overridden from Documentation/devicetree/bindings/Makefile -DT_TMP_SCHEMA ?= $(objtree)/$(DT_BINDING_DIR)/processed-schema.json +DT_TMP_SCHEMA := $(objtree)/$(DT_BINDING_DIR)/processed-schema.json quiet_cmd_dtb_check = CHECK $@ cmd_dtb_check = $(DT_CHECKER) $(DT_CHECKER_FLAGS) -u $(srctree)/$(DT_BINDING_DIR) -p $(DT_TMP_SCHEMA) $@ From ef8795f3f1cef2b2d2cd5dfab3758a7601898bc9 Mon Sep 17 00:00:00 2001 From: Rob Herring Date: Thu, 10 Mar 2022 10:05:13 -0600 Subject: [PATCH 309/370] dt-bindings: kbuild: Use DTB files for validation Switch the DT validation to use DTB files directly instead of a DTS to YAML conversion. The original motivation for supporting validation on DTB files was to enable running validation on a running system (e.g. 'dt-validate /sys/firmware/fdt') or other cases where the original source DTS is not available. The YAML format was not without issues. Using DTBs with the schema type information solves some of those problems. The YAML format relies on the DTS source level information including bracketing of properties, size directives, and phandle tags all of which are lost in a DTB file. While standardizing the bracketing is a good thing, it does cause a lot of extra warnings and churn to fix them. Another issue has been signed types are not validated correctly as sign information is not propagated to YAML. Using the schema type information allows for proper handling of signed types. YAML also can't represent the full range of 64-bit integers as numbers are stored as floats by most/all parsers. The DTB validation works by decoding property values using the type information in the schemas themselves. The main corner case this does not work for is matrix types where neither dimension is fixed. For now, checking the dimensions in these cases are skipped. Signed-off-by: Rob Herring Tested-by: Geert Uytterhoeven Link: https://lore.kernel.org/r/20220310160513.1708182-3-robh@kernel.org --- Documentation/devicetree/bindings/Makefile | 7 +++---- .../devicetree/bindings/writing-schema.rst | 17 +++++----------- scripts/Makefile.lib | 20 +++++++------------ scripts/dtc/Makefile | 13 ------------ scripts/dtc/update-dtc-source.sh | 2 +- 5 files changed, 16 insertions(+), 43 deletions(-) diff --git a/Documentation/devicetree/bindings/Makefile b/Documentation/devicetree/bindings/Makefile index 2716f7b9e25e..e594e5898be0 100644 --- a/Documentation/devicetree/bindings/Makefile +++ b/Documentation/devicetree/bindings/Makefile @@ -26,8 +26,7 @@ $(obj)/%.example.dts: $(src)/%.yaml check_dtschema_version FORCE $(call if_changed,extract_ex) find_all_cmd = find $(srctree)/$(src) \( -name '*.yaml' ! \ - -name 'processed-schema*' ! \ - -name '*.example.dt.yaml' \) + -name 'processed-schema*' \) find_cmd = $(find_all_cmd) | grep -F "$(DT_SCHEMA_FILES)" CHK_DT_DOCS := $(shell $(find_cmd)) @@ -72,9 +71,9 @@ $(obj)/processed-schema.json: $(DT_DOCS) $(src)/.yamllint check_dtschema_version always-y += processed-schema.json always-$(CHECK_DT_BINDING) += $(patsubst $(srctree)/$(src)/%.yaml,%.example.dts, $(CHK_DT_DOCS)) -always-$(CHECK_DT_BINDING) += $(patsubst $(srctree)/$(src)/%.yaml,%.example.dt.yaml, $(CHK_DT_DOCS)) +always-$(CHECK_DT_BINDING) += $(patsubst $(srctree)/$(src)/%.yaml,%.example.dtb, $(CHK_DT_DOCS)) # Hack: avoid 'Argument list too long' error for 'make clean'. Remove most of # build artifacts here before they are processed by scripts/Makefile.clean clean-files = $(shell find $(obj) \( -name '*.example.dts' -o \ - -name '*.example.dt.yaml' \) -delete 2>/dev/null) + -name '*.example.dtb' \) -delete 2>/dev/null) diff --git a/Documentation/devicetree/bindings/writing-schema.rst b/Documentation/devicetree/bindings/writing-schema.rst index 3b00fe981494..95ecf55559e5 100644 --- a/Documentation/devicetree/bindings/writing-schema.rst +++ b/Documentation/devicetree/bindings/writing-schema.rst @@ -120,21 +120,14 @@ project can be installed with pip:: pip3 install dtschema +Note that 'dtschema' installation requires 'swig' and Python development files +installed first. On Debian/Ubuntu systems:: + + apt install swig python3-dev + Several executables (dt-doc-validate, dt-mk-schema, dt-validate) will be installed. Ensure they are in your PATH (~/.local/bin by default). -dtc must also be built with YAML output support enabled. This requires that -libyaml and its headers be installed on the host system. For some distributions -that involves installing the development package, such as: - -Debian:: - - apt-get install libyaml-dev - -Fedora:: - - dnf -y install libyaml-devel - Running checks ~~~~~~~~~~~~~~ diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib index c8c6f1745d03..9d5320a47ef8 100644 --- a/scripts/Makefile.lib +++ b/scripts/Makefile.lib @@ -87,11 +87,6 @@ base-dtb-y := $(foreach m, $(multi-dtb-y), $(firstword $(call suffix-search, $m, always-y += $(dtb-y) -ifneq ($(CHECK_DTBS),) -always-y += $(patsubst %.dtb,%.dt.yaml, $(real-dtb-y)) -always-y += $(patsubst %.dtbo,%.dt.yaml, $(real-dtb-y)) -endif - # Add subdir path extra-y := $(addprefix $(obj)/,$(extra-y)) @@ -347,12 +342,6 @@ cmd_dtc = $(HOSTCC) -E $(dtc_cpp_flags) -x assembler-with-cpp -o $(dtc-tmp) $< ; -d $(depfile).dtc.tmp $(dtc-tmp) ; \ cat $(depfile).pre.tmp $(depfile).dtc.tmp > $(depfile) -$(obj)/%.dtb: $(src)/%.dts $(DTC) FORCE - $(call if_changed_dep,dtc) - -$(obj)/%.dtbo: $(src)/%.dts $(DTC) FORCE - $(call if_changed_dep,dtc) - quiet_cmd_fdtoverlay = DTOVL $@ cmd_fdtoverlay = $(objtree)/scripts/dtc/fdtoverlay -o $@ -i $(real-prereqs) @@ -360,22 +349,27 @@ $(multi-dtb-y): FORCE $(call if_changed,fdtoverlay) $(call multi_depend, $(multi-dtb-y), .dtb, -dtbs) +ifneq ($(CHECK_DTBS)$(CHECK_DT_BINDING),) DT_CHECKER ?= dt-validate DT_CHECKER_FLAGS ?= $(if $(DT_SCHEMA_FILES),-l $(DT_SCHEMA_FILES),-m) DT_BINDING_DIR := Documentation/devicetree/bindings DT_TMP_SCHEMA := $(objtree)/$(DT_BINDING_DIR)/processed-schema.json quiet_cmd_dtb_check = CHECK $@ - cmd_dtb_check = $(DT_CHECKER) $(DT_CHECKER_FLAGS) -u $(srctree)/$(DT_BINDING_DIR) -p $(DT_TMP_SCHEMA) $@ + cmd_dtb_check = $(DT_CHECKER) $(DT_CHECKER_FLAGS) -u $(srctree)/$(DT_BINDING_DIR) -p $(DT_TMP_SCHEMA) $@ || true +endif define rule_dtc $(call cmd_and_fixdep,dtc) $(call cmd,dtb_check) endef -$(obj)/%.dt.yaml: $(src)/%.dts $(DTC) $(DT_TMP_SCHEMA) FORCE +$(obj)/%.dtb: $(src)/%.dts $(DTC) $(DT_TMP_SCHEMA) FORCE $(call if_changed_rule,dtc) +$(obj)/%.dtbo: $(src)/%.dts $(DTC) FORCE + $(call if_changed_dep,dtc) + dtc-tmp = $(subst $(comma),_,$(dot-target).dts.tmp) # Bzip2 diff --git a/scripts/dtc/Makefile b/scripts/dtc/Makefile index 1cba78e1dce6..4d32b9497da9 100644 --- a/scripts/dtc/Makefile +++ b/scripts/dtc/Makefile @@ -17,20 +17,7 @@ fdtoverlay-objs := $(libfdt) fdtoverlay.o util.o # Source files need to get at the userspace version of libfdt_env.h to compile HOST_EXTRACFLAGS += -I $(srctree)/$(src)/libfdt - -ifeq ($(shell pkg-config --exists yaml-0.1 2>/dev/null && echo yes),) -ifneq ($(CHECK_DT_BINDING)$(CHECK_DTBS),) -$(error dtc needs libyaml for DT schema validation support. \ - Install the necessary libyaml development package.) -endif HOST_EXTRACFLAGS += -DNO_YAML -else -dtc-objs += yamltree.o -# To include installed in a non-default path -HOSTCFLAGS_yamltree.o := $(shell pkg-config --cflags yaml-0.1) -# To link libyaml installed in a non-default path -HOSTLDLIBS_dtc := $(shell pkg-config --libs yaml-0.1) -endif # Generated files need one more search path to include headers in source tree HOSTCFLAGS_dtc-lexer.lex.o := -I $(srctree)/$(src) diff --git a/scripts/dtc/update-dtc-source.sh b/scripts/dtc/update-dtc-source.sh index 32ff17ffd089..94627541533e 100755 --- a/scripts/dtc/update-dtc-source.sh +++ b/scripts/dtc/update-dtc-source.sh @@ -32,7 +32,7 @@ DTC_UPSTREAM_PATH=`pwd`/../dtc DTC_LINUX_PATH=`pwd`/scripts/dtc DTC_SOURCE="checks.c data.c dtc.c dtc.h flattree.c fstree.c livetree.c srcpos.c \ - srcpos.h treesource.c util.c util.h version_gen.h yamltree.c \ + srcpos.h treesource.c util.c util.h version_gen.h \ dtc-lexer.l dtc-parser.y" LIBFDT_SOURCE="fdt.c fdt.h fdt_addresses.c fdt_empty_tree.c \ fdt_overlay.c fdt_ro.c fdt_rw.c fdt_strerror.c fdt_sw.c \ From 52c74d17d89c6e69f9b774cdd477517e62383f55 Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Thu, 3 Mar 2022 17:42:56 +0100 Subject: [PATCH 310/370] i2c: i801: Drop two outdated comments * Timeouts are reported even in interrupt mode since commit b3b8df97723d ("i2c: i801: Use wait_event_timeout to wait for interrupts") so drop the comment which claims this only happens in polled mode. * xact does not include the PEC bit, as the driver does not support software PEC. Signed-off-by: Jean Delvare Reviewed-by: Jarkko Nikula Signed-off-by: Wolfram Sang --- drivers/i2c/busses/i2c-i801.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/drivers/i2c/busses/i2c-i801.c b/drivers/i2c/busses/i2c-i801.c index 1fc006a1d532..ff706349bdfb 100644 --- a/drivers/i2c/busses/i2c-i801.c +++ b/drivers/i2c/busses/i2c-i801.c @@ -364,9 +364,6 @@ static int i801_check_post(struct i801_priv *priv, int status) /* * If the SMBus is still busy, we give up - * Note: This timeout condition only happens when using polling - * transactions. For interrupt operation, NAK/timeout is indicated by - * DEV_ERR. */ if (unlikely(status < 0)) { dev_err(&priv->pci_dev->dev, "Transaction timeout\n"); @@ -475,8 +472,6 @@ static int i801_transaction(struct i801_priv *priv, int xact) return i801_check_post(priv, result ? priv->status : -ETIMEDOUT); } - /* the current contents of SMBHSTCNT can be overwritten, since PEC, - * SMBSCMD are passed in xact */ outb_p(xact | SMBHSTCNT_START, SMBHSTCNT(priv)); status = i801_wait_intr(priv); From 0016a32f7591aec5413cf1f52b9ce522f1cae44f Mon Sep 17 00:00:00 2001 From: AngeloGioacchino Del Regno Date: Thu, 3 Mar 2022 10:15:47 +0100 Subject: [PATCH 311/370] i2c: mt65xx: Simplify with clk-bulk Since depending on the SoC or specific bus functionality some clocks may be optional, we cannot get the benefit of using devm_clk_bulk_get() but, by migrating to clk-bulk, we are able to remove the custom functions mtk_i2c_clock_enable() and mtk_i2c_clock_disable(), increasing common APIs usage, hence (lightly) decreasing kernel footprint. Signed-off-by: AngeloGioacchino Del Regno Reviewed-by: Qii Wang Signed-off-by: Wolfram Sang --- drivers/i2c/busses/i2c-mt65xx.c | 124 +++++++++++++------------------- 1 file changed, 51 insertions(+), 73 deletions(-) diff --git a/drivers/i2c/busses/i2c-mt65xx.c b/drivers/i2c/busses/i2c-mt65xx.c index 5bf7f965800d..7dde3b64766b 100644 --- a/drivers/i2c/busses/i2c-mt65xx.c +++ b/drivers/i2c/busses/i2c-mt65xx.c @@ -86,6 +86,27 @@ #define I2C_DRV_NAME "i2c-mt65xx" +/** + * enum i2c_mt65xx_clks - Clocks enumeration for MT65XX I2C + * + * @I2C_MT65XX_CLK_MAIN: main clock for i2c bus + * @I2C_MT65XX_CLK_DMA: DMA clock for i2c via DMA + * @I2C_MT65XX_CLK_PMIC: PMIC clock for i2c from PMIC + * @I2C_MT65XX_CLK_ARB: Arbitrator clock for i2c + * @I2C_MT65XX_CLK_MAX: Number of supported clocks + */ +enum i2c_mt65xx_clks { + I2C_MT65XX_CLK_MAIN = 0, + I2C_MT65XX_CLK_DMA, + I2C_MT65XX_CLK_PMIC, + I2C_MT65XX_CLK_ARB, + I2C_MT65XX_CLK_MAX +}; + +static const char * const i2c_mt65xx_clk_ids[I2C_MT65XX_CLK_MAX] = { + "main", "dma", "pmic", "arb" +}; + enum DMA_REGS_OFFSET { OFFSET_INT_FLAG = 0x0, OFFSET_INT_EN = 0x04, @@ -244,10 +265,7 @@ struct mtk_i2c { /* set in i2c probe */ void __iomem *base; /* i2c base addr */ void __iomem *pdmabase; /* dma base address*/ - struct clk *clk_main; /* main clock for i2c bus */ - struct clk *clk_dma; /* DMA clock for i2c via DMA */ - struct clk *clk_pmic; /* PMIC clock for i2c from PMIC */ - struct clk *clk_arb; /* Arbitrator clock for i2c */ + struct clk_bulk_data clocks[I2C_MT65XX_CLK_MAX]; /* clocks for i2c */ bool have_pmic; /* can use i2c pins from PMIC */ bool use_push_pull; /* IO config push-pull mode */ @@ -449,52 +467,6 @@ static void mtk_i2c_writew(struct mtk_i2c *i2c, u16 val, writew(val, i2c->base + i2c->dev_comp->regs[reg]); } -static int mtk_i2c_clock_enable(struct mtk_i2c *i2c) -{ - int ret; - - ret = clk_prepare_enable(i2c->clk_dma); - if (ret) - return ret; - - ret = clk_prepare_enable(i2c->clk_main); - if (ret) - goto err_main; - - if (i2c->have_pmic) { - ret = clk_prepare_enable(i2c->clk_pmic); - if (ret) - goto err_pmic; - } - - if (i2c->clk_arb) { - ret = clk_prepare_enable(i2c->clk_arb); - if (ret) - goto err_arb; - } - - return 0; - -err_arb: - clk_disable_unprepare(i2c->clk_pmic); -err_pmic: - clk_disable_unprepare(i2c->clk_main); -err_main: - clk_disable_unprepare(i2c->clk_dma); - - return ret; -} - -static void mtk_i2c_clock_disable(struct mtk_i2c *i2c) -{ - clk_disable_unprepare(i2c->clk_arb); - - clk_disable_unprepare(i2c->clk_pmic); - - clk_disable_unprepare(i2c->clk_main); - clk_disable_unprepare(i2c->clk_dma); -} - static void mtk_i2c_init_hw(struct mtk_i2c *i2c) { u16 control_reg; @@ -1191,7 +1163,7 @@ static int mtk_i2c_transfer(struct i2c_adapter *adap, int left_num = num; struct mtk_i2c *i2c = i2c_get_adapdata(adap); - ret = mtk_i2c_clock_enable(i2c); + ret = clk_bulk_prepare_enable(I2C_MT65XX_CLK_MAX, i2c->clocks); if (ret) return ret; @@ -1245,7 +1217,7 @@ static int mtk_i2c_transfer(struct i2c_adapter *adap, ret = num; err_exit: - mtk_i2c_clock_disable(i2c); + clk_bulk_disable_unprepare(I2C_MT65XX_CLK_MAX, i2c->clocks); return ret; } @@ -1323,9 +1295,8 @@ static int mtk_i2c_probe(struct platform_device *pdev) { int ret = 0; struct mtk_i2c *i2c; - struct clk *clk; struct resource *res; - int irq; + int i, irq, speed_clk; i2c = devm_kzalloc(&pdev->dev, sizeof(*i2c), GFP_KERNEL); if (!i2c) @@ -1371,35 +1342,42 @@ static int mtk_i2c_probe(struct platform_device *pdev) if (i2c->have_pmic && !i2c->dev_comp->pmic_i2c) return -EINVAL; - i2c->clk_main = devm_clk_get(&pdev->dev, "main"); - if (IS_ERR(i2c->clk_main)) { + /* Fill in clk-bulk IDs */ + for (i = 0; i < I2C_MT65XX_CLK_MAX; i++) + i2c->clocks[i].id = i2c_mt65xx_clk_ids[i]; + + /* Get clocks one by one, some may be optional */ + i2c->clocks[I2C_MT65XX_CLK_MAIN].clk = devm_clk_get(&pdev->dev, "main"); + if (IS_ERR(i2c->clocks[I2C_MT65XX_CLK_MAIN].clk)) { dev_err(&pdev->dev, "cannot get main clock\n"); - return PTR_ERR(i2c->clk_main); + return PTR_ERR(i2c->clocks[I2C_MT65XX_CLK_MAIN].clk); } - i2c->clk_dma = devm_clk_get(&pdev->dev, "dma"); - if (IS_ERR(i2c->clk_dma)) { + i2c->clocks[I2C_MT65XX_CLK_DMA].clk = devm_clk_get(&pdev->dev, "dma"); + if (IS_ERR(i2c->clocks[I2C_MT65XX_CLK_DMA].clk)) { dev_err(&pdev->dev, "cannot get dma clock\n"); - return PTR_ERR(i2c->clk_dma); + return PTR_ERR(i2c->clocks[I2C_MT65XX_CLK_DMA].clk); } - i2c->clk_arb = devm_clk_get(&pdev->dev, "arb"); - if (IS_ERR(i2c->clk_arb)) - i2c->clk_arb = NULL; + i2c->clocks[I2C_MT65XX_CLK_ARB].clk = devm_clk_get_optional(&pdev->dev, "arb"); + if (IS_ERR(i2c->clocks[I2C_MT65XX_CLK_ARB].clk)) + return PTR_ERR(i2c->clocks[I2C_MT65XX_CLK_ARB].clk); - clk = i2c->clk_main; if (i2c->have_pmic) { - i2c->clk_pmic = devm_clk_get(&pdev->dev, "pmic"); - if (IS_ERR(i2c->clk_pmic)) { + i2c->clocks[I2C_MT65XX_CLK_PMIC].clk = devm_clk_get(&pdev->dev, "pmic"); + if (IS_ERR(i2c->clocks[I2C_MT65XX_CLK_PMIC].clk)) { dev_err(&pdev->dev, "cannot get pmic clock\n"); - return PTR_ERR(i2c->clk_pmic); + return PTR_ERR(i2c->clocks[I2C_MT65XX_CLK_PMIC].clk); } - clk = i2c->clk_pmic; + speed_clk = I2C_MT65XX_CLK_PMIC; + } else { + i2c->clocks[I2C_MT65XX_CLK_PMIC].clk = NULL; + speed_clk = I2C_MT65XX_CLK_MAIN; } strlcpy(i2c->adap.name, I2C_DRV_NAME, sizeof(i2c->adap.name)); - ret = mtk_i2c_set_speed(i2c, clk_get_rate(clk)); + ret = mtk_i2c_set_speed(i2c, clk_get_rate(i2c->clocks[speed_clk].clk)); if (ret) { dev_err(&pdev->dev, "Failed to set the speed.\n"); return -EINVAL; @@ -1414,13 +1392,13 @@ static int mtk_i2c_probe(struct platform_device *pdev) } } - ret = mtk_i2c_clock_enable(i2c); + ret = clk_bulk_prepare_enable(I2C_MT65XX_CLK_MAX, i2c->clocks); if (ret) { dev_err(&pdev->dev, "clock enable failed!\n"); return ret; } mtk_i2c_init_hw(i2c); - mtk_i2c_clock_disable(i2c); + clk_bulk_disable_unprepare(I2C_MT65XX_CLK_MAX, i2c->clocks); ret = devm_request_irq(&pdev->dev, irq, mtk_i2c_irq, IRQF_NO_SUSPEND | IRQF_TRIGGER_NONE, @@ -1465,7 +1443,7 @@ static int mtk_i2c_resume_noirq(struct device *dev) int ret; struct mtk_i2c *i2c = dev_get_drvdata(dev); - ret = mtk_i2c_clock_enable(i2c); + ret = clk_bulk_prepare_enable(I2C_MT65XX_CLK_MAX, i2c->clocks); if (ret) { dev_err(dev, "clock enable failed!\n"); return ret; @@ -1473,7 +1451,7 @@ static int mtk_i2c_resume_noirq(struct device *dev) mtk_i2c_init_hw(i2c); - mtk_i2c_clock_disable(i2c); + clk_bulk_disable_unprepare(I2C_MT65XX_CLK_MAX, i2c->clocks); i2c_mark_adapter_resumed(&i2c->adap); From 09055eb060a434bdafa3904cfc92d393b9438a64 Mon Sep 17 00:00:00 2001 From: Kewei Xu Date: Mon, 7 Mar 2022 11:36:48 +0800 Subject: [PATCH 312/370] dt-bindings: i2c: update bindings for MT8168 SoC Add a DT binding documentation for the MT8168 soc. Signed-off-by: Kewei Xu Reviewed-by: AngeloGioacchino Del Regno Acked-by: Krzysztof Kozlowski Reviewed-by: Qii Wang Signed-off-by: Wolfram Sang --- Documentation/devicetree/bindings/i2c/i2c-mt65xx.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/Documentation/devicetree/bindings/i2c/i2c-mt65xx.txt b/Documentation/devicetree/bindings/i2c/i2c-mt65xx.txt index 88f74a3c81ec..026985b8f61a 100644 --- a/Documentation/devicetree/bindings/i2c/i2c-mt65xx.txt +++ b/Documentation/devicetree/bindings/i2c/i2c-mt65xx.txt @@ -12,6 +12,7 @@ Required properties: "mediatek,mt7622-i2c": for MediaTek MT7622 "mediatek,mt7623-i2c", "mediatek,mt6577-i2c": for MediaTek MT7623 "mediatek,mt7629-i2c", "mediatek,mt2712-i2c": for MediaTek MT7629 + "mediatek,mt8168-i2c": for MediaTek MT8168 "mediatek,mt8173-i2c": for MediaTek MT8173 "mediatek,mt8183-i2c": for MediaTek MT8183 "mediatek,mt8186-i2c": for MediaTek MT8186 From 1bff55b57ea16bac882715017fc9b8f9e16894e2 Mon Sep 17 00:00:00 2001 From: Kewei Xu Date: Mon, 7 Mar 2022 11:36:49 +0800 Subject: [PATCH 313/370] i2c: mediatek: Add i2c compatible for Mediatek MT8168 Add i2c compatible for MT8168. Compare to MT2712 i2c controller, MT8168 need to synchronize signal with dma. Signed-off-by: Kewei Xu Reviewed-by: AngeloGioacchino Del Regno Reviewed-by: Qii Wang Signed-off-by: Wolfram Sang --- drivers/i2c/busses/i2c-mt65xx.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/drivers/i2c/busses/i2c-mt65xx.c b/drivers/i2c/busses/i2c-mt65xx.c index 7dde3b64766b..f651d3e124d6 100644 --- a/drivers/i2c/busses/i2c-mt65xx.c +++ b/drivers/i2c/busses/i2c-mt65xx.c @@ -389,6 +389,19 @@ static const struct mtk_i2c_compatible mt7622_compat = { .max_dma_support = 32, }; +static const struct mtk_i2c_compatible mt8168_compat = { + .regs = mt_i2c_regs_v1, + .pmic_i2c = 0, + .dcm = 1, + .auto_restart = 1, + .aux_len_reg = 1, + .timing_adjust = 1, + .dma_sync = 1, + .ltiming_adjust = 0, + .apdma_sync = 0, + .max_dma_support = 33, +}; + static const struct mtk_i2c_compatible mt8173_compat = { .regs = mt_i2c_regs_v1, .pmic_i2c = 0, @@ -448,6 +461,7 @@ static const struct of_device_id mtk_i2c_of_match[] = { { .compatible = "mediatek,mt6577-i2c", .data = &mt6577_compat }, { .compatible = "mediatek,mt6589-i2c", .data = &mt6589_compat }, { .compatible = "mediatek,mt7622-i2c", .data = &mt7622_compat }, + { .compatible = "mediatek,mt8168-i2c", .data = &mt8168_compat }, { .compatible = "mediatek,mt8173-i2c", .data = &mt8173_compat }, { .compatible = "mediatek,mt8183-i2c", .data = &mt8183_compat }, { .compatible = "mediatek,mt8186-i2c", .data = &mt8186_compat }, From d0583229bcf5090495d0621892d5da93d9fb6e3c Mon Sep 17 00:00:00 2001 From: Nathan Chancellor Date: Thu, 3 Mar 2022 12:17:13 -0700 Subject: [PATCH 314/370] i2c: designware: Mark dw_i2c_plat_{suspend,resume}() as __maybe_unused When CONFIG_PM is set but CONFIG_PM_SLEEP is not, two compiler warnings appear: drivers/i2c/busses/i2c-designware-platdrv.c:444:12: error: unused function 'dw_i2c_plat_suspend' [-Werror,-Wunused-function] static int dw_i2c_plat_suspend(struct device *dev) ^ drivers/i2c/busses/i2c-designware-platdrv.c:465:12: error: unused function 'dw_i2c_plat_resume' [-Werror,-Wunused-function] static int dw_i2c_plat_resume(struct device *dev) ^ 2 errors generated. These functions are only used in SET_LATE_SYSTEM_SLEEP_PM_OPS(), which is defined as empty when CONFIG_PM_SLEEP is not defined. Mark the functions as __maybe_unused to make it clear that these functions might be unused in this configuration. Fixes: c57813b8b288 ("i2c: designware: Lock the adapter while setting the suspended flag") Signed-off-by: Nathan Chancellor Reviewed-by: Hans de Goede Reviewed-by: Andy Shevchenko Acked-by: Jarkko Nikula Acked-by: Geert Uytterhoeven Signed-off-by: Wolfram Sang --- drivers/i2c/busses/i2c-designware-platdrv.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/i2c/busses/i2c-designware-platdrv.c b/drivers/i2c/busses/i2c-designware-platdrv.c index 116a297d1f6b..70ade5306e45 100644 --- a/drivers/i2c/busses/i2c-designware-platdrv.c +++ b/drivers/i2c/busses/i2c-designware-platdrv.c @@ -441,7 +441,7 @@ static int dw_i2c_plat_runtime_suspend(struct device *dev) return 0; } -static int dw_i2c_plat_suspend(struct device *dev) +static int __maybe_unused dw_i2c_plat_suspend(struct device *dev) { struct dw_i2c_dev *i_dev = dev_get_drvdata(dev); @@ -462,7 +462,7 @@ static int dw_i2c_plat_runtime_resume(struct device *dev) return 0; } -static int dw_i2c_plat_resume(struct device *dev) +static int __maybe_unused dw_i2c_plat_resume(struct device *dev) { struct dw_i2c_dev *i_dev = dev_get_drvdata(dev); From 246313e31316804c87887d3f33f8dc8ab6893560 Mon Sep 17 00:00:00 2001 From: Lukas Bulwahn Date: Tue, 8 Mar 2022 08:54:14 +0100 Subject: [PATCH 315/370] MAINTAINERS: adjust XLP9XX I2C DRIVER after removing the devicetree binding Commit 0e5f897708e8 ("dt-bindings: Remove Netlogic bindings") removes the devicetree binding i2c-xlp9xx.txt, but misses to adjust the reference in MAINTAINERS. Hence, ./scripts/get_maintainer.pl --self-test=patterns complains about a broken reference. Remove the file reference to i2c-xlp9xx.txt in XLP9XX I2C DRIVER. As commit ef99066c7ded ("i2c: Remove Netlogic XLP variant") explains, the i2c-xlp9xx driver is still used by the Cavium ThunderX2 platform. So, keep the XLP9XX I2C DRIVER section in MAINTAINERS with its reference to drivers/i2c/busses/i2c-xlp9xx.c. Signed-off-by: Lukas Bulwahn Signed-off-by: Wolfram Sang --- MAINTAINERS | 1 - 1 file changed, 1 deletion(-) diff --git a/MAINTAINERS b/MAINTAINERS index f7396689f33e..01c2eee734ea 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -21307,7 +21307,6 @@ M: George Cherian L: linux-i2c@vger.kernel.org S: Supported W: http://www.marvell.com -F: Documentation/devicetree/bindings/i2c/i2c-xlp9xx.txt F: drivers/i2c/busses/i2c-xlp9xx.c XRA1403 GPIO EXPANDER From 8b6d8d00a46a12a4baa08d547d4231e50a558254 Mon Sep 17 00:00:00 2001 From: Xiang wangx Date: Mon, 6 Dec 2021 00:27:52 +0800 Subject: [PATCH 316/370] i2c: cros-ec-tunnel: Fix syntax errors in comments Delete the redundant word 'to' Signed-off-by: Xiang wangx [wsa: fixed prefix in subject] Signed-off-by: Wolfram Sang --- drivers/i2c/busses/i2c-cros-ec-tunnel.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/i2c/busses/i2c-cros-ec-tunnel.c b/drivers/i2c/busses/i2c-cros-ec-tunnel.c index 790ea3fda693..892213d51f43 100644 --- a/drivers/i2c/busses/i2c-cros-ec-tunnel.c +++ b/drivers/i2c/busses/i2c-cros-ec-tunnel.c @@ -107,7 +107,7 @@ static int ec_i2c_construct_message(u8 *buf, const struct i2c_msg i2c_msgs[], /** * ec_i2c_count_response - Count bytes needed for ec_i2c_parse_response * - * @i2c_msgs: The i2c messages to to fill up. + * @i2c_msgs: The i2c messages to fill up. * @num: The number of i2c messages expected. * * Returns the number of response bytes expeced. @@ -131,7 +131,7 @@ static int ec_i2c_count_response(struct i2c_msg i2c_msgs[], int num) * We'll take the EC's response and copy it back into msgs. * * @buf: The buffer to parse. - * @i2c_msgs: The i2c messages to to fill up. + * @i2c_msgs: The i2c messages to fill up. * @num: The number of i2c messages; will be modified to include the actual * number received. * From 7f4f25a6887c7d1381756deba882f6f6106433f6 Mon Sep 17 00:00:00 2001 From: Frank Wunderlich Date: Fri, 11 Mar 2022 22:03:52 +0100 Subject: [PATCH 317/370] dt-bindings: ata: ahci-platform: Convert DT bindings to yaml Create a yaml file for dtbs_check from the old txt binding. Signed-off-by: Frank Wunderlich Signed-off-by: Rob Herring Link: https://lore.kernel.org/r/20220311210357.222830-2-linux@fw-web.de --- .../devicetree/bindings/ata/ahci-platform.txt | 79 -------- .../bindings/ata/ahci-platform.yaml | 182 ++++++++++++++++++ 2 files changed, 182 insertions(+), 79 deletions(-) delete mode 100644 Documentation/devicetree/bindings/ata/ahci-platform.txt create mode 100644 Documentation/devicetree/bindings/ata/ahci-platform.yaml diff --git a/Documentation/devicetree/bindings/ata/ahci-platform.txt b/Documentation/devicetree/bindings/ata/ahci-platform.txt deleted file mode 100644 index 77091a277642..000000000000 --- a/Documentation/devicetree/bindings/ata/ahci-platform.txt +++ /dev/null @@ -1,79 +0,0 @@ -* AHCI SATA Controller - -SATA nodes are defined to describe on-chip Serial ATA controllers. -Each SATA controller should have its own node. - -It is possible, but not required, to represent each port as a sub-node. -It allows to enable each port independently when dealing with multiple -PHYs. - -Required properties: -- compatible : compatible string, one of: - - "brcm,iproc-ahci" - - "hisilicon,hisi-ahci" - - "cavium,octeon-7130-ahci" - - "ibm,476gtr-ahci" - - "marvell,armada-380-ahci" - - "marvell,armada-3700-ahci" - - "snps,dwc-ahci" - - "snps,spear-ahci" - - "generic-ahci" -- interrupts : -- reg : - -Please note that when using "generic-ahci" you must also specify a SoC specific -compatible: - compatible = "manufacturer,soc-model-ahci", "generic-ahci"; - -Optional properties: -- dma-coherent : Present if dma operations are coherent -- clocks : a list of phandle + clock specifier pairs -- resets : a list of phandle + reset specifier pairs -- target-supply : regulator for SATA target power -- phy-supply : regulator for PHY power -- phys : reference to the SATA PHY node -- phy-names : must be "sata-phy" -- ahci-supply : regulator for AHCI controller -- ports-implemented : Mask that indicates which ports that the HBA supports - are available for software to use. Useful if PORTS_IMPL - is not programmed by the BIOS, which is true with - some embedded SOC's. - -Required properties when using sub-nodes: -- #address-cells : number of cells to encode an address -- #size-cells : number of cells representing the size of an address - -Sub-nodes required properties: -- reg : the port number -And at least one of the following properties: -- phys : reference to the SATA PHY node -- target-supply : regulator for SATA target power - -Examples: - sata@ffe08000 { - compatible = "snps,spear-ahci"; - reg = <0xffe08000 0x1000>; - interrupts = <115>; - }; - -With sub-nodes: - sata@f7e90000 { - compatible = "marvell,berlin2q-achi", "generic-ahci"; - reg = <0xe90000 0x1000>; - interrupts = ; - clocks = <&chip CLKID_SATA>; - #address-cells = <1>; - #size-cells = <0>; - - sata0: sata-port@0 { - reg = <0>; - phys = <&sata_phy 0>; - target-supply = <®_sata0>; - }; - - sata1: sata-port@1 { - reg = <1>; - phys = <&sata_phy 1>; - target-supply = <®_sata1>;; - }; - }; diff --git a/Documentation/devicetree/bindings/ata/ahci-platform.yaml b/Documentation/devicetree/bindings/ata/ahci-platform.yaml new file mode 100644 index 000000000000..e71bfb04d7f1 --- /dev/null +++ b/Documentation/devicetree/bindings/ata/ahci-platform.yaml @@ -0,0 +1,182 @@ +# SPDX-License-Identifier: GPL-2.0 +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/ata/ahci-platform.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: AHCI SATA Controller + +description: | + SATA nodes are defined to describe on-chip Serial ATA controllers. + Each SATA controller should have its own node. + + It is possible, but not required, to represent each port as a sub-node. + It allows to enable each port independently when dealing with multiple + PHYs. + +maintainers: + - Hans de Goede + - Jens Axboe + +select: + properties: + compatible: + contains: + enum: + - brcm,iproc-ahci + - cavium,octeon-7130-ahci + - hisilicon,hisi-ahci + - ibm,476gtr-ahci + - marvell,armada-3700-ahci + - marvell,armada-8k-ahci + - marvell,berlin2q-ahci + - snps,dwc-ahci + - snps,spear-ahci + required: + - compatible + +allOf: + - $ref: "sata-common.yaml#" + + +properties: + compatible: + oneOf: + - items: + - enum: + - brcm,iproc-ahci + - marvell,armada-8k-ahci + - marvell,berlin2-ahci + - marvell,berlin2q-ahci + - const: generic-ahci + - enum: + - cavium,octeon-7130-ahci + - hisilicon,hisi-ahci + - ibm,476gtr-ahci + - marvell,armada-3700-ahci + - snps,dwc-ahci + - snps,spear-ahci + + reg: + minItems: 1 + maxItems: 2 + + reg-names: + maxItems: 1 + + clocks: + description: + Clock IDs array as required by the controller. + minItems: 1 + maxItems: 3 + + clock-names: + description: + Names of clocks corresponding to IDs in the clock property. + minItems: 1 + maxItems: 3 + + interrupts: + maxItems: 1 + + ahci-supply: + description: + regulator for AHCI controller + + dma-coherent: true + + phy-supply: + description: + regulator for PHY power + + phys: + description: + List of all PHYs on this controller + maxItems: 1 + + phy-names: + description: + Name specifier for the PHYs + maxItems: 1 + + ports-implemented: + $ref: '/schemas/types.yaml#/definitions/uint32' + description: | + Mask that indicates which ports that the HBA supports + are available for software to use. Useful if PORTS_IMPL + is not programmed by the BIOS, which is true with + some embedded SoCs. + maximum: 0x1f + + resets: + maxItems: 1 + + target-supply: + description: + regulator for SATA target power + +required: + - compatible + - reg + - interrupts + +patternProperties: + "^sata-port@[0-9a-f]+$": + type: object + additionalProperties: false + description: + Subnode with configuration of the Ports. + + properties: + reg: + maxItems: 1 + + phys: + maxItems: 1 + + phy-names: + maxItems: 1 + + target-supply: + description: + regulator for SATA target power + + required: + - reg + + anyOf: + - required: [ phys ] + - required: [ target-supply ] + +unevaluatedProperties: false + +examples: + - | + sata@ffe08000 { + compatible = "snps,spear-ahci"; + reg = <0xffe08000 0x1000>; + interrupts = <115>; + }; + - | + #include + #include + sata@f7e90000 { + compatible = "marvell,berlin2q-ahci", "generic-ahci"; + reg = <0xf7e90000 0x1000>; + interrupts = ; + clocks = <&chip CLKID_SATA>; + #address-cells = <1>; + #size-cells = <0>; + + sata0: sata-port@0 { + reg = <0>; + phys = <&sata_phy 0>; + target-supply = <®_sata0>; + }; + + sata1: sata-port@1 { + reg = <1>; + phys = <&sata_phy 1>; + target-supply = <®_sata1>; + }; + }; From 3f5a539b35e45c53d6f0629b0e7312f10ad34052 Mon Sep 17 00:00:00 2001 From: Frank Wunderlich Date: Fri, 11 Mar 2022 22:03:55 +0100 Subject: [PATCH 318/370] dt-bindings: ata: ahci-platform: Add power-domains property Some SoC using power-domains property so add it here Signed-off-by: Frank Wunderlich Reviewed-by: Krzysztof Kozlowski Signed-off-by: Rob Herring Link: https://lore.kernel.org/r/20220311210357.222830-5-linux@fw-web.de --- Documentation/devicetree/bindings/ata/ahci-platform.yaml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Documentation/devicetree/bindings/ata/ahci-platform.yaml b/Documentation/devicetree/bindings/ata/ahci-platform.yaml index e71bfb04d7f1..a02f6d12773e 100644 --- a/Documentation/devicetree/bindings/ata/ahci-platform.yaml +++ b/Documentation/devicetree/bindings/ata/ahci-platform.yaml @@ -108,6 +108,9 @@ properties: some embedded SoCs. maximum: 0x1f + power-domains: + maxItems: 1 + resets: maxItems: 1 From 593adaa6459903728cb59392239f2c615b8dadbb Mon Sep 17 00:00:00 2001 From: Frank Wunderlich Date: Fri, 11 Mar 2022 22:03:56 +0100 Subject: [PATCH 319/370] dt-bindings: ata: ahci-platform: Add rk3568-dwc-ahci compatible Add SoC specific compatible for rk3568 ahci controller Signed-off-by: Frank Wunderlich Reviewed-by: Krzysztof Kozlowski Signed-off-by: Rob Herring Link: https://lore.kernel.org/r/20220311210357.222830-6-linux@fw-web.de --- Documentation/devicetree/bindings/ata/ahci-platform.yaml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Documentation/devicetree/bindings/ata/ahci-platform.yaml b/Documentation/devicetree/bindings/ata/ahci-platform.yaml index a02f6d12773e..c146ab8e14e5 100644 --- a/Documentation/devicetree/bindings/ata/ahci-platform.yaml +++ b/Documentation/devicetree/bindings/ata/ahci-platform.yaml @@ -49,6 +49,10 @@ properties: - marvell,berlin2-ahci - marvell,berlin2q-ahci - const: generic-ahci + - items: + - enum: + - rockchip,rk3568-dwc-ahci + - const: snps,dwc-ahci - enum: - cavium,octeon-7130-ahci - hisilicon,hisi-ahci From f92ca72b0263d601807bbd23ed25cbe6f4da89f4 Mon Sep 17 00:00:00 2001 From: Bang Li Date: Fri, 11 Mar 2022 23:12:40 +0800 Subject: [PATCH 320/370] fsnotify: remove redundant parameter judgment iput() has already judged the incoming parameter, so there is no need to repeat the judgment here. Link: https://lore.kernel.org/r/20220311151240.62045-1-libang.linuxer@gmail.com Signed-off-by: Bang Li Signed-off-by: Jan Kara --- fs/notify/fsnotify.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/fs/notify/fsnotify.c b/fs/notify/fsnotify.c index 494f653efbc6..70a8516b78bc 100644 --- a/fs/notify/fsnotify.c +++ b/fs/notify/fsnotify.c @@ -70,8 +70,7 @@ static void fsnotify_unmount_inodes(struct super_block *sb) spin_unlock(&inode->i_lock); spin_unlock(&sb->s_inode_list_lock); - if (iput_inode) - iput(iput_inode); + iput(iput_inode); /* for each watch, send FS_UNMOUNT and then remove it */ fsnotify_inode(inode, FS_UNMOUNT); @@ -85,8 +84,7 @@ static void fsnotify_unmount_inodes(struct super_block *sb) } spin_unlock(&sb->s_inode_list_lock); - if (iput_inode) - iput(iput_inode); + iput(iput_inode); } void fsnotify_sb_delete(struct super_block *sb) From fba6eb4fc4e6819d9684d378ace339c4212d5ce1 Mon Sep 17 00:00:00 2001 From: Yihao Han Date: Thu, 3 Mar 2022 04:34:27 -0800 Subject: [PATCH 321/370] mtd: rawnand: rockchip: fix platform_get_irq.cocci warning Remove dev_err() messages after platform_get_irq*() failures. platform_get_irq() already prints an error. Generated by: scripts/coccinelle/api/platform_get_irq.cocci Signed-off-by: Yihao Han Signed-off-by: Miquel Raynal Link: https://lore.kernel.org/linux-mtd/20220303123431.3170-1-hanyihao@vivo.com --- drivers/mtd/nand/raw/rockchip-nand-controller.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/mtd/nand/raw/rockchip-nand-controller.c b/drivers/mtd/nand/raw/rockchip-nand-controller.c index b5405bc7ca3a..cbaa4f1c83da 100644 --- a/drivers/mtd/nand/raw/rockchip-nand-controller.c +++ b/drivers/mtd/nand/raw/rockchip-nand-controller.c @@ -1403,7 +1403,6 @@ static int rk_nfc_probe(struct platform_device *pdev) irq = platform_get_irq(pdev, 0); if (irq < 0) { - dev_err(dev, "no NFC irq resource\n"); ret = -EINVAL; goto clk_disable; } From fecbd4a317c95d73c849648c406bcf1b6a0ec1cf Mon Sep 17 00:00:00 2001 From: Xin Xiong Date: Fri, 4 Mar 2022 16:53:32 +0800 Subject: [PATCH 322/370] mtd: rawnand: atmel: fix refcount issue in atmel_nand_controller_init The reference counting issue happens in several error handling paths on a refcounted object "nc->dmac". In these paths, the function simply returns the error code, forgetting to balance the reference count of "nc->dmac", increased earlier by dma_request_channel(), which may cause refcount leaks. Fix it by decrementing the refcount of specific object in those error paths. Fixes: f88fc122cc34 ("mtd: nand: Cleanup/rework the atmel_nand driver") Co-developed-by: Xiyu Yang Signed-off-by: Xiyu Yang Co-developed-by: Xin Tan Signed-off-by: Xin Tan Signed-off-by: Xin Xiong Reviewed-by: Claudiu Beznea Signed-off-by: Miquel Raynal Link: https://lore.kernel.org/linux-mtd/20220304085330.3610-1-xiongx18@fudan.edu.cn --- drivers/mtd/nand/raw/atmel/nand-controller.c | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/drivers/mtd/nand/raw/atmel/nand-controller.c b/drivers/mtd/nand/raw/atmel/nand-controller.c index f3276ee9e4fe..ddd93bc38ea6 100644 --- a/drivers/mtd/nand/raw/atmel/nand-controller.c +++ b/drivers/mtd/nand/raw/atmel/nand-controller.c @@ -2060,13 +2060,15 @@ static int atmel_nand_controller_init(struct atmel_nand_controller *nc, nc->mck = of_clk_get(dev->parent->of_node, 0); if (IS_ERR(nc->mck)) { dev_err(dev, "Failed to retrieve MCK clk\n"); - return PTR_ERR(nc->mck); + ret = PTR_ERR(nc->mck); + goto out_release_dma; } np = of_parse_phandle(dev->parent->of_node, "atmel,smc", 0); if (!np) { dev_err(dev, "Missing or invalid atmel,smc property\n"); - return -EINVAL; + ret = -EINVAL; + goto out_release_dma; } nc->smc = syscon_node_to_regmap(np); @@ -2074,10 +2076,16 @@ static int atmel_nand_controller_init(struct atmel_nand_controller *nc, if (IS_ERR(nc->smc)) { ret = PTR_ERR(nc->smc); dev_err(dev, "Could not get SMC regmap (err = %d)\n", ret); - return ret; + goto out_release_dma; } return 0; + +out_release_dma: + if (nc->dmac) + dma_release_channel(nc->dmac); + + return ret; } static int From ceef4cf97bec31403a73bd2facff8651a2ae4369 Mon Sep 17 00:00:00 2001 From: Amit Kumar Mahapatra Date: Tue, 8 Feb 2022 16:09:05 +0530 Subject: [PATCH 323/370] mtd: tests: Fix eraseblock read speed miscalculation for lower partition sizes While calculating speed during mtd_speedtest, the time interval (i.e., start - finish) is rounded off to the nearest milliseconds by ignoring the fractional part. This leads to miscalculation of speed. The miscalculation is more visible while running speed test on small partition sizes(i.e., when partition size is equal to eraseblock size or twice the eraseblock size) at higher spi frequencies. For e.g., while calculating eraseblock read speed for a mtd partition with size equal to the eraseblock size(i.e., 64KiB) the eraseblock read time interval comes out to be 966490 nanosecond. This is then converted to millisecond(i.e., 0.966 msec.). The integer part (i.e., 0 msec) of the value is considered and the fractional part (i.e., 0.966) is ignored,for calculating the eraseblock read speed. So the reported eraseblock read speed is 0 KiB/s, which is incorrect. There are two approaches to fix this issue. First approach will be to keep the time interval in millisecond. and round up the integer value, with this approach the 0.966msec time interval in the above example will be rounded up to 1msec and this value is used for calculating the speed. Downside of this approach is that the reported speed is still not accurate. Second approach will be to convert the time interval to microseconds instead of milliseconds, with this approach the 966490 nanosecond time interval in the above example will be converted t0 966.490usec and this value is used for calculating the speed. As compared to the current implementation and the suggested First approach, this approach will report a more accurate speed. Downside of this approach is that, in future if the mtd size is too large then the u64 variable, that holds the number of bytes, might overflow. In this patch we have gone with the second approach as this reports a more accurate speed. With this approach the eraseblock read speed in the above example comes out to be 132505 KiB/s when the spi clock is configured at 150Mhz. Signed-off-by: Amit Kumar Mahapatra Signed-off-by: Miquel Raynal Link: https://lore.kernel.org/linux-mtd/20220208103905.13354-1-amit.kumar-mahapatra@xilinx.com --- drivers/mtd/tests/speedtest.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/drivers/mtd/tests/speedtest.c b/drivers/mtd/tests/speedtest.c index 93e76648f676..c9ec7086bfa1 100644 --- a/drivers/mtd/tests/speedtest.c +++ b/drivers/mtd/tests/speedtest.c @@ -160,14 +160,13 @@ static inline void stop_timing(void) static long calc_speed(void) { - uint64_t k; - long ms; + uint64_t k, us; - ms = ktime_ms_delta(finish, start); - if (ms == 0) + us = ktime_us_delta(finish, start); + if (us == 0) return 0; - k = (uint64_t)goodebcnt * (mtd->erasesize / 1024) * 1000; - do_div(k, ms); + k = (uint64_t)goodebcnt * (mtd->erasesize / 1024) * 1000000; + do_div(k, us); return k; } From d9a16830e10eafde6f0bce91047bb869c44425ab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= Date: Wed, 16 Feb 2022 11:41:35 +0100 Subject: [PATCH 324/370] dt-bindings: mtd: partitions: convert BCM47xx to the json-schema MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This helps validating DTS files. Signed-off-by: Rafał Miłecki Reviewed-by: Rob Herring Signed-off-by: Miquel Raynal Link: https://lore.kernel.org/linux-mtd/20220216104135.31307-1-zajec5@gmail.com --- .../brcm,bcm947xx-cfe-partitions.txt | 42 ---------------- .../brcm,bcm947xx-cfe-partitions.yaml | 48 +++++++++++++++++++ 2 files changed, 48 insertions(+), 42 deletions(-) delete mode 100644 Documentation/devicetree/bindings/mtd/partitions/brcm,bcm947xx-cfe-partitions.txt create mode 100644 Documentation/devicetree/bindings/mtd/partitions/brcm,bcm947xx-cfe-partitions.yaml diff --git a/Documentation/devicetree/bindings/mtd/partitions/brcm,bcm947xx-cfe-partitions.txt b/Documentation/devicetree/bindings/mtd/partitions/brcm,bcm947xx-cfe-partitions.txt deleted file mode 100644 index 1d61a029395e..000000000000 --- a/Documentation/devicetree/bindings/mtd/partitions/brcm,bcm947xx-cfe-partitions.txt +++ /dev/null @@ -1,42 +0,0 @@ -Broadcom BCM47xx Partitions -=========================== - -Broadcom is one of hardware manufacturers providing SoCs (BCM47xx) used in -home routers. Their BCM947xx boards using CFE bootloader have several partitions -without any on-flash partition table. On some devices their sizes and/or -meanings can also vary so fixed partitioning can't be used. - -Discovering partitions on these devices is possible thanks to having a special -header and/or magic signature at the beginning of each of them. They are also -block aligned which is important for determinig a size. - -Most of partitions use ASCII text based magic for determining a type. More -complex partitions (like TRX with its HDR0 magic) may include extra header -containing some details, including a length. - -A list of supported partitions includes: -1) Bootloader with Broadcom's CFE (Common Firmware Environment) -2) NVRAM with configuration/calibration data -3) Device manufacturer's data with some default values (e.g. SSIDs) -4) TRX firmware container which can hold up to 4 subpartitions -5) Backup TRX firmware used after failed upgrade - -As mentioned earlier, role of some partitions may depend on extra configuration. -For example both: main firmware and backup firmware use the same TRX format with -the same header. To distinguish currently used firmware a CFE's environment -variable "bootpartition" is used. - - -Devices using Broadcom partitions described above should should have flash node -with a subnode named "partitions" using following properties: - -Required properties: -- compatible : (required) must be "brcm,bcm947xx-cfe-partitions" - -Example: - -flash@0 { - partitions { - compatible = "brcm,bcm947xx-cfe-partitions"; - }; -}; diff --git a/Documentation/devicetree/bindings/mtd/partitions/brcm,bcm947xx-cfe-partitions.yaml b/Documentation/devicetree/bindings/mtd/partitions/brcm,bcm947xx-cfe-partitions.yaml new file mode 100644 index 000000000000..3484e06d6bcb --- /dev/null +++ b/Documentation/devicetree/bindings/mtd/partitions/brcm,bcm947xx-cfe-partitions.yaml @@ -0,0 +1,48 @@ +# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/mtd/partitions/brcm,bcm947xx-cfe-partitions.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Broadcom BCM47xx Partitions + +description: | + Broadcom is one of hardware manufacturers providing SoCs (BCM47xx) used in + home routers. Their BCM947xx boards using CFE bootloader have several + partitions without any on-flash partition table. On some devices their sizes + and/or meanings can also vary so fixed partitioning can't be used. + + Discovering partitions on these devices is possible thanks to having a special + header and/or magic signature at the beginning of each of them. They are also + block aligned which is important for determinig a size. + + Most of partitions use ASCII text based magic for determining a type. More + complex partitions (like TRX with its HDR0 magic) may include extra header + containing some details, including a length. + + A list of supported partitions includes: + 1) Bootloader with Broadcom's CFE (Common Firmware Environment) + 2) NVRAM with configuration/calibration data + 3) Device manufacturer's data with some default values (e.g. SSIDs) + 4) TRX firmware container which can hold up to 4 subpartitions + 5) Backup TRX firmware used after failed upgrade + + As mentioned earlier, role of some partitions may depend on extra + configuration. For example both: main firmware and backup firmware use the + same TRX format with the same header. To distinguish currently used firmware a + CFE's environment variable "bootpartition" is used. + +maintainers: + - Rafał Miłecki + +properties: + compatible: + const: brcm,bcm947xx-cfe-partitions + +additionalProperties: false + +examples: + - | + partitions { + compatible = "brcm,bcm947xx-cfe-partitions"; + }; From ec090a0392ff634e9304c19a8578d476a9e0c830 Mon Sep 17 00:00:00 2001 From: Tudor Ambarus Date: Fri, 25 Feb 2022 16:46:56 +0200 Subject: [PATCH 325/370] mtd: core: Remove partid and partname debugfs files partid and partname debugfs files were used just by SPI NOR, but they were replaced by sysfs entries. Since these debugfs files are no longer used in mtd, remove dead code. The directory is kept as it is used by nandsim, mtdswap and docg3. Signed-off-by: Tudor Ambarus Reviewed-by: Pratyush Yadav Signed-off-by: Miquel Raynal Link: https://lore.kernel.org/linux-mtd/20220225144656.634682-1-tudor.ambarus@microchip.com --- drivers/mtd/mtdcore.c | 35 +---------------------------------- include/linux/mtd/mtd.h | 3 --- 2 files changed, 1 insertion(+), 37 deletions(-) diff --git a/drivers/mtd/mtdcore.c b/drivers/mtd/mtdcore.c index 1e7f3bbf847e..7dd105daf19d 100644 --- a/drivers/mtd/mtdcore.c +++ b/drivers/mtd/mtdcore.c @@ -336,28 +336,6 @@ static const struct device_type mtd_devtype = { .release = mtd_release, }; -static int mtd_partid_debug_show(struct seq_file *s, void *p) -{ - struct mtd_info *mtd = s->private; - - seq_printf(s, "%s\n", mtd->dbg.partid); - - return 0; -} - -DEFINE_SHOW_ATTRIBUTE(mtd_partid_debug); - -static int mtd_partname_debug_show(struct seq_file *s, void *p) -{ - struct mtd_info *mtd = s->private; - - seq_printf(s, "%s\n", mtd->dbg.partname); - - return 0; -} - -DEFINE_SHOW_ATTRIBUTE(mtd_partname_debug); - static bool mtd_expert_analysis_mode; #ifdef CONFIG_DEBUG_FS @@ -377,23 +355,12 @@ static struct dentry *dfs_dir_mtd; static void mtd_debugfs_populate(struct mtd_info *mtd) { - struct mtd_info *master = mtd_get_master(mtd); struct device *dev = &mtd->dev; - struct dentry *root; if (IS_ERR_OR_NULL(dfs_dir_mtd)) return; - root = debugfs_create_dir(dev_name(dev), dfs_dir_mtd); - mtd->dbg.dfs_dir = root; - - if (master->dbg.partid) - debugfs_create_file("partid", 0400, root, master, - &mtd_partid_debug_fops); - - if (master->dbg.partname) - debugfs_create_file("partname", 0400, root, master, - &mtd_partname_debug_fops); + mtd->dbg.dfs_dir = debugfs_create_dir(dev_name(dev), dfs_dir_mtd); } #ifndef CONFIG_MMU diff --git a/include/linux/mtd/mtd.h b/include/linux/mtd/mtd.h index 1b3fc8c71ab3..151607e9d64a 100644 --- a/include/linux/mtd/mtd.h +++ b/include/linux/mtd/mtd.h @@ -188,9 +188,6 @@ struct module; /* only needed for owner field in mtd_info */ */ struct mtd_debug_info { struct dentry *dfs_dir; - - const char *partname; - const char *partid; }; /** From 5fc69b6e51ae2da28081c201f595898c5c1f40cc Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Mon, 7 Mar 2022 13:27:02 +0100 Subject: [PATCH 326/370] mtd: hyperbus: HBMC_AM654 should depend on ARCH_K3 The AM65x HyperBus controller is only present on Texas Instruments AM65x SoCs. Hence add a dependency on ARCH_K3, to prevent asking the user about this driver when configuring a kernel without support for the Texas Instruments Inc. K3 multicore SoC architecture. Signed-off-by: Geert Uytterhoeven Signed-off-by: Miquel Raynal Link: https://lore.kernel.org/linux-mtd/9fd6b975adba710158f28aa603cf87a6d189a418.1646655894.git.geert+renesas@glider.be --- drivers/mtd/hyperbus/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/mtd/hyperbus/Kconfig b/drivers/mtd/hyperbus/Kconfig index 46c7e407e378..30ffc4c16e4d 100644 --- a/drivers/mtd/hyperbus/Kconfig +++ b/drivers/mtd/hyperbus/Kconfig @@ -15,7 +15,7 @@ if MTD_HYPERBUS config HBMC_AM654 tristate "HyperBus controller driver for AM65x SoC" - depends on ARM64 || COMPILE_TEST + depends on ARCH_K3 || COMPILE_TEST select MULTIPLEXER imply MUX_MMIO help From 5a368fb65ad9aaf68f2bbe02d42969741317d44c Mon Sep 17 00:00:00 2001 From: Colin Ian King Date: Mon, 7 Mar 2022 23:09:40 +0000 Subject: [PATCH 327/370] mtd: nand: mxic-ecc: make two read-only arrays static const Don't populate the read-only arrays possible_strength and spare_size on the stack but instead make them static const. Also makes the object code a little smaller. Signed-off-by: Colin Ian King Signed-off-by: Miquel Raynal Link: https://lore.kernel.org/linux-mtd/20220307230940.169235-1-colin.i.king@gmail.com --- drivers/mtd/nand/ecc-mxic.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/mtd/nand/ecc-mxic.c b/drivers/mtd/nand/ecc-mxic.c index c122139255e5..8afdca731b87 100644 --- a/drivers/mtd/nand/ecc-mxic.c +++ b/drivers/mtd/nand/ecc-mxic.c @@ -224,8 +224,8 @@ static int mxic_ecc_init_ctx(struct nand_device *nand, struct device *dev) struct nand_ecc_props *user = &nand->ecc.user_conf; struct mtd_info *mtd = nanddev_to_mtd(nand); int step_size = 0, strength = 0, desired_correction = 0, steps, idx; - int possible_strength[] = {4, 8, 40, 48}; - int spare_size[] = {32, 32, 96, 96}; + static const int possible_strength[] = {4, 8, 40, 48}; + static const int spare_size[] = {32, 32, 96, 96}; struct mxic_ecc_ctx *ctx; u32 spare_reg; int ret; From 8f877b7eab9d60a9deef6beae95656b77d55ab75 Mon Sep 17 00:00:00 2001 From: Miquel Raynal Date: Mon, 14 Mar 2022 16:23:36 +0100 Subject: [PATCH 328/370] mtd: nand: ecc: mxic: Fix compile test issue Avoid random build errors with architectures which do not select HAS_IOMEM by depending on it in Kconfig. This fixes the following warning: /home/mraynal/0day/gcc-11.2.0-nolibc/s390-linux/bin/s390-linux-ld: drivers/mtd/nand/ecc-mxic.o: in function `mxic_ecc_probe': ecc-mxic.c:(.text+0x2244): undefined reference to `devm_platform_ioremap_resource' Reported-by: kernel test robot Signed-off-by: Miquel Raynal Link: https://lore.kernel.org/linux-mtd/20220314152336.75447-1-miquel.raynal@bootlin.com --- drivers/mtd/nand/Kconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/mtd/nand/Kconfig b/drivers/mtd/nand/Kconfig index 8431292ff49d..9b249826ef93 100644 --- a/drivers/mtd/nand/Kconfig +++ b/drivers/mtd/nand/Kconfig @@ -48,6 +48,7 @@ config MTD_NAND_ECC_SW_BCH config MTD_NAND_ECC_MXIC bool "Macronix external hardware ECC engine" + depends on HAS_IOMEM select MTD_NAND_ECC help This enables support for the hardware ECC engine from Macronix. From 3364c0ef8732694084f8238ffd9c62819209fd7f Mon Sep 17 00:00:00 2001 From: Jan Dabros Date: Mon, 14 Mar 2022 10:03:23 +0100 Subject: [PATCH 329/370] i2c: designware: Remove code duplication Simplify code by moving common part to one function. Signed-off-by: Jan Dabros Suggested-by: Andy Shevchenko Reviewed-by: Andy Shevchenko Acked-by: Jarkko Nikula Signed-off-by: Wolfram Sang --- drivers/i2c/busses/i2c-designware-amdpsp.c | 35 ++++++++++------------ 1 file changed, 15 insertions(+), 20 deletions(-) diff --git a/drivers/i2c/busses/i2c-designware-amdpsp.c b/drivers/i2c/busses/i2c-designware-amdpsp.c index 3844695e6bf3..9b37f2b95abc 100644 --- a/drivers/i2c/busses/i2c-designware-amdpsp.c +++ b/drivers/i2c/busses/i2c-designware-amdpsp.c @@ -214,17 +214,28 @@ static int psp_send_i2c_req(enum psp_i2c_req_type i2c_req_type) PSP_I2C_REQ_RETRY_DELAY_US, PSP_I2C_REQ_RETRY_CNT * PSP_I2C_REQ_RETRY_DELAY_US, 0, req); - if (ret) + if (ret) { + dev_err(psp_i2c_dev, "Timed out waiting for PSP to %s I2C bus\n", + (i2c_req_type == PSP_I2C_REQ_ACQUIRE) ? + "release" : "acquire"); goto cleanup; + } ret = status; - if (ret) + if (ret) { + dev_err(psp_i2c_dev, "PSP communication error\n"); goto cleanup; + } dev_dbg(psp_i2c_dev, "Request accepted by PSP after %ums\n", jiffies_to_msecs(jiffies - start)); cleanup: + if (ret) { + dev_err(psp_i2c_dev, "Assume i2c bus is for exclusive host usage\n"); + psp_i2c_mbox_fail = true; + } + kfree(req); return ret; } @@ -249,16 +260,8 @@ static int psp_acquire_i2c_bus(void) } status = psp_send_i2c_req(PSP_I2C_REQ_ACQUIRE); - if (status) { - if (status == -ETIMEDOUT) - dev_err(psp_i2c_dev, "Timed out waiting for PSP to release I2C bus\n"); - else - dev_err(psp_i2c_dev, "PSP communication error\n"); - - dev_err(psp_i2c_dev, "Assume i2c bus is for exclusive host usage\n"); - psp_i2c_mbox_fail = true; + if (status) goto cleanup; - } psp_i2c_sem_acquired = jiffies; psp_i2c_access_count++; @@ -294,16 +297,8 @@ static void psp_release_i2c_bus(void) /* Send a release command to PSP */ status = psp_send_i2c_req(PSP_I2C_REQ_RELEASE); - if (status) { - if (status == -ETIMEDOUT) - dev_err(psp_i2c_dev, "Timed out waiting for PSP to acquire I2C bus\n"); - else - dev_err(psp_i2c_dev, "PSP communication error\n"); - - dev_err(psp_i2c_dev, "Assume i2c bus is for exclusive host usage\n"); - psp_i2c_mbox_fail = true; + if (status) goto cleanup; - } dev_dbg(psp_i2c_dev, "PSP semaphore held for %ums\n", jiffies_to_msecs(jiffies - psp_i2c_sem_acquired)); From d714fb25e755ad96b699993fac47f48c4d6cebe9 Mon Sep 17 00:00:00 2001 From: Jae Hyun Yoo Date: Fri, 18 Mar 2022 13:41:33 -0700 Subject: [PATCH 330/370] i2c: add tracepoints for I2C slave events I2C slave events tracepoints can be enabled by: echo 1 > /sys/kernel/tracing/events/i2c_slave/enable and logs in /sys/kernel/tracing/trace will look like: ... i2c_slave: i2c-0 a=010 ret=0 WR_REQ [] ... i2c_slave: i2c-0 a=010 ret=0 WR_RCV [02] ... i2c_slave: i2c-0 a=010 ret=0 WR_RCV [0c] ... i2c_slave: i2c-0 a=010 ret=0 STOP [] ... i2c_slave: i2c-0 a=010 ret=0 RD_REQ [04] ... i2c_slave: i2c-0 a=010 ret=0 RD_PRO [b4] ... i2c_slave: i2c-0 a=010 ret=0 STOP [] formatted as: i2c- a= ret= <- callback return value [] trace printings can be selected by adding a filter like: echo adapter_nr==1 >/sys/kernel/tracing/events/i2c_slave/filter Signed-off-by: Jae Hyun Yoo Signed-off-by: Wolfram Sang --- drivers/i2c/i2c-core-slave.c | 15 +++++++ include/linux/i2c.h | 8 +--- include/trace/events/i2c_slave.h | 67 ++++++++++++++++++++++++++++++++ 3 files changed, 84 insertions(+), 6 deletions(-) create mode 100644 include/trace/events/i2c_slave.h diff --git a/drivers/i2c/i2c-core-slave.c b/drivers/i2c/i2c-core-slave.c index 1589179d5eb9..e3765e12f93b 100644 --- a/drivers/i2c/i2c-core-slave.c +++ b/drivers/i2c/i2c-core-slave.c @@ -14,6 +14,9 @@ #include "i2c-core.h" +#define CREATE_TRACE_POINTS +#include + int i2c_slave_register(struct i2c_client *client, i2c_slave_cb_t slave_cb) { int ret; @@ -79,6 +82,18 @@ int i2c_slave_unregister(struct i2c_client *client) } EXPORT_SYMBOL_GPL(i2c_slave_unregister); +int i2c_slave_event(struct i2c_client *client, + enum i2c_slave_event event, u8 *val) +{ + int ret = client->slave_cb(client, event, val); + + if (trace_i2c_slave_enabled()) + trace_i2c_slave(client, event, val, ret); + + return ret; +} +EXPORT_SYMBOL_GPL(i2c_slave_event); + /** * i2c_detect_slave_mode - detect operation mode * @dev: The device owning the bus diff --git a/include/linux/i2c.h b/include/linux/i2c.h index 7d4f52ceb7b5..fbda5ada2afc 100644 --- a/include/linux/i2c.h +++ b/include/linux/i2c.h @@ -392,12 +392,8 @@ enum i2c_slave_event { int i2c_slave_register(struct i2c_client *client, i2c_slave_cb_t slave_cb); int i2c_slave_unregister(struct i2c_client *client); bool i2c_detect_slave_mode(struct device *dev); - -static inline int i2c_slave_event(struct i2c_client *client, - enum i2c_slave_event event, u8 *val) -{ - return client->slave_cb(client, event, val); -} +int i2c_slave_event(struct i2c_client *client, + enum i2c_slave_event event, u8 *val); #else static inline bool i2c_detect_slave_mode(struct device *dev) { return false; } #endif diff --git a/include/trace/events/i2c_slave.h b/include/trace/events/i2c_slave.h new file mode 100644 index 000000000000..811166abbe3a --- /dev/null +++ b/include/trace/events/i2c_slave.h @@ -0,0 +1,67 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * I2C slave tracepoints + * + * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. + */ +#undef TRACE_SYSTEM +#define TRACE_SYSTEM i2c_slave + +#if !defined(_TRACE_I2C_SLAVE_H) || defined(TRACE_HEADER_MULTI_READ) +#define _TRACE_I2C_SLAVE_H + +#include +#include + +TRACE_DEFINE_ENUM(I2C_SLAVE_READ_REQUESTED); +TRACE_DEFINE_ENUM(I2C_SLAVE_WRITE_REQUESTED); +TRACE_DEFINE_ENUM(I2C_SLAVE_READ_PROCESSED); +TRACE_DEFINE_ENUM(I2C_SLAVE_WRITE_RECEIVED); +TRACE_DEFINE_ENUM(I2C_SLAVE_STOP); + +#define show_event_type(type) \ + __print_symbolic(type, \ + { I2C_SLAVE_READ_REQUESTED, "RD_REQ" }, \ + { I2C_SLAVE_WRITE_REQUESTED, "WR_REQ" }, \ + { I2C_SLAVE_READ_PROCESSED, "RD_PRO" }, \ + { I2C_SLAVE_WRITE_RECEIVED, "WR_RCV" }, \ + { I2C_SLAVE_STOP, " STOP" }) + +TRACE_EVENT(i2c_slave, + TP_PROTO(const struct i2c_client *client, enum i2c_slave_event event, + __u8 *val, int cb_ret), + TP_ARGS(client, event, val, cb_ret), + TP_STRUCT__entry( + __field(int, adapter_nr ) + __field(int, ret ) + __field(__u16, addr ) + __field(__u16, len ) + __field(enum i2c_slave_event, event ) + __array(__u8, buf, 1) ), + + TP_fast_assign( + __entry->adapter_nr = client->adapter->nr; + __entry->addr = client->addr; + __entry->event = event; + __entry->ret = cb_ret; + switch (event) { + case I2C_SLAVE_READ_REQUESTED: + case I2C_SLAVE_READ_PROCESSED: + case I2C_SLAVE_WRITE_RECEIVED: + __entry->len = 1; + memcpy(__entry->buf, val, __entry->len); + break; + default: + __entry->len = 0; + break; + } + ), + TP_printk("i2c-%d a=%03x ret=%d %s [%*phD]", + __entry->adapter_nr, __entry->addr, __entry->ret, + show_event_type(__entry->event), __entry->len, __entry->buf + )); + +#endif /* _TRACE_I2C_SLAVE_H */ + +/* This part must be outside protection */ +#include From cb13aa16f34f794a9cee2626862af8a95f0f0ee9 Mon Sep 17 00:00:00 2001 From: Lucas Tanure Date: Tue, 1 Mar 2022 07:26:00 +0000 Subject: [PATCH 331/370] i2c: meson: Fix wrong speed use from probe Having meson_i2c_set_clk_div after i2c_add_adapter causes issues for client drivers that try to use the bus before the requested speed is applied. The bus can be used just after i2c_add_adapter, so move i2c_add_adapter to the final step as meson_i2c_set_clk_div needs to be called before the bus is used. Fixes: 09af1c2fa490 ("i2c: meson: set clock divider in probe instead of setting it for each transfer") Signed-off-by: Lucas Tanure Reviewed-by: Neil Armstrong Signed-off-by: Wolfram Sang --- drivers/i2c/busses/i2c-meson.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/i2c/busses/i2c-meson.c b/drivers/i2c/busses/i2c-meson.c index ef73a42577cc..07eb819072c4 100644 --- a/drivers/i2c/busses/i2c-meson.c +++ b/drivers/i2c/busses/i2c-meson.c @@ -465,18 +465,18 @@ static int meson_i2c_probe(struct platform_device *pdev) */ meson_i2c_set_mask(i2c, REG_CTRL, REG_CTRL_START, 0); - ret = i2c_add_adapter(&i2c->adap); - if (ret < 0) { - clk_disable_unprepare(i2c->clk); - return ret; - } - /* Disable filtering */ meson_i2c_set_mask(i2c, REG_SLAVE_ADDR, REG_SLV_SDA_FILTER | REG_SLV_SCL_FILTER, 0); meson_i2c_set_clk_div(i2c, timings.bus_freq_hz); + ret = i2c_add_adapter(&i2c->adap); + if (ret < 0) { + clk_disable_unprepare(i2c->clk); + return ret; + } + return 0; } From 1a22aabf20adf89cb216f566913196128766f25b Mon Sep 17 00:00:00 2001 From: Peter Rosin Date: Wed, 2 Mar 2022 12:22:35 +0100 Subject: [PATCH 332/370] i2c: mux: demux-pinctrl: do not deactivate a master that is not active Attempting to rollback the activation of the current master when the current master has not been activated is bad. priv->cur_chan and priv->cur_adap are both still zeroed out and the rollback may result in attempts to revert an of changeset that has not been applied and do result in calls to both del and put the zeroed out i2c_adapter. Maybe it crashes, or whatever, but it's bad in any case. Fixes: e9d1a0a41d44 ("i2c: mux: demux-pinctrl: Fix an error handling path in 'i2c_demux_pinctrl_probe()'") Signed-off-by: Peter Rosin Signed-off-by: Wolfram Sang --- drivers/i2c/muxes/i2c-demux-pinctrl.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/i2c/muxes/i2c-demux-pinctrl.c b/drivers/i2c/muxes/i2c-demux-pinctrl.c index 5365199a31f4..f7a7405d4350 100644 --- a/drivers/i2c/muxes/i2c-demux-pinctrl.c +++ b/drivers/i2c/muxes/i2c-demux-pinctrl.c @@ -261,7 +261,7 @@ static int i2c_demux_pinctrl_probe(struct platform_device *pdev) err = device_create_file(&pdev->dev, &dev_attr_available_masters); if (err) - goto err_rollback; + goto err_rollback_activation; err = device_create_file(&pdev->dev, &dev_attr_current_master); if (err) @@ -271,8 +271,9 @@ static int i2c_demux_pinctrl_probe(struct platform_device *pdev) err_rollback_available: device_remove_file(&pdev->dev, &dev_attr_available_masters); -err_rollback: +err_rollback_activation: i2c_demux_deactivate_master(priv); +err_rollback: for (j = 0; j < i; j++) { of_node_put(priv->chan[j].parent_np); of_changeset_destroy(&priv->chan[j].chgset); From 8d10ea152e2fb9b4a42b282cb90bfc4d98e319a3 Mon Sep 17 00:00:00 2001 From: Tom Rix Date: Sun, 20 Mar 2022 06:59:54 -0700 Subject: [PATCH 333/370] ipmi: initialize len variable Clang static analysis reports this issue ipmi_ssif.c:1731:3: warning: 4th function call argument is an uninitialized value dev_info(&ssif_info->client->dev, ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ The 4th parameter is the 'len' variable. len is only set by a successful call to do_cmd(). Initialize to len 0. Signed-off-by: Tom Rix Message-Id: <20220320135954.2258545-1-trix@redhat.com> Signed-off-by: Corey Minyard --- drivers/char/ipmi/ipmi_ssif.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/char/ipmi/ipmi_ssif.c b/drivers/char/ipmi/ipmi_ssif.c index ba779f1abb5b..f199cc194844 100644 --- a/drivers/char/ipmi/ipmi_ssif.c +++ b/drivers/char/ipmi/ipmi_ssif.c @@ -1625,7 +1625,7 @@ static int ssif_probe(struct i2c_client *client, const struct i2c_device_id *id) unsigned char *resp; struct ssif_info *ssif_info; int rv = 0; - int len; + int len = 0; int i; u8 slave_addr = 0; struct ssif_addr_info *addr_info = NULL; From dba529605f55e7eee725dd8e48a70f95ecdd612c Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Thu, 17 Mar 2022 23:58:40 +0100 Subject: [PATCH 334/370] dt-bindings: gnss: Rewrite common bindings in YAML This rewrites the text-based GNSS common bindings to use a YAML schema. Cc: devicetree@vger.kernel.org Reviewed-by: Krzysztof Kozlowski Signed-off-by: Linus Walleij Signed-off-by: Rob Herring Link: https://lore.kernel.org/r/20220317225844.1262643-1-linus.walleij@linaro.org --- .../devicetree/bindings/gnss/gnss-common.yaml | 55 +++++++++++++++++++ .../devicetree/bindings/gnss/gnss.txt | 37 ------------- 2 files changed, 55 insertions(+), 37 deletions(-) create mode 100644 Documentation/devicetree/bindings/gnss/gnss-common.yaml delete mode 100644 Documentation/devicetree/bindings/gnss/gnss.txt diff --git a/Documentation/devicetree/bindings/gnss/gnss-common.yaml b/Documentation/devicetree/bindings/gnss/gnss-common.yaml new file mode 100644 index 000000000000..963b926e30a7 --- /dev/null +++ b/Documentation/devicetree/bindings/gnss/gnss-common.yaml @@ -0,0 +1,55 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/gnss/gnss-common.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Common Properties for Global Navigation Satellite Systems (GNSS) + receiver devices + +maintainers: + - Johan Hovold + +description: | + This document defines device tree properties common to Global Navigation + Satellite System receivers. + +properties: + $nodename: + pattern: "^gnss(@.*)?$" + + lna-supply: + description: A separate regulator supplying power for the Low Noise + Amplifier (LNA). This is an amplifier connected between the GNSS + device and the receiver antenna. + + enable-gpios: + description: A GPIO line that will enable the GNSS receiver when + asserted. If this line is active low, the GPIO phandle should + consequently be tagged with the GPIO_ACTIVE_LOW flag so the operating + system can rely on asserting the line to enable the GNSS device. + maxItems: 1 + + timepulse-gpios: + description: When a timepulse is provided to the GNSS device using a + GPIO line, this is used. + maxItems: 1 + + current-speed: + description: The baudrate in bits per second of the device as it comes + online, current active speed. + $ref: /schemas/types.yaml#/definitions/uint32 + +additionalProperties: true + +examples: + - | + #include + serial { + gnss { + compatible = "u-blox,neo-8"; + vcc-supply = <&gnss_reg>; + timepulse-gpios = <&gpio0 16 GPIO_ACTIVE_HIGH>; + current-speed = <4800>; + }; + }; diff --git a/Documentation/devicetree/bindings/gnss/gnss.txt b/Documentation/devicetree/bindings/gnss/gnss.txt deleted file mode 100644 index d6dc9c0d8249..000000000000 --- a/Documentation/devicetree/bindings/gnss/gnss.txt +++ /dev/null @@ -1,37 +0,0 @@ -GNSS Receiver DT binding - -This documents the binding structure and common properties for GNSS receiver -devices. - -A GNSS receiver node is a node named "gnss" and typically resides on a serial -bus (e.g. UART, I2C or SPI). - -Please refer to the following documents for generic properties: - - Documentation/devicetree/bindings/serial/serial.yaml - Documentation/devicetree/bindings/spi/spi-bus.txt - -Required properties: - -- compatible : A string reflecting the vendor and specific device the node - represents - -Optional properties: -- lna-supply : Separate supply for an LNA -- enable-gpios : GPIO used to enable the device -- timepulse-gpios : Time pulse GPIO - -Example: - -serial@1234 { - compatible = "ns16550a"; - - gnss { - compatible = "u-blox,neo-8"; - - vcc-supply = <&gnss_reg>; - timepulse-gpios = <&gpio0 16 GPIO_ACTIVE_HIGH>; - - current-speed = <4800>; - }; -}; From 069e6bc6dba532604050f559a5c06fb1525cec04 Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Thu, 17 Mar 2022 23:58:41 +0100 Subject: [PATCH 335/370] dt-bindings: gnss: Modify u-blox to use common bindings This modifies the existing U-Blox GNSS bindings to reference the common GNSS YAML bindings. Fixed an unrelated whitespace error while at it. Cc: devicetree@vger.kernel.org Cc: Krzysztof Kozlowski Signed-off-by: Linus Walleij Reviewed-by: Krzysztof Kozlowski Signed-off-by: Rob Herring Link: https://lore.kernel.org/r/20220317225844.1262643-2-linus.walleij@linaro.org --- .../devicetree/bindings/gnss/u-blox,neo-6m.yaml | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/Documentation/devicetree/bindings/gnss/u-blox,neo-6m.yaml b/Documentation/devicetree/bindings/gnss/u-blox,neo-6m.yaml index 396101a223e7..35a760cfd343 100644 --- a/Documentation/devicetree/bindings/gnss/u-blox,neo-6m.yaml +++ b/Documentation/devicetree/bindings/gnss/u-blox,neo-6m.yaml @@ -6,6 +6,9 @@ $schema: http://devicetree.org/meta-schemas/core.yaml# title: U-blox GNSS Receiver Device Tree Bindings +allOf: + - $ref: gnss-common.yaml# + maintainers: - Johan Hovold @@ -29,27 +32,20 @@ properties: description: > Main voltage regulator - timepulse-gpios: - maxItems: 1 - description: > - Time pulse GPIO - u-blox,extint-gpios: maxItems: 1 description: > GPIO connected to the "external interrupt" input pin - + v-bckp-supply: description: > Backup voltage regulator - current-speed: true - required: - compatible - vcc-supply -additionalProperties: false +unevaluatedProperties: false examples: - | From 5505409e423f61c981d84f53dee2a93bf3ba5913 Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Thu, 17 Mar 2022 23:58:42 +0100 Subject: [PATCH 336/370] dt-bindings: gnss: Rewrite sirfstar binding in YAML This rewrites the SiRFstar DT bindings in YAML. Cc: devicetree@vger.kernel.org Cc: Krzysztof Kozlowski Signed-off-by: Linus Walleij Signed-off-by: Rob Herring Link: https://lore.kernel.org/r/20220317225844.1262643-3-linus.walleij@linaro.org --- .../devicetree/bindings/gnss/sirfstar.txt | 46 ------------- .../devicetree/bindings/gnss/sirfstar.yaml | 68 +++++++++++++++++++ 2 files changed, 68 insertions(+), 46 deletions(-) delete mode 100644 Documentation/devicetree/bindings/gnss/sirfstar.txt create mode 100644 Documentation/devicetree/bindings/gnss/sirfstar.yaml diff --git a/Documentation/devicetree/bindings/gnss/sirfstar.txt b/Documentation/devicetree/bindings/gnss/sirfstar.txt deleted file mode 100644 index f4252b6b660b..000000000000 --- a/Documentation/devicetree/bindings/gnss/sirfstar.txt +++ /dev/null @@ -1,46 +0,0 @@ -SiRFstar-based GNSS Receiver DT binding - -SiRFstar chipsets are used in GNSS-receiver modules produced by several -vendors and can use UART, SPI or I2C interfaces. - -Please see Documentation/devicetree/bindings/gnss/gnss.txt for generic -properties. - -Required properties: - -- compatible : Must be one of - - "fastrax,uc430" - "linx,r4" - "wi2wi,w2sg0004" - "wi2wi,w2sg0008i" - "wi2wi,w2sg0084i" - -- vcc-supply : Main voltage regulator (pin name: 3V3_IN, VCC, VDD) - -Required properties (I2C): -- reg : I2C slave address - -Required properties (SPI): -- reg : SPI chip select address - -Optional properties: - -- sirf,onoff-gpios : GPIO used to power on and off device (pin name: ON_OFF) -- sirf,wakeup-gpios : GPIO used to determine device power state - (pin name: RFPWRUP, WAKEUP) -- timepulse-gpios : Time pulse GPIO (pin name: 1PPS, TM) - -Example: - -serial@1234 { - compatible = "ns16550a"; - - gnss { - compatible = "wi2wi,w2sg0084i"; - - vcc-supply = <&gnss_reg>; - sirf,onoff-gpios = <&gpio0 16 GPIO_ACTIVE_HIGH>; - sirf,wakeup-gpios = <&gpio0 17 GPIO_ACTIVE_HIGH>; - }; -}; diff --git a/Documentation/devicetree/bindings/gnss/sirfstar.yaml b/Documentation/devicetree/bindings/gnss/sirfstar.yaml new file mode 100644 index 000000000000..1178d4b32a5c --- /dev/null +++ b/Documentation/devicetree/bindings/gnss/sirfstar.yaml @@ -0,0 +1,68 @@ +# SPDX-License-Identifier: GPL-2.0 +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/gnss/sirfstar.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: SiRFstar GNSS Receiver Device Tree Bindings + +maintainers: + - Johan Hovold + +description: + The SiRFstar GNSS receivers have incarnated over the years in different + chips, starting from the SiRFstarIII which was a chip that was introduced in + 2004 and used in a lot of dedicated GPS devices. In 2009 SiRF was acquired + by CSR (Cambridge Silicon Radio) and in 2012 the CSR GPS business was + acquired by Samsung, while some products remained with CSR. In 2014 CSR + was acquired by Qualcomm who still sell some of the SiRF products. + + SiRF chips can be used over UART, I2C or SPI buses. + +allOf: + - $ref: gnss-common.yaml# + +properties: + compatible: + enum: + - fastrax,uc430 + - linx,r4 + - wi2wi,w2sg0004 + - wi2wi,w2sg0008i + - wi2wi,w2sg0084i + + reg: + description: + The I2C Address, SPI chip select address. Not required on UART buses. + + vcc-supply: + description: + Main voltage regulator, pin names such as 3V3_IN, VCC, VDD. + + sirf,onoff-gpios: + maxItems: 1 + description: GPIO used to power on and off device, pin name ON_OFF. + + sirf,wakeup-gpios: + maxItems: 1 + description: GPIO used to determine device power state, pin names such + as RFPWRUP, WAKEUP. + +required: + - compatible + - vcc-supply + +unevaluatedProperties: false + +examples: + - | + #include + serial { + gnss { + compatible = "wi2wi,w2sg0084i"; + vcc-supply = <&gnss_vcc_reg>; + sirf,onoff-gpios = <&gpio0 16 GPIO_ACTIVE_HIGH>; + sirf,wakeup-gpios = <&gpio0 17 GPIO_ACTIVE_HIGH>; + current-speed = <38400>; + }; + }; From 094b10cb795a85e2f90f03c24b030888ab2f1fa3 Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Thu, 17 Mar 2022 23:58:43 +0100 Subject: [PATCH 337/370] dt-bindings: gnss: Add two more chips The CSR GSD4t is a CSR product using the SiRFstarIV core, and the CSR CSRG05TA03-ICJE-R is a CSR product using the SiRFstarV core. These chips have a SRESETN line that can be pulled low to hard reset the chip and in some designs this is connected to a GPIO, so add this as an optional property. Update the example with a reset line so users see that it need to be tagged as active low. Cc: devicetree@vger.kernel.org Cc: Krzysztof Kozlowski Signed-off-by: Linus Walleij Reviewed-by: Krzysztof Kozlowski Signed-off-by: Rob Herring Link: https://lore.kernel.org/r/20220317225844.1262643-4-linus.walleij@linaro.org --- Documentation/devicetree/bindings/gnss/sirfstar.yaml | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/Documentation/devicetree/bindings/gnss/sirfstar.yaml b/Documentation/devicetree/bindings/gnss/sirfstar.yaml index 1178d4b32a5c..991599cdaa6b 100644 --- a/Documentation/devicetree/bindings/gnss/sirfstar.yaml +++ b/Documentation/devicetree/bindings/gnss/sirfstar.yaml @@ -25,6 +25,8 @@ allOf: properties: compatible: enum: + - csr,gsd4t + - csr,csrg05ta03-icje-r - fastrax,uc430 - linx,r4 - wi2wi,w2sg0004 @@ -39,6 +41,11 @@ properties: description: Main voltage regulator, pin names such as 3V3_IN, VCC, VDD. + reset-gpios: + maxItems: 1 + description: An optional active low reset line, should be flagged with + GPIO_ACTIVE_LOW. + sirf,onoff-gpios: maxItems: 1 description: GPIO used to power on and off device, pin name ON_OFF. @@ -61,6 +68,7 @@ examples: gnss { compatible = "wi2wi,w2sg0084i"; vcc-supply = <&gnss_vcc_reg>; + reset-gpios = <&gpio0 15 GPIO_ACTIVE_LOW>; sirf,onoff-gpios = <&gpio0 16 GPIO_ACTIVE_HIGH>; sirf,wakeup-gpios = <&gpio0 17 GPIO_ACTIVE_HIGH>; current-speed = <38400>; From 6ac02df3fff71ddacc71e2ae79b73c16873b41c5 Mon Sep 17 00:00:00 2001 From: Rob Herring Date: Wed, 9 Mar 2022 19:35:27 -0600 Subject: [PATCH 338/370] dt-bindings: virtio,mmio: Allow setting devices 'dma-coherent' 'virtio,mmio' devices are always coherent within a guest. As Arm DTs are default non-coherent, the 'dma-coherent' property needs to be set on the virtio device to mark them as such. This aligns with the QEMU 'virt' machine DTB. Signed-off-by: Rob Herring Link: https://lore.kernel.org/r/20220310013528.549030-1-robh@kernel.org --- Documentation/devicetree/bindings/virtio/mmio.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Documentation/devicetree/bindings/virtio/mmio.yaml b/Documentation/devicetree/bindings/virtio/mmio.yaml index 4b7a0273181c..10c22b5bd16a 100644 --- a/Documentation/devicetree/bindings/virtio/mmio.yaml +++ b/Documentation/devicetree/bindings/virtio/mmio.yaml @@ -20,6 +20,8 @@ properties: reg: maxItems: 1 + dma-coherent: true + interrupts: maxItems: 1 From 1d204ee10817aed6666e020ef1b4c643d68bef11 Mon Sep 17 00:00:00 2001 From: Zack Rusin Date: Fri, 18 Mar 2022 13:43:32 -0400 Subject: [PATCH 339/370] drm/ttm: Fix a kernel oops due to an invalid read MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The res is initialized here only if there's no errors so passing it to ttm_resource_fini in the error paths results in a kernel oops. In the error paths, instead of the unitialized res, we have to use to use node->base on which ttm_resource_init was called. Sample affected backtrace: Unable to handle kernel NULL pointer dereference at virtual address 00000000000000d8 Mem abort info: ESR = 0x96000004 EC = 0x25: DABT (current EL), IL = 32 bits SET = 0, FnV = 0 EA = 0, S1PTW = 0 FSC = 0x04: level 0 translation fault Data abort info: ISV = 0, ISS = 0x00000004 CM = 0, WnR = 0 user pgtable: 4k pages, 48-bit VAs, pgdp=0000000106ac0000 [00000000000000d8] pgd=0000000000000000, p4d=0000000000000000 Internal error: Oops: 96000004 [#1] SMP Modules linked in: bnep vsock_loopback vmw_vsock_virtio_transport_common vsock snd_hda_codec_generic snd_hda_intel snd_intel_dspcfg snd_hda_codec snd_hwdep > CPU: 0 PID: 1197 Comm: gnome-shell Tainted: G U 5.17.0-rc2-vmwgfx #2 Hardware name: VMware, Inc. VBSA/VBSA, BIOS VEFI 12/31/2020 pstate: 60400005 (nZCv daif +PAN -UAO -TCO -DIT -SSBS BTYPE=--) pc : ttm_resource_fini+0x5c/0xac [ttm] lr : ttm_range_man_alloc+0x128/0x1e0 [ttm] sp : ffff80000d783510 x29: ffff80000d783510 x28: 0000000000000000 x27: ffff000086514400 x26: 0000000000000300 x25: ffff0000809f9e78 x24: 0000000000000000 x23: ffff80000d783680 x22: ffff000086514400 x21: 00000000ffffffe4 x20: ffff80000d7836a0 x19: ffff0000809f9e00 x18: 0000000000000000 x17: 0000000000000000 x16: 0000000000000000 x15: 0000000000000000 x14: 0000000000000000 x13: 0000000000000800 x12: ffff0000f2600a00 x11: 000000000000fc96 x10: 0000000000000000 x9 : ffff800001295c18 x8 : 0000000000000000 x7 : 0000000000000300 x6 : 0000000000000000 x5 : 0000000000000000 x4 : ffff0000f1034e20 x3 : ffff0000f1034600 x2 : 0000000000000000 x1 : 0000000000000000 x0 : 0000000000600000 Call trace: ttm_resource_fini+0x5c/0xac [ttm] ttm_range_man_alloc+0x128/0x1e0 [ttm] ttm_resource_alloc+0x58/0x90 [ttm] ttm_bo_mem_space+0xc8/0x3e4 [ttm] ttm_bo_validate+0xb4/0x134 [ttm] vmw_bo_pin_in_start_of_vram+0xbc/0x200 [vmwgfx] vmw_framebuffer_pin+0xc0/0x154 [vmwgfx] vmw_ldu_primary_plane_atomic_update+0x8c/0x6e0 [vmwgfx] drm_atomic_helper_commit_planes+0x11c/0x2e0 drm_atomic_helper_commit_tail+0x60/0xb0 commit_tail+0x1b0/0x210 drm_atomic_helper_commit+0x168/0x400 drm_atomic_commit+0x64/0x74 drm_atomic_helper_set_config+0xdc/0x11c drm_mode_setcrtc+0x1c4/0x780 drm_ioctl_kernel+0xd0/0x1a0 drm_ioctl+0x2c4/0x690 vmw_generic_ioctl+0xe0/0x174 [vmwgfx] vmw_unlocked_ioctl+0x24/0x30 [vmwgfx] __arm64_sys_ioctl+0xb4/0x100 invoke_syscall+0x78/0x100 el0_svc_common.constprop.0+0x54/0x184 do_el0_svc+0x34/0x9c el0_svc+0x48/0x1b0 el0t_64_sync_handler+0xa4/0x130 el0t_64_sync+0x1a4/0x1a8 Code: 35000260 f9401a81 52800002 f9403a60 (f9406c23) ---[ end trace 0000000000000000 ]--- Signed-off-by: Zack Rusin Fixes: de3688e469b0 ("drm/ttm: add ttm_resource_fini v2") Cc: Christian König Cc: Daniel Vetter Reviewed-by: Martin Krastev Reviewed-by: Christian König Signed-off-by: Christian König Link: https://patchwork.freedesktop.org/patch/msgid/20220318174332.440068-6-zack@kde.org --- drivers/gpu/drm/ttm/ttm_range_manager.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/ttm/ttm_range_manager.c b/drivers/gpu/drm/ttm/ttm_range_manager.c index 8cd4f3fb9f79..d91666721dc6 100644 --- a/drivers/gpu/drm/ttm/ttm_range_manager.c +++ b/drivers/gpu/drm/ttm/ttm_range_manager.c @@ -89,7 +89,7 @@ static int ttm_range_man_alloc(struct ttm_resource_manager *man, spin_unlock(&rman->lock); if (unlikely(ret)) { - ttm_resource_fini(man, *res); + ttm_resource_fini(man, &node->base); kfree(node); return ret; } From a860f266a0e19f271b839451d291a6acf6ddcfe8 Mon Sep 17 00:00:00 2001 From: Nathan Chancellor Date: Wed, 2 Mar 2022 16:59:09 -0700 Subject: [PATCH 340/370] drm/selftest: plane_helper: Put test structures in static storage Clang warns on certain 32-bit architectures: drivers/gpu/drm/selftests/test-drm_plane_helper.c:76:5: warning: stack frame size (1064) exceeds limit (1024) in 'igt_check_plane_state' [-Wframe-larger-than] int igt_check_plane_state(void *ignored) ^ 1 warning generated. The structures in igt_check_plane_state() total 1008 bytes, so any small amount of inlining will cause the stack frame to exceed the 32-bit limit of 1024, triggering the warning. Move these structures to static storage, which dramatically reduces the amount of stack space in igt_check_plane_state(). There is no testing impact, as igt_check_plane_state() is only called once in the driver. Fixes: 943e6a8beeac ("mock a drm_plane in igt_check_plane_state to make the test more robust") Link: https://github.com/ClangBuiltLinux/linux/issues/1600 Reported-by: kernel test robot Suggested-by: Nick Desaulniers Signed-off-by: Nathan Chancellor Reviewed-by: Nick Desaulniers Signed-off-by: Maxime Ripard Link: https://patchwork.freedesktop.org/patch/msgid/20220302235909.784935-1-nathan@kernel.org --- drivers/gpu/drm/selftests/test-drm_plane_helper.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/selftests/test-drm_plane_helper.c b/drivers/gpu/drm/selftests/test-drm_plane_helper.c index ceebeede55ea..b61273e9c403 100644 --- a/drivers/gpu/drm/selftests/test-drm_plane_helper.c +++ b/drivers/gpu/drm/selftests/test-drm_plane_helper.c @@ -77,7 +77,7 @@ int igt_check_plane_state(void *ignored) { int ret; - const struct drm_crtc_state crtc_state = { + static const struct drm_crtc_state crtc_state = { .crtc = ZERO_SIZE_PTR, .enable = true, .active = true, @@ -87,14 +87,14 @@ int igt_check_plane_state(void *ignored) DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) }, }; - struct drm_plane plane = { + static struct drm_plane plane = { .dev = NULL }; - struct drm_framebuffer fb = { + static struct drm_framebuffer fb = { .width = 2048, .height = 2048 }; - struct drm_plane_state plane_state = { + static struct drm_plane_state plane_state = { .plane = &plane, .crtc = ZERO_SIZE_PTR, .fb = &fb, From 9cddf03b2af07443bebdc73cba21acb360c079e8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Fri, 11 Mar 2022 23:28:45 +0200 Subject: [PATCH 341/370] drm/i915: Reject unsupported TMDS rates on ICL+ MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ICL+ PLLs can't genenerate certain frequencies. Running the PLL algorithms through for all frequencies 25-594MHz we see a gap just above 500 MHz. Specifically 500-522.8MHZ for TC PLLs, and 500-533.2 MHz for combo PHY PLLs. Reject those frequencies hdmi_port_clock_valid() so that we properly filter out unsupported modes and/or color depths for HDMI. Cc: stable@vger.kernel.org Closes: https://gitlab.freedesktop.org/drm/intel/-/issues/5247 Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20220311212845.32358-1-ville.syrjala@linux.intel.com Reviewed-by: Mika Kahola (cherry picked from commit e5086cb3f3d3f94091be29eec38cf13f8a75a778) Signed-off-by: Tvrtko Ursulin --- drivers/gpu/drm/i915/display/intel_hdmi.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/drivers/gpu/drm/i915/display/intel_hdmi.c b/drivers/gpu/drm/i915/display/intel_hdmi.c index 1aa5bdc7b0dc..6512f014cad4 100644 --- a/drivers/gpu/drm/i915/display/intel_hdmi.c +++ b/drivers/gpu/drm/i915/display/intel_hdmi.c @@ -1836,6 +1836,7 @@ hdmi_port_clock_valid(struct intel_hdmi *hdmi, bool has_hdmi_sink) { struct drm_i915_private *dev_priv = intel_hdmi_to_i915(hdmi); + enum phy phy = intel_port_to_phy(dev_priv, hdmi_to_dig_port(hdmi)->base.port); if (clock < 25000) return MODE_CLOCK_LOW; @@ -1856,6 +1857,14 @@ hdmi_port_clock_valid(struct intel_hdmi *hdmi, if (IS_CHERRYVIEW(dev_priv) && clock > 216000 && clock < 240000) return MODE_CLOCK_RANGE; + /* ICL+ combo PHY PLL can't generate 500-533.2 MHz */ + if (intel_phy_is_combo(dev_priv, phy) && clock > 500000 && clock < 533200) + return MODE_CLOCK_RANGE; + + /* ICL+ TC PHY PLL can't generate 500-532.8 MHz */ + if (intel_phy_is_tc(dev_priv, phy) && clock > 500000 && clock < 532800) + return MODE_CLOCK_RANGE; + /* * SNPS PHYs' MPLLB table-based programming can only handle a fixed * set of link rates. From 1937f3feb0e84089ae4065e09c871b8ab4676f01 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Wed, 9 Mar 2022 18:49:41 +0200 Subject: [PATCH 342/370] drm/i915: Treat SAGV block time 0 as SAGV disabled MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit For modern platforms the spec explicitly states that a SAGV block time of zero means that SAGV is not supported. Let's extend that to all platforms. Supposedly there should be no systems where this isn't true, and it'll allow us to: - use the same code regardless of older vs. newer platform - wm latencies already treat 0 as disabled, so this fits well with other related code - make it a bit more clear when SAGV is used vs. not - avoid overflows from adding U32_MAX with a u16 wm0 latency value which could cause us to miscalculate the SAGV watermarks on tgl+ Cc: stable@vger.kernel.org Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20220309164948.10671-2-ville.syrjala@linux.intel.com Reviewed-by: Stanislav Lisovskiy (cherry picked from commit d8f5855b31c0523ea3b171db8dfb998830e8735d) Signed-off-by: Tvrtko Ursulin --- drivers/gpu/drm/i915/intel_pm.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index 71f7fba2c9e2..9333f732cda8 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -3698,8 +3698,7 @@ skl_setup_sagv_block_time(struct drm_i915_private *dev_priv) MISSING_CASE(DISPLAY_VER(dev_priv)); } - /* Default to an unusable block time */ - dev_priv->sagv_block_time_us = -1; + dev_priv->sagv_block_time_us = 0; } /* @@ -5645,7 +5644,7 @@ static void skl_compute_plane_wm(const struct intel_crtc_state *crtc_state, result->min_ddb_alloc = max(min_ddb_alloc, blocks) + 1; result->enable = true; - if (DISPLAY_VER(dev_priv) < 12) + if (DISPLAY_VER(dev_priv) < 12 && dev_priv->sagv_block_time_us) result->can_sagv = latency >= dev_priv->sagv_block_time_us; } @@ -5678,7 +5677,10 @@ static void tgl_compute_sagv_wm(const struct intel_crtc_state *crtc_state, struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev); struct skl_wm_level *sagv_wm = &plane_wm->sagv.wm0; struct skl_wm_level *levels = plane_wm->wm; - unsigned int latency = dev_priv->wm.skl_latency[0] + dev_priv->sagv_block_time_us; + unsigned int latency = 0; + + if (dev_priv->sagv_block_time_us) + latency = dev_priv->sagv_block_time_us + dev_priv->wm.skl_latency[0]; skl_compute_plane_wm(crtc_state, plane, 0, latency, wm_params, &levels[0], From 3ef8b5e19ead5a79600ea55f9549658281415893 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Wed, 9 Mar 2022 18:49:46 +0200 Subject: [PATCH 343/370] drm/i915: Fix PSF GV point mask when SAGV is not possible MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Don't just mask off all the PSF GV points when SAGV gets disabled. This should in fact cause the Pcode to reject the request since at least one PSF point must remain enabled at all times. Cc: stable@vger.kernel.org Cc: Stanislav Lisovskiy Fixes: 192fbfb76744 ("drm/i915: Implement PSF GV point support") Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20220309164948.10671-7-ville.syrjala@linux.intel.com Reviewed-by: Stanislav Lisovskiy (cherry picked from commit 0fed4ddd18f064d2359b430c6e83ee60dd1f49b1) Signed-off-by: Tvrtko Ursulin --- drivers/gpu/drm/i915/display/intel_bw.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/display/intel_bw.c b/drivers/gpu/drm/i915/display/intel_bw.c index ad1564ca7269..adf58c58513b 100644 --- a/drivers/gpu/drm/i915/display/intel_bw.c +++ b/drivers/gpu/drm/i915/display/intel_bw.c @@ -992,7 +992,8 @@ int intel_bw_atomic_check(struct intel_atomic_state *state) * cause. */ if (!intel_can_enable_sagv(dev_priv, new_bw_state)) { - allowed_points = BIT(max_bw_point); + allowed_points &= ADLS_PSF_PT_MASK; + allowed_points |= BIT(max_bw_point); drm_dbg_kms(&dev_priv->drm, "No SAGV, using single QGV point %d\n", max_bw_point); } From 00f4150d27d2c01eaeffe1091fc311a7c0872c69 Mon Sep 17 00:00:00 2001 From: Lucas De Marchi Date: Wed, 16 Mar 2022 16:45:37 -0700 Subject: [PATCH 344/370] drm/i915: Fix renamed struct field MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Earlier versions of commit a5b7ef27da60 ("drm/i915: Add struct to hold IP version") named "ver" as "arch" and then when it was renamed it missed the rename on MEDIA_VER_FULL() since it it's currently not used. Fixes: a5b7ef27da60 ("drm/i915: Add struct to hold IP version") Cc: José Roberto de Souza Cc: Matt Roper Signed-off-by: Lucas De Marchi Reviewed-by: José Roberto de Souza Link: https://patchwork.freedesktop.org/patch/msgid/20220316234538.434357-1-lucas.demarchi@intel.com (cherry picked from commit b4ac33b973233dc08a56c8ef9d3c2edeab7a4370) Signed-off-by: Tvrtko Ursulin --- drivers/gpu/drm/i915/i915_drv.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index d134838b3458..fa14da84362e 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -947,7 +947,7 @@ static inline struct intel_gt *to_gt(struct drm_i915_private *i915) (GRAPHICS_VER(i915) >= (from) && GRAPHICS_VER(i915) <= (until)) #define MEDIA_VER(i915) (INTEL_INFO(i915)->media.ver) -#define MEDIA_VER_FULL(i915) IP_VER(INTEL_INFO(i915)->media.arch, \ +#define MEDIA_VER_FULL(i915) IP_VER(INTEL_INFO(i915)->media.ver, \ INTEL_INFO(i915)->media.rel) #define IS_MEDIA_VER(i915, from, until) \ (MEDIA_VER(i915) >= (from) && MEDIA_VER(i915) <= (until)) From 028152260c5782504995e1fe3910ad39d4e4f34a Mon Sep 17 00:00:00 2001 From: Rob Herring Date: Mon, 21 Mar 2022 11:35:29 -0500 Subject: [PATCH 345/370] Revert "of: base: Introduce of_alias_get_alias_list() to check alias IDs" This reverts commit b1078c355d76769b5ddefc67d143fbd9b6e52c05. The single user of of_alias_get_alias_list(), drivers/tty/serial/xilinx_uartps.c, has since been refactored and no longer needs this function. It also contained a Smatch checker warning: drivers/of/base.c:2038 of_alias_get_alias_list() warn: passing negative bit value 's32min-(-2),0-s32max' to 'set_bit()' Reported-by: Dan Carpenter Signed-off-by: Rob Herring --- drivers/of/base.c | 54 ---------------------------------------------- include/linux/of.h | 10 --------- 2 files changed, 64 deletions(-) diff --git a/drivers/of/base.c b/drivers/of/base.c index e7d92b67cb8a..d4f98c8469ed 100644 --- a/drivers/of/base.c +++ b/drivers/of/base.c @@ -16,7 +16,6 @@ #define pr_fmt(fmt) "OF: " fmt -#include #include #include #include @@ -1992,59 +1991,6 @@ int of_alias_get_id(struct device_node *np, const char *stem) } EXPORT_SYMBOL_GPL(of_alias_get_id); -/** - * of_alias_get_alias_list - Get alias list for the given device driver - * @matches: Array of OF device match structures to search in - * @stem: Alias stem of the given device_node - * @bitmap: Bitmap field pointer - * @nbits: Maximum number of alias IDs which can be recorded in bitmap - * - * The function travels the lookup table to record alias ids for the given - * device match structures and alias stem. - * - * Return: 0 or -ENOSYS when !CONFIG_OF or - * -EOVERFLOW if alias ID is greater then allocated nbits - */ -int of_alias_get_alias_list(const struct of_device_id *matches, - const char *stem, unsigned long *bitmap, - unsigned int nbits) -{ - struct alias_prop *app; - int ret = 0; - - /* Zero bitmap field to make sure that all the time it is clean */ - bitmap_zero(bitmap, nbits); - - mutex_lock(&of_mutex); - pr_debug("%s: Looking for stem: %s\n", __func__, stem); - list_for_each_entry(app, &aliases_lookup, link) { - pr_debug("%s: stem: %s, id: %d\n", - __func__, app->stem, app->id); - - if (strcmp(app->stem, stem) != 0) { - pr_debug("%s: stem comparison didn't pass %s\n", - __func__, app->stem); - continue; - } - - if (of_match_node(matches, app->np)) { - pr_debug("%s: Allocated ID %d\n", __func__, app->id); - - if (app->id >= nbits) { - pr_warn("%s: ID %d >= than bitmap field %d\n", - __func__, app->id, nbits); - ret = -EOVERFLOW; - } else { - set_bit(app->id, bitmap); - } - } - } - mutex_unlock(&of_mutex); - - return ret; -} -EXPORT_SYMBOL_GPL(of_alias_get_alias_list); - /** * of_alias_get_highest_id - Get highest alias id for the given stem * @stem: Alias stem to be examined diff --git a/include/linux/of.h b/include/linux/of.h index 2dc77430a91a..04971e85fbc9 100644 --- a/include/linux/of.h +++ b/include/linux/of.h @@ -388,9 +388,6 @@ extern int of_phandle_iterator_args(struct of_phandle_iterator *it, extern void of_alias_scan(void * (*dt_alloc)(u64 size, u64 align)); extern int of_alias_get_id(struct device_node *np, const char *stem); extern int of_alias_get_highest_id(const char *stem); -extern int of_alias_get_alias_list(const struct of_device_id *matches, - const char *stem, unsigned long *bitmap, - unsigned int nbits); extern int of_machine_is_compatible(const char *compat); @@ -766,13 +763,6 @@ static inline int of_alias_get_highest_id(const char *stem) return -ENOSYS; } -static inline int of_alias_get_alias_list(const struct of_device_id *matches, - const char *stem, unsigned long *bitmap, - unsigned int nbits) -{ - return -ENOSYS; -} - static inline int of_machine_is_compatible(const char *compat) { return 0; From 3f9a07558f1e3420c9319f39606f06fe3ebc865e Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Wed, 16 Mar 2022 14:08:57 +0100 Subject: [PATCH 346/370] dt-bindings: gpio: pca95xx: drop useless consumer example Consumer examples in the bindings of resource providers are trivial, useless and duplication of code. Remove the example code for consumer Signed-off-by: Krzysztof Kozlowski Signed-off-by: Rob Herring Link: https://lore.kernel.org/r/20220316130858.93455-1-krzysztof.kozlowski@canonical.com --- Documentation/devicetree/bindings/gpio/gpio-pca95xx.yaml | 8 -------- 1 file changed, 8 deletions(-) diff --git a/Documentation/devicetree/bindings/gpio/gpio-pca95xx.yaml b/Documentation/devicetree/bindings/gpio/gpio-pca95xx.yaml index b6a6e742b66d..dc0fc8fc4839 100644 --- a/Documentation/devicetree/bindings/gpio/gpio-pca95xx.yaml +++ b/Documentation/devicetree/bindings/gpio/gpio-pca95xx.yaml @@ -190,14 +190,6 @@ examples: "chg-status+red", "green", "blue", "en-esata", "fault1", "p26", "p27"; }; - - ts3a227@3b { - compatible = "ti,ts3a227e"; - reg = <0x3b>; - interrupt-parent = <&gpio99>; - interrupts = <14 IRQ_TYPE_EDGE_RISING>; - ti,micbias = <0>; /* 2.1V */ - }; }; - | From 09f724e196e5b84b578d558d755638dd802800d8 Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Fri, 18 Mar 2022 17:20:43 +0100 Subject: [PATCH 347/370] dt-bindings: dmaengine: sifive,fu540-c000: include generic schema Include generic dma-controller.yaml schema, which enforces node naming and other generic properties. Signed-off-by: Krzysztof Kozlowski Signed-off-by: Rob Herring Link: https://lore.kernel.org/r/20220318162044.169350-1-krzysztof.kozlowski@canonical.com --- .../devicetree/bindings/dma/sifive,fu540-c000-pdma.yaml | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/Documentation/devicetree/bindings/dma/sifive,fu540-c000-pdma.yaml b/Documentation/devicetree/bindings/dma/sifive,fu540-c000-pdma.yaml index 75ad898c59bc..47c46af25536 100644 --- a/Documentation/devicetree/bindings/dma/sifive,fu540-c000-pdma.yaml +++ b/Documentation/devicetree/bindings/dma/sifive,fu540-c000-pdma.yaml @@ -22,6 +22,9 @@ description: | https://static.dev.sifive.com/FU540-C000-v1.0.pdf +allOf: + - $ref: "dma-controller.yaml#" + properties: compatible: items: @@ -41,13 +44,12 @@ required: - compatible - reg - interrupts - - '#dma-cells' -additionalProperties: false +unevaluatedProperties: false examples: - | - dma@3000000 { + dma-controller@3000000 { compatible = "sifive,fu540-c000-pdma"; reg = <0x3000000 0x8000>; interrupts = <23>, <24>, <25>, <26>, <27>, <28>, <29>, <30>; From 3d8fa7a22dcd54ccfdcea6ed0d9badbdb8594274 Mon Sep 17 00:00:00 2001 From: Luca Weiss Date: Mon, 21 Mar 2022 14:33:13 +0100 Subject: [PATCH 348/370] dt-bindings: ufs: qcom: Add SM6350 compatible string Document the compatible for the UFS found on SM6350. Signed-off-by: Luca Weiss Reviewed-by: Krzysztof Kozlowski Reviewed-by: Alim Akhtar Signed-off-by: Rob Herring Link: https://lore.kernel.org/r/20220321133318.99406-2-luca.weiss@fairphone.com --- Documentation/devicetree/bindings/ufs/qcom,ufs.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Documentation/devicetree/bindings/ufs/qcom,ufs.yaml b/Documentation/devicetree/bindings/ufs/qcom,ufs.yaml index 5b3a2157f7e5..dcd32c10205a 100644 --- a/Documentation/devicetree/bindings/ufs/qcom,ufs.yaml +++ b/Documentation/devicetree/bindings/ufs/qcom,ufs.yaml @@ -27,6 +27,7 @@ properties: - qcom,msm8996-ufshc - qcom,msm8998-ufshc - qcom,sdm845-ufshc + - qcom,sm6350-ufshc - qcom,sm8150-ufshc - qcom,sm8250-ufshc - qcom,sm8350-ufshc @@ -125,6 +126,7 @@ allOf: contains: enum: - qcom,sdm845-ufshc + - qcom,sm6350-ufshc - qcom,sm8150-ufshc then: properties: From 1e21270685ae4c14361dd501da62cdc4be867d4e Mon Sep 17 00:00:00 2001 From: Keith Busch Date: Tue, 22 Mar 2022 08:21:07 -0600 Subject: [PATCH 349/370] crypto: fix crc64 testmgr digest byte order The result is set in little endian, so the expected digest needs to be consistent for big endian machines. Fixes: f3813f4b287e ("crypto: add rocksoft 64b crc guard tag framework") Reported-by: Vasily Gorbik Reported-by: Corentin Labbe Signed-off-by: Keith Busch Link: https://lore.kernel.org/r/20220322142107.4581-1-kbusch@kernel.org Signed-off-by: Jens Axboe --- crypto/testmgr.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/crypto/testmgr.h b/crypto/testmgr.h index f1a22794c404..59919a636508 100644 --- a/crypto/testmgr.h +++ b/crypto/testmgr.h @@ -3686,11 +3686,11 @@ static const struct hash_testvec crc64_rocksoft_tv_template[] = { { .plaintext = zeroes, .psize = 4096, - .digest = (u8 *)(u64[]){ 0x6482d367eb22b64eull }, + .digest = "\x4e\xb6\x22\xeb\x67\xd3\x82\x64", }, { .plaintext = ones, .psize = 4096, - .digest = (u8 *)(u64[]){ 0xc0ddba7302eca3acull }, + .digest = "\xac\xa3\xec\x02\x73\xba\xdd\xc0", } }; From 748718bcc0a2bc3bdc03ea86819bdf60dc6412e7 Mon Sep 17 00:00:00 2001 From: Claudiu Beznea Date: Tue, 7 Dec 2021 13:15:15 +0200 Subject: [PATCH 350/370] mfd: atmel-flexcom: Fix compilation warning Fix "unused variable 'atmel_flexcom_pm_ops' [-Wunused-const-variable]" compilation warning by using __maybe_unused on PM ops. Reported-by: kernel test robot Signed-off-by: Claudiu Beznea Acked-by: Nicolas Ferre Signed-off-by: Lee Jones Link: https://lore.kernel.org/r/20211207111515.814653-1-claudiu.beznea@microchip.com --- drivers/mfd/atmel-flexcom.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/mfd/atmel-flexcom.c b/drivers/mfd/atmel-flexcom.c index 559eb4d352b6..33caa4fba6af 100644 --- a/drivers/mfd/atmel-flexcom.c +++ b/drivers/mfd/atmel-flexcom.c @@ -105,7 +105,7 @@ static int __maybe_unused atmel_flexcom_resume_noirq(struct device *dev) return 0; } -static const struct dev_pm_ops atmel_flexcom_pm_ops = { +static const struct dev_pm_ops __maybe_unused atmel_flexcom_pm_ops = { .resume_noirq = atmel_flexcom_resume_noirq, }; From 9876ef1d7ea038a9d0a6cb850cc8b12f9098dc45 Mon Sep 17 00:00:00 2001 From: Rob Herring Date: Mon, 28 Feb 2022 16:15:37 -0600 Subject: [PATCH 351/370] dt-bindings: Add compatibles for undocumented trivial syscons 'intel,lgm-syscon', 'marvell,armada-3700-usb2-host-misc', 'mediatek,mt8135-pctl-a-syscfg', and 'mediatek,mt8135-pctl-b-syscfg' are all used in DT binding examples and/or dts files, but are not documented. Add them to syscon.yaml as they are all trivial cases. Signed-off-by: Rob Herring Reviewed-by: Matthias Brugger Signed-off-by: Lee Jones Link: https://lore.kernel.org/r/20220228221537.1700071-1-robh@kernel.org --- Documentation/devicetree/bindings/mfd/syscon.yaml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Documentation/devicetree/bindings/mfd/syscon.yaml b/Documentation/devicetree/bindings/mfd/syscon.yaml index eeac1cbc5a17..29d4a97f7108 100644 --- a/Documentation/devicetree/bindings/mfd/syscon.yaml +++ b/Documentation/devicetree/bindings/mfd/syscon.yaml @@ -44,6 +44,10 @@ properties: - hisilicon,hi6220-sramctrl - hisilicon,pcie-sas-subctrl - hisilicon,peri-subctrl + - intel,lgm-syscon + - marvell,armada-3700-usb2-host-misc + - mediatek,mt8135-pctl-a-syscfg + - mediatek,mt8135-pctl-b-syscfg - microchip,sparx5-cpu-syscon - mstar,msc313-pmsleep - rockchip,px30-qos From e7391b021e3f7bac37ec485f2ed1ca6787a800a7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= Date: Wed, 16 Feb 2022 12:29:28 +0100 Subject: [PATCH 352/370] dt-bindings: mfd: brcm,cru: Rename pinctrl node MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This matches pinctrl.yaml requirement and fixes: Documentation/devicetree/bindings/mfd/brcm,cru.example.dt.yaml: pin-controller@1c0: $nodename:0: 'pin-controller@1c0' does not match '^(pinctrl|pinmux)(@[0-9a-f]+)?$' From schema: Documentation/devicetree/bindings/pinctrl/brcm,ns-pinmux.yaml Signed-off-by: Rafał Miłecki Reviewed-by: Rob Herring Signed-off-by: Lee Jones Link: https://lore.kernel.org/r/20220216112928.5330-1-zajec5@gmail.com --- Documentation/devicetree/bindings/mfd/brcm,cru.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Documentation/devicetree/bindings/mfd/brcm,cru.yaml b/Documentation/devicetree/bindings/mfd/brcm,cru.yaml index be4a2df71c25..b85819fbb07c 100644 --- a/Documentation/devicetree/bindings/mfd/brcm,cru.yaml +++ b/Documentation/devicetree/bindings/mfd/brcm,cru.yaml @@ -39,7 +39,7 @@ patternProperties: '^phy@[a-f0-9]+$': $ref: ../phy/bcm-ns-usb2-phy.yaml - '^pin-controller@[a-f0-9]+$': + '^pinctrl@[a-f0-9]+$': $ref: ../pinctrl/brcm,ns-pinmux.yaml '^syscon@[a-f0-9]+$': @@ -94,7 +94,7 @@ examples: reg = <0x180 0x4>; }; - pin-controller@1c0 { + pinctrl@1c0 { compatible = "brcm,bcm4708-pinmux"; reg = <0x1c0 0x24>; reg-names = "cru_gpio_control"; From 5a2d27c283db049e46c7fac5092ea45c6add2d47 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Tue, 1 Mar 2022 22:50:56 +0200 Subject: [PATCH 353/370] mfd: intel-lpss: Provide an SSP type to the driver The SPI driver wants to know the exact type of the controller. Provide this information to it, hence it allows to fix the Intel Cannon Lake and others in the future. Signed-off-by: Andy Shevchenko Signed-off-by: Lee Jones Link: https://lore.kernel.org/r/20220301205056.79810-1-andriy.shevchenko@linux.intel.com --- drivers/mfd/intel-lpss-acpi.c | 41 ++++++++++++++++++++++++++++++++--- 1 file changed, 38 insertions(+), 3 deletions(-) diff --git a/drivers/mfd/intel-lpss-acpi.c b/drivers/mfd/intel-lpss-acpi.c index f2ea6540a01e..a143c8dca2d9 100644 --- a/drivers/mfd/intel-lpss-acpi.c +++ b/drivers/mfd/intel-lpss-acpi.c @@ -15,11 +15,22 @@ #include #include #include +#include #include "intel-lpss.h" +static const struct property_entry spt_spi_properties[] = { + PROPERTY_ENTRY_U32("intel,spi-pxa2xx-type", LPSS_SPT_SSP), + { } +}; + +static const struct software_node spt_spi_node = { + .properties = spt_spi_properties, +}; + static const struct intel_lpss_platform_info spt_info = { .clk_rate = 120000000, + .swnode = &spt_spi_node, }; static const struct property_entry spt_i2c_properties[] = { @@ -53,8 +64,18 @@ static const struct intel_lpss_platform_info spt_uart_info = { .swnode = &uart_node, }; +static const struct property_entry bxt_spi_properties[] = { + PROPERTY_ENTRY_U32("intel,spi-pxa2xx-type", LPSS_BXT_SSP), + { } +}; + +static const struct software_node bxt_spi_node = { + .properties = bxt_spi_properties, +}; + static const struct intel_lpss_platform_info bxt_info = { .clk_rate = 100000000, + .swnode = &bxt_spi_node, }; static const struct property_entry bxt_i2c_properties[] = { @@ -89,6 +110,20 @@ static const struct intel_lpss_platform_info apl_i2c_info = { .swnode = &apl_i2c_node, }; +static const struct property_entry cnl_spi_properties[] = { + PROPERTY_ENTRY_U32("intel,spi-pxa2xx-type", LPSS_CNL_SSP), + { } +}; + +static const struct software_node cnl_spi_node = { + .properties = cnl_spi_properties, +}; + +static const struct intel_lpss_platform_info cnl_info = { + .clk_rate = 120000000, + .swnode = &cnl_spi_node, +}; + static const struct intel_lpss_platform_info cnl_i2c_info = { .clk_rate = 216000000, .swnode = &spt_i2c_node, @@ -108,8 +143,8 @@ static const struct acpi_device_id intel_lpss_acpi_ids[] = { { "INT3449", (kernel_ulong_t)&spt_uart_info }, { "INT344A", (kernel_ulong_t)&spt_uart_info }, /* CNL */ - { "INT34B0", (kernel_ulong_t)&spt_info }, - { "INT34B1", (kernel_ulong_t)&spt_info }, + { "INT34B0", (kernel_ulong_t)&cnl_info }, + { "INT34B1", (kernel_ulong_t)&cnl_info }, { "INT34B2", (kernel_ulong_t)&cnl_i2c_info }, { "INT34B3", (kernel_ulong_t)&cnl_i2c_info }, { "INT34B4", (kernel_ulong_t)&cnl_i2c_info }, @@ -119,7 +154,7 @@ static const struct acpi_device_id intel_lpss_acpi_ids[] = { { "INT34B8", (kernel_ulong_t)&spt_uart_info }, { "INT34B9", (kernel_ulong_t)&spt_uart_info }, { "INT34BA", (kernel_ulong_t)&spt_uart_info }, - { "INT34BC", (kernel_ulong_t)&spt_info }, + { "INT34BC", (kernel_ulong_t)&cnl_info }, /* BXT */ { "80860AAC", (kernel_ulong_t)&bxt_i2c_info }, { "80860ABC", (kernel_ulong_t)&bxt_info }, From e4f8e06515e2ed015e36f1a1ef6ebc811f446d10 Mon Sep 17 00:00:00 2001 From: Lukas Bulwahn Date: Tue, 8 Mar 2022 09:51:36 +0100 Subject: [PATCH 354/370] MAINTAINERS: Rectify entry for ROHM MULTIFUNCTION BD9571MWV-M PMIC DEVICE DRIVERS Commit 983b62975e90 ("dt-bindings: mfd: bd9571mwv: Convert to json-schema") converts bd9571mwv.txt to rohm,bd9571mwv.yaml, but missed to adjust its reference in MAINTAINERS. Hence, ./scripts/get_maintainer.pl --self-test=patterns complains about a broken reference. Repair this file reference in ROHM MULTIFUNCTION BD9571MWV-M PMIC DEVICE DRIVERS. Signed-off-by: Lukas Bulwahn Reviewed-by: Geert Uytterhoeven Signed-off-by: Lee Jones Link: https://lore.kernel.org/r/20220308085136.30753-1-lukas.bulwahn@gmail.com --- MAINTAINERS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MAINTAINERS b/MAINTAINERS index 89d074afdafe..e7b13cc7684d 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -16674,7 +16674,7 @@ M: Marek Vasut L: linux-kernel@vger.kernel.org L: linux-renesas-soc@vger.kernel.org S: Supported -F: Documentation/devicetree/bindings/mfd/bd9571mwv.txt +F: Documentation/devicetree/bindings/mfd/rohm,bd9571mwv.yaml F: drivers/gpio/gpio-bd9571mwv.c F: drivers/mfd/bd9571mwv.c F: drivers/regulator/bd9571mwv-regulator.c From e84ee1a75f944a0fe3c277aaa10c426603d2b0bc Mon Sep 17 00:00:00 2001 From: Miaoqian Lin Date: Mon, 7 Mar 2022 07:29:47 +0000 Subject: [PATCH 355/370] mfd: asic3: Add missing iounmap() on error asic3_mfd_probe Add the missing iounmap() before return from asic3_mfd_probe in the error handling case. Fixes: 64e8867ba809 ("mfd: tmio_mmc hardware abstraction for CNF area") Signed-off-by: Miaoqian Lin Signed-off-by: Lee Jones Link: https://lore.kernel.org/r/20220307072947.5369-1-linmq006@gmail.com --- drivers/mfd/asic3.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/drivers/mfd/asic3.c b/drivers/mfd/asic3.c index 8d58c8df46cf..56338f9dbd0b 100644 --- a/drivers/mfd/asic3.c +++ b/drivers/mfd/asic3.c @@ -906,14 +906,14 @@ static int __init asic3_mfd_probe(struct platform_device *pdev, ret = mfd_add_devices(&pdev->dev, pdev->id, &asic3_cell_ds1wm, 1, mem, asic->irq_base, NULL); if (ret < 0) - goto out; + goto out_unmap; } if (mem_sdio && (irq >= 0)) { ret = mfd_add_devices(&pdev->dev, pdev->id, &asic3_cell_mmc, 1, mem_sdio, irq, NULL); if (ret < 0) - goto out; + goto out_unmap; } ret = 0; @@ -927,8 +927,12 @@ static int __init asic3_mfd_probe(struct platform_device *pdev, ret = mfd_add_devices(&pdev->dev, 0, asic3_cell_leds, ASIC3_NUM_LEDS, NULL, 0, NULL); } + return ret; - out: +out_unmap: + if (asic->tmio_cnf) + iounmap(asic->tmio_cnf); +out: return ret; } From 3cf2b4344b651b94d62411963e666c9cb5b99e62 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Mon, 7 Mar 2022 18:38:43 +0100 Subject: [PATCH 356/370] mfd: arizona-spi: Split Windows ACPI init code into its own function x86/ACPI boards with an arizona WM5102 codec ship with either Windows or Android as factory installed OS. The ACPI fwnode describing the codec differs depending on the factory OS, and the current arizona_spi_acpi_probe() function is tailored for use with the Windows board ACPI tables. Split out the Windows board ACPI tables specific bits into a new arizona_spi_acpi_windows_probe() function in preparation for also adding support for the Android board ACPI tables. Signed-off-by: Hans de Goede Acked-by: Charles Keepax Signed-off-by: Lee Jones Link: https://lore.kernel.org/r/20220307173844.199135-1-hdegoede@redhat.com --- drivers/mfd/arizona-spi.c | 52 ++++++++++++++++++++++++--------------- 1 file changed, 32 insertions(+), 20 deletions(-) diff --git a/drivers/mfd/arizona-spi.c b/drivers/mfd/arizona-spi.c index 98c87d3bd00f..6f8076439e74 100644 --- a/drivers/mfd/arizona-spi.c +++ b/drivers/mfd/arizona-spi.c @@ -43,31 +43,13 @@ static const struct gpiod_lookup arizona_soc_gpios[] = { { "arizona", 4, "wlf,micd-pol", 0, GPIO_ACTIVE_LOW }, }; -/* - * The AOSP 3.5 mm Headset: Accessory Specification gives the following values: - * Function A Play/Pause: 0 ohm - * Function D Voice assistant: 135 ohm - * Function B Volume Up 240 ohm - * Function C Volume Down 470 ohm - * Minimum Mic DC resistance 1000 ohm - * Minimum Ear speaker impedance 16 ohm - * Note the first max value below must be less then the min. speaker impedance, - * to allow CTIA/OMTP detection to work. The other max values are the closest - * value from extcon-arizona.c:arizona_micd_levels halfway 2 button resistances. - */ -static const struct arizona_micd_range arizona_micd_aosp_ranges[] = { - { .max = 11, .key = KEY_PLAYPAUSE }, - { .max = 186, .key = KEY_VOICECOMMAND }, - { .max = 348, .key = KEY_VOLUMEUP }, - { .max = 752, .key = KEY_VOLUMEDOWN }, -}; - static void arizona_spi_acpi_remove_lookup(void *lookup) { gpiod_remove_lookup_table(lookup); } -static int arizona_spi_acpi_probe(struct arizona *arizona) +/* For ACPI tables from boards which ship with Windows as factory OS */ +static int arizona_spi_acpi_windows_probe(struct arizona *arizona) { struct gpiod_lookup_table *lookup; acpi_status status; @@ -96,6 +78,36 @@ static int arizona_spi_acpi_probe(struct arizona *arizona) if (ACPI_FAILURE(status)) dev_warn(arizona->dev, "Failed to enable 32KHz clk ACPI error %d\n", status); + return 0; +} + +/* + * The AOSP 3.5 mm Headset: Accessory Specification gives the following values: + * Function A Play/Pause: 0 ohm + * Function D Voice assistant: 135 ohm + * Function B Volume Up 240 ohm + * Function C Volume Down 470 ohm + * Minimum Mic DC resistance 1000 ohm + * Minimum Ear speaker impedance 16 ohm + * Note the first max value below must be less then the min. speaker impedance, + * to allow CTIA/OMTP detection to work. The other max values are the closest + * value from extcon-arizona.c:arizona_micd_levels halfway 2 button resistances. + */ +static const struct arizona_micd_range arizona_micd_aosp_ranges[] = { + { .max = 11, .key = KEY_PLAYPAUSE }, + { .max = 186, .key = KEY_VOICECOMMAND }, + { .max = 348, .key = KEY_VOLUMEUP }, + { .max = 752, .key = KEY_VOLUMEDOWN }, +}; + +static int arizona_spi_acpi_probe(struct arizona *arizona) +{ + int ret; + + ret = arizona_spi_acpi_windows_probe(arizona); + if (ret) + return ret; + /* * Some DSDTs wrongly declare the IRQ trigger-type as IRQF_TRIGGER_FALLING * The IRQ line will stay low when a new IRQ event happens between reading From 9ed55e9ac536a3d60e5dd75def3e9158d1d09f5e Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Mon, 7 Mar 2022 18:38:44 +0100 Subject: [PATCH 357/370] mfd: arizona-spi: Add Android board ACPI table handling x86/ACPI boards with an arizona WM5102 codec ship with either Windows or Android as factory installed OS. The ACPI fwnode for the codec on Android boards misses 2 things compared to the Windows boards (this is hardcoded in the Android board kernels): 1. There is no CLKE ACPI method to enabe the 32 KHz clock the codec needs for jack-detection. 2. The GPIOs used by the codec are not listed in the fwnode for the codec. The ACPI tables on x86/ACPI boards shipped with Android being incomplete happens a lot. The special drivers/platform/x86/x86-android-tablets.c module contains DMI based per model handling to compensate for this. This module will enable the 32KHz clock through the pinctrl framework to fix 1. and it will also register a gpio-lookup table for all GPIOs needed by the codec + machine driver, including the GPIOs coming from the codec itself. Add an arizona_spi_acpi_android_probe() function which waits for the x86-android-tablets to have set things up before continue with probing the arizona WM5102 codec. Acked-by: Charles Keepax Signed-off-by: Hans de Goede Signed-off-by: Lee Jones Link: https://lore.kernel.org/r/20220307173844.199135-2-hdegoede@redhat.com --- drivers/mfd/arizona-spi.c | 35 ++++++++++++++++++++++++++++++++++- 1 file changed, 34 insertions(+), 1 deletion(-) diff --git a/drivers/mfd/arizona-spi.c b/drivers/mfd/arizona-spi.c index 6f8076439e74..16a675149b11 100644 --- a/drivers/mfd/arizona-spi.c +++ b/drivers/mfd/arizona-spi.c @@ -81,6 +81,30 @@ static int arizona_spi_acpi_windows_probe(struct arizona *arizona) return 0; } +/* For ACPI tables from boards which ship with Android as factory OS */ +static int arizona_spi_acpi_android_probe(struct arizona *arizona) +{ + int ret; + + /* + * Get the reset GPIO, treating -ENOENT as -EPROBE_DEFER to wait for + * the x86-android-tablets module to register the board specific GPIO + * lookup table. + */ + arizona->pdata.reset = devm_gpiod_get(arizona->dev, "reset", GPIOD_OUT_LOW); + if (IS_ERR(arizona->pdata.reset)) { + ret = PTR_ERR(arizona->pdata.reset); + if (ret == -ENOENT) { + dev_info_once(arizona->dev, + "Deferring probe till GPIO lookup is registered\n"); + ret = -EPROBE_DEFER; + } + return dev_err_probe(arizona->dev, ret, "getting reset GPIO\n"); + } + + return 0; +} + /* * The AOSP 3.5 mm Headset: Accessory Specification gives the following values: * Function A Play/Pause: 0 ohm @@ -102,9 +126,14 @@ static const struct arizona_micd_range arizona_micd_aosp_ranges[] = { static int arizona_spi_acpi_probe(struct arizona *arizona) { + struct acpi_device *adev = ACPI_COMPANION(arizona->dev); int ret; - ret = arizona_spi_acpi_windows_probe(arizona); + if (acpi_dev_hid_uid_match(adev, "10WM5102", NULL)) + ret = arizona_spi_acpi_android_probe(arizona); + else + ret = arizona_spi_acpi_windows_probe(arizona); + if (ret) return ret; @@ -142,6 +171,10 @@ static const struct acpi_device_id arizona_acpi_match[] = { .id = "WM510205", .driver_data = WM5102, }, + { + .id = "10WM5102", + .driver_data = WM5102, + }, { } }; MODULE_DEVICE_TABLE(acpi, arizona_acpi_match); From 553f685ebf9689e701ec6b95c0ca3595cf1a743f Mon Sep 17 00:00:00 2001 From: YueHaibing Date: Fri, 11 Mar 2022 20:55:18 +0800 Subject: [PATCH 358/370] mfd: db8500-prcmu: Remove unused inline function commit b0e846248de5 ("mfd: db8500-prcmu: Remove dead code for a non-existing config") left behind this, remove it. Signed-off-by: YueHaibing Reviewed-by: Linus Walleij Signed-off-by: Lee Jones Link: https://lore.kernel.org/r/20220311125518.31064-1-yuehaibing@huawei.com --- include/linux/mfd/dbx500-prcmu.h | 4 ---- 1 file changed, 4 deletions(-) diff --git a/include/linux/mfd/dbx500-prcmu.h b/include/linux/mfd/dbx500-prcmu.h index 2a255362b5ac..e7a7e70fdb38 100644 --- a/include/linux/mfd/dbx500-prcmu.h +++ b/include/linux/mfd/dbx500-prcmu.h @@ -561,10 +561,6 @@ static inline unsigned long prcmu_qos_get_cpufreq_opp_delay(void) return 0; } -static inline void prcmu_qos_set_cpufreq_opp_delay(unsigned long n) {} - -static inline void prcmu_qos_force_opp(int prcmu_qos_class, s32 i) {} - static inline int prcmu_qos_requirement(int prcmu_qos_class) { return 0; From fc832ac98752950e267081d1ea6048d948969037 Mon Sep 17 00:00:00 2001 From: "Minghao Chi (CGEL ZTE)" Date: Wed, 9 Mar 2022 03:56:07 +0000 Subject: [PATCH 359/370] mfd: Use platform_get_irq() to get the interrupt It is not recommened to use platform_get_resource(pdev, IORESOURCE_IRQ) for requesting IRQ's resources any more, as they can be not ready yet in case of DT-booting. platform_get_irq() instead is a recommended way for getting IRQ even if it was not retrieved earlier. It also makes code simpler because we're getting "int" value right away and no conversion from resource to int is required. The print function dev_err() is redundant because platform_get_irq() already prints an error. Reported-by: Zeal Robot Signed-off-by: Minghao Chi (CGEL ZTE) Reviewed-by: Linus Walleij Signed-off-by: Lee Jones Link: https://lore.kernel.org/r/20220309035607.2080884-1-chi.minghao@zte.com.cn --- drivers/mfd/ab8500-core.c | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/drivers/mfd/ab8500-core.c b/drivers/mfd/ab8500-core.c index 6a059270acdc..9d9e9787d5e8 100644 --- a/drivers/mfd/ab8500-core.c +++ b/drivers/mfd/ab8500-core.c @@ -1022,9 +1022,9 @@ static int ab8500_probe(struct platform_device *pdev) enum ab8500_version version = AB8500_VERSION_UNDEFINED; struct device_node *np = pdev->dev.of_node; struct ab8500 *ab8500; - struct resource *resource; int ret; int i; + int irq; u8 value; ab8500 = devm_kzalloc(&pdev->dev, sizeof(*ab8500), GFP_KERNEL); @@ -1033,13 +1033,11 @@ static int ab8500_probe(struct platform_device *pdev) ab8500->dev = &pdev->dev; - resource = platform_get_resource(pdev, IORESOURCE_IRQ, 0); - if (!resource) { - dev_err(&pdev->dev, "no IRQ resource\n"); - return -ENODEV; - } + irq = platform_get_irq(pdev, 0); + if (irq < 0) + return irq; - ab8500->irq = resource->start; + ab8500->irq = irq; ab8500->read = ab8500_prcmu_read; ab8500->write = ab8500_prcmu_write; From def387a2395708ccba333ccc0cea82ef5108f9be Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Mon, 14 Mar 2022 12:53:52 +0100 Subject: [PATCH 360/370] mfd: bd9576: fix typos in comments Various spelling mistakes in comments. Detected with the help of Coccinelle. Signed-off-by: Julia Lawall Reviewed-by: Matti Vaittinen Signed-off-by: Lee Jones Link: https://lore.kernel.org/r/20220314115354.144023-29-Julia.Lawall@inria.fr --- drivers/mfd/rohm-bd9576.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/mfd/rohm-bd9576.c b/drivers/mfd/rohm-bd9576.c index 6661a27d69a8..f37cd4f27aeb 100644 --- a/drivers/mfd/rohm-bd9576.c +++ b/drivers/mfd/rohm-bd9576.c @@ -23,7 +23,7 @@ enum { }; /* - * Due to the BD9576MUF nasty IRQ behaiour we don't always populate IRQs. + * Due to the BD9576MUF nasty IRQ behaviour we don't always populate IRQs. * These will be added to regulator resources only if IRQ information for the * PMIC is populated in device-tree. */ From d99460ed5cdcc28feba6b992630b04650e410902 Mon Sep 17 00:00:00 2001 From: Michael Walle Date: Sun, 13 Mar 2022 01:31:22 +0100 Subject: [PATCH 361/370] dt-bindings: mfd: syscon: Add microchip,lan966x-cpu-syscon compatible Add the Microchip LAN966x CPU system registers compatible. Signed-off-by: Michael Walle Acked-by: Krzysztof Kozlowski Acked-by: Rob Herring Signed-off-by: Lee Jones Link: https://lore.kernel.org/r/20220313003122.19155-1-michael@walle.cc --- Documentation/devicetree/bindings/mfd/syscon.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/Documentation/devicetree/bindings/mfd/syscon.yaml b/Documentation/devicetree/bindings/mfd/syscon.yaml index 29d4a97f7108..13baa452cc9d 100644 --- a/Documentation/devicetree/bindings/mfd/syscon.yaml +++ b/Documentation/devicetree/bindings/mfd/syscon.yaml @@ -48,6 +48,7 @@ properties: - marvell,armada-3700-usb2-host-misc - mediatek,mt8135-pctl-a-syscfg - mediatek,mt8135-pctl-b-syscfg + - microchip,lan966x-cpu-syscon - microchip,sparx5-cpu-syscon - mstar,msc313-pmsleep - rockchip,px30-qos From 61285ff72ae59e1603f908b13363e99883d67e09 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Wed, 23 Mar 2022 16:39:52 +0100 Subject: [PATCH 362/370] fs: do not pass __GFP_HIGHMEM to bio_alloc in do_mpage_readpage The mpage bio alloc cleanup accidentally removed clearing ~GFP_KERNEL bits from the mask passed to bio_alloc. Fix this up in a slightly less obsfucated way that mirrors what iomap does in its readpage code. Fixes: 77c436de01c0 ("mpage: pass the operation to bio_alloc") Reported-by: Guenter Roeck Signed-off-by: Christoph Hellwig Tested-by: Ryusuke Konishi Link: https://lore.kernel.org/r/20220323153952.1418560-1-hch@lst.de Signed-off-by: Jens Axboe --- fs/mpage.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/fs/mpage.c b/fs/mpage.c index 6c4b810a21d0..2492b30192c0 100644 --- a/fs/mpage.c +++ b/fs/mpage.c @@ -148,13 +148,11 @@ static struct bio *do_mpage_readpage(struct mpage_readpage_args *args) int op = REQ_OP_READ; unsigned nblocks; unsigned relative_block; - gfp_t gfp; + gfp_t gfp = mapping_gfp_constraint(page->mapping, GFP_KERNEL); if (args->is_readahead) { op |= REQ_RAHEAD; - gfp = readahead_gfp_mask(page->mapping); - } else { - gfp = mapping_gfp_constraint(page->mapping, GFP_KERNEL); + gfp |= __GFP_NORETRY | __GFP_NOWARN; } if (page_has_buffers(page)) From 5db1c2dbc04c161d9e6b3f93457452e2ee904bde Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= Date: Mon, 28 Feb 2022 14:12:50 +0100 Subject: [PATCH 363/370] dt-bindings: nvmem: add U-Boot environment variables binding MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit U-Boot uses environment variables for storing device setup data. It usually needs to be accessed by a bootloader, kernel and often user-space. This binding allows describing environment data located in a raw flash partition. It's treated as NVMEM device and can be reused later for other storage devices. Using DT should be cleaner than hardcoding & duplicating such info in multiple places. Bootloader & kernel can share DTS and user-space can try reading it too or just have correct data exposed by a kernel. A custom "compatible" string allows system to automatically load relevant NVMEM driver but phandle can be also used for reading raw location. Signed-off-by: Rafał Miłecki Reviewed-by: Tom Rini Signed-off-by: Rob Herring Link: https://lore.kernel.org/r/20220228131250.16943-1-zajec5@gmail.com --- .../devicetree/bindings/nvmem/u-boot,env.yaml | 62 +++++++++++++++++++ MAINTAINERS | 5 ++ 2 files changed, 67 insertions(+) create mode 100644 Documentation/devicetree/bindings/nvmem/u-boot,env.yaml diff --git a/Documentation/devicetree/bindings/nvmem/u-boot,env.yaml b/Documentation/devicetree/bindings/nvmem/u-boot,env.yaml new file mode 100644 index 000000000000..e70b2a60cb9a --- /dev/null +++ b/Documentation/devicetree/bindings/nvmem/u-boot,env.yaml @@ -0,0 +1,62 @@ +# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/nvmem/u-boot,env.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: U-Boot environment variables + +description: | + U-Boot uses environment variables to store device parameters and + configuration. They may be used for booting process, setup or keeping end user + info. + + Data is stored using U-Boot specific formats (variant specific header and NUL + separated key-value pairs). + + Environment data can be stored on various storage entities, e.g.: + 1. Raw flash partition + 2. UBI volume + + This binding allows marking storage device (as containing env data) and + specifying used format. + + Right now only flash partition case is covered but it may be extended to e.g. + UBI volumes in the future. + +maintainers: + - Rafał Miłecki + +properties: + compatible: + oneOf: + - description: A standalone env data block + const: u-boot,env + - description: Two redundant blocks with active one flagged + const: u-boot,env-redundant-bool + - description: Two redundant blocks with active having higher counter + const: u-boot,env-redundant-count + + reg: + maxItems: 1 + +additionalProperties: false + +examples: + - | + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + partition@0 { + reg = <0x0 0x40000>; + label = "u-boot"; + read-only; + }; + + env: partition@40000 { + compatible = "u-boot,env"; + reg = <0x40000 0x10000>; + }; + }; diff --git a/MAINTAINERS b/MAINTAINERS index fa7eb84277a3..562571223095 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -19665,6 +19665,11 @@ W: http://linuxtv.org T: git git://linuxtv.org/media_tree.git F: drivers/media/pci/tw686x/ +U-BOOT ENVIRONMENT VARIABLES +M: Rafał Miłecki +S: Maintained +F: Documentation/devicetree/bindings/nvmem/u-boot,env.yaml + UACCE ACCELERATOR FRAMEWORK M: Zhangfei Gao M: Zhou Wang From 6b49f3409a090c8e9d1f46ff2705c479b45a54d4 Mon Sep 17 00:00:00 2001 From: Nathan Chancellor Date: Tue, 15 Mar 2022 13:25:43 -0700 Subject: [PATCH 364/370] dt-bindings: kbuild: Make DT_SCHEMA_LINT a recursive variable A recent change added a warning when yamllint is not installed, as it is needed for 'make dt_binding_check'. However, it also changed DT_SCHEMA_LINT to be a simple make variable, which is evaluated when a Makefile is evaluated. This causes a warning when running 'make clean', as Documentation/devicetree/bindings/Makefile has a "clean-files" variable: $ make -s clean which: no yamllint in (...) warning: python package 'yamllint' not installed, skipping Make DT_SCHEMA_LINT a recursive variable so it is evaluated only when it is used. The warning still triggers when 'make dt_binding_check' is run. Fixes: b3e664a7f449 ("dt-bindings: kbuild: Print a warning if yamllint is not found") Signed-off-by: Nathan Chancellor Signed-off-by: Rob Herring Link: https://lore.kernel.org/r/20220315202542.2071351-1-nathan@kernel.org --- Documentation/devicetree/bindings/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/Makefile b/Documentation/devicetree/bindings/Makefile index e594e5898be0..c9953f86b19d 100644 --- a/Documentation/devicetree/bindings/Makefile +++ b/Documentation/devicetree/bindings/Makefile @@ -3,7 +3,7 @@ DT_DOC_CHECKER ?= dt-doc-validate DT_EXTRACT_EX ?= dt-extract-example DT_MK_SCHEMA ?= dt-mk-schema -DT_SCHEMA_LINT := $(shell which yamllint || \ +DT_SCHEMA_LINT = $(shell which yamllint || \ echo "warning: python package 'yamllint' not installed, skipping" >&2) DT_SCHEMA_MIN_VERSION = 2022.3 From 5662abf6e21338be6d085d6375d3732ac6147fd2 Mon Sep 17 00:00:00 2001 From: Cooper Chiou Date: Thu, 24 Mar 2022 14:12:18 +0800 Subject: [PATCH 365/370] drm/edid: check basic audio support on CEA extension block Tag code stored in bit7:5 for CTA block byte[3] is not the same as CEA extension block definition. Only check CEA block has basic audio support. v3: update commit message. Cc: stable@vger.kernel.org Cc: Jani Nikula Cc: Shawn C Lee Cc: intel-gfx Signed-off-by: Cooper Chiou Signed-off-by: Lee Shawn C Fixes: e28ad544f462 ("drm/edid: parse CEA blocks embedded in DisplayID") Reviewed-by: Jani Nikula Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/20220324061218.32739-1-shawn.c.lee@intel.com --- drivers/gpu/drm/drm_edid.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c index 561f53831e29..f07af6786cec 100644 --- a/drivers/gpu/drm/drm_edid.c +++ b/drivers/gpu/drm/drm_edid.c @@ -4859,7 +4859,8 @@ bool drm_detect_monitor_audio(struct edid *edid) if (!edid_ext) goto end; - has_audio = ((edid_ext[3] & EDID_BASIC_AUDIO) != 0); + has_audio = (edid_ext[0] == CEA_EXT && + (edid_ext[3] & EDID_BASIC_AUDIO) != 0); if (has_audio) { DRM_DEBUG_KMS("Monitor has basic audio support\n"); From 7344bad7fb6daa4877a1c064b52c7d5f9182c41b Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Wed, 23 Mar 2022 12:04:38 +0200 Subject: [PATCH 366/370] drm/edid: fix CEA extension byte #3 parsing MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Only an EDID CEA extension has byte #3, while the CTA DisplayID Data Block does not. Don't interpret bogus data for color formats. For most displays it's probably an unlikely scenario you'd have a CTA DisplayID Data Block without a CEA extension, but they do exist. Fixes: e28ad544f462 ("drm/edid: parse CEA blocks embedded in DisplayID") Cc: Cc: Shawn C Lee Cc: Ville Syrjälä Signed-off-by: Jani Nikula Reviewed-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20220323100438.1757295-1-jani.nikula@intel.com --- drivers/gpu/drm/drm_edid.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c index f07af6786cec..cc7bd58369df 100644 --- a/drivers/gpu/drm/drm_edid.c +++ b/drivers/gpu/drm/drm_edid.c @@ -5188,10 +5188,14 @@ static void drm_parse_cea_ext(struct drm_connector *connector, /* The existence of a CEA block should imply RGB support */ info->color_formats = DRM_COLOR_FORMAT_RGB444; - if (edid_ext[3] & EDID_CEA_YCRCB444) - info->color_formats |= DRM_COLOR_FORMAT_YCBCR444; - if (edid_ext[3] & EDID_CEA_YCRCB422) - info->color_formats |= DRM_COLOR_FORMAT_YCBCR422; + + /* CTA DisplayID Data Block does not have byte #3 */ + if (edid_ext[0] == CEA_EXT) { + if (edid_ext[3] & EDID_CEA_YCRCB444) + info->color_formats |= DRM_COLOR_FORMAT_YCBCR444; + if (edid_ext[3] & EDID_CEA_YCRCB422) + info->color_formats |= DRM_COLOR_FORMAT_YCBCR422; + } if (cea_db_offsets(edid_ext, &start, &end)) return; From 40faaf80c463b2c99a0351d28bd74d75d64ed017 Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann Date: Sun, 13 Mar 2022 20:29:51 +0100 Subject: [PATCH 367/370] fbdev: Fix sys_imageblit() for arbitrary image widths Commit 6f29e04938bf ("fbdev: Improve performance of sys_imageblit()") broke sys_imageblit() for image width that are not aligned to 8-bit boundaries. Fix this by handling the trailing pixels on each line separately. The performance improvements in the original commit do not regress by this change. Signed-off-by: Thomas Zimmermann Fixes: 6f29e04938bf ("fbdev: Improve performance of sys_imageblit()") Cc: Thomas Zimmermann Cc: Javier Martinez Canillas Cc: Sam Ravnborg Tested-by: Geert Uytterhoeven Reviewed-by: Javier Martinez Canillas Signed-off-by: Dave Airlie Link: https://patchwork.freedesktop.org/patch/msgid/20220313192952.12058-2-tzimmermann@suse.de --- drivers/video/fbdev/core/sysimgblt.c | 29 ++++++++++++++++++++++++---- 1 file changed, 25 insertions(+), 4 deletions(-) diff --git a/drivers/video/fbdev/core/sysimgblt.c b/drivers/video/fbdev/core/sysimgblt.c index 722c327a381b..335e92b813fc 100644 --- a/drivers/video/fbdev/core/sysimgblt.c +++ b/drivers/video/fbdev/core/sysimgblt.c @@ -188,7 +188,7 @@ static void fast_imageblit(const struct fb_image *image, struct fb_info *p, { u32 fgx = fgcolor, bgx = bgcolor, bpp = p->var.bits_per_pixel; u32 ppw = 32/bpp, spitch = (image->width + 7)/8; - u32 bit_mask, eorx; + u32 bit_mask, eorx, shift; const char *s = image->data, *src; u32 *dst; const u32 *tab; @@ -229,17 +229,23 @@ static void fast_imageblit(const struct fb_image *image, struct fb_info *p, for (i = image->height; i--; ) { dst = dst1; + shift = 8; src = s; + /* + * Manually unroll the per-line copying loop for better + * performance. This works until we processed the last + * completely filled source byte (inclusive). + */ switch (ppw) { case 4: /* 8 bpp */ - for (j = k; j; j -= 2, ++src) { + for (j = k; j >= 2; j -= 2, ++src) { *dst++ = colortab[(*src >> 4) & bit_mask]; *dst++ = colortab[(*src >> 0) & bit_mask]; } break; case 2: /* 16 bpp */ - for (j = k; j; j -= 4, ++src) { + for (j = k; j >= 4; j -= 4, ++src) { *dst++ = colortab[(*src >> 6) & bit_mask]; *dst++ = colortab[(*src >> 4) & bit_mask]; *dst++ = colortab[(*src >> 2) & bit_mask]; @@ -247,7 +253,7 @@ static void fast_imageblit(const struct fb_image *image, struct fb_info *p, } break; case 1: /* 32 bpp */ - for (j = k; j; j -= 8, ++src) { + for (j = k; j >= 8; j -= 8, ++src) { *dst++ = colortab[(*src >> 7) & bit_mask]; *dst++ = colortab[(*src >> 6) & bit_mask]; *dst++ = colortab[(*src >> 5) & bit_mask]; @@ -259,6 +265,21 @@ static void fast_imageblit(const struct fb_image *image, struct fb_info *p, } break; } + + /* + * For image widths that are not a multiple of 8, there + * are trailing pixels left on the current line. Print + * them as well. + */ + for (; j--; ) { + shift -= ppw; + *dst++ = colortab[(*src >> shift) & bit_mask]; + if (!shift) { + shift = 8; + ++src; + } + } + dst1 += p->fix.line_length; s += spitch; } From 2a81dba4b577099717cea86d429f053e85e74d96 Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann Date: Sun, 13 Mar 2022 20:29:52 +0100 Subject: [PATCH 368/370] fbdev: Fix cfb_imageblit() for arbitrary image widths Commit 0d03011894d2 ("fbdev: Improve performance of cfb_imageblit()") broke cfb_imageblit() for image widths that are not aligned to 8-bit boundaries. Fix this by handling the trailing pixels on each line separately. The performance improvements in the original commit do not regress by this change. Signed-off-by: Thomas Zimmermann Fixes: 0d03011894d2 ("fbdev: Improve performance of cfb_imageblit()") Reported-by: Marek Szyprowski Cc: Thomas Zimmermann Cc: Javier Martinez Canillas Cc: Sam Ravnborg Tested-by: Marek Szyprowski Acked-by: Daniel Vetter Reviewed-by: Javier Martinez Canillas Tested-by: Guenter Roeck Signed-off-by: Dave Airlie Link: https://patchwork.freedesktop.org/patch/msgid/20220313192952.12058-3-tzimmermann@suse.de --- drivers/video/fbdev/core/cfbimgblt.c | 28 ++++++++++++++++++++++++---- 1 file changed, 24 insertions(+), 4 deletions(-) diff --git a/drivers/video/fbdev/core/cfbimgblt.c b/drivers/video/fbdev/core/cfbimgblt.c index 7361cfabdd85..9ebda4e0dc7a 100644 --- a/drivers/video/fbdev/core/cfbimgblt.c +++ b/drivers/video/fbdev/core/cfbimgblt.c @@ -218,7 +218,7 @@ static inline void fast_imageblit(const struct fb_image *image, struct fb_info * { u32 fgx = fgcolor, bgx = bgcolor, bpp = p->var.bits_per_pixel; u32 ppw = 32/bpp, spitch = (image->width + 7)/8; - u32 bit_mask, eorx; + u32 bit_mask, eorx, shift; const char *s = image->data, *src; u32 __iomem *dst; const u32 *tab = NULL; @@ -259,17 +259,23 @@ static inline void fast_imageblit(const struct fb_image *image, struct fb_info * for (i = image->height; i--; ) { dst = (u32 __iomem *)dst1; + shift = 8; src = s; + /* + * Manually unroll the per-line copying loop for better + * performance. This works until we processed the last + * completely filled source byte (inclusive). + */ switch (ppw) { case 4: /* 8 bpp */ - for (j = k; j; j -= 2, ++src) { + for (j = k; j >= 2; j -= 2, ++src) { FB_WRITEL(colortab[(*src >> 4) & bit_mask], dst++); FB_WRITEL(colortab[(*src >> 0) & bit_mask], dst++); } break; case 2: /* 16 bpp */ - for (j = k; j; j -= 4, ++src) { + for (j = k; j >= 4; j -= 4, ++src) { FB_WRITEL(colortab[(*src >> 6) & bit_mask], dst++); FB_WRITEL(colortab[(*src >> 4) & bit_mask], dst++); FB_WRITEL(colortab[(*src >> 2) & bit_mask], dst++); @@ -277,7 +283,7 @@ static inline void fast_imageblit(const struct fb_image *image, struct fb_info * } break; case 1: /* 32 bpp */ - for (j = k; j; j -= 8, ++src) { + for (j = k; j >= 8; j -= 8, ++src) { FB_WRITEL(colortab[(*src >> 7) & bit_mask], dst++); FB_WRITEL(colortab[(*src >> 6) & bit_mask], dst++); FB_WRITEL(colortab[(*src >> 5) & bit_mask], dst++); @@ -290,6 +296,20 @@ static inline void fast_imageblit(const struct fb_image *image, struct fb_info * break; } + /* + * For image widths that are not a multiple of 8, there + * are trailing pixels left on the current line. Print + * them as well. + */ + for (; j--; ) { + shift -= ppw; + FB_WRITEL(colortab[(*src >> shift) & bit_mask], dst++); + if (!shift) { + shift = 8; + ++src; + } + } + dst1 += p->fix.line_length; s += spitch; } From 631f871f071746789e9242e514ab0f49067fa97a Mon Sep 17 00:00:00 2001 From: Andreas Gruenbacher Date: Tue, 9 Nov 2021 12:56:06 +0100 Subject: [PATCH 369/370] fs/iomap: Fix buffered write page prefaulting When part of the user buffer passed to generic_perform_write() or iomap_file_buffered_write() cannot be faulted in for reading, the entire write currently fails. The correct behavior would be to write all the data that can be written, up to the point of failure. Commit a6294593e8a1 ("iov_iter: Turn iov_iter_fault_in_readable into fault_in_iov_iter_readable") gave us the information needed, so fix the page prefaulting in generic_perform_write() and iomap_write_iter() to only bail out when no pages could be faulted in. We already factor in that pages that are faulted in may no longer be resident by the time they are accessed. Paging out pages has the same effect as not faulting in those pages in the first place, so the code can already deal with that. Signed-off-by: Andreas Gruenbacher Reviewed-by: Catalin Marinas Reviewed-by: Christoph Hellwig --- fs/iomap/buffered-io.c | 2 +- mm/filemap.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/fs/iomap/buffered-io.c b/fs/iomap/buffered-io.c index 1753c26c8e76..54516ab464cd 100644 --- a/fs/iomap/buffered-io.c +++ b/fs/iomap/buffered-io.c @@ -750,7 +750,7 @@ again: * same page as we're writing to, without it being marked * up-to-date. */ - if (unlikely(fault_in_iov_iter_readable(i, bytes))) { + if (unlikely(fault_in_iov_iter_readable(i, bytes) == bytes)) { status = -EFAULT; break; } diff --git a/mm/filemap.c b/mm/filemap.c index daa0e23a6ee6..767202265048 100644 --- a/mm/filemap.c +++ b/mm/filemap.c @@ -3743,7 +3743,7 @@ again: * same page as we're writing to, without it being marked * up-to-date. */ - if (unlikely(fault_in_iov_iter_readable(i, bytes))) { + if (unlikely(fault_in_iov_iter_readable(i, bytes) == bytes)) { status = -EFAULT; break; } From bddac7c1e02ba47f0570e494c9289acea3062cc1 Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Sat, 26 Mar 2022 10:42:04 -0700 Subject: [PATCH 370/370] Revert "swiotlb: rework "fix info leak with DMA_FROM_DEVICE"" MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This reverts commit aa6f8dcbab473f3a3c7454b74caa46d36cdc5d13. It turns out this breaks at least the ath9k wireless driver, and possibly others. What the ath9k driver does on packet receive is to set up the DMA transfer with: int ath_rx_init(..) .. bf->bf_buf_addr = dma_map_single(sc->dev, skb->data, common->rx_bufsize, DMA_FROM_DEVICE); and then the receive logic (through ath_rx_tasklet()) will fetch incoming packets static bool ath_edma_get_buffers(..) .. dma_sync_single_for_cpu(sc->dev, bf->bf_buf_addr, common->rx_bufsize, DMA_FROM_DEVICE); ret = ath9k_hw_process_rxdesc_edma(ah, rs, skb->data); if (ret == -EINPROGRESS) { /*let device gain the buffer again*/ dma_sync_single_for_device(sc->dev, bf->bf_buf_addr, common->rx_bufsize, DMA_FROM_DEVICE); return false; } and it's worth noting how that first DMA sync: dma_sync_single_for_cpu(..DMA_FROM_DEVICE); is there to make sure the CPU can read the DMA buffer (possibly by copying it from the bounce buffer area, or by doing some cache flush). The iommu correctly turns that into a "copy from bounce bufer" so that the driver can look at the state of the packets. In the meantime, the device may continue to write to the DMA buffer, but we at least have a snapshot of the state due to that first DMA sync. But that _second_ DMA sync: dma_sync_single_for_device(..DMA_FROM_DEVICE); is telling the DMA mapping that the CPU wasn't interested in the area because the packet wasn't there. In the case of a DMA bounce buffer, that is a no-op. Note how it's not a sync for the CPU (the "for_device()" part), and it's not a sync for data written by the CPU (the "DMA_FROM_DEVICE" part). Or rather, it _should_ be a no-op. That's what commit aa6f8dcbab47 broke: it made the code bounce the buffer unconditionally, and changed the DMA_FROM_DEVICE to just unconditionally and illogically be DMA_TO_DEVICE. [ Side note: purely within the confines of the swiotlb driver it wasn't entirely illogical: The reason it did that odd DMA_FROM_DEVICE -> DMA_TO_DEVICE conversion thing is because inside the swiotlb driver, it uses just a swiotlb_bounce() helper that doesn't care about the whole distinction of who the sync is for - only which direction to bounce. So it took the "sync for device" to mean that the CPU must have been the one writing, and thought it meant DMA_TO_DEVICE. ] Also note how the commentary in that commit was wrong, probably due to that whole confusion, claiming that the commit makes the swiotlb code "bounce unconditionally (that is, also when dir == DMA_TO_DEVICE) in order do avoid synchronising back stale data from the swiotlb buffer" which is nonsensical for two reasons: - that "also when dir == DMA_TO_DEVICE" is nonsensical, as that was exactly when it always did - and should do - the bounce. - since this is a sync for the device (not for the CPU), we're clearly fundamentally not coping back stale data from the bounce buffers at all, because we'd be copying *to* the bounce buffers. So that commit was just very confused. It confused the direction of the synchronization (to the device, not the cpu) with the direction of the DMA (from the device). Reported-and-bisected-by: Oleksandr Natalenko Reported-by: Olha Cherevyk Cc: Halil Pasic Cc: Christoph Hellwig Cc: Kalle Valo Cc: Robin Murphy Cc: Toke Høiland-Jørgensen Cc: Maxime Bizon Cc: Johannes Berg Signed-off-by: Linus Torvalds --- Documentation/core-api/dma-attributes.rst | 8 ++++++++ include/linux/dma-mapping.h | 8 ++++++++ kernel/dma/swiotlb.c | 23 ++++++++--------------- 3 files changed, 24 insertions(+), 15 deletions(-) diff --git a/Documentation/core-api/dma-attributes.rst b/Documentation/core-api/dma-attributes.rst index 1887d92e8e92..17706dc91ec9 100644 --- a/Documentation/core-api/dma-attributes.rst +++ b/Documentation/core-api/dma-attributes.rst @@ -130,3 +130,11 @@ accesses to DMA buffers in both privileged "supervisor" and unprivileged subsystem that the buffer is fully accessible at the elevated privilege level (and ideally inaccessible or at least read-only at the lesser-privileged levels). + +DMA_ATTR_OVERWRITE +------------------ + +This is a hint to the DMA-mapping subsystem that the device is expected to +overwrite the entire mapped size, thus the caller does not require any of the +previous buffer contents to be preserved. This allows bounce-buffering +implementations to optimise DMA_FROM_DEVICE transfers. diff --git a/include/linux/dma-mapping.h b/include/linux/dma-mapping.h index dca2b1355bb1..6150d11a607e 100644 --- a/include/linux/dma-mapping.h +++ b/include/linux/dma-mapping.h @@ -61,6 +61,14 @@ */ #define DMA_ATTR_PRIVILEGED (1UL << 9) +/* + * This is a hint to the DMA-mapping subsystem that the device is expected + * to overwrite the entire mapped size, thus the caller does not require any + * of the previous buffer contents to be preserved. This allows + * bounce-buffering implementations to optimise DMA_FROM_DEVICE transfers. + */ +#define DMA_ATTR_OVERWRITE (1UL << 10) + /* * A dma_addr_t can hold any valid DMA or bus address for the platform. It can * be given to a device to use as a DMA source or target. It is specific to a diff --git a/kernel/dma/swiotlb.c b/kernel/dma/swiotlb.c index 6db1c475ec82..bfc56cb21705 100644 --- a/kernel/dma/swiotlb.c +++ b/kernel/dma/swiotlb.c @@ -627,14 +627,10 @@ phys_addr_t swiotlb_tbl_map_single(struct device *dev, phys_addr_t orig_addr, for (i = 0; i < nr_slots(alloc_size + offset); i++) mem->slots[index + i].orig_addr = slot_addr(orig_addr, i); tlb_addr = slot_addr(mem->start, index) + offset; - /* - * When dir == DMA_FROM_DEVICE we could omit the copy from the orig - * to the tlb buffer, if we knew for sure the device will - * overwirte the entire current content. But we don't. Thus - * unconditional bounce may prevent leaking swiotlb content (i.e. - * kernel memory) to user-space. - */ - swiotlb_bounce(dev, tlb_addr, mapping_size, DMA_TO_DEVICE); + if (!(attrs & DMA_ATTR_SKIP_CPU_SYNC) && + (!(attrs & DMA_ATTR_OVERWRITE) || dir == DMA_TO_DEVICE || + dir == DMA_BIDIRECTIONAL)) + swiotlb_bounce(dev, tlb_addr, mapping_size, DMA_TO_DEVICE); return tlb_addr; } @@ -701,13 +697,10 @@ void swiotlb_tbl_unmap_single(struct device *dev, phys_addr_t tlb_addr, void swiotlb_sync_single_for_device(struct device *dev, phys_addr_t tlb_addr, size_t size, enum dma_data_direction dir) { - /* - * Unconditional bounce is necessary to avoid corruption on - * sync_*_for_cpu or dma_ummap_* when the device didn't overwrite - * the whole lengt of the bounce buffer. - */ - swiotlb_bounce(dev, tlb_addr, size, DMA_TO_DEVICE); - BUG_ON(!valid_dma_direction(dir)); + if (dir == DMA_TO_DEVICE || dir == DMA_BIDIRECTIONAL) + swiotlb_bounce(dev, tlb_addr, size, DMA_TO_DEVICE); + else + BUG_ON(dir != DMA_FROM_DEVICE); } void swiotlb_sync_single_for_cpu(struct device *dev, phys_addr_t tlb_addr,