xref: /linux/drivers/platform/x86/dell/dcdbas.c (revision 4ceb681f1822819f78b747ddc189479fead43be2)
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 			     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 			      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 DCDBAS_BIN_ATTR_RW(smi_data);
640 
641 static struct bin_attribute *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 = 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]*:*");
782