1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * USB Power Delivery sysfs entries 4 * 5 * Copyright (C) 2022, Intel Corporation 6 * Author: Heikki Krogerus <heikki.krogerus@linux.intel.com> 7 */ 8 9 #include <linux/slab.h> 10 #include <linux/usb/pd.h> 11 12 #include "pd.h" 13 14 static DEFINE_IDA(pd_ida); 15 16 static struct class pd_class = { 17 .name = "usb_power_delivery", 18 }; 19 20 #define to_pdo(o) container_of(o, struct pdo, dev) 21 22 struct pdo { 23 struct device dev; 24 int object_position; 25 u32 pdo; 26 }; 27 28 static void pdo_release(struct device *dev) 29 { 30 kfree(to_pdo(dev)); 31 } 32 33 /* -------------------------------------------------------------------------- */ 34 /* Fixed Supply */ 35 36 static ssize_t 37 dual_role_power_show(struct device *dev, struct device_attribute *attr, char *buf) 38 { 39 return sysfs_emit(buf, "%u\n", !!(to_pdo(dev)->pdo & PDO_FIXED_DUAL_ROLE)); 40 } 41 static DEVICE_ATTR_RO(dual_role_power); 42 43 static ssize_t 44 usb_suspend_supported_show(struct device *dev, struct device_attribute *attr, char *buf) 45 { 46 return sysfs_emit(buf, "%u\n", !!(to_pdo(dev)->pdo & PDO_FIXED_SUSPEND)); 47 } 48 static DEVICE_ATTR_RO(usb_suspend_supported); 49 50 static ssize_t 51 higher_capability_show(struct device *dev, struct device_attribute *attr, char *buf) 52 { 53 return sysfs_emit(buf, "%u\n", !!(to_pdo(dev)->pdo & PDO_FIXED_HIGHER_CAP)); 54 } 55 static DEVICE_ATTR_RO(higher_capability); 56 57 static ssize_t 58 unconstrained_power_show(struct device *dev, struct device_attribute *attr, char *buf) 59 { 60 return sysfs_emit(buf, "%u\n", !!(to_pdo(dev)->pdo & PDO_FIXED_EXTPOWER)); 61 } 62 static DEVICE_ATTR_RO(unconstrained_power); 63 64 static ssize_t 65 usb_communication_capable_show(struct device *dev, struct device_attribute *attr, char *buf) 66 { 67 return sysfs_emit(buf, "%u\n", !!(to_pdo(dev)->pdo & PDO_FIXED_USB_COMM)); 68 } 69 static DEVICE_ATTR_RO(usb_communication_capable); 70 71 static ssize_t 72 dual_role_data_show(struct device *dev, struct device_attribute *attr, char *buf) 73 { 74 return sysfs_emit(buf, "%u\n", !!(to_pdo(dev)->pdo & PDO_FIXED_DATA_SWAP)); 75 } 76 static DEVICE_ATTR_RO(dual_role_data); 77 78 static ssize_t 79 unchunked_extended_messages_supported_show(struct device *dev, 80 struct device_attribute *attr, char *buf) 81 { 82 return sysfs_emit(buf, "%u\n", !!(to_pdo(dev)->pdo & PDO_FIXED_UNCHUNK_EXT)); 83 } 84 static DEVICE_ATTR_RO(unchunked_extended_messages_supported); 85 86 /* 87 * REVISIT: Peak Current requires access also to the RDO. 88 static ssize_t 89 peak_current_show(struct device *dev, struct device_attribute *attr, char *buf) 90 { 91 ... 92 } 93 */ 94 95 static ssize_t 96 fast_role_swap_current_show(struct device *dev, struct device_attribute *attr, char *buf) 97 { 98 return sysfs_emit(buf, "%u\n", to_pdo(dev)->pdo >> PDO_FIXED_FRS_CURR_SHIFT) & 3; 99 } 100 static DEVICE_ATTR_RO(fast_role_swap_current); 101 102 static ssize_t voltage_show(struct device *dev, struct device_attribute *attr, char *buf) 103 { 104 return sysfs_emit(buf, "%umV\n", pdo_fixed_voltage(to_pdo(dev)->pdo)); 105 } 106 static DEVICE_ATTR_RO(voltage); 107 108 /* Shared with Variable supplies, both source and sink */ 109 static ssize_t current_show(struct device *dev, struct device_attribute *attr, char *buf) 110 { 111 return sysfs_emit(buf, "%umA\n", pdo_max_current(to_pdo(dev)->pdo)); 112 } 113 114 /* Shared with Variable type supplies */ 115 static struct device_attribute maximum_current_attr = { 116 .attr = { 117 .name = "maximum_current", 118 .mode = 0444, 119 }, 120 .show = current_show, 121 }; 122 123 static struct device_attribute operational_current_attr = { 124 .attr = { 125 .name = "operational_current", 126 .mode = 0444, 127 }, 128 .show = current_show, 129 }; 130 131 static struct attribute *source_fixed_supply_attrs[] = { 132 &dev_attr_dual_role_power.attr, 133 &dev_attr_usb_suspend_supported.attr, 134 &dev_attr_unconstrained_power.attr, 135 &dev_attr_usb_communication_capable.attr, 136 &dev_attr_dual_role_data.attr, 137 &dev_attr_unchunked_extended_messages_supported.attr, 138 /*&dev_attr_peak_current.attr,*/ 139 &dev_attr_voltage.attr, 140 &maximum_current_attr.attr, 141 NULL 142 }; 143 144 static umode_t fixed_attr_is_visible(struct kobject *kobj, struct attribute *attr, int n) 145 { 146 if (to_pdo(kobj_to_dev(kobj))->object_position && 147 /*attr != &dev_attr_peak_current.attr &&*/ 148 attr != &dev_attr_voltage.attr && 149 attr != &maximum_current_attr.attr && 150 attr != &operational_current_attr.attr) 151 return 0; 152 153 return attr->mode; 154 } 155 156 static const struct attribute_group source_fixed_supply_group = { 157 .is_visible = fixed_attr_is_visible, 158 .attrs = source_fixed_supply_attrs, 159 }; 160 __ATTRIBUTE_GROUPS(source_fixed_supply); 161 162 static struct device_type source_fixed_supply_type = { 163 .name = "pdo", 164 .release = pdo_release, 165 .groups = source_fixed_supply_groups, 166 }; 167 168 static struct attribute *sink_fixed_supply_attrs[] = { 169 &dev_attr_dual_role_power.attr, 170 &dev_attr_higher_capability.attr, 171 &dev_attr_unconstrained_power.attr, 172 &dev_attr_usb_communication_capable.attr, 173 &dev_attr_dual_role_data.attr, 174 &dev_attr_unchunked_extended_messages_supported.attr, 175 &dev_attr_fast_role_swap_current.attr, 176 &dev_attr_voltage.attr, 177 &operational_current_attr.attr, 178 NULL 179 }; 180 181 static const struct attribute_group sink_fixed_supply_group = { 182 .is_visible = fixed_attr_is_visible, 183 .attrs = sink_fixed_supply_attrs, 184 }; 185 __ATTRIBUTE_GROUPS(sink_fixed_supply); 186 187 static struct device_type sink_fixed_supply_type = { 188 .name = "pdo", 189 .release = pdo_release, 190 .groups = sink_fixed_supply_groups, 191 }; 192 193 /* -------------------------------------------------------------------------- */ 194 /* Variable Supply */ 195 196 static ssize_t 197 maximum_voltage_show(struct device *dev, struct device_attribute *attr, char *buf) 198 { 199 return sysfs_emit(buf, "%umV\n", pdo_max_voltage(to_pdo(dev)->pdo)); 200 } 201 static DEVICE_ATTR_RO(maximum_voltage); 202 203 static ssize_t 204 minimum_voltage_show(struct device *dev, struct device_attribute *attr, char *buf) 205 { 206 return sysfs_emit(buf, "%umV\n", pdo_min_voltage(to_pdo(dev)->pdo)); 207 } 208 static DEVICE_ATTR_RO(minimum_voltage); 209 210 static struct attribute *source_variable_supply_attrs[] = { 211 &dev_attr_maximum_voltage.attr, 212 &dev_attr_minimum_voltage.attr, 213 &maximum_current_attr.attr, 214 NULL 215 }; 216 ATTRIBUTE_GROUPS(source_variable_supply); 217 218 static struct device_type source_variable_supply_type = { 219 .name = "pdo", 220 .release = pdo_release, 221 .groups = source_variable_supply_groups, 222 }; 223 224 static struct attribute *sink_variable_supply_attrs[] = { 225 &dev_attr_maximum_voltage.attr, 226 &dev_attr_minimum_voltage.attr, 227 &operational_current_attr.attr, 228 NULL 229 }; 230 ATTRIBUTE_GROUPS(sink_variable_supply); 231 232 static struct device_type sink_variable_supply_type = { 233 .name = "pdo", 234 .release = pdo_release, 235 .groups = sink_variable_supply_groups, 236 }; 237 238 /* -------------------------------------------------------------------------- */ 239 /* Battery */ 240 241 static ssize_t 242 maximum_power_show(struct device *dev, struct device_attribute *attr, char *buf) 243 { 244 return sysfs_emit(buf, "%umW\n", pdo_max_power(to_pdo(dev)->pdo)); 245 } 246 static DEVICE_ATTR_RO(maximum_power); 247 248 static ssize_t 249 operational_power_show(struct device *dev, struct device_attribute *attr, char *buf) 250 { 251 return sysfs_emit(buf, "%umW\n", pdo_max_power(to_pdo(dev)->pdo)); 252 } 253 static DEVICE_ATTR_RO(operational_power); 254 255 static struct attribute *source_battery_attrs[] = { 256 &dev_attr_maximum_voltage.attr, 257 &dev_attr_minimum_voltage.attr, 258 &dev_attr_maximum_power.attr, 259 NULL 260 }; 261 ATTRIBUTE_GROUPS(source_battery); 262 263 static struct device_type source_battery_type = { 264 .name = "pdo", 265 .release = pdo_release, 266 .groups = source_battery_groups, 267 }; 268 269 static struct attribute *sink_battery_attrs[] = { 270 &dev_attr_maximum_voltage.attr, 271 &dev_attr_minimum_voltage.attr, 272 &dev_attr_operational_power.attr, 273 NULL 274 }; 275 ATTRIBUTE_GROUPS(sink_battery); 276 277 static struct device_type sink_battery_type = { 278 .name = "pdo", 279 .release = pdo_release, 280 .groups = sink_battery_groups, 281 }; 282 283 /* -------------------------------------------------------------------------- */ 284 /* Standard Power Range (SPR) Programmable Power Supply (PPS) */ 285 286 static ssize_t 287 pps_power_limited_show(struct device *dev, struct device_attribute *attr, char *buf) 288 { 289 return sysfs_emit(buf, "%u\n", !!(to_pdo(dev)->pdo & BIT(27))); 290 } 291 static DEVICE_ATTR_RO(pps_power_limited); 292 293 static ssize_t 294 pps_max_voltage_show(struct device *dev, struct device_attribute *attr, char *buf) 295 { 296 return sysfs_emit(buf, "%umV\n", pdo_pps_apdo_max_voltage(to_pdo(dev)->pdo)); 297 } 298 299 static ssize_t 300 pps_min_voltage_show(struct device *dev, struct device_attribute *attr, char *buf) 301 { 302 return sysfs_emit(buf, "%umV\n", pdo_pps_apdo_min_voltage(to_pdo(dev)->pdo)); 303 } 304 305 static ssize_t 306 pps_max_current_show(struct device *dev, struct device_attribute *attr, char *buf) 307 { 308 return sysfs_emit(buf, "%umA\n", pdo_pps_apdo_max_current(to_pdo(dev)->pdo)); 309 } 310 311 static struct device_attribute pps_max_voltage_attr = { 312 .attr = { 313 .name = "maximum_voltage", 314 .mode = 0444, 315 }, 316 .show = pps_max_voltage_show, 317 }; 318 319 static struct device_attribute pps_min_voltage_attr = { 320 .attr = { 321 .name = "minimum_voltage", 322 .mode = 0444, 323 }, 324 .show = pps_min_voltage_show, 325 }; 326 327 static struct device_attribute pps_max_current_attr = { 328 .attr = { 329 .name = "maximum_current", 330 .mode = 0444, 331 }, 332 .show = pps_max_current_show, 333 }; 334 335 static struct attribute *source_pps_attrs[] = { 336 &dev_attr_pps_power_limited.attr, 337 &pps_max_voltage_attr.attr, 338 &pps_min_voltage_attr.attr, 339 &pps_max_current_attr.attr, 340 NULL 341 }; 342 ATTRIBUTE_GROUPS(source_pps); 343 344 static struct device_type source_pps_type = { 345 .name = "pdo", 346 .release = pdo_release, 347 .groups = source_pps_groups, 348 }; 349 350 static struct attribute *sink_pps_attrs[] = { 351 &pps_max_voltage_attr.attr, 352 &pps_min_voltage_attr.attr, 353 &pps_max_current_attr.attr, 354 NULL 355 }; 356 ATTRIBUTE_GROUPS(sink_pps); 357 358 static struct device_type sink_pps_type = { 359 .name = "pdo", 360 .release = pdo_release, 361 .groups = sink_pps_groups, 362 }; 363 364 /* -------------------------------------------------------------------------- */ 365 366 static const char * const supply_name[] = { 367 [PDO_TYPE_FIXED] = "fixed_supply", 368 [PDO_TYPE_BATT] = "battery", 369 [PDO_TYPE_VAR] = "variable_supply", 370 }; 371 372 static const char * const apdo_supply_name[] = { 373 [APDO_TYPE_PPS] = "programmable_supply", 374 }; 375 376 static struct device_type *source_type[] = { 377 [PDO_TYPE_FIXED] = &source_fixed_supply_type, 378 [PDO_TYPE_BATT] = &source_battery_type, 379 [PDO_TYPE_VAR] = &source_variable_supply_type, 380 }; 381 382 static struct device_type *source_apdo_type[] = { 383 [APDO_TYPE_PPS] = &source_pps_type, 384 }; 385 386 static struct device_type *sink_type[] = { 387 [PDO_TYPE_FIXED] = &sink_fixed_supply_type, 388 [PDO_TYPE_BATT] = &sink_battery_type, 389 [PDO_TYPE_VAR] = &sink_variable_supply_type, 390 }; 391 392 static struct device_type *sink_apdo_type[] = { 393 [APDO_TYPE_PPS] = &sink_pps_type, 394 }; 395 396 /* REVISIT: Export when EPR_*_Capabilities need to be supported. */ 397 static int add_pdo(struct usb_power_delivery_capabilities *cap, u32 pdo, int position) 398 { 399 struct device_type *type; 400 const char *name; 401 struct pdo *p; 402 int ret; 403 404 p = kzalloc(sizeof(*p), GFP_KERNEL); 405 if (!p) 406 return -ENOMEM; 407 408 p->pdo = pdo; 409 p->object_position = position; 410 411 if (pdo_type(pdo) == PDO_TYPE_APDO) { 412 /* FIXME: Only PPS supported for now! Skipping others. */ 413 if (pdo_apdo_type(pdo) > APDO_TYPE_PPS) { 414 dev_warn(&cap->dev, "Unknown APDO type. PDO 0x%08x\n", pdo); 415 kfree(p); 416 return 0; 417 } 418 419 if (is_source(cap->role)) 420 type = source_apdo_type[pdo_apdo_type(pdo)]; 421 else 422 type = sink_apdo_type[pdo_apdo_type(pdo)]; 423 424 name = apdo_supply_name[pdo_apdo_type(pdo)]; 425 } else { 426 if (is_source(cap->role)) 427 type = source_type[pdo_type(pdo)]; 428 else 429 type = sink_type[pdo_type(pdo)]; 430 431 name = supply_name[pdo_type(pdo)]; 432 } 433 434 p->dev.parent = &cap->dev; 435 p->dev.type = type; 436 dev_set_name(&p->dev, "%u:%s", position + 1, name); 437 438 ret = device_register(&p->dev); 439 if (ret) { 440 put_device(&p->dev); 441 return ret; 442 } 443 444 return 0; 445 } 446 447 static int remove_pdo(struct device *dev, void *data) 448 { 449 device_unregister(dev); 450 return 0; 451 } 452 453 /* -------------------------------------------------------------------------- */ 454 455 static const char * const cap_name[] = { 456 [TYPEC_SINK] = "sink-capabilities", 457 [TYPEC_SOURCE] = "source-capabilities", 458 }; 459 460 static void pd_capabilities_release(struct device *dev) 461 { 462 kfree(to_usb_power_delivery_capabilities(dev)); 463 } 464 465 static struct device_type pd_capabilities_type = { 466 .name = "capabilities", 467 .release = pd_capabilities_release, 468 }; 469 470 /** 471 * usb_power_delivery_register_capabilities - Register a set of capabilities. 472 * @pd: The USB PD instance that the capabilities belong to. 473 * @desc: Description of the Capablities Message. 474 * 475 * This function registers a Capabilities Message described in @desc. The 476 * capabilities will have their own sub-directory under @pd in sysfs. 477 * 478 * The function returns pointer to struct usb_power_delivery_capabilities, or 479 * ERR_PRT(errno). 480 */ 481 struct usb_power_delivery_capabilities * 482 usb_power_delivery_register_capabilities(struct usb_power_delivery *pd, 483 struct usb_power_delivery_capabilities_desc *desc) 484 { 485 struct usb_power_delivery_capabilities *cap; 486 int ret; 487 int i; 488 489 cap = kzalloc(sizeof(*cap), GFP_KERNEL); 490 if (!cap) 491 return ERR_PTR(-ENOMEM); 492 493 cap->pd = pd; 494 cap->role = desc->role; 495 496 cap->dev.parent = &pd->dev; 497 cap->dev.type = &pd_capabilities_type; 498 dev_set_name(&cap->dev, "%s", cap_name[cap->role]); 499 500 ret = device_register(&cap->dev); 501 if (ret) { 502 put_device(&cap->dev); 503 return ERR_PTR(ret); 504 } 505 506 for (i = 0; i < PDO_MAX_OBJECTS && desc->pdo[i]; i++) { 507 ret = add_pdo(cap, desc->pdo[i], i); 508 if (ret) { 509 usb_power_delivery_unregister_capabilities(cap); 510 return ERR_PTR(ret); 511 } 512 } 513 514 return cap; 515 } 516 EXPORT_SYMBOL_GPL(usb_power_delivery_register_capabilities); 517 518 /** 519 * usb_power_delivery_unregister_capabilities - Unregister a set of capabilities 520 * @cap: The capabilities 521 */ 522 void usb_power_delivery_unregister_capabilities(struct usb_power_delivery_capabilities *cap) 523 { 524 if (!cap) 525 return; 526 527 device_for_each_child(&cap->dev, NULL, remove_pdo); 528 device_unregister(&cap->dev); 529 } 530 EXPORT_SYMBOL_GPL(usb_power_delivery_unregister_capabilities); 531 532 /* -------------------------------------------------------------------------- */ 533 534 static ssize_t revision_show(struct device *dev, struct device_attribute *attr, char *buf) 535 { 536 struct usb_power_delivery *pd = to_usb_power_delivery(dev); 537 538 return sysfs_emit(buf, "%u.%u\n", (pd->revision >> 8) & 0xff, (pd->revision >> 4) & 0xf); 539 } 540 static DEVICE_ATTR_RO(revision); 541 542 static ssize_t version_show(struct device *dev, struct device_attribute *attr, char *buf) 543 { 544 struct usb_power_delivery *pd = to_usb_power_delivery(dev); 545 546 return sysfs_emit(buf, "%u.%u\n", (pd->version >> 8) & 0xff, (pd->version >> 4) & 0xf); 547 } 548 static DEVICE_ATTR_RO(version); 549 550 static struct attribute *pd_attrs[] = { 551 &dev_attr_revision.attr, 552 &dev_attr_version.attr, 553 NULL 554 }; 555 556 static umode_t pd_attr_is_visible(struct kobject *kobj, struct attribute *attr, int n) 557 { 558 struct usb_power_delivery *pd = to_usb_power_delivery(kobj_to_dev(kobj)); 559 560 if (attr == &dev_attr_version.attr && !pd->version) 561 return 0; 562 563 return attr->mode; 564 } 565 566 static const struct attribute_group pd_group = { 567 .is_visible = pd_attr_is_visible, 568 .attrs = pd_attrs, 569 }; 570 __ATTRIBUTE_GROUPS(pd); 571 572 static void pd_release(struct device *dev) 573 { 574 struct usb_power_delivery *pd = to_usb_power_delivery(dev); 575 576 ida_simple_remove(&pd_ida, pd->id); 577 kfree(pd); 578 } 579 580 static struct device_type pd_type = { 581 .name = "usb_power_delivery", 582 .release = pd_release, 583 .groups = pd_groups, 584 }; 585 586 struct usb_power_delivery *usb_power_delivery_find(const char *name) 587 { 588 struct device *dev; 589 590 dev = class_find_device_by_name(&pd_class, name); 591 592 return dev ? to_usb_power_delivery(dev) : NULL; 593 } 594 595 /** 596 * usb_power_delivery_register - Register USB Power Delivery Support. 597 * @parent: Parent device. 598 * @desc: Description of the USB PD contract. 599 * 600 * This routine can be used to register USB Power Delivery capabilities that a 601 * device or devices can support. These capabilities represent all the 602 * capabilities that can be negotiated with a partner, so not only the Power 603 * Capabilities that are negotiated using the USB PD Capabilities Message. 604 * 605 * The USB Power Delivery Support object that this routine generates can be used 606 * as the parent object for all the actual USB Power Delivery Messages and 607 * objects that can be negotiated with the partner. 608 * 609 * Returns handle to struct usb_power_delivery or ERR_PTR. 610 */ 611 struct usb_power_delivery * 612 usb_power_delivery_register(struct device *parent, struct usb_power_delivery_desc *desc) 613 { 614 struct usb_power_delivery *pd; 615 int ret; 616 617 pd = kzalloc(sizeof(*pd), GFP_KERNEL); 618 if (!pd) 619 return ERR_PTR(-ENOMEM); 620 621 ret = ida_simple_get(&pd_ida, 0, 0, GFP_KERNEL); 622 if (ret < 0) { 623 kfree(pd); 624 return ERR_PTR(ret); 625 } 626 627 pd->id = ret; 628 pd->revision = desc->revision; 629 pd->version = desc->version; 630 631 pd->dev.parent = parent; 632 pd->dev.type = &pd_type; 633 pd->dev.class = &pd_class; 634 dev_set_name(&pd->dev, "pd%d", pd->id); 635 636 ret = device_register(&pd->dev); 637 if (ret) { 638 put_device(&pd->dev); 639 return ERR_PTR(ret); 640 } 641 642 return pd; 643 } 644 EXPORT_SYMBOL_GPL(usb_power_delivery_register); 645 646 /** 647 * usb_power_delivery_unregister - Unregister USB Power Delivery Support. 648 * @pd: The USB PD contract. 649 */ 650 void usb_power_delivery_unregister(struct usb_power_delivery *pd) 651 { 652 if (IS_ERR_OR_NULL(pd)) 653 return; 654 655 device_unregister(&pd->dev); 656 } 657 EXPORT_SYMBOL_GPL(usb_power_delivery_unregister); 658 659 /** 660 * usb_power_delivery_link_device - Link device to its USB PD object. 661 * @pd: The USB PD instance. 662 * @dev: The device. 663 * 664 * This function can be used to create a symlink named "usb_power_delivery" for 665 * @dev that points to @pd. 666 */ 667 int usb_power_delivery_link_device(struct usb_power_delivery *pd, struct device *dev) 668 { 669 int ret; 670 671 if (IS_ERR_OR_NULL(pd) || !dev) 672 return 0; 673 674 ret = sysfs_create_link(&dev->kobj, &pd->dev.kobj, "usb_power_delivery"); 675 if (ret) 676 return ret; 677 678 get_device(&pd->dev); 679 get_device(dev); 680 681 return 0; 682 } 683 EXPORT_SYMBOL_GPL(usb_power_delivery_link_device); 684 685 /** 686 * usb_power_delivery_unlink_device - Unlink device from its USB PD object. 687 * @pd: The USB PD instance. 688 * @dev: The device. 689 * 690 * Remove the symlink that was previously created with pd_link_device(). 691 */ 692 void usb_power_delivery_unlink_device(struct usb_power_delivery *pd, struct device *dev) 693 { 694 if (IS_ERR_OR_NULL(pd) || !dev) 695 return; 696 697 sysfs_remove_link(&dev->kobj, "usb_power_delivery"); 698 put_device(&pd->dev); 699 put_device(dev); 700 } 701 EXPORT_SYMBOL_GPL(usb_power_delivery_unlink_device); 702 703 /* -------------------------------------------------------------------------- */ 704 705 int __init usb_power_delivery_init(void) 706 { 707 return class_register(&pd_class); 708 } 709 710 void __exit usb_power_delivery_exit(void) 711 { 712 ida_destroy(&pd_ida); 713 class_unregister(&pd_class); 714 } 715