forked from ~ljy/RK356X_SDK_RELEASE

hc
2024-01-03 2f7c68cb55ecb7331f2381deb497c27155f32faf
kernel/drivers/usb/roles/intel-xhci-usb-role-switch.c
....@@ -19,6 +19,7 @@
1919 #include <linux/module.h>
2020 #include <linux/platform_device.h>
2121 #include <linux/pm_runtime.h>
22
+#include <linux/property.h>
2223 #include <linux/usb/role.h>
2324
2425 /* register definition */
....@@ -26,6 +27,12 @@
2627 #define SW_VBUS_VALID BIT(24)
2728 #define SW_IDPIN_EN BIT(21)
2829 #define SW_IDPIN BIT(20)
30
+#define SW_SWITCH_EN BIT(16)
31
+
32
+#define DRD_CONFIG_DYNAMIC 0
33
+#define DRD_CONFIG_STATIC_HOST 1
34
+#define DRD_CONFIG_STATIC_DEVICE 2
35
+#define DRD_CONFIG_MASK 3
2936
3037 #define DUAL_ROLE_CFG1 0x6c
3138 #define HOST_MODE BIT(29)
....@@ -35,16 +42,24 @@
3542 #define DRV_NAME "intel_xhci_usb_sw"
3643
3744 struct intel_xhci_usb_data {
45
+ struct device *dev;
3846 struct usb_role_switch *role_sw;
3947 void __iomem *base;
48
+ bool enable_sw_switch;
4049 };
4150
42
-static int intel_xhci_usb_set_role(struct device *dev, enum usb_role role)
51
+static const struct software_node intel_xhci_usb_node = {
52
+ "intel-xhci-usb-sw",
53
+};
54
+
55
+static int intel_xhci_usb_set_role(struct usb_role_switch *sw,
56
+ enum usb_role role)
4357 {
44
- struct intel_xhci_usb_data *data = dev_get_drvdata(dev);
58
+ struct intel_xhci_usb_data *data = usb_role_switch_get_drvdata(sw);
4559 unsigned long timeout;
4660 acpi_status status;
4761 u32 glk, val;
62
+ u32 drd_config = DRD_CONFIG_DYNAMIC;
4863
4964 /*
5065 * On many CHT devices ACPI event (_AEI) handlers read / modify /
....@@ -53,30 +68,41 @@
5368 */
5469 status = acpi_acquire_global_lock(ACPI_WAIT_FOREVER, &glk);
5570 if (ACPI_FAILURE(status) && status != AE_NOT_CONFIGURED) {
56
- dev_err(dev, "Error could not acquire lock\n");
71
+ dev_err(data->dev, "Error could not acquire lock\n");
5772 return -EIO;
5873 }
5974
60
- pm_runtime_get_sync(dev);
75
+ pm_runtime_get_sync(data->dev);
6176
62
- /* Set idpin value as requested */
77
+ /*
78
+ * Set idpin value as requested.
79
+ * Since some devices rely on firmware setting DRD_CONFIG and
80
+ * SW_SWITCH_EN bits to be zero for role switch,
81
+ * do not set these bits for those devices.
82
+ */
6383 val = readl(data->base + DUAL_ROLE_CFG0);
6484 switch (role) {
6585 case USB_ROLE_NONE:
6686 val |= SW_IDPIN;
6787 val &= ~SW_VBUS_VALID;
88
+ drd_config = DRD_CONFIG_DYNAMIC;
6889 break;
6990 case USB_ROLE_HOST:
7091 val &= ~SW_IDPIN;
7192 val &= ~SW_VBUS_VALID;
93
+ drd_config = DRD_CONFIG_STATIC_HOST;
7294 break;
7395 case USB_ROLE_DEVICE:
7496 val |= SW_IDPIN;
7597 val |= SW_VBUS_VALID;
98
+ drd_config = DRD_CONFIG_STATIC_DEVICE;
7699 break;
77100 }
78101 val |= SW_IDPIN_EN;
79
-
102
+ if (data->enable_sw_switch) {
103
+ val &= ~DRD_CONFIG_MASK;
104
+ val |= SW_SWITCH_EN | drd_config;
105
+ }
80106 writel(val, data->base + DUAL_ROLE_CFG0);
81107
82108 acpi_release_global_lock(glk);
....@@ -88,7 +114,7 @@
88114 do {
89115 val = readl(data->base + DUAL_ROLE_CFG1);
90116 if (!!(val & HOST_MODE) == (role == USB_ROLE_HOST)) {
91
- pm_runtime_put(dev);
117
+ pm_runtime_put(data->dev);
92118 return 0;
93119 }
94120
....@@ -96,21 +122,21 @@
96122 usleep_range(5000, 10000);
97123 } while (time_before(jiffies, timeout));
98124
99
- pm_runtime_put(dev);
125
+ pm_runtime_put(data->dev);
100126
101
- dev_warn(dev, "Timeout waiting for role-switch\n");
127
+ dev_warn(data->dev, "Timeout waiting for role-switch\n");
102128 return -ETIMEDOUT;
103129 }
104130
105
-static enum usb_role intel_xhci_usb_get_role(struct device *dev)
131
+static enum usb_role intel_xhci_usb_get_role(struct usb_role_switch *sw)
106132 {
107
- struct intel_xhci_usb_data *data = dev_get_drvdata(dev);
133
+ struct intel_xhci_usb_data *data = usb_role_switch_get_drvdata(sw);
108134 enum usb_role role;
109135 u32 val;
110136
111
- pm_runtime_get_sync(dev);
137
+ pm_runtime_get_sync(data->dev);
112138 val = readl(data->base + DUAL_ROLE_CFG0);
113
- pm_runtime_put(dev);
139
+ pm_runtime_put(data->dev);
114140
115141 if (!(val & SW_IDPIN))
116142 role = USB_ROLE_HOST;
....@@ -122,17 +148,13 @@
122148 return role;
123149 }
124150
125
-static const struct usb_role_switch_desc sw_desc = {
126
- .set = intel_xhci_usb_set_role,
127
- .get = intel_xhci_usb_get_role,
128
- .allow_userspace_control = true,
129
-};
130
-
131151 static int intel_xhci_usb_probe(struct platform_device *pdev)
132152 {
153
+ struct usb_role_switch_desc sw_desc = { };
133154 struct device *dev = &pdev->dev;
134155 struct intel_xhci_usb_data *data;
135156 struct resource *res;
157
+ int ret;
136158
137159 data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
138160 if (!data)
....@@ -141,15 +163,31 @@
141163 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
142164 if (!res)
143165 return -EINVAL;
144
- data->base = devm_ioremap_nocache(dev, res->start, resource_size(res));
166
+ data->base = devm_ioremap(dev, res->start, resource_size(res));
145167 if (!data->base)
146168 return -ENOMEM;
147169
148170 platform_set_drvdata(pdev, data);
149171
172
+ ret = software_node_register(&intel_xhci_usb_node);
173
+ if (ret)
174
+ return ret;
175
+
176
+ sw_desc.set = intel_xhci_usb_set_role,
177
+ sw_desc.get = intel_xhci_usb_get_role,
178
+ sw_desc.allow_userspace_control = true,
179
+ sw_desc.fwnode = software_node_fwnode(&intel_xhci_usb_node);
180
+ sw_desc.driver_data = data;
181
+
182
+ data->dev = dev;
183
+ data->enable_sw_switch = !device_property_read_bool(dev,
184
+ "sw_switch_disable");
185
+
150186 data->role_sw = usb_role_switch_register(dev, &sw_desc);
151
- if (IS_ERR(data->role_sw))
187
+ if (IS_ERR(data->role_sw)) {
188
+ fwnode_handle_put(sw_desc.fwnode);
152189 return PTR_ERR(data->role_sw);
190
+ }
153191
154192 pm_runtime_set_active(dev);
155193 pm_runtime_enable(dev);
....@@ -164,6 +202,8 @@
164202 pm_runtime_disable(&pdev->dev);
165203
166204 usb_role_switch_unregister(data->role_sw);
205
+ fwnode_handle_put(software_node_fwnode(&intel_xhci_usb_node));
206
+
167207 return 0;
168208 }
169209