This will add an array of known USB Type-C Port devices that
will be used as a blacklist for enabling userspace-control,
and remove the PMIC ACPI HID which was used for the same
purpose.

It turns out that on some CHT based platforms the X-Powers
PMIC is handled in firmware. The ACPI HID for it is
therefore not usable for determining the port type. The
driver now searches for known USB Type-C port devices
instead.

Signed-off-by: Heikki Krogerus <heikki.kroge...@linux.intel.com>
---
Hi Hans,

So it seems that we can't rely on the PMIC. This is my proposal for a
fix. I'm in practice just using blacklist instead of whitelist for
identifying the port type.

Let me know if it's OK to you.


Thanks,

---
 .../usb/roles/intel-xhci-usb-role-switch.c    | 40 +++++++++++--------
 1 file changed, 24 insertions(+), 16 deletions(-)

diff --git a/drivers/usb/roles/intel-xhci-usb-role-switch.c 
b/drivers/usb/roles/intel-xhci-usb-role-switch.c
index de72eedb762e..1696d1f25769 100644
--- a/drivers/usb/roles/intel-xhci-usb-role-switch.c
+++ b/drivers/usb/roles/intel-xhci-usb-role-switch.c
@@ -38,19 +38,26 @@ struct intel_xhci_usb_data {
        void __iomem *base;
 };
 
-struct intel_xhci_acpi_match {
-       const char *hid;
-       int hrv;
+static const struct acpi_device_id typec_port_devices[] = {
+       { "PNP0CA0", 0 }, /* UCSI */
+       { "INT33FE", 0 }, /* CHT USB Type-C PHY */
+       { },
 };
 
-/*
- * ACPI IDs for PMICs which do not support separate data and power role
- * detection (USB ACA detection for micro USB OTG), we allow userspace to
- * change the role manually on these.
- */
-static const struct intel_xhci_acpi_match allow_userspace_ctrl_ids[] = {
-       { "INT33F4",  3 }, /* X-Powers AXP288 PMIC */
-};
+static acpi_status intel_xhci_userspace_ctrl(acpi_handle handle, u32 level,
+                                            void *ctx, void **ret)
+{
+       struct acpi_device *adev;
+
+       if (acpi_bus_get_device(handle, &adev))
+               return AE_OK;
+
+       /* Don't allow userspace-control with Type-C ports */
+       if (!acpi_match_device_ids(adev, typec_port_devices))
+               return AE_ACCESS;
+
+       return AE_OK;
+}
 
 static int intel_xhci_usb_set_role(struct device *dev, enum usb_role role)
 {
@@ -137,7 +144,7 @@ static int intel_xhci_usb_probe(struct platform_device 
*pdev)
        struct device *dev = &pdev->dev;
        struct intel_xhci_usb_data *data;
        struct resource *res;
-       int i;
+       acpi_status status;
 
        data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
        if (!data)
@@ -148,10 +155,11 @@ static int intel_xhci_usb_probe(struct platform_device 
*pdev)
        if (!data->base)
                return -ENOMEM;
 
-       for (i = 0; i < ARRAY_SIZE(allow_userspace_ctrl_ids); i++)
-               if (acpi_dev_present(allow_userspace_ctrl_ids[i].hid, "1",
-                                    allow_userspace_ctrl_ids[i].hrv))
-                       sw_desc.allow_userspace_control = true;
+       status = acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT,
+                                    ACPI_UINT32_MAX, intel_xhci_userspace_ctrl,
+                                    NULL, NULL, NULL);
+       if (ACPI_SUCCESS(status))
+               sw_desc.allow_userspace_control = true;
 
        platform_set_drvdata(pdev, data);
 
-- 
2.17.0

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to