diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2015-07-16 23:57:25 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2015-07-16 23:57:25 -0400 |
commit | 3e87ee06d0d6b759471a487ceb8a48ecc5dee1f8 (patch) | |
tree | 56e2bc4c8a645e4761852b31618d9f55b65e13b2 | |
parent | f85c712429ca43ca21daa35f8a47bcaffdb3d5a1 (diff) | |
parent | 8642d7f8364d9fa84a83629129e78402c169c54a (diff) |
Merge tag 'platform-drivers-x86-v4.2-3' of git://git.infradead.org/users/dvhart/linux-platform-drivers-x86
Pull x86 platform driver fixes from Darren Hart:
"Fix SMBIOS call handling and hwswitch state coherency in the
dell-laptop driver. Cleanups for intel_*_ipc drivers. Details:
dell-laptop:
- Do not cache hwswitch state
- Check return value of each SMBIOS call
- Clear buffer before each SMBIOS call
intel_scu_ipc:
- Move local memory initialization out of a mutex
intel_pmc_ipc:
- Update kerneldoc formatting
- Fix compiler casting warnings"
* tag 'platform-drivers-x86-v4.2-3' of git://git.infradead.org/users/dvhart/linux-platform-drivers-x86:
intel_scu_ipc: move local memory initialization out of a mutex
intel_pmc_ipc: Update kerneldoc formatting
dell-laptop: Do not cache hwswitch state
dell-laptop: Check return value of each SMBIOS call
dell-laptop: Clear buffer before each SMBIOS call
intel_pmc_ipc: Fix compiler casting warnings
-rw-r--r-- | arch/x86/include/asm/intel_pmc_ipc.h | 27 | ||||
-rw-r--r-- | drivers/platform/x86/dell-laptop.c | 171 | ||||
-rw-r--r-- | drivers/platform/x86/intel_pmc_ipc.c | 83 | ||||
-rw-r--r-- | drivers/platform/x86/intel_scu_ipc.c | 6 |
4 files changed, 176 insertions, 111 deletions
diff --git a/arch/x86/include/asm/intel_pmc_ipc.h b/arch/x86/include/asm/intel_pmc_ipc.h index 200ec2e7821d..cd0310e186f4 100644 --- a/arch/x86/include/asm/intel_pmc_ipc.h +++ b/arch/x86/include/asm/intel_pmc_ipc.h | |||
@@ -25,36 +25,9 @@ | |||
25 | 25 | ||
26 | #if IS_ENABLED(CONFIG_INTEL_PMC_IPC) | 26 | #if IS_ENABLED(CONFIG_INTEL_PMC_IPC) |
27 | 27 | ||
28 | /* | ||
29 | * intel_pmc_ipc_simple_command | ||
30 | * @cmd: command | ||
31 | * @sub: sub type | ||
32 | */ | ||
33 | int intel_pmc_ipc_simple_command(int cmd, int sub); | 28 | int intel_pmc_ipc_simple_command(int cmd, int sub); |
34 | |||
35 | /* | ||
36 | * intel_pmc_ipc_raw_cmd | ||
37 | * @cmd: command | ||
38 | * @sub: sub type | ||
39 | * @in: input data | ||
40 | * @inlen: input length in bytes | ||
41 | * @out: output data | ||
42 | * @outlen: output length in dwords | ||
43 | * @sptr: data writing to SPTR register | ||
44 | * @dptr: data writing to DPTR register | ||
45 | */ | ||
46 | int intel_pmc_ipc_raw_cmd(u32 cmd, u32 sub, u8 *in, u32 inlen, | 29 | int intel_pmc_ipc_raw_cmd(u32 cmd, u32 sub, u8 *in, u32 inlen, |
47 | u32 *out, u32 outlen, u32 dptr, u32 sptr); | 30 | u32 *out, u32 outlen, u32 dptr, u32 sptr); |
48 | |||
49 | /* | ||
50 | * intel_pmc_ipc_command | ||
51 | * @cmd: command | ||
52 | * @sub: sub type | ||
53 | * @in: input data | ||
54 | * @inlen: input length in bytes | ||
55 | * @out: output data | ||
56 | * @outlen: output length in dwords | ||
57 | */ | ||
58 | int intel_pmc_ipc_command(u32 cmd, u32 sub, u8 *in, u32 inlen, | 31 | int intel_pmc_ipc_command(u32 cmd, u32 sub, u8 *in, u32 inlen, |
59 | u32 *out, u32 outlen); | 32 | u32 *out, u32 outlen); |
60 | 33 | ||
diff --git a/drivers/platform/x86/dell-laptop.c b/drivers/platform/x86/dell-laptop.c index ed317ccac4a2..aaeeae81e3a9 100644 --- a/drivers/platform/x86/dell-laptop.c +++ b/drivers/platform/x86/dell-laptop.c | |||
@@ -309,12 +309,15 @@ static const struct dmi_system_id dell_quirks[] __initconst = { | |||
309 | static struct calling_interface_buffer *buffer; | 309 | static struct calling_interface_buffer *buffer; |
310 | static DEFINE_MUTEX(buffer_mutex); | 310 | static DEFINE_MUTEX(buffer_mutex); |
311 | 311 | ||
312 | static int hwswitch_state; | 312 | static void clear_buffer(void) |
313 | { | ||
314 | memset(buffer, 0, sizeof(struct calling_interface_buffer)); | ||
315 | } | ||
313 | 316 | ||
314 | static void get_buffer(void) | 317 | static void get_buffer(void) |
315 | { | 318 | { |
316 | mutex_lock(&buffer_mutex); | 319 | mutex_lock(&buffer_mutex); |
317 | memset(buffer, 0, sizeof(struct calling_interface_buffer)); | 320 | clear_buffer(); |
318 | } | 321 | } |
319 | 322 | ||
320 | static void release_buffer(void) | 323 | static void release_buffer(void) |
@@ -548,21 +551,41 @@ static int dell_rfkill_set(void *data, bool blocked) | |||
548 | int disable = blocked ? 1 : 0; | 551 | int disable = blocked ? 1 : 0; |
549 | unsigned long radio = (unsigned long)data; | 552 | unsigned long radio = (unsigned long)data; |
550 | int hwswitch_bit = (unsigned long)data - 1; | 553 | int hwswitch_bit = (unsigned long)data - 1; |
554 | int hwswitch; | ||
555 | int status; | ||
556 | int ret; | ||
551 | 557 | ||
552 | get_buffer(); | 558 | get_buffer(); |
559 | |||
560 | dell_send_request(buffer, 17, 11); | ||
561 | ret = buffer->output[0]; | ||
562 | status = buffer->output[1]; | ||
563 | |||
564 | if (ret != 0) | ||
565 | goto out; | ||
566 | |||
567 | clear_buffer(); | ||
568 | |||
569 | buffer->input[0] = 0x2; | ||
553 | dell_send_request(buffer, 17, 11); | 570 | dell_send_request(buffer, 17, 11); |
571 | ret = buffer->output[0]; | ||
572 | hwswitch = buffer->output[1]; | ||
554 | 573 | ||
555 | /* If the hardware switch controls this radio, and the hardware | 574 | /* If the hardware switch controls this radio, and the hardware |
556 | switch is disabled, always disable the radio */ | 575 | switch is disabled, always disable the radio */ |
557 | if ((hwswitch_state & BIT(hwswitch_bit)) && | 576 | if (ret == 0 && (hwswitch & BIT(hwswitch_bit)) && |
558 | !(buffer->output[1] & BIT(16))) | 577 | (status & BIT(0)) && !(status & BIT(16))) |
559 | disable = 1; | 578 | disable = 1; |
560 | 579 | ||
580 | clear_buffer(); | ||
581 | |||
561 | buffer->input[0] = (1 | (radio<<8) | (disable << 16)); | 582 | buffer->input[0] = (1 | (radio<<8) | (disable << 16)); |
562 | dell_send_request(buffer, 17, 11); | 583 | dell_send_request(buffer, 17, 11); |
584 | ret = buffer->output[0]; | ||
563 | 585 | ||
586 | out: | ||
564 | release_buffer(); | 587 | release_buffer(); |
565 | return 0; | 588 | return dell_smi_error(ret); |
566 | } | 589 | } |
567 | 590 | ||
568 | /* Must be called with the buffer held */ | 591 | /* Must be called with the buffer held */ |
@@ -572,6 +595,7 @@ static void dell_rfkill_update_sw_state(struct rfkill *rfkill, int radio, | |||
572 | if (status & BIT(0)) { | 595 | if (status & BIT(0)) { |
573 | /* Has hw-switch, sync sw_state to BIOS */ | 596 | /* Has hw-switch, sync sw_state to BIOS */ |
574 | int block = rfkill_blocked(rfkill); | 597 | int block = rfkill_blocked(rfkill); |
598 | clear_buffer(); | ||
575 | buffer->input[0] = (1 | (radio << 8) | (block << 16)); | 599 | buffer->input[0] = (1 | (radio << 8) | (block << 16)); |
576 | dell_send_request(buffer, 17, 11); | 600 | dell_send_request(buffer, 17, 11); |
577 | } else { | 601 | } else { |
@@ -581,23 +605,43 @@ static void dell_rfkill_update_sw_state(struct rfkill *rfkill, int radio, | |||
581 | } | 605 | } |
582 | 606 | ||
583 | static void dell_rfkill_update_hw_state(struct rfkill *rfkill, int radio, | 607 | static void dell_rfkill_update_hw_state(struct rfkill *rfkill, int radio, |
584 | int status) | 608 | int status, int hwswitch) |
585 | { | 609 | { |
586 | if (hwswitch_state & (BIT(radio - 1))) | 610 | if (hwswitch & (BIT(radio - 1))) |
587 | rfkill_set_hw_state(rfkill, !(status & BIT(16))); | 611 | rfkill_set_hw_state(rfkill, !(status & BIT(16))); |
588 | } | 612 | } |
589 | 613 | ||
590 | static void dell_rfkill_query(struct rfkill *rfkill, void *data) | 614 | static void dell_rfkill_query(struct rfkill *rfkill, void *data) |
591 | { | 615 | { |
616 | int radio = ((unsigned long)data & 0xF); | ||
617 | int hwswitch; | ||
592 | int status; | 618 | int status; |
619 | int ret; | ||
593 | 620 | ||
594 | get_buffer(); | 621 | get_buffer(); |
622 | |||
595 | dell_send_request(buffer, 17, 11); | 623 | dell_send_request(buffer, 17, 11); |
624 | ret = buffer->output[0]; | ||
596 | status = buffer->output[1]; | 625 | status = buffer->output[1]; |
597 | 626 | ||
598 | dell_rfkill_update_hw_state(rfkill, (unsigned long)data, status); | 627 | if (ret != 0 || !(status & BIT(0))) { |
628 | release_buffer(); | ||
629 | return; | ||
630 | } | ||
631 | |||
632 | clear_buffer(); | ||
633 | |||
634 | buffer->input[0] = 0x2; | ||
635 | dell_send_request(buffer, 17, 11); | ||
636 | ret = buffer->output[0]; | ||
637 | hwswitch = buffer->output[1]; | ||
599 | 638 | ||
600 | release_buffer(); | 639 | release_buffer(); |
640 | |||
641 | if (ret != 0) | ||
642 | return; | ||
643 | |||
644 | dell_rfkill_update_hw_state(rfkill, radio, status, hwswitch); | ||
601 | } | 645 | } |
602 | 646 | ||
603 | static const struct rfkill_ops dell_rfkill_ops = { | 647 | static const struct rfkill_ops dell_rfkill_ops = { |
@@ -609,13 +653,27 @@ static struct dentry *dell_laptop_dir; | |||
609 | 653 | ||
610 | static int dell_debugfs_show(struct seq_file *s, void *data) | 654 | static int dell_debugfs_show(struct seq_file *s, void *data) |
611 | { | 655 | { |
656 | int hwswitch_state; | ||
657 | int hwswitch_ret; | ||
612 | int status; | 658 | int status; |
659 | int ret; | ||
613 | 660 | ||
614 | get_buffer(); | 661 | get_buffer(); |
662 | |||
615 | dell_send_request(buffer, 17, 11); | 663 | dell_send_request(buffer, 17, 11); |
664 | ret = buffer->output[0]; | ||
616 | status = buffer->output[1]; | 665 | status = buffer->output[1]; |
666 | |||
667 | clear_buffer(); | ||
668 | |||
669 | buffer->input[0] = 0x2; | ||
670 | dell_send_request(buffer, 17, 11); | ||
671 | hwswitch_ret = buffer->output[0]; | ||
672 | hwswitch_state = buffer->output[1]; | ||
673 | |||
617 | release_buffer(); | 674 | release_buffer(); |
618 | 675 | ||
676 | seq_printf(s, "return:\t%d\n", ret); | ||
619 | seq_printf(s, "status:\t0x%X\n", status); | 677 | seq_printf(s, "status:\t0x%X\n", status); |
620 | seq_printf(s, "Bit 0 : Hardware switch supported: %lu\n", | 678 | seq_printf(s, "Bit 0 : Hardware switch supported: %lu\n", |
621 | status & BIT(0)); | 679 | status & BIT(0)); |
@@ -657,7 +715,8 @@ static int dell_debugfs_show(struct seq_file *s, void *data) | |||
657 | seq_printf(s, "Bit 21: WiGig is blocked: %lu\n", | 715 | seq_printf(s, "Bit 21: WiGig is blocked: %lu\n", |
658 | (status & BIT(21)) >> 21); | 716 | (status & BIT(21)) >> 21); |
659 | 717 | ||
660 | seq_printf(s, "\nhwswitch_state:\t0x%X\n", hwswitch_state); | 718 | seq_printf(s, "\nhwswitch_return:\t%d\n", hwswitch_ret); |
719 | seq_printf(s, "hwswitch_state:\t0x%X\n", hwswitch_state); | ||
661 | seq_printf(s, "Bit 0 : Wifi controlled by switch: %lu\n", | 720 | seq_printf(s, "Bit 0 : Wifi controlled by switch: %lu\n", |
662 | hwswitch_state & BIT(0)); | 721 | hwswitch_state & BIT(0)); |
663 | seq_printf(s, "Bit 1 : Bluetooth controlled by switch: %lu\n", | 722 | seq_printf(s, "Bit 1 : Bluetooth controlled by switch: %lu\n", |
@@ -693,25 +752,43 @@ static const struct file_operations dell_debugfs_fops = { | |||
693 | 752 | ||
694 | static void dell_update_rfkill(struct work_struct *ignored) | 753 | static void dell_update_rfkill(struct work_struct *ignored) |
695 | { | 754 | { |
755 | int hwswitch = 0; | ||
696 | int status; | 756 | int status; |
757 | int ret; | ||
697 | 758 | ||
698 | get_buffer(); | 759 | get_buffer(); |
760 | |||
699 | dell_send_request(buffer, 17, 11); | 761 | dell_send_request(buffer, 17, 11); |
762 | ret = buffer->output[0]; | ||
700 | status = buffer->output[1]; | 763 | status = buffer->output[1]; |
701 | 764 | ||
765 | if (ret != 0) | ||
766 | goto out; | ||
767 | |||
768 | clear_buffer(); | ||
769 | |||
770 | buffer->input[0] = 0x2; | ||
771 | dell_send_request(buffer, 17, 11); | ||
772 | ret = buffer->output[0]; | ||
773 | |||
774 | if (ret == 0 && (status & BIT(0))) | ||
775 | hwswitch = buffer->output[1]; | ||
776 | |||
702 | if (wifi_rfkill) { | 777 | if (wifi_rfkill) { |
703 | dell_rfkill_update_hw_state(wifi_rfkill, 1, status); | 778 | dell_rfkill_update_hw_state(wifi_rfkill, 1, status, hwswitch); |
704 | dell_rfkill_update_sw_state(wifi_rfkill, 1, status); | 779 | dell_rfkill_update_sw_state(wifi_rfkill, 1, status); |
705 | } | 780 | } |
706 | if (bluetooth_rfkill) { | 781 | if (bluetooth_rfkill) { |
707 | dell_rfkill_update_hw_state(bluetooth_rfkill, 2, status); | 782 | dell_rfkill_update_hw_state(bluetooth_rfkill, 2, status, |
783 | hwswitch); | ||
708 | dell_rfkill_update_sw_state(bluetooth_rfkill, 2, status); | 784 | dell_rfkill_update_sw_state(bluetooth_rfkill, 2, status); |
709 | } | 785 | } |
710 | if (wwan_rfkill) { | 786 | if (wwan_rfkill) { |
711 | dell_rfkill_update_hw_state(wwan_rfkill, 3, status); | 787 | dell_rfkill_update_hw_state(wwan_rfkill, 3, status, hwswitch); |
712 | dell_rfkill_update_sw_state(wwan_rfkill, 3, status); | 788 | dell_rfkill_update_sw_state(wwan_rfkill, 3, status); |
713 | } | 789 | } |
714 | 790 | ||
791 | out: | ||
715 | release_buffer(); | 792 | release_buffer(); |
716 | } | 793 | } |
717 | static DECLARE_DELAYED_WORK(dell_rfkill_work, dell_update_rfkill); | 794 | static DECLARE_DELAYED_WORK(dell_rfkill_work, dell_update_rfkill); |
@@ -773,21 +850,17 @@ static int __init dell_setup_rfkill(void) | |||
773 | 850 | ||
774 | get_buffer(); | 851 | get_buffer(); |
775 | dell_send_request(buffer, 17, 11); | 852 | dell_send_request(buffer, 17, 11); |
853 | ret = buffer->output[0]; | ||
776 | status = buffer->output[1]; | 854 | status = buffer->output[1]; |
777 | buffer->input[0] = 0x2; | ||
778 | dell_send_request(buffer, 17, 11); | ||
779 | hwswitch_state = buffer->output[1]; | ||
780 | release_buffer(); | 855 | release_buffer(); |
781 | 856 | ||
782 | if (!(status & BIT(0))) { | 857 | /* dell wireless info smbios call is not supported */ |
783 | if (force_rfkill) { | 858 | if (ret != 0) |
784 | /* No hwsitch, clear all hw-controlled bits */ | 859 | return 0; |
785 | hwswitch_state &= ~7; | 860 | |
786 | } else { | 861 | /* rfkill is only tested on laptops with a hwswitch */ |
787 | /* rfkill is only tested on laptops with a hwswitch */ | 862 | if (!(status & BIT(0)) && !force_rfkill) |
788 | return 0; | 863 | return 0; |
789 | } | ||
790 | } | ||
791 | 864 | ||
792 | if ((status & (1<<2|1<<8)) == (1<<2|1<<8)) { | 865 | if ((status & (1<<2|1<<8)) == (1<<2|1<<8)) { |
793 | wifi_rfkill = rfkill_alloc("dell-wifi", &platform_device->dev, | 866 | wifi_rfkill = rfkill_alloc("dell-wifi", &platform_device->dev, |
@@ -932,47 +1005,50 @@ static void dell_cleanup_rfkill(void) | |||
932 | 1005 | ||
933 | static int dell_send_intensity(struct backlight_device *bd) | 1006 | static int dell_send_intensity(struct backlight_device *bd) |
934 | { | 1007 | { |
935 | int ret = 0; | 1008 | int token; |
1009 | int ret; | ||
1010 | |||
1011 | token = find_token_location(BRIGHTNESS_TOKEN); | ||
1012 | if (token == -1) | ||
1013 | return -ENODEV; | ||
936 | 1014 | ||
937 | get_buffer(); | 1015 | get_buffer(); |
938 | buffer->input[0] = find_token_location(BRIGHTNESS_TOKEN); | 1016 | buffer->input[0] = token; |
939 | buffer->input[1] = bd->props.brightness; | 1017 | buffer->input[1] = bd->props.brightness; |
940 | 1018 | ||
941 | if (buffer->input[0] == -1) { | ||
942 | ret = -ENODEV; | ||
943 | goto out; | ||
944 | } | ||
945 | |||
946 | if (power_supply_is_system_supplied() > 0) | 1019 | if (power_supply_is_system_supplied() > 0) |
947 | dell_send_request(buffer, 1, 2); | 1020 | dell_send_request(buffer, 1, 2); |
948 | else | 1021 | else |
949 | dell_send_request(buffer, 1, 1); | 1022 | dell_send_request(buffer, 1, 1); |
950 | 1023 | ||
951 | out: | 1024 | ret = dell_smi_error(buffer->output[0]); |
1025 | |||
952 | release_buffer(); | 1026 | release_buffer(); |
953 | return ret; | 1027 | return ret; |
954 | } | 1028 | } |
955 | 1029 | ||
956 | static int dell_get_intensity(struct backlight_device *bd) | 1030 | static int dell_get_intensity(struct backlight_device *bd) |
957 | { | 1031 | { |
958 | int ret = 0; | 1032 | int token; |
1033 | int ret; | ||
959 | 1034 | ||
960 | get_buffer(); | 1035 | token = find_token_location(BRIGHTNESS_TOKEN); |
961 | buffer->input[0] = find_token_location(BRIGHTNESS_TOKEN); | 1036 | if (token == -1) |
1037 | return -ENODEV; | ||
962 | 1038 | ||
963 | if (buffer->input[0] == -1) { | 1039 | get_buffer(); |
964 | ret = -ENODEV; | 1040 | buffer->input[0] = token; |
965 | goto out; | ||
966 | } | ||
967 | 1041 | ||
968 | if (power_supply_is_system_supplied() > 0) | 1042 | if (power_supply_is_system_supplied() > 0) |
969 | dell_send_request(buffer, 0, 2); | 1043 | dell_send_request(buffer, 0, 2); |
970 | else | 1044 | else |
971 | dell_send_request(buffer, 0, 1); | 1045 | dell_send_request(buffer, 0, 1); |
972 | 1046 | ||
973 | ret = buffer->output[1]; | 1047 | if (buffer->output[0]) |
1048 | ret = dell_smi_error(buffer->output[0]); | ||
1049 | else | ||
1050 | ret = buffer->output[1]; | ||
974 | 1051 | ||
975 | out: | ||
976 | release_buffer(); | 1052 | release_buffer(); |
977 | return ret; | 1053 | return ret; |
978 | } | 1054 | } |
@@ -2036,6 +2112,7 @@ static void kbd_led_exit(void) | |||
2036 | static int __init dell_init(void) | 2112 | static int __init dell_init(void) |
2037 | { | 2113 | { |
2038 | int max_intensity = 0; | 2114 | int max_intensity = 0; |
2115 | int token; | ||
2039 | int ret; | 2116 | int ret; |
2040 | 2117 | ||
2041 | if (!dmi_check_system(dell_device_table)) | 2118 | if (!dmi_check_system(dell_device_table)) |
@@ -2094,13 +2171,15 @@ static int __init dell_init(void) | |||
2094 | if (acpi_video_get_backlight_type() != acpi_backlight_vendor) | 2171 | if (acpi_video_get_backlight_type() != acpi_backlight_vendor) |
2095 | return 0; | 2172 | return 0; |
2096 | 2173 | ||
2097 | get_buffer(); | 2174 | token = find_token_location(BRIGHTNESS_TOKEN); |
2098 | buffer->input[0] = find_token_location(BRIGHTNESS_TOKEN); | 2175 | if (token != -1) { |
2099 | if (buffer->input[0] != -1) { | 2176 | get_buffer(); |
2177 | buffer->input[0] = token; | ||
2100 | dell_send_request(buffer, 0, 2); | 2178 | dell_send_request(buffer, 0, 2); |
2101 | max_intensity = buffer->output[3]; | 2179 | if (buffer->output[0] == 0) |
2180 | max_intensity = buffer->output[3]; | ||
2181 | release_buffer(); | ||
2102 | } | 2182 | } |
2103 | release_buffer(); | ||
2104 | 2183 | ||
2105 | if (max_intensity) { | 2184 | if (max_intensity) { |
2106 | struct backlight_properties props; | 2185 | struct backlight_properties props; |
diff --git a/drivers/platform/x86/intel_pmc_ipc.c b/drivers/platform/x86/intel_pmc_ipc.c index d734763dab69..105cfffe82c6 100644 --- a/drivers/platform/x86/intel_pmc_ipc.c +++ b/drivers/platform/x86/intel_pmc_ipc.c | |||
@@ -96,18 +96,18 @@ static struct intel_pmc_ipc_dev { | |||
96 | struct completion cmd_complete; | 96 | struct completion cmd_complete; |
97 | 97 | ||
98 | /* The following PMC BARs share the same ACPI device with the IPC */ | 98 | /* The following PMC BARs share the same ACPI device with the IPC */ |
99 | void *acpi_io_base; | 99 | resource_size_t acpi_io_base; |
100 | int acpi_io_size; | 100 | int acpi_io_size; |
101 | struct platform_device *tco_dev; | 101 | struct platform_device *tco_dev; |
102 | 102 | ||
103 | /* gcr */ | 103 | /* gcr */ |
104 | void *gcr_base; | 104 | resource_size_t gcr_base; |
105 | int gcr_size; | 105 | int gcr_size; |
106 | 106 | ||
107 | /* punit */ | 107 | /* punit */ |
108 | void *punit_base; | 108 | resource_size_t punit_base; |
109 | int punit_size; | 109 | int punit_size; |
110 | void *punit_base2; | 110 | resource_size_t punit_base2; |
111 | int punit_size2; | 111 | int punit_size2; |
112 | struct platform_device *punit_dev; | 112 | struct platform_device *punit_dev; |
113 | } ipcdev; | 113 | } ipcdev; |
@@ -210,10 +210,15 @@ static int intel_pmc_ipc_check_status(void) | |||
210 | return ret; | 210 | return ret; |
211 | } | 211 | } |
212 | 212 | ||
213 | /* | 213 | /** |
214 | * intel_pmc_ipc_simple_command | 214 | * intel_pmc_ipc_simple_command() - Simple IPC command |
215 | * @cmd: command | 215 | * @cmd: IPC command code. |
216 | * @sub: sub type | 216 | * @sub: IPC command sub type. |
217 | * | ||
218 | * Send a simple IPC command to PMC when don't need to specify | ||
219 | * input/output data and source/dest pointers. | ||
220 | * | ||
221 | * Return: an IPC error code or 0 on success. | ||
217 | */ | 222 | */ |
218 | int intel_pmc_ipc_simple_command(int cmd, int sub) | 223 | int intel_pmc_ipc_simple_command(int cmd, int sub) |
219 | { | 224 | { |
@@ -232,16 +237,20 @@ int intel_pmc_ipc_simple_command(int cmd, int sub) | |||
232 | } | 237 | } |
233 | EXPORT_SYMBOL_GPL(intel_pmc_ipc_simple_command); | 238 | EXPORT_SYMBOL_GPL(intel_pmc_ipc_simple_command); |
234 | 239 | ||
235 | /* | 240 | /** |
236 | * intel_pmc_ipc_raw_cmd | 241 | * intel_pmc_ipc_raw_cmd() - IPC command with data and pointers |
237 | * @cmd: command | 242 | * @cmd: IPC command code. |
238 | * @sub: sub type | 243 | * @sub: IPC command sub type. |
239 | * @in: input data | 244 | * @in: input data of this IPC command. |
240 | * @inlen: input length in bytes | 245 | * @inlen: input data length in bytes. |
241 | * @out: output data | 246 | * @out: output data of this IPC command. |
242 | * @outlen: output length in dwords | 247 | * @outlen: output data length in dwords. |
243 | * @sptr: data writing to SPTR register | 248 | * @sptr: data writing to SPTR register. |
244 | * @dptr: data writing to DPTR register | 249 | * @dptr: data writing to DPTR register. |
250 | * | ||
251 | * Send an IPC command to PMC with input/output data and source/dest pointers. | ||
252 | * | ||
253 | * Return: an IPC error code or 0 on success. | ||
245 | */ | 254 | */ |
246 | int intel_pmc_ipc_raw_cmd(u32 cmd, u32 sub, u8 *in, u32 inlen, u32 *out, | 255 | int intel_pmc_ipc_raw_cmd(u32 cmd, u32 sub, u8 *in, u32 inlen, u32 *out, |
247 | u32 outlen, u32 dptr, u32 sptr) | 256 | u32 outlen, u32 dptr, u32 sptr) |
@@ -278,14 +287,18 @@ int intel_pmc_ipc_raw_cmd(u32 cmd, u32 sub, u8 *in, u32 inlen, u32 *out, | |||
278 | } | 287 | } |
279 | EXPORT_SYMBOL_GPL(intel_pmc_ipc_raw_cmd); | 288 | EXPORT_SYMBOL_GPL(intel_pmc_ipc_raw_cmd); |
280 | 289 | ||
281 | /* | 290 | /** |
282 | * intel_pmc_ipc_command | 291 | * intel_pmc_ipc_command() - IPC command with input/output data |
283 | * @cmd: command | 292 | * @cmd: IPC command code. |
284 | * @sub: sub type | 293 | * @sub: IPC command sub type. |
285 | * @in: input data | 294 | * @in: input data of this IPC command. |
286 | * @inlen: input length in bytes | 295 | * @inlen: input data length in bytes. |
287 | * @out: output data | 296 | * @out: output data of this IPC command. |
288 | * @outlen: output length in dwords | 297 | * @outlen: output data length in dwords. |
298 | * | ||
299 | * Send an IPC command to PMC with input/output data. | ||
300 | * | ||
301 | * Return: an IPC error code or 0 on success. | ||
289 | */ | 302 | */ |
290 | int intel_pmc_ipc_command(u32 cmd, u32 sub, u8 *in, u32 inlen, | 303 | int intel_pmc_ipc_command(u32 cmd, u32 sub, u8 *in, u32 inlen, |
291 | u32 *out, u32 outlen) | 304 | u32 *out, u32 outlen) |
@@ -480,11 +493,11 @@ static int ipc_create_punit_device(void) | |||
480 | pdev->dev.parent = ipcdev.dev; | 493 | pdev->dev.parent = ipcdev.dev; |
481 | 494 | ||
482 | res = punit_res; | 495 | res = punit_res; |
483 | res->start = (resource_size_t)ipcdev.punit_base; | 496 | res->start = ipcdev.punit_base; |
484 | res->end = res->start + ipcdev.punit_size - 1; | 497 | res->end = res->start + ipcdev.punit_size - 1; |
485 | 498 | ||
486 | res = punit_res + PUNIT_RESOURCE_INTER; | 499 | res = punit_res + PUNIT_RESOURCE_INTER; |
487 | res->start = (resource_size_t)ipcdev.punit_base2; | 500 | res->start = ipcdev.punit_base2; |
488 | res->end = res->start + ipcdev.punit_size2 - 1; | 501 | res->end = res->start + ipcdev.punit_size2 - 1; |
489 | 502 | ||
490 | ret = platform_device_add_resources(pdev, punit_res, | 503 | ret = platform_device_add_resources(pdev, punit_res, |
@@ -522,15 +535,15 @@ static int ipc_create_tco_device(void) | |||
522 | pdev->dev.parent = ipcdev.dev; | 535 | pdev->dev.parent = ipcdev.dev; |
523 | 536 | ||
524 | res = tco_res + TCO_RESOURCE_ACPI_IO; | 537 | res = tco_res + TCO_RESOURCE_ACPI_IO; |
525 | res->start = (resource_size_t)ipcdev.acpi_io_base + TCO_BASE_OFFSET; | 538 | res->start = ipcdev.acpi_io_base + TCO_BASE_OFFSET; |
526 | res->end = res->start + TCO_REGS_SIZE - 1; | 539 | res->end = res->start + TCO_REGS_SIZE - 1; |
527 | 540 | ||
528 | res = tco_res + TCO_RESOURCE_SMI_EN_IO; | 541 | res = tco_res + TCO_RESOURCE_SMI_EN_IO; |
529 | res->start = (resource_size_t)ipcdev.acpi_io_base + SMI_EN_OFFSET; | 542 | res->start = ipcdev.acpi_io_base + SMI_EN_OFFSET; |
530 | res->end = res->start + SMI_EN_SIZE - 1; | 543 | res->end = res->start + SMI_EN_SIZE - 1; |
531 | 544 | ||
532 | res = tco_res + TCO_RESOURCE_GCR_MEM; | 545 | res = tco_res + TCO_RESOURCE_GCR_MEM; |
533 | res->start = (resource_size_t)ipcdev.gcr_base; | 546 | res->start = ipcdev.gcr_base; |
534 | res->end = res->start + ipcdev.gcr_size - 1; | 547 | res->end = res->start + ipcdev.gcr_size - 1; |
535 | 548 | ||
536 | ret = platform_device_add_resources(pdev, tco_res, ARRAY_SIZE(tco_res)); | 549 | ret = platform_device_add_resources(pdev, tco_res, ARRAY_SIZE(tco_res)); |
@@ -589,7 +602,7 @@ static int ipc_plat_get_res(struct platform_device *pdev) | |||
589 | return -ENXIO; | 602 | return -ENXIO; |
590 | } | 603 | } |
591 | size = resource_size(res); | 604 | size = resource_size(res); |
592 | ipcdev.acpi_io_base = (void *)res->start; | 605 | ipcdev.acpi_io_base = res->start; |
593 | ipcdev.acpi_io_size = size; | 606 | ipcdev.acpi_io_size = size; |
594 | dev_info(&pdev->dev, "io res: %llx %x\n", | 607 | dev_info(&pdev->dev, "io res: %llx %x\n", |
595 | (long long)res->start, (int)resource_size(res)); | 608 | (long long)res->start, (int)resource_size(res)); |
@@ -601,7 +614,7 @@ static int ipc_plat_get_res(struct platform_device *pdev) | |||
601 | return -ENXIO; | 614 | return -ENXIO; |
602 | } | 615 | } |
603 | size = resource_size(res); | 616 | size = resource_size(res); |
604 | ipcdev.punit_base = (void *)res->start; | 617 | ipcdev.punit_base = res->start; |
605 | ipcdev.punit_size = size; | 618 | ipcdev.punit_size = size; |
606 | dev_info(&pdev->dev, "punit data res: %llx %x\n", | 619 | dev_info(&pdev->dev, "punit data res: %llx %x\n", |
607 | (long long)res->start, (int)resource_size(res)); | 620 | (long long)res->start, (int)resource_size(res)); |
@@ -613,7 +626,7 @@ static int ipc_plat_get_res(struct platform_device *pdev) | |||
613 | return -ENXIO; | 626 | return -ENXIO; |
614 | } | 627 | } |
615 | size = resource_size(res); | 628 | size = resource_size(res); |
616 | ipcdev.punit_base2 = (void *)res->start; | 629 | ipcdev.punit_base2 = res->start; |
617 | ipcdev.punit_size2 = size; | 630 | ipcdev.punit_size2 = size; |
618 | dev_info(&pdev->dev, "punit interface res: %llx %x\n", | 631 | dev_info(&pdev->dev, "punit interface res: %llx %x\n", |
619 | (long long)res->start, (int)resource_size(res)); | 632 | (long long)res->start, (int)resource_size(res)); |
@@ -637,7 +650,7 @@ static int ipc_plat_get_res(struct platform_device *pdev) | |||
637 | } | 650 | } |
638 | ipcdev.ipc_base = addr; | 651 | ipcdev.ipc_base = addr; |
639 | 652 | ||
640 | ipcdev.gcr_base = (void *)(res->start + size); | 653 | ipcdev.gcr_base = res->start + size; |
641 | ipcdev.gcr_size = PLAT_RESOURCE_GCR_SIZE; | 654 | ipcdev.gcr_size = PLAT_RESOURCE_GCR_SIZE; |
642 | dev_info(&pdev->dev, "ipc res: %llx %x\n", | 655 | dev_info(&pdev->dev, "ipc res: %llx %x\n", |
643 | (long long)res->start, (int)resource_size(res)); | 656 | (long long)res->start, (int)resource_size(res)); |
diff --git a/drivers/platform/x86/intel_scu_ipc.c b/drivers/platform/x86/intel_scu_ipc.c index 001b199a8c33..187d1086d15c 100644 --- a/drivers/platform/x86/intel_scu_ipc.c +++ b/drivers/platform/x86/intel_scu_ipc.c | |||
@@ -216,13 +216,13 @@ static int pwr_reg_rdwr(u16 *addr, u8 *data, u32 count, u32 op, u32 id) | |||
216 | int nc; | 216 | int nc; |
217 | u32 offset = 0; | 217 | u32 offset = 0; |
218 | int err; | 218 | int err; |
219 | u8 cbuf[IPC_WWBUF_SIZE] = { }; | 219 | u8 cbuf[IPC_WWBUF_SIZE]; |
220 | u32 *wbuf = (u32 *)&cbuf; | 220 | u32 *wbuf = (u32 *)&cbuf; |
221 | 221 | ||
222 | mutex_lock(&ipclock); | ||
223 | |||
224 | memset(cbuf, 0, sizeof(cbuf)); | 222 | memset(cbuf, 0, sizeof(cbuf)); |
225 | 223 | ||
224 | mutex_lock(&ipclock); | ||
225 | |||
226 | if (ipcdev.pdev == NULL) { | 226 | if (ipcdev.pdev == NULL) { |
227 | mutex_unlock(&ipclock); | 227 | mutex_unlock(&ipclock); |
228 | return -ENODEV; | 228 | return -ENODEV; |