From patchwork Mon May 27 12:41:11 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Geert Uytterhoeven X-Patchwork-Id: 13675155 X-Patchwork-Delegate: geert@linux-m68k.org Received: from laurent.telenet-ops.be (laurent.telenet-ops.be [195.130.137.89]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 861F015E5A2 for ; Mon, 27 May 2024 12:41:21 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=195.130.137.89 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1716813684; cv=none; b=Gv6k/ZR8/KpzWoKts4B3TZJHvX347BYyMnGuzGu3zv5vGUx38Hw/u0GwNuJqOKY0XczewUIvqRKvAFqCZPg5NzUUmHB8u2Ut4ICWvm6bD2BJhGTJ+SRDhr9Lml1Ki1/vpGpLsEOaO+rCTvZtRv7NxLTmOFr2Yf6vueTE/x6G4+E= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1716813684; c=relaxed/simple; bh=EIepfrHfmhIc9MJ0QvPBLJEXp/OzidtfVr/2NHCOLWI=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=Q+MB6k/wvJ/EPA492BdeUlFly8NxUKQFS5u1Cx/hf5J1q5BFqp5EHMaGJ2dHQ1qUoe6oSIah+udheZK42SlOQIO62RQVeR/6S4Js9FDl6u25o34ImrwkfORsBed7UENN9cFrTaFHP+kVLUQY/Oze7X0SMYUoEqzS8+grQmKFj5c= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=glider.be; spf=none smtp.mailfrom=linux-m68k.org; arc=none smtp.client-ip=195.130.137.89 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=glider.be Authentication-Results: smtp.subspace.kernel.org; spf=none smtp.mailfrom=linux-m68k.org Received: from ramsan.of.borg ([IPv6:2a02:1810:ac12:ed80:c993:5573:f894:7353]) by laurent.telenet-ops.be with bizsmtp id UChF2C0022nC7mg01ChFPu; Mon, 27 May 2024 14:41:19 +0200 Received: from rox.of.borg ([192.168.97.57]) by ramsan.of.borg with esmtp (Exim 4.95) (envelope-from ) id 1sBZeD-00CfTe-4S; Mon, 27 May 2024 14:41:14 +0200 Received: from geert by rox.of.borg with local (Exim 4.95) (envelope-from ) id 1sBZf8-003hdZ-Sf; Mon, 27 May 2024 14:41:14 +0200 From: Geert Uytterhoeven To: Ulf Hansson , Greg Kroah-Hartman , Jiri Slaby , "Rafael J . Wysocki" , Rob Herring , Saravana Kannan Cc: Claudiu Beznea , Peng Fan , linux-pm@vger.kernel.org, linux-serial@vger.kernel.org, linux-renesas-soc@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, Geert Uytterhoeven Subject: [PATCH/RFC 1/3] earlycon: Export clock and PM Domain info from FDT Date: Mon, 27 May 2024 14:41:11 +0200 Message-Id: X-Mailer: git-send-email 2.34.1 In-Reply-To: References: Precedence: bulk X-Mailing-List: linux-renesas-soc@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Earlycon relies on the serial port to be initialized by the firmware and/or bootloader. Linux is not aware of any hardware dependencies that must be met to keep the port working, and thus cannot guarantee they stay met, until the full serial driver takes over. E.g. all unused clocks and unused PM Domains are disabled in a late initcall. As this happens after the full serial driver has taken over, the serial port's clock and/or PM Domain are no longer deemed unused, and this is typically not a problem. However, if the serial port's clock or PM Domain is shared with another device, and that other device is runtime-suspended before the full serial driver has probed, the serial port's clock and/or PM Domain will be disabled inadvertently. Any subsequent serial console output will cause a crash or system lock-up. Provide a mechanism to let the clock and/or PM Domain subsystem or drivers handle this, by exporting the clock and PM Domain dependencies for the serial port, as available in the system's device tree. Note that as this is done during early boot-up, the device_node structure pointing to the earlycon console is not yet created, so this has to resort to raw property data. Signed-off-by: Geert Uytterhoeven --- drivers/tty/serial/earlycon.c | 14 +++++++++++++- include/linux/serial_core.h | 10 ++++++++++ 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/drivers/tty/serial/earlycon.c b/drivers/tty/serial/earlycon.c index a5fbb6ed38aed681..abe4831d9685e2b8 100644 --- a/drivers/tty/serial/earlycon.c +++ b/drivers/tty/serial/earlycon.c @@ -250,11 +250,14 @@ early_param("earlycon", param_setup_earlycon); #ifdef CONFIG_OF_EARLY_FLATTREE +const __be32 *earlycon_clocks, *earlycon_power_domains; +int earlycon_clocks_ncells, earlycon_power_domains_ncells; + int __init of_setup_earlycon(const struct earlycon_id *match, unsigned long node, const char *options) { - int err; + int err, size; struct uart_port *port = &early_console_dev.port; const __be32 *val; bool big_endian; @@ -309,6 +312,15 @@ int __init of_setup_earlycon(const struct earlycon_id *match, if (val) port->uartclk = be32_to_cpu(*val); + earlycon_clocks = of_get_flat_dt_prop(node, "clocks", &size); + if (earlycon_clocks) + earlycon_clocks_ncells = size / sizeof(u32); + + earlycon_power_domains = of_get_flat_dt_prop(node, "power-domains", + &size); + if (earlycon_power_domains) + earlycon_power_domains_ncells = size / sizeof(u32); + if (options) { early_console_dev.baud = simple_strtoul(options, NULL, 0); strscpy(early_console_dev.options, options, diff --git a/include/linux/serial_core.h b/include/linux/serial_core.h index 8cb65f50e830c8d4..70689a3363951dac 100644 --- a/include/linux/serial_core.h +++ b/include/linux/serial_core.h @@ -954,6 +954,16 @@ static const bool earlycon_acpi_spcr_enable EARLYCON_USED_OR_UNUSED; static inline int setup_earlycon(char *buf) { return 0; } #endif +#ifdef CONFIG_OF_EARLY_FLATTREE +extern const __be32 *earlycon_clocks, *earlycon_power_domains; +extern int earlycon_clocks_ncells, earlycon_power_domains_ncells; +#else +#define earlycon_clocks NULL +#define earlycon_clocks_ncells 0 +#define earlycon_power_domains NULL +#define earlycon_power_domains_ncells 0 +#endif + /* Variant of uart_console_registered() when the console_list_lock is held. */ static inline bool uart_console_registered_locked(struct uart_port *port) { From patchwork Mon May 27 12:41:12 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Geert Uytterhoeven X-Patchwork-Id: 13675156 X-Patchwork-Delegate: geert@linux-m68k.org Received: from xavier.telenet-ops.be (xavier.telenet-ops.be [195.130.132.52]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id A2EA415E5DF for ; Mon, 27 May 2024 12:41:28 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=195.130.132.52 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1716813691; cv=none; b=CH62pgjPCt8vQR8NEh2ayKgsj9ibB2AGENBpIUQGmhNz8b7Rbb6Q9XlUqfwmgr3f/WKyqhGYa2XoSdSdSb5o28Uj9iW17hIiAcggTvjVxyaMy+X3PsdTLOnoerCVaZEEE4aESNQv89wCuGlPML4+wAvtbL36guipfYrlI63nF/I= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1716813691; c=relaxed/simple; bh=DKPGT9zCwjT97JfwUeLGsvdXWvcfL2iqAGQFqV9g4PU=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=dSX71/170EM6vZGzf626Icb+hObGwpanDpEInB1GNXb5YFw3zScSEadGGNV0788tL5uxSu5o5UPUg10bWIOc+dmJUYN6h0VvOPHDlM93ifFlgdA2DnpttKjsXTnQXfQgNAY+hFXJgbZXIEHpu5hsXRQU5HqOoF6Fvx0hMJGOUz8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=glider.be; spf=none smtp.mailfrom=linux-m68k.org; arc=none smtp.client-ip=195.130.132.52 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=glider.be Authentication-Results: smtp.subspace.kernel.org; spf=none smtp.mailfrom=linux-m68k.org Received: from ramsan.of.borg ([IPv6:2a02:1810:ac12:ed80:c993:5573:f894:7353]) by xavier.telenet-ops.be with bizsmtp id UChF2C0052nC7mg01ChFB4; Mon, 27 May 2024 14:41:25 +0200 Received: from rox.of.borg ([192.168.97.57]) by ramsan.of.borg with esmtp (Exim 4.95) (envelope-from ) id 1sBZeD-00CfTf-5D; Mon, 27 May 2024 14:41:14 +0200 Received: from geert by rox.of.borg with local (Exim 4.95) (envelope-from ) id 1sBZf8-003hdc-TN; Mon, 27 May 2024 14:41:14 +0200 From: Geert Uytterhoeven To: Ulf Hansson , Greg Kroah-Hartman , Jiri Slaby , "Rafael J . Wysocki" , Rob Herring , Saravana Kannan Cc: Claudiu Beznea , Peng Fan , linux-pm@vger.kernel.org, linux-serial@vger.kernel.org, linux-renesas-soc@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, Geert Uytterhoeven Subject: [PATCH/RFC 2/3] pmdomain: core: Avoid earlycon power-down Date: Mon, 27 May 2024 14:41:12 +0200 Message-Id: <7c5c0c8a10b8f755e5a75c7836b43cac63762eec.1716811405.git.geert+renesas@glider.be> X-Mailer: git-send-email 2.34.1 In-Reply-To: References: Precedence: bulk X-Mailing-List: linux-renesas-soc@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 If the earlycon serial port's PM Domain is shared with another device, and that other device is runtime-suspended before the full serial driver has overtaken earlycon, the serial port's PM Domain will be disabled inadvertently. Any subsequent serial console output will cause a crash or system lock-up. Avoid this by introducing a new flag to handle a PM domain that must be kept powered-on during early boot, and by setting this flag if the PM Domain contains the serial console. Note that the PM Domain can still be powered off later, when the serial port's power state agrees, e.g. during s2ram without no_console_suspend. Signed-off-by: Geert Uytterhoeven --- drivers/pmdomain/core.c | 24 ++++++++++++++++++++++-- include/linux/pm_domain.h | 4 ++++ 2 files changed, 26 insertions(+), 2 deletions(-) diff --git a/drivers/pmdomain/core.c b/drivers/pmdomain/core.c index 342779464c0d7e84..97b9b50257eb354c 100644 --- a/drivers/pmdomain/core.c +++ b/drivers/pmdomain/core.c @@ -22,6 +22,7 @@ #include #include #include +#include #define GENPD_RETRY_MAX_MS 250 /* Approximate */ @@ -129,6 +130,7 @@ static const struct genpd_lock_ops genpd_spin_ops = { #define genpd_is_cpu_domain(genpd) (genpd->flags & GENPD_FLAG_CPU_DOMAIN) #define genpd_is_rpm_always_on(genpd) (genpd->flags & GENPD_FLAG_RPM_ALWAYS_ON) #define genpd_is_opp_table_fw(genpd) (genpd->flags & GENPD_FLAG_OPP_TABLE_FW) +#define genpd_is_early_on(genpd) (genpd->flags & GENPD_FLAG_EARLY_ON) static inline bool irq_safe_dev_in_sleep_domain(struct device *dev, const struct generic_pm_domain *genpd) @@ -725,8 +727,9 @@ static int genpd_power_off(struct generic_pm_domain *genpd, bool one_dev_on, * (2) When the domain has a subdomain being powered on. */ if (genpd_is_always_on(genpd) || - genpd_is_rpm_always_on(genpd) || - atomic_read(&genpd->sd_count) > 0) + (genpd_is_early_on(genpd) && system_state < SYSTEM_RUNNING) || + genpd_is_rpm_always_on(genpd) || + atomic_read(&genpd->sd_count) > 0) return -EBUSY; /* @@ -2367,6 +2370,10 @@ int of_genpd_add_provider_simple(struct device_node *np, genpd->dev.of_node = np; + if (earlycon_power_domains && + np->phandle == be32_to_cpup(earlycon_power_domains)) + genpd->flags |= GENPD_FLAG_EARLY_ON; + /* Parse genpd OPP table */ if (!genpd_is_opp_table_fw(genpd) && genpd->set_performance_state) { ret = dev_pm_opp_of_add_table(&genpd->dev); @@ -2447,6 +2454,19 @@ int of_genpd_add_provider_onecell(struct device_node *np, genpd->has_provider = true; } + if (earlycon_power_domains && earlycon_power_domains_ncells == 2 && + np->phandle == be32_to_cpup(earlycon_power_domains)) { + struct of_phandle_args genpdspec = { + .np = np, + .args_count = 1, + .args[0] = be32_to_cpup(earlycon_power_domains + 1), + }; + + genpd = data->xlate(&genpdspec, data); + if (!IS_ERR(genpd)) + genpd->flags |= GENPD_FLAG_EARLY_ON; + } + ret = genpd_add_provider(np, data->xlate, data); if (ret < 0) goto error; diff --git a/include/linux/pm_domain.h b/include/linux/pm_domain.h index 772d3280d35fafa2..012d58ffc7059e0d 100644 --- a/include/linux/pm_domain.h +++ b/include/linux/pm_domain.h @@ -92,6 +92,9 @@ struct dev_pm_domain_list { * GENPD_FLAG_OPP_TABLE_FW: The genpd provider supports performance states, * but its corresponding OPP tables are not * described in DT, but are given directly by FW. + * + * GENPD_FLAG_EARLY_ON: Instructs genpd to keep the PM domain powered + * on during early boot. */ #define GENPD_FLAG_PM_CLK (1U << 0) #define GENPD_FLAG_IRQ_SAFE (1U << 1) @@ -101,6 +104,7 @@ struct dev_pm_domain_list { #define GENPD_FLAG_RPM_ALWAYS_ON (1U << 5) #define GENPD_FLAG_MIN_RESIDENCY (1U << 6) #define GENPD_FLAG_OPP_TABLE_FW (1U << 7) +#define GENPD_FLAG_EARLY_ON (1U << 8) enum gpd_status { GENPD_STATE_ON = 0, /* PM domain is on */ From patchwork Mon May 27 12:41:13 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Geert Uytterhoeven X-Patchwork-Id: 13675158 X-Patchwork-Delegate: geert@linux-m68k.org Received: from riemann.telenet-ops.be (riemann.telenet-ops.be [195.130.137.80]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id EE0EC15ECC1 for ; Mon, 27 May 2024 12:41:28 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=195.130.137.80 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1716813692; cv=none; b=NkJFRI4D3Hl6dIgptJiHe5xIzGrMfzaQrIebXPEdLSStIiwrHrJYf5fAbPj80/jyKyna57zhDluWCVEqxdI7XhkI86oSWB62AtO1PMexpruvtSRYqR0m+FyuBs0+FnakwoztJgDjxzBPAspLNlxGtdRbXhKqB4BZc4GDBQWZfL0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1716813692; c=relaxed/simple; bh=/6WTDSc5iLDDk2l/Y6xCKmU+DGYC5Ga9O6+yrTK+INs=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=Jr7S/ob4gQudMvA2uJL9gBHVp9T7MEz52iFwP1oi8lHvS82QbFPRx7UgUJ13L1/li1OgZ8fLK6huXe0VGgVlnm18MtAiJxe9bZUlan1pdPGTZIw1CiUjNhqKZG1mJOnDeKMMPHaLAOTgZRXogokRSPpUbYbLJ8N0GxqR7uhqEL0= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=glider.be; spf=none smtp.mailfrom=linux-m68k.org; arc=none smtp.client-ip=195.130.137.80 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=glider.be Authentication-Results: smtp.subspace.kernel.org; spf=none smtp.mailfrom=linux-m68k.org Received: from michel.telenet-ops.be (michel.telenet-ops.be [IPv6:2a02:1800:110:4::f00:18]) by riemann.telenet-ops.be (Postfix) with ESMTPS id 4VnwHq27fjz4wwk3 for ; Mon, 27 May 2024 14:41:27 +0200 (CEST) Received: from ramsan.of.borg ([IPv6:2a02:1810:ac12:ed80:c993:5573:f894:7353]) by michel.telenet-ops.be with bizsmtp id UChF2C0022nC7mg06ChFXw; Mon, 27 May 2024 14:41:19 +0200 Received: from rox.of.borg ([192.168.97.57]) by ramsan.of.borg with esmtp (Exim 4.95) (envelope-from ) id 1sBZeD-00CfTk-6G; Mon, 27 May 2024 14:41:15 +0200 Received: from geert by rox.of.borg with local (Exim 4.95) (envelope-from ) id 1sBZf8-003hdh-UO; Mon, 27 May 2024 14:41:14 +0200 From: Geert Uytterhoeven To: Ulf Hansson , Greg Kroah-Hartman , Jiri Slaby , "Rafael J . Wysocki" , Rob Herring , Saravana Kannan Cc: Claudiu Beznea , Peng Fan , linux-pm@vger.kernel.org, linux-serial@vger.kernel.org, linux-renesas-soc@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, Geert Uytterhoeven Subject: [PATCHPATCH 3/3] pmdomain: renesas: rmobile-sysc: Remove serial console handling Date: Mon, 27 May 2024 14:41:13 +0200 Message-Id: X-Mailer: git-send-email 2.34.1 In-Reply-To: References: Precedence: bulk X-Mailing-List: linux-renesas-soc@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Since commit a47cf07f60dcb02d ("serial: core: Call device_set_awake_path() for console port"), the serial driver properly handles the case where the serial console is part of the awake path, so the special serial console handling can be removed from the R-Mobile SYSC PM Domain driver. The PM Domain containing the serial port can now be powered down when none of its devices are in use. Before, it was only powered down during s2ram without no_console_suspend. Signed-off-by: Geert Uytterhoeven --- drivers/pmdomain/renesas/rmobile-sysc.c | 33 +------------------------ 1 file changed, 1 insertion(+), 32 deletions(-) diff --git a/drivers/pmdomain/renesas/rmobile-sysc.c b/drivers/pmdomain/renesas/rmobile-sysc.c index 0b77f37787d58f48..cc1f6f8b7a746850 100644 --- a/drivers/pmdomain/renesas/rmobile-sysc.c +++ b/drivers/pmdomain/renesas/rmobile-sysc.c @@ -10,7 +10,6 @@ * Copyright (C) 2011 Magnus Damm */ #include -#include #include #include #include @@ -31,8 +30,6 @@ struct rmobile_pm_domain { struct generic_pm_domain genpd; - struct dev_power_governor *gov; - int (*suspend)(void); void __iomem *base; unsigned int bit_shift; }; @@ -49,13 +46,6 @@ static int rmobile_pd_power_down(struct generic_pm_domain *genpd) unsigned int mask = BIT(rmobile_pd->bit_shift); u32 val; - if (rmobile_pd->suspend) { - int ret = rmobile_pd->suspend(); - - if (ret) - return ret; - } - if (readl(rmobile_pd->base + PSTR) & mask) { writel(mask, rmobile_pd->base + SPDCR); @@ -98,7 +88,6 @@ static int rmobile_pd_power_up(struct generic_pm_domain *genpd) static void rmobile_init_pm_domain(struct rmobile_pm_domain *rmobile_pd) { struct generic_pm_domain *genpd = &rmobile_pd->genpd; - struct dev_power_governor *gov = rmobile_pd->gov; genpd->flags |= GENPD_FLAG_PM_CLK | GENPD_FLAG_ACTIVE_WAKEUP; genpd->attach_dev = cpg_mstp_attach_dev; @@ -110,22 +99,12 @@ static void rmobile_init_pm_domain(struct rmobile_pm_domain *rmobile_pd) __rmobile_pd_power_up(rmobile_pd); } - pm_genpd_init(genpd, gov ? : &simple_qos_governor, false); -} - -static int rmobile_pd_suspend_console(void) -{ - /* - * Serial consoles make use of SCIF hardware located in this domain, - * hence keep the power domain on if "no_console_suspend" is set. - */ - return console_suspend_enabled ? 0 : -EBUSY; + pm_genpd_init(genpd, &simple_qos_governor, false); } enum pd_types { PD_NORMAL, PD_CPU, - PD_CONSOLE, PD_DEBUG, PD_MEMCTL, }; @@ -184,10 +163,6 @@ static void __init get_special_pds(void) for_each_of_cpu_node(np) add_special_pd(np, PD_CPU); - /* PM domain containing console */ - if (of_stdout) - add_special_pd(of_stdout, PD_CONSOLE); - /* PM domains containing other special devices */ for_each_matching_node_and_match(np, special_ids, &id) add_special_pd(np, (uintptr_t)id->data); @@ -227,12 +202,6 @@ static void __init rmobile_setup_pm_domain(struct device_node *np, pd->genpd.flags |= GENPD_FLAG_ALWAYS_ON; break; - case PD_CONSOLE: - pr_debug("PM domain %s contains serial console\n", name); - pd->gov = &pm_domain_always_on_gov; - pd->suspend = rmobile_pd_suspend_console; - break; - case PD_DEBUG: /* * This domain contains the Coresight-ETM hardware block and