All of lore.kernel.org
 help / color / mirror / Atom feed
* [UBUNTU:acpi/ec] Use semaphore instead of spinlock
@ 2006-06-14 23:22 Randy Dunlap
  2006-06-15  5:38 ` Bongani Hlope
  2006-06-16 14:31 ` Luiz Fernando N. Capitulino
  0 siblings, 2 replies; 16+ messages in thread
From: Randy Dunlap @ 2006-06-14 23:22 UTC (permalink / raw)
  To: lkml; +Cc: akpm, len.brown

From: Ben Collins <bcollins@ubuntu.com>

[UBUNTU:acpi/ec] Use semaphore instead of spinlock to get rid of missed
interrupts on ACPI EC (embedded controller)

Reference: https://launchpad.net/bugs/39315
http://www.kernel.org/git/?p=linux/kernel/git/bcollins/ubuntu-dapper.git;a=commitdiff;h=c484728a760fcfcbad2319ed5364414bc86c3d38

Signed-off-by: Ben Collins <bcollins@ubuntu.com>
---

--- a/drivers/acpi/ec.c
+++ b/drivers/acpi/ec.c
@@ -53,8 +53,8 @@ ACPI_MODULE_NAME("acpi_ec")
 #define ACPI_EC_EVENT_IBE	0x02	/* Input buffer empty */
 #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	/* Poll @ 1ms increments */
+#define ACPI_EC_MSLEEP_COUNT	10	/* Wait 10ms max. during EC ops */
 #define ACPI_EC_COMMAND_READ	0x80
 #define ACPI_EC_COMMAND_WRITE	0x81
 #define ACPI_EC_BURST_ENABLE	0x82
@@ -116,7 +116,7 @@ union acpi_ec {
 		struct acpi_generic_address command_addr;
 		struct acpi_generic_address data_addr;
 		unsigned long global_lock;
-		spinlock_t lock;
+		struct semaphore sem;
 	} poll;
 };
 
@@ -172,7 +172,7 @@ static int acpi_ec_wait(union acpi_ec *e
 static int acpi_ec_poll_wait(union acpi_ec *ec, u8 event)
 {
 	u32 acpi_ec_status = 0;
-	u32 i = ACPI_EC_UDELAY_COUNT;
+	u32 i = ACPI_EC_MSLEEP_COUNT;
 
 	if (!ec)
 		return -EINVAL;
@@ -185,7 +185,7 @@ static int acpi_ec_poll_wait(union acpi_
 					       &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:
@@ -194,7 +194,7 @@ static int acpi_ec_poll_wait(union acpi_
 					       &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:
@@ -326,7 +326,6 @@ static int acpi_ec_poll_read(union acpi_
 {
 	acpi_status status = AE_OK;
 	int result = 0;
-	unsigned long flags = 0;
 	u32 glk = 0;
 
 	ACPI_FUNCTION_TRACE("acpi_ec_read");
@@ -342,7 +341,10 @@ static int acpi_ec_poll_read(union acpi_
 			return_VALUE(-ENODEV);
 	}
 
-	spin_lock_irqsave(&ec->poll.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);
@@ -361,7 +363,8 @@ static int acpi_ec_poll_read(union acpi_
 			  *data, address));
 
       end:
-	spin_unlock_irqrestore(&ec->poll.lock, flags);
+	up(&ec->polling.sem);
+end_nosem:
 
 	if (ec->common.global_lock)
 		acpi_release_global_lock(glk);
@@ -387,7 +390,10 @@ static int acpi_ec_poll_write(union acpi
 			return_VALUE(-ENODEV);
 	}
 
-	spin_lock_irqsave(&ec->poll.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);
@@ -409,7 +415,8 @@ static int acpi_ec_poll_write(union acpi
 			  data, address));
 
       end:
-	spin_unlock_irqrestore(&ec->poll.lock, flags);
+	up(&ec->polling.sem);
+end_nosem:
 
 	if (ec->common.global_lock)
 		acpi_release_global_lock(glk);
@@ -592,7 +599,10 @@ static int acpi_ec_poll_query(union acpi
 	 * 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->poll.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);
@@ -605,7 +615,8 @@ static int acpi_ec_poll_query(union acpi
 		result = -ENODATA;
 
       end:
-	spin_unlock_irqrestore(&ec->poll.lock, flags);
+	up(&ec->polling.sem);
+end_nosem:
 
 	if (ec->common.global_lock)
 		acpi_release_global_lock(glk);
@@ -694,9 +705,10 @@ static void acpi_ec_gpe_poll_query(void 
 	if (!ec_cxt)
 		goto end;
 
-	spin_lock_irqsave(&ec->poll.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->poll.lock, flags);
+	up(&ec->polling.sem);
 
 	/* TBD: Implement asynch events!
 	 * NOTE: All we care about are EC-SCI's.  Other EC events are
@@ -1008,7 +1020,7 @@ static int acpi_ec_poll_add(struct acpi_
 
 	ec->common.handle = device->handle;
 	ec->common.uid = -1;
-	spin_lock_init(&ec->poll.lock);
+	init_MUTEX(&ec->polling.sem);
 	strcpy(acpi_device_name(device), ACPI_EC_DEVICE_NAME);
 	strcpy(acpi_device_class(device), ACPI_EC_CLASS);
 	acpi_driver_data(device) = ec;
@@ -1303,7 +1315,7 @@ acpi_fake_ecdt_poll_callback(acpi_handle
 				  &ec_ecdt->common.gpe_bit);
 	if (ACPI_FAILURE(status))
 		return status;
-	spin_lock_init(&ec_ecdt->poll.lock);
+	init_MUTEX(&ec_ecdt->polling.sem);
 	ec_ecdt->common.global_lock = TRUE;
 	ec_ecdt->common.handle = handle;
 
@@ -1419,7 +1431,7 @@ static int __init acpi_ec_poll_get_real_
 	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->poll.lock);
+	init_MUTEX(&ec_ecdt->polling.sem);
 	/* use the GL just to be safe */
 	ec_ecdt->common.global_lock = TRUE;
 	ec_ecdt->common.uid = ecdt_ptr->uid;


^ permalink raw reply	[flat|nested] 16+ messages in thread
* Re: [UBUNTU:acpi/ec] Use semaphore instead of spinlock
@ 2006-06-14 23:08 Voluspa
  2006-06-15  0:26 ` Randy Dunlap
  2006-06-15  1:14 ` Randy Dunlap
  0 siblings, 2 replies; 16+ messages in thread
From: Voluspa @ 2006-06-14 23:08 UTC (permalink / raw)
  To: randy.dunlap; +Cc: linux-kernel


  CC      drivers/acpi/glue.o
  CC      drivers/acpi/ec.o
drivers/acpi/ec.c: In function `acpi_ec_poll_read':
drivers/acpi/ec.c:341: error: union has no member named `polling'
drivers/acpi/ec.c:363: error: union has no member named `polling'
drivers/acpi/ec.c: In function `acpi_ec_poll_write':
drivers/acpi/ec.c:390: error: union has no member named `polling'
drivers/acpi/ec.c:415: error: union has no member named `polling'
drivers/acpi/ec.c:376: warning: unused variable `flags'
drivers/acpi/ec.c: In function `acpi_ec_poll_query':
drivers/acpi/ec.c:599: error: union has no member named `polling'
drivers/acpi/ec.c:615: error: union has no member named `polling'
drivers/acpi/ec.c:578: warning: unused variable `flags'
drivers/acpi/ec.c: In function `acpi_ec_gpe_poll_query':
drivers/acpi/ec.c:705: error: union has no member named `polling'
drivers/acpi/ec.c:708: error: union has no member named `polling'
drivers/acpi/ec.c:694: warning: unused variable `flags'
drivers/acpi/ec.c: In function `acpi_ec_poll_add':
drivers/acpi/ec.c:1020: error: union has no member named `polling'
drivers/acpi/ec.c: In function `acpi_fake_ecdt_poll_callback':
drivers/acpi/ec.c:1315: error: union has no member named `polling'
drivers/acpi/ec.c: In function `acpi_ec_poll_get_real_ecdt':
drivers/acpi/ec.c:1431: error: union has no member named `polling'
make[2]: *** [drivers/acpi/ec.o] Error 1
make[1]: *** [drivers/acpi] Error 2
make: *** [drivers] Error 2

Mvh
Mats Johannesson
--

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

end of thread, other threads:[~2006-06-20  1:06 UTC | newest]

Thread overview: 16+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2006-06-14 23:22 [UBUNTU:acpi/ec] Use semaphore instead of spinlock Randy Dunlap
2006-06-15  5:38 ` Bongani Hlope
2006-06-20  0:40   ` Andrew Morton
2006-06-20  0:41     ` Randy Dunlap
2006-06-20  1:10       ` Andrew Morton
2006-06-16 14:31 ` Luiz Fernando N. Capitulino
2006-06-16 17:43   ` Randy Dunlap
  -- strict thread matches above, loose matches on Subject: below --
2006-06-14 23:08 Voluspa
2006-06-15  0:26 ` Randy Dunlap
2006-06-15  1:14 ` Randy Dunlap
2006-06-15  5:45   ` Roland Dreier
2006-06-15 11:03   ` Voluspa
2006-06-15 16:27     ` Lee Revell
2006-06-16  9:23       ` Voluspa
2006-06-17  2:57         ` Lee Revell
2006-06-15 15:40   ` Arjan van de Ven

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.