diff options
author | Dmitry Torokhov <dmitry.torokhov@gmail.com> | 2018-03-20 18:31:33 -0400 |
---|---|---|
committer | Benson Leung <bleung@chromium.org> | 2018-04-10 01:44:53 -0400 |
commit | 65582920d72d2562e44c07aa530586a3583477b9 (patch) | |
tree | c2d058102560cbebfd2eb8610789bc028f4776c7 | |
parent | 28cd38f105fc30ccda7a15170cbaa977d2601272 (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.c | 120 |
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 | ||
69 | static struct chromeos_laptop *cros_laptop; | 69 | static struct chromeos_laptop *cros_laptop; |
70 | 70 | ||
71 | static 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 | |||
91 | static struct i2c_client * | 71 | static struct i2c_client * |
92 | chromes_laptop_instantiate_i2c_device(int bus, | 72 | chromes_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 | ||
233 | static 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 | |||
242 | static int chromeos_laptop_probe(struct platform_device *pdev) | 202 | static 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 | |||
506 | static const struct dmi_system_id chromeos_laptop_dmi_table[] __initconst = { | 462 | static 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 | ||
558 | static 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 | |||
578 | static struct chromeos_laptop * __init | ||
579 | chromeos_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 | |||
602 | static int __init chromeos_laptop_init(void) | 602 | static 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; |