x86/mrst: Add SFI platform device parsing code

SFI provides a series of tables. These describe the platform devices present
including SPI and I²C devices, as well as various sensors, keypads and other
glue as well as interfaces provided via the SCU IPC mechanism (intel_scu_ipc.c)

This patch is a merge of the core elements and relevant fixes from the
Intel development code by Feng, Alek, myself into a single coherent patch
for upstream submission.

It provides the needed infrastructure to register I2C, SPI and platform devices
described by the tables, as well as handlers for some of the hardware already
supported in kernel. The 0.8 firmware also provides GPIO tables.

Devices are created at boot time or if they are SCU dependant at the point an
SCU is discovered. The existing Linux device mechanisms will then handle the
device binding. At an abstract level this is an SFI to Linux device translator.

Device/platform specific setup/glue is in this file. This is done so that the
drivers for the generic I²C and SPI bus devices remain cross platform as they
should.

(Updated from RFC version to correct the emc1403 name used by the firmware
and a wrongly used #define)

Signed-off-by: Alek Du <alek.du@linux.intel.com>
LKML-Reference: <20101109112158.20013.6158.stgit@localhost.localdomain>
[Clean ups, removal of 0.7 support]
Signed-off-by: Feng Tang <feng.tang@linux.intel.com>
[Clean ups]
Signed-off-by: Alan Cox <alan@linux.intel.com>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>

authored by

Feng Tang and committed by
Thomas Gleixner
1da4b1c6 814ce252

+527 -7
+2
arch/x86/Kconfig
··· 385 385 depends on X86_EXTENDED_PLATFORM 386 386 depends on X86_IO_APIC 387 387 select APB_TIMER 388 + select I2C 389 + select SPI 388 390 ---help--- 389 391 Moorestown is Intel's Low Power Intel Architecture (LPIA) based Moblin 390 392 Internet Device(MID) platform. Moorestown consists of two chips:
+4
arch/x86/include/asm/mrst.h
··· 50 50 51 51 extern struct console early_hsu_console; 52 52 extern void hsu_early_console_init(void); 53 + 54 + extern void intel_scu_devices_create(void); 55 + extern void intel_scu_devices_destroy(void); 56 + 53 57 #endif /* _ASM_X86_MRST_H */
+511 -4
arch/x86/platform/mrst/mrst.c
··· 9 9 * as published by the Free Software Foundation; version 2 10 10 * of the License. 11 11 */ 12 + 13 + #define pr_fmt(fmt) "mrst: " fmt 14 + 12 15 #include <linux/init.h> 13 16 #include <linux/kernel.h> 14 17 #include <linux/sfi.h> 18 + #include <linux/intel_pmic_gpio.h> 19 + #include <linux/spi/spi.h> 20 + #include <linux/i2c.h> 21 + #include <linux/i2c/pca953x.h> 22 + #include <linux/gpio_keys.h> 23 + #include <linux/input.h> 24 + #include <linux/platform_device.h> 15 25 #include <linux/irq.h> 16 26 #include <linux/module.h> 17 27 ··· 33 23 #include <asm/mrst.h> 34 24 #include <asm/io.h> 35 25 #include <asm/i8259.h> 26 + #include <asm/intel_scu_ipc.h> 36 27 #include <asm/apb_timer.h> 28 + 37 29 38 30 /* 39 31 * the clockevent devices on Moorestown/Medfield can be APBT or LAPIC clock, ··· 114 102 memcpy(sfi_mtimer_array, pentry, totallen); 115 103 } 116 104 117 - printk(KERN_INFO "SFI: MTIMER info (num = %d):\n", sfi_mtimer_num); 105 + pr_debug("SFI MTIMER info (num = %d):\n", sfi_mtimer_num); 118 106 pentry = sfi_mtimer_array; 119 107 for (totallen = 0; totallen < sfi_mtimer_num; totallen++, pentry++) { 120 - printk(KERN_INFO "timer[%d]: paddr = 0x%08x, freq = %dHz," 108 + pr_debug("timer[%d]: paddr = 0x%08x, freq = %dHz," 121 109 " irq = %d\n", totallen, (u32)pentry->phys_addr, 122 110 pentry->freq_hz, pentry->irq); 123 111 if (!pentry->irq) ··· 188 176 memcpy(sfi_mrtc_array, pentry, totallen); 189 177 } 190 178 191 - printk(KERN_INFO "SFI: RTC info (num = %d):\n", sfi_mrtc_num); 179 + pr_debug("SFI RTC info (num = %d):\n", sfi_mrtc_num); 192 180 pentry = sfi_mrtc_array; 193 181 for (totallen = 0; totallen < sfi_mrtc_num; totallen++, pentry++) { 194 - printk(KERN_INFO "RTC[%d]: paddr = 0x%08x, irq = %d\n", 182 + pr_debug("RTC[%d]: paddr = 0x%08x, irq = %d\n", 195 183 totallen, (u32)pentry->phys_addr, pentry->irq); 196 184 mp_irq.type = MP_IOAPIC; 197 185 mp_irq.irqtype = mp_INT; ··· 321 309 return 0; 322 310 } 323 311 __setup("x86_mrst_timer=", setup_x86_mrst_timer); 312 + 313 + /* 314 + * Parsing GPIO table first, since the DEVS table will need this table 315 + * to map the pin name to the actual pin. 316 + */ 317 + static struct sfi_gpio_table_entry *gpio_table; 318 + static int gpio_num_entry; 319 + 320 + static int __init sfi_parse_gpio(struct sfi_table_header *table) 321 + { 322 + struct sfi_table_simple *sb; 323 + struct sfi_gpio_table_entry *pentry; 324 + int num, i; 325 + 326 + if (gpio_table) 327 + return 0; 328 + sb = (struct sfi_table_simple *)table; 329 + num = SFI_GET_NUM_ENTRIES(sb, struct sfi_gpio_table_entry); 330 + pentry = (struct sfi_gpio_table_entry *)sb->pentry; 331 + 332 + gpio_table = (struct sfi_gpio_table_entry *) 333 + kmalloc(num * sizeof(*pentry), GFP_KERNEL); 334 + if (!gpio_table) 335 + return -1; 336 + memcpy(gpio_table, pentry, num * sizeof(*pentry)); 337 + gpio_num_entry = num; 338 + 339 + pr_debug("GPIO pin info:\n"); 340 + for (i = 0; i < num; i++, pentry++) 341 + pr_debug("info[%2d]: controller = %16.16s, pin_name = %16.16s," 342 + " pin = %d\n", i, 343 + pentry->controller_name, 344 + pentry->pin_name, 345 + pentry->pin_no); 346 + return 0; 347 + } 348 + 349 + static int get_gpio_by_name(const char *name) 350 + { 351 + struct sfi_gpio_table_entry *pentry = gpio_table; 352 + int i; 353 + 354 + if (!pentry) 355 + return -1; 356 + for (i = 0; i < gpio_num_entry; i++, pentry++) { 357 + if (!strncmp(name, pentry->pin_name, SFI_NAME_LEN)) 358 + return pentry->pin_no; 359 + } 360 + return -1; 361 + } 362 + 363 + /* 364 + * Here defines the array of devices platform data that IAFW would export 365 + * through SFI "DEVS" table, we use name and type to match the device and 366 + * its platform data. 367 + */ 368 + struct devs_id { 369 + char name[SFI_NAME_LEN + 1]; 370 + u8 type; 371 + u8 delay; 372 + void *(*get_platform_data)(void *info); 373 + }; 374 + 375 + /* the offset for the mapping of global gpio pin to irq */ 376 + #define MRST_IRQ_OFFSET 0x100 377 + 378 + static void __init *pmic_gpio_platform_data(void *info) 379 + { 380 + static struct intel_pmic_gpio_platform_data pmic_gpio_pdata; 381 + int gpio_base = get_gpio_by_name("pmic_gpio_base"); 382 + 383 + if (gpio_base == -1) 384 + gpio_base = 64; 385 + pmic_gpio_pdata.gpio_base = gpio_base; 386 + pmic_gpio_pdata.irq_base = gpio_base + MRST_IRQ_OFFSET; 387 + pmic_gpio_pdata.gpiointr = 0xffffeff8; 388 + 389 + return &pmic_gpio_pdata; 390 + } 391 + 392 + static void __init *max3111_platform_data(void *info) 393 + { 394 + struct spi_board_info *spi_info = info; 395 + int intr = get_gpio_by_name("max3111_int"); 396 + 397 + if (intr == -1) 398 + return NULL; 399 + spi_info->irq = intr + MRST_IRQ_OFFSET; 400 + return NULL; 401 + } 402 + 403 + /* we have multiple max7315 on the board ... */ 404 + #define MAX7315_NUM 2 405 + static void __init *max7315_platform_data(void *info) 406 + { 407 + static struct pca953x_platform_data max7315_pdata[MAX7315_NUM]; 408 + static int nr; 409 + struct pca953x_platform_data *max7315 = &max7315_pdata[nr]; 410 + struct i2c_board_info *i2c_info = info; 411 + int gpio_base, intr; 412 + char base_pin_name[SFI_NAME_LEN + 1]; 413 + char intr_pin_name[SFI_NAME_LEN + 1]; 414 + 415 + if (nr == MAX7315_NUM) { 416 + pr_err("too many max7315s, we only support %d\n", 417 + MAX7315_NUM); 418 + return NULL; 419 + } 420 + /* we have several max7315 on the board, we only need load several 421 + * instances of the same pca953x driver to cover them 422 + */ 423 + strcpy(i2c_info->type, "max7315"); 424 + if (nr++) { 425 + sprintf(base_pin_name, "max7315_%d_base", nr); 426 + sprintf(intr_pin_name, "max7315_%d_int", nr); 427 + } else { 428 + strcpy(base_pin_name, "max7315_base"); 429 + strcpy(intr_pin_name, "max7315_int"); 430 + } 431 + 432 + gpio_base = get_gpio_by_name(base_pin_name); 433 + intr = get_gpio_by_name(intr_pin_name); 434 + 435 + if (gpio_base == -1) 436 + return NULL; 437 + max7315->gpio_base = gpio_base; 438 + if (intr != -1) { 439 + i2c_info->irq = intr + MRST_IRQ_OFFSET; 440 + max7315->irq_base = gpio_base + MRST_IRQ_OFFSET; 441 + } else { 442 + i2c_info->irq = -1; 443 + max7315->irq_base = -1; 444 + } 445 + return max7315; 446 + } 447 + 448 + static void __init *emc1403_platform_data(void *info) 449 + { 450 + static short intr2nd_pdata; 451 + struct i2c_board_info *i2c_info = info; 452 + int intr = get_gpio_by_name("thermal_int"); 453 + int intr2nd = get_gpio_by_name("thermal_alert"); 454 + 455 + if (intr == -1 || intr2nd == -1) 456 + return NULL; 457 + 458 + i2c_info->irq = intr + MRST_IRQ_OFFSET; 459 + intr2nd_pdata = intr2nd + MRST_IRQ_OFFSET; 460 + 461 + return &intr2nd_pdata; 462 + } 463 + 464 + static void __init *lis331dl_platform_data(void *info) 465 + { 466 + static short intr2nd_pdata; 467 + struct i2c_board_info *i2c_info = info; 468 + int intr = get_gpio_by_name("accel_int"); 469 + int intr2nd = get_gpio_by_name("accel_2"); 470 + 471 + if (intr == -1 || intr2nd == -1) 472 + return NULL; 473 + 474 + i2c_info->irq = intr + MRST_IRQ_OFFSET; 475 + intr2nd_pdata = intr2nd + MRST_IRQ_OFFSET; 476 + 477 + return &intr2nd_pdata; 478 + } 479 + 480 + static const struct devs_id __initconst device_ids[] = { 481 + {"pmic_gpio", SFI_DEV_TYPE_SPI, 1, &pmic_gpio_platform_data}, 482 + {"spi_max3111", SFI_DEV_TYPE_SPI, 0, &max3111_platform_data}, 483 + {"i2c_max7315", SFI_DEV_TYPE_I2C, 1, &max7315_platform_data}, 484 + {"i2c_max7315_2", SFI_DEV_TYPE_I2C, 1, &max7315_platform_data}, 485 + {"emc1403", SFI_DEV_TYPE_I2C, 1, &emc1403_platform_data}, 486 + {"i2c_accel", SFI_DEV_TYPE_I2C, 0, &lis331dl_platform_data}, 487 + {}, 488 + }; 489 + 490 + #define MAX_IPCDEVS 24 491 + static struct platform_device *ipc_devs[MAX_IPCDEVS]; 492 + static int ipc_next_dev; 493 + 494 + #define MAX_SCU_SPI 24 495 + static struct spi_board_info *spi_devs[MAX_SCU_SPI]; 496 + static int spi_next_dev; 497 + 498 + #define MAX_SCU_I2C 24 499 + static struct i2c_board_info *i2c_devs[MAX_SCU_I2C]; 500 + static int i2c_bus[MAX_SCU_I2C]; 501 + static int i2c_next_dev; 502 + 503 + static void __init intel_scu_device_register(struct platform_device *pdev) 504 + { 505 + if(ipc_next_dev == MAX_IPCDEVS) 506 + pr_err("too many SCU IPC devices"); 507 + else 508 + ipc_devs[ipc_next_dev++] = pdev; 509 + } 510 + 511 + static void __init intel_scu_spi_device_register(struct spi_board_info *sdev) 512 + { 513 + struct spi_board_info *new_dev; 514 + 515 + if (spi_next_dev == MAX_SCU_SPI) { 516 + pr_err("too many SCU SPI devices"); 517 + return; 518 + } 519 + 520 + new_dev = kzalloc(sizeof(*sdev), GFP_KERNEL); 521 + if (!new_dev) { 522 + pr_err("failed to alloc mem for delayed spi dev %s\n", 523 + sdev->modalias); 524 + return; 525 + } 526 + memcpy(new_dev, sdev, sizeof(*sdev)); 527 + 528 + spi_devs[spi_next_dev++] = new_dev; 529 + } 530 + 531 + static void __init intel_scu_i2c_device_register(int bus, 532 + struct i2c_board_info *idev) 533 + { 534 + struct i2c_board_info *new_dev; 535 + 536 + if (i2c_next_dev == MAX_SCU_I2C) { 537 + pr_err("too many SCU I2C devices"); 538 + return; 539 + } 540 + 541 + new_dev = kzalloc(sizeof(*idev), GFP_KERNEL); 542 + if (!new_dev) { 543 + pr_err("failed to alloc mem for delayed i2c dev %s\n", 544 + idev->type); 545 + return; 546 + } 547 + memcpy(new_dev, idev, sizeof(*idev)); 548 + 549 + i2c_bus[i2c_next_dev] = bus; 550 + i2c_devs[i2c_next_dev++] = new_dev; 551 + } 552 + 553 + /* Called by IPC driver */ 554 + void intel_scu_devices_create(void) 555 + { 556 + int i; 557 + 558 + for (i = 0; i < ipc_next_dev; i++) 559 + platform_device_add(ipc_devs[i]); 560 + 561 + for (i = 0; i < spi_next_dev; i++) 562 + spi_register_board_info(spi_devs[i], 1); 563 + 564 + for (i = 0; i < i2c_next_dev; i++) { 565 + struct i2c_adapter *adapter; 566 + struct i2c_client *client; 567 + 568 + adapter = i2c_get_adapter(i2c_bus[i]); 569 + if (adapter) { 570 + client = i2c_new_device(adapter, i2c_devs[i]); 571 + if (!client) 572 + pr_err("can't create i2c device %s\n", 573 + i2c_devs[i]->type); 574 + } else 575 + i2c_register_board_info(i2c_bus[i], i2c_devs[i], 1); 576 + } 577 + } 578 + EXPORT_SYMBOL_GPL(intel_scu_devices_create); 579 + 580 + /* Called by IPC driver */ 581 + void intel_scu_devices_destroy(void) 582 + { 583 + int i; 584 + 585 + for (i = 0; i < ipc_next_dev; i++) 586 + platform_device_del(ipc_devs[i]); 587 + } 588 + EXPORT_SYMBOL_GPL(intel_scu_devices_destroy); 589 + 590 + static void __init install_irq_resource(struct platform_device *pdev, int irq) 591 + { 592 + /* Single threaded */ 593 + static struct resource __initdata res = { 594 + .name = "IRQ", 595 + .flags = IORESOURCE_IRQ, 596 + }; 597 + res.start = irq; 598 + platform_device_add_resources(pdev, &res, 1); 599 + } 600 + 601 + static void __init sfi_handle_ipc_dev(struct platform_device *pdev) 602 + { 603 + const struct devs_id *dev = device_ids; 604 + void *pdata = NULL; 605 + 606 + while (dev->name[0]) { 607 + if (dev->type == SFI_DEV_TYPE_IPC && 608 + !strncmp(dev->name, pdev->name, SFI_NAME_LEN)) { 609 + pdata = dev->get_platform_data(pdev); 610 + break; 611 + } 612 + dev++; 613 + } 614 + pdev->dev.platform_data = pdata; 615 + intel_scu_device_register(pdev); 616 + } 617 + 618 + static void __init sfi_handle_spi_dev(struct spi_board_info *spi_info) 619 + { 620 + const struct devs_id *dev = device_ids; 621 + void *pdata = NULL; 622 + 623 + while (dev->name[0]) { 624 + if (dev->type == SFI_DEV_TYPE_SPI && 625 + !strncmp(dev->name, spi_info->modalias, SFI_NAME_LEN)) { 626 + pdata = dev->get_platform_data(spi_info); 627 + break; 628 + } 629 + dev++; 630 + } 631 + spi_info->platform_data = pdata; 632 + if (dev->delay) 633 + intel_scu_spi_device_register(spi_info); 634 + else 635 + spi_register_board_info(spi_info, 1); 636 + } 637 + 638 + static void __init sfi_handle_i2c_dev(int bus, struct i2c_board_info *i2c_info) 639 + { 640 + const struct devs_id *dev = device_ids; 641 + void *pdata = NULL; 642 + 643 + while (dev->name[0]) { 644 + if (dev->type == SFI_DEV_TYPE_I2C && 645 + !strncmp(dev->name, i2c_info->type, SFI_NAME_LEN)) { 646 + pdata = dev->get_platform_data(i2c_info); 647 + break; 648 + } 649 + dev++; 650 + } 651 + i2c_info->platform_data = pdata; 652 + 653 + if (dev->delay) 654 + intel_scu_i2c_device_register(bus, i2c_info); 655 + else 656 + i2c_register_board_info(bus, i2c_info, 1); 657 + } 658 + 659 + 660 + static int __init sfi_parse_devs(struct sfi_table_header *table) 661 + { 662 + struct sfi_table_simple *sb; 663 + struct sfi_device_table_entry *pentry; 664 + struct spi_board_info spi_info; 665 + struct i2c_board_info i2c_info; 666 + struct platform_device *pdev; 667 + int num, i, bus; 668 + int ioapic; 669 + struct io_apic_irq_attr irq_attr; 670 + 671 + sb = (struct sfi_table_simple *)table; 672 + num = SFI_GET_NUM_ENTRIES(sb, struct sfi_device_table_entry); 673 + pentry = (struct sfi_device_table_entry *)sb->pentry; 674 + 675 + for (i = 0; i < num; i++, pentry++) { 676 + if (pentry->irq != (u8)0xff) { /* native RTE case */ 677 + /* these SPI2 devices are not exposed to system as PCI 678 + * devices, but they have separate RTE entry in IOAPIC 679 + * so we have to enable them one by one here 680 + */ 681 + ioapic = mp_find_ioapic(pentry->irq); 682 + irq_attr.ioapic = ioapic; 683 + irq_attr.ioapic_pin = pentry->irq; 684 + irq_attr.trigger = 1; 685 + irq_attr.polarity = 1; 686 + io_apic_set_pci_routing(NULL, pentry->irq, &irq_attr); 687 + } 688 + switch (pentry->type) { 689 + case SFI_DEV_TYPE_IPC: 690 + /* ID as IRQ is a hack that will go away */ 691 + pdev = platform_device_alloc(pentry->name, pentry->irq); 692 + if (pdev == NULL) { 693 + pr_err("out of memory for SFI platform device '%s'.\n", 694 + pentry->name); 695 + continue; 696 + } 697 + install_irq_resource(pdev, pentry->irq); 698 + pr_debug("info[%2d]: IPC bus, name = %16.16s, " 699 + "irq = 0x%2x\n", i, pentry->name, pentry->irq); 700 + sfi_handle_ipc_dev(pdev); 701 + break; 702 + case SFI_DEV_TYPE_SPI: 703 + memset(&spi_info, 0, sizeof(spi_info)); 704 + strncpy(spi_info.modalias, pentry->name, SFI_NAME_LEN); 705 + spi_info.irq = pentry->irq; 706 + spi_info.bus_num = pentry->host_num; 707 + spi_info.chip_select = pentry->addr; 708 + spi_info.max_speed_hz = pentry->max_freq; 709 + pr_debug("info[%2d]: SPI bus = %d, name = %16.16s, " 710 + "irq = 0x%2x, max_freq = %d, cs = %d\n", i, 711 + spi_info.bus_num, 712 + spi_info.modalias, 713 + spi_info.irq, 714 + spi_info.max_speed_hz, 715 + spi_info.chip_select); 716 + sfi_handle_spi_dev(&spi_info); 717 + break; 718 + case SFI_DEV_TYPE_I2C: 719 + memset(&i2c_info, 0, sizeof(i2c_info)); 720 + bus = pentry->host_num; 721 + strncpy(i2c_info.type, pentry->name, SFI_NAME_LEN); 722 + i2c_info.irq = pentry->irq; 723 + i2c_info.addr = pentry->addr; 724 + pr_debug("info[%2d]: I2C bus = %d, name = %16.16s, " 725 + "irq = 0x%2x, addr = 0x%x\n", i, bus, 726 + i2c_info.type, 727 + i2c_info.irq, 728 + i2c_info.addr); 729 + sfi_handle_i2c_dev(bus, &i2c_info); 730 + break; 731 + case SFI_DEV_TYPE_UART: 732 + case SFI_DEV_TYPE_HSI: 733 + default: 734 + ; 735 + } 736 + } 737 + return 0; 738 + } 739 + 740 + static int __init mrst_platform_init(void) 741 + { 742 + sfi_table_parse(SFI_SIG_GPIO, NULL, NULL, sfi_parse_gpio); 743 + sfi_table_parse(SFI_SIG_DEVS, NULL, NULL, sfi_parse_devs); 744 + return 0; 745 + } 746 + arch_initcall(mrst_platform_init); 747 + 748 + /* 749 + * we will search these buttons in SFI GPIO table (by name) 750 + * and register them dynamically. Please add all possible 751 + * buttons here, we will shrink them if no GPIO found. 752 + */ 753 + static struct gpio_keys_button gpio_button[] = { 754 + {KEY_POWER, -1, 1, "power_btn", EV_KEY, 0, 3000}, 755 + {KEY_PROG1, -1, 1, "prog_btn1", EV_KEY, 0, 20}, 756 + {KEY_PROG2, -1, 1, "prog_btn2", EV_KEY, 0, 20}, 757 + {SW_LID, -1, 1, "lid_switch", EV_SW, 0, 20}, 758 + {KEY_VOLUMEUP, -1, 1, "vol_up", EV_KEY, 0, 20}, 759 + {KEY_VOLUMEDOWN, -1, 1, "vol_down", EV_KEY, 0, 20}, 760 + {KEY_CAMERA, -1, 1, "camera_full", EV_KEY, 0, 20}, 761 + {KEY_CAMERA_FOCUS, -1, 1, "camera_half", EV_KEY, 0, 20}, 762 + {SW_KEYPAD_SLIDE, -1, 1, "MagSw1", EV_SW, 0, 20}, 763 + {SW_KEYPAD_SLIDE, -1, 1, "MagSw2", EV_SW, 0, 20}, 764 + }; 765 + 766 + static struct gpio_keys_platform_data mrst_gpio_keys = { 767 + .buttons = gpio_button, 768 + .rep = 1, 769 + .nbuttons = -1, /* will fill it after search */ 770 + }; 771 + 772 + static struct platform_device pb_device = { 773 + .name = "gpio-keys", 774 + .id = -1, 775 + .dev = { 776 + .platform_data = &mrst_gpio_keys, 777 + }, 778 + }; 779 + 780 + /* 781 + * Shrink the non-existent buttons, register the gpio button 782 + * device if there is some 783 + */ 784 + static int __init pb_keys_init(void) 785 + { 786 + struct gpio_keys_button *gb = gpio_button; 787 + int i, num, good = 0; 788 + 789 + num = sizeof(gpio_button) / sizeof(struct gpio_keys_button); 790 + for (i = 0; i < num; i++) { 791 + gb[i].gpio = get_gpio_by_name(gb[i].desc); 792 + if (gb[i].gpio == -1) 793 + continue; 794 + 795 + if (i != good) 796 + gb[good] = gb[i]; 797 + good++; 798 + } 799 + 800 + if (good) { 801 + mrst_gpio_keys.nbuttons = good; 802 + return platform_device_register(&pb_device); 803 + } 804 + return 0; 805 + } 806 + late_initcall(pb_keys_init);
+5
drivers/platform/x86/intel_scu_ipc.c
··· 26 26 #include <linux/sfi.h> 27 27 #include <asm/mrst.h> 28 28 #include <asm/intel_scu_ipc.h> 29 + #include <asm/mrst.h> 29 30 30 31 /* IPC defines the following message types */ 31 32 #define IPCMSG_WATCHDOG_TIMER 0xF8 /* Set Kernel Watchdog Threshold */ ··· 700 699 iounmap(ipcdev.ipc_base); 701 700 return -ENOMEM; 702 701 } 702 + 703 + intel_scu_devices_create(); 704 + 703 705 return 0; 704 706 } 705 707 ··· 724 720 iounmap(ipcdev.ipc_base); 725 721 iounmap(ipcdev.i2c_base); 726 722 ipcdev.pdev = NULL; 723 + intel_scu_devices_destroy(); 727 724 } 728 725 729 726 static const struct pci_device_id pci_ids[] = {
+5 -3
include/linux/sfi.h
··· 77 77 #define SFI_OEM_ID_SIZE 6 78 78 #define SFI_OEM_TABLE_ID_SIZE 8 79 79 80 + #define SFI_NAME_LEN 16 81 + 80 82 #define SFI_SYST_SEARCH_BEGIN 0x000E0000 81 83 #define SFI_SYST_SEARCH_END 0x000FFFFF 82 84 ··· 158 156 u16 addr; 159 157 u8 irq; 160 158 u32 max_freq; 161 - char name[16]; 159 + char name[SFI_NAME_LEN]; 162 160 } __packed; 163 161 164 162 struct sfi_gpio_table_entry { 165 - char controller_name[16]; 163 + char controller_name[SFI_NAME_LEN]; 166 164 u16 pin_no; 167 - char pin_name[16]; 165 + char pin_name[SFI_NAME_LEN]; 168 166 } __packed; 169 167 170 168 typedef int (*sfi_table_handler) (struct sfi_table_header *table);