From 3370db35193b241ba5836a66df6ec1a559108389 Mon Sep 17 00:00:00 2001 From: Heikki Krogerus Date: Fri, 31 May 2019 17:15:41 +0300 Subject: usb: typec: Registering real device entries for the muxes Registering real device entries (struct device) for the mode muxes as well as for the orientation switches. The Type-C mux code was deliberately attempting to avoid creation of separate device entries for the orientation switch and the mode switch (alternate modes) because they are not physical devices. They are functions of a single physical multiplexer/demultiplexer switch device. Unfortunately because of the dependency we still have on the underlying mux device driver, we had to put in hacks like the one in the commit 3e3b81965cbf ("usb: typec: mux: Take care of driver module reference counting") to make sure the driver does not disappear from underneath us. Even with those hacks we were still left with a potential NUll pointer dereference scenario, so just creating the device entries, and letting the core take care of the dependencies. No more hacks needed. Signed-off-by: Heikki Krogerus Reviewed-by: Andy Shevchenko Tested-by: Hans de Goede Signed-off-by: Rafael J. Wysocki --- drivers/platform/x86/intel_cht_int33fe.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/platform') diff --git a/drivers/platform/x86/intel_cht_int33fe.c b/drivers/platform/x86/intel_cht_int33fe.c index 6fa3cced6f8e..657b8d61554c 100644 --- a/drivers/platform/x86/intel_cht_int33fe.c +++ b/drivers/platform/x86/intel_cht_int33fe.c @@ -173,10 +173,10 @@ static int cht_int33fe_probe(struct platform_device *pdev) } data->connections[0].endpoint[0] = "port0"; - data->connections[0].endpoint[1] = "i2c-pi3usb30532"; + data->connections[0].endpoint[1] = "i2c-pi3usb30532-switch"; data->connections[0].id = "orientation-switch"; data->connections[1].endpoint[0] = "port0"; - data->connections[1].endpoint[1] = "i2c-pi3usb30532"; + data->connections[1].endpoint[1] = "i2c-pi3usb30532-mux"; data->connections[1].id = "mode-switch"; data->connections[2].endpoint[0] = "i2c-fusb302"; data->connections[2].endpoint[1] = "intel_xhci_usb_sw-role-switch"; -- cgit v1.2.3-59-g8ed1b From d84af483033d56d466d67c1a76a0028e3be6300d Mon Sep 17 00:00:00 2001 From: Heikki Krogerus Date: Fri, 31 May 2019 17:15:42 +0300 Subject: platform/x86: intel_cht_int33fe: Register max17047 in its own function To make the probe function a bit more nicer looking, moving the registration of max17047 to its own function. Signed-off-by: Heikki Krogerus Reviewed-by: Andy Shevchenko Reviewed-by: Hans de Goede Tested-by: Hans de Goede Signed-off-by: Rafael J. Wysocki --- drivers/platform/x86/intel_cht_int33fe.c | 62 +++++++++++++++++--------------- 1 file changed, 33 insertions(+), 29 deletions(-) (limited to 'drivers/platform') diff --git a/drivers/platform/x86/intel_cht_int33fe.c b/drivers/platform/x86/intel_cht_int33fe.c index 657b8d61554c..3f532b5a5133 100644 --- a/drivers/platform/x86/intel_cht_int33fe.c +++ b/drivers/platform/x86/intel_cht_int33fe.c @@ -63,14 +63,6 @@ static int cht_int33fe_check_for_max17047(struct device *dev, void *data) return 1; } -static struct i2c_client *cht_int33fe_find_max17047(void) -{ - struct i2c_client *max17047 = NULL; - - i2c_for_each_dev(&max17047, cht_int33fe_check_for_max17047); - return max17047; -} - static const char * const max17047_suppliers[] = { "bq24190-charger" }; static const struct property_entry max17047_props[] = { @@ -86,12 +78,40 @@ static const struct property_entry fusb302_props[] = { { } }; +static int +cht_int33fe_register_max17047(struct device *dev, struct cht_int33fe_data *data) +{ + struct i2c_client *max17047 = NULL; + struct i2c_board_info board_info; + int ret; + + i2c_for_each_dev(&max17047, cht_int33fe_check_for_max17047); + if (max17047) { + /* Pre-existing i2c-client for the max17047, add device-props */ + ret = device_add_properties(&max17047->dev, max17047_props); + if (ret) + return ret; + /* And re-probe to get the new device-props applied. */ + ret = device_reprobe(&max17047->dev); + if (ret) + dev_warn(dev, "Reprobing max17047 error: %d\n", ret); + return 0; + } + + memset(&board_info, 0, sizeof(board_info)); + strlcpy(board_info.type, "max17047", I2C_NAME_SIZE); + board_info.dev_name = "max17047"; + board_info.properties = max17047_props; + data->max17047 = i2c_acpi_new_device(dev, 1, &board_info); + + return PTR_ERR_OR_ZERO(data->max17047); +} + static int cht_int33fe_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; struct i2c_board_info board_info; struct cht_int33fe_data *data; - struct i2c_client *max17047; struct regulator *regulator; unsigned long long ptyp; acpi_status status; @@ -151,26 +171,10 @@ static int cht_int33fe_probe(struct platform_device *pdev) if (!data) return -ENOMEM; - /* Work around BIOS bug, see comment on cht_int33fe_find_max17047 */ - max17047 = cht_int33fe_find_max17047(); - if (max17047) { - /* Pre-existing i2c-client for the max17047, add device-props */ - ret = device_add_properties(&max17047->dev, max17047_props); - if (ret) - return ret; - /* And re-probe to get the new device-props applied. */ - ret = device_reprobe(&max17047->dev); - if (ret) - dev_warn(dev, "Reprobing max17047 error: %d\n", ret); - } else { - memset(&board_info, 0, sizeof(board_info)); - strlcpy(board_info.type, "max17047", I2C_NAME_SIZE); - board_info.dev_name = "max17047"; - board_info.properties = max17047_props; - data->max17047 = i2c_acpi_new_device(dev, 1, &board_info); - if (IS_ERR(data->max17047)) - return PTR_ERR(data->max17047); - } + /* Work around BIOS bug, see comment on cht_int33fe_check_for_max17047 */ + ret = cht_int33fe_register_max17047(dev, data); + if (ret) + return ret; data->connections[0].endpoint[0] = "port0"; data->connections[0].endpoint[1] = "i2c-pi3usb30532-switch"; -- cgit v1.2.3-59-g8ed1b From 80b915c11dbd4a13fc31ce879ad910277f89e7a7 Mon Sep 17 00:00:00 2001 From: Heikki Krogerus Date: Fri, 31 May 2019 17:15:43 +0300 Subject: platform/x86: intel_cht_int33fe: Remove unused fusb302 device property Device property "fcs,max-sink-microwatt" is not used in fusb302.c, so dropping it. Signed-off-by: Heikki Krogerus Reviewed-by: Andy Shevchenko Reviewed-by: Hans de Goede Tested-by: Hans de Goede Signed-off-by: Rafael J. Wysocki --- drivers/platform/x86/intel_cht_int33fe.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers/platform') diff --git a/drivers/platform/x86/intel_cht_int33fe.c b/drivers/platform/x86/intel_cht_int33fe.c index 3f532b5a5133..4ab47d6df413 100644 --- a/drivers/platform/x86/intel_cht_int33fe.c +++ b/drivers/platform/x86/intel_cht_int33fe.c @@ -74,7 +74,6 @@ static const struct property_entry fusb302_props[] = { PROPERTY_ENTRY_STRING("linux,extcon-name", "cht_wcove_pwrsrc"), PROPERTY_ENTRY_U32("fcs,max-sink-microvolt", 12000000), PROPERTY_ENTRY_U32("fcs,max-sink-microamp", 3000000), - PROPERTY_ENTRY_U32("fcs,max-sink-microwatt", 36000000), { } }; -- cgit v1.2.3-59-g8ed1b From 4ed89a005a97c5e729548567810f9d766efbb0d6 Mon Sep 17 00:00:00 2001 From: Heikki Krogerus Date: Fri, 31 May 2019 17:15:44 +0300 Subject: platform/x86: intel_cht_int33fe: Provide software nodes for the devices Software nodes provide two features that we will need later. 1) Software nodes can have references to other software nodes. 2) Software nodes can exist before a device entry is created. Signed-off-by: Heikki Krogerus Reviewed-by: Andy Shevchenko Reviewed-by: Hans de Goede Tested-by: Hans de Goede Signed-off-by: Rafael J. Wysocki --- drivers/platform/x86/intel_cht_int33fe.c | 54 +++++++++++++++++++++++++++----- 1 file changed, 46 insertions(+), 8 deletions(-) (limited to 'drivers/platform') diff --git a/drivers/platform/x86/intel_cht_int33fe.c b/drivers/platform/x86/intel_cht_int33fe.c index 4ab47d6df413..9eb2ec47b47e 100644 --- a/drivers/platform/x86/intel_cht_int33fe.c +++ b/drivers/platform/x86/intel_cht_int33fe.c @@ -27,6 +27,13 @@ #define EXPECTED_PTYPE 4 +enum { + INT33FE_NODE_FUSB302, + INT33FE_NODE_MAX17047, + INT33FE_NODE_PI3USB30532, + INT33FE_NODE_MAX, +}; + struct cht_int33fe_data { struct i2c_client *max17047; struct i2c_client *fusb302; @@ -72,8 +79,13 @@ static const struct property_entry max17047_props[] = { static const struct property_entry fusb302_props[] = { PROPERTY_ENTRY_STRING("linux,extcon-name", "cht_wcove_pwrsrc"), - PROPERTY_ENTRY_U32("fcs,max-sink-microvolt", 12000000), - PROPERTY_ENTRY_U32("fcs,max-sink-microamp", 3000000), + { } +}; + +static const struct software_node nodes[] = { + { "fusb302", NULL, fusb302_props }, + { "max17047", NULL, max17047_props }, + { "pi3usb30532" }, { } }; @@ -82,14 +94,18 @@ cht_int33fe_register_max17047(struct device *dev, struct cht_int33fe_data *data) { struct i2c_client *max17047 = NULL; struct i2c_board_info board_info; + struct fwnode_handle *fwnode; int ret; + fwnode = software_node_fwnode(&nodes[INT33FE_NODE_MAX17047]); + if (!fwnode) + return -ENODEV; + i2c_for_each_dev(&max17047, cht_int33fe_check_for_max17047); if (max17047) { /* Pre-existing i2c-client for the max17047, add device-props */ - ret = device_add_properties(&max17047->dev, max17047_props); - if (ret) - return ret; + fwnode->secondary = ERR_PTR(-ENODEV); + max17047->dev.fwnode->secondary = fwnode; /* And re-probe to get the new device-props applied. */ ret = device_reprobe(&max17047->dev); if (ret) @@ -100,7 +116,7 @@ cht_int33fe_register_max17047(struct device *dev, struct cht_int33fe_data *data) memset(&board_info, 0, sizeof(board_info)); strlcpy(board_info.type, "max17047", I2C_NAME_SIZE); board_info.dev_name = "max17047"; - board_info.properties = max17047_props; + board_info.fwnode = fwnode; data->max17047 = i2c_acpi_new_device(dev, 1, &board_info); return PTR_ERR_OR_ZERO(data->max17047); @@ -111,6 +127,7 @@ static int cht_int33fe_probe(struct platform_device *pdev) struct device *dev = &pdev->dev; struct i2c_board_info board_info; struct cht_int33fe_data *data; + struct fwnode_handle *fwnode; struct regulator *regulator; unsigned long long ptyp; acpi_status status; @@ -170,10 +187,14 @@ static int cht_int33fe_probe(struct platform_device *pdev) if (!data) return -ENOMEM; + ret = software_node_register_nodes(nodes); + if (ret) + return ret; + /* Work around BIOS bug, see comment on cht_int33fe_check_for_max17047 */ ret = cht_int33fe_register_max17047(dev, data); if (ret) - return ret; + goto out_remove_nodes; data->connections[0].endpoint[0] = "port0"; data->connections[0].endpoint[1] = "i2c-pi3usb30532-switch"; @@ -187,10 +208,16 @@ static int cht_int33fe_probe(struct platform_device *pdev) device_connections_add(data->connections); + fwnode = software_node_fwnode(&nodes[INT33FE_NODE_FUSB302]); + if (!fwnode) { + ret = -ENODEV; + goto out_unregister_max17047; + } + memset(&board_info, 0, sizeof(board_info)); strlcpy(board_info.type, "typec_fusb302", I2C_NAME_SIZE); board_info.dev_name = "fusb302"; - board_info.properties = fusb302_props; + board_info.fwnode = fwnode; board_info.irq = fusb302_irq; data->fusb302 = i2c_acpi_new_device(dev, 2, &board_info); @@ -199,8 +226,15 @@ static int cht_int33fe_probe(struct platform_device *pdev) goto out_unregister_max17047; } + fwnode = software_node_fwnode(&nodes[INT33FE_NODE_PI3USB30532]); + if (!fwnode) { + ret = -ENODEV; + goto out_unregister_fusb302; + } + memset(&board_info, 0, sizeof(board_info)); board_info.dev_name = "pi3usb30532"; + board_info.fwnode = fwnode; strlcpy(board_info.type, "pi3usb30532", I2C_NAME_SIZE); data->pi3usb30532 = i2c_acpi_new_device(dev, 3, &board_info); @@ -221,6 +255,9 @@ out_unregister_max17047: device_connections_remove(data->connections); +out_remove_nodes: + software_node_unregister_nodes(nodes); + return ret; } @@ -233,6 +270,7 @@ static int cht_int33fe_remove(struct platform_device *pdev) i2c_unregister_device(data->max17047); device_connections_remove(data->connections); + software_node_unregister_nodes(nodes); return 0; } -- cgit v1.2.3-59-g8ed1b From 9338aacf01466d6f43c73b2182d5a42228fe63d7 Mon Sep 17 00:00:00 2001 From: Heikki Krogerus Date: Fri, 31 May 2019 17:15:45 +0300 Subject: platform/x86: intel_cht_int33fe: Provide fwnode for the USB connector In ACPI, and now also in DT, the USB connectors usually have their own device nodes. In case of USB Type-C, those connector (port) nodes are child nodes of the controller or PHY device, in our case the fusb302. The software fwnodes allow us to create a similar child node for fusb302 that represents the connector also on Intel CHT. This makes it possible replace the fusb302 specific device properties which were deprecated with the common USB connector properties that tcpm.c is able to use directly. Signed-off-by: Heikki Krogerus Reviewed-by: Andy Shevchenko Reviewed-by: Hans de Goede Tested-by: Hans de Goede Signed-off-by: Rafael J. Wysocki --- drivers/platform/x86/intel_cht_int33fe.c | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) (limited to 'drivers/platform') diff --git a/drivers/platform/x86/intel_cht_int33fe.c b/drivers/platform/x86/intel_cht_int33fe.c index 9eb2ec47b47e..dcfe47baff72 100644 --- a/drivers/platform/x86/intel_cht_int33fe.c +++ b/drivers/platform/x86/intel_cht_int33fe.c @@ -24,6 +24,7 @@ #include #include #include +#include #define EXPECTED_PTYPE 4 @@ -31,6 +32,7 @@ enum { INT33FE_NODE_FUSB302, INT33FE_NODE_MAX17047, INT33FE_NODE_PI3USB30532, + INT33FE_NODE_USB_CONNECTOR, INT33FE_NODE_MAX, }; @@ -82,10 +84,33 @@ static const struct property_entry fusb302_props[] = { { } }; +#define PDO_FIXED_FLAGS \ + (PDO_FIXED_DUAL_ROLE | PDO_FIXED_DATA_SWAP | PDO_FIXED_USB_COMM) + +static const u32 src_pdo[] = { + PDO_FIXED(5000, 1500, PDO_FIXED_FLAGS), +}; + +static const u32 snk_pdo[] = { + PDO_FIXED(5000, 400, PDO_FIXED_FLAGS), + PDO_VAR(5000, 12000, 3000), +}; + +static const struct property_entry usb_connector_props[] = { + PROPERTY_ENTRY_STRING("data-role", "dual"), + PROPERTY_ENTRY_STRING("power-role", "dual"), + PROPERTY_ENTRY_STRING("try-power-role", "sink"), + PROPERTY_ENTRY_U32_ARRAY("source-pdos", src_pdo), + PROPERTY_ENTRY_U32_ARRAY("sink-pdos", snk_pdo), + PROPERTY_ENTRY_U32("op-sink-microwatt", 2500000), + { } +}; + static const struct software_node nodes[] = { { "fusb302", NULL, fusb302_props }, { "max17047", NULL, max17047_props }, { "pi3usb30532" }, + { "connector", &nodes[0], usb_connector_props }, { } }; -- cgit v1.2.3-59-g8ed1b From 62499330f7bb0904b2d798dbb55e4afe4e7b1541 Mon Sep 17 00:00:00 2001 From: Heikki Krogerus Date: Fri, 31 May 2019 17:15:46 +0300 Subject: platform/x86: intel_cht_int33fe: Supply fwnodes for the external dependencies Supplying also external devices, the DisplayPort connector and the USB role switch, software fwnodes. After this the driver has access to all the components tied to the USB Type-C connector and can start creating software node references to actually associate them with the USB Type-C connector device. Signed-off-by: Heikki Krogerus Reviewed-by: Andy Shevchenko Reviewed-by: Hans de Goede Tested-by: Hans de Goede Signed-off-by: Rafael J. Wysocki --- drivers/platform/x86/intel_cht_int33fe.c | 128 ++++++++++++++++++++++++++++++- 1 file changed, 125 insertions(+), 3 deletions(-) (limited to 'drivers/platform') diff --git a/drivers/platform/x86/intel_cht_int33fe.c b/drivers/platform/x86/intel_cht_int33fe.c index dcfe47baff72..9e1848e0343d 100644 --- a/drivers/platform/x86/intel_cht_int33fe.c +++ b/drivers/platform/x86/intel_cht_int33fe.c @@ -21,6 +21,7 @@ #include #include #include +#include #include #include #include @@ -32,6 +33,8 @@ enum { INT33FE_NODE_FUSB302, INT33FE_NODE_MAX17047, INT33FE_NODE_PI3USB30532, + INT33FE_NODE_DISPLAYPORT, + INT33FE_NODE_ROLE_SWITCH, INT33FE_NODE_USB_CONNECTOR, INT33FE_NODE_MAX, }; @@ -42,6 +45,9 @@ struct cht_int33fe_data { struct i2c_client *pi3usb30532; /* Contain a list-head must be per device */ struct device_connection connections[4]; + + struct fwnode_handle *dp; + struct fwnode_handle *mux; }; /* @@ -110,10 +116,126 @@ static const struct software_node nodes[] = { { "fusb302", NULL, fusb302_props }, { "max17047", NULL, max17047_props }, { "pi3usb30532" }, + { "displayport" }, + { "usb-role-switch" }, { "connector", &nodes[0], usb_connector_props }, { } }; +static int cht_int33fe_setup_mux(struct cht_int33fe_data *data) +{ + struct fwnode_handle *fwnode; + struct device *dev; + struct device *p; + + fwnode = software_node_fwnode(&nodes[INT33FE_NODE_ROLE_SWITCH]); + if (!fwnode) + return -ENODEV; + + /* First finding the platform device */ + p = bus_find_device_by_name(&platform_bus_type, NULL, + "intel_xhci_usb_sw"); + if (!p) + return -EPROBE_DEFER; + + /* Then the mux child device */ + dev = device_find_child_by_name(p, "intel_xhci_usb_sw-role-switch"); + put_device(p); + if (!dev) + return -EPROBE_DEFER; + + /* If there already is a node for the mux, using that one. */ + if (dev->fwnode) + fwnode_remove_software_node(fwnode); + else + dev->fwnode = fwnode; + + data->mux = fwnode_handle_get(dev->fwnode); + put_device(dev); + + return 0; +} + +static int cht_int33fe_setup_dp(struct cht_int33fe_data *data) +{ + struct fwnode_handle *fwnode; + struct pci_dev *pdev; + + fwnode = software_node_fwnode(&nodes[INT33FE_NODE_DISPLAYPORT]); + if (!fwnode) + return -ENODEV; + + /* First let's find the GPU PCI device */ + pdev = pci_get_class(PCI_CLASS_DISPLAY_VGA << 8, NULL); + if (!pdev || pdev->vendor != PCI_VENDOR_ID_INTEL) { + pci_dev_put(pdev); + return -ENODEV; + } + + /* Then the DP child device node */ + data->dp = device_get_named_child_node(&pdev->dev, "DD02"); + pci_dev_put(pdev); + if (!data->dp) + return -ENODEV; + + fwnode->secondary = ERR_PTR(-ENODEV); + data->dp->secondary = fwnode; + + return 0; +} + +static void cht_int33fe_remove_nodes(struct cht_int33fe_data *data) +{ + software_node_unregister_nodes(nodes); + + if (data->mux) { + fwnode_handle_put(data->mux); + data->mux = NULL; + } + + if (data->dp) { + data->dp->secondary = NULL; + fwnode_handle_put(data->dp); + data->dp = NULL; + } +} + +static int cht_int33fe_add_nodes(struct cht_int33fe_data *data) +{ + int ret; + + ret = software_node_register_nodes(nodes); + if (ret) + return ret; + + /* The devices that are not created in this driver need extra steps. */ + + /* + * There is no ACPI device node for the USB role mux, so we need to find + * the mux device and assign our node directly to it. That means we + * depend on the mux driver. This function will return -PROBE_DEFER + * until the mux device is registered. + */ + ret = cht_int33fe_setup_mux(data); + if (ret) + goto err_remove_nodes; + + /* + * The DP connector does have ACPI device node. In this case we can just + * find that ACPI node and assign our node as the secondary node to it. + */ + ret = cht_int33fe_setup_dp(data); + if (ret) + goto err_remove_nodes; + + return 0; + +err_remove_nodes: + cht_int33fe_remove_nodes(data); + + return ret; +} + static int cht_int33fe_register_max17047(struct device *dev, struct cht_int33fe_data *data) { @@ -212,7 +334,7 @@ static int cht_int33fe_probe(struct platform_device *pdev) if (!data) return -ENOMEM; - ret = software_node_register_nodes(nodes); + ret = cht_int33fe_add_nodes(data); if (ret) return ret; @@ -281,7 +403,7 @@ out_unregister_max17047: device_connections_remove(data->connections); out_remove_nodes: - software_node_unregister_nodes(nodes); + cht_int33fe_remove_nodes(data); return ret; } @@ -295,7 +417,7 @@ static int cht_int33fe_remove(struct platform_device *pdev) i2c_unregister_device(data->max17047); device_connections_remove(data->connections); - software_node_unregister_nodes(nodes); + cht_int33fe_remove_nodes(data); return 0; } -- cgit v1.2.3-59-g8ed1b From be6dc3291e0fc19e6c8cc8f231968ab9b51f5abf Mon Sep 17 00:00:00 2001 From: Heikki Krogerus Date: Fri, 31 May 2019 17:15:47 +0300 Subject: platform/x86: intel_cht_int33fe: Replacing the old connections with references Replacing the old connection descriptions with software node references. Supplying the USB connector also a reference to the DisplayPort while at it. Signed-off-by: Heikki Krogerus Reviewed-by: Andy Shevchenko Reviewed-by: Hans de Goede Tested-by: Hans de Goede Signed-off-by: Rafael J. Wysocki --- drivers/platform/x86/intel_cht_int33fe.c | 47 +++++++++++++++++++------------- 1 file changed, 28 insertions(+), 19 deletions(-) (limited to 'drivers/platform') diff --git a/drivers/platform/x86/intel_cht_int33fe.c b/drivers/platform/x86/intel_cht_int33fe.c index 9e1848e0343d..4fbdff48a4b5 100644 --- a/drivers/platform/x86/intel_cht_int33fe.c +++ b/drivers/platform/x86/intel_cht_int33fe.c @@ -43,13 +43,35 @@ struct cht_int33fe_data { struct i2c_client *max17047; struct i2c_client *fusb302; struct i2c_client *pi3usb30532; - /* Contain a list-head must be per device */ - struct device_connection connections[4]; struct fwnode_handle *dp; struct fwnode_handle *mux; }; +static const struct software_node nodes[]; + +static const struct software_node_ref_args pi3usb30532_ref = { + &nodes[INT33FE_NODE_PI3USB30532] +}; + +static const struct software_node_ref_args dp_ref = { + &nodes[INT33FE_NODE_DISPLAYPORT] +}; + +static struct software_node_ref_args mux_ref; + +static const struct software_node_reference usb_connector_refs[] = { + { "orientation-switch", 1, &pi3usb30532_ref}, + { "mode-switch", 1, &pi3usb30532_ref}, + { "displayport", 1, &dp_ref}, + { } +}; + +static const struct software_node_reference fusb302_refs[] = { + { "usb-role-switch", 1, &mux_ref}, + { } +}; + /* * Grrr I severly dislike buggy BIOS-es. At least one BIOS enumerates * the max17047 both through the INT33FE ACPI device (it is right there @@ -113,12 +135,12 @@ static const struct property_entry usb_connector_props[] = { }; static const struct software_node nodes[] = { - { "fusb302", NULL, fusb302_props }, + { "fusb302", NULL, fusb302_props, fusb302_refs }, { "max17047", NULL, max17047_props }, { "pi3usb30532" }, { "displayport" }, { "usb-role-switch" }, - { "connector", &nodes[0], usb_connector_props }, + { "connector", &nodes[0], usb_connector_props, usb_connector_refs }, { } }; @@ -152,6 +174,7 @@ static int cht_int33fe_setup_mux(struct cht_int33fe_data *data) data->mux = fwnode_handle_get(dev->fwnode); put_device(dev); + mux_ref.node = to_software_node(data->mux); return 0; } @@ -190,6 +213,7 @@ static void cht_int33fe_remove_nodes(struct cht_int33fe_data *data) if (data->mux) { fwnode_handle_put(data->mux); + mux_ref.node = NULL; data->mux = NULL; } @@ -343,18 +367,6 @@ static int cht_int33fe_probe(struct platform_device *pdev) if (ret) goto out_remove_nodes; - data->connections[0].endpoint[0] = "port0"; - data->connections[0].endpoint[1] = "i2c-pi3usb30532-switch"; - data->connections[0].id = "orientation-switch"; - data->connections[1].endpoint[0] = "port0"; - data->connections[1].endpoint[1] = "i2c-pi3usb30532-mux"; - data->connections[1].id = "mode-switch"; - data->connections[2].endpoint[0] = "i2c-fusb302"; - data->connections[2].endpoint[1] = "intel_xhci_usb_sw-role-switch"; - data->connections[2].id = "usb-role-switch"; - - device_connections_add(data->connections); - fwnode = software_node_fwnode(&nodes[INT33FE_NODE_FUSB302]); if (!fwnode) { ret = -ENODEV; @@ -400,8 +412,6 @@ out_unregister_fusb302: out_unregister_max17047: i2c_unregister_device(data->max17047); - device_connections_remove(data->connections); - out_remove_nodes: cht_int33fe_remove_nodes(data); @@ -416,7 +426,6 @@ static int cht_int33fe_remove(struct platform_device *pdev) i2c_unregister_device(data->fusb302); i2c_unregister_device(data->max17047); - device_connections_remove(data->connections); cht_int33fe_remove_nodes(data); return 0; -- cgit v1.2.3-59-g8ed1b