Revert "unicode: Don't special case ignorable code points"
[linux.git] / drivers / mfd / kempld-core.c
blobc5bfb6440a930f5492c6fa1f9b61d50cfc9b4731
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3 * Kontron PLD MFD core driver
5 * Copyright (c) 2010-2013 Kontron Europe GmbH
6 * Author: Michael Brunner <michael.brunner@kontron.com>
7 */
9 #include <linux/err.h>
10 #include <linux/platform_device.h>
11 #include <linux/mfd/core.h>
12 #include <linux/mfd/kempld.h>
13 #include <linux/mod_devicetable.h>
14 #include <linux/module.h>
15 #include <linux/property.h>
16 #include <linux/dmi.h>
17 #include <linux/io.h>
18 #include <linux/delay.h>
19 #include <linux/sysfs.h>
21 #define MAX_ID_LEN 4
22 static char force_device_id[MAX_ID_LEN + 1] = "";
23 module_param_string(force_device_id, force_device_id,
24 sizeof(force_device_id), 0);
25 MODULE_PARM_DESC(force_device_id, "Override detected product");
28 * Get hardware mutex to block firmware from accessing the pld.
29 * It is possible for the firmware may hold the mutex for an extended length of
30 * time. This function will block until access has been granted.
32 static void kempld_get_hardware_mutex(struct kempld_device_data *pld)
34 /* The mutex bit will read 1 until access has been granted */
35 while (ioread8(pld->io_index) & KEMPLD_MUTEX_KEY)
36 usleep_range(1000, 3000);
39 static void kempld_release_hardware_mutex(struct kempld_device_data *pld)
41 /* The harware mutex is released when 1 is written to the mutex bit. */
42 iowrite8(KEMPLD_MUTEX_KEY, pld->io_index);
45 static int kempld_get_info_generic(struct kempld_device_data *pld)
47 u16 version;
48 u8 spec;
50 kempld_get_mutex(pld);
52 version = kempld_read16(pld, KEMPLD_VERSION);
53 spec = kempld_read8(pld, KEMPLD_SPEC);
54 pld->info.buildnr = kempld_read16(pld, KEMPLD_BUILDNR);
56 pld->info.minor = KEMPLD_VERSION_GET_MINOR(version);
57 pld->info.major = KEMPLD_VERSION_GET_MAJOR(version);
58 pld->info.number = KEMPLD_VERSION_GET_NUMBER(version);
59 pld->info.type = KEMPLD_VERSION_GET_TYPE(version);
61 if (spec == 0xff) {
62 pld->info.spec_minor = 0;
63 pld->info.spec_major = 1;
64 } else {
65 pld->info.spec_minor = KEMPLD_SPEC_GET_MINOR(spec);
66 pld->info.spec_major = KEMPLD_SPEC_GET_MAJOR(spec);
69 if (pld->info.spec_major > 0)
70 pld->feature_mask = kempld_read16(pld, KEMPLD_FEATURE);
71 else
72 pld->feature_mask = 0;
74 kempld_release_mutex(pld);
76 return 0;
79 enum kempld_cells {
80 KEMPLD_I2C = 0,
81 KEMPLD_WDT,
82 KEMPLD_GPIO,
83 KEMPLD_UART,
86 static const char *kempld_dev_names[] = {
87 [KEMPLD_I2C] = "kempld-i2c",
88 [KEMPLD_WDT] = "kempld-wdt",
89 [KEMPLD_GPIO] = "kempld-gpio",
90 [KEMPLD_UART] = "kempld-uart",
93 #define KEMPLD_MAX_DEVS ARRAY_SIZE(kempld_dev_names)
95 static int kempld_register_cells_generic(struct kempld_device_data *pld)
97 struct mfd_cell devs[KEMPLD_MAX_DEVS] = {};
98 int i = 0;
100 if (pld->feature_mask & KEMPLD_FEATURE_BIT_I2C)
101 devs[i++].name = kempld_dev_names[KEMPLD_I2C];
103 if (pld->feature_mask & KEMPLD_FEATURE_BIT_WATCHDOG)
104 devs[i++].name = kempld_dev_names[KEMPLD_WDT];
106 if (pld->feature_mask & KEMPLD_FEATURE_BIT_GPIO)
107 devs[i++].name = kempld_dev_names[KEMPLD_GPIO];
109 if (pld->feature_mask & KEMPLD_FEATURE_MASK_UART)
110 devs[i++].name = kempld_dev_names[KEMPLD_UART];
112 return mfd_add_devices(pld->dev, PLATFORM_DEVID_NONE, devs, i, NULL, 0, NULL);
115 static struct resource kempld_ioresource = {
116 .start = KEMPLD_IOINDEX,
117 .end = KEMPLD_IODATA,
118 .flags = IORESOURCE_IO,
121 static const struct kempld_platform_data kempld_platform_data_generic = {
122 .pld_clock = KEMPLD_CLK,
123 .ioresource = &kempld_ioresource,
124 .get_hardware_mutex = kempld_get_hardware_mutex,
125 .release_hardware_mutex = kempld_release_hardware_mutex,
126 .get_info = kempld_get_info_generic,
127 .register_cells = kempld_register_cells_generic,
130 static struct platform_device *kempld_pdev;
132 static int kempld_create_platform_device(const struct kempld_platform_data *pdata)
134 const struct platform_device_info pdevinfo = {
135 .name = "kempld",
136 .id = PLATFORM_DEVID_NONE,
137 .res = pdata->ioresource,
138 .num_res = 1,
139 .data = pdata,
140 .size_data = sizeof(*pdata),
143 kempld_pdev = platform_device_register_full(&pdevinfo);
144 if (IS_ERR(kempld_pdev))
145 return PTR_ERR(kempld_pdev);
147 return 0;
151 * kempld_read8 - read 8 bit register
152 * @pld: kempld_device_data structure describing the PLD
153 * @index: register index on the chip
155 * kempld_get_mutex must be called prior to calling this function.
157 u8 kempld_read8(struct kempld_device_data *pld, u8 index)
159 iowrite8(index, pld->io_index);
160 return ioread8(pld->io_data);
162 EXPORT_SYMBOL_GPL(kempld_read8);
165 * kempld_write8 - write 8 bit register
166 * @pld: kempld_device_data structure describing the PLD
167 * @index: register index on the chip
168 * @data: new register value
170 * kempld_get_mutex must be called prior to calling this function.
172 void kempld_write8(struct kempld_device_data *pld, u8 index, u8 data)
174 iowrite8(index, pld->io_index);
175 iowrite8(data, pld->io_data);
177 EXPORT_SYMBOL_GPL(kempld_write8);
180 * kempld_read16 - read 16 bit register
181 * @pld: kempld_device_data structure describing the PLD
182 * @index: register index on the chip
184 * kempld_get_mutex must be called prior to calling this function.
186 u16 kempld_read16(struct kempld_device_data *pld, u8 index)
188 return kempld_read8(pld, index) | kempld_read8(pld, index + 1) << 8;
190 EXPORT_SYMBOL_GPL(kempld_read16);
193 * kempld_write16 - write 16 bit register
194 * @pld: kempld_device_data structure describing the PLD
195 * @index: register index on the chip
196 * @data: new register value
198 * kempld_get_mutex must be called prior to calling this function.
200 void kempld_write16(struct kempld_device_data *pld, u8 index, u16 data)
202 kempld_write8(pld, index, (u8)data);
203 kempld_write8(pld, index + 1, (u8)(data >> 8));
205 EXPORT_SYMBOL_GPL(kempld_write16);
208 * kempld_read32 - read 32 bit register
209 * @pld: kempld_device_data structure describing the PLD
210 * @index: register index on the chip
212 * kempld_get_mutex must be called prior to calling this function.
214 u32 kempld_read32(struct kempld_device_data *pld, u8 index)
216 return kempld_read16(pld, index) | kempld_read16(pld, index + 2) << 16;
218 EXPORT_SYMBOL_GPL(kempld_read32);
221 * kempld_write32 - write 32 bit register
222 * @pld: kempld_device_data structure describing the PLD
223 * @index: register index on the chip
224 * @data: new register value
226 * kempld_get_mutex must be called prior to calling this function.
228 void kempld_write32(struct kempld_device_data *pld, u8 index, u32 data)
230 kempld_write16(pld, index, (u16)data);
231 kempld_write16(pld, index + 2, (u16)(data >> 16));
233 EXPORT_SYMBOL_GPL(kempld_write32);
236 * kempld_get_mutex - acquire PLD mutex
237 * @pld: kempld_device_data structure describing the PLD
239 void kempld_get_mutex(struct kempld_device_data *pld)
241 const struct kempld_platform_data *pdata = dev_get_platdata(pld->dev);
243 mutex_lock(&pld->lock);
244 pdata->get_hardware_mutex(pld);
246 EXPORT_SYMBOL_GPL(kempld_get_mutex);
249 * kempld_release_mutex - release PLD mutex
250 * @pld: kempld_device_data structure describing the PLD
252 void kempld_release_mutex(struct kempld_device_data *pld)
254 const struct kempld_platform_data *pdata = dev_get_platdata(pld->dev);
256 pdata->release_hardware_mutex(pld);
257 mutex_unlock(&pld->lock);
259 EXPORT_SYMBOL_GPL(kempld_release_mutex);
262 * kempld_get_info - update device specific information
263 * @pld: kempld_device_data structure describing the PLD
265 * This function calls the configured board specific kempld_get_info_XXXX
266 * function which is responsible for gathering information about the specific
267 * hardware. The information is then stored within the pld structure.
269 static int kempld_get_info(struct kempld_device_data *pld)
271 int ret;
272 const struct kempld_platform_data *pdata = dev_get_platdata(pld->dev);
273 char major, minor;
275 ret = pdata->get_info(pld);
276 if (ret)
277 return ret;
279 /* The Kontron PLD firmware version string has the following format:
280 * Pwxy.zzzz
281 * P: Fixed
282 * w: PLD number - 1 hex digit
283 * x: Major version - 1 alphanumerical digit (0-9A-V)
284 * y: Minor version - 1 alphanumerical digit (0-9A-V)
285 * zzzz: Build number - 4 zero padded hex digits */
287 if (pld->info.major < 10)
288 major = pld->info.major + '0';
289 else
290 major = (pld->info.major - 10) + 'A';
291 if (pld->info.minor < 10)
292 minor = pld->info.minor + '0';
293 else
294 minor = (pld->info.minor - 10) + 'A';
296 scnprintf(pld->info.version, sizeof(pld->info.version), "P%X%c%c.%04X",
297 pld->info.number, major, minor, pld->info.buildnr);
299 return 0;
303 * kempld_register_cells - register cell drivers
305 * This function registers cell drivers for the detected hardware by calling
306 * the configured kempld_register_cells_XXXX function which is responsible
307 * to detect and register the needed cell drivers.
309 static int kempld_register_cells(struct kempld_device_data *pld)
311 const struct kempld_platform_data *pdata = dev_get_platdata(pld->dev);
313 return pdata->register_cells(pld);
316 static const char *kempld_get_type_string(struct kempld_device_data *pld)
318 const char *version_type;
320 switch (pld->info.type) {
321 case 0:
322 version_type = "release";
323 break;
324 case 1:
325 version_type = "debug";
326 break;
327 case 2:
328 version_type = "custom";
329 break;
330 default:
331 version_type = "unspecified";
332 break;
335 return version_type;
338 static ssize_t pld_version_show(struct device *dev,
339 struct device_attribute *attr, char *buf)
341 struct kempld_device_data *pld = dev_get_drvdata(dev);
343 return sysfs_emit(buf, "%s\n", pld->info.version);
346 static ssize_t pld_specification_show(struct device *dev,
347 struct device_attribute *attr, char *buf)
349 struct kempld_device_data *pld = dev_get_drvdata(dev);
351 return sysfs_emit(buf, "%d.%d\n", pld->info.spec_major, pld->info.spec_minor);
354 static ssize_t pld_type_show(struct device *dev,
355 struct device_attribute *attr, char *buf)
357 struct kempld_device_data *pld = dev_get_drvdata(dev);
359 return sysfs_emit(buf, "%s\n", kempld_get_type_string(pld));
362 static DEVICE_ATTR_RO(pld_version);
363 static DEVICE_ATTR_RO(pld_specification);
364 static DEVICE_ATTR_RO(pld_type);
366 static struct attribute *pld_attrs[] = {
367 &dev_attr_pld_version.attr,
368 &dev_attr_pld_specification.attr,
369 &dev_attr_pld_type.attr,
370 NULL
372 ATTRIBUTE_GROUPS(pld);
374 static int kempld_detect_device(struct kempld_device_data *pld)
376 u8 index_reg;
377 int ret;
379 mutex_lock(&pld->lock);
381 /* Check for empty IO space */
382 index_reg = ioread8(pld->io_index);
383 if (index_reg == 0xff && ioread8(pld->io_data) == 0xff) {
384 mutex_unlock(&pld->lock);
385 return -ENODEV;
388 /* Release hardware mutex if acquired */
389 if (!(index_reg & KEMPLD_MUTEX_KEY)) {
390 iowrite8(KEMPLD_MUTEX_KEY, pld->io_index);
391 /* PXT and COMe-cPC2 boards may require a second release */
392 iowrite8(KEMPLD_MUTEX_KEY, pld->io_index);
395 mutex_unlock(&pld->lock);
397 ret = kempld_get_info(pld);
398 if (ret)
399 return ret;
401 dev_info(pld->dev, "Found Kontron PLD - %s (%s), spec %d.%d\n",
402 pld->info.version, kempld_get_type_string(pld),
403 pld->info.spec_major, pld->info.spec_minor);
405 return kempld_register_cells(pld);
408 static int kempld_probe(struct platform_device *pdev)
410 const struct kempld_platform_data *pdata;
411 struct device *dev = &pdev->dev;
412 struct kempld_device_data *pld;
413 struct resource *ioport;
414 int ret;
416 if (IS_ERR_OR_NULL(kempld_pdev)) {
418 * No kempld_pdev device has been registered in kempld_init,
419 * so we seem to be probing an ACPI platform device.
421 pdata = device_get_match_data(dev);
422 if (!pdata)
423 return -ENODEV;
425 ret = platform_device_add_data(pdev, pdata, sizeof(*pdata));
426 if (ret)
427 return ret;
428 } else if (kempld_pdev == pdev) {
429 pdata = dev_get_platdata(dev);
430 } else {
432 * The platform device we are probing is not the one we
433 * registered in kempld_init using the DMI table, so this one
434 * comes from ACPI.
435 * As we can only probe one - abort here and use the DMI
436 * based one instead.
438 dev_notice(dev, "platform device exists - not using ACPI\n");
439 return -ENODEV;
442 pld = devm_kzalloc(dev, sizeof(*pld), GFP_KERNEL);
443 if (!pld)
444 return -ENOMEM;
446 ioport = platform_get_resource(pdev, IORESOURCE_IO, 0);
447 if (!ioport)
448 return -EINVAL;
450 pld->io_base = devm_ioport_map(dev, ioport->start,
451 resource_size(ioport));
452 if (!pld->io_base)
453 return -ENOMEM;
455 pld->io_index = pld->io_base;
456 pld->io_data = pld->io_base + 1;
457 pld->pld_clock = pdata->pld_clock;
458 pld->dev = dev;
460 mutex_init(&pld->lock);
461 platform_set_drvdata(pdev, pld);
463 return kempld_detect_device(pld);
466 static void kempld_remove(struct platform_device *pdev)
468 struct kempld_device_data *pld = platform_get_drvdata(pdev);
469 const struct kempld_platform_data *pdata = dev_get_platdata(pld->dev);
471 mfd_remove_devices(&pdev->dev);
472 pdata->release_hardware_mutex(pld);
475 static const struct acpi_device_id kempld_acpi_table[] = {
476 { "KEM0000", (kernel_ulong_t)&kempld_platform_data_generic },
477 { "KEM0001", (kernel_ulong_t)&kempld_platform_data_generic },
480 MODULE_DEVICE_TABLE(acpi, kempld_acpi_table);
482 static struct platform_driver kempld_driver = {
483 .driver = {
484 .name = "kempld",
485 .acpi_match_table = kempld_acpi_table,
486 .dev_groups = pld_groups,
488 .probe = kempld_probe,
489 .remove = kempld_remove,
492 static const struct dmi_system_id kempld_dmi_table[] __initconst = {
494 .ident = "BBD6",
495 .matches = {
496 DMI_MATCH(DMI_BOARD_VENDOR, "Kontron"),
497 DMI_MATCH(DMI_BOARD_NAME, "COMe-bBD"),
499 }, {
500 .ident = "BBL6",
501 .matches = {
502 DMI_MATCH(DMI_BOARD_VENDOR, "Kontron"),
503 DMI_MATCH(DMI_BOARD_NAME, "COMe-bBL6"),
505 }, {
506 .ident = "BDV7",
507 .matches = {
508 DMI_MATCH(DMI_BOARD_VENDOR, "Kontron"),
509 DMI_MATCH(DMI_BOARD_NAME, "COMe-bDV7"),
511 }, {
512 .ident = "BHL6",
513 .matches = {
514 DMI_MATCH(DMI_BOARD_VENDOR, "Kontron"),
515 DMI_MATCH(DMI_BOARD_NAME, "COMe-bHL6"),
517 }, {
518 .ident = "BKL6",
519 .matches = {
520 DMI_MATCH(DMI_BOARD_VENDOR, "Kontron"),
521 DMI_MATCH(DMI_BOARD_NAME, "COMe-bKL6"),
523 }, {
524 .ident = "BSL6",
525 .matches = {
526 DMI_MATCH(DMI_BOARD_VENDOR, "Kontron"),
527 DMI_MATCH(DMI_BOARD_NAME, "COMe-bSL6"),
529 }, {
530 .ident = "CAL6",
531 .matches = {
532 DMI_MATCH(DMI_BOARD_VENDOR, "Kontron"),
533 DMI_MATCH(DMI_BOARD_NAME, "COMe-cAL"),
535 }, {
536 .ident = "CBL6",
537 .matches = {
538 DMI_MATCH(DMI_BOARD_VENDOR, "Kontron"),
539 DMI_MATCH(DMI_BOARD_NAME, "COMe-cBL6"),
541 }, {
542 .ident = "CBW6",
543 .matches = {
544 DMI_MATCH(DMI_BOARD_VENDOR, "Kontron"),
545 DMI_MATCH(DMI_BOARD_NAME, "COMe-cBW6"),
547 }, {
548 .ident = "CCR2",
549 .matches = {
550 DMI_MATCH(DMI_BOARD_VENDOR, "Kontron"),
551 DMI_MATCH(DMI_BOARD_NAME, "COMe-bIP2"),
553 }, {
554 .ident = "CCR6",
555 .matches = {
556 DMI_MATCH(DMI_BOARD_VENDOR, "Kontron"),
557 DMI_MATCH(DMI_BOARD_NAME, "COMe-bIP6"),
559 }, {
560 .ident = "CDV7",
561 .matches = {
562 DMI_MATCH(DMI_BOARD_VENDOR, "Kontron"),
563 DMI_MATCH(DMI_BOARD_NAME, "COMe-cDV7"),
565 }, {
566 .ident = "CHL6",
567 .matches = {
568 DMI_MATCH(DMI_BOARD_VENDOR, "Kontron"),
569 DMI_MATCH(DMI_BOARD_NAME, "COMe-cHL6"),
571 }, {
572 .ident = "CHR2",
573 .matches = {
574 DMI_MATCH(DMI_BOARD_VENDOR, "Kontron"),
575 DMI_MATCH(DMI_BOARD_NAME, "ETXexpress-SC T2"),
577 }, {
578 .ident = "CHR2",
579 .matches = {
580 DMI_MATCH(DMI_BOARD_VENDOR, "Kontron"),
581 DMI_MATCH(DMI_BOARD_NAME, "ETXe-SC T2"),
583 }, {
584 .ident = "CHR2",
585 .matches = {
586 DMI_MATCH(DMI_BOARD_VENDOR, "Kontron"),
587 DMI_MATCH(DMI_BOARD_NAME, "COMe-bSC2"),
589 }, {
590 .ident = "CHR6",
591 .matches = {
592 DMI_MATCH(DMI_BOARD_VENDOR, "Kontron"),
593 DMI_MATCH(DMI_BOARD_NAME, "ETXexpress-SC T6"),
595 }, {
596 .ident = "CHR6",
597 .matches = {
598 DMI_MATCH(DMI_BOARD_VENDOR, "Kontron"),
599 DMI_MATCH(DMI_BOARD_NAME, "ETXe-SC T6"),
601 }, {
602 .ident = "CHR6",
603 .matches = {
604 DMI_MATCH(DMI_BOARD_VENDOR, "Kontron"),
605 DMI_MATCH(DMI_BOARD_NAME, "COMe-bSC6"),
607 }, {
608 .ident = "CKL6",
609 .matches = {
610 DMI_MATCH(DMI_BOARD_VENDOR, "Kontron"),
611 DMI_MATCH(DMI_BOARD_NAME, "COMe-cKL6"),
613 }, {
614 .ident = "CNTG",
615 .matches = {
616 DMI_MATCH(DMI_BOARD_VENDOR, "Kontron"),
617 DMI_MATCH(DMI_BOARD_NAME, "ETXexpress-PC"),
619 }, {
620 .ident = "CNTG",
621 .matches = {
622 DMI_MATCH(DMI_BOARD_VENDOR, "Kontron"),
623 DMI_MATCH(DMI_BOARD_NAME, "COMe-bPC2"),
625 }, {
626 .ident = "CNTX",
627 .matches = {
628 DMI_MATCH(DMI_BOARD_VENDOR, "Kontron"),
629 DMI_MATCH(DMI_BOARD_NAME, "PXT"),
631 }, {
632 .ident = "CSL6",
633 .matches = {
634 DMI_MATCH(DMI_BOARD_VENDOR, "Kontron"),
635 DMI_MATCH(DMI_BOARD_NAME, "COMe-cSL6"),
637 }, {
638 .ident = "CVV6",
639 .matches = {
640 DMI_MATCH(DMI_BOARD_VENDOR, "Kontron"),
641 DMI_MATCH(DMI_BOARD_NAME, "COMe-cBT"),
643 }, {
644 .ident = "FRI2",
645 .matches = {
646 DMI_MATCH(DMI_BOARD_VENDOR, "Kontron"),
647 DMI_MATCH(DMI_BIOS_VERSION, "FRI2"),
649 }, {
650 .ident = "FRI2",
651 .matches = {
652 DMI_MATCH(DMI_PRODUCT_NAME, "Fish River Island II"),
654 }, {
655 .ident = "A203",
656 .matches = {
657 DMI_MATCH(DMI_BOARD_VENDOR, "Kontron"),
658 DMI_MATCH(DMI_BOARD_NAME, "KBox A-203"),
660 }, {
661 .ident = "M4A1",
662 .matches = {
663 DMI_MATCH(DMI_BOARD_VENDOR, "Kontron"),
664 DMI_MATCH(DMI_BOARD_NAME, "COMe-m4AL"),
666 }, {
667 .ident = "MAL1",
668 .matches = {
669 DMI_MATCH(DMI_BOARD_VENDOR, "Kontron"),
670 DMI_MATCH(DMI_BOARD_NAME, "COMe-mAL10"),
672 }, {
673 .ident = "MAPL",
674 .matches = {
675 DMI_MATCH(DMI_BOARD_VENDOR, "Kontron"),
676 DMI_MATCH(DMI_BOARD_NAME, "mITX-APL"),
678 }, {
679 .ident = "MBR1",
680 .matches = {
681 DMI_MATCH(DMI_BOARD_VENDOR, "Kontron"),
682 DMI_MATCH(DMI_BOARD_NAME, "ETX-OH"),
684 }, {
685 .ident = "MVV1",
686 .matches = {
687 DMI_MATCH(DMI_BOARD_VENDOR, "Kontron"),
688 DMI_MATCH(DMI_BOARD_NAME, "COMe-mBT"),
690 }, {
691 .ident = "NTC1",
692 .matches = {
693 DMI_MATCH(DMI_BOARD_VENDOR, "Kontron"),
694 DMI_MATCH(DMI_BOARD_NAME, "nanoETXexpress-TT"),
696 }, {
697 .ident = "NTC1",
698 .matches = {
699 DMI_MATCH(DMI_BOARD_VENDOR, "Kontron"),
700 DMI_MATCH(DMI_BOARD_NAME, "nETXe-TT"),
702 }, {
703 .ident = "NTC1",
704 .matches = {
705 DMI_MATCH(DMI_BOARD_VENDOR, "Kontron"),
706 DMI_MATCH(DMI_BOARD_NAME, "COMe-mTT"),
708 }, {
709 .ident = "NUP1",
710 .matches = {
711 DMI_MATCH(DMI_BOARD_VENDOR, "Kontron"),
712 DMI_MATCH(DMI_BOARD_NAME, "COMe-mCT"),
714 }, {
715 .ident = "PAPL",
716 .matches = {
717 DMI_MATCH(DMI_BOARD_VENDOR, "Kontron"),
718 DMI_MATCH(DMI_BOARD_NAME, "pITX-APL"),
720 }, {
721 .ident = "SXAL",
722 .matches = {
723 DMI_MATCH(DMI_BOARD_VENDOR, "Kontron"),
724 DMI_MATCH(DMI_BOARD_NAME, "SMARC-sXAL"),
726 }, {
727 .ident = "SXAL4",
728 .matches = {
729 DMI_MATCH(DMI_BOARD_VENDOR, "Kontron"),
730 DMI_MATCH(DMI_BOARD_NAME, "SMARC-sXA4"),
732 }, {
733 .ident = "UNP1",
734 .matches = {
735 DMI_MATCH(DMI_BOARD_VENDOR, "Kontron"),
736 DMI_MATCH(DMI_BOARD_NAME, "microETXexpress-DC"),
738 }, {
739 .ident = "UNP1",
740 .matches = {
741 DMI_MATCH(DMI_BOARD_VENDOR, "Kontron"),
742 DMI_MATCH(DMI_BOARD_NAME, "COMe-cDC2"),
744 }, {
745 .ident = "UNTG",
746 .matches = {
747 DMI_MATCH(DMI_BOARD_VENDOR, "Kontron"),
748 DMI_MATCH(DMI_BOARD_NAME, "microETXexpress-PC"),
750 }, {
751 .ident = "UNTG",
752 .matches = {
753 DMI_MATCH(DMI_BOARD_VENDOR, "Kontron"),
754 DMI_MATCH(DMI_BOARD_NAME, "COMe-cPC2"),
756 }, {
757 .ident = "UUP6",
758 .matches = {
759 DMI_MATCH(DMI_BOARD_VENDOR, "Kontron"),
760 DMI_MATCH(DMI_BOARD_NAME, "COMe-cCT6"),
762 }, {
763 .ident = "UTH6",
764 .matches = {
765 DMI_MATCH(DMI_BOARD_VENDOR, "Kontron"),
766 DMI_MATCH(DMI_BOARD_NAME, "COMe-cTH6"),
768 }, {
769 .ident = "Q7AL",
770 .matches = {
771 DMI_MATCH(DMI_BOARD_VENDOR, "Kontron"),
772 DMI_MATCH(DMI_BOARD_NAME, "Qseven-Q7AL"),
777 MODULE_DEVICE_TABLE(dmi, kempld_dmi_table);
779 static int __init kempld_init(void)
781 const struct dmi_system_id *id;
782 int ret = -ENODEV;
784 for (id = dmi_first_match(kempld_dmi_table); id; id = dmi_first_match(id + 1)) {
785 /* Check, if user asked for the exact device ID match */
786 if (force_device_id[0] && !strstr(id->ident, force_device_id))
787 continue;
789 ret = kempld_create_platform_device(&kempld_platform_data_generic);
790 if (ret)
791 continue;
793 break;
795 if (ret)
796 return ret;
798 return platform_driver_register(&kempld_driver);
801 static void __exit kempld_exit(void)
803 platform_device_unregister(kempld_pdev);
804 platform_driver_unregister(&kempld_driver);
807 module_init(kempld_init);
808 module_exit(kempld_exit);
810 MODULE_DESCRIPTION("KEM PLD Core Driver");
811 MODULE_AUTHOR("Michael Brunner <michael.brunner@kontron.com>");
812 MODULE_LICENSE("GPL");
813 MODULE_ALIAS("platform:kempld-core");