Commit e713c80a authored by Linus Torvalds's avatar Linus Torvalds

Merge branch 'x86-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip

Pull x86 clockevent update from Thomas Gleixner:
 "A single commit, which converts HPET clockevents driver to the new
  callbacks"

* 'x86-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
  x86/hpet: Migrate to new set_state interface
parents 43af9872 c8b5db7d
...@@ -226,22 +226,7 @@ static void hpet_reserve_platform_timers(unsigned int id) { } ...@@ -226,22 +226,7 @@ static void hpet_reserve_platform_timers(unsigned int id) { }
*/ */
static unsigned long hpet_freq; static unsigned long hpet_freq;
static void hpet_legacy_set_mode(enum clock_event_mode mode, static struct clock_event_device hpet_clockevent;
struct clock_event_device *evt);
static int hpet_legacy_next_event(unsigned long delta,
struct clock_event_device *evt);
/*
* The hpet clock event device
*/
static struct clock_event_device hpet_clockevent = {
.name = "hpet",
.features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT,
.set_mode = hpet_legacy_set_mode,
.set_next_event = hpet_legacy_next_event,
.irq = 0,
.rating = 50,
};
static void hpet_stop_counter(void) static void hpet_stop_counter(void)
{ {
...@@ -306,64 +291,74 @@ static void hpet_legacy_clockevent_register(void) ...@@ -306,64 +291,74 @@ static void hpet_legacy_clockevent_register(void)
printk(KERN_DEBUG "hpet clockevent registered\n"); printk(KERN_DEBUG "hpet clockevent registered\n");
} }
static void hpet_set_mode(enum clock_event_mode mode, static int hpet_set_periodic(struct clock_event_device *evt, int timer)
struct clock_event_device *evt, int timer)
{ {
unsigned int cfg, cmp, now; unsigned int cfg, cmp, now;
uint64_t delta; uint64_t delta;
switch (mode) { hpet_stop_counter();
case CLOCK_EVT_MODE_PERIODIC: delta = ((uint64_t)(NSEC_PER_SEC / HZ)) * evt->mult;
hpet_stop_counter(); delta >>= evt->shift;
delta = ((uint64_t)(NSEC_PER_SEC/HZ)) * evt->mult; now = hpet_readl(HPET_COUNTER);
delta >>= evt->shift; cmp = now + (unsigned int)delta;
now = hpet_readl(HPET_COUNTER); cfg = hpet_readl(HPET_Tn_CFG(timer));
cmp = now + (unsigned int) delta; cfg |= HPET_TN_ENABLE | HPET_TN_PERIODIC | HPET_TN_SETVAL |
cfg = hpet_readl(HPET_Tn_CFG(timer)); HPET_TN_32BIT;
cfg |= HPET_TN_ENABLE | HPET_TN_PERIODIC | hpet_writel(cfg, HPET_Tn_CFG(timer));
HPET_TN_SETVAL | HPET_TN_32BIT; hpet_writel(cmp, HPET_Tn_CMP(timer));
hpet_writel(cfg, HPET_Tn_CFG(timer)); udelay(1);
hpet_writel(cmp, HPET_Tn_CMP(timer)); /*
udelay(1); * HPET on AMD 81xx needs a second write (with HPET_TN_SETVAL
/* * cleared) to T0_CMP to set the period. The HPET_TN_SETVAL
* HPET on AMD 81xx needs a second write (with HPET_TN_SETVAL * bit is automatically cleared after the first write.
* cleared) to T0_CMP to set the period. The HPET_TN_SETVAL * (See AMD-8111 HyperTransport I/O Hub Data Sheet,
* bit is automatically cleared after the first write. * Publication # 24674)
* (See AMD-8111 HyperTransport I/O Hub Data Sheet, */
* Publication # 24674) hpet_writel((unsigned int)delta, HPET_Tn_CMP(timer));
*/ hpet_start_counter();
hpet_writel((unsigned int) delta, HPET_Tn_CMP(timer)); hpet_print_config();
hpet_start_counter();
hpet_print_config();
break;
case CLOCK_EVT_MODE_ONESHOT: return 0;
cfg = hpet_readl(HPET_Tn_CFG(timer)); }
cfg &= ~HPET_TN_PERIODIC;
cfg |= HPET_TN_ENABLE | HPET_TN_32BIT;
hpet_writel(cfg, HPET_Tn_CFG(timer));
break;
case CLOCK_EVT_MODE_UNUSED: static int hpet_set_oneshot(struct clock_event_device *evt, int timer)
case CLOCK_EVT_MODE_SHUTDOWN: {
cfg = hpet_readl(HPET_Tn_CFG(timer)); unsigned int cfg;
cfg &= ~HPET_TN_ENABLE;
hpet_writel(cfg, HPET_Tn_CFG(timer));
break;
case CLOCK_EVT_MODE_RESUME: cfg = hpet_readl(HPET_Tn_CFG(timer));
if (timer == 0) { cfg &= ~HPET_TN_PERIODIC;
hpet_enable_legacy_int(); cfg |= HPET_TN_ENABLE | HPET_TN_32BIT;
} else { hpet_writel(cfg, HPET_Tn_CFG(timer));
struct hpet_dev *hdev = EVT_TO_HPET_DEV(evt);
irq_domain_activate_irq(irq_get_irq_data(hdev->irq)); return 0;
disable_irq(hdev->irq); }
irq_set_affinity(hdev->irq, cpumask_of(hdev->cpu));
enable_irq(hdev->irq); static int hpet_shutdown(struct clock_event_device *evt, int timer)
} {
hpet_print_config(); unsigned int cfg;
break;
cfg = hpet_readl(HPET_Tn_CFG(timer));
cfg &= ~HPET_TN_ENABLE;
hpet_writel(cfg, HPET_Tn_CFG(timer));
return 0;
}
static int hpet_resume(struct clock_event_device *evt, int timer)
{
if (!timer) {
hpet_enable_legacy_int();
} else {
struct hpet_dev *hdev = EVT_TO_HPET_DEV(evt);
irq_domain_activate_irq(irq_get_irq_data(hdev->irq));
disable_irq(hdev->irq);
irq_set_affinity(hdev->irq, cpumask_of(hdev->cpu));
enable_irq(hdev->irq);
} }
hpet_print_config();
return 0;
} }
static int hpet_next_event(unsigned long delta, static int hpet_next_event(unsigned long delta,
...@@ -403,10 +398,24 @@ static int hpet_next_event(unsigned long delta, ...@@ -403,10 +398,24 @@ static int hpet_next_event(unsigned long delta,
return res < HPET_MIN_CYCLES ? -ETIME : 0; return res < HPET_MIN_CYCLES ? -ETIME : 0;
} }
static void hpet_legacy_set_mode(enum clock_event_mode mode, static int hpet_legacy_shutdown(struct clock_event_device *evt)
struct clock_event_device *evt) {
return hpet_shutdown(evt, 0);
}
static int hpet_legacy_set_oneshot(struct clock_event_device *evt)
{
return hpet_set_oneshot(evt, 0);
}
static int hpet_legacy_set_periodic(struct clock_event_device *evt)
{ {
hpet_set_mode(mode, evt, 0); return hpet_set_periodic(evt, 0);
}
static int hpet_legacy_resume(struct clock_event_device *evt)
{
return hpet_resume(evt, 0);
} }
static int hpet_legacy_next_event(unsigned long delta, static int hpet_legacy_next_event(unsigned long delta,
...@@ -415,6 +424,22 @@ static int hpet_legacy_next_event(unsigned long delta, ...@@ -415,6 +424,22 @@ static int hpet_legacy_next_event(unsigned long delta,
return hpet_next_event(delta, evt, 0); return hpet_next_event(delta, evt, 0);
} }
/*
* The hpet clock event device
*/
static struct clock_event_device hpet_clockevent = {
.name = "hpet",
.features = CLOCK_EVT_FEAT_PERIODIC |
CLOCK_EVT_FEAT_ONESHOT,
.set_state_periodic = hpet_legacy_set_periodic,
.set_state_oneshot = hpet_legacy_set_oneshot,
.set_state_shutdown = hpet_legacy_shutdown,
.tick_resume = hpet_legacy_resume,
.set_next_event = hpet_legacy_next_event,
.irq = 0,
.rating = 50,
};
/* /*
* HPET MSI Support * HPET MSI Support
*/ */
...@@ -459,11 +484,32 @@ void hpet_msi_read(struct hpet_dev *hdev, struct msi_msg *msg) ...@@ -459,11 +484,32 @@ void hpet_msi_read(struct hpet_dev *hdev, struct msi_msg *msg)
msg->address_hi = 0; msg->address_hi = 0;
} }
static void hpet_msi_set_mode(enum clock_event_mode mode, static int hpet_msi_shutdown(struct clock_event_device *evt)
struct clock_event_device *evt) {
struct hpet_dev *hdev = EVT_TO_HPET_DEV(evt);
return hpet_shutdown(evt, hdev->num);
}
static int hpet_msi_set_oneshot(struct clock_event_device *evt)
{
struct hpet_dev *hdev = EVT_TO_HPET_DEV(evt);
return hpet_set_oneshot(evt, hdev->num);
}
static int hpet_msi_set_periodic(struct clock_event_device *evt)
{ {
struct hpet_dev *hdev = EVT_TO_HPET_DEV(evt); struct hpet_dev *hdev = EVT_TO_HPET_DEV(evt);
hpet_set_mode(mode, evt, hdev->num);
return hpet_set_periodic(evt, hdev->num);
}
static int hpet_msi_resume(struct clock_event_device *evt)
{
struct hpet_dev *hdev = EVT_TO_HPET_DEV(evt);
return hpet_resume(evt, hdev->num);
} }
static int hpet_msi_next_event(unsigned long delta, static int hpet_msi_next_event(unsigned long delta,
...@@ -523,10 +569,14 @@ static void init_one_hpet_msi_clockevent(struct hpet_dev *hdev, int cpu) ...@@ -523,10 +569,14 @@ static void init_one_hpet_msi_clockevent(struct hpet_dev *hdev, int cpu)
evt->rating = 110; evt->rating = 110;
evt->features = CLOCK_EVT_FEAT_ONESHOT; evt->features = CLOCK_EVT_FEAT_ONESHOT;
if (hdev->flags & HPET_DEV_PERI_CAP) if (hdev->flags & HPET_DEV_PERI_CAP) {
evt->features |= CLOCK_EVT_FEAT_PERIODIC; evt->features |= CLOCK_EVT_FEAT_PERIODIC;
evt->set_state_periodic = hpet_msi_set_periodic;
}
evt->set_mode = hpet_msi_set_mode; evt->set_state_shutdown = hpet_msi_shutdown;
evt->set_state_oneshot = hpet_msi_set_oneshot;
evt->tick_resume = hpet_msi_resume;
evt->set_next_event = hpet_msi_next_event; evt->set_next_event = hpet_msi_next_event;
evt->cpumask = cpumask_of(hdev->cpu); evt->cpumask = cpumask_of(hdev->cpu);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment