Memory controller drivers for v6.20

1. Mediatek SMI: Fix old struct device reference leaks during error
    paths and device unbinding.
 
 2. Memory Devicetree bindings: refactor existing LPDDR bindings and add
    bindings for DDR4 SDRAM.  These will be used for example in
    stm32mp257f-ev1 DTS.
 -----BEGIN PGP SIGNATURE-----
 
 iQJEBAABCgAuFiEE3dJiKD0RGyM7briowTdm5oaLg9cFAmlx4A4QHGtyemtAa2Vy
 bmVsLm9yZwAKCRDBN2bmhouD14qDD/9to8dx0KggWc/zMOjpuwwHC1l3mGf+sVo7
 NjV8vMvrVxbhcg5JlVkvgQCFqrE8cXLr/+cfCk15J0EW9wOFsII5e/NCCzYwwZKO
 HWIV2ze0qDjRa+16umlm+lRJFWtkmW1ynxdh0E/xrL7gC+7OCvKMY3d1uckayDbb
 HQqvC3C5ec9gr8GlvAhIh6e8qNawYjdw2U5m0wT6ojMRBHdjil/1BROQzKdmqYpZ
 gWFWCVeqfUBu19wjs+0nQJwNHtOB9cDC0yP3iPoL8z58K6kGby+0v7W03GrfsFeF
 l/Awee/Na8rNCoaHwPyUOJm33kN4yCJlQqaVBZ10Z+R2/cFajeHTraF85VUtupZP
 W94vfkPg2BbhKC2AKUroa6oLu4qQ3Hoe8N+SMQt4m8dbUdN6w/HSq60L5GT0u7J6
 sN8YDreGXkLVHyS8+3zB6dFOEUcXzfQXqpRSbw3I2o0WXMWeMPA/eao6eKtdXplr
 LMy9110JzQbH8kx9qeaten6OBOatHnBwz1WGiImwTd1FTtfY311zlIe3cwSOEW2c
 UrV+QiC1JEJwLiejYzIuHEV6k4dHQ13n0k/2m7PHbo+yZCxZ85iA3xmWKwpy43+D
 xBVg8KaydsFEgkdXIf793TOO7EygO33mv9WcWvsdWwp0WXpaFE27vWwDFn3dXXWF
 i+NIMe3How==
 =eWI6
 -----END PGP SIGNATURE-----
gpgsig -----BEGIN PGP SIGNATURE-----
 
 iQIzBAABCgAdFiEEo6/YBQwIrVS28WGKmmx57+YAGNkFAml7JNcACgkQmmx57+YA
 GNnmgQ//cYAGf2SyMm9ZYrEDTpRwS1eLxlSJLrbRtPDlZ+Csxde7LDQ0Jpuo9YC/
 7EdK2d4kl9TPx0ADliwC30Yp4d3JDTHTU//oY3voOBsiPzUtltTwhKOq1Ih1A/Eb
 t0yJW3ECP4Oo4zWWF6R8t34wuRVbcYhiMRUJhjmk3wNjxoNtPMUzJ0ExnNss+lp1
 6F8y3Vki0uVm5jXNoChcUjRsB5u4sXyUYPk7LZk2WwvSSFpUgtP0+K8TfhtJXcOZ
 yp5Lr1gxadEx0K1z5JVka/6VnJAoXU60+gYSri9mY8Ez6tkh4YEuAKMOfhIEnNl/
 XFMB+cVMltqWDgEWXx9+VqJ5RtEEVmOTHAoUYYCvcm5+u3smMA0AJ90uw17XHJ9H
 mcXg3uc0eKvVUQ2I/Vw9xmeNXpOa+Xls5bUmXxNNb6fX0Gv1okbeYol3Iz6mExad
 evo09B6lUHZU6zJz7FqKQqCONMv8GSg/HIOkeMh4UfaOWSXEcywDYiCqOZks/SWQ
 01k95F1X63XZQkaq8OWYgS9jbZJnVY6yHM/KwC2l5W6OvJ7qPSL0chStOX/u0DbW
 uBcjjtyPPHPgOBWXjYvRa8kpqauKNKgRcwvgaJUc+/Ye7Hd9gEQIYjQfkcqcKmaD
 HBXOmZua5L2Kk0aL0yh5gDgAj2eugoILQQdEohSWGVrS1oq/FX8=
 =jANh
 -----END PGP SIGNATURE-----

Merge tag 'memory-controller-drv-6.20' of https://git.kernel.org/pub/scm/linux/kernel/git/krzk/linux-mem-ctrl into soc/drivers

Memory controller drivers for v6.20

1. Mediatek SMI: Fix old struct device reference leaks during error
   paths and device unbinding.

2. Memory Devicetree bindings: refactor existing LPDDR bindings and add
   bindings for DDR4 SDRAM.  These will be used for example in
   stm32mp257f-ev1 DTS.

* tag 'memory-controller-drv-6.20' of https://git.kernel.org/pub/scm/linux/kernel/git/krzk/linux-mem-ctrl:
  dt-bindings: memory: SDRAM channel: standardise node name
  dt-bindings: memory: add DDR4 channel compatible
  dt-bindings: memory: factorise LPDDR channel binding into SDRAM channel
  dt-bindings: memory: introduce DDR4
  dt-bindings: memory: factorise LPDDR props into SDRAM props
  memory: mtk-smi: clean up device link creation
  memory: mtk-smi: fix device leak on larb probe
  memory: mtk-smi: fix device leaks on common probe

Signed-off-by: Arnd Bergmann <arnd@arndb.de>
This commit is contained in:
Arnd Bergmann 2026-01-29 10:13:55 +01:00
commit 5b303a0207
9 changed files with 181 additions and 107 deletions

View File

@ -0,0 +1,34 @@
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/memory-controllers/ddr/jedec,ddr4.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: DDR4 SDRAM compliant to JEDEC JESD79-4D
maintainers:
- Krzysztof Kozlowski <krzk@kernel.org>
allOf:
- $ref: jedec,sdram-props.yaml#
properties:
compatible:
items:
- pattern: "^ddr4-[0-9a-f]{4},[a-z]{1,20}-[0-9a-f]{2}$"
- const: jedec,ddr4
required:
- compatible
- density
- io-width
unevaluatedProperties: false
examples:
- |
ddr {
compatible = "ddr4-00ff,azaz-ff", "jedec,ddr4";
density = <8192>;
io-width = <8>;
};

View File

@ -1,74 +0,0 @@
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/memory-controllers/ddr/jedec,lpddr-props.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Common properties for LPDDR types
description:
Different LPDDR types generally use the same properties and only differ in the
range of legal values for each. This file defines the common parts that can be
reused for each type. Nodes using this schema should generally be nested under
an LPDDR channel node.
maintainers:
- Krzysztof Kozlowski <krzk@kernel.org>
properties:
compatible:
description:
Compatible strings can be either explicit vendor names and part numbers
(e.g. elpida,ECB240ABACN), or generated strings of the form
lpddrX-YY,ZZZZ where X is the LPDDR version, YY is the manufacturer ID
(from MR5) and ZZZZ is the revision ID (from MR6 and MR7). Both IDs are
formatted in lower case hexadecimal representation with leading zeroes.
The latter form can be useful when LPDDR nodes are created at runtime by
boot firmware that doesn't have access to static part number information.
reg:
description:
The rank number of this LPDDR rank when used as a subnode to an LPDDR
channel.
minimum: 0
maximum: 3
revision-id:
$ref: /schemas/types.yaml#/definitions/uint32-array
description:
Revision IDs read from Mode Register 6 and 7. One byte per uint32 cell (i.e. <MR6 MR7>).
maxItems: 2
items:
minimum: 0
maximum: 255
density:
$ref: /schemas/types.yaml#/definitions/uint32
description:
Density in megabits of SDRAM chip. Decoded from Mode Register 8.
enum:
- 64
- 128
- 256
- 512
- 1024
- 2048
- 3072
- 4096
- 6144
- 8192
- 12288
- 16384
- 24576
- 32768
io-width:
$ref: /schemas/types.yaml#/definitions/uint32
description:
IO bus width in bits of SDRAM chip. Decoded from Mode Register 8.
enum:
- 8
- 16
- 32
additionalProperties: true

View File

@ -10,7 +10,7 @@ maintainers:
- Krzysztof Kozlowski <krzk@kernel.org>
allOf:
- $ref: jedec,lpddr-props.yaml#
- $ref: jedec,sdram-props.yaml#
properties:
compatible:

View File

@ -10,7 +10,7 @@ maintainers:
- Krzysztof Kozlowski <krzk@kernel.org>
allOf:
- $ref: jedec,lpddr-props.yaml#
- $ref: jedec,sdram-props.yaml#
properties:
compatible:

View File

@ -10,7 +10,7 @@ maintainers:
- Krzysztof Kozlowski <krzk@kernel.org>
allOf:
- $ref: jedec,lpddr-props.yaml#
- $ref: jedec,sdram-props.yaml#
properties:
compatible:

View File

@ -10,7 +10,7 @@ maintainers:
- Krzysztof Kozlowski <krzk@kernel.org>
allOf:
- $ref: jedec,lpddr-props.yaml#
- $ref: jedec,sdram-props.yaml#
properties:
compatible:

View File

@ -1,23 +1,28 @@
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/memory-controllers/ddr/jedec,lpddr-channel.yaml#
$id: http://devicetree.org/schemas/memory-controllers/ddr/jedec,sdram-channel.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: LPDDR channel with chip/rank topology description
title: SDRAM channel with chip/rank topology description
description:
An LPDDR channel is a completely independent set of LPDDR pins (DQ, CA, CS,
CK, etc.) that connect one or more LPDDR chips to a host system. The main
purpose of this node is to overall LPDDR topology of the system, including the
amount of individual LPDDR chips and the ranks per chip.
A memory channel of SDRAM memory like DDR SDRAM or LPDDR SDRAM is a completely
independent set of pins (DQ, CA, CS, CK, etc.) that connect one or more memory
chips to a host system. The main purpose of this node is to overall memory
topology of the system, including the amount of individual memory chips and
the ranks per chip.
maintainers:
- Julius Werner <jwerner@chromium.org>
properties:
$nodename:
pattern: "sdram-channel-[0-9]+$"
compatible:
enum:
- jedec,ddr4-channel
- jedec,lpddr2-channel
- jedec,lpddr3-channel
- jedec,lpddr4-channel
@ -26,14 +31,14 @@ properties:
io-width:
description:
The number of DQ pins in the channel. If this number is different
from (a multiple of) the io-width of the LPDDR chip, that means that
from (a multiple of) the io-width of the SDRAM chip, that means that
multiple instances of that type of chip are wired in parallel on this
channel (with the channel's DQ pins split up between the different
chips, and the CA, CS, etc. pins of the different chips all shorted
together). This means that the total physical memory controlled by a
channel is equal to the sum of the densities of each rank on the
connected LPDDR chip, times the io-width of the channel divided by
the io-width of the LPDDR chip.
connected SDRAM chip, times the io-width of the channel divided by
the io-width of the SDRAM chip.
enum:
- 8
- 16
@ -51,8 +56,8 @@ patternProperties:
"^rank@[0-9]+$":
type: object
description:
Each physical LPDDR chip may have one or more ranks. Ranks are
internal but fully independent sub-units of the chip. Each LPDDR bus
Each physical SDRAM chip may have one or more ranks. Ranks are
internal but fully independent sub-units of the chip. Each SDRAM bus
transaction on the channel targets exactly one rank, based on the
state of the CS pins. Different ranks may have different densities and
timing requirements.
@ -60,6 +65,15 @@ patternProperties:
- reg
allOf:
- if:
properties:
compatible:
contains:
const: jedec,ddr4-channel
then:
patternProperties:
"^rank@[0-9]+$":
$ref: /schemas/memory-controllers/ddr/jedec,ddr4.yaml#
- if:
properties:
compatible:
@ -107,7 +121,7 @@ additionalProperties: false
examples:
- |
lpddr-channel0 {
sdram-channel-0 {
#address-cells = <1>;
#size-cells = <0>;
compatible = "jedec,lpddr3-channel";
@ -122,7 +136,7 @@ examples:
};
};
lpddr-channel1 {
sdram-channel-1 {
#address-cells = <1>;
#size-cells = <0>;
compatible = "jedec,lpddr4-channel";

View File

@ -0,0 +1,94 @@
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/memory-controllers/ddr/jedec,sdram-props.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Common properties for SDRAM types
description:
Different SDRAM types generally use the same properties and only differ in the
range of legal values for each. This file defines the common parts that can be
reused for each type. Nodes using this schema should generally be nested under
a SDRAM channel node.
maintainers:
- Krzysztof Kozlowski <krzk@kernel.org>
properties:
compatible:
description: |
Compatible strings can be either explicit vendor names and part numbers
(e.g. elpida,ECB240ABACN), or generated strings of the form
lpddrX-YY,ZZZZ or ddrX-YYYY,AAAA...-ZZ where X, Y, and Z are lowercase
hexadecimal with leading zeroes, and A is lowercase ASCII.
For LPDDR and DDR SDRAM, X is the SDRAM version (2, 3, 4, etc.).
For LPDDR SDRAM:
- YY is the manufacturer ID (from MR5), 1 byte
- ZZZZ is the revision ID (from MR6 and MR7), 2 bytes
For DDR4 SDRAM with SPD, according to JEDEC SPD4.1.2.L-6:
- YYYY is the manufacturer ID, 2 bytes, from bytes 320 and 321
- AAAA... is the part number, 20 bytes (20 chars) from bytes 329 to 348
without trailing spaces
- ZZ is the revision ID, 1 byte, from byte 349
The former form is useful when the SDRAM vendor and part number are
known, for example, when memory is soldered on the board. The latter
form is useful when SDRAM nodes are created at runtime by boot firmware
that doesn't have access to static part number information.
reg:
description:
The rank number of this memory rank when used as a subnode to an memory
channel.
minimum: 0
maximum: 3
revision-id:
$ref: /schemas/types.yaml#/definitions/uint32-array
description: |
SDRAM revision ID:
- LPDDR SDRAM, decoded from Mode Registers 6 and 7, always 2 bytes.
- DDR4 SDRAM, decoded from the SPD from byte 349 according to
JEDEC SPD4.1.2.L-6, always 1 byte.
One byte per uint32 cell (e.g., <MR6 MR7>).
maxItems: 2
items:
minimum: 0
maximum: 255
density:
$ref: /schemas/types.yaml#/definitions/uint32
description: |
Density of the SDRAM chip in megabits:
- LPDDR SDRAM, decoded from Mode Register 8.
- DDR4 SDRAM, decoded from the SPD from bits 3-0 of byte 4 according to
JEDEC SPD4.1.2.L-6.
enum:
- 64
- 128
- 256
- 512
- 1024
- 2048
- 3072
- 4096
- 6144
- 8192
- 12288
- 16384
- 24576
- 32768
io-width:
$ref: /schemas/types.yaml#/definitions/uint32
description: |
I/O bus width in bits of the SDRAM chip:
- LPDDR SDRAM, decoded from Mode Register 8.
- DDR4 SDRAM, decoded from the SPD from bits 2-0 of byte 12 according to
JEDEC SPD4.1.2.L-6.
enum:
- 8
- 16
- 32
additionalProperties: true

View File

@ -595,25 +595,28 @@ static int mtk_smi_device_link_common(struct device *dev, struct device **com_de
smi_com_pdev = of_find_device_by_node(smi_com_node);
of_node_put(smi_com_node);
if (smi_com_pdev) {
/* smi common is the supplier, Make sure it is ready before */
if (!platform_get_drvdata(smi_com_pdev)) {
put_device(&smi_com_pdev->dev);
return -EPROBE_DEFER;
}
smi_com_dev = &smi_com_pdev->dev;
link = device_link_add(dev, smi_com_dev,
DL_FLAG_PM_RUNTIME | DL_FLAG_STATELESS);
if (!link) {
dev_err(dev, "Unable to link smi-common dev\n");
put_device(&smi_com_pdev->dev);
return -ENODEV;
}
*com_dev = smi_com_dev;
} else {
if (!smi_com_pdev) {
dev_err(dev, "Failed to get the smi_common device\n");
return -EINVAL;
}
/* smi common is the supplier, Make sure it is ready before */
if (!platform_get_drvdata(smi_com_pdev)) {
put_device(&smi_com_pdev->dev);
return -EPROBE_DEFER;
}
smi_com_dev = &smi_com_pdev->dev;
link = device_link_add(dev, smi_com_dev,
DL_FLAG_PM_RUNTIME | DL_FLAG_STATELESS);
if (!link) {
dev_err(dev, "Unable to link smi-common dev\n");
put_device(&smi_com_pdev->dev);
return -ENODEV;
}
*com_dev = smi_com_dev;
return 0;
}
@ -674,6 +677,7 @@ static int mtk_smi_larb_probe(struct platform_device *pdev)
err_pm_disable:
pm_runtime_disable(dev);
device_link_remove(dev, larb->smi_common_dev);
put_device(larb->smi_common_dev);
return ret;
}
@ -684,6 +688,7 @@ static void mtk_smi_larb_remove(struct platform_device *pdev)
device_link_remove(&pdev->dev, larb->smi_common_dev);
pm_runtime_disable(&pdev->dev);
component_del(&pdev->dev, &mtk_smi_larb_component_ops);
put_device(larb->smi_common_dev);
}
static int __maybe_unused mtk_smi_larb_resume(struct device *dev)
@ -917,6 +922,7 @@ static void mtk_smi_common_remove(struct platform_device *pdev)
if (common->plat->type == MTK_SMI_GEN2_SUB_COMM)
device_link_remove(&pdev->dev, common->smi_common_dev);
pm_runtime_disable(&pdev->dev);
put_device(common->smi_common_dev);
}
static int __maybe_unused mtk_smi_common_resume(struct device *dev)