1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Intel On Demand (Software Defined Silicon) driver 4 * 5 * Copyright (c) 2022, Intel Corporation. 6 * All Rights Reserved. 7 * 8 * Author: "David E. Box" <david.e.box@linux.intel.com> 9 */ 10 11 #include <linux/auxiliary_bus.h> 12 #include <linux/bits.h> 13 #include <linux/bitfield.h> 14 #include <linux/device.h> 15 #include <linux/iopoll.h> 16 #include <linux/kernel.h> 17 #include <linux/module.h> 18 #include <linux/overflow.h> 19 #include <linux/pci.h> 20 #include <linux/slab.h> 21 #include <linux/sysfs.h> 22 #include <linux/types.h> 23 #include <linux/uaccess.h> 24 25 #include "vsec.h" 26 27 #define ACCESS_TYPE_BARID 2 28 #define ACCESS_TYPE_LOCAL 3 29 30 #define SDSI_MIN_SIZE_DWORDS 276 31 #define SDSI_SIZE_MAILBOX 1024 32 #define SDSI_SIZE_REGS 80 33 #define SDSI_SIZE_CMD sizeof(u64) 34 35 /* 36 * Write messages are currently up to the size of the mailbox 37 * while read messages are up to 4 times the size of the 38 * mailbox, sent in packets 39 */ 40 #define SDSI_SIZE_WRITE_MSG SDSI_SIZE_MAILBOX 41 #define SDSI_SIZE_READ_MSG (SDSI_SIZE_MAILBOX * 4) 42 43 #define SDSI_ENABLED_FEATURES_OFFSET 16 44 #define SDSI_FEATURE_SDSI BIT(3) 45 #define SDSI_FEATURE_METERING BIT(26) 46 47 #define SDSI_SOCKET_ID_OFFSET 64 48 #define SDSI_SOCKET_ID GENMASK(3, 0) 49 50 #define SDSI_MBOX_CMD_SUCCESS 0x40 51 #define SDSI_MBOX_CMD_TIMEOUT 0x80 52 53 #define MBOX_TIMEOUT_US 500000 54 #define MBOX_TIMEOUT_ACQUIRE_US 1000 55 #define MBOX_POLLING_PERIOD_US 100 56 #define MBOX_ACQUIRE_NUM_RETRIES 5 57 #define MBOX_ACQUIRE_RETRY_DELAY_MS 500 58 #define MBOX_MAX_PACKETS 4 59 60 #define MBOX_OWNER_NONE 0x00 61 #define MBOX_OWNER_INBAND 0x01 62 63 #define CTRL_RUN_BUSY BIT(0) 64 #define CTRL_READ_WRITE BIT(1) 65 #define CTRL_SOM BIT(2) 66 #define CTRL_EOM BIT(3) 67 #define CTRL_OWNER GENMASK(5, 4) 68 #define CTRL_COMPLETE BIT(6) 69 #define CTRL_READY BIT(7) 70 #define CTRL_INBAND_LOCK BIT(32) 71 #define CTRL_METER_ENABLE_DRAM BIT(33) 72 #define CTRL_STATUS GENMASK(15, 8) 73 #define CTRL_PACKET_SIZE GENMASK(31, 16) 74 #define CTRL_MSG_SIZE GENMASK(63, 48) 75 76 #define DISC_TABLE_SIZE 12 77 #define DT_ACCESS_TYPE GENMASK(3, 0) 78 #define DT_SIZE GENMASK(27, 12) 79 #define DT_TBIR GENMASK(2, 0) 80 #define DT_OFFSET(v) ((v) & GENMASK(31, 3)) 81 82 #define SDSI_GUID_V1 0x006DD191 83 #define GUID_V1_CNTRL_SIZE 8 84 #define GUID_V1_REGS_SIZE 72 85 #define SDSI_GUID_V2 0xF210D9EF 86 #define GUID_V2_CNTRL_SIZE 16 87 #define GUID_V2_REGS_SIZE 80 88 89 enum sdsi_command { 90 SDSI_CMD_PROVISION_AKC = 0x0004, 91 SDSI_CMD_PROVISION_CAP = 0x0008, 92 SDSI_CMD_READ_STATE = 0x0010, 93 SDSI_CMD_READ_METER = 0x0014, 94 }; 95 96 struct sdsi_mbox_info { 97 u64 *payload; 98 void *buffer; 99 u64 control_flags; 100 int size; 101 }; 102 103 struct disc_table { 104 u32 access_info; 105 u32 guid; 106 u32 offset; 107 }; 108 109 struct sdsi_priv { 110 struct mutex mb_lock; /* Mailbox access lock */ 111 struct device *dev; 112 void __iomem *control_addr; 113 void __iomem *mbox_addr; 114 void __iomem *regs_addr; 115 int control_size; 116 int maibox_size; 117 int registers_size; 118 u32 guid; 119 u32 features; 120 }; 121 122 /* SDSi mailbox operations must be performed using 64bit mov instructions */ 123 static __always_inline void 124 sdsi_memcpy64_toio(u64 __iomem *to, const u64 *from, size_t count_bytes) 125 { 126 size_t count = count_bytes / sizeof(*to); 127 int i; 128 129 for (i = 0; i < count; i++) 130 writeq(from[i], &to[i]); 131 } 132 133 static __always_inline void 134 sdsi_memcpy64_fromio(u64 *to, const u64 __iomem *from, size_t count_bytes) 135 { 136 size_t count = count_bytes / sizeof(*to); 137 int i; 138 139 for (i = 0; i < count; i++) 140 to[i] = readq(&from[i]); 141 } 142 143 static inline void sdsi_complete_transaction(struct sdsi_priv *priv) 144 { 145 u64 control = FIELD_PREP(CTRL_COMPLETE, 1); 146 147 lockdep_assert_held(&priv->mb_lock); 148 writeq(control, priv->control_addr); 149 } 150 151 static int sdsi_status_to_errno(u32 status) 152 { 153 switch (status) { 154 case SDSI_MBOX_CMD_SUCCESS: 155 return 0; 156 case SDSI_MBOX_CMD_TIMEOUT: 157 return -ETIMEDOUT; 158 default: 159 return -EIO; 160 } 161 } 162 163 static int sdsi_mbox_poll(struct sdsi_priv *priv, struct sdsi_mbox_info *info, 164 size_t *data_size) 165 { 166 struct device *dev = priv->dev; 167 u32 total, loop, eom, status, message_size; 168 u64 control; 169 int ret; 170 171 lockdep_assert_held(&priv->mb_lock); 172 173 /* For reads, data sizes that are larger than the mailbox size are read in packets. */ 174 total = 0; 175 loop = 0; 176 do { 177 u32 packet_size; 178 179 /* Poll on ready bit */ 180 ret = readq_poll_timeout(priv->control_addr, control, control & CTRL_READY, 181 MBOX_POLLING_PERIOD_US, MBOX_TIMEOUT_US); 182 if (ret) 183 break; 184 185 eom = FIELD_GET(CTRL_EOM, control); 186 status = FIELD_GET(CTRL_STATUS, control); 187 packet_size = FIELD_GET(CTRL_PACKET_SIZE, control); 188 message_size = FIELD_GET(CTRL_MSG_SIZE, control); 189 190 ret = sdsi_status_to_errno(status); 191 if (ret) 192 break; 193 194 if (!packet_size) { 195 sdsi_complete_transaction(priv); 196 break; 197 } 198 199 /* Only the last packet can be less than the mailbox size. */ 200 if (!eom && packet_size != SDSI_SIZE_MAILBOX) { 201 dev_err(dev, "Invalid packet size\n"); 202 ret = -EPROTO; 203 break; 204 } 205 206 if (packet_size > SDSI_SIZE_MAILBOX) { 207 dev_err(dev, "Packet size too large\n"); 208 ret = -EPROTO; 209 break; 210 } 211 212 if (info->buffer) { 213 void *buf = info->buffer + array_size(SDSI_SIZE_MAILBOX, loop); 214 215 sdsi_memcpy64_fromio(buf, priv->mbox_addr, 216 round_up(packet_size, SDSI_SIZE_CMD)); 217 total += packet_size; 218 } 219 220 sdsi_complete_transaction(priv); 221 } while (!eom && ++loop < MBOX_MAX_PACKETS); 222 223 if (ret) { 224 sdsi_complete_transaction(priv); 225 return ret; 226 } 227 228 if (!eom) { 229 dev_err(dev, "Exceeded read attempts\n"); 230 return -EPROTO; 231 } 232 233 /* Message size check is only valid for multi-packet transfers */ 234 if (loop && total != message_size) 235 dev_warn(dev, "Read count %u differs from expected count %u\n", 236 total, message_size); 237 238 if (data_size) 239 *data_size = total; 240 241 return 0; 242 } 243 244 static int sdsi_mbox_cmd_read(struct sdsi_priv *priv, struct sdsi_mbox_info *info, 245 size_t *data_size) 246 { 247 u64 control; 248 249 lockdep_assert_held(&priv->mb_lock); 250 251 /* Format and send the read command */ 252 control = FIELD_PREP(CTRL_EOM, 1) | 253 FIELD_PREP(CTRL_SOM, 1) | 254 FIELD_PREP(CTRL_RUN_BUSY, 1) | 255 FIELD_PREP(CTRL_PACKET_SIZE, info->size) | 256 info->control_flags; 257 writeq(control, priv->control_addr); 258 259 return sdsi_mbox_poll(priv, info, data_size); 260 } 261 262 static int sdsi_mbox_cmd_write(struct sdsi_priv *priv, struct sdsi_mbox_info *info, 263 size_t *data_size) 264 { 265 u64 control; 266 267 lockdep_assert_held(&priv->mb_lock); 268 269 /* Write rest of the payload */ 270 sdsi_memcpy64_toio(priv->mbox_addr + SDSI_SIZE_CMD, info->payload + 1, 271 info->size - SDSI_SIZE_CMD); 272 273 /* Format and send the write command */ 274 control = FIELD_PREP(CTRL_EOM, 1) | 275 FIELD_PREP(CTRL_SOM, 1) | 276 FIELD_PREP(CTRL_RUN_BUSY, 1) | 277 FIELD_PREP(CTRL_READ_WRITE, 1) | 278 FIELD_PREP(CTRL_MSG_SIZE, info->size) | 279 FIELD_PREP(CTRL_PACKET_SIZE, info->size); 280 writeq(control, priv->control_addr); 281 282 return sdsi_mbox_poll(priv, info, data_size); 283 } 284 285 static int sdsi_mbox_acquire(struct sdsi_priv *priv, struct sdsi_mbox_info *info) 286 { 287 u64 control; 288 u32 owner; 289 int ret, retries = 0; 290 291 lockdep_assert_held(&priv->mb_lock); 292 293 /* Check mailbox is available */ 294 control = readq(priv->control_addr); 295 owner = FIELD_GET(CTRL_OWNER, control); 296 if (owner != MBOX_OWNER_NONE) 297 return -EBUSY; 298 299 /* 300 * If there has been no recent transaction and no one owns the mailbox, 301 * we should acquire it in under 1ms. However, if we've accessed it 302 * recently it may take up to 2.1 seconds to acquire it again. 303 */ 304 do { 305 /* Write first qword of payload */ 306 writeq(info->payload[0], priv->mbox_addr); 307 308 /* Check for ownership */ 309 ret = readq_poll_timeout(priv->control_addr, control, 310 FIELD_GET(CTRL_OWNER, control) == MBOX_OWNER_INBAND, 311 MBOX_POLLING_PERIOD_US, MBOX_TIMEOUT_ACQUIRE_US); 312 313 if (FIELD_GET(CTRL_OWNER, control) == MBOX_OWNER_NONE && 314 retries++ < MBOX_ACQUIRE_NUM_RETRIES) { 315 msleep(MBOX_ACQUIRE_RETRY_DELAY_MS); 316 continue; 317 } 318 319 /* Either we got it or someone else did. */ 320 break; 321 } while (true); 322 323 return ret; 324 } 325 326 static int sdsi_mbox_write(struct sdsi_priv *priv, struct sdsi_mbox_info *info, 327 size_t *data_size) 328 { 329 int ret; 330 331 lockdep_assert_held(&priv->mb_lock); 332 333 ret = sdsi_mbox_acquire(priv, info); 334 if (ret) 335 return ret; 336 337 return sdsi_mbox_cmd_write(priv, info, data_size); 338 } 339 340 static int sdsi_mbox_read(struct sdsi_priv *priv, struct sdsi_mbox_info *info, size_t *data_size) 341 { 342 int ret; 343 344 lockdep_assert_held(&priv->mb_lock); 345 346 ret = sdsi_mbox_acquire(priv, info); 347 if (ret) 348 return ret; 349 350 return sdsi_mbox_cmd_read(priv, info, data_size); 351 } 352 353 static bool sdsi_ib_locked(struct sdsi_priv *priv) 354 { 355 return !!FIELD_GET(CTRL_INBAND_LOCK, readq(priv->control_addr)); 356 } 357 358 static ssize_t sdsi_provision(struct sdsi_priv *priv, char *buf, size_t count, 359 enum sdsi_command command) 360 { 361 struct sdsi_mbox_info info = {}; 362 int ret; 363 364 if (count > (SDSI_SIZE_WRITE_MSG - SDSI_SIZE_CMD)) 365 return -EOVERFLOW; 366 367 /* Make sure In-band lock is not set */ 368 if (sdsi_ib_locked(priv)) 369 return -EPERM; 370 371 /* Qword aligned message + command qword */ 372 info.size = round_up(count, SDSI_SIZE_CMD) + SDSI_SIZE_CMD; 373 374 info.payload = kzalloc(info.size, GFP_KERNEL); 375 if (!info.payload) 376 return -ENOMEM; 377 378 /* Copy message to payload buffer */ 379 memcpy(info.payload, buf, count); 380 381 /* Command is last qword of payload buffer */ 382 info.payload[(info.size - SDSI_SIZE_CMD) / SDSI_SIZE_CMD] = command; 383 384 ret = mutex_lock_interruptible(&priv->mb_lock); 385 if (ret) 386 goto free_payload; 387 388 ret = sdsi_mbox_write(priv, &info, NULL); 389 390 mutex_unlock(&priv->mb_lock); 391 392 free_payload: 393 kfree(info.payload); 394 395 if (ret) 396 return ret; 397 398 return count; 399 } 400 401 static ssize_t provision_akc_write(struct file *filp, struct kobject *kobj, 402 struct bin_attribute *attr, char *buf, loff_t off, 403 size_t count) 404 { 405 struct device *dev = kobj_to_dev(kobj); 406 struct sdsi_priv *priv = dev_get_drvdata(dev); 407 408 if (off) 409 return -ESPIPE; 410 411 return sdsi_provision(priv, buf, count, SDSI_CMD_PROVISION_AKC); 412 } 413 static BIN_ATTR_WO(provision_akc, SDSI_SIZE_WRITE_MSG); 414 415 static ssize_t provision_cap_write(struct file *filp, struct kobject *kobj, 416 struct bin_attribute *attr, char *buf, loff_t off, 417 size_t count) 418 { 419 struct device *dev = kobj_to_dev(kobj); 420 struct sdsi_priv *priv = dev_get_drvdata(dev); 421 422 if (off) 423 return -ESPIPE; 424 425 return sdsi_provision(priv, buf, count, SDSI_CMD_PROVISION_CAP); 426 } 427 static BIN_ATTR_WO(provision_cap, SDSI_SIZE_WRITE_MSG); 428 429 static ssize_t 430 certificate_read(u64 command, u64 control_flags, struct sdsi_priv *priv, 431 char *buf, loff_t off, size_t count) 432 { 433 struct sdsi_mbox_info info = {}; 434 size_t size; 435 int ret; 436 437 if (off) 438 return 0; 439 440 /* Buffer for return data */ 441 info.buffer = kmalloc(SDSI_SIZE_READ_MSG, GFP_KERNEL); 442 if (!info.buffer) 443 return -ENOMEM; 444 445 info.payload = &command; 446 info.size = sizeof(command); 447 info.control_flags = control_flags; 448 449 ret = mutex_lock_interruptible(&priv->mb_lock); 450 if (ret) 451 goto free_buffer; 452 ret = sdsi_mbox_read(priv, &info, &size); 453 mutex_unlock(&priv->mb_lock); 454 if (ret < 0) 455 goto free_buffer; 456 457 if (size > count) 458 size = count; 459 460 memcpy(buf, info.buffer, size); 461 462 free_buffer: 463 kfree(info.buffer); 464 465 if (ret) 466 return ret; 467 468 return size; 469 } 470 471 static ssize_t 472 state_certificate_read(struct file *filp, struct kobject *kobj, 473 struct bin_attribute *attr, char *buf, loff_t off, 474 size_t count) 475 { 476 struct device *dev = kobj_to_dev(kobj); 477 struct sdsi_priv *priv = dev_get_drvdata(dev); 478 479 return certificate_read(SDSI_CMD_READ_STATE, 0, priv, buf, off, count); 480 } 481 static BIN_ATTR_ADMIN_RO(state_certificate, SDSI_SIZE_READ_MSG); 482 483 static ssize_t 484 meter_certificate_read(struct file *filp, struct kobject *kobj, 485 struct bin_attribute *attr, char *buf, loff_t off, 486 size_t count) 487 { 488 struct device *dev = kobj_to_dev(kobj); 489 struct sdsi_priv *priv = dev_get_drvdata(dev); 490 491 return certificate_read(SDSI_CMD_READ_METER, 0, priv, buf, off, count); 492 } 493 static BIN_ATTR_ADMIN_RO(meter_certificate, SDSI_SIZE_READ_MSG); 494 495 static ssize_t 496 meter_current_read(struct file *filp, struct kobject *kobj, 497 struct bin_attribute *attr, char *buf, loff_t off, 498 size_t count) 499 { 500 struct device *dev = kobj_to_dev(kobj); 501 struct sdsi_priv *priv = dev_get_drvdata(dev); 502 503 return certificate_read(SDSI_CMD_READ_METER, CTRL_METER_ENABLE_DRAM, 504 priv, buf, off, count); 505 } 506 static BIN_ATTR_ADMIN_RO(meter_current, SDSI_SIZE_READ_MSG); 507 508 static ssize_t registers_read(struct file *filp, struct kobject *kobj, 509 struct bin_attribute *attr, char *buf, loff_t off, 510 size_t count) 511 { 512 struct device *dev = kobj_to_dev(kobj); 513 struct sdsi_priv *priv = dev_get_drvdata(dev); 514 void __iomem *addr = priv->regs_addr; 515 int size = priv->registers_size; 516 517 /* 518 * The check below is performed by the sysfs caller based on the static 519 * file size. But this may be greater than the actual size which is based 520 * on the GUID. So check here again based on actual size before reading. 521 */ 522 if (off >= size) 523 return 0; 524 525 if (off + count > size) 526 count = size - off; 527 528 memcpy_fromio(buf, addr + off, count); 529 530 return count; 531 } 532 static BIN_ATTR_ADMIN_RO(registers, SDSI_SIZE_REGS); 533 534 static struct bin_attribute *sdsi_bin_attrs[] = { 535 &bin_attr_registers, 536 &bin_attr_state_certificate, 537 &bin_attr_meter_certificate, 538 &bin_attr_meter_current, 539 &bin_attr_provision_akc, 540 &bin_attr_provision_cap, 541 NULL 542 }; 543 544 static umode_t 545 sdsi_battr_is_visible(struct kobject *kobj, struct bin_attribute *attr, int n) 546 { 547 struct device *dev = kobj_to_dev(kobj); 548 struct sdsi_priv *priv = dev_get_drvdata(dev); 549 550 /* Registers file is always readable if the device is present */ 551 if (attr == &bin_attr_registers) 552 return attr->attr.mode; 553 554 /* All other attributes not visible if BIOS has not enabled On Demand */ 555 if (!(priv->features & SDSI_FEATURE_SDSI)) 556 return 0; 557 558 if (attr == &bin_attr_meter_certificate || attr == &bin_attr_meter_current) 559 return (priv->features & SDSI_FEATURE_METERING) ? 560 attr->attr.mode : 0; 561 562 return attr->attr.mode; 563 } 564 565 static ssize_t guid_show(struct device *dev, struct device_attribute *attr, char *buf) 566 { 567 struct sdsi_priv *priv = dev_get_drvdata(dev); 568 569 return sysfs_emit(buf, "0x%x\n", priv->guid); 570 } 571 static DEVICE_ATTR_RO(guid); 572 573 static struct attribute *sdsi_attrs[] = { 574 &dev_attr_guid.attr, 575 NULL 576 }; 577 578 static const struct attribute_group sdsi_group = { 579 .attrs = sdsi_attrs, 580 .bin_attrs = sdsi_bin_attrs, 581 .is_bin_visible = sdsi_battr_is_visible, 582 }; 583 __ATTRIBUTE_GROUPS(sdsi); 584 585 static int sdsi_get_layout(struct sdsi_priv *priv, struct disc_table *table) 586 { 587 switch (table->guid) { 588 case SDSI_GUID_V1: 589 priv->control_size = GUID_V1_CNTRL_SIZE; 590 priv->registers_size = GUID_V1_REGS_SIZE; 591 break; 592 case SDSI_GUID_V2: 593 priv->control_size = GUID_V2_CNTRL_SIZE; 594 priv->registers_size = GUID_V2_REGS_SIZE; 595 break; 596 default: 597 dev_err(priv->dev, "Unrecognized GUID 0x%x\n", table->guid); 598 return -EINVAL; 599 } 600 return 0; 601 } 602 603 static int sdsi_map_mbox_registers(struct sdsi_priv *priv, struct pci_dev *parent, 604 struct disc_table *disc_table, struct resource *disc_res) 605 { 606 u32 access_type = FIELD_GET(DT_ACCESS_TYPE, disc_table->access_info); 607 u32 size = FIELD_GET(DT_SIZE, disc_table->access_info); 608 u32 tbir = FIELD_GET(DT_TBIR, disc_table->offset); 609 u32 offset = DT_OFFSET(disc_table->offset); 610 struct resource res = {}; 611 612 /* Starting location of SDSi MMIO region based on access type */ 613 switch (access_type) { 614 case ACCESS_TYPE_LOCAL: 615 if (tbir) { 616 dev_err(priv->dev, "Unsupported BAR index %u for access type %u\n", 617 tbir, access_type); 618 return -EINVAL; 619 } 620 621 /* 622 * For access_type LOCAL, the base address is as follows: 623 * base address = end of discovery region + base offset + 1 624 */ 625 res.start = disc_res->end + offset + 1; 626 break; 627 628 case ACCESS_TYPE_BARID: 629 res.start = pci_resource_start(parent, tbir) + offset; 630 break; 631 632 default: 633 dev_err(priv->dev, "Unrecognized access_type %u\n", access_type); 634 return -EINVAL; 635 } 636 637 res.end = res.start + size * sizeof(u32) - 1; 638 res.flags = IORESOURCE_MEM; 639 640 priv->control_addr = devm_ioremap_resource(priv->dev, &res); 641 if (IS_ERR(priv->control_addr)) 642 return PTR_ERR(priv->control_addr); 643 644 priv->mbox_addr = priv->control_addr + priv->control_size; 645 priv->regs_addr = priv->mbox_addr + SDSI_SIZE_MAILBOX; 646 647 priv->features = readq(priv->regs_addr + SDSI_ENABLED_FEATURES_OFFSET); 648 649 return 0; 650 } 651 652 static int sdsi_probe(struct auxiliary_device *auxdev, const struct auxiliary_device_id *id) 653 { 654 struct intel_vsec_device *intel_cap_dev = auxdev_to_ivdev(auxdev); 655 struct disc_table disc_table; 656 struct resource *disc_res; 657 void __iomem *disc_addr; 658 struct sdsi_priv *priv; 659 int ret; 660 661 priv = devm_kzalloc(&auxdev->dev, sizeof(*priv), GFP_KERNEL); 662 if (!priv) 663 return -ENOMEM; 664 665 priv->dev = &auxdev->dev; 666 mutex_init(&priv->mb_lock); 667 auxiliary_set_drvdata(auxdev, priv); 668 669 /* Get the SDSi discovery table */ 670 disc_res = &intel_cap_dev->resource[0]; 671 disc_addr = devm_ioremap_resource(&auxdev->dev, disc_res); 672 if (IS_ERR(disc_addr)) 673 return PTR_ERR(disc_addr); 674 675 memcpy_fromio(&disc_table, disc_addr, DISC_TABLE_SIZE); 676 677 priv->guid = disc_table.guid; 678 679 /* Get guid based layout info */ 680 ret = sdsi_get_layout(priv, &disc_table); 681 if (ret) 682 return ret; 683 684 /* Map the SDSi mailbox registers */ 685 ret = sdsi_map_mbox_registers(priv, intel_cap_dev->pcidev, &disc_table, disc_res); 686 if (ret) 687 return ret; 688 689 return 0; 690 } 691 692 static const struct auxiliary_device_id sdsi_aux_id_table[] = { 693 { .name = "intel_vsec.sdsi" }, 694 {} 695 }; 696 MODULE_DEVICE_TABLE(auxiliary, sdsi_aux_id_table); 697 698 static struct auxiliary_driver sdsi_aux_driver = { 699 .driver = { 700 .dev_groups = sdsi_groups, 701 }, 702 .id_table = sdsi_aux_id_table, 703 .probe = sdsi_probe, 704 /* No remove. All resources are handled under devm */ 705 }; 706 module_auxiliary_driver(sdsi_aux_driver); 707 708 MODULE_AUTHOR("David E. Box <david.e.box@linux.intel.com>"); 709 MODULE_DESCRIPTION("Intel On Demand (SDSi) driver"); 710 MODULE_LICENSE("GPL"); 711