* Re: [PATCH v3 05/17] arm64, hibernate: check pgd table allocation
From: James Morse @ 2019-09-06 15:17 UTC (permalink / raw)
To: Pavel Tatashin
Cc: sashal, mark.rutland, vladimir.murzin, corbet, marc.zyngier,
catalin.marinas, bhsharma, kexec, linux-kernel, jmorris, linux-mm,
ebiederm, matthias.bgg, will, linux-arm-kernel
In-Reply-To: <20190821183204.23576-6-pasha.tatashin@soleen.com>
Hi Pavel,
On 21/08/2019 19:31, Pavel Tatashin wrote:
> There is a bug in create_safe_exec_page(), when page table is allocated
> it is not checked that table is allocated successfully:
>
> But it is dereferenced in: pgd_none(READ_ONCE(*pgdp)).
If there is a bug, it shouldn't be fixed part way through a series. This makes it
difficult to backport the fix.
Please split this out as an independent patch with a 'Fixes:' tag for the commit that
introduced the bug.
> Another issue,
So this patch does two things? That is rarely a good idea. Again, this makes it difficult
to backport the fix.
> is that phys_to_ttbr() uses an offset in page table instead
> of pgd directly.
If you were going to reuse this, that would be a bug. But because the only page that is
being mapped, is mapped to PAGE_SIZE, all the top bits will be 0. The offset calls are
boiler-plate. It doesn't look intentional, but its harmless.
Please separate out the potential NULL-dereference bits so there is a clean stand-alone
fix that can be sent to the stable trees.
Thanks,
James
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* Re: [PATCH v3 04/17] arm64, hibernate: rename dst to page in create_safe_exec_page
From: James Morse @ 2019-09-06 15:17 UTC (permalink / raw)
To: Pavel Tatashin
Cc: sashal, mark.rutland, vladimir.murzin, corbet, marc.zyngier,
catalin.marinas, bhsharma, kexec, linux-kernel, jmorris, linux-mm,
ebiederm, matthias.bgg, will, linux-arm-kernel
In-Reply-To: <20190821183204.23576-5-pasha.tatashin@soleen.com>
Hi Pavel,
On 21/08/2019 19:31, Pavel Tatashin wrote:
> create_safe_exec_page() allocates a safe page and maps it at a
> specific location, also this function returns the physical address
> of newly allocated page.
>
> The destination VA, and PA are specified in arguments: dst_addr,
> phys_dst_addr
>
> However, within the function it uses "dst" which has unsigned long
> type, but is actually a pointers in the current virtual space. This
> is confusing to read.
The type? There are plenty of places in the kernel that an unsigned-long is actually a
pointer. This isn't unusual.
> Rename dst to more appropriate page (page that is created), and also
> change its time to "void *"
If you think its clearer,
Reviewed-by: James Morse <james.morse@arm.com>
Thanks,
James
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* Re: [PATCH v3 03/17] arm64, hibernate: remove gotos in create_safe_exec_page
From: James Morse @ 2019-09-06 15:17 UTC (permalink / raw)
To: Pavel Tatashin
Cc: sashal, mark.rutland, vladimir.murzin, corbet, marc.zyngier,
catalin.marinas, bhsharma, kexec, linux-kernel, jmorris, linux-mm,
ebiederm, matthias.bgg, will, linux-arm-kernel
In-Reply-To: <20190821183204.23576-4-pasha.tatashin@soleen.com>
Hi Pavel,
On 21/08/2019 19:31, Pavel Tatashin wrote:
> Usually, gotos are used to handle cleanup after exception, but
> in case of create_safe_exec_page there are no clean-ups. So,
> simply return the errors directly.
Reviewed-by: James Morse <james.morse@arm.com>
Thanks,
James
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* Re: [PATCH v3 02/17] arm64, hibernate: use get_safe_page directly
From: James Morse @ 2019-09-06 15:17 UTC (permalink / raw)
To: Pavel Tatashin
Cc: sashal, mark.rutland, vladimir.murzin, corbet, marc.zyngier,
catalin.marinas, bhsharma, kexec, linux-kernel, jmorris, linux-mm,
ebiederm, matthias.bgg, will, linux-arm-kernel
In-Reply-To: <20190821183204.23576-3-pasha.tatashin@soleen.com>
Hi Pavel,
Nit: The pattern for the subject prefix should be "arm64: hibernate:"..
Its usually possible to spot the pattern from "git log --oneline $file".
On 21/08/2019 19:31, Pavel Tatashin wrote:
> create_safe_exec_page is a local function that uses the
> get_safe_page() to allocate page table and pages and one pages
> that is getting mapped.
I can't parse this.
create_safe_exec_page() uses hibernate's allocator to create a set of page table to map a
single page that will contain the relocation code.
> Remove the allocator related arguments, and use get_safe_page
> directly, as it is done in other local functions in this
> file.
... because kexec can't use this as it doesn't have a working allocator.
Removing this function pointer makes it easier to refactor the code later.
(this thing is only a function pointer so kexec could use it too ... It looks like you're
creating extra work. Patch 7 moves these new calls out to a new file... presumably so
another patch can remove them again)
As stand-alone cleanup the patch looks fine, but you probably don't need to do this.
Thanks,
James
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* Re: [PATCH v3 01/17] kexec: quiet down kexec reboot
From: James Morse @ 2019-09-06 15:17 UTC (permalink / raw)
To: Pavel Tatashin
Cc: sashal, mark.rutland, vladimir.murzin, corbet, marc.zyngier,
catalin.marinas, bhsharma, kexec, linux-kernel, jmorris, linux-mm,
ebiederm, matthias.bgg, will, linux-arm-kernel
In-Reply-To: <20190821183204.23576-2-pasha.tatashin@soleen.com>
Hi Pavel,
On 21/08/2019 19:31, Pavel Tatashin wrote:
> Here is a regular kexec command sequence and output:
> =====
> $ kexec --reuse-cmdline -i --load Image
> $ kexec -e
> [ 161.342002] kexec_core: Starting new kernel
>
> Welcome to Buildroot
> buildroot login:
> =====
>
> Even when "quiet" kernel parameter is specified, "kexec_core: Starting
> new kernel" is printed.
>
> This message has KERN_EMERG level, but there is no emergency, it is a
> normal kexec operation, so quiet it down to appropriate KERN_NOTICE.
As this doesn't have a dependency with the rest of the series, you may want to post it
independently so it can be picked up independently.
Thanks,
James
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* [RESEND PATCH] memory: atmel-ebi: switch to SPDX license identifiers
From: Tudor.Ambarus @ 2019-09-06 15:15 UTC (permalink / raw)
To: Nicolas.Ferre, alexandre.belloni, Ludovic.Desroches,
linux-arm-kernel, linux-kernel
Cc: Tudor.Ambarus
From: Tudor Ambarus <tudor.ambarus@microchip.com>
Adopt the SPDX license identifiers to ease license compliance
management.
Signed-off-by: Tudor Ambarus <tudor.ambarus@microchip.com>
---
drivers/memory/atmel-ebi.c | 5 +----
1 file changed, 1 insertion(+), 4 deletions(-)
diff --git a/drivers/memory/atmel-ebi.c b/drivers/memory/atmel-ebi.c
index 111e09a5b4e9..20252bea8635 100644
--- a/drivers/memory/atmel-ebi.c
+++ b/drivers/memory/atmel-ebi.c
@@ -1,12 +1,9 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* EBI driver for Atmel chips
* inspired by the fsl weim bus driver
*
* Copyright (C) 2013 Jean-Jacques Hiblot <jjhiblot@traphandler.com>
- *
- * This file is licensed under the terms of the GNU General Public
- * License version 2. This program is licensed "as is" without any
- * warranty of any kind, whether express or implied.
*/
#include <linux/clk.h>
--
2.9.5
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* [PATCH v3 1/2] ASoC: dt-bindings: Convert Allwinner A10 codec to a schema
From: Maxime Ripard @ 2019-09-06 15:12 UTC (permalink / raw)
To: Mark Brown, Liam Girdwood, Mark Rutland, Rob Herring,
Frank Rowand
Cc: linux-arm-kernel, devicetree, alsa-devel, Chen-Yu Tsai,
Maxime Ripard
From: Maxime Ripard <maxime.ripard@bootlin.com>
The Allwinner SoCs have an embedded audio codec that is supported in Linux,
with a matching Device Tree binding.
Now that we have the DT validation in place, let's convert the device tree
bindings for that controller over to a YAML schemas.
Signed-off-by: Maxime Ripard <maxime.ripard@bootlin.com>
---
Changes from v2:
- Change the audio-routing values to an enum, and enforce boundaries on
the size
- Add restrictions to the possible values of audio-routing
Changes from v1:
- Fix subject prefix
---
.../sound/allwinner,sun4i-a10-codec.yaml | 262 ++++++++++++++++++
.../devicetree/bindings/sound/sun4i-codec.txt | 94 -------
2 files changed, 262 insertions(+), 94 deletions(-)
create mode 100644 Documentation/devicetree/bindings/sound/allwinner,sun4i-a10-codec.yaml
delete mode 100644 Documentation/devicetree/bindings/sound/sun4i-codec.txt
diff --git a/Documentation/devicetree/bindings/sound/allwinner,sun4i-a10-codec.yaml b/Documentation/devicetree/bindings/sound/allwinner,sun4i-a10-codec.yaml
new file mode 100644
index 000000000000..faa75b91c072
--- /dev/null
+++ b/Documentation/devicetree/bindings/sound/allwinner,sun4i-a10-codec.yaml
@@ -0,0 +1,262 @@
+# SPDX-License-Identifier: GPL-2.0
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/sound/allwinner,sun4i-a10-codec.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Allwinner A10 Codec Device Tree Bindings
+
+maintainers:
+ - Chen-Yu Tsai <wens@csie.org>
+ - Maxime Ripard <maxime.ripard@bootlin.com>
+
+properties:
+ "#sound-dai-cells":
+ const: 0
+
+ compatible:
+ enum:
+ - allwinner,sun4i-a10-codec
+ - allwinner,sun6i-a31-codec
+ - allwinner,sun7i-a20-codec
+ - allwinner,sun8i-a23-codec
+ - allwinner,sun8i-h3-codec
+ - allwinner,sun8i-v3s-codec
+
+ reg:
+ maxItems: 1
+
+ interrupts:
+ maxItems: 1
+
+ clocks:
+ items:
+ - description: Bus Clock
+ - description: Module Clock
+
+ clock-names:
+ items:
+ - const: apb
+ - const: codec
+
+ dmas:
+ items:
+ - description: RX DMA Channel
+ - description: TX DMA Channel
+
+ dma-names:
+ items:
+ - const: rx
+ - const: tx
+
+ resets:
+ maxItems: 1
+
+ allwinner,audio-routing:
+ description: |-
+ A list of the connections between audio components. Each entry
+ is a pair of strings, the first being the connection's sink, the
+ second being the connection's source.
+ allOf:
+ - $ref: /schemas/types.yaml#definitions/non-unique-string-array
+ - minItems: 2
+ maxItems: 18
+ enum:
+ # Audio Pins on the SoC
+ - HP
+ - HPCOM
+ - LINEIN
+ - LINEOUT
+ - MIC1
+ - MIC2
+ - MIC3
+
+ # Microphone Biases from the SoC
+ - HBIAS
+ - MBIAS
+
+ # Board Connectors
+ - Headphone
+ - Headset Mic
+ - Line In
+ - Line Out
+ - Mic
+ - Speaker
+
+ allwinner,codec-analog-controls:
+ $ref: /schemas/types.yaml#/definitions/phandle
+ description: Phandle to the codec analog controls in the PRCM
+
+ allwinner,pa-gpios:
+ description: GPIO to enable the external amplifier
+
+required:
+ - "#sound-dai-cells"
+ - compatible
+ - reg
+ - interrupts
+ - clocks
+ - clock-names
+ - dmas
+ - dma-names
+
+allOf:
+ - if:
+ properties:
+ compatible:
+ enum:
+ - allwinner,sun6i-a31-codec
+ - allwinner,sun8i-a23-codec
+ - allwinner,sun8i-h3-codec
+ - allwinner,sun8i-v3s-codec
+
+ then:
+ if:
+ properties:
+ compatible:
+ const: allwinner,sun6i-a31-codec
+
+ then:
+ required:
+ - resets
+ - allwinner,audio-routing
+
+ else:
+ required:
+ - resets
+ - allwinner,audio-routing
+ - allwinner,codec-analog-controls
+
+ - if:
+ properties:
+ compatible:
+ enum:
+ - allwinner,sun6i-a31-codec
+
+ then:
+ properties:
+ allwinner,audio-routing:
+ enum:
+ - HP
+ - HPCOM
+ - LINEIN
+ - LINEOUT
+ - MIC1
+ - MIC2
+ - MIC3
+ - HBIAS
+ - MBIAS
+ - Headphone
+ - Headset Mic
+ - Line In
+ - Line Out
+ - Mic
+ - Speaker
+
+ - if:
+ properties:
+ compatible:
+ enum:
+ - allwinner,sun8i-a23-codec
+
+ then:
+ properties:
+ allwinner,audio-routing:
+ enum:
+ - HP
+ - HPCOM
+ - LINEIN
+ - MIC1
+ - MIC2
+ - HBIAS
+ - MBIAS
+ - Headphone
+ - Headset Mic
+ - Line In
+ - Line Out
+ - Mic
+ - Speaker
+
+ - if:
+ properties:
+ compatible:
+ enum:
+ - allwinner,sun8i-h3-codec
+
+ then:
+ properties:
+ allwinner,audio-routing:
+ enum:
+ - HP
+ - HPCOM
+ - LINEIN
+ - LINEOUT
+ - MIC1
+ - MIC2
+ - HBIAS
+ - MBIAS
+ - Headphone
+ - Headset Mic
+ - Line In
+ - Line Out
+ - Mic
+ - Speaker
+
+ - if:
+ properties:
+ compatible:
+ enum:
+ - allwinner,sun8i-v3s-codec
+
+ then:
+ properties:
+ allwinner,audio-routing:
+ enum:
+ - HP
+ - HPCOM
+ - MIC1
+ - HBIAS
+ - Headphone
+ - Headset Mic
+ - Line In
+ - Line Out
+ - Mic
+ - Speaker
+
+additionalProperties: false
+
+examples:
+ - |
+ codec@1c22c00 {
+ #sound-dai-cells = <0>;
+ compatible = "allwinner,sun7i-a20-codec";
+ reg = <0x01c22c00 0x40>;
+ interrupts = <0 30 4>;
+ clocks = <&apb0_gates 0>, <&codec_clk>;
+ clock-names = "apb", "codec";
+ dmas = <&dma 0 19>, <&dma 0 19>;
+ dma-names = "rx", "tx";
+ };
+
+ - |
+ codec@1c22c00 {
+ #sound-dai-cells = <0>;
+ compatible = "allwinner,sun6i-a31-codec";
+ reg = <0x01c22c00 0x98>;
+ interrupts = <0 29 4>;
+ clocks = <&ccu 61>, <&ccu 135>;
+ clock-names = "apb", "codec";
+ resets = <&ccu 42>;
+ dmas = <&dma 15>, <&dma 15>;
+ dma-names = "rx", "tx";
+ allwinner,audio-routing =
+ "Headphone", "HP",
+ "Speaker", "LINEOUT",
+ "LINEIN", "Line In",
+ "MIC1", "MBIAS",
+ "MIC1", "Mic",
+ "MIC2", "HBIAS",
+ "MIC2", "Headset Mic";
+ };
+
+...
diff --git a/Documentation/devicetree/bindings/sound/sun4i-codec.txt b/Documentation/devicetree/bindings/sound/sun4i-codec.txt
deleted file mode 100644
index 66579bbd3294..000000000000
--- a/Documentation/devicetree/bindings/sound/sun4i-codec.txt
+++ /dev/null
@@ -1,94 +0,0 @@
-* Allwinner A10 Codec
-
-Required properties:
-- compatible: must be one of the following compatibles:
- - "allwinner,sun4i-a10-codec"
- - "allwinner,sun6i-a31-codec"
- - "allwinner,sun7i-a20-codec"
- - "allwinner,sun8i-a23-codec"
- - "allwinner,sun8i-h3-codec"
- - "allwinner,sun8i-v3s-codec"
-- reg: must contain the registers location and length
-- interrupts: must contain the codec interrupt
-- dmas: DMA channels for tx and rx dma. See the DMA client binding,
- Documentation/devicetree/bindings/dma/dma.txt
-- dma-names: should include "tx" and "rx".
-- clocks: a list of phandle + clock-specifer pairs, one for each entry
- in clock-names.
-- clock-names: should contain the following:
- - "apb": the parent APB clock for this controller
- - "codec": the parent module clock
-
-Optional properties:
-- allwinner,pa-gpios: gpio to enable external amplifier
-
-Required properties for the following compatibles:
- - "allwinner,sun6i-a31-codec"
- - "allwinner,sun8i-a23-codec"
- - "allwinner,sun8i-h3-codec"
- - "allwinner,sun8i-v3s-codec"
-- resets: phandle to the reset control for this device
-- allwinner,audio-routing: A list of the connections between audio components.
- Each entry is a pair of strings, the first being the
- connection's sink, the second being the connection's
- source. Valid names include:
-
- Audio pins on the SoC:
- "HP"
- "HPCOM"
- "LINEIN" (not on sun8i-v3s)
- "LINEOUT" (not on sun8i-a23 or sun8i-v3s)
- "MIC1"
- "MIC2" (not on sun8i-v3s)
- "MIC3" (sun6i-a31 only)
-
- Microphone biases from the SoC:
- "HBIAS"
- "MBIAS" (not on sun8i-v3s)
-
- Board connectors:
- "Headphone"
- "Headset Mic"
- "Line In"
- "Line Out"
- "Mic"
- "Speaker"
-
-Required properties for the following compatibles:
- - "allwinner,sun8i-a23-codec"
- - "allwinner,sun8i-h3-codec"
- - "allwinner,sun8i-v3s-codec"
-- allwinner,codec-analog-controls: A phandle to the codec analog controls
- block in the PRCM.
-
-Example:
-codec: codec@1c22c00 {
- #sound-dai-cells = <0>;
- compatible = "allwinner,sun7i-a20-codec";
- reg = <0x01c22c00 0x40>;
- interrupts = <0 30 4>;
- clocks = <&apb0_gates 0>, <&codec_clk>;
- clock-names = "apb", "codec";
- dmas = <&dma 0 19>, <&dma 0 19>;
- dma-names = "rx", "tx";
-};
-
-codec: codec@1c22c00 {
- #sound-dai-cells = <0>;
- compatible = "allwinner,sun6i-a31-codec";
- reg = <0x01c22c00 0x98>;
- interrupts = <GIC_SPI 29 IRQ_TYPE_LEVEL_HIGH>;
- clocks = <&ccu CLK_APB1_CODEC>, <&ccu CLK_CODEC>;
- clock-names = "apb", "codec";
- resets = <&ccu RST_APB1_CODEC>;
- dmas = <&dma 15>, <&dma 15>;
- dma-names = "rx", "tx";
- allwinner,audio-routing =
- "Headphone", "HP",
- "Speaker", "LINEOUT",
- "LINEIN", "Line In",
- "MIC1", "MBIAS",
- "MIC1", "Mic",
- "MIC2", "HBIAS",
- "MIC2", "Headset Mic";
-};
--
2.21.0
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* [PATCH v3 2/2] ASoC: dt-bindings: Convert Allwinner A23 analog codec to a schema
From: Maxime Ripard @ 2019-09-06 15:12 UTC (permalink / raw)
To: Mark Brown, Liam Girdwood, Mark Rutland, Rob Herring,
Frank Rowand
Cc: linux-arm-kernel, devicetree, alsa-devel, Chen-Yu Tsai,
Maxime Ripard
In-Reply-To: <20190906151221.3148-1-mripard@kernel.org>
From: Maxime Ripard <maxime.ripard@bootlin.com>
The Allwinner A23 SoC and later have an embedded audio codec that uses a
separate controller to drive its analog part, which is supported in Linux,
with a matching Device Tree binding.
Now that we have the DT validation in place, let's convert the device tree
bindings for that controller over to a YAML schemas.
Signed-off-by: Maxime Ripard <maxime.ripard@bootlin.com>
---
Changes from v2:
- Use an enum instead of a oneOf for the compatibles
Changes from v1:
- Fix subject prefix
---
.../allwinner,sun8i-a23-codec-analog.yaml | 38 +++++++++++++++++++
.../bindings/sound/sun8i-codec-analog.txt | 17 ---------
2 files changed, 38 insertions(+), 17 deletions(-)
create mode 100644 Documentation/devicetree/bindings/sound/allwinner,sun8i-a23-codec-analog.yaml
delete mode 100644 Documentation/devicetree/bindings/sound/sun8i-codec-analog.txt
diff --git a/Documentation/devicetree/bindings/sound/allwinner,sun8i-a23-codec-analog.yaml b/Documentation/devicetree/bindings/sound/allwinner,sun8i-a23-codec-analog.yaml
new file mode 100644
index 000000000000..85305b4c2729
--- /dev/null
+++ b/Documentation/devicetree/bindings/sound/allwinner,sun8i-a23-codec-analog.yaml
@@ -0,0 +1,38 @@
+# SPDX-License-Identifier: GPL-2.0
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/sound/allwinner,sun8i-a23-codec-analog.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Allwinner A23 Analog Codec Device Tree Bindings
+
+maintainers:
+ - Chen-Yu Tsai <wens@csie.org>
+ - Maxime Ripard <maxime.ripard@bootlin.com>
+
+properties:
+ compatible:
+ enum:
+ # FIXME: This is documented in the PRCM binding, but needs to be
+ # migrated here at some point
+ # - allwinner,sun8i-a23-codec-analog
+ - allwinner,sun8i-h3-codec-analog
+ - allwinner,sun8i-v3s-codec-analog
+
+ reg:
+ maxItems: 1
+
+required:
+ - compatible
+ - reg
+
+additionalProperties: false
+
+examples:
+ - |
+ codec_analog: codec-analog@1f015c0 {
+ compatible = "allwinner,sun8i-h3-codec-analog";
+ reg = <0x01f015c0 0x4>;
+ };
+
+...
diff --git a/Documentation/devicetree/bindings/sound/sun8i-codec-analog.txt b/Documentation/devicetree/bindings/sound/sun8i-codec-analog.txt
deleted file mode 100644
index 07356758bd91..000000000000
--- a/Documentation/devicetree/bindings/sound/sun8i-codec-analog.txt
+++ /dev/null
@@ -1,17 +0,0 @@
-* Allwinner Codec Analog Controls
-
-Required properties:
-- compatible: must be one of the following compatibles:
- - "allwinner,sun8i-a23-codec-analog"
- - "allwinner,sun8i-h3-codec-analog"
- - "allwinner,sun8i-v3s-codec-analog"
-
-Required properties if not a sub-node of the PRCM node:
-- reg: must contain the registers location and length
-
-Example:
-prcm: prcm@1f01400 {
- codec_analog: codec-analog {
- compatible = "allwinner,sun8i-a23-codec-analog";
- };
-};
--
2.21.0
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* [PATCH] media: imx7-mipi-csis: make array 'registers' static const, makes object smaller
From: Colin King @ 2019-09-06 15:08 UTC (permalink / raw)
To: Rui Miguel Silva, Steve Longerbeam, Philipp Zabel,
Mauro Carvalho Chehab, Greg Kroah-Hartman, Shawn Guo,
Sascha Hauer, linux-media, devel, linux-arm-kernel
Cc: kernel-janitors, linux-kernel
From: Colin Ian King <colin.king@canonical.com>
Don't populate the array 'registers' on the stack but instead make it
static const. Makes the object code smaller by 10 bytes.
Before:
text data bss dec hex filename
20138 5196 128 25462 6376 staging/media/imx/imx7-mipi-csis.o
After:
text data bss dec hex filename
20032 5292 128 25452 636c staging/media/imx/imx7-mipi-csis.o
(gcc version 9.2.1, amd64)
Signed-off-by: Colin Ian King <colin.king@canonical.com>
---
drivers/staging/media/imx/imx7-mipi-csis.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/staging/media/imx/imx7-mipi-csis.c b/drivers/staging/media/imx/imx7-mipi-csis.c
index 73d8354e618c..f8a97b7e2535 100644
--- a/drivers/staging/media/imx/imx7-mipi-csis.c
+++ b/drivers/staging/media/imx/imx7-mipi-csis.c
@@ -293,7 +293,7 @@ static int mipi_csis_dump_regs(struct csi_state *state)
struct device *dev = &state->pdev->dev;
unsigned int i;
u32 cfg;
- struct {
+ static const struct {
u32 offset;
const char * const name;
} registers[] = {
--
2.20.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* [RESEND PATCH] memory: atmel-ebi: move NUM_CS definition inside EBI driver
From: Tudor.Ambarus @ 2019-09-06 15:06 UTC (permalink / raw)
To: Nicolas.Ferre, alexandre.belloni, Ludovic.Desroches, lee.jones,
linux-arm-kernel, linux-kernel
Cc: Tudor.Ambarus
From: Tudor Ambarus <tudor.ambarus@microchip.com>
The total number of EBI CS lines is described by the EBI controller
and not by the Matrix. Move the definition for the number of CS
inside EBI driver.
Signed-off-by: Tudor Ambarus <tudor.ambarus@microchip.com>
---
drivers/memory/atmel-ebi.c | 6 ++++--
include/linux/mfd/syscon/atmel-matrix.h | 1 -
2 files changed, 4 insertions(+), 3 deletions(-)
diff --git a/drivers/memory/atmel-ebi.c b/drivers/memory/atmel-ebi.c
index d0cd57aaebb4..111e09a5b4e9 100644
--- a/drivers/memory/atmel-ebi.c
+++ b/drivers/memory/atmel-ebi.c
@@ -19,6 +19,8 @@
#include <linux/regmap.h>
#include <soc/at91/atmel-sfr.h>
+#define AT91_EBI_NUM_CS 8
+
struct atmel_ebi_dev_config {
int cs;
struct atmel_smc_cs_conf smcconf;
@@ -314,7 +316,7 @@ static int atmel_ebi_dev_setup(struct atmel_ebi *ebi, struct device_node *np,
if (ret)
return ret;
- if (cs >= AT91_MATRIX_EBI_NUM_CS ||
+ if (cs >= AT91_EBI_NUM_CS ||
!(ebi->caps->available_cs & BIT(cs))) {
dev_err(dev, "invalid reg property in %pOF\n", np);
return -EINVAL;
@@ -345,7 +347,7 @@ static int atmel_ebi_dev_setup(struct atmel_ebi *ebi, struct device_node *np,
apply = true;
i = 0;
- for_each_set_bit(cs, &cslines, AT91_MATRIX_EBI_NUM_CS) {
+ for_each_set_bit(cs, &cslines, AT91_EBI_NUM_CS) {
ebid->configs[i].cs = cs;
if (apply) {
diff --git a/include/linux/mfd/syscon/atmel-matrix.h b/include/linux/mfd/syscon/atmel-matrix.h
index 8293c3e2a82a..1e2cd118e4e3 100644
--- a/include/linux/mfd/syscon/atmel-matrix.h
+++ b/include/linux/mfd/syscon/atmel-matrix.h
@@ -110,7 +110,6 @@
#define AT91_MATRIX_DDR_IOSR BIT(18)
#define AT91_MATRIX_NFD0_SELECT BIT(24)
#define AT91_MATRIX_DDR_MP_EN BIT(25)
-#define AT91_MATRIX_EBI_NUM_CS 8
#define AT91_MATRIX_USBPUCR_PUON BIT(30)
--
2.9.5
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* Re: [PATCH 09/11] swiotlb-xen: simplify cache maintainance
From: Boris Ostrovsky @ 2019-09-06 14:46 UTC (permalink / raw)
To: Konrad Rzeszutek Wilk
Cc: Juergen Gross, Stefano Stabellini, x86, linux-kernel, iommu,
xen-devel, Christoph Hellwig, linux-arm-kernel
In-Reply-To: <20190906144300.GD7824@char.us.oracle.com>
On 9/6/19 10:43 AM, Konrad Rzeszutek Wilk wrote:
> On Fri, Sep 06, 2019 at 10:19:01AM -0400, Boris Ostrovsky wrote:
>> On 9/6/19 10:01 AM, Christoph Hellwig wrote:
>>> On Fri, Sep 06, 2019 at 09:52:12AM -0400, Boris Ostrovsky wrote:
>>>> We need nop definitions of these two for x86.
>>>>
>>>> Everything builds now but that's probably because the calls are under
>>>> 'if (!dev_is_dma_coherent(dev))' which is always false so compiler
>>>> optimized is out. I don't think we should rely on that.
>>> That is how a lot of the kernel works. Provide protypes only for code
>>> that is semantically compiled, but can't ever be called due to
>>> IS_ENABLED() checks. It took me a while to get used to it, but it
>>> actually is pretty nice as the linker does the work for you to check
>>> that it really is never called. Much better than say a BUILD_BUG_ON().
>>
>> (with corrected Juergen's email)
>>
>> I know about IS_ENABLED() but I didn't realize that this is allowed for
>> compile-time inlines and such as well.
>>
>> Anyway, for non-ARM bits
>>
>> Reviewed-by: Boris Ostrovsky <boris.ostrovsky@oracle.com>
> Acked-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
>
> as well.
>
> Albeit folks have tested this under x86 Xen with 'swiotlb=force' right?
Yes, I did.
-boris
>
> I can test it myself but it will take a couple of days.
>> If this goes via Xen tree then the first couple of patches need an ack
>> from ARM maintainers.
>>
>> -boris
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* Re: [PATCH 09/11] swiotlb-xen: simplify cache maintainance
From: Konrad Rzeszutek Wilk @ 2019-09-06 14:43 UTC (permalink / raw)
To: Boris Ostrovsky
Cc: Juergen Gross, Stefano Stabellini, x86, linux-kernel, iommu,
xen-devel, Christoph Hellwig, linux-arm-kernel
In-Reply-To: <ca88e7b8-08ca-51b2-0c77-c828d92da0db@oracle.com>
On Fri, Sep 06, 2019 at 10:19:01AM -0400, Boris Ostrovsky wrote:
> On 9/6/19 10:01 AM, Christoph Hellwig wrote:
> > On Fri, Sep 06, 2019 at 09:52:12AM -0400, Boris Ostrovsky wrote:
> >> We need nop definitions of these two for x86.
> >>
> >> Everything builds now but that's probably because the calls are under
> >> 'if (!dev_is_dma_coherent(dev))' which is always false so compiler
> >> optimized is out. I don't think we should rely on that.
> > That is how a lot of the kernel works. Provide protypes only for code
> > that is semantically compiled, but can't ever be called due to
> > IS_ENABLED() checks. It took me a while to get used to it, but it
> > actually is pretty nice as the linker does the work for you to check
> > that it really is never called. Much better than say a BUILD_BUG_ON().
>
>
> (with corrected Juergen's email)
>
> I know about IS_ENABLED() but I didn't realize that this is allowed for
> compile-time inlines and such as well.
>
> Anyway, for non-ARM bits
>
> Reviewed-by: Boris Ostrovsky <boris.ostrovsky@oracle.com>
Acked-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
as well.
Albeit folks have tested this under x86 Xen with 'swiotlb=force' right?
I can test it myself but it will take a couple of days.
>
> If this goes via Xen tree then the first couple of patches need an ack
> from ARM maintainers.
>
> -boris
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* [PATCH -next] perf/arm-cci: use devm_platform_ioremap_resource() to simplify code
From: YueHaibing @ 2019-09-06 14:40 UTC (permalink / raw)
To: will, mark.rutland; +Cc: YueHaibing, linux-kernel, linux-arm-kernel
Use devm_platform_ioremap_resource() to simplify the code a bit.
This is detected by coccinelle.
Signed-off-by: YueHaibing <yuehaibing@huawei.com>
---
drivers/perf/arm-cci.c | 4 +---
1 file changed, 1 insertion(+), 3 deletions(-)
diff --git a/drivers/perf/arm-cci.c b/drivers/perf/arm-cci.c
index 8f8606b..1b8e337 100644
--- a/drivers/perf/arm-cci.c
+++ b/drivers/perf/arm-cci.c
@@ -1642,7 +1642,6 @@ static struct cci_pmu *cci_pmu_alloc(struct device *dev)
static int cci_pmu_probe(struct platform_device *pdev)
{
- struct resource *res;
struct cci_pmu *cci_pmu;
int i, ret, irq;
@@ -1650,8 +1649,7 @@ static int cci_pmu_probe(struct platform_device *pdev)
if (IS_ERR(cci_pmu))
return PTR_ERR(cci_pmu);
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- cci_pmu->base = devm_ioremap_resource(&pdev->dev, res);
+ cci_pmu->base = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(cci_pmu->base))
return -ENOMEM;
--
2.7.4
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* [PATCH -next] perf/arm-ccn: use devm_platform_ioremap_resource() to simplify code
From: YueHaibing @ 2019-09-06 14:39 UTC (permalink / raw)
To: will, mark.rutland; +Cc: YueHaibing, linux-kernel, linux-arm-kernel
Use devm_platform_ioremap_resource() to simplify the code a bit.
This is detected by coccinelle.
Signed-off-by: YueHaibing <yuehaibing@huawei.com>
---
drivers/perf/arm-ccn.c | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/drivers/perf/arm-ccn.c b/drivers/perf/arm-ccn.c
index 6fc0273..fee5cb2 100644
--- a/drivers/perf/arm-ccn.c
+++ b/drivers/perf/arm-ccn.c
@@ -1477,8 +1477,7 @@ static int arm_ccn_probe(struct platform_device *pdev)
ccn->dev = &pdev->dev;
platform_set_drvdata(pdev, ccn);
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- ccn->base = devm_ioremap_resource(ccn->dev, res);
+ ccn->base = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(ccn->base))
return PTR_ERR(ccn->base);
--
2.7.4
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* Re: [v2] ACPI: support for NXP i2c controller
From: Oleksij Rempel @ 2019-09-06 14:39 UTC (permalink / raw)
To: Biwen Li
Cc: wsa, s.hauer, udit.kumar, rjw, linux-kernel, leoyang.li,
linux-acpi, andy.shevchenko, meenakshi.aggarwal, linux-i2c,
chuanhua.han, rafael, shawnguo, linux-arm-kernel
In-Reply-To: <20190906075319.21244-1-biwen.li@nxp.com>
On Fri, Sep 06, 2019 at 03:53:19PM +0800, Biwen Li wrote:
> From: Chuanhua Han <chuanhua.han@nxp.com>
>
> Enable NXP i2c controller to boot with ACPI
>
> Signed-off-by: Meenakshi Aggarwal <meenakshi.aggarwal@nxp.com>
> Signed-off-by: Udit Kumar <udit.kumar@nxp.com>
> Signed-off-by: Chuanhua Han <chuanhua.han@nxp.com>
> Signed-off-by: Biwen Li <biwen.li@nxp.com>
for i2c-imx.c:
Acked-by: Oleksij Rempel <o.rempel@pengutronix.de>
Tested on iMX6Q SabreSD
Tested-by: Oleksij Rempel <o.rempel@pengutronix.de>
> ---
> Change in v2:
> - Simplify code
> - Adjust header file order
> - Not use ACPI_PTR()
>
> drivers/acpi/acpi_apd.c | 7 +++++++
> drivers/i2c/busses/i2c-imx.c | 17 +++++++++++++----
> 2 files changed, 20 insertions(+), 4 deletions(-)
>
> diff --git a/drivers/acpi/acpi_apd.c b/drivers/acpi/acpi_apd.c
> index 7cd0c9ac71ea..71511ae2dfcd 100644
> --- a/drivers/acpi/acpi_apd.c
> +++ b/drivers/acpi/acpi_apd.c
> @@ -160,11 +160,17 @@ static const struct apd_device_desc hip08_i2c_desc = {
> .setup = acpi_apd_setup,
> .fixed_clk_rate = 250000000,
> };
> +
> static const struct apd_device_desc thunderx2_i2c_desc = {
> .setup = acpi_apd_setup,
> .fixed_clk_rate = 125000000,
> };
>
> +static const struct apd_device_desc nxp_i2c_desc = {
> + .setup = acpi_apd_setup,
> + .fixed_clk_rate = 350000000,
> +};
> +
> static const struct apd_device_desc hip08_spi_desc = {
> .setup = acpi_apd_setup,
> .fixed_clk_rate = 250000000,
> @@ -238,6 +244,7 @@ static const struct acpi_device_id acpi_apd_device_ids[] = {
> { "HISI02A1", APD_ADDR(hip07_i2c_desc) },
> { "HISI02A2", APD_ADDR(hip08_i2c_desc) },
> { "HISI0173", APD_ADDR(hip08_spi_desc) },
> + { "NXP0001", APD_ADDR(nxp_i2c_desc) },
> #endif
> { }
> };
> diff --git a/drivers/i2c/busses/i2c-imx.c b/drivers/i2c/busses/i2c-imx.c
> index 15f6cde6452f..a3b61336fe55 100644
> --- a/drivers/i2c/busses/i2c-imx.c
> +++ b/drivers/i2c/busses/i2c-imx.c
> @@ -20,6 +20,7 @@
> *
> */
>
> +#include <linux/acpi.h>
> #include <linux/clk.h>
> #include <linux/completion.h>
> #include <linux/delay.h>
> @@ -255,6 +256,12 @@ static const struct of_device_id i2c_imx_dt_ids[] = {
> };
> MODULE_DEVICE_TABLE(of, i2c_imx_dt_ids);
>
> +static const struct acpi_device_id i2c_imx_acpi_ids[] = {
> + {"NXP0001", .driver_data = (kernel_ulong_t)&vf610_i2c_hwdata},
> + { }
> +};
> +MODULE_DEVICE_TABLE(acpi, i2c_imx_acpi_ids);
> +
> static inline int is_imx1_i2c(struct imx_i2c_struct *i2c_imx)
> {
> return i2c_imx->hwdata->devtype == IMX1_I2C;
> @@ -1048,14 +1055,13 @@ static const struct i2c_algorithm i2c_imx_algo = {
>
> static int i2c_imx_probe(struct platform_device *pdev)
> {
> - const struct of_device_id *of_id = of_match_device(i2c_imx_dt_ids,
> - &pdev->dev);
> struct imx_i2c_struct *i2c_imx;
> struct resource *res;
> struct imxi2c_platform_data *pdata = dev_get_platdata(&pdev->dev);
> void __iomem *base;
> int irq, ret;
> dma_addr_t phy_addr;
> + const struct imx_i2c_hwdata *match;
>
> dev_dbg(&pdev->dev, "<%s>\n", __func__);
>
> @@ -1075,8 +1081,9 @@ static int i2c_imx_probe(struct platform_device *pdev)
> if (!i2c_imx)
> return -ENOMEM;
>
> - if (of_id)
> - i2c_imx->hwdata = of_id->data;
> + match = device_get_match_data(&pdev->dev);
> + if (match)
> + i2c_imx->hwdata = match;
> else
> i2c_imx->hwdata = (struct imx_i2c_hwdata *)
> platform_get_device_id(pdev)->driver_data;
> @@ -1089,6 +1096,7 @@ static int i2c_imx_probe(struct platform_device *pdev)
> i2c_imx->adapter.nr = pdev->id;
> i2c_imx->adapter.dev.of_node = pdev->dev.of_node;
> i2c_imx->base = base;
> + ACPI_COMPANION_SET(&i2c_imx->adapter.dev, ACPI_COMPANION(&pdev->dev));
>
> /* Get I2C clock */
> i2c_imx->clk = devm_clk_get(&pdev->dev, NULL);
> @@ -1247,6 +1255,7 @@ static struct platform_driver i2c_imx_driver = {
> .name = DRIVER_NAME,
> .pm = &i2c_imx_pm_ops,
> .of_match_table = i2c_imx_dt_ids,
> + .acpi_match_table = i2c_imx_acpi_ids,
> },
> .id_table = imx_i2c_devtype,
> };
> --
> 2.17.1
>
>
--
Pengutronix e.K. | |
Industrial Linux Solutions | http://www.pengutronix.de/ |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0 |
Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* [PATCH -next] perf/smmuv3: gpio: creg-snps: use devm_platform_ioremap_resource() to simplify code
From: YueHaibing @ 2019-09-06 14:38 UTC (permalink / raw)
To: will, mark.rutland; +Cc: YueHaibing, linux-kernel, linux-arm-kernel
Use devm_platform_ioremap_resource() to simplify the code a bit.
This is detected by coccinelle.
Signed-off-by: YueHaibing <yuehaibing@huawei.com>
---
drivers/perf/arm_smmuv3_pmu.c | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/drivers/perf/arm_smmuv3_pmu.c b/drivers/perf/arm_smmuv3_pmu.c
index abcf54f..773128f 100644
--- a/drivers/perf/arm_smmuv3_pmu.c
+++ b/drivers/perf/arm_smmuv3_pmu.c
@@ -727,7 +727,7 @@ static void smmu_pmu_get_acpi_options(struct smmu_pmu *smmu_pmu)
static int smmu_pmu_probe(struct platform_device *pdev)
{
struct smmu_pmu *smmu_pmu;
- struct resource *res_0, *res_1;
+ struct resource *res_0;
u32 cfgr, reg_size;
u64 ceid_64[2];
int irq, err;
@@ -764,8 +764,7 @@ static int smmu_pmu_probe(struct platform_device *pdev)
/* Determine if page 1 is present */
if (cfgr & SMMU_PMCG_CFGR_RELOC_CTRS) {
- res_1 = platform_get_resource(pdev, IORESOURCE_MEM, 1);
- smmu_pmu->reloc_base = devm_ioremap_resource(dev, res_1);
+ smmu_pmu->reloc_base = devm_platform_ioremap_resource(pdev, 1);
if (IS_ERR(smmu_pmu->reloc_base))
return PTR_ERR(smmu_pmu->reloc_base);
} else {
--
2.7.4
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* [PATCH -next] perf: xgene: use devm_platform_ioremap_resource() to simplify code
From: YueHaibing @ 2019-09-06 14:37 UTC (permalink / raw)
To: will, mark.rutland, khuong; +Cc: YueHaibing, linux-kernel, linux-arm-kernel
Use devm_platform_ioremap_resource() to simplify the code a bit.
This is detected by coccinelle.
Signed-off-by: YueHaibing <yuehaibing@huawei.com>
---
drivers/perf/xgene_pmu.c | 14 ++++----------
1 file changed, 4 insertions(+), 10 deletions(-)
diff --git a/drivers/perf/xgene_pmu.c b/drivers/perf/xgene_pmu.c
index 7e328d6..46ee680 100644
--- a/drivers/perf/xgene_pmu.c
+++ b/drivers/perf/xgene_pmu.c
@@ -1282,25 +1282,21 @@ static int acpi_pmu_probe_active_mcb_mcu_l3c(struct xgene_pmu *xgene_pmu,
struct platform_device *pdev)
{
void __iomem *csw_csr, *mcba_csr, *mcbb_csr;
- struct resource *res;
unsigned int reg;
- res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
- csw_csr = devm_ioremap_resource(&pdev->dev, res);
+ csw_csr = devm_platform_ioremap_resource(pdev, 1);
if (IS_ERR(csw_csr)) {
dev_err(&pdev->dev, "ioremap failed for CSW CSR resource\n");
return PTR_ERR(csw_csr);
}
- res = platform_get_resource(pdev, IORESOURCE_MEM, 2);
- mcba_csr = devm_ioremap_resource(&pdev->dev, res);
+ mcba_csr = devm_platform_ioremap_resource(pdev, 2);
if (IS_ERR(mcba_csr)) {
dev_err(&pdev->dev, "ioremap failed for MCBA CSR resource\n");
return PTR_ERR(mcba_csr);
}
- res = platform_get_resource(pdev, IORESOURCE_MEM, 3);
- mcbb_csr = devm_ioremap_resource(&pdev->dev, res);
+ mcbb_csr = devm_platform_ioremap_resource(pdev, 3);
if (IS_ERR(mcbb_csr)) {
dev_err(&pdev->dev, "ioremap failed for MCBB CSR resource\n");
return PTR_ERR(mcbb_csr);
@@ -1332,13 +1328,11 @@ static int acpi_pmu_v3_probe_active_mcb_mcu_l3c(struct xgene_pmu *xgene_pmu,
struct platform_device *pdev)
{
void __iomem *csw_csr;
- struct resource *res;
unsigned int reg;
u32 mcb0routing;
u32 mcb1routing;
- res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
- csw_csr = devm_ioremap_resource(&pdev->dev, res);
+ csw_csr = devm_platform_ioremap_resource(pdev, 1);
if (IS_ERR(csw_csr)) {
dev_err(&pdev->dev, "ioremap failed for CSW CSR resource\n");
return PTR_ERR(csw_csr);
--
2.7.4
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* [PATCH v4 5/5] locking/qspinlock: Introduce the shuffle reduction optimization into CNA
From: Alex Kogan @ 2019-09-06 14:25 UTC (permalink / raw)
To: linux, peterz, mingo, will.deacon, arnd, longman, linux-arch,
linux-arm-kernel, linux-kernel, tglx, bp, hpa, x86, guohanjun,
jglauber
Cc: alex.kogan, dave.dice, rahul.x.yadav, steven.sistare,
daniel.m.jordan
In-Reply-To: <20190906142541.34061-1-alex.kogan@oracle.com>
This optimization reduces the probability threads will be shuffled between
the main and secondary queues when the secondary queue is empty.
It is helpful when the lock is only lightly contended.
Signed-off-by: Alex Kogan <alex.kogan@oracle.com>
Reviewed-by: Steve Sistare <steven.sistare@oracle.com>
---
kernel/locking/qspinlock_cna.h | 20 ++++++++++++++++++++
1 file changed, 20 insertions(+)
diff --git a/kernel/locking/qspinlock_cna.h b/kernel/locking/qspinlock_cna.h
index e86182e6163b..1c3a8905b2ca 100644
--- a/kernel/locking/qspinlock_cna.h
+++ b/kernel/locking/qspinlock_cna.h
@@ -64,6 +64,15 @@ static DEFINE_PER_CPU(u32, seed);
#define INTRA_NODE_HANDOFF_PROB_ARG (16)
/*
+ * Controls the probability for enabling the scan of the main queue when
+ * the secondary queue is empty. The chosen value reduces the amount of
+ * unnecessary shuffling of threads between the two waiting queues when
+ * the contention is low, while responding fast enough and enabling
+ * the shuffling when the contention is high.
+ */
+#define SHUFFLE_REDUCTION_PROB_ARG (7)
+
+/*
* Return false with probability 1 / 2^@num_bits.
* Intuitively, the larger @num_bits the less likely false is to be returned.
* @num_bits must be a number between 0 and 31.
@@ -230,6 +239,16 @@ static inline void cna_pass_lock(struct mcs_spinlock *node,
u32 val = 1;
/*
+ * Limit thread shuffling when the secondary queue is empty.
+ * This copes with the overhead the shuffling creates when the
+ * lock is only lightly contended, and threads do not stay
+ * in the secondary queue long enough to reap the benefit of moving
+ * them there.
+ */
+ if (node->locked <= 1 && probably(SHUFFLE_REDUCTION_PROB_ARG))
+ goto pass_lock;
+
+ /*
* Try to find a successor running on the same NUMA node
* as the current lock holder. For long-term fairness,
* search for such a thread with high probability rather than always.
@@ -252,5 +271,6 @@ static inline void cna_pass_lock(struct mcs_spinlock *node,
((struct cna_node *)next_holder)->tail->mcs.next = next;
}
+pass_lock:
arch_mcs_pass_lock(&next_holder->locked, val);
}
--
2.11.0 (Apple Git-81)
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* [PATCH v4 2/5] locking/qspinlock: Refactor the qspinlock slow path
From: Alex Kogan @ 2019-09-06 14:25 UTC (permalink / raw)
To: linux, peterz, mingo, will.deacon, arnd, longman, linux-arch,
linux-arm-kernel, linux-kernel, tglx, bp, hpa, x86, guohanjun,
jglauber
Cc: alex.kogan, dave.dice, rahul.x.yadav, steven.sistare,
daniel.m.jordan
In-Reply-To: <20190906142541.34061-1-alex.kogan@oracle.com>
Move some of the code manipulating the spin lock into separate functions.
This would allow easier integration of alternative ways to manipulate
that lock.
Signed-off-by: Alex Kogan <alex.kogan@oracle.com>
Reviewed-by: Steve Sistare <steven.sistare@oracle.com>
---
kernel/locking/qspinlock.c | 38 ++++++++++++++++++++++++++++++++++++--
1 file changed, 36 insertions(+), 2 deletions(-)
diff --git a/kernel/locking/qspinlock.c b/kernel/locking/qspinlock.c
index c3dfcb689400..070015156a10 100644
--- a/kernel/locking/qspinlock.c
+++ b/kernel/locking/qspinlock.c
@@ -288,6 +288,34 @@ static __always_inline u32 __pv_wait_head_or_lock(struct qspinlock *lock,
#define queued_spin_lock_slowpath native_queued_spin_lock_slowpath
#endif
+/*
+ * __try_clear_tail - try to clear tail by setting the lock value to
+ * _Q_LOCKED_VAL.
+ * @lock: Pointer to the queued spinlock structure
+ * @val: Current value of the lock
+ * @node: Pointer to the MCS node of the lock holder
+ */
+static __always_inline bool __try_clear_tail(struct qspinlock *lock,
+ u32 val,
+ struct mcs_spinlock *node)
+{
+ return atomic_try_cmpxchg_relaxed(&lock->val, &val, _Q_LOCKED_VAL);
+}
+
+/*
+ * __mcs_pass_lock - pass the MCS lock to the next waiter
+ * @node: Pointer to the MCS node of the lock holder
+ * @next: Pointer to the MCS node of the first waiter in the MCS queue
+ */
+static __always_inline void __mcs_pass_lock(struct mcs_spinlock *node,
+ struct mcs_spinlock *next)
+{
+ arch_mcs_pass_lock(&next->locked, 1);
+}
+
+#define try_clear_tail __try_clear_tail
+#define mcs_pass_lock __mcs_pass_lock
+
#endif /* _GEN_PV_LOCK_SLOWPATH */
/**
@@ -532,7 +560,7 @@ void queued_spin_lock_slowpath(struct qspinlock *lock, u32 val)
* PENDING will make the uncontended transition fail.
*/
if ((val & _Q_TAIL_MASK) == tail) {
- if (atomic_try_cmpxchg_relaxed(&lock->val, &val, _Q_LOCKED_VAL))
+ if (try_clear_tail(lock, val, node))
goto release; /* No contention */
}
@@ -549,7 +577,7 @@ void queued_spin_lock_slowpath(struct qspinlock *lock, u32 val)
if (!next)
next = smp_cond_load_relaxed(&node->next, (VAL));
- arch_mcs_pass_lock(&next->locked, 1);
+ mcs_pass_lock(node, next);
pv_kick_node(lock, next);
release:
@@ -574,6 +602,12 @@ EXPORT_SYMBOL(queued_spin_lock_slowpath);
#undef pv_kick_node
#undef pv_wait_head_or_lock
+#undef try_clear_tail
+#define try_clear_tail __try_clear_tail
+
+#undef mcs_pass_lock
+#define mcs_pass_lock __mcs_pass_lock
+
#undef queued_spin_lock_slowpath
#define queued_spin_lock_slowpath __pv_queued_spin_lock_slowpath
--
2.11.0 (Apple Git-81)
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* [PATCH v4 1/5] locking/qspinlock: Rename arch_mcs_spin_unlock_contended to arch_mcs_pass_lock and make it more generic
From: Alex Kogan @ 2019-09-06 14:25 UTC (permalink / raw)
To: linux, peterz, mingo, will.deacon, arnd, longman, linux-arch,
linux-arm-kernel, linux-kernel, tglx, bp, hpa, x86, guohanjun,
jglauber
Cc: alex.kogan, dave.dice, rahul.x.yadav, steven.sistare,
daniel.m.jordan
In-Reply-To: <20190906142541.34061-1-alex.kogan@oracle.com>
The new macro should accept the value to be stored into the lock argument
as another argument. This allows using the same macro in cases where the
value to be stored when passing the lock is different from 1.
Signed-off-by: Alex Kogan <alex.kogan@oracle.com>
Reviewed-by: Steve Sistare <steven.sistare@oracle.com>
---
arch/arm/include/asm/mcs_spinlock.h | 4 ++--
kernel/locking/mcs_spinlock.h | 6 +++---
kernel/locking/qspinlock.c | 2 +-
3 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/arch/arm/include/asm/mcs_spinlock.h b/arch/arm/include/asm/mcs_spinlock.h
index 529d2cf4d06f..f3f9efdcd2ca 100644
--- a/arch/arm/include/asm/mcs_spinlock.h
+++ b/arch/arm/include/asm/mcs_spinlock.h
@@ -14,9 +14,9 @@ do { \
wfe(); \
} while (0) \
-#define arch_mcs_spin_unlock_contended(lock) \
+#define arch_mcs_pass_lock(lock, val) \
do { \
- smp_store_release(lock, 1); \
+ smp_store_release((lock), (val)); \
dsb_sev(); \
} while (0)
diff --git a/kernel/locking/mcs_spinlock.h b/kernel/locking/mcs_spinlock.h
index 5e10153b4d3c..84327ca21650 100644
--- a/kernel/locking/mcs_spinlock.h
+++ b/kernel/locking/mcs_spinlock.h
@@ -41,8 +41,8 @@ do { \
* operations in the critical section has been completed before
* unlocking.
*/
-#define arch_mcs_spin_unlock_contended(l) \
- smp_store_release((l), 1)
+#define arch_mcs_pass_lock(l, val) \
+ smp_store_release((l), (val))
#endif
/*
@@ -115,7 +115,7 @@ void mcs_spin_unlock(struct mcs_spinlock **lock, struct mcs_spinlock *node)
}
/* Pass lock to next waiter. */
- arch_mcs_spin_unlock_contended(&next->locked);
+ arch_mcs_pass_lock(&next->locked, 1);
}
#endif /* __LINUX_MCS_SPINLOCK_H */
diff --git a/kernel/locking/qspinlock.c b/kernel/locking/qspinlock.c
index 2473f10c6956..c3dfcb689400 100644
--- a/kernel/locking/qspinlock.c
+++ b/kernel/locking/qspinlock.c
@@ -549,7 +549,7 @@ void queued_spin_lock_slowpath(struct qspinlock *lock, u32 val)
if (!next)
next = smp_cond_load_relaxed(&node->next, (VAL));
- arch_mcs_spin_unlock_contended(&next->locked);
+ arch_mcs_pass_lock(&next->locked, 1);
pv_kick_node(lock, next);
release:
--
2.11.0 (Apple Git-81)
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* [PATCH v4 0/5] Add NUMA-awareness to qspinlock
From: Alex Kogan @ 2019-09-06 14:25 UTC (permalink / raw)
To: linux, peterz, mingo, will.deacon, arnd, longman, linux-arch,
linux-arm-kernel, linux-kernel, tglx, bp, hpa, x86, guohanjun,
jglauber
Cc: alex.kogan, dave.dice, rahul.x.yadav, steven.sistare,
daniel.m.jordan
Changes from v3:
----------------
- Store encoded pointer in @locked, as suggested by Longman.
As a result, mcs_node size is now intact.
- Add a new kernel boot command-line option "numa_spinlock=on/off/auto",
which may override the selection of the NUMA-aware spinlock during boot,
as requested by Longman.
- Add a dependency on QUEUED_SPINLOCKS to NUMA_AWARE_SPINLOCKS and fix
the help text, as requested by Longman.
- Init the cna_node state in early_initcall(), so we do it only once
instead of every time the node is used, as suggested by Longman.
- Rename macros & functions, refactor cna_try_find_next() (former
find_successor()), as suggested by Peter.
- Add more commentary, including textual graphics to CNA, as suggested by
Longman and Peter.
- Change the argument in probably() to num_bits, as suggested by Peter.
Summary
-------
Lock throughput can be increased by handing a lock to a waiter on the
same NUMA node as the lock holder, provided care is taken to avoid
starvation of waiters on other NUMA nodes. This patch introduces CNA
(compact NUMA-aware lock) as the slow path for qspinlock. It is
enabled through a configuration option (NUMA_AWARE_SPINLOCKS).
CNA is a NUMA-aware version of the MCS spin-lock. Spinning threads are
organized in two queues, a main queue for threads running on the same
node as the current lock holder, and a secondary queue for threads
running on other nodes. Threads store the ID of the node on which
they are running in their queue nodes. At the unlock time, the lock
holder scans the main queue looking for a thread running on the same
node. If found (call it thread T), all threads in the main queue
between the current lock holder and T are moved to the end of the
secondary queue, and the lock is passed to T. If such T is not found, the
lock is passed to the first node in the secondary queue. Finally, if the
secondary queue is empty, the lock is passed to the next thread in the
main queue. To avoid starvation of threads in the secondary queue,
those threads are moved back to the head of the main queue
after a certain expected number of intra-node lock hand-offs.
More details are available at https://arxiv.org/abs/1810.05600.
We have done some performance evaluation with the locktorture module
as well as with several benchmarks from the will-it-scale repo.
The following locktorture results are from an Oracle X5-4 server
(four Intel Xeon E7-8895 v3 @ 2.60GHz sockets with 18 hyperthreaded
cores each). Each number represents an average (over 25 runs) of the
total number of ops (x10^7) reported at the end of each run. The
standard deviation is also reported in (), and in general is about 3%
from the average. The 'stock' kernel is v5.3.0-rc2,
commit 74e6314df6bc, compiled in the default configuration.
'patch-CNA' is the modified kernel with NUMA_AWARE_SPINLOCKS set;
the speedup is calculated dividing 'patch-CNA' by 'stock'.
#thr stock patch-CNA speedup (patch-CNA/stock)
1 2.692 (0.094) 2.660 (0.100) 0.988
2 2.634 (0.122) 2.631 (0.136) 0.999
4 4.152 (0.090) 4.370 (0.152) 1.052
8 5.420 (0.112) 6.978 (0.237) 1.288
16 6.593 (0.141) 8.597 (0.253) 1.304
32 7.335 (0.168) 9.296 (0.223) 1.267
36 7.505 (0.195) 9.329 (0.251) 1.243
72 6.552 (0.180) 9.846 (0.256) 1.503
108 6.194 (0.114) 9.901 (0.196) 1.599
142 5.706 (0.093) 9.866 (0.193) 1.729
The following tables contain throughput results (ops/us) from the same
setup for will-it-scale/open1_threads:
#thr stock patch-CNA speedup (patch-CNA/stock)
1 0.537 (0.001) 0.539 (0.001) 1.003
2 0.808 (0.021) 0.799 (0.022) 0.988
4 1.434 (0.031) 1.425 (0.024) 0.994
8 1.727 (0.102) 1.725 (0.115) 0.999
16 1.714 (0.094) 1.739 (0.082) 1.015
32 0.929 (0.070) 1.677 (0.081) 1.804
36 0.935 (0.087) 1.694 (0.079) 1.812
72 0.842 (0.040) 1.687 (0.069) 2.004
108 0.842 (0.049) 1.737 (0.074) 2.063
142 0.823 (0.049) 1.744 (0.085) 2.119
and will-it-scale/lock2_threads:
#thr stock patch-CNA speedup (patch-CNA/stock)
1 1.601 (0.013) 1.615 (0.006) 1.009
2 2.719 (0.060) 2.741 (0.060) 1.008
4 5.269 (0.392) 5.336 (0.272) 1.013
8 4.061 (0.302) 4.210 (0.311) 1.037
16 4.081 (0.113) 4.170 (0.133) 1.022
32 2.503 (0.104) 4.029 (0.120) 1.610
36 2.493 (0.104) 3.987 (0.111) 1.599
72 1.966 (0.092) 3.968 (0.118) 2.019
108 2.084 (0.116) 3.951 (0.121) 1.896
142 1.925 (0.123) 3.877 (0.088) 2.014
We also evaluated the patch on a single-node machine (Intel i7-4770 with
4 hyperthreaded cores) with will-it-scale, and observed no meaningful
performance impact, as expected. For instance, below are results for
will-it-scale/open1_threads:
#thr stock patch-CNA speedup (patch-CNA/stock)
1 0.866 (0.003) 0.867 (0.001) 1.001
2 1.463 (0.014) 1.463 (0.019) 1.000
4 2.656 (0.052) 2.671 (0.052) 1.005
6 2.872 (0.054) 2.857 (0.045) 0.995
Furthermore, we evaluated the patch in the paravirt setup, booting the
kernel with virtme (qemu) and $(nproc) cores on the same Oracle X5-4 server
as above. We run will-it-scale benchmarks, and once again observed
no meaningful performance impact. For instance, below are results for
will-it-scale/open1_threads:
#thr stock patch-CNA speedup (patch-CNA/stock)
1 0.743 (0.009) 0.747 (0.011) 1.005
2 0.615 (0.031) 0.611 (0.040) 0.993
4 0.629 (0.027) 0.619 (0.034) 0.984
8 0.580 (0.023) 0.574 (0.022) 0.991
16 0.676 (0.019) 0.680 (0.019) 1.006
32 0.566 (0.046) 0.562 (0.026) 0.992
36 0.545 (0.047) 0.544 (0.025) 1.000
72 0.358 (0.010) 0.361 (0.011) 1.009
108 0.353 (0.013) 0.356 (0.012) 1.010
142 0.350 (0.010) 0.355 (0.008) 1.013
Our evaluation shows that CNA also improves performance of user
applications that have hot pthread mutexes. Those mutexes are
blocking, and waiting threads park and unpark via the futex
mechanism in the kernel. Given that kernel futex chains, which
are hashed by the mutex address, are each protected by a
chain-specific spin lock, the contention on a user-mode mutex
translates into contention on a kernel level spinlock.
Here are the results for the leveldb ‘readrandom’ benchmark:
#thr stock patch-CNA speedup (patch-CNA/stock)
1 0.535 (0.010) 0.530 (0.020) 0.990
2 0.659 (0.023) 0.675 (0.030) 1.024
4 0.709 (0.017) 0.707 (0.028) 0.998
8 0.671 (0.026) 0.670 (0.024) 0.999
16 0.716 (0.017) 0.717 (0.020) 1.002
32 0.741 (0.036) 1.040 (0.090) 1.403
36 0.727 (0.042) 1.152 (0.086) 1.585
72 0.639 (0.028) 1.192 (0.023) 1.863
108 0.621 (0.024) 1.181 (0.028) 1.902
142 0.604 (0.015) 1.158 (0.028) 1.919
Further comments are welcome and appreciated.
Alex Kogan (5):
locking/qspinlock: Rename arch_mcs_spin_unlock_contended to
arch_mcs_pass_lock and make it more generic
locking/qspinlock: Refactor the qspinlock slow path
locking/qspinlock: Introduce CNA into the slow path of qspinlock
locking/qspinlock: Introduce starvation avoidance into CNA
locking/qspinlock: Introduce the shuffle reduction optimization into
CNA
arch/arm/include/asm/mcs_spinlock.h | 4 +-
arch/x86/Kconfig | 19 +++
arch/x86/include/asm/qspinlock.h | 4 +
arch/x86/kernel/alternative.c | 41 ++++++
kernel/locking/mcs_spinlock.h | 8 +-
kernel/locking/qspinlock.c | 69 ++++++++-
kernel/locking/qspinlock_cna.h | 276 ++++++++++++++++++++++++++++++++++++
7 files changed, 409 insertions(+), 12 deletions(-)
create mode 100644 kernel/locking/qspinlock_cna.h
--
2.11.0 (Apple Git-81)
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* [PATCH v4 4/5] locking/qspinlock: Introduce starvation avoidance into CNA
From: Alex Kogan @ 2019-09-06 14:25 UTC (permalink / raw)
To: linux, peterz, mingo, will.deacon, arnd, longman, linux-arch,
linux-arm-kernel, linux-kernel, tglx, bp, hpa, x86, guohanjun,
jglauber
Cc: alex.kogan, dave.dice, rahul.x.yadav, steven.sistare,
daniel.m.jordan
In-Reply-To: <20190906142541.34061-1-alex.kogan@oracle.com>
Choose the next lock holder among spinning threads running on the same
node with high probability rather than always. With small probability,
hand the lock to the first thread in the secondary queue or, if that
queue is empty, to the immediate successor of the current lock holder
in the main queue. Thus, assuming no failures while threads hold the
lock, every thread would be able to acquire the lock after a bounded
number of lock transitions, with high probability.
Signed-off-by: Alex Kogan <alex.kogan@oracle.com>
Reviewed-by: Steve Sistare <steven.sistare@oracle.com>
---
kernel/locking/qspinlock_cna.h | 35 +++++++++++++++++++++++++++++++++--
1 file changed, 33 insertions(+), 2 deletions(-)
diff --git a/kernel/locking/qspinlock_cna.h b/kernel/locking/qspinlock_cna.h
index f983debf20bb..e86182e6163b 100644
--- a/kernel/locking/qspinlock_cna.h
+++ b/kernel/locking/qspinlock_cna.h
@@ -4,6 +4,7 @@
#endif
#include <linux/topology.h>
+#include <linux/random.h>
/*
* Implement a NUMA-aware version of MCS (aka CNA, or compact NUMA-aware lock).
@@ -50,6 +51,34 @@ struct cna_node {
struct cna_node *tail; /* points to the secondary queue tail */
};
+/* Per-CPU pseudo-random number seed */
+static DEFINE_PER_CPU(u32, seed);
+
+/*
+ * Controls the probability for intra-node lock hand-off. It can be
+ * tuned and depend, e.g., on the number of CPUs per node. For now,
+ * choose a value that provides reasonable long-term fairness without
+ * sacrificing performance compared to a version that does not have any
+ * fairness guarantees.
+ */
+#define INTRA_NODE_HANDOFF_PROB_ARG (16)
+
+/*
+ * Return false with probability 1 / 2^@num_bits.
+ * Intuitively, the larger @num_bits the less likely false is to be returned.
+ * @num_bits must be a number between 0 and 31.
+ */
+static bool probably(unsigned int num_bits)
+{
+ u32 s;
+
+ s = this_cpu_read(seed);
+ s = next_pseudo_random32(s);
+ this_cpu_write(seed, s);
+
+ return s & ((1 << num_bits) - 1);
+}
+
static void __init cna_init_nodes_per_cpu(unsigned int cpu)
{
struct mcs_spinlock *base = per_cpu_ptr(&qnodes[0].mcs, cpu);
@@ -202,9 +231,11 @@ static inline void cna_pass_lock(struct mcs_spinlock *node,
/*
* Try to find a successor running on the same NUMA node
- * as the current lock holder.
+ * as the current lock holder. For long-term fairness,
+ * search for such a thread with high probability rather than always.
*/
- new_next = cna_try_find_next(node, next);
+ if (probably(INTRA_NODE_HANDOFF_PROB_ARG))
+ new_next = cna_try_find_next(node, next);
if (new_next) { /* if such successor is found */
next_holder = new_next;
--
2.11.0 (Apple Git-81)
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* [PATCH v4 3/5] locking/qspinlock: Introduce CNA into the slow path of qspinlock
From: Alex Kogan @ 2019-09-06 14:25 UTC (permalink / raw)
To: linux, peterz, mingo, will.deacon, arnd, longman, linux-arch,
linux-arm-kernel, linux-kernel, tglx, bp, hpa, x86, guohanjun,
jglauber
Cc: alex.kogan, dave.dice, rahul.x.yadav, steven.sistare,
daniel.m.jordan
In-Reply-To: <20190906142541.34061-1-alex.kogan@oracle.com>
In CNA, spinning threads are organized in two queues, a main queue for
threads running on the same node as the current lock holder, and a
secondary queue for threads running on other nodes. At the unlock time,
the lock holder scans the main queue looking for a thread running on
the same node. If found (call it thread T), all threads in the main queue
between the current lock holder and T are moved to the end of the
secondary queue, and the lock is passed to T. If such T is not found, the
lock is passed to the first node in the secondary queue. Finally, if the
secondary queue is empty, the lock is passed to the next thread in the
main queue. For more details, see https://arxiv.org/abs/1810.05600.
Note that this variant of CNA may introduce starvation by continuously
passing the lock to threads running on the same node. This issue
will be addressed later in the series.
Enabling CNA is controlled via a new configuration option
(NUMA_AWARE_SPINLOCKS). By default, the CNA variant is patched in at the
boot time only if we run on a multi-node machine in native environment and
the new config is enabled. (For the time being, the patching requires
CONFIG_PARAVIRT_SPINLOCKS to be enabled as well. However, this should be
resolved once static_call() is available.) This default behavior can be
overridden with the new kernel boot command-line option
"numa_spinlock=on/off" (default is "auto").
Signed-off-by: Alex Kogan <alex.kogan@oracle.com>
Reviewed-by: Steve Sistare <steven.sistare@oracle.com>
---
arch/x86/Kconfig | 19 ++++
arch/x86/include/asm/qspinlock.h | 4 +
arch/x86/kernel/alternative.c | 41 +++++++
kernel/locking/mcs_spinlock.h | 2 +-
kernel/locking/qspinlock.c | 31 +++++-
kernel/locking/qspinlock_cna.h | 225 +++++++++++++++++++++++++++++++++++++++
6 files changed, 317 insertions(+), 5 deletions(-)
create mode 100644 kernel/locking/qspinlock_cna.h
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index 222855cc0158..9d0d87edff62 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -1567,6 +1567,25 @@ config NUMA
Otherwise, you should say N.
+config NUMA_AWARE_SPINLOCKS
+ bool "Numa-aware spinlocks"
+ depends on NUMA
+ depends on QUEUED_SPINLOCKS
+ # For now, we depend on PARAVIRT_SPINLOCKS to make the patching work.
+ # This is awkward, but hopefully would be resolved once static_call()
+ # is available.
+ depends on PARAVIRT_SPINLOCKS
+ default y
+ help
+ Introduce NUMA (Non Uniform Memory Access) awareness into
+ the slow path of spinlocks.
+
+ In this variant of qspinlock, the kernel will try to keep the lock
+ on the same node, thus reducing the number of remote cache misses,
+ while trading some of the short term fairness for better performance.
+
+ Say N if you want absolute first come first serve fairness.
+
config AMD_NUMA
def_bool y
prompt "Old style AMD Opteron NUMA detection"
diff --git a/arch/x86/include/asm/qspinlock.h b/arch/x86/include/asm/qspinlock.h
index bd5ac6cc37db..d9b6c34d5eb4 100644
--- a/arch/x86/include/asm/qspinlock.h
+++ b/arch/x86/include/asm/qspinlock.h
@@ -27,6 +27,10 @@ static __always_inline u32 queued_fetch_set_pending_acquire(struct qspinlock *lo
return val;
}
+#ifdef CONFIG_NUMA_AWARE_SPINLOCKS
+extern void __cna_queued_spin_lock_slowpath(struct qspinlock *lock, u32 val);
+#endif
+
#ifdef CONFIG_PARAVIRT_SPINLOCKS
extern void native_queued_spin_lock_slowpath(struct qspinlock *lock, u32 val);
extern void __pv_init_lock_hash(void);
diff --git a/arch/x86/kernel/alternative.c b/arch/x86/kernel/alternative.c
index ccd32013c47a..d5194e342db9 100644
--- a/arch/x86/kernel/alternative.c
+++ b/arch/x86/kernel/alternative.c
@@ -698,6 +698,33 @@ static void __init int3_selftest(void)
unregister_die_notifier(&int3_exception_nb);
}
+#if defined(CONFIG_NUMA_AWARE_SPINLOCKS)
+/*
+ * Constant (boot-param configurable) flag selecting the NUMA-aware variant
+ * of spinlock. Possible values: -1 (off) / 0 (auto, default) / 1 (on).
+ */
+static int numa_spinlock_flag;
+
+static int __init numa_spinlock_setup(char *str)
+{
+ if (!strcmp(str, "auto")) {
+ numa_spinlock_flag = 0;
+ return 1;
+ } else if (!strcmp(str, "on")) {
+ numa_spinlock_flag = 1;
+ return 1;
+ } else if (!strcmp(str, "off")) {
+ numa_spinlock_flag = -1;
+ return 1;
+ }
+
+ return 0;
+}
+
+__setup("numa_spinlock=", numa_spinlock_setup);
+
+#endif
+
void __init alternative_instructions(void)
{
int3_selftest();
@@ -738,6 +765,20 @@ void __init alternative_instructions(void)
}
#endif
+#if defined(CONFIG_NUMA_AWARE_SPINLOCKS)
+ /*
+ * By default, switch to the NUMA-friendly slow path for
+ * spinlocks when we have multiple NUMA nodes in native environment.
+ */
+ if ((numa_spinlock_flag == 1) ||
+ (numa_spinlock_flag == 0 && nr_node_ids > 1 &&
+ pv_ops.lock.queued_spin_lock_slowpath ==
+ native_queued_spin_lock_slowpath)) {
+ pv_ops.lock.queued_spin_lock_slowpath =
+ __cna_queued_spin_lock_slowpath;
+ }
+#endif
+
apply_paravirt(__parainstructions, __parainstructions_end);
restart_nmi();
diff --git a/kernel/locking/mcs_spinlock.h b/kernel/locking/mcs_spinlock.h
index 84327ca21650..bd127b21b70c 100644
--- a/kernel/locking/mcs_spinlock.h
+++ b/kernel/locking/mcs_spinlock.h
@@ -17,7 +17,7 @@
struct mcs_spinlock {
struct mcs_spinlock *next;
- int locked; /* 1 if lock acquired */
+ unsigned int locked; /* 1 if lock acquired */
int count; /* nesting count, see qspinlock.c */
};
diff --git a/kernel/locking/qspinlock.c b/kernel/locking/qspinlock.c
index 070015156a10..e4e482685fc1 100644
--- a/kernel/locking/qspinlock.c
+++ b/kernel/locking/qspinlock.c
@@ -11,7 +11,7 @@
* Peter Zijlstra <peterz@infradead.org>
*/
-#ifndef _GEN_PV_LOCK_SLOWPATH
+#if !defined(_GEN_PV_LOCK_SLOWPATH) && !defined(_GEN_CNA_LOCK_SLOWPATH)
#include <linux/smp.h>
#include <linux/bug.h>
@@ -70,7 +70,8 @@
/*
* On 64-bit architectures, the mcs_spinlock structure will be 16 bytes in
* size and four of them will fit nicely in one 64-byte cacheline. For
- * pvqspinlock, however, we need more space for extra data. To accommodate
+ * pvqspinlock, however, we need more space for extra data. The same also
+ * applies for the NUMA-aware variant of spinlocks (CNA). To accommodate
* that, we insert two more long words to pad it up to 32 bytes. IOW, only
* two of them can fit in a cacheline in this case. That is OK as it is rare
* to have more than 2 levels of slowpath nesting in actual use. We don't
@@ -79,7 +80,7 @@
*/
struct qnode {
struct mcs_spinlock mcs;
-#ifdef CONFIG_PARAVIRT_SPINLOCKS
+#if defined(CONFIG_PARAVIRT_SPINLOCKS) || defined(CONFIG_NUMA_AWARE_SPINLOCKS)
long reserved[2];
#endif
};
@@ -103,6 +104,8 @@ struct qnode {
* Exactly fits one 64-byte cacheline on a 64-bit architecture.
*
* PV doubles the storage and uses the second cacheline for PV state.
+ * CNA also doubles the storage and uses the second cacheline for
+ * CNA-specific state.
*/
static DEFINE_PER_CPU_ALIGNED(struct qnode, qnodes[MAX_NODES]);
@@ -316,7 +319,7 @@ static __always_inline void __mcs_pass_lock(struct mcs_spinlock *node,
#define try_clear_tail __try_clear_tail
#define mcs_pass_lock __mcs_pass_lock
-#endif /* _GEN_PV_LOCK_SLOWPATH */
+#endif /* _GEN_PV_LOCK_SLOWPATH && _GEN_CNA_LOCK_SLOWPATH */
/**
* queued_spin_lock_slowpath - acquire the queued spinlock
@@ -589,6 +592,26 @@ void queued_spin_lock_slowpath(struct qspinlock *lock, u32 val)
EXPORT_SYMBOL(queued_spin_lock_slowpath);
/*
+ * Generate the code for NUMA-aware spinlocks
+ */
+#if !defined(_GEN_CNA_LOCK_SLOWPATH) && defined(CONFIG_NUMA_AWARE_SPINLOCKS)
+#define _GEN_CNA_LOCK_SLOWPATH
+
+#undef try_clear_tail
+#define try_clear_tail cna_try_change_tail
+
+#undef mcs_pass_lock
+#define mcs_pass_lock cna_pass_lock
+
+#undef queued_spin_lock_slowpath
+#define queued_spin_lock_slowpath __cna_queued_spin_lock_slowpath
+
+#include "qspinlock_cna.h"
+#include "qspinlock.c"
+
+#endif
+
+/*
* Generate the paravirt code for queued_spin_unlock_slowpath().
*/
#if !defined(_GEN_PV_LOCK_SLOWPATH) && defined(CONFIG_PARAVIRT_SPINLOCKS)
diff --git a/kernel/locking/qspinlock_cna.h b/kernel/locking/qspinlock_cna.h
new file mode 100644
index 000000000000..f983debf20bb
--- /dev/null
+++ b/kernel/locking/qspinlock_cna.h
@@ -0,0 +1,225 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef _GEN_CNA_LOCK_SLOWPATH
+#error "do not include this file"
+#endif
+
+#include <linux/topology.h>
+
+/*
+ * Implement a NUMA-aware version of MCS (aka CNA, or compact NUMA-aware lock).
+ *
+ * In CNA, spinning threads are organized in two queues, a main queue for
+ * threads running on the same NUMA node as the current lock holder, and a
+ * secondary queue for threads running on other nodes. Schematically, it
+ * looks like this:
+ *
+ * cna_node
+ * +----------+ +--------+ +--------+
+ * |mcs:next | -> |mcs:next| -> ... |mcs:next| -> NULL [Main queue]
+ * |mcs:locked| +--------+ +--------+
+ * +----------+
+ * | +--------+ +--------+
+ * +-> |mcs:next| -> ... |mcs:next| -> NULL [Secondary queue]
+ * |cna:tail| -+ +--------+
+ * +--------+ | ^
+ * +-------+
+ *
+ * N.B. locked = 1 if secondary queue is absent.
+ *
+ * At the unlock time, the lock holder scans the main queue looking for a thread
+ * running on the same node. If found (call it thread T), all threads in the
+ * main queue between the current lock holder and T are moved to the end of the
+ * secondary queue, and the lock is passed to T. If such T is not found, the
+ * lock is passed to the first node in the secondary queue. Finally, if the
+ * secondary queue is empty, the lock is passed to the next thread in the
+ * main queue. To avoid starvation of threads in the secondary queue,
+ * those threads are moved back to the head of the main queue after a certain
+ * expected number of intra-node lock hand-offs.
+ *
+ *
+ * For more details, see https://arxiv.org/abs/1810.05600.
+ *
+ * Authors: Alex Kogan <alex.kogan@oracle.com>
+ * Dave Dice <dave.dice@oracle.com>
+ */
+
+struct cna_node {
+ struct mcs_spinlock mcs;
+ int numa_node;
+ u32 encoded_tail;
+ struct cna_node *tail; /* points to the secondary queue tail */
+};
+
+static void __init cna_init_nodes_per_cpu(unsigned int cpu)
+{
+ struct mcs_spinlock *base = per_cpu_ptr(&qnodes[0].mcs, cpu);
+ int numa_node = cpu_to_node(cpu);
+ int i;
+
+ for (i = 0; i < MAX_NODES; i++) {
+ struct cna_node *cn = (struct cna_node *)grab_mcs_node(base, i);
+
+ cn->numa_node = numa_node;
+ cn->encoded_tail = encode_tail(cpu, i);
+ /*
+ * @encoded_tail has to be larger than 1, so we do not confuse
+ * it with other valid values for @locked (0 or 1)
+ */
+ WARN_ON(cn->encoded_tail <= 1);
+ }
+}
+
+static void __init cna_init_nodes(void)
+{
+ unsigned int cpu;
+
+ BUILD_BUG_ON(sizeof(struct cna_node) > sizeof(struct qnode));
+ /* we store an ecoded tail word in the node's @locked field */
+ BUILD_BUG_ON(sizeof(u32) > sizeof(unsigned int));
+
+ for_each_possible_cpu(cpu)
+ cna_init_nodes_per_cpu(cpu);
+}
+early_initcall(cna_init_nodes);
+
+static inline bool cna_try_change_tail(struct qspinlock *lock, u32 val,
+ struct mcs_spinlock *node)
+{
+ struct cna_node *succ;
+ u32 new;
+
+ /* If the secondary queue is empty, do what MCS does. */
+ if (node->locked <= 1)
+ return __try_clear_tail(lock, val, node);
+
+ /*
+ * Try to update the tail value to the last node in the secondary queue.
+ * If successful, pass the lock to the first thread in the secondary
+ * queue. Doing those two actions effectively moves all nodes from the
+ * secondary queue into the main one.
+ */
+ succ = (struct cna_node *)decode_tail(node->locked);
+ new = succ->tail->encoded_tail + _Q_LOCKED_VAL;
+
+ if (atomic_try_cmpxchg_relaxed(&lock->val, &val, new)) {
+ arch_mcs_pass_lock(&succ->mcs.locked, 1);
+ return true;
+ }
+
+ return false;
+}
+
+/*
+ * cna_splice_tail -- splice nodes in the main queue between [first, last]
+ * onto the secondary queue.
+ */
+static void cna_splice_tail(struct cna_node *cn, struct cna_node *first,
+ struct cna_node *last)
+{
+ /* remove [first,last] */
+ cn->mcs.next = last->mcs.next;
+ last->mcs.next = NULL;
+
+ /* stick [first,last] on the secondary queue tail */
+ if (cn->mcs.locked <= 1) { /* if secondary queue is empty */
+ /* create secondary queue */
+ first->tail = last;
+ cn->mcs.locked = first->encoded_tail;
+ } else {
+ /* add to the tail of the secondary queue */
+ struct cna_node *head_2nd =
+ (struct cna_node *)decode_tail(cn->mcs.locked);
+ head_2nd->tail->mcs.next = &first->mcs;
+ head_2nd->tail = last;
+ }
+}
+
+/*
+ * cna_try_find_next - scan the main waiting queue looking for the first
+ * thread running on the same NUMA node as the lock holder. If found (call it
+ * thread T), move all threads in the main queue between the lock holder and
+ * T to the end of the secondary queue and return T; otherwise, return NULL.
+ *
+ * Schematically, this may look like the following (nn stands for numa_node and
+ * et stands for encoded_tail).
+ *
+ * when cna_try_find_next() is called (the secondary queue is empty):
+ *
+ * A+------------+ B+--------+ C+--------+ T+--------+
+ * |mcs:next | -> |mcs:next| -> |mcs:next| -> |mcs:next| -> NULL
+ * |mcs:locked=1| |cna:nn=0| |cna:nn=2| |cna:nn=1|
+ * |cna:nn=1 | +--------+ +--------+ +--------+
+ * +----------- +
+ *
+ * when cna_try_find_next() returns (the secondary queue contains B and C):
+ *
+ * A+----------------+ T+--------+
+ * |mcs:next | -> |mcs:next| -> NULL
+ * |mcs:locked=B.et | -+ |cna:nn=1|
+ * |cna:nn=1 | | +--------+
+ * +--------------- + |
+ * |
+ * +-> B+--------+ C+--------+
+ * |mcs:next| -> |mcs:next|
+ * |cna:nn=0| |cna:nn=2|
+ * |cna:tail| -> +--------+
+ * +--------+
+ *
+ * The worst case complexity of the scan is O(n), where n is the number
+ * of current waiters. However, the fast path, which is expected to be the
+ * common case, is O(1).
+ */
+static struct mcs_spinlock *cna_try_find_next(struct mcs_spinlock *node,
+ struct mcs_spinlock *next)
+{
+ struct cna_node *cn = (struct cna_node *)node;
+ struct cna_node *cni = (struct cna_node *)next;
+ struct cna_node *first, *last = NULL;
+ int my_numa_node = cn->numa_node;
+
+ /* fast path: immediate successor is on the same NUMA node */
+ if (cni->numa_node == my_numa_node)
+ return next;
+
+ /* find any next waiter on 'our' NUMA node */
+ for (first = cni;
+ cni && cni->numa_node != my_numa_node;
+ last = cni, cni = (struct cna_node *)READ_ONCE(cni->mcs.next))
+ ;
+
+ /* if found, splice any skipped waiters onto the secondary queue */
+ if (cni && last)
+ cna_splice_tail(cn, first, last);
+
+ return (struct mcs_spinlock *)cni;
+}
+
+static inline void cna_pass_lock(struct mcs_spinlock *node,
+ struct mcs_spinlock *next)
+{
+ struct mcs_spinlock *next_holder = next, *new_next = NULL;
+ u32 val = 1;
+
+ /*
+ * Try to find a successor running on the same NUMA node
+ * as the current lock holder.
+ */
+ new_next = cna_try_find_next(node, next);
+
+ if (new_next) { /* if such successor is found */
+ next_holder = new_next;
+ /*
+ * Note that @locked here can be 0, 1 or an encoded pointer to
+ * the head of the secondary queue. We pass the lock by storing
+ * a non-zero value, so make sure @val gets 1 iff @locked is 0.
+ */
+ val = node->locked + (node->locked == 0);
+ } else if (node->locked > 1) { /* if secondary queue is not empty */
+ /* next holder will be the first node in the secondary queue */
+ next_holder = decode_tail(node->locked);
+ /* splice the secondary queue onto the head of the main queue */
+ ((struct cna_node *)next_holder)->tail->mcs.next = next;
+ }
+
+ arch_mcs_pass_lock(&next_holder->locked, val);
+}
--
2.11.0 (Apple Git-81)
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* [RESEND PATCH v3 3/3] arm64: dts: meson-g12b-ugoos-am6: add initial device-tree
From: Christian Hewitt @ 2019-09-06 14:32 UTC (permalink / raw)
To: Rob Herring, Mark Rutland, Kevin Hilman, devicetree,
linux-arm-kernel, linux-amlogic, linux-kernel
Cc: Oleg Ivanov, Chrisitian Hewitt
In-Reply-To: <1567780354-59472-1-git-send-email-christianshewitt@gmail.com>
The Ugoos AM6 is based on the Amlogic W400 (G12B) reference design using the
S922X chipset. Hardware specifications:
- 2GB LPDDR4 RAM
- 16GB eMMC storage
- 10/100/1000 Base-T Ethernet using External RGMII PHY
- 802.11 a/b/g/b/ac + BT 5.0 sdio wireless (Ampak 6398S)
- HDMI 2.0 (4k@60p) video
- Composite video + 2-channel audio output on 3.5mm jack
- S/PDIF audio output
- Aux input
- 1x USB 3.0
- 3x USB 2.0
- 1x micro SD card slot
The device-tree is largely based on meson-g12b-odroid-n2 but with audio
and USB config copied from meson-g12a-x96-max.
Tested-by: Oleg Ivanov <balbes-150@yandex.ru>
Signed-off-by: Christian Hewitt <christianshewitt@gmail.com>
---
arch/arm64/boot/dts/amlogic/Makefile | 1 +
.../boot/dts/amlogic/meson-g12b-ugoos-am6.dts | 557 +++++++++++++++++++++
2 files changed, 558 insertions(+)
create mode 100644 arch/arm64/boot/dts/amlogic/meson-g12b-ugoos-am6.dts
diff --git a/arch/arm64/boot/dts/amlogic/Makefile b/arch/arm64/boot/dts/amlogic/Makefile
index 07b861f..21e2810 100644
--- a/arch/arm64/boot/dts/amlogic/Makefile
+++ b/arch/arm64/boot/dts/amlogic/Makefile
@@ -4,6 +4,7 @@ dtb-$(CONFIG_ARCH_MESON) += meson-g12a-sei510.dtb
dtb-$(CONFIG_ARCH_MESON) += meson-g12a-u200.dtb
dtb-$(CONFIG_ARCH_MESON) += meson-g12a-x96-max.dtb
dtb-$(CONFIG_ARCH_MESON) += meson-g12b-odroid-n2.dtb
+dtb-$(CONFIG_ARCH_MESON) += meson-g12b-ugoos-am6.dtb
dtb-$(CONFIG_ARCH_MESON) += meson-gxbb-nanopi-k2.dtb
dtb-$(CONFIG_ARCH_MESON) += meson-gxbb-nexbox-a95x.dtb
dtb-$(CONFIG_ARCH_MESON) += meson-gxbb-odroidc2.dtb
diff --git a/arch/arm64/boot/dts/amlogic/meson-g12b-ugoos-am6.dts b/arch/arm64/boot/dts/amlogic/meson-g12b-ugoos-am6.dts
new file mode 100644
index 0000000..8bf4482
--- /dev/null
+++ b/arch/arm64/boot/dts/amlogic/meson-g12b-ugoos-am6.dts
@@ -0,0 +1,557 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2019 BayLibre, SAS
+ * Author: Neil Armstrong <narmstrong@baylibre.com>
+ * Copyright (c) 2019 Christian Hewitt <christianshewitt@gmail.com>
+ */
+
+/dts-v1/;
+
+#include "meson-g12b.dtsi"
+#include "meson-g12b-s922x.dtsi"
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/gpio/meson-g12a-gpio.h>
+#include <dt-bindings/sound/meson-g12a-tohdmitx.h>
+
+/ {
+ compatible = "ugoos,am6", "amlogic,g12b";
+ model = "Ugoos AM6";
+
+ aliases {
+ serial0 = &uart_AO;
+ ethernet0 = ðmac;
+ };
+
+ spdif_dit: audio-codec-1 {
+ #sound-dai-cells = <0>;
+ compatible = "linux,spdif-dit";
+ status = "okay";
+ sound-name-prefix = "DIT";
+ };
+
+ chosen {
+ stdout-path = "serial0:115200n8";
+ };
+
+ memory@0 {
+ device_type = "memory";
+ reg = <0x0 0x0 0x0 0x40000000>;
+ };
+
+ emmc_pwrseq: emmc-pwrseq {
+ compatible = "mmc-pwrseq-emmc";
+ reset-gpios = <&gpio BOOT_12 GPIO_ACTIVE_LOW>;
+ };
+
+ sdio_pwrseq: sdio-pwrseq {
+ compatible = "mmc-pwrseq-simple";
+ reset-gpios = <&gpio GPIOX_6 GPIO_ACTIVE_LOW>;
+ clocks = <&wifi32k>;
+ clock-names = "ext_clock";
+ };
+
+ flash_1v8: regulator-flash_1v8 {
+ compatible = "regulator-fixed";
+ regulator-name = "FLASH_1V8";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ vin-supply = <&vcc_3v3>;
+ regulator-always-on;
+ };
+
+ main_12v: regulator-main_12v {
+ compatible = "regulator-fixed";
+ regulator-name = "12V";
+ regulator-min-microvolt = <12000000>;
+ regulator-max-microvolt = <12000000>;
+ regulator-always-on;
+ };
+
+ vcc_5v: regulator-vcc_5v {
+ compatible = "regulator-fixed";
+ regulator-name = "VCC_5V";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ vin-supply = <&main_12v>;
+
+ gpio = <&gpio GPIOH_8 GPIO_OPEN_DRAIN>;
+ enable-active-high;
+ };
+
+ vcc_1v8: regulator-vcc_1v8 {
+ compatible = "regulator-fixed";
+ regulator-name = "VCC_1V8";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ vin-supply = <&vcc_3v3>;
+ regulator-always-on;
+ };
+
+ vcc_3v3: regulator-vcc_3v3 {
+ compatible = "regulator-fixed";
+ regulator-name = "VCC_3V3";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ vin-supply = <&vddao_3v3>;
+ regulator-always-on;
+ /* FIXME: actually controlled by VDDCPU_B_EN */
+ };
+
+ vddcpu_a: regulator-vddcpu-a {
+ /*
+ * MP1653 Regulator.
+ */
+ compatible = "pwm-regulator";
+
+ regulator-name = "VDDCPU_A";
+ regulator-min-microvolt = <721000>;
+ regulator-max-microvolt = <1022000>;
+
+ vin-supply = <&main_12v>;
+
+ pwms = <&pwm_ab 0 1250 0>;
+ pwm-dutycycle-range = <100 0>;
+
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ vddcpu_b: regulator-vddcpu-b {
+ /*
+ * MP1652 Regulator.
+ */
+ compatible = "pwm-regulator";
+
+ regulator-name = "VDDCPU_B";
+ regulator-min-microvolt = <721000>;
+ regulator-max-microvolt = <1022000>;
+
+ vin-supply = <&main_12v>;
+
+ pwms = <&pwm_AO_cd 1 1250 0>;
+ pwm-dutycycle-range = <100 0>;
+
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ usb1_pow: regulator-usb1_pow {
+ compatible = "regulator-fixed";
+ regulator-name = "USB1_POW";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ vin-supply = <&vcc_5v>;
+
+ /* connected to SY6280A Power Switch */
+ gpio = <&gpio GPIOA_8 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ };
+
+ usb_pwr_en: regulator-usb_pwr_en {
+ compatible = "regulator-fixed";
+ regulator-name = "USB_PWR_EN";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ vin-supply = <&vcc_5v>;
+
+ /* Connected to USB3 Type-A Port power enable */
+ gpio = <&gpio GPIOAO_7 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ };
+
+ vddao_1v8: regulator-vddao_1v8 {
+ compatible = "regulator-fixed";
+ regulator-name = "VDDAO_1V8";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ vin-supply = <&vddao_3v3>;
+ regulator-always-on;
+ };
+
+ vddao_3v3: regulator-vddao_3v3 {
+ compatible = "regulator-fixed";
+ regulator-name = "VDDAO_3V3";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ vin-supply = <&main_12v>;
+ regulator-always-on;
+ };
+
+ cvbs-connector {
+ compatible = "composite-video-connector";
+
+ port {
+ cvbs_connector_in: endpoint {
+ remote-endpoint = <&cvbs_vdac_out>;
+ };
+ };
+ };
+
+ hdmi-connector {
+ compatible = "hdmi-connector";
+ type = "a";
+
+ port {
+ hdmi_connector_in: endpoint {
+ remote-endpoint = <&hdmi_tx_tmds_out>;
+ };
+ };
+ };
+
+ sound {
+ compatible = "amlogic,axg-sound-card";
+ model = "G12B-UGOOS-AM6";
+ audio-aux-devs = <&tdmout_b>;
+ audio-routing = "TDMOUT_B IN 0", "FRDDR_A OUT 1",
+ "TDMOUT_B IN 1", "FRDDR_B OUT 1",
+ "TDMOUT_B IN 2", "FRDDR_C OUT 1",
+ "TDM_B Playback", "TDMOUT_B OUT",
+ "SPDIFOUT IN 0", "FRDDR_A OUT 3",
+ "SPDIFOUT IN 1", "FRDDR_B OUT 3",
+ "SPDIFOUT IN 2", "FRDDR_C OUT 3";
+
+ assigned-clocks = <&clkc CLKID_MPLL2>,
+ <&clkc CLKID_MPLL0>,
+ <&clkc CLKID_MPLL1>;
+ assigned-clock-parents = <0>, <0>, <0>;
+ assigned-clock-rates = <294912000>,
+ <270950400>,
+ <393216000>;
+ status = "okay";
+
+ dai-link-0 {
+ sound-dai = <&frddr_a>;
+ };
+
+ dai-link-1 {
+ sound-dai = <&frddr_b>;
+ };
+
+ dai-link-2 {
+ sound-dai = <&frddr_c>;
+ };
+
+ /* 8ch hdmi interface */
+ dai-link-3 {
+ sound-dai = <&tdmif_b>;
+ dai-format = "i2s";
+ dai-tdm-slot-tx-mask-0 = <1 1>;
+ dai-tdm-slot-tx-mask-1 = <1 1>;
+ dai-tdm-slot-tx-mask-2 = <1 1>;
+ dai-tdm-slot-tx-mask-3 = <1 1>;
+ mclk-fs = <256>;
+
+ codec {
+ sound-dai = <&tohdmitx TOHDMITX_I2S_IN_B>;
+ };
+ };
+
+ /* spdif hdmi or toslink interface */
+ dai-link-4 {
+ sound-dai = <&spdifout>;
+
+ codec-0 {
+ sound-dai = <&spdif_dit>;
+ };
+
+ codec-1 {
+ sound-dai = <&tohdmitx TOHDMITX_SPDIF_IN_A>;
+ };
+ };
+
+ /* spdif hdmi interface */
+ dai-link-5 {
+ sound-dai = <&spdifout_b>;
+
+ codec {
+ sound-dai = <&tohdmitx TOHDMITX_SPDIF_IN_B>;
+ };
+ };
+
+ /* hdmi glue */
+ dai-link-6 {
+ sound-dai = <&tohdmitx TOHDMITX_I2S_OUT>;
+
+ codec {
+ sound-dai = <&hdmi_tx>;
+ };
+ };
+ };
+
+ wifi32k: wifi32k {
+ compatible = "pwm-clock";
+ #clock-cells = <0>;
+ clock-frequency = <32768>;
+ pwms = <&pwm_ef 0 30518 0>; /* PWM_E at 32.768KHz */
+ };
+};
+
+&arb {
+ status = "okay";
+};
+
+&cec_AO {
+ pinctrl-0 = <&cec_ao_a_h_pins>;
+ pinctrl-names = "default";
+ status = "disabled";
+ hdmi-phandle = <&hdmi_tx>;
+};
+
+&cecb_AO {
+ pinctrl-0 = <&cec_ao_b_h_pins>;
+ pinctrl-names = "default";
+ status = "okay";
+ hdmi-phandle = <&hdmi_tx>;
+};
+
+&clkc_audio {
+ status = "okay";
+};
+
+&cpu0 {
+ cpu-supply = <&vddcpu_b>;
+ operating-points-v2 = <&cpu_opp_table_0>;
+ clocks = <&clkc CLKID_CPU_CLK>;
+ clock-latency = <50000>;
+};
+
+&cpu1 {
+ cpu-supply = <&vddcpu_b>;
+ operating-points-v2 = <&cpu_opp_table_0>;
+ clocks = <&clkc CLKID_CPU_CLK>;
+ clock-latency = <50000>;
+};
+
+&cpu100 {
+ cpu-supply = <&vddcpu_a>;
+ operating-points-v2 = <&cpub_opp_table_1>;
+ clocks = <&clkc CLKID_CPUB_CLK>;
+ clock-latency = <50000>;
+};
+
+&cpu101 {
+ cpu-supply = <&vddcpu_a>;
+ operating-points-v2 = <&cpub_opp_table_1>;
+ clocks = <&clkc CLKID_CPUB_CLK>;
+ clock-latency = <50000>;
+};
+
+&cpu102 {
+ cpu-supply = <&vddcpu_a>;
+ operating-points-v2 = <&cpub_opp_table_1>;
+ clocks = <&clkc CLKID_CPUB_CLK>;
+ clock-latency = <50000>;
+};
+
+&cpu103 {
+ cpu-supply = <&vddcpu_a>;
+ operating-points-v2 = <&cpub_opp_table_1>;
+ clocks = <&clkc CLKID_CPUB_CLK>;
+ clock-latency = <50000>;
+};
+
+&cvbs_vdac_port {
+ cvbs_vdac_out: endpoint {
+ remote-endpoint = <&cvbs_connector_in>;
+ };
+};
+
+&ext_mdio {
+ external_phy: ethernet-phy@0 {
+ /* Realtek RTL8211F (0x001cc916) */
+ reg = <0>;
+ max-speed = <1000>;
+
+ reset-assert-us = <10000>;
+ reset-deassert-us = <30000>;
+ reset-gpios = <&gpio GPIOZ_15 (GPIO_ACTIVE_LOW | GPIO_OPEN_DRAIN)>;
+
+ interrupt-parent = <&gpio_intc>;
+ /* MAC_INTR on GPIOZ_14 */
+ interrupts = <26 IRQ_TYPE_LEVEL_LOW>;
+ };
+};
+
+ðmac {
+ pinctrl-0 = <ð_pins>, <ð_rgmii_pins>;
+ pinctrl-names = "default";
+ status = "okay";
+ phy-mode = "rgmii";
+ phy-handle = <&external_phy>;
+ amlogic,tx-delay-ns = <2>;
+};
+
+&frddr_a {
+ status = "okay";
+};
+
+&frddr_b {
+ status = "okay";
+};
+
+&frddr_c {
+ status = "okay";
+};
+
+&hdmi_tx {
+ status = "okay";
+ pinctrl-0 = <&hdmitx_hpd_pins>, <&hdmitx_ddc_pins>;
+ pinctrl-names = "default";
+ hdmi-supply = <&vcc_5v>;
+};
+
+&hdmi_tx_tmds_port {
+ hdmi_tx_tmds_out: endpoint {
+ remote-endpoint = <&hdmi_connector_in>;
+ };
+};
+
+&ir {
+ status = "okay";
+ pinctrl-0 = <&remote_input_ao_pins>;
+ pinctrl-names = "default";
+ linux,rc-map-name = "rc-khadas";
+};
+
+&pwm_ab {
+ pinctrl-0 = <&pwm_a_e_pins>;
+ pinctrl-names = "default";
+ clocks = <&xtal>;
+ clock-names = "clkin0";
+ status = "okay";
+};
+
+&pwm_AO_cd {
+ pinctrl-0 = <&pwm_ao_d_e_pins>;
+ pinctrl-names = "default";
+ clocks = <&xtal>;
+ clock-names = "clkin1";
+ status = "okay";
+};
+
+&pwm_ef {
+ pinctrl-0 = <&pwm_e_pins>;
+ pinctrl-names = "default";
+ clocks = <&xtal>;
+ clock-names = "clkin0";
+ status = "okay";
+};
+
+&uart_A {
+ status = "okay";
+ pinctrl-0 = <&uart_a_pins>, <&uart_a_cts_rts_pins>;
+ pinctrl-names = "default";
+ uart-has-rtscts;
+
+ bluetooth {
+ compatible = "brcm,bcm43438-bt";
+ shutdown-gpios = <&gpio GPIOX_17 GPIO_ACTIVE_HIGH>;
+ max-speed = <2000000>;
+ clocks = <&wifi32k>;
+ clock-names = "lpo";
+ };
+};
+
+&uart_AO {
+ status = "okay";
+ pinctrl-0 = <&uart_ao_a_pins>;
+ pinctrl-names = "default";
+};
+
+&usb {
+ status = "okay";
+ dr_mode = "host";
+ vbus-regulator = <&usb_pwr_en>;
+};
+
+&usb2_phy0 {
+ phy-supply = <&usb1_pow>;
+};
+
+&usb2_phy1 {
+ phy-supply = <&usb1_pow>;
+};
+
+/* SDIO */
+&sd_emmc_a {
+ status = "okay";
+ pinctrl-0 = <&sdio_pins>;
+ pinctrl-1 = <&sdio_clk_gate_pins>;
+ pinctrl-names = "default", "clk-gate";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ bus-width = <4>;
+ cap-sd-highspeed;
+ sd-uhs-sdr50;
+ max-frequency = <100000000>;
+
+ non-removable;
+ disable-wp;
+
+ mmc-pwrseq = <&sdio_pwrseq>;
+
+ vmmc-supply = <&vddao_3v3>;
+ vqmmc-supply = <&vddao_1v8>;
+
+ brcmf: wifi@1 {
+ reg = <1>;
+ compatible = "brcm,bcm4329-fmac";
+ };
+};
+
+/* SD card */
+&sd_emmc_b {
+ status = "okay";
+ pinctrl-0 = <&sdcard_c_pins>;
+ pinctrl-1 = <&sdcard_clk_gate_c_pins>;
+ pinctrl-names = "default", "clk-gate";
+
+ bus-width = <4>;
+ cap-sd-highspeed;
+ max-frequency = <50000000>;
+ disable-wp;
+
+ cd-gpios = <&gpio GPIOC_6 GPIO_ACTIVE_LOW>;
+ vmmc-supply = <&vddao_3v3>;
+ vqmmc-supply = <&vddao_3v3>;
+};
+
+/* eMMC */
+&sd_emmc_c {
+ status = "okay";
+ pinctrl-0 = <&emmc_pins>, <&emmc_ds_pins>;
+ pinctrl-1 = <&emmc_clk_gate_pins>;
+ pinctrl-names = "default", "clk-gate";
+
+ bus-width = <8>;
+ cap-mmc-highspeed;
+ max-frequency = <100000000>;
+ disable-wp;
+
+ mmc-pwrseq = <&emmc_pwrseq>;
+ vmmc-supply = <&vcc_3v3>;
+ vqmmc-supply = <&flash_1v8>;
+};
+
+&spdifout {
+ pinctrl-0 = <&spdif_out_h_pins>;
+ pinctrl-names = "default";
+ status = "okay";
+};
+
+&spdifout_b {
+ status = "okay";
+};
+
+&tdmif_b {
+ status = "okay";
+};
+
+&tdmout_b {
+ status = "okay";
+};
+
+&tohdmitx {
+ status = "okay";
+};
--
2.7.4
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* [RESEND PATCH v3 2/3] dt-bindings: arm: amlogic: Add support for the Ugoos AM6
From: Christian Hewitt @ 2019-09-06 14:32 UTC (permalink / raw)
To: Rob Herring, Mark Rutland, Kevin Hilman, devicetree,
linux-arm-kernel, linux-amlogic, linux-kernel
Cc: Oleg Ivanov, Chrisitian Hewitt
In-Reply-To: <1567780354-59472-1-git-send-email-christianshewitt@gmail.com>
The Ugoos AM6 is based on the Amlogic W400 (G12B) reference design using the
S922X chipset.
Acked-by: Rob Herring <robh@kernel.org>
Signed-off-by: Christian Hewitt <christianshewitt@gmail.com>
---
Documentation/devicetree/bindings/arm/amlogic.yaml | 1 +
1 file changed, 1 insertion(+)
diff --git a/Documentation/devicetree/bindings/arm/amlogic.yaml b/Documentation/devicetree/bindings/arm/amlogic.yaml
index 325c6fd..2ded61d 100644
--- a/Documentation/devicetree/bindings/arm/amlogic.yaml
+++ b/Documentation/devicetree/bindings/arm/amlogic.yaml
@@ -139,6 +139,7 @@ properties:
items:
- enum:
- hardkernel,odroid-n2
+ - ugoos,am6
- const: amlogic,g12b
...
--
2.7.4
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox