Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 6c128e79 authored by Rafael J. Wysocki's avatar Rafael J. Wysocki
Browse files

Merge branches 'acpi-cppc', 'acpi-misc', 'acpi-battery' and 'acpi-ac'

* acpi-cppc:
  mailbox: PCC: erroneous error message when parsing ACPI PCCT
  ACPI / CPPC: Fix invalid PCC channel status errors
  ACPI / CPPC: Document CPPC sysfs interface
  cpufreq / CPPC: Support for CPPC v3
  ACPI / CPPC: Check for valid PCC subspace only if PCC is used
  ACPI / CPPC: Add support for CPPC v3

* acpi-misc:
  ACPI: Add missing prototype_for arch_post_acpi_subsys_init()
  ACPI: add missing newline to printk

* acpi-battery:
  ACPI / battery: Add quirk to avoid checking for PMIC with native driver
  ACPI / battery: Ignore AC state in handle_discharging on systems where it is broken
  ACPI / battery: Add handling for devices which wrongly report discharging state
  ACPI / battery: Remove initializer for unused ident dmi_system_id
  ACPI / AC: Remove initializer for unused ident dmi_system_id

* acpi-ac:
  ACPI / AC: Add quirk to avoid checking for PMIC with native driver
Loading
Loading
Loading
Loading
+69 −0
Original line number Diff line number Diff line

	Collaborative Processor Performance Control (CPPC)

CPPC defined in the ACPI spec describes a mechanism for the OS to manage the
performance of a logical processor on a contigious and abstract performance
scale. CPPC exposes a set of registers to describe abstract performance scale,
to request performance levels and to measure per-cpu delivered performance.

For more details on CPPC please refer to the ACPI specification at:

http://uefi.org/specifications

Some of the CPPC registers are exposed via sysfs under:

/sys/devices/system/cpu/cpuX/acpi_cppc/

for each cpu X

--------------------------------------------------------------------------------

$ ls -lR  /sys/devices/system/cpu/cpu0/acpi_cppc/
/sys/devices/system/cpu/cpu0/acpi_cppc/:
total 0
-r--r--r-- 1 root root 65536 Mar  5 19:38 feedback_ctrs
-r--r--r-- 1 root root 65536 Mar  5 19:38 highest_perf
-r--r--r-- 1 root root 65536 Mar  5 19:38 lowest_freq
-r--r--r-- 1 root root 65536 Mar  5 19:38 lowest_nonlinear_perf
-r--r--r-- 1 root root 65536 Mar  5 19:38 lowest_perf
-r--r--r-- 1 root root 65536 Mar  5 19:38 nominal_freq
-r--r--r-- 1 root root 65536 Mar  5 19:38 nominal_perf
-r--r--r-- 1 root root 65536 Mar  5 19:38 reference_perf
-r--r--r-- 1 root root 65536 Mar  5 19:38 wraparound_time

--------------------------------------------------------------------------------

* highest_perf : Highest performance of this processor (abstract scale).
* nominal_perf : Highest sustained performance of this processor (abstract scale).
* lowest_nonlinear_perf : Lowest performance of this processor with nonlinear
  power savings (abstract scale).
* lowest_perf : Lowest performance of this processor (abstract scale).

* lowest_freq : CPU frequency corresponding to lowest_perf (in MHz).
* nominal_freq : CPU frequency corresponding to nominal_perf (in MHz).
  The above frequencies should only be used to report processor performance in
  freqency instead of abstract scale. These values should not be used for any
  functional decisions.

* feedback_ctrs : Includes both Reference and delivered performance counter.
  Reference counter ticks up proportional to processor's reference performance.
  Delivered counter ticks up proportional to processor's delivered performance.
* wraparound_time: Minimum time for the feedback counters to wraparound (seconds).
* reference_perf : Performance level at which reference performance counter
  accumulates (abstract scale).

--------------------------------------------------------------------------------

		Computing Average Delivered Performance

Below describes the steps to compute the average performance delivered by taking
two different snapshots of feedback counters at time T1 and T2.

T1: Read feedback_ctrs as fbc_t1
    Wait or run some workload
T2: Read feedback_ctrs as fbc_t2

delivered_counter_delta = fbc_t2[del] - fbc_t1[del]
reference_counter_delta = fbc_t2[ref] - fbc_t1[ref]

delivered_perf = (refernce_perf x delivered_counter_delta) / reference_counter_delta
+37 −11
Original line number Diff line number Diff line
@@ -87,6 +87,7 @@ static int acpi_ac_open_fs(struct inode *inode, struct file *file);


static int ac_sleep_before_get_state_ms;
static int ac_check_pmic = 1;

static struct acpi_driver acpi_ac_driver = {
	.name = "ac",
@@ -310,21 +311,43 @@ static int acpi_ac_battery_notify(struct notifier_block *nb,
	return NOTIFY_OK;
}

static int thinkpad_e530_quirk(const struct dmi_system_id *d)
static int __init thinkpad_e530_quirk(const struct dmi_system_id *d)
{
	ac_sleep_before_get_state_ms = 1000;
	return 0;
}

static const struct dmi_system_id ac_dmi_table[] = {
static int __init ac_do_not_check_pmic_quirk(const struct dmi_system_id *d)
{
	ac_check_pmic = 0;
	return 0;
}

static const struct dmi_system_id ac_dmi_table[]  __initconst = {
	{
	/* Thinkpad e530 */
	.callback = thinkpad_e530_quirk,
	.ident = "thinkpad e530",
	.matches = {
		DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
		DMI_MATCH(DMI_PRODUCT_NAME, "32597CG"),
		},
	},
	{
		/* ECS EF20EA */
		.callback = ac_do_not_check_pmic_quirk,
		.matches = {
			DMI_MATCH(DMI_PRODUCT_NAME, "EF20EA"),
		},
	},
	{
		/* Lenovo Ideapad Miix 320 */
		.callback = ac_do_not_check_pmic_quirk,
		.matches = {
		  DMI_EXACT_MATCH(DMI_SYS_VENDOR, "LENOVO"),
		  DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "80XF"),
		  DMI_EXACT_MATCH(DMI_PRODUCT_VERSION, "Lenovo MIIX 320-10ICR"),
		},
	},
	{},
};

@@ -384,7 +407,6 @@ static int acpi_ac_add(struct acpi_device *device)
		kfree(ac);
	}

	dmi_check_system(ac_dmi_table);
	return result;
}

@@ -442,6 +464,9 @@ static int __init acpi_ac_init(void)
	if (acpi_disabled)
		return -ENODEV;

	dmi_check_system(ac_dmi_table);

	if (ac_check_pmic) {
		for (i = 0; i < ARRAY_SIZE(acpi_ac_blacklist); i++)
			if (acpi_dev_present(acpi_ac_blacklist[i].hid, "1",
					     acpi_ac_blacklist[i].hrv)) {
@@ -449,6 +474,7 @@ static int __init acpi_ac_init(void)
					acpi_ac_blacklist[i].hid);
				return -ENODEV;
			}
	}

#ifdef CONFIG_ACPI_PROCFS_POWER
	acpi_ac_dir = acpi_lock_ac_dir();
+70 −11
Original line number Diff line number Diff line
@@ -74,6 +74,8 @@ static async_cookie_t async_cookie;
static bool battery_driver_registered;
static int battery_bix_broken_package;
static int battery_notification_delay_ms;
static int battery_ac_is_broken;
static int battery_check_pmic = 1;
static unsigned int cache_time = 1000;
module_param(cache_time, uint, 0644);
MODULE_PARM_DESC(cache_time, "cache time in milliseconds");
@@ -215,6 +217,20 @@ static bool acpi_battery_is_degraded(struct acpi_battery *battery)
		battery->full_charge_capacity < battery->design_capacity;
}

static int acpi_battery_handle_discharging(struct acpi_battery *battery)
{
	/*
	 * Some devices wrongly report discharging if the battery's charge level
	 * was above the device's start charging threshold atm the AC adapter
	 * was plugged in and the device thus did not start a new charge cycle.
	 */
	if ((battery_ac_is_broken || power_supply_is_system_supplied()) &&
	    battery->rate_now == 0)
		return POWER_SUPPLY_STATUS_NOT_CHARGING;

	return POWER_SUPPLY_STATUS_DISCHARGING;
}

static int acpi_battery_get_property(struct power_supply *psy,
				     enum power_supply_property psp,
				     union power_supply_propval *val)
@@ -230,7 +246,7 @@ static int acpi_battery_get_property(struct power_supply *psy,
	switch (psp) {
	case POWER_SUPPLY_PROP_STATUS:
		if (battery->state & ACPI_BATTERY_STATE_DISCHARGING)
			val->intval = POWER_SUPPLY_STATUS_DISCHARGING;
			val->intval = acpi_battery_handle_discharging(battery);
		else if (battery->state & ACPI_BATTERY_STATE_CHARGING)
			val->intval = POWER_SUPPLY_STATUS_CHARGING;
		else if (acpi_battery_is_charged(battery))
@@ -1332,23 +1348,64 @@ battery_notification_delay_quirk(const struct dmi_system_id *d)
	return 0;
}

static int __init
battery_ac_is_broken_quirk(const struct dmi_system_id *d)
{
	battery_ac_is_broken = 1;
	return 0;
}

static int __init
battery_do_not_check_pmic_quirk(const struct dmi_system_id *d)
{
	battery_check_pmic = 0;
	return 0;
}

static const struct dmi_system_id bat_dmi_table[] __initconst = {
	{
		/* NEC LZ750/LS */
		.callback = battery_bix_broken_package_quirk,
		.ident = "NEC LZ750/LS",
		.matches = {
			DMI_MATCH(DMI_SYS_VENDOR, "NEC"),
			DMI_MATCH(DMI_PRODUCT_NAME, "PC-LZ750LS"),
		},
	},
	{
		/* Acer Aspire V5-573G */
		.callback = battery_notification_delay_quirk,
		.ident = "Acer Aspire V5-573G",
		.matches = {
			DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
			DMI_MATCH(DMI_PRODUCT_NAME, "Aspire V5-573G"),
		},
	},
	{
		/* Point of View mobii wintab p800w */
		.callback = battery_ac_is_broken_quirk,
		.matches = {
			DMI_MATCH(DMI_BOARD_VENDOR, "AMI Corporation"),
			DMI_MATCH(DMI_BOARD_NAME, "Aptio CRB"),
			DMI_MATCH(DMI_BIOS_VERSION, "3BAIR1013"),
			/* Above matches are too generic, add bios-date match */
			DMI_MATCH(DMI_BIOS_DATE, "08/22/2014"),
		},
	},
	{
		/* ECS EF20EA */
		.callback = battery_do_not_check_pmic_quirk,
		.matches = {
			DMI_MATCH(DMI_PRODUCT_NAME, "EF20EA"),
		},
	},
	{
		/* Lenovo Ideapad Miix 320 */
		.callback = battery_do_not_check_pmic_quirk,
		.matches = {
		  DMI_EXACT_MATCH(DMI_SYS_VENDOR, "LENOVO"),
		  DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "80XF"),
		  DMI_EXACT_MATCH(DMI_PRODUCT_VERSION, "Lenovo MIIX 320-10ICR"),
		},
	},
	{},
};

@@ -1488,6 +1545,9 @@ static void __init acpi_battery_init_async(void *unused, async_cookie_t cookie)
	unsigned int i;
	int result;

	dmi_check_system(bat_dmi_table);

	if (battery_check_pmic) {
		for (i = 0; i < ARRAY_SIZE(acpi_battery_blacklist); i++)
			if (acpi_dev_present(acpi_battery_blacklist[i], "1", -1)) {
				pr_info(PREFIX ACPI_BATTERY_DEVICE_NAME
@@ -1495,8 +1555,7 @@ static void __init acpi_battery_init_async(void *unused, async_cookie_t cookie)
					acpi_battery_blacklist[i]);
				return;
			}

	dmi_check_system(bat_dmi_table);
	}

#ifdef CONFIG_ACPI_PROCFS_POWER
	acpi_battery_dir = acpi_lock_battery_dir();
+105 −54
Original line number Diff line number Diff line
@@ -39,6 +39,7 @@

#include <linux/cpufreq.h>
#include <linux/delay.h>
#include <linux/iopoll.h>
#include <linux/ktime.h>
#include <linux/rwsem.h>
#include <linux/wait.h>
@@ -49,7 +50,7 @@ struct cppc_pcc_data {
	struct mbox_chan *pcc_channel;
	void __iomem *pcc_comm_addr;
	bool pcc_channel_acquired;
	ktime_t deadline;
	unsigned int deadline_us;
	unsigned int pcc_mpar, pcc_mrtt, pcc_nominal;

	bool pending_pcc_write_cmd;	/* Any pending/batched PCC write cmds? */
@@ -156,6 +157,9 @@ show_cppc_data(cppc_get_perf_caps, cppc_perf_caps, highest_perf);
show_cppc_data(cppc_get_perf_caps, cppc_perf_caps, lowest_perf);
show_cppc_data(cppc_get_perf_caps, cppc_perf_caps, nominal_perf);
show_cppc_data(cppc_get_perf_caps, cppc_perf_caps, lowest_nonlinear_perf);
show_cppc_data(cppc_get_perf_caps, cppc_perf_caps, lowest_freq);
show_cppc_data(cppc_get_perf_caps, cppc_perf_caps, nominal_freq);

show_cppc_data(cppc_get_perf_ctrs, cppc_perf_fb_ctrs, reference_perf);
show_cppc_data(cppc_get_perf_ctrs, cppc_perf_fb_ctrs, wraparound_time);

@@ -183,6 +187,8 @@ static struct attribute *cppc_attrs[] = {
	&lowest_perf.attr,
	&lowest_nonlinear_perf.attr,
	&nominal_perf.attr,
	&nominal_freq.attr,
	&lowest_freq.attr,
	NULL
};

@@ -193,42 +199,31 @@ static struct kobj_type cppc_ktype = {

static int check_pcc_chan(int pcc_ss_id, bool chk_err_bit)
{
	int ret = -EIO, status = 0;
	int ret, status;
	struct cppc_pcc_data *pcc_ss_data = pcc_data[pcc_ss_id];
	struct acpi_pcct_shared_memory __iomem *generic_comm_base =
		pcc_ss_data->pcc_comm_addr;
	ktime_t next_deadline = ktime_add(ktime_get(),
					  pcc_ss_data->deadline);

	if (!pcc_ss_data->platform_owns_pcc)
		return 0;

	/* Retry in case the remote processor was too slow to catch up. */
	while (!ktime_after(ktime_get(), next_deadline)) {
	/*
		 * Per spec, prior to boot the PCC space wil be initialized by
		 * platform and should have set the command completion bit when
		 * PCC can be used by OSPM
	 * Poll PCC status register every 3us(delay_us) for maximum of
	 * deadline_us(timeout_us) until PCC command complete bit is set(cond)
	 */
		status = readw_relaxed(&generic_comm_base->status);
		if (status & PCC_CMD_COMPLETE_MASK) {
			ret = 0;
	ret = readw_relaxed_poll_timeout(&generic_comm_base->status, status,
					status & PCC_CMD_COMPLETE_MASK, 3,
					pcc_ss_data->deadline_us);

	if (likely(!ret)) {
		pcc_ss_data->platform_owns_pcc = false;
		if (chk_err_bit && (status & PCC_ERROR_MASK))
			ret = -EIO;
			break;
		}
		/*
		 * Reducing the bus traffic in case this loop takes longer than
		 * a few retries.
		 */
		udelay(3);
	}

	if (likely(!ret))
		pcc_ss_data->platform_owns_pcc = false;
	else
		pr_err("PCC check channel failed for ss: %d. Status=%x\n",
		       pcc_ss_id, status);
	if (unlikely(ret))
		pr_err("PCC check channel failed for ss: %d. ret=%d\n",
		       pcc_ss_id, ret);

	return ret;
}
@@ -580,7 +575,7 @@ static int register_pcc_channel(int pcc_ss_idx)
		 * So add an arbitrary amount of wait on top of Nominal.
		 */
		usecs_lat = NUM_RETRIES * cppc_ss->latency;
		pcc_data[pcc_ss_idx]->deadline = ns_to_ktime(usecs_lat * NSEC_PER_USEC);
		pcc_data[pcc_ss_idx]->deadline_us = usecs_lat;
		pcc_data[pcc_ss_idx]->pcc_mrtt = cppc_ss->min_turnaround_time;
		pcc_data[pcc_ss_idx]->pcc_mpar = cppc_ss->max_access_rate;
		pcc_data[pcc_ss_idx]->pcc_nominal = cppc_ss->latency;
@@ -613,7 +608,6 @@ bool __weak cpc_ffh_supported(void)
	return false;
}


/**
 * pcc_data_alloc() - Allocate the pcc_data memory for pcc subspace
 *
@@ -641,6 +635,34 @@ int pcc_data_alloc(int pcc_ss_id)

	return 0;
}

/* Check if CPPC revision + num_ent combination is supported */
static bool is_cppc_supported(int revision, int num_ent)
{
	int expected_num_ent;

	switch (revision) {
	case CPPC_V2_REV:
		expected_num_ent = CPPC_V2_NUM_ENT;
		break;
	case CPPC_V3_REV:
		expected_num_ent = CPPC_V3_NUM_ENT;
		break;
	default:
		pr_debug("Firmware exports unsupported CPPC revision: %d\n",
			revision);
		return false;
	}

	if (expected_num_ent != num_ent) {
		pr_debug("Firmware exports %d entries. Expected: %d for CPPC rev:%d\n",
			num_ent, expected_num_ent, revision);
		return false;
	}

	return true;
}

/*
 * An example CPC table looks like the following.
 *
@@ -731,14 +753,6 @@ int acpi_cppc_processor_probe(struct acpi_processor *pr)
				cpc_obj->type);
		goto out_free;
	}

	/* Only support CPPCv2. Bail otherwise. */
	if (num_ent != CPPC_NUM_ENT) {
		pr_debug("Firmware exports %d entries. Expected: %d\n",
				num_ent, CPPC_NUM_ENT);
		goto out_free;
	}

	cpc_ptr->num_entries = num_ent;

	/* Second entry should be revision. */
@@ -750,12 +764,10 @@ int acpi_cppc_processor_probe(struct acpi_processor *pr)
				cpc_obj->type);
		goto out_free;
	}
	cpc_ptr->version = cpc_rev;

	if (cpc_rev != CPPC_REV) {
		pr_debug("Firmware exports revision:%d. Expected:%d\n",
				cpc_rev, CPPC_REV);
	if (!is_cppc_supported(cpc_rev, num_ent))
		goto out_free;
	}

	/* Iterate through remaining entries in _CPC */
	for (i = 2; i < num_ent; i++) {
@@ -808,6 +820,18 @@ int acpi_cppc_processor_probe(struct acpi_processor *pr)
		}
	}
	per_cpu(cpu_pcc_subspace_idx, pr->id) = pcc_subspace_id;

	/*
	 * Initialize the remaining cpc_regs as unsupported.
	 * Example: In case FW exposes CPPC v2, the below loop will initialize
	 * LOWEST_FREQ and NOMINAL_FREQ regs as unsupported
	 */
	for (i = num_ent - 2; i < MAX_CPC_REG_ENT; i++) {
		cpc_ptr->cpc_regs[i].type = ACPI_TYPE_INTEGER;
		cpc_ptr->cpc_regs[i].cpc_entry.int_value = 0;
	}


	/* Store CPU Logical ID */
	cpc_ptr->cpu_id = pr->id;

@@ -1037,26 +1061,34 @@ int cppc_get_perf_caps(int cpunum, struct cppc_perf_caps *perf_caps)
{
	struct cpc_desc *cpc_desc = per_cpu(cpc_desc_ptr, cpunum);
	struct cpc_register_resource *highest_reg, *lowest_reg,
		*lowest_non_linear_reg, *nominal_reg;
	u64 high, low, nom, min_nonlinear;
		*lowest_non_linear_reg, *nominal_reg,
		*low_freq_reg = NULL, *nom_freq_reg = NULL;
	u64 high, low, nom, min_nonlinear, low_f = 0, nom_f = 0;
	int pcc_ss_id = per_cpu(cpu_pcc_subspace_idx, cpunum);
	struct cppc_pcc_data *pcc_ss_data;
	struct cppc_pcc_data *pcc_ss_data = NULL;
	int ret = 0, regs_in_pcc = 0;

	if (!cpc_desc || pcc_ss_id < 0) {
	if (!cpc_desc) {
		pr_debug("No CPC descriptor for CPU:%d\n", cpunum);
		return -ENODEV;
	}

	pcc_ss_data = pcc_data[pcc_ss_id];
	highest_reg = &cpc_desc->cpc_regs[HIGHEST_PERF];
	lowest_reg = &cpc_desc->cpc_regs[LOWEST_PERF];
	lowest_non_linear_reg = &cpc_desc->cpc_regs[LOW_NON_LINEAR_PERF];
	nominal_reg = &cpc_desc->cpc_regs[NOMINAL_PERF];
	low_freq_reg = &cpc_desc->cpc_regs[LOWEST_FREQ];
	nom_freq_reg = &cpc_desc->cpc_regs[NOMINAL_FREQ];

	/* Are any of the regs PCC ?*/
	if (CPC_IN_PCC(highest_reg) || CPC_IN_PCC(lowest_reg) ||
		CPC_IN_PCC(lowest_non_linear_reg) || CPC_IN_PCC(nominal_reg)) {
		CPC_IN_PCC(lowest_non_linear_reg) || CPC_IN_PCC(nominal_reg) ||
		CPC_IN_PCC(low_freq_reg) || CPC_IN_PCC(nom_freq_reg)) {
		if (pcc_ss_id < 0) {
			pr_debug("Invalid pcc_ss_id\n");
			return -ENODEV;
		}
		pcc_ss_data = pcc_data[pcc_ss_id];
		regs_in_pcc = 1;
		down_write(&pcc_ss_data->pcc_lock);
		/* Ring doorbell once to update PCC subspace */
@@ -1081,6 +1113,17 @@ int cppc_get_perf_caps(int cpunum, struct cppc_perf_caps *perf_caps)
	if (!high || !low || !nom || !min_nonlinear)
		ret = -EFAULT;

	/* Read optional lowest and nominal frequencies if present */
	if (CPC_SUPPORTED(low_freq_reg))
		cpc_read(cpunum, low_freq_reg, &low_f);

	if (CPC_SUPPORTED(nom_freq_reg))
		cpc_read(cpunum, nom_freq_reg, &nom_f);

	perf_caps->lowest_freq = low_f;
	perf_caps->nominal_freq = nom_f;


out_err:
	if (regs_in_pcc)
		up_write(&pcc_ss_data->pcc_lock);
@@ -1101,16 +1144,15 @@ int cppc_get_perf_ctrs(int cpunum, struct cppc_perf_fb_ctrs *perf_fb_ctrs)
	struct cpc_register_resource *delivered_reg, *reference_reg,
		*ref_perf_reg, *ctr_wrap_reg;
	int pcc_ss_id = per_cpu(cpu_pcc_subspace_idx, cpunum);
	struct cppc_pcc_data *pcc_ss_data;
	struct cppc_pcc_data *pcc_ss_data = NULL;
	u64 delivered, reference, ref_perf, ctr_wrap_time;
	int ret = 0, regs_in_pcc = 0;

	if (!cpc_desc || pcc_ss_id < 0) {
	if (!cpc_desc) {
		pr_debug("No CPC descriptor for CPU:%d\n", cpunum);
		return -ENODEV;
	}

	pcc_ss_data = pcc_data[pcc_ss_id];
	delivered_reg = &cpc_desc->cpc_regs[DELIVERED_CTR];
	reference_reg = &cpc_desc->cpc_regs[REFERENCE_CTR];
	ref_perf_reg = &cpc_desc->cpc_regs[REFERENCE_PERF];
@@ -1126,6 +1168,11 @@ int cppc_get_perf_ctrs(int cpunum, struct cppc_perf_fb_ctrs *perf_fb_ctrs)
	/* Are any of the regs PCC ?*/
	if (CPC_IN_PCC(delivered_reg) || CPC_IN_PCC(reference_reg) ||
		CPC_IN_PCC(ctr_wrap_reg) || CPC_IN_PCC(ref_perf_reg)) {
		if (pcc_ss_id < 0) {
			pr_debug("Invalid pcc_ss_id\n");
			return -ENODEV;
		}
		pcc_ss_data = pcc_data[pcc_ss_id];
		down_write(&pcc_ss_data->pcc_lock);
		regs_in_pcc = 1;
		/* Ring doorbell once to update PCC subspace */
@@ -1176,15 +1223,14 @@ int cppc_set_perf(int cpu, struct cppc_perf_ctrls *perf_ctrls)
	struct cpc_desc *cpc_desc = per_cpu(cpc_desc_ptr, cpu);
	struct cpc_register_resource *desired_reg;
	int pcc_ss_id = per_cpu(cpu_pcc_subspace_idx, cpu);
	struct cppc_pcc_data *pcc_ss_data;
	struct cppc_pcc_data *pcc_ss_data = NULL;
	int ret = 0;

	if (!cpc_desc || pcc_ss_id < 0) {
	if (!cpc_desc) {
		pr_debug("No CPC descriptor for CPU:%d\n", cpu);
		return -ENODEV;
	}

	pcc_ss_data = pcc_data[pcc_ss_id];
	desired_reg = &cpc_desc->cpc_regs[DESIRED_PERF];

	/*
@@ -1195,6 +1241,11 @@ int cppc_set_perf(int cpu, struct cppc_perf_ctrls *perf_ctrls)
	 * achieve that goal here
	 */
	if (CPC_IN_PCC(desired_reg)) {
		if (pcc_ss_id < 0) {
			pr_debug("Invalid pcc_ss_id\n");
			return -ENODEV;
		}
		pcc_ss_data = pcc_data[pcc_ss_id];
		down_read(&pcc_ss_data->pcc_lock); /* BEGIN Phase-I */
		if (pcc_ss_data->platform_owns_pcc) {
			ret = check_pcc_chan(pcc_ss_id, false);
+2 −2
Original line number Diff line number Diff line
@@ -8,8 +8,8 @@ void acpi_reboot(void)
{
	struct acpi_generic_address *rr;
	struct pci_bus *bus0;
	u8 reset_value;
	unsigned int devfn;
	u8 reset_value;

	if (acpi_disabled)
		return;
@@ -40,7 +40,7 @@ void acpi_reboot(void)
		/* Form PCI device/function pair. */
		devfn = PCI_DEVFN((rr->address >> 32) & 0xffff,
				  (rr->address >> 16) & 0xffff);
		printk(KERN_DEBUG "Resetting with ACPI PCI RESET_REG.");
		printk(KERN_DEBUG "Resetting with ACPI PCI RESET_REG.\n");
		/* Write the value that resets us. */
		pci_bus_write_config_byte(bus0, devfn,
				(rr->address & 0xffff), reset_value);
Loading