From patchwork Wed Mar 22 10:46:30 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Pin-yen Lin X-Patchwork-Id: 666241 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id A48E8C761AF for ; Wed, 22 Mar 2023 10:47:21 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229688AbjCVKrT (ORCPT ); Wed, 22 Mar 2023 06:47:19 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:40766 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229788AbjCVKrS (ORCPT ); Wed, 22 Mar 2023 06:47:18 -0400 Received: from mail-pl1-x62e.google.com (mail-pl1-x62e.google.com [IPv6:2607:f8b0:4864:20::62e]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id D334A5F6D7 for ; Wed, 22 Mar 2023 03:46:54 -0700 (PDT) Received: by mail-pl1-x62e.google.com with SMTP id u5so18861775plq.7 for ; Wed, 22 Mar 2023 03:46:54 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; t=1679482014; 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=taPmB4+Xp9EC511rcY4vhFNfgJl8IMtTdglowbBg2bA=; b=TRfNa5Bjym9D/QOWv3oireKkb637T2hgKBgTBhwgznroO/IjIvby1HKxj8T78xQsPf gA7BKv0GlqGZZTjg9B+pKlOcISJ5w8svZIcbRBIQKpRbmBW8arjwvK3SbvfPeK7gfrf+ pf6LJFcpkKHiwR3AHOWxcu4hh6JK9N+jVw22I= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; t=1679482014; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=taPmB4+Xp9EC511rcY4vhFNfgJl8IMtTdglowbBg2bA=; b=gaNOBg7jgHtM1EmLO4biuR1xTeiVeZWnGf+YDoI14CVuZ+efthrkZzijUVUWP/wNjA FedWc05IJaAYcrDtLKaJWp8h3AJYEWdloChDeaMhtB0E8Vas0Jc5DCVOh2Q9o6DycAGY SB1IcQbQfl7ZS17LAz7oU2MAa8eLb3vrBsh3mI/cLgdmbFD7uRJRjgTPYIp0b7h91Uum gfWAnsw4b6JK7JcSgBPasZP4Mz4hX8MhbtHlLzrplBEN/adF5htz7Ex4Ef5xs9mb7kJa l3kU7sQd9HacLhW+wZlyUnwl2MmgrMgS1xqXBMLyUvxMRVb/CO1W+rI2jMJvGioUp45M nLTg== X-Gm-Message-State: AO0yUKVLobDzvOADjUa/YG6hF9fOa7VrtB6HmvZ12Mm9PJ2YmVCW+7uA RYykuoPs3AROhQcS4JQChry70g== X-Google-Smtp-Source: AK7set8NY7gSVoQ4fC5GN+MPbT1csTFpfLKJNC4YeNu9C5XL+LD4947BMZpiMhYqHKm0ufkRA9/KIg== X-Received: by 2002:a17:90b:1a81:b0:23e:f855:79f2 with SMTP id ng1-20020a17090b1a8100b0023ef85579f2mr3799890pjb.12.1679482014097; Wed, 22 Mar 2023 03:46:54 -0700 (PDT) Received: from treapking.tpe.corp.google.com ([2401:fa00:1:10:343d:79bf:55f9:1da5]) by smtp.gmail.com with ESMTPSA id hg4-20020a17090b300400b002340d317f3esm9508742pjb.52.2023.03.22.03.46.49 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 22 Mar 2023 03:46:53 -0700 (PDT) From: Pin-yen Lin To: Andrzej Hajda , Neil Armstrong , Robert Foss , Laurent Pinchart , Jonas Karlman , Jernej Skrabec , David Airlie , Daniel Vetter , Rob Herring , Krzysztof Kozlowski , Andy Shevchenko , Daniel Scally , Heikki Krogerus , Sakari Ailus , Greg Kroah-Hartman , "Rafael J . Wysocki" , Prashant Malani , Benson Leung , Guenter Roeck Cc: Xin Ji , linux-kernel@vger.kernel.org, Thomas Zimmermann , linux-acpi@vger.kernel.org, Javier Martinez Canillas , AngeloGioacchino Del Regno , Pin-yen Lin , Hsin-Yi Wang , Lyude Paul , =?utf-8?q?N=C3=ADcolas_F_=2E_R_=2E_A_=2E_Pra?= =?utf-8?q?do?= , Allen Chen , dri-devel@lists.freedesktop.org, Marek Vasut , Stephen Boyd , chrome-platform@lists.linux.dev, devicetree@vger.kernel.org Subject: [PATCH v14 01/10] device property: Add remote endpoint to devcon matcher Date: Wed, 22 Mar 2023 18:46:30 +0800 Message-Id: <20230322104639.221402-2-treapking@chromium.org> X-Mailer: git-send-email 2.40.0.rc1.284.g88254d51c5-goog In-Reply-To: <20230322104639.221402-1-treapking@chromium.org> References: <20230322104639.221402-1-treapking@chromium.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-acpi@vger.kernel.org From: Prashant Malani When searching the device graph for device matches, check the remote-endpoint itself for a match. Some drivers register devices for individual endpoints. This allows the matcher code to evaluate those for a match too, instead of only looking at the remote parent devices. This is required when a device supports two mode switches in its endpoints, so we can't simply register the mode switch with the parent node. Signed-off-by: Prashant Malani Signed-off-by: Pin-yen Lin Reviewed-by: Andy Shevchenko Reviewed-by: Sakari Ailus Reviewed-by: Heikki Krogerus --- Changes in v14: - Collect review tags Changes in v13: - Update the kernel doc of fwnode_connection_find_match Changes in v12: - Check the availability of the device node in fwnode_graph_devcon_matches - Ensured valid access to "matches" in fwnode_graph_devcon_matches - Updated the documentation in fwnode_connection_find_match(es) - Dropped collected tags due to the new changes Changes in v11: - Added missing fwnode_handle_put in drivers/base/property.c Changes in v10: - Collected Reviewed-by and Tested-by tags Changes in v6: - New in v6 drivers/base/property.c | 31 ++++++++++++++++++++++++++----- 1 file changed, 26 insertions(+), 5 deletions(-) diff --git a/drivers/base/property.c b/drivers/base/property.c index 083a95791d3b..4426ac2b16ca 100644 --- a/drivers/base/property.c +++ b/drivers/base/property.c @@ -1243,6 +1243,23 @@ static unsigned int fwnode_graph_devcon_matches(const struct fwnode_handle *fwno continue; } + ret = match(node, con_id, data); + fwnode_handle_put(node); + if (ret) { + if (matches) + matches[count] = ret; + count++; + + if (matches && count >= matches_len) + break; + } + + /* + * Some drivers may register devices for endpoints. Check + * the remote-endpoints for matches in addition to the remote + * port parent. + */ + node = fwnode_graph_get_remote_endpoint(ep); ret = match(node, con_id, data); fwnode_handle_put(node); if (ret) { @@ -1293,8 +1310,11 @@ static unsigned int fwnode_devcon_matches(const struct fwnode_handle *fwnode, * @match: Function to check and convert the connection description * * Find a connection with unique identifier @con_id between @fwnode and another - * device node. @match will be used to convert the connection description to - * data the caller is expecting to be returned. + * device node. For fwnode graph connections, the graph endpoints are also + * checked. @match will be used to convert the connection description to data + * the caller is expecting to be returned. + * + * Return: The pointer to the matched node, or NULL on error. */ void *fwnode_connection_find_match(const struct fwnode_handle *fwnode, const char *con_id, void *data, @@ -1325,9 +1345,10 @@ EXPORT_SYMBOL_GPL(fwnode_connection_find_match); * @matches_len: Length of @matches * * Find up to @matches_len connections with unique identifier @con_id between - * @fwnode and other device nodes. @match will be used to convert the - * connection description to data the caller is expecting to be returned - * through the @matches array. + * @fwnode and other device nodes. For fwnode graph connections, the graph + * endpoints are also checked. @match will be used to convert the connection + * description to data the caller is expecting to be returned through the + * @matches array. * If @matches is NULL @matches_len is ignored and the total number of resolved * matches is returned. * From patchwork Wed Mar 22 10:46:31 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Pin-yen Lin X-Patchwork-Id: 665941 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 4C316C6FD1F for ; Wed, 22 Mar 2023 10:47:37 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229911AbjCVKre (ORCPT ); Wed, 22 Mar 2023 06:47:34 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:40826 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229631AbjCVKrV (ORCPT ); Wed, 22 Mar 2023 06:47:21 -0400 Received: from mail-pj1-x102f.google.com (mail-pj1-x102f.google.com [IPv6:2607:f8b0:4864:20::102f]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 6F91261ABD for ; Wed, 22 Mar 2023 03:47:00 -0700 (PDT) Received: by mail-pj1-x102f.google.com with SMTP id j3-20020a17090adc8300b0023d09aea4a6so23179768pjv.5 for ; Wed, 22 Mar 2023 03:47:00 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; t=1679482019; 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=4+5+KeEGvj5Q2Ho8473pkowWeg3TWrycUDtZWzvt1Sk=; b=UGpIC/Esbs9QLxaTfp3b+iA9ZmIWKea/P1K5lNMblbFya52zYzHjcYV9Z1dh4jHxNT 5aHsz059WF//B+UsDC8QyXJ5zQHDy4bbjSVoqWq64B6RkpGTSGA24V1Tz7DMUrOe12jI xFPBgkoHzetP5XlAMPY3aZX7q415j8RX4XHXY= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; t=1679482019; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=4+5+KeEGvj5Q2Ho8473pkowWeg3TWrycUDtZWzvt1Sk=; b=cOcxI5t7gefJCIpygc8wAmqutKKkgj+L0kbgy56JtVLNRuzEgqABa1qRMAlCU6HmEN J6Zjxn4vbf+dzPMWHS7ggb/Wrjg0L0rq3yfrtsvbKHwV7A6RD9MKlqFZb4rsDXlsrhB/ 5u6+DpmHAxMS6k2anxixWrV1o7OuWqZNGP+DL2YVQhtwk8ShXkAchXeLNTrZx0Cc+zpj L8R1QXmadq7Hc+ttCqQMPCKqn8fS07eGrk3z85lsnF46dOyi6pClMia+Mor2rqpy149O vkZSeAokdB8l3HXlQ9P4Cibnlqg7j9un3CyRh8jVIOEZni/4Q5ikLDFHZ8M8JCNHSKp7 keSQ== X-Gm-Message-State: AO0yUKUqeencB1bMXpBWS/qDcDLEq1ovjJbpij/SadDr0uM1XYLHNN3p q0DsywIu5zGx7gCk+JTQ7iopVg== X-Google-Smtp-Source: AK7set90wpsycDChw65ny437J2h3RkWbTdHA+NGhsdfPnCYIlZE0iipJ0qCRLlLh4eP/BKLB8wMrnA== X-Received: by 2002:a17:90a:50:b0:23f:ebf2:d3e9 with SMTP id 16-20020a17090a005000b0023febf2d3e9mr3333274pjb.6.1679482019432; Wed, 22 Mar 2023 03:46:59 -0700 (PDT) Received: from treapking.tpe.corp.google.com ([2401:fa00:1:10:343d:79bf:55f9:1da5]) by smtp.gmail.com with ESMTPSA id hg4-20020a17090b300400b002340d317f3esm9508742pjb.52.2023.03.22.03.46.54 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 22 Mar 2023 03:46:59 -0700 (PDT) From: Pin-yen Lin To: Andrzej Hajda , Neil Armstrong , Robert Foss , Laurent Pinchart , Jonas Karlman , Jernej Skrabec , David Airlie , Daniel Vetter , Rob Herring , Krzysztof Kozlowski , Andy Shevchenko , Daniel Scally , Heikki Krogerus , Sakari Ailus , Greg Kroah-Hartman , "Rafael J . Wysocki" , Prashant Malani , Benson Leung , Guenter Roeck Cc: Xin Ji , linux-kernel@vger.kernel.org, Thomas Zimmermann , linux-acpi@vger.kernel.org, Javier Martinez Canillas , AngeloGioacchino Del Regno , Pin-yen Lin , Hsin-Yi Wang , Lyude Paul , =?utf-8?q?N=C3=ADcolas_F_=2E_R_=2E_A_=2E_Pra?= =?utf-8?q?do?= , Allen Chen , dri-devel@lists.freedesktop.org, Marek Vasut , Stephen Boyd , chrome-platform@lists.linux.dev, devicetree@vger.kernel.org, Chen-Yu Tsai Subject: [PATCH v14 02/10] platform/chrome: cros_ec_typec: Purge blocking switch devlinks Date: Wed, 22 Mar 2023 18:46:31 +0800 Message-Id: <20230322104639.221402-3-treapking@chromium.org> X-Mailer: git-send-email 2.40.0.rc1.284.g88254d51c5-goog In-Reply-To: <20230322104639.221402-1-treapking@chromium.org> References: <20230322104639.221402-1-treapking@chromium.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-acpi@vger.kernel.org From: Prashant Malani When using OF graph, the fw_devlink code will create links between the individual port driver (cros-ec-typec here) and the parent device for a Type-C switch (like mode-switch). Since the mode-switch will in turn have the usb-c-connector (i.e the child of the port driver) as a supplier, fw_devlink will not be able to resolve the cyclic dependency correctly. As a result, the mode-switch driver probe() never runs, so mode-switches are never registered. Because of that, the port driver probe constantly fails with -EPROBE_DEFER, because the Type-C connector class requires all switch devices to be registered prior to port registration. To break this deadlock and allow the mode-switch registration to occur, purge all the usb-c-connector nodes' absent suppliers. This eliminates the connector as a supplier for a switch and allows it to be probed. Signed-off-by: Prashant Malani Signed-off-by: Pin-yen Lin Reviewed-by: Chen-Yu Tsai Tested-by: Chen-Yu Tsai Acked-by: Heikki Krogerus --- (no changes since v11) Changes in v11: - Collected Acked-by tag Changes in v10: - Collected Reviewed-by and Tested-by tags Changes in v7: - Fix the long comment lines Changes in v6: - New in v6 drivers/platform/chrome/cros_ec_typec.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/drivers/platform/chrome/cros_ec_typec.c b/drivers/platform/chrome/cros_ec_typec.c index a673c3342470..5911cd9640cb 100644 --- a/drivers/platform/chrome/cros_ec_typec.c +++ b/drivers/platform/chrome/cros_ec_typec.c @@ -325,6 +325,16 @@ static int cros_typec_init_ports(struct cros_typec_data *typec) return -EINVAL; } + /* + * OF graph may have set up some device links with switches, + * since connectors have their own compatible. Purge these + * to avoid a deadlock in switch probe (the switch mistakenly + * assumes the connector is a supplier). + */ + if (dev_of_node(dev)) + device_for_each_child_node(dev, fwnode) + fw_devlink_purge_absent_suppliers(fwnode); + /* DT uses "reg" to specify port number. */ port_prop = dev->of_node ? "reg" : "port-number"; device_for_each_child_node(dev, fwnode) { From patchwork Wed Mar 22 10:46:32 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Pin-yen Lin X-Patchwork-Id: 666240 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 2911AC7619A for ; Wed, 22 Mar 2023 10:47:58 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230466AbjCVKr4 (ORCPT ); Wed, 22 Mar 2023 06:47:56 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:41304 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230341AbjCVKrr (ORCPT ); Wed, 22 Mar 2023 06:47:47 -0400 Received: from mail-pj1-x102b.google.com (mail-pj1-x102b.google.com [IPv6:2607:f8b0:4864:20::102b]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id F352B618A0 for ; Wed, 22 Mar 2023 03:47:07 -0700 (PDT) Received: by mail-pj1-x102b.google.com with SMTP id om3-20020a17090b3a8300b0023efab0e3bfso23055014pjb.3 for ; Wed, 22 Mar 2023 03:47:07 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; t=1679482025; 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=QwE+rQNB/r0zkpUtn1CEsBq5RXYR8mJoWWozziC24t4=; b=h6CtmOhMLvCWoW1JhkmdVQbfSpbuLj+UDn/FgrDuq8Nz4REQeqhe89lhrTnXucrVkD xBpwEt5YRVSIE47/iD7CDRI/SbU7u7YP6jciZ+ZxJ6cv2siMYy+BFt+Zm1i19AtdUF8V Y11vs4zu3yUhHpUU9OoEO1DCccG6xbolMXONk= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; t=1679482025; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=QwE+rQNB/r0zkpUtn1CEsBq5RXYR8mJoWWozziC24t4=; b=vq5tvjmIyngfsXlRDinZ3zvHVNIImeHNxjT+cHub3ucJlWxmUZ1H20HhWyXoo8zTa9 VWNHa564X4/30e/Lx9u+nhRIJPM8Fw1kQfhaLgyvO2VY4ms6sJw561iY9Ynddoi+sIi5 HKYn0aYk45G9ifz3BxvKICTwQbIZdFtfAwXHI4pZAMb42BPUvVTobgeAsV1DPISA7kFa JuyZ63a7OzcAT0GHvUSmrhlZB//kdlD3JIx0MjwFvL4r/SU6slTk39Hm4yE1ycL+r2NG rmVFiGGjtMlB+aHIOf5cnqzcNBfUrYAbi/ewkE08nPPtn5+r0VKUzzQRL2BbyKtg4wDk MQ+A== X-Gm-Message-State: AO0yUKVFS2B+z8HVHeaKhtEWpWrSnmLFSIFR5iWdc2cVYhcyG3GEs+iW luz0/aUTb+vfzcKOgR4tZjjUyA== X-Google-Smtp-Source: AK7set8ED3YpZszbpfEASp0JiCv0mfXwOVC7TjOLn7h9bWWnaNT58THOPSZzoLwYo6hf+Ym9Lqr1qw== X-Received: by 2002:a17:90b:3850:b0:23b:3699:b8a9 with SMTP id nl16-20020a17090b385000b0023b3699b8a9mr3160147pjb.17.1679482025556; Wed, 22 Mar 2023 03:47:05 -0700 (PDT) Received: from treapking.tpe.corp.google.com ([2401:fa00:1:10:343d:79bf:55f9:1da5]) by smtp.gmail.com with ESMTPSA id hg4-20020a17090b300400b002340d317f3esm9508742pjb.52.2023.03.22.03.46.59 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 22 Mar 2023 03:47:05 -0700 (PDT) From: Pin-yen Lin To: Andrzej Hajda , Neil Armstrong , Robert Foss , Laurent Pinchart , Jonas Karlman , Jernej Skrabec , David Airlie , Daniel Vetter , Rob Herring , Krzysztof Kozlowski , Andy Shevchenko , Daniel Scally , Heikki Krogerus , Sakari Ailus , Greg Kroah-Hartman , "Rafael J . Wysocki" , Prashant Malani , Benson Leung , Guenter Roeck Cc: Xin Ji , linux-kernel@vger.kernel.org, Thomas Zimmermann , linux-acpi@vger.kernel.org, Javier Martinez Canillas , AngeloGioacchino Del Regno , Pin-yen Lin , Hsin-Yi Wang , Lyude Paul , =?utf-8?q?N=C3=ADcolas_F_=2E_R_=2E_A_=2E_Pra?= =?utf-8?q?do?= , Allen Chen , dri-devel@lists.freedesktop.org, Marek Vasut , Stephen Boyd , chrome-platform@lists.linux.dev, devicetree@vger.kernel.org, Andi Shyti , Dmitry Baryshkov , Douglas Anderson , Imre Deak , Jani Nikula , Linus Walleij , YueHaibing Subject: [PATCH v14 03/10] drm/display: Add Type-C switch helpers Date: Wed, 22 Mar 2023 18:46:32 +0800 Message-Id: <20230322104639.221402-4-treapking@chromium.org> X-Mailer: git-send-email 2.40.0.rc1.284.g88254d51c5-goog In-Reply-To: <20230322104639.221402-1-treapking@chromium.org> References: <20230322104639.221402-1-treapking@chromium.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-acpi@vger.kernel.org Add helpers to register and unregister Type-C "switches" for bridges capable of switching their output between two downstream devices. The helper registers USB Type-C mode switches when the "mode-switch" and the "reg" properties are available in Device Tree. Signed-off-by: Pin-yen Lin --- Changes in v14: - Introduce a new Kconfig becuase it didn't build when CONFIG_TYPEC=m - Add comments about devm_* usage - Fix style issues Changes in v13: - Add typec_mode_switch_node_count helper - Fix style issues Changes in v12: - Add fwnode_for_each_typec_mode_switch macro - Remove a duplicated dmesg in the helper - Used IS_REACHABLE instead to guard the function signatures Changes in v11: - Use fwnode helpers instead of DT - Moved the helpers to a new file - Use "reg" instead of "data-lanes" to determine the port number - Dropped collected tags due to new changes Changes in v10: - Collected Reviewed-by and Tested-by tags - Replaced "void *" with "typec_mux_set_fn_t" for mux_set callbacks - Print out the node name when errors on parsing DT - Use dev_dbg instead of dev_warn when no Type-C switch nodes available - Made the return path of drm_dp_register_mode_switch clearer Changes in v8: - Fixed the build issue when CONFIG_TYPEC=m - Fixed some style issues Changes in v7: - Extracted the common codes to a helper function - New in v7 drivers/gpu/drm/display/Kconfig | 8 ++ drivers/gpu/drm/display/Makefile | 2 + drivers/gpu/drm/display/drm_dp_typec_helper.c | 105 ++++++++++++++++++ include/drm/display/drm_dp_helper.h | 46 ++++++++ 4 files changed, 161 insertions(+) create mode 100644 drivers/gpu/drm/display/drm_dp_typec_helper.c diff --git a/drivers/gpu/drm/display/Kconfig b/drivers/gpu/drm/display/Kconfig index 09712b88a5b8..d61076947a1c 100644 --- a/drivers/gpu/drm/display/Kconfig +++ b/drivers/gpu/drm/display/Kconfig @@ -29,6 +29,14 @@ config DRM_DISPLAY_HDMI_HELPER help DRM display helpers for HDMI. +config DRM_DISPLAY_DP_TYPEC_HELPER + bool + default y + depends on DRM_DISPLAY_HELPER + depends on DRM_DISPLAY_HELPER=TYPEC || TYPEC=y + help + DRM display helpers for USB Type-C Displayport Alternate mode. + config DRM_DP_AUX_CHARDEV bool "DRM DP AUX Interface" depends on DRM && DRM_DISPLAY_HELPER diff --git a/drivers/gpu/drm/display/Makefile b/drivers/gpu/drm/display/Makefile index 17ac4a1006a8..2202a6aea38e 100644 --- a/drivers/gpu/drm/display/Makefile +++ b/drivers/gpu/drm/display/Makefile @@ -8,6 +8,8 @@ drm_display_helper-$(CONFIG_DRM_DISPLAY_DP_HELPER) += \ drm_dp_helper.o \ drm_dp_mst_topology.o \ drm_dsc_helper.o +drm_display_helper-$(CONFIG_DRM_DISPLAY_DP_TYPEC_HELPER) += \ + drm_dp_typec_helper.o drm_display_helper-$(CONFIG_DRM_DISPLAY_HDCP_HELPER) += drm_hdcp_helper.o drm_display_helper-$(CONFIG_DRM_DISPLAY_HDMI_HELPER) += \ drm_hdmi_helper.o \ diff --git a/drivers/gpu/drm/display/drm_dp_typec_helper.c b/drivers/gpu/drm/display/drm_dp_typec_helper.c new file mode 100644 index 000000000000..1562a9ccdaf2 --- /dev/null +++ b/drivers/gpu/drm/display/drm_dp_typec_helper.c @@ -0,0 +1,105 @@ +// SPDX-License-Identifier: GPL-2.0 + +#include +#include + +static int drm_dp_register_mode_switch(struct device *dev, + struct fwnode_handle *fwnode, + struct drm_dp_typec_switch_desc *switch_desc, + void *data, typec_mux_set_fn_t mux_set) +{ + struct drm_dp_typec_port_data *port_data; + struct typec_mux_desc mux_desc = {}; + char name[32]; + u32 port_num; + int ret; + + ret = fwnode_property_read_u32(fwnode, "reg", &port_num); + if (ret) { + dev_err(dev, "Failed to read reg property: %d\n", ret); + return ret; + } + + port_data = &switch_desc->typec_ports[port_num]; + port_data->data = data; + port_data->port_num = port_num; + port_data->fwnode = fwnode; + mux_desc.fwnode = fwnode; + mux_desc.drvdata = port_data; + snprintf(name, sizeof(name), "%pfwP-%u", fwnode, port_num); + mux_desc.name = name; + mux_desc.set = mux_set; + + port_data->typec_mux = typec_mux_register(dev, &mux_desc); + ret = PTR_ERR_OR_ZERO(port_data->typec_mux); + if (ret) + dev_err(dev, "Mode switch register for port %d failed: %d\n", + port_num, ret); + + return ret; +} + +/** + * drm_dp_register_typec_switches() - register Type-C switches + * @dev: Device that registers Type-C switches + * @port: Device node for the switch + * @switch_desc: A Type-C switch descriptor + * @data: Private data for the switches + * @mux_set: Callback function for typec_mux_set + * + * This function registers USB Type-C switches for DP bridges that can switch + * the output signal between their output pins. This function uses devm_kcalloc + * to allocate memory, so it is expected to only call this in the driver probe + * functions. + * + * Currently only mode switches are implemented, and the function assumes the + * given @port device node has endpoints with "mode-switch" property. + * The port number is determined by the "reg" property of the endpoint. + */ +int drm_dp_register_typec_switches(struct device *dev, struct fwnode_handle *port, + struct drm_dp_typec_switch_desc *switch_desc, + void *data, typec_mux_set_fn_t mux_set) +{ + struct fwnode_handle *sw; + int ret; + + switch_desc->num_typec_switches = typec_mode_switch_node_count(port); + if (!switch_desc->num_typec_switches) { + dev_dbg(dev, "No Type-C switches node found\n"); + return 0; + } + + switch_desc->typec_ports = devm_kcalloc(dev, switch_desc->num_typec_switches, + sizeof(struct drm_dp_typec_port_data), + GFP_KERNEL); + if (!switch_desc->typec_ports) + return -ENOMEM; + + /* Register switches for each connector. */ + for_each_typec_mode_switch_node(port, sw) { + ret = drm_dp_register_mode_switch(dev, sw, switch_desc, data, mux_set); + if (ret) + goto err_unregister_typec_switches; + } + + return 0; + +err_unregister_typec_switches: + fwnode_handle_put(sw); + drm_dp_unregister_typec_switches(switch_desc); + return ret; +} +EXPORT_SYMBOL(drm_dp_register_typec_switches); + +/** + * drm_dp_unregister_typec_switches() - unregister Type-C switches + * @switch_desc: A Type-C switch descriptor + */ +void drm_dp_unregister_typec_switches(struct drm_dp_typec_switch_desc *switch_desc) +{ + unsigned int i; + + for (i = 0; i < switch_desc->num_typec_switches; i++) + typec_mux_unregister(switch_desc->typec_ports[i].typec_mux); +} +EXPORT_SYMBOL(drm_dp_unregister_typec_switches); diff --git a/include/drm/display/drm_dp_helper.h b/include/drm/display/drm_dp_helper.h index ab55453f2d2c..0fe56586d7bc 100644 --- a/include/drm/display/drm_dp_helper.h +++ b/include/drm/display/drm_dp_helper.h @@ -25,6 +25,7 @@ #include #include +#include #include #include @@ -763,4 +764,49 @@ bool drm_dp_downstream_rgb_to_ycbcr_conversion(const u8 dpcd[DP_RECEIVER_CAP_SIZ const u8 port_cap[4], u8 color_spc); int drm_dp_pcon_convert_rgb_to_ycbcr(struct drm_dp_aux *aux, u8 color_spc); +struct drm_dp_typec_port_data { + struct typec_mux_dev *typec_mux; + int port_num; + struct fwnode_handle *fwnode; + void *data; +}; + +struct drm_dp_typec_switch_desc { + int num_typec_switches; + struct drm_dp_typec_port_data *typec_ports; +}; + +#define for_each_typec_mode_switch_node(port, sw) \ + fwnode_for_each_child_node((port), (sw)) \ + for_each_if(fwnode_property_present((sw), "mode-switch")) + +static inline unsigned int typec_mode_switch_node_count(struct fwnode_handle *port) +{ + struct fwnode_handle *sw; + unsigned int count = 0; + + for_each_typec_mode_switch_node(port, sw) + count++; + + return count; +} + +#ifdef CONFIG_DRM_DISPLAY_DP_TYPEC_HELPER +void drm_dp_unregister_typec_switches(struct drm_dp_typec_switch_desc *switch_desc); +int drm_dp_register_typec_switches(struct device *dev, struct fwnode_handle *port, + struct drm_dp_typec_switch_desc *switch_desc, + void *data, typec_mux_set_fn_t mux_set); +#else +static inline void drm_dp_unregister_typec_switches(struct drm_dp_typec_switch_desc *switch_desc) +{ +} +static inline int drm_dp_register_typec_switches( + struct device *dev, struct fwnode_handle *port, + struct drm_dp_typec_switch_desc *switch_desc, void *data, + typec_mux_set_fn_t mux_set) +{ + return -EOPNOTSUPP; +} +#endif + #endif /* _DRM_DP_HELPER_H_ */ From patchwork Wed Mar 22 10:46:33 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Pin-yen Lin X-Patchwork-Id: 665940 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 162F2C6FD1C for ; Wed, 22 Mar 2023 10:48:11 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230428AbjCVKsK (ORCPT ); Wed, 22 Mar 2023 06:48:10 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:42136 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230440AbjCVKry (ORCPT ); Wed, 22 Mar 2023 06:47:54 -0400 Received: from mail-pl1-x62b.google.com (mail-pl1-x62b.google.com [IPv6:2607:f8b0:4864:20::62b]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id DEA3262338 for ; Wed, 22 Mar 2023 03:47:13 -0700 (PDT) Received: by mail-pl1-x62b.google.com with SMTP id kc4so4264377plb.10 for ; Wed, 22 Mar 2023 03:47:13 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; t=1679482031; 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=Qv3ksKSCg+9IA4ODwUD5ZGbwkN5dvfp2M1XcwFFi/6g=; b=JIReK93e9p3sTkiq3OYuLEGCFxKP8/gMxCdLkl5MQ2WZ/V1EsedH8G9N3s0sFDYqM0 n3ozxCe5Fwxogi2DmK7gyr0EPq0l9phlm8ldgXITjZw02JzuJwUqwQJShe6K4otInt++ QYNbFnmRRl3NxLtntHjKLLvQM/IKRg9pkpbbs= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; t=1679482031; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=Qv3ksKSCg+9IA4ODwUD5ZGbwkN5dvfp2M1XcwFFi/6g=; b=7zID0UzVI6S3G0lTqIkarVJtm08ArlggqDKM2mQtf1EfSl2cO4eoC8h5OkpJ1CgDcL hHdhF9mP6ln9/RbB1O+MicGycIhInrA0SOh21U9Xz3farUE0Q8A6Wsv3aYNhvSsSwS6q DFFJK0hryGVlfxAkIZL2Zj71gft1ujhzVTjcXxHPENltjPzstfnbGXl4YIK5dVKPJXaC etCm7SbziGb+uudtsKlYZ8ejJRyMGfGrZB3HpLXU5+mXAtjwQzTk8U0UghF6GhgFsmT3 9Ww1pLbu19nUZ3zEg6hS57Hkje+8cwt/Q++eL27drhhokCDqkq9hquD3JYuA8dR0O371 3I4w== X-Gm-Message-State: AO0yUKX2Z6GuwJOvhk6SEAP7DuS3LlUFhfa5XMZv9Mg3XDB2mbeq0K8n kqxk/QSMAFjyIOYbeXzIGA7r7Q== X-Google-Smtp-Source: AK7set+f9Wb+Q2WCbYZ0MAoO/CIWeV7uIpVl8+z0cc76zHIsYDd9CwxxsIb/zDGYgilYuXTTcCb1dg== X-Received: by 2002:a17:90b:1c04:b0:23f:48b9:266d with SMTP id oc4-20020a17090b1c0400b0023f48b9266dmr3089936pjb.21.1679482030989; Wed, 22 Mar 2023 03:47:10 -0700 (PDT) Received: from treapking.tpe.corp.google.com ([2401:fa00:1:10:343d:79bf:55f9:1da5]) by smtp.gmail.com with ESMTPSA id hg4-20020a17090b300400b002340d317f3esm9508742pjb.52.2023.03.22.03.47.05 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 22 Mar 2023 03:47:10 -0700 (PDT) From: Pin-yen Lin To: Andrzej Hajda , Neil Armstrong , Robert Foss , Laurent Pinchart , Jonas Karlman , Jernej Skrabec , David Airlie , Daniel Vetter , Rob Herring , Krzysztof Kozlowski , Andy Shevchenko , Daniel Scally , Heikki Krogerus , Sakari Ailus , Greg Kroah-Hartman , "Rafael J . Wysocki" , Prashant Malani , Benson Leung , Guenter Roeck Cc: Xin Ji , linux-kernel@vger.kernel.org, Thomas Zimmermann , linux-acpi@vger.kernel.org, Javier Martinez Canillas , AngeloGioacchino Del Regno , Pin-yen Lin , Hsin-Yi Wang , Lyude Paul , =?utf-8?q?N=C3=ADcolas_F_=2E_R_=2E_A_=2E_Pra?= =?utf-8?q?do?= , Allen Chen , dri-devel@lists.freedesktop.org, Marek Vasut , Stephen Boyd , chrome-platform@lists.linux.dev, devicetree@vger.kernel.org, Krzysztof Kozlowski , Chen-Yu Tsai Subject: [PATCH v14 04/10] dt-bindings: display: bridge: anx7625: Add mode-switch support Date: Wed, 22 Mar 2023 18:46:33 +0800 Message-Id: <20230322104639.221402-5-treapking@chromium.org> X-Mailer: git-send-email 2.40.0.rc1.284.g88254d51c5-goog In-Reply-To: <20230322104639.221402-1-treapking@chromium.org> References: <20230322104639.221402-1-treapking@chromium.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-acpi@vger.kernel.org Analogix 7625 can be used in systems to switch the DP traffic between two downstreams, which can be USB Type-C DisplayPort alternate mode lane or regular DisplayPort output ports. Update the binding to accommodate this usage by introducing a data-lanes and a mode-switch property on endpoints. Also include the link to the product brief in the bindings. Signed-off-by: Pin-yen Lin Reviewed-by: Krzysztof Kozlowski Reviewed-by: Chen-Yu Tsai Tested-by: Chen-Yu Tsai Reviewed-by: AngeloGioacchino Del Regno --- (no changes since v12) Changes in v12: - Removed the 4-lane binding in analogix,anx7625.yaml - Reworded the description for the mode-switch property Changes in v11: - Updated the description of the endpoints - Referenced video-interfaces.yaml instead for the endpoints Changes in v10: - Collected Reviewed-by and Tested-by tags Changes in v9: - Collected Reviewed-by tag Changes in v8: - Updated anx7625 bindings for data-lane property - Fixed the subject prefix Changes in v7: - Fixed issues reported by dt_binding_check - Updated the schema and the example dts for data-lanes. - Changed to generic naming for the example dts node. Changes in v6: - Remove switches node and use endpoints and data-lanes property to describe the connections. .../display/bridge/analogix,anx7625.yaml | 88 ++++++++++++++++++- 1 file changed, 85 insertions(+), 3 deletions(-) diff --git a/Documentation/devicetree/bindings/display/bridge/analogix,anx7625.yaml b/Documentation/devicetree/bindings/display/bridge/analogix,anx7625.yaml index 4590186c4a0b..a50de536cffd 100644 --- a/Documentation/devicetree/bindings/display/bridge/analogix,anx7625.yaml +++ b/Documentation/devicetree/bindings/display/bridge/analogix,anx7625.yaml @@ -12,7 +12,8 @@ maintainers: description: | The ANX7625 is an ultra-low power 4K Mobile HD Transmitter - designed for portable devices. + designed for portable devices. Product brief is available at + https://www.analogix.com/en/system/files/AA-002291-PB-6-ANX7625_ProductBrief.pdf properties: compatible: @@ -112,9 +113,40 @@ properties: data-lanes: true port@1: - $ref: /schemas/graph.yaml#/properties/port + $ref: /schemas/graph.yaml#/$defs/port-base description: - Video port for panel or connector. + Video port for panel or connector. Each endpoint connects to a video + output downstream, and the "data-lanes" property is used to describe + the pin connections. 0, 1, 2, 3 in "data-lanes" maps to SSRX1, SSTX1, + SSRX2, SSTX2, respectively. + + patternProperties: + "^endpoint@[01]$": + $ref: /schemas/media/video-interfaces.yaml# + properties: + reg: true + + remote-endpoint: true + + data-lanes: + oneOf: + - items: + - enum: [0, 1, 2, 3] + + - items: + - const: 0 + - const: 1 + + - items: + - const: 2 + - const: 3 + + mode-switch: + type: boolean + description: Serves as Type-C mode switch if present. + + required: + - remote-endpoint required: - port@0 @@ -186,3 +218,53 @@ examples: }; }; }; + - | + i2c3 { + #address-cells = <1>; + #size-cells = <0>; + + encoder@58 { + compatible = "analogix,anx7625"; + reg = <0x58>; + pinctrl-names = "default"; + pinctrl-0 = <&anx7625_dp_pins>; + enable-gpios = <&pio 176 GPIO_ACTIVE_HIGH>; + reset-gpios = <&pio 177 GPIO_ACTIVE_HIGH>; + vdd10-supply = <&pp1100_dpbrdg>; + vdd18-supply = <&pp1800_dpbrdg_dx>; + vdd33-supply = <&pp3300_dpbrdg_dx>; + analogix,audio-enable; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + anx7625_dp_in: endpoint { + bus-type = <7>; + remote-endpoint = <&dpi_out>; + }; + }; + + port@1 { + #address-cells = <1>; + #size-cells = <0>; + + reg = <1>; + anx_typec0: endpoint@0 { + reg = <0>; + mode-switch; + data-lanes = <0 1>; + remote-endpoint = <&typec_port0>; + }; + anx_typec1: endpoint@1 { + reg = <1>; + mode-switch; + data-lanes = <2 3>; + remote-endpoint = <&typec_port1>; + }; + }; + }; + }; + }; From patchwork Wed Mar 22 10:46:34 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Pin-yen Lin X-Patchwork-Id: 666239 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 681B1C6FD1C for ; Wed, 22 Mar 2023 10:48:16 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229923AbjCVKsP (ORCPT ); Wed, 22 Mar 2023 06:48:15 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:42200 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230448AbjCVKrz (ORCPT ); Wed, 22 Mar 2023 06:47:55 -0400 Received: from mail-pl1-x631.google.com (mail-pl1-x631.google.com [IPv6:2607:f8b0:4864:20::631]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 56C765DED1 for ; Wed, 22 Mar 2023 03:47:19 -0700 (PDT) Received: by mail-pl1-x631.google.com with SMTP id le6so18847225plb.12 for ; Wed, 22 Mar 2023 03:47:19 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; t=1679482037; 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=cS29WoxUQLo4BQ309Cl3H3ZApJrAXVrclnM2SVgJFsU=; b=OMtCtiUazE3zaX2l1R50ngdXVHr+uI3FBVunt9kTXSHbM/uN7wiJOvx+pdFWt2TiqP 9OT8Xv/U8O1i6s5otVZUfFwAvpqurw4vsHaNl4ctoDbP2lDqxe4pJswDEGt0q0UxfbM5 WBtYPrhNigAP5Qhtnhg3p6Xlh6jiHhH172wzA= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; t=1679482037; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=cS29WoxUQLo4BQ309Cl3H3ZApJrAXVrclnM2SVgJFsU=; b=gmkQMSW5PpqkoGk01tjt6JBxpkqBWPCMQ4DgryjDgq6OxUqquTo9Z8BBINP+iaBs/W KceUCeSA1qEG5JRRktzQ+qoDtj+cI25IL4GFaFjYgTHULP5LiIA+pwouXkyA9a/nM3jS bIZcuUeUF6EeI6GBS8vwQCBFvo0bNc9gFJjWdvNS3B0Kr/1vubjeiKKv5j84HTFgUQKb vJJAg3XrCb8kDwhZXGVoYp9rEb3Ilf74/09uiCUhXMPS4I07X8wBDSgAucvMW50EpbnM Tw0FAaYrO9vXmgV4izsesS5x3HTJ1Ue+xWsPL7hrHnT1VVUO8vqh3ewCAUSRG4Ohhrl1 IpYQ== X-Gm-Message-State: AO0yUKXwna0LTOZM6Oxad1d7s5kBtBALamUM6oGlR9SotnNuBdLlrBWg Qg8DlkHEchGyxa0jjE8+LPH14g== X-Google-Smtp-Source: AK7set8fGmVxBLUWTjSl7r8WnygWcPOj87bCDMAljt4SxYg+KZgChWl1HjWbCDYL09wfME9RVQEO1g== X-Received: by 2002:a17:90a:191e:b0:237:50b6:9838 with SMTP id 30-20020a17090a191e00b0023750b69838mr3135278pjg.45.1679482036826; Wed, 22 Mar 2023 03:47:16 -0700 (PDT) Received: from treapking.tpe.corp.google.com ([2401:fa00:1:10:343d:79bf:55f9:1da5]) by smtp.gmail.com with ESMTPSA id hg4-20020a17090b300400b002340d317f3esm9508742pjb.52.2023.03.22.03.47.12 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 22 Mar 2023 03:47:16 -0700 (PDT) From: Pin-yen Lin To: Andrzej Hajda , Neil Armstrong , Robert Foss , Laurent Pinchart , Jonas Karlman , Jernej Skrabec , David Airlie , Daniel Vetter , Rob Herring , Krzysztof Kozlowski , Andy Shevchenko , Daniel Scally , Heikki Krogerus , Sakari Ailus , Greg Kroah-Hartman , "Rafael J . Wysocki" , Prashant Malani , Benson Leung , Guenter Roeck Cc: Xin Ji , linux-kernel@vger.kernel.org, Thomas Zimmermann , linux-acpi@vger.kernel.org, Javier Martinez Canillas , AngeloGioacchino Del Regno , Pin-yen Lin , Hsin-Yi Wang , Lyude Paul , =?utf-8?q?N=C3=ADcolas_F_=2E_R_=2E_A_=2E_Pra?= =?utf-8?q?do?= , Allen Chen , dri-devel@lists.freedesktop.org, Marek Vasut , Stephen Boyd , chrome-platform@lists.linux.dev, devicetree@vger.kernel.org Subject: [PATCH v14 05/10] drm/bridge: anx7625: Check for Type-C during panel registration Date: Wed, 22 Mar 2023 18:46:34 +0800 Message-Id: <20230322104639.221402-6-treapking@chromium.org> X-Mailer: git-send-email 2.40.0.rc1.284.g88254d51c5-goog In-Reply-To: <20230322104639.221402-1-treapking@chromium.org> References: <20230322104639.221402-1-treapking@chromium.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-acpi@vger.kernel.org The output port endpoints can be connected to USB-C connectors. Running drm_of_find_panel_or_bridge() with such endpoints leads to a continuous return value of -EPROBE_DEFER, even though there is no panel present. To avoid this, check for the existence of a "mode-switch" property in the port endpoint, and skip panel registration completely if so. Signed-off-by: Pin-yen Lin Reviewed-by: Andy Shevchenko --- Changes in v14: - Collect review tag Changes in v13: - Use the new typec_mode_switch_node_count helper Changes in v12: - Updated to use fwnode_for_each_typec_mode_switch macro - Dropped collected tags Changes in v10: - Collected Reviewed-by and Tested-by tags Changes in v6: - New in v6 drivers/gpu/drm/bridge/analogix/anx7625.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/bridge/analogix/anx7625.c b/drivers/gpu/drm/bridge/analogix/anx7625.c index 6846199a2ee1..3f6bf7674d32 100644 --- a/drivers/gpu/drm/bridge/analogix/anx7625.c +++ b/drivers/gpu/drm/bridge/analogix/anx7625.c @@ -1648,7 +1648,8 @@ static int anx7625_get_swing_setting(struct device *dev, static int anx7625_parse_dt(struct device *dev, struct anx7625_platform_data *pdata) { - struct device_node *np = dev->of_node, *ep0; + struct device_node *np = dev->of_node, *ep0, *port_node; + unsigned int count; int bus_type, mipi_lanes; anx7625_get_swing_setting(dev, pdata); @@ -1687,6 +1688,15 @@ static int anx7625_parse_dt(struct device *dev, if (of_property_read_bool(np, "analogix,audio-enable")) pdata->audio_en = 1; + /* + * Don't bother finding a panel if a Type-C `mode-switch` property is + * present in one of the endpoints in the output port. + */ + port_node = of_graph_get_port_by_id(np, 1); + count = typec_mode_switch_node_count(&port_node->fwnode); + if (count) + return 0; + pdata->panel_bridge = devm_drm_of_get_bridge(dev, np, 1, 0); if (IS_ERR(pdata->panel_bridge)) { if (PTR_ERR(pdata->panel_bridge) == -ENODEV) { From patchwork Wed Mar 22 10:46:35 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Pin-yen Lin X-Patchwork-Id: 665939 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id E52F9C6FD1C for ; Wed, 22 Mar 2023 10:48:28 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230120AbjCVKs1 (ORCPT ); Wed, 22 Mar 2023 06:48:27 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:42420 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230241AbjCVKr5 (ORCPT ); Wed, 22 Mar 2023 06:47:57 -0400 Received: from mail-pl1-x629.google.com (mail-pl1-x629.google.com [IPv6:2607:f8b0:4864:20::629]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id E7C2562333 for ; Wed, 22 Mar 2023 03:47:22 -0700 (PDT) Received: by mail-pl1-x629.google.com with SMTP id ja10so18877429plb.5 for ; Wed, 22 Mar 2023 03:47:22 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; t=1679482042; 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=Zi5kRr1rKA9wYplZo1eciMlGKtNnjsOD4nLoCcW5ycY=; b=j8+Qriw2FxqOOr9uGlvsHYw37O5aqZQgxpfadsVvzBCMVQTTE8TZaEDOZ7k07SKhzg na9Xaj7Z3ju8BUKQvTLqFg6fl0uz/rPPJCu0b+rGSE5hQDYgE4lECOVDGa9P/IltEKRH njgRrMSBRo04CkZ2RJ6DAsHq0m9PwEj9RYTtA= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; t=1679482042; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=Zi5kRr1rKA9wYplZo1eciMlGKtNnjsOD4nLoCcW5ycY=; b=tub4wf6j4mrA/HogKAyBarlbPJA1qeyUJOpSM9Y5mxbhJkkT4hnGMxP0EDKy9VubCL bWyIhuAwiddxS0T76peC/4OSugSiiPpK2NBU7eUkkKHkE4YDusdDxIxigk5gKSrGpFak OWaWjW8Urtp26ajOuFZyPDY39Uf3vACUCPmFFN254opaUB5aXwnWN5hjoaxDj4fFYr6N STL2Jbuk/AMBUUFF/uVLNUiNVNg/p0QQ7q8zfPnXgg0DUikl7OU3AZYhY8bhcXi3fZWY 77klhHNQs3UV0f/YZrrQ+VodaYU3HMUwX9bZlaJPC6NNZyJiavKqvbDsveJiKiRnAbZE Pwng== X-Gm-Message-State: AO0yUKWgbSfJ+MYyLydkd6DgbG9B/eDpGLOsH3uQuZ45E2tVaTy07+KM Oz++b4jpvsh24+akjgvBjrk43Q== X-Google-Smtp-Source: AK7set8sqKKY5MR3zx6z4kZ8AxVP6rSKRQygVLNpE3BtKSadWMuJ+DOa86uCmA8EPH8cK7uMk0pVlw== X-Received: by 2002:a17:90b:4b51:b0:23d:1aae:29e5 with SMTP id mi17-20020a17090b4b5100b0023d1aae29e5mr3333471pjb.20.1679482042307; Wed, 22 Mar 2023 03:47:22 -0700 (PDT) Received: from treapking.tpe.corp.google.com ([2401:fa00:1:10:343d:79bf:55f9:1da5]) by smtp.gmail.com with ESMTPSA id hg4-20020a17090b300400b002340d317f3esm9508742pjb.52.2023.03.22.03.47.17 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 22 Mar 2023 03:47:22 -0700 (PDT) From: Pin-yen Lin To: Andrzej Hajda , Neil Armstrong , Robert Foss , Laurent Pinchart , Jonas Karlman , Jernej Skrabec , David Airlie , Daniel Vetter , Rob Herring , Krzysztof Kozlowski , Andy Shevchenko , Daniel Scally , Heikki Krogerus , Sakari Ailus , Greg Kroah-Hartman , "Rafael J . Wysocki" , Prashant Malani , Benson Leung , Guenter Roeck Cc: Xin Ji , linux-kernel@vger.kernel.org, Thomas Zimmermann , linux-acpi@vger.kernel.org, Javier Martinez Canillas , AngeloGioacchino Del Regno , Pin-yen Lin , Hsin-Yi Wang , Lyude Paul , =?utf-8?q?N=C3=ADcolas_F_=2E_R_=2E_A_=2E_Pra?= =?utf-8?q?do?= , Allen Chen , dri-devel@lists.freedesktop.org, Marek Vasut , Stephen Boyd , chrome-platform@lists.linux.dev, devicetree@vger.kernel.org, =?utf-8?q?Uwe_?= =?utf-8?q?Kleine-K=C3=B6nig?= Subject: [PATCH v14 06/10] drm/bridge: Remove redundant i2c_client in anx7625/it6505 Date: Wed, 22 Mar 2023 18:46:35 +0800 Message-Id: <20230322104639.221402-7-treapking@chromium.org> X-Mailer: git-send-email 2.40.0.rc1.284.g88254d51c5-goog In-Reply-To: <20230322104639.221402-1-treapking@chromium.org> References: <20230322104639.221402-1-treapking@chromium.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-acpi@vger.kernel.org These two drivers embed a i2c_client in their private driver data, but only strict device is actually needed. Replace the i2c_client reference with a struct device one. Signed-off-by: Pin-yen Lin Reviewed-by: Andy Shevchenko --- (no changes since v13) Changes in v13: - Update a typo in the commit message - Collect Reviewed-by tag Changes in v12: - New in v12 drivers/gpu/drm/bridge/analogix/anx7625.c | 96 ++++++++-------- drivers/gpu/drm/bridge/analogix/anx7625.h | 2 +- drivers/gpu/drm/bridge/ite-it6505.c | 128 +++++++++++----------- 3 files changed, 113 insertions(+), 113 deletions(-) diff --git a/drivers/gpu/drm/bridge/analogix/anx7625.c b/drivers/gpu/drm/bridge/analogix/anx7625.c index 3f6bf7674d32..76d46db3f8dc 100644 --- a/drivers/gpu/drm/bridge/analogix/anx7625.c +++ b/drivers/gpu/drm/bridge/analogix/anx7625.c @@ -207,7 +207,7 @@ static int anx7625_read_ctrl_status_p0(struct anx7625_data *ctx) static int wait_aux_op_finish(struct anx7625_data *ctx) { - struct device *dev = &ctx->client->dev; + struct device *dev = ctx->dev; int val; int ret; @@ -234,7 +234,7 @@ static int wait_aux_op_finish(struct anx7625_data *ctx) static int anx7625_aux_trans(struct anx7625_data *ctx, u8 op, u32 address, u8 len, u8 *buf) { - struct device *dev = &ctx->client->dev; + struct device *dev = ctx->dev; int ret; u8 addrh, addrm, addrl; u8 cmd; @@ -427,7 +427,7 @@ static int anx7625_odfc_config(struct anx7625_data *ctx, u8 post_divider) { int ret; - struct device *dev = &ctx->client->dev; + struct device *dev = ctx->dev; /* Config input reference clock frequency 27MHz/19.2MHz */ ret = anx7625_write_and(ctx, ctx->i2c.rx_p1_client, MIPI_DIGITAL_PLL_16, @@ -477,7 +477,7 @@ static int anx7625_set_k_value(struct anx7625_data *ctx) static int anx7625_dsi_video_timing_config(struct anx7625_data *ctx) { - struct device *dev = &ctx->client->dev; + struct device *dev = ctx->dev; unsigned long m, n; u16 htotal; int ret; @@ -575,7 +575,7 @@ static int anx7625_dsi_video_timing_config(struct anx7625_data *ctx) static int anx7625_swap_dsi_lane3(struct anx7625_data *ctx) { int val; - struct device *dev = &ctx->client->dev; + struct device *dev = ctx->dev; /* Swap MIPI-DSI data lane 3 P and N */ val = anx7625_reg_read(ctx, ctx->i2c.rx_p1_client, MIPI_SWAP); @@ -592,7 +592,7 @@ static int anx7625_api_dsi_config(struct anx7625_data *ctx) { int val, ret; - struct device *dev = &ctx->client->dev; + struct device *dev = ctx->dev; /* Swap MIPI-DSI data lane 3 P and N */ ret = anx7625_swap_dsi_lane3(ctx); @@ -657,7 +657,7 @@ static int anx7625_api_dsi_config(struct anx7625_data *ctx) static int anx7625_dsi_config(struct anx7625_data *ctx) { - struct device *dev = &ctx->client->dev; + struct device *dev = ctx->dev; int ret; DRM_DEV_DEBUG_DRIVER(dev, "config dsi.\n"); @@ -689,7 +689,7 @@ static int anx7625_dsi_config(struct anx7625_data *ctx) static int anx7625_api_dpi_config(struct anx7625_data *ctx) { - struct device *dev = &ctx->client->dev; + struct device *dev = ctx->dev; u16 freq = ctx->dt.pixelclock.min / 1000; int ret; @@ -720,7 +720,7 @@ static int anx7625_api_dpi_config(struct anx7625_data *ctx) static int anx7625_dpi_config(struct anx7625_data *ctx) { - struct device *dev = &ctx->client->dev; + struct device *dev = ctx->dev; int ret; DRM_DEV_DEBUG_DRIVER(dev, "config dpi\n"); @@ -765,7 +765,7 @@ static int anx7625_read_flash_status(struct anx7625_data *ctx) static int anx7625_hdcp_key_probe(struct anx7625_data *ctx) { int ret, val; - struct device *dev = &ctx->client->dev; + struct device *dev = ctx->dev; u8 ident[FLASH_BUF_LEN]; ret = anx7625_reg_write(ctx, ctx->i2c.rx_p0_client, @@ -815,7 +815,7 @@ static int anx7625_hdcp_key_probe(struct anx7625_data *ctx) static int anx7625_hdcp_key_load(struct anx7625_data *ctx) { int ret; - struct device *dev = &ctx->client->dev; + struct device *dev = ctx->dev; /* Select HDCP 1.4 KEY */ ret = anx7625_reg_write(ctx, ctx->i2c.rx_p0_client, @@ -843,7 +843,7 @@ static int anx7625_hdcp_key_load(struct anx7625_data *ctx) static int anx7625_hdcp_disable(struct anx7625_data *ctx) { int ret; - struct device *dev = &ctx->client->dev; + struct device *dev = ctx->dev; dev_dbg(dev, "disable HDCP 1.4\n"); @@ -864,7 +864,7 @@ static int anx7625_hdcp_enable(struct anx7625_data *ctx) { u8 bcap; int ret; - struct device *dev = &ctx->client->dev; + struct device *dev = ctx->dev; ret = anx7625_hdcp_key_probe(ctx); if (ret) { @@ -922,7 +922,7 @@ static int anx7625_hdcp_enable(struct anx7625_data *ctx) static void anx7625_dp_start(struct anx7625_data *ctx) { int ret; - struct device *dev = &ctx->client->dev; + struct device *dev = ctx->dev; u8 data; if (!ctx->display_timing_valid) { @@ -955,7 +955,7 @@ static void anx7625_dp_start(struct anx7625_data *ctx) static void anx7625_dp_stop(struct anx7625_data *ctx) { - struct device *dev = &ctx->client->dev; + struct device *dev = ctx->dev; int ret; u8 data; @@ -1020,7 +1020,7 @@ static int sp_tx_aux_rd(struct anx7625_data *ctx, u8 len_cmd) static int sp_tx_get_edid_block(struct anx7625_data *ctx) { int c = 0; - struct device *dev = &ctx->client->dev; + struct device *dev = ctx->dev; sp_tx_aux_wr(ctx, 0x7e); sp_tx_aux_rd(ctx, 0x01); @@ -1042,7 +1042,7 @@ static int edid_read(struct anx7625_data *ctx, u8 offset, u8 *pblock_buf) { int ret, cnt; - struct device *dev = &ctx->client->dev; + struct device *dev = ctx->dev; for (cnt = 0; cnt <= EDID_TRY_CNT; cnt++) { sp_tx_aux_wr(ctx, offset); @@ -1073,7 +1073,7 @@ static int segments_edid_read(struct anx7625_data *ctx, { u8 cnt; int ret; - struct device *dev = &ctx->client->dev; + struct device *dev = ctx->dev; /* Write address only */ ret = anx7625_reg_write(ctx, ctx->i2c.rx_p0_client, @@ -1128,7 +1128,7 @@ static int sp_tx_edid_read(struct anx7625_data *ctx, u8 i, j; int g_edid_break = 0; int ret; - struct device *dev = &ctx->client->dev; + struct device *dev = ctx->dev; /* Address initial */ ret = anx7625_reg_write(ctx, ctx->i2c.rx_p0_client, @@ -1235,7 +1235,7 @@ static int sp_tx_edid_read(struct anx7625_data *ctx, static void anx7625_power_on(struct anx7625_data *ctx) { - struct device *dev = &ctx->client->dev; + struct device *dev = ctx->dev; int ret, i; if (!ctx->pdata.low_power_mode) { @@ -1271,7 +1271,7 @@ static void anx7625_power_on(struct anx7625_data *ctx) static void anx7625_power_standby(struct anx7625_data *ctx) { - struct device *dev = &ctx->client->dev; + struct device *dev = ctx->dev; int ret; if (!ctx->pdata.low_power_mode) { @@ -1301,7 +1301,7 @@ static void anx7625_config(struct anx7625_data *ctx) static void anx7625_disable_pd_protocol(struct anx7625_data *ctx) { - struct device *dev = &ctx->client->dev; + struct device *dev = ctx->dev; int ret; /* Reset main ocm */ @@ -1321,7 +1321,7 @@ static void anx7625_disable_pd_protocol(struct anx7625_data *ctx) static int anx7625_ocm_loading_check(struct anx7625_data *ctx) { int ret; - struct device *dev = &ctx->client->dev; + struct device *dev = ctx->dev; /* Check interface workable */ ret = anx7625_reg_read(ctx, ctx->i2c.rx_p0_client, @@ -1367,7 +1367,7 @@ static void anx7625_power_on_init(struct anx7625_data *ctx) static void anx7625_init_gpio(struct anx7625_data *platform) { - struct device *dev = &platform->client->dev; + struct device *dev = platform->dev; DRM_DEV_DEBUG_DRIVER(dev, "init gpio\n"); @@ -1407,7 +1407,7 @@ static void anx7625_stop_dp_work(struct anx7625_data *ctx) static void anx7625_start_dp_work(struct anx7625_data *ctx) { int ret; - struct device *dev = &ctx->client->dev; + struct device *dev = ctx->dev; if (ctx->hpd_high_cnt >= 2) { DRM_DEV_DEBUG_DRIVER(dev, "filter useless HPD\n"); @@ -1459,7 +1459,7 @@ static int _anx7625_hpd_polling(struct anx7625_data *ctx, unsigned long wait_us) { int ret, val; - struct device *dev = &ctx->client->dev; + struct device *dev = ctx->dev; /* Interrupt mode, no need poll HPD status, just return */ if (ctx->pdata.intp_irq) @@ -1493,7 +1493,7 @@ static int anx7625_wait_hpd_asserted(struct drm_dp_aux *aux, unsigned long wait_us) { struct anx7625_data *ctx = container_of(aux, struct anx7625_data, aux); - struct device *dev = &ctx->client->dev; + struct device *dev = ctx->dev; int ret; pm_runtime_get_sync(dev); @@ -1526,7 +1526,7 @@ static void anx7625_dp_adjust_swing(struct anx7625_data *ctx) static void dp_hpd_change_handler(struct anx7625_data *ctx, bool on) { - struct device *dev = &ctx->client->dev; + struct device *dev = ctx->dev; /* HPD changed */ DRM_DEV_DEBUG_DRIVER(dev, "dp_hpd_change_default_func: %d\n", @@ -1546,7 +1546,7 @@ static void dp_hpd_change_handler(struct anx7625_data *ctx, bool on) static int anx7625_hpd_change_detect(struct anx7625_data *ctx) { int intr_vector, status; - struct device *dev = &ctx->client->dev; + struct device *dev = ctx->dev; status = anx7625_reg_write(ctx, ctx->i2c.tcpc_client, INTR_ALERT_1, 0xFF); @@ -1594,7 +1594,7 @@ static void anx7625_work_func(struct work_struct *work) mutex_lock(&ctx->lock); - if (pm_runtime_suspended(&ctx->client->dev)) + if (pm_runtime_suspended(ctx->dev)) goto unlock; event = anx7625_hpd_change_detect(ctx); @@ -1738,7 +1738,7 @@ static ssize_t anx7625_aux_transfer(struct drm_dp_aux *aux, struct drm_dp_aux_msg *msg) { struct anx7625_data *ctx = container_of(aux, struct anx7625_data, aux); - struct device *dev = &ctx->client->dev; + struct device *dev = ctx->dev; u8 request = msg->request & ~DP_AUX_I2C_MOT; int ret = 0; @@ -1764,7 +1764,7 @@ static ssize_t anx7625_aux_transfer(struct drm_dp_aux *aux, static struct edid *anx7625_get_edid(struct anx7625_data *ctx) { - struct device *dev = &ctx->client->dev; + struct device *dev = ctx->dev; struct s_edid_data *p_edid = &ctx->slimport_edid_p; int edid_num; u8 *edid; @@ -1800,7 +1800,7 @@ static struct edid *anx7625_get_edid(struct anx7625_data *ctx) static enum drm_connector_status anx7625_sink_detect(struct anx7625_data *ctx) { - struct device *dev = &ctx->client->dev; + struct device *dev = ctx->dev; DRM_DEV_DEBUG_DRIVER(dev, "sink detect\n"); @@ -2009,7 +2009,7 @@ static const struct hdmi_codec_ops anx7625_codec_ops = { static void anx7625_unregister_audio(struct anx7625_data *ctx) { - struct device *dev = &ctx->client->dev; + struct device *dev = ctx->dev; if (ctx->audio_pdev) { platform_device_unregister(ctx->audio_pdev); @@ -2045,7 +2045,7 @@ static int anx7625_register_audio(struct device *dev, struct anx7625_data *ctx) static int anx7625_attach_dsi(struct anx7625_data *ctx) { struct mipi_dsi_device *dsi; - struct device *dev = &ctx->client->dev; + struct device *dev = ctx->dev; struct mipi_dsi_host *host; const struct mipi_dsi_device_info info = { .type = "anx7625", @@ -2098,7 +2098,7 @@ static void hdcp_check_work_func(struct work_struct *work) dwork = to_delayed_work(work); ctx = container_of(dwork, struct anx7625_data, hdcp_work); - dev = &ctx->client->dev; + dev = ctx->dev; if (!ctx->connector) { dev_err(dev, "HDCP connector is null!"); @@ -2125,7 +2125,7 @@ static void hdcp_check_work_func(struct work_struct *work) static int anx7625_connector_atomic_check(struct anx7625_data *ctx, struct drm_connector_state *state) { - struct device *dev = &ctx->client->dev; + struct device *dev = ctx->dev; int cp; dev_dbg(dev, "hdcp state check\n"); @@ -2170,7 +2170,7 @@ static int anx7625_bridge_attach(struct drm_bridge *bridge, { struct anx7625_data *ctx = bridge_to_anx7625(bridge); int err; - struct device *dev = &ctx->client->dev; + struct device *dev = ctx->dev; DRM_DEV_DEBUG_DRIVER(dev, "drm attach\n"); if (!(flags & DRM_BRIDGE_ATTACH_NO_CONNECTOR)) @@ -2214,7 +2214,7 @@ anx7625_bridge_mode_valid(struct drm_bridge *bridge, const struct drm_display_mode *mode) { struct anx7625_data *ctx = bridge_to_anx7625(bridge); - struct device *dev = &ctx->client->dev; + struct device *dev = ctx->dev; DRM_DEV_DEBUG_DRIVER(dev, "drm mode checking\n"); @@ -2235,7 +2235,7 @@ static void anx7625_bridge_mode_set(struct drm_bridge *bridge, const struct drm_display_mode *mode) { struct anx7625_data *ctx = bridge_to_anx7625(bridge); - struct device *dev = &ctx->client->dev; + struct device *dev = ctx->dev; DRM_DEV_DEBUG_DRIVER(dev, "drm mode set\n"); @@ -2281,7 +2281,7 @@ static bool anx7625_bridge_mode_fixup(struct drm_bridge *bridge, struct drm_display_mode *adj) { struct anx7625_data *ctx = bridge_to_anx7625(bridge); - struct device *dev = &ctx->client->dev; + struct device *dev = ctx->dev; u32 hsync, hfp, hbp, hblanking; u32 adj_hsync, adj_hfp, adj_hbp, adj_hblanking, delta_adj; u32 vref, adj_clock; @@ -2399,7 +2399,7 @@ static int anx7625_bridge_atomic_check(struct drm_bridge *bridge, struct drm_connector_state *conn_state) { struct anx7625_data *ctx = bridge_to_anx7625(bridge); - struct device *dev = &ctx->client->dev; + struct device *dev = ctx->dev; dev_dbg(dev, "drm bridge atomic check\n"); @@ -2413,7 +2413,7 @@ static void anx7625_bridge_atomic_enable(struct drm_bridge *bridge, struct drm_bridge_state *state) { struct anx7625_data *ctx = bridge_to_anx7625(bridge); - struct device *dev = &ctx->client->dev; + struct device *dev = ctx->dev; struct drm_connector *connector; dev_dbg(dev, "drm atomic enable\n"); @@ -2440,7 +2440,7 @@ static void anx7625_bridge_atomic_disable(struct drm_bridge *bridge, struct drm_bridge_state *old) { struct anx7625_data *ctx = bridge_to_anx7625(bridge); - struct device *dev = &ctx->client->dev; + struct device *dev = ctx->dev; dev_dbg(dev, "drm atomic disable\n"); @@ -2454,7 +2454,7 @@ static enum drm_connector_status anx7625_bridge_detect(struct drm_bridge *bridge) { struct anx7625_data *ctx = bridge_to_anx7625(bridge); - struct device *dev = &ctx->client->dev; + struct device *dev = ctx->dev; DRM_DEV_DEBUG_DRIVER(dev, "drm bridge detect\n"); @@ -2465,7 +2465,7 @@ static struct edid *anx7625_bridge_get_edid(struct drm_bridge *bridge, struct drm_connector *connector) { struct anx7625_data *ctx = bridge_to_anx7625(bridge); - struct device *dev = &ctx->client->dev; + struct device *dev = ctx->dev; DRM_DEV_DEBUG_DRIVER(dev, "drm bridge get edid\n"); @@ -2490,7 +2490,7 @@ static const struct drm_bridge_funcs anx7625_bridge_funcs = { static int anx7625_register_i2c_dummy_clients(struct anx7625_data *ctx, struct i2c_client *client) { - struct device *dev = &ctx->client->dev; + struct device *dev = ctx->dev; ctx->i2c.tx_p0_client = devm_i2c_new_dummy_device(dev, client->adapter, TX_P0_ADDR >> 1); @@ -2591,7 +2591,7 @@ static int anx7625_i2c_probe(struct i2c_client *client) pdata = &platform->pdata; - platform->client = client; + platform->dev = &client->dev; i2c_set_clientdata(client, platform); pdata->supplies[0].supply = "vdd10"; diff --git a/drivers/gpu/drm/bridge/analogix/anx7625.h b/drivers/gpu/drm/bridge/analogix/anx7625.h index 14f33d6be289..5af819611ebc 100644 --- a/drivers/gpu/drm/bridge/analogix/anx7625.h +++ b/drivers/gpu/drm/bridge/analogix/anx7625.h @@ -458,7 +458,7 @@ struct anx7625_data { int hdcp_cp; /* Lock for work queue */ struct mutex lock; - struct i2c_client *client; + struct device *dev; struct anx7625_i2c_client i2c; struct i2c_client *last_client; struct timer_list hdcp_timer; diff --git a/drivers/gpu/drm/bridge/ite-it6505.c b/drivers/gpu/drm/bridge/ite-it6505.c index bc451b2a77c2..d4bc388b68ac 100644 --- a/drivers/gpu/drm/bridge/ite-it6505.c +++ b/drivers/gpu/drm/bridge/ite-it6505.c @@ -404,7 +404,7 @@ struct debugfs_entries { struct it6505 { struct drm_dp_aux aux; struct drm_bridge bridge; - struct i2c_client *client; + struct device *dev; struct it6505_drm_dp_link link; struct it6505_platform_data pdata; /* @@ -508,7 +508,7 @@ static int it6505_read(struct it6505 *it6505, unsigned int reg_addr) { unsigned int value; int err; - struct device *dev = &it6505->client->dev; + struct device *dev = it6505->dev; if (!it6505->powered) return -ENODEV; @@ -526,7 +526,7 @@ static int it6505_write(struct it6505 *it6505, unsigned int reg_addr, unsigned int reg_val) { int err; - struct device *dev = &it6505->client->dev; + struct device *dev = it6505->dev; if (!it6505->powered) return -ENODEV; @@ -546,7 +546,7 @@ static int it6505_set_bits(struct it6505 *it6505, unsigned int reg, unsigned int mask, unsigned int value) { int err; - struct device *dev = &it6505->client->dev; + struct device *dev = it6505->dev; if (!it6505->powered) return -ENODEV; @@ -564,7 +564,7 @@ static int it6505_set_bits(struct it6505 *it6505, unsigned int reg, static void it6505_debug_print(struct it6505 *it6505, unsigned int reg, const char *prefix) { - struct device *dev = &it6505->client->dev; + struct device *dev = it6505->dev; int val; if (!drm_debug_enabled(DRM_UT_DRIVER)) @@ -583,7 +583,7 @@ static int it6505_dpcd_read(struct it6505 *it6505, unsigned long offset) { u8 value; int ret; - struct device *dev = &it6505->client->dev; + struct device *dev = it6505->dev; ret = drm_dp_dpcd_readb(&it6505->aux, offset, &value); if (ret < 0) { @@ -597,7 +597,7 @@ static int it6505_dpcd_write(struct it6505 *it6505, unsigned long offset, u8 datain) { int ret; - struct device *dev = &it6505->client->dev; + struct device *dev = it6505->dev; ret = drm_dp_dpcd_writeb(&it6505->aux, offset, datain); if (ret < 0) { @@ -610,7 +610,7 @@ static int it6505_dpcd_write(struct it6505 *it6505, unsigned long offset, static int it6505_get_dpcd(struct it6505 *it6505, int offset, u8 *dpcd, int num) { int ret; - struct device *dev = &it6505->client->dev; + struct device *dev = it6505->dev; ret = drm_dp_dpcd_read(&it6505->aux, offset, dpcd, num); @@ -627,7 +627,7 @@ static void it6505_dump(struct it6505 *it6505) { unsigned int i, j; u8 regs[16]; - struct device *dev = &it6505->client->dev; + struct device *dev = it6505->dev; for (i = 0; i <= 0xff; i += 16) { for (j = 0; j < 16; j++) @@ -666,7 +666,7 @@ static int it6505_read_word(struct it6505 *it6505, unsigned int reg) static void it6505_calc_video_info(struct it6505 *it6505) { - struct device *dev = &it6505->client->dev; + struct device *dev = it6505->dev; int hsync_pol, vsync_pol, interlaced; int htotal, hdes, hdew, hfph, hsyncw; int vtotal, vdes, vdew, vfph, vsyncw; @@ -910,7 +910,7 @@ static int it6505_aux_wait(struct it6505 *it6505) { int status; unsigned long timeout; - struct device *dev = &it6505->client->dev; + struct device *dev = it6505->dev; timeout = jiffies + msecs_to_jiffies(AUX_WAIT_TIMEOUT_MS) + 1; @@ -1125,7 +1125,7 @@ static int it6505_get_edid_block(void *data, u8 *buf, unsigned int block, size_t len) { struct it6505 *it6505 = data; - struct device *dev = &it6505->client->dev; + struct device *dev = it6505->dev; enum aux_cmd_reply reply; int offset, ret, aux_retry = 100; @@ -1185,7 +1185,7 @@ static int it6505_send_video_infoframe(struct it6505 *it6505, { u8 buffer[HDMI_INFOFRAME_HEADER_SIZE + HDMI_AVI_INFOFRAME_SIZE]; int err; - struct device *dev = &it6505->client->dev; + struct device *dev = it6505->dev; err = hdmi_avi_infoframe_pack(frame, buffer, sizeof(buffer)); if (err < 0) { @@ -1215,7 +1215,7 @@ static void it6505_get_extcon_property(struct it6505 *it6505) { int err; union extcon_property_value property; - struct device *dev = &it6505->client->dev; + struct device *dev = it6505->dev; if (it6505->extcon && !it6505->lane_swap_disabled) { err = extcon_get_property(it6505->extcon, EXTCON_DISP_DP, @@ -1368,7 +1368,7 @@ static void it6505_enable_audio_source(struct it6505 *it6505) static void it6505_enable_audio_infoframe(struct it6505 *it6505) { - struct device *dev = &it6505->client->dev; + struct device *dev = it6505->dev; u8 audio_info_ca[] = { 0x00, 0x00, 0x01, 0x03, 0x07, 0x0B, 0x0F, 0x1F }; DRM_DEV_DEBUG_DRIVER(dev, "infoframe channel_allocation:0x%02x", @@ -1397,7 +1397,7 @@ static void it6505_disable_audio(struct it6505 *it6505) static void it6505_enable_audio(struct it6505 *it6505) { - struct device *dev = &it6505->client->dev; + struct device *dev = it6505->dev; int regbe; DRM_DEV_DEBUG_DRIVER(dev, "start"); @@ -1432,7 +1432,7 @@ static bool it6505_use_step_train_check(struct it6505 *it6505) static void it6505_parse_link_capabilities(struct it6505 *it6505) { - struct device *dev = &it6505->client->dev; + struct device *dev = it6505->dev; struct it6505_drm_dp_link *link = &it6505->link; int bcaps; @@ -1545,7 +1545,7 @@ static void it6505_lane_count_setup(struct it6505 *it6505) static void it6505_link_training_setup(struct it6505 *it6505) { - struct device *dev = &it6505->client->dev; + struct device *dev = it6505->dev; if (it6505->enable_enhanced_frame) it6505_set_bits(it6505, REG_DATA_MUTE_CTRL, @@ -1696,7 +1696,7 @@ it6505_step_cr_train(struct it6505 *it6505, FORCE_CR_DONE); return true; } - DRM_DEV_DEBUG_DRIVER(&it6505->client->dev, "cr not done"); + DRM_DEV_DEBUG_DRIVER(it6505->dev, "cr not done"); if (it6505_check_max_voltage_swing_reached(lane_level_config, it6505->lane_count)) @@ -1773,7 +1773,7 @@ it6505_step_eq_train(struct it6505 *it6505, FORCE_EQ_DONE); return true; } - DRM_DEV_DEBUG_DRIVER(&it6505->client->dev, "eq not done"); + DRM_DEV_DEBUG_DRIVER(it6505->dev, "eq not done"); for (i = 0; i < it6505->lane_count; i++) { lane_voltage_pre_emphasis->voltage_swing[i] = @@ -1808,7 +1808,7 @@ static bool it6505_link_start_step_train(struct it6505 *it6505) .pre_emphasis = { 0 }, }; - DRM_DEV_DEBUG_DRIVER(&it6505->client->dev, "start"); + DRM_DEV_DEBUG_DRIVER(it6505->dev, "start"); err = it6505_drm_dp_link_configure(it6505); if (err < 0) @@ -1842,7 +1842,7 @@ static void it6505_reset_hdcp(struct it6505 *it6505) static void it6505_start_hdcp(struct it6505 *it6505) { - struct device *dev = &it6505->client->dev; + struct device *dev = it6505->dev; DRM_DEV_DEBUG_DRIVER(dev, "start"); it6505_reset_hdcp(it6505); @@ -1870,7 +1870,7 @@ static bool it6505_hdcp_is_ksv_valid(u8 *ksv) static void it6505_hdcp_part1_auth(struct it6505 *it6505) { - struct device *dev = &it6505->client->dev; + struct device *dev = it6505->dev; u8 hdcp_bcaps; it6505_set_bits(it6505, REG_RESET_CTRL, HDCP_RESET, 0x00); @@ -1911,7 +1911,7 @@ static int it6505_sha1_digest(struct it6505 *it6505, u8 *sha1_input, struct shash_desc *desc; struct crypto_shash *tfm; int err; - struct device *dev = &it6505->client->dev; + struct device *dev = it6505->dev; tfm = crypto_alloc_shash("sha1", 0, 0); if (IS_ERR(tfm)) { @@ -1936,7 +1936,7 @@ static int it6505_sha1_digest(struct it6505 *it6505, u8 *sha1_input, static int it6505_setup_sha1_input(struct it6505 *it6505, u8 *sha1_input) { - struct device *dev = &it6505->client->dev; + struct device *dev = it6505->dev; u8 binfo[2]; int down_stream_count, i, err, msg_count = 0; @@ -2000,7 +2000,7 @@ static int it6505_setup_sha1_input(struct it6505 *it6505, u8 *sha1_input) static bool it6505_hdcp_part2_ksvlist_check(struct it6505 *it6505) { - struct device *dev = &it6505->client->dev; + struct device *dev = it6505->dev; u8 av[5][4], bv[5][4]; int i, err; @@ -2033,7 +2033,7 @@ static void it6505_hdcp_wait_ksv_list(struct work_struct *work) { struct it6505 *it6505 = container_of(work, struct it6505, hdcp_wait_ksv_list); - struct device *dev = &it6505->client->dev; + struct device *dev = it6505->dev; unsigned int timeout = 5000; u8 bstatus = 0; bool ksv_list_check; @@ -2075,7 +2075,7 @@ static void it6505_hdcp_work(struct work_struct *work) { struct it6505 *it6505 = container_of(work, struct it6505, hdcp_work.work); - struct device *dev = &it6505->client->dev; + struct device *dev = it6505->dev; int ret; u8 link_status[DP_LINK_STATUS_SIZE] = { 0 }; @@ -2116,7 +2116,7 @@ static void it6505_hdcp_work(struct work_struct *work) static void it6505_show_hdcp_info(struct it6505 *it6505) { - struct device *dev = &it6505->client->dev; + struct device *dev = it6505->dev; int i; u8 *sha1 = it6505->sha1_input; @@ -2150,7 +2150,7 @@ static void it6505_stop_link_train(struct it6505 *it6505) static void it6505_link_train_ok(struct it6505 *it6505) { - struct device *dev = &it6505->client->dev; + struct device *dev = it6505->dev; it6505->link_state = LINK_OK; /* disalbe mute enable avi info frame */ @@ -2169,7 +2169,7 @@ static void it6505_link_train_ok(struct it6505 *it6505) static void it6505_link_step_train_process(struct it6505 *it6505) { - struct device *dev = &it6505->client->dev; + struct device *dev = it6505->dev; int ret, i, step_retry = 3; DRM_DEV_DEBUG_DRIVER(dev, "Start step train"); @@ -2207,7 +2207,7 @@ static void it6505_link_step_train_process(struct it6505 *it6505) static void it6505_link_training_work(struct work_struct *work) { struct it6505 *it6505 = container_of(work, struct it6505, link_works); - struct device *dev = &it6505->client->dev; + struct device *dev = it6505->dev; int ret; DRM_DEV_DEBUG_DRIVER(dev, "it6505->sink_count: %d", @@ -2255,7 +2255,7 @@ static void it6505_remove_edid(struct it6505 *it6505) static int it6505_process_hpd_irq(struct it6505 *it6505) { - struct device *dev = &it6505->client->dev; + struct device *dev = it6505->dev; int ret, dpcd_sink_count, dp_irq_vector, bstatus; u8 link_status[DP_LINK_STATUS_SIZE]; @@ -2319,7 +2319,7 @@ static int it6505_process_hpd_irq(struct it6505 *it6505) static void it6505_irq_hpd(struct it6505 *it6505) { - struct device *dev = &it6505->client->dev; + struct device *dev = it6505->dev; int dp_sink_count; it6505->hpd_state = it6505_get_sink_hpd_status(it6505); @@ -2381,7 +2381,7 @@ static void it6505_irq_hpd(struct it6505 *it6505) static void it6505_irq_hpd_irq(struct it6505 *it6505) { - struct device *dev = &it6505->client->dev; + struct device *dev = it6505->dev; DRM_DEV_DEBUG_DRIVER(dev, "hpd_irq interrupt"); @@ -2391,7 +2391,7 @@ static void it6505_irq_hpd_irq(struct it6505 *it6505) static void it6505_irq_scdt(struct it6505 *it6505) { - struct device *dev = &it6505->client->dev; + struct device *dev = it6505->dev; bool data; data = it6505_get_video_status(it6505); @@ -2406,7 +2406,7 @@ static void it6505_irq_scdt(struct it6505 *it6505) static void it6505_irq_hdcp_done(struct it6505 *it6505) { - struct device *dev = &it6505->client->dev; + struct device *dev = it6505->dev; DRM_DEV_DEBUG_DRIVER(dev, "hdcp done interrupt"); it6505->hdcp_status = HDCP_AUTH_DONE; @@ -2415,7 +2415,7 @@ static void it6505_irq_hdcp_done(struct it6505 *it6505) static void it6505_irq_hdcp_fail(struct it6505 *it6505) { - struct device *dev = &it6505->client->dev; + struct device *dev = it6505->dev; DRM_DEV_DEBUG_DRIVER(dev, "hdcp fail interrupt"); it6505->hdcp_status = HDCP_AUTH_IDLE; @@ -2425,14 +2425,14 @@ static void it6505_irq_hdcp_fail(struct it6505 *it6505) static void it6505_irq_aux_cmd_fail(struct it6505 *it6505) { - struct device *dev = &it6505->client->dev; + struct device *dev = it6505->dev; DRM_DEV_DEBUG_DRIVER(dev, "AUX PC Request Fail Interrupt"); } static void it6505_irq_hdcp_ksv_check(struct it6505 *it6505) { - struct device *dev = &it6505->client->dev; + struct device *dev = it6505->dev; DRM_DEV_DEBUG_DRIVER(dev, "HDCP event Interrupt"); schedule_work(&it6505->hdcp_wait_ksv_list); @@ -2440,7 +2440,7 @@ static void it6505_irq_hdcp_ksv_check(struct it6505 *it6505) static void it6505_irq_audio_fifo_error(struct it6505 *it6505) { - struct device *dev = &it6505->client->dev; + struct device *dev = it6505->dev; DRM_DEV_DEBUG_DRIVER(dev, "audio fifo error Interrupt"); @@ -2450,7 +2450,7 @@ static void it6505_irq_audio_fifo_error(struct it6505 *it6505) static void it6505_irq_link_train_fail(struct it6505 *it6505) { - struct device *dev = &it6505->client->dev; + struct device *dev = it6505->dev; DRM_DEV_DEBUG_DRIVER(dev, "link training fail interrupt"); schedule_work(&it6505->link_works); @@ -2458,7 +2458,7 @@ static void it6505_irq_link_train_fail(struct it6505 *it6505) static void it6505_irq_video_fifo_error(struct it6505 *it6505) { - struct device *dev = &it6505->client->dev; + struct device *dev = it6505->dev; DRM_DEV_DEBUG_DRIVER(dev, "video fifo overflow interrupt"); it6505->auto_train_retry = AUTO_TRAIN_RETRY; @@ -2469,7 +2469,7 @@ static void it6505_irq_video_fifo_error(struct it6505 *it6505) static void it6505_irq_io_latch_fifo_overflow(struct it6505 *it6505) { - struct device *dev = &it6505->client->dev; + struct device *dev = it6505->dev; DRM_DEV_DEBUG_DRIVER(dev, "IO latch fifo overflow interrupt"); it6505->auto_train_retry = AUTO_TRAIN_RETRY; @@ -2486,7 +2486,7 @@ static bool it6505_test_bit(unsigned int bit, const unsigned int *addr) static irqreturn_t it6505_int_threaded_handler(int unused, void *data) { struct it6505 *it6505 = data; - struct device *dev = &it6505->client->dev; + struct device *dev = it6505->dev; static const struct { int bit; void (*handler)(struct it6505 *it6505); @@ -2538,7 +2538,7 @@ static irqreturn_t it6505_int_threaded_handler(int unused, void *data) static int it6505_poweron(struct it6505 *it6505) { - struct device *dev = &it6505->client->dev; + struct device *dev = it6505->dev; struct it6505_platform_data *pdata = &it6505->pdata; int err; @@ -2587,7 +2587,7 @@ static int it6505_poweron(struct it6505 *it6505) static int it6505_poweroff(struct it6505 *it6505) { - struct device *dev = &it6505->client->dev; + struct device *dev = it6505->dev; struct it6505_platform_data *pdata = &it6505->pdata; int err; @@ -2621,7 +2621,7 @@ static int it6505_poweroff(struct it6505 *it6505) static enum drm_connector_status it6505_detect(struct it6505 *it6505) { - struct device *dev = &it6505->client->dev; + struct device *dev = it6505->dev; enum drm_connector_status status = connector_status_disconnected; int dp_sink_count; @@ -2682,7 +2682,7 @@ static int it6505_extcon_notifier(struct notifier_block *self, static void it6505_extcon_work(struct work_struct *work) { struct it6505 *it6505 = container_of(work, struct it6505, extcon_wq); - struct device *dev = &it6505->client->dev; + struct device *dev = it6505->dev; int state, ret; if (it6505->enable_drv_hold) @@ -2727,11 +2727,11 @@ static void it6505_extcon_work(struct work_struct *work) static int it6505_use_notifier_module(struct it6505 *it6505) { int ret; - struct device *dev = &it6505->client->dev; + struct device *dev = it6505->dev; it6505->event_nb.notifier_call = it6505_extcon_notifier; INIT_WORK(&it6505->extcon_wq, it6505_extcon_work); - ret = devm_extcon_register_notifier(&it6505->client->dev, + ret = devm_extcon_register_notifier(it6505->dev, it6505->extcon, EXTCON_DISP_DP, &it6505->event_nb); if (ret) { @@ -2747,7 +2747,7 @@ static int it6505_use_notifier_module(struct it6505 *it6505) static void it6505_remove_notifier_module(struct it6505 *it6505) { if (it6505->extcon) { - devm_extcon_unregister_notifier(&it6505->client->dev, + devm_extcon_unregister_notifier(it6505->dev, it6505->extcon, EXTCON_DISP_DP, &it6505->event_nb); @@ -2760,7 +2760,7 @@ static void __maybe_unused it6505_delayed_audio(struct work_struct *work) struct it6505 *it6505 = container_of(work, struct it6505, delayed_audio.work); - DRM_DEV_DEBUG_DRIVER(&it6505->client->dev, "start"); + DRM_DEV_DEBUG_DRIVER(it6505->dev, "start"); if (!it6505->powered) return; @@ -2773,7 +2773,7 @@ static int __maybe_unused it6505_audio_setup_hw_params(struct it6505 *it6505, struct hdmi_codec_params *params) { - struct device *dev = &it6505->client->dev; + struct device *dev = it6505->dev; int i = 0; DRM_DEV_DEBUG_DRIVER(dev, "%s %d Hz, %d bit, %d channels\n", __func__, @@ -2857,7 +2857,7 @@ static int it6505_bridge_attach(struct drm_bridge *bridge, enum drm_bridge_attach_flags flags) { struct it6505 *it6505 = bridge_to_it6505(bridge); - struct device *dev = &it6505->client->dev; + struct device *dev = it6505->dev; int ret; if (!(flags & DRM_BRIDGE_ATTACH_NO_CONNECTOR)) { @@ -2921,7 +2921,7 @@ static void it6505_bridge_atomic_enable(struct drm_bridge *bridge, struct drm_bridge_state *old_state) { struct it6505 *it6505 = bridge_to_it6505(bridge); - struct device *dev = &it6505->client->dev; + struct device *dev = it6505->dev; struct drm_atomic_state *state = old_state->base.state; struct hdmi_avi_infoframe frame; struct drm_crtc_state *crtc_state; @@ -2977,7 +2977,7 @@ static void it6505_bridge_atomic_disable(struct drm_bridge *bridge, struct drm_bridge_state *old_state) { struct it6505 *it6505 = bridge_to_it6505(bridge); - struct device *dev = &it6505->client->dev; + struct device *dev = it6505->dev; DRM_DEV_DEBUG_DRIVER(dev, "start"); @@ -2992,7 +2992,7 @@ static void it6505_bridge_atomic_pre_enable(struct drm_bridge *bridge, struct drm_bridge_state *old_state) { struct it6505 *it6505 = bridge_to_it6505(bridge); - struct device *dev = &it6505->client->dev; + struct device *dev = it6505->dev; DRM_DEV_DEBUG_DRIVER(dev, "start"); @@ -3003,7 +3003,7 @@ static void it6505_bridge_atomic_post_disable(struct drm_bridge *bridge, struct drm_bridge_state *old_state) { struct it6505 *it6505 = bridge_to_it6505(bridge); - struct device *dev = &it6505->client->dev; + struct device *dev = it6505->dev; DRM_DEV_DEBUG_DRIVER(dev, "start"); @@ -3022,7 +3022,7 @@ static struct edid *it6505_bridge_get_edid(struct drm_bridge *bridge, struct drm_connector *connector) { struct it6505 *it6505 = bridge_to_it6505(bridge); - struct device *dev = &it6505->client->dev; + struct device *dev = it6505->dev; if (!it6505->cached_edid) { it6505->cached_edid = drm_do_get_edid(connector, it6505_get_edid_block, @@ -3074,7 +3074,7 @@ static const struct dev_pm_ops it6505_bridge_pm_ops = { static int it6505_init_pdata(struct it6505 *it6505) { struct it6505_platform_data *pdata = &it6505->pdata; - struct device *dev = &it6505->client->dev; + struct device *dev = it6505->dev; /* 1.0V digital core power regulator */ pdata->pwr18 = devm_regulator_get(dev, "pwr18"); @@ -3116,7 +3116,7 @@ static int it6505_get_data_lanes_count(const struct device_node *endpoint, static void it6505_parse_dt(struct it6505 *it6505) { - struct device *dev = &it6505->client->dev; + struct device *dev = it6505->dev; struct device_node *np = dev->of_node, *ep = NULL; int len; u64 link_frequencies; @@ -3320,7 +3320,7 @@ static void debugfs_create_files(struct it6505 *it6505) static void debugfs_init(struct it6505 *it6505) { - struct device *dev = &it6505->client->dev; + struct device *dev = it6505->dev; it6505->debugfs = debugfs_create_dir(DEBUGFS_DIR_NAME, NULL); @@ -3362,7 +3362,7 @@ static int it6505_i2c_probe(struct i2c_client *client) it6505->bridge.of_node = client->dev.of_node; it6505->connector_status = connector_status_disconnected; - it6505->client = client; + it6505->dev = &client->dev; i2c_set_clientdata(client, it6505); /* get extcon device from DTS */ From patchwork Wed Mar 22 10:46:36 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Pin-yen Lin X-Patchwork-Id: 666238 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 0412EC6FD1F for ; Wed, 22 Mar 2023 10:49:02 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230487AbjCVKtA (ORCPT ); Wed, 22 Mar 2023 06:49:00 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:41370 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230259AbjCVKsJ (ORCPT ); Wed, 22 Mar 2023 06:48:09 -0400 Received: from mail-pj1-x1029.google.com (mail-pj1-x1029.google.com [IPv6:2607:f8b0:4864:20::1029]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 026516287F for ; Wed, 22 Mar 2023 03:47:33 -0700 (PDT) Received: by mail-pj1-x1029.google.com with SMTP id fy10-20020a17090b020a00b0023b4bcf0727so18735005pjb.0 for ; Wed, 22 Mar 2023 03:47:33 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; t=1679482047; 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=/4YiSH1IkJ0n1Hd2VWWavtDAOx8Cy0N2XlN60ziReaI=; b=HMoxZvWcxSqJHdCMgZLmXJJNIKvGaKv6dXzaLAo1QHugMoIP+unIbrgSH/h1m1qUBn /uH4OYpG7wd6VPDpkjPFEaPsm5usYw/9sOvF/3weGpy7UWUw1AlkgB3oqDcnEEL2SOBs nZlruRxQzeu7py18C0vst2G4EwuSi3B6eTglo= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; t=1679482047; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=/4YiSH1IkJ0n1Hd2VWWavtDAOx8Cy0N2XlN60ziReaI=; b=I+O4VyWpqdVjNDQrI39Kl8bQrMREosrZjMta9uM3Xw3o7mjnrgzPBD3iPJwPUtGP6a 7KAgPmrDwCx4bC3xL2aQKlfnoxc4JAVb6g20/mExWbNJARbh5ypknvSxBm4i9YRhE6De MFOClFd3KuMZUE8Mtiznsz15rcL0B2kf8EJm0WYEV/1wKWuUqUscz2y63XvVMge8U9pd oFYTGx4Tm9fvWTS9lXRdE4NDTyKyudb2S57VW43U7QEWt+0nFBeXeTZm6SpqDFkr+LQ0 hNBSqmUeTefOegP2eTaaAFPly/tNzWFAHnsbumtF9DYqVcsvoU3qU/WyCxQG/uQnkniB H6sw== X-Gm-Message-State: AAQBX9dZX3s/VPXlzUNK1VN4sE7VriRP/Qb6TtC3lKCtgRCo0MN6ExwL Vgwi1BOSsk+H2492bev1YQLBlA== X-Google-Smtp-Source: AKy350acyt4SddG6fs1i2fjAkJNKgW9ZrwnvAU1NQ7DrkddqYc3Aog+9Vpzqb544hX71L6aQYHg6zg== X-Received: by 2002:a17:90b:3b90:b0:23d:27fc:8437 with SMTP id pc16-20020a17090b3b9000b0023d27fc8437mr1682775pjb.14.1679482047532; Wed, 22 Mar 2023 03:47:27 -0700 (PDT) Received: from treapking.tpe.corp.google.com ([2401:fa00:1:10:343d:79bf:55f9:1da5]) by smtp.gmail.com with ESMTPSA id hg4-20020a17090b300400b002340d317f3esm9508742pjb.52.2023.03.22.03.47.22 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 22 Mar 2023 03:47:27 -0700 (PDT) From: Pin-yen Lin To: Andrzej Hajda , Neil Armstrong , Robert Foss , Laurent Pinchart , Jonas Karlman , Jernej Skrabec , David Airlie , Daniel Vetter , Rob Herring , Krzysztof Kozlowski , Andy Shevchenko , Daniel Scally , Heikki Krogerus , Sakari Ailus , Greg Kroah-Hartman , "Rafael J . Wysocki" , Prashant Malani , Benson Leung , Guenter Roeck Cc: Xin Ji , linux-kernel@vger.kernel.org, Thomas Zimmermann , linux-acpi@vger.kernel.org, Javier Martinez Canillas , AngeloGioacchino Del Regno , Pin-yen Lin , Hsin-Yi Wang , Lyude Paul , =?utf-8?q?N=C3=ADcolas_F_=2E_R_=2E_A_=2E_Pra?= =?utf-8?q?do?= , Allen Chen , dri-devel@lists.freedesktop.org, Marek Vasut , Stephen Boyd , chrome-platform@lists.linux.dev, devicetree@vger.kernel.org Subject: [PATCH v14 07/10] drm/bridge: anx7625: Register Type C mode switches Date: Wed, 22 Mar 2023 18:46:36 +0800 Message-Id: <20230322104639.221402-8-treapking@chromium.org> X-Mailer: git-send-email 2.40.0.rc1.284.g88254d51c5-goog In-Reply-To: <20230322104639.221402-1-treapking@chromium.org> References: <20230322104639.221402-1-treapking@chromium.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-acpi@vger.kernel.org Register USB Type-C mode switches when the "mode-switch" property and relevant ports are available in Device Tree. Configure the crosspoint switch based on the entered alternate mode for a specific Type-C connector. Crosspoint switch can also be used for switching the output signal for different orientations of a single USB Type-C connector, but the orientation switch is not implemented yet. A TODO is added for this. Signed-off-by: Pin-yen Lin --- Changes in v14: - Fix style issues Changes in v12: - Fixed style issues in anx7625 driver - Fixed the inverted orientation setting in anx7625 driver - Changed "&ctx->client->dev" to "ctx->dev" - Fix style issues - Updated the error logs when parsing data-lanes property Changes in v11: - Added back "data-lanes" parsing logics - Removed Kconfig dependency - Updated the usage of the private data - Dropped Tested-by tag because of the new changes Changes in v10: - Added a TODO for implementing orientation switch for anx7625 - Updated the commit message for the absence of orientation switch - Fixed typo in the commit message - Collected Tested-by tag Changes in v7: - Fixed style issues in anx7625 driver - Removed DT property validation in anx7625 driver. - Extracted common codes to another commit. Changes in v6: - Squashed to a single patch drivers/gpu/drm/bridge/analogix/anx7625.c | 148 ++++++++++++++++++++++ drivers/gpu/drm/bridge/analogix/anx7625.h | 20 +++ 2 files changed, 168 insertions(+) diff --git a/drivers/gpu/drm/bridge/analogix/anx7625.c b/drivers/gpu/drm/bridge/analogix/anx7625.c index 76d46db3f8dc..9b259c07743f 100644 --- a/drivers/gpu/drm/bridge/analogix/anx7625.c +++ b/drivers/gpu/drm/bridge/analogix/anx7625.c @@ -15,6 +15,8 @@ #include #include #include +#include +#include #include #include @@ -2570,6 +2572,145 @@ static void anx7625_runtime_disable(void *data) pm_runtime_disable(data); } +static void anx7625_set_crosspoint_switch(struct anx7625_data *ctx, + enum typec_orientation orientation) +{ + if (orientation == TYPEC_ORIENTATION_NORMAL) { + anx7625_reg_write(ctx, ctx->i2c.tcpc_client, TCPC_SWITCH_0, + SW_SEL1_SSRX_RX1 | SW_SEL1_DPTX0_RX2); + anx7625_reg_write(ctx, ctx->i2c.tcpc_client, TCPC_SWITCH_1, + SW_SEL2_SSTX_TX1 | SW_SEL2_DPTX1_TX2); + } else if (orientation == TYPEC_ORIENTATION_REVERSE) { + anx7625_reg_write(ctx, ctx->i2c.tcpc_client, TCPC_SWITCH_0, + SW_SEL1_SSRX_RX2 | SW_SEL1_DPTX0_RX1); + anx7625_reg_write(ctx, ctx->i2c.tcpc_client, TCPC_SWITCH_1, + SW_SEL2_SSTX_TX2 | SW_SEL2_DPTX1_TX1); + } +} + +static void anx7625_typec_two_ports_update(struct anx7625_data *ctx) +{ + unsigned int i; + + /* Check if both ports available and do nothing to retain the current one */ + if (ctx->port_data[0].dp_connected && ctx->port_data[1].dp_connected) + return; + + for (i = 0; i < 2; i++) { + if (ctx->port_data[i].dp_connected) + anx7625_set_crosspoint_switch(ctx, + ctx->port_data[i].orientation); + } +} + +static int anx7625_typec_mux_set(struct typec_mux_dev *mux, + struct typec_mux_state *state) +{ + struct drm_dp_typec_port_data *port = typec_mux_get_drvdata(mux); + struct anx7625_data *ctx = port->data; + struct device *dev = ctx->dev; + struct drm_dp_typec_switch_desc switch_desc = ctx->switch_desc; + bool new_dp_connected, old_dp_connected; + + if (switch_desc.num_typec_switches == 1) + return 0; + + wait_for_completion(&ctx->mux_register); + + old_dp_connected = ctx->port_data[0].dp_connected || + ctx->port_data[1].dp_connected; + + ctx->port_data[port->port_num].dp_connected = + state->alt && + state->alt->svid == USB_TYPEC_DP_SID && + state->alt->mode == USB_TYPEC_DP_MODE; + + dev_dbg(dev, "mux_set dp_connected: c0=%d, c1=%d\n", + ctx->port_data[0].dp_connected, ctx->port_data[1].dp_connected); + + new_dp_connected = ctx->port_data[0].dp_connected || + ctx->port_data[1].dp_connected; + + /* DP on, power on first */ + if (!old_dp_connected && new_dp_connected) + pm_runtime_get_sync(dev); + + anx7625_typec_two_ports_update(ctx); + + /* DP off, power off last */ + if (old_dp_connected && !new_dp_connected) + pm_runtime_put_sync(dev); + + return 0; +} + +static void anx7625_unregister_typec_switches(struct anx7625_data *ctx) +{ + drm_dp_unregister_typec_switches(&ctx->switch_desc); +} + +static int anx7625_register_typec_switches(struct device *dev, struct anx7625_data *ctx) +{ + struct device_node *port_node = of_graph_get_port_by_id(dev->of_node, 1); + struct drm_dp_typec_switch_desc *switch_desc = &ctx->switch_desc; + int ret; + u32 dp_lanes[4]; + unsigned int i, num_lanes; + + /* + * Currently, only mode switch is implemented. + * TODO: Implement Type-C orientation switch for anx7625. + */ + ret = drm_dp_register_typec_switches(dev, &port_node->fwnode, + &ctx->switch_desc, ctx, + anx7625_typec_mux_set); + if (ret) + return ret; + + ctx->port_data = devm_kcalloc(dev, switch_desc->num_typec_switches, + sizeof(struct anx7625_typec_port_data), + GFP_KERNEL); + if (!ctx->port_data) { + ret = -ENOMEM; + goto unregister_mux; + } + + for (i = 0; i < switch_desc->num_typec_switches; i++) { + struct drm_dp_typec_port_data *port = &switch_desc->typec_ports[i]; + struct fwnode_handle *fwnode = port->fwnode; + + ret = fwnode_property_count_u32(fwnode, "data-lanes"); + if (ret < 0) { + dev_err(dev, + "Error on getting data lanes count from %pfwP: %d\n", + fwnode, ret); + goto unregister_mux; + } + num_lanes = ret; + + ret = fwnode_property_read_u32_array(fwnode, "data-lanes", + dp_lanes, num_lanes); + if (ret) { + dev_err(dev, + "Failed to read the data-lanes variable: %d\n", + ret); + goto unregister_mux; + } + + ctx->port_data[i].orientation = dp_lanes[0] < 2 ? + TYPEC_ORIENTATION_REVERSE : TYPEC_ORIENTATION_NORMAL; + ctx->port_data[i].dp_connected = false; + } + complete_all(&ctx->mux_register); + + return 0; + +unregister_mux: + complete_all(&ctx->mux_register); + anx7625_unregister_typec_switches(ctx); + return ret; +} + static int anx7625_i2c_probe(struct i2c_client *client) { struct anx7625_data *platform; @@ -2607,6 +2748,7 @@ static int anx7625_i2c_probe(struct i2c_client *client) mutex_init(&platform->lock); mutex_init(&platform->hdcp_wq_lock); + init_completion(&platform->mux_register); INIT_DELAYED_WORK(&platform->hdcp_work, hdcp_check_work_func); platform->hdcp_workqueue = create_workqueue("hdcp workqueue"); @@ -2677,6 +2819,10 @@ static int anx7625_i2c_probe(struct i2c_client *client) if (platform->pdata.intp_irq) queue_work(platform->workqueue, &platform->work); + ret = anx7625_register_typec_switches(dev, platform); + if (ret && ret != -ENODEV) + dev_warn(dev, "Didn't register Type-C switches, err: %d\n", ret); + platform->bridge.funcs = &anx7625_bridge_funcs; platform->bridge.of_node = client->dev.of_node; if (!anx7625_of_panel_on_aux_bus(&client->dev)) @@ -2728,6 +2874,8 @@ static void anx7625_i2c_remove(struct i2c_client *client) drm_bridge_remove(&platform->bridge); + anx7625_unregister_typec_switches(platform); + if (platform->pdata.intp_irq) destroy_workqueue(platform->workqueue); diff --git a/drivers/gpu/drm/bridge/analogix/anx7625.h b/drivers/gpu/drm/bridge/analogix/anx7625.h index 5af819611ebc..5a200da34800 100644 --- a/drivers/gpu/drm/bridge/analogix/anx7625.h +++ b/drivers/gpu/drm/bridge/analogix/anx7625.h @@ -55,6 +55,18 @@ #define HPD_STATUS_CHANGE 0x80 #define HPD_STATUS 0x80 +#define TCPC_SWITCH_0 0xB4 +#define SW_SEL1_DPTX0_RX2 BIT(0) +#define SW_SEL1_DPTX0_RX1 BIT(1) +#define SW_SEL1_SSRX_RX2 BIT(4) +#define SW_SEL1_SSRX_RX1 BIT(5) + +#define TCPC_SWITCH_1 0xB5 +#define SW_SEL2_DPTX1_TX2 BIT(0) +#define SW_SEL2_DPTX1_TX1 BIT(1) +#define SW_SEL2_SSTX_TX2 BIT(4) +#define SW_SEL2_SSTX_TX1 BIT(5) + /******** END of I2C Address 0x58 ********/ /***************************************************************/ @@ -449,6 +461,11 @@ struct anx7625_i2c_client { struct i2c_client *tcpc_client; }; +struct anx7625_typec_port_data { + bool dp_connected; + enum typec_orientation orientation; +}; + struct anx7625_data { struct anx7625_platform_data pdata; struct platform_device *audio_pdev; @@ -479,6 +496,9 @@ struct anx7625_data { struct drm_connector *connector; struct mipi_dsi_device *dsi; struct drm_dp_aux aux; + struct completion mux_register; + struct drm_dp_typec_switch_desc switch_desc; + struct anx7625_typec_port_data *port_data; }; #endif /* __ANX7625_H__ */ From patchwork Wed Mar 22 10:46:37 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Pin-yen Lin X-Patchwork-Id: 665938 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id E36B4C7619A for ; Wed, 22 Mar 2023 10:49:02 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230259AbjCVKtB (ORCPT ); Wed, 22 Mar 2023 06:49:01 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:42144 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230492AbjCVKsK (ORCPT ); Wed, 22 Mar 2023 06:48:10 -0400 Received: from mail-pl1-x630.google.com (mail-pl1-x630.google.com [IPv6:2607:f8b0:4864:20::630]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id E5D8862876 for ; Wed, 22 Mar 2023 03:47:34 -0700 (PDT) Received: by mail-pl1-x630.google.com with SMTP id k2so18868276pll.8 for ; Wed, 22 Mar 2023 03:47:34 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; t=1679482053; 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=/8yfn2DmllskdKP/oOcQ9B405UmJOgHc+y1qZoocZy8=; b=O5uKHQ9H+aO2fBv01xe8xdY7oBrreI5ewWbZElSXkWxkPzP2xScs0UAJKKrtPXCVg6 ZQ37l5vdd9fC5HuJgYpgMWtf4riT6buEa2xmSPyxgCnQhVMFSFKZpx8FbzokLNjyLWPu +BCIGjv6+iRWIL/JaBAHVsuEQ+3TT/bJS6s94= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; t=1679482053; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=/8yfn2DmllskdKP/oOcQ9B405UmJOgHc+y1qZoocZy8=; b=3auwC/n89qDeAxv6BTptK4M1wqISyLCVPuXzJ0Vf6BykbK1X+TRwYf8VHYPJmSbiPX ECXDnwQhw5xsfxU3JD28RgERgGn+XJcTMpZDY+fmj7hdeyge+QCci9adOCOy0zUR97Fm 5lTQ9OaGqaaw92/bpUNkPaNLBQjHokVQx5kTji4ezf+Xn1Np+/qsZhunTVbDXt5nbe2D bCCgctHS09WKeJ2pIZBLSt/5XfHRheNMB4fil0LLm1qd3Raic6cA4fE/TnNWyjbgsfbw MXXJrmPPeQVClnmYjBuspwDUDJkXnEIKyubTxMijmtX/hNWAiFuCSNXWs71vAdx0JFG7 o5ag== X-Gm-Message-State: AO0yUKUVzmzmO2tERj7HsbdT/fQcUIgWZU5k8rOQG14qaL1iOCox+g6h Q9QXbRFAnRxNrwMXjP2yOVxxUA== X-Google-Smtp-Source: AK7set/q0g0SgD5KxrTZbJCzBXxFDUxW3Rn/n92NryRdOtXJ6of3S1G0Y/QuG1AwOgmH0nrMVCMriw== X-Received: by 2002:a17:90a:bc85:b0:23f:d7ea:6212 with SMTP id x5-20020a17090abc8500b0023fd7ea6212mr2746126pjr.38.1679482052774; Wed, 22 Mar 2023 03:47:32 -0700 (PDT) Received: from treapking.tpe.corp.google.com ([2401:fa00:1:10:343d:79bf:55f9:1da5]) by smtp.gmail.com with ESMTPSA id hg4-20020a17090b300400b002340d317f3esm9508742pjb.52.2023.03.22.03.47.27 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 22 Mar 2023 03:47:32 -0700 (PDT) From: Pin-yen Lin To: Andrzej Hajda , Neil Armstrong , Robert Foss , Laurent Pinchart , Jonas Karlman , Jernej Skrabec , David Airlie , Daniel Vetter , Rob Herring , Krzysztof Kozlowski , Andy Shevchenko , Daniel Scally , Heikki Krogerus , Sakari Ailus , Greg Kroah-Hartman , "Rafael J . Wysocki" , Prashant Malani , Benson Leung , Guenter Roeck Cc: Xin Ji , linux-kernel@vger.kernel.org, Thomas Zimmermann , linux-acpi@vger.kernel.org, Javier Martinez Canillas , AngeloGioacchino Del Regno , Pin-yen Lin , Hsin-Yi Wang , Lyude Paul , =?utf-8?q?N=C3=ADcolas_F_=2E_R_=2E_A_=2E_Pra?= =?utf-8?q?do?= , Allen Chen , dri-devel@lists.freedesktop.org, Marek Vasut , Stephen Boyd , chrome-platform@lists.linux.dev, devicetree@vger.kernel.org Subject: [PATCH v14 08/10] dt-bindings: display: bridge: it6505: Add mode-switch support Date: Wed, 22 Mar 2023 18:46:37 +0800 Message-Id: <20230322104639.221402-9-treapking@chromium.org> X-Mailer: git-send-email 2.40.0.rc1.284.g88254d51c5-goog In-Reply-To: <20230322104639.221402-1-treapking@chromium.org> References: <20230322104639.221402-1-treapking@chromium.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-acpi@vger.kernel.org ITE IT6505 can be used in systems to switch the DP traffic between two downstreams, which can be USB Type-C DisplayPort alternate mode lane or regular DisplayPort output ports. Update the binding to accommodate this usage by introducing a data-lanes and a mode-switch property on endpoints. Signed-off-by: Pin-yen Lin --- (no changes since v12) Changes in v12: - Fixed the schema of "data-lanes" property for it6505 - Reworded the description of the mode-switch property Changes in v11: - Updated the description of the endpoints in the bindings - Referenced video-interfaces.yaml instead for the endpoints binding - Removed duplicated definitions from inherited schema Changes in v9: - Fixed subject prefix again - Changed the naming of the example node for it6505 Changes in v8: - Updated bindings for data-lanes property - Fixed subject prefix Changes in v7: - Fixed issues reported by dt_binding_check. - Updated the schema and the example dts for data-lanes. - Changed to generic naming for the example dts node. Changes in v6: - Remove switches node and use endpoints and data-lanes property to describe the connections. .../bindings/display/bridge/ite,it6505.yaml | 101 +++++++++++++++--- 1 file changed, 88 insertions(+), 13 deletions(-) diff --git a/Documentation/devicetree/bindings/display/bridge/ite,it6505.yaml b/Documentation/devicetree/bindings/display/bridge/ite,it6505.yaml index c9a882ee6d98..348b02f26041 100644 --- a/Documentation/devicetree/bindings/display/bridge/ite,it6505.yaml +++ b/Documentation/devicetree/bindings/display/bridge/ite,it6505.yaml @@ -75,22 +75,49 @@ properties: port@1: $ref: /schemas/graph.yaml#/$defs/port-base unevaluatedProperties: false - description: Video port for DP output + description: + Video port for DP output. Each endpoint connects to a video output + downstream, and the "data-lanes" property is used to describe the pin + connections. 0, 1, 2, 3 in "data-lanes" maps to TX0, TX1, TX2, TX3, + respectively. - properties: - endpoint: - $ref: /schemas/graph.yaml#/$defs/endpoint-base + + patternProperties: + "^endpoint@[01]$": + $ref: /schemas/media/video-interfaces.yaml# unevaluatedProperties: false properties: + reg: true + + remote-endpoint: true + data-lanes: - minItems: 1 - uniqueItems: true - items: - - enum: [ 0, 1 ] - - const: 1 - - const: 2 - - const: 3 + oneOf: + - items: + - enum: [0, 3] + + - items: + - const: 0 + - const: 1 + + - items: + - const: 3 + - const: 2 + + - items: + - const: 0 + - const: 1 + - const: 2 + - const: 3 + + mode-switch: + type: boolean + description: Serves as Type-C mode switch if present. + + required: + - reg + - remote-endpoint required: - port@0 @@ -102,7 +129,6 @@ required: - pwr18-supply - interrupts - reset-gpios - - extcon - ports additionalProperties: false @@ -139,8 +165,11 @@ examples: }; port@1 { + #address-cells = <1>; + #size-cells = <0>; reg = <1>; - it6505_out: endpoint { + it6505_out: endpoint@0 { + reg = <0>; remote-endpoint = <&dp_in>; data-lanes = <0 1>; }; @@ -148,3 +177,49 @@ examples: }; }; }; + - | + #include + + i2c { + #address-cells = <1>; + #size-cells = <0>; + + dp-bridge@5c { + compatible = "ite,it6505"; + interrupts = <8 IRQ_TYPE_LEVEL_LOW 8 0>; + reg = <0x5c>; + pinctrl-names = "default"; + pinctrl-0 = <&it6505_pins>; + ovdd-supply = <&mt6366_vsim2_reg>; + pwr18-supply = <&pp1800_dpbrdg_dx>; + reset-gpios = <&pio 177 0>; + + ports { + #address-cells = <1>; + #size-cells = <0>; + port@0 { + reg = <0>; + it6505_dpi_in: endpoint { + remote-endpoint = <&dpi_out>; + }; + }; + port@1 { + #address-cells = <1>; + #size-cells = <0>; + reg = <1>; + ite_typec0: endpoint@0 { + reg = <0>; + mode-switch; + data-lanes = <0 1>; + remote-endpoint = <&typec_port0>; + }; + ite_typec1: endpoint@1 { + reg = <1>; + mode-switch; + data-lanes = <3 2>; + remote-endpoint = <&typec_port1>; + }; + }; + }; + }; + }; From patchwork Wed Mar 22 10:46:38 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Pin-yen Lin X-Patchwork-Id: 666237 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 82F38C77B60 for ; Wed, 22 Mar 2023 10:49:05 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230444AbjCVKtE (ORCPT ); Wed, 22 Mar 2023 06:49:04 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:41822 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230358AbjCVKsY (ORCPT ); Wed, 22 Mar 2023 06:48:24 -0400 Received: from mail-pl1-x62f.google.com (mail-pl1-x62f.google.com [IPv6:2607:f8b0:4864:20::62f]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 63FBC61522 for ; Wed, 22 Mar 2023 03:47:40 -0700 (PDT) Received: by mail-pl1-x62f.google.com with SMTP id iw3so18876728plb.6 for ; Wed, 22 Mar 2023 03:47:40 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; t=1679482058; 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=oBJWqFf529bD8jjCDuA2KK02mIaG17tQPXtMSxF+r5U=; b=Bs4oVb7r/GfydoLVRsXK6ciaCdAlCJGoVC0GBKWS1bTpRNwfiaabHTmJK2AHkPEPQX RzQtwPyf7FxbsQDNZxOum0m7WE6xa2OuCyyognSZd0uLr+HNNiSVsc7B2e8CU0z0XajQ 9nmP92+emXT/ECYkmr+V9ptY/Dvk7M/yMynz0= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; t=1679482058; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=oBJWqFf529bD8jjCDuA2KK02mIaG17tQPXtMSxF+r5U=; b=S97TC6GzG5PScTAjc0ZlC60/laJ+pdtdGYoEeOaqK4PLOkq7LN0JOLjc3/5KerS4uY xck81JiVZ0HAcoX4aW6CvzvXu0JY8D5ew23E5tRxrbsUr9dPqwA8ZyWWHgc5GxgZGEu5 Lt9VGfmi7/8kuMH1l3+ncri/+kHK4T9R8PtvQ0OelQn40Cc78WH9Y3pqEHBwiBh5+phC u+xYoGgkwbYJHGntoSyFqQmgcO6OGufE+xu5o4Pg1/hG6cenCUQ8glcIVSjclVhuSw2D 8U7EQyGCMm8NM39w6cE4SXZyDmCZkdiaBbcqQPjLHpGBB2/Y3bbQoRHIzNW86P7j/V11 OLlw== X-Gm-Message-State: AO0yUKWlPKkvHEOgZEBNPM34UraEaowOV8P81Kkehl0SW2lg8EHVR0Fl 6I9POSmgJLe1Vaa7whMHLbZPeg== X-Google-Smtp-Source: AK7set8Ei3DqOnokIBECX7S8i8g1KL2mbbHUechKS4aqr0RMz86pm38BSbfR/++b+hwW4t2FFU+JAg== X-Received: by 2002:a17:90b:4b44:b0:23d:39d5:f81e with SMTP id mi4-20020a17090b4b4400b0023d39d5f81emr3468217pjb.11.1679482058020; Wed, 22 Mar 2023 03:47:38 -0700 (PDT) Received: from treapking.tpe.corp.google.com ([2401:fa00:1:10:343d:79bf:55f9:1da5]) by smtp.gmail.com with ESMTPSA id hg4-20020a17090b300400b002340d317f3esm9508742pjb.52.2023.03.22.03.47.33 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 22 Mar 2023 03:47:37 -0700 (PDT) From: Pin-yen Lin To: Andrzej Hajda , Neil Armstrong , Robert Foss , Laurent Pinchart , Jonas Karlman , Jernej Skrabec , David Airlie , Daniel Vetter , Rob Herring , Krzysztof Kozlowski , Andy Shevchenko , Daniel Scally , Heikki Krogerus , Sakari Ailus , Greg Kroah-Hartman , "Rafael J . Wysocki" , Prashant Malani , Benson Leung , Guenter Roeck Cc: Xin Ji , linux-kernel@vger.kernel.org, Thomas Zimmermann , linux-acpi@vger.kernel.org, Javier Martinez Canillas , AngeloGioacchino Del Regno , Pin-yen Lin , Hsin-Yi Wang , Lyude Paul , =?utf-8?q?N=C3=ADcolas_F_=2E_R_=2E_A_=2E_Pra?= =?utf-8?q?do?= , Allen Chen , dri-devel@lists.freedesktop.org, Marek Vasut , Stephen Boyd , chrome-platform@lists.linux.dev, devicetree@vger.kernel.org Subject: [PATCH v14 09/10] drm/bridge: it6505: Fix Kconfig indentation Date: Wed, 22 Mar 2023 18:46:38 +0800 Message-Id: <20230322104639.221402-10-treapking@chromium.org> X-Mailer: git-send-email 2.40.0.rc1.284.g88254d51c5-goog In-Reply-To: <20230322104639.221402-1-treapking@chromium.org> References: <20230322104639.221402-1-treapking@chromium.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-acpi@vger.kernel.org Replace the spaces with tab characters in the Kconfig file. Signed-off-by: Pin-yen Lin Reviewed-by: AngeloGioacchino Del Regno --- (no changes since v10) Changes in v10: - Collected Reviewed-by tag Changes in v7: - New in v7 drivers/gpu/drm/bridge/Kconfig | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/drivers/gpu/drm/bridge/Kconfig b/drivers/gpu/drm/bridge/Kconfig index 12e8f30c65f7..28dc7711bf5f 100644 --- a/drivers/gpu/drm/bridge/Kconfig +++ b/drivers/gpu/drm/bridge/Kconfig @@ -74,19 +74,19 @@ config DRM_FSL_LDB Support for i.MX8MP DPI-to-LVDS on-SoC encoder. config DRM_ITE_IT6505 - tristate "ITE IT6505 DisplayPort bridge" - depends on OF + tristate "ITE IT6505 DisplayPort bridge" + depends on OF select DRM_DISPLAY_DP_HELPER select DRM_DISPLAY_HDCP_HELPER select DRM_DISPLAY_HELPER - select DRM_DP_AUX_BUS - select DRM_KMS_HELPER - select DRM_DP_HELPER - select EXTCON - select CRYPTO - select CRYPTO_HASH - help - ITE IT6505 DisplayPort bridge chip driver. + select DRM_DP_AUX_BUS + select DRM_KMS_HELPER + select DRM_DP_HELPER + select EXTCON + select CRYPTO + select CRYPTO_HASH + help + ITE IT6505 DisplayPort bridge chip driver. config DRM_LONTIUM_LT8912B tristate "Lontium LT8912B DSI/HDMI bridge" From patchwork Wed Mar 22 10:46:39 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Pin-yen Lin X-Patchwork-Id: 665937 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id C7BA8C6FD1C for ; Wed, 22 Mar 2023 10:49:24 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230494AbjCVKtX (ORCPT ); Wed, 22 Mar 2023 06:49:23 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:40870 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230498AbjCVKs1 (ORCPT ); Wed, 22 Mar 2023 06:48:27 -0400 Received: from mail-pj1-x102e.google.com (mail-pj1-x102e.google.com [IPv6:2607:f8b0:4864:20::102e]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 4248F62B5D for ; Wed, 22 Mar 2023 03:47:46 -0700 (PDT) Received: by mail-pj1-x102e.google.com with SMTP id mp3-20020a17090b190300b0023fcc8ce113so8223360pjb.4 for ; Wed, 22 Mar 2023 03:47:46 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; t=1679482063; 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=+FF2ESmiiihfdUKZ1gHccbyU50W0AbxwPHMUw+YJ4po=; b=nfLgwSYCb6c8k79DrPtmV/SnDKXeLf/SKbimoDCIuB9DzO+ChXJZp0SJ7NLDZL6aes PCUUEnUHd8ePkTydG75UrPkpsXgNp9vW5OAGozkn4XjPWoyrEhEaqx+nnscCaLNN2q/O nMZMU0IOrkSM7450xgpev38xoUB/TVGcA1HeE= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; t=1679482063; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=+FF2ESmiiihfdUKZ1gHccbyU50W0AbxwPHMUw+YJ4po=; b=npl//1DV4NDZUBkIj6mIrZjzmQVvMgWsR4VXHPlJry0lQ+7Afa/m3AaU/cirKF5v/s bI0OwWRjkCiHMoYjnXeD8su+KZMM0SmTu81C5FxJ3pMmd4fmNzvZI2UYAqCNjsyYJiGg QYvJrcfmJmwaRhNDNrivGNDdo1ZKE3tlMGYuX42fX4zVBZdsVVVAEH9V88yZ4VZVoyiW H34oeGjJhAyGt4/072HsMvq7j+dk3euPe/6GWv2qkVTEPwA5R7zMtVOd1fWziGciz272 V8XvfN9EDhcpHz+N3XLZUAu4xhAqli68dGUc81Xs7neqPGFANNUr0UiP8+PkpbS9ZK7A VUbQ== X-Gm-Message-State: AO0yUKXM21q4NsBEw3eXf2uH7aLMJjQdkGYNiKjSnjj4I1EPY/pEzB8g PWI32yQyJGPj09xYh6bKlmYCEA== X-Google-Smtp-Source: AK7set95cBQsa0keVL6mVamcmGVinLOyF+09EHb16w+HRk9NSY7l9YPI2xwhYoVj3l1Hu5DSdYYBAA== X-Received: by 2002:a17:90a:56:b0:23f:ebf2:d3de with SMTP id 22-20020a17090a005600b0023febf2d3demr3016122pjb.27.1679482063289; Wed, 22 Mar 2023 03:47:43 -0700 (PDT) Received: from treapking.tpe.corp.google.com ([2401:fa00:1:10:343d:79bf:55f9:1da5]) by smtp.gmail.com with ESMTPSA id hg4-20020a17090b300400b002340d317f3esm9508742pjb.52.2023.03.22.03.47.38 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 22 Mar 2023 03:47:43 -0700 (PDT) From: Pin-yen Lin To: Andrzej Hajda , Neil Armstrong , Robert Foss , Laurent Pinchart , Jonas Karlman , Jernej Skrabec , David Airlie , Daniel Vetter , Rob Herring , Krzysztof Kozlowski , Andy Shevchenko , Daniel Scally , Heikki Krogerus , Sakari Ailus , Greg Kroah-Hartman , "Rafael J . Wysocki" , Prashant Malani , Benson Leung , Guenter Roeck Cc: Xin Ji , linux-kernel@vger.kernel.org, Thomas Zimmermann , linux-acpi@vger.kernel.org, Javier Martinez Canillas , AngeloGioacchino Del Regno , Pin-yen Lin , Hsin-Yi Wang , Lyude Paul , =?utf-8?q?N=C3=ADcolas_F_=2E_R_=2E_A_=2E_Pra?= =?utf-8?q?do?= , Allen Chen , dri-devel@lists.freedesktop.org, Marek Vasut , Stephen Boyd , chrome-platform@lists.linux.dev, devicetree@vger.kernel.org Subject: [PATCH v14 10/10] drm/bridge: it6505: Register Type C mode switches Date: Wed, 22 Mar 2023 18:46:39 +0800 Message-Id: <20230322104639.221402-11-treapking@chromium.org> X-Mailer: git-send-email 2.40.0.rc1.284.g88254d51c5-goog In-Reply-To: <20230322104639.221402-1-treapking@chromium.org> References: <20230322104639.221402-1-treapking@chromium.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-acpi@vger.kernel.org Register USB Type-C mode switches when the "mode-switch" property and relevant port are available in Device Tree. Configure the "lane_swap" state based on the entered alternate mode for a specific Type-C connector, which ends up updating the lane swap registers of the it6505 chip. Signed-off-by: Pin-yen Lin --- Changes in v14: - Fix style issues Changes in v13: - Fix style issues Changes in v12: - Fixes style issues in it6505 driver - Replaced &it6505->client->dev with it6505->dev - Updated the error logs when parsing data-lanes property Changes in v11: - Added back "data-lanes" parsing logics - Removed Kconfig dependency - Updated the usage of the private data Changes in v7: - Fixed style issues in it6505 driver - Removed the redundant sleep in it6505 driver - Removed DT property validation in it6505 driver - Rebased to drm-misc-next - Extracted common codes to another commit Changes in v6: - Changed it6505_typec_mux_set callback function to accommodate with the latest drm-misc patches - Changed the driver implementation to accommodate with the new binding - Squashed to a single patch drivers/gpu/drm/bridge/ite-it6505.c | 190 +++++++++++++++++++++++++++- 1 file changed, 183 insertions(+), 7 deletions(-) diff --git a/drivers/gpu/drm/bridge/ite-it6505.c b/drivers/gpu/drm/bridge/ite-it6505.c index d4bc388b68ac..28d07fd7486b 100644 --- a/drivers/gpu/drm/bridge/ite-it6505.c +++ b/drivers/gpu/drm/bridge/ite-it6505.c @@ -17,6 +17,8 @@ #include #include #include +#include +#include #include #include @@ -27,6 +29,7 @@ #include #include #include +#include #include #include @@ -401,6 +404,11 @@ struct debugfs_entries { const struct file_operations *fops; }; +struct it6505_typec_port_data { + bool dp_connected; + bool lane_swap; +}; + struct it6505 { struct drm_dp_aux aux; struct drm_bridge bridge; @@ -454,6 +462,9 @@ struct it6505 { struct delayed_work delayed_audio; struct it6505_audio_data audio; struct dentry *debugfs; + struct completion mux_register; + struct drm_dp_typec_switch_desc switch_desc; + struct it6505_typec_port_data *port_data; /* it6505 driver hold option */ bool enable_drv_hold; @@ -3345,12 +3356,162 @@ static void it6505_shutdown(struct i2c_client *client) it6505_lane_off(it6505); } +static void it6505_typec_ports_update(struct it6505 *it6505) +{ + unsigned int i; + + /* Check if both ports available and do nothing to retain the current one */ + if (it6505->port_data[0].dp_connected && it6505->port_data[1].dp_connected) + return; + + for (i = 0; i < 2; i++) { + if (it6505->port_data[i].dp_connected) + it6505->lane_swap = it6505->port_data[i].lane_swap; + } +} + +static int it6505_typec_mux_set(struct typec_mux_dev *mux, + struct typec_mux_state *state) +{ + struct drm_dp_typec_port_data *port = typec_mux_get_drvdata(mux); + struct it6505 *it6505 = port->data; + struct device *dev = it6505->dev; + struct drm_dp_typec_switch_desc switch_desc = it6505->switch_desc; + bool old_dp_connected, new_dp_connected; + + if (switch_desc.num_typec_switches == 1) + return 0; + + mutex_lock(&it6505->extcon_lock); + wait_for_completion(&it6505->mux_register); + + old_dp_connected = it6505->port_data[0].dp_connected || + it6505->port_data[1].dp_connected; + + it6505->port_data[port->port_num].dp_connected = + state->alt && + state->alt->svid == USB_TYPEC_DP_SID && + state->alt->mode == USB_TYPEC_DP_MODE; + + dev_dbg(dev, "mux_set dp_connected: c0=%d, c1=%d\n", + it6505->port_data[0].dp_connected, it6505->port_data[1].dp_connected); + + new_dp_connected = it6505->port_data[0].dp_connected || + it6505->port_data[1].dp_connected; + + if (it6505->enable_drv_hold) { + dev_dbg(dev, "enable driver hold\n"); + goto unlock; + } + + it6505_typec_ports_update(it6505); + + if (!old_dp_connected && new_dp_connected) { + int ret = pm_runtime_get_sync(dev); + + /* + * pm_runtime_force_suspend() disables runtime PM when the + * system enters suspend state. But on system resume, mux_set + * can be triggered before pm_runtime_force_resume() re-enables + * runtime PM. This makes the bridge stay powered off if the + * downstream display is connected when the system is suspended. + * Handling the error here to make sure the bridge is powered + * on, and leave the PM runtime usage count incremented so + * the future runtime PM calls is balanced. + */ + if (ret < 0) + it6505_poweron(it6505); + + complete_all(&it6505->extcon_completion); + } + + if (old_dp_connected && !new_dp_connected) { + reinit_completion(&it6505->extcon_completion); + pm_runtime_put_sync(dev); + if (it6505->bridge.dev) + drm_helper_hpd_irq_event(it6505->bridge.dev); + memset(it6505->dpcd, 0, sizeof(it6505->dpcd)); + } + +unlock: + mutex_unlock(&it6505->extcon_lock); + return 0; +} + +static void it6505_unregister_typec_switches(struct it6505 *it6505) +{ + drm_dp_unregister_typec_switches(&it6505->switch_desc); +} + +static int it6505_register_typec_switches(struct device *dev, struct it6505 *it6505) +{ + struct device_node *port_node = of_graph_get_port_by_id(dev->of_node, 1); + struct drm_dp_typec_switch_desc *switch_desc = &it6505->switch_desc; + int ret; + u32 dp_lanes[4]; + unsigned int i, num_lanes; + + ret = drm_dp_register_typec_switches(dev, &port_node->fwnode, + &it6505->switch_desc, it6505, + it6505_typec_mux_set); + if (ret) + return ret; + + it6505->port_data = devm_kcalloc(dev, switch_desc->num_typec_switches, + sizeof(struct it6505_typec_port_data), + GFP_KERNEL); + if (!it6505->port_data) { + ret = -ENOMEM; + goto unregister_mux; + } + + for (i = 0; i < switch_desc->num_typec_switches; i++) { + struct drm_dp_typec_port_data *port = &switch_desc->typec_ports[i]; + struct fwnode_handle *fwnode = port->fwnode; + + ret = fwnode_property_count_u32(fwnode, "data-lanes"); + if (ret < 0) { + dev_err(dev, + "Error on getting data lanes count from %pfwP: %d\n", + fwnode, ret); + goto unregister_mux; + } + if (ret > 2) { + dev_err(dev, + "Invalid data lanes count for mode switches from %pfwP: %d\n", + fwnode, ret); + ret = -EINVAL; + goto unregister_mux; + } + num_lanes = ret; + + ret = fwnode_property_read_u32_array(fwnode, "data-lanes", + dp_lanes, num_lanes); + if (ret) { + dev_err(dev, + "Failed to read the data-lanes variable: %d\n", + ret); + goto unregister_mux; + } + + it6505->port_data[i].lane_swap = (dp_lanes[0] >= 2); + } + complete_all(&it6505->mux_register); + + return 0; + +unregister_mux: + complete_all(&it6505->mux_register); + it6505_unregister_typec_switches(it6505); + return ret; +} + static int it6505_i2c_probe(struct i2c_client *client) { struct it6505 *it6505; struct device *dev = &client->dev; struct extcon_dev *extcon; - int err, intp_irq; + int err, intp_irq, ret; it6505 = devm_kzalloc(&client->dev, sizeof(*it6505), GFP_KERNEL); if (!it6505) @@ -3367,14 +3528,28 @@ static int it6505_i2c_probe(struct i2c_client *client) /* get extcon device from DTS */ extcon = extcon_get_edev_by_phandle(dev, 0); - if (PTR_ERR(extcon) == -EPROBE_DEFER) - return -EPROBE_DEFER; - if (IS_ERR(extcon)) { - dev_err(dev, "can not get extcon device!"); - return PTR_ERR(extcon); + ret = PTR_ERR_OR_ZERO(extcon); + if (ret == -EPROBE_DEFER) + return ret; + + if (ret) { + if (ret != -ENODEV) + dev_warn(dev, "Cannot get extcon device: %d\n", ret); + + it6505->extcon = NULL; + } else { + it6505->extcon = extcon; } - it6505->extcon = extcon; + init_completion(&it6505->mux_register); + ret = it6505_register_typec_switches(dev, it6505); + if (ret != -ENODEV) + dev_warn(dev, "Didn't register Type-C switches, err: %d\n", ret); + + if (ret && !it6505->extcon) { + dev_err(dev, "Both extcon and Type-C switch are not registered.\n"); + return -EINVAL; + } it6505->regmap = devm_regmap_init_i2c(client, &it6505_regmap_config); if (IS_ERR(it6505->regmap)) { @@ -3446,6 +3621,7 @@ static void it6505_i2c_remove(struct i2c_client *client) it6505_debugfs_remove(it6505); it6505_poweroff(it6505); it6505_remove_edid(it6505); + it6505_unregister_typec_switches(it6505); } static const struct i2c_device_id it6505_id[] = {