From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mail-pg1-f171.google.com (mail-pg1-f171.google.com [209.85.215.171]) (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 47BCE2A1CF for ; Sun, 23 Nov 2025 23:33:59 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.215.171 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1763940841; cv=none; b=BM9IYJTZV4JduFVuXMNrisXiPky4Mz++S5HYtG0rMcjF2uNIf5XaKRiJuaKkj0GA2/dewQ67OcUikwHz5z7rm37m9W/3mWl2QiDF1n7HpnTnxuYzYCYcywg7I4Eayh+NFbkt2gpLt1vd6U9L1myLPhS6F4t47U2M1MW323HTMfc= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1763940841; c=relaxed/simple; bh=iI/UzSXipXfe24j5ZIwP4aZNqmE0tbzsYwLtG+dw3H8=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=mZVAgxyS6phozMDV6Cao0JbFCiN64lzEusm/QFlQN9GcFw0xEg8PwcorvzKej9Ah2NgCNCAf9zBItRTKn6XobVBHZcA+62/g0fkVKYPkPKZdAbykgpupnIwV+0KBA1lCrMvFAy9ZBBFaoOFPOG0nez+FNSIzzqWnIHF+LxCLpq0= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=LfkwOaNP; arc=none smtp.client-ip=209.85.215.171 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="LfkwOaNP" Received: by mail-pg1-f171.google.com with SMTP id 41be03b00d2f7-b553412a19bso3369445a12.1 for ; Sun, 23 Nov 2025 15:33:59 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1763940839; x=1764545639; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=/ROCmV+AwPU/0W3OW5Sl9mTvJtTUzV6s8Q7227sNi9I=; b=LfkwOaNPbczzCtK3s+GYfN2vO0thhfjRDdBGJXYFB347hy3HPitUIRI81dTGl2Gqjg XWtLio/+zXarAX6fcZppseTesw5cT96lkdjicj9BnmXBXg5bUS93UMY4DBQNgRDRFBJb 7Aj41Y+wYRmksuEVm0sWQ7ubuQQFll4XbadV/LJ14XF3+QILoHE8bzL53/9E/Cq+056P rVr3vCa4G3YioEJqfb0rZsh2eCfOCocccmq3JMBwdh2KnPMIcVvXktgB1YyPbRZUg3Uw ttj0643WgQLi7whnaPabLdTeGPEop5sRedLaO7NyhuJNpN/OynfLB/RnQ183Nkw46OTW yA7w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1763940839; x=1764545639; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=/ROCmV+AwPU/0W3OW5Sl9mTvJtTUzV6s8Q7227sNi9I=; b=kIvFYo7MgtSvuHlGIG8luI/Pv98el3WleLOZ8nssURUTyDxm0GoZ54KcmZS6hCBMJk +hGJ5okEic/xLoK3K13rDlC8EiWku2x1bvfgzUhtd6Niy5qDlOEdWIq+qTenFZhuHG5R GXvuqNO09H1wltrSiSM1nUgXcjH29xLqoDwwxI9QlRh+UDCwyPdDFYCqKMHI+wN+9xj/ hS0GDSS5PLnojO8GwgJ6SY3IOtCm/cnyYtIBi+/ihrxqfai/X3PwzHlAFtz5F0DT4amu q2UaSvNtKkv/Ti/F/rNNmx7azaI+RSzb1pP054elujtJgehE7mqwVb5fYivV8r9kcNMB JQiw== X-Gm-Message-State: AOJu0YybgGHz4GKiVkJx/K5+KxdrBo4ubNYg7PSqgt4aqYj1PN4WlUOF nWECxzxcb7OKyGngty35Qb85dzc1GQy0PRX9kFdpWrlPGQ8tyHxL8EjQ X-Gm-Gg: ASbGncuxtp6RhQotFvXoMS5uZlVUdm3kra0U4ULbLo4Ukm3pq8EuoQ8dpDzWpGNrPKn INfUWBJHhxaErRwoLfz0Gsb8xjVFhIDculMwqVZGedzDDzIAqXFjX0RP1ebxKnjKkJUbDUw8q+Y qZ0l9rzT7iXuNhC+gxT0Xb7q+FwG37JI+8xV+Zrr5gJNCZNPZ8Tb/kkOIDEgC/+iIkKA74sPacj +Lrem/6RATq2mMOhWq2CTjtgyRmgYJXG0eiECH2SgN1VPDXbmJp95w8+LAHSt/933yGAaILF/CH OCJTDOfJIN7FWlMGNMQKJxIt/6xjbRfSJL0eQLuqxRY5map01t6Zp+VIshlHd9SC7+JjFPL6Olw SXVjquZiaj5X5zvWt5fg7b5zWnmJdzsnoCJNR6KTx0jSMFIW4Un3UhaWeOd2lY3yacx6txIwJvv BGL9ImVDy7/fhsJemffs6yoZAKOSfJ02wg/CDAedWmOQ2JMAO6YPm9/Q== X-Google-Smtp-Source: AGHT+IEAa2rMrvXcwz/4xJsVFyvI/gB3zi+0m0yfEBFVhgQrk7lnBETDWtMzu/1u+dc9inxC36vZ9A== X-Received: by 2002:a05:7301:da0a:b0:2a4:6c43:b0c9 with SMTP id 5a478bee46e88-2a7192d9e84mr3233527eec.30.1763940839350; Sun, 23 Nov 2025 15:33:59 -0800 (PST) Received: from ParadiseLost.localdomain (lohr.com.br. [177.69.253.233]) by smtp.gmail.com with ESMTPSA id 5a478bee46e88-2a6fc5e3750sm41858139eec.6.2025.11.23.15.33.57 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 23 Nov 2025 15:33:58 -0800 (PST) From: "Rafael V. Volkmer" To: rafael.v.volkmer@gmail.com Cc: linux-kernel@vger.kernel.org, linux-pwm@vger.kernel.org, ukleinek@kernel.org Subject: [PATCH v6 5/6] pwm: tiehrpwm: handle already-running channels at probe Date: Sun, 23 Nov 2025 20:33:49 -0300 Message-ID: <20251123233349.2122-1-rafael.v.volkmer@gmail.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20251123233151.2103-1-rafael.v.volkmer@gmail.com> References: <20251123233151.2103-1-rafael.v.volkmer@gmail.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Detect active A/B outputs from AQCTL(A/B) when they are not software-forced in AQCSFRC, take one pm_runtime_get_sync() per active channel, and enable tbclk only if at least one channel is active. This keeps runtime PM usage counts and tbclk state consistent with the actual hardware configuration. Before, an eHRPWM instance left running by firmware or the bootloader could have no runtime PM reference and no tbclk enable, leaving the driver out of sync with hardware. After this change, PM and clock state match the active channels observed at probe. Signed-off-by: Rafael V. Volkmer --- drivers/pwm/pwm-tiehrpwm.c | 64 +++++++++++++++++++++++++++++++++----- 1 file changed, 57 insertions(+), 7 deletions(-) diff --git a/drivers/pwm/pwm-tiehrpwm.c b/drivers/pwm/pwm-tiehrpwm.c index cc525626b2f9..1a9be36fc7b2 100644 --- a/drivers/pwm/pwm-tiehrpwm.c +++ b/drivers/pwm/pwm-tiehrpwm.c @@ -554,13 +554,35 @@ static int ehrpwm_pwm_probe(struct platform_device *pdev) struct ehrpwm_pwm_chip *pc; struct pwm_chip *chip; struct clk *clk; - int ret; + int ret, ch_idx, ch_disable; + u16 aqcsfrc_reg, aqctla_reg, aqctlb_reg; + bool enabled_ch[NUM_PWM_CHANNEL] = { false, false }; chip = devm_pwmchip_alloc(&pdev->dev, NUM_PWM_CHANNEL, sizeof(*pc)); if (IS_ERR(chip)) return PTR_ERR(chip); pc = to_ehrpwm_pwm_chip(chip); + pc->mmio_base = devm_platform_ioremap_resource(pdev, 0); + if (IS_ERR(pc->mmio_base)) + return PTR_ERR(pc->mmio_base); + + /* + * Best-effort snapshot of AQCSFRC/AQCTLx before touching clocks or + * runtime PM. If the eHRPWM block is power-gated or its clock is + * disabled these registers are expected to read as 0, which we + * interpret as "channel not configured / disabled". + */ + aqcsfrc_reg = readw(pc->mmio_base + AQCSFRC); + aqctla_reg = readw(pc->mmio_base + AQCTLA); + aqctlb_reg = readw(pc->mmio_base + AQCTLB); + + if (aqctla_reg != 0 && !FIELD_GET(AQCSFRC_CSFA_MASK, aqcsfrc_reg)) + enabled_ch[PWM_CHA] = true; + + if (aqctlb_reg != 0 && !FIELD_GET(AQCSFRC_CSFB_MASK, aqcsfrc_reg)) + enabled_ch[PWM_CHB] = true; + clk = devm_clk_get(&pdev->dev, "fck"); if (IS_ERR(clk)) { if (of_device_is_compatible(np, "ti,am33xx-ecap")) { @@ -580,10 +602,6 @@ static int ehrpwm_pwm_probe(struct platform_device *pdev) chip->ops = &ehrpwm_pwm_ops; - pc->mmio_base = devm_platform_ioremap_resource(pdev, 0); - if (IS_ERR(pc->mmio_base)) - return PTR_ERR(pc->mmio_base); - /* Acquire tbclk for Time Base EHRPWM submodule */ pc->tbclk = devm_clk_get(&pdev->dev, "tbclk"); if (IS_ERR(pc->tbclk)) @@ -595,17 +613,49 @@ static int ehrpwm_pwm_probe(struct platform_device *pdev) return ret; } + if (enabled_ch[PWM_CHA] || enabled_ch[PWM_CHB]) { + ret = clk_enable(pc->tbclk); + if (ret) { + dev_err_probe(&pdev->dev, ret, "clk_enable(tbclk) failed\n"); + goto err_clk_unprepare; + } + } + ret = pwmchip_add(chip); if (ret < 0) { dev_err(&pdev->dev, "pwmchip_add() failed: %d\n", ret); - goto err_clk_unprepare; + goto err_disable_tbclk; } platform_set_drvdata(pdev, chip); pm_runtime_enable(&pdev->dev); - return 0; + /* + * Treat channels that were configured and not software-forced at probe + * time as "pre-enabled": take a runtime PM reference so the eHRPWM block + * stays powered while such channels exist. Consumers still get/put PM + * on top of this bias via pwm_enable()/pwm_disable(). + */ + for (ch_idx = 0; ch_idx < NUM_PWM_CHANNEL; ch_idx++) { + if (enabled_ch[ch_idx]) { + ret = pm_runtime_get_sync(&pdev->dev); + if (ret < 0) { + for (ch_disable = 0; ch_disable <= ch_idx; ch_disable++) { + if (enabled_ch[ch_disable]) + pm_runtime_put_noidle(&pdev->dev); + } + + pwmchip_remove(chip); + pm_runtime_disable(&pdev->dev); + goto err_disable_tbclk; + } + } + } + return 0; +err_disable_tbclk: + if (enabled_ch[PWM_CHA] || enabled_ch[PWM_CHB]) + clk_disable(pc->tbclk); err_clk_unprepare: clk_unprepare(pc->tbclk); -- 2.43.0