diff options
Diffstat (limited to 'drivers/acpi/cppc_acpi.c')
-rw-r--r-- | drivers/acpi/cppc_acpi.c | 30 |
1 files changed, 16 insertions, 14 deletions
diff --git a/drivers/acpi/cppc_acpi.c b/drivers/acpi/cppc_acpi.c index fea58e209b5b..93826c7b73ae 100644 --- a/drivers/acpi/cppc_acpi.c +++ b/drivers/acpi/cppc_acpi.c | |||
@@ -763,7 +763,7 @@ int cppc_get_perf_caps(int cpunum, struct cppc_perf_caps *perf_caps) | |||
763 | struct cpc_register_resource *highest_reg, *lowest_reg, *ref_perf, | 763 | struct cpc_register_resource *highest_reg, *lowest_reg, *ref_perf, |
764 | *nom_perf; | 764 | *nom_perf; |
765 | u64 high, low, ref, nom; | 765 | u64 high, low, ref, nom; |
766 | int ret = 0; | 766 | int ret = 0, regs_in_pcc = 0; |
767 | 767 | ||
768 | if (!cpc_desc) { | 768 | if (!cpc_desc) { |
769 | pr_debug("No CPC descriptor for CPU:%d\n", cpunum); | 769 | pr_debug("No CPC descriptor for CPU:%d\n", cpunum); |
@@ -775,13 +775,13 @@ int cppc_get_perf_caps(int cpunum, struct cppc_perf_caps *perf_caps) | |||
775 | ref_perf = &cpc_desc->cpc_regs[REFERENCE_PERF]; | 775 | ref_perf = &cpc_desc->cpc_regs[REFERENCE_PERF]; |
776 | nom_perf = &cpc_desc->cpc_regs[NOMINAL_PERF]; | 776 | nom_perf = &cpc_desc->cpc_regs[NOMINAL_PERF]; |
777 | 777 | ||
778 | spin_lock(&pcc_lock); | ||
779 | |||
780 | /* Are any of the regs PCC ?*/ | 778 | /* Are any of the regs PCC ?*/ |
781 | if ((highest_reg->cpc_entry.reg.space_id == ACPI_ADR_SPACE_PLATFORM_COMM) || | 779 | if ((highest_reg->cpc_entry.reg.space_id == ACPI_ADR_SPACE_PLATFORM_COMM) || |
782 | (lowest_reg->cpc_entry.reg.space_id == ACPI_ADR_SPACE_PLATFORM_COMM) || | 780 | (lowest_reg->cpc_entry.reg.space_id == ACPI_ADR_SPACE_PLATFORM_COMM) || |
783 | (ref_perf->cpc_entry.reg.space_id == ACPI_ADR_SPACE_PLATFORM_COMM) || | 781 | (ref_perf->cpc_entry.reg.space_id == ACPI_ADR_SPACE_PLATFORM_COMM) || |
784 | (nom_perf->cpc_entry.reg.space_id == ACPI_ADR_SPACE_PLATFORM_COMM)) { | 782 | (nom_perf->cpc_entry.reg.space_id == ACPI_ADR_SPACE_PLATFORM_COMM)) { |
783 | spin_lock(&pcc_lock); | ||
784 | regs_in_pcc = 1; | ||
785 | /* Ring doorbell once to update PCC subspace */ | 785 | /* Ring doorbell once to update PCC subspace */ |
786 | if (send_pcc_cmd(CMD_READ) < 0) { | 786 | if (send_pcc_cmd(CMD_READ) < 0) { |
787 | ret = -EIO; | 787 | ret = -EIO; |
@@ -808,7 +808,8 @@ int cppc_get_perf_caps(int cpunum, struct cppc_perf_caps *perf_caps) | |||
808 | ret = -EFAULT; | 808 | ret = -EFAULT; |
809 | 809 | ||
810 | out_err: | 810 | out_err: |
811 | spin_unlock(&pcc_lock); | 811 | if (regs_in_pcc) |
812 | spin_unlock(&pcc_lock); | ||
812 | return ret; | 813 | return ret; |
813 | } | 814 | } |
814 | EXPORT_SYMBOL_GPL(cppc_get_perf_caps); | 815 | EXPORT_SYMBOL_GPL(cppc_get_perf_caps); |
@@ -825,7 +826,7 @@ int cppc_get_perf_ctrs(int cpunum, struct cppc_perf_fb_ctrs *perf_fb_ctrs) | |||
825 | struct cpc_desc *cpc_desc = per_cpu(cpc_desc_ptr, cpunum); | 826 | struct cpc_desc *cpc_desc = per_cpu(cpc_desc_ptr, cpunum); |
826 | struct cpc_register_resource *delivered_reg, *reference_reg; | 827 | struct cpc_register_resource *delivered_reg, *reference_reg; |
827 | u64 delivered, reference; | 828 | u64 delivered, reference; |
828 | int ret = 0; | 829 | int ret = 0, regs_in_pcc = 0; |
829 | 830 | ||
830 | if (!cpc_desc) { | 831 | if (!cpc_desc) { |
831 | pr_debug("No CPC descriptor for CPU:%d\n", cpunum); | 832 | pr_debug("No CPC descriptor for CPU:%d\n", cpunum); |
@@ -835,11 +836,11 @@ int cppc_get_perf_ctrs(int cpunum, struct cppc_perf_fb_ctrs *perf_fb_ctrs) | |||
835 | delivered_reg = &cpc_desc->cpc_regs[DELIVERED_CTR]; | 836 | delivered_reg = &cpc_desc->cpc_regs[DELIVERED_CTR]; |
836 | reference_reg = &cpc_desc->cpc_regs[REFERENCE_CTR]; | 837 | reference_reg = &cpc_desc->cpc_regs[REFERENCE_CTR]; |
837 | 838 | ||
838 | spin_lock(&pcc_lock); | ||
839 | |||
840 | /* Are any of the regs PCC ?*/ | 839 | /* Are any of the regs PCC ?*/ |
841 | if ((delivered_reg->cpc_entry.reg.space_id == ACPI_ADR_SPACE_PLATFORM_COMM) || | 840 | if ((delivered_reg->cpc_entry.reg.space_id == ACPI_ADR_SPACE_PLATFORM_COMM) || |
842 | (reference_reg->cpc_entry.reg.space_id == ACPI_ADR_SPACE_PLATFORM_COMM)) { | 841 | (reference_reg->cpc_entry.reg.space_id == ACPI_ADR_SPACE_PLATFORM_COMM)) { |
842 | spin_lock(&pcc_lock); | ||
843 | regs_in_pcc = 1; | ||
843 | /* Ring doorbell once to update PCC subspace */ | 844 | /* Ring doorbell once to update PCC subspace */ |
844 | if (send_pcc_cmd(CMD_READ) < 0) { | 845 | if (send_pcc_cmd(CMD_READ) < 0) { |
845 | ret = -EIO; | 846 | ret = -EIO; |
@@ -865,7 +866,8 @@ int cppc_get_perf_ctrs(int cpunum, struct cppc_perf_fb_ctrs *perf_fb_ctrs) | |||
865 | perf_fb_ctrs->prev_reference = reference; | 866 | perf_fb_ctrs->prev_reference = reference; |
866 | 867 | ||
867 | out_err: | 868 | out_err: |
868 | spin_unlock(&pcc_lock); | 869 | if (regs_in_pcc) |
870 | spin_unlock(&pcc_lock); | ||
869 | return ret; | 871 | return ret; |
870 | } | 872 | } |
871 | EXPORT_SYMBOL_GPL(cppc_get_perf_ctrs); | 873 | EXPORT_SYMBOL_GPL(cppc_get_perf_ctrs); |
@@ -890,10 +892,9 @@ int cppc_set_perf(int cpu, struct cppc_perf_ctrls *perf_ctrls) | |||
890 | 892 | ||
891 | desired_reg = &cpc_desc->cpc_regs[DESIRED_PERF]; | 893 | desired_reg = &cpc_desc->cpc_regs[DESIRED_PERF]; |
892 | 894 | ||
893 | spin_lock(&pcc_lock); | ||
894 | |||
895 | /* If this is PCC reg, check if channel is free before writing */ | 895 | /* If this is PCC reg, check if channel is free before writing */ |
896 | if (desired_reg->cpc_entry.reg.space_id == ACPI_ADR_SPACE_PLATFORM_COMM) { | 896 | if (desired_reg->cpc_entry.reg.space_id == ACPI_ADR_SPACE_PLATFORM_COMM) { |
897 | spin_lock(&pcc_lock); | ||
897 | ret = check_pcc_chan(); | 898 | ret = check_pcc_chan(); |
898 | if (ret) | 899 | if (ret) |
899 | goto busy_channel; | 900 | goto busy_channel; |
@@ -912,7 +913,8 @@ int cppc_set_perf(int cpu, struct cppc_perf_ctrls *perf_ctrls) | |||
912 | ret = -EIO; | 913 | ret = -EIO; |
913 | } | 914 | } |
914 | busy_channel: | 915 | busy_channel: |
915 | spin_unlock(&pcc_lock); | 916 | if (desired_reg->cpc_entry.reg.space_id == ACPI_ADR_SPACE_PLATFORM_COMM) |
917 | spin_unlock(&pcc_lock); | ||
916 | return ret; | 918 | return ret; |
917 | } | 919 | } |
918 | EXPORT_SYMBOL_GPL(cppc_set_perf); | 920 | EXPORT_SYMBOL_GPL(cppc_set_perf); |