From nobody Tue Jun 16 04:52:30 2026 Received: from mail-wm1-f51.google.com (mail-wm1-f51.google.com [209.85.128.51]) (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 4B895366074 for ; Thu, 16 Apr 2026 08:29:33 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.51 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1776328176; cv=none; b=TNwIdo4T/N47UvfZ3//oT5ynFtsVdW2VJmnPiunWxUyLsV4GM7F84YDFE85Bed9IZ01VF8KrEfEQq/sIkjhWe+a/4Gc6/kCmemNs4CZV45Yn/Hq3nBxY64hV4MBhHoD76QO9dUziVTpvxsCTpR/vKPaa7AZxj/TSq/MqLR6eXLw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1776328176; c=relaxed/simple; bh=iWDbdaRjeQipAEFM/Boy5viigqE6jeEkGju2KVnnxAQ=; h=From:To:Cc:Subject:Date:Message-ID:MIME-Version; b=aFxADB6wc/1JUEIme88Klknpnl+G7/NWlpYOkwvx0OtIZiXZIKlkB30TGTbI8wERWMSsj3ierwNTgd5EGUdw3tAvrWGW8BedqkQnZRjLHEcGLjppwOK+EAe9aaCk0fAXPLX+haVv1a4c5zouIFglO4LOXf4588PYyb8kFoOhmaE= 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=iHZWdLuI; arc=none smtp.client-ip=209.85.128.51 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="iHZWdLuI" Received: by mail-wm1-f51.google.com with SMTP id 5b1f17b1804b1-4887fd35e60so53160765e9.2 for ; Thu, 16 Apr 2026 01:29:33 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1776328172; x=1776932972; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:from:to:cc:subject:date:message-id:reply-to; bh=AxfxNFJlvGuF2Od+yfnihIdQvBKtTrOm36dg4RbUpAM=; b=iHZWdLuI1YAIWSNsOLoJ9b9PPoRXksquynxo8uAOFsAmBqpyQrHzgurU3Hq44XLgNL ZYeQwYwV260Sd77rngxtZ1flEbyZHzHSrnRrCYiBhYCxyc5QnxUP90piI+WG+MqJbBRE HnX0YH84THhm1DbjiLyfjEhl1NT7CKL+B8DWoKGdhKY/W9leG/beIxVaOF5LKqDYgmV8 WhNSa1GSh3wpRKLFsNQ/AsewWWXD/4mTnOAf3TZJWnj59RnREZ6EBiW8BHjHf89mHSxA CV+rqrfGUl5fewRMvDDy8EpiJM+z8M3Pk2SyzgiUoyKZaTf8ylFFMA3HWWhAot8Z3it/ FGCQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1776328172; x=1776932972; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:x-gm-gg:x-gm-message-state:from:to:cc:subject:date :message-id:reply-to; bh=AxfxNFJlvGuF2Od+yfnihIdQvBKtTrOm36dg4RbUpAM=; b=QCgUjtAh0Ini+bsiaa38mBlumVglfnpdW1UkCT2gLVk0SnBoLlIKOucQFGiZkts/+B T52L0NFhNBrMXl0Ln/7brF2q7SyUlBaTeID8JIvNQbIDbT2UwGxde9cLwS07nZxL4//o U7XS2tdMym/XVF5O2y7nvhqKkrEcLpmRee32R8+onZiiXGGqVBuj9stTSUMrLyzlrp/o kdsZ4qhOXxJyB9qS2q5FHexUJj4d5ViqljS4Gv2Q1U3N6cZog8lmLEgx4+9wia8/ZdcT uoZ5SaBTpVyTUC9EscQvKU+HrJQtURlY7rdiYV3xQel9oSX4HwDg36nSBFECA7m1Crai pdkw== X-Forwarded-Encrypted: i=1; AFNElJ8HR4oGyduhzJgf+vHWOWKb3rT0FVj9Ry7nIHfyl+kRb28+MOh8rOubvYO/4ReI8xpzZ42S5nY/YDhzyj4=@vger.kernel.org X-Gm-Message-State: AOJu0YzG+0N9W2/j4haREVvO66TU3yAzoN2JAid85QKNXeghOHysxBK3 AuyH5e1a47IxKgkacg8OBhtI0vMY4FKZreF42IuHlfov5Ely21URLcw2 X-Gm-Gg: AeBDieusLtFXIp+HM0+rSiJZ0sU/cCuHtfJob1pK+//XlsxxWiRkIjLzYLiyy+MEb/I PKzx5EsXx+yMsfoOQ2ptln3kva4mLIPCzm7nhO8BI9XoZ1PS0ner5TYnzy/GXos46umAj1z0zeB CoSNe8aIVO2S+2NQ9gKfHCw816+m2TyCckttEDzjjceSEUAj1HzyeLyQpro66vfmNHZz7jjK2A1 5RdJcY1tlRkDWGyDWXtpJ8n3OFQ0F/biBJ2FdTjESH9BBfR9SPa+9AFLi/IUXwN5Q57EA34KC3o efcohrEu5lKw1BUFMHRbZxv3JSy2G+JDUM8+yl2f+6Yl9hNqas6nWQnX3xz5l1W69K2RQK6u5DJ mcmqF0Rh8/FO80VQlM4rGGMsPnm1uub/ZpUDAuvwI2gu0sfDqF94tYk09yb7FdRCofdp+SSMFHi i8RF1cRzv7Nmuef/R3RrP2DxxZBV4OtqaNH1Zf8d/Pj1XIeQ2FDLSRMV0WCQ== X-Received: by 2002:a05:600c:a404:b0:487:1108:48b8 with SMTP id 5b1f17b1804b1-488d67b8d97mr295243195e9.2.1776328171424; Thu, 16 Apr 2026 01:29:31 -0700 (PDT) Received: from localhost.localdomain ([2a00:23c4:a758:8a01:b39:3660:ce8b:3f82]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-488f582048bsm34597475e9.7.2026.04.16.01.29.30 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 16 Apr 2026 01:29:31 -0700 (PDT) From: Biju X-Google-Original-From: Biju To: Liu Ying , Andrzej Hajda , Neil Armstrong , Robert Foss , Maarten Lankhorst , Maxime Ripard , Thomas Zimmermann , David Airlie , Simona Vetter Cc: Biju Das , Laurent Pinchart , Jonas Karlman , Jernej Skrabec , dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org, Geert Uytterhoeven , Prabhakar Mahadev Lad , Biju Das , linux-renesas-soc@vger.kernel.org Subject: [PATCH v2] drm/bridge: ite-it6263: Add suspend/resume support Date: Thu, 16 Apr 2026 09:29:25 +0100 Message-ID: <20260416082928.169347-1-biju.das.jz@bp.renesas.com> X-Mailer: git-send-email 2.43.0 Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Biju Das On the RZ/G3L SMARC EVK using PSCI, suspend to RAM powers down the ITE IT6263 chip. The display controller driver's system PM callbacks invoke drm_mode_config_helper_{suspend,resume}, which in turn call the bridge's atomic_{disable,enable} callbacks can handle suspend/resume for the bridge without dedicated PM ops. Introduce it6263_bridge_init() and it6263_bridge_uninit() helpers to consolidate power sequencing, hardware reset, I2C address setup, and LVDS/HDMI configuration. These replace the open-coded init sequence in probe() and are hooked into atomic_enable/atomic_disable respectively, guarded by a powered flag to avoid redundant re-initialisation. Switch from devm_regulator_bulk_get_enable() to devm_regulator_bulk_get() so that regulators can be explicitly enabled and disabled across power cycles. Move reset_gpio and regulator state into the it6263 struct so they are accessible beyond probe time. Add a remove() callback to cleanly power down the bridge on driver unbind via it6263_bridge_uninit(). Signed-off-by: Biju Das --- v1->v2: * Dropped system PM callbacks instead using bridge's atomic_{disable,enable} callbacks to handle suspend/resume. --- drivers/gpu/drm/bridge/ite-it6263.c | 88 ++++++++++++++++++++++++----- 1 file changed, 73 insertions(+), 15 deletions(-) diff --git a/drivers/gpu/drm/bridge/ite-it6263.c b/drivers/gpu/drm/bridge/i= te-it6263.c index 4f3ebb7af4d4..1954bb11f7f4 100644 --- a/drivers/gpu/drm/bridge/ite-it6263.c +++ b/drivers/gpu/drm/bridge/ite-it6263.c @@ -200,9 +200,13 @@ struct it6263 { struct regmap *lvds_regmap; struct drm_bridge bridge; struct drm_bridge *next_bridge; + struct gpio_desc *reset_gpio; + struct regulator_bulk_data *supplies; + unsigned int num_supplies; int lvds_data_mapping; bool lvds_dual_link; bool lvds_link12_swap; + bool powered; }; =20 static inline struct it6263 *bridge_to_it6263(struct drm_bridge *bridge) @@ -578,6 +582,41 @@ static int it6263_read_edid(void *data, u8 *buf, unsig= ned int block, size_t len) return 0; } =20 +static int it6263_bridge_init(struct it6263 *it) +{ + int ret; + + ret =3D regulator_bulk_enable(it->num_supplies, it->supplies); + if (ret) { + dev_err(it->dev, "failed to enable power supplies\n"); + return ret; + } + + it6263_hw_reset(it->reset_gpio); + + ret =3D it6263_lvds_set_i2c_addr(it); + if (ret) { + dev_err(it->dev, "failed to set I2C addr\n"); + regulator_bulk_disable(it->num_supplies, it->supplies); + return ret; + } + + it6263_lvds_config(it); + it6263_hdmi_config(it); + + it->powered =3D true; + + return 0; +} + +static int it6263_bridge_uninit(struct it6263 *it) +{ + regulator_bulk_disable(it->num_supplies, it->supplies); + it->powered =3D false; + + return 0; +} + static void it6263_bridge_atomic_disable(struct drm_bridge *bridge, struct drm_atomic_state *state) { @@ -587,6 +626,8 @@ static void it6263_bridge_atomic_disable(struct drm_bri= dge *bridge, regmap_write(it->hdmi_regmap, HDMI_REG_PKT_GENERAL_CTRL, 0); regmap_write(it->hdmi_regmap, HDMI_REG_AFE_DRV_CTRL, AFE_DRV_RST | AFE_DRV_PWD); + + it6263_bridge_uninit(it); } =20 static void it6263_bridge_atomic_enable(struct drm_bridge *bridge, @@ -603,6 +644,9 @@ static void it6263_bridge_atomic_enable(struct drm_brid= ge *bridge, bool pclk_high; int i, ret; =20 + if (!it->powered) + it6263_bridge_init(it); + connector =3D drm_atomic_get_new_connector_for_encoder(state, bridge->encoder); crtc =3D drm_atomic_get_new_connector_state(state, connector)->crtc; @@ -840,7 +884,6 @@ static const struct drm_bridge_funcs it6263_bridge_func= s =3D { static int it6263_probe(struct i2c_client *client) { struct device *dev =3D &client->dev; - struct gpio_desc *reset_gpio; struct it6263 *it; int ret; =20 @@ -858,13 +901,21 @@ static int it6263_probe(struct i2c_client *client) return dev_err_probe(dev, PTR_ERR(it->hdmi_regmap), "failed to init I2C regmap for HDMI\n"); =20 - reset_gpio =3D devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_LOW); - if (IS_ERR(reset_gpio)) - return dev_err_probe(dev, PTR_ERR(reset_gpio), + it->reset_gpio =3D devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_LOW); + if (IS_ERR(it->reset_gpio)) + return dev_err_probe(dev, PTR_ERR(it->reset_gpio), "failed to get reset gpio\n"); =20 - ret =3D devm_regulator_bulk_get_enable(dev, ARRAY_SIZE(it6263_supplies), - it6263_supplies); + it->num_supplies =3D ARRAY_SIZE(it6263_supplies); + it->supplies =3D devm_kcalloc(dev, it->num_supplies, + sizeof(*it->supplies), GFP_KERNEL); + if (!it->supplies) + return -ENOMEM; + + for (unsigned int i =3D 0; i < it->num_supplies; i++) + it->supplies[i].supply =3D it6263_supplies[i]; + + ret =3D devm_regulator_bulk_get(dev, it->num_supplies, it->supplies); if (ret) return dev_err_probe(dev, ret, "failed to get power supplies\n"); =20 @@ -872,12 +923,6 @@ static int it6263_probe(struct i2c_client *client) if (ret) return ret; =20 - it6263_hw_reset(reset_gpio); - - ret =3D it6263_lvds_set_i2c_addr(it); - if (ret) - return dev_err_probe(dev, ret, "failed to set I2C addr\n"); - it->lvds_i2c =3D devm_i2c_new_dummy_device(dev, client->adapter, LVDS_INPUT_CTRL_I2C_ADDR); if (IS_ERR(it->lvds_i2c)) @@ -890,8 +935,9 @@ static int it6263_probe(struct i2c_client *client) return dev_err_probe(dev, PTR_ERR(it->lvds_regmap), "failed to init I2C regmap for LVDS\n"); =20 - it6263_lvds_config(it); - it6263_hdmi_config(it); + ret =3D it6263_bridge_init(it); + if (ret) + return ret; =20 i2c_set_clientdata(client, it); =20 @@ -903,7 +949,18 @@ static int it6263_probe(struct i2c_client *client) it->bridge.vendor =3D "ITE"; it->bridge.product =3D "IT6263"; =20 - return devm_drm_bridge_add(dev, &it->bridge); + ret =3D devm_drm_bridge_add(dev, &it->bridge); + if (ret) + it6263_bridge_uninit(it); + + return ret; +} + +static void it6263_remove(struct i2c_client *i2c) +{ + struct it6263 *it =3D i2c_get_clientdata(i2c); + + it6263_bridge_uninit(it); } =20 static const struct of_device_id it6263_of_match[] =3D { @@ -920,6 +977,7 @@ MODULE_DEVICE_TABLE(i2c, it6263_i2c_ids); =20 static struct i2c_driver it6263_driver =3D { .probe =3D it6263_probe, + .remove =3D it6263_remove, .driver =3D { .name =3D "it6263", .of_match_table =3D it6263_of_match, --=20 2.43.0