@@ -658,7 +663,6 @@
{
int result = 0;
acpi_status status = AE_OK;
- unsigned long flags = 0;
u32 glk = 0;
ACPI_FUNCTION_TRACE("acpi_ec_query");
@@ -679,7 +683,10 @@
* 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->polling.lock, flags);
+ if (down_interruptible (&ec->polling.sem)) {
+ result = -ERESTARTSYS;
+ goto end_nosem;
+ }
acpi_hw_low_level_write(8, ACPI_EC_COMMAND_QUERY, &ec-
>common.command_addr);
result = acpi_ec_wait(ec, ACPI_EC_EVENT_OBF);
@@ -691,8 +698,8 @@
result = -ENODATA;
Logged In: NO
--- linux-2.6.13-gentoo-r3/drivers/acpi/ec.c 2005-10-14 18:55:15.
000000000 +0200
+++ linux-2.6.13-gentoo-r3-ec-nospinlock/drivers/acpi/ec.c 2005-10-18
16:37:34.000000000 +0200
@@ -31,6 +31,7 @@
#include <linux/delay.h>
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
+#include <asm/semaphore.h>
#include <linux/interrupt.h>
#include <asm/io.h>
#include <acpi/acpi_bus.h>
@@ -59,8 +60,8 @@
#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_UDELAY 100 /* Poll @ 100us increments */
-#define ACPI_EC_UDELAY_COUNT 1000 /* Wait 10ms max. during EC
ops */
+#define ACPI_EC_MSLEEP 1 /* Sleep 1ms between polling */
+#define ACPI_EC_MSLEEP_COUNT 10 /* Wait 10ms max. during EC
ops */
#define ACPI_EC_COMMAND_READ 0x80
#define ACPI_EC_COMMAND_WRITE 0x81
@@ -126,7 +127,7 @@
struct acpi_generic_address command_addr;
struct acpi_generic_address data_addr;
unsigned long global_lock;
- spinlock_t lock;
+ struct semaphore sem;
}polling;
};
@@ -196,7 +197,7 @@
u8 event)
{
u32 acpi_ec_status = 0;
- u32 i = ACPI_EC_UDELAY_COUNT;
+ u32 i = ACPI_EC_MSLEEP_COUNT;
if (!ec)
return -EINVAL;
@@ -208,7 +209,7 @@
acpi_hw_low_level_read(8, &acpi_ec_status, &ec-
>common.status_addr);
if (acpi_ec_status & ACPI_EC_FLAG_OBF)
return 0;
- udelay(ACPI_EC_UDELAY);
+ msleep(ACPI_EC_MSLEEP);
} while (--i>0);
break;
case ACPI_EC_EVENT_IBE:
@@ -216,7 +217,7 @@
acpi_hw_low_level_read(8, &acpi_ec_status, &ec-
>common.status_addr);
if (!(acpi_ec_status & ACPI_EC_FLAG_IBF))
return 0;
- udelay(ACPI_EC_UDELAY);
+ msleep(ACPI_EC_MSLEEP);
} while (--i>0);
break;
default:
@@ -345,7 +346,7 @@
else
return acpi_ec_burst_write(ec, address, data);
}
-static int
+int
acpi_ec_polling_read (
union acpi_ec *ec,
u8 address,
@@ -353,7 +354,6 @@
{
acpi_status status = AE_OK;
int result = 0;
- unsigned long flags = 0;
u32 glk = 0;
ACPI_FUNCTION_TRACE("acpi_ec_read");
@@ -369,7 +369,10 @@
return_VALUE(-ENODEV);
}
- spin_lock_irqsave(&ec->polling.lock, flags);
+ if (down_interruptible (&ec->polling.sem)) {
+ result = -ERESTARTSYS;
+ goto end_nosem;
+ }
acpi_hw_low_level_write(8, ACPI_EC_COMMAND_READ, &ec-
>common.command_addr);
result = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE);
@@ -387,8 +390,8 @@
*data, address));
end:
- spin_unlock_irqrestore(&ec->polling.lock, flags);
-
+ up(&ec->polling.sem);
+end_nosem:
if (ec->common.global_lock)
acpi_release_global_lock(glk);
@@ -396,7 +399,7 @@
}
-static int
+int
acpi_ec_polling_write (
union acpi_ec *ec,
u8 address,
@@ -404,7 +407,6 @@
{
int result = 0;
acpi_status status = AE_OK;
- unsigned long flags = 0;
u32 glk = 0;
ACPI_FUNCTION_TRACE("acpi_ec_write");
@@ -418,7 +420,10 @@
return_VALUE(-ENODEV);
}
- spin_lock_irqsave(&ec->polling.lock, flags);
+ if (down_interruptible (&ec->polling.sem)) {
+ result = - ERESTARTSYS;
+ goto end_nosem;
+ }
acpi_hw_low_level_write(8, ACPI_EC_COMMAND_WRITE, &ec-
>common.command_addr);
result = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE);
@@ -439,8 +444,8 @@
data, address));
end:
- spin_unlock_irqrestore(&ec->polling.lock, flags);
-
+ up(&ec->polling.sem);
+end_nosem:
if (ec->common.global_lock)
acpi_release_global_lock(glk);
@@ -658,7 +663,6 @@
{
int result = 0;
acpi_status status = AE_OK;
- unsigned long flags = 0;
u32 glk = 0;
ACPI_FUNCTION_TRACE("acpi_ec_query");
@@ -679,7 +683,10 @@
* 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->polling.lock, flags);
+ if (down_interruptible (&ec->polling.sem)) {
+ result = -ERESTARTSYS;
+ goto end_nosem;
+ }
acpi_hw_low_level_write(8, ACPI_EC_COMMAND_QUERY, &ec-
>common.command_addr);
result = acpi_ec_wait(ec, ACPI_EC_EVENT_OBF);
@@ -691,8 +698,8 @@
result = -ENODATA;
end:
- spin_unlock_irqrestore(&ec->polling.lock, flags);
-
+ up(&ec->polling.sem);
+end_nosem:
if (ec->common.global_lock)
acpi_release_global_lock(glk);
@@ -779,7 +786,6 @@
{
union acpi_ec *ec = (union 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'};
@@ -789,9 +795,11 @@
if (!ec_cxt)
goto end;
- spin_lock_irqsave(&ec->polling.lock, flags);
+ if (down_interruptible (&ec->polling.sem)) {
+ return_VOID;
+ }
acpi_hw_low_level_read(8, &value, &ec->common.command_addr);
- spin_unlock_irqrestore(&ec->polling.lock, flags);
+ up(&ec->polling.sem);
/* TBD: Implement asynch events!
* NOTE: All we care about are EC-SCI's. Other EC events are
@@ -1137,7 +1145,7 @@
ec->common.handle = device->handle;
ec->common.uid = -1;
- spin_lock_init(&ec->polling.lock);
+ sema_init(&ec->polling.sem, 1);
strcpy(acpi_device_name(device), ACPI_EC_DEVICE_NAME);
strcpy(acpi_device_class(device), ACPI_EC_CLASS);
acpi_driver_data(device) = ec;
@@ -1434,7 +1442,7 @@
status = acpi_evaluate_integer(handle, "_GPE", NULL, &ec_ecdt-
>common.gpe_bit);
if (ACPI_FAILURE(status))
return status;
- spin_lock_init(&ec_ecdt->polling.lock);
+ sema_init(&ec_ecdt->polling.sem, 1);
ec_ecdt->common.global_lock = TRUE;
ec_ecdt->common.handle = handle;
@@ -1553,7 +1561,7 @@
ec_ecdt->common.status_addr = ecdt_ptr->ec_control;
ec_ecdt->common.data_addr = ecdt_ptr->ec_data;
ec_ecdt->common.gpe_bit = ecdt_ptr->gpe_bit;
- spin_lock_init(&ec_ecdt->polling.lock);
+ sema_init(&ec_ecdt->polling.sem, 1);
/* use the GL just to be safe */
ec_ecdt->common.global_lock = TRUE;
ec_ecdt->common.uid = ecdt_ptr->uid;