Skip to content

Commit

Permalink
Merge tag 'pm+acpi-4.1-rc2' of git://git.kernel.org/pub/scm/linux/ker…
Browse files Browse the repository at this point in the history
…nel/git/rafael/linux-pm

Pull power management and ACPI fixes from Rafael Wysocki:
 "Three regression fixes this time, one for a recent regression in the
  cpuidle core affecting multiple systems, one for an inadvertently
  added duplicate typedef in ACPICA that breaks compilation with GCC 4.5
  and one for an ACPI Smart Battery Subsystem driver regression
  introduced during the 3.18 cycle (stable-candidate).

  Specifics:

   - Fix for a regression in the cpuidle core introduced by one of the
     recent commits in the clockevents_notify() removal series that put
     a call to a function which had to be executed with disabled
     interrupts into a code path running with enabled interrupts (Rafael
     J Wysocki)

   - Fix for a build problem in ACPICA (with GCC 4.5) introduced by one
     of the recent ACPICA tools commits that added a duplicate typedef
     to one of the ACPICA's header files by mistake (Olaf Hering)

   - Fix for a regression in the ACPI SBS (Smart Battery Subsystem)
     driver introduced during the 3.18 development cycle causing the
     smart battery manager to be marked as not present when it should be
     marked as present (Chris Bainbridge)"

* tag 'pm+acpi-4.1-rc2' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm:
  cpuidle: Run tick_broadcast_exit() with disabled interrupts
  ACPI / SBS: Enable battery manager when present
  ACPICA: remove duplicate u8 typedef
  • Loading branch information
torvalds committed Apr 30, 2015
2 parents 5a2e73b + 50904a7 commit 4a152c3
Show file tree
Hide file tree
Showing 4 changed files with 19 additions and 16 deletions.
2 changes: 1 addition & 1 deletion drivers/acpi/sbs.c
Original file line number Diff line number Diff line change
Expand Up @@ -684,7 +684,7 @@ static int acpi_sbs_add(struct acpi_device *device)
if (!sbs_manager_broken) {
result = acpi_manager_get_info(sbs);
if (!result) {
sbs->manager_present = 0;
sbs->manager_present = 1;
for (id = 0; id < MAX_SBS_BAT; ++id)
if ((sbs->batteries_supported & (1 << id)))
acpi_battery_add(sbs, id);
Expand Down
16 changes: 16 additions & 0 deletions drivers/cpuidle/cpuidle.c
Original file line number Diff line number Diff line change
Expand Up @@ -158,9 +158,18 @@ int cpuidle_enter_state(struct cpuidle_device *dev, struct cpuidle_driver *drv,
int entered_state;

struct cpuidle_state *target_state = &drv->states[index];
bool broadcast = !!(target_state->flags & CPUIDLE_FLAG_TIMER_STOP);
ktime_t time_start, time_end;
s64 diff;

/*
* Tell the time framework to switch to a broadcast timer because our
* local timer will be shut down. If a local timer is used from another
* CPU as a broadcast timer, this call may fail if it is not available.
*/
if (broadcast && tick_broadcast_enter())
return -EBUSY;

trace_cpu_idle_rcuidle(index, dev->cpu);
time_start = ktime_get();

Expand All @@ -169,6 +178,13 @@ int cpuidle_enter_state(struct cpuidle_device *dev, struct cpuidle_driver *drv,
time_end = ktime_get();
trace_cpu_idle_rcuidle(PWR_EVENT_EXIT, dev->cpu);

if (broadcast) {
if (WARN_ON_ONCE(!irqs_disabled()))
local_irq_disable();

tick_broadcast_exit();
}

if (!cpuidle_state_is_coupled(dev, drv, entered_state))
local_irq_enable();

Expand Down
1 change: 0 additions & 1 deletion include/acpi/actypes.h
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,6 @@

#ifndef ACPI_USE_SYSTEM_INTTYPES

typedef unsigned char u8;
typedef unsigned char u8;
typedef unsigned short u16;
typedef short s16;
Expand Down
16 changes: 2 additions & 14 deletions kernel/sched/idle.c
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,6 @@ static void cpuidle_idle_call(void)
struct cpuidle_device *dev = __this_cpu_read(cpuidle_devices);
struct cpuidle_driver *drv = cpuidle_get_cpu_driver(dev);
int next_state, entered_state;
unsigned int broadcast;
bool reflect;

/*
Expand Down Expand Up @@ -150,17 +149,6 @@ static void cpuidle_idle_call(void)
goto exit_idle;
}

broadcast = drv->states[next_state].flags & CPUIDLE_FLAG_TIMER_STOP;

/*
* Tell the time framework to switch to a broadcast timer
* because our local timer will be shutdown. If a local timer
* is used from another cpu as a broadcast timer, this call may
* fail if it is not available
*/
if (broadcast && tick_broadcast_enter())
goto use_default;

/* Take note of the planned idle state. */
idle_set_state(this_rq(), &drv->states[next_state]);

Expand All @@ -174,8 +162,8 @@ static void cpuidle_idle_call(void)
/* The cpu is no longer idle or about to enter idle. */
idle_set_state(this_rq(), NULL);

if (broadcast)
tick_broadcast_exit();
if (entered_state == -EBUSY)
goto use_default;

/*
* Give the governor an opportunity to reflect on the outcome
Expand Down

0 comments on commit 4a152c3

Please sign in to comment.