aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDmitry Torokhov <dmitry.torokhov@gmail.com>2018-03-20 18:31:33 -0400
committerBenson Leung <bleung@chromium.org>2018-04-10 01:44:53 -0400
commit65582920d72d2562e44c07aa530586a3583477b9 (patch)
treec2d058102560cbebfd2eb8610789bc028f4776c7
parent28cd38f105fc30ccda7a15170cbaa977d2601272 (diff)
platform/chrome: chromeos_laptop - parse DMI IRQ data once
Instead of trying to parse DMI IRQ data every time we try to instantiate a device, let's do it once, when we identify the device we are working with. This allows us to mark chromeos_laptop_get_irq_from_dmi() as __init and discard it once module is initialized. Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com> Signed-off-by: Benson Leung <bleung@chromium.org>
-rw-r--r--drivers/platform/chrome/chromeos_laptop.c120
1 files changed, 64 insertions, 56 deletions
diff --git a/drivers/platform/chrome/chromeos_laptop.c b/drivers/platform/chrome/chromeos_laptop.c
index 2a81ae4c15c9..d6d2bc6f3aaf 100644
--- a/drivers/platform/chrome/chromeos_laptop.c
+++ b/drivers/platform/chrome/chromeos_laptop.c
@@ -68,26 +68,6 @@ struct chromeos_laptop {
68 68
69static struct chromeos_laptop *cros_laptop; 69static struct chromeos_laptop *cros_laptop;
70 70
71static int chromeos_laptop_get_irq_from_dmi(const char *dmi_name)
72{
73 const struct dmi_device *dmi_dev;
74 const struct dmi_dev_onboard *dev_data;
75
76 dmi_dev = dmi_find_device(DMI_DEV_TYPE_DEV_ONBOARD, dmi_name, NULL);
77 if (!dmi_dev) {
78 pr_err("failed to find DMI device '%s'\n", dmi_name);
79 return -ENOENT;
80 }
81
82 dev_data = dmi_dev->device_data;
83 if (!dev_data) {
84 pr_err("failed to get data from DMI for '%s'\n", dmi_name);
85 return -EINVAL;
86 }
87
88 return dev_data->instance;
89}
90
91static struct i2c_client * 71static struct i2c_client *
92chromes_laptop_instantiate_i2c_device(int bus, 72chromes_laptop_instantiate_i2c_device(int bus,
93 struct i2c_board_info *info, 73 struct i2c_board_info *info,
@@ -185,7 +165,6 @@ static int chromeos_laptop_add_peripheral(struct i2c_peripheral *i2c_dev)
185{ 165{
186 struct i2c_client *client; 166 struct i2c_client *client;
187 int bus; 167 int bus;
188 int irq;
189 168
190 /* 169 /*
191 * Check that the i2c adapter is present. 170 * Check that the i2c adapter is present.
@@ -196,16 +175,6 @@ static int chromeos_laptop_add_peripheral(struct i2c_peripheral *i2c_dev)
196 if (bus < 0) 175 if (bus < 0)
197 return bus == -ENODEV ? -EPROBE_DEFER : bus; 176 return bus == -ENODEV ? -EPROBE_DEFER : bus;
198 177
199 if (i2c_dev->dmi_name) {
200 irq = chromeos_laptop_get_irq_from_dmi(i2c_dev->dmi_name);
201 if (irq < 0) {
202 i2c_dev->state = FAILED;
203 return irq;
204 }
205
206 i2c_dev->board_info.irq = irq;
207 }
208
209 client = chromes_laptop_instantiate_i2c_device(bus, 178 client = chromes_laptop_instantiate_i2c_device(bus,
210 &i2c_dev->board_info, 179 &i2c_dev->board_info,
211 i2c_dev->alt_addr); 180 i2c_dev->alt_addr);
@@ -230,15 +199,6 @@ static int chromeos_laptop_add_peripheral(struct i2c_peripheral *i2c_dev)
230 return 0; 199 return 0;
231} 200}
232 201
233static int __init chromeos_laptop_dmi_matched(const struct dmi_system_id *id)
234{
235 cros_laptop = (void *)id->driver_data;
236 pr_debug("DMI Matched %s\n", id->ident);
237
238 /* Indicate to dmi_scan that processing is done. */
239 return 1;
240}
241
242static int chromeos_laptop_probe(struct platform_device *pdev) 202static int chromeos_laptop_probe(struct platform_device *pdev)
243{ 203{
244 struct i2c_peripheral *i2c_dev; 204 struct i2c_peripheral *i2c_dev;
@@ -499,10 +459,6 @@ static struct chromeos_laptop cr48 = {
499 }, 459 },
500}; 460};
501 461
502#define _CBDD(board_) \
503 .callback = chromeos_laptop_dmi_matched, \
504 .driver_data = (void *)&board_
505
506static const struct dmi_system_id chromeos_laptop_dmi_table[] __initconst = { 462static const struct dmi_system_id chromeos_laptop_dmi_table[] __initconst = {
507 { 463 {
508 .ident = "Samsung Series 5 550", 464 .ident = "Samsung Series 5 550",
@@ -510,14 +466,14 @@ static const struct dmi_system_id chromeos_laptop_dmi_table[] __initconst = {
510 DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG"), 466 DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG"),
511 DMI_MATCH(DMI_PRODUCT_NAME, "Lumpy"), 467 DMI_MATCH(DMI_PRODUCT_NAME, "Lumpy"),
512 }, 468 },
513 _CBDD(samsung_series_5_550), 469 .driver_data = (void *)&samsung_series_5_550,
514 }, 470 },
515 { 471 {
516 .ident = "Samsung Series 5", 472 .ident = "Samsung Series 5",
517 .matches = { 473 .matches = {
518 DMI_MATCH(DMI_PRODUCT_NAME, "Alex"), 474 DMI_MATCH(DMI_PRODUCT_NAME, "Alex"),
519 }, 475 },
520 _CBDD(samsung_series_5), 476 .driver_data = (void *)&samsung_series_5,
521 }, 477 },
522 { 478 {
523 .ident = "Chromebook Pixel", 479 .ident = "Chromebook Pixel",
@@ -525,7 +481,7 @@ static const struct dmi_system_id chromeos_laptop_dmi_table[] __initconst = {
525 DMI_MATCH(DMI_SYS_VENDOR, "GOOGLE"), 481 DMI_MATCH(DMI_SYS_VENDOR, "GOOGLE"),
526 DMI_MATCH(DMI_PRODUCT_NAME, "Link"), 482 DMI_MATCH(DMI_PRODUCT_NAME, "Link"),
527 }, 483 },
528 _CBDD(chromebook_pixel), 484 .driver_data = (void *)&chromebook_pixel,
529 }, 485 },
530 { 486 {
531 .ident = "Wolf", 487 .ident = "Wolf",
@@ -533,7 +489,7 @@ static const struct dmi_system_id chromeos_laptop_dmi_table[] __initconst = {
533 DMI_MATCH(DMI_BIOS_VENDOR, "coreboot"), 489 DMI_MATCH(DMI_BIOS_VENDOR, "coreboot"),
534 DMI_MATCH(DMI_PRODUCT_NAME, "Wolf"), 490 DMI_MATCH(DMI_PRODUCT_NAME, "Wolf"),
535 }, 491 },
536 _CBDD(dell_chromebook_11), 492 .driver_data = (void *)&dell_chromebook_11,
537 }, 493 },
538 { 494 {
539 .ident = "HP Chromebook 14", 495 .ident = "HP Chromebook 14",
@@ -541,7 +497,7 @@ static const struct dmi_system_id chromeos_laptop_dmi_table[] __initconst = {
541 DMI_MATCH(DMI_BIOS_VENDOR, "coreboot"), 497 DMI_MATCH(DMI_BIOS_VENDOR, "coreboot"),
542 DMI_MATCH(DMI_PRODUCT_NAME, "Falco"), 498 DMI_MATCH(DMI_PRODUCT_NAME, "Falco"),
543 }, 499 },
544 _CBDD(hp_chromebook_14), 500 .driver_data = (void *)&hp_chromebook_14,
545 }, 501 },
546 { 502 {
547 .ident = "Toshiba CB35", 503 .ident = "Toshiba CB35",
@@ -549,42 +505,42 @@ static const struct dmi_system_id chromeos_laptop_dmi_table[] __initconst = {
549 DMI_MATCH(DMI_BIOS_VENDOR, "coreboot"), 505 DMI_MATCH(DMI_BIOS_VENDOR, "coreboot"),
550 DMI_MATCH(DMI_PRODUCT_NAME, "Leon"), 506 DMI_MATCH(DMI_PRODUCT_NAME, "Leon"),
551 }, 507 },
552 _CBDD(toshiba_cb35), 508 .driver_data = (void *)&toshiba_cb35,
553 }, 509 },
554 { 510 {
555 .ident = "Acer C7 Chromebook", 511 .ident = "Acer C7 Chromebook",
556 .matches = { 512 .matches = {
557 DMI_MATCH(DMI_PRODUCT_NAME, "Parrot"), 513 DMI_MATCH(DMI_PRODUCT_NAME, "Parrot"),
558 }, 514 },
559 _CBDD(acer_c7_chromebook), 515 .driver_data = (void *)&acer_c7_chromebook,
560 }, 516 },
561 { 517 {
562 .ident = "Acer AC700", 518 .ident = "Acer AC700",
563 .matches = { 519 .matches = {
564 DMI_MATCH(DMI_PRODUCT_NAME, "ZGB"), 520 DMI_MATCH(DMI_PRODUCT_NAME, "ZGB"),
565 }, 521 },
566 _CBDD(acer_ac700), 522 .driver_data = (void *)&acer_ac700,
567 }, 523 },
568 { 524 {
569 .ident = "Acer C720", 525 .ident = "Acer C720",
570 .matches = { 526 .matches = {
571 DMI_MATCH(DMI_PRODUCT_NAME, "Peppy"), 527 DMI_MATCH(DMI_PRODUCT_NAME, "Peppy"),
572 }, 528 },
573 _CBDD(acer_c720), 529 .driver_data = (void *)&acer_c720,
574 }, 530 },
575 { 531 {
576 .ident = "HP Pavilion 14 Chromebook", 532 .ident = "HP Pavilion 14 Chromebook",
577 .matches = { 533 .matches = {
578 DMI_MATCH(DMI_PRODUCT_NAME, "Butterfly"), 534 DMI_MATCH(DMI_PRODUCT_NAME, "Butterfly"),
579 }, 535 },
580 _CBDD(hp_pavilion_14_chromebook), 536 .driver_data = (void *)&hp_pavilion_14_chromebook,
581 }, 537 },
582 { 538 {
583 .ident = "Cr-48", 539 .ident = "Cr-48",
584 .matches = { 540 .matches = {
585 DMI_MATCH(DMI_PRODUCT_NAME, "Mario"), 541 DMI_MATCH(DMI_PRODUCT_NAME, "Mario"),
586 }, 542 },
587 _CBDD(cr48), 543 .driver_data = (void *)&cr48,
588 }, 544 },
589 { } 545 { }
590}; 546};
@@ -599,15 +555,67 @@ static struct platform_driver cros_platform_driver = {
599 .probe = chromeos_laptop_probe, 555 .probe = chromeos_laptop_probe,
600}; 556};
601 557
558static int __init chromeos_laptop_get_irq_from_dmi(const char *dmi_name)
559{
560 const struct dmi_device *dmi_dev;
561 const struct dmi_dev_onboard *dev_data;
562
563 dmi_dev = dmi_find_device(DMI_DEV_TYPE_DEV_ONBOARD, dmi_name, NULL);
564 if (!dmi_dev) {
565 pr_err("failed to find DMI device '%s'\n", dmi_name);
566 return -ENOENT;
567 }
568
569 dev_data = dmi_dev->device_data;
570 if (!dev_data) {
571 pr_err("failed to get data from DMI for '%s'\n", dmi_name);
572 return -EINVAL;
573 }
574
575 return dev_data->instance;
576}
577
578static struct chromeos_laptop * __init
579chromeos_laptop_prepare(const struct dmi_system_id *id)
580{
581 struct i2c_peripheral *i2c_dev;
582 int irq;
583 int i;
584
585 cros_laptop = (void *)id->driver_data;
586
587 for (i = 0; i < MAX_I2C_PERIPHERALS; i++) {
588 i2c_dev = &cros_laptop->i2c_peripherals[i];
589
590 if (!i2c_dev->dmi_name)
591 continue;
592
593 irq = chromeos_laptop_get_irq_from_dmi(i2c_dev->dmi_name);
594 if (irq < 0)
595 return ERR_PTR(irq);
596 }
597
598 return cros_laptop;
599}
600
601
602static int __init chromeos_laptop_init(void) 602static int __init chromeos_laptop_init(void)
603{ 603{
604 const struct dmi_system_id *dmi_id;
604 int ret; 605 int ret;
605 606
606 if (!dmi_check_system(chromeos_laptop_dmi_table)) { 607 dmi_id = dmi_first_match(chromeos_laptop_dmi_table);
608 if (!dmi_id) {
607 pr_debug("unsupported system\n"); 609 pr_debug("unsupported system\n");
608 return -ENODEV; 610 return -ENODEV;
609 } 611 }
610 612
613 pr_debug("DMI Matched %s\n", dmi_id->ident);
614
615 cros_laptop = chromeos_laptop_prepare(dmi_id->driver_data);
616 if (IS_ERR(cros_laptop))
617 return PTR_ERR(cros_laptop);
618
611 ret = platform_driver_register(&cros_platform_driver); 619 ret = platform_driver_register(&cros_platform_driver);
612 if (ret) 620 if (ret)
613 return ret; 621 return ret;