aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi/cppc_acpi.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/acpi/cppc_acpi.c')
-rw-r--r--drivers/acpi/cppc_acpi.c30
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
810out_err: 810out_err:
811 spin_unlock(&pcc_lock); 811 if (regs_in_pcc)
812 spin_unlock(&pcc_lock);
812 return ret; 813 return ret;
813} 814}
814EXPORT_SYMBOL_GPL(cppc_get_perf_caps); 815EXPORT_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
867out_err: 868out_err:
868 spin_unlock(&pcc_lock); 869 if (regs_in_pcc)
870 spin_unlock(&pcc_lock);
869 return ret; 871 return ret;
870} 872}
871EXPORT_SYMBOL_GPL(cppc_get_perf_ctrs); 873EXPORT_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 }
914busy_channel: 915busy_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}
918EXPORT_SYMBOL_GPL(cppc_set_perf); 920EXPORT_SYMBOL_GPL(cppc_set_perf);