1 // SPDX-License-Identifier: GPL-2.0-only
3 * Kontron PLD MFD core driver
5 * Copyright (c) 2010-2013 Kontron Europe GmbH
6 * Author: Michael Brunner <michael.brunner@kontron.com>
9 #include <linux/platform_device.h>
10 #include <linux/mfd/core.h>
11 #include <linux/mfd/kempld.h>
12 #include <linux/module.h>
13 #include <linux/dmi.h>
15 #include <linux/delay.h>
16 #include <linux/acpi.h>
19 static char force_device_id
[MAX_ID_LEN
+ 1] = "";
20 module_param_string(force_device_id
, force_device_id
,
21 sizeof(force_device_id
), 0);
22 MODULE_PARM_DESC(force_device_id
, "Override detected product");
25 * Get hardware mutex to block firmware from accessing the pld.
26 * It is possible for the firmware may hold the mutex for an extended length of
27 * time. This function will block until access has been granted.
29 static void kempld_get_hardware_mutex(struct kempld_device_data
*pld
)
31 /* The mutex bit will read 1 until access has been granted */
32 while (ioread8(pld
->io_index
) & KEMPLD_MUTEX_KEY
)
33 usleep_range(1000, 3000);
36 static void kempld_release_hardware_mutex(struct kempld_device_data
*pld
)
38 /* The harware mutex is released when 1 is written to the mutex bit. */
39 iowrite8(KEMPLD_MUTEX_KEY
, pld
->io_index
);
42 static int kempld_get_info_generic(struct kempld_device_data
*pld
)
47 kempld_get_mutex(pld
);
49 version
= kempld_read16(pld
, KEMPLD_VERSION
);
50 spec
= kempld_read8(pld
, KEMPLD_SPEC
);
51 pld
->info
.buildnr
= kempld_read16(pld
, KEMPLD_BUILDNR
);
53 pld
->info
.minor
= KEMPLD_VERSION_GET_MINOR(version
);
54 pld
->info
.major
= KEMPLD_VERSION_GET_MAJOR(version
);
55 pld
->info
.number
= KEMPLD_VERSION_GET_NUMBER(version
);
56 pld
->info
.type
= KEMPLD_VERSION_GET_TYPE(version
);
59 pld
->info
.spec_minor
= 0;
60 pld
->info
.spec_major
= 1;
62 pld
->info
.spec_minor
= KEMPLD_SPEC_GET_MINOR(spec
);
63 pld
->info
.spec_major
= KEMPLD_SPEC_GET_MAJOR(spec
);
66 if (pld
->info
.spec_major
> 0)
67 pld
->feature_mask
= kempld_read16(pld
, KEMPLD_FEATURE
);
69 pld
->feature_mask
= 0;
71 kempld_release_mutex(pld
);
83 static const char *kempld_dev_names
[] = {
84 [KEMPLD_I2C
] = "kempld-i2c",
85 [KEMPLD_WDT
] = "kempld-wdt",
86 [KEMPLD_GPIO
] = "kempld-gpio",
87 [KEMPLD_UART
] = "kempld-uart",
90 #define KEMPLD_MAX_DEVS ARRAY_SIZE(kempld_dev_names)
92 static int kempld_register_cells_generic(struct kempld_device_data
*pld
)
94 struct mfd_cell devs
[KEMPLD_MAX_DEVS
] = {};
97 if (pld
->feature_mask
& KEMPLD_FEATURE_BIT_I2C
)
98 devs
[i
++].name
= kempld_dev_names
[KEMPLD_I2C
];
100 if (pld
->feature_mask
& KEMPLD_FEATURE_BIT_WATCHDOG
)
101 devs
[i
++].name
= kempld_dev_names
[KEMPLD_WDT
];
103 if (pld
->feature_mask
& KEMPLD_FEATURE_BIT_GPIO
)
104 devs
[i
++].name
= kempld_dev_names
[KEMPLD_GPIO
];
106 if (pld
->feature_mask
& KEMPLD_FEATURE_MASK_UART
)
107 devs
[i
++].name
= kempld_dev_names
[KEMPLD_UART
];
109 return mfd_add_devices(pld
->dev
, -1, devs
, i
, NULL
, 0, NULL
);
112 static struct resource kempld_ioresource
= {
113 .start
= KEMPLD_IOINDEX
,
114 .end
= KEMPLD_IODATA
,
115 .flags
= IORESOURCE_IO
,
118 static const struct kempld_platform_data kempld_platform_data_generic
= {
119 .pld_clock
= KEMPLD_CLK
,
120 .ioresource
= &kempld_ioresource
,
121 .get_hardware_mutex
= kempld_get_hardware_mutex
,
122 .release_hardware_mutex
= kempld_release_hardware_mutex
,
123 .get_info
= kempld_get_info_generic
,
124 .register_cells
= kempld_register_cells_generic
,
127 static struct platform_device
*kempld_pdev
;
129 static int kempld_create_platform_device(const struct dmi_system_id
*id
)
131 const struct kempld_platform_data
*pdata
= id
->driver_data
;
134 kempld_pdev
= platform_device_alloc("kempld", -1);
138 ret
= platform_device_add_data(kempld_pdev
, pdata
, sizeof(*pdata
));
142 ret
= platform_device_add_resources(kempld_pdev
, pdata
->ioresource
, 1);
146 ret
= platform_device_add(kempld_pdev
);
152 platform_device_put(kempld_pdev
);
157 * kempld_read8 - read 8 bit register
158 * @pld: kempld_device_data structure describing the PLD
159 * @index: register index on the chip
161 * kempld_get_mutex must be called prior to calling this function.
163 u8
kempld_read8(struct kempld_device_data
*pld
, u8 index
)
165 iowrite8(index
, pld
->io_index
);
166 return ioread8(pld
->io_data
);
168 EXPORT_SYMBOL_GPL(kempld_read8
);
171 * kempld_write8 - write 8 bit register
172 * @pld: kempld_device_data structure describing the PLD
173 * @index: register index on the chip
174 * @data: new register value
176 * kempld_get_mutex must be called prior to calling this function.
178 void kempld_write8(struct kempld_device_data
*pld
, u8 index
, u8 data
)
180 iowrite8(index
, pld
->io_index
);
181 iowrite8(data
, pld
->io_data
);
183 EXPORT_SYMBOL_GPL(kempld_write8
);
186 * kempld_read16 - read 16 bit register
187 * @pld: kempld_device_data structure describing the PLD
188 * @index: register index on the chip
190 * kempld_get_mutex must be called prior to calling this function.
192 u16
kempld_read16(struct kempld_device_data
*pld
, u8 index
)
194 return kempld_read8(pld
, index
) | kempld_read8(pld
, index
+ 1) << 8;
196 EXPORT_SYMBOL_GPL(kempld_read16
);
199 * kempld_write16 - write 16 bit register
200 * @pld: kempld_device_data structure describing the PLD
201 * @index: register index on the chip
202 * @data: new register value
204 * kempld_get_mutex must be called prior to calling this function.
206 void kempld_write16(struct kempld_device_data
*pld
, u8 index
, u16 data
)
208 kempld_write8(pld
, index
, (u8
)data
);
209 kempld_write8(pld
, index
+ 1, (u8
)(data
>> 8));
211 EXPORT_SYMBOL_GPL(kempld_write16
);
214 * kempld_read32 - read 32 bit register
215 * @pld: kempld_device_data structure describing the PLD
216 * @index: register index on the chip
218 * kempld_get_mutex must be called prior to calling this function.
220 u32
kempld_read32(struct kempld_device_data
*pld
, u8 index
)
222 return kempld_read16(pld
, index
) | kempld_read16(pld
, index
+ 2) << 16;
224 EXPORT_SYMBOL_GPL(kempld_read32
);
227 * kempld_write32 - write 32 bit register
228 * @pld: kempld_device_data structure describing the PLD
229 * @index: register index on the chip
230 * @data: new register value
232 * kempld_get_mutex must be called prior to calling this function.
234 void kempld_write32(struct kempld_device_data
*pld
, u8 index
, u32 data
)
236 kempld_write16(pld
, index
, (u16
)data
);
237 kempld_write16(pld
, index
+ 2, (u16
)(data
>> 16));
239 EXPORT_SYMBOL_GPL(kempld_write32
);
242 * kempld_get_mutex - acquire PLD mutex
243 * @pld: kempld_device_data structure describing the PLD
245 void kempld_get_mutex(struct kempld_device_data
*pld
)
247 const struct kempld_platform_data
*pdata
= dev_get_platdata(pld
->dev
);
249 mutex_lock(&pld
->lock
);
250 pdata
->get_hardware_mutex(pld
);
252 EXPORT_SYMBOL_GPL(kempld_get_mutex
);
255 * kempld_release_mutex - release PLD mutex
256 * @pld: kempld_device_data structure describing the PLD
258 void kempld_release_mutex(struct kempld_device_data
*pld
)
260 const struct kempld_platform_data
*pdata
= dev_get_platdata(pld
->dev
);
262 pdata
->release_hardware_mutex(pld
);
263 mutex_unlock(&pld
->lock
);
265 EXPORT_SYMBOL_GPL(kempld_release_mutex
);
268 * kempld_get_info - update device specific information
269 * @pld: kempld_device_data structure describing the PLD
271 * This function calls the configured board specific kempld_get_info_XXXX
272 * function which is responsible for gathering information about the specific
273 * hardware. The information is then stored within the pld structure.
275 static int kempld_get_info(struct kempld_device_data
*pld
)
278 const struct kempld_platform_data
*pdata
= dev_get_platdata(pld
->dev
);
281 ret
= pdata
->get_info(pld
);
285 /* The Kontron PLD firmware version string has the following format:
288 * w: PLD number - 1 hex digit
289 * x: Major version - 1 alphanumerical digit (0-9A-V)
290 * y: Minor version - 1 alphanumerical digit (0-9A-V)
291 * zzzz: Build number - 4 zero padded hex digits */
293 if (pld
->info
.major
< 10)
294 major
= pld
->info
.major
+ '0';
296 major
= (pld
->info
.major
- 10) + 'A';
297 if (pld
->info
.minor
< 10)
298 minor
= pld
->info
.minor
+ '0';
300 minor
= (pld
->info
.minor
- 10) + 'A';
302 ret
= scnprintf(pld
->info
.version
, sizeof(pld
->info
.version
),
303 "P%X%c%c.%04X", pld
->info
.number
, major
, minor
,
312 * kempld_register_cells - register cell drivers
314 * This function registers cell drivers for the detected hardware by calling
315 * the configured kempld_register_cells_XXXX function which is responsible
316 * to detect and register the needed cell drivers.
318 static int kempld_register_cells(struct kempld_device_data
*pld
)
320 const struct kempld_platform_data
*pdata
= dev_get_platdata(pld
->dev
);
322 return pdata
->register_cells(pld
);
325 static const char *kempld_get_type_string(struct kempld_device_data
*pld
)
327 const char *version_type
;
329 switch (pld
->info
.type
) {
331 version_type
= "release";
334 version_type
= "debug";
337 version_type
= "custom";
340 version_type
= "unspecified";
347 static ssize_t
kempld_version_show(struct device
*dev
,
348 struct device_attribute
*attr
, char *buf
)
350 struct kempld_device_data
*pld
= dev_get_drvdata(dev
);
352 return scnprintf(buf
, PAGE_SIZE
, "%s\n", pld
->info
.version
);
355 static ssize_t
kempld_specification_show(struct device
*dev
,
356 struct device_attribute
*attr
, char *buf
)
358 struct kempld_device_data
*pld
= dev_get_drvdata(dev
);
360 return scnprintf(buf
, PAGE_SIZE
, "%d.%d\n", pld
->info
.spec_major
,
361 pld
->info
.spec_minor
);
364 static ssize_t
kempld_type_show(struct device
*dev
,
365 struct device_attribute
*attr
, char *buf
)
367 struct kempld_device_data
*pld
= dev_get_drvdata(dev
);
369 return scnprintf(buf
, PAGE_SIZE
, "%s\n", kempld_get_type_string(pld
));
372 static DEVICE_ATTR(pld_version
, S_IRUGO
, kempld_version_show
, NULL
);
373 static DEVICE_ATTR(pld_specification
, S_IRUGO
, kempld_specification_show
,
375 static DEVICE_ATTR(pld_type
, S_IRUGO
, kempld_type_show
, NULL
);
377 static struct attribute
*pld_attributes
[] = {
378 &dev_attr_pld_version
.attr
,
379 &dev_attr_pld_specification
.attr
,
380 &dev_attr_pld_type
.attr
,
384 static const struct attribute_group pld_attr_group
= {
385 .attrs
= pld_attributes
,
388 static int kempld_detect_device(struct kempld_device_data
*pld
)
393 mutex_lock(&pld
->lock
);
395 /* Check for empty IO space */
396 index_reg
= ioread8(pld
->io_index
);
397 if (index_reg
== 0xff && ioread8(pld
->io_data
) == 0xff) {
398 mutex_unlock(&pld
->lock
);
402 /* Release hardware mutex if acquired */
403 if (!(index_reg
& KEMPLD_MUTEX_KEY
)) {
404 iowrite8(KEMPLD_MUTEX_KEY
, pld
->io_index
);
405 /* PXT and COMe-cPC2 boards may require a second release */
406 iowrite8(KEMPLD_MUTEX_KEY
, pld
->io_index
);
409 mutex_unlock(&pld
->lock
);
411 ret
= kempld_get_info(pld
);
415 dev_info(pld
->dev
, "Found Kontron PLD - %s (%s), spec %d.%d\n",
416 pld
->info
.version
, kempld_get_type_string(pld
),
417 pld
->info
.spec_major
, pld
->info
.spec_minor
);
419 ret
= sysfs_create_group(&pld
->dev
->kobj
, &pld_attr_group
);
423 ret
= kempld_register_cells(pld
);
425 sysfs_remove_group(&pld
->dev
->kobj
, &pld_attr_group
);
431 static int kempld_get_acpi_data(struct platform_device
*pdev
)
433 struct list_head resource_list
;
434 struct resource
*resources
;
435 struct resource_entry
*rentry
;
436 struct device
*dev
= &pdev
->dev
;
437 struct acpi_device
*acpi_dev
= ACPI_COMPANION(dev
);
438 const struct kempld_platform_data
*pdata
;
442 pdata
= acpi_device_get_match_data(dev
);
443 ret
= platform_device_add_data(pdev
, pdata
,
444 sizeof(struct kempld_platform_data
));
448 INIT_LIST_HEAD(&resource_list
);
449 ret
= acpi_dev_get_resources(acpi_dev
, &resource_list
, NULL
, NULL
);
456 ret
= platform_device_add_resources(pdev
, pdata
->ioresource
, 1);
460 resources
= devm_kcalloc(&acpi_dev
->dev
, count
, sizeof(*resources
),
468 list_for_each_entry(rentry
, &resource_list
, node
) {
469 memcpy(&resources
[count
], rentry
->res
,
473 ret
= platform_device_add_resources(pdev
, resources
, count
);
476 acpi_dev_free_resource_list(&resource_list
);
481 static int kempld_get_acpi_data(struct platform_device
*pdev
)
485 #endif /* CONFIG_ACPI */
487 static int kempld_probe(struct platform_device
*pdev
)
489 const struct kempld_platform_data
*pdata
;
490 struct device
*dev
= &pdev
->dev
;
491 struct kempld_device_data
*pld
;
492 struct resource
*ioport
;
495 if (kempld_pdev
== NULL
) {
497 * No kempld_pdev device has been registered in kempld_init,
498 * so we seem to be probing an ACPI platform device.
500 ret
= kempld_get_acpi_data(pdev
);
503 } else if (kempld_pdev
!= pdev
) {
505 * The platform device we are probing is not the one we
506 * registered in kempld_init using the DMI table, so this one
508 * As we can only probe one - abort here and use the DMI
511 dev_notice(dev
, "platform device exists - not using ACPI\n");
514 pdata
= dev_get_platdata(dev
);
516 pld
= devm_kzalloc(dev
, sizeof(*pld
), GFP_KERNEL
);
520 ioport
= platform_get_resource(pdev
, IORESOURCE_IO
, 0);
524 pld
->io_base
= devm_ioport_map(dev
, ioport
->start
,
525 resource_size(ioport
));
529 pld
->io_index
= pld
->io_base
;
530 pld
->io_data
= pld
->io_base
+ 1;
531 pld
->pld_clock
= pdata
->pld_clock
;
534 mutex_init(&pld
->lock
);
535 platform_set_drvdata(pdev
, pld
);
537 return kempld_detect_device(pld
);
540 static int kempld_remove(struct platform_device
*pdev
)
542 struct kempld_device_data
*pld
= platform_get_drvdata(pdev
);
543 const struct kempld_platform_data
*pdata
= dev_get_platdata(pld
->dev
);
545 sysfs_remove_group(&pld
->dev
->kobj
, &pld_attr_group
);
547 mfd_remove_devices(&pdev
->dev
);
548 pdata
->release_hardware_mutex(pld
);
554 static const struct acpi_device_id kempld_acpi_table
[] = {
555 { "KEM0000", (kernel_ulong_t
)&kempld_platform_data_generic
},
556 { "KEM0001", (kernel_ulong_t
)&kempld_platform_data_generic
},
559 MODULE_DEVICE_TABLE(acpi
, kempld_acpi_table
);
562 static struct platform_driver kempld_driver
= {
565 .acpi_match_table
= ACPI_PTR(kempld_acpi_table
),
567 .probe
= kempld_probe
,
568 .remove
= kempld_remove
,
571 static const struct dmi_system_id kempld_dmi_table
[] __initconst
= {
575 DMI_MATCH(DMI_BOARD_VENDOR
, "Kontron"),
576 DMI_MATCH(DMI_BOARD_NAME
, "COMe-bBD"),
578 .driver_data
= (void *)&kempld_platform_data_generic
,
579 .callback
= kempld_create_platform_device
,
583 DMI_MATCH(DMI_BOARD_VENDOR
, "Kontron"),
584 DMI_MATCH(DMI_BOARD_NAME
, "COMe-bBL6"),
586 .driver_data
= (void *)&kempld_platform_data_generic
,
587 .callback
= kempld_create_platform_device
,
591 DMI_MATCH(DMI_BOARD_VENDOR
, "Kontron"),
592 DMI_MATCH(DMI_BOARD_NAME
, "COMe-bDV7"),
594 .driver_data
= (void *)&kempld_platform_data_generic
,
595 .callback
= kempld_create_platform_device
,
599 DMI_MATCH(DMI_BOARD_VENDOR
, "Kontron"),
600 DMI_MATCH(DMI_BOARD_NAME
, "COMe-bHL6"),
602 .driver_data
= (void *)&kempld_platform_data_generic
,
603 .callback
= kempld_create_platform_device
,
607 DMI_MATCH(DMI_BOARD_VENDOR
, "Kontron"),
608 DMI_MATCH(DMI_BOARD_NAME
, "COMe-bKL6"),
610 .driver_data
= (void *)&kempld_platform_data_generic
,
611 .callback
= kempld_create_platform_device
,
615 DMI_MATCH(DMI_BOARD_VENDOR
, "Kontron"),
616 DMI_MATCH(DMI_BOARD_NAME
, "COMe-bSL6"),
618 .driver_data
= (void *)&kempld_platform_data_generic
,
619 .callback
= kempld_create_platform_device
,
623 DMI_MATCH(DMI_BOARD_VENDOR
, "Kontron"),
624 DMI_MATCH(DMI_BOARD_NAME
, "COMe-cAL"),
626 .driver_data
= (void *)&kempld_platform_data_generic
,
627 .callback
= kempld_create_platform_device
,
631 DMI_MATCH(DMI_BOARD_VENDOR
, "Kontron"),
632 DMI_MATCH(DMI_BOARD_NAME
, "COMe-cBL6"),
634 .driver_data
= (void *)&kempld_platform_data_generic
,
635 .callback
= kempld_create_platform_device
,
639 DMI_MATCH(DMI_BOARD_VENDOR
, "Kontron"),
640 DMI_MATCH(DMI_BOARD_NAME
, "COMe-cBW6"),
642 .driver_data
= (void *)&kempld_platform_data_generic
,
643 .callback
= kempld_create_platform_device
,
647 DMI_MATCH(DMI_BOARD_VENDOR
, "Kontron"),
648 DMI_MATCH(DMI_BOARD_NAME
, "COMe-bIP2"),
650 .driver_data
= (void *)&kempld_platform_data_generic
,
651 .callback
= kempld_create_platform_device
,
655 DMI_MATCH(DMI_BOARD_VENDOR
, "Kontron"),
656 DMI_MATCH(DMI_BOARD_NAME
, "COMe-bIP6"),
658 .driver_data
= (void *)&kempld_platform_data_generic
,
659 .callback
= kempld_create_platform_device
,
663 DMI_MATCH(DMI_BOARD_VENDOR
, "Kontron"),
664 DMI_MATCH(DMI_BOARD_NAME
, "COMe-cDV7"),
666 .driver_data
= (void *)&kempld_platform_data_generic
,
667 .callback
= kempld_create_platform_device
,
671 DMI_MATCH(DMI_BOARD_VENDOR
, "Kontron"),
672 DMI_MATCH(DMI_BOARD_NAME
, "COMe-cHL6"),
674 .driver_data
= (void *)&kempld_platform_data_generic
,
675 .callback
= kempld_create_platform_device
,
679 DMI_MATCH(DMI_BOARD_VENDOR
, "Kontron"),
680 DMI_MATCH(DMI_BOARD_NAME
, "ETXexpress-SC T2"),
682 .driver_data
= (void *)&kempld_platform_data_generic
,
683 .callback
= kempld_create_platform_device
,
687 DMI_MATCH(DMI_BOARD_VENDOR
, "Kontron"),
688 DMI_MATCH(DMI_BOARD_NAME
, "ETXe-SC T2"),
690 .driver_data
= (void *)&kempld_platform_data_generic
,
691 .callback
= kempld_create_platform_device
,
695 DMI_MATCH(DMI_BOARD_VENDOR
, "Kontron"),
696 DMI_MATCH(DMI_BOARD_NAME
, "COMe-bSC2"),
698 .driver_data
= (void *)&kempld_platform_data_generic
,
699 .callback
= kempld_create_platform_device
,
703 DMI_MATCH(DMI_BOARD_VENDOR
, "Kontron"),
704 DMI_MATCH(DMI_BOARD_NAME
, "ETXexpress-SC T6"),
706 .driver_data
= (void *)&kempld_platform_data_generic
,
707 .callback
= kempld_create_platform_device
,
711 DMI_MATCH(DMI_BOARD_VENDOR
, "Kontron"),
712 DMI_MATCH(DMI_BOARD_NAME
, "ETXe-SC T6"),
714 .driver_data
= (void *)&kempld_platform_data_generic
,
715 .callback
= kempld_create_platform_device
,
719 DMI_MATCH(DMI_BOARD_VENDOR
, "Kontron"),
720 DMI_MATCH(DMI_BOARD_NAME
, "COMe-bSC6"),
722 .driver_data
= (void *)&kempld_platform_data_generic
,
723 .callback
= kempld_create_platform_device
,
727 DMI_MATCH(DMI_BOARD_VENDOR
, "Kontron"),
728 DMI_MATCH(DMI_BOARD_NAME
, "COMe-cKL6"),
730 .driver_data
= (void *)&kempld_platform_data_generic
,
731 .callback
= kempld_create_platform_device
,
735 DMI_MATCH(DMI_BOARD_VENDOR
, "Kontron"),
736 DMI_MATCH(DMI_BOARD_NAME
, "ETXexpress-PC"),
738 .driver_data
= (void *)&kempld_platform_data_generic
,
739 .callback
= kempld_create_platform_device
,
743 DMI_MATCH(DMI_BOARD_VENDOR
, "Kontron"),
744 DMI_MATCH(DMI_BOARD_NAME
, "COMe-bPC2"),
746 .driver_data
= (void *)&kempld_platform_data_generic
,
747 .callback
= kempld_create_platform_device
,
751 DMI_MATCH(DMI_BOARD_VENDOR
, "Kontron"),
752 DMI_MATCH(DMI_BOARD_NAME
, "PXT"),
754 .driver_data
= (void *)&kempld_platform_data_generic
,
755 .callback
= kempld_create_platform_device
,
759 DMI_MATCH(DMI_BOARD_VENDOR
, "Kontron"),
760 DMI_MATCH(DMI_BOARD_NAME
, "COMe-cSL6"),
762 .driver_data
= (void *)&kempld_platform_data_generic
,
763 .callback
= kempld_create_platform_device
,
767 DMI_MATCH(DMI_BOARD_VENDOR
, "Kontron"),
768 DMI_MATCH(DMI_BOARD_NAME
, "COMe-cBT"),
770 .driver_data
= (void *)&kempld_platform_data_generic
,
771 .callback
= kempld_create_platform_device
,
775 DMI_MATCH(DMI_BOARD_VENDOR
, "Kontron"),
776 DMI_MATCH(DMI_BIOS_VERSION
, "FRI2"),
778 .driver_data
= (void *)&kempld_platform_data_generic
,
779 .callback
= kempld_create_platform_device
,
783 DMI_MATCH(DMI_PRODUCT_NAME
, "Fish River Island II"),
785 .driver_data
= (void *)&kempld_platform_data_generic
,
786 .callback
= kempld_create_platform_device
,
790 DMI_MATCH(DMI_BOARD_VENDOR
, "Kontron"),
791 DMI_MATCH(DMI_BOARD_NAME
, "KBox A-203"),
793 .driver_data
= (void *)&kempld_platform_data_generic
,
794 .callback
= kempld_create_platform_device
,
798 DMI_MATCH(DMI_BOARD_VENDOR
, "Kontron"),
799 DMI_MATCH(DMI_BOARD_NAME
, "COMe-m4AL"),
801 .driver_data
= (void *)&kempld_platform_data_generic
,
802 .callback
= kempld_create_platform_device
,
806 DMI_MATCH(DMI_BOARD_VENDOR
, "Kontron"),
807 DMI_MATCH(DMI_BOARD_NAME
, "COMe-mAL10"),
809 .driver_data
= (void *)&kempld_platform_data_generic
,
810 .callback
= kempld_create_platform_device
,
814 DMI_MATCH(DMI_BOARD_VENDOR
, "Kontron"),
815 DMI_MATCH(DMI_BOARD_NAME
, "mITX-APL"),
817 .driver_data
= (void *)&kempld_platform_data_generic
,
818 .callback
= kempld_create_platform_device
,
822 DMI_MATCH(DMI_BOARD_VENDOR
, "Kontron"),
823 DMI_MATCH(DMI_BOARD_NAME
, "ETX-OH"),
825 .driver_data
= (void *)&kempld_platform_data_generic
,
826 .callback
= kempld_create_platform_device
,
830 DMI_MATCH(DMI_BOARD_VENDOR
, "Kontron"),
831 DMI_MATCH(DMI_BOARD_NAME
, "COMe-mBT"),
833 .driver_data
= (void *)&kempld_platform_data_generic
,
834 .callback
= kempld_create_platform_device
,
838 DMI_MATCH(DMI_BOARD_VENDOR
, "Kontron"),
839 DMI_MATCH(DMI_BOARD_NAME
, "nanoETXexpress-TT"),
841 .driver_data
= (void *)&kempld_platform_data_generic
,
842 .callback
= kempld_create_platform_device
,
846 DMI_MATCH(DMI_BOARD_VENDOR
, "Kontron"),
847 DMI_MATCH(DMI_BOARD_NAME
, "nETXe-TT"),
849 .driver_data
= (void *)&kempld_platform_data_generic
,
850 .callback
= kempld_create_platform_device
,
854 DMI_MATCH(DMI_BOARD_VENDOR
, "Kontron"),
855 DMI_MATCH(DMI_BOARD_NAME
, "COMe-mTT"),
857 .driver_data
= (void *)&kempld_platform_data_generic
,
858 .callback
= kempld_create_platform_device
,
862 DMI_MATCH(DMI_BOARD_VENDOR
, "Kontron"),
863 DMI_MATCH(DMI_BOARD_NAME
, "COMe-mCT"),
865 .driver_data
= (void *)&kempld_platform_data_generic
,
866 .callback
= kempld_create_platform_device
,
870 DMI_MATCH(DMI_BOARD_VENDOR
, "Kontron"),
871 DMI_MATCH(DMI_BOARD_NAME
, "pITX-APL"),
873 .driver_data
= (void *)&kempld_platform_data_generic
,
874 .callback
= kempld_create_platform_device
,
878 DMI_MATCH(DMI_BOARD_VENDOR
, "Kontron"),
879 DMI_MATCH(DMI_BOARD_NAME
, "SMARC-sXAL"),
881 .driver_data
= (void *)&kempld_platform_data_generic
,
882 .callback
= kempld_create_platform_device
,
886 DMI_MATCH(DMI_BOARD_VENDOR
, "Kontron"),
887 DMI_MATCH(DMI_BOARD_NAME
, "SMARC-sXA4"),
889 .driver_data
= (void *)&kempld_platform_data_generic
,
890 .callback
= kempld_create_platform_device
,
894 DMI_MATCH(DMI_BOARD_VENDOR
, "Kontron"),
895 DMI_MATCH(DMI_BOARD_NAME
, "microETXexpress-DC"),
897 .driver_data
= (void *)&kempld_platform_data_generic
,
898 .callback
= kempld_create_platform_device
,
902 DMI_MATCH(DMI_BOARD_VENDOR
, "Kontron"),
903 DMI_MATCH(DMI_BOARD_NAME
, "COMe-cDC2"),
905 .driver_data
= (void *)&kempld_platform_data_generic
,
906 .callback
= kempld_create_platform_device
,
910 DMI_MATCH(DMI_BOARD_VENDOR
, "Kontron"),
911 DMI_MATCH(DMI_BOARD_NAME
, "microETXexpress-PC"),
913 .driver_data
= (void *)&kempld_platform_data_generic
,
914 .callback
= kempld_create_platform_device
,
918 DMI_MATCH(DMI_BOARD_VENDOR
, "Kontron"),
919 DMI_MATCH(DMI_BOARD_NAME
, "COMe-cPC2"),
921 .driver_data
= (void *)&kempld_platform_data_generic
,
922 .callback
= kempld_create_platform_device
,
926 DMI_MATCH(DMI_BOARD_VENDOR
, "Kontron"),
927 DMI_MATCH(DMI_BOARD_NAME
, "COMe-cCT6"),
929 .driver_data
= (void *)&kempld_platform_data_generic
,
930 .callback
= kempld_create_platform_device
,
934 DMI_MATCH(DMI_BOARD_VENDOR
, "Kontron"),
935 DMI_MATCH(DMI_BOARD_NAME
, "COMe-cTH6"),
937 .driver_data
= (void *)&kempld_platform_data_generic
,
938 .callback
= kempld_create_platform_device
,
942 DMI_MATCH(DMI_BOARD_VENDOR
, "Kontron"),
943 DMI_MATCH(DMI_BOARD_NAME
, "Qseven-Q7AL"),
945 .driver_data
= (void *)&kempld_platform_data_generic
,
946 .callback
= kempld_create_platform_device
,
950 MODULE_DEVICE_TABLE(dmi
, kempld_dmi_table
);
952 static int __init
kempld_init(void)
954 const struct dmi_system_id
*id
;
956 if (force_device_id
[0]) {
957 for (id
= kempld_dmi_table
;
958 id
->matches
[0].slot
!= DMI_NONE
; id
++)
959 if (strstr(id
->ident
, force_device_id
))
960 if (id
->callback
&& !id
->callback(id
))
962 if (id
->matches
[0].slot
== DMI_NONE
)
965 dmi_check_system(kempld_dmi_table
);
968 return platform_driver_register(&kempld_driver
);
971 static void __exit
kempld_exit(void)
974 platform_device_unregister(kempld_pdev
);
976 platform_driver_unregister(&kempld_driver
);
979 module_init(kempld_init
);
980 module_exit(kempld_exit
);
982 MODULE_DESCRIPTION("KEM PLD Core Driver");
983 MODULE_AUTHOR("Michael Brunner <michael.brunner@kontron.com>");
984 MODULE_LICENSE("GPL");
985 MODULE_ALIAS("platform:kempld-core");