* Re: [PATCH pinctrl/fixes] pinctrl: aspeed: Fix spurious mux failures on the AST2500
From: Linus Walleij @ 2019-09-12 8:23 UTC (permalink / raw)
To: Andrew Jeffery
Cc: linux-aspeed, OpenBMC Maillist, linux-kernel@vger.kernel.org,
open list:GPIO SUBSYSTEM, Joel Stanley, Linux ARM, John Wang
In-Reply-To: <20190829071738.2523-1-andrew@aj.id.au>
On Thu, Aug 29, 2019 at 8:17 AM Andrew Jeffery <andrew@aj.id.au> wrote:
> Commit 674fa8daa8c9 ("pinctrl: aspeed-g5: Delay acquisition of regmaps")
> was determined to be a partial fix to the problem of acquiring the LPC
> Host Controller and GFX regmaps: The AST2500 pin controller may need to
> fetch syscon regmaps during expression evaluation as well as when
> setting mux state. For example, this case is hit by attempting to export
> pins exposing the LPC Host Controller as GPIOs.
>
> An optional eval() hook is added to the Aspeed pinmux operation struct
> and called from aspeed_sig_expr_eval() if the pointer is set by the
> SoC-specific driver. This enables the AST2500 to perform the custom
> action of acquiring its regmap dependencies as required.
>
> John Wang tested the fix on an Inspur FP5280G2 machine (AST2500-based)
> where the issue was found, and I've booted the fix on Witherspoon
> (AST2500) and Palmetto (AST2400) machines, and poked at relevant pins
> under QEMU by forcing mux configurations via devmem before exporting
> GPIOs to exercise the driver.
>
> Fixes: 7d29ed88acbb ("pinctrl: aspeed: Read and write bits in LPC and GFX controllers")
> Fixes: 674fa8daa8c9 ("pinctrl: aspeed-g5: Delay acquisition of regmaps")
> Reported-by: John Wang <wangzqbj@inspur.com>
> Tested-by: John Wang <wangzqbj@inspur.com>
> Signed-off-by: Andrew Jeffery <andrew@aj.id.au>
Applied for fixes already yesterday!
Yours,
Linus Walleij
_______________________________________________
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/4] arm64: dts: add support for A1 based Amlogic AD401
From: Jianxin Pan @ 2019-09-12 8:19 UTC (permalink / raw)
To: Kevin Hilman, linux-amlogic
Cc: devicetree, Hanjie Lin, Victor Wan, Jianxin Pan, Neil Armstrong,
Martin Blumenstingl, linux-kernel, Qiufang Dai, Rob Herring,
Jian Hu, Xingyu Chen, Carlo Caione, Tao Zeng, linux-arm-kernel,
Jerome Brunet
In-Reply-To: <1568276370-54181-1-git-send-email-jianxin.pan@amlogic.com>
Add basic support for the Amlogic A1 based Amlogic AD401 board:
which describe components as follows: Reserve Memory, CPU, GIC, IRQ,
Timer, UART. It's capable of booting up into the serial console.
Signed-off-by: Jianxin Pan <jianxin.pan@amlogic.com>
Reviewed-by: Jerome Brunet <jbrunet@baylibre.com>
Reviewed-by: Neil Armstrong <narmstrong@baylibre.com>
---
arch/arm64/boot/dts/amlogic/Makefile | 1 +
arch/arm64/boot/dts/amlogic/meson-a1-ad401.dts | 30 ++++++
arch/arm64/boot/dts/amlogic/meson-a1.dtsi | 130 +++++++++++++++++++++++++
3 files changed, 161 insertions(+)
create mode 100644 arch/arm64/boot/dts/amlogic/meson-a1-ad401.dts
create mode 100644 arch/arm64/boot/dts/amlogic/meson-a1.dtsi
diff --git a/arch/arm64/boot/dts/amlogic/Makefile b/arch/arm64/boot/dts/amlogic/Makefile
index 84afecb..a90be52 100644
--- a/arch/arm64/boot/dts/amlogic/Makefile
+++ b/arch/arm64/boot/dts/amlogic/Makefile
@@ -36,3 +36,4 @@ dtb-$(CONFIG_ARCH_MESON) += meson-gxm-rbox-pro.dtb
dtb-$(CONFIG_ARCH_MESON) += meson-gxm-vega-s96.dtb
dtb-$(CONFIG_ARCH_MESON) += meson-sm1-sei610.dtb
dtb-$(CONFIG_ARCH_MESON) += meson-sm1-khadas-vim3l.dtb
+dtb-$(CONFIG_ARCH_MESON) += meson-a1-ad401.dtb
diff --git a/arch/arm64/boot/dts/amlogic/meson-a1-ad401.dts b/arch/arm64/boot/dts/amlogic/meson-a1-ad401.dts
new file mode 100644
index 00000000..69c25c6
--- /dev/null
+++ b/arch/arm64/boot/dts/amlogic/meson-a1-ad401.dts
@@ -0,0 +1,30 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2019 Amlogic, Inc. All rights reserved.
+ */
+
+/dts-v1/;
+
+#include "meson-a1.dtsi"
+
+/ {
+ compatible = "amlogic,ad401", "amlogic,a1";
+ model = "Amlogic Meson A1 AD401 Development Board";
+
+ aliases {
+ serial0 = &uart_AO_B;
+ };
+
+ chosen {
+ stdout-path = "serial0:115200n8";
+ };
+
+ memory@0 {
+ device_type = "memory";
+ reg = <0x0 0x0 0x0 0x8000000>;
+ };
+};
+
+&uart_AO_B {
+ status = "okay";
+};
diff --git a/arch/arm64/boot/dts/amlogic/meson-a1.dtsi b/arch/arm64/boot/dts/amlogic/meson-a1.dtsi
new file mode 100644
index 00000000..7210ad0
--- /dev/null
+++ b/arch/arm64/boot/dts/amlogic/meson-a1.dtsi
@@ -0,0 +1,130 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2019 Amlogic, Inc. All rights reserved.
+ */
+
+#include <dt-bindings/interrupt-controller/irq.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+
+/ {
+ compatible = "amlogic,a1";
+
+ interrupt-parent = <&gic>;
+ #address-cells = <2>;
+ #size-cells = <2>;
+
+ cpus {
+ #address-cells = <2>;
+ #size-cells = <0>;
+
+ cpu0: cpu@0 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a35";
+ reg = <0x0 0x0>;
+ enable-method = "psci";
+ next-level-cache = <&l2>;
+ };
+
+ cpu1: cpu@1 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a35";
+ reg = <0x0 0x1>;
+ enable-method = "psci";
+ next-level-cache = <&l2>;
+ };
+
+ l2: l2-cache0 {
+ compatible = "cache";
+ };
+ };
+
+ psci {
+ compatible = "arm,psci-1.0";
+ method = "smc";
+ };
+
+ reserved-memory {
+ #address-cells = <2>;
+ #size-cells = <2>;
+ ranges;
+
+ linux,cma {
+ compatible = "shared-dma-pool";
+ reusable;
+ size = <0x0 0x800000>;
+ alignment = <0x0 0x400000>;
+ linux,cma-default;
+ };
+ };
+
+ sm: secure-monitor {
+ compatible = "amlogic,meson-gxbb-sm";
+ };
+
+ soc {
+ compatible = "simple-bus";
+ #address-cells = <2>;
+ #size-cells = <2>;
+ ranges;
+
+ apb: bus@fe000000 {
+ compatible = "simple-bus";
+ reg = <0x0 0xfe000000 0x0 0x1000000>;
+ #address-cells = <2>;
+ #size-cells = <2>;
+ ranges = <0x0 0x0 0x0 0xfe000000 0x0 0x1000000>;
+
+ uart_AO: serial@1c00 {
+ compatible = "amlogic,meson-gx-uart",
+ "amlogic,meson-ao-uart";
+ reg = <0x0 0x1c00 0x0 0x18>;
+ interrupts = <GIC_SPI 25 IRQ_TYPE_EDGE_RISING>;
+ clocks = <&xtal>, <&xtal>, <&xtal>;
+ clock-names = "xtal", "pclk", "baud";
+ status = "disabled";
+ };
+
+ uart_AO_B: serial@2000 {
+ compatible = "amlogic,meson-gx-uart",
+ "amlogic,meson-ao-uart";
+ reg = <0x0 0x2000 0x0 0x18>;
+ interrupts = <GIC_SPI 26 IRQ_TYPE_EDGE_RISING>;
+ clocks = <&xtal>, <&xtal>, <&xtal>;
+ clock-names = "xtal", "pclk", "baud";
+ status = "disabled";
+ };
+ };
+
+ gic: interrupt-controller@ff901000 {
+ compatible = "arm,gic-400";
+ reg = <0x0 0xff901000 0x0 0x1000>,
+ <0x0 0xff902000 0x0 0x2000>,
+ <0x0 0xff904000 0x0 0x2000>,
+ <0x0 0xff906000 0x0 0x2000>;
+ interrupt-controller;
+ interrupts = <GIC_PPI 9
+ (GIC_CPU_MASK_SIMPLE(8) | IRQ_TYPE_LEVEL_HIGH)>;
+ #interrupt-cells = <3>;
+ #address-cells = <0>;
+ };
+ };
+
+ timer {
+ compatible = "arm,armv8-timer";
+ interrupts = <GIC_PPI 13
+ (GIC_CPU_MASK_RAW(0xff) | IRQ_TYPE_LEVEL_LOW)>,
+ <GIC_PPI 14
+ (GIC_CPU_MASK_RAW(0xff) | IRQ_TYPE_LEVEL_LOW)>,
+ <GIC_PPI 11
+ (GIC_CPU_MASK_RAW(0xff) | IRQ_TYPE_LEVEL_LOW)>,
+ <GIC_PPI 10
+ (GIC_CPU_MASK_RAW(0xff) | IRQ_TYPE_LEVEL_LOW)>;
+ };
+
+ xtal: xtal-clk {
+ compatible = "fixed-clock";
+ clock-frequency = <24000000>;
+ clock-output-names = "xtal";
+ #clock-cells = <0>;
+ };
+};
--
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 3/4] dt-bindings: arm: amlogic: add Amlogic AD401 bindings
From: Jianxin Pan @ 2019-09-12 8:19 UTC (permalink / raw)
To: Kevin Hilman, linux-amlogic
Cc: devicetree, Hanjie Lin, Victor Wan, Jianxin Pan, Neil Armstrong,
Martin Blumenstingl, linux-kernel, Qiufang Dai, Rob Herring,
Jian Hu, Xingyu Chen, Carlo Caione, Tao Zeng, linux-arm-kernel,
Jerome Brunet
In-Reply-To: <1568276370-54181-1-git-send-email-jianxin.pan@amlogic.com>
Add the compatible for the Amlogic A1 Based AD401 board.
Signed-off-by: Jianxin Pan <jianxin.pan@amlogic.com>
Reviewed-by: Rob Herring <robh@kernel.org>
---
Documentation/devicetree/bindings/arm/amlogic.yaml | 2 ++
1 file changed, 2 insertions(+)
diff --git a/Documentation/devicetree/bindings/arm/amlogic.yaml b/Documentation/devicetree/bindings/arm/amlogic.yaml
index 0ef45ac..ee5703c 100644
--- a/Documentation/devicetree/bindings/arm/amlogic.yaml
+++ b/Documentation/devicetree/bindings/arm/amlogic.yaml
@@ -159,5 +159,7 @@ properties:
- description: Boards with the Amlogic Meson A1 A113L SoC
items:
+ - enum:
+ - amlogic,ad401
- const: amlogic,a1
...
--
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 2/4] dt-bindings: arm: amlogic: add A1 bindings
From: Jianxin Pan @ 2019-09-12 8:19 UTC (permalink / raw)
To: Kevin Hilman, linux-amlogic
Cc: devicetree, Hanjie Lin, Victor Wan, Jianxin Pan, Neil Armstrong,
Martin Blumenstingl, linux-kernel, Qiufang Dai, Rob Herring,
Jian Hu, Xingyu Chen, Carlo Caione, Tao Zeng, linux-arm-kernel,
Jerome Brunet
In-Reply-To: <1568276370-54181-1-git-send-email-jianxin.pan@amlogic.com>
Add bindings for the new Amlogic A1 SoC family.
A1 is an application processor designed for smart audio and IoT applications,
with dual core Cortex-A35.
Signed-off-by: Jianxin Pan <jianxin.pan@amlogic.com>
Reviewed-by: Rob Herring <robh@kernel.org>
---
Documentation/devicetree/bindings/arm/amlogic.yaml | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/Documentation/devicetree/bindings/arm/amlogic.yaml b/Documentation/devicetree/bindings/arm/amlogic.yaml
index 99015ce..0ef45ac 100644
--- a/Documentation/devicetree/bindings/arm/amlogic.yaml
+++ b/Documentation/devicetree/bindings/arm/amlogic.yaml
@@ -156,4 +156,8 @@ properties:
- seirobotics,sei610
- khadas,vim3l
- const: amlogic,sm1
+
+ - description: Boards with the Amlogic Meson A1 A113L SoC
+ items:
+ - const: amlogic,a1
...
--
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 1/4] soc: amlogic: meson-gx-socinfo: Add A1 and A113L IDs
From: Jianxin Pan @ 2019-09-12 8:19 UTC (permalink / raw)
To: Kevin Hilman, linux-amlogic
Cc: devicetree, Hanjie Lin, Victor Wan, Jianxin Pan, Neil Armstrong,
Martin Blumenstingl, linux-kernel, Qiufang Dai, Rob Herring,
Jian Hu, Xingyu Chen, Carlo Caione, Tao Zeng, linux-arm-kernel,
Jerome Brunet
In-Reply-To: <1568276370-54181-1-git-send-email-jianxin.pan@amlogic.com>
Add the SoC IDs for the A113L Amlogic A1 SoC.
Signed-off-by: Jianxin Pan <jianxin.pan@amlogic.com>
Reviewed-by: Neil Armstrong <narmstrong@baylibre.com>
---
drivers/soc/amlogic/meson-gx-socinfo.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/drivers/soc/amlogic/meson-gx-socinfo.c b/drivers/soc/amlogic/meson-gx-socinfo.c
index 6d0d04f..3c86d8d 100644
--- a/drivers/soc/amlogic/meson-gx-socinfo.c
+++ b/drivers/soc/amlogic/meson-gx-socinfo.c
@@ -40,6 +40,7 @@ static const struct meson_gx_soc_id {
{ "G12A", 0x28 },
{ "G12B", 0x29 },
{ "SM1", 0x2b },
+ { "A1", 0x2c },
};
static const struct meson_gx_package_id {
@@ -68,6 +69,7 @@ static const struct meson_gx_package_id {
{ "S922X", 0x29, 0x40, 0xf0 },
{ "A311D", 0x29, 0x10, 0xf0 },
{ "S905X3", 0x2b, 0x5, 0xf },
+ { "A113L", 0x2c, 0x0, 0xf8 },
};
static inline unsigned int socinfo_to_major(u32 socinfo)
--
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 0/4] arm64: Add basic support for Amlogic A1 SoC Family
From: Jianxin Pan @ 2019-09-12 8:19 UTC (permalink / raw)
To: Kevin Hilman, linux-amlogic
Cc: devicetree, Hanjie Lin, Victor Wan, Jianxin Pan, Neil Armstrong,
Martin Blumenstingl, linux-kernel, Qiufang Dai, Rob Herring,
Jian Hu, Xingyu Chen, Carlo Caione, Tao Zeng, linux-arm-kernel,
Jerome Brunet
A1 is an application processor designed for smart audio and IoT applications,
with Dual core ARM Cortex-A35 CPU. Unlike the previous GXL and G12 series,
there is no Cortex-M3 AO CPU in it.
This serial add basic support for the Amlogic A1 based Amlogic AD401 board:
which describe components as follows: Reserve Memory, CPU, GIC, IRQ,
Timer, UART. It's capable of booting up into the serial console.
The pclk for uart_AO_B need to be fixed once A1 clock driver is merged.
In this version, it rely on bootloader to enable the pclk gate
Changes since v3 at [2]:
- remove 0x in bus
Changes since v2 at [1]:
- add bus in dts according Martin's suggestion
- remove useless comment line
Changes since v1 at [0]:
- fix coding style
- collect Reviewed-by
[0] https://lore.kernel.org/linux-amlogic/1567493475-75451-1-git-send-email-jianxin.pan@amlogic.com
[1] https://lore.kernel.org/linux-amlogic/1567667251-33466-1-git-send-email-jianxin.pan@amlogic.com
[2] https://lore.kernel.org/linux-amlogic/1568216290-84219-1-git-send-email-jianxin.pan@amlogic.com
Jianxin Pan (4):
soc: amlogic: meson-gx-socinfo: Add A1 and A113L IDs
dt-bindings: arm: amlogic: add A1 bindings
dt-bindings: arm: amlogic: add Amlogic AD401 bindings
arm64: dts: add support for A1 based Amlogic AD401
Documentation/devicetree/bindings/arm/amlogic.yaml | 6 +
arch/arm64/boot/dts/amlogic/Makefile | 1 +
arch/arm64/boot/dts/amlogic/meson-a1-ad401.dts | 30 +++++
arch/arm64/boot/dts/amlogic/meson-a1.dtsi | 130 +++++++++++++++++++++
drivers/soc/amlogic/meson-gx-socinfo.c | 2 +
5 files changed, 169 insertions(+)
create mode 100644 arch/arm64/boot/dts/amlogic/meson-a1-ad401.dts
create mode 100644 arch/arm64/boot/dts/amlogic/meson-a1.dtsi
--
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
* Re: [PATCH] aarch64/mm: speedup memory initialisation
From: Anshuman Khandual @ 2019-09-12 8:12 UTC (permalink / raw)
To: Hubert Ralf, linux-arm-kernel@lists.infradead.org
In-Reply-To: <20190910085822.27072-1-ralf.hubert@preh.de>
On 09/10/2019 02:29 PM, Hubert Ralf wrote:
> On ARM64 memmap_init_zone is used during bootmem_init, which iterates over
> all pages in the memory starting at the lowest address until the highest
> address is reached. On arm64 this ends up in searching a memmory region
> containing for each single page between lowest and highest available
> physicall address.
>
> Having a sparse memory system there may be some big holes in the
> memory map. For each page in this holes a lookup is done, which is
> implemented as a binary search on the available memory blocks.
>
> Adding a memmap_init for aarch64 to do the init only for the available
> memory areas reduces the time needed for initialising memory on startup.
> On a Renesas R-CAR M3 based system with a total hole of 20GB bootmem_init
> execution time is reduced from 378ms to 84ms.
>
> Signed-off-by: Ralf Hubert <ralf.hubert@preh.de>
> ---
> arch/arm64/include/asm/pgtable.h | 7 +++++++
> arch/arm64/mm/init.c | 24 ++++++++++++++++++++++++
> 2 files changed, 31 insertions(+)
>
> diff --git a/arch/arm64/include/asm/pgtable.h b/arch/arm64/include/asm/pgtable.h
> index e09760ece844..8c6eefc08b0b 100644
> --- a/arch/arm64/include/asm/pgtable.h
> +++ b/arch/arm64/include/asm/pgtable.h
> @@ -298,6 +298,13 @@ static inline int pte_same(pte_t pte_a, pte_t pte_b)
> return (lhs == rhs);
> }
>
> +#ifdef CONFIG_SPARSEMEM
> +/* arch mem_map init routine is needed due to holes in a memmap */
> +# define __HAVE_ARCH_MEMMAP_INIT
This is not required any more. Its gone with the following commit which
also made generic memmap_init() an weak function currently overridden
only on ia64.
dfb3ccd00a0 ("mm: make memmap_init a proper function")
> + void memmap_init(unsigned long size, int nid, unsigned long zone,
> + unsigned long start_pfn);
> +#endif /* CONFIG_SPARSEMEM */
> +
> /*
> * Huge pte definitions.
> */
> diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c
> index f3c795278def..206b28310872 100644
> --- a/arch/arm64/mm/init.c
> +++ b/arch/arm64/mm/init.c
> @@ -250,6 +250,30 @@ int pfn_valid(unsigned long pfn)
> }
> EXPORT_SYMBOL(pfn_valid);
>
> +#ifdef CONFIG_SPARSEMEM
> +void __meminit
> +memmap_init(unsigned long size, int nid, unsigned long zone,
> + unsigned long start_pfn)
> +{
> + struct memblock_region *reg;
> +
> + for_each_memblock(memory, reg) {
> + unsigned long start = memblock_region_memory_base_pfn(reg);
> + unsigned long end = memblock_region_memory_end_pfn(reg);
> +
> + if (start < start_pfn)
> + start = start_pfn;
> + if (end > start_pfn + size)
> + end = start_pfn + size;
> +
> + if (start < end) {
> + memmap_init_zone(end - start, nid, zone, start,
> + MEMMAP_EARLY, NULL);
> + }
> + }
> +}
> +#endif /* CONFIG_SPARSEMEM */
In generic mmap_init(), the current high cost comes from early_pfn_valid()
check for each pfn in memmap_init_zone() given that early_pfn_valid() is
pfn_valid() when CONFIG_SPARSEMEM which is known to be expensive on arm64.
Though we cannot do anything about pfns which are really present but the
high cost for non present pfns should be eliminated. The following check
in the above for_each_memblock() loop can achieve that.
if (reg->flags & MEMBLOCK_NOMAP)
continue;
MEMBLOCK_NOMAP universally should not be initialized into a zone and holes
if any should also be universally skipped across platforms. So these changes
can be moved into generic memmap_init() which will benefit other platforms.
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* [PATCH] mfd: mt6360: add pmic mt6360 driver
From: Gene Chen @ 2019-09-12 8:10 UTC (permalink / raw)
To: matthias.bgg, gene_chen, Wilma.Wu
Cc: Gene Chen, linux-mediatek, linux-kernel, linux-arm-kernel
From: Gene Chen <gene_chen@mediatek.corp-partner.google.com>
---
drivers/mfd/Kconfig | 12 ++
drivers/mfd/Makefile | 1 +
drivers/mfd/mt6360-core.c | 463 ++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 476 insertions(+)
create mode 100644 drivers/mfd/mt6360-core.c
diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
index f129f96..a422c76 100644
--- a/drivers/mfd/Kconfig
+++ b/drivers/mfd/Kconfig
@@ -862,6 +862,18 @@ config MFD_MAX8998
additional drivers must be enabled in order to use the functionality
of the device.
+config MFD_MT6360
+ tristate "Mediatek MT6360 SubPMIC"
+ select MFD_CORE
+ select REGMAP_I2C
+ select REGMAP_IRQ
+ depends on I2C
+ help
+ Say Y here to enable MT6360 PMU/PMIC/LDO functional support.
+ PMU part include charger, flashlight, rgb led
+ PMIC part include 2-channel BUCKs and 2-channel LDOs
+ LDO part include 4-channel LDOs
+
config MFD_MT6397
tristate "MediaTek MT6397 PMIC Support"
select MFD_CORE
diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile
index f026ada..77a8f0b 100644
--- a/drivers/mfd/Makefile
+++ b/drivers/mfd/Makefile
@@ -241,6 +241,7 @@ obj-$(CONFIG_INTEL_SOC_PMIC) += intel-soc-pmic.o
obj-$(CONFIG_INTEL_SOC_PMIC_BXTWC) += intel_soc_pmic_bxtwc.o
obj-$(CONFIG_INTEL_SOC_PMIC_CHTWC) += intel_soc_pmic_chtwc.o
obj-$(CONFIG_INTEL_SOC_PMIC_CHTDC_TI) += intel_soc_pmic_chtdc_ti.o
+obj-$(CONFIG_MFD_MT6360) += mt6360-core.o
obj-$(CONFIG_MFD_MT6397) += mt6397-core.o
obj-$(CONFIG_MFD_ALTERA_A10SR) += altera-a10sr.o
diff --git a/drivers/mfd/mt6360-core.c b/drivers/mfd/mt6360-core.c
new file mode 100644
index 0000000..d3580618
--- /dev/null
+++ b/drivers/mfd/mt6360-core.c
@@ -0,0 +1,463 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2019 MediaTek Inc.
+ */
+
+#include <linux/i2c.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/mfd/core.h>
+#include <linux/module.h>
+#include <linux/of_irq.h>
+#include <linux/of_platform.h>
+#include <linux/version.h>
+
+#include <linux/mfd/mt6360.h>
+#include <linux/mfd/mt6360-private.h>
+
+/* reg 0 -> 0 ~ 7 */
+#define MT6360_CHG_TREG_EVT (4)
+#define MT6360_CHG_AICR_EVT (5)
+#define MT6360_CHG_MIVR_EVT (6)
+#define MT6360_PWR_RDY_EVT (7)
+/* REG 1 -> 8 ~ 15 */
+#define MT6360_CHG_BATSYSUV_EVT (9)
+#define MT6360_FLED_CHG_VINOVP_EVT (11)
+#define MT6360_CHG_VSYSUV_EVT (12)
+#define MT6360_CHG_VSYSOV_EVT (13)
+#define MT6360_CHG_VBATOV_EVT (14)
+#define MT6360_CHG_VBUSOV_EVT (15)
+/* REG 2 -> 16 ~ 23 */
+/* REG 3 -> 24 ~ 31 */
+#define MT6360_WD_PMU_DET (25)
+#define MT6360_WD_PMU_DONE (26)
+#define MT6360_CHG_TMRI (27)
+#define MT6360_CHG_ADPBADI (29)
+#define MT6360_CHG_RVPI (30)
+#define MT6360_OTPI (31)
+/* REG 4 -> 32 ~ 39 */
+#define MT6360_CHG_AICCMEASL (32)
+#define MT6360_CHGDET_DONEI (34)
+#define MT6360_WDTMRI (35)
+#define MT6360_SSFINISHI (36)
+#define MT6360_CHG_RECHGI (37)
+#define MT6360_CHG_TERMI (38)
+#define MT6360_CHG_IEOCI (39)
+/* REG 5 -> 40 ~ 47 */
+#define MT6360_PUMPX_DONEI (40)
+#define MT6360_BAT_OVP_ADC_EVT (41)
+#define MT6360_TYPEC_OTP_EVT (42)
+#define MT6360_ADC_WAKEUP_EVT (43)
+#define MT6360_ADC_DONEI (44)
+#define MT6360_BST_BATUVI (45)
+#define MT6360_BST_VBUSOVI (46)
+#define MT6360_BST_OLPI (47)
+/* REG 6 -> 48 ~ 55 */
+#define MT6360_ATTACH_I (48)
+#define MT6360_DETACH_I (49)
+#define MT6360_QC30_STPDONE (51)
+#define MT6360_QC_VBUSDET_DONE (52)
+#define MT6360_HVDCP_DET (53)
+#define MT6360_CHGDETI (54)
+#define MT6360_DCDTI (55)
+/* REG 7 -> 56 ~ 63 */
+#define MT6360_FOD_DONE_EVT (56)
+#define MT6360_FOD_OV_EVT (57)
+#define MT6360_CHRDET_UVP_EVT (58)
+#define MT6360_CHRDET_OVP_EVT (59)
+#define MT6360_CHRDET_EXT_EVT (60)
+#define MT6360_FOD_LR_EVT (61)
+#define MT6360_FOD_HR_EVT (62)
+#define MT6360_FOD_DISCHG_FAIL_EVT (63)
+/* REG 8 -> 64 ~ 71 */
+#define MT6360_USBID_EVT (64)
+#define MT6360_APWDTRST_EVT (65)
+#define MT6360_EN_EVT (66)
+#define MT6360_QONB_RST_EVT (67)
+#define MT6360_MRSTB_EVT (68)
+#define MT6360_OTP_EVT (69)
+#define MT6360_VDDAOV_EVT (70)
+#define MT6360_SYSUV_EVT (71)
+/* REG 9 -> 72 ~ 79 */
+#define MT6360_FLED_STRBPIN_EVT (72)
+#define MT6360_FLED_TORPIN_EVT (73)
+#define MT6360_FLED_TX_EVT (74)
+#define MT6360_FLED_LVF_EVT (75)
+#define MT6360_FLED2_SHORT_EVT (78)
+#define MT6360_FLED1_SHORT_EVT (79)
+/* REG 10 -> 80 ~ 87 */
+#define MT6360_FLED2_STRB_EVT (80)
+#define MT6360_FLED1_STRB_EVT (81)
+#define MT6360_FLED2_STRB_TO_EVT (82)
+#define MT6360_FLED1_STRB_TO_EVT (83)
+#define MT6360_FLED2_TOR_EVT (84)
+#define MT6360_FLED1_TOR_EVT (85)
+/* REG 11 -> 88 ~ 95 */
+/* REG 12 -> 96 ~ 103 */
+#define MT6360_BUCK1_PGB_EVT (96)
+#define MT6360_BUCK1_OC_EVT (100)
+#define MT6360_BUCK1_OV_EVT (101)
+#define MT6360_BUCK1_UV_EVT (102)
+/* REG 13 -> 104 ~ 111 */
+#define MT6360_BUCK2_PGB_EVT (104)
+#define MT6360_BUCK2_OC_EVT (108)
+#define MT6360_BUCK2_OV_EVT (109)
+#define MT6360_BUCK2_UV_EVT (110)
+/* REG 14 -> 112 ~ 119 */
+#define MT6360_LDO1_OC_EVT (113)
+#define MT6360_LDO2_OC_EVT (114)
+#define MT6360_LDO3_OC_EVT (115)
+#define MT6360_LDO5_OC_EVT (117)
+#define MT6360_LDO6_OC_EVT (118)
+#define MT6360_LDO7_OC_EVT (119)
+/* REG 15 -> 120 ~ 127 */
+#define MT6360_LDO1_PGB_EVT (121)
+#define MT6360_LDO2_PGB_EVT (122)
+#define MT6360_LDO3_PGB_EVT (123)
+#define MT6360_LDO5_PGB_EVT (125)
+#define MT6360_LDO6_PGB_EVT (126)
+#define MT6360_LDO7_PGB_EVT (127)
+
+#define MT6360_REGMAP_IRQ_REG(_irq_evt) \
+ REGMAP_IRQ_REG(_irq_evt, (_irq_evt) / 8, BIT((_irq_evt) % 8))
+
+#define MT6360_MFD_CELL(_name) \
+ { \
+ .name = #_name, \
+ .of_compatible = "mediatek," #_name, \
+ .num_resources = ARRAY_SIZE(_name##_resources), \
+ .resources = _name##_resources, \
+ }
+
+static const struct regmap_irq mt6360_pmu_irqs[] = {
+ MT6360_REGMAP_IRQ_REG(MT6360_CHG_TREG_EVT),
+ MT6360_REGMAP_IRQ_REG(MT6360_CHG_AICR_EVT),
+ MT6360_REGMAP_IRQ_REG(MT6360_CHG_MIVR_EVT),
+ MT6360_REGMAP_IRQ_REG(MT6360_PWR_RDY_EVT),
+ MT6360_REGMAP_IRQ_REG(MT6360_CHG_BATSYSUV_EVT),
+ MT6360_REGMAP_IRQ_REG(MT6360_FLED_CHG_VINOVP_EVT),
+ MT6360_REGMAP_IRQ_REG(MT6360_CHG_VSYSUV_EVT),
+ MT6360_REGMAP_IRQ_REG(MT6360_CHG_VSYSOV_EVT),
+ MT6360_REGMAP_IRQ_REG(MT6360_CHG_VBATOV_EVT),
+ MT6360_REGMAP_IRQ_REG(MT6360_CHG_VBUSOV_EVT),
+ MT6360_REGMAP_IRQ_REG(MT6360_WD_PMU_DET),
+ MT6360_REGMAP_IRQ_REG(MT6360_WD_PMU_DONE),
+ MT6360_REGMAP_IRQ_REG(MT6360_CHG_TMRI),
+ MT6360_REGMAP_IRQ_REG(MT6360_CHG_ADPBADI),
+ MT6360_REGMAP_IRQ_REG(MT6360_CHG_RVPI),
+ MT6360_REGMAP_IRQ_REG(MT6360_OTPI),
+ MT6360_REGMAP_IRQ_REG(MT6360_CHG_AICCMEASL),
+ MT6360_REGMAP_IRQ_REG(MT6360_CHGDET_DONEI),
+ MT6360_REGMAP_IRQ_REG(MT6360_WDTMRI),
+ MT6360_REGMAP_IRQ_REG(MT6360_SSFINISHI),
+ MT6360_REGMAP_IRQ_REG(MT6360_CHG_RECHGI),
+ MT6360_REGMAP_IRQ_REG(MT6360_CHG_TERMI),
+ MT6360_REGMAP_IRQ_REG(MT6360_CHG_IEOCI),
+ MT6360_REGMAP_IRQ_REG(MT6360_PUMPX_DONEI),
+ MT6360_REGMAP_IRQ_REG(MT6360_CHG_TREG_EVT),
+ MT6360_REGMAP_IRQ_REG(MT6360_BAT_OVP_ADC_EVT),
+ MT6360_REGMAP_IRQ_REG(MT6360_TYPEC_OTP_EVT),
+ MT6360_REGMAP_IRQ_REG(MT6360_ADC_WAKEUP_EVT),
+ MT6360_REGMAP_IRQ_REG(MT6360_ADC_DONEI),
+ MT6360_REGMAP_IRQ_REG(MT6360_BST_BATUVI),
+ MT6360_REGMAP_IRQ_REG(MT6360_BST_VBUSOVI),
+ MT6360_REGMAP_IRQ_REG(MT6360_BST_OLPI),
+ MT6360_REGMAP_IRQ_REG(MT6360_ATTACH_I),
+ MT6360_REGMAP_IRQ_REG(MT6360_DETACH_I),
+ MT6360_REGMAP_IRQ_REG(MT6360_QC30_STPDONE),
+ MT6360_REGMAP_IRQ_REG(MT6360_QC_VBUSDET_DONE),
+ MT6360_REGMAP_IRQ_REG(MT6360_HVDCP_DET),
+ MT6360_REGMAP_IRQ_REG(MT6360_CHGDETI),
+ MT6360_REGMAP_IRQ_REG(MT6360_DCDTI),
+ MT6360_REGMAP_IRQ_REG(MT6360_FOD_DONE_EVT),
+ MT6360_REGMAP_IRQ_REG(MT6360_FOD_OV_EVT),
+ MT6360_REGMAP_IRQ_REG(MT6360_CHRDET_UVP_EVT),
+ MT6360_REGMAP_IRQ_REG(MT6360_CHRDET_OVP_EVT),
+ MT6360_REGMAP_IRQ_REG(MT6360_CHRDET_EXT_EVT),
+ MT6360_REGMAP_IRQ_REG(MT6360_FOD_LR_EVT),
+ MT6360_REGMAP_IRQ_REG(MT6360_FOD_HR_EVT),
+ MT6360_REGMAP_IRQ_REG(MT6360_FOD_DISCHG_FAIL_EVT),
+ MT6360_REGMAP_IRQ_REG(MT6360_USBID_EVT),
+ MT6360_REGMAP_IRQ_REG(MT6360_APWDTRST_EVT),
+ MT6360_REGMAP_IRQ_REG(MT6360_EN_EVT),
+ MT6360_REGMAP_IRQ_REG(MT6360_QONB_RST_EVT),
+ MT6360_REGMAP_IRQ_REG(MT6360_MRSTB_EVT),
+ MT6360_REGMAP_IRQ_REG(MT6360_OTP_EVT),
+ MT6360_REGMAP_IRQ_REG(MT6360_VDDAOV_EVT),
+ MT6360_REGMAP_IRQ_REG(MT6360_SYSUV_EVT),
+ MT6360_REGMAP_IRQ_REG(MT6360_FLED_STRBPIN_EVT),
+ MT6360_REGMAP_IRQ_REG(MT6360_FLED_TORPIN_EVT),
+ MT6360_REGMAP_IRQ_REG(MT6360_FLED_TX_EVT),
+ MT6360_REGMAP_IRQ_REG(MT6360_FLED_LVF_EVT),
+ MT6360_REGMAP_IRQ_REG(MT6360_FLED2_SHORT_EVT),
+ MT6360_REGMAP_IRQ_REG(MT6360_FLED1_SHORT_EVT),
+ MT6360_REGMAP_IRQ_REG(MT6360_FLED2_STRB_EVT),
+ MT6360_REGMAP_IRQ_REG(MT6360_FLED1_STRB_EVT),
+ MT6360_REGMAP_IRQ_REG(MT6360_FLED2_STRB_TO_EVT),
+ MT6360_REGMAP_IRQ_REG(MT6360_FLED1_STRB_TO_EVT),
+ MT6360_REGMAP_IRQ_REG(MT6360_FLED2_TOR_EVT),
+ MT6360_REGMAP_IRQ_REG(MT6360_FLED1_TOR_EVT),
+ MT6360_REGMAP_IRQ_REG(MT6360_BUCK1_PGB_EVT),
+ MT6360_REGMAP_IRQ_REG(MT6360_BUCK1_OC_EVT),
+ MT6360_REGMAP_IRQ_REG(MT6360_BUCK1_OV_EVT),
+ MT6360_REGMAP_IRQ_REG(MT6360_BUCK1_UV_EVT),
+ MT6360_REGMAP_IRQ_REG(MT6360_BUCK2_PGB_EVT),
+ MT6360_REGMAP_IRQ_REG(MT6360_BUCK2_OC_EVT),
+ MT6360_REGMAP_IRQ_REG(MT6360_BUCK2_OV_EVT),
+ MT6360_REGMAP_IRQ_REG(MT6360_BUCK2_UV_EVT),
+ MT6360_REGMAP_IRQ_REG(MT6360_LDO1_OC_EVT),
+ MT6360_REGMAP_IRQ_REG(MT6360_LDO2_OC_EVT),
+ MT6360_REGMAP_IRQ_REG(MT6360_LDO3_OC_EVT),
+ MT6360_REGMAP_IRQ_REG(MT6360_LDO5_OC_EVT),
+ MT6360_REGMAP_IRQ_REG(MT6360_LDO6_OC_EVT),
+ MT6360_REGMAP_IRQ_REG(MT6360_LDO7_OC_EVT),
+ MT6360_REGMAP_IRQ_REG(MT6360_LDO1_PGB_EVT),
+ MT6360_REGMAP_IRQ_REG(MT6360_LDO2_PGB_EVT),
+ MT6360_REGMAP_IRQ_REG(MT6360_LDO3_PGB_EVT),
+ MT6360_REGMAP_IRQ_REG(MT6360_LDO5_PGB_EVT),
+ MT6360_REGMAP_IRQ_REG(MT6360_LDO6_PGB_EVT),
+ MT6360_REGMAP_IRQ_REG(MT6360_LDO7_PGB_EVT),
+};
+
+static int mt6360_pmu_handle_post_irq(void *irq_drv_data)
+{
+ struct mt6360_pmu_info *mpi = irq_drv_data;
+
+ return regmap_update_bits(mpi->regmap,
+ MT6360_PMU_IRQ_SET, MT6360_IRQ_RETRIG, MT6360_IRQ_RETRIG);
+}
+
+static const struct regmap_irq_chip mt6360_pmu_irq_chip = {
+ .irqs = mt6360_pmu_irqs,
+ .num_irqs = ARRAY_SIZE(mt6360_pmu_irqs),
+ .num_regs = MT6360_PMU_IRQ_REGNUM,
+ .mask_base = MT6360_PMU_CHG_MASK1,
+ .status_base = MT6360_PMU_CHG_IRQ1,
+ .ack_base = MT6360_PMU_CHG_IRQ1,
+ .init_ack_masked = true,
+ .use_ack = true,
+ .handle_post_irq = mt6360_pmu_handle_post_irq,
+};
+
+static const struct regmap_config mt6360_pmu_regmap_config = {
+ .reg_bits = 8,
+ .val_bits = 8,
+ .max_register = MT6360_PMU_MAXREG,
+};
+
+static const struct resource mt6360_adc_resources[] = {
+ DEFINE_RES_IRQ_NAMED(MT6360_ADC_DONEI, "adc_donei"),
+};
+
+static const struct resource mt6360_chg_resources[] = {
+ DEFINE_RES_IRQ_NAMED(MT6360_CHG_TREG_EVT, "chg_treg_evt"),
+ DEFINE_RES_IRQ_NAMED(MT6360_PWR_RDY_EVT, "pwr_rdy_evt"),
+ DEFINE_RES_IRQ_NAMED(MT6360_CHG_BATSYSUV_EVT, "chg_batsysuv_evt"),
+ DEFINE_RES_IRQ_NAMED(MT6360_CHG_VSYSUV_EVT, "chg_vsysuv_evt"),
+ DEFINE_RES_IRQ_NAMED(MT6360_CHG_VSYSOV_EVT, "chg_vsysov_evt"),
+ DEFINE_RES_IRQ_NAMED(MT6360_CHG_VBATOV_EVT, "chg_vbatov_evt"),
+ DEFINE_RES_IRQ_NAMED(MT6360_CHG_VBUSOV_EVT, "chg_vbusov_evt"),
+ DEFINE_RES_IRQ_NAMED(MT6360_CHG_AICCMEASL, "chg_aiccmeasl"),
+ DEFINE_RES_IRQ_NAMED(MT6360_WDTMRI, "wdtmri"),
+ DEFINE_RES_IRQ_NAMED(MT6360_CHG_RECHGI, "chg_rechgi"),
+ DEFINE_RES_IRQ_NAMED(MT6360_CHG_TERMI, "chg_termi"),
+ DEFINE_RES_IRQ_NAMED(MT6360_CHG_IEOCI, "chg_ieoci"),
+ DEFINE_RES_IRQ_NAMED(MT6360_PUMPX_DONEI, "pumpx_donei"),
+ DEFINE_RES_IRQ_NAMED(MT6360_ATTACH_I, "attach_i"),
+ DEFINE_RES_IRQ_NAMED(MT6360_CHRDET_EXT_EVT, "chrdet_ext_evt"),
+};
+
+static const struct resource mt6360_led_resources[] = {
+ DEFINE_RES_IRQ_NAMED(MT6360_FLED_CHG_VINOVP_EVT, "fled_chg_vinovp_evt"),
+ DEFINE_RES_IRQ_NAMED(MT6360_FLED_LVF_EVT, "fled_lvf_evt"),
+ DEFINE_RES_IRQ_NAMED(MT6360_FLED2_SHORT_EVT, "fled2_short_evt"),
+ DEFINE_RES_IRQ_NAMED(MT6360_FLED1_SHORT_EVT, "fled1_short_evt"),
+ DEFINE_RES_IRQ_NAMED(MT6360_FLED2_STRB_TO_EVT, "fled2_strb_to_evt"),
+ DEFINE_RES_IRQ_NAMED(MT6360_FLED1_STRB_TO_EVT, "fled1_strb_to_evt"),
+};
+
+static const struct resource mt6360_pmic_resources[] = {
+ DEFINE_RES_IRQ_NAMED(MT6360_BUCK1_PGB_EVT, "buck1_pgb_evt"),
+ DEFINE_RES_IRQ_NAMED(MT6360_BUCK1_OC_EVT, "buck1_oc_evt"),
+ DEFINE_RES_IRQ_NAMED(MT6360_BUCK1_OV_EVT, "buck1_ov_evt"),
+ DEFINE_RES_IRQ_NAMED(MT6360_BUCK1_UV_EVT, "buck1_uv_evt"),
+ DEFINE_RES_IRQ_NAMED(MT6360_BUCK2_PGB_EVT, "buck2_pgb_evt"),
+ DEFINE_RES_IRQ_NAMED(MT6360_BUCK2_OC_EVT, "buck2_oc_evt"),
+ DEFINE_RES_IRQ_NAMED(MT6360_BUCK2_OV_EVT, "buck2_ov_evt"),
+ DEFINE_RES_IRQ_NAMED(MT6360_BUCK2_UV_EVT, "buck2_uv_evt"),
+ DEFINE_RES_IRQ_NAMED(MT6360_LDO6_OC_EVT, "ldo6_oc_evt"),
+ DEFINE_RES_IRQ_NAMED(MT6360_LDO7_OC_EVT, "ldo7_oc_evt"),
+ DEFINE_RES_IRQ_NAMED(MT6360_LDO6_PGB_EVT, "ldo6_pgb_evt"),
+ DEFINE_RES_IRQ_NAMED(MT6360_LDO7_PGB_EVT, "ldo7_pgb_evt"),
+};
+
+static const struct resource mt6360_ldo_resources[] = {
+ DEFINE_RES_IRQ_NAMED(MT6360_LDO1_OC_EVT, "ldo1_oc_evt"),
+ DEFINE_RES_IRQ_NAMED(MT6360_LDO2_OC_EVT, "ldo2_oc_evt"),
+ DEFINE_RES_IRQ_NAMED(MT6360_LDO3_OC_EVT, "ldo3_oc_evt"),
+ DEFINE_RES_IRQ_NAMED(MT6360_LDO5_OC_EVT, "ldo5_oc_evt"),
+ DEFINE_RES_IRQ_NAMED(MT6360_LDO1_PGB_EVT, "ldo1_pgb_evt"),
+ DEFINE_RES_IRQ_NAMED(MT6360_LDO2_PGB_EVT, "ldo2_pgb_evt"),
+ DEFINE_RES_IRQ_NAMED(MT6360_LDO3_PGB_EVT, "ldo3_pgb_evt"),
+ DEFINE_RES_IRQ_NAMED(MT6360_LDO5_PGB_EVT, "ldo5_pgb_evt"),
+};
+
+static const struct mfd_cell mt6360_devs[] = {
+ MT6360_MFD_CELL(mt6360_adc),
+ MT6360_MFD_CELL(mt6360_chg),
+ MT6360_MFD_CELL(mt6360_led),
+ MT6360_MFD_CELL(mt6360_pmic),
+ MT6360_MFD_CELL(mt6360_ldo),
+ /* tcpc dev */
+ {
+ .name = "mt6360_tcpc",
+ .of_compatible = "mediatek,mt6360_tcpc",
+ },
+};
+
+static const unsigned short mt6360_slave_addr[MT6360_SLAVE_MAX] = {
+ MT6360_PMU_SLAVEID,
+ MT6360_PMIC_SLAVEID,
+ MT6360_LDO_SLAVEID,
+ MT6360_TCPC_SLAVEID,
+};
+
+static int mt6360_pmu_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
+{
+ struct mt6360_pmu_info *mpi;
+ unsigned int reg_data = 0;
+ int i, ret;
+
+ mpi = devm_kzalloc(&client->dev, sizeof(*mpi), GFP_KERNEL);
+ if (!mpi)
+ return -ENOMEM;
+ mpi->dev = &client->dev;
+ i2c_set_clientdata(client, mpi);
+
+ /* regmap regiser */
+ mpi->regmap = devm_regmap_init_i2c(client, &mt6360_pmu_regmap_config);
+ if (IS_ERR(mpi->regmap)) {
+ dev_err(&client->dev, "regmap register fail\n");
+ return PTR_ERR(mpi->regmap);
+ }
+ /* chip id check */
+ ret = regmap_read(mpi->regmap, MT6360_PMU_DEV_INFO, ®_data);
+ if (ret < 0) {
+ dev_err(&client->dev, "device not found\n");
+ return ret;
+ }
+ if ((reg_data & CHIP_VEN_MASK) != CHIP_VEN_MT6360) {
+ dev_err(&client->dev, "not mt6360 chip\n");
+ return -ENODEV;
+ }
+ mpi->chip_rev = reg_data & CHIP_REV_MASK;
+ /* irq register */
+ memcpy(&mpi->irq_chip, &mt6360_pmu_irq_chip, sizeof(mpi->irq_chip));
+ mpi->irq_chip.name = dev_name(&client->dev);
+ mpi->irq_chip.irq_drv_data = mpi;
+ ret = devm_regmap_add_irq_chip(&client->dev, mpi->regmap, client->irq,
+ IRQF_TRIGGER_FALLING, 0, &mpi->irq_chip,
+ &mpi->irq_data);
+ if (ret < 0) {
+ dev_err(&client->dev, "regmap irq chip add fail\n");
+ return ret;
+ }
+ /* new i2c slave device */
+ for (i = 0; i < MT6360_SLAVE_MAX; i++) {
+ if (mt6360_slave_addr[i] == client->addr) {
+ mpi->i2c[i] = client;
+ continue;
+ }
+ mpi->i2c[i] = i2c_new_dummy(client->adapter,
+ mt6360_slave_addr[i]);
+ if (!mpi->i2c[i]) {
+ dev_err(&client->dev, "new i2c dev [%d] fail\n", i);
+ ret = -ENODEV;
+ goto out;
+ }
+ i2c_set_clientdata(mpi->i2c[i], mpi);
+ }
+ /* mfd cell register */
+ ret = devm_mfd_add_devices(&client->dev, PLATFORM_DEVID_AUTO,
+ mt6360_devs, ARRAY_SIZE(mt6360_devs), NULL,
+ 0, regmap_irq_get_domain(mpi->irq_data));
+ if (ret < 0) {
+ dev_err(&client->dev, "mfd add cells fail\n");
+ goto out;
+ }
+ dev_info(&client->dev, "Successfully probed\n");
+ return 0;
+out:
+ while (--i >= 0) {
+ if (mpi->i2c[i]->addr == client->addr)
+ continue;
+ i2c_unregister_device(mpi->i2c[i]);
+ }
+ return ret;
+}
+
+static int mt6360_pmu_remove(struct i2c_client *client)
+{
+ struct mt6360_pmu_info *mpi = i2c_get_clientdata(client);
+ int i;
+
+ for (i = 0; i < MT6360_SLAVE_MAX; i++) {
+ if (mpi->i2c[i]->addr == client->addr)
+ continue;
+ i2c_unregister_device(mpi->i2c[i]);
+ }
+ return 0;
+}
+
+static int __maybe_unused mt6360_pmu_suspend(struct device *dev)
+{
+ struct i2c_client *i2c = to_i2c_client(dev);
+
+ if (device_may_wakeup(dev))
+ enable_irq_wake(i2c->irq);
+ return 0;
+}
+
+static int __maybe_unused mt6360_pmu_resume(struct device *dev)
+{
+
+ struct i2c_client *i2c = to_i2c_client(dev);
+
+ if (device_may_wakeup(dev))
+ disable_irq_wake(i2c->irq);
+ return 0;
+}
+
+static SIMPLE_DEV_PM_OPS(mt6360_pmu_pm_ops,
+ mt6360_pmu_suspend, mt6360_pmu_resume);
+
+static const struct of_device_id __maybe_unused mt6360_pmu_of_id[] = {
+ { .compatible = "mediatek,mt6360_pmu", },
+ {},
+};
+MODULE_DEVICE_TABLE(of, mt6360_pmu_of_id);
+
+static const struct i2c_device_id mt6360_pmu_id[] = {
+ { "mt6360_pmu", 0 },
+ {},
+};
+MODULE_DEVICE_TABLE(i2c, mt6360_pmu_id);
+
+static struct i2c_driver mt6360_pmu_driver = {
+ .driver = {
+ .name = "mt6360_pmu",
+ .owner = THIS_MODULE,
+ .pm = &mt6360_pmu_pm_ops,
+ .of_match_table = of_match_ptr(mt6360_pmu_of_id),
+ },
+ .probe = mt6360_pmu_probe,
+ .remove = mt6360_pmu_remove,
+ .id_table = mt6360_pmu_id,
+};
+module_i2c_driver(mt6360_pmu_driver);
+
+MODULE_AUTHOR("CY_Huang <cy_huang@richtek.com>");
+MODULE_DESCRIPTION("MT6360 PMU I2C Driver");
+MODULE_LICENSE("GPL");
+MODULE_VERSION("1.0.0");
--
1.9.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
* Re: offline CPUs shown in sysfs core_siblings mask
From: Brice Goglin @ 2019-09-12 8:09 UTC (permalink / raw)
To: James Morse; +Cc: Jeremy Linton, linux-arm-kernel
In-Reply-To: <4568af7d-724e-5ee7-3ba1-87a5db662447@arm.com>
Le 11/09/2019 à 18:06, James Morse a écrit :
> On 9/11/19 2:23 PM, Brice Goglin wrote:
>> We have a report from a user of hwloc/lstopo on ThunderX2 that complains
>> that offline CPUs are shown in sysfs cpu core_siblings files.
>
> Hmmm, this doesn't happen on my TX2, running mainline:
> root@eglon:/sys/devices/system/cpu# cat cpu1/topology/core_siblings
> 00000000,00000000,00000000,00000000,ffffffff,ffffffff,ffffffff,ffffffff
> root@eglon:/sys/devices/system/cpu# echo 0 > cpu0/online
> root@eglon:/sys/devices/system/cpu# cat cpu1/topology/core_siblings
> 00000000,00000000,00000000,00000000,ffffffff,ffffffff,ffffffff,fffffffe
> root@eglon:/sys/devices/system/cpu# echo 1 > cpu0/online
> root@eglon:/sys/devices/system/cpu# cat cpu1/topology/core_siblings
> 00000000,00000000,00000000,00000000,ffffffff,ffffffff,ffffffff,ffffffff
>
>
>> Only 8 online logicial CPUs, but 56 are shown in these masks. This is on
>> RHEL7 with a kernel 4.14.0-115.2.2.el7a.aarch64 but I couldn't find any
>> significant change in Linux git.
>
> Could you try a recent mainline kernel?
>
> Does your system have an ACPI PPTT table? (I assume its ACPI)
>
> Prior to the ACPI PPTT table handling, it wasn't possible for an arm64
> ACPI system to know about packages and threads.
>
Yes the machine has an ACPI PPTT table. I am working with admins to
verify that recent kernels with 7f9545aa1a91 work better.
Thanks
Brice
_______________________________________________
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 v9 0/8] stg mail -e --version=v9 \
From: David Hildenbrand @ 2019-09-12 7:47 UTC (permalink / raw)
To: Michal Hocko
Cc: Yang Zhang, Pankaj Gupta, kvm list, Michael S. Tsirkin,
Catalin Marinas, Alexander Duyck, lcapitulino, linux-mm,
Alexander Duyck, will, Andrea Arcangeli, virtio-dev, Rik van Riel,
Matthew Wilcox, Wang, Wei W, ying.huang, Konrad Rzeszutek Wilk,
Dan Williams, linux-arm-kernel, Oscar Salvador,
Nitesh Narayan Lal, Dave Hansen, LKML, Paolo Bonzini,
Andrew Morton, Fengguang Wu, Kirill A. Shutemov
In-Reply-To: <20190912071633.GL4023@dhcp22.suse.cz>
On 12.09.19 09:16, Michal Hocko wrote:
> On Wed 11-09-19 18:09:18, David Hildenbrand wrote:
>> On 11.09.19 15:51, Michal Hocko wrote:
>>> On Wed 11-09-19 15:20:02, Michal Hocko wrote:
>>> [...]
>>>>> 4. Continuously report, not the "one time report everything" approach.
>>>>
>>>> So you mean the allocator reporting this rather than an external code to
>>>> poll right? I do not know, how much this is nice to have than must have?
>>>
>>> Another idea that I haven't really thought through so it might turned
>>> out to be completely bogus but let's try anyway. Your "report everything"
>>> just made me look and realize that free_pages_prepare already performs
>>> stuff that actually does something similar yet unrelated.
>>>
>>> We do report to special page poisoning, zeroying or
>>> CONFIG_DEBUG_PAGEALLOC to unmap the address from the kernel address
>>> space. This sounds like something fitting your model no?
>>>
>>
>> AFAIKS, the poisoning/unmapping is done whenever a page is freed. I
>> don't quite see yet how that would help to remember if a page was
>> already reported.
>
> Do you still have to differ that state when each page is reported?
Ah, very good point. I can see that the reason for this was not
discussed in this thread so far. (Alexander, Nitesh, please correct me
if I am wrong). It's buried in the long history of free page
hinting/reporting.
Some early patch sets tried to report during every free synchronously.
Free a page, report them to the hypervisor. This resulted in some issues
(especially, locking-related and the virtio + the hypervisor being
involved, resulting in unpredictable delays, quite some overhead ...).
It was no good.
One design decision then was to not report single pages, but a bunch of
pages at once. This made it necessary to "remember" the pages to be
reported and to temporarily block them from getting allocated while
reporting.
Nitesh implemented (at least) two "capture PFNs of free pages in an
array when freeing" approaches. One being synchronous from the freeing
CPU once the list was full (having similar issues as plain synchronous
reporting) and one being asynchronous by a separate thread (which solved
many locking issues).
Turned out the a simple array can quickly lead to us having to drop
"reports" to the hypervisor because the array is full and the reporting
thread was not able to keep up. Not good as well. Especially, if some
process frees a lot of memory this can happen quickly and Nitesh wa
sable to trigger this scenario frequently.
Finally, Nitesh decided to use the bitmap instead to keep track of pages
to report. I'd like to note that this approach could still be combined
with an "array of potentially free PFNs". Only when the array/circular
buffer runs out of entries ("reporting thread cannot keep up"), we would
have to go back to scanning the bitmap.
That was also the point where Alexander decided to look into integrating
tracking/handling reported/unreported pages directly in the buddy.
>
>> After reporting the page we would have to switch some
>> state (Nitesh: bitmap bit, Alexander: page flag) to identify that.
>
> Yes, you can either store the state somewhere.
>
>> Of course, we could map the page and treat that as "the state" when we
>> reported it, but I am not sure that's such a good idea :)
>>
>> As always, I might be very wrong ...
>
> I still do not fully understand the usecase so I might be equally wrong.
> My thinking is along these lines. Why should you scan free pages when
> you can effectively capture each freed page? If you go one step further
> then post_alloc_hook would be the counterpart to know that your page has
> been allocated.
I'd like to note that Nitesh's patch set contains the following hunk,
which is roughly what you were thinking :)
-static inline void __free_one_page(struct page *page,
+inline void __free_one_page(struct page *page,
unsigned long pfn,
struct zone *zone, unsigned int order,
- int migratetype)
+ int migratetype, bool hint)
{
unsigned long combined_pfn;
unsigned long uninitialized_var(buddy_pfn);
@@ -980,7 +981,8 @@ static inline void __free_one_page(struct page *page,
migratetype);
else
add_to_free_area(page, &zone->free_area[order], migratetype);
-
+ if (hint)
+ page_hinting_enqueue(page, order);
}
(ignore the hint parameter, when he would switch to a isolate vs.
alloc/free, that can go away and all we left is the enqueue part)
Inside that callback we can remember the pages any way we want. Right
now in a bitmap. Maybe later in a array + bitmap (as discussed above).
Another idea I had was to simply go over all pages and report them when
running into this "array full" condition. But I am not yet sure about
the performance implications on rather large machines. So the bitmap
idea might have some other limitations but seems to do its job.
Hoe that makes things clearer and am not missing something.
--
Thanks,
David / dhildenb
_______________________________________________
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 v1 1/2] iommu: pass cell_count = -1 to of_for_each_phandle with cells_name
From: Uwe Kleine-König @ 2019-09-12 7:43 UTC (permalink / raw)
To: Joerg Roedel
Cc: devicetree, Will Deacon, Robin Murphy, linux-kernel, iommu,
Rob Herring, linux-mediatek, kernel, Matthias Brugger,
Frank Rowand, linux-arm-kernel
In-Reply-To: <20190903125210.GB11530@8bytes.org>
On Tue, Sep 03, 2019 at 02:52:10PM +0200, Joerg Roedel wrote:
> On Sat, Aug 24, 2019 at 03:28:45PM +0200, Uwe Kleine-König wrote:
> > Currently of_for_each_phandle ignores the cell_count parameter when a
> > cells_name is given. I intend to change that and let the iterator fall
> > back to a non-negative cell_count if the cells_name property is missing
> > in the referenced node.
> >
> > To not change how existing of_for_each_phandle's users iterate, fix them
> > to pass cell_count = -1 when also cells_name is given which yields the
> > expected behaviour with and without my change.
> >
> > Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
> > ---
> > drivers/iommu/arm-smmu.c | 2 +-
> > drivers/iommu/mtk_iommu_v1.c | 2 +-
> > 2 files changed, 2 insertions(+), 2 deletions(-)
>
> Acked-by: Joerg Roedel <jroedel@suse.de>
Does this ack mean that Rob is expected to apply this together with
patch 2?
Best regards
Uwe
--
Pengutronix e.K. | Uwe Kleine-König |
Industrial Linux Solutions | http://www.pengutronix.de/ |
_______________________________________________
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 v9 0/8] stg mail -e --version=v9 \
From: Michal Hocko @ 2019-09-12 7:16 UTC (permalink / raw)
To: David Hildenbrand
Cc: Yang Zhang, Pankaj Gupta, kvm list, Michael S. Tsirkin,
Catalin Marinas, Alexander Duyck, lcapitulino, linux-mm,
Alexander Duyck, will, Andrea Arcangeli, virtio-dev, Rik van Riel,
Matthew Wilcox, Wang, Wei W, ying.huang, Konrad Rzeszutek Wilk,
Dan Williams, linux-arm-kernel, Oscar Salvador,
Nitesh Narayan Lal, Dave Hansen, LKML, Paolo Bonzini,
Andrew Morton, Fengguang Wu, Kirill A. Shutemov
In-Reply-To: <abea20a0-463c-68c0-e810-2e341d971b30@redhat.com>
On Wed 11-09-19 18:09:18, David Hildenbrand wrote:
> On 11.09.19 15:51, Michal Hocko wrote:
> > On Wed 11-09-19 15:20:02, Michal Hocko wrote:
> > [...]
> >>> 4. Continuously report, not the "one time report everything" approach.
> >>
> >> So you mean the allocator reporting this rather than an external code to
> >> poll right? I do not know, how much this is nice to have than must have?
> >
> > Another idea that I haven't really thought through so it might turned
> > out to be completely bogus but let's try anyway. Your "report everything"
> > just made me look and realize that free_pages_prepare already performs
> > stuff that actually does something similar yet unrelated.
> >
> > We do report to special page poisoning, zeroying or
> > CONFIG_DEBUG_PAGEALLOC to unmap the address from the kernel address
> > space. This sounds like something fitting your model no?
> >
>
> AFAIKS, the poisoning/unmapping is done whenever a page is freed. I
> don't quite see yet how that would help to remember if a page was
> already reported.
Do you still have to differ that state when each page is reported?
> After reporting the page we would have to switch some
> state (Nitesh: bitmap bit, Alexander: page flag) to identify that.
Yes, you can either store the state somewhere.
> Of course, we could map the page and treat that as "the state" when we
> reported it, but I am not sure that's such a good idea :)
>
> As always, I might be very wrong ...
I still do not fully understand the usecase so I might be equally wrong.
My thinking is along these lines. Why should you scan free pages when
you can effectively capture each freed page? If you go one step further
then post_alloc_hook would be the counterpart to know that your page has
been allocated.
--
Michal Hocko
SUSE Labs
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* Re: [GIT PULL 1/2] arm64: dts: exynos: Pull for v5.4
From: Marek Szyprowski @ 2019-09-12 6:56 UTC (permalink / raw)
To: Krzysztof Kozlowski, Arnd Bergmann
Cc: DTML, moderated list:ARM/SAMSUNG EXYNOS ARM ARCHITECTURES,
linux-kernel@vger.kernel.org, SoC Team, arm-soc, Kukjin Kim,
Olof Johansson, Linux ARM
In-Reply-To: <CAJKOXPcOSvc2DfoN+7Tca=t5dSm3RcKqmm06AfR0PAVBeY=GvQ@mail.gmail.com>
Hi
On 2019-09-12 08:32, Krzysztof Kozlowski wrote:
> On Wed, 11 Sep 2019 at 23:07, Arnd Bergmann <arnd@arndb.de> wrote:
>> On Wed, Sep 11, 2019 at 8:36 PM Krzysztof Kozlowski <krzk@kernel.org> wrote:
>>> Hi,
>>>
>>> Unfortunately the patches were applied right after closing the linux-next.
>> Hi Krzysztof,
>>
>> I took a look at these and am not convinced this is right:
>>
>>> 1. Fix boot of Exynos7 due to wrong address/size of memory node,
>> The current state is clearly broken and a fix is needed, but
>> I'm not sure this is the right fix. Why do you have 32-bit physical
>> addressing on a 64-bit chip? I looked at commit ef72171b3621
>> that introduced it, and it seems it would be better to just
>> revert back to 64-bit addresses.
> We discussed with Marek Szyprowski that either we can go back to
> 64-bit addressing or stick to 32. There are not known boards with more
> than 4 GB of RAM so from this point of view the choice was irrelevant.
> At the end of discussion I mentioned to stick with other arm64 boards
> (although not all), so revert to have 64 bit address... but Marek
> chosen differently. Since you ask, let's go back with revert.
I decided to go with 32bit version to make the fix smaller and easier to
backport. If you select revert, make sure that it is applied after
moving gpu node under /soc, otherwise the gpu node will have incorrect
(32bit) reg property. Also add the gpu related patch as an (optional?)
prerequisite for it.
>> 2. Move GPU under /soc node,
>> No problem
>>
>>> 3. Minor cleanup of #address-cells.
>> IIRC, an interrupt-controller is required to have a #address-cells
>> property, even if that is normally zero. I don't remember the
>> details, but the gic binding lists it as mandatory, and I think
>> the PCI interrupt-map relies on it. I would just drop this patch.
> Indeed, binding requires both address and size cells. I'll drop it.
Ookay, I wasn't aware of that.
Best regards
--
Marek Szyprowski, PhD
Samsung R&D Institute Poland
_______________________________________________
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 2/2] crypto: sun4i-ss: enable pm_runtime
From: Maxime Ripard @ 2019-09-12 6:35 UTC (permalink / raw)
To: Corentin Labbe
Cc: herbert, linux-sunxi, linux-kernel, Maxime Ripard, Chen-Yu Tsai,
linux-crypto, davem, linux-arm-kernel
In-Reply-To: <20190911114650.20567-3-clabbe.montjoie@gmail.com>
Hi,
Le mer. 11 sept. 2019 à 13:46, Corentin Labbe
<clabbe.montjoie@gmail.com> a écrit :
>
> This patch enables power management on the Security System.
>
> Signed-off-by: Corentin Labbe <clabbe.montjoie@gmail.com>
> ---
> drivers/crypto/sunxi-ss/sun4i-ss-cipher.c | 5 +++
> drivers/crypto/sunxi-ss/sun4i-ss-core.c | 42 ++++++++++++++++++++++-
> 2 files changed, 46 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/crypto/sunxi-ss/sun4i-ss-cipher.c b/drivers/crypto/sunxi-ss/sun4i-ss-cipher.c
> index fa4b1b47822e..1fedec9e83b0 100644
> --- a/drivers/crypto/sunxi-ss/sun4i-ss-cipher.c
> +++ b/drivers/crypto/sunxi-ss/sun4i-ss-cipher.c
> @@ -10,6 +10,8 @@
> *
> * You could find the datasheet in Documentation/arm/sunxi.rst
> */
> +
> +#include <linux/pm_runtime.h>
> #include "sun4i-ss.h"
>
> static int noinline_for_stack sun4i_ss_opti_poll(struct skcipher_request *areq)
> @@ -497,13 +499,16 @@ int sun4i_ss_cipher_init(struct crypto_tfm *tfm)
> return PTR_ERR(op->fallback_tfm);
> }
>
> + pm_runtime_get_sync(op->ss->dev);
> return 0;
> }
>
> void sun4i_ss_cipher_exit(struct crypto_tfm *tfm)
> {
> struct sun4i_tfm_ctx *op = crypto_tfm_ctx(tfm);
> +
> crypto_free_sync_skcipher(op->fallback_tfm);
> + pm_runtime_put_sync(op->ss->dev);
> }
>
> /* check and set the AES key, prepare the mode to be used */
> diff --git a/drivers/crypto/sunxi-ss/sun4i-ss-core.c b/drivers/crypto/sunxi-ss/sun4i-ss-core.c
> index 2c9ff01dddfc..5e6e1a308f60 100644
> --- a/drivers/crypto/sunxi-ss/sun4i-ss-core.c
> +++ b/drivers/crypto/sunxi-ss/sun4i-ss-core.c
> @@ -14,6 +14,7 @@
> #include <linux/module.h>
> #include <linux/of.h>
> #include <linux/platform_device.h>
> +#include <linux/pm_runtime.h>
> #include <crypto/scatterwalk.h>
> #include <linux/scatterlist.h>
> #include <linux/interrupt.h>
> @@ -258,6 +259,37 @@ static int sun4i_ss_enable(struct sun4i_ss_ctx *ss)
> return err;
> }
>
> +#ifdef CONFIG_PM
> +static int sun4i_ss_pm_suspend(struct device *dev)
> +{
> + struct sun4i_ss_ctx *ss = dev_get_drvdata(dev);
> +
> + sun4i_ss_disable(ss);
> + return 0;
> +}
> +
> +static int sun4i_ss_pm_resume(struct device *dev)
> +{
> + struct sun4i_ss_ctx *ss = dev_get_drvdata(dev);
> +
> + return sun4i_ss_enable(ss);
> +}
> +#endif
> +
> +const struct dev_pm_ops sun4i_ss_pm_ops = {
> + SET_RUNTIME_PM_OPS(sun4i_ss_pm_suspend, sun4i_ss_pm_resume, NULL)
> +};
> +
> +static void sun4i_ss_pm_init(struct sun4i_ss_ctx *ss)
> +{
> + pm_runtime_use_autosuspend(ss->dev);
> + pm_runtime_set_autosuspend_delay(ss->dev, 1000);
> +
> + pm_runtime_get_noresume(ss->dev);
> + pm_runtime_set_active(ss->dev);
> + pm_runtime_enable(ss->dev);
> +}
It's not really clear to me what you're doing here? Can you explain?
The rest looks fine.
Maxime
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* [PATCH v2 3/3] scsi: ufs-mediatek: enable auto suspend capability
From: Stanley Chu @ 2019-09-12 6:35 UTC (permalink / raw)
To: linux-scsi, martin.petersen, avri.altman, alim.akhtar,
pedrom.sousa, sthumma, jejb, bvanassche
Cc: marc.w.gonzalez, andy.teng, chun-hung.wu, kuohong.wang, evgreen,
subhashj, linux-mediatek, peter.wang, vivek.gautam, matthias.bgg,
Stanley Chu, linux-arm-kernel, beanhuo
In-Reply-To: <1568270135-32442-1-git-send-email-stanley.chu@mediatek.com>
Enable auto suspend capability in MediaTek UFS driver.
Signed-off-by: Stanley Chu <stanley.chu@mediatek.com>
Reviewed-by: Avri Altman <avri.altman@wdc.com>
---
drivers/scsi/ufs/ufs-mediatek.c | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/drivers/scsi/ufs/ufs-mediatek.c b/drivers/scsi/ufs/ufs-mediatek.c
index 0f6ff33ce52e..b7b177c6194c 100644
--- a/drivers/scsi/ufs/ufs-mediatek.c
+++ b/drivers/scsi/ufs/ufs-mediatek.c
@@ -117,6 +117,11 @@ static int ufs_mtk_setup_clocks(struct ufs_hba *hba, bool on,
return ret;
}
+static void ufs_mtk_set_caps(struct ufs_hba *hba)
+{
+ hba->caps |= UFSHCD_CAP_RPM_AUTOSUSPEND;
+}
+
/**
* ufs_mtk_init - find other essential mmio bases
* @hba: host controller instance
@@ -147,6 +152,8 @@ static int ufs_mtk_init(struct ufs_hba *hba)
if (err)
goto out_variant_clear;
+ ufs_mtk_set_caps(hba);
+
/*
* ufshcd_vops_init() is invoked after
* ufshcd_setup_clock(true) in ufshcd_hba_init() thus
--
2.18.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 v2 1/3] scsi: core: allow auto suspend override by low-level driver
From: Stanley Chu @ 2019-09-12 6:35 UTC (permalink / raw)
To: linux-scsi, martin.petersen, avri.altman, alim.akhtar,
pedrom.sousa, sthumma, jejb, bvanassche
Cc: marc.w.gonzalez, andy.teng, chun-hung.wu, kuohong.wang, evgreen,
subhashj, linux-mediatek, peter.wang, vivek.gautam, matthias.bgg,
Stanley Chu, linux-arm-kernel, beanhuo
In-Reply-To: <1568270135-32442-1-git-send-email-stanley.chu@mediatek.com>
Rework from previous work by:
Sujit Reddy Thumma <sthumma@codeaurora.org>
Until now the scsi mid-layer forbids runtime suspend till userspace
enables it. This is mainly to quarantine some disks with broken
runtime power management or have high latencies executing suspend
resume callbacks. If the userspace doesn't enable the runtime suspend
the underlying hardware will be always on even when it is not doing
any useful work and thus wasting power.
Some low-level drivers for the controllers can efficiently use runtime
power management to reduce power consumption and improve battery life.
Allow runtime suspend parameters override within the LLD itself
instead of waiting for userspace to control the power management.
Signed-off-by: Stanley Chu <stanley.chu@mediatek.com>
Reviewed-by: Avri Altman <avri.altman@wdc.com>
---
drivers/scsi/scsi_scan.c | 6 ++++++
drivers/scsi/scsi_sysfs.c | 3 ++-
drivers/scsi/sd.c | 4 ++++
include/scsi/scsi_device.h | 2 +-
4 files changed, 13 insertions(+), 2 deletions(-)
diff --git a/drivers/scsi/scsi_scan.c b/drivers/scsi/scsi_scan.c
index 058079f915f1..caf700a6b7c8 100644
--- a/drivers/scsi/scsi_scan.c
+++ b/drivers/scsi/scsi_scan.c
@@ -280,6 +280,12 @@ static struct scsi_device *scsi_alloc_sdev(struct scsi_target *starget,
scsi_change_queue_depth(sdev, sdev->host->cmd_per_lun ?
sdev->host->cmd_per_lun : 1);
+ /*
+ * Keep autosuspend disabled by default unless LLDD specifically
+ * enables it in slave_configure.
+ */
+ sdev->rpm_autosuspend_delay = -1;
+
scsi_sysfs_device_initialize(sdev);
if (shost->hostt->slave_alloc) {
diff --git a/drivers/scsi/scsi_sysfs.c b/drivers/scsi/scsi_sysfs.c
index 64c96c7828ee..461aafadd208 100644
--- a/drivers/scsi/scsi_sysfs.c
+++ b/drivers/scsi/scsi_sysfs.c
@@ -1300,7 +1300,8 @@ int scsi_sysfs_add_sdev(struct scsi_device *sdev)
device_enable_async_suspend(&sdev->sdev_gendev);
scsi_autopm_get_target(starget);
pm_runtime_set_active(&sdev->sdev_gendev);
- pm_runtime_forbid(&sdev->sdev_gendev);
+ if (sdev->rpm_autosuspend_delay < 0)
+ pm_runtime_forbid(&sdev->sdev_gendev);
pm_runtime_enable(&sdev->sdev_gendev);
scsi_autopm_put_target(starget);
diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c
index 149d406aacc9..de410b272158 100644
--- a/drivers/scsi/sd.c
+++ b/drivers/scsi/sd.c
@@ -3371,6 +3371,10 @@ static int sd_probe(struct device *dev)
}
blk_pm_runtime_init(sdp->request_queue, dev);
+ if (sdp->rpm_autosuspend_delay >= 0) {
+ pm_runtime_set_autosuspend_delay(dev,
+ sdp->rpm_autosuspend_delay);
+ }
device_add_disk(dev, gd, NULL);
if (sdkp->capacity)
sd_dif_config_host(sdkp);
diff --git a/include/scsi/scsi_device.h b/include/scsi/scsi_device.h
index 202f4d6a4342..133b282fae5a 100644
--- a/include/scsi/scsi_device.h
+++ b/include/scsi/scsi_device.h
@@ -199,7 +199,7 @@ struct scsi_device {
unsigned broken_fua:1; /* Don't set FUA bit */
unsigned lun_in_cdb:1; /* Store LUN bits in CDB[1] */
unsigned unmap_limit_for_ws:1; /* Use the UNMAP limit for WRITE SAME */
-
+ int rpm_autosuspend_delay;
atomic_t disk_events_disable_depth; /* disable depth for disk events */
DECLARE_BITMAP(supported_events, SDEV_EVT_MAXBITS); /* supported events */
--
2.18.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 v2] scsi: allow auto suspend override by low-level driver
From: Stanley Chu @ 2019-09-12 6:35 UTC (permalink / raw)
To: linux-scsi, martin.petersen, avri.altman, alim.akhtar,
pedrom.sousa, sthumma, jejb, bvanassche
Cc: marc.w.gonzalez, andy.teng, chun-hung.wu, kuohong.wang, evgreen,
subhashj, linux-mediatek, peter.wang, vivek.gautam, matthias.bgg,
Stanley Chu, linux-arm-kernel, beanhuo
Until now the scsi mid-layer forbids runtime suspend till userspace
enables it. This is mainly to quarantine some disks with broken
runtime power management or have high latencies executing suspend
resume callbacks. If the userspace doesn't enable the runtime suspend
the underlying hardware will be always on even when it is not doing
any useful work and thus wasting power.
Some low-level drivers for the controllers can efficiently use runtime
power management to reduce power consumption and improve battery life.
This patchset allows runtime suspend parameters override within the LLD itself
instead of waiting for userspace to control the power management, and
make UFS as the first user of this capability.
v1 => v2:
- Allow "zero" sdev->rpm_autosuspend_delay (Avri)
- Fix format of some lines (Avri)
Stanley Chu (3):
scsi: core: allow auto suspend override by low-level driver
scsi: ufs: override auto suspend tunables for ufs
scsi: ufs-mediatek: enable auto suspend capability
drivers/scsi/scsi_scan.c | 6 ++++++
drivers/scsi/scsi_sysfs.c | 3 ++-
drivers/scsi/sd.c | 4 ++++
drivers/scsi/ufs/ufs-mediatek.c | 7 +++++++
drivers/scsi/ufs/ufshcd.c | 8 ++++++++
drivers/scsi/ufs/ufshcd.h | 10 ++++++++++
include/scsi/scsi_device.h | 2 +-
7 files changed, 38 insertions(+), 2 deletions(-)
--
2.18.0
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* [PATCH v2 2/3] scsi: ufs: override auto suspend tunables for ufs
From: Stanley Chu @ 2019-09-12 6:35 UTC (permalink / raw)
To: linux-scsi, martin.petersen, avri.altman, alim.akhtar,
pedrom.sousa, sthumma, jejb, bvanassche
Cc: marc.w.gonzalez, andy.teng, chun-hung.wu, kuohong.wang, evgreen,
subhashj, linux-mediatek, peter.wang, vivek.gautam, matthias.bgg,
Stanley Chu, linux-arm-kernel, beanhuo
In-Reply-To: <1568270135-32442-1-git-send-email-stanley.chu@mediatek.com>
Rework from previous work by:
Sujit Reddy Thumma <sthumma@codeaurora.org>
Override auto suspend tunables for UFS device LUNs during
initialization so as to efficiently manage background operations
and the power consumption.
Signed-off-by: Stanley Chu <stanley.chu@mediatek.com>
Reviewed-by: Avri Altman <avri.altman@wdc.com>
---
drivers/scsi/ufs/ufshcd.c | 8 ++++++++
drivers/scsi/ufs/ufshcd.h | 10 ++++++++++
2 files changed, 18 insertions(+)
diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c
index 30b752c61b97..d253a018a73b 100644
--- a/drivers/scsi/ufs/ufshcd.c
+++ b/drivers/scsi/ufs/ufshcd.c
@@ -88,6 +88,9 @@
/* Interrupt aggregation default timeout, unit: 40us */
#define INT_AGGR_DEF_TO 0x02
+/* default delay of autosuspend: 2000 ms */
+#define RPM_AUTOSUSPEND_DELAY_MS 2000
+
#define ufshcd_toggle_vreg(_dev, _vreg, _on) \
({ \
int _ret; \
@@ -4612,9 +4615,14 @@ static int ufshcd_change_queue_depth(struct scsi_device *sdev, int depth)
*/
static int ufshcd_slave_configure(struct scsi_device *sdev)
{
+ struct ufs_hba *hba = shost_priv(sdev->host);
struct request_queue *q = sdev->request_queue;
blk_queue_update_dma_pad(q, PRDT_DATA_BYTE_COUNT_PAD - 1);
+
+ if (ufshcd_is_rpm_autosuspend_allowed(hba))
+ sdev->rpm_autosuspend_delay = RPM_AUTOSUSPEND_DELAY_MS;
+
return 0;
}
diff --git a/drivers/scsi/ufs/ufshcd.h b/drivers/scsi/ufs/ufshcd.h
index a43c7135f33d..99ea416519af 100644
--- a/drivers/scsi/ufs/ufshcd.h
+++ b/drivers/scsi/ufs/ufshcd.h
@@ -714,6 +714,12 @@ struct ufs_hba {
* the performance of ongoing read/write operations.
*/
#define UFSHCD_CAP_KEEP_AUTO_BKOPS_ENABLED_EXCEPT_SUSPEND (1 << 5)
+ /*
+ * This capability allows host controller driver to automatically
+ * enable runtime power management by itself instead of waiting
+ * for userspace to control the power management.
+ */
+#define UFSHCD_CAP_RPM_AUTOSUSPEND (1 << 6)
struct devfreq *devfreq;
struct ufs_clk_scaling clk_scaling;
@@ -747,6 +753,10 @@ static inline bool ufshcd_can_autobkops_during_suspend(struct ufs_hba *hba)
{
return hba->caps & UFSHCD_CAP_AUTO_BKOPS_SUSPEND;
}
+static inline bool ufshcd_is_rpm_autosuspend_allowed(struct ufs_hba *hba)
+{
+ return hba->caps & UFSHCD_CAP_RPM_AUTOSUSPEND;
+}
static inline bool ufshcd_is_intr_aggr_allowed(struct ufs_hba *hba)
{
--
2.18.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
* Re: FYI: imx-sdma firmware is not compatible with SLUB slab allocator
From: Uwe Kleine-König @ 2019-09-12 6:33 UTC (permalink / raw)
To: Jurgen Lambrecht
Cc: Aisheng Dong, thesven73@gmail.com, Leonard Crestez, dl-linux-imx,
Fabio Estevam, Robin Gong, linux-arm-kernel@lists.infradead.org,
Lucas Stach
In-Reply-To: <c0ddd111-5b2c-080f-373e-a595f5d2e386@televic.com>
[adding Lucas to Cc:]
Hello,
On Wed, Sep 04, 2019 at 02:26:17PM +0000, Jurgen Lambrecht wrote:
> On 9/3/19 4:48 PM, Leonard Crestez wrote:
> > On 03.09.2019 17:32, Jurgen Lambrecht wrote:
> >> On 9/3/19 7:57 AM, Robin Gong wrote:
> >>
> >>>> And that are the last commits on drivers/dma/imx-sdma.c for my 4.19.x+fslc
> >>>> branch. But I have already tried 5.1.x+fslc, and it also got stuck.
> >>> Sorry, I can't reproduce your issue on Linux 5.3-rc6 with 'CONFIG_SLOB=y' and
> >>> SDMA firmware built in kernel, Could you have a try on our imx6ul-14x14-evk
> >>> board with Linux 5.3-rc6 directly(no any patch needed)?
> >> This works on our own board (with imx6ul)!
> > Something seems to be wrong with the fslc tree, using 5.1.x+fslc at
> > latest commit cd1d083333e76e03d16f015c23f1f1b8c8637381 I can reproduce
> > the issue on imx6ul-14x14-evk board.
> >
> > Running without SLOB and builtin firmware it's fine.
> >
> > I couldn't reproduce with latest 4.19.x+fslc (currently at commit
> > 91d5756ab9096bbec256115d1d6b85f5d7139f85), maybe some additional SDMA
> > patches were applied which fixed this issue?
>
> My 4.19.x+fslc was a 4.19.56 (cda746ffc).
>
> Now I updated to your version 4.19.66, and it does not hang anymore, but
> I get a *kernel panic* (oops) (so with sdma FW and with the SLOB
> allocator). Also when I remove earlycon and update the dts not to enable
> sdma on the uart, it still panics. Also with our patches on top kernel
> panics. To be completely sure, I compiled 4.19.66+fslc (so
> 91d5756ab9096bbec256115d1d6b85f5d7139f85) with imx_v6_v7_defconfig
> (instead of our minimal defconfig) and then it panics half of the time
> (see below).
>
> With SLUB, it works. And with SLOB without sdma it also works!
>
> Here the kernel panic log:
>
> [ 0.971298] io scheduler noop registered (default)
> [ 1.045927] imx-sdma 20ec000.sdma: loaded firmware 3.5
> [ 1.060382] console [ttymxc0] enabled
> [ 1.064199] bootconsole [ec_imx6q0] disabled
> [ 1.104663] Unable to handle kernel paging request at virtual address ffffffe8
> [ 1.112035] pgd = (ptrval)
> [ 1.114772] [ffffffe8] *pgd=9ffff841, *pte=00000000, *ppte=00000000
> [ 1.121138] Internal error: Oops: 27 [#1] PREEMPT ARM
> [ 1.126212] Modules linked in:
> [ 1.129305] CPU: 0 PID: 1 Comm: swapper Not tainted 4.19.66-televic-rail-33.97.1802-00072-g39a835ebea4c #2
> [ 1.138979] Hardware name: Freescale i.MX6 Ultralite (Device Tree)
> [ 1.145197] PC is at alloc_vmap_area+0x140/0x3ec
> [ 1.149836] LR is at 0x1000
> [ 1.152650] pc : [<c01cc150>] lr : [<00001000>] psr: 00000053
> [ 1.158937] sp : df055cb0 ip : 00009000 fp : ff800000
> [ 1.164183] r10: 00000001 r9 : c0a74204 r8 : 00000001
> [ 1.169430] r7 : c0a74204 r6 : ffffffff r5 : 00000001 r4 : 00009000
> [ 1.175980] r3 : 00000000 r2 : 00000000 r1 : c0a11df0 r0 : e0876000
> [ 1.182533] Flags: nzcv IRQs on FIQs off Mode SVC_32 ISA ARM Segment none
> [ 1.189778] Control: 10c53c7d Table: 80004059 DAC: 00000051
> [ 1.195546] Process swapper (pid: 1, stack limit = 0x(ptrval))
> [ 1.201399] Stack: (0xdf055cb0 to 0xdf056000)
> [ 1.205785] 5ca0: e0800000 00000000 e0809000 e0800000
> [ 1.213993] 5cc0: 00000000 df2ed640 df2d4d80 b65d4d11 ffffffff 00009000 df2ed5c0 00000022
> [ 1.222202] 5ce0: 006080c0 00000001 e0800000 c0a03048 df2d4d80 c01cc490 ffffffff 006080c0
> [ 1.230412] 5d00: df2c1980 00008000 ffffffff ffffffff 006080c0 df2d4d80 00000001 c01cd870
> [ 1.238621] 5d20: ff800000 ffffffff 006080c0 c0382754 c0a12028 c0382754 ffffffff 00000000
> [ 1.246829] 5d40: df2c1940 df2d4d80 00000001 c01cda50 006080c0 0000024f 00000000 ffffffff
> [ 1.255038] 5d60: c0382754 00000000 df2c1940 df2ed540 00000100 c01cdb1c ffffffff c0382754
> [ 1.263247] 5d80: df2d4d80 c0382754 df2d4d80 df2c1940 00000000 df2d4d90 00000000 c03808d4
> [ 1.271457] 5da0: df2c1940 c037f4f0 c037f514 df2ec640 00000000 c037f520 df2c1940 df2d4d80
> [ 1.279666] 5dc0: c0a12030 c037d7d4 006000c0 00100000 00000013 c05ee130 00000200 df2c1940
> [ 1.287875] 5de0: 00000000 00000000 df2d4d90 00000000 00000001 c0a03048 df2d4d80 c02131cc
> [ 1.296082] 5e00: 00000000 c01f5640 00000000 b65d4d11 00000000 00000000 df2d4d80 c0a03048
> [ 1.304290] 5e20: 00000001 00000000 df2c194c 00000001 df2d4d80 c02134a8 df2d4e70 00000001
> [ 1.312498] 5e40: 00000000 b65d4d11 c09005a4 c01f4bb8 df2d4df8 c02129a4 df2c19b0 b65d4d11
> [ 1.320707] 5e60: df2c1980 df2c1940 00000000 c0a03048 00000001 df2c19b0 df2c194c 00000001
> [ 1.328915] 5e80: df2d4d80 c037f138 c037d7d4 c037f514 df2c1940 c0a1cd48 00100000 c05fcbcc
> [ 1.337124] 5ea0: 0000000d df29f5f0 c09005a4 b65d4d11 df29d740 df2c3cc0 c0a1cd48 c0a1cd48
> [ 1.345333] 5ec0: c0a1cd4c 00000000 c0a1cd4c c0a1cd48 c09005a4 c091b158 c091ac58 00000000
> [ 1.353542] 5ee0: c0a2b080 00000006 c0a03048 c091b0a8 00000000 c0929830 c0929838 c0102658
> [ 1.361751] 5f00: 00000000 00000084 00000084 dfbea400 00000065 c081f5e4 00000084 c013845c
> [ 1.369959] 5f20: c081eba8 00000000 c09005a4 00000000 00000006 00000006 00000000 dfbea401
> [ 1.378168] 5f40: 00000000 b65d4d11 00000000 b65d4d11 c0934f90 00000006 c0a2b080 00000084
> [ 1.386376] 5f60: c0a2b080 c0929838 c09005a4 c0900dbc 00000006 00000006 00000000 c09005a4
> [ 1.394584] 5f80: c05fd99c 00000000 c05fd99c 00000000 00000000 00000000 00000000 00000000
> [ 1.402792] 5fa0: 00000000 c05fd9a4 00000000 c01010e8 00000000 00000000 00000000 00000000
> [ 1.410998] 5fc0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
> [ 1.419205] 5fe0: 00000000 00000000 00000000 00000000 00000013 00000000 00000000 00000000
> [ 1.427434] [<c01cc150>] (alloc_vmap_area) from [<c01cc490>] (__get_vm_area_node+0x94/0x168)
> [ 1.435917] [<c01cc490>] (__get_vm_area_node) from [<c01cd870>] (__vmalloc_node_range+0x58/0x1f4)
> [ 1.444825] [<c01cd870>] (__vmalloc_node_range) from [<c01cda50>] (__vmalloc_node+0x44/0x54)
> [ 1.453300] [<c01cda50>] (__vmalloc_node) from [<c01cdb1c>] (vzalloc+0x2c/0x3c)
> [ 1.460652] [<c01cdb1c>] (vzalloc) from [<c0382754>] (check_partition+0x38/0x1d4)
> [ 1.468177] [<c0382754>] (check_partition) from [<c03808d4>] (rescan_partitions+0x78/0x440)
> [ 1.476567] [<c03808d4>] (rescan_partitions) from [<c02131cc>] (__blkdev_get+0x25c/0x414)
> [ 1.484779] [<c02131cc>] (__blkdev_get) from [<c02134a8>] (blkdev_get+0x124/0x3e8)
> [ 1.492385] [<c02134a8>] (blkdev_get) from [<c037f138>] (__device_add_disk+0x404/0x4b8)
> [ 1.500432] [<c037f138>] (__device_add_disk) from [<c091b158>] (brd_init+0xb0/0x170)
> [ 1.508218] [<c091b158>] (brd_init) from [<c0102658>] (do_one_initcall+0x48/0x1a0)
> [ 1.515833] [<c0102658>] (do_one_initcall) from [<c0900dbc>] (kernel_init_freeable+0x100/0x1c8)
> [ 1.524579] [<c0900dbc>] (kernel_init_freeable) from [<c05fd9a4>] (kernel_init+0x8/0x11c)
> [ 1.532796] [<c05fd9a4>] (kernel_init) from [<c01010e8>] (ret_from_fork+0x14/0x2c)
> [ 1.540386] Exception stack(0xdf055fb0 to 0xdf055ff8)
> [ 1.545463] 5fa0: 00000000 00000000 00000000 00000000
> [ 1.553671] 5fc0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
> [ 1.561875] 5fe0: 00000000 00000000 00000000 00000000 00000013 00000000
> [ 1.568522] Code: e5922018 e59f129c e1520001 0a00002f (e5121018)
These instructions are:
ldr r2, [r2, 0x18]
ldr r1, [pc, 0x29c]
cmp r2, r1
beq 0xd0
ldr r1, [r2, -0x18]
The last instruction tries to load from r2-0x18, but r2 is NULL.
I guess this is about inserting the new vmap area into the rbtree of
areas.
> [ 1.574733] ---[ end trace abfef683febb0cb6 ]---
> [ 1.579384] Kernel panic - not syncing: Fatal exception
> [ 1.584640] Rebooting in 180 seconds..
>
> I checked the patches on drivers/dma/imx-sdma.c and "dmaengine:
> imx-sdma: fix use-after-free on probe error path"
> 09593c25b975458025fd4cd15d5861cbaa33683d seems to describe the issue....
> but not solving it for me. So that is why I put Sven in CC.
>
> Also with 4.19.56 with our own patches on top, the kernel did not hang,
> but panicked. It looks like a timing problem inside the sdma driver.
> Because kernel did not crash always, sometimes it did boot. Also now,
> but only with 4.19.66+fslc with imx_v6_v7_defconfig it booted the first
> time correctly, after a reboot it panicked very late, I even got a login
> console, but then it rebooted again, but again good. Here the log:
>
> [ 49.763843] Unable to handle kernel paging request at virtual address
> a72e118d
> [ 49.772789] pgd = b60d9f54
> [ 49.775817] [a72e118d] *pgd=00000000
> [ 49.779501] Internal error: Oops: 5 [#1] SMP ARM
> [ 49.784152] Modules linked in:
> [ 49.787259] CPU: 0 PID: 455 Comm: ntpd Not tainted
> 4.19.66-00020-g91d5756ab909 #3
> [ 49.794770] Hardware name: Freescale i.MX6 Ultralite (Device Tree)
> [ 49.800991] PC is at find_entry+0x5c/0xc4
> [ 49.805032] LR is at find_entry+0x88/0xc4
> [ 49.809073] pc : [<c03090fc>] lr : [<c0309128>] psr: a0070013
> [ 49.815365] sp : d96c9d40 ip : e9cb8463 fp : d96c9d74
> [ 49.820616] r10: 00000001 r9 : 00000002 r8 : d8864040
> [ 49.825870] r7 : d88640bc r6 : c0e70108 r5 : d96c48fc r4 : 0000000b
> [ 49.832425] r3 : 0000006e r2 : 00000009 r1 : c0e70108 r0 : ffffffff
> [ 49.838982] Flags: NzCv IRQs on FIQs on Mode SVC_32 ISA ARM
> Segment none
> [ 49.846146] Control: 10c5387d Table: 996cc06a DAC: 00000051
> [ 49.851924] Process ntpd (pid: 455, stack limit = 0x873acf61)
> [ 49.857699] Stack: (0xd96c9d40 to 0xd96ca000)
> [ 49.862095] 9d40: d96c9d74 d96c9d88 c0ba1030 c1132fb4 0000000b d8090040 d96c48c0 c1108908
> [ 49.870308] 9d60: d90f44d8 00000000 d96c9dbc d96c9d78 c030a94c c03090ac c02a2d04 d96c48fc
> [ 49.878519] 9d80: 00000001 00000000 c0294844 7d9fdb21 d96c9dbc 00000000 d90f0f18 00000000
> [ 49.886732] 9da0: d96c9e90 d96c9f50 d96c48c0 d96c48c0 d96c9e8c d96c9dc0 c0294ff4 c030a8e4
> [ 49.894945] 9dc0: d96c9e7c d96c9dd0 c017eb8c c017e028 d96c48c0 00000000 00000000 00000000
> [ 49.903157] 9de0: d90f44d8 00000041 00000000 d96c2140 00000004 00000000 00000000 c1748cc0
> [ 49.911370] 9e00: 00000000 d96ae4f0 6ca44a47 00000000 dead4ead ffffffff ffffffff c193441c
> [ 49.919581] 9e20: 00000000 00000000 c0e795c8 d96c9e2c d96c9e2c 00000000 dead4ead ffffffff
> [ 49.927794] 9e40: ffffffff c193441c 00000000 00000000 c0e795c8 d96c9e2c d96c9e2c 7d9fdb21
> [ 49.936006] 9e60: 00000000 00000003 d96c9f50 d96c9e90 c1108908 00000001 d96c8000 00000142
> [ 49.944219] 9e80: d96c9f44 d96c9e90 c02966e4 c02942a8 d8f0ad10 d90f0f18 04ff40f7 0000000b
> [ 49.952433] 9ea0: d96dd021 60070013 d8e9d3d0 d8ed0960 d90f44d8 00000101 c030ac14 0000005c
> [ 49.960645] 9ec0: 00000000 00000000 00000000 d96c9ed0 d96c9ef4 d96c9ee0 c0ba1258 c0184904
> [ 49.968856] 9ee0: 00000000 d96acd24 d96c9f34 d96c9ef8 c02a80d4 c0ba123c d96c9f34 00000000
> [ 49.977069] 9f00: d96dd000 00000000 00000000 00000002 ffffff9c ffffff9c d96dd000 7d9fdb21
> [ 49.985282] 9f20: d96c8000 00000003 c1108908 ffffff9c d96dd000 c01011e4 d96c9f94 d96c9f48
> [ 49.993493] 9f40: c0281ccc c029667c d96ae000 00000001 00000000 00000000 00000004 00000100
> [ 50.001704] 9f60: 00000001 7d9fdb21 00000000 00000003 01b9da68 000003e6 00000142 c01011e4
> [ 50.009917] 9f80: d96c8000 00000142 d96c9fa4 d96c9f98 c0281dd0 c0281bb4 00000000 d96c9fa8
> [ 50.018130] 9fa0: c0101000 c0281dc8 00000003 01b9da68 ffffff9c b6cd6c68 00000000 00000000
> [ 50.026343] 9fc0: 00000003 01b9da68 000003e6 00000142 b6f7c900 0058ead8 bee697bc 0053b50c
> [ 50.034555] 9fe0: 00000142 bee696c8 b6c930d5 b6c1a6c6 20070030 ffffff9c 00000000 00000000
> [ 50.042753] Backtrace:
> [ 50.045258] [<c03090a0>] (find_entry) from [<c030a94c>] (proc_sys_lookup+0x74/0x180)
> [ 50.053042] r10:00000000 r9:d90f44d8 r8:c1108908 r7:d96c48c0 r6:d8090040 r5:0000000b
> [ 50.060897] r4:c1132fb4
> [ 50.063472] [<c030a8d8>] (proc_sys_lookup) from [<c0294ff4>] (path_openat+0xd58/0x108c)
> [ 50.071511] r10:d96c48c0 r9:d96c48c0 r8:d96c9f50 r7:d96c9e90 r6:00000000 r5:d90f0f18
> [ 50.079366] r4:00000000
> [ 50.081939] [<c029429c>] (path_openat) from [<c02966e4>] (do_filp_open+0x74/0xe4)
> [ 50.089459] r10:00000142 r9:d96c8000 r8:00000001 r7:c1108908 r6:d96c9e90 r5:d96c9f50
> [ 50.097311] r4:00000003
> [ 50.099884] [<c0296670>] (do_filp_open) from [<c0281ccc>] (do_sys_open+0x124/0x1ec)
> [ 50.107574] r8:c01011e4 r7:d96dd000 r6:ffffff9c r5:c1108908 r4:00000003
> [ 50.114311] [<c0281ba8>] (do_sys_open) from [<c0281dd0>] (sys_openat+0x14/0x18)
> [ 50.121656] r10:00000142 r9:d96c8000 r8:c01011e4 r7:00000142 r6:000003e6 r5:01b9da68
> [ 50.129511] r4:00000003
> [ 50.132083] [<c0281dbc>] (sys_openat) from [<c0101000>] (ret_fast_syscall+0x0/0x28)
> [ 50.139766] Exception stack(0xd96c9fa8 to 0xd96c9ff0)
> [ 50.144851] 9fa0: 00000003 01b9da68 ffffff9c b6cd6c68 00000000 00000000
> [ 50.153063] 9fc0: 00000003 01b9da68 000003e6 00000142 b6f7c900 0058ead8 bee697bc 0053b50c
> [ 50.161269] 9fe0: 00000142 bee696c8 b6c930d5 b6c1a6c6
> [ 50.166357] Code: e598a000 e06cc007 e1a0c24c e08cc18c (e79a610c)
> [ 50.172754] ---[ end trace 9e22ce3f534d2b3d ]---
>
> Then I logged into the serial console, rebooted, and again a kernel
> panic, but much sooner :
>
> [ 3.711085] imx-sdma 20ec000.sdma: loaded firmware 3.5
> [ 3.739709] console [ttymxc0] enabled
> [ 3.743626] bootconsole [ec_imx6q0] disabled
> [ 4.078675] brd: module loaded
> [ 4.327831] loop: module loaded
> [ 4.343852] at24 0-0050: 256 byte 24c02 EEPROM, writable, 8 bytes/write
> [ 4.434753] nand: device found, Manufacturer ID: 0x2c, Chip ID: 0xdc
> [ 4.441437] nand: Micron MT29F4G08ABADAH4
> [ 4.445582] nand: 512 MiB, SLC, erase size: 128 KiB, page size: 2048, OOB size: 64
> [ 4.466637] Bad block table not found for chip 0
> [ 4.474598] Bad block table not found for chip 0
> [ 4.479535] Scanning device for bad blocks
> [ 7.108753] Bad block table written to 0x00001ffe0000, version 0x01
> [ 7.118100] Bad block table written to 0x00001ffc0000, version 0x01
> [ 7.125068] 1 cmdlinepart partitions found on MTD device gpmi-nand
> [ 7.131616] Creating 1 MTD partitions on "gpmi-nand":
> [ 7.137028] 0x000000000000-0x000020000000 : "nandflash"
> [ 7.166797] random: crng init done
> [ 8.081299] gpmi-nand 1806000.gpmi-nand: driver registered.
> [ 8.089377] Unable to handle kernel NULL pointer dereference at virtual address 00000070
> [ 8.098055] pgd = a7175e07
> [ 8.100896] [00000070] *pgd=00000000
> [ 8.104636] Internal error: Oops: 5 [#1] SMP ARM
> [ 8.109316] Modules linked in:
> [ 8.112459] CPU: 0 PID: 1 Comm: swapper/0 Not tainted 4.19.66-00020-g91d5756ab909 #3
> [ 8.120255] Hardware name: Freescale i.MX6 Ultralite (Device Tree)
> [ 8.126506] PC is at strcmp+0x18/0x44
> [ 8.130236] LR is at kset_find_obj+0x44/0x8c
> [ 8.134568] pc : [<c0b9358c>] lr : [<c0b88054>] psr: 20000013
> [ 8.140887] sp : d80a9e50 ip : d80a9e60 fp : d80a9e5c
> [ 8.146165] r10: 00000000 r9 : c1108930 r8 : c1108908
> [ 8.151444] r7 : d8139e88 r6 : c0edbd04 r5 : d8139e80 r4 : c0eba704
> [ 8.158023] r3 : 00000070 r2 : 00000066 r1 : c0edbd04 r0 : 00000070
> [ 8.164608] Flags: nzCv IRQs on FIQs on Mode SVC_32 ISA ARM Segment none
> [ 8.171797] Control: 10c5387d Table: 8000406a DAC: 00000051
> [ 8.177602] Process swapper/0 (pid: 1, stack limit = 0x0e667d51)
> [ 8.183664] Stack: (0xd80a9e50 to 0xd80aa000)
> [ 8.188084] 9e40: d80a9e7c d80a9e60 c0b88054 c0b93580
> [ 8.196328] 9e60: c117f87c c105f984 c10a7dc4 c11d7ac0 d80a9e94 d80a9e80 c0612c60 c0b8801c
> [ 8.204570] 9e80: c1174e28 c117f87c d80a9eac d80a9e98 c0612cf0 c0612c50 c11d6970 c105f984
> [ 8.212813] 9ea0: d80a9ebc d80a9eb0 c0613d68 c0612c88 d80a9ecc d80a9ec0 c105f99c c0613d3c
> [ 8.221056] 9ec0: d80a9f4c d80a9ed0 c01031f4 c105f990 00000000 c0f8f438 000000f7 dffffb00
> [ 8.229298] 9ee0: d80a9f4c d80a9ef0 c014f5a8 c1000710 00000000 00000006 d8092000 00000000
> [ 8.237542] 9f00: 60000053 c11d6970 c11dc900 c11d7ac0 d80a9f34 d80a9f20 c017bf04 7d9fdb21
> [ 8.245785] 9f20: c115d3c4 00000006 c1090850 c10a7dc4 c11dc900 c11d7ac0 d80a8000 00000000
> [ 8.254027] 9f40: d80a9f94 d80a9f50 c10011d4 c0103178 00000006 00000006 00000000 c1000704
> [ 8.262270] 9f60: c0ba1310 000000f7 d8092000 00000000 c0b99d14 00000000 00000000 00000000
> [ 8.270511] 9f80: 00000000 00000000 d80a9fac d80a9f98 c0b99d24 c1000f24 d8092000 00000000
> [ 8.278753] 9fa0: 00000000 d80a9fb0 c01010b4 c0b99d20 00000000 00000000 00000000 00000000
> [ 8.286993] 9fc0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
> [ 8.295233] 9fe0: 00000000 00000000 00000000 00000000 00000013 00000000 00000000 00000000
> [ 8.303456] Backtrace:
> [ 8.305993] [<c0b93574>] (strcmp) from [<c0b88054>] (kset_find_obj+0x44/0x8c)
> [ 8.313208] [<c0b88010>] (kset_find_obj) from [<c0612c60>] (driver_find+0x1c/0x38)
> [ 8.320846] r7:c11d7ac0 r6:c10a7dc4 r5:c105f984 r4:c117f87c
> [ 8.326575] [<c0612c44>] (driver_find) from [<c0612cf0>] (driver_register+0x74/0x11c)
> [ 8.334465] r4:c117f87c r3:c1174e28
> [ 8.338114] [<c0612c7c>] (driver_register) from [<c0613d68>] (__platform_driver_register+0x38/0x4c)
> [ 8.347215] r5:c105f984 r4:c11d6970
> [ 8.350865] [<c0613d30>] (__platform_driver_register) from [<c105f99c>] (fsl_qspi_driver_init+0x18/0x20)
> [ 8.360415] [<c105f984>] (fsl_qspi_driver_init) from [<c01031f4>] (do_one_initcall+0x88/0x31c)
> [ 8.369103] [<c010316c>] (do_one_initcall) from [<c10011d4>] (kernel_init_freeable+0x2bc/0x3e8)
> [ 8.377871] r10:00000000 r9:d80a8000 r8:c11d7ac0 r7:c11dc900 r6:c10a7dc4 r5:c1090850
> [ 8.385750] r4:00000006
> [ 8.388356] [<c1000f18>] (kernel_init_freeable) from [<c0b99d24>] (kernel_init+0x10/0x120)
> [ 8.396688] r10:00000000 r9:00000000 r8:00000000 r7:00000000 r6:00000000 r5:c0b99d14
> [ 8.404567] r4:00000000
> [ 8.407169] [<c0b99d14>] (kernel_init) from [<c01010b4>] (ret_from_fork+0x14/0x20)
> [ 8.414792] Exception stack(0xd80a9fb0 to 0xd80a9ff8)
> [ 8.419902] 9fa0: 00000000 00000000 00000000 00000000
> [ 8.428143] 9fc0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
> [ 8.436379] 9fe0: 00000000 00000000 00000000 00000000 00000013 00000000
> [ 8.443049] r4:00000000 r3:d8092000
> [ 8.446690] Code: e24cb004 ea000001 e3530000 0a000008 (e4d03001)
> [ 8.453044] ---[ end trace b6f2a017d259fade ]---
> [ 8.457941] Kernel panic - not syncing: Attempted to kill init! exitcode=0x0000000b
> [ 8.457941]
> [ 8.467193] ---[ end Kernel panic - not syncing: Attempted to kill init! exitcode=0x0000000b
> [ 8.467193] ]---
this is something different:
sub fp, ip, 4
b 0x10
cmp r3, 0
beq 0x34
ldrb r3, [r0], 1
Maybe the sdma driver does something strage that confused SLOB but not
the other allocaters?
Best regards
Uwe
--
Pengutronix e.K. | Uwe Kleine-König |
Industrial Linux Solutions | http://www.pengutronix.de/ |
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* Re: [GIT PULL 1/2] arm64: dts: exynos: Pull for v5.4
From: Krzysztof Kozlowski @ 2019-09-12 6:32 UTC (permalink / raw)
To: Arnd Bergmann
Cc: DTML, moderated list:ARM/SAMSUNG EXYNOS ARM ARCHITECTURES,
linux-kernel@vger.kernel.org, SoC Team, arm-soc, Kukjin Kim,
Olof Johansson, Linux ARM
In-Reply-To: <CAK8P3a2pBV+fh0rHitZ30Zz61QNRLfNSD-nhnzq4ZtxSh66F1Q@mail.gmail.com>
On Wed, 11 Sep 2019 at 23:07, Arnd Bergmann <arnd@arndb.de> wrote:
>
> On Wed, Sep 11, 2019 at 8:36 PM Krzysztof Kozlowski <krzk@kernel.org> wrote:
> >
> > Hi,
> >
> > Unfortunately the patches were applied right after closing the linux-next.
>
> Hi Krzysztof,
>
> I took a look at these and am not convinced this is right:
>
> > 1. Fix boot of Exynos7 due to wrong address/size of memory node,
>
> The current state is clearly broken and a fix is needed, but
> I'm not sure this is the right fix. Why do you have 32-bit physical
> addressing on a 64-bit chip? I looked at commit ef72171b3621
> that introduced it, and it seems it would be better to just
> revert back to 64-bit addresses.
We discussed with Marek Szyprowski that either we can go back to
64-bit addressing or stick to 32. There are not known boards with more
than 4 GB of RAM so from this point of view the choice was irrelevant.
At the end of discussion I mentioned to stick with other arm64 boards
(although not all), so revert to have 64 bit address... but Marek
chosen differently. Since you ask, let's go back with revert.
>
> > 2. Move GPU under /soc node,
>
> No problem
>
> > 3. Minor cleanup of #address-cells.
>
> IIRC, an interrupt-controller is required to have a #address-cells
> property, even if that is normally zero. I don't remember the
> details, but the gic binding lists it as mandatory, and I think
> the PCI interrupt-map relies on it. I would just drop this patch.
Indeed, binding requires both address and size cells. I'll drop it.
Best regards,
Krzysztof
_______________________________________________
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 1/2] crypto: sun4i-ss: simplify enable/disable of the device
From: Maxime Ripard @ 2019-09-12 6:32 UTC (permalink / raw)
To: Corentin Labbe
Cc: herbert, linux-sunxi, linux-kernel, Maxime Ripard, Chen-Yu Tsai,
linux-crypto, davem, linux-arm-kernel
In-Reply-To: <20190911114650.20567-2-clabbe.montjoie@gmail.com>
Hi,
Le mer. 11 sept. 2019 à 13:46, Corentin Labbe
<clabbe.montjoie@gmail.com> a écrit :
>
> This patch regroups resource enabling/disabling in dedicated function.
> This simplify error handling and will permit to support power
> management.
>
> Signed-off-by: Corentin Labbe <clabbe.montjoie@gmail.com>
> ---
> drivers/crypto/sunxi-ss/sun4i-ss-core.c | 73 ++++++++++++++-----------
> 1 file changed, 42 insertions(+), 31 deletions(-)
>
> diff --git a/drivers/crypto/sunxi-ss/sun4i-ss-core.c b/drivers/crypto/sunxi-ss/sun4i-ss-core.c
> index 9aa6fe081a27..2c9ff01dddfc 100644
> --- a/drivers/crypto/sunxi-ss/sun4i-ss-core.c
> +++ b/drivers/crypto/sunxi-ss/sun4i-ss-core.c
> @@ -223,6 +223,41 @@ static struct sun4i_ss_alg_template ss_algs[] = {
> #endif
> };
>
> +static void sun4i_ss_disable(struct sun4i_ss_ctx *ss)
> +{
> + if (ss->reset)
> + reset_control_assert(ss->reset);
> + clk_disable_unprepare(ss->ssclk);
> + clk_disable_unprepare(ss->busclk);
> +}
While you're at it, can you add a new line after the reset_control_assert here?
> +static int sun4i_ss_enable(struct sun4i_ss_ctx *ss)
> +{
> + int err;
> +
> + err = clk_prepare_enable(ss->busclk);
> + if (err) {
> + dev_err(ss->dev, "Cannot prepare_enable busclk\n");
> + goto err_enable;
> + }
> + err = clk_prepare_enable(ss->ssclk);
> + if (err) {
> + dev_err(ss->dev, "Cannot prepare_enable ssclk\n");
> + goto err_enable;
> + }
> + if (ss->reset) {
> + err = reset_control_deassert(ss->reset);
> + if (err) {
> + dev_err(ss->dev, "Cannot deassert reset control\n");
> + goto err_enable;
> + }
> + }
> + return err;
And after each block here?
With that fixed:
Acked-by: Maxime Ripard <mripard@kernel.org>
Thanks!
Maxime
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* Re: [RFC PATCH V3 4/5] platform: mtk-isp: Add Mediatek DIP driver
From: Tomasz Figa @ 2019-09-12 5:58 UTC (permalink / raw)
To: Frederic Chen
Cc: Shik Chen, devicetree, Sean Cheng (鄭昇弘),
Laurent Pinchart, Rynn Wu (吳育恩),
Christie Yu (游雅惠), srv_heupstream,
Allan Yang (楊智鈞),
Holmes Chiou (邱挺), suleiman, Jerry-ch Chen,
Jungo Lin (林明俊), Sj Huang, yuzhao,
Hans Verkuil, zwisler, Matthias Brugger,
moderated list:ARM/Mediatek SoC support, Mauro Carvalho Chehab,
list@263.net:IOMMU DRIVERS <iommu@lists.linux-foundation.org>, Joerg Roedel <joro@8bytes.org>, ,
Linux Media Mailing List
In-Reply-To: <1568223671.19171.12.camel@mtksdccf07>
On Thu, Sep 12, 2019 at 2:41 AM Frederic Chen
<frederic.chen@mediatek.com> wrote:
>
> Hi Tomasz,
>
> I appreciate your helpful comments.
>
>
> On Tue, 2019-09-10 at 13:04 +0900, Tomasz Figa wrote:
> > Hi Frederic,
> >
> > On Tue, Sep 10, 2019 at 4:23 AM <frederic.chen@mediatek.com> wrote:
> > >
> > > From: Frederic Chen <frederic.chen@mediatek.com>
> > >
> > > This patch adds the driver of Digital Image Processing (DIP)
> > > unit in Mediatek ISP system, providing image format
> > > conversion, resizing, and rotation features.
> > >
> > > The mtk-isp directory will contain drivers for multiple IP
> > > blocks found in Mediatek ISP system. It will include ISP
> > > Pass 1 driver(CAM), sensor interface driver, DIP driver and
> > > face detection driver.
> > >
> > > Signed-off-by: Frederic Chen <frederic.chen@mediatek.com>
> > > ---
> > > drivers/media/platform/mtk-isp/Makefile | 7 +
> > > .../media/platform/mtk-isp/isp_50/Makefile | 7 +
> > > .../platform/mtk-isp/isp_50/dip/Makefile | 18 +
> > > .../platform/mtk-isp/isp_50/dip/mtk_dip-dev.c | 650 +++++
> > > .../platform/mtk-isp/isp_50/dip/mtk_dip-dev.h | 566 +++++
> > > .../platform/mtk-isp/isp_50/dip/mtk_dip-hw.h | 156 ++
> > > .../platform/mtk-isp/isp_50/dip/mtk_dip-sys.c | 521 ++++
> > > .../mtk-isp/isp_50/dip/mtk_dip-v4l2.c | 2255 +++++++++++++++++
> > > 8 files changed, 4180 insertions(+)
> > > create mode 100644 drivers/media/platform/mtk-isp/Makefile
> > > create mode 100644 drivers/media/platform/mtk-isp/isp_50/Makefile
> > > create mode 100644 drivers/media/platform/mtk-isp/isp_50/dip/Makefile
> > > create mode 100644 drivers/media/platform/mtk-isp/isp_50/dip/mtk_dip-dev.c
> > > create mode 100644 drivers/media/platform/mtk-isp/isp_50/dip/mtk_dip-dev.h
> > > create mode 100644 drivers/media/platform/mtk-isp/isp_50/dip/mtk_dip-hw.h
> > > create mode 100644 drivers/media/platform/mtk-isp/isp_50/dip/mtk_dip-sys.c
> > > create mode 100644 drivers/media/platform/mtk-isp/isp_50/dip/mtk_dip-v4l2.c
> > >
> >
> > Thanks for sending v3!
> >
> > I'm going to do a full review a bit later, but please check one
> > comment about power handling below.
> >
> > Other than that one comment, from a quick look, I think we only have a
> > number of style issues left. Thanks for the hard work!
> >
> > [snip]
> > > +static void dip_runner_func(struct work_struct *work)
> > > +{
> > > + struct mtk_dip_request *req = mtk_dip_hw_mdp_work_to_req(work);
> > > + struct mtk_dip_dev *dip_dev = req->dip_pipe->dip_dev;
> > > + struct img_config *config_data =
> > > + (struct img_config *)req->working_buf->config_data.vaddr;
> > > +
> > > + /*
> > > + * Call MDP/GCE API to do HW excecution
> > > + * Pass the framejob to MDP driver
> > > + */
> > > + pm_runtime_get_sync(dip_dev->dev);
> > > + mdp_cmdq_sendtask(dip_dev->mdp_pdev, config_data,
> > > + &req->img_fparam.frameparam, NULL, false,
> > > + dip_mdp_cb_func, req);
> > > +}
> > [snip]
> > > +static void dip_composer_workfunc(struct work_struct *work)
> > > +{
> > > + struct mtk_dip_request *req = mtk_dip_hw_fw_work_to_req(work);
> > > + struct mtk_dip_dev *dip_dev = req->dip_pipe->dip_dev;
> > > + struct img_ipi_param ipi_param;
> > > + struct mtk_dip_hw_subframe *buf;
> > > + int ret;
> > > +
> > > + down(&dip_dev->sem);
> > > +
> > > + buf = mtk_dip_hw_working_buf_alloc(req->dip_pipe->dip_dev);
> > > + if (!buf) {
> > > + dev_err(req->dip_pipe->dip_dev->dev,
> > > + "%s:%s:req(%p): no free working buffer available\n",
> > > + __func__, req->dip_pipe->desc->name, req);
> > > + }
> > > +
> > > + req->working_buf = buf;
> > > + mtk_dip_wbuf_to_ipi_img_addr(&req->img_fparam.frameparam.subfrm_data,
> > > + &buf->buffer);
> > > + memset(buf->buffer.vaddr, 0, DIP_SUB_FRM_SZ);
> > > + mtk_dip_wbuf_to_ipi_img_sw_addr(&req->img_fparam.frameparam.config_data,
> > > + &buf->config_data);
> > > + memset(buf->config_data.vaddr, 0, DIP_COMP_SZ);
> > > +
> > > + if (!req->img_fparam.frameparam.tuning_data.present) {
> > > + /*
> > > + * When user enqueued without tuning buffer,
> > > + * it would use driver internal buffer.
> > > + */
> > > + dev_dbg(dip_dev->dev,
> > > + "%s: frame_no(%d) has no tuning_data\n",
> > > + __func__, req->img_fparam.frameparam.frame_no);
> > > +
> > > + mtk_dip_wbuf_to_ipi_tuning_addr
> > > + (&req->img_fparam.frameparam.tuning_data,
> > > + &buf->tuning_buf);
> > > + memset(buf->tuning_buf.vaddr, 0, DIP_TUNING_SZ);
> > > + }
> > > +
> > > + mtk_dip_wbuf_to_ipi_img_sw_addr(&req->img_fparam.frameparam.self_data,
> > > + &buf->frameparam);
> > > + memcpy(buf->frameparam.vaddr, &req->img_fparam.frameparam,
> > > + sizeof(req->img_fparam.frameparam));
> > > + ipi_param.usage = IMG_IPI_FRAME;
> > > + ipi_param.frm_param.handle = req->id;
> > > + ipi_param.frm_param.scp_addr = (u32)buf->frameparam.scp_daddr;
> > > +
> > > + mutex_lock(&dip_dev->hw_op_lock);
> > > + atomic_inc(&dip_dev->num_composing);
> > > + ret = scp_ipi_send(dip_dev->scp_pdev, SCP_IPI_DIP, &ipi_param,
> > > + sizeof(ipi_param), 0);
> >
> > We're not holding the pm_runtime enable count here
> > (pm_runtime_get_sync() wasn't called), so rproc_shutdown() might have
> > been called. Wouldn't that affect the ability for this IPI to run?
> >
> > We had a related discussion with Jerry on the FD series and I think
> > the conclusion is:
> > a) if there is any state that needs to be preserved between jobs, that
> > would be cleared by rproc_shutdown() then we need to call
> > rproc_boot/shutdown() when we start/stop streaming.
> > b) it there is no such state, we can keep them inside runtime PM
> > callbacks, but we need to call pm_runtime_get_sync() before sending an
> > IPI and pm_runtime_mark_last_busy() + pm_runtime_put_autosuspend()
> > after the SCP signals completion. In this case the runtime PM
> > autosuspend delay should be set to around 2-3 times the delay needed
> > for rproc_shutdown() + rproc_boot() to complete.
>
> Since each IMG_IPI_FRAME command is stateless, I would like to
> use pm_runtime_get_sync()/ pm_runtime_mark_last_busy()/
> pm_runtime_put_autosuspend() to fix this issue (solution b).
What does IMG_IPI_INIT do then? Do we need it at all?
I'm worried about the fact that we call rproc_boot(), IMG_IPI_INIT and
then rproc_shutdown(). The latter can completely shutdown the SCP and
clear any state there. How would the effects of IMG_IPI_INIT be
preserved until IMG_IPI_FRAME is called?
Best regards,
Tomasz
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* [PATCH V2 2/2] mm/pgtable/debug: Add test validating architecture page table helpers
From: Anshuman Khandual @ 2019-09-12 6:02 UTC (permalink / raw)
To: linux-mm
Cc: Mark Rutland, linux-ia64, linux-sh, Peter Zijlstra, James Hogan,
Tetsuo Handa, Heiko Carstens, Michal Hocko, Dave Hansen,
Paul Mackerras, sparclinux, Thomas Gleixner, linux-s390,
Michael Ellerman, x86, Russell King - ARM Linux, Matthew Wilcox,
Steven Price, Jason Gunthorpe, Gerald Schaefer, linux-snps-arc,
linux-arm-kernel, Kees Cook, Anshuman Khandual, Masahiro Yamada,
Mark Brown, Kirill A . Shutemov, Dan Williams, Vlastimil Babka,
Christophe Leroy, Sri Krishna chowdary, Ard Biesheuvel,
Greg Kroah-Hartman, linux-mips, Ralf Baechle, linux-kernel,
Paul Burton, Mike Rapoport, Vineet Gupta, Martin Schwidefsky,
Andrew Morton, linuxppc-dev, David S. Miller
In-Reply-To: <1568268173-31302-1-git-send-email-anshuman.khandual@arm.com>
This adds a test module which will validate architecture page table helpers
and accessors regarding compliance with generic MM semantics expectations.
This will help various architectures in validating changes to the existing
page table helpers or addition of new ones.
Test page table and memory pages creating it's entries at various level are
all allocated from system memory with required alignments. If memory pages
with required size and alignment could not be allocated, then all depending
individual tests are skipped.
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Vlastimil Babka <vbabka@suse.cz>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Mike Rapoport <rppt@linux.vnet.ibm.com>
Cc: Jason Gunthorpe <jgg@ziepe.ca>
Cc: Dan Williams <dan.j.williams@intel.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Michal Hocko <mhocko@kernel.org>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Mark Brown <broonie@kernel.org>
Cc: Steven Price <Steven.Price@arm.com>
Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Cc: Masahiro Yamada <yamada.masahiro@socionext.com>
Cc: Kees Cook <keescook@chromium.org>
Cc: Tetsuo Handa <penguin-kernel@i-love.sakura.ne.jp>
Cc: Matthew Wilcox <willy@infradead.org>
Cc: Sri Krishna chowdary <schowdary@nvidia.com>
Cc: Dave Hansen <dave.hansen@intel.com>
Cc: Russell King - ARM Linux <linux@armlinux.org.uk>
Cc: Michael Ellerman <mpe@ellerman.id.au>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Martin Schwidefsky <schwidefsky@de.ibm.com>
Cc: Heiko Carstens <heiko.carstens@de.ibm.com>
Cc: "David S. Miller" <davem@davemloft.net>
Cc: Vineet Gupta <vgupta@synopsys.com>
Cc: James Hogan <jhogan@kernel.org>
Cc: Paul Burton <paul.burton@mips.com>
Cc: Ralf Baechle <ralf@linux-mips.org>
Cc: Kirill A. Shutemov <kirill@shutemov.name>
Cc: Gerald Schaefer <gerald.schaefer@de.ibm.com>
Cc: Christophe Leroy <christophe.leroy@c-s.fr>
Cc: linux-snps-arc@lists.infradead.org
Cc: linux-mips@vger.kernel.org
Cc: linux-arm-kernel@lists.infradead.org
Cc: linux-ia64@vger.kernel.org
Cc: linuxppc-dev@lists.ozlabs.org
Cc: linux-s390@vger.kernel.org
Cc: linux-sh@vger.kernel.org
Cc: sparclinux@vger.kernel.org
Cc: x86@kernel.org
Cc: linux-kernel@vger.kernel.org
Suggested-by: Catalin Marinas <catalin.marinas@arm.com>
Signed-off-by: Anshuman Khandual <anshuman.khandual@arm.com>
---
arch/x86/include/asm/pgtable_64_types.h | 2 +
mm/Kconfig.debug | 14 +
mm/Makefile | 1 +
mm/arch_pgtable_test.c | 429 ++++++++++++++++++++++++
4 files changed, 446 insertions(+)
create mode 100644 mm/arch_pgtable_test.c
diff --git a/arch/x86/include/asm/pgtable_64_types.h b/arch/x86/include/asm/pgtable_64_types.h
index 52e5f5f2240d..b882792a3999 100644
--- a/arch/x86/include/asm/pgtable_64_types.h
+++ b/arch/x86/include/asm/pgtable_64_types.h
@@ -40,6 +40,8 @@ static inline bool pgtable_l5_enabled(void)
#define pgtable_l5_enabled() 0
#endif /* CONFIG_X86_5LEVEL */
+#define mm_p4d_folded(mm) (!pgtable_l5_enabled())
+
extern unsigned int pgdir_shift;
extern unsigned int ptrs_per_p4d;
diff --git a/mm/Kconfig.debug b/mm/Kconfig.debug
index 327b3ebf23bf..ce9c397f7b07 100644
--- a/mm/Kconfig.debug
+++ b/mm/Kconfig.debug
@@ -117,3 +117,17 @@ config DEBUG_RODATA_TEST
depends on STRICT_KERNEL_RWX
---help---
This option enables a testcase for the setting rodata read-only.
+
+config DEBUG_ARCH_PGTABLE_TEST
+ bool "Test arch page table helpers for semantics compliance"
+ depends on MMU
+ depends on DEBUG_KERNEL
+ help
+ This options provides a kernel module which can be used to test
+ architecture page table helper functions on various platform in
+ verifying if they comply with expected generic MM semantics. This
+ will help architectures code in making sure that any changes or
+ new additions of these helpers will still conform to generic MM
+ expected semantics.
+
+ If unsure, say N.
diff --git a/mm/Makefile b/mm/Makefile
index d996846697ef..bb572c5aa8c5 100644
--- a/mm/Makefile
+++ b/mm/Makefile
@@ -86,6 +86,7 @@ obj-$(CONFIG_HWPOISON_INJECT) += hwpoison-inject.o
obj-$(CONFIG_DEBUG_KMEMLEAK) += kmemleak.o
obj-$(CONFIG_DEBUG_KMEMLEAK_TEST) += kmemleak-test.o
obj-$(CONFIG_DEBUG_RODATA_TEST) += rodata_test.o
+obj-$(CONFIG_DEBUG_ARCH_PGTABLE_TEST) += arch_pgtable_test.o
obj-$(CONFIG_PAGE_OWNER) += page_owner.o
obj-$(CONFIG_CLEANCACHE) += cleancache.o
obj-$(CONFIG_MEMORY_ISOLATION) += page_isolation.o
diff --git a/mm/arch_pgtable_test.c b/mm/arch_pgtable_test.c
new file mode 100644
index 000000000000..8b4a92756ad8
--- /dev/null
+++ b/mm/arch_pgtable_test.c
@@ -0,0 +1,429 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * This kernel module validates architecture page table helpers &
+ * accessors and helps in verifying their continued compliance with
+ * generic MM semantics.
+ *
+ * Copyright (C) 2019 ARM Ltd.
+ *
+ * Author: Anshuman Khandual <anshuman.khandual@arm.com>
+ */
+#define pr_fmt(fmt) "arch_pgtable_test: %s " fmt, __func__
+
+#include <linux/gfp.h>
+#include <linux/hugetlb.h>
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <linux/mman.h>
+#include <linux/mm_types.h>
+#include <linux/module.h>
+#include <linux/pfn_t.h>
+#include <linux/printk.h>
+#include <linux/random.h>
+#include <linux/spinlock.h>
+#include <linux/swap.h>
+#include <linux/swapops.h>
+#include <linux/sched/mm.h>
+#include <asm/pgalloc.h>
+#include <asm/pgtable.h>
+
+/*
+ * Basic operations
+ *
+ * mkold(entry) = An old and not a young entry
+ * mkyoung(entry) = A young and not an old entry
+ * mkdirty(entry) = A dirty and not a clean entry
+ * mkclean(entry) = A clean and not a dirty entry
+ * mkwrite(entry) = A write and not a write protected entry
+ * wrprotect(entry) = A write protected and not a write entry
+ * pxx_bad(entry) = A mapped and non-table entry
+ * pxx_same(entry1, entry2) = Both entries hold the exact same value
+ */
+#define VMFLAGS (VM_READ|VM_WRITE|VM_EXEC)
+
+/*
+ * On s390 platform, the lower 12 bits are used to identify given page table
+ * entry type and for other arch specific requirements. But these bits might
+ * affect the ability to clear entries with pxx_clear(). So while loading up
+ * the entries skip all lower 12 bits in order to accommodate s390 platform.
+ * It does not have affect any other platform.
+ */
+#define RANDOM_ORVALUE (0xfffffffffffff000UL)
+#define RANDOM_NZVALUE (0xff)
+
+static bool pud_aligned;
+static bool pmd_aligned;
+
+static void pte_basic_tests(struct page *page, pgprot_t prot)
+{
+ pte_t pte = mk_pte(page, prot);
+
+ WARN_ON(!pte_same(pte, pte));
+ WARN_ON(!pte_young(pte_mkyoung(pte)));
+ WARN_ON(!pte_dirty(pte_mkdirty(pte)));
+ WARN_ON(!pte_write(pte_mkwrite(pte)));
+ WARN_ON(pte_young(pte_mkold(pte)));
+ WARN_ON(pte_dirty(pte_mkclean(pte)));
+ WARN_ON(pte_write(pte_wrprotect(pte)));
+}
+
+#ifdef CONFIG_HAVE_ARCH_TRANSPARENT_HUGEPAGE
+static void pmd_basic_tests(struct page *page, pgprot_t prot)
+{
+ pmd_t pmd;
+
+ /*
+ * Memory block here must be PMD_SIZE aligned. Abort this
+ * test in case we could not allocate such a memory block.
+ */
+ if (!pmd_aligned) {
+ pr_warn("Could not proceed with PMD tests\n");
+ return;
+ }
+
+ pmd = mk_pmd(page, prot);
+ WARN_ON(!pmd_same(pmd, pmd));
+ WARN_ON(!pmd_young(pmd_mkyoung(pmd)));
+ WARN_ON(!pmd_dirty(pmd_mkdirty(pmd)));
+ WARN_ON(!pmd_write(pmd_mkwrite(pmd)));
+ WARN_ON(pmd_young(pmd_mkold(pmd)));
+ WARN_ON(pmd_dirty(pmd_mkclean(pmd)));
+ WARN_ON(pmd_write(pmd_wrprotect(pmd)));
+ /*
+ * A huge page does not point to next level page table
+ * entry. Hence this must qualify as pmd_bad().
+ */
+ WARN_ON(!pmd_bad(pmd_mkhuge(pmd)));
+}
+#else
+static void pmd_basic_tests(struct page *page, pgprot_t prot) { }
+#endif
+
+#ifdef CONFIG_HAVE_ARCH_TRANSPARENT_HUGEPAGE_PUD
+static void pud_basic_tests(struct page *page, pgprot_t prot)
+{
+ pud_t pud;
+
+ /*
+ * Memory block here must be PUD_SIZE aligned. Abort this
+ * test in case we could not allocate such a memory block.
+ */
+ if (!pud_aligned) {
+ pr_warn("Could not proceed with PUD tests\n");
+ return;
+ }
+
+ pud = pfn_pud(page_to_pfn(page), prot);
+ WARN_ON(!pud_same(pud, pud));
+ WARN_ON(!pud_young(pud_mkyoung(pud)));
+ WARN_ON(!pud_write(pud_mkwrite(pud)));
+ WARN_ON(pud_write(pud_wrprotect(pud)));
+ WARN_ON(pud_young(pud_mkold(pud)));
+
+#if !defined(__PAGETABLE_PMD_FOLDED) && !defined(__ARCH_HAS_4LEVEL_HACK)
+ /*
+ * A huge page does not point to next level page table
+ * entry. Hence this must qualify as pud_bad().
+ */
+ WARN_ON(!pud_bad(pud_mkhuge(pud)));
+#endif
+}
+#else
+static void pud_basic_tests(struct page *page, pgprot_t prot) { }
+#endif
+
+static void p4d_basic_tests(struct page *page, pgprot_t prot)
+{
+ p4d_t p4d;
+
+ memset(&p4d, RANDOM_NZVALUE, sizeof(p4d_t));
+ WARN_ON(!p4d_same(p4d, p4d));
+}
+
+static void pgd_basic_tests(struct page *page, pgprot_t prot)
+{
+ pgd_t pgd;
+
+ memset(&pgd, RANDOM_NZVALUE, sizeof(pgd_t));
+ WARN_ON(!pgd_same(pgd, pgd));
+}
+
+#if !defined(__PAGETABLE_PMD_FOLDED) && !defined(__ARCH_HAS_4LEVEL_HACK)
+static void pud_clear_tests(pud_t *pudp)
+{
+ pud_t pud = READ_ONCE(*pudp);
+
+ pud = __pud(pud_val(pud) | RANDOM_ORVALUE);
+ WRITE_ONCE(*pudp, pud);
+ pud_clear(pudp);
+ pud = READ_ONCE(*pudp);
+ WARN_ON(!pud_none(pud));
+}
+
+static void pud_populate_tests(struct mm_struct *mm, pud_t *pudp, pmd_t *pmdp)
+{
+ pud_t pud;
+
+ /*
+ * This entry points to next level page table page.
+ * Hence this must not qualify as pud_bad().
+ */
+ pmd_clear(pmdp);
+ pud_clear(pudp);
+ pud_populate(mm, pudp, pmdp);
+ pud = READ_ONCE(*pudp);
+ WARN_ON(pud_bad(pud));
+}
+#else
+static void pud_clear_tests(pud_t *pudp) { }
+static void pud_populate_tests(struct mm_struct *mm, pud_t *pudp, pmd_t *pmdp)
+{
+}
+#endif
+
+#if !defined(__PAGETABLE_PUD_FOLDED) && !defined(__ARCH_HAS_5LEVEL_HACK)
+static void p4d_clear_tests(p4d_t *p4dp)
+{
+ p4d_t p4d = READ_ONCE(*p4dp);
+
+ p4d = __p4d(p4d_val(p4d) | RANDOM_ORVALUE);
+ WRITE_ONCE(*p4dp, p4d);
+ p4d_clear(p4dp);
+ p4d = READ_ONCE(*p4dp);
+ WARN_ON(!p4d_none(p4d));
+}
+
+static void p4d_populate_tests(struct mm_struct *mm, p4d_t *p4dp, pud_t *pudp)
+{
+ p4d_t p4d;
+
+ /*
+ * This entry points to next level page table page.
+ * Hence this must not qualify as p4d_bad().
+ */
+ pud_clear(pudp);
+ p4d_clear(p4dp);
+ p4d_populate(mm, p4dp, pudp);
+ p4d = READ_ONCE(*p4dp);
+ WARN_ON(p4d_bad(p4d));
+}
+#else
+static void p4d_clear_tests(p4d_t *p4dp) { }
+static void p4d_populate_tests(struct mm_struct *mm, p4d_t *p4dp, pud_t *pudp)
+{
+}
+#endif
+
+#ifndef __ARCH_HAS_5LEVEL_HACK
+static void pgd_clear_tests(struct mm_struct *mm, pgd_t *pgdp)
+{
+ pgd_t pgd = READ_ONCE(*pgdp);
+
+ if (mm_p4d_folded(mm))
+ return;
+
+ pgd = __pgd(pgd_val(pgd) | RANDOM_ORVALUE);
+ WRITE_ONCE(*pgdp, pgd);
+ pgd_clear(pgdp);
+ pgd = READ_ONCE(*pgdp);
+ WARN_ON(!pgd_none(pgd));
+}
+
+static void pgd_populate_tests(struct mm_struct *mm, pgd_t *pgdp, p4d_t *p4dp)
+{
+ pgd_t pgd;
+
+ if (mm_p4d_folded(mm))
+ return;
+
+ /*
+ * This entry points to next level page table page.
+ * Hence this must not qualify as pgd_bad().
+ */
+ p4d_clear(p4dp);
+ pgd_clear(pgdp);
+ pgd_populate(mm, pgdp, p4dp);
+ pgd = READ_ONCE(*pgdp);
+ WARN_ON(pgd_bad(pgd));
+}
+#else
+static void pgd_clear_tests(struct mm_struct *mm, pgd_t *pgdp) { }
+static void pgd_populate_tests(struct mm_struct *mm, pgd_t *pgdp, p4d_t *p4dp)
+{
+}
+#endif
+
+static void pte_clear_tests(struct mm_struct *mm, pte_t *ptep)
+{
+ pte_t pte = READ_ONCE(*ptep);
+
+ pte = __pte(pte_val(pte) | RANDOM_ORVALUE);
+ WRITE_ONCE(*ptep, pte);
+ pte_clear(mm, 0, ptep);
+ pte = READ_ONCE(*ptep);
+ WARN_ON(!pte_none(pte));
+}
+
+static void pmd_clear_tests(pmd_t *pmdp)
+{
+ pmd_t pmd = READ_ONCE(*pmdp);
+
+ pmd = __pmd(pmd_val(pmd) | RANDOM_ORVALUE);
+ WRITE_ONCE(*pmdp, pmd);
+ pmd_clear(pmdp);
+ pmd = READ_ONCE(*pmdp);
+ WARN_ON(!pmd_none(pmd));
+}
+
+static void pmd_populate_tests(struct mm_struct *mm, pmd_t *pmdp,
+ pgtable_t pgtable)
+{
+ pmd_t pmd;
+
+ /*
+ * This entry points to next level page table page.
+ * Hence this must not qualify as pmd_bad().
+ */
+ pmd_clear(pmdp);
+ pmd_populate(mm, pmdp, pgtable);
+ pmd = READ_ONCE(*pmdp);
+ WARN_ON(pmd_bad(pmd));
+}
+
+static struct page *alloc_mapped_page(void)
+{
+ struct page *page;
+ gfp_t gfp_mask = GFP_KERNEL | __GFP_ZERO;
+
+ page = alloc_gigantic_page_order(get_order(PUD_SIZE), gfp_mask,
+ first_memory_node, &node_states[N_MEMORY]);
+ if (page) {
+ pud_aligned = true;
+ pmd_aligned = true;
+ return page;
+ }
+
+ page = alloc_pages(gfp_mask, get_order(PMD_SIZE));
+ if (page) {
+ pmd_aligned = true;
+ return page;
+ }
+ return alloc_page(gfp_mask);
+}
+
+static void free_mapped_page(struct page *page)
+{
+ if (pud_aligned) {
+ unsigned long pfn = page_to_pfn(page);
+
+ free_contig_range(pfn, 1ULL << get_order(PUD_SIZE));
+ return;
+ }
+
+ if (pmd_aligned) {
+ int order = get_order(PMD_SIZE);
+
+ free_pages((unsigned long)page_address(page), order);
+ return;
+ }
+ free_page((unsigned long)page_address(page));
+}
+
+static unsigned long get_random_vaddr(void)
+{
+ unsigned long random_vaddr, random_pages, total_user_pages;
+
+ total_user_pages = (TASK_SIZE - FIRST_USER_ADDRESS) / PAGE_SIZE;
+
+ random_pages = get_random_long() % total_user_pages;
+ random_vaddr = FIRST_USER_ADDRESS + random_pages * PAGE_SIZE;
+
+ WARN_ON(random_vaddr > TASK_SIZE);
+ WARN_ON(random_vaddr < FIRST_USER_ADDRESS);
+ return random_vaddr;
+}
+
+static int __init arch_pgtable_tests_init(void)
+{
+ struct mm_struct *mm;
+ struct page *page;
+ pgd_t *pgdp;
+ p4d_t *p4dp, *saved_p4dp;
+ pud_t *pudp, *saved_pudp;
+ pmd_t *pmdp, *saved_pmdp, pmd;
+ pte_t *ptep;
+ pgtable_t saved_ptep;
+ pgprot_t prot;
+ unsigned long vaddr;
+
+ prot = vm_get_page_prot(VMFLAGS);
+ vaddr = get_random_vaddr();
+ mm = mm_alloc();
+ if (!mm) {
+ pr_err("mm_struct allocation failed\n");
+ return 1;
+ }
+
+ page = alloc_mapped_page();
+ if (!page) {
+ pr_err("memory allocation failed\n");
+ return 1;
+ }
+
+ pgdp = pgd_offset(mm, vaddr);
+ p4dp = p4d_alloc(mm, pgdp, vaddr);
+ pudp = pud_alloc(mm, p4dp, vaddr);
+ pmdp = pmd_alloc(mm, pudp, vaddr);
+ ptep = pte_alloc_map(mm, pmdp, vaddr);
+
+ /*
+ * Save all the page table page addresses as the page table
+ * entries will be used for testing with random or garbage
+ * values. These saved addresses will be used for freeing
+ * page table pages.
+ */
+ pmd = READ_ONCE(*pmdp);
+ saved_p4dp = p4d_offset(pgdp, 0UL);
+ saved_pudp = pud_offset(p4dp, 0UL);
+ saved_pmdp = pmd_offset(pudp, 0UL);
+ saved_ptep = pmd_pgtable(pmd);
+
+ pte_basic_tests(page, prot);
+ pmd_basic_tests(page, prot);
+ pud_basic_tests(page, prot);
+ p4d_basic_tests(page, prot);
+ pgd_basic_tests(page, prot);
+
+ pte_clear_tests(mm, ptep);
+ pmd_clear_tests(pmdp);
+ pud_clear_tests(pudp);
+ p4d_clear_tests(p4dp);
+ pgd_clear_tests(mm, pgdp);
+
+ pmd_populate_tests(mm, pmdp, saved_ptep);
+ pud_populate_tests(mm, pudp, saved_pmdp);
+ p4d_populate_tests(mm, p4dp, saved_pudp);
+ pgd_populate_tests(mm, pgdp, saved_p4dp);
+
+ p4d_free(mm, saved_p4dp);
+ pud_free(mm, saved_pudp);
+ pmd_free(mm, saved_pmdp);
+ pte_free(mm, saved_ptep);
+
+ mm_dec_nr_puds(mm);
+ mm_dec_nr_pmds(mm);
+ mm_dec_nr_ptes(mm);
+ __mmdrop(mm);
+
+ free_mapped_page(page);
+ return 0;
+}
+
+static void __exit arch_pgtable_tests_exit(void) { }
+
+module_init(arch_pgtable_tests_init);
+module_exit(arch_pgtable_tests_exit);
+
+MODULE_LICENSE("GPL v2");
+MODULE_AUTHOR("Anshuman Khandual <anshuman.khandual@arm.com>");
+MODULE_DESCRIPTION("Test architecture page table helpers");
--
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
* [PATCH V2 0/2] mm/debug: Add tests for architecture exported page table helpers
From: Anshuman Khandual @ 2019-09-12 6:02 UTC (permalink / raw)
To: linux-mm
Cc: Mark Rutland, linux-ia64, linux-sh, Peter Zijlstra, James Hogan,
Tetsuo Handa, Heiko Carstens, Michal Hocko, Dave Hansen,
Paul Mackerras, sparclinux, Thomas Gleixner, linux-s390,
Michael Ellerman, x86, Russell King - ARM Linux, Matthew Wilcox,
Steven Price, Jason Gunthorpe, Gerald Schaefer, linux-snps-arc,
linux-arm-kernel, Kees Cook, Anshuman Khandual, Masahiro Yamada,
Mark Brown, Kirill A . Shutemov, Dan Williams, Vlastimil Babka,
Christophe Leroy, Sri Krishna chowdary, Ard Biesheuvel,
Greg Kroah-Hartman, linux-mips, Ralf Baechle, linux-kernel,
Paul Burton, Mike Rapoport, Vineet Gupta, Martin Schwidefsky,
Andrew Morton, linuxppc-dev, David S. Miller, Mike Kravetz
This series adds a test validation for architecture exported page table
helpers. Patch in the series adds basic transformation tests at various
levels of the page table. Before that it exports gigantic page allocation
function from HugeTLB.
This test was originally suggested by Catalin during arm64 THP migration
RFC discussion earlier. Going forward it can include more specific tests
with respect to various generic MM functions like THP, HugeTLB etc and
platform specific tests.
https://lore.kernel.org/linux-mm/20190628102003.GA56463@arrakis.emea.arm.com/
Testing:
Successfully build and boot tested on both arm64 and x86 platforms without
any test failing. Only build tested on some other platforms.
But I would really appreciate if folks can help validate this test on other
platforms and report back problems. All suggestions, comments and inputs
welcome. Thank you.
Changes in V2:
- Fixed small typo error in MODULE_DESCRIPTION()
- Fixed m64k build problems for lvalue concerns in pmd_xxx_tests()
- Fixed dynamic page table level folding problems on x86 as per Kirril
- Fixed second pointers during pxx_populate_tests() per Kirill and Gerald
- Allocate and free pte table with pte_alloc_one/pte_free per Kirill
- Modified pxx_clear_tests() to accommodate s390 lower 12 bits situation
- Changed RANDOM_NZVALUE value from 0xbe to 0xff
- Changed allocation, usage, free sequence for saved_ptep
- Renamed VMA_FLAGS as VMFLAGS
- Implemented a new method for random vaddr generation
- Implemented some other cleanups
- Dropped extern reference to mm_alloc()
- Created and exported new alloc_gigantic_page_order()
- Dropped the custom allocator and used new alloc_gigantic_page_order()
Changes in V1:
https://lore.kernel.org/linux-mm/1567497706-8649-1-git-send-email-anshuman.khandual@arm.com/
- Added fallback mechanism for PMD aligned memory allocation failure
Changes in RFC V2:
https://lore.kernel.org/linux-mm/1565335998-22553-1-git-send-email-anshuman.khandual@arm.com/T/#u
- Moved test module and it's config from lib/ to mm/
- Renamed config TEST_ARCH_PGTABLE as DEBUG_ARCH_PGTABLE_TEST
- Renamed file from test_arch_pgtable.c to arch_pgtable_test.c
- Added relevant MODULE_DESCRIPTION() and MODULE_AUTHOR() details
- Dropped loadable module config option
- Basic tests now use memory blocks with required size and alignment
- PUD aligned memory block gets allocated with alloc_contig_range()
- If PUD aligned memory could not be allocated it falls back on PMD aligned
memory block from page allocator and pud_* tests are skipped
- Clear and populate tests now operate on real in memory page table entries
- Dummy mm_struct gets allocated with mm_alloc()
- Dummy page table entries get allocated with [pud|pmd|pte]_alloc_[map]()
- Simplified [p4d|pgd]_basic_tests(), now has random values in the entries
Original RFC V1:
https://lore.kernel.org/linux-mm/1564037723-26676-1-git-send-email-anshuman.khandual@arm.com/
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Vlastimil Babka <vbabka@suse.cz>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Mike Rapoport <rppt@linux.vnet.ibm.com>
Cc: Jason Gunthorpe <jgg@ziepe.ca>
Cc: Dan Williams <dan.j.williams@intel.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Michal Hocko <mhocko@kernel.org>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Mark Brown <broonie@kernel.org>
Cc: Steven Price <Steven.Price@arm.com>
Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Cc: Masahiro Yamada <yamada.masahiro@socionext.com>
Cc: Kees Cook <keescook@chromium.org>
Cc: Tetsuo Handa <penguin-kernel@i-love.sakura.ne.jp>
Cc: Matthew Wilcox <willy@infradead.org>
Cc: Sri Krishna chowdary <schowdary@nvidia.com>
Cc: Dave Hansen <dave.hansen@intel.com>
Cc: Russell King - ARM Linux <linux@armlinux.org.uk>
Cc: Michael Ellerman <mpe@ellerman.id.au>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Martin Schwidefsky <schwidefsky@de.ibm.com>
Cc: Heiko Carstens <heiko.carstens@de.ibm.com>
Cc: "David S. Miller" <davem@davemloft.net>
Cc: Vineet Gupta <vgupta@synopsys.com>
Cc: James Hogan <jhogan@kernel.org>
Cc: Paul Burton <paul.burton@mips.com>
Cc: Ralf Baechle <ralf@linux-mips.org>
Cc: Kirill A. Shutemov <kirill@shutemov.name>
Cc: Gerald Schaefer <gerald.schaefer@de.ibm.com>
Cc: Christophe Leroy <christophe.leroy@c-s.fr>
Cc: Mike Kravetz <mike.kravetz@oracle.com>
Cc: linux-snps-arc@lists.infradead.org
Cc: linux-mips@vger.kernel.org
Cc: linux-arm-kernel@lists.infradead.org
Cc: linux-ia64@vger.kernel.org
Cc: linuxppc-dev@lists.ozlabs.org
Cc: linux-s390@vger.kernel.org
Cc: linux-sh@vger.kernel.org
Cc: sparclinux@vger.kernel.org
Cc: x86@kernel.org
Cc: linux-kernel@vger.kernel.org
Anshuman Khandual (2):
mm/hugetlb: Make alloc_gigantic_page() available for general use
mm/pgtable/debug: Add test validating architecture page table helpers
arch/x86/include/asm/pgtable_64_types.h | 2 +
include/linux/hugetlb.h | 9 +
mm/Kconfig.debug | 14 +
mm/Makefile | 1 +
mm/arch_pgtable_test.c | 429 ++++++++++++++++++++++++
mm/hugetlb.c | 24 +-
6 files changed, 477 insertions(+), 2 deletions(-)
create mode 100644 mm/arch_pgtable_test.c
--
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
* [PATCH 3/3] arm64: kexec_file: add crash dump support
From: AKASHI Takahiro @ 2019-09-12 6:01 UTC (permalink / raw)
To: catalin.marinas, will.deacon, robh+dt, frowand.list
Cc: kexec, james.morse, linux-kernel, linux-arm-kernel,
AKASHI Takahiro
In-Reply-To: <20190912060150.10818-1-takahiro.akashi@linaro.org>
Enabling crash dump (kdump) includes
* prepare contents of ELF header of a core dump file, /proc/vmcore,
using crash_prepare_elf64_headers(), and
* add two device tree properties, "linux,usable-memory-range" and
"linux,elfcorehdr", which represent respectively a memory range
to be used by crash dump kernel and the header's location
Signed-off-by: AKASHI Takahiro <takahiro.akashi@linaro.org>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: Will Deacon <will.deacon@arm.com>
Reviewed-by: James Morse <james.morse@arm.com>
---
arch/arm64/include/asm/kexec.h | 4 +
arch/arm64/kernel/kexec_image.c | 4 -
arch/arm64/kernel/machine_kexec_file.c | 105 ++++++++++++++++++++++++-
3 files changed, 106 insertions(+), 7 deletions(-)
diff --git a/arch/arm64/include/asm/kexec.h b/arch/arm64/include/asm/kexec.h
index 12a561a54128..d24b527e8c00 100644
--- a/arch/arm64/include/asm/kexec.h
+++ b/arch/arm64/include/asm/kexec.h
@@ -96,6 +96,10 @@ static inline void crash_post_resume(void) {}
struct kimage_arch {
void *dtb;
unsigned long dtb_mem;
+ /* Core ELF header buffer */
+ void *elf_headers;
+ unsigned long elf_headers_mem;
+ unsigned long elf_headers_sz;
};
extern const struct kexec_file_ops kexec_image_ops;
diff --git a/arch/arm64/kernel/kexec_image.c b/arch/arm64/kernel/kexec_image.c
index 2514fd6f12cb..60cedfa9529b 100644
--- a/arch/arm64/kernel/kexec_image.c
+++ b/arch/arm64/kernel/kexec_image.c
@@ -47,10 +47,6 @@ static void *image_load(struct kimage *image,
struct kexec_segment *kernel_segment;
int ret;
- /* We don't support crash kernels yet. */
- if (image->type == KEXEC_TYPE_CRASH)
- return ERR_PTR(-EOPNOTSUPP);
-
/*
* We require a kernel with an unambiguous Image header. Per
* Documentation/arm64/booting.rst, this is the case when image_size
diff --git a/arch/arm64/kernel/machine_kexec_file.c b/arch/arm64/kernel/machine_kexec_file.c
index 58871333737a..f5276e27c12b 100644
--- a/arch/arm64/kernel/machine_kexec_file.c
+++ b/arch/arm64/kernel/machine_kexec_file.c
@@ -17,12 +17,15 @@
#include <linux/memblock.h>
#include <linux/of_fdt.h>
#include <linux/random.h>
+#include <linux/slab.h>
#include <linux/string.h>
#include <linux/types.h>
#include <linux/vmalloc.h>
#include <asm/byteorder.h>
/* relevant device tree properties */
+#define FDT_PROP_KEXEC_ELFHDR "linux,elfcorehdr"
+#define FDT_PROP_MEM_RANGE "linux,usable-memory-range"
#define FDT_PROP_INITRD_START "linux,initrd-start"
#define FDT_PROP_INITRD_END "linux,initrd-end"
#define FDT_PROP_BOOTARGS "bootargs"
@@ -38,6 +41,10 @@ int arch_kimage_file_post_load_cleanup(struct kimage *image)
vfree(image->arch.dtb);
image->arch.dtb = NULL;
+ vfree(image->arch.elf_headers);
+ image->arch.elf_headers = NULL;
+ image->arch.elf_headers_sz = 0;
+
return kexec_image_post_load_cleanup_default(image);
}
@@ -53,6 +60,31 @@ static int setup_dtb(struct kimage *image,
off = ret;
+ ret = fdt_delprop(dtb, off, FDT_PROP_KEXEC_ELFHDR);
+ if (ret && ret != -FDT_ERR_NOTFOUND)
+ goto out;
+ ret = fdt_delprop(dtb, off, FDT_PROP_MEM_RANGE);
+ if (ret && ret != -FDT_ERR_NOTFOUND)
+ goto out;
+
+ if (image->type == KEXEC_TYPE_CRASH) {
+ /* add linux,elfcorehdr */
+ ret = fdt_appendprop_addrrange(dtb, 0, off,
+ FDT_PROP_KEXEC_ELFHDR,
+ image->arch.elf_headers_mem,
+ image->arch.elf_headers_sz);
+ if (ret)
+ return (ret == -FDT_ERR_NOSPACE ? -ENOMEM : -EINVAL);
+
+ /* add linux,usable-memory-range */
+ ret = fdt_appendprop_addrrange(dtb, 0, off,
+ FDT_PROP_MEM_RANGE,
+ crashk_res.start,
+ crashk_res.end - crashk_res.start + 1);
+ if (ret)
+ return (ret == -FDT_ERR_NOSPACE ? -ENOMEM : -EINVAL);
+ }
+
/* add bootargs */
if (cmdline) {
ret = fdt_setprop_string(dtb, off, FDT_PROP_BOOTARGS, cmdline);
@@ -110,7 +142,8 @@ static int setup_dtb(struct kimage *image,
}
/*
- * More space needed so that we can add initrd, bootargs and kaslr-seed.
+ * More space needed so that we can add initrd, bootargs, kaslr-seed,
+ * userable-memory-range and elfcorehdr.
*/
#define DTB_EXTRA_SPACE 0x1000
@@ -158,6 +191,43 @@ static int create_dtb(struct kimage *image,
}
}
+static int prepare_elf_headers(void **addr, unsigned long *sz)
+{
+ struct crash_mem *cmem;
+ unsigned int nr_ranges;
+ int ret;
+ u64 i;
+ phys_addr_t start, end;
+
+ nr_ranges = 1; /* for exclusion of crashkernel region */
+ for_each_mem_range(i, &memblock.memory, NULL, NUMA_NO_NODE,
+ MEMBLOCK_NONE, &start, &end, NULL)
+ nr_ranges++;
+
+ cmem = kmalloc(sizeof(struct crash_mem) +
+ sizeof(struct crash_mem_range) * nr_ranges, GFP_KERNEL);
+ if (!cmem)
+ return -ENOMEM;
+
+ cmem->max_nr_ranges = nr_ranges;
+ cmem->nr_ranges = 0;
+ for_each_mem_range(i, &memblock.memory, NULL, NUMA_NO_NODE,
+ MEMBLOCK_NONE, &start, &end, NULL) {
+ cmem->ranges[cmem->nr_ranges].start = start;
+ cmem->ranges[cmem->nr_ranges].end = end - 1;
+ cmem->nr_ranges++;
+ }
+
+ /* Exclude crashkernel region */
+ ret = crash_exclude_mem_range(cmem, crashk_res.start, crashk_res.end);
+
+ if (!ret)
+ ret = crash_prepare_elf64_headers(cmem, true, addr, sz);
+
+ kfree(cmem);
+ return ret;
+}
+
int load_other_segments(struct kimage *image,
unsigned long kernel_load_addr,
unsigned long kernel_size,
@@ -165,14 +235,43 @@ int load_other_segments(struct kimage *image,
char *cmdline)
{
struct kexec_buf kbuf;
- void *dtb = NULL;
- unsigned long initrd_load_addr = 0, dtb_len;
+ void *headers, *dtb = NULL;
+ unsigned long headers_sz, initrd_load_addr = 0, dtb_len;
int ret = 0;
kbuf.image = image;
/* not allocate anything below the kernel */
kbuf.buf_min = kernel_load_addr + kernel_size;
+ /* load elf core header */
+ if (image->type == KEXEC_TYPE_CRASH) {
+ ret = prepare_elf_headers(&headers, &headers_sz);
+ if (ret) {
+ pr_err("Preparing elf core header failed\n");
+ goto out_err;
+ }
+
+ kbuf.buffer = headers;
+ kbuf.bufsz = headers_sz;
+ kbuf.mem = 0;
+ kbuf.memsz = headers_sz;
+ kbuf.buf_align = SZ_64K; /* largest supported page size */
+ kbuf.buf_max = ULONG_MAX;
+ kbuf.top_down = true;
+
+ ret = kexec_add_buffer(&kbuf);
+ if (ret) {
+ vfree(headers);
+ goto out_err;
+ }
+ image->arch.elf_headers = headers;
+ image->arch.elf_headers_mem = kbuf.mem;
+ image->arch.elf_headers_sz = headers_sz;
+
+ pr_debug("Loaded elf core header at 0x%lx bufsz=0x%lx memsz=0x%lx\n",
+ image->arch.elf_headers_mem, headers_sz, headers_sz);
+ }
+
/* load initrd */
if (initrd) {
kbuf.buffer = initrd;
--
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
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