Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 110103
b: refs/heads/master
c: d3a47e8
h: refs/heads/master
i:
  110101: 257ec36
  110099: 452e942
  110095: 45ea3ea
v: v3
  • Loading branch information
Linus Torvalds committed Sep 30, 2008
1 parent d3a9079 commit 2359848
Show file tree
Hide file tree
Showing 12 changed files with 180 additions and 88 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: c459ce8b5a7d933a3bcf6915ab17ac1e036e2ac4
refs/heads/master: d3a47e82b6bc3724dd60f3ee4e84fe4479104382
106 changes: 53 additions & 53 deletions trunk/arch/powerpc/boot/dts/holly.dts
Original file line number Diff line number Diff line change
Expand Up @@ -133,61 +133,61 @@
reg = <0x00007400 0x00000400>;
big-endian;
};
};

pci@1000 {
device_type = "pci";
compatible = "tsi109-pci", "tsi108-pci";
#interrupt-cells = <1>;
#size-cells = <2>;
#address-cells = <3>;
reg = <0x00001000 0x00001000>;
bus-range = <0x0 0x0>;
/*----------------------------------------------------+
| PCI memory range.
| 01 denotes I/O space
| 02 denotes 32-bit memory space
+----------------------------------------------------*/
ranges = <0x02000000 0x00000000 0x40000000 0x40000000 0x00000000 0x10000000
0x01000000 0x00000000 0x00000000 0x7e000000 0x00000000 0x00010000>;
clock-frequency = <133333332>;
interrupt-parent = <&MPIC>;
pci@c0001000 {
device_type = "pci";
compatible = "tsi109-pci", "tsi108-pci";
#interrupt-cells = <1>;
#size-cells = <2>;
#address-cells = <3>;
reg = <0xc0001000 0x00001000>;
bus-range = <0x0 0x0>;
/*----------------------------------------------------+
| PCI memory range.
| 01 denotes I/O space
| 02 denotes 32-bit memory space
+----------------------------------------------------*/
ranges = <0x02000000 0x00000000 0x40000000 0x40000000 0x00000000 0x10000000
0x01000000 0x00000000 0x00000000 0x7e000000 0x00000000 0x00010000>;
clock-frequency = <133333332>;
interrupt-parent = <&MPIC>;
interrupts = <0x17 0x2>;
interrupt-map-mask = <0xf800 0x0 0x0 0x7>;
/*----------------------------------------------------+
| The INTA, INTB, INTC, INTD are shared.
+----------------------------------------------------*/
interrupt-map = <
0x800 0x0 0x0 0x1 &RT0 0x24 0x0
0x800 0x0 0x0 0x2 &RT0 0x25 0x0
0x800 0x0 0x0 0x3 &RT0 0x26 0x0
0x800 0x0 0x0 0x4 &RT0 0x27 0x0

0x1000 0x0 0x0 0x1 &RT0 0x25 0x0
0x1000 0x0 0x0 0x2 &RT0 0x26 0x0
0x1000 0x0 0x0 0x3 &RT0 0x27 0x0
0x1000 0x0 0x0 0x4 &RT0 0x24 0x0

0x1800 0x0 0x0 0x1 &RT0 0x26 0x0
0x1800 0x0 0x0 0x2 &RT0 0x27 0x0
0x1800 0x0 0x0 0x3 &RT0 0x24 0x0
0x1800 0x0 0x0 0x4 &RT0 0x25 0x0

0x2000 0x0 0x0 0x1 &RT0 0x27 0x0
0x2000 0x0 0x0 0x2 &RT0 0x24 0x0
0x2000 0x0 0x0 0x3 &RT0 0x25 0x0
0x2000 0x0 0x0 0x4 &RT0 0x26 0x0
>;

RT0: router@1180 {
device_type = "pic-router";
interrupt-controller;
big-endian;
clock-frequency = <0>;
#address-cells = <0>;
#interrupt-cells = <2>;
interrupts = <0x17 0x2>;
interrupt-map-mask = <0xf800 0x0 0x0 0x7>;
/*----------------------------------------------------+
| The INTA, INTB, INTC, INTD are shared.
+----------------------------------------------------*/
interrupt-map = <
0x800 0x0 0x0 0x1 &RT0 0x24 0x0
0x800 0x0 0x0 0x2 &RT0 0x25 0x0
0x800 0x0 0x0 0x3 &RT0 0x26 0x0
0x800 0x0 0x0 0x4 &RT0 0x27 0x0

0x1000 0x0 0x0 0x1 &RT0 0x25 0x0
0x1000 0x0 0x0 0x2 &RT0 0x26 0x0
0x1000 0x0 0x0 0x3 &RT0 0x27 0x0
0x1000 0x0 0x0 0x4 &RT0 0x24 0x0

0x1800 0x0 0x0 0x1 &RT0 0x26 0x0
0x1800 0x0 0x0 0x2 &RT0 0x27 0x0
0x1800 0x0 0x0 0x3 &RT0 0x24 0x0
0x1800 0x0 0x0 0x4 &RT0 0x25 0x0

0x2000 0x0 0x0 0x1 &RT0 0x27 0x0
0x2000 0x0 0x0 0x2 &RT0 0x24 0x0
0x2000 0x0 0x0 0x3 &RT0 0x25 0x0
0x2000 0x0 0x0 0x4 &RT0 0x26 0x0
>;

RT0: router@1180 {
device_type = "pic-router";
interrupt-controller;
big-endian;
clock-frequency = <0>;
#address-cells = <0>;
#interrupt-cells = <2>;
interrupts = <0x17 0x2>;
interrupt-parent = <&MPIC>;
};
interrupt-parent = <&MPIC>;
};
};

Expand Down
6 changes: 1 addition & 5 deletions trunk/arch/powerpc/kernel/idle.c
Original file line number Diff line number Diff line change
Expand Up @@ -34,11 +34,7 @@
#include <asm/smp.h>

#ifdef CONFIG_HOTPLUG_CPU
/* this is used for software suspend, and that shuts down
* CPUs even while the system is still booting... */
#define cpu_should_die() (cpu_is_offline(smp_processor_id()) && \
(system_state == SYSTEM_RUNNING \
|| system_state == SYSTEM_BOOTING))
#define cpu_should_die() cpu_is_offline(smp_processor_id())
#else
#define cpu_should_die() 0
#endif
Expand Down
4 changes: 2 additions & 2 deletions trunk/drivers/mfd/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -21,15 +21,15 @@ config MFD_SM501

config MFD_SM501_GPIO
bool "Export GPIO via GPIO layer"
depends on MFD_SM501 && HAVE_GPIO_LIB
depends on MFD_SM501 && GPIOLIB
---help---
This option uses the gpio library layer to export the 64 GPIO
lines on the SM501. The platform data is used to supply the
base number for the first GPIO line to register.

config MFD_ASIC3
bool "Support for Compaq ASIC3"
depends on GENERIC_HARDIRQS && HAVE_GPIO_LIB && ARM
depends on GENERIC_HARDIRQS && GPIOLIB && ARM
---help---
This driver supports the ASIC3 multifunction chip found on many
PDAs (mainly iPAQ and HTC based ones)
Expand Down
2 changes: 1 addition & 1 deletion trunk/drivers/mfd/asic3.c
Original file line number Diff line number Diff line change
Expand Up @@ -312,7 +312,6 @@ static int __init asic3_irq_probe(struct platform_device *pdev)
struct asic3 *asic = platform_get_drvdata(pdev);
unsigned long clksel = 0;
unsigned int irq, irq_base;
int map_size;
int ret;

ret = platform_get_irq(pdev, 0);
Expand Down Expand Up @@ -534,6 +533,7 @@ static int __init asic3_probe(struct platform_device *pdev)
struct asic3 *asic;
struct resource *mem;
unsigned long clksel;
int map_size;
int ret = 0;

asic = kzalloc(sizeof(struct asic3), GFP_KERNEL);
Expand Down
18 changes: 14 additions & 4 deletions trunk/include/linux/hrtimer.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,14 +47,22 @@ enum hrtimer_restart {
* HRTIMER_CB_IRQSAFE: Callback may run in hardirq context
* HRTIMER_CB_IRQSAFE_NO_RESTART: Callback may run in hardirq context and
* does not restart the timer
* HRTIMER_CB_IRQSAFE_NO_SOFTIRQ: Callback must run in hardirq context
* Special mode for tick emultation
* HRTIMER_CB_IRQSAFE_PERCPU: Callback must run in hardirq context
* Special mode for tick emulation and
* scheduler timer. Such timers are per
* cpu and not allowed to be migrated on
* cpu unplug.
* HRTIMER_CB_IRQSAFE_UNLOCKED: Callback should run in hardirq context
* with timer->base lock unlocked
* used for timers which call wakeup to
* avoid lock order problems with rq->lock
*/
enum hrtimer_cb_mode {
HRTIMER_CB_SOFTIRQ,
HRTIMER_CB_IRQSAFE,
HRTIMER_CB_IRQSAFE_NO_RESTART,
HRTIMER_CB_IRQSAFE_NO_SOFTIRQ,
HRTIMER_CB_IRQSAFE_PERCPU,
HRTIMER_CB_IRQSAFE_UNLOCKED,
};

/*
Expand All @@ -67,9 +75,10 @@ enum hrtimer_cb_mode {
* 0x02 callback function running
* 0x04 callback pending (high resolution mode)
*
* Special case:
* Special cases:
* 0x03 callback function running and enqueued
* (was requeued on another CPU)
* 0x09 timer was migrated on CPU hotunplug
* The "callback function running and enqueued" status is only possible on
* SMP. It happens for example when a posix timer expired and the callback
* queued a signal. Between dropping the lock which protects the posix timer
Expand All @@ -87,6 +96,7 @@ enum hrtimer_cb_mode {
#define HRTIMER_STATE_ENQUEUED 0x01
#define HRTIMER_STATE_CALLBACK 0x02
#define HRTIMER_STATE_PENDING 0x04
#define HRTIMER_STATE_MIGRATE 0x08

/**
* struct hrtimer - the basic hrtimer structure
Expand Down
95 changes: 85 additions & 10 deletions trunk/kernel/hrtimer.c
Original file line number Diff line number Diff line change
Expand Up @@ -672,13 +672,14 @@ static inline int hrtimer_enqueue_reprogram(struct hrtimer *timer,
*/
BUG_ON(timer->function(timer) != HRTIMER_NORESTART);
return 1;
case HRTIMER_CB_IRQSAFE_NO_SOFTIRQ:
case HRTIMER_CB_IRQSAFE_PERCPU:
case HRTIMER_CB_IRQSAFE_UNLOCKED:
/*
* This is solely for the sched tick emulation with
* dynamic tick support to ensure that we do not
* restart the tick right on the edge and end up with
* the tick timer in the softirq ! The calling site
* takes care of this.
* takes care of this. Also used for hrtimer sleeper !
*/
debug_hrtimer_deactivate(timer);
return 1;
Expand Down Expand Up @@ -1245,7 +1246,8 @@ static void __run_hrtimer(struct hrtimer *timer)
timer_stats_account_hrtimer(timer);

fn = timer->function;
if (timer->cb_mode == HRTIMER_CB_IRQSAFE_NO_SOFTIRQ) {
if (timer->cb_mode == HRTIMER_CB_IRQSAFE_PERCPU ||
timer->cb_mode == HRTIMER_CB_IRQSAFE_UNLOCKED) {
/*
* Used for scheduler timers, avoid lock inversion with
* rq->lock and tasklist_lock.
Expand Down Expand Up @@ -1452,7 +1454,7 @@ void hrtimer_init_sleeper(struct hrtimer_sleeper *sl, struct task_struct *task)
sl->timer.function = hrtimer_wakeup;
sl->task = task;
#ifdef CONFIG_HIGH_RES_TIMERS
sl->timer.cb_mode = HRTIMER_CB_IRQSAFE_NO_SOFTIRQ;
sl->timer.cb_mode = HRTIMER_CB_IRQSAFE_UNLOCKED;
#endif
}

Expand Down Expand Up @@ -1591,29 +1593,95 @@ static void __cpuinit init_hrtimers_cpu(int cpu)

#ifdef CONFIG_HOTPLUG_CPU

static void migrate_hrtimer_list(struct hrtimer_clock_base *old_base,
struct hrtimer_clock_base *new_base)
static int migrate_hrtimer_list(struct hrtimer_clock_base *old_base,
struct hrtimer_clock_base *new_base, int dcpu)
{
struct hrtimer *timer;
struct rb_node *node;
int raise = 0;

while ((node = rb_first(&old_base->active))) {
timer = rb_entry(node, struct hrtimer, node);
BUG_ON(hrtimer_callback_running(timer));
debug_hrtimer_deactivate(timer);
__remove_hrtimer(timer, old_base, HRTIMER_STATE_INACTIVE, 0);

/*
* Should not happen. Per CPU timers should be
* canceled _before_ the migration code is called
*/
if (timer->cb_mode == HRTIMER_CB_IRQSAFE_PERCPU) {
__remove_hrtimer(timer, old_base,
HRTIMER_STATE_INACTIVE, 0);
WARN(1, "hrtimer (%p %p)active but cpu %d dead\n",
timer, timer->function, dcpu);
continue;
}

/*
* Mark it as STATE_MIGRATE not INACTIVE otherwise the
* timer could be seen as !active and just vanish away
* under us on another CPU
*/
__remove_hrtimer(timer, old_base, HRTIMER_STATE_MIGRATE, 0);
timer->base = new_base;
/*
* Enqueue the timer. Allow reprogramming of the event device
*/
enqueue_hrtimer(timer, new_base, 1);

#ifdef CONFIG_HIGH_RES_TIMERS
/*
* Happens with high res enabled when the timer was
* already expired and the callback mode is
* HRTIMER_CB_IRQSAFE_UNLOCKED (hrtimer_sleeper). The
* enqueue code does not move them to the soft irq
* pending list for performance/latency reasons, but
* in the migration state, we need to do that
* otherwise we end up with a stale timer.
*/
if (timer->state == HRTIMER_STATE_MIGRATE) {
timer->state = HRTIMER_STATE_PENDING;
list_add_tail(&timer->cb_entry,
&new_base->cpu_base->cb_pending);
raise = 1;
}
#endif
/* Clear the migration state bit */
timer->state &= ~HRTIMER_STATE_MIGRATE;
}
return raise;
}

#ifdef CONFIG_HIGH_RES_TIMERS
static int migrate_hrtimer_pending(struct hrtimer_cpu_base *old_base,
struct hrtimer_cpu_base *new_base)
{
struct hrtimer *timer;
int raise = 0;

while (!list_empty(&old_base->cb_pending)) {
timer = list_entry(old_base->cb_pending.next,
struct hrtimer, cb_entry);

__remove_hrtimer(timer, timer->base, HRTIMER_STATE_PENDING, 0);
timer->base = &new_base->clock_base[timer->base->index];
list_add_tail(&timer->cb_entry, &new_base->cb_pending);
raise = 1;
}
return raise;
}
#else
static int migrate_hrtimer_pending(struct hrtimer_cpu_base *old_base,
struct hrtimer_cpu_base *new_base)
{
return 0;
}
#endif

static void migrate_hrtimers(int cpu)
{
struct hrtimer_cpu_base *old_base, *new_base;
int i;
int i, raise = 0;

BUG_ON(cpu_online(cpu));
old_base = &per_cpu(hrtimer_bases, cpu);
Expand All @@ -1626,14 +1694,21 @@ static void migrate_hrtimers(int cpu)
spin_lock_nested(&old_base->lock, SINGLE_DEPTH_NESTING);

for (i = 0; i < HRTIMER_MAX_CLOCK_BASES; i++) {
migrate_hrtimer_list(&old_base->clock_base[i],
&new_base->clock_base[i]);
if (migrate_hrtimer_list(&old_base->clock_base[i],
&new_base->clock_base[i], cpu))
raise = 1;
}

if (migrate_hrtimer_pending(old_base, new_base))
raise = 1;

spin_unlock(&old_base->lock);
spin_unlock(&new_base->lock);
local_irq_enable();
put_cpu_var(hrtimer_bases);

if (raise)
hrtimer_raise_softirq();
}
#endif /* CONFIG_HOTPLUG_CPU */

Expand Down
4 changes: 2 additions & 2 deletions trunk/kernel/sched.c
Original file line number Diff line number Diff line change
Expand Up @@ -201,7 +201,7 @@ void init_rt_bandwidth(struct rt_bandwidth *rt_b, u64 period, u64 runtime)
hrtimer_init(&rt_b->rt_period_timer,
CLOCK_MONOTONIC, HRTIMER_MODE_REL);
rt_b->rt_period_timer.function = sched_rt_period_timer;
rt_b->rt_period_timer.cb_mode = HRTIMER_CB_IRQSAFE_NO_SOFTIRQ;
rt_b->rt_period_timer.cb_mode = HRTIMER_CB_IRQSAFE_UNLOCKED;
}

static void start_rt_bandwidth(struct rt_bandwidth *rt_b)
Expand Down Expand Up @@ -1119,7 +1119,7 @@ static void init_rq_hrtick(struct rq *rq)

hrtimer_init(&rq->hrtick_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
rq->hrtick_timer.function = hrtick;
rq->hrtick_timer.cb_mode = HRTIMER_CB_IRQSAFE_NO_SOFTIRQ;
rq->hrtick_timer.cb_mode = HRTIMER_CB_IRQSAFE_PERCPU;
}
#else
static inline void hrtick_clear(struct rq *rq)
Expand Down
2 changes: 1 addition & 1 deletion trunk/kernel/time/tick-sched.c
Original file line number Diff line number Diff line change
Expand Up @@ -625,7 +625,7 @@ void tick_setup_sched_timer(void)
*/
hrtimer_init(&ts->sched_timer, CLOCK_MONOTONIC, HRTIMER_MODE_ABS);
ts->sched_timer.function = tick_sched_timer;
ts->sched_timer.cb_mode = HRTIMER_CB_IRQSAFE_NO_SOFTIRQ;
ts->sched_timer.cb_mode = HRTIMER_CB_IRQSAFE_PERCPU;

/* Get the next period (per cpu) */
ts->sched_timer.expires = tick_init_jiffy_update();
Expand Down
Loading

0 comments on commit 2359848

Please sign in to comment.