root/drivers/mfd/kempld-core.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. kempld_get_hardware_mutex
  2. kempld_release_hardware_mutex
  3. kempld_get_info_generic
  4. kempld_register_cells_generic
  5. kempld_create_platform_device
  6. kempld_read8
  7. kempld_write8
  8. kempld_read16
  9. kempld_write16
  10. kempld_read32
  11. kempld_write32
  12. kempld_get_mutex
  13. kempld_release_mutex
  14. kempld_get_info
  15. kempld_register_cells
  16. kempld_get_type_string
  17. kempld_version_show
  18. kempld_specification_show
  19. kempld_type_show
  20. kempld_detect_device
  21. kempld_probe
  22. kempld_remove
  23. kempld_init
  24. kempld_exit

   1 // SPDX-License-Identifier: GPL-2.0-only
   2 /*
   3  * Kontron PLD MFD core driver
   4  *
   5  * Copyright (c) 2010-2013 Kontron Europe GmbH
   6  * Author: Michael Brunner <michael.brunner@kontron.com>
   7  */
   8 
   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>
  14 #include <linux/io.h>
  15 #include <linux/delay.h>
  16 
  17 #define MAX_ID_LEN 4
  18 static char force_device_id[MAX_ID_LEN + 1] = "";
  19 module_param_string(force_device_id, force_device_id,
  20                     sizeof(force_device_id), 0);
  21 MODULE_PARM_DESC(force_device_id, "Override detected product");
  22 
  23 /*
  24  * Get hardware mutex to block firmware from accessing the pld.
  25  * It is possible for the firmware may hold the mutex for an extended length of
  26  * time. This function will block until access has been granted.
  27  */
  28 static void kempld_get_hardware_mutex(struct kempld_device_data *pld)
  29 {
  30         /* The mutex bit will read 1 until access has been granted */
  31         while (ioread8(pld->io_index) & KEMPLD_MUTEX_KEY)
  32                 usleep_range(1000, 3000);
  33 }
  34 
  35 static void kempld_release_hardware_mutex(struct kempld_device_data *pld)
  36 {
  37         /* The harware mutex is released when 1 is written to the mutex bit. */
  38         iowrite8(KEMPLD_MUTEX_KEY, pld->io_index);
  39 }
  40 
  41 static int kempld_get_info_generic(struct kempld_device_data *pld)
  42 {
  43         u16 version;
  44         u8 spec;
  45 
  46         kempld_get_mutex(pld);
  47 
  48         version = kempld_read16(pld, KEMPLD_VERSION);
  49         spec = kempld_read8(pld, KEMPLD_SPEC);
  50         pld->info.buildnr = kempld_read16(pld, KEMPLD_BUILDNR);
  51 
  52         pld->info.minor = KEMPLD_VERSION_GET_MINOR(version);
  53         pld->info.major = KEMPLD_VERSION_GET_MAJOR(version);
  54         pld->info.number = KEMPLD_VERSION_GET_NUMBER(version);
  55         pld->info.type = KEMPLD_VERSION_GET_TYPE(version);
  56 
  57         if (spec == 0xff) {
  58                 pld->info.spec_minor = 0;
  59                 pld->info.spec_major = 1;
  60         } else {
  61                 pld->info.spec_minor = KEMPLD_SPEC_GET_MINOR(spec);
  62                 pld->info.spec_major = KEMPLD_SPEC_GET_MAJOR(spec);
  63         }
  64 
  65         if (pld->info.spec_major > 0)
  66                 pld->feature_mask = kempld_read16(pld, KEMPLD_FEATURE);
  67         else
  68                 pld->feature_mask = 0;
  69 
  70         kempld_release_mutex(pld);
  71 
  72         return 0;
  73 }
  74 
  75 enum kempld_cells {
  76         KEMPLD_I2C = 0,
  77         KEMPLD_WDT,
  78         KEMPLD_GPIO,
  79         KEMPLD_UART,
  80 };
  81 
  82 static const struct mfd_cell kempld_devs[] = {
  83         [KEMPLD_I2C] = {
  84                 .name = "kempld-i2c",
  85         },
  86         [KEMPLD_WDT] = {
  87                 .name = "kempld-wdt",
  88         },
  89         [KEMPLD_GPIO] = {
  90                 .name = "kempld-gpio",
  91         },
  92         [KEMPLD_UART] = {
  93                 .name = "kempld-uart",
  94         },
  95 };
  96 
  97 #define KEMPLD_MAX_DEVS ARRAY_SIZE(kempld_devs)
  98 
  99 static int kempld_register_cells_generic(struct kempld_device_data *pld)
 100 {
 101         struct mfd_cell devs[KEMPLD_MAX_DEVS];
 102         int i = 0;
 103 
 104         if (pld->feature_mask & KEMPLD_FEATURE_BIT_I2C)
 105                 devs[i++] = kempld_devs[KEMPLD_I2C];
 106 
 107         if (pld->feature_mask & KEMPLD_FEATURE_BIT_WATCHDOG)
 108                 devs[i++] = kempld_devs[KEMPLD_WDT];
 109 
 110         if (pld->feature_mask & KEMPLD_FEATURE_BIT_GPIO)
 111                 devs[i++] = kempld_devs[KEMPLD_GPIO];
 112 
 113         if (pld->feature_mask & KEMPLD_FEATURE_MASK_UART)
 114                 devs[i++] = kempld_devs[KEMPLD_UART];
 115 
 116         return mfd_add_devices(pld->dev, -1, devs, i, NULL, 0, NULL);
 117 }
 118 
 119 static struct resource kempld_ioresource = {
 120         .start  = KEMPLD_IOINDEX,
 121         .end    = KEMPLD_IODATA,
 122         .flags  = IORESOURCE_IO,
 123 };
 124 
 125 static const struct kempld_platform_data kempld_platform_data_generic = {
 126         .pld_clock              = KEMPLD_CLK,
 127         .ioresource             = &kempld_ioresource,
 128         .get_hardware_mutex     = kempld_get_hardware_mutex,
 129         .release_hardware_mutex = kempld_release_hardware_mutex,
 130         .get_info               = kempld_get_info_generic,
 131         .register_cells         = kempld_register_cells_generic,
 132 };
 133 
 134 static struct platform_device *kempld_pdev;
 135 
 136 static int kempld_create_platform_device(const struct dmi_system_id *id)
 137 {
 138         const struct kempld_platform_data *pdata = id->driver_data;
 139         int ret;
 140 
 141         kempld_pdev = platform_device_alloc("kempld", -1);
 142         if (!kempld_pdev)
 143                 return -ENOMEM;
 144 
 145         ret = platform_device_add_data(kempld_pdev, pdata, sizeof(*pdata));
 146         if (ret)
 147                 goto err;
 148 
 149         ret = platform_device_add_resources(kempld_pdev, pdata->ioresource, 1);
 150         if (ret)
 151                 goto err;
 152 
 153         ret = platform_device_add(kempld_pdev);
 154         if (ret)
 155                 goto err;
 156 
 157         return 0;
 158 err:
 159         platform_device_put(kempld_pdev);
 160         return ret;
 161 }
 162 
 163 /**
 164  * kempld_read8 - read 8 bit register
 165  * @pld: kempld_device_data structure describing the PLD
 166  * @index: register index on the chip
 167  *
 168  * kempld_get_mutex must be called prior to calling this function.
 169  */
 170 u8 kempld_read8(struct kempld_device_data *pld, u8 index)
 171 {
 172         iowrite8(index, pld->io_index);
 173         return ioread8(pld->io_data);
 174 }
 175 EXPORT_SYMBOL_GPL(kempld_read8);
 176 
 177 /**
 178  * kempld_write8 - write 8 bit register
 179  * @pld: kempld_device_data structure describing the PLD
 180  * @index: register index on the chip
 181  * @data: new register value
 182  *
 183  * kempld_get_mutex must be called prior to calling this function.
 184  */
 185 void kempld_write8(struct kempld_device_data *pld, u8 index, u8 data)
 186 {
 187         iowrite8(index, pld->io_index);
 188         iowrite8(data, pld->io_data);
 189 }
 190 EXPORT_SYMBOL_GPL(kempld_write8);
 191 
 192 /**
 193  * kempld_read16 - read 16 bit register
 194  * @pld: kempld_device_data structure describing the PLD
 195  * @index: register index on the chip
 196  *
 197  * kempld_get_mutex must be called prior to calling this function.
 198  */
 199 u16 kempld_read16(struct kempld_device_data *pld, u8 index)
 200 {
 201         return kempld_read8(pld, index) | kempld_read8(pld, index + 1) << 8;
 202 }
 203 EXPORT_SYMBOL_GPL(kempld_read16);
 204 
 205 /**
 206  * kempld_write16 - write 16 bit register
 207  * @pld: kempld_device_data structure describing the PLD
 208  * @index: register index on the chip
 209  * @data: new register value
 210  *
 211  * kempld_get_mutex must be called prior to calling this function.
 212  */
 213 void kempld_write16(struct kempld_device_data *pld, u8 index, u16 data)
 214 {
 215         kempld_write8(pld, index, (u8)data);
 216         kempld_write8(pld, index + 1, (u8)(data >> 8));
 217 }
 218 EXPORT_SYMBOL_GPL(kempld_write16);
 219 
 220 /**
 221  * kempld_read32 - read 32 bit register
 222  * @pld: kempld_device_data structure describing the PLD
 223  * @index: register index on the chip
 224  *
 225  * kempld_get_mutex must be called prior to calling this function.
 226  */
 227 u32 kempld_read32(struct kempld_device_data *pld, u8 index)
 228 {
 229         return kempld_read16(pld, index) | kempld_read16(pld, index + 2) << 16;
 230 }
 231 EXPORT_SYMBOL_GPL(kempld_read32);
 232 
 233 /**
 234  * kempld_write32 - write 32 bit register
 235  * @pld: kempld_device_data structure describing the PLD
 236  * @index: register index on the chip
 237  * @data: new register value
 238  *
 239  * kempld_get_mutex must be called prior to calling this function.
 240  */
 241 void kempld_write32(struct kempld_device_data *pld, u8 index, u32 data)
 242 {
 243         kempld_write16(pld, index, (u16)data);
 244         kempld_write16(pld, index + 2, (u16)(data >> 16));
 245 }
 246 EXPORT_SYMBOL_GPL(kempld_write32);
 247 
 248 /**
 249  * kempld_get_mutex - acquire PLD mutex
 250  * @pld: kempld_device_data structure describing the PLD
 251  */
 252 void kempld_get_mutex(struct kempld_device_data *pld)
 253 {
 254         const struct kempld_platform_data *pdata = dev_get_platdata(pld->dev);
 255 
 256         mutex_lock(&pld->lock);
 257         pdata->get_hardware_mutex(pld);
 258 }
 259 EXPORT_SYMBOL_GPL(kempld_get_mutex);
 260 
 261 /**
 262  * kempld_release_mutex - release PLD mutex
 263  * @pld: kempld_device_data structure describing the PLD
 264  */
 265 void kempld_release_mutex(struct kempld_device_data *pld)
 266 {
 267         const struct kempld_platform_data *pdata = dev_get_platdata(pld->dev);
 268 
 269         pdata->release_hardware_mutex(pld);
 270         mutex_unlock(&pld->lock);
 271 }
 272 EXPORT_SYMBOL_GPL(kempld_release_mutex);
 273 
 274 /**
 275  * kempld_get_info - update device specific information
 276  * @pld: kempld_device_data structure describing the PLD
 277  *
 278  * This function calls the configured board specific kempld_get_info_XXXX
 279  * function which is responsible for gathering information about the specific
 280  * hardware. The information is then stored within the pld structure.
 281  */
 282 static int kempld_get_info(struct kempld_device_data *pld)
 283 {
 284         int ret;
 285         const struct kempld_platform_data *pdata = dev_get_platdata(pld->dev);
 286         char major, minor;
 287 
 288         ret = pdata->get_info(pld);
 289         if (ret)
 290                 return ret;
 291 
 292         /* The Kontron PLD firmware version string has the following format:
 293          * Pwxy.zzzz
 294          *   P:    Fixed
 295          *   w:    PLD number    - 1 hex digit
 296          *   x:    Major version - 1 alphanumerical digit (0-9A-V)
 297          *   y:    Minor version - 1 alphanumerical digit (0-9A-V)
 298          *   zzzz: Build number  - 4 zero padded hex digits */
 299 
 300         if (pld->info.major < 10)
 301                 major = pld->info.major + '0';
 302         else
 303                 major = (pld->info.major - 10) + 'A';
 304         if (pld->info.minor < 10)
 305                 minor = pld->info.minor + '0';
 306         else
 307                 minor = (pld->info.minor - 10) + 'A';
 308 
 309         ret = scnprintf(pld->info.version, sizeof(pld->info.version),
 310                         "P%X%c%c.%04X", pld->info.number, major, minor,
 311                         pld->info.buildnr);
 312         if (ret < 0)
 313                 return ret;
 314 
 315         return 0;
 316 }
 317 
 318 /*
 319  * kempld_register_cells - register cell drivers
 320  *
 321  * This function registers cell drivers for the detected hardware by calling
 322  * the configured kempld_register_cells_XXXX function which is responsible
 323  * to detect and register the needed cell drivers.
 324  */
 325 static int kempld_register_cells(struct kempld_device_data *pld)
 326 {
 327         const struct kempld_platform_data *pdata = dev_get_platdata(pld->dev);
 328 
 329         return pdata->register_cells(pld);
 330 }
 331 
 332 static const char *kempld_get_type_string(struct kempld_device_data *pld)
 333 {
 334         const char *version_type;
 335 
 336         switch (pld->info.type) {
 337         case 0:
 338                 version_type = "release";
 339                 break;
 340         case 1:
 341                 version_type = "debug";
 342                 break;
 343         case 2:
 344                 version_type = "custom";
 345                 break;
 346         default:
 347                 version_type = "unspecified";
 348                 break;
 349         }
 350 
 351         return version_type;
 352 }
 353 
 354 static ssize_t kempld_version_show(struct device *dev,
 355                 struct device_attribute *attr, char *buf)
 356 {
 357         struct kempld_device_data *pld = dev_get_drvdata(dev);
 358 
 359         return scnprintf(buf, PAGE_SIZE, "%s\n", pld->info.version);
 360 }
 361 
 362 static ssize_t kempld_specification_show(struct device *dev,
 363                 struct device_attribute *attr, char *buf)
 364 {
 365         struct kempld_device_data *pld = dev_get_drvdata(dev);
 366 
 367         return scnprintf(buf, PAGE_SIZE, "%d.%d\n", pld->info.spec_major,
 368                        pld->info.spec_minor);
 369 }
 370 
 371 static ssize_t kempld_type_show(struct device *dev,
 372                 struct device_attribute *attr, char *buf)
 373 {
 374         struct kempld_device_data *pld = dev_get_drvdata(dev);
 375 
 376         return scnprintf(buf, PAGE_SIZE, "%s\n", kempld_get_type_string(pld));
 377 }
 378 
 379 static DEVICE_ATTR(pld_version, S_IRUGO, kempld_version_show, NULL);
 380 static DEVICE_ATTR(pld_specification, S_IRUGO, kempld_specification_show,
 381                    NULL);
 382 static DEVICE_ATTR(pld_type, S_IRUGO, kempld_type_show, NULL);
 383 
 384 static struct attribute *pld_attributes[] = {
 385         &dev_attr_pld_version.attr,
 386         &dev_attr_pld_specification.attr,
 387         &dev_attr_pld_type.attr,
 388         NULL
 389 };
 390 
 391 static const struct attribute_group pld_attr_group = {
 392         .attrs = pld_attributes,
 393 };
 394 
 395 static int kempld_detect_device(struct kempld_device_data *pld)
 396 {
 397         u8 index_reg;
 398         int ret;
 399 
 400         mutex_lock(&pld->lock);
 401 
 402         /* Check for empty IO space */
 403         index_reg = ioread8(pld->io_index);
 404         if (index_reg == 0xff && ioread8(pld->io_data) == 0xff) {
 405                 mutex_unlock(&pld->lock);
 406                 return -ENODEV;
 407         }
 408 
 409         /* Release hardware mutex if acquired */
 410         if (!(index_reg & KEMPLD_MUTEX_KEY)) {
 411                 iowrite8(KEMPLD_MUTEX_KEY, pld->io_index);
 412                 /* PXT and COMe-cPC2 boards may require a second release */
 413                 iowrite8(KEMPLD_MUTEX_KEY, pld->io_index);
 414         }
 415 
 416         mutex_unlock(&pld->lock);
 417 
 418         ret = kempld_get_info(pld);
 419         if (ret)
 420                 return ret;
 421 
 422         dev_info(pld->dev, "Found Kontron PLD - %s (%s), spec %d.%d\n",
 423                  pld->info.version, kempld_get_type_string(pld),
 424                  pld->info.spec_major, pld->info.spec_minor);
 425 
 426         ret = sysfs_create_group(&pld->dev->kobj, &pld_attr_group);
 427         if (ret)
 428                 return ret;
 429 
 430         ret = kempld_register_cells(pld);
 431         if (ret)
 432                 sysfs_remove_group(&pld->dev->kobj, &pld_attr_group);
 433 
 434         return ret;
 435 }
 436 
 437 static int kempld_probe(struct platform_device *pdev)
 438 {
 439         const struct kempld_platform_data *pdata =
 440                 dev_get_platdata(&pdev->dev);
 441         struct device *dev = &pdev->dev;
 442         struct kempld_device_data *pld;
 443         struct resource *ioport;
 444 
 445         pld = devm_kzalloc(dev, sizeof(*pld), GFP_KERNEL);
 446         if (!pld)
 447                 return -ENOMEM;
 448 
 449         ioport = platform_get_resource(pdev, IORESOURCE_IO, 0);
 450         if (!ioport)
 451                 return -EINVAL;
 452 
 453         pld->io_base = devm_ioport_map(dev, ioport->start,
 454                                         resource_size(ioport));
 455         if (!pld->io_base)
 456                 return -ENOMEM;
 457 
 458         pld->io_index = pld->io_base;
 459         pld->io_data = pld->io_base + 1;
 460         pld->pld_clock = pdata->pld_clock;
 461         pld->dev = dev;
 462 
 463         mutex_init(&pld->lock);
 464         platform_set_drvdata(pdev, pld);
 465 
 466         return kempld_detect_device(pld);
 467 }
 468 
 469 static int kempld_remove(struct platform_device *pdev)
 470 {
 471         struct kempld_device_data *pld = platform_get_drvdata(pdev);
 472         const struct kempld_platform_data *pdata = dev_get_platdata(pld->dev);
 473 
 474         sysfs_remove_group(&pld->dev->kobj, &pld_attr_group);
 475 
 476         mfd_remove_devices(&pdev->dev);
 477         pdata->release_hardware_mutex(pld);
 478 
 479         return 0;
 480 }
 481 
 482 static struct platform_driver kempld_driver = {
 483         .driver         = {
 484                 .name   = "kempld",
 485         },
 486         .probe          = kempld_probe,
 487         .remove         = kempld_remove,
 488 };
 489 
 490 static const struct dmi_system_id kempld_dmi_table[] __initconst = {
 491         {
 492                 .ident = "BBD6",
 493                 .matches = {
 494                         DMI_MATCH(DMI_BOARD_VENDOR, "Kontron"),
 495                         DMI_MATCH(DMI_BOARD_NAME, "COMe-bBD"),
 496                 },
 497                 .driver_data = (void *)&kempld_platform_data_generic,
 498                 .callback = kempld_create_platform_device,
 499         }, {
 500                 .ident = "BBL6",
 501                 .matches = {
 502                         DMI_MATCH(DMI_BOARD_VENDOR, "Kontron"),
 503                         DMI_MATCH(DMI_BOARD_NAME, "COMe-bBL6"),
 504                 },
 505                 .driver_data = (void *)&kempld_platform_data_generic,
 506                 .callback = kempld_create_platform_device,
 507         }, {
 508                 .ident = "BHL6",
 509                 .matches = {
 510                         DMI_MATCH(DMI_BOARD_VENDOR, "Kontron"),
 511                         DMI_MATCH(DMI_BOARD_NAME, "COMe-bHL6"),
 512                 },
 513                 .driver_data = (void *)&kempld_platform_data_generic,
 514                 .callback = kempld_create_platform_device,
 515         }, {
 516                 .ident = "BKL6",
 517                 .matches = {
 518                         DMI_MATCH(DMI_BOARD_VENDOR, "Kontron"),
 519                         DMI_MATCH(DMI_BOARD_NAME, "COMe-bKL6"),
 520                 },
 521                 .driver_data = (void *)&kempld_platform_data_generic,
 522                 .callback = kempld_create_platform_device,
 523         }, {
 524                 .ident = "BSL6",
 525                 .matches = {
 526                         DMI_MATCH(DMI_BOARD_VENDOR, "Kontron"),
 527                         DMI_MATCH(DMI_BOARD_NAME, "COMe-bSL6"),
 528                 },
 529                 .driver_data = (void *)&kempld_platform_data_generic,
 530                 .callback = kempld_create_platform_device,
 531         }, {
 532                 .ident = "CAL6",
 533                 .matches = {
 534                         DMI_MATCH(DMI_BOARD_VENDOR, "Kontron"),
 535                         DMI_MATCH(DMI_BOARD_NAME, "COMe-cAL"),
 536                 },
 537                 .driver_data = (void *)&kempld_platform_data_generic,
 538                 .callback = kempld_create_platform_device,
 539         }, {
 540                 .ident = "CBL6",
 541                 .matches = {
 542                         DMI_MATCH(DMI_BOARD_VENDOR, "Kontron"),
 543                         DMI_MATCH(DMI_BOARD_NAME, "COMe-cBL6"),
 544                 },
 545                 .driver_data = (void *)&kempld_platform_data_generic,
 546                 .callback = kempld_create_platform_device,
 547         }, {
 548                 .ident = "CBW6",
 549                 .matches = {
 550                         DMI_MATCH(DMI_BOARD_VENDOR, "Kontron"),
 551                         DMI_MATCH(DMI_BOARD_NAME, "COMe-cBW6"),
 552                 },
 553                 .driver_data = (void *)&kempld_platform_data_generic,
 554                 .callback = kempld_create_platform_device,
 555         }, {
 556                 .ident = "CCR2",
 557                 .matches = {
 558                         DMI_MATCH(DMI_BOARD_VENDOR, "Kontron"),
 559                         DMI_MATCH(DMI_BOARD_NAME, "COMe-bIP2"),
 560                 },
 561                 .driver_data = (void *)&kempld_platform_data_generic,
 562                 .callback = kempld_create_platform_device,
 563         }, {
 564                 .ident = "CCR6",
 565                 .matches = {
 566                         DMI_MATCH(DMI_BOARD_VENDOR, "Kontron"),
 567                         DMI_MATCH(DMI_BOARD_NAME, "COMe-bIP6"),
 568                 },
 569                 .driver_data = (void *)&kempld_platform_data_generic,
 570                 .callback = kempld_create_platform_device,
 571         }, {
 572                 .ident = "CHL6",
 573                 .matches = {
 574                         DMI_MATCH(DMI_BOARD_VENDOR, "Kontron"),
 575                         DMI_MATCH(DMI_BOARD_NAME, "COMe-cHL6"),
 576                 },
 577                 .driver_data = (void *)&kempld_platform_data_generic,
 578                 .callback = kempld_create_platform_device,
 579         }, {
 580                 .ident = "CHR2",
 581                 .matches = {
 582                         DMI_MATCH(DMI_BOARD_VENDOR, "Kontron"),
 583                         DMI_MATCH(DMI_BOARD_NAME, "ETXexpress-SC T2"),
 584                 },
 585                 .driver_data = (void *)&kempld_platform_data_generic,
 586                 .callback = kempld_create_platform_device,
 587         }, {
 588                 .ident = "CHR2",
 589                 .matches = {
 590                         DMI_MATCH(DMI_BOARD_VENDOR, "Kontron"),
 591                         DMI_MATCH(DMI_BOARD_NAME, "ETXe-SC T2"),
 592                 },
 593                 .driver_data = (void *)&kempld_platform_data_generic,
 594                 .callback = kempld_create_platform_device,
 595         }, {
 596                 .ident = "CHR2",
 597                 .matches = {
 598                         DMI_MATCH(DMI_BOARD_VENDOR, "Kontron"),
 599                         DMI_MATCH(DMI_BOARD_NAME, "COMe-bSC2"),
 600                 },
 601                 .driver_data = (void *)&kempld_platform_data_generic,
 602                 .callback = kempld_create_platform_device,
 603         }, {
 604                 .ident = "CHR6",
 605                 .matches = {
 606                         DMI_MATCH(DMI_BOARD_VENDOR, "Kontron"),
 607                         DMI_MATCH(DMI_BOARD_NAME, "ETXexpress-SC T6"),
 608                 },
 609                 .driver_data = (void *)&kempld_platform_data_generic,
 610                 .callback = kempld_create_platform_device,
 611         }, {
 612                 .ident = "CHR6",
 613                 .matches = {
 614                         DMI_MATCH(DMI_BOARD_VENDOR, "Kontron"),
 615                         DMI_MATCH(DMI_BOARD_NAME, "ETXe-SC T6"),
 616                 },
 617                 .driver_data = (void *)&kempld_platform_data_generic,
 618                 .callback = kempld_create_platform_device,
 619         }, {
 620                 .ident = "CHR6",
 621                 .matches = {
 622                         DMI_MATCH(DMI_BOARD_VENDOR, "Kontron"),
 623                         DMI_MATCH(DMI_BOARD_NAME, "COMe-bSC6"),
 624                 },
 625                 .driver_data = (void *)&kempld_platform_data_generic,
 626                 .callback = kempld_create_platform_device,
 627         }, {
 628                 .ident = "CKL6",
 629                 .matches = {
 630                         DMI_MATCH(DMI_BOARD_VENDOR, "Kontron"),
 631                         DMI_MATCH(DMI_BOARD_NAME, "COMe-cKL6"),
 632                 },
 633                 .driver_data = (void *)&kempld_platform_data_generic,
 634                 .callback = kempld_create_platform_device,
 635         }, {
 636                 .ident = "CNTG",
 637                 .matches = {
 638                         DMI_MATCH(DMI_BOARD_VENDOR, "Kontron"),
 639                         DMI_MATCH(DMI_BOARD_NAME, "ETXexpress-PC"),
 640                 },
 641                 .driver_data = (void *)&kempld_platform_data_generic,
 642                 .callback = kempld_create_platform_device,
 643         }, {
 644                 .ident = "CNTG",
 645                 .matches = {
 646                         DMI_MATCH(DMI_BOARD_VENDOR, "Kontron"),
 647                         DMI_MATCH(DMI_BOARD_NAME, "COMe-bPC2"),
 648                 },
 649                 .driver_data = (void *)&kempld_platform_data_generic,
 650                 .callback = kempld_create_platform_device,
 651         }, {
 652                 .ident = "CNTX",
 653                 .matches = {
 654                         DMI_MATCH(DMI_BOARD_VENDOR, "Kontron"),
 655                         DMI_MATCH(DMI_BOARD_NAME, "PXT"),
 656                 },
 657                 .driver_data = (void *)&kempld_platform_data_generic,
 658                 .callback = kempld_create_platform_device,
 659         }, {
 660                 .ident = "CSL6",
 661                 .matches = {
 662                         DMI_MATCH(DMI_BOARD_VENDOR, "Kontron"),
 663                         DMI_MATCH(DMI_BOARD_NAME, "COMe-cSL6"),
 664                 },
 665                 .driver_data = (void *)&kempld_platform_data_generic,
 666                 .callback = kempld_create_platform_device,
 667         }, {
 668                 .ident = "CVV6",
 669                 .matches = {
 670                         DMI_MATCH(DMI_BOARD_VENDOR, "Kontron"),
 671                         DMI_MATCH(DMI_BOARD_NAME, "COMe-cBT"),
 672                 },
 673                 .driver_data = (void *)&kempld_platform_data_generic,
 674                 .callback = kempld_create_platform_device,
 675         }, {
 676                 .ident = "FRI2",
 677                 .matches = {
 678                         DMI_MATCH(DMI_BOARD_VENDOR, "Kontron"),
 679                         DMI_MATCH(DMI_BIOS_VERSION, "FRI2"),
 680                 },
 681                 .driver_data = (void *)&kempld_platform_data_generic,
 682                 .callback = kempld_create_platform_device,
 683         }, {
 684                 .ident = "FRI2",
 685                 .matches = {
 686                         DMI_MATCH(DMI_PRODUCT_NAME, "Fish River Island II"),
 687                 },
 688                 .driver_data = (void *)&kempld_platform_data_generic,
 689                 .callback = kempld_create_platform_device,
 690         }, {
 691                 .ident = "MAL1",
 692                 .matches = {
 693                         DMI_MATCH(DMI_BOARD_VENDOR, "Kontron"),
 694                         DMI_MATCH(DMI_BOARD_NAME, "COMe-mAL10"),
 695                 },
 696                 .driver_data = (void *)&kempld_platform_data_generic,
 697                 .callback = kempld_create_platform_device,
 698         }, {
 699                 .ident = "MBR1",
 700                 .matches = {
 701                         DMI_MATCH(DMI_BOARD_VENDOR, "Kontron"),
 702                         DMI_MATCH(DMI_BOARD_NAME, "ETX-OH"),
 703                 },
 704                 .driver_data = (void *)&kempld_platform_data_generic,
 705                 .callback = kempld_create_platform_device,
 706         }, {
 707                 .ident = "MVV1",
 708                 .matches = {
 709                         DMI_MATCH(DMI_BOARD_VENDOR, "Kontron"),
 710                         DMI_MATCH(DMI_BOARD_NAME, "COMe-mBT"),
 711                 },
 712                 .driver_data = (void *)&kempld_platform_data_generic,
 713                 .callback = kempld_create_platform_device,
 714         }, {
 715                 .ident = "NTC1",
 716                 .matches = {
 717                         DMI_MATCH(DMI_BOARD_VENDOR, "Kontron"),
 718                         DMI_MATCH(DMI_BOARD_NAME, "nanoETXexpress-TT"),
 719                 },
 720                 .driver_data = (void *)&kempld_platform_data_generic,
 721                 .callback = kempld_create_platform_device,
 722         }, {
 723                 .ident = "NTC1",
 724                 .matches = {
 725                         DMI_MATCH(DMI_BOARD_VENDOR, "Kontron"),
 726                         DMI_MATCH(DMI_BOARD_NAME, "nETXe-TT"),
 727                 },
 728                 .driver_data = (void *)&kempld_platform_data_generic,
 729                 .callback = kempld_create_platform_device,
 730         }, {
 731                 .ident = "NTC1",
 732                 .matches = {
 733                         DMI_MATCH(DMI_BOARD_VENDOR, "Kontron"),
 734                         DMI_MATCH(DMI_BOARD_NAME, "COMe-mTT"),
 735                 },
 736                 .driver_data = (void *)&kempld_platform_data_generic,
 737                 .callback = kempld_create_platform_device,
 738         }, {
 739                 .ident = "NUP1",
 740                 .matches = {
 741                         DMI_MATCH(DMI_BOARD_VENDOR, "Kontron"),
 742                         DMI_MATCH(DMI_BOARD_NAME, "COMe-mCT"),
 743                 },
 744                 .driver_data = (void *)&kempld_platform_data_generic,
 745                 .callback = kempld_create_platform_device,
 746         }, {
 747                 .ident = "UNP1",
 748                 .matches = {
 749                         DMI_MATCH(DMI_BOARD_VENDOR, "Kontron"),
 750                         DMI_MATCH(DMI_BOARD_NAME, "microETXexpress-DC"),
 751                 },
 752                 .driver_data = (void *)&kempld_platform_data_generic,
 753                 .callback = kempld_create_platform_device,
 754         }, {
 755                 .ident = "UNP1",
 756                 .matches = {
 757                         DMI_MATCH(DMI_BOARD_VENDOR, "Kontron"),
 758                         DMI_MATCH(DMI_BOARD_NAME, "COMe-cDC2"),
 759                 },
 760                 .driver_data = (void *)&kempld_platform_data_generic,
 761                 .callback = kempld_create_platform_device,
 762         }, {
 763                 .ident = "UNTG",
 764                 .matches = {
 765                         DMI_MATCH(DMI_BOARD_VENDOR, "Kontron"),
 766                         DMI_MATCH(DMI_BOARD_NAME, "microETXexpress-PC"),
 767                 },
 768                 .driver_data = (void *)&kempld_platform_data_generic,
 769                 .callback = kempld_create_platform_device,
 770         }, {
 771                 .ident = "UNTG",
 772                 .matches = {
 773                         DMI_MATCH(DMI_BOARD_VENDOR, "Kontron"),
 774                         DMI_MATCH(DMI_BOARD_NAME, "COMe-cPC2"),
 775                 },
 776                 .driver_data = (void *)&kempld_platform_data_generic,
 777                 .callback = kempld_create_platform_device,
 778         }, {
 779                 .ident = "UUP6",
 780                 .matches = {
 781                         DMI_MATCH(DMI_BOARD_VENDOR, "Kontron"),
 782                         DMI_MATCH(DMI_BOARD_NAME, "COMe-cCT6"),
 783                 },
 784                 .driver_data = (void *)&kempld_platform_data_generic,
 785                 .callback = kempld_create_platform_device,
 786         },
 787         {
 788                 .ident = "UTH6",
 789                 .matches = {
 790                         DMI_MATCH(DMI_BOARD_VENDOR, "Kontron"),
 791                         DMI_MATCH(DMI_BOARD_NAME, "COMe-cTH6"),
 792                 },
 793                 .driver_data = (void *)&kempld_platform_data_generic,
 794                 .callback = kempld_create_platform_device,
 795         },
 796         {}
 797 };
 798 MODULE_DEVICE_TABLE(dmi, kempld_dmi_table);
 799 
 800 static int __init kempld_init(void)
 801 {
 802         const struct dmi_system_id *id;
 803 
 804         if (force_device_id[0]) {
 805                 for (id = kempld_dmi_table;
 806                      id->matches[0].slot != DMI_NONE; id++)
 807                         if (strstr(id->ident, force_device_id))
 808                                 if (id->callback && !id->callback(id))
 809                                         break;
 810                 if (id->matches[0].slot == DMI_NONE)
 811                         return -ENODEV;
 812         } else {
 813                 if (!dmi_check_system(kempld_dmi_table))
 814                         return -ENODEV;
 815         }
 816 
 817         return platform_driver_register(&kempld_driver);
 818 }
 819 
 820 static void __exit kempld_exit(void)
 821 {
 822         if (kempld_pdev)
 823                 platform_device_unregister(kempld_pdev);
 824 
 825         platform_driver_unregister(&kempld_driver);
 826 }
 827 
 828 module_init(kempld_init);
 829 module_exit(kempld_exit);
 830 
 831 MODULE_DESCRIPTION("KEM PLD Core Driver");
 832 MODULE_AUTHOR("Michael Brunner <michael.brunner@kontron.com>");
 833 MODULE_LICENSE("GPL");
 834 MODULE_ALIAS("platform:kempld-core");

/* [<][>][^][v][top][bottom][index][help] */