From e74673120b6b9497f1e044b3cf75d2fb5ed61fc3 Mon Sep 17 00:00:00 2001 From: Marek Szyprowski Date: Mon, 18 Feb 2019 15:34:09 +0100 Subject: [PATCH 1/8] ARM: exynos: Move Exynos542x CPU state reset to pm_prepare() Reset the CPU state entry in sysram in pm_prepare() callback. That entry doesn't need to be reset for every suspended CPU, so make it symmetic with the code, which restores it in pm_resume() callback. Tested on Samsung Chromebook2 Pit (Exynos5420) and Pi (Exynos5800) boards. Signed-off-by: Marek Szyprowski Signed-off-by: Krzysztof Kozlowski --- arch/arm/mach-exynos/suspend.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/arch/arm/mach-exynos/suspend.c b/arch/arm/mach-exynos/suspend.c index 0850505ac78b..c1e082ab2a1e 100644 --- a/arch/arm/mach-exynos/suspend.c +++ b/arch/arm/mach-exynos/suspend.c @@ -265,8 +265,6 @@ static int exynos5420_cpu_suspend(unsigned long arg) unsigned int cluster = MPIDR_AFFINITY_LEVEL(mpidr, 1); unsigned int cpu = MPIDR_AFFINITY_LEVEL(mpidr, 0); - writel_relaxed(0x0, pm_state.sysram_base + EXYNOS5420_CPU_STATE); - if (IS_ENABLED(CONFIG_EXYNOS5420_MCPM)) { mcpm_set_entry_vector(cpu, cluster, exynos_cpu_resume); mcpm_cpu_suspend(); @@ -341,6 +339,7 @@ static void exynos5420_pm_prepare(void) */ pm_state.cpu_state = readl_relaxed(pm_state.sysram_base + EXYNOS5420_CPU_STATE); + writel_relaxed(0x0, pm_state.sysram_base + EXYNOS5420_CPU_STATE); exynos_pm_enter_sleep_mode(); From 47efaf6ba6971e669f198e8e60fe6e674b5020ac Mon Sep 17 00:00:00 2001 From: Marek Szyprowski Date: Mon, 18 Feb 2019 15:34:10 +0100 Subject: [PATCH 2/8] ARM: exynos: Add Exynos SMC values for secure memory write Add defines for the (secure)-memory write for Exynos Secure Monitor Call. The values comes from the vendor kernel. Signed-off-by: Marek Szyprowski Signed-off-by: Krzysztof Kozlowski --- arch/arm/mach-exynos/smc.h | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/arch/arm/mach-exynos/smc.h b/arch/arm/mach-exynos/smc.h index f355185d4239..98832e50852d 100644 --- a/arch/arm/mach-exynos/smc.h +++ b/arch/arm/mach-exynos/smc.h @@ -25,6 +25,13 @@ #define SMC_CMD_L2X0INVALL (-24) #define SMC_CMD_L2X0DEBUG (-25) +/* For Accessing CP15/SFR (General) */ +#define SMC_CMD_REG (-101) + +/* defines for SMC_CMD_REG */ +#define SMC_REG_CLASS_SFR_W (0x1 << 30) +#define SMC_REG_ID_SFR_W(addr) (SMC_REG_CLASS_SFR_W | ((addr) >> 2)) + #ifndef __ASSEMBLY__ extern void exynos_smc(u32 cmd, u32 arg1, u32 arg2, u32 arg3); From 3a1f2f38fb82b7a3bc7351d7e38df5a1e9c901d2 Mon Sep 17 00:00:00 2001 From: Joonyoung Shim Date: Mon, 18 Feb 2019 15:34:11 +0100 Subject: [PATCH 3/8] ARM: exynos: Add CPU state management for Exynos542x under secure firmware Add required CPU state management done via secure monitor call for Exynos542x running unsed Secure Firmware. Signed-off-by: Joonyoung Shim [mszyprow: rewrote code to use defines and sysram base address instead of the magic numbers, added second smc call in pm_resume, rephrased subject and commit message] Signed-off-by: Marek Szyprowski Signed-off-by: Krzysztof Kozlowski --- arch/arm/mach-exynos/common.h | 1 + arch/arm/mach-exynos/exynos.c | 3 +++ arch/arm/mach-exynos/suspend.c | 19 +++++++++++++++++-- 3 files changed, 21 insertions(+), 2 deletions(-) diff --git a/arch/arm/mach-exynos/common.h b/arch/arm/mach-exynos/common.h index 1b8699e94098..c93356a8d662 100644 --- a/arch/arm/mach-exynos/common.h +++ b/arch/arm/mach-exynos/common.h @@ -91,6 +91,7 @@ extern u32 cp15_save_power; extern void __iomem *sysram_ns_base_addr; extern void __iomem *sysram_base_addr; +extern phys_addr_t sysram_base_phys; extern void __iomem *pmu_base_addr; void exynos_sysram_init(void); diff --git a/arch/arm/mach-exynos/exynos.c b/arch/arm/mach-exynos/exynos.c index 865dcc4c3181..9aa483366ebc 100644 --- a/arch/arm/mach-exynos/exynos.c +++ b/arch/arm/mach-exynos/exynos.c @@ -33,6 +33,7 @@ static struct platform_device exynos_cpuidle = { }; void __iomem *sysram_base_addr __ro_after_init; +phys_addr_t sysram_base_phys __ro_after_init; void __iomem *sysram_ns_base_addr __ro_after_init; void __init exynos_sysram_init(void) @@ -43,6 +44,8 @@ void __init exynos_sysram_init(void) if (!of_device_is_available(node)) continue; sysram_base_addr = of_iomap(node, 0); + sysram_base_phys = of_translate_address(node, + of_get_address(node, 0, NULL, NULL)); break; } diff --git a/arch/arm/mach-exynos/suspend.c b/arch/arm/mach-exynos/suspend.c index c1e082ab2a1e..42f36843892e 100644 --- a/arch/arm/mach-exynos/suspend.c +++ b/arch/arm/mach-exynos/suspend.c @@ -31,6 +31,7 @@ #include #include "common.h" +#include "smc.h" #define REG_TABLE_END (-1U) @@ -62,6 +63,8 @@ struct exynos_pm_state { int cpu_state; unsigned int pmu_spare3; void __iomem *sysram_base; + phys_addr_t sysram_phys; + bool secure_firmware; }; static const struct exynos_pm_data *pm_data __ro_after_init; @@ -340,6 +343,10 @@ static void exynos5420_pm_prepare(void) pm_state.cpu_state = readl_relaxed(pm_state.sysram_base + EXYNOS5420_CPU_STATE); writel_relaxed(0x0, pm_state.sysram_base + EXYNOS5420_CPU_STATE); + if (pm_state.secure_firmware) + exynos_smc(SMC_CMD_REG, SMC_REG_ID_SFR_W(pm_state.sysram_phys + + EXYNOS5420_CPU_STATE), + 0, 0); exynos_pm_enter_sleep_mode(); @@ -459,6 +466,11 @@ static void exynos5420_pm_resume(void) /* Restore the sysram cpu state register */ writel_relaxed(pm_state.cpu_state, pm_state.sysram_base + EXYNOS5420_CPU_STATE); + if (pm_state.secure_firmware) + exynos_smc(SMC_CMD_REG, + SMC_REG_ID_SFR_W(pm_state.sysram_phys + + EXYNOS5420_CPU_STATE), + EXYNOS_AFTR_MAGIC, 0); pmu_raw_writel(EXYNOS5420_USE_STANDBY_WFI_ALL, S5P_CENTRAL_SEQ_OPTION); @@ -658,8 +670,11 @@ void __init exynos_pm_init(void) * Applicable as of now only to Exynos542x. If booted under secure * firmware, the non-secure region of sysram should be used. */ - if (exynos_secure_firmware_available()) + if (exynos_secure_firmware_available()) { + pm_state.sysram_phys = sysram_base_phys; pm_state.sysram_base = sysram_ns_base_addr; - else + pm_state.secure_firmware = true; + } else { pm_state.sysram_base = sysram_base_addr; + } } From 4d8e3e951a856777720272ce27f2c738a3eeef8c Mon Sep 17 00:00:00 2001 From: Marek Szyprowski Date: Mon, 18 Feb 2019 15:34:12 +0100 Subject: [PATCH 4/8] ARM: exynos: Fix undefined instruction during Exynos5422 resume During early system resume on Exynos5422 with performance counters enabled the following kernel oops happens: Internal error: Oops - undefined instruction: 0 [#1] PREEMPT SMP ARM Modules linked in: CPU: 0 PID: 1433 Comm: bash Tainted: G W 5.0.0-rc5-next-20190208-00023-gd5fb5a8a13e6-dirty #5480 Hardware name: SAMSUNG EXYNOS (Flattened Device Tree) ... Flags: nZCv IRQs off FIQs off Mode SVC_32 ISA ARM Segment none Control: 10c5387d Table: 4451006a DAC: 00000051 Process bash (pid: 1433, stack limit = 0xb7e0e22f) ... (reset_ctrl_regs) from [] (dbg_cpu_pm_notify+0x1c/0x24) (dbg_cpu_pm_notify) from [] (notifier_call_chain+0x44/0x84) (notifier_call_chain) from [] (__atomic_notifier_call_chain+0x7c/0x128) (__atomic_notifier_call_chain) from [] (cpu_pm_notify+0x30/0x54) (cpu_pm_notify) from [] (syscore_resume+0x98/0x3f4) (syscore_resume) from [] (suspend_devices_and_enter+0x97c/0xe74) (suspend_devices_and_enter) from [] (pm_suspend+0x770/0xc04) (pm_suspend) from [] (state_store+0x6c/0xcc) (state_store) from [] (kobj_attr_store+0x14/0x20) (kobj_attr_store) from [] (sysfs_kf_write+0x4c/0x50) (sysfs_kf_write) from [] (kernfs_fop_write+0xfc/0x1e0) (kernfs_fop_write) from [] (__vfs_write+0x2c/0x160) (__vfs_write) from [] (vfs_write+0xa4/0x16c) (vfs_write) from [] (ksys_write+0x40/0x8c) (ksys_write) from [] (ret_fast_syscall+0x0/0x28) Undefined instruction is triggered during CP14 reset, because bits: #16 (Secure privileged invasive debug disabled) and #17 (Secure privileged noninvasive debug disable) are set in DSCR. Those bits depend on SPNIDEN and SPIDEN lines, which are provided by Secure JTAG hardware block. That block in turn is powered from cluster 0 (big/Eagle), but the Exynos5422 boots on cluster 1 (LITTLE/KFC). To fix this issue it is enough to turn on the power on the cluster 0 for a while. This lets the Secure JTAG block to propagate the needed signals to LITTLE/KFC cores and change their DSCR. Signed-off-by: Marek Szyprowski Signed-off-by: Krzysztof Kozlowski --- arch/arm/mach-exynos/suspend.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/arch/arm/mach-exynos/suspend.c b/arch/arm/mach-exynos/suspend.c index 42f36843892e..c521af625e40 100644 --- a/arch/arm/mach-exynos/suspend.c +++ b/arch/arm/mach-exynos/suspend.c @@ -450,8 +450,27 @@ early_wakeup: static void exynos5420_prepare_pm_resume(void) { + unsigned int mpidr, cluster; + + mpidr = read_cpuid_mpidr(); + cluster = MPIDR_AFFINITY_LEVEL(mpidr, 1); + if (IS_ENABLED(CONFIG_EXYNOS5420_MCPM)) WARN_ON(mcpm_cpu_powered_up()); + + if (IS_ENABLED(CONFIG_HW_PERF_EVENTS) && cluster != 0) { + /* + * When system is resumed on the LITTLE/KFC core (cluster 1), + * the DSCR is not properly updated until the power is turned + * on also for the cluster 0. Enable it for a while to + * propagate the SPNIDEN and SPIDEN signals from Secure JTAG + * block and avoid undefined instruction issue on CP14 reset. + */ + pmu_raw_writel(S5P_CORE_LOCAL_PWR_EN, + EXYNOS_COMMON_CONFIGURATION(0)); + pmu_raw_writel(0, + EXYNOS_COMMON_CONFIGURATION(0)); + } } static void exynos5420_pm_resume(void) From 629266bf7229cd6a550075f5961f95607b823b59 Mon Sep 17 00:00:00 2001 From: Wen Yang Date: Tue, 5 Mar 2019 19:33:54 +0800 Subject: [PATCH 5/8] ARM: exynos: Fix a leaked reference by adding missing of_node_put The call to of_get_next_child returns a node pointer with refcount incremented thus it must be explicitly decremented after the last usage. Detected by coccinelle with warnings like: arch/arm/mach-exynos/firmware.c:201:2-8: ERROR: missing of_node_put; acquired a node pointer with refcount incremented on line 193, but without a corresponding object release within this function. Cc: stable@vger.kernel.org Signed-off-by: Wen Yang Signed-off-by: Krzysztof Kozlowski --- arch/arm/mach-exynos/firmware.c | 1 + arch/arm/mach-exynos/suspend.c | 2 ++ 2 files changed, 3 insertions(+) diff --git a/arch/arm/mach-exynos/firmware.c b/arch/arm/mach-exynos/firmware.c index d602e3bf3f96..2eaf2dbb8e81 100644 --- a/arch/arm/mach-exynos/firmware.c +++ b/arch/arm/mach-exynos/firmware.c @@ -196,6 +196,7 @@ bool __init exynos_secure_firmware_available(void) return false; addr = of_get_address(nd, 0, NULL, NULL); + of_node_put(nd); if (!addr) { pr_err("%s: No address specified.\n", __func__); return false; diff --git a/arch/arm/mach-exynos/suspend.c b/arch/arm/mach-exynos/suspend.c index c521af625e40..64a57e703fc2 100644 --- a/arch/arm/mach-exynos/suspend.c +++ b/arch/arm/mach-exynos/suspend.c @@ -669,8 +669,10 @@ void __init exynos_pm_init(void) if (WARN_ON(!of_find_property(np, "interrupt-controller", NULL))) { pr_warn("Outdated DT detected, suspend/resume will NOT work\n"); + of_node_put(np); return; } + of_node_put(np); pm_data = (const struct exynos_pm_data *) match->data; From 98a3308ea864afa1e42ae546ddbe5e4641f7716c Mon Sep 17 00:00:00 2001 From: Marek Szyprowski Date: Tue, 26 Mar 2019 15:03:59 +0100 Subject: [PATCH 6/8] ARM: exynos: Fix infinite loops on CPU powerup failure Add timeout to infinite loops during the CPU powerup procedures. It is better to report an error instead of busylooping for infinite time in case of failure. Signed-off-by: Marek Szyprowski Signed-off-by: Krzysztof Kozlowski --- arch/arm/mach-exynos/mcpm-exynos.c | 13 ++++++++++++- arch/arm/mach-exynos/platsmp.c | 9 ++++++++- 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/arch/arm/mach-exynos/mcpm-exynos.c b/arch/arm/mach-exynos/mcpm-exynos.c index 72bc035bedbe..9a681b421ae1 100644 --- a/arch/arm/mach-exynos/mcpm-exynos.c +++ b/arch/arm/mach-exynos/mcpm-exynos.c @@ -75,14 +75,25 @@ static int exynos_cpu_powerup(unsigned int cpu, unsigned int cluster) */ if (cluster && cluster == MPIDR_AFFINITY_LEVEL(cpu_logical_map(0), 1)) { + unsigned int timeout = 16; + /* * Before we reset the Little cores, we should wait * the SPARE2 register is set to 1 because the init * codes of the iROM will set the register after * initialization. */ - while (!pmu_raw_readl(S5P_PMU_SPARE2)) + while (timeout && !pmu_raw_readl(S5P_PMU_SPARE2)) { + timeout--; udelay(10); + } + + if (timeout == 0) { + pr_err("cpu %u cluster %u powerup failed\n", + cpu, cluster); + exynos_cpu_power_down(cpunr); + return -ETIMEDOUT; + } pmu_raw_writel(EXYNOS5420_KFC_CORE_RESET(cpu), EXYNOS_SWRESET); diff --git a/arch/arm/mach-exynos/platsmp.c b/arch/arm/mach-exynos/platsmp.c index abcac6164233..0cbbae8bf1f8 100644 --- a/arch/arm/mach-exynos/platsmp.c +++ b/arch/arm/mach-exynos/platsmp.c @@ -214,13 +214,20 @@ static inline void __iomem *cpu_boot_reg(int cpu) */ void exynos_core_restart(u32 core_id) { + unsigned int timeout = 16; u32 val; if (!of_machine_is_compatible("samsung,exynos3250")) return; - while (!pmu_raw_readl(S5P_PMU_SPARE2)) + while (timeout && !pmu_raw_readl(S5P_PMU_SPARE2)) { + timeout--; udelay(10); + } + if (timeout == 0) { + pr_err("cpu core %u restart failed\n", core_id); + return; + } udelay(10); val = pmu_raw_readl(EXYNOS_ARM_CORE_STATUS(core_id)); From 2997520c2d4e4d112e7b237bfa5a17a968ffc4bf Mon Sep 17 00:00:00 2001 From: Marek Szyprowski Date: Tue, 9 Apr 2019 11:56:02 +0200 Subject: [PATCH 7/8] ARM: exynos: Set MCPM as mandatory for Exynos542x/5800 SoCs Support for Exynos5420/5422/5800 SoCs requires MCPM to properly boot all CPU cores on all currectly supported platforms: Peach Pit (Exynos5420), Odroid XU3/XU3lite/XU4/HC1 (Exynos5422) and Peach Pi (Exynos5800). Without it some CPU cores fail to come online. Remove then the ability to disable MCPM and make it mandatory when Exynos542x/5800 support is enabled. Signed-off-by: Marek Szyprowski Signed-off-by: Krzysztof Kozlowski --- arch/arm/configs/exynos_defconfig | 1 - arch/arm/configs/multi_v7_defconfig | 1 - arch/arm/mach-exynos/Kconfig | 12 +++--------- arch/arm/mach-exynos/Makefile | 2 +- arch/arm/mach-exynos/suspend.c | 6 +++--- 5 files changed, 7 insertions(+), 15 deletions(-) diff --git a/arch/arm/configs/exynos_defconfig b/arch/arm/configs/exynos_defconfig index d635edfb6ff2..c95c54284da2 100644 --- a/arch/arm/configs/exynos_defconfig +++ b/arch/arm/configs/exynos_defconfig @@ -9,7 +9,6 @@ CONFIG_MODULE_UNLOAD=y CONFIG_PARTITION_ADVANCED=y CONFIG_ARCH_EXYNOS=y CONFIG_ARCH_EXYNOS3=y -CONFIG_EXYNOS5420_MCPM=y CONFIG_SMP=y CONFIG_BIG_LITTLE=y CONFIG_NR_CPUS=8 diff --git a/arch/arm/configs/multi_v7_defconfig b/arch/arm/configs/multi_v7_defconfig index c75051b9392c..e4b5fd46fdef 100644 --- a/arch/arm/configs/multi_v7_defconfig +++ b/arch/arm/configs/multi_v7_defconfig @@ -33,7 +33,6 @@ CONFIG_MACH_BERLIN_BG2CD=y CONFIG_MACH_BERLIN_BG2Q=y CONFIG_ARCH_DIGICOLOR=y CONFIG_ARCH_EXYNOS=y -CONFIG_EXYNOS5420_MCPM=y CONFIG_ARCH_HIGHBANK=y CONFIG_ARCH_HISI=y CONFIG_ARCH_HI3xxx=y diff --git a/arch/arm/mach-exynos/Kconfig b/arch/arm/mach-exynos/Kconfig index b40963cf91c7..1c518b8ee520 100644 --- a/arch/arm/mach-exynos/Kconfig +++ b/arch/arm/mach-exynos/Kconfig @@ -106,21 +106,15 @@ config SOC_EXYNOS5420 bool "SAMSUNG EXYNOS5420" default y depends on ARCH_EXYNOS5 + select MCPM if SMP + select ARM_CCI400_PORT_CTRL + select ARM_CPU_SUSPEND config SOC_EXYNOS5800 bool "SAMSUNG EXYNOS5800" default y depends on SOC_EXYNOS5420 -config EXYNOS5420_MCPM - bool "Exynos5420 Multi-Cluster PM support" - depends on MCPM && SOC_EXYNOS5420 - select ARM_CCI400_PORT_CTRL - select ARM_CPU_SUSPEND - help - This is needed to provide CPU and cluster power management - on Exynos5420 implementing big.LITTLE. - config EXYNOS_CPU_SUSPEND bool select ARM_CPU_SUSPEND diff --git a/arch/arm/mach-exynos/Makefile b/arch/arm/mach-exynos/Makefile index cd00c82a1add..264dbaa89c3d 100644 --- a/arch/arm/mach-exynos/Makefile +++ b/arch/arm/mach-exynos/Makefile @@ -18,5 +18,5 @@ plus_sec := $(call as-instr,.arch_extension sec,+sec) AFLAGS_exynos-smc.o :=-Wa,-march=armv7-a$(plus_sec) AFLAGS_sleep.o :=-Wa,-march=armv7-a$(plus_sec) -obj-$(CONFIG_EXYNOS5420_MCPM) += mcpm-exynos.o +obj-$(CONFIG_MCPM) += mcpm-exynos.o CFLAGS_mcpm-exynos.o += -march=armv7-a diff --git a/arch/arm/mach-exynos/suspend.c b/arch/arm/mach-exynos/suspend.c index 64a57e703fc2..be122af0de8f 100644 --- a/arch/arm/mach-exynos/suspend.c +++ b/arch/arm/mach-exynos/suspend.c @@ -268,7 +268,7 @@ static int exynos5420_cpu_suspend(unsigned long arg) unsigned int cluster = MPIDR_AFFINITY_LEVEL(mpidr, 1); unsigned int cpu = MPIDR_AFFINITY_LEVEL(mpidr, 0); - if (IS_ENABLED(CONFIG_EXYNOS5420_MCPM)) { + if (IS_ENABLED(CONFIG_MCPM)) { mcpm_set_entry_vector(cpu, cluster, exynos_cpu_resume); mcpm_cpu_suspend(); } @@ -351,7 +351,7 @@ static void exynos5420_pm_prepare(void) exynos_pm_enter_sleep_mode(); /* ensure at least INFORM0 has the resume address */ - if (IS_ENABLED(CONFIG_EXYNOS5420_MCPM)) + if (IS_ENABLED(CONFIG_MCPM)) pmu_raw_writel(__pa_symbol(mcpm_entry_point), S5P_INFORM0); tmp = pmu_raw_readl(EXYNOS_L2_OPTION(0)); @@ -455,7 +455,7 @@ static void exynos5420_prepare_pm_resume(void) mpidr = read_cpuid_mpidr(); cluster = MPIDR_AFFINITY_LEVEL(mpidr, 1); - if (IS_ENABLED(CONFIG_EXYNOS5420_MCPM)) + if (IS_ENABLED(CONFIG_MCPM)) WARN_ON(mcpm_cpu_powered_up()); if (IS_ENABLED(CONFIG_HW_PERF_EVENTS) && cluster != 0) { From 7676e667c841375b41d9438b559756141aa93d0e Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Fri, 12 Apr 2019 09:14:58 +0200 Subject: [PATCH 8/8] ARM: s3c64xx: Tidy up handling of regulator GPIO lookups Rather than unconditionally registering the GPIO lookup table only do so for devices that require it. Signed-off-by: Charles Keepax [Fixed up to also handle wm5102 and wm5102 reva] Signed-off-by: Linus Walleij Signed-off-by: Krzysztof Kozlowski --- arch/arm/mach-s3c64xx/mach-crag6410-module.c | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/arch/arm/mach-s3c64xx/mach-crag6410-module.c b/arch/arm/mach-s3c64xx/mach-crag6410-module.c index 76c4855a03bc..937d0a83f8fd 100644 --- a/arch/arm/mach-s3c64xx/mach-crag6410-module.c +++ b/arch/arm/mach-s3c64xx/mach-crag6410-module.c @@ -328,6 +328,8 @@ static const struct { int num_i2c_devs; const struct spi_board_info *spi_devs; int num_spi_devs; + + struct gpiod_lookup_table *gpiod_table; } gf_mods[] = { { .id = 0x01, .rev = 0xff, .name = "1250-EV1 Springbank" }, { .id = 0x02, .rev = 0xff, .name = "1251-EV1 Jura" }, @@ -362,13 +364,16 @@ static const struct { .i2c_devs = wm1255_devs, .num_i2c_devs = ARRAY_SIZE(wm1255_devs) }, { .id = 0x3c, .rev = 0xff, .name = "1273-EV1 Longmorn" }, { .id = 0x3d, .rev = 0xff, .name = "1277-EV1 Littlemill", - .i2c_devs = wm1277_devs, .num_i2c_devs = ARRAY_SIZE(wm1277_devs) }, + .i2c_devs = wm1277_devs, .num_i2c_devs = ARRAY_SIZE(wm1277_devs), + .gpiod_table = &wm8994_gpiod_table }, { .id = 0x3e, .rev = 0, .name = "WM5102-6271-EV1-CS127 Amrut", .spi_devs = wm5102_reva_spi_devs, - .num_spi_devs = ARRAY_SIZE(wm5102_reva_spi_devs) }, + .num_spi_devs = ARRAY_SIZE(wm5102_reva_spi_devs), + .gpiod_table = &wm5102_reva_gpiod_table }, { .id = 0x3e, .rev = -1, .name = "WM5102-6271-EV1-CS127 Amrut", .spi_devs = wm5102_spi_devs, - .num_spi_devs = ARRAY_SIZE(wm5102_spi_devs) }, + .num_spi_devs = ARRAY_SIZE(wm5102_spi_devs), + .gpiod_table = &wm5102_gpiod_table }, { .id = 0x3f, .rev = -1, .name = "WM2200-6271-CS90-M-REV1", .i2c_devs = wm2200_i2c, .num_i2c_devs = ARRAY_SIZE(wm2200_i2c) }, }; @@ -408,6 +413,9 @@ static int wlf_gf_module_probe(struct i2c_client *i2c, spi_register_board_info(gf_mods[i].spi_devs, gf_mods[i].num_spi_devs); + + if (gf_mods[i].gpiod_table) + gpiod_add_lookup_table(gf_mods[i].gpiod_table); } else { dev_warn(&i2c->dev, "Unknown module ID 0x%x revision %d\n", id, rev + 1);