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

Commit 6c89cce7 authored by Len Brown's avatar Len Brown
Browse files

Merge acpi-2.6.12 to-akpm

parents 13779c73 50526df6
Loading
Loading
Loading
Loading
+59 −112
Original line number Diff line number Diff line
@@ -212,19 +212,29 @@ static int acpi_ec_burst_wait(union acpi_ec *ec, unsigned int event)
	ec->burst.expect_event = event;
	smp_mb();

	result = wait_event_interruptible_timeout(ec->burst.wait,
	switch (event) {
	case ACPI_EC_EVENT_OBF:
		if (acpi_ec_read_status(ec) & event) {
			ec->burst.expect_event = 0;
			return_VALUE(0);
		}
		break;

	case ACPI_EC_EVENT_IBE:
		if (~acpi_ec_read_status(ec) & event) {
			ec->burst.expect_event = 0;
			return_VALUE(0);
		}
		break;
	}

	result = wait_event_timeout(ec->burst.wait,
				    !ec->burst.expect_event,
						  msecs_to_jiffies
						  (ACPI_EC_DELAY));
				    msecs_to_jiffies(ACPI_EC_DELAY));

	ec->burst.expect_event = 0;
	smp_mb();

	if (result < 0) {
		ACPI_DEBUG_PRINT((ACPI_DB_ERROR, " result  = %d ", result));
		return_VALUE(result);
	}

	/*
	 * Verify that the event in question has actually happened by
	 * querying EC status. Do the check even if operation timed-out
@@ -254,15 +264,15 @@ static int acpi_ec_enter_burst_mode(union acpi_ec *ec)

	status = acpi_ec_read_status(ec);
	if (status != -EINVAL && !(status & ACPI_EC_FLAG_BURST)) {
		status = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE);
		if (status)
			goto end;
		acpi_hw_low_level_write(8, ACPI_EC_BURST_ENABLE,
					&ec->common.command_addr);
		status = acpi_ec_wait(ec, ACPI_EC_EVENT_OBF);
		if (status) {
			acpi_enable_gpe(NULL, ec->common.gpe_bit, ACPI_NOT_ISR);
		if (status)
			return_VALUE(-EINVAL);
		}
		acpi_hw_low_level_read(8, &tmp, &ec->common.data_addr);
		acpi_enable_gpe(NULL, ec->common.gpe_bit, ACPI_NOT_ISR);
		if (tmp != 0x90) {	/* Burst ACK byte */
			return_VALUE(-EINVAL);
		}
@@ -270,30 +280,17 @@ static int acpi_ec_enter_burst_mode(union acpi_ec *ec)

	atomic_set(&ec->burst.leaving_burst, 0);
	return_VALUE(0);
      end:
	printk("Error in acpi_ec_wait\n");
	return_VALUE(-1);
}

static int acpi_ec_leave_burst_mode(union acpi_ec *ec)
{
	int status = 0;

	ACPI_FUNCTION_TRACE("acpi_ec_leave_burst_mode");

	atomic_set(&ec->burst.leaving_burst, 1);
	status = acpi_ec_read_status(ec);
	if (status != -EINVAL && (status & ACPI_EC_FLAG_BURST)) {
		acpi_hw_low_level_write(8, ACPI_EC_BURST_DISABLE,
					&ec->common.command_addr);
		status = acpi_ec_wait(ec, ACPI_EC_FLAG_IBF);
		if (status) {
			acpi_enable_gpe(NULL, ec->common.gpe_bit, ACPI_NOT_ISR);
			ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
					  "------->wait fail\n"));
			return_VALUE(-EINVAL);
		}
		acpi_enable_gpe(NULL, ec->common.gpe_bit, ACPI_NOT_ISR);
		status = acpi_ec_read_status(ec);
	}

	return_VALUE(0);
}

@@ -416,7 +413,6 @@ static int acpi_ec_burst_read(union acpi_ec *ec, u8 address, u32 * data)
	if (!ec || !data)
		return_VALUE(-EINVAL);

      retry:
	*data = 0;

	if (ec->common.global_lock) {
@@ -428,27 +424,26 @@ static int acpi_ec_burst_read(union acpi_ec *ec, u8 address, u32 * data)
	WARN_ON(in_interrupt());
	down(&ec->burst.sem);

	if (acpi_ec_enter_burst_mode(ec))
	acpi_ec_enter_burst_mode(ec);
	status = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE);
	if (status) {
		printk("read EC, IB not empty\n");
		goto end;

	}
	acpi_hw_low_level_write(8, ACPI_EC_COMMAND_READ,
				&ec->common.command_addr);
	status = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE);
	acpi_enable_gpe(NULL, ec->common.gpe_bit, ACPI_NOT_ISR);
	if (status) {
		goto end;
		printk("read EC, IB not empty\n");
	}

	acpi_hw_low_level_write(8, address, &ec->common.data_addr);
	status = acpi_ec_wait(ec, ACPI_EC_EVENT_OBF);
	if (status) {
		acpi_enable_gpe(NULL, ec->common.gpe_bit, ACPI_NOT_ISR);
		printk("read EC, OB not full\n");
		goto end;
	}

	acpi_hw_low_level_read(8, data, &ec->common.data_addr);
	acpi_enable_gpe(NULL, ec->common.gpe_bit, ACPI_NOT_ISR);

	ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Read [%02x] from address [%02x]\n",
			  *data, address));

@@ -459,15 +454,6 @@ static int acpi_ec_burst_read(union acpi_ec *ec, u8 address, u32 * data)
	if (ec->common.global_lock)
		acpi_release_global_lock(glk);

	if (atomic_read(&ec->burst.leaving_burst) == 2) {
		ACPI_DEBUG_PRINT((ACPI_DB_INFO, "aborted, retry ...\n"));
		while (atomic_read(&ec->burst.pending_gpe)) {
			msleep(1);
		}
		acpi_enable_gpe(NULL, ec->common.gpe_bit, ACPI_NOT_ISR);
		goto retry;
	}

	return_VALUE(status);
}

@@ -475,13 +461,12 @@ static int acpi_ec_burst_write(union acpi_ec *ec, u8 address, u8 data)
{
	int status = 0;
	u32 glk;
	u32 tmp;

	ACPI_FUNCTION_TRACE("acpi_ec_write");

	if (!ec)
		return_VALUE(-EINVAL);
      retry:

	if (ec->common.global_lock) {
		status = acpi_acquire_global_lock(ACPI_EC_UDELAY_GLK, &glk);
		if (ACPI_FAILURE(status))
@@ -491,62 +476,36 @@ static int acpi_ec_burst_write(union acpi_ec *ec, u8 address, u8 data)
	WARN_ON(in_interrupt());
	down(&ec->burst.sem);

	if (acpi_ec_enter_burst_mode(ec))
		goto end;
	acpi_ec_enter_burst_mode(ec);

	status = acpi_ec_read_status(ec);
	if (status != -EINVAL && !(status & ACPI_EC_FLAG_BURST)) {
		acpi_hw_low_level_write(8, ACPI_EC_BURST_ENABLE,
					&ec->common.command_addr);
		status = acpi_ec_wait(ec, ACPI_EC_EVENT_OBF);
		if (status)
			goto end;
		acpi_hw_low_level_read(8, &tmp, &ec->common.data_addr);
		if (tmp != 0x90)	/* Burst ACK byte */
			goto end;
	status = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE);
	if (status) {
		printk("write EC, IB not empty\n");
	}
	/*Now we are in burst mode */

	acpi_hw_low_level_write(8, ACPI_EC_COMMAND_WRITE,
				&ec->common.command_addr);
	status = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE);
	acpi_enable_gpe(NULL, ec->common.gpe_bit, ACPI_NOT_ISR);
	if (status) {
		goto end;
		printk("write EC, IB not empty\n");
	}

	acpi_hw_low_level_write(8, address, &ec->common.data_addr);
	status = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE);
	if (status) {
		acpi_enable_gpe(NULL, ec->common.gpe_bit, ACPI_NOT_ISR);
		goto end;
		printk("write EC, IB not empty\n");
	}

	acpi_hw_low_level_write(8, data, &ec->common.data_addr);
	status = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE);
	acpi_enable_gpe(NULL, ec->common.gpe_bit, ACPI_NOT_ISR);
	if (status)
		goto end;

	ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Wrote [%02x] to address [%02x]\n",
			  data, address));

      end:
	acpi_ec_leave_burst_mode(ec);
	up(&ec->burst.sem);

	if (ec->common.global_lock)
		acpi_release_global_lock(glk);

	if (atomic_read(&ec->burst.leaving_burst) == 2) {
		ACPI_DEBUG_PRINT((ACPI_DB_INFO, "aborted, retry ...\n"));
		while (atomic_read(&ec->burst.pending_gpe)) {
			msleep(1);
		}
		acpi_enable_gpe(NULL, ec->common.gpe_bit, ACPI_NOT_ISR);
		goto retry;
	}

	return_VALUE(status);
}

@@ -662,8 +621,12 @@ static int acpi_ec_burst_query(union acpi_ec *ec, u32 * data)
	}

	down(&ec->burst.sem);
	if (acpi_ec_enter_burst_mode(ec))

	status = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE);
	if (status) {
		printk("query EC, IB not empty\n");
		goto end;
	}
	/*
	 * 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
@@ -673,27 +636,20 @@ static int acpi_ec_burst_query(union acpi_ec *ec, u32 * data)
				&ec->common.command_addr);
	status = acpi_ec_wait(ec, ACPI_EC_EVENT_OBF);
	if (status) {
		acpi_enable_gpe(NULL, ec->common.gpe_bit, ACPI_NOT_ISR);
		printk("query EC, OB not full\n");
		goto end;
	}

	acpi_hw_low_level_read(8, data, &ec->common.data_addr);
	acpi_enable_gpe(NULL, ec->common.gpe_bit, ACPI_NOT_ISR);
	if (!*data)
		status = -ENODATA;

      end:
	acpi_ec_leave_burst_mode(ec);
	up(&ec->burst.sem);

	if (ec->common.global_lock)
		acpi_release_global_lock(glk);

	if (atomic_read(&ec->burst.leaving_burst) == 2) {
		ACPI_DEBUG_PRINT((ACPI_DB_INFO, "aborted, retry ...\n"));
		acpi_enable_gpe(NULL, ec->common.gpe_bit, ACPI_NOT_ISR);
		status = -ENODATA;
	}
	return_VALUE(status);
}

@@ -818,31 +774,21 @@ static u32 acpi_ec_gpe_burst_handler(void *data)
	if (!ec)
		return ACPI_INTERRUPT_NOT_HANDLED;

	acpi_disable_gpe(NULL, ec->common.gpe_bit, ACPI_ISR);

	acpi_clear_gpe(NULL, ec->common.gpe_bit, ACPI_ISR);
	value = acpi_ec_read_status(ec);

	if ((value & ACPI_EC_FLAG_IBF) &&
	    !(value & ACPI_EC_FLAG_BURST) &&
	    (atomic_read(&ec->burst.leaving_burst) == 0)) {
		/*
		 * the embedded controller disables 
		 * burst mode for any reason other 
		 * than the burst disable command
		 * to process critical event.
		 */
		atomic_set(&ec->burst.leaving_burst, 2);	/* block current pending transaction
								   and retry */
		wake_up(&ec->burst.wait);
	} else {
		if ((ec->burst.expect_event == ACPI_EC_EVENT_OBF &&
		     (value & ACPI_EC_FLAG_OBF)) ||
		    (ec->burst.expect_event == ACPI_EC_EVENT_IBE &&
		     !(value & ACPI_EC_FLAG_IBF))) {
	switch (ec->burst.expect_event) {
	case ACPI_EC_EVENT_OBF:
		if (!(value & ACPI_EC_FLAG_OBF))
			break;
	case ACPI_EC_EVENT_IBE:
		if ((value & ACPI_EC_FLAG_IBF))
			break;
		ec->burst.expect_event = 0;
		wake_up(&ec->burst.wait);
		return ACPI_INTERRUPT_HANDLED;
		}
	default:
		break;
	}

	if (value & ACPI_EC_FLAG_SCI) {
@@ -1166,6 +1112,7 @@ static int acpi_ec_burst_add(struct acpi_device *device)
	if (result)
		goto end;

	printk("burst-mode-ec-10-Aug\n");
	printk(KERN_INFO PREFIX "%s [%s] (gpe %d)\n",
	       acpi_device_name(device), acpi_device_bid(device),
	       (u32) ec->common.gpe_bit);