]> Git Repo - linux.git/blob - drivers/platform/x86/intel/sdsi.c
Merge tag 'drm-xe-next-2024-06-06' of https://gitlab.freedesktop.org/drm/xe/kernel...
[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/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 <[email protected]>");
709 MODULE_DESCRIPTION("Intel On Demand (SDSi) driver");
710 MODULE_LICENSE("GPL");
This page took 0.081537 seconds and 4 git commands to generate.