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