diff options
Diffstat (limited to 'drivers/acpi/ec.c')
| -rw-r--r-- | drivers/acpi/ec.c | 420 | 
1 files changed, 288 insertions, 132 deletions
| diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c index fdf143b405be..8e665f2e3138 100644 --- a/drivers/acpi/ec.c +++ b/drivers/acpi/ec.c @@ -31,6 +31,7 @@  #include <linux/delay.h>  #include <linux/proc_fs.h>  #include <linux/seq_file.h> +#include <linux/interrupt.h>  #include <asm/io.h>  #include <acpi/acpi_bus.h>  #include <acpi/acpi_drivers.h> @@ -49,17 +50,19 @@ ACPI_MODULE_NAME		("acpi_ec")  #define ACPI_EC_FLAG_OBF	0x01	/* Output buffer full */  #define ACPI_EC_FLAG_IBF	0x02	/* Input buffer full */ +#define ACPI_EC_FLAG_BURST	0x10	/* burst mode */  #define ACPI_EC_FLAG_SCI	0x20	/* EC-SCI occurred */  #define ACPI_EC_EVENT_OBF	0x01	/* Output buffer full */  #define ACPI_EC_EVENT_IBE	0x02	/* Input buffer empty */ -#define ACPI_EC_UDELAY		100	/* Poll @ 100us increments */ -#define ACPI_EC_UDELAY_COUNT	1000	/* Wait 10ms max. during EC ops */ +#define ACPI_EC_DELAY		50	/* Wait 50ms max. during EC ops */  #define ACPI_EC_UDELAY_GLK	1000	/* Wait 1ms max. to get global lock */  #define ACPI_EC_COMMAND_READ	0x80  #define ACPI_EC_COMMAND_WRITE	0x81 +#define ACPI_EC_BURST_ENABLE	0x82 +#define ACPI_EC_BURST_DISABLE	0x83  #define ACPI_EC_COMMAND_QUERY	0x84  static int acpi_ec_add (struct acpi_device *device); @@ -87,7 +90,11 @@ struct acpi_ec {  	struct acpi_generic_address	command_addr;  	struct acpi_generic_address	data_addr;  	unsigned long			global_lock; -	spinlock_t			lock; +	unsigned int			expect_event; +	atomic_t			leaving_burst; /* 0 : No, 1 : Yes, 2: abort*/ +	atomic_t			pending_gpe; +	struct semaphore		sem; +	wait_queue_head_t		wait;  };  /* If we find an EC via the ECDT, we need to keep a ptr to its context */ @@ -100,42 +107,122 @@ static struct acpi_device *first_ec;                               Transaction Management     -------------------------------------------------------------------------- */ -static int -acpi_ec_wait ( -	struct acpi_ec		*ec, -	u8			event) +static inline u32 acpi_ec_read_status(struct acpi_ec *ec)  { -	u32			acpi_ec_status = 0; -	u32			i = ACPI_EC_UDELAY_COUNT; +	u32	status = 0; -	if (!ec) -		return -EINVAL; +	acpi_hw_low_level_read(8, &status, &ec->status_addr); +	return status; +} + +static int acpi_ec_wait(struct acpi_ec *ec, unsigned int event) +{ +	int	result = 0; + +	ACPI_FUNCTION_TRACE("acpi_ec_wait"); -	/* Poll the EC status register waiting for the event to occur. */ +	ec->expect_event = event; +	smp_mb(); + +	result = wait_event_interruptible_timeout(ec->wait, +					!ec->expect_event, +					msecs_to_jiffies(ACPI_EC_DELAY)); +	 +	ec->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 +	 * to make sure that we did not miss interrupt. +	 */  	switch (event) {  	case ACPI_EC_EVENT_OBF: -		do { -			acpi_hw_low_level_read(8, &acpi_ec_status, &ec->status_addr); -			if (acpi_ec_status & ACPI_EC_FLAG_OBF) -				return 0; -			udelay(ACPI_EC_UDELAY); -		} while (--i>0); +		if (acpi_ec_read_status(ec) & ACPI_EC_FLAG_OBF) +			return_VALUE(0);  		break; +  	case ACPI_EC_EVENT_IBE: -		do { -			acpi_hw_low_level_read(8, &acpi_ec_status, &ec->status_addr); -			if (!(acpi_ec_status & ACPI_EC_FLAG_IBF)) -				return 0; -			udelay(ACPI_EC_UDELAY); -		} while (--i>0); +		if (~acpi_ec_read_status(ec) & ACPI_EC_FLAG_IBF) +			return_VALUE(0);  		break; -	default: -		return -EINVAL;  	} -	return -ETIME; +	return_VALUE(-ETIME); +} + + + +static int +acpi_ec_enter_burst_mode ( +	struct acpi_ec		*ec) +{ +	u32			tmp = 0; +	int			status = 0; + +	ACPI_FUNCTION_TRACE("acpi_ec_enter_burst_mode"); + +	status = acpi_ec_read_status(ec); +	if (status != -EINVAL && +		!(status & ACPI_EC_FLAG_BURST)){ +		ACPI_DEBUG_PRINT((ACPI_DB_INFO,"entering burst mode \n")); +		acpi_hw_low_level_write(8, ACPI_EC_BURST_ENABLE, &ec->command_addr); +		status = acpi_ec_wait(ec, ACPI_EC_EVENT_OBF); +		if (status){ +			acpi_enable_gpe(NULL, ec->gpe_bit, ACPI_NOT_ISR); +			ACPI_DEBUG_PRINT((ACPI_DB_ERROR," status = %d\n", status)); +			return_VALUE(-EINVAL); +		} +		acpi_hw_low_level_read(8, &tmp, &ec->data_addr); +		acpi_enable_gpe(NULL, ec->gpe_bit, ACPI_NOT_ISR); +		if(tmp != 0x90 ) {/* Burst ACK byte*/ +			ACPI_DEBUG_PRINT((ACPI_DB_ERROR,"Ack failed \n")); +			return_VALUE(-EINVAL); +		} +	} else +		ACPI_DEBUG_PRINT((ACPI_DB_INFO,"already be in burst mode \n")); +	atomic_set(&ec->leaving_burst , 0); +	return_VALUE(0);  } +static int +acpi_ec_leave_burst_mode ( +	struct acpi_ec		*ec) +{ +	int			status =0; + +	ACPI_FUNCTION_TRACE("acpi_ec_leave_burst_mode"); + +	atomic_set(&ec->leaving_burst , 1); +	status = acpi_ec_read_status(ec); +	if (status != -EINVAL && +		(status & ACPI_EC_FLAG_BURST)){ +		ACPI_DEBUG_PRINT((ACPI_DB_INFO,"leaving burst mode\n")); +		acpi_hw_low_level_write(8, ACPI_EC_BURST_DISABLE, &ec->command_addr); +		status = acpi_ec_wait(ec, ACPI_EC_FLAG_IBF); +		if (status){ +			acpi_enable_gpe(NULL, ec->gpe_bit, ACPI_NOT_ISR); +			ACPI_DEBUG_PRINT((ACPI_DB_ERROR,"------->wait fail\n")); +			return_VALUE(-EINVAL); +		} +		acpi_enable_gpe(NULL, ec->gpe_bit, ACPI_NOT_ISR); +		status = acpi_ec_read_status(ec); +		if (status != -EINVAL && +			(status & ACPI_EC_FLAG_BURST)) { +			ACPI_DEBUG_PRINT((ACPI_DB_ERROR,"------->status fail\n")); +			return_VALUE(-EINVAL); +		} +	}else +		ACPI_DEBUG_PRINT((ACPI_DB_INFO,"already be in Non-burst mode \n")); +	ACPI_DEBUG_PRINT((ACPI_DB_INFO,"leaving burst mode\n")); + +	return_VALUE(0); +}  static int  acpi_ec_read ( @@ -143,16 +230,15 @@ acpi_ec_read (  	u8			address,  	u32			*data)  { -	acpi_status		status = AE_OK; -	int			result = 0; -	unsigned long		flags = 0; -	u32			glk = 0; +	int			status = 0; +	u32			glk;  	ACPI_FUNCTION_TRACE("acpi_ec_read");  	if (!ec || !data)  		return_VALUE(-EINVAL); +retry:  	*data = 0;  	if (ec->global_lock) { @@ -160,32 +246,50 @@ acpi_ec_read (  		if (ACPI_FAILURE(status))  			return_VALUE(-ENODEV);  	} -	 -	spin_lock_irqsave(&ec->lock, flags); + +	WARN_ON(in_interrupt()); +	down(&ec->sem); + +	if(acpi_ec_enter_burst_mode(ec)) +		goto end;  	acpi_hw_low_level_write(8, ACPI_EC_COMMAND_READ, &ec->command_addr); -	result = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE); -	if (result) +	status = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE); +	acpi_enable_gpe(NULL, ec->gpe_bit, ACPI_NOT_ISR); +	if (status) {  		goto end; +	}  	acpi_hw_low_level_write(8, address, &ec->data_addr); -	result = acpi_ec_wait(ec, ACPI_EC_EVENT_OBF); -	if (result) +	status= acpi_ec_wait(ec, ACPI_EC_EVENT_OBF); +	if (status){ +		acpi_enable_gpe(NULL, ec->gpe_bit, ACPI_NOT_ISR);  		goto end; - +	}  	acpi_hw_low_level_read(8, data, &ec->data_addr); +	acpi_enable_gpe(NULL, ec->gpe_bit, ACPI_NOT_ISR);  	ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Read [%02x] from address [%02x]\n",  		*data, address)); - +	  end: -	spin_unlock_irqrestore(&ec->lock, flags); +	acpi_ec_leave_burst_mode(ec); +	up(&ec->sem);  	if (ec->global_lock)  		acpi_release_global_lock(glk); -	return_VALUE(result); +	if(atomic_read(&ec->leaving_burst) == 2){ +		ACPI_DEBUG_PRINT((ACPI_DB_INFO,"aborted, retry ...\n")); +		while(atomic_read(&ec->pending_gpe)){ +			msleep(1);	 +		} +		acpi_enable_gpe(NULL, ec->gpe_bit, ACPI_NOT_ISR); +		goto retry; +	} + +	return_VALUE(status);  } @@ -195,49 +299,80 @@ acpi_ec_write (  	u8			address,  	u8			data)  { -	int			result = 0; -	acpi_status		status = AE_OK; -	unsigned long		flags = 0; -	u32			glk = 0; +	int			status = 0; +	u32			glk; +	u32			tmp;  	ACPI_FUNCTION_TRACE("acpi_ec_write");  	if (!ec)  		return_VALUE(-EINVAL); - +retry:  	if (ec->global_lock) {  		status = acpi_acquire_global_lock(ACPI_EC_UDELAY_GLK, &glk);  		if (ACPI_FAILURE(status))  			return_VALUE(-ENODEV);  	} -	spin_lock_irqsave(&ec->lock, flags); +	WARN_ON(in_interrupt()); +	down(&ec->sem); + +	if(acpi_ec_enter_burst_mode(ec)) +		goto end; + +	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->command_addr); +		status = acpi_ec_wait(ec, ACPI_EC_EVENT_OBF); +		if (status) +			goto end; +		acpi_hw_low_level_read(8, &tmp, &ec->data_addr); +		if(tmp != 0x90 ) /* Burst ACK byte*/ +			goto end; +	} +	/*Now we are in burst mode*/  	acpi_hw_low_level_write(8, ACPI_EC_COMMAND_WRITE, &ec->command_addr); -	result = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE); -	if (result) +	status = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE); +	acpi_enable_gpe(NULL, ec->gpe_bit, ACPI_NOT_ISR); +	if (status){  		goto end; +	}  	acpi_hw_low_level_write(8, address, &ec->data_addr); -	result = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE); -	if (result) +	status = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE); +	if (status){ +		acpi_enable_gpe(NULL, ec->gpe_bit, ACPI_NOT_ISR);  		goto end; +	}  	acpi_hw_low_level_write(8, data, &ec->data_addr); -	result = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE); -	if (result) +	status = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE); +	acpi_enable_gpe(NULL, ec->gpe_bit, ACPI_NOT_ISR); +	if (status)  		goto end;  	ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Wrote [%02x] to address [%02x]\n",  		data, address));  end: -	spin_unlock_irqrestore(&ec->lock, flags); +	acpi_ec_leave_burst_mode(ec); +	up(&ec->sem);  	if (ec->global_lock)  		acpi_release_global_lock(glk); -	return_VALUE(result); +	if(atomic_read(&ec->leaving_burst) == 2){ +		ACPI_DEBUG_PRINT((ACPI_DB_INFO,"aborted, retry ...\n")); +		while(atomic_read(&ec->pending_gpe)){ +			msleep(1);	 +		} +		acpi_enable_gpe(NULL, ec->gpe_bit, ACPI_NOT_ISR); +		goto retry; +	} + +	return_VALUE(status);  }  /* @@ -289,16 +424,13 @@ acpi_ec_query (  	struct acpi_ec		*ec,  	u32			*data)  { -	int			result = 0; -	acpi_status		status = AE_OK; -	unsigned long		flags = 0; -	u32			glk = 0; +	int			status = 0; +	u32			glk;  	ACPI_FUNCTION_TRACE("acpi_ec_query");  	if (!ec || !data)  		return_VALUE(-EINVAL); -  	*data = 0;  	if (ec->global_lock) { @@ -307,29 +439,39 @@ acpi_ec_query (  			return_VALUE(-ENODEV);  	} +	down(&ec->sem); +	if(acpi_ec_enter_burst_mode(ec)) +		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  	 * bit to be cleared (and thus clearing the interrupt source).  	 */ -	spin_lock_irqsave(&ec->lock, flags); -  	acpi_hw_low_level_write(8, ACPI_EC_COMMAND_QUERY, &ec->command_addr); -	result = acpi_ec_wait(ec, ACPI_EC_EVENT_OBF); -	if (result) +	status = acpi_ec_wait(ec, ACPI_EC_EVENT_OBF); +	if (status){ +		acpi_enable_gpe(NULL, ec->gpe_bit, ACPI_NOT_ISR);  		goto end; -	 +	} +  	acpi_hw_low_level_read(8, data, &ec->data_addr); +	acpi_enable_gpe(NULL, ec->gpe_bit, ACPI_NOT_ISR);  	if (!*data) -		result = -ENODATA; +		status = -ENODATA;  end: -	spin_unlock_irqrestore(&ec->lock, flags); +	acpi_ec_leave_burst_mode(ec); +	up(&ec->sem);  	if (ec->global_lock)  		acpi_release_global_lock(glk); -	return_VALUE(result); +	if(atomic_read(&ec->leaving_burst) == 2){ +		ACPI_DEBUG_PRINT((ACPI_DB_INFO,"aborted, retry ...\n")); +		acpi_enable_gpe(NULL, ec->gpe_bit, ACPI_NOT_ISR); +		status = -ENODATA; +	} +	return_VALUE(status);  } @@ -347,42 +489,29 @@ acpi_ec_gpe_query (  	void			*ec_cxt)  {  	struct acpi_ec		*ec = (struct acpi_ec *) ec_cxt; -	u32			value = 0; -	unsigned long		flags = 0; +	u32			value; +	int			result = -ENODATA;  	static char		object_name[5] = {'_','Q','0','0','\0'};  	const char		hex[] = {'0','1','2','3','4','5','6','7',  				         '8','9','A','B','C','D','E','F'};  	ACPI_FUNCTION_TRACE("acpi_ec_gpe_query"); -	if (!ec_cxt) -		goto end;	 - -	spin_lock_irqsave(&ec->lock, flags); -	acpi_hw_low_level_read(8, &value, &ec->command_addr); -	spin_unlock_irqrestore(&ec->lock, flags); +	if (acpi_ec_read_status(ec) & ACPI_EC_FLAG_SCI) +		result = acpi_ec_query(ec, &value); -	/* TBD: Implement asynch events! -	 * NOTE: All we care about are EC-SCI's.  Other EC events are -	 * handled via polling (yuck!).  This is because some systems -	 * treat EC-SCIs as level (versus EDGE!) triggered, preventing -	 *  a purely interrupt-driven approach (grumble, grumble). -	 */ -	if (!(value & ACPI_EC_FLAG_SCI)) +	if (result)  		goto end; -	if (acpi_ec_query(ec, &value)) -		goto end; -	  	object_name[2] = hex[((value >> 4) & 0x0F)];  	object_name[3] = hex[(value & 0x0F)];  	ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Evaluating %s\n", object_name));  	acpi_evaluate_object(ec->handle, object_name, NULL, NULL); - -end: -	acpi_enable_gpe(NULL, ec->gpe_bit, ACPI_NOT_ISR); +end:	 +	atomic_dec(&ec->pending_gpe); +	return;  }  static u32 @@ -390,6 +519,7 @@ acpi_ec_gpe_handler (  	void			*data)  {  	acpi_status		status = AE_OK; +	u32			value;  	struct acpi_ec		*ec = (struct acpi_ec *) data;  	if (!ec) @@ -397,13 +527,41 @@ acpi_ec_gpe_handler (  	acpi_disable_gpe(NULL, ec->gpe_bit, ACPI_ISR); -	status = acpi_os_queue_for_execution(OSD_PRIORITY_GPE, -		acpi_ec_gpe_query, ec); +	value = acpi_ec_read_status(ec); -	if (status == AE_OK) -		return ACPI_INTERRUPT_HANDLED; -	else -		return ACPI_INTERRUPT_NOT_HANDLED; +	if((value & ACPI_EC_FLAG_IBF) && +		!(value & ACPI_EC_FLAG_BURST) && +			(atomic_read(&ec->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->leaving_burst , 2); /* block current pending transaction +					and retry */ +		wake_up(&ec->wait); +	}else { +		if ((ec->expect_event == ACPI_EC_EVENT_OBF && +				(value & ACPI_EC_FLAG_OBF)) || +	    			(ec->expect_event == ACPI_EC_EVENT_IBE && +				!(value & ACPI_EC_FLAG_IBF))) { +			ec->expect_event = 0; +			wake_up(&ec->wait); +			return ACPI_INTERRUPT_HANDLED; +		} +	} + +	if (value & ACPI_EC_FLAG_SCI){ +		atomic_add(1, &ec->pending_gpe) ; +		status = acpi_os_queue_for_execution(OSD_PRIORITY_GPE, +						acpi_ec_gpe_query, ec); +		return status == AE_OK ? +		ACPI_INTERRUPT_HANDLED : ACPI_INTERRUPT_NOT_HANDLED; +	}  +	acpi_enable_gpe(NULL, ec->gpe_bit, ACPI_ISR); +	return status == AE_OK ? +		ACPI_INTERRUPT_HANDLED : ACPI_INTERRUPT_NOT_HANDLED;  }  /* -------------------------------------------------------------------------- @@ -421,10 +579,8 @@ acpi_ec_space_setup (  	 * The EC object is in the handler context and is needed  	 * when calling the acpi_ec_space_handler.  	 */ -	if(function == ACPI_REGION_DEACTIVATE)  -		*return_context = NULL; -	else  -		*return_context = handler_context; +	*return_context  = (function != ACPI_REGION_DEACTIVATE) ? +						handler_context : NULL;  	return AE_OK;  } @@ -441,7 +597,7 @@ acpi_ec_space_handler (  {  	int			result = 0;  	struct acpi_ec		*ec = NULL; -	u32			temp = 0; +	u64			temp = *value;  	acpi_integer		f_v = 0;  	int 			i = 0; @@ -450,10 +606,9 @@ acpi_ec_space_handler (  	if ((address > 0xFF) || !value || !handler_context)  		return_VALUE(AE_BAD_PARAMETER); -	if(bit_width != 8) { +	if (bit_width != 8 && acpi_strict) {  		printk(KERN_WARNING PREFIX "acpi_ec_space_handler: bit_width should be 8\n"); -		if (acpi_strict) -			return_VALUE(AE_BAD_PARAMETER); +		return_VALUE(AE_BAD_PARAMETER);  	}  	ec = (struct acpi_ec *) handler_context; @@ -461,11 +616,11 @@ acpi_ec_space_handler (  next_byte:  	switch (function) {  	case ACPI_READ: -		result = acpi_ec_read(ec, (u8) address, &temp); -		*value = (acpi_integer) temp; +		temp = 0; +		result = acpi_ec_read(ec, (u8) address, (u32 *)&temp);  		break;  	case ACPI_WRITE: -		result = acpi_ec_write(ec, (u8) address, (u8) *value); +		result = acpi_ec_write(ec, (u8) address, (u8) temp);  		break;  	default:  		result = -EINVAL; @@ -474,19 +629,18 @@ next_byte:  	}  	bit_width -= 8; -	if(bit_width){ - -		if(function == ACPI_READ) -			f_v |= (acpi_integer) (*value) << 8*i; -		if(function == ACPI_WRITE) -			(*value) >>=8;  +	if (bit_width) { +		if (function == ACPI_READ) +			f_v |= temp << 8 * i; +		if (function == ACPI_WRITE) +			temp >>= 8;  		i++; +		address++;  		goto next_byte;  	} - -	if(function == ACPI_READ){ -		f_v |= (acpi_integer) (*value) << 8*i; +	if (function == ACPI_READ) { +		f_v |= temp << 8 * i;  		*value = f_v;  	} @@ -505,8 +659,6 @@ out:  	default:  		return_VALUE(AE_OK);  	} -	 -  } @@ -533,6 +685,7 @@ acpi_ec_read_info (struct seq_file *seq, void *offset)  		(u32) ec->status_addr.address, (u32) ec->data_addr.address);  	seq_printf(seq, "use global lock:         %s\n",  		ec->global_lock?"yes":"no"); +	acpi_enable_gpe(NULL, ec->gpe_bit, ACPI_NOT_ISR);  end:  	return_VALUE(0); @@ -555,7 +708,7 @@ static int  acpi_ec_add_fs (  	struct acpi_device	*device)  { -	struct proc_dir_entry	*entry = NULL; +	struct proc_dir_entry	*entry;  	ACPI_FUNCTION_TRACE("acpi_ec_add_fs"); @@ -606,9 +759,9 @@ static int  acpi_ec_add (  	struct acpi_device	*device)  { -	int			result = 0; -	acpi_status		status = AE_OK; -	struct acpi_ec		*ec = NULL; +	int			result; +	acpi_status		status; +	struct acpi_ec		*ec;  	unsigned long		uid;  	ACPI_FUNCTION_TRACE("acpi_ec_add"); @@ -623,7 +776,10 @@ acpi_ec_add (  	ec->handle = device->handle;  	ec->uid = -1; -	spin_lock_init(&ec->lock); + 	atomic_set(&ec->pending_gpe, 0); + 	atomic_set(&ec->leaving_burst , 1); + 	init_MUTEX(&ec->sem); + 	init_waitqueue_head(&ec->wait);  	strcpy(acpi_device_name(device), ACPI_EC_DEVICE_NAME);  	strcpy(acpi_device_class(device), ACPI_EC_CLASS);  	acpi_driver_data(device) = ec; @@ -637,7 +793,7 @@ acpi_ec_add (  	if (ec_ecdt && ec_ecdt->uid == uid) {  		acpi_remove_address_space_handler(ACPI_ROOT_OBJECT,  			ACPI_ADR_SPACE_EC, &acpi_ec_space_handler); -	 +  		acpi_remove_gpe_handler(NULL, ec_ecdt->gpe_bit, &acpi_ec_gpe_handler);  		kfree(ec_ecdt); @@ -677,7 +833,7 @@ acpi_ec_remove (  	struct acpi_device	*device,  	int			type)  { -	struct acpi_ec		*ec = NULL; +	struct acpi_ec		*ec;  	ACPI_FUNCTION_TRACE("acpi_ec_remove"); @@ -732,8 +888,8 @@ static int  acpi_ec_start (  	struct acpi_device	*device)  { -	acpi_status		status = AE_OK; -	struct acpi_ec		*ec = NULL; +	acpi_status		status; +	struct acpi_ec		*ec;  	ACPI_FUNCTION_TRACE("acpi_ec_start"); @@ -789,8 +945,8 @@ acpi_ec_stop (  	struct acpi_device	*device,  	int			type)  { -	acpi_status		status = AE_OK; -	struct acpi_ec		*ec = NULL; +	acpi_status		status; +	struct acpi_ec		*ec;  	ACPI_FUNCTION_TRACE("acpi_ec_stop"); @@ -832,7 +988,6 @@ acpi_fake_ecdt_callback (  	status = acpi_evaluate_integer(handle, "_GPE", NULL, &ec_ecdt->gpe_bit);  	if (ACPI_FAILURE(status))  		return status; -	spin_lock_init(&ec_ecdt->lock);  	ec_ecdt->global_lock = TRUE;  	ec_ecdt->handle = handle; @@ -890,7 +1045,7 @@ acpi_ec_get_real_ecdt(void)  	acpi_status		status;  	struct acpi_table_ecdt 	*ecdt_ptr; -	status = acpi_get_firmware_table("ECDT", 1, ACPI_LOGICAL_ADDRESSING,  +	status = acpi_get_firmware_table("ECDT", 1, ACPI_LOGICAL_ADDRESSING,  		(struct acpi_table_header **) &ecdt_ptr);  	if (ACPI_FAILURE(status))  		return -ENODEV; @@ -905,11 +1060,12 @@ acpi_ec_get_real_ecdt(void)  		return -ENOMEM;  	memset(ec_ecdt, 0, sizeof(struct acpi_ec)); + 	init_MUTEX(&ec_ecdt->sem); + 	init_waitqueue_head(&ec_ecdt->wait);  	ec_ecdt->command_addr = ecdt_ptr->ec_control;  	ec_ecdt->status_addr = ecdt_ptr->ec_control;  	ec_ecdt->data_addr = ecdt_ptr->ec_data;  	ec_ecdt->gpe_bit = ecdt_ptr->gpe_bit; -	spin_lock_init(&ec_ecdt->lock);  	/* use the GL just to be safe */  	ec_ecdt->global_lock = TRUE;  	ec_ecdt->uid = ecdt_ptr->uid; @@ -978,7 +1134,7 @@ error:  static int __init acpi_ec_init (void)  { -	int			result = 0; +	int			result;  	ACPI_FUNCTION_TRACE("acpi_ec_init"); | 
