linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Thomas Gleixner <tglx@linutronix.de>
To: LKML <linux-kernel@vger.kernel.org>
Cc: x86@kernel.org, Peter Zijlstra <peterz@infradead.org>,
	Ricardo Neri <ricardo.neri-calderon@linux.intel.com>,
	Ashok Raj <ashok.raj@intel.com>,
	Andi Kleen <andi.kleen@intel.com>,
	Suravee Suthikulpanit <Suravee.Suthikulpanit@amd.com>,
	Stephane Eranian <eranian@google.com>,
	Ravi Shankar <ravi.v.shankar@intel.com>
Subject: [patch 18/29] x86/hpet: Introduce struct hpet_base and struct hpet_channel
Date: Sun, 23 Jun 2019 15:23:58 +0200	[thread overview]
Message-ID: <20190623132435.728456320@linutronix.de> (raw)
In-Reply-To: 20190623132340.463097504@linutronix.de

Introduce new data structures to replace the ad hoc collection of separate
variables and pointers.

Replace the boot configuration store and restore as a first step.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
 arch/x86/kernel/hpet.c |   84 ++++++++++++++++++++++++++++---------------------
 1 file changed, 49 insertions(+), 35 deletions(-)

--- a/arch/x86/kernel/hpet.c
+++ b/arch/x86/kernel/hpet.c
@@ -22,6 +22,17 @@ struct hpet_dev {
 	char				name[10];
 };
 
+struct hpet_channel {
+	unsigned int			num;
+	unsigned int			boot_cfg;
+};
+
+struct hpet_base {
+	unsigned int			nr_channels;
+	unsigned int			boot_cfg;
+	struct hpet_channel		*channels;
+};
+
 #define HPET_MASK			CLOCKSOURCE_MASK(32)
 
 #define HPET_DEV_USED_BIT		2
@@ -48,7 +59,7 @@ static struct irq_domain		*hpet_domain;
 #endif
 
 static void __iomem			*hpet_virt_address;
-static u32				*hpet_boot_cfg;
+static struct hpet_base			hpet_base;
 
 static bool				hpet_legacy_int_enabled;
 static unsigned long			hpet_freq;
@@ -860,6 +871,7 @@ int __init hpet_enable(void)
 {
 	u32 hpet_period, cfg, id;
 	unsigned int i, channels;
+	struct hpet_channel *hc;
 	u64 freq;
 
 	if (!is_hpet_capable())
@@ -899,34 +911,39 @@ int __init hpet_enable(void)
 	/* This is the HPET channel number which is zero based */
 	channels = ((id & HPET_ID_NUMBER) >> HPET_ID_NUMBER_SHIFT) + 1;
 
-#ifdef CONFIG_HPET_EMULATE_RTC
 	/*
 	 * The legacy routing mode needs at least two channels, tick timer
 	 * and the rtc emulation channel.
 	 */
-	if (channels < 2)
+	if (IS_ENABLED(CONFIG_HPET_EMULATE_RTC) && channels < 2)
 		goto out_nohpet;
-#endif
 
+	hc = kcalloc(channels, sizeof(*hc), GFP_KERNEL);
+	if (!hc) {
+		pr_warn("Disabling HPET.\n");
+		goto out_nohpet;
+	}
+	hpet_base.channels = hc;
+	hpet_base.nr_channels = channels;
+
+	/* Read, store and sanitize the global configuration */
 	cfg = hpet_readl(HPET_CFG);
-	/* Allocate entries for the global and the channel configurations */
-	hpet_boot_cfg = kmalloc_array(channels + 1, sizeof(*hpet_boot_cfg),
-				      GFP_KERNEL);
-	if (hpet_boot_cfg)
-		*hpet_boot_cfg = cfg;
-	else
-		pr_warn("HPET initial state will not be saved\n");
+	hpet_base.boot_cfg = cfg;
 	cfg &= ~(HPET_CFG_ENABLE | HPET_CFG_LEGACY);
 	hpet_writel(cfg, HPET_CFG);
 	if (cfg)
 		pr_warn("Global config: Unknown bits %#x\n", cfg);
 
-	for (i = 0; i < channels; ++i) {
+	/* Read, store and sanitize the per channel configuration */
+	for (i = 0; i < channels; i++, hc++) {
+		hc->num = i;
+
 		cfg = hpet_readl(HPET_Tn_CFG(i));
-		if (hpet_boot_cfg)
-			hpet_boot_cfg[i + 1] = cfg;
+		hc->boot_cfg = cfg;
+
 		cfg &= ~(HPET_TN_ENABLE | HPET_TN_LEVEL | HPET_TN_FSB);
 		hpet_writel(cfg, HPET_Tn_CFG(i));
+
 		cfg &= ~(HPET_TN_PERIODIC | HPET_TN_PERIODIC_CAP
 			 | HPET_TN_64BIT_CAP | HPET_TN_32BIT | HPET_TN_ROUTE
 			 | HPET_TN_FSB | HPET_TN_FSB_CAP);
@@ -944,6 +961,9 @@ int __init hpet_enable(void)
 	return 0;
 
 out_nohpet:
+	kfree(hpet_base.channels);
+	hpet_base.channels = NULL;
+	hpet_base.nr_channels = 0;
 	hpet_clear_mapping();
 	hpet_address = 0;
 	return 0;
@@ -1000,30 +1020,24 @@ fs_initcall(hpet_late_init);
 
 void hpet_disable(void)
 {
-	if (is_hpet_capable() && hpet_virt_address) {
-		unsigned int cfg = hpet_readl(HPET_CFG), id, last;
-
-		if (hpet_boot_cfg)
-			cfg = *hpet_boot_cfg;
-		else if (hpet_legacy_int_enabled) {
-			cfg &= ~HPET_CFG_LEGACY;
-			hpet_legacy_int_enabled = false;
-		}
-		cfg &= ~HPET_CFG_ENABLE;
-		hpet_writel(cfg, HPET_CFG);
-
-		if (!hpet_boot_cfg)
-			return;
+	unsigned int i;
+	u32 cfg;
 
-		id = hpet_readl(HPET_ID);
-		last = ((id & HPET_ID_NUMBER) >> HPET_ID_NUMBER_SHIFT);
+	if (!is_hpet_capable() || !hpet_virt_address)
+		return;
 
-		for (id = 0; id <= last; ++id)
-			hpet_writel(hpet_boot_cfg[id + 1], HPET_Tn_CFG(id));
+	/* Restore boot configuration with the enable bit cleared */
+	cfg = hpet_base.boot_cfg;
+	cfg &= ~HPET_CFG_ENABLE;
+	hpet_writel(cfg, HPET_CFG);
 
-		if (*hpet_boot_cfg & HPET_CFG_ENABLE)
-			hpet_writel(*hpet_boot_cfg, HPET_CFG);
-	}
+	/* Restore the channel boot configuration */
+	for (i = 0; i < hpet_base.nr_channels; i++)
+		hpet_writel(hpet_base.channels[i].boot_cfg, HPET_Tn_CFG(i));
+
+	/* If the HPET was enabled at boot time, reenable it */
+	if (hpet_base.boot_cfg & HPET_CFG_ENABLE)
+		hpet_writel(hpet_base.boot_cfg, HPET_CFG);
 }
 
 #ifdef CONFIG_HPET_EMULATE_RTC



  parent reply	other threads:[~2019-06-23 13:28 UTC|newest]

Thread overview: 66+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-06-23 13:23 [patch 00/29] x86/hpet: Cleanup the channel management Thomas Gleixner
2019-06-23 13:23 ` [patch 01/29] x86/hpet: Simplify CPU online code Thomas Gleixner
2019-06-27 23:34   ` [tip:x86/timers] " tip-bot for Thomas Gleixner
2019-06-23 13:23 ` [patch 02/29] x86/hpet: Replace printk(KERN...) with pr_...() Thomas Gleixner
2019-06-27 23:34   ` [tip:x86/timers] " tip-bot for Thomas Gleixner
2019-06-23 13:23 ` [patch 03/29] x86/hpet: Restructure init code Thomas Gleixner
2019-06-27 23:35   ` [tip:x86/timers] " tip-bot for Thomas Gleixner
2019-06-23 13:23 ` [patch 04/29] x86/hpet: Remove pointless x86-64 specific #include Thomas Gleixner
2019-06-27 23:36   ` [tip:x86/timers] " tip-bot for Thomas Gleixner
2019-06-23 13:23 ` [patch 05/29] x86/hpet: Remove unused parameter from hpet_next_event() Thomas Gleixner
2019-06-27 23:36   ` [tip:x86/timers] " tip-bot for Thomas Gleixner
2019-06-23 13:23 ` [patch 06/29] x86/hpet: Remove the unused hpet_msi_read() function Thomas Gleixner
2019-06-27 23:37   ` [tip:x86/timers] " tip-bot for Thomas Gleixner
2019-06-23 13:23 ` [patch 07/29] x86/hpet: Mark init functions __init Thomas Gleixner
2019-06-27 23:38   ` [tip:x86/timers] " tip-bot for Thomas Gleixner
2019-06-23 13:23 ` [patch 08/29] x86/hpet: Sanitize stub functions Thomas Gleixner
2019-06-27 23:39   ` [tip:x86/timers] " tip-bot for Thomas Gleixner
2019-06-23 13:23 ` [patch 09/29] x86/hpet: Move static and global variables to one place Thomas Gleixner
2019-06-27 23:39   ` [tip:x86/timers] " tip-bot for Thomas Gleixner
2019-06-23 13:23 ` [patch 10/29] x86/hpet: Shuffle code around for readability sake Thomas Gleixner
2019-06-27 23:40   ` [tip:x86/timers] " tip-bot for Thomas Gleixner
2019-06-23 13:23 ` [patch 11/29] x86/hpet: Separate counter check out of clocksource register code Thomas Gleixner
2019-06-27 23:41   ` [tip:x86/timers] " tip-bot for Thomas Gleixner
2019-06-23 13:23 ` [patch 12/29] x86/hpet: Simplify counter validation Thomas Gleixner
2019-06-27 23:41   ` [tip:x86/timers] " tip-bot for Thomas Gleixner
2019-06-23 13:23 ` [patch 13/29] x86/hpet: Decapitalize and rename EVT_TO_HPET_DEV Thomas Gleixner
2019-06-27 23:42   ` [tip:x86/timers] " tip-bot for Thomas Gleixner
2019-06-23 13:23 ` [patch 14/29] x86/hpet: Remove not required includes Thomas Gleixner
2019-06-27 23:43   ` [tip:x86/timers] " tip-bot for Ingo Molnar
2019-06-23 13:23 ` [patch 15/29] x86/hpet: Make naming consistent Thomas Gleixner
2019-06-27 23:44   ` [tip:x86/timers] " tip-bot for Ingo Molnar
2019-06-23 13:23 ` [patch 16/29] x86/hpet: Clean up comments Thomas Gleixner
2019-06-27 23:44   ` [tip:x86/timers] " tip-bot for Ingo Molnar
2019-06-23 13:23 ` [patch 17/29] x86/hpet: Coding style cleanup Thomas Gleixner
2019-06-27 23:45   ` [tip:x86/timers] " tip-bot for Ingo Molnar
2019-06-23 13:23 ` Thomas Gleixner [this message]
2019-06-27 23:46   ` [tip:x86/timers] x86/hpet: Introduce struct hpet_base and struct hpet_channel tip-bot for Thomas Gleixner
2019-06-23 13:23 ` [patch 19/29] x86/hpet: Use cached channel data Thomas Gleixner
2019-06-27 23:46   ` [tip:x86/timers] " tip-bot for Thomas Gleixner
2019-06-23 13:24 ` [patch 20/29] x86/hpet: Add mode information to struct hpet_channel Thomas Gleixner
2019-06-27 23:47   ` [tip:x86/timers] " tip-bot for Thomas Gleixner
2019-06-23 13:24 ` [patch 21/29] x86/hpet: Add function to select a /dev/hpet channel Thomas Gleixner
2019-06-27 23:48   ` [tip:x86/timers] " tip-bot for Thomas Gleixner
2019-06-23 13:24 ` [patch 22/29] x86/hpet: Rename variables to prepare for switching to channels Thomas Gleixner
2019-06-27 23:49   ` [tip:x86/timers] " tip-bot for Ingo Molnar
2019-06-23 13:24 ` [patch 23/29] x86/hpet: Move clockevents into channels Thomas Gleixner
2019-06-27 23:49   ` [tip:x86/timers] " tip-bot for Thomas Gleixner
2019-06-23 13:24 ` [patch 24/29] x86/hpet: Use cached info instead of extra flags Thomas Gleixner
2019-06-26 21:20   ` Ingo Molnar
2019-06-27 23:50   ` [tip:x86/timers] " tip-bot for Thomas Gleixner
2019-06-23 13:24 ` [patch 25/29] x86/hpet: Wrap legacy clockevent in hpet_channel Thomas Gleixner
2019-06-27 23:51   ` [tip:x86/timers] " tip-bot for Thomas Gleixner
2019-06-23 13:24 ` [patch 26/29] x86/hpet: Consolidate clockevent functions Thomas Gleixner
2019-06-26 21:17   ` Ingo Molnar
2019-06-27 22:44     ` Thomas Gleixner
2019-06-27 22:53       ` Thomas Gleixner
2019-06-28  8:32         ` Ingo Molnar
2019-06-27 23:51   ` [tip:x86/timers] " tip-bot for Thomas Gleixner
2019-06-23 13:24 ` [patch 27/29] x86/hpet: Carve out shareable parts of init_one_hpet_msi_clockevent() Thomas Gleixner
2019-06-27 23:52   ` [tip:x86/timers] " tip-bot for Thomas Gleixner
2019-06-23 13:24 ` [patch 28/29] x86/hpet: Use common init for legacy clockevent Thomas Gleixner
2019-06-26 21:13   ` Ingo Molnar
2019-06-27 23:53   ` [tip:x86/timers] " tip-bot for Thomas Gleixner
2019-06-23 13:24 ` [patch 29/29] x86/hpet: Use channel for legacy clockevent storage Thomas Gleixner
2019-06-27 23:53   ` [tip:x86/timers] " tip-bot for Thomas Gleixner
2019-06-26 21:22 ` [patch 00/29] x86/hpet: Cleanup the channel management Ingo Molnar

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20190623132435.728456320@linutronix.de \
    --to=tglx@linutronix.de \
    --cc=Suravee.Suthikulpanit@amd.com \
    --cc=andi.kleen@intel.com \
    --cc=ashok.raj@intel.com \
    --cc=eranian@google.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=peterz@infradead.org \
    --cc=ravi.v.shankar@intel.com \
    --cc=ricardo.neri-calderon@linux.intel.com \
    --cc=x86@kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).