public inbox for linux-acpi@vger.kernel.org
 help / color / mirror / Atom feed
* RE: [PATCH] Don't disable interrupts during EC access
@ 2004-11-17  7:10 Li, Shaohua
       [not found] ` <16A54BF5D6E14E4D916CE26C9AD305758EF9BD-4yWAQGcml66iAffOGbnezLfspsVTdybXVpNB7YpNyf8@public.gmane.org>
  0 siblings, 1 reply; 16+ messages in thread
From: Li, Shaohua @ 2004-11-17  7:10 UTC (permalink / raw)
  To: Dmitry Torokhov, acpi-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f
  Cc: Andi Kleen, Yu, Luming, Matthew Wilcox, Fu, Michael, Brown, Len,
	Moore, Robert

>On Tuesday 16 November 2004 10:37 am, Andi Kleen wrote:
>> > For detail, please refer to ACPI spec :
>> > 12 ? ACPI Embedded Controller Interface Specification.
>>
>> Ok. But the problem is not the actual write, but the waiting
>> for the event which takes extremly long on these machines
>> (it's not a single broken machine, but has been observed
>> on several VIA based laptops). Would it work to only disable
>> interrupts during the register write/read, but not during the
>> polling delay?
>
>Actually, the proper solution would be to get rid of polling entirely,
>like in the patch below. Could anyone with a box with EC verify that
>it works?
>
>Btw, what's up with initializing every variable in ACPI code? It is
>not free after all...
>
I agree the right solution should be to stop polling, but did you look
at the comments in ec.c (line 361)? It said some systems can't work with
asynchronous mode.

Thanks,
Shaohua


-------------------------------------------------------
This SF.Net email is sponsored by: InterSystems CACHE
FREE OODBMS DOWNLOAD - A multidimensional database that combines
robust object and relational technologies, making it a perfect match
for Java, C++,COM, XML, ODBC and JDBC. www.intersystems.com/match8

^ permalink raw reply	[flat|nested] 16+ messages in thread
* RE: [PATCH] Don't disable interrupts during EC access
@ 2004-11-17  7:46 Yu, Luming
  2004-11-17  8:02 ` Dmitry Torokhov
  0 siblings, 1 reply; 16+ messages in thread
From: Yu, Luming @ 2004-11-17  7:46 UTC (permalink / raw)
  To: Li, Shaohua, Dmitry Torokhov,
	acpi-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f
  Cc: Andi Kleen, Matthew Wilcox, Fu, Michael, Brown, Len,
	Moore, Robert

Spec defined EC-SCI is edge-trigged.
So, I think that is solution sticking with Spec.
Not sure, how many laptop break this rule.

If  wait_event_interruptible_timeout  returns due to timeout,
Can we think it of polling timeout?

So, I suggest Dmitry to complete  that to include
level-trigged situation.

Thanks
Luming 

>-----Original Message-----
>From: Li, Shaohua 
>Sent: 2004年11月17日 15:10
>To: Dmitry Torokhov; acpi-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f@public.gmane.org
>Cc: Andi Kleen; Yu, Luming; Matthew Wilcox; Fu, Michael; 
>Brown, Len; Moore, Robert
>Subject: RE: [ACPI] [PATCH] Don't disable interrupts during EC access
>
>>On Tuesday 16 November 2004 10:37 am, Andi Kleen wrote:
>>> > For detail, please refer to ACPI spec :
>>> > 12 ? ACPI Embedded Controller Interface Specification.
>>>
>>> Ok. But the problem is not the actual write, but the waiting
>>> for the event which takes extremly long on these machines
>>> (it's not a single broken machine, but has been observed
>>> on several VIA based laptops). Would it work to only disable
>>> interrupts during the register write/read, but not during the
>>> polling delay?
>>
>>Actually, the proper solution would be to get rid of polling entirely,
>>like in the patch below. Could anyone with a box with EC verify that
>>it works?
>>
>>Btw, what's up with initializing every variable in ACPI code? It is
>>not free after all...
>>
>I agree the right solution should be to stop polling, but did 
>you look at the comments in ec.c (line 361)? It said some 
>systems can't work with asynchronous mode.
>
>Thanks,
>Shaohua
>


-------------------------------------------------------
This SF.Net email is sponsored by: InterSystems CACHE
FREE OODBMS DOWNLOAD - A multidimensional database that combines
robust object and relational technologies, making it a perfect match
for Java, C++,COM, XML, ODBC and JDBC. www.intersystems.com/match8

^ permalink raw reply	[flat|nested] 16+ messages in thread
* RE: [PATCH] Don't disable interrupts during EC access
@ 2004-11-17  6:12 Yu, Luming
  0 siblings, 0 replies; 16+ messages in thread
From: Yu, Luming @ 2004-11-17  6:12 UTC (permalink / raw)
  To: Andi Kleen
  Cc: Matthew Wilcox, acpi-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f,
	Fu, Michael, Brown, Len, Moore, Robert

>Another possible way would be to only disable the ACPI interrupt
>in the local APIC and keep the others alive  (but what to do 
>in PIC mode?) 

Disable EC GPE in your patch could achieve the goal.

Thanks,
Luming


-------------------------------------------------------
This SF.Net email is sponsored by: InterSystems CACHE
FREE OODBMS DOWNLOAD - A multidimensional database that combines
robust object and relational technologies, making it a perfect match
for Java, C++,COM, XML, ODBC and JDBC. www.intersystems.com/match8

^ permalink raw reply	[flat|nested] 16+ messages in thread
* RE: [PATCH] Don't disable interrupts during EC access
@ 2004-11-16 15:41 Yu, Luming
  0 siblings, 0 replies; 16+ messages in thread
From: Yu, Luming @ 2004-11-16 15:41 UTC (permalink / raw)
  To: Yu, Luming, Andi Kleen, Matthew Wilcox
  Cc: acpi-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f, Fu, Michael,
	Brown, Len, Moore, Robert

  I forget one thing that could make me feel frustrated.
  There is a user outside of ACPI driver, that is sonypi_ec_read,
which can be invoked by sonypi_misc_ioctl, which haven't
disable EC-GPE. :-)
  If everything is handled by kacpid. I even think semaphore
is also unnecessary. Because every thing is run in the order
of a queue. :-)

Thanks
Luming 

>-----Original Message-----
>From: acpi-devel-admin-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f@public.gmane.org 
>[mailto:acpi-devel-admin-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f@public.gmane.org] On Behalf Of Yu, Luming
>Sent: 2004年11月16日 23:21
>To: Andi Kleen; Matthew Wilcox
>Cc: acpi-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f@public.gmane.org; Fu, Michael; Brown, Len; 
>Moore, Robert
>Subject: RE: [ACPI] [PATCH] Don't disable interrupts during EC access
>
>>On Tue, Nov 16, 2004 at 12:16:16PM +0000, Matthew Wilcox wrote:
>>> On Tue, Nov 16, 2004 at 02:15:47PM +0800, Yu, Luming wrote:
>>> > Andi,
>>> > 
>>> > This patch seems to break the atomic operation.
>>> > The original code enclosed by 
>>spin_lock_irqsave/spin_unlock_irqresotre is trying to make 
>>sure the first operation to EC_COMMAND
>>> > register , and the second operation to EC_DATA register 
>>belong to one atomic transaction.
>>> 
>>> Why would converting from a spinlock to a semaphore break this?
>>
>>As Willy said the operation should be still atomic in respect to
>>the register.
>
>It is just due to odd hardware behavior.  :-)
>For example, if you want to read data from EC.  The first step
>is writing 0x80 (read command) to ec command register.
>Then, if EC (hardware) write data into the output buffer, the
>output buffer flag (OBF) in the status register is set.
>(I assume it is within 1ms). According to ACPI spec,
>now, EC interrupt will get triggered. And this is
>firmware generated edge interrupt. It will hold until OBF get reset.
>When the host processor reads this data from the output buffer, 
>the OBF can be reset.
>
>So, if you remove the spin_lock_irqsave, when OBF is set
>you could get interrupt storm.  
>
>For detail, please refer to ACPI spec :
>12   ACPI Embedded Controller Interface Specification.
>
>>
>>And the event polling can take several ms, there is just no way 
>>to do this during runtime with interrupts off. Especially since
>>thermal will do this every few seconds. With my patch at least 
>>only kacpid is blocked for that long, not the whole system.
>>
>>-Andi
>>
>
>As for thermal event, AFAIK,  not all laptops use EC to 
>generate thermal
>event. And I'm thinking of a algorithm.
>
>  There is a issue of kacpid consuming a lot of CPU time, which should 
>be due to GPEs keep firing without any control. Current GPE handling
>just
>re-enable GPEs after handling GPEs without considering any semantics 
>conveyed by that GPE.  For example,  some laptop could keep generating 
>thermal GPE interrupt, if temperature is above a threshold. All these
>thermal events
>is just telling OS one thing, that is "temperature is above a specific
>threshold,
> please turn on cooling methods ...." .  Maybe this is platform issue,
> but driver  should handle this case smoothly.
> 
>http://bugme.osdl.org/show_bug.cgi?id=3686
> 
>
>Thanks
>Luming
>
>
>
>-------------------------------------------------------
>This SF.Net email is sponsored by: InterSystems CACHE
>FREE OODBMS DOWNLOAD - A multidimensional database that combines
>robust object and relational technologies, making it a perfect match
>for Java, C++,COM, XML, ODBC and JDBC. www.intersystems.com/match8
>_______________________________________________
>Acpi-devel mailing list
>Acpi-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f@public.gmane.org
>https://lists.sourceforge.net/lists/listinfo/acpi-devel
>


-------------------------------------------------------
This SF.Net email is sponsored by: InterSystems CACHE
FREE OODBMS DOWNLOAD - A multidimensional database that combines
robust object and relational technologies, making it a perfect match
for Java, C++,COM, XML, ODBC and JDBC. www.intersystems.com/match8

^ permalink raw reply	[flat|nested] 16+ messages in thread
* RE: [PATCH] Don't disable interrupts during EC access
@ 2004-11-16 15:21 Yu, Luming
  2004-11-16 15:37 ` Andi Kleen
  0 siblings, 1 reply; 16+ messages in thread
From: Yu, Luming @ 2004-11-16 15:21 UTC (permalink / raw)
  To: Andi Kleen, Matthew Wilcox
  Cc: acpi-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f, Fu, Michael,
	Brown, Len, Moore, Robert

>On Tue, Nov 16, 2004 at 12:16:16PM +0000, Matthew Wilcox wrote:
>> On Tue, Nov 16, 2004 at 02:15:47PM +0800, Yu, Luming wrote:
>> > Andi,
>> > 
>> > This patch seems to break the atomic operation.
>> > The original code enclosed by 
>spin_lock_irqsave/spin_unlock_irqresotre is trying to make 
>sure the first operation to EC_COMMAND
>> > register , and the second operation to EC_DATA register 
>belong to one atomic transaction.
>> 
>> Why would converting from a spinlock to a semaphore break this?
>
>As Willy said the operation should be still atomic in respect to
>the register.

It is just due to odd hardware behavior.  :-)
For example, if you want to read data from EC.  The first step
is writing 0x80 (read command) to ec command register.
Then, if EC (hardware) write data into the output buffer, the
output buffer flag (OBF) in the status register is set.
(I assume it is within 1ms). According to ACPI spec,
now, EC interrupt will get triggered. And this is
firmware generated edge interrupt. It will hold until OBF get reset.
When the host processor reads this data from the output buffer, 
the OBF can be reset.

So, if you remove the spin_lock_irqsave, when OBF is set
you could get interrupt storm.  

For detail, please refer to ACPI spec :
12   ACPI Embedded Controller Interface Specification.

>
>And the event polling can take several ms, there is just no way 
>to do this during runtime with interrupts off. Especially since
>thermal will do this every few seconds. With my patch at least 
>only kacpid is blocked for that long, not the whole system.
>
>-Andi
>

As for thermal event, AFAIK,  not all laptops use EC to generate thermal
event. And I'm thinking of a algorithm.

  There is a issue of kacpid consuming a lot of CPU time, which should 
be due to GPEs keep firing without any control. Current GPE handling
just
re-enable GPEs after handling GPEs without considering any semantics 
conveyed by that GPE.  For example,  some laptop could keep generating 
thermal GPE interrupt, if temperature is above a threshold. All these
thermal events
is just telling OS one thing, that is "temperature is above a specific
threshold,
 please turn on cooling methods ...." .  Maybe this is platform issue,
 but driver  should handle this case smoothly.
 
http://bugme.osdl.org/show_bug.cgi?id=3686
 

Thanks
Luming



-------------------------------------------------------
This SF.Net email is sponsored by: InterSystems CACHE
FREE OODBMS DOWNLOAD - A multidimensional database that combines
robust object and relational technologies, making it a perfect match
for Java, C++,COM, XML, ODBC and JDBC. www.intersystems.com/match8

^ permalink raw reply	[flat|nested] 16+ messages in thread
* RE: [PATCH] Don't disable interrupts during EC access
@ 2004-11-16  6:15 Yu, Luming
  2004-11-16 12:16 ` Matthew Wilcox
  0 siblings, 1 reply; 16+ messages in thread
From: Yu, Luming @ 2004-11-16  6:15 UTC (permalink / raw)
  To: Andi Kleen, acpi-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f; +Cc: Fu, Michael

Andi,

This patch seems to break the atomic operation.
The original code enclosed by spin_lock_irqsave/spin_unlock_irqresotre is trying to make sure the first operation to EC_COMMAND
register , and the second operation to EC_DATA register belong to one atomic transaction.

Thanks
Luming 

>-----Original Message-----
>From: acpi-devel-admin-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f@public.gmane.org 
>[mailto:acpi-devel-admin-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f@public.gmane.org] On Behalf Of Andi Kleen
>Sent: 2004年11月16日 6:56
>To: acpi-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f@public.gmane.org
>Subject: [ACPI] [PATCH] Don't disable interrupts during EC access
>
>
>On VIA chipset + A64 laptops the EC access can take a long 
>time. This causes
>the system to lose timer interrupts while ACPI waits for the event, 
>and causes it to always fallback to slower timer sources.
>
>This patch replaces the spinlock with a semaphore and sleeps instead
>of busy polling. This should also save power. 
>
>Signed-off-by: Andi Kleen <ak-l3A5Bk7waGM@public.gmane.org>
>
>-Andi
>
>diff -u linux/drivers/acpi/ec.c-o linux/drivers/acpi/ec.c
>--- linux/drivers/acpi/ec.c-o	2004-10-26 09:57:32.000000000 -0700
>+++ linux/drivers/acpi/ec.c	2004-11-15 12:55:58.000000000 -0800
>@@ -29,10 +29,12 @@
> #include <linux/types.h>
> #include <linux/delay.h>
> #include <linux/proc_fs.h>
>+#include <linux/interrupt.h>
> #include <asm/io.h>
> #include <acpi/acpi_bus.h>
> #include <acpi/acpi_drivers.h>
> #include <acpi/actypes.h>
>+#include <asm/msr.h>
> 
> #define _COMPONENT		ACPI_EC_COMPONENT
> ACPI_MODULE_NAME		("acpi_ec")
>@@ -53,7 +55,7 @@
> #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_UDELAY_COUNT	10	/* Wait 10ms max. 
>during EC ops */
> #define ACPI_EC_UDELAY_GLK	1000	/* Wait 1ms max. to get 
>global lock */
> 
> #define ACPI_EC_COMMAND_READ	0x80
>@@ -85,7 +87,6 @@
> 	struct acpi_generic_address	command_addr;
> 	struct acpi_generic_address	data_addr;
> 	unsigned long			global_lock;
>-	spinlock_t			lock;
> };
> 
> /* If we find an EC via the ECDT, we need to keep a ptr to 
>its context */
>@@ -116,7 +117,7 @@
> 			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);
>+			msleep(1);
> 		} while (--i>0);
> 		break;
> 	case ACPI_EC_EVENT_IBE:
>@@ -124,16 +125,16 @@
> 			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);
>+			msleep(1);
> 		} while (--i>0);
> 		break;
> 	default:
> 		return -EINVAL;
> 	}
>-
> 	return -ETIME;
> }
> 
>+static DECLARE_MUTEX(ec_mutex);
> 
> static int
> acpi_ec_read (
>@@ -143,7 +144,6 @@
> {
> 	acpi_status		status = AE_OK;
> 	int			result = 0;
>-	unsigned long		flags = 0;
> 	u32			glk = 0;
> 
> 	ACPI_FUNCTION_TRACE("acpi_ec_read");
>@@ -158,8 +158,9 @@
> 		if (ACPI_FAILURE(status))
> 			return_VALUE(-ENODEV);
> 	}
>-	
>-	spin_lock_irqsave(&ec->lock, flags);
>+
>+	WARN_ON(in_interrupt());
>+	down(&ec_mutex);
> 
> 	acpi_hw_low_level_write(8, ACPI_EC_COMMAND_READ, 
>&ec->command_addr);
> 	result = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE);
>@@ -173,16 +174,15 @@
> 
> 
> 	acpi_hw_low_level_read(8, data, &ec->data_addr);
>-
> 	ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Read [%02x] from 
>address [%02x]\n",
> 		*data, address));
> 
>+		
> end:
>-	spin_unlock_irqrestore(&ec->lock, flags);
>+	up(&ec_mutex);
> 
> 	if (ec->global_lock)
> 		acpi_release_global_lock(glk);
>-
> 	return_VALUE(result);
> }
> 
>@@ -195,7 +195,6 @@
> {
> 	int			result = 0;
> 	acpi_status		status = AE_OK;
>-	unsigned long		flags = 0;
> 	u32			glk = 0;
> 
> 	ACPI_FUNCTION_TRACE("acpi_ec_write");
>@@ -209,7 +208,8 @@
> 			return_VALUE(-ENODEV);
> 	}
> 
>-	spin_lock_irqsave(&ec->lock, flags);
>+	WARN_ON(in_interrupt());
>+	down(&ec_mutex);
> 
> 	acpi_hw_low_level_write(8, ACPI_EC_COMMAND_WRITE, 
>&ec->command_addr);
> 	result = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE);
>@@ -230,7 +230,7 @@
> 		data, address));
> 
> end:
>-	spin_unlock_irqrestore(&ec->lock, flags);
>+	up(&ec_mutex);
> 
> 	if (ec->global_lock)
> 		acpi_release_global_lock(glk);
>@@ -287,7 +287,6 @@
> {
> 	int			result = 0;
> 	acpi_status		status = AE_OK;
>-	unsigned long		flags = 0;
> 	u32			glk = 0;
> 
> 	ACPI_FUNCTION_TRACE("acpi_ec_query");
>@@ -308,7 +307,7 @@
> 	 * 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);
>+	down(&ec_mutex);
> 
> 	acpi_hw_low_level_write(8, ACPI_EC_COMMAND_QUERY, 
>&ec->command_addr);
> 	result = acpi_ec_wait(ec, ACPI_EC_EVENT_OBF);
>@@ -320,7 +319,7 @@
> 		result = -ENODATA;
> 
> end:
>-	spin_unlock_irqrestore(&ec->lock, flags);
>+	up(&ec_mutex);
> 
> 	if (ec->global_lock)
> 		acpi_release_global_lock(glk);
>@@ -344,7 +343,6 @@
> {
> 	struct acpi_ec		*ec = (struct acpi_ec *) ec_cxt;
> 	u32			value = 0;
>-	unsigned long		flags = 0;
> 	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'};
>@@ -354,9 +352,9 @@
> 	if (!ec_cxt)
> 		goto end;	
> 
>-	spin_lock_irqsave(&ec->lock, flags);
>+	down(&ec_mutex);
> 	acpi_hw_low_level_read(8, &value, &ec->command_addr);
>-	spin_unlock_irqrestore(&ec->lock, flags);
>+	up(&ec_mutex);
> 
> 	/* TBD: Implement asynch events!
> 	 * NOTE: All we care about are EC-SCI's.  Other EC events are
>@@ -588,7 +586,6 @@
> 
> 	ec->handle = device->handle;
> 	ec->uid = -1;
>-	ec->lock = SPIN_LOCK_UNLOCKED;
> 	strcpy(acpi_device_name(device), ACPI_EC_DEVICE_NAME);
> 	strcpy(acpi_device_class(device), ACPI_EC_CLASS);
> 	acpi_driver_data(device) = ec;
>@@ -802,7 +799,6 @@
> 	ec_ecdt->status_addr = ecdt_ptr->ec_control;
> 	ec_ecdt->data_addr = ecdt_ptr->ec_data;
> 	ec_ecdt->gpe_bit = ecdt_ptr->gpe_bit;
>-	ec_ecdt->lock = SPIN_LOCK_UNLOCKED;
> 	/* use the GL just to be safe */
> 	ec_ecdt->global_lock = TRUE;
> 	ec_ecdt->uid = ecdt_ptr->uid;
>
>
>-------------------------------------------------------
>This SF.Net email is sponsored by: InterSystems CACHE
>FREE OODBMS DOWNLOAD - A multidimensional database that combines
>robust object and relational technologies, making it a perfect match
>for Java, C++,COM, XML, ODBC and JDBC. www.intersystems.com/match8
>_______________________________________________
>Acpi-devel mailing list
>Acpi-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f@public.gmane.org
>https://lists.sourceforge.net/lists/listinfo/acpi-devel
>


-------------------------------------------------------
This SF.Net email is sponsored by: InterSystems CACHE
FREE OODBMS DOWNLOAD - A multidimensional database that combines
robust object and relational technologies, making it a perfect match
for Java, C++,COM, XML, ODBC and JDBC. www.intersystems.com/match8

^ permalink raw reply	[flat|nested] 16+ messages in thread
* [PATCH] Don't disable interrupts during EC access
@ 2004-11-15 22:56 Andi Kleen
  0 siblings, 0 replies; 16+ messages in thread
From: Andi Kleen @ 2004-11-15 22:56 UTC (permalink / raw)
  To: acpi-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f


On VIA chipset + A64 laptops the EC access can take a long time. This causes
the system to lose timer interrupts while ACPI waits for the event, 
and causes it to always fallback to slower timer sources.

This patch replaces the spinlock with a semaphore and sleeps instead
of busy polling. This should also save power. 

Signed-off-by: Andi Kleen <ak-l3A5Bk7waGM@public.gmane.org>

-Andi

diff -u linux/drivers/acpi/ec.c-o linux/drivers/acpi/ec.c
--- linux/drivers/acpi/ec.c-o	2004-10-26 09:57:32.000000000 -0700
+++ linux/drivers/acpi/ec.c	2004-11-15 12:55:58.000000000 -0800
@@ -29,10 +29,12 @@
 #include <linux/types.h>
 #include <linux/delay.h>
 #include <linux/proc_fs.h>
+#include <linux/interrupt.h>
 #include <asm/io.h>
 #include <acpi/acpi_bus.h>
 #include <acpi/acpi_drivers.h>
 #include <acpi/actypes.h>
+#include <asm/msr.h>
 
 #define _COMPONENT		ACPI_EC_COMPONENT
 ACPI_MODULE_NAME		("acpi_ec")
@@ -53,7 +55,7 @@
 #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_UDELAY_COUNT	10	/* Wait 10ms max. during EC ops */
 #define ACPI_EC_UDELAY_GLK	1000	/* Wait 1ms max. to get global lock */
 
 #define ACPI_EC_COMMAND_READ	0x80
@@ -85,7 +87,6 @@
 	struct acpi_generic_address	command_addr;
 	struct acpi_generic_address	data_addr;
 	unsigned long			global_lock;
-	spinlock_t			lock;
 };
 
 /* If we find an EC via the ECDT, we need to keep a ptr to its context */
@@ -116,7 +117,7 @@
 			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);
+			msleep(1);
 		} while (--i>0);
 		break;
 	case ACPI_EC_EVENT_IBE:
@@ -124,16 +125,16 @@
 			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);
+			msleep(1);
 		} while (--i>0);
 		break;
 	default:
 		return -EINVAL;
 	}
-
 	return -ETIME;
 }
 
+static DECLARE_MUTEX(ec_mutex);
 
 static int
 acpi_ec_read (
@@ -143,7 +144,6 @@
 {
 	acpi_status		status = AE_OK;
 	int			result = 0;
-	unsigned long		flags = 0;
 	u32			glk = 0;
 
 	ACPI_FUNCTION_TRACE("acpi_ec_read");
@@ -158,8 +158,9 @@
 		if (ACPI_FAILURE(status))
 			return_VALUE(-ENODEV);
 	}
-	
-	spin_lock_irqsave(&ec->lock, flags);
+
+	WARN_ON(in_interrupt());
+	down(&ec_mutex);
 
 	acpi_hw_low_level_write(8, ACPI_EC_COMMAND_READ, &ec->command_addr);
 	result = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE);
@@ -173,16 +174,15 @@
 
 
 	acpi_hw_low_level_read(8, data, &ec->data_addr);
-
 	ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Read [%02x] from address [%02x]\n",
 		*data, address));
 
+		
 end:
-	spin_unlock_irqrestore(&ec->lock, flags);
+	up(&ec_mutex);
 
 	if (ec->global_lock)
 		acpi_release_global_lock(glk);
-
 	return_VALUE(result);
 }
 
@@ -195,7 +195,6 @@
 {
 	int			result = 0;
 	acpi_status		status = AE_OK;
-	unsigned long		flags = 0;
 	u32			glk = 0;
 
 	ACPI_FUNCTION_TRACE("acpi_ec_write");
@@ -209,7 +208,8 @@
 			return_VALUE(-ENODEV);
 	}
 
-	spin_lock_irqsave(&ec->lock, flags);
+	WARN_ON(in_interrupt());
+	down(&ec_mutex);
 
 	acpi_hw_low_level_write(8, ACPI_EC_COMMAND_WRITE, &ec->command_addr);
 	result = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE);
@@ -230,7 +230,7 @@
 		data, address));
 
 end:
-	spin_unlock_irqrestore(&ec->lock, flags);
+	up(&ec_mutex);
 
 	if (ec->global_lock)
 		acpi_release_global_lock(glk);
@@ -287,7 +287,6 @@
 {
 	int			result = 0;
 	acpi_status		status = AE_OK;
-	unsigned long		flags = 0;
 	u32			glk = 0;
 
 	ACPI_FUNCTION_TRACE("acpi_ec_query");
@@ -308,7 +307,7 @@
 	 * 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);
+	down(&ec_mutex);
 
 	acpi_hw_low_level_write(8, ACPI_EC_COMMAND_QUERY, &ec->command_addr);
 	result = acpi_ec_wait(ec, ACPI_EC_EVENT_OBF);
@@ -320,7 +319,7 @@
 		result = -ENODATA;
 
 end:
-	spin_unlock_irqrestore(&ec->lock, flags);
+	up(&ec_mutex);
 
 	if (ec->global_lock)
 		acpi_release_global_lock(glk);
@@ -344,7 +343,6 @@
 {
 	struct acpi_ec		*ec = (struct acpi_ec *) ec_cxt;
 	u32			value = 0;
-	unsigned long		flags = 0;
 	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'};
@@ -354,9 +352,9 @@
 	if (!ec_cxt)
 		goto end;	
 
-	spin_lock_irqsave(&ec->lock, flags);
+	down(&ec_mutex);
 	acpi_hw_low_level_read(8, &value, &ec->command_addr);
-	spin_unlock_irqrestore(&ec->lock, flags);
+	up(&ec_mutex);
 
 	/* TBD: Implement asynch events!
 	 * NOTE: All we care about are EC-SCI's.  Other EC events are
@@ -588,7 +586,6 @@
 
 	ec->handle = device->handle;
 	ec->uid = -1;
-	ec->lock = SPIN_LOCK_UNLOCKED;
 	strcpy(acpi_device_name(device), ACPI_EC_DEVICE_NAME);
 	strcpy(acpi_device_class(device), ACPI_EC_CLASS);
 	acpi_driver_data(device) = ec;
@@ -802,7 +799,6 @@
 	ec_ecdt->status_addr = ecdt_ptr->ec_control;
 	ec_ecdt->data_addr = ecdt_ptr->ec_data;
 	ec_ecdt->gpe_bit = ecdt_ptr->gpe_bit;
-	ec_ecdt->lock = SPIN_LOCK_UNLOCKED;
 	/* use the GL just to be safe */
 	ec_ecdt->global_lock = TRUE;
 	ec_ecdt->uid = ecdt_ptr->uid;


-------------------------------------------------------
This SF.Net email is sponsored by: InterSystems CACHE
FREE OODBMS DOWNLOAD - A multidimensional database that combines
robust object and relational technologies, making it a perfect match
for Java, C++,COM, XML, ODBC and JDBC. www.intersystems.com/match8

^ permalink raw reply	[flat|nested] 16+ messages in thread

end of thread, other threads:[~2004-11-18  6:14 UTC | newest]

Thread overview: 16+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2004-11-17  7:10 [PATCH] Don't disable interrupts during EC access Li, Shaohua
     [not found] ` <16A54BF5D6E14E4D916CE26C9AD305758EF9BD-4yWAQGcml66iAffOGbnezLfspsVTdybXVpNB7YpNyf8@public.gmane.org>
2004-11-17  7:58   ` Dmitry Torokhov
  -- strict thread matches above, loose matches on Subject: below --
2004-11-17  7:46 Yu, Luming
2004-11-17  8:02 ` Dmitry Torokhov
     [not found]   ` <200411170302.58634.dtor_core-yWtbtysYrB+LZ21kGMrzwg@public.gmane.org>
2004-11-17 21:53     ` Len Brown
2004-11-18  6:14       ` Dmitry Torokhov
2004-11-17  6:12 Yu, Luming
2004-11-16 15:41 Yu, Luming
2004-11-16 15:21 Yu, Luming
2004-11-16 15:37 ` Andi Kleen
     [not found]   ` <20041116153709.GA2392-B4tOwbsTzaBolqkO4TVVkw@public.gmane.org>
2004-11-17  6:55     ` Dmitry Torokhov
2004-11-16  6:15 Yu, Luming
2004-11-16 12:16 ` Matthew Wilcox
     [not found]   ` <20041116121616.GG1108-+pPCBgu9SkPzIGdyhVEDUDl5KyyQGfY2kSSpQ9I8OhVaa/9Udqfwiw@public.gmane.org>
2004-11-16 12:29     ` Andi Kleen
     [not found]       ` <20041116122946.GG28839-B4tOwbsTzaBolqkO4TVVkw@public.gmane.org>
2004-11-17  1:25         ` Stefan Seyfried
2004-11-15 22:56 Andi Kleen

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox