1 // SPDX-License-Identifier: GPL-2.0
2 /*
3 * Driver for Intel PMC USB mux control
4 *
5 * Copyright (C) 2020 Intel Corporation
6 * Author: Heikki Krogerus <heikki.krogerus@linux.intel.com>
7 */
8
9 #include <linux/acpi.h>
10 #include <linux/module.h>
11 #include <linux/platform_device.h>
12 #include <linux/property.h>
13 #include <linux/usb/pd.h>
14 #include <linux/usb/role.h>
15 #include <linux/usb/typec_mux.h>
16 #include <linux/usb/typec_dp.h>
17 #include <linux/usb/typec_tbt.h>
18
19 #include <asm/intel_scu_ipc.h>
20
21 #define PMC_USBC_CMD 0xa7
22
23 /* Response status bits */
24 #define PMC_USB_RESP_STATUS_FAILURE BIT(0)
25 #define PMC_USB_RESP_STATUS_FATAL BIT(1)
26
27 /* "Usage" OOB Message field values */
28 enum {
29 PMC_USB_CONNECT,
30 PMC_USB_DISCONNECT,
31 PMC_USB_SAFE_MODE,
32 PMC_USB_ALT_MODE,
33 PMC_USB_DP_HPD,
34 };
35
36 #define PMC_USB_MSG_USB2_PORT_SHIFT 0
37 #define PMC_USB_MSG_USB3_PORT_SHIFT 4
38 #define PMC_USB_MSG_UFP_SHIFT 4
39 #define PMC_USB_MSG_ORI_HSL_SHIFT 5
40 #define PMC_USB_MSG_ORI_AUX_SHIFT 6
41
42 /* Alt Mode Request */
43 struct altmode_req {
44 u8 usage;
45 u8 mode_type;
46 u8 mode_id;
47 u8 reserved;
48 u32 mode_data;
49 } __packed;
50
51 #define PMC_USB_MODE_TYPE_SHIFT 4
52
53 enum {
54 PMC_USB_MODE_TYPE_USB,
55 PMC_USB_MODE_TYPE_DP,
56 PMC_USB_MODE_TYPE_TBT,
57 };
58
59 /* Common Mode Data bits */
60 #define PMC_USB_ALTMODE_ACTIVE_CABLE BIT(2)
61
62 #define PMC_USB_ALTMODE_ORI_SHIFT 1
63 #define PMC_USB_ALTMODE_UFP_SHIFT 3
64
65 /* DP specific Mode Data bits */
66 #define PMC_USB_ALTMODE_DP_MODE_SHIFT 8
67
68 /* TBT specific Mode Data bits */
69 #define PMC_USB_ALTMODE_TBT_TYPE BIT(17)
70 #define PMC_USB_ALTMODE_CABLE_TYPE BIT(18)
71 #define PMC_USB_ALTMODE_ACTIVE_LINK BIT(20)
72 #define PMC_USB_ALTMODE_FORCE_LSR BIT(23)
73 #define PMC_USB_ALTMODE_CABLE_SPD(_s_) (((_s_) & GENMASK(2, 0)) << 25)
74 #define PMC_USB_ALTMODE_CABLE_USB31 1
75 #define PMC_USB_ALTMODE_CABLE_10GPS 2
76 #define PMC_USB_ALTMODE_CABLE_20GPS 3
77 #define PMC_USB_ALTMODE_TBT_GEN(_g_) (((_g_) & GENMASK(1, 0)) << 28)
78
79 /* Display HPD Request bits */
80 #define PMC_USB_DP_HPD_LVL BIT(4)
81 #define PMC_USB_DP_HPD_IRQ BIT(5)
82
83 /*
84 * Input Output Manager (IOM) PORT STATUS
85 */
86 #define IOM_PORT_STATUS_OFFSET 0x560
87
88 #define IOM_PORT_STATUS_ACTIVITY_TYPE_MASK GENMASK(9, 6)
89 #define IOM_PORT_STATUS_ACTIVITY_TYPE_SHIFT 6
90 #define IOM_PORT_STATUS_ACTIVITY_TYPE_USB 0x03
91 /* activity type: Safe Mode */
92 #define IOM_PORT_STATUS_ACTIVITY_TYPE_SAFE_MODE 0x04
93 /* activity type: Display Port */
94 #define IOM_PORT_STATUS_ACTIVITY_TYPE_DP 0x05
95 /* activity type: Display Port Multi Function Device */
96 #define IOM_PORT_STATUS_ACTIVITY_TYPE_DP_MFD 0x06
97 /* activity type: Thunderbolt */
98 #define IOM_PORT_STATUS_ACTIVITY_TYPE_TBT 0x07
99 #define IOM_PORT_STATUS_ACTIVITY_TYPE_ALT_MODE_USB 0x0c
100 #define IOM_PORT_STATUS_ACTIVITY_TYPE_ALT_MODE_TBT_USB 0x0d
101 /* Upstream Facing Port Information */
102 #define IOM_PORT_STATUS_UFP BIT(10)
103 /* Display Port Hot Plug Detect status */
104 #define IOM_PORT_STATUS_DHPD_HPD_STATUS_MASK GENMASK(13, 12)
105 #define IOM_PORT_STATUS_DHPD_HPD_STATUS_SHIFT 12
106 #define IOM_PORT_STATUS_DHPD_HPD_STATUS_ASSERT 0x01
107 #define IOM_PORT_STATUS_DHPD_HPD_SOURCE_TBT BIT(14)
108 #define IOM_PORT_STATUS_CONNECTED BIT(31)
109
110 #define IOM_PORT_ACTIVITY_IS(_status_, _type_) \
111 ((((_status_) & IOM_PORT_STATUS_ACTIVITY_TYPE_MASK) >> \
112 IOM_PORT_STATUS_ACTIVITY_TYPE_SHIFT) == \
113 (IOM_PORT_STATUS_ACTIVITY_TYPE_##_type_))
114
115 #define IOM_PORT_HPD_ASSERTED(_status_) \
116 ((((_status_) & IOM_PORT_STATUS_DHPD_HPD_STATUS_MASK) >> \
117 IOM_PORT_STATUS_DHPD_HPD_STATUS_SHIFT) & \
118 IOM_PORT_STATUS_DHPD_HPD_STATUS_ASSERT)
119
120 struct pmc_usb;
121
122 struct pmc_usb_port {
123 int num;
124 u32 iom_status;
125 struct pmc_usb *pmc;
126 struct typec_mux *typec_mux;
127 struct typec_switch *typec_sw;
128 struct usb_role_switch *usb_sw;
129
130 enum typec_orientation orientation;
131 enum usb_role role;
132
133 u8 usb2_port;
134 u8 usb3_port;
135
136 enum typec_orientation sbu_orientation;
137 enum typec_orientation hsl_orientation;
138 };
139
140 struct pmc_usb {
141 u8 num_ports;
142 struct device *dev;
143 struct intel_scu_ipc_dev *ipc;
144 struct pmc_usb_port *port;
145 struct acpi_device *iom_adev;
146 void __iomem *iom_base;
147 };
148
update_port_status(struct pmc_usb_port * port)149 static void update_port_status(struct pmc_usb_port *port)
150 {
151 u8 port_num;
152
153 /* SoC expects the USB Type-C port numbers to start with 0 */
154 port_num = port->usb3_port - 1;
155
156 port->iom_status = readl(port->pmc->iom_base + IOM_PORT_STATUS_OFFSET +
157 port_num * sizeof(u32));
158 }
159
sbu_orientation(struct pmc_usb_port * port)160 static int sbu_orientation(struct pmc_usb_port *port)
161 {
162 if (port->sbu_orientation)
163 return port->sbu_orientation - 1;
164
165 return port->orientation - 1;
166 }
167
hsl_orientation(struct pmc_usb_port * port)168 static int hsl_orientation(struct pmc_usb_port *port)
169 {
170 if (port->hsl_orientation)
171 return port->hsl_orientation - 1;
172
173 return port->orientation - 1;
174 }
175
pmc_usb_command(struct pmc_usb_port * port,u8 * msg,u32 len)176 static int pmc_usb_command(struct pmc_usb_port *port, u8 *msg, u32 len)
177 {
178 u8 response[4];
179 int ret;
180
181 /*
182 * Error bit will always be 0 with the USBC command.
183 * Status can be checked from the response message if the
184 * function intel_scu_ipc_dev_command succeeds.
185 */
186 ret = intel_scu_ipc_dev_command(port->pmc->ipc, PMC_USBC_CMD, 0, msg,
187 len, response, sizeof(response));
188
189 if (ret)
190 return ret;
191
192 if (response[2] & PMC_USB_RESP_STATUS_FAILURE) {
193 if (response[2] & PMC_USB_RESP_STATUS_FATAL)
194 return -EIO;
195 return -EBUSY;
196 }
197
198 return 0;
199 }
200
201 static int
pmc_usb_mux_dp_hpd(struct pmc_usb_port * port,struct typec_displayport_data * dp)202 pmc_usb_mux_dp_hpd(struct pmc_usb_port *port, struct typec_displayport_data *dp)
203 {
204 u8 msg[2] = { };
205
206 msg[0] = PMC_USB_DP_HPD;
207 msg[0] |= port->usb3_port << PMC_USB_MSG_USB3_PORT_SHIFT;
208
209 if (dp->status & DP_STATUS_IRQ_HPD)
210 msg[1] = PMC_USB_DP_HPD_IRQ;
211
212 if (dp->status & DP_STATUS_HPD_STATE)
213 msg[1] |= PMC_USB_DP_HPD_LVL;
214
215 return pmc_usb_command(port, msg, sizeof(msg));
216 }
217
218 static int
pmc_usb_mux_dp(struct pmc_usb_port * port,struct typec_mux_state * state)219 pmc_usb_mux_dp(struct pmc_usb_port *port, struct typec_mux_state *state)
220 {
221 struct typec_displayport_data *data = state->data;
222 struct altmode_req req = { };
223 int ret;
224
225 if (IOM_PORT_ACTIVITY_IS(port->iom_status, DP) ||
226 IOM_PORT_ACTIVITY_IS(port->iom_status, DP_MFD)) {
227 if (IOM_PORT_HPD_ASSERTED(port->iom_status) &&
228 (!(data->status & DP_STATUS_IRQ_HPD) &&
229 data->status & DP_STATUS_HPD_STATE))
230 return 0;
231
232 return pmc_usb_mux_dp_hpd(port, state->data);
233 }
234
235 req.usage = PMC_USB_ALT_MODE;
236 req.usage |= port->usb3_port << PMC_USB_MSG_USB3_PORT_SHIFT;
237 req.mode_type = PMC_USB_MODE_TYPE_DP << PMC_USB_MODE_TYPE_SHIFT;
238
239 req.mode_data = (port->orientation - 1) << PMC_USB_ALTMODE_ORI_SHIFT;
240 req.mode_data |= (port->role - 1) << PMC_USB_ALTMODE_UFP_SHIFT;
241
242 req.mode_data |= (state->mode - TYPEC_STATE_MODAL) <<
243 PMC_USB_ALTMODE_DP_MODE_SHIFT;
244
245 ret = pmc_usb_command(port, (void *)&req, sizeof(req));
246 if (ret)
247 return ret;
248
249 if (data->status & (DP_STATUS_IRQ_HPD | DP_STATUS_HPD_STATE))
250 return pmc_usb_mux_dp_hpd(port, state->data);
251
252 return 0;
253 }
254
255 static int
pmc_usb_mux_tbt(struct pmc_usb_port * port,struct typec_mux_state * state)256 pmc_usb_mux_tbt(struct pmc_usb_port *port, struct typec_mux_state *state)
257 {
258 struct typec_thunderbolt_data *data = state->data;
259 u8 cable_speed = TBT_CABLE_SPEED(data->cable_mode);
260 struct altmode_req req = { };
261
262 if (IOM_PORT_ACTIVITY_IS(port->iom_status, TBT) ||
263 IOM_PORT_ACTIVITY_IS(port->iom_status, ALT_MODE_TBT_USB))
264 return 0;
265
266 req.usage = PMC_USB_ALT_MODE;
267 req.usage |= port->usb3_port << PMC_USB_MSG_USB3_PORT_SHIFT;
268 req.mode_type = PMC_USB_MODE_TYPE_TBT << PMC_USB_MODE_TYPE_SHIFT;
269
270 req.mode_data = (port->orientation - 1) << PMC_USB_ALTMODE_ORI_SHIFT;
271 req.mode_data |= (port->role - 1) << PMC_USB_ALTMODE_UFP_SHIFT;
272
273 if (TBT_ADAPTER(data->device_mode) == TBT_ADAPTER_TBT3)
274 req.mode_data |= PMC_USB_ALTMODE_TBT_TYPE;
275
276 if (data->cable_mode & TBT_CABLE_OPTICAL)
277 req.mode_data |= PMC_USB_ALTMODE_CABLE_TYPE;
278
279 if (data->cable_mode & TBT_CABLE_LINK_TRAINING)
280 req.mode_data |= PMC_USB_ALTMODE_ACTIVE_LINK;
281
282 if (data->enter_vdo & TBT_ENTER_MODE_ACTIVE_CABLE)
283 req.mode_data |= PMC_USB_ALTMODE_ACTIVE_CABLE;
284
285 req.mode_data |= PMC_USB_ALTMODE_CABLE_SPD(cable_speed);
286
287 return pmc_usb_command(port, (void *)&req, sizeof(req));
288 }
289
290 static int
pmc_usb_mux_usb4(struct pmc_usb_port * port,struct typec_mux_state * state)291 pmc_usb_mux_usb4(struct pmc_usb_port *port, struct typec_mux_state *state)
292 {
293 struct enter_usb_data *data = state->data;
294 struct altmode_req req = { };
295 u8 cable_speed;
296
297 if (IOM_PORT_ACTIVITY_IS(port->iom_status, TBT) ||
298 IOM_PORT_ACTIVITY_IS(port->iom_status, ALT_MODE_TBT_USB))
299 return 0;
300
301 req.usage = PMC_USB_ALT_MODE;
302 req.usage |= port->usb3_port << PMC_USB_MSG_USB3_PORT_SHIFT;
303 req.mode_type = PMC_USB_MODE_TYPE_TBT << PMC_USB_MODE_TYPE_SHIFT;
304
305 /* USB4 Mode */
306 req.mode_data = PMC_USB_ALTMODE_FORCE_LSR;
307
308 if (data->active_link_training)
309 req.mode_data |= PMC_USB_ALTMODE_ACTIVE_LINK;
310
311 req.mode_data |= (port->orientation - 1) << PMC_USB_ALTMODE_ORI_SHIFT;
312 req.mode_data |= (port->role - 1) << PMC_USB_ALTMODE_UFP_SHIFT;
313
314 switch ((data->eudo & EUDO_CABLE_TYPE_MASK) >> EUDO_CABLE_TYPE_SHIFT) {
315 case EUDO_CABLE_TYPE_PASSIVE:
316 break;
317 case EUDO_CABLE_TYPE_OPTICAL:
318 req.mode_data |= PMC_USB_ALTMODE_CABLE_TYPE;
319 fallthrough;
320 default:
321 req.mode_data |= PMC_USB_ALTMODE_ACTIVE_CABLE;
322 break;
323 }
324
325 cable_speed = (data->eudo & EUDO_CABLE_SPEED_MASK) >> EUDO_CABLE_SPEED_SHIFT;
326 req.mode_data |= PMC_USB_ALTMODE_CABLE_SPD(cable_speed);
327
328 return pmc_usb_command(port, (void *)&req, sizeof(req));
329 }
330
pmc_usb_mux_safe_state(struct pmc_usb_port * port)331 static int pmc_usb_mux_safe_state(struct pmc_usb_port *port)
332 {
333 u8 msg;
334
335 if (IOM_PORT_ACTIVITY_IS(port->iom_status, SAFE_MODE))
336 return 0;
337
338 msg = PMC_USB_SAFE_MODE;
339 msg |= port->usb3_port << PMC_USB_MSG_USB3_PORT_SHIFT;
340
341 return pmc_usb_command(port, &msg, sizeof(msg));
342 }
343
pmc_usb_disconnect(struct pmc_usb_port * port)344 static int pmc_usb_disconnect(struct pmc_usb_port *port)
345 {
346 struct typec_displayport_data data = { };
347 u8 msg[2];
348
349 if (!(port->iom_status & IOM_PORT_STATUS_CONNECTED))
350 return 0;
351
352 /* Clear DisplayPort HPD if it's still asserted. */
353 if (IOM_PORT_HPD_ASSERTED(port->iom_status))
354 pmc_usb_mux_dp_hpd(port, &data);
355
356 msg[0] = PMC_USB_DISCONNECT;
357 msg[0] |= port->usb3_port << PMC_USB_MSG_USB3_PORT_SHIFT;
358
359 msg[1] = port->usb2_port << PMC_USB_MSG_USB2_PORT_SHIFT;
360
361 return pmc_usb_command(port, msg, sizeof(msg));
362 }
363
pmc_usb_connect(struct pmc_usb_port * port,enum usb_role role)364 static int pmc_usb_connect(struct pmc_usb_port *port, enum usb_role role)
365 {
366 u8 ufp = role == USB_ROLE_DEVICE ? 1 : 0;
367 u8 msg[2];
368 int ret;
369
370 if (port->orientation == TYPEC_ORIENTATION_NONE)
371 return -EINVAL;
372
373 if (port->iom_status & IOM_PORT_STATUS_CONNECTED) {
374 if (port->role == role || port->role == USB_ROLE_NONE)
375 return 0;
376
377 /* Role swap */
378 ret = pmc_usb_disconnect(port);
379 if (ret)
380 return ret;
381 }
382
383 msg[0] = PMC_USB_CONNECT;
384 msg[0] |= port->usb3_port << PMC_USB_MSG_USB3_PORT_SHIFT;
385
386 msg[1] = port->usb2_port << PMC_USB_MSG_USB2_PORT_SHIFT;
387 msg[1] |= ufp << PMC_USB_MSG_UFP_SHIFT;
388 msg[1] |= hsl_orientation(port) << PMC_USB_MSG_ORI_HSL_SHIFT;
389 msg[1] |= sbu_orientation(port) << PMC_USB_MSG_ORI_AUX_SHIFT;
390
391 return pmc_usb_command(port, msg, sizeof(msg));
392 }
393
394 static int
pmc_usb_mux_set(struct typec_mux * mux,struct typec_mux_state * state)395 pmc_usb_mux_set(struct typec_mux *mux, struct typec_mux_state *state)
396 {
397 struct pmc_usb_port *port = typec_mux_get_drvdata(mux);
398
399 update_port_status(port);
400
401 if (port->orientation == TYPEC_ORIENTATION_NONE || port->role == USB_ROLE_NONE)
402 return 0;
403
404 if (state->mode == TYPEC_STATE_SAFE)
405 return pmc_usb_mux_safe_state(port);
406 if (state->mode == TYPEC_STATE_USB)
407 return pmc_usb_connect(port, port->role);
408
409 if (state->alt) {
410 switch (state->alt->svid) {
411 case USB_TYPEC_TBT_SID:
412 return pmc_usb_mux_tbt(port, state);
413 case USB_TYPEC_DP_SID:
414 return pmc_usb_mux_dp(port, state);
415 }
416 } else {
417 switch (state->mode) {
418 case TYPEC_MODE_USB2:
419 /* REVISIT: Try with usb3_port set to 0? */
420 break;
421 case TYPEC_MODE_USB3:
422 return pmc_usb_connect(port, port->role);
423 case TYPEC_MODE_USB4:
424 return pmc_usb_mux_usb4(port, state);
425 }
426 }
427
428 return -EOPNOTSUPP;
429 }
430
pmc_usb_set_orientation(struct typec_switch * sw,enum typec_orientation orientation)431 static int pmc_usb_set_orientation(struct typec_switch *sw,
432 enum typec_orientation orientation)
433 {
434 struct pmc_usb_port *port = typec_switch_get_drvdata(sw);
435
436 update_port_status(port);
437
438 port->orientation = orientation;
439
440 return 0;
441 }
442
pmc_usb_set_role(struct usb_role_switch * sw,enum usb_role role)443 static int pmc_usb_set_role(struct usb_role_switch *sw, enum usb_role role)
444 {
445 struct pmc_usb_port *port = usb_role_switch_get_drvdata(sw);
446 int ret;
447
448 update_port_status(port);
449
450 if (role == USB_ROLE_NONE)
451 ret = pmc_usb_disconnect(port);
452 else
453 ret = pmc_usb_connect(port, role);
454
455 port->role = role;
456
457 return ret;
458 }
459
pmc_usb_register_port(struct pmc_usb * pmc,int index,struct fwnode_handle * fwnode)460 static int pmc_usb_register_port(struct pmc_usb *pmc, int index,
461 struct fwnode_handle *fwnode)
462 {
463 struct pmc_usb_port *port = &pmc->port[index];
464 struct usb_role_switch_desc desc = { };
465 struct typec_switch_desc sw_desc = { };
466 struct typec_mux_desc mux_desc = { };
467 const char *str;
468 int ret;
469
470 ret = fwnode_property_read_u8(fwnode, "usb2-port-number", &port->usb2_port);
471 if (ret)
472 return ret;
473
474 ret = fwnode_property_read_u8(fwnode, "usb3-port-number", &port->usb3_port);
475 if (ret)
476 return ret;
477
478 ret = fwnode_property_read_string(fwnode, "sbu-orientation", &str);
479 if (!ret)
480 port->sbu_orientation = typec_find_orientation(str);
481
482 ret = fwnode_property_read_string(fwnode, "hsl-orientation", &str);
483 if (!ret)
484 port->hsl_orientation = typec_find_orientation(str);
485
486 port->num = index;
487 port->pmc = pmc;
488
489 sw_desc.fwnode = fwnode;
490 sw_desc.drvdata = port;
491 sw_desc.name = fwnode_get_name(fwnode);
492 sw_desc.set = pmc_usb_set_orientation;
493
494 port->typec_sw = typec_switch_register(pmc->dev, &sw_desc);
495 if (IS_ERR(port->typec_sw))
496 return PTR_ERR(port->typec_sw);
497
498 mux_desc.fwnode = fwnode;
499 mux_desc.drvdata = port;
500 mux_desc.name = fwnode_get_name(fwnode);
501 mux_desc.set = pmc_usb_mux_set;
502
503 port->typec_mux = typec_mux_register(pmc->dev, &mux_desc);
504 if (IS_ERR(port->typec_mux)) {
505 ret = PTR_ERR(port->typec_mux);
506 goto err_unregister_switch;
507 }
508
509 desc.fwnode = fwnode;
510 desc.driver_data = port;
511 desc.name = fwnode_get_name(fwnode);
512 desc.set = pmc_usb_set_role;
513
514 port->usb_sw = usb_role_switch_register(pmc->dev, &desc);
515 if (IS_ERR(port->usb_sw)) {
516 ret = PTR_ERR(port->usb_sw);
517 goto err_unregister_mux;
518 }
519
520 return 0;
521
522 err_unregister_mux:
523 typec_mux_unregister(port->typec_mux);
524
525 err_unregister_switch:
526 typec_switch_unregister(port->typec_sw);
527
528 return ret;
529 }
530
is_memory(struct acpi_resource * res,void * data)531 static int is_memory(struct acpi_resource *res, void *data)
532 {
533 struct resource r;
534
535 return !acpi_dev_resource_memory(res, &r);
536 }
537
pmc_usb_probe_iom(struct pmc_usb * pmc)538 static int pmc_usb_probe_iom(struct pmc_usb *pmc)
539 {
540 struct list_head resource_list;
541 struct resource_entry *rentry;
542 struct acpi_device *adev;
543 int ret;
544
545 adev = acpi_dev_get_first_match_dev("INTC1072", NULL, -1);
546 if (!adev)
547 return -ENODEV;
548
549 INIT_LIST_HEAD(&resource_list);
550 ret = acpi_dev_get_resources(adev, &resource_list, is_memory, NULL);
551 if (ret < 0)
552 return ret;
553
554 rentry = list_first_entry_or_null(&resource_list, struct resource_entry, node);
555 if (rentry)
556 pmc->iom_base = devm_ioremap_resource(pmc->dev, rentry->res);
557
558 acpi_dev_free_resource_list(&resource_list);
559
560 if (!pmc->iom_base) {
561 put_device(&adev->dev);
562 return -ENOMEM;
563 }
564
565 pmc->iom_adev = adev;
566
567 return 0;
568 }
569
pmc_usb_probe(struct platform_device * pdev)570 static int pmc_usb_probe(struct platform_device *pdev)
571 {
572 struct fwnode_handle *fwnode = NULL;
573 struct pmc_usb *pmc;
574 int i = 0;
575 int ret;
576
577 pmc = devm_kzalloc(&pdev->dev, sizeof(*pmc), GFP_KERNEL);
578 if (!pmc)
579 return -ENOMEM;
580
581 device_for_each_child_node(&pdev->dev, fwnode)
582 pmc->num_ports++;
583
584 /* The IOM microcontroller has a limitation of max 4 ports. */
585 if (pmc->num_ports > 4) {
586 dev_err(&pdev->dev, "driver limited to 4 ports\n");
587 return -ERANGE;
588 }
589
590 pmc->port = devm_kcalloc(&pdev->dev, pmc->num_ports,
591 sizeof(struct pmc_usb_port), GFP_KERNEL);
592 if (!pmc->port)
593 return -ENOMEM;
594
595 pmc->ipc = devm_intel_scu_ipc_dev_get(&pdev->dev);
596 if (!pmc->ipc)
597 return -ENODEV;
598
599 pmc->dev = &pdev->dev;
600
601 ret = pmc_usb_probe_iom(pmc);
602 if (ret)
603 return ret;
604
605 /*
606 * For every physical USB connector (USB2 and USB3 combo) there is a
607 * child ACPI device node under the PMC mux ACPI device object.
608 */
609 for (i = 0; i < pmc->num_ports; i++) {
610 fwnode = device_get_next_child_node(pmc->dev, fwnode);
611 if (!fwnode)
612 break;
613
614 ret = pmc_usb_register_port(pmc, i, fwnode);
615 if (ret)
616 goto err_remove_ports;
617 }
618
619 platform_set_drvdata(pdev, pmc);
620
621 return 0;
622
623 err_remove_ports:
624 for (i = 0; i < pmc->num_ports; i++) {
625 typec_switch_unregister(pmc->port[i].typec_sw);
626 typec_mux_unregister(pmc->port[i].typec_mux);
627 usb_role_switch_unregister(pmc->port[i].usb_sw);
628 }
629
630 put_device(&pmc->iom_adev->dev);
631
632 return ret;
633 }
634
pmc_usb_remove(struct platform_device * pdev)635 static int pmc_usb_remove(struct platform_device *pdev)
636 {
637 struct pmc_usb *pmc = platform_get_drvdata(pdev);
638 int i;
639
640 for (i = 0; i < pmc->num_ports; i++) {
641 typec_switch_unregister(pmc->port[i].typec_sw);
642 typec_mux_unregister(pmc->port[i].typec_mux);
643 usb_role_switch_unregister(pmc->port[i].usb_sw);
644 }
645
646 put_device(&pmc->iom_adev->dev);
647
648 return 0;
649 }
650
651 static const struct acpi_device_id pmc_usb_acpi_ids[] = {
652 { "INTC105C", },
653 { }
654 };
655 MODULE_DEVICE_TABLE(acpi, pmc_usb_acpi_ids);
656
657 static struct platform_driver pmc_usb_driver = {
658 .driver = {
659 .name = "intel_pmc_usb",
660 .acpi_match_table = ACPI_PTR(pmc_usb_acpi_ids),
661 },
662 .probe = pmc_usb_probe,
663 .remove = pmc_usb_remove,
664 };
665
666 module_platform_driver(pmc_usb_driver);
667
668 MODULE_AUTHOR("Heikki Krogerus <heikki.krogerus@linux.intel.com>");
669 MODULE_LICENSE("GPL v2");
670 MODULE_DESCRIPTION("Intel PMC USB mux control");
671