Commit dedd0c2a authored by Linus Torvalds's avatar Linus Torvalds
Browse files
* 'release' of git://git.kernel.org/pub/scm/linux/kernel/git/lenb/linux-acpi-2.6: (23 commits)
  ACPI: delete acpi_processor_power_verify_c2()
  ACPI: allow C3 > 1000usec
  ACPI: enable C2 and Turbo-mode on Nehalem notebooks on A/C
  ACPI: power_meter: remove double kfree()
  ACPI: processor: restrict early _PDC to opt-in platforms
  ACPI: Fix unused variable warning in sbs.c
  acpi: make ACPI device id constant
  sony-laptop - fix using of uninitialized variable
  ACPI: Fix section mismatch error for acpi_early_processor_set_pdc()
  eeepc-laptop: disable wireless hotplug for 1201N
  eeepc-laptop: add hotplug_disable parameter
  eeepc-laptop: switch to using sparse keymap library
  eeepc-laptop: dmi blacklist to disable pci hotplug code
  eeepc-laptop: disable cpu speed control on EeePC 701
  ACPI: don't cond_resched if irq is disabled
  ACPI: Remove unnecessary cast.
  ACPI: Advertise to BIOS in _OSC: _OST on _PPC changes
  ACPI: EC: Add wait for irq storm
  ACPI: SBS: Move SBS HC callback to faster Notify queue
  x86, ACPI: delete acpi_boot_table_init() return value
  ...
parents 15e551e5 418521de
Loading
Loading
Loading
Loading
+6 −16
Original line number Original line Diff line number Diff line
@@ -1529,16 +1529,10 @@ static struct dmi_system_id __initdata acpi_dmi_table_late[] = {
 *	if acpi_blacklisted() acpi_disabled = 1;
 *	if acpi_blacklisted() acpi_disabled = 1;
 *	acpi_irq_model=...
 *	acpi_irq_model=...
 *	...
 *	...
 *
 * return value: (currently ignored)
 *	0: success
 *	!0: failure
 */
 */


int __init acpi_boot_table_init(void)
void __init acpi_boot_table_init(void)
{
{
	int error;

	dmi_check_system(acpi_dmi_table);
	dmi_check_system(acpi_dmi_table);


	/*
	/*
@@ -1546,15 +1540,14 @@ int __init acpi_boot_table_init(void)
	 * One exception: acpi=ht continues far enough to enumerate LAPICs
	 * One exception: acpi=ht continues far enough to enumerate LAPICs
	 */
	 */
	if (acpi_disabled && !acpi_ht)
	if (acpi_disabled && !acpi_ht)
		return 1;
		return; 


	/*
	/*
	 * Initialize the ACPI boot-time table parser.
	 * Initialize the ACPI boot-time table parser.
	 */
	 */
	error = acpi_table_init();
	if (acpi_table_init()) {
	if (error) {
		disable_acpi();
		disable_acpi();
		return error;
		return;
	}
	}


	acpi_table_parse(ACPI_SIG_BOOT, acpi_parse_sbf);
	acpi_table_parse(ACPI_SIG_BOOT, acpi_parse_sbf);
@@ -1562,18 +1555,15 @@ int __init acpi_boot_table_init(void)
	/*
	/*
	 * blacklist may disable ACPI entirely
	 * blacklist may disable ACPI entirely
	 */
	 */
	error = acpi_blacklisted();
	if (acpi_blacklisted()) {
	if (error) {
		if (acpi_force) {
		if (acpi_force) {
			printk(KERN_WARNING PREFIX "acpi=force override\n");
			printk(KERN_WARNING PREFIX "acpi=force override\n");
		} else {
		} else {
			printk(KERN_WARNING PREFIX "Disabling ACPI support\n");
			printk(KERN_WARNING PREFIX "Disabling ACPI support\n");
			disable_acpi();
			disable_acpi();
			return error;
			return;
		}
		}
	}
	}

	return 0;
}
}


int __init early_acpi_boot_init(void)
int __init early_acpi_boot_init(void)
+20 −17
Original line number Original line Diff line number Diff line
@@ -208,7 +208,7 @@ static int power_saving_thread(void *data)
		 * the mechanism only works when all CPUs have RT task running,
		 * the mechanism only works when all CPUs have RT task running,
		 * as if one CPU hasn't RT task, RT task from other CPUs will
		 * as if one CPU hasn't RT task, RT task from other CPUs will
		 * borrow CPU time from this CPU and cause RT task use > 95%
		 * borrow CPU time from this CPU and cause RT task use > 95%
		 * CPU time. To make 'avoid staration' work, takes a nap here.
		 * CPU time. To make 'avoid starvation' work, takes a nap here.
		 */
		 */
		if (do_sleep)
		if (do_sleep)
			schedule_timeout_killable(HZ * idle_pct / 100);
			schedule_timeout_killable(HZ * idle_pct / 100);
@@ -222,14 +222,18 @@ static struct task_struct *ps_tsks[NR_CPUS];
static unsigned int ps_tsk_num;
static unsigned int ps_tsk_num;
static int create_power_saving_task(void)
static int create_power_saving_task(void)
{
{
	int rc = -ENOMEM;

	ps_tsks[ps_tsk_num] = kthread_run(power_saving_thread,
	ps_tsks[ps_tsk_num] = kthread_run(power_saving_thread,
		(void *)(unsigned long)ps_tsk_num,
		(void *)(unsigned long)ps_tsk_num,
		"power_saving/%d", ps_tsk_num);
		"power_saving/%d", ps_tsk_num);
	if (ps_tsks[ps_tsk_num]) {
	rc = IS_ERR(ps_tsks[ps_tsk_num]) ? PTR_ERR(ps_tsks[ps_tsk_num]) : 0;
	if (!rc)
		ps_tsk_num++;
		ps_tsk_num++;
		return 0;
	else
	}
		ps_tsks[ps_tsk_num] = NULL;
	return -EINVAL;

	return rc;
}
}


static void destroy_power_saving_task(void)
static void destroy_power_saving_task(void)
@@ -237,6 +241,7 @@ static void destroy_power_saving_task(void)
	if (ps_tsk_num > 0) {
	if (ps_tsk_num > 0) {
		ps_tsk_num--;
		ps_tsk_num--;
		kthread_stop(ps_tsks[ps_tsk_num]);
		kthread_stop(ps_tsks[ps_tsk_num]);
		ps_tsks[ps_tsk_num] = NULL;
	}
	}
}
}


@@ -253,7 +258,7 @@ static void set_power_saving_task_num(unsigned int num)
	}
	}
}
}


static int acpi_pad_idle_cpus(unsigned int num_cpus)
static void acpi_pad_idle_cpus(unsigned int num_cpus)
{
{
	get_online_cpus();
	get_online_cpus();


@@ -261,7 +266,6 @@ static int acpi_pad_idle_cpus(unsigned int num_cpus)
	set_power_saving_task_num(num_cpus);
	set_power_saving_task_num(num_cpus);


	put_online_cpus();
	put_online_cpus();
	return 0;
}
}


static uint32_t acpi_pad_idle_cpus_num(void)
static uint32_t acpi_pad_idle_cpus_num(void)
@@ -369,19 +373,21 @@ static void acpi_pad_remove_sysfs(struct acpi_device *device)
static int acpi_pad_pur(acpi_handle handle, int *num_cpus)
static int acpi_pad_pur(acpi_handle handle, int *num_cpus)
{
{
	struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL};
	struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL};
	acpi_status status;
	union acpi_object *package;
	union acpi_object *package;
	int rev, num, ret = -EINVAL;
	int rev, num, ret = -EINVAL;


	status = acpi_evaluate_object(handle, "_PUR", NULL, &buffer);
	if (ACPI_FAILURE(acpi_evaluate_object(handle, "_PUR", NULL, &buffer)))
	if (ACPI_FAILURE(status))
		return -EINVAL;

	if (!buffer.length || !buffer.pointer)
		return -EINVAL;
		return -EINVAL;

	package = buffer.pointer;
	package = buffer.pointer;
	if (package->type != ACPI_TYPE_PACKAGE || package->package.count != 2)
	if (package->type != ACPI_TYPE_PACKAGE || package->package.count != 2)
		goto out;
		goto out;
	rev = package->package.elements[0].integer.value;
	rev = package->package.elements[0].integer.value;
	num = package->package.elements[1].integer.value;
	num = package->package.elements[1].integer.value;
	if (rev != 1)
	if (rev != 1 || num < 0)
		goto out;
		goto out;
	*num_cpus = num;
	*num_cpus = num;
	ret = 0;
	ret = 0;
@@ -410,7 +416,7 @@ static void acpi_pad_ost(acpi_handle handle, int stat,


static void acpi_pad_handle_notify(acpi_handle handle)
static void acpi_pad_handle_notify(acpi_handle handle)
{
{
	int num_cpus, ret;
	int num_cpus;
	uint32_t idle_cpus;
	uint32_t idle_cpus;


	mutex_lock(&isolated_cpus_lock);
	mutex_lock(&isolated_cpus_lock);
@@ -418,12 +424,9 @@ static void acpi_pad_handle_notify(acpi_handle handle)
		mutex_unlock(&isolated_cpus_lock);
		mutex_unlock(&isolated_cpus_lock);
		return;
		return;
	}
	}
	ret = acpi_pad_idle_cpus(num_cpus);
	acpi_pad_idle_cpus(num_cpus);
	idle_cpus = acpi_pad_idle_cpus_num();
	idle_cpus = acpi_pad_idle_cpus_num();
	if (!ret)
	acpi_pad_ost(handle, 0, idle_cpus);
	acpi_pad_ost(handle, 0, idle_cpus);
	else
		acpi_pad_ost(handle, 1, 0);
	mutex_unlock(&isolated_cpus_lock);
	mutex_unlock(&isolated_cpus_lock);
}
}


+6 −1
Original line number Original line Diff line number Diff line
@@ -490,9 +490,14 @@ static void acpi_bus_osc_support(void)


	capbuf[OSC_QUERY_TYPE] = OSC_QUERY_ENABLE;
	capbuf[OSC_QUERY_TYPE] = OSC_QUERY_ENABLE;
	capbuf[OSC_SUPPORT_TYPE] = OSC_SB_PR3_SUPPORT; /* _PR3 is in use */
	capbuf[OSC_SUPPORT_TYPE] = OSC_SB_PR3_SUPPORT; /* _PR3 is in use */
#ifdef CONFIG_ACPI_PROCESSOR_AGGREGATOR
#if defined(CONFIG_ACPI_PROCESSOR_AGGREGATOR) ||\
			defined(CONFIG_ACPI_PROCESSOR_AGGREGATOR_MODULE)
	capbuf[OSC_SUPPORT_TYPE] |= OSC_SB_PAD_SUPPORT;
	capbuf[OSC_SUPPORT_TYPE] |= OSC_SB_PAD_SUPPORT;
#endif
#endif

#if defined(CONFIG_ACPI_PROCESSOR) || defined(CONFIG_ACPI_PROCESSOR_MODULE)
	capbuf[OSC_SUPPORT_TYPE] |= OSC_SB_PPC_OST_SUPPORT;
#endif
	if (ACPI_FAILURE(acpi_get_handle(NULL, "\\_SB", &handle)))
	if (ACPI_FAILURE(acpi_get_handle(NULL, "\\_SB", &handle)))
		return;
		return;
	if (ACPI_SUCCESS(acpi_run_osc(handle, &context)))
	if (ACPI_SUCCESS(acpi_run_osc(handle, &context)))
+80 −46
Original line number Original line Diff line number Diff line
@@ -201,14 +201,13 @@ unlock:
	spin_unlock_irqrestore(&ec->curr_lock, flags);
	spin_unlock_irqrestore(&ec->curr_lock, flags);
}
}


static void acpi_ec_gpe_query(void *ec_cxt);
static int acpi_ec_sync_query(struct acpi_ec *ec);


static int ec_check_sci(struct acpi_ec *ec, u8 state)
static int ec_check_sci_sync(struct acpi_ec *ec, u8 state)
{
{
	if (state & ACPI_EC_FLAG_SCI) {
	if (state & ACPI_EC_FLAG_SCI) {
		if (!test_and_set_bit(EC_FLAGS_QUERY_PENDING, &ec->flags))
		if (!test_and_set_bit(EC_FLAGS_QUERY_PENDING, &ec->flags))
			return acpi_os_execute(OSL_EC_BURST_HANDLER,
			return acpi_ec_sync_query(ec);
				acpi_ec_gpe_query, ec);
	}
	}
	return 0;
	return 0;
}
}
@@ -249,11 +248,6 @@ static int acpi_ec_transaction_unlocked(struct acpi_ec *ec,
{
{
	unsigned long tmp;
	unsigned long tmp;
	int ret = 0;
	int ret = 0;
	pr_debug(PREFIX "transaction start\n");
	/* disable GPE during transaction if storm is detected */
	if (test_bit(EC_FLAGS_GPE_STORM, &ec->flags)) {
		acpi_disable_gpe(NULL, ec->gpe);
	}
	if (EC_FLAGS_MSI)
	if (EC_FLAGS_MSI)
		udelay(ACPI_EC_MSI_UDELAY);
		udelay(ACPI_EC_MSI_UDELAY);
	/* start transaction */
	/* start transaction */
@@ -265,20 +259,9 @@ static int acpi_ec_transaction_unlocked(struct acpi_ec *ec,
		clear_bit(EC_FLAGS_QUERY_PENDING, &ec->flags);
		clear_bit(EC_FLAGS_QUERY_PENDING, &ec->flags);
	spin_unlock_irqrestore(&ec->curr_lock, tmp);
	spin_unlock_irqrestore(&ec->curr_lock, tmp);
	ret = ec_poll(ec);
	ret = ec_poll(ec);
	pr_debug(PREFIX "transaction end\n");
	spin_lock_irqsave(&ec->curr_lock, tmp);
	spin_lock_irqsave(&ec->curr_lock, tmp);
	ec->curr = NULL;
	ec->curr = NULL;
	spin_unlock_irqrestore(&ec->curr_lock, tmp);
	spin_unlock_irqrestore(&ec->curr_lock, tmp);
	if (test_bit(EC_FLAGS_GPE_STORM, &ec->flags)) {
		/* check if we received SCI during transaction */
		ec_check_sci(ec, acpi_ec_read_status(ec));
		/* it is safe to enable GPE outside of transaction */
		acpi_enable_gpe(NULL, ec->gpe);
	} else if (t->irq_count > ACPI_EC_STORM_THRESHOLD) {
		pr_info(PREFIX "GPE storm detected, "
			"transactions will use polling mode\n");
		set_bit(EC_FLAGS_GPE_STORM, &ec->flags);
	}
	return ret;
	return ret;
}
}


@@ -321,7 +304,26 @@ static int acpi_ec_transaction(struct acpi_ec *ec, struct transaction *t)
		status = -ETIME;
		status = -ETIME;
		goto end;
		goto end;
	}
	}
	pr_debug(PREFIX "transaction start\n");
	/* disable GPE during transaction if storm is detected */
	if (test_bit(EC_FLAGS_GPE_STORM, &ec->flags)) {
		acpi_disable_gpe(NULL, ec->gpe);
	}

	status = acpi_ec_transaction_unlocked(ec, t);
	status = acpi_ec_transaction_unlocked(ec, t);

	/* check if we received SCI during transaction */
	ec_check_sci_sync(ec, acpi_ec_read_status(ec));
	if (test_bit(EC_FLAGS_GPE_STORM, &ec->flags)) {
		msleep(1);
		/* it is safe to enable GPE outside of transaction */
		acpi_enable_gpe(NULL, ec->gpe);
	} else if (t->irq_count > ACPI_EC_STORM_THRESHOLD) {
		pr_info(PREFIX "GPE storm detected, "
			"transactions will use polling mode\n");
		set_bit(EC_FLAGS_GPE_STORM, &ec->flags);
	}
	pr_debug(PREFIX "transaction end\n");
end:
end:
	if (ec->global_lock)
	if (ec->global_lock)
		acpi_release_global_lock(glk);
		acpi_release_global_lock(glk);
@@ -443,7 +445,7 @@ int ec_transaction(u8 command,


EXPORT_SYMBOL(ec_transaction);
EXPORT_SYMBOL(ec_transaction);


static int acpi_ec_query(struct acpi_ec *ec, u8 * data)
static int acpi_ec_query_unlocked(struct acpi_ec *ec, u8 * data)
{
{
	int result;
	int result;
	u8 d;
	u8 d;
@@ -452,20 +454,16 @@ static int acpi_ec_query(struct acpi_ec *ec, u8 * data)
				.wlen = 0, .rlen = 1};
				.wlen = 0, .rlen = 1};
	if (!ec || !data)
	if (!ec || !data)
		return -EINVAL;
		return -EINVAL;

	/*
	/*
	 * Query the EC to find out which _Qxx method we need to evaluate.
	 * Query the EC to find out which _Qxx method we need to evaluate.
	 * Note that successful completion of the query causes the ACPI_EC_SCI
	 * Note that successful completion of the query causes the ACPI_EC_SCI
	 * bit to be cleared (and thus clearing the interrupt source).
	 * bit to be cleared (and thus clearing the interrupt source).
	 */
	 */

	result = acpi_ec_transaction_unlocked(ec, &t);
	result = acpi_ec_transaction(ec, &t);
	if (result)
	if (result)
		return result;
		return result;

	if (!d)
	if (!d)
		return -ENODATA;
		return -ENODATA;

	*data = d;
	*data = d;
	return 0;
	return 0;
}
}
@@ -509,43 +507,79 @@ void acpi_ec_remove_query_handler(struct acpi_ec *ec, u8 query_bit)


EXPORT_SYMBOL_GPL(acpi_ec_remove_query_handler);
EXPORT_SYMBOL_GPL(acpi_ec_remove_query_handler);


static void acpi_ec_gpe_query(void *ec_cxt)
static void acpi_ec_run(void *cxt)
{
{
	struct acpi_ec *ec = ec_cxt;
	struct acpi_ec_query_handler *handler = cxt;
	u8 value = 0;
	if (!handler)
	struct acpi_ec_query_handler *handler, copy;

	if (!ec || acpi_ec_query(ec, &value))
		return;
		return;
	mutex_lock(&ec->lock);
	pr_debug(PREFIX "start query execution\n");
	if (handler->func)
		handler->func(handler->data);
	else if (handler->handle)
		acpi_evaluate_object(handler->handle, NULL, NULL, NULL);
	pr_debug(PREFIX "stop query execution\n");
	kfree(handler);
}

static int acpi_ec_sync_query(struct acpi_ec *ec)
{
	u8 value = 0;
	int status;
	struct acpi_ec_query_handler *handler, *copy;
	if ((status = acpi_ec_query_unlocked(ec, &value)))
		return status;
	list_for_each_entry(handler, &ec->list, node) {
	list_for_each_entry(handler, &ec->list, node) {
		if (value == handler->query_bit) {
		if (value == handler->query_bit) {
			/* have custom handler for this bit */
			/* have custom handler for this bit */
			memcpy(&copy, handler, sizeof(copy));
			copy = kmalloc(sizeof(*handler), GFP_KERNEL);
			mutex_unlock(&ec->lock);
			if (!copy)
			if (copy.func) {
				return -ENOMEM;
				copy.func(copy.data);
			memcpy(copy, handler, sizeof(*copy));
			} else if (copy.handle) {
			pr_debug(PREFIX "push query execution (0x%2x) on queue\n", value);
				acpi_evaluate_object(copy.handle, NULL, NULL, NULL);
			return acpi_os_execute((copy->func) ?
				OSL_NOTIFY_HANDLER : OSL_GPE_HANDLER,
				acpi_ec_run, copy);
		}
		}
			return;
	}
	}
	return 0;
}
}

static void acpi_ec_gpe_query(void *ec_cxt)
{
	struct acpi_ec *ec = ec_cxt;
	if (!ec)
		return;
	mutex_lock(&ec->lock);
	acpi_ec_sync_query(ec);
	mutex_unlock(&ec->lock);
	mutex_unlock(&ec->lock);
}
}


static void acpi_ec_gpe_query(void *ec_cxt);

static int ec_check_sci(struct acpi_ec *ec, u8 state)
{
	if (state & ACPI_EC_FLAG_SCI) {
		if (!test_and_set_bit(EC_FLAGS_QUERY_PENDING, &ec->flags)) {
			pr_debug(PREFIX "push gpe query to the queue\n");
			return acpi_os_execute(OSL_NOTIFY_HANDLER,
				acpi_ec_gpe_query, ec);
		}
	}
	return 0;
}

static u32 acpi_ec_gpe_handler(void *data)
static u32 acpi_ec_gpe_handler(void *data)
{
{
	struct acpi_ec *ec = data;
	struct acpi_ec *ec = data;
	u8 status;


	pr_debug(PREFIX "~~~> interrupt\n");
	pr_debug(PREFIX "~~~> interrupt\n");
	status = acpi_ec_read_status(ec);


	advance_transaction(ec, status);
	advance_transaction(ec, acpi_ec_read_status(ec));
	if (ec_transaction_done(ec) && (status & ACPI_EC_FLAG_IBF) == 0)
	if (ec_transaction_done(ec) &&
	    (acpi_ec_read_status(ec) & ACPI_EC_FLAG_IBF) == 0) {
		wake_up(&ec->wait);
		wake_up(&ec->wait);
	ec_check_sci(ec, status);
		ec_check_sci(ec, acpi_ec_read_status(ec));
	}
	return ACPI_INTERRUPT_HANDLED;
	return ACPI_INTERRUPT_HANDLED;
}
}


+1 −1
Original line number Original line Diff line number Diff line
@@ -56,7 +56,7 @@ ACPI_MODULE_NAME("pci_link");
static int acpi_pci_link_add(struct acpi_device *device);
static int acpi_pci_link_add(struct acpi_device *device);
static int acpi_pci_link_remove(struct acpi_device *device, int type);
static int acpi_pci_link_remove(struct acpi_device *device, int type);


static struct acpi_device_id link_device_ids[] = {
static const struct acpi_device_id link_device_ids[] = {
	{"PNP0C0F", 0},
	{"PNP0C0F", 0},
	{"", 0},
	{"", 0},
};
};
Loading