2023-02-21 09:51:18

by Pin-yen Lin

[permalink] [raw]
Subject: [PATCH v12 00/10] Register Type-C mode-switch in DP bridge endpoints


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/[email protected]/
v9: https://lore.kernel.org/all/[email protected]/
v8: https://lore.kernel.org/all/[email protected]/
v7: https://lore.kernel.org/all/[email protected]/
v6: https://lore.kernel.org/all/[email protected]/
v5: https://lore.kernel.org/linux-usb/[email protected]/

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



2023-02-21 09:51:29

by Pin-yen Lin

[permalink] [raw]
Subject: [PATCH v12 01/10] device property: Add remote endpoint to devcon matcher

From: Prashant Malani <[email protected]>

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 <[email protected]>
Signed-off-by: Pin-yen Lin <[email protected]>

---

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


2023-02-21 09:51:37

by Pin-yen Lin

[permalink] [raw]
Subject: [PATCH v12 02/10] platform/chrome: cros_ec_typec: Purge blocking switch devlinks

From: Prashant Malani <[email protected]>

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 <[email protected]>
Signed-off-by: Pin-yen Lin <[email protected]>
Reviewed-by: Chen-Yu Tsai <[email protected]>
Tested-by: Chen-Yu Tsai <[email protected]>
Acked-by: Heikki Krogerus <[email protected]>

---

(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


2023-02-21 09:51:52

by Pin-yen Lin

[permalink] [raw]
Subject: [PATCH v12 03/10] drm/display: Add Type-C switch helpers

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 <[email protected]>

---

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


2023-02-21 09:52:10

by Pin-yen Lin

[permalink] [raw]
Subject: [PATCH v12 04/10] dt-bindings: display: bridge: anx7625: Add mode-switch support

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 <[email protected]>
Reviewed-by: Krzysztof Kozlowski <[email protected]>
Reviewed-by: Chen-Yu Tsai <[email protected]>
Tested-by: Chen-Yu Tsai <[email protected]>
Reviewed-by: AngeloGioacchino Del Regno <[email protected]>

---

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


2023-02-21 09:52:25

by Pin-yen Lin

[permalink] [raw]
Subject: [PATCH v12 05/10] drm/bridge: anx7625: Check for Type-C during panel registration

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 <[email protected]>

---

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


2023-02-21 09:52:30

by Pin-yen Lin

[permalink] [raw]
Subject: [PATCH v12 06/10] drm/bridge: Remove redundant i2c_client in anx7625/it6505

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 <[email protected]>
---

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


2023-02-21 09:52:53

by Pin-yen Lin

[permalink] [raw]
Subject: [PATCH v12 07/10] drm/bridge: anx7625: Register Type C mode switches

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 <[email protected]>

---

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


2023-02-21 09:52:56

by Pin-yen Lin

[permalink] [raw]
Subject: [PATCH v12 08/10] dt-bindings: display: bridge: it6505: Add mode-switch support

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 <[email protected]>

---

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


2023-02-21 09:53:09

by Pin-yen Lin

[permalink] [raw]
Subject: [PATCH v12 09/10] drm/bridge: it6505: Fix Kconfig indentation

Replace the spaces with tab characters in the Kconfig file.

Signed-off-by: Pin-yen Lin <[email protected]>
Reviewed-by: AngeloGioacchino Del Regno <[email protected]>

---

(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


2023-02-21 09:53:13

by Pin-yen Lin

[permalink] [raw]
Subject: [PATCH v12 10/10] drm/bridge: it6505: Register Type C mode switches

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 <[email protected]>

---

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


2023-02-21 11:27:54

by Andy Shevchenko

[permalink] [raw]
Subject: Re: [PATCH v12 01/10] device property: Add remote endpoint to devcon matcher

On Tue, Feb 21, 2023 at 05:50:45PM +0800, Pin-yen Lin wrote:
> From: Prashant Malani <[email protected]>
>
> 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



2023-02-21 11:37:24

by Andy Shevchenko

[permalink] [raw]
Subject: Re: [PATCH v12 07/10] drm/bridge: anx7625: Register Type C mode switches

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



2023-02-21 11:38:02

by Andy Shevchenko

[permalink] [raw]
Subject: Re: [PATCH v12 06/10] drm/bridge: Remove redundant i2c_client in anx7625/it6505

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 <[email protected]>

> Signed-off-by: Pin-yen Lin <[email protected]>
> ---
>
> 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



2023-02-21 11:48:42

by Andy Shevchenko

[permalink] [raw]
Subject: Re: [PATCH v12 03/10] drm/display: Add Type-C switch helpers

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 <[email protected]>

...

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



2023-02-21 11:51:21

by Andy Shevchenko

[permalink] [raw]
Subject: Re: [PATCH v12 05/10] drm/bridge: anx7625: Check for Type-C during panel registration

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



2023-02-21 11:55:40

by Andy Shevchenko

[permalink] [raw]
Subject: Re: [PATCH v12 10/10] drm/bridge: it6505: Register Type C mode switches

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



2023-02-22 04:56:25

by Pin-yen Lin

[permalink] [raw]
Subject: Re: [PATCH v12 06/10] drm/bridge: Remove redundant i2c_client in anx7625/it6505

On Tue, Feb 21, 2023 at 5:51 PM Pin-yen Lin <[email protected]> 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 <[email protected]>
> ---
>
> 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
>

2023-02-22 05:05:41

by Pin-yen Lin

[permalink] [raw]
Subject: Re: [PATCH v12 07/10] drm/bridge: anx7625: Register Type C mode switches

Hi Andy,

Thanks for the review.

On Tue, Feb 21, 2023 at 7:36 PM Andy Shevchenko
<[email protected]> 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
>
>

2023-02-22 08:54:00

by Pin-yen Lin

[permalink] [raw]
Subject: Re: [PATCH v12 03/10] drm/display: Add Type-C switch helpers

Hi Andy,

Thanks for the review.

On Tue, Feb 21, 2023 at 7:48 PM Andy Shevchenko
<[email protected]> 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 <[email protected]>
>
> ...
>
> > + 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
>
>

2023-02-22 14:09:43

by Andy Shevchenko

[permalink] [raw]
Subject: Re: [PATCH v12 03/10] drm/display: Add Type-C switch helpers

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