Skip to content

Commit 805d849

Browse files
committed
Merge tag 'acpi-6.8-rc7' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm
Pull ACPI fix from Rafael Wysocki: "Revert a recent EC driver change that introduced an unexpected and undesirable user-visible difference in behavior (Rafael Wysocki)" * tag 'acpi-6.8-rc7' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm: Revert "ACPI: EC: Use a spin lock without disabing interrupts"
2 parents 022d0c6 + e0359f1 commit 805d849

File tree

1 file changed

+66
-46
lines changed

1 file changed

+66
-46
lines changed

drivers/acpi/ec.c

Lines changed: 66 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -525,10 +525,12 @@ static void acpi_ec_clear(struct acpi_ec *ec)
525525

526526
static void acpi_ec_enable_event(struct acpi_ec *ec)
527527
{
528-
spin_lock(&ec->lock);
528+
unsigned long flags;
529+
530+
spin_lock_irqsave(&ec->lock, flags);
529531
if (acpi_ec_started(ec))
530532
__acpi_ec_enable_event(ec);
531-
spin_unlock(&ec->lock);
533+
spin_unlock_irqrestore(&ec->lock, flags);
532534

533535
/* Drain additional events if hardware requires that */
534536
if (EC_FLAGS_CLEAR_ON_RESUME)
@@ -544,9 +546,11 @@ static void __acpi_ec_flush_work(void)
544546

545547
static void acpi_ec_disable_event(struct acpi_ec *ec)
546548
{
547-
spin_lock(&ec->lock);
549+
unsigned long flags;
550+
551+
spin_lock_irqsave(&ec->lock, flags);
548552
__acpi_ec_disable_event(ec);
549-
spin_unlock(&ec->lock);
553+
spin_unlock_irqrestore(&ec->lock, flags);
550554

551555
/*
552556
* When ec_freeze_events is true, we need to flush events in
@@ -567,9 +571,10 @@ void acpi_ec_flush_work(void)
567571

568572
static bool acpi_ec_guard_event(struct acpi_ec *ec)
569573
{
574+
unsigned long flags;
570575
bool guarded;
571576

572-
spin_lock(&ec->lock);
577+
spin_lock_irqsave(&ec->lock, flags);
573578
/*
574579
* If firmware SCI_EVT clearing timing is "event", we actually
575580
* don't know when the SCI_EVT will be cleared by firmware after
@@ -585,29 +590,31 @@ static bool acpi_ec_guard_event(struct acpi_ec *ec)
585590
guarded = ec_event_clearing == ACPI_EC_EVT_TIMING_EVENT &&
586591
ec->event_state != EC_EVENT_READY &&
587592
(!ec->curr || ec->curr->command != ACPI_EC_COMMAND_QUERY);
588-
spin_unlock(&ec->lock);
593+
spin_unlock_irqrestore(&ec->lock, flags);
589594
return guarded;
590595
}
591596

592597
static int ec_transaction_polled(struct acpi_ec *ec)
593598
{
599+
unsigned long flags;
594600
int ret = 0;
595601

596-
spin_lock(&ec->lock);
602+
spin_lock_irqsave(&ec->lock, flags);
597603
if (ec->curr && (ec->curr->flags & ACPI_EC_COMMAND_POLL))
598604
ret = 1;
599-
spin_unlock(&ec->lock);
605+
spin_unlock_irqrestore(&ec->lock, flags);
600606
return ret;
601607
}
602608

603609
static int ec_transaction_completed(struct acpi_ec *ec)
604610
{
611+
unsigned long flags;
605612
int ret = 0;
606613

607-
spin_lock(&ec->lock);
614+
spin_lock_irqsave(&ec->lock, flags);
608615
if (ec->curr && (ec->curr->flags & ACPI_EC_COMMAND_COMPLETE))
609616
ret = 1;
610-
spin_unlock(&ec->lock);
617+
spin_unlock_irqrestore(&ec->lock, flags);
611618
return ret;
612619
}
613620

@@ -749,6 +756,7 @@ static int ec_guard(struct acpi_ec *ec)
749756

750757
static int ec_poll(struct acpi_ec *ec)
751758
{
759+
unsigned long flags;
752760
int repeat = 5; /* number of command restarts */
753761

754762
while (repeat--) {
@@ -757,25 +765,26 @@ static int ec_poll(struct acpi_ec *ec)
757765
do {
758766
if (!ec_guard(ec))
759767
return 0;
760-
spin_lock(&ec->lock);
768+
spin_lock_irqsave(&ec->lock, flags);
761769
advance_transaction(ec, false);
762-
spin_unlock(&ec->lock);
770+
spin_unlock_irqrestore(&ec->lock, flags);
763771
} while (time_before(jiffies, delay));
764772
pr_debug("controller reset, restart transaction\n");
765-
spin_lock(&ec->lock);
773+
spin_lock_irqsave(&ec->lock, flags);
766774
start_transaction(ec);
767-
spin_unlock(&ec->lock);
775+
spin_unlock_irqrestore(&ec->lock, flags);
768776
}
769777
return -ETIME;
770778
}
771779

772780
static int acpi_ec_transaction_unlocked(struct acpi_ec *ec,
773781
struct transaction *t)
774782
{
783+
unsigned long tmp;
775784
int ret = 0;
776785

777786
/* start transaction */
778-
spin_lock(&ec->lock);
787+
spin_lock_irqsave(&ec->lock, tmp);
779788
/* Enable GPE for command processing (IBF=0/OBF=1) */
780789
if (!acpi_ec_submit_flushable_request(ec)) {
781790
ret = -EINVAL;
@@ -786,11 +795,11 @@ static int acpi_ec_transaction_unlocked(struct acpi_ec *ec,
786795
ec->curr = t;
787796
ec_dbg_req("Command(%s) started", acpi_ec_cmd_string(t->command));
788797
start_transaction(ec);
789-
spin_unlock(&ec->lock);
798+
spin_unlock_irqrestore(&ec->lock, tmp);
790799

791800
ret = ec_poll(ec);
792801

793-
spin_lock(&ec->lock);
802+
spin_lock_irqsave(&ec->lock, tmp);
794803
if (t->irq_count == ec_storm_threshold)
795804
acpi_ec_unmask_events(ec);
796805
ec_dbg_req("Command(%s) stopped", acpi_ec_cmd_string(t->command));
@@ -799,7 +808,7 @@ static int acpi_ec_transaction_unlocked(struct acpi_ec *ec,
799808
acpi_ec_complete_request(ec);
800809
ec_dbg_ref(ec, "Decrease command");
801810
unlock:
802-
spin_unlock(&ec->lock);
811+
spin_unlock_irqrestore(&ec->lock, tmp);
803812
return ret;
804813
}
805814

@@ -927,7 +936,9 @@ EXPORT_SYMBOL(ec_get_handle);
927936

928937
static void acpi_ec_start(struct acpi_ec *ec, bool resuming)
929938
{
930-
spin_lock(&ec->lock);
939+
unsigned long flags;
940+
941+
spin_lock_irqsave(&ec->lock, flags);
931942
if (!test_and_set_bit(EC_FLAGS_STARTED, &ec->flags)) {
932943
ec_dbg_drv("Starting EC");
933944
/* Enable GPE for event processing (SCI_EVT=1) */
@@ -937,28 +948,31 @@ static void acpi_ec_start(struct acpi_ec *ec, bool resuming)
937948
}
938949
ec_log_drv("EC started");
939950
}
940-
spin_unlock(&ec->lock);
951+
spin_unlock_irqrestore(&ec->lock, flags);
941952
}
942953

943954
static bool acpi_ec_stopped(struct acpi_ec *ec)
944955
{
956+
unsigned long flags;
945957
bool flushed;
946958

947-
spin_lock(&ec->lock);
959+
spin_lock_irqsave(&ec->lock, flags);
948960
flushed = acpi_ec_flushed(ec);
949-
spin_unlock(&ec->lock);
961+
spin_unlock_irqrestore(&ec->lock, flags);
950962
return flushed;
951963
}
952964

953965
static void acpi_ec_stop(struct acpi_ec *ec, bool suspending)
954966
{
955-
spin_lock(&ec->lock);
967+
unsigned long flags;
968+
969+
spin_lock_irqsave(&ec->lock, flags);
956970
if (acpi_ec_started(ec)) {
957971
ec_dbg_drv("Stopping EC");
958972
set_bit(EC_FLAGS_STOPPED, &ec->flags);
959-
spin_unlock(&ec->lock);
973+
spin_unlock_irqrestore(&ec->lock, flags);
960974
wait_event(ec->wait, acpi_ec_stopped(ec));
961-
spin_lock(&ec->lock);
975+
spin_lock_irqsave(&ec->lock, flags);
962976
/* Disable GPE for event processing (SCI_EVT=1) */
963977
if (!suspending) {
964978
acpi_ec_complete_request(ec);
@@ -969,25 +983,29 @@ static void acpi_ec_stop(struct acpi_ec *ec, bool suspending)
969983
clear_bit(EC_FLAGS_STOPPED, &ec->flags);
970984
ec_log_drv("EC stopped");
971985
}
972-
spin_unlock(&ec->lock);
986+
spin_unlock_irqrestore(&ec->lock, flags);
973987
}
974988

975989
static void acpi_ec_enter_noirq(struct acpi_ec *ec)
976990
{
977-
spin_lock(&ec->lock);
991+
unsigned long flags;
992+
993+
spin_lock_irqsave(&ec->lock, flags);
978994
ec->busy_polling = true;
979995
ec->polling_guard = 0;
980996
ec_log_drv("interrupt blocked");
981-
spin_unlock(&ec->lock);
997+
spin_unlock_irqrestore(&ec->lock, flags);
982998
}
983999

9841000
static void acpi_ec_leave_noirq(struct acpi_ec *ec)
9851001
{
986-
spin_lock(&ec->lock);
1002+
unsigned long flags;
1003+
1004+
spin_lock_irqsave(&ec->lock, flags);
9871005
ec->busy_polling = ec_busy_polling;
9881006
ec->polling_guard = ec_polling_guard;
9891007
ec_log_drv("interrupt unblocked");
990-
spin_unlock(&ec->lock);
1008+
spin_unlock_irqrestore(&ec->lock, flags);
9911009
}
9921010

9931011
void acpi_ec_block_transactions(void)
@@ -1119,9 +1137,9 @@ static void acpi_ec_event_processor(struct work_struct *work)
11191137

11201138
ec_dbg_evt("Query(0x%02x) stopped", handler->query_bit);
11211139

1122-
spin_lock(&ec->lock);
1140+
spin_lock_irq(&ec->lock);
11231141
ec->queries_in_progress--;
1124-
spin_unlock(&ec->lock);
1142+
spin_unlock_irq(&ec->lock);
11251143

11261144
acpi_ec_put_query_handler(handler);
11271145
kfree(q);
@@ -1184,12 +1202,12 @@ static int acpi_ec_submit_query(struct acpi_ec *ec)
11841202
*/
11851203
ec_dbg_evt("Query(0x%02x) scheduled", value);
11861204

1187-
spin_lock(&ec->lock);
1205+
spin_lock_irq(&ec->lock);
11881206

11891207
ec->queries_in_progress++;
11901208
queue_work(ec_query_wq, &q->work);
11911209

1192-
spin_unlock(&ec->lock);
1210+
spin_unlock_irq(&ec->lock);
11931211

11941212
return 0;
11951213

@@ -1205,14 +1223,14 @@ static void acpi_ec_event_handler(struct work_struct *work)
12051223

12061224
ec_dbg_evt("Event started");
12071225

1208-
spin_lock(&ec->lock);
1226+
spin_lock_irq(&ec->lock);
12091227

12101228
while (ec->events_to_process) {
1211-
spin_unlock(&ec->lock);
1229+
spin_unlock_irq(&ec->lock);
12121230

12131231
acpi_ec_submit_query(ec);
12141232

1215-
spin_lock(&ec->lock);
1233+
spin_lock_irq(&ec->lock);
12161234

12171235
ec->events_to_process--;
12181236
}
@@ -1229,11 +1247,11 @@ static void acpi_ec_event_handler(struct work_struct *work)
12291247

12301248
ec_dbg_evt("Event stopped");
12311249

1232-
spin_unlock(&ec->lock);
1250+
spin_unlock_irq(&ec->lock);
12331251

12341252
guard_timeout = !!ec_guard(ec);
12351253

1236-
spin_lock(&ec->lock);
1254+
spin_lock_irq(&ec->lock);
12371255

12381256
/* Take care of SCI_EVT unless someone else is doing that. */
12391257
if (guard_timeout && !ec->curr)
@@ -1246,7 +1264,7 @@ static void acpi_ec_event_handler(struct work_struct *work)
12461264

12471265
ec->events_in_progress--;
12481266

1249-
spin_unlock(&ec->lock);
1267+
spin_unlock_irq(&ec->lock);
12501268
}
12511269

12521270
static void clear_gpe_and_advance_transaction(struct acpi_ec *ec, bool interrupt)
@@ -1271,11 +1289,13 @@ static void clear_gpe_and_advance_transaction(struct acpi_ec *ec, bool interrupt
12711289

12721290
static void acpi_ec_handle_interrupt(struct acpi_ec *ec)
12731291
{
1274-
spin_lock(&ec->lock);
1292+
unsigned long flags;
1293+
1294+
spin_lock_irqsave(&ec->lock, flags);
12751295

12761296
clear_gpe_and_advance_transaction(ec, true);
12771297

1278-
spin_unlock(&ec->lock);
1298+
spin_unlock_irqrestore(&ec->lock, flags);
12791299
}
12801300

12811301
static u32 acpi_ec_gpe_handler(acpi_handle gpe_device,
@@ -2085,7 +2105,7 @@ bool acpi_ec_dispatch_gpe(void)
20852105
* Dispatch the EC GPE in-band, but do not report wakeup in any case
20862106
* to allow the caller to process events properly after that.
20872107
*/
2088-
spin_lock(&first_ec->lock);
2108+
spin_lock_irq(&first_ec->lock);
20892109

20902110
if (acpi_ec_gpe_status_set(first_ec)) {
20912111
pm_pr_dbg("ACPI EC GPE status set\n");
@@ -2094,7 +2114,7 @@ bool acpi_ec_dispatch_gpe(void)
20942114
work_in_progress = acpi_ec_work_in_progress(first_ec);
20952115
}
20962116

2097-
spin_unlock(&first_ec->lock);
2117+
spin_unlock_irq(&first_ec->lock);
20982118

20992119
if (!work_in_progress)
21002120
return false;
@@ -2107,11 +2127,11 @@ bool acpi_ec_dispatch_gpe(void)
21072127

21082128
pm_pr_dbg("ACPI EC work flushed\n");
21092129

2110-
spin_lock(&first_ec->lock);
2130+
spin_lock_irq(&first_ec->lock);
21112131

21122132
work_in_progress = acpi_ec_work_in_progress(first_ec);
21132133

2114-
spin_unlock(&first_ec->lock);
2134+
spin_unlock_irq(&first_ec->lock);
21152135
} while (work_in_progress && !pm_wakeup_pending());
21162136

21172137
return false;

0 commit comments

Comments
 (0)