]> Git Repo - linux.git/blob - drivers/platform/x86/dell/dcdbas.c
Linux 6.14-rc3
[linux.git] / drivers / platform / x86 / dell / dcdbas.c
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  *  dcdbas.c: Dell Systems Management Base Driver
4  *
5  *  The Dell Systems Management Base Driver provides a sysfs interface for
6  *  systems management software to perform System Management Interrupts (SMIs)
7  *  and Host Control Actions (power cycle or power off after OS shutdown) on
8  *  Dell systems.
9  *
10  *  See Documentation/userspace-api/dcdbas.rst for more information.
11  *
12  *  Copyright (C) 1995-2006 Dell Inc.
13  */
14
15 #include <linux/platform_device.h>
16 #include <linux/acpi.h>
17 #include <linux/dma-mapping.h>
18 #include <linux/dmi.h>
19 #include <linux/errno.h>
20 #include <linux/cpu.h>
21 #include <linux/gfp.h>
22 #include <linux/init.h>
23 #include <linux/io.h>
24 #include <linux/kernel.h>
25 #include <linux/mc146818rtc.h>
26 #include <linux/module.h>
27 #include <linux/reboot.h>
28 #include <linux/sched.h>
29 #include <linux/smp.h>
30 #include <linux/spinlock.h>
31 #include <linux/string.h>
32 #include <linux/sysfs.h>
33 #include <linux/types.h>
34 #include <linux/mutex.h>
35
36 #include "dcdbas.h"
37
38 #define DRIVER_NAME             "dcdbas"
39 #define DRIVER_VERSION          "5.6.0-3.4"
40 #define DRIVER_DESCRIPTION      "Dell Systems Management Base Driver"
41
42 static struct platform_device *dcdbas_pdev;
43
44 static unsigned long max_smi_data_buf_size = MAX_SMI_DATA_BUF_SIZE;
45 static DEFINE_MUTEX(smi_data_lock);
46 static u8 *bios_buffer;
47 static struct smi_buffer smi_buf;
48
49 static unsigned int host_control_action;
50 static unsigned int host_control_smi_type;
51 static unsigned int host_control_on_shutdown;
52
53 static bool wsmt_enabled;
54
55 int dcdbas_smi_alloc(struct smi_buffer *smi_buffer, unsigned long size)
56 {
57         smi_buffer->virt = dma_alloc_coherent(&dcdbas_pdev->dev, size,
58                                               &smi_buffer->dma, GFP_KERNEL);
59         if (!smi_buffer->virt) {
60                 dev_dbg(&dcdbas_pdev->dev,
61                         "%s: failed to allocate memory size %lu\n",
62                         __func__, size);
63                 return -ENOMEM;
64         }
65         smi_buffer->size = size;
66
67         dev_dbg(&dcdbas_pdev->dev, "%s: phys: %x size: %lu\n",
68                 __func__, (u32)smi_buffer->dma, smi_buffer->size);
69
70         return 0;
71 }
72 EXPORT_SYMBOL_GPL(dcdbas_smi_alloc);
73
74 void dcdbas_smi_free(struct smi_buffer *smi_buffer)
75 {
76         if (!smi_buffer->virt)
77                 return;
78
79         dev_dbg(&dcdbas_pdev->dev, "%s: phys: %x size: %lu\n",
80                 __func__, (u32)smi_buffer->dma, smi_buffer->size);
81         dma_free_coherent(&dcdbas_pdev->dev, smi_buffer->size,
82                           smi_buffer->virt, smi_buffer->dma);
83         smi_buffer->virt = NULL;
84         smi_buffer->dma = 0;
85         smi_buffer->size = 0;
86 }
87 EXPORT_SYMBOL_GPL(dcdbas_smi_free);
88
89 /**
90  * smi_data_buf_free: free SMI data buffer
91  */
92 static void smi_data_buf_free(void)
93 {
94         if (!smi_buf.virt || wsmt_enabled)
95                 return;
96
97         dcdbas_smi_free(&smi_buf);
98 }
99
100 /**
101  * smi_data_buf_realloc: grow SMI data buffer if needed
102  */
103 static int smi_data_buf_realloc(unsigned long size)
104 {
105         struct smi_buffer tmp;
106         int ret;
107
108         if (smi_buf.size >= size)
109                 return 0;
110
111         if (size > max_smi_data_buf_size)
112                 return -EINVAL;
113
114         /* new buffer is needed */
115         ret = dcdbas_smi_alloc(&tmp, size);
116         if (ret)
117                 return ret;
118
119         /* memory zeroed by dma_alloc_coherent */
120         if (smi_buf.virt)
121                 memcpy(tmp.virt, smi_buf.virt, smi_buf.size);
122
123         /* free any existing buffer */
124         smi_data_buf_free();
125
126         /* set up new buffer for use */
127         smi_buf = tmp;
128
129         return 0;
130 }
131
132 static ssize_t smi_data_buf_phys_addr_show(struct device *dev,
133                                            struct device_attribute *attr,
134                                            char *buf)
135 {
136         return sysfs_emit(buf, "%x\n", (u32)smi_buf.dma);
137 }
138
139 static ssize_t smi_data_buf_size_show(struct device *dev,
140                                       struct device_attribute *attr,
141                                       char *buf)
142 {
143         return sysfs_emit(buf, "%lu\n", smi_buf.size);
144 }
145
146 static ssize_t smi_data_buf_size_store(struct device *dev,
147                                        struct device_attribute *attr,
148                                        const char *buf, size_t count)
149 {
150         unsigned long buf_size;
151         ssize_t ret;
152
153         buf_size = simple_strtoul(buf, NULL, 10);
154
155         /* make sure SMI data buffer is at least buf_size */
156         mutex_lock(&smi_data_lock);
157         ret = smi_data_buf_realloc(buf_size);
158         mutex_unlock(&smi_data_lock);
159         if (ret)
160                 return ret;
161
162         return count;
163 }
164
165 static ssize_t smi_data_read(struct file *filp, struct kobject *kobj,
166                              const struct bin_attribute *bin_attr,
167                              char *buf, loff_t pos, size_t count)
168 {
169         ssize_t ret;
170
171         mutex_lock(&smi_data_lock);
172         ret = memory_read_from_buffer(buf, count, &pos, smi_buf.virt,
173                                         smi_buf.size);
174         mutex_unlock(&smi_data_lock);
175         return ret;
176 }
177
178 static ssize_t smi_data_write(struct file *filp, struct kobject *kobj,
179                               const struct bin_attribute *bin_attr,
180                               char *buf, loff_t pos, size_t count)
181 {
182         ssize_t ret;
183
184         if ((pos + count) > max_smi_data_buf_size)
185                 return -EINVAL;
186
187         mutex_lock(&smi_data_lock);
188
189         ret = smi_data_buf_realloc(pos + count);
190         if (ret)
191                 goto out;
192
193         memcpy(smi_buf.virt + pos, buf, count);
194         ret = count;
195 out:
196         mutex_unlock(&smi_data_lock);
197         return ret;
198 }
199
200 static ssize_t host_control_action_show(struct device *dev,
201                                         struct device_attribute *attr,
202                                         char *buf)
203 {
204         return sysfs_emit(buf, "%u\n", host_control_action);
205 }
206
207 static ssize_t host_control_action_store(struct device *dev,
208                                          struct device_attribute *attr,
209                                          const char *buf, size_t count)
210 {
211         ssize_t ret;
212
213         /* make sure buffer is available for host control command */
214         mutex_lock(&smi_data_lock);
215         ret = smi_data_buf_realloc(sizeof(struct apm_cmd));
216         mutex_unlock(&smi_data_lock);
217         if (ret)
218                 return ret;
219
220         host_control_action = simple_strtoul(buf, NULL, 10);
221         return count;
222 }
223
224 static ssize_t host_control_smi_type_show(struct device *dev,
225                                           struct device_attribute *attr,
226                                           char *buf)
227 {
228         return sysfs_emit(buf, "%u\n", host_control_smi_type);
229 }
230
231 static ssize_t host_control_smi_type_store(struct device *dev,
232                                            struct device_attribute *attr,
233                                            const char *buf, size_t count)
234 {
235         host_control_smi_type = simple_strtoul(buf, NULL, 10);
236         return count;
237 }
238
239 static ssize_t host_control_on_shutdown_show(struct device *dev,
240                                              struct device_attribute *attr,
241                                              char *buf)
242 {
243         return sysfs_emit(buf, "%u\n", host_control_on_shutdown);
244 }
245
246 static ssize_t host_control_on_shutdown_store(struct device *dev,
247                                               struct device_attribute *attr,
248                                               const char *buf, size_t count)
249 {
250         host_control_on_shutdown = simple_strtoul(buf, NULL, 10);
251         return count;
252 }
253
254 static int raise_smi(void *par)
255 {
256         struct smi_cmd *smi_cmd = par;
257
258         if (smp_processor_id() != 0) {
259                 dev_dbg(&dcdbas_pdev->dev, "%s: failed to get CPU 0\n",
260                         __func__);
261                 return -EBUSY;
262         }
263
264         /* generate SMI */
265         /* inb to force posted write through and make SMI happen now */
266         asm volatile (
267                 "outb %b0,%w1\n"
268                 "inb %w1"
269                 : /* no output args */
270                 : "a" (smi_cmd->command_code),
271                   "d" (smi_cmd->command_address),
272                   "b" (smi_cmd->ebx),
273                   "c" (smi_cmd->ecx)
274                 : "memory"
275         );
276
277         return 0;
278 }
279 /**
280  * dcdbas_smi_request: generate SMI request
281  *
282  * Called with smi_data_lock.
283  */
284 int dcdbas_smi_request(struct smi_cmd *smi_cmd)
285 {
286         int ret;
287
288         if (smi_cmd->magic != SMI_CMD_MAGIC) {
289                 dev_info(&dcdbas_pdev->dev, "%s: invalid magic value\n",
290                          __func__);
291                 return -EBADR;
292         }
293
294         /* SMI requires CPU 0 */
295         cpus_read_lock();
296         ret = smp_call_on_cpu(0, raise_smi, smi_cmd, true);
297         cpus_read_unlock();
298
299         return ret;
300 }
301 EXPORT_SYMBOL(dcdbas_smi_request);
302
303 /**
304  * smi_request_store:
305  *
306  * The valid values are:
307  * 0: zero SMI data buffer
308  * 1: generate calling interface SMI
309  * 2: generate raw SMI
310  *
311  * User application writes smi_cmd to smi_data before telling driver
312  * to generate SMI.
313  */
314 static ssize_t smi_request_store(struct device *dev,
315                                  struct device_attribute *attr,
316                                  const char *buf, size_t count)
317 {
318         struct smi_cmd *smi_cmd;
319         unsigned long val = simple_strtoul(buf, NULL, 10);
320         ssize_t ret;
321
322         mutex_lock(&smi_data_lock);
323
324         if (smi_buf.size < sizeof(struct smi_cmd)) {
325                 ret = -ENODEV;
326                 goto out;
327         }
328         smi_cmd = (struct smi_cmd *)smi_buf.virt;
329
330         switch (val) {
331         case 2:
332                 /* Raw SMI */
333                 ret = dcdbas_smi_request(smi_cmd);
334                 if (!ret)
335                         ret = count;
336                 break;
337         case 1:
338                 /*
339                  * Calling Interface SMI
340                  *
341                  * Provide physical address of command buffer field within
342                  * the struct smi_cmd to BIOS.
343                  *
344                  * Because the address that smi_cmd (smi_buf.virt) points to
345                  * will be from memremap() of a non-memory address if WSMT
346                  * is present, we can't use virt_to_phys() on smi_cmd, so
347                  * we have to use the physical address that was saved when
348                  * the virtual address for smi_cmd was received.
349                  */
350                 smi_cmd->ebx = (u32)smi_buf.dma +
351                                 offsetof(struct smi_cmd, command_buffer);
352                 ret = dcdbas_smi_request(smi_cmd);
353                 if (!ret)
354                         ret = count;
355                 break;
356         case 0:
357                 memset(smi_buf.virt, 0, smi_buf.size);
358                 ret = count;
359                 break;
360         default:
361                 ret = -EINVAL;
362                 break;
363         }
364
365 out:
366         mutex_unlock(&smi_data_lock);
367         return ret;
368 }
369
370 /**
371  * host_control_smi: generate host control SMI
372  *
373  * Caller must set up the host control command in smi_buf.virt.
374  */
375 static int host_control_smi(void)
376 {
377         struct apm_cmd *apm_cmd;
378         u8 *data;
379         unsigned long flags;
380         u32 num_ticks;
381         s8 cmd_status;
382         u8 index;
383
384         apm_cmd = (struct apm_cmd *)smi_buf.virt;
385         apm_cmd->status = ESM_STATUS_CMD_UNSUCCESSFUL;
386
387         switch (host_control_smi_type) {
388         case HC_SMITYPE_TYPE1:
389                 spin_lock_irqsave(&rtc_lock, flags);
390                 /* write SMI data buffer physical address */
391                 data = (u8 *)&smi_buf.dma;
392                 for (index = PE1300_CMOS_CMD_STRUCT_PTR;
393                      index < (PE1300_CMOS_CMD_STRUCT_PTR + 4);
394                      index++, data++) {
395                         outb(index,
396                              (CMOS_BASE_PORT + CMOS_PAGE2_INDEX_PORT_PIIX4));
397                         outb(*data,
398                              (CMOS_BASE_PORT + CMOS_PAGE2_DATA_PORT_PIIX4));
399                 }
400
401                 /* first set status to -1 as called by spec */
402                 cmd_status = ESM_STATUS_CMD_UNSUCCESSFUL;
403                 outb((u8) cmd_status, PCAT_APM_STATUS_PORT);
404
405                 /* generate SMM call */
406                 outb(ESM_APM_CMD, PCAT_APM_CONTROL_PORT);
407                 spin_unlock_irqrestore(&rtc_lock, flags);
408
409                 /* wait a few to see if it executed */
410                 num_ticks = TIMEOUT_USEC_SHORT_SEMA_BLOCKING;
411                 while ((s8)inb(PCAT_APM_STATUS_PORT) == ESM_STATUS_CMD_UNSUCCESSFUL) {
412                         num_ticks--;
413                         if (num_ticks == EXPIRED_TIMER)
414                                 return -ETIME;
415                 }
416                 break;
417
418         case HC_SMITYPE_TYPE2:
419         case HC_SMITYPE_TYPE3:
420                 spin_lock_irqsave(&rtc_lock, flags);
421                 /* write SMI data buffer physical address */
422                 data = (u8 *)&smi_buf.dma;
423                 for (index = PE1400_CMOS_CMD_STRUCT_PTR;
424                      index < (PE1400_CMOS_CMD_STRUCT_PTR + 4);
425                      index++, data++) {
426                         outb(index, (CMOS_BASE_PORT + CMOS_PAGE1_INDEX_PORT));
427                         outb(*data, (CMOS_BASE_PORT + CMOS_PAGE1_DATA_PORT));
428                 }
429
430                 /* generate SMM call */
431                 if (host_control_smi_type == HC_SMITYPE_TYPE3)
432                         outb(ESM_APM_CMD, PCAT_APM_CONTROL_PORT);
433                 else
434                         outb(ESM_APM_CMD, PE1400_APM_CONTROL_PORT);
435
436                 /* restore RTC index pointer since it was written to above */
437                 CMOS_READ(RTC_REG_C);
438                 spin_unlock_irqrestore(&rtc_lock, flags);
439
440                 /* read control port back to serialize write */
441                 cmd_status = inb(PE1400_APM_CONTROL_PORT);
442
443                 /* wait a few to see if it executed */
444                 num_ticks = TIMEOUT_USEC_SHORT_SEMA_BLOCKING;
445                 while (apm_cmd->status == ESM_STATUS_CMD_UNSUCCESSFUL) {
446                         num_ticks--;
447                         if (num_ticks == EXPIRED_TIMER)
448                                 return -ETIME;
449                 }
450                 break;
451
452         default:
453                 dev_dbg(&dcdbas_pdev->dev, "%s: invalid SMI type %u\n",
454                         __func__, host_control_smi_type);
455                 return -ENOSYS;
456         }
457
458         return 0;
459 }
460
461 /**
462  * dcdbas_host_control: initiate host control
463  *
464  * This function is called by the driver after the system has
465  * finished shutting down if the user application specified a
466  * host control action to perform on shutdown.  It is safe to
467  * use smi_buf.virt at this point because the system has finished
468  * shutting down and no userspace apps are running.
469  */
470 static void dcdbas_host_control(void)
471 {
472         struct apm_cmd *apm_cmd;
473         u8 action;
474
475         if (host_control_action == HC_ACTION_NONE)
476                 return;
477
478         action = host_control_action;
479         host_control_action = HC_ACTION_NONE;
480
481         if (!smi_buf.virt) {
482                 dev_dbg(&dcdbas_pdev->dev, "%s: no SMI buffer\n", __func__);
483                 return;
484         }
485
486         if (smi_buf.size < sizeof(struct apm_cmd)) {
487                 dev_dbg(&dcdbas_pdev->dev, "%s: SMI buffer too small\n",
488                         __func__);
489                 return;
490         }
491
492         apm_cmd = (struct apm_cmd *)smi_buf.virt;
493
494         /* power off takes precedence */
495         if (action & HC_ACTION_HOST_CONTROL_POWEROFF) {
496                 apm_cmd->command = ESM_APM_POWER_CYCLE;
497                 apm_cmd->reserved = 0;
498                 *((s16 *)&apm_cmd->parameters.shortreq.parm[0]) = (s16) 0;
499                 host_control_smi();
500         } else if (action & HC_ACTION_HOST_CONTROL_POWERCYCLE) {
501                 apm_cmd->command = ESM_APM_POWER_CYCLE;
502                 apm_cmd->reserved = 0;
503                 *((s16 *)&apm_cmd->parameters.shortreq.parm[0]) = (s16) 20;
504                 host_control_smi();
505         }
506 }
507
508 /* WSMT */
509
510 static u8 checksum(u8 *buffer, u8 length)
511 {
512         u8 sum = 0;
513         u8 *end = buffer + length;
514
515         while (buffer < end)
516                 sum += *buffer++;
517         return sum;
518 }
519
520 static inline struct smm_eps_table *check_eps_table(u8 *addr)
521 {
522         struct smm_eps_table *eps = (struct smm_eps_table *)addr;
523
524         if (strncmp(eps->smm_comm_buff_anchor, SMM_EPS_SIG, 4) != 0)
525                 return NULL;
526
527         if (checksum(addr, eps->length) != 0)
528                 return NULL;
529
530         return eps;
531 }
532
533 static int dcdbas_check_wsmt(void)
534 {
535         const struct dmi_device *dev = NULL;
536         struct acpi_table_wsmt *wsmt = NULL;
537         struct smm_eps_table *eps = NULL;
538         u64 bios_buf_paddr;
539         u64 remap_size;
540         u8 *addr;
541
542         acpi_get_table(ACPI_SIG_WSMT, 0, (struct acpi_table_header **)&wsmt);
543         if (!wsmt)
544                 return 0;
545
546         /* Check if WSMT ACPI table shows that protection is enabled */
547         if (!(wsmt->protection_flags & ACPI_WSMT_FIXED_COMM_BUFFERS) ||
548             !(wsmt->protection_flags & ACPI_WSMT_COMM_BUFFER_NESTED_PTR_PROTECTION))
549                 return 0;
550
551         /*
552          * BIOS could provide the address/size of the protected buffer
553          * in an SMBIOS string or in an EPS structure in 0xFxxxx.
554          */
555
556         /* Check SMBIOS for buffer address */
557         while ((dev = dmi_find_device(DMI_DEV_TYPE_OEM_STRING, NULL, dev)))
558                 if (sscanf(dev->name, "30[%16llx;%8llx]", &bios_buf_paddr,
559                     &remap_size) == 2)
560                         goto remap;
561
562         /* Scan for EPS (entry point structure) */
563         for (addr = (u8 *)__va(0xf0000);
564              addr < (u8 *)__va(0x100000 - sizeof(struct smm_eps_table));
565              addr += 16) {
566                 eps = check_eps_table(addr);
567                 if (eps)
568                         break;
569         }
570
571         if (!eps) {
572                 dev_dbg(&dcdbas_pdev->dev, "found WSMT, but no firmware buffer found\n");
573                 return -ENODEV;
574         }
575         bios_buf_paddr = eps->smm_comm_buff_addr;
576         remap_size = eps->num_of_4k_pages * PAGE_SIZE;
577
578 remap:
579         /*
580          * Get physical address of buffer and map to virtual address.
581          * Table gives size in 4K pages, regardless of actual system page size.
582          */
583         if (upper_32_bits(bios_buf_paddr + 8)) {
584                 dev_warn(&dcdbas_pdev->dev, "found WSMT, but buffer address is above 4GB\n");
585                 return -EINVAL;
586         }
587         /*
588          * Limit remap size to MAX_SMI_DATA_BUF_SIZE + 8 (since the first 8
589          * bytes are used for a semaphore, not the data buffer itself).
590          */
591         if (remap_size > MAX_SMI_DATA_BUF_SIZE + 8)
592                 remap_size = MAX_SMI_DATA_BUF_SIZE + 8;
593
594         bios_buffer = memremap(bios_buf_paddr, remap_size, MEMREMAP_WB);
595         if (!bios_buffer) {
596                 dev_warn(&dcdbas_pdev->dev, "found WSMT, but failed to map buffer\n");
597                 return -ENOMEM;
598         }
599
600         /* First 8 bytes is for a semaphore, not part of the smi_buf.virt */
601         smi_buf.dma = bios_buf_paddr + 8;
602         smi_buf.virt = bios_buffer + 8;
603         smi_buf.size = remap_size - 8;
604         max_smi_data_buf_size = smi_buf.size;
605         wsmt_enabled = true;
606         dev_info(&dcdbas_pdev->dev,
607                  "WSMT found, using firmware-provided SMI buffer.\n");
608         return 1;
609 }
610
611 /**
612  * dcdbas_reboot_notify: handle reboot notification for host control
613  */
614 static int dcdbas_reboot_notify(struct notifier_block *nb, unsigned long code,
615                                 void *unused)
616 {
617         switch (code) {
618         case SYS_DOWN:
619         case SYS_HALT:
620         case SYS_POWER_OFF:
621                 if (host_control_on_shutdown) {
622                         /* firmware is going to perform host control action */
623                         printk(KERN_WARNING "Please wait for shutdown "
624                                "action to complete...\n");
625                         dcdbas_host_control();
626                 }
627                 break;
628         }
629
630         return NOTIFY_DONE;
631 }
632
633 static struct notifier_block dcdbas_reboot_nb = {
634         .notifier_call = dcdbas_reboot_notify,
635         .next = NULL,
636         .priority = INT_MIN
637 };
638
639 static const BIN_ATTR_ADMIN_RW(smi_data, 0);
640
641 static const struct bin_attribute *const dcdbas_bin_attrs[] = {
642         &bin_attr_smi_data,
643         NULL
644 };
645
646 static DCDBAS_DEV_ATTR_RW(smi_data_buf_size);
647 static DCDBAS_DEV_ATTR_RO(smi_data_buf_phys_addr);
648 static DCDBAS_DEV_ATTR_WO(smi_request);
649 static DCDBAS_DEV_ATTR_RW(host_control_action);
650 static DCDBAS_DEV_ATTR_RW(host_control_smi_type);
651 static DCDBAS_DEV_ATTR_RW(host_control_on_shutdown);
652
653 static struct attribute *dcdbas_dev_attrs[] = {
654         &dev_attr_smi_data_buf_size.attr,
655         &dev_attr_smi_data_buf_phys_addr.attr,
656         &dev_attr_smi_request.attr,
657         &dev_attr_host_control_action.attr,
658         &dev_attr_host_control_smi_type.attr,
659         &dev_attr_host_control_on_shutdown.attr,
660         NULL
661 };
662
663 static const struct attribute_group dcdbas_attr_group = {
664         .attrs = dcdbas_dev_attrs,
665         .bin_attrs_new = dcdbas_bin_attrs,
666 };
667
668 static int dcdbas_probe(struct platform_device *dev)
669 {
670         int error;
671
672         host_control_action = HC_ACTION_NONE;
673         host_control_smi_type = HC_SMITYPE_NONE;
674
675         dcdbas_pdev = dev;
676
677         /* Check if ACPI WSMT table specifies protected SMI buffer address */
678         error = dcdbas_check_wsmt();
679         if (error < 0)
680                 return error;
681
682         /*
683          * BIOS SMI calls require buffer addresses be in 32-bit address space.
684          * This is done by setting the DMA mask below.
685          */
686         error = dma_set_coherent_mask(&dcdbas_pdev->dev, DMA_BIT_MASK(32));
687         if (error)
688                 return error;
689
690         error = sysfs_create_group(&dev->dev.kobj, &dcdbas_attr_group);
691         if (error)
692                 return error;
693
694         register_reboot_notifier(&dcdbas_reboot_nb);
695
696         dev_info(&dev->dev, "%s (version %s)\n",
697                  DRIVER_DESCRIPTION, DRIVER_VERSION);
698
699         return 0;
700 }
701
702 static void dcdbas_remove(struct platform_device *dev)
703 {
704         unregister_reboot_notifier(&dcdbas_reboot_nb);
705         sysfs_remove_group(&dev->dev.kobj, &dcdbas_attr_group);
706 }
707
708 static struct platform_driver dcdbas_driver = {
709         .driver         = {
710                 .name   = DRIVER_NAME,
711         },
712         .probe          = dcdbas_probe,
713         .remove         = dcdbas_remove,
714 };
715
716 static const struct platform_device_info dcdbas_dev_info __initconst = {
717         .name           = DRIVER_NAME,
718         .id             = PLATFORM_DEVID_NONE,
719         .dma_mask       = DMA_BIT_MASK(32),
720 };
721
722 static struct platform_device *dcdbas_pdev_reg;
723
724 /**
725  * dcdbas_init: initialize driver
726  */
727 static int __init dcdbas_init(void)
728 {
729         int error;
730
731         error = platform_driver_register(&dcdbas_driver);
732         if (error)
733                 return error;
734
735         dcdbas_pdev_reg = platform_device_register_full(&dcdbas_dev_info);
736         if (IS_ERR(dcdbas_pdev_reg)) {
737                 error = PTR_ERR(dcdbas_pdev_reg);
738                 goto err_unregister_driver;
739         }
740
741         return 0;
742
743  err_unregister_driver:
744         platform_driver_unregister(&dcdbas_driver);
745         return error;
746 }
747
748 /**
749  * dcdbas_exit: perform driver cleanup
750  */
751 static void __exit dcdbas_exit(void)
752 {
753         /*
754          * make sure functions that use dcdbas_pdev are called
755          * before platform_device_unregister
756          */
757         unregister_reboot_notifier(&dcdbas_reboot_nb);
758
759         /*
760          * We have to free the buffer here instead of dcdbas_remove
761          * because only in module exit function we can be sure that
762          * all sysfs attributes belonging to this module have been
763          * released.
764          */
765         if (dcdbas_pdev)
766                 smi_data_buf_free();
767         if (bios_buffer)
768                 memunmap(bios_buffer);
769         platform_device_unregister(dcdbas_pdev_reg);
770         platform_driver_unregister(&dcdbas_driver);
771 }
772
773 subsys_initcall_sync(dcdbas_init);
774 module_exit(dcdbas_exit);
775
776 MODULE_DESCRIPTION(DRIVER_DESCRIPTION " (version " DRIVER_VERSION ")");
777 MODULE_VERSION(DRIVER_VERSION);
778 MODULE_AUTHOR("Dell Inc.");
779 MODULE_LICENSE("GPL");
780 /* Any System or BIOS claiming to be by Dell */
781 MODULE_ALIAS("dmi:*:[bs]vnD[Ee][Ll][Ll]*:*");
This page took 0.073479 seconds and 4 git commands to generate.