Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit c8b5db7d authored by Viresh Kumar's avatar Viresh Kumar Committed by Thomas Gleixner
Browse files

x86/hpet: Migrate to new set_state interface



Migrate hpet driver to the new 'set-state' interface provided by
clockevents core, the earlier 'set-mode' interface is marked obsolete
now.

This also enables us to implement callbacks for new states of clockevent
devices, for example: ONESHOT_STOPPED.

Forward definition of 'hpet_clockevent' wasn't required and so it is
placed after all the callback are defined, to avoid forward declaring
all the callbacks.

Signed-off-by: default avatarViresh Kumar <viresh.kumar@linaro.org>
Cc: linaro-kernel@lists.linaro.org
Cc: Jiang Liu <jiang.liu@linux.intel.com>
Cc: Rasmus Villemoes <linux@rasmusvillemoes.dk>
Link: http://lkml.kernel.org/r/8cc9864b6d6342dfac28f270cf69f4cba46fffae.1437042675.git.viresh.kumar@linaro.org


Signed-off-by: default avatarThomas Gleixner <tglx@linutronix.de>
parent cbfe8fa6
Loading
Loading
Loading
Loading
+124 −74
Original line number Diff line number Diff line
@@ -226,22 +226,7 @@ static void hpet_reserve_platform_timers(unsigned int id) { }
 */
static unsigned long hpet_freq;

static void hpet_legacy_set_mode(enum clock_event_mode mode,
			  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 struct clock_event_device hpet_clockevent;

static void hpet_stop_counter(void)
{
@@ -306,22 +291,19 @@ static void hpet_legacy_clockevent_register(void)
	printk(KERN_DEBUG "hpet clockevent registered\n");
}

static void hpet_set_mode(enum clock_event_mode mode,
			  struct clock_event_device *evt, int timer)
static int hpet_set_periodic(struct clock_event_device *evt, int timer)
{
	unsigned int cfg, cmp, now;
	uint64_t delta;

	switch (mode) {
	case CLOCK_EVT_MODE_PERIODIC:
	hpet_stop_counter();
	delta = ((uint64_t)(NSEC_PER_SEC / HZ)) * evt->mult;
	delta >>= evt->shift;
	now = hpet_readl(HPET_COUNTER);
	cmp = now + (unsigned int)delta;
	cfg = hpet_readl(HPET_Tn_CFG(timer));
		cfg |= HPET_TN_ENABLE | HPET_TN_PERIODIC |
		       HPET_TN_SETVAL | HPET_TN_32BIT;
	cfg |= HPET_TN_ENABLE | HPET_TN_PERIODIC | HPET_TN_SETVAL |
	       HPET_TN_32BIT;
	hpet_writel(cfg, HPET_Tn_CFG(timer));
	hpet_writel(cmp, HPET_Tn_CMP(timer));
	udelay(1);
@@ -335,35 +317,48 @@ static void hpet_set_mode(enum clock_event_mode mode,
	hpet_writel((unsigned int)delta, HPET_Tn_CMP(timer));
	hpet_start_counter();
	hpet_print_config();
		break;

	case CLOCK_EVT_MODE_ONESHOT:
	return 0;
}

static int hpet_set_oneshot(struct clock_event_device *evt, int timer)
{
	unsigned int cfg;

	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:
	case CLOCK_EVT_MODE_SHUTDOWN:
	return 0;
}

static int hpet_shutdown(struct clock_event_device *evt, int timer)
{
	unsigned int cfg;

	cfg = hpet_readl(HPET_Tn_CFG(timer));
	cfg &= ~HPET_TN_ENABLE;
	hpet_writel(cfg, HPET_Tn_CFG(timer));
		break;

	case CLOCK_EVT_MODE_RESUME:
		if (timer == 0) {
	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();
		break;
	}

	return 0;
}

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;
}

static void hpet_legacy_set_mode(enum clock_event_mode mode,
			struct clock_event_device *evt)
static int hpet_legacy_shutdown(struct clock_event_device *evt)
{
	hpet_set_mode(mode, evt, 0);
	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)
{
	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,
@@ -415,6 +424,22 @@ static int hpet_legacy_next_event(unsigned long delta,
	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
 */
@@ -459,11 +484,32 @@ void hpet_msi_read(struct hpet_dev *hdev, struct msi_msg *msg)
	msg->address_hi = 0;
}

static void hpet_msi_set_mode(enum clock_event_mode mode,
				struct clock_event_device *evt)
static int hpet_msi_shutdown(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);
	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,
@@ -523,10 +569,14 @@ static void init_one_hpet_msi_clockevent(struct hpet_dev *hdev, int cpu)

	evt->rating = 110;
	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->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->cpumask = cpumask_of(hdev->cpu);