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