int acpi_processor_tstate_has_changed(struct acpi_processor *pr)
 {
-       return acpi_processor_get_platform_limit(pr);
+       int result = 0;
+       int throttling_limit;
+       int current_state;
+       struct acpi_processor_limit *limit;
+       int target_state;
+
+       result = acpi_processor_get_platform_limit(pr);
+       if (result) {
+               /* Throttling Limit is unsupported */
+               return result;
+       }
+
+       throttling_limit = pr->throttling_platform_limit;
+       if (throttling_limit >= pr->throttling.state_count) {
+               /* Uncorrect Throttling Limit */
+               return -EINVAL;
+       }
+
+       current_state = pr->throttling.state;
+       if (current_state > throttling_limit) {
+               /*
+                * The current state can meet the requirement of
+                * _TPC limit. But it is reasonable that OSPM changes
+                * t-states from high to low for better performance.
+                * Of course the limit condition of thermal
+                * and user should be considered.
+                */
+               limit = &pr->limit;
+               target_state = throttling_limit;
+               if (limit->thermal.tx > target_state)
+                       target_state = limit->thermal.tx;
+               if (limit->user.tx > target_state)
+                       target_state = limit->user.tx;
+       } else if (current_state == throttling_limit) {
+               /*
+                * Unnecessary to change the throttling state
+                */
+               return 0;
+       } else {
+               /*
+                * If the current state is lower than the limit of _TPC, it
+                * will be forced to switch to the throttling state defined
+                * by throttling_platfor_limit.
+                * Because the previous state meets with the limit condition
+                * of thermal and user, it is unnecessary to check it again.
+                */
+               target_state = throttling_limit;
+       }
+       return acpi_processor_set_throttling(pr, target_state);
 }
 
 /*