chrome-platform.lists.linux.dev archive mirror
 help / color / mirror / Atom feed
* [PATCH v12 00/10] Register Type-C mode-switch in DP bridge endpoints
@ 2023-02-21  9:50 Pin-yen Lin
  2023-02-21  9:50 ` [PATCH v12 01/10] device property: Add remote endpoint to devcon matcher Pin-yen Lin
                   ` (9 more replies)
  0 siblings, 10 replies; 21+ messages in thread
From: Pin-yen Lin @ 2023-02-21  9:50 UTC (permalink / raw)
  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: Pin-yen Lin, linux-kernel, Hsin-Yi Wang, Marek Vasut,
	Thomas Zimmermann, dri-devel, Xin Ji, Lyude Paul, Allen Chen,
	devicetree, AngeloGioacchino Del Regno,
	Nícolas F . R . A . Prado, chrome-platform,
	Javier Martinez Canillas, linux-acpi, Stephen Boyd,
	Douglas Anderson, Gustavo A. R. Silva, Imre Deak, Jani Nikula,
	Kees Cook, Uwe Kleine-König


This series introduces bindings for anx7625/it6505 to register Type-C
mode-switch in their output endpoints, and use data-lanes property to
describe the pin connections.

This series is not directly related to the built-in mux in anx7625,
which automatically switches between the two orientations of a single
Type-C connector. This series adds support of registering mode switches
for two downstream devices, while we use orientation switches for two
orientations of the Type-C connector.

The first two patch modifies fwnode_graph_devcon_matches and
cros_typec_init_ports to enable the registration of the switches.

Patch 4~6 introduce the bindings for anx7625 and the corresponding driver
modifications.

Patch 7~9 add similar bindings and driver changes for it6505.

v10: https://lore.kernel.org/all/20230112042104.4107253-1-treapking@chromium.org/
v9: https://lore.kernel.org/all/20230109084101.265664-1-treapking@chromium.org/
v8: https://lore.kernel.org/all/20230107102231.23682-1-treapking@chromium.org/
v7: https://lore.kernel.org/all/20230105132457.4125372-1-treapking@chromium.org/
v6: https://lore.kernel.org/all/20221124102056.393220-1-treapking@chromium.org/
v5: https://lore.kernel.org/linux-usb/20220622173605.1168416-1-pmalani@chromium.org/

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)
- Add fwnode_for_each_typec_mode_switch macro
- Remove a duplicated dmesg in the helper
- Used IS_REACHABLE instead to guard the function signatures
- Removed the 4-lane binding in analogix,anx7625.yaml
- Reworded the desription for the mode-switch property
- Fixed style issues in anx7625 driver
- Fixed the inverted orientation setting in anx7625 driver
- Changed "&ctx->client->dev" to "ctx->dev"
- Fixed the schema of "data-lanes" property for it6505
- 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 missing fwnode_handle_put in drivers/base/property.c
- Collected Acked-by tag
- Use fwnode helpers instead of DT
- Moved the helpers to a new file
- Use "reg" instead of "data-lanes" to determine the port number
- Updated the description of the endpoints in the bindings
- Referenced video-interfaces.yaml instead for the endpoints binding
- Removed duplicated definitions from inherited schema
- Moved the "data-lanes" parsing logics to bridge drivers
- Removed Kconfig dependencies for the bridge drivers
- Updated the usage of the private bridge driver data
- Added a clarification on the anx7625 built-in mux in the cover letter

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
- 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

Changes in v9:
- Collected Reviewed-by tag
- Fixed subject prefix again
- Changed the naming of the example node for it6505

Changes in v8:
- Fixed the build issue when CONFIG_TYPEC=m
- Fixed some style issues
- Fixed the subject prefixes for the bindings patch
- Fixed the bindings for data-lanes properties

Changes in v7:
- Fix the long comment lines
- Extracted the common codes to a helper function
- Fixed style issues in anx7625 driver
- Removed DT property validation in anx7625 driver.
- 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
- Fixed indentations in bindings patches
- Added a new patch to fix indentations in Kconfig

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
- Dropped typec-switch binding and use endpoints and data-lanes properties
  to describe the pin connections
- Added new patches (patch 1,2,4) to fix probing issues
- Changed the bindings of it6505/anx7625 and modified the drivers
  accordingly
- Merged it6505/anx7625 driver changes into a single patch

Pin-yen Lin (8):
  drm/display: Add Type-C switch helpers
  dt-bindings: display: bridge: anx7625: Add mode-switch support
  drm/bridge: anx7625: Check for Type-C during panel registration
  drm/bridge: Remove redundant i2c_client in anx7625/it6505
  drm/bridge: anx7625: Register Type C mode switches
  dt-bindings: display: bridge: it6505: Add mode-switch support
  drm/bridge: it6505: Fix Kconfig indentation
  drm/bridge: it6505: Register Type C mode switches

Prashant Malani (2):
  device property: Add remote endpoint to devcon matcher
  platform/chrome: cros_ec_typec: Purge blocking switch devlinks

 .../display/bridge/analogix,anx7625.yaml      |  88 ++++-
 .../bindings/display/bridge/ite,it6505.yaml   | 101 +++++-
 drivers/base/property.c                       |  29 +-
 drivers/gpu/drm/bridge/Kconfig                |  20 +-
 drivers/gpu/drm/bridge/analogix/anx7625.c     | 257 +++++++++++---
 drivers/gpu/drm/bridge/analogix/anx7625.h     |  22 +-
 drivers/gpu/drm/bridge/ite-it6505.c           | 314 ++++++++++++++----
 drivers/gpu/drm/display/Makefile              |   1 +
 drivers/gpu/drm/display/drm_dp_typec_helper.c | 108 ++++++
 drivers/platform/chrome/cros_ec_typec.c       |  10 +
 include/drm/display/drm_dp_helper.h           |  35 ++
 11 files changed, 836 insertions(+), 149 deletions(-)
 create mode 100644 drivers/gpu/drm/display/drm_dp_typec_helper.c

-- 
2.39.2.637.g21b0678d19-goog


^ permalink raw reply	[flat|nested] 21+ messages in thread

* [PATCH v12 01/10] device property: Add remote endpoint to devcon matcher
  2023-02-21  9:50 [PATCH v12 00/10] Register Type-C mode-switch in DP bridge endpoints Pin-yen Lin
@ 2023-02-21  9:50 ` Pin-yen Lin
  2023-02-21 11:26   ` Andy Shevchenko
  2023-02-21  9:50 ` [PATCH v12 02/10] platform/chrome: cros_ec_typec: Purge blocking switch devlinks Pin-yen Lin
                   ` (8 subsequent siblings)
  9 siblings, 1 reply; 21+ messages in thread
From: Pin-yen Lin @ 2023-02-21  9:50 UTC (permalink / raw)
  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: Pin-yen Lin, linux-kernel, Hsin-Yi Wang, Marek Vasut,
	Thomas Zimmermann, dri-devel, Xin Ji, Lyude Paul, Allen Chen,
	devicetree, AngeloGioacchino Del Regno,
	Nícolas F . R . A . Prado, chrome-platform,
	Javier Martinez Canillas, linux-acpi, Stephen Boyd

From: Prashant Malani <pmalani@chromium.org>

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 <pmalani@chromium.org>
Signed-off-by: Pin-yen Lin <treapking@chromium.org>

---

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 | 29 ++++++++++++++++++++++++-----
 1 file changed, 24 insertions(+), 5 deletions(-)

diff --git a/drivers/base/property.c b/drivers/base/property.c
index 083a95791d3b..45f7f40eb5fa 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,9 @@ 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.
  */
 void *fwnode_connection_find_match(const struct fwnode_handle *fwnode,
 				   const char *con_id, void *data,
@@ -1325,9 +1343,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.
  *
-- 
2.39.2.637.g21b0678d19-goog


^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH v12 02/10] platform/chrome: cros_ec_typec: Purge blocking switch devlinks
  2023-02-21  9:50 [PATCH v12 00/10] Register Type-C mode-switch in DP bridge endpoints Pin-yen Lin
  2023-02-21  9:50 ` [PATCH v12 01/10] device property: Add remote endpoint to devcon matcher Pin-yen Lin
@ 2023-02-21  9:50 ` Pin-yen Lin
  2023-02-21  9:50 ` [PATCH v12 03/10] drm/display: Add Type-C switch helpers Pin-yen Lin
                   ` (7 subsequent siblings)
  9 siblings, 0 replies; 21+ messages in thread
From: Pin-yen Lin @ 2023-02-21  9:50 UTC (permalink / raw)
  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: Pin-yen Lin, linux-kernel, Hsin-Yi Wang, Marek Vasut,
	Thomas Zimmermann, dri-devel, Xin Ji, Lyude Paul, Allen Chen,
	devicetree, AngeloGioacchino Del Regno,
	Nícolas F . R . A . Prado, chrome-platform,
	Javier Martinez Canillas, linux-acpi, Stephen Boyd, Chen-Yu Tsai

From: Prashant Malani <pmalani@chromium.org>

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 <pmalani@chromium.org>
Signed-off-by: Pin-yen Lin <treapking@chromium.org>
Reviewed-by: Chen-Yu Tsai <wenst@chromium.org>
Tested-by: Chen-Yu Tsai <wenst@chromium.org>
Acked-by: Heikki Krogerus <heikki.krogerus@linux.intel.com>

---

(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 001b0de95a46..bbc95a3ba5a7 100644
--- a/drivers/platform/chrome/cros_ec_typec.c
+++ b/drivers/platform/chrome/cros_ec_typec.c
@@ -385,6 +385,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) {
-- 
2.39.2.637.g21b0678d19-goog


^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH v12 03/10] drm/display: Add Type-C switch helpers
  2023-02-21  9:50 [PATCH v12 00/10] Register Type-C mode-switch in DP bridge endpoints Pin-yen Lin
  2023-02-21  9:50 ` [PATCH v12 01/10] device property: Add remote endpoint to devcon matcher Pin-yen Lin
  2023-02-21  9:50 ` [PATCH v12 02/10] platform/chrome: cros_ec_typec: Purge blocking switch devlinks Pin-yen Lin
@ 2023-02-21  9:50 ` Pin-yen Lin
  2023-02-21 11:48   ` Andy Shevchenko
  2023-02-21  9:50 ` [PATCH v12 04/10] dt-bindings: display: bridge: anx7625: Add mode-switch support Pin-yen Lin
                   ` (6 subsequent siblings)
  9 siblings, 1 reply; 21+ messages in thread
From: Pin-yen Lin @ 2023-02-21  9:50 UTC (permalink / raw)
  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: Pin-yen Lin, linux-kernel, Hsin-Yi Wang, Marek Vasut,
	Thomas Zimmermann, dri-devel, Xin Ji, Lyude Paul, Allen Chen,
	devicetree, AngeloGioacchino Del Regno,
	Nícolas F . R . A . Prado, chrome-platform,
	Javier Martinez Canillas, linux-acpi, Stephen Boyd,
	Douglas Anderson, Gustavo A. R. Silva, Imre Deak, Jani Nikula,
	Kees Cook

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 <treapking@chromium.org>

---

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/Makefile              |   1 +
 drivers/gpu/drm/display/drm_dp_typec_helper.c | 108 ++++++++++++++++++
 include/drm/display/drm_dp_helper.h           |  35 ++++++
 3 files changed, 144 insertions(+)
 create mode 100644 drivers/gpu/drm/display/drm_dp_typec_helper.c

diff --git a/drivers/gpu/drm/display/Makefile b/drivers/gpu/drm/display/Makefile
index 17ac4a1006a8..ef80b9fde615 100644
--- a/drivers/gpu/drm/display/Makefile
+++ b/drivers/gpu/drm/display/Makefile
@@ -14,5 +14,6 @@ drm_display_helper-$(CONFIG_DRM_DISPLAY_HDMI_HELPER) += \
 	drm_scdc_helper.o
 drm_display_helper-$(CONFIG_DRM_DP_AUX_CHARDEV) += drm_dp_aux_dev.o
 drm_display_helper-$(CONFIG_DRM_DP_CEC) += drm_dp_cec.o
+drm_display_helper-$(CONFIG_TYPEC) += drm_dp_typec_helper.o
 
 obj-$(CONFIG_DRM_DISPLAY_HELPER) += drm_display_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..161e4110f6b9
--- /dev/null
+++ b/drivers/gpu/drm/display/drm_dp_typec_helper.c
@@ -0,0 +1,108 @@
+// SPDX-License-Identifier: GPL-2.0
+
+#include <linux/usb/typec_mux.h>
+#include <drm/display/drm_dp_helper.h>
+
+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);
+	if (IS_ERR(port_data->typec_mux)) {
+		ret = PTR_ERR(port_data->typec_mux);
+		dev_err(dev, "Mode switch register for port %d failed: %d\n",
+			port_num, ret);
+		return ret;
+	}
+
+	return 0;
+}
+
+/**
+ * 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.
+ *
+ * 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;
+
+	fwnode_for_each_typec_mode_switch(port, sw)
+		switch_desc->num_typec_switches++;
+
+	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. */
+	fwnode_for_each_typec_mode_switch(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)
+{
+	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..d2ac4be09c8e 100644
--- a/include/drm/display/drm_dp_helper.h
+++ b/include/drm/display/drm_dp_helper.h
@@ -25,6 +25,7 @@
 
 #include <linux/delay.h>
 #include <linux/i2c.h>
+#include <linux/usb/typec_mux.h>
 
 #include <drm/display/drm_dp.h>
 #include <drm/drm_connector.h>
@@ -763,4 +764,38 @@ 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 fwnode_for_each_typec_mode_switch(port, sw)	\
+	fwnode_for_each_child_node((port), (sw))	\
+		for_each_if(fwnode_property_present((sw), "mode-switch"))
+
+#if IS_REACHABLE(CONFIG_TYPEC)
+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_ */
-- 
2.39.2.637.g21b0678d19-goog


^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH v12 04/10] dt-bindings: display: bridge: anx7625: Add mode-switch support
  2023-02-21  9:50 [PATCH v12 00/10] Register Type-C mode-switch in DP bridge endpoints Pin-yen Lin
                   ` (2 preceding siblings ...)
  2023-02-21  9:50 ` [PATCH v12 03/10] drm/display: Add Type-C switch helpers Pin-yen Lin
@ 2023-02-21  9:50 ` Pin-yen Lin
  2023-02-21  9:50 ` [PATCH v12 05/10] drm/bridge: anx7625: Check for Type-C during panel registration Pin-yen Lin
                   ` (5 subsequent siblings)
  9 siblings, 0 replies; 21+ messages in thread
From: Pin-yen Lin @ 2023-02-21  9:50 UTC (permalink / raw)
  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: Pin-yen Lin, linux-kernel, Hsin-Yi Wang, Marek Vasut,
	Thomas Zimmermann, dri-devel, Xin Ji, Lyude Paul, Allen Chen,
	devicetree, AngeloGioacchino Del Regno,
	Nícolas F . R . A . Prado, chrome-platform,
	Javier Martinez Canillas, linux-acpi, Stephen Boyd,
	Krzysztof Kozlowski, Chen-Yu Tsai

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 <treapking@chromium.org>
Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
Reviewed-by: Chen-Yu Tsai <wenst@chromium.org>
Tested-by: Chen-Yu Tsai <wenst@chromium.org>
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>

---

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>;
+                    };
+                };
+            };
+        };
+    };
-- 
2.39.2.637.g21b0678d19-goog


^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH v12 05/10] drm/bridge: anx7625: Check for Type-C during panel registration
  2023-02-21  9:50 [PATCH v12 00/10] Register Type-C mode-switch in DP bridge endpoints Pin-yen Lin
                   ` (3 preceding siblings ...)
  2023-02-21  9:50 ` [PATCH v12 04/10] dt-bindings: display: bridge: anx7625: Add mode-switch support Pin-yen Lin
@ 2023-02-21  9:50 ` Pin-yen Lin
  2023-02-21 11:50   ` Andy Shevchenko
  2023-02-21  9:50 ` [PATCH v12 06/10] drm/bridge: Remove redundant i2c_client in anx7625/it6505 Pin-yen Lin
                   ` (4 subsequent siblings)
  9 siblings, 1 reply; 21+ messages in thread
From: Pin-yen Lin @ 2023-02-21  9:50 UTC (permalink / raw)
  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: Pin-yen Lin, linux-kernel, Hsin-Yi Wang, Marek Vasut,
	Thomas Zimmermann, dri-devel, Xin Ji, Lyude Paul, Allen Chen,
	devicetree, AngeloGioacchino Del Regno,
	Nícolas F . R . A . Prado, chrome-platform,
	Javier Martinez Canillas, linux-acpi, Stephen Boyd

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 <treapking@chromium.org>

---

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 | 13 ++++++++++++-
 1 file changed, 12 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/bridge/analogix/anx7625.c b/drivers/gpu/drm/bridge/analogix/anx7625.c
index 6846199a2ee1..486b5099f5dd 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;
+	struct fwnode_handle *fwnode;
 	int bus_type, mipi_lanes;
 
 	anx7625_get_swing_setting(dev, pdata);
@@ -1687,6 +1688,16 @@ 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);
+	fwnode_for_each_typec_mode_switch(&port_node->fwnode, fwnode) {
+		fwnode_handle_put(fwnode);
+		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) {
-- 
2.39.2.637.g21b0678d19-goog


^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH v12 06/10] drm/bridge: Remove redundant i2c_client in anx7625/it6505
  2023-02-21  9:50 [PATCH v12 00/10] Register Type-C mode-switch in DP bridge endpoints Pin-yen Lin
                   ` (4 preceding siblings ...)
  2023-02-21  9:50 ` [PATCH v12 05/10] drm/bridge: anx7625: Check for Type-C during panel registration Pin-yen Lin
@ 2023-02-21  9:50 ` Pin-yen Lin
  2023-02-21 11:37   ` Andy Shevchenko
  2023-02-22  4:56   ` Pin-yen Lin
  2023-02-21  9:50 ` [PATCH v12 07/10] drm/bridge: anx7625: Register Type C mode switches Pin-yen Lin
                   ` (3 subsequent siblings)
  9 siblings, 2 replies; 21+ messages in thread
From: Pin-yen Lin @ 2023-02-21  9:50 UTC (permalink / raw)
  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: Pin-yen Lin, linux-kernel, Hsin-Yi Wang, Marek Vasut,
	Thomas Zimmermann, dri-devel, Xin Ji, Lyude Paul, Allen Chen,
	devicetree, AngeloGioacchino Del Regno,
	Nícolas F . R . A . Prado, chrome-platform,
	Javier Martinez Canillas, linux-acpi, Stephen Boyd

These two drivers embed a i2c_client in there 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 <treapking@chromium.org>
---

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 486b5099f5dd..cd628a2e2e50 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);
@@ -1739,7 +1739,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;
 
@@ -1765,7 +1765,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;
@@ -1801,7 +1801,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");
 
@@ -2010,7 +2010,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);
@@ -2046,7 +2046,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",
@@ -2099,7 +2099,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!");
@@ -2126,7 +2126,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");
@@ -2171,7 +2171,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))
@@ -2215,7 +2215,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");
 
@@ -2236,7 +2236,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");
 
@@ -2282,7 +2282,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;
@@ -2400,7 +2400,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");
 
@@ -2414,7 +2414,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");
@@ -2441,7 +2441,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");
 
@@ -2455,7 +2455,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");
 
@@ -2466,7 +2466,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");
 
@@ -2491,7 +2491,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);
@@ -2592,7 +2592,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 */
-- 
2.39.2.637.g21b0678d19-goog


^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH v12 07/10] drm/bridge: anx7625: Register Type C mode switches
  2023-02-21  9:50 [PATCH v12 00/10] Register Type-C mode-switch in DP bridge endpoints Pin-yen Lin
                   ` (5 preceding siblings ...)
  2023-02-21  9:50 ` [PATCH v12 06/10] drm/bridge: Remove redundant i2c_client in anx7625/it6505 Pin-yen Lin
@ 2023-02-21  9:50 ` Pin-yen Lin
  2023-02-21 11:36   ` Andy Shevchenko
  2023-02-21  9:50 ` [PATCH v12 08/10] dt-bindings: display: bridge: it6505: Add mode-switch support Pin-yen Lin
                   ` (2 subsequent siblings)
  9 siblings, 1 reply; 21+ messages in thread
From: Pin-yen Lin @ 2023-02-21  9:50 UTC (permalink / raw)
  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: Pin-yen Lin, linux-kernel, Hsin-Yi Wang, Marek Vasut,
	Thomas Zimmermann, dri-devel, Xin Ji, Lyude Paul, Allen Chen,
	devicetree, AngeloGioacchino Del Regno,
	Nícolas F . R . A . Prado, chrome-platform,
	Javier Martinez Canillas, linux-acpi, Stephen Boyd,
	Uwe Kleine-König

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 <treapking@chromium.org>

---

Changes in v12:
- Fixed style issues in anx7625 driver
- Fixed the inverted orientation setting in anx7625 driver
- Changed "&ctx->client->dev" to "ctx->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
- 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 cd628a2e2e50..62133aba0f8c 100644
--- a/drivers/gpu/drm/bridge/analogix/anx7625.c
+++ b/drivers/gpu/drm/bridge/analogix/anx7625.c
@@ -15,6 +15,8 @@
 #include <linux/regulator/consumer.h>
 #include <linux/slab.h>
 #include <linux/types.h>
+#include <linux/usb/typec_dp.h>
+#include <linux/usb/typec_mux.h>
 #include <linux/workqueue.h>
 
 #include <linux/of_gpio.h>
@@ -2571,6 +2573,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)
+{
+	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;
+
+		num_lanes = fwnode_property_count_u32(fwnode, "data-lanes");
+
+		if (num_lanes < 0) {
+			dev_err(dev,
+				"Error on getting data lanes count from %pfwP: %d\n",
+				fwnode, num_lanes);
+			ret = num_lanes;
+			goto unregister_mux;
+		}
+
+		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 == 0) ?
+			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;
@@ -2608,6 +2749,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");
@@ -2678,6 +2820,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))
@@ -2729,6 +2875,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__ */
-- 
2.39.2.637.g21b0678d19-goog


^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH v12 08/10] dt-bindings: display: bridge: it6505: Add mode-switch support
  2023-02-21  9:50 [PATCH v12 00/10] Register Type-C mode-switch in DP bridge endpoints Pin-yen Lin
                   ` (6 preceding siblings ...)
  2023-02-21  9:50 ` [PATCH v12 07/10] drm/bridge: anx7625: Register Type C mode switches Pin-yen Lin
@ 2023-02-21  9:50 ` Pin-yen Lin
  2023-02-21  9:50 ` [PATCH v12 09/10] drm/bridge: it6505: Fix Kconfig indentation Pin-yen Lin
  2023-02-21  9:50 ` [PATCH v12 10/10] drm/bridge: it6505: Register Type C mode switches Pin-yen Lin
  9 siblings, 0 replies; 21+ messages in thread
From: Pin-yen Lin @ 2023-02-21  9:50 UTC (permalink / raw)
  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: Pin-yen Lin, linux-kernel, Hsin-Yi Wang, Marek Vasut,
	Thomas Zimmermann, dri-devel, Xin Ji, Lyude Paul, Allen Chen,
	devicetree, AngeloGioacchino Del Regno,
	Nícolas F . R . A . Prado, chrome-platform,
	Javier Martinez Canillas, linux-acpi, Stephen Boyd

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 <treapking@chromium.org>

---

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 <dt-bindings/interrupt-controller/irq.h>
+
+    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>;
+                    };
+                };
+            };
+        };
+    };
-- 
2.39.2.637.g21b0678d19-goog


^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH v12 09/10] drm/bridge: it6505: Fix Kconfig indentation
  2023-02-21  9:50 [PATCH v12 00/10] Register Type-C mode-switch in DP bridge endpoints Pin-yen Lin
                   ` (7 preceding siblings ...)
  2023-02-21  9:50 ` [PATCH v12 08/10] dt-bindings: display: bridge: it6505: Add mode-switch support Pin-yen Lin
@ 2023-02-21  9:50 ` Pin-yen Lin
  2023-02-21  9:50 ` [PATCH v12 10/10] drm/bridge: it6505: Register Type C mode switches Pin-yen Lin
  9 siblings, 0 replies; 21+ messages in thread
From: Pin-yen Lin @ 2023-02-21  9:50 UTC (permalink / raw)
  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: Pin-yen Lin, linux-kernel, Hsin-Yi Wang, Marek Vasut,
	Thomas Zimmermann, dri-devel, Xin Ji, Lyude Paul, Allen Chen,
	devicetree, AngeloGioacchino Del Regno,
	Nícolas F . R . A . Prado, chrome-platform,
	Javier Martinez Canillas, linux-acpi, Stephen Boyd

Replace the spaces with tab characters in the Kconfig file.

Signed-off-by: Pin-yen Lin <treapking@chromium.org>
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>

---

(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"
-- 
2.39.2.637.g21b0678d19-goog


^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH v12 10/10] drm/bridge: it6505: Register Type C mode switches
  2023-02-21  9:50 [PATCH v12 00/10] Register Type-C mode-switch in DP bridge endpoints Pin-yen Lin
                   ` (8 preceding siblings ...)
  2023-02-21  9:50 ` [PATCH v12 09/10] drm/bridge: it6505: Fix Kconfig indentation Pin-yen Lin
@ 2023-02-21  9:50 ` Pin-yen Lin
  2023-02-21 11:54   ` Andy Shevchenko
  9 siblings, 1 reply; 21+ messages in thread
From: Pin-yen Lin @ 2023-02-21  9:50 UTC (permalink / raw)
  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: Pin-yen Lin, linux-kernel, Hsin-Yi Wang, Marek Vasut,
	Thomas Zimmermann, dri-devel, Xin Ji, Lyude Paul, Allen Chen,
	devicetree, AngeloGioacchino Del Regno,
	Nícolas F . R . A . Prado, chrome-platform,
	Javier Martinez Canillas, linux-acpi, Stephen Boyd

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 <treapking@chromium.org>

---

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 | 186 +++++++++++++++++++++++++++-
 1 file changed, 182 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/bridge/ite-it6505.c b/drivers/gpu/drm/bridge/ite-it6505.c
index d4bc388b68ac..6c03a853a876 100644
--- a/drivers/gpu/drm/bridge/ite-it6505.c
+++ b/drivers/gpu/drm/bridge/ite-it6505.c
@@ -17,6 +17,8 @@
 #include <linux/regmap.h>
 #include <linux/regulator/consumer.h>
 #include <linux/types.h>
+#include <linux/usb/typec_dp.h>
+#include <linux/usb/typec_mux.h>
 #include <linux/wait.h>
 
 #include <crypto/hash.h>
@@ -27,6 +29,7 @@
 #include <drm/drm_bridge.h>
 #include <drm/drm_crtc.h>
 #include <drm/drm_edid.h>
+#include <drm/drm_of.h>
 #include <drm/drm_print.h>
 #include <drm/drm_probe_helper.h>
 
@@ -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,164 @@ static void it6505_shutdown(struct i2c_client *client)
 		it6505_lane_off(it6505);
 }
 
+static void it6505_typec_ports_update(struct it6505 *it6505)
+{
+	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;
+
+		num_lanes = fwnode_property_count_u32(fwnode, "data-lanes");
+
+		if (num_lanes < 0) {
+			dev_err(dev,
+				"Error on getting data lanes count from %pfwP: %d\n",
+				fwnode, num_lanes);
+			ret = num_lanes;
+			goto unregister_mux;
+		}
+
+		if (num_lanes > 2) {
+			dev_err(dev,
+				"Invalid data lanes count for mode switches from %pfwP: %d\n",
+				fwnode, num_lanes);
+			ret = -EINVAL;
+			goto unregister_mux;
+		}
+
+		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 == 1);
+	}
+	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)
@@ -3370,11 +3533,25 @@ static int it6505_i2c_probe(struct i2c_client *client)
 	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);
+		if (PTR_ERR(extcon) != -ENODEV)
+			dev_warn(dev, "Cannot get extcon device: %ld\n",
+				 PTR_ERR(extcon));
+		it6505->extcon = NULL;
+	} else {
+		it6505->extcon = extcon;
 	}
 
-	it6505->extcon = extcon;
+	init_completion(&it6505->mux_register);
+	ret = it6505_register_typec_switches(dev, it6505);
+	if (ret) {
+		if (ret != -ENODEV)
+			dev_warn(dev, "Didn't register Type-C switches, err: %d\n",
+				 ret);
+		if (!it6505->extcon) {
+			dev_err(dev, "Both extcon and typec-switch are not registered.\n");
+			return -EINVAL;
+		}
+	}
 
 	it6505->regmap = devm_regmap_init_i2c(client, &it6505_regmap_config);
 	if (IS_ERR(it6505->regmap)) {
@@ -3446,6 +3623,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[] = {
-- 
2.39.2.637.g21b0678d19-goog


^ permalink raw reply related	[flat|nested] 21+ messages in thread

* Re: [PATCH v12 01/10] device property: Add remote endpoint to devcon matcher
  2023-02-21  9:50 ` [PATCH v12 01/10] device property: Add remote endpoint to devcon matcher Pin-yen Lin
@ 2023-02-21 11:26   ` Andy Shevchenko
  0 siblings, 0 replies; 21+ messages in thread
From: Andy Shevchenko @ 2023-02-21 11:26 UTC (permalink / raw)
  To: Pin-yen Lin
  Cc: Andrzej Hajda, Neil Armstrong, Robert Foss, Laurent Pinchart,
	Jonas Karlman, Jernej Skrabec, David Airlie, Daniel Vetter,
	Rob Herring, Krzysztof Kozlowski, Daniel Scally, Heikki Krogerus,
	Sakari Ailus, Greg Kroah-Hartman, Rafael J . Wysocki,
	Prashant Malani, Benson Leung, Guenter Roeck, linux-kernel,
	Hsin-Yi Wang, Marek Vasut, Thomas Zimmermann, dri-devel, Xin Ji,
	Lyude Paul, Allen Chen, devicetree, AngeloGioacchino Del Regno,
	Nícolas F . R . A . Prado, chrome-platform,
	Javier Martinez Canillas, linux-acpi, Stephen Boyd

On Tue, Feb 21, 2023 at 05:50:45PM +0800, Pin-yen Lin wrote:
> From: Prashant Malani <pmalani@chromium.org>
> 
> 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.

...

>   * @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.
>   */

Please add a Return: section at the end of the kernel doc.
Otherwise it complains that there is none.

...

>   * @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.

Ditto.

-- 
With Best Regards,
Andy Shevchenko



^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH v12 07/10] drm/bridge: anx7625: Register Type C mode switches
  2023-02-21  9:50 ` [PATCH v12 07/10] drm/bridge: anx7625: Register Type C mode switches Pin-yen Lin
@ 2023-02-21 11:36   ` Andy Shevchenko
  2023-02-22  5:05     ` Pin-yen Lin
  0 siblings, 1 reply; 21+ messages in thread
From: Andy Shevchenko @ 2023-02-21 11:36 UTC (permalink / raw)
  To: Pin-yen Lin
  Cc: Andrzej Hajda, Neil Armstrong, Robert Foss, Laurent Pinchart,
	Jonas Karlman, Jernej Skrabec, David Airlie, Daniel Vetter,
	Rob Herring, Krzysztof Kozlowski, Daniel Scally, Heikki Krogerus,
	Sakari Ailus, Greg Kroah-Hartman, Rafael J . Wysocki,
	Prashant Malani, Benson Leung, Guenter Roeck, linux-kernel,
	Hsin-Yi Wang, Marek Vasut, Thomas Zimmermann, dri-devel, Xin Ji,
	Lyude Paul, Allen Chen, devicetree, AngeloGioacchino Del Regno,
	Nícolas F . R . A . Prado, chrome-platform,
	Javier Martinez Canillas, linux-acpi, Stephen Boyd,
	Uwe Kleine-König

On Tue, Feb 21, 2023 at 05:50:51PM +0800, Pin-yen Lin wrote:
> 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.

...

> +static void anx7625_typec_two_ports_update(struct anx7625_data *ctx)
> +{
> +	int i;

unsigned?

+ Blank line.

> +	/* 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);
> +	}
> +}

...

> +	ctx->port_data[port->port_num].dp_connected =
> +		state->alt && state->alt->svid == USB_TYPEC_DP_SID &&

I would move the first parameter of && to the separate line for slightly better
readability.

> +		state->alt->mode == USB_TYPEC_DP_MODE;

...

> +	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;
> +
> +		num_lanes = fwnode_property_count_u32(fwnode, "data-lanes");

> +

Redundant blank line.

> +		if (num_lanes < 0) {
> +			dev_err(dev,
> +				"Error on getting data lanes count from %pfwP: %d\n",
> +				fwnode, num_lanes);

> +			ret = num_lanes;

Can be written differently:

> +			goto unregister_mux;
> +		}

		ret = ...
		if (ret < 0) {
			...
		}
		num_lanes = ret;


What if it's 0?

> +		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 == 0) ?
> +			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;
> +}

-- 
With Best Regards,
Andy Shevchenko



^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH v12 06/10] drm/bridge: Remove redundant i2c_client in anx7625/it6505
  2023-02-21  9:50 ` [PATCH v12 06/10] drm/bridge: Remove redundant i2c_client in anx7625/it6505 Pin-yen Lin
@ 2023-02-21 11:37   ` Andy Shevchenko
  2023-02-22  4:56   ` Pin-yen Lin
  1 sibling, 0 replies; 21+ messages in thread
From: Andy Shevchenko @ 2023-02-21 11:37 UTC (permalink / raw)
  To: Pin-yen Lin
  Cc: Andrzej Hajda, Neil Armstrong, Robert Foss, Laurent Pinchart,
	Jonas Karlman, Jernej Skrabec, David Airlie, Daniel Vetter,
	Rob Herring, Krzysztof Kozlowski, Daniel Scally, Heikki Krogerus,
	Sakari Ailus, Greg Kroah-Hartman, Rafael J . Wysocki,
	Prashant Malani, Benson Leung, Guenter Roeck, linux-kernel,
	Hsin-Yi Wang, Marek Vasut, Thomas Zimmermann, dri-devel, Xin Ji,
	Lyude Paul, Allen Chen, devicetree, AngeloGioacchino Del Regno,
	Nícolas F . R . A . Prado, chrome-platform,
	Javier Martinez Canillas, linux-acpi, Stephen Boyd

On Tue, Feb 21, 2023 at 05:50:50PM +0800, Pin-yen Lin wrote:
> These two drivers embed a i2c_client in there private driver data, but
> only strict device is actually needed. Replace the i2c_client reference
> with a struct device one.

LGTM,
Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>

> Signed-off-by: Pin-yen Lin <treapking@chromium.org>
> ---
> 
> 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 486b5099f5dd..cd628a2e2e50 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);
> @@ -1739,7 +1739,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;
>  
> @@ -1765,7 +1765,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;
> @@ -1801,7 +1801,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");
>  
> @@ -2010,7 +2010,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);
> @@ -2046,7 +2046,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",
> @@ -2099,7 +2099,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!");
> @@ -2126,7 +2126,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");
> @@ -2171,7 +2171,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))
> @@ -2215,7 +2215,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");
>  
> @@ -2236,7 +2236,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");
>  
> @@ -2282,7 +2282,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;
> @@ -2400,7 +2400,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");
>  
> @@ -2414,7 +2414,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");
> @@ -2441,7 +2441,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");
>  
> @@ -2455,7 +2455,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");
>  
> @@ -2466,7 +2466,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");
>  
> @@ -2491,7 +2491,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);
> @@ -2592,7 +2592,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 */
> -- 
> 2.39.2.637.g21b0678d19-goog
> 

-- 
With Best Regards,
Andy Shevchenko



^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH v12 03/10] drm/display: Add Type-C switch helpers
  2023-02-21  9:50 ` [PATCH v12 03/10] drm/display: Add Type-C switch helpers Pin-yen Lin
@ 2023-02-21 11:48   ` Andy Shevchenko
  2023-02-22  8:53     ` Pin-yen Lin
  0 siblings, 1 reply; 21+ messages in thread
From: Andy Shevchenko @ 2023-02-21 11:48 UTC (permalink / raw)
  To: Pin-yen Lin
  Cc: Andrzej Hajda, Neil Armstrong, Robert Foss, Laurent Pinchart,
	Jonas Karlman, Jernej Skrabec, David Airlie, Daniel Vetter,
	Rob Herring, Krzysztof Kozlowski, Daniel Scally, Heikki Krogerus,
	Sakari Ailus, Greg Kroah-Hartman, Rafael J . Wysocki,
	Prashant Malani, Benson Leung, Guenter Roeck, linux-kernel,
	Hsin-Yi Wang, Marek Vasut, Thomas Zimmermann, dri-devel, Xin Ji,
	Lyude Paul, Allen Chen, devicetree, AngeloGioacchino Del Regno,
	Nícolas F . R . A . Prado, chrome-platform,
	Javier Martinez Canillas, linux-acpi, Stephen Boyd,
	Douglas Anderson, Gustavo A. R. Silva, Imre Deak, Jani Nikula,
	Kees Cook

On Tue, Feb 21, 2023 at 05:50:47PM +0800, Pin-yen Lin wrote:
> 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 <treapking@chromium.org>

...

> +	fwnode_for_each_typec_mode_switch(port, sw)
> +		switch_desc->num_typec_switches++;
> +
> +	if (!switch_desc->num_typec_switches) {
> +		dev_dbg(dev, "No Type-C switches node found\n");
> +		return 0;
> +	}

What about

static inline unsigned int typec_mode_switch_node_count(... *port)
{
	... *sw;
	unsigned int count = 0;

	for_each_typec_mode_switch_node(port, sw)
		count++;

	return count;
}


And then it seems something like

	unsigned int count;

	count = typec_mode_switch_node_count(port);
	if (!count) {
		...
	}

	_switches = count;

...

> +	switch_desc->typec_ports = devm_kcalloc(
> +		dev, switch_desc->num_typec_switches,

Strange indentation.

> +		sizeof(struct drm_dp_typec_port_data), GFP_KERNEL);

> +

Redundant blank line.

> +	if (!switch_desc->typec_ports)
> +		return -ENOMEM;

...

> +void drm_dp_unregister_typec_switches(struct drm_dp_typec_switch_desc *switch_desc)
> +{
> +	int i;

unsigned?

> +	for (i = 0; i < switch_desc->num_typec_switches; i++)
> +		typec_mux_unregister(switch_desc->typec_ports[i].typec_mux);
> +}

...

>  #include <linux/delay.h>
>  #include <linux/i2c.h>
> +#include <linux/usb/typec_mux.h>

I don't see users of this.
But a few forward declarations are missing.

>  #include <drm/display/drm_dp.h>
>  #include <drm/drm_connector.h>

...

> +#define fwnode_for_each_typec_mode_switch(port, sw)	\
> +	fwnode_for_each_child_node((port), (sw))	\
> +		for_each_if(fwnode_property_present((sw), "mode-switch"))

Please don't use fwnode namespace (see above), something like

#define for_each_typec_mode_switch_node(port, sw)	\
	...

-- 
With Best Regards,
Andy Shevchenko



^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH v12 05/10] drm/bridge: anx7625: Check for Type-C during panel registration
  2023-02-21  9:50 ` [PATCH v12 05/10] drm/bridge: anx7625: Check for Type-C during panel registration Pin-yen Lin
@ 2023-02-21 11:50   ` Andy Shevchenko
  0 siblings, 0 replies; 21+ messages in thread
From: Andy Shevchenko @ 2023-02-21 11:50 UTC (permalink / raw)
  To: Pin-yen Lin
  Cc: Andrzej Hajda, Neil Armstrong, Robert Foss, Laurent Pinchart,
	Jonas Karlman, Jernej Skrabec, David Airlie, Daniel Vetter,
	Rob Herring, Krzysztof Kozlowski, Daniel Scally, Heikki Krogerus,
	Sakari Ailus, Greg Kroah-Hartman, Rafael J . Wysocki,
	Prashant Malani, Benson Leung, Guenter Roeck, linux-kernel,
	Hsin-Yi Wang, Marek Vasut, Thomas Zimmermann, dri-devel, Xin Ji,
	Lyude Paul, Allen Chen, devicetree, AngeloGioacchino Del Regno,
	Nícolas F . R . A . Prado, chrome-platform,
	Javier Martinez Canillas, linux-acpi, Stephen Boyd

On Tue, Feb 21, 2023 at 05:50:49PM +0800, Pin-yen Lin wrote:
> 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.

...

> +	port_node = of_graph_get_port_by_id(np, 1);
> +	fwnode_for_each_typec_mode_switch(&port_node->fwnode, fwnode) {
> +		fwnode_handle_put(fwnode);
> +		return 0;
> +	}

With the proposed count API:

	unsigned int count;
	...
	port_node = ...
	count = typec_mode_switch_node_count(&port_node->fwnode);
	if (count == 0)
		return 0;

-- 
With Best Regards,
Andy Shevchenko



^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH v12 10/10] drm/bridge: it6505: Register Type C mode switches
  2023-02-21  9:50 ` [PATCH v12 10/10] drm/bridge: it6505: Register Type C mode switches Pin-yen Lin
@ 2023-02-21 11:54   ` Andy Shevchenko
  0 siblings, 0 replies; 21+ messages in thread
From: Andy Shevchenko @ 2023-02-21 11:54 UTC (permalink / raw)
  To: Pin-yen Lin
  Cc: Andrzej Hajda, Neil Armstrong, Robert Foss, Laurent Pinchart,
	Jonas Karlman, Jernej Skrabec, David Airlie, Daniel Vetter,
	Rob Herring, Krzysztof Kozlowski, Daniel Scally, Heikki Krogerus,
	Sakari Ailus, Greg Kroah-Hartman, Rafael J . Wysocki,
	Prashant Malani, Benson Leung, Guenter Roeck, linux-kernel,
	Hsin-Yi Wang, Marek Vasut, Thomas Zimmermann, dri-devel, Xin Ji,
	Lyude Paul, Allen Chen, devicetree, AngeloGioacchino Del Regno,
	Nícolas F . R . A . Prado, chrome-platform,
	Javier Martinez Canillas, linux-acpi, Stephen Boyd

On Tue, Feb 21, 2023 at 05:50:54PM +0800, Pin-yen Lin wrote:
> 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.

...

> +static void it6505_typec_ports_update(struct it6505 *it6505)
> +{
> +	int i;

unsigned?

(and just note that here you have already blank line which is good)

> +	/* 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;
> +	}
> +}


,,,

> +	it6505->port_data[port->port_num].dp_connected =
> +		state->alt && state->alt->svid == USB_TYPEC_DP_SID &&
> +		state->alt->mode == USB_TYPEC_DP_MODE;

Split first parameter?

...

> +	it6505->port_data = devm_kcalloc(
> +		dev, switch_desc->num_typec_switches,

Strange indentation.

> +		sizeof(struct it6505_typec_port_data), GFP_KERNEL);

> +

Redundant blank line.

> +	if (!it6505->port_data) {
> +		ret = -ENOMEM;
> +		goto unregister_mux;
> +	}

...

> +		num_lanes = fwnode_property_count_u32(fwnode, "data-lanes");
> +
> +		if (num_lanes < 0) {
> +			dev_err(dev,
> +				"Error on getting data lanes count from %pfwP: %d\n",
> +				fwnode, num_lanes);
> +			ret = num_lanes;
> +			goto unregister_mux;
> +		}

Same two comments as per previous patch of similar semantics.

-- 
With Best Regards,
Andy Shevchenko



^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH v12 06/10] drm/bridge: Remove redundant i2c_client in anx7625/it6505
  2023-02-21  9:50 ` [PATCH v12 06/10] drm/bridge: Remove redundant i2c_client in anx7625/it6505 Pin-yen Lin
  2023-02-21 11:37   ` Andy Shevchenko
@ 2023-02-22  4:56   ` Pin-yen Lin
  1 sibling, 0 replies; 21+ messages in thread
From: Pin-yen Lin @ 2023-02-22  4:56 UTC (permalink / raw)
  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: linux-kernel, Hsin-Yi Wang, Marek Vasut, Thomas Zimmermann,
	dri-devel, Xin Ji, Lyude Paul, Allen Chen, devicetree,
	AngeloGioacchino Del Regno, Nícolas F . R . A . Prado,
	chrome-platform, Javier Martinez Canillas, linux-acpi,
	Stephen Boyd

On Tue, Feb 21, 2023 at 5:51 PM Pin-yen Lin <treapking@chromium.org> wrote:
>
> These two drivers embed a i2c_client in there private driver data, but

This should be "their private driver data".  I'll fix this in the next version.

Pin-yen

> only strict device is actually needed. Replace the i2c_client reference
> with a struct device one.
>
> Signed-off-by: Pin-yen Lin <treapking@chromium.org>
> ---
>
> 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 486b5099f5dd..cd628a2e2e50 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);
> @@ -1739,7 +1739,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;
>
> @@ -1765,7 +1765,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;
> @@ -1801,7 +1801,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");
>
> @@ -2010,7 +2010,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);
> @@ -2046,7 +2046,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",
> @@ -2099,7 +2099,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!");
> @@ -2126,7 +2126,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");
> @@ -2171,7 +2171,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))
> @@ -2215,7 +2215,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");
>
> @@ -2236,7 +2236,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");
>
> @@ -2282,7 +2282,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;
> @@ -2400,7 +2400,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");
>
> @@ -2414,7 +2414,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");
> @@ -2441,7 +2441,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");
>
> @@ -2455,7 +2455,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");
>
> @@ -2466,7 +2466,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");
>
> @@ -2491,7 +2491,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);
> @@ -2592,7 +2592,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 */
> --
> 2.39.2.637.g21b0678d19-goog
>

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH v12 07/10] drm/bridge: anx7625: Register Type C mode switches
  2023-02-21 11:36   ` Andy Shevchenko
@ 2023-02-22  5:05     ` Pin-yen Lin
  0 siblings, 0 replies; 21+ messages in thread
From: Pin-yen Lin @ 2023-02-22  5:05 UTC (permalink / raw)
  To: Andy Shevchenko
  Cc: Andrzej Hajda, Neil Armstrong, Robert Foss, Laurent Pinchart,
	Jonas Karlman, Jernej Skrabec, David Airlie, Daniel Vetter,
	Rob Herring, Krzysztof Kozlowski, Daniel Scally, Heikki Krogerus,
	Sakari Ailus, Greg Kroah-Hartman, Rafael J . Wysocki,
	Prashant Malani, Benson Leung, Guenter Roeck, linux-kernel,
	Hsin-Yi Wang, Marek Vasut, Thomas Zimmermann, dri-devel, Xin Ji,
	Lyude Paul, Allen Chen, devicetree, AngeloGioacchino Del Regno,
	Nícolas F . R . A . Prado, chrome-platform,
	Javier Martinez Canillas, linux-acpi, Stephen Boyd,
	Uwe Kleine-König

Hi Andy,

Thanks for the review.

On Tue, Feb 21, 2023 at 7:36 PM Andy Shevchenko
<andriy.shevchenko@linux.intel.com> wrote:
>
> On Tue, Feb 21, 2023 at 05:50:51PM +0800, Pin-yen Lin wrote:
> > 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.
>
> ...
>
> > +static void anx7625_typec_two_ports_update(struct anx7625_data *ctx)
> > +{
> > +     int i;
>
> unsigned?
>
> + Blank line.
>
> > +     /* 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);
> > +     }
> > +}
>
> ...
>
> > +     ctx->port_data[port->port_num].dp_connected =
> > +             state->alt && state->alt->svid == USB_TYPEC_DP_SID &&
>
> I would move the first parameter of && to the separate line for slightly better
> readability.
>
> > +             state->alt->mode == USB_TYPEC_DP_MODE;
>
> ...
>
> > +     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;
> > +
> > +             num_lanes = fwnode_property_count_u32(fwnode, "data-lanes");
>
> > +
>
> Redundant blank line.
>
> > +             if (num_lanes < 0) {
> > +                     dev_err(dev,
> > +                             "Error on getting data lanes count from %pfwP: %d\n",
> > +                             fwnode, num_lanes);
>
> > +                     ret = num_lanes;
>
> Can be written differently:
>
> > +                     goto unregister_mux;
> > +             }
>
>                 ret = ...
>                 if (ret < 0) {
>                         ...
>                 }
>                 num_lanes = ret;
>
>
> What if it's 0?

The binding does not allow that, so I don't think we should check it here.

I'll address other comments in the next version.

Regards,
Pin-yen
>
> > +             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 == 0) ?
> > +                     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;
> > +}
>
> --
> With Best Regards,
> Andy Shevchenko
>
>

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH v12 03/10] drm/display: Add Type-C switch helpers
  2023-02-21 11:48   ` Andy Shevchenko
@ 2023-02-22  8:53     ` Pin-yen Lin
  2023-02-22 14:08       ` Andy Shevchenko
  0 siblings, 1 reply; 21+ messages in thread
From: Pin-yen Lin @ 2023-02-22  8:53 UTC (permalink / raw)
  To: Andy Shevchenko
  Cc: Andrzej Hajda, Neil Armstrong, Robert Foss, Laurent Pinchart,
	Jonas Karlman, Jernej Skrabec, David Airlie, Daniel Vetter,
	Rob Herring, Krzysztof Kozlowski, Daniel Scally, Heikki Krogerus,
	Sakari Ailus, Greg Kroah-Hartman, Rafael J . Wysocki,
	Prashant Malani, Benson Leung, Guenter Roeck, linux-kernel,
	Hsin-Yi Wang, Marek Vasut, Thomas Zimmermann, dri-devel, Xin Ji,
	Lyude Paul, Allen Chen, devicetree, AngeloGioacchino Del Regno,
	Nícolas F . R . A . Prado, chrome-platform,
	Javier Martinez Canillas, linux-acpi, Stephen Boyd,
	Douglas Anderson, Gustavo A. R. Silva, Imre Deak, Jani Nikula,
	Kees Cook

Hi Andy,

Thanks for the review.

On Tue, Feb 21, 2023 at 7:48 PM Andy Shevchenko
<andriy.shevchenko@linux.intel.com> wrote:
>
> On Tue, Feb 21, 2023 at 05:50:47PM +0800, Pin-yen Lin wrote:
> > 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 <treapking@chromium.org>
>
> ...
>
> > +     fwnode_for_each_typec_mode_switch(port, sw)
> > +             switch_desc->num_typec_switches++;
> > +
> > +     if (!switch_desc->num_typec_switches) {
> > +             dev_dbg(dev, "No Type-C switches node found\n");
> > +             return 0;
> > +     }
>
> What about
>
> static inline unsigned int typec_mode_switch_node_count(... *port)
> {
>         ... *sw;
>         unsigned int count = 0;
>
>         for_each_typec_mode_switch_node(port, sw)
>                 count++;
>
>         return count;
> }
>
>
> And then it seems something like
>
>         unsigned int count;
>
>         count = typec_mode_switch_node_count(port);
>         if (!count) {
>                 ...
>         }
>
>         _switches = count;
>
> ...
>
> > +     switch_desc->typec_ports = devm_kcalloc(
> > +             dev, switch_desc->num_typec_switches,
>
> Strange indentation.
>
> > +             sizeof(struct drm_dp_typec_port_data), GFP_KERNEL);
>
> > +
>
> Redundant blank line.
>
> > +     if (!switch_desc->typec_ports)
> > +             return -ENOMEM;
>
> ...
>
> > +void drm_dp_unregister_typec_switches(struct drm_dp_typec_switch_desc *switch_desc)
> > +{
> > +     int i;
>
> unsigned?
>
> > +     for (i = 0; i < switch_desc->num_typec_switches; i++)
> > +             typec_mux_unregister(switch_desc->typec_ports[i].typec_mux);
> > +}
>
> ...
>
> >  #include <linux/delay.h>
> >  #include <linux/i2c.h>
> > +#include <linux/usb/typec_mux.h>
>
> I don't see users of this.
> But a few forward declarations are missing.

I can put a `struct typec_mux_dev;` here, but there is also a usage of
typec_mux_set_fn_t.

Should I add the typedef into this header file as well?

Regards,
Pin-yen
>
> >  #include <drm/display/drm_dp.h>
> >  #include <drm/drm_connector.h>
>
> ...
>
> > +#define fwnode_for_each_typec_mode_switch(port, sw)  \
> > +     fwnode_for_each_child_node((port), (sw))        \
> > +             for_each_if(fwnode_property_present((sw), "mode-switch"))
>
> Please don't use fwnode namespace (see above), something like
>
> #define for_each_typec_mode_switch_node(port, sw)       \
>         ...
>
> --
> With Best Regards,
> Andy Shevchenko
>
>

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH v12 03/10] drm/display: Add Type-C switch helpers
  2023-02-22  8:53     ` Pin-yen Lin
@ 2023-02-22 14:08       ` Andy Shevchenko
  0 siblings, 0 replies; 21+ messages in thread
From: Andy Shevchenko @ 2023-02-22 14:08 UTC (permalink / raw)
  To: Pin-yen Lin
  Cc: Andrzej Hajda, Neil Armstrong, Robert Foss, Laurent Pinchart,
	Jonas Karlman, Jernej Skrabec, David Airlie, Daniel Vetter,
	Rob Herring, Krzysztof Kozlowski, Daniel Scally, Heikki Krogerus,
	Sakari Ailus, Greg Kroah-Hartman, Rafael J . Wysocki,
	Prashant Malani, Benson Leung, Guenter Roeck, linux-kernel,
	Hsin-Yi Wang, Marek Vasut, Thomas Zimmermann, dri-devel, Xin Ji,
	Lyude Paul, Allen Chen, devicetree, AngeloGioacchino Del Regno,
	Nícolas F . R . A . Prado, chrome-platform,
	Javier Martinez Canillas, linux-acpi, Stephen Boyd,
	Douglas Anderson, Gustavo A. R. Silva, Imre Deak, Jani Nikula,
	Kees Cook

On Wed, Feb 22, 2023 at 04:53:41PM +0800, Pin-yen Lin wrote:
> On Tue, Feb 21, 2023 at 7:48 PM Andy Shevchenko
> > On Tue, Feb 21, 2023 at 05:50:47PM +0800, Pin-yen Lin wrote:

...

> > >  #include <linux/delay.h>
> > >  #include <linux/i2c.h>
> > > +#include <linux/usb/typec_mux.h>
> >
> > I don't see users of this.
> > But a few forward declarations are missing.
> 
> I can put a `struct typec_mux_dev;` here, but there is also a usage of
> typec_mux_set_fn_t.
> 
> Should I add the typedef into this header file as well?

No, inclusion is fine, it's me who didn't notice the type in use.

-- 
With Best Regards,
Andy Shevchenko



^ permalink raw reply	[flat|nested] 21+ messages in thread

end of thread, other threads:[~2023-02-22 14:09 UTC | newest]

Thread overview: 21+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-02-21  9:50 [PATCH v12 00/10] Register Type-C mode-switch in DP bridge endpoints Pin-yen Lin
2023-02-21  9:50 ` [PATCH v12 01/10] device property: Add remote endpoint to devcon matcher Pin-yen Lin
2023-02-21 11:26   ` Andy Shevchenko
2023-02-21  9:50 ` [PATCH v12 02/10] platform/chrome: cros_ec_typec: Purge blocking switch devlinks Pin-yen Lin
2023-02-21  9:50 ` [PATCH v12 03/10] drm/display: Add Type-C switch helpers Pin-yen Lin
2023-02-21 11:48   ` Andy Shevchenko
2023-02-22  8:53     ` Pin-yen Lin
2023-02-22 14:08       ` Andy Shevchenko
2023-02-21  9:50 ` [PATCH v12 04/10] dt-bindings: display: bridge: anx7625: Add mode-switch support Pin-yen Lin
2023-02-21  9:50 ` [PATCH v12 05/10] drm/bridge: anx7625: Check for Type-C during panel registration Pin-yen Lin
2023-02-21 11:50   ` Andy Shevchenko
2023-02-21  9:50 ` [PATCH v12 06/10] drm/bridge: Remove redundant i2c_client in anx7625/it6505 Pin-yen Lin
2023-02-21 11:37   ` Andy Shevchenko
2023-02-22  4:56   ` Pin-yen Lin
2023-02-21  9:50 ` [PATCH v12 07/10] drm/bridge: anx7625: Register Type C mode switches Pin-yen Lin
2023-02-21 11:36   ` Andy Shevchenko
2023-02-22  5:05     ` Pin-yen Lin
2023-02-21  9:50 ` [PATCH v12 08/10] dt-bindings: display: bridge: it6505: Add mode-switch support Pin-yen Lin
2023-02-21  9:50 ` [PATCH v12 09/10] drm/bridge: it6505: Fix Kconfig indentation Pin-yen Lin
2023-02-21  9:50 ` [PATCH v12 10/10] drm/bridge: it6505: Register Type C mode switches Pin-yen Lin
2023-02-21 11:54   ` Andy Shevchenko

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).