114 lines
3.6 KiB
Diff
114 lines
3.6 KiB
Diff
From: Clark Williams <williams@redhat.com>
|
|
Date: Sat Dec 3 09:15:46 2011 -0600
|
|
Subject: ACPI: Convert embedded controller lock to raw spinlock
|
|
|
|
Was seeing multiple "scheduling while atomic" backtraces on the
|
|
3.2-rc2-rt5 realtime kernel. This patch converts the spinlock in
|
|
the ACPI embedded controller structure (curr_lock) to be a raw
|
|
spinlock.
|
|
|
|
Signed-off-by: Clark Williams <williams@redhat.com>
|
|
Link: http://lkml.kernel.org/r/20111203093537.7d805f64@redhat.com
|
|
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
|
|
Cc: stable-rt@vger.kernel.org
|
|
diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c
|
|
index b19a18d..5812e01 100644
|
|
--- a/drivers/acpi/ec.c
|
|
+++ b/drivers/acpi/ec.c
|
|
@@ -152,10 +152,10 @@ static int ec_transaction_done(struct acpi_ec *ec)
|
|
{
|
|
unsigned long flags;
|
|
int ret = 0;
|
|
- spin_lock_irqsave(&ec->curr_lock, flags);
|
|
+ raw_spin_lock_irqsave(&ec->curr_lock, flags);
|
|
if (!ec->curr || ec->curr->done)
|
|
ret = 1;
|
|
- spin_unlock_irqrestore(&ec->curr_lock, flags);
|
|
+ raw_spin_unlock_irqrestore(&ec->curr_lock, flags);
|
|
return ret;
|
|
}
|
|
|
|
@@ -169,7 +169,7 @@ static void start_transaction(struct acpi_ec *ec)
|
|
static void advance_transaction(struct acpi_ec *ec, u8 status)
|
|
{
|
|
unsigned long flags;
|
|
- spin_lock_irqsave(&ec->curr_lock, flags);
|
|
+ raw_spin_lock_irqsave(&ec->curr_lock, flags);
|
|
if (!ec->curr)
|
|
goto unlock;
|
|
if (ec->curr->wlen > ec->curr->wi) {
|
|
@@ -194,7 +194,7 @@ err:
|
|
if (in_interrupt())
|
|
++ec->curr->irq_count;
|
|
unlock:
|
|
- spin_unlock_irqrestore(&ec->curr_lock, flags);
|
|
+ raw_spin_unlock_irqrestore(&ec->curr_lock, flags);
|
|
}
|
|
|
|
static int acpi_ec_sync_query(struct acpi_ec *ec);
|
|
@@ -232,9 +232,9 @@ static int ec_poll(struct acpi_ec *ec)
|
|
if (acpi_ec_read_status(ec) & ACPI_EC_FLAG_IBF)
|
|
break;
|
|
pr_debug(PREFIX "controller reset, restart transaction\n");
|
|
- spin_lock_irqsave(&ec->curr_lock, flags);
|
|
+ raw_spin_lock_irqsave(&ec->curr_lock, flags);
|
|
start_transaction(ec);
|
|
- spin_unlock_irqrestore(&ec->curr_lock, flags);
|
|
+ raw_spin_unlock_irqrestore(&ec->curr_lock, flags);
|
|
}
|
|
return -ETIME;
|
|
}
|
|
@@ -247,17 +247,17 @@ static int acpi_ec_transaction_unlocked(struct acpi_ec *ec,
|
|
if (EC_FLAGS_MSI)
|
|
udelay(ACPI_EC_MSI_UDELAY);
|
|
/* start transaction */
|
|
- spin_lock_irqsave(&ec->curr_lock, tmp);
|
|
+ raw_spin_lock_irqsave(&ec->curr_lock, tmp);
|
|
/* following two actions should be kept atomic */
|
|
ec->curr = t;
|
|
start_transaction(ec);
|
|
if (ec->curr->command == ACPI_EC_COMMAND_QUERY)
|
|
clear_bit(EC_FLAGS_QUERY_PENDING, &ec->flags);
|
|
- spin_unlock_irqrestore(&ec->curr_lock, tmp);
|
|
+ raw_spin_unlock_irqrestore(&ec->curr_lock, tmp);
|
|
ret = ec_poll(ec);
|
|
- spin_lock_irqsave(&ec->curr_lock, tmp);
|
|
+ raw_spin_lock_irqsave(&ec->curr_lock, tmp);
|
|
ec->curr = NULL;
|
|
- spin_unlock_irqrestore(&ec->curr_lock, tmp);
|
|
+ raw_spin_unlock_irqrestore(&ec->curr_lock, tmp);
|
|
return ret;
|
|
}
|
|
|
|
@@ -678,7 +678,7 @@ static struct acpi_ec *make_acpi_ec(void)
|
|
mutex_init(&ec->lock);
|
|
init_waitqueue_head(&ec->wait);
|
|
INIT_LIST_HEAD(&ec->list);
|
|
- spin_lock_init(&ec->curr_lock);
|
|
+ raw_spin_lock_init(&ec->curr_lock);
|
|
return ec;
|
|
}
|
|
|
|
diff --git a/drivers/acpi/internal.h b/drivers/acpi/internal.h
|
|
index ca75b9c..68ed95f 100644
|
|
--- a/drivers/acpi/internal.h
|
|
+++ b/drivers/acpi/internal.h
|
|
@@ -62,7 +62,7 @@ struct acpi_ec {
|
|
wait_queue_head_t wait;
|
|
struct list_head list;
|
|
struct transaction *curr;
|
|
- spinlock_t curr_lock;
|
|
+ raw_spinlock_t curr_lock;
|
|
};
|
|
|
|
extern struct acpi_ec *first_ec;
|
|
|
|
-----BEGIN PGP SIGNATURE-----
|
|
Version: GnuPG v2.0.18 (GNU/Linux)
|
|
|
|
iEYEARECAAYFAk7aQc0ACgkQHyuj/+TTEp1wdQCdGi7huqfZZYwMBW91bICU9zew
|
|
FZcAoM6leP805J/d5rruxEvbU1nNPQ6Z
|
|
=+fyw
|
|
-----END PGP SIGNATURE-----
|
|
|