linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Mika Westerberg <mika.westerberg@linux.intel.com>
To: Guenter Roeck <linux@roeck-us.net>
Cc: "Rafael J. Wysocki" <rjw@rjwysocki.net>,
	Len Brown <lenb@kernel.org>, Jean Delvare <jdelvare@suse.com>,
	Wolfram Sang <wsa@the-dreams.de>,
	Peter Tyser <ptyser@xes-inc.com>,
	Lee Jones <lee.jones@linaro.org>,
	Zha Qipeng <qipeng.zha@intel.com>,
	Darren Hart <dvhart@infradead.org>,
	Wim Van Sebroeck <wim@iguana.be>,
	linux-acpi@vger.kernel.org, linux-kernel@vger.kernel.org
Subject: Re: [PATCH 1/4] ACPI / watchdog: Add support for WDAT hardware watchdog
Date: Wed, 14 Sep 2016 18:29:17 +0300	[thread overview]
Message-ID: <20160914152917.GA1811@lahna.fi.intel.com> (raw)
In-Reply-To: <dce4b919-a861-ca05-47e0-71d743f9a017@roeck-us.net>

On Wed, Sep 14, 2016 at 07:54:34AM -0700, Guenter Roeck wrote:
> On 09/14/2016 01:06 AM, Mika Westerberg wrote:
> > On Tue, Sep 13, 2016 at 02:00:25PM -0700, Guenter Roeck wrote:
> > > On 09/13/2016 08:23 AM, Mika Westerberg wrote:
> > > > Starting from Intel Skylake the iTCO watchdog timer registers were moved to
> > > > reside in the same register space with SMBus host controller.  Not all
> > > > needed registers are available though and we need to unhide P2SB (Primary
> > > > to Sideband) device briefly to be able to read status of required NO_REBOOT
> > > > bit. The i2c-i801.c SMBus driver used to handle this and creation of the
> > > > iTCO watchdog platform device.
> > > > 
> > > > Windows, on the other hand, does not use the iTCO watchdog hardware
> > > > directly even if it is available. Instead it relies on ACPI Watchdog Action
> > > > Table (WDAT) table to describe the watchdog hardware to the OS. This table
> > > > contains necessary information about the the hardware and also set of
> > > > actions which are executed by a driver as needed.
> > > > 
> > > > This patch implements a new watchdog driver that takes advantage of the
> > > > ACPI WDAT table. We split the functionality into two parts: first part
> > > > enumerates the WDAT table and if found, populates resources and creates
> > > > platform device for the actual driver. The second part is the driver
> > > > itself.
> > > > 
> > > > The reason for the split is that this way we can make the driver itself to
> > > > be a module and loaded automatically if the WDAT table is found. Otherwise
> > > > the module is not loaded.
> > > > 
> > > What I don't really like is that the driver won't be in the watchdog directory,
> > > and will thus easily be overlooked in the future by watchdog maintainers.
> > 
> > It is in ACPI directory because we expose the functionality to users as
> > "ACPI Watchdog Action Table (WDAT)" which works with other similar table
> > options in drivers/acpi/Kconfig.
> > 
> > I'm fine moving the driver itself (wdat_wdt.c) under drivers/watchdog
> > but at least the enumeration part should be part of drivers/acpi and I
> > would still like to have only one user selectable option.
> > 
> 
> SGTM, but up to you and Wim to decide, really.
> 
> > > > +	wdat->wdd.max_timeout = wdat->period * tbl->max_count / 1000;
> > > > +	wdat->wdd.min_timeout = wdat->period * tbl->min_count / 1000;
> > > 
> > > Are those guaranteed to be correct, ie max_timeout >= min_timeout
> > > and both valid ?
> > 
> > The WDAT spec says nothing about those. I'll add sanity check here and
> > return -EINVAL if the values cannot be used. While there I think I can
> > do the same for tbl->timer_period, just in case.
> > 
> Using max_hw_heartbeat_ms would help a bit here. Then the actual timeout
> is not limited by the hardware maximum, and the watchdog core will ping
> the watchdog if the selected timeout is larger than the maximum hardware
> timeout.
> 
> Not sure how well the core would handle a maximum timeout of 1ms, though,
> so some basic sanity checking might still make sense.

OK

> > > Reason for asking is that the core will accept any timeouts if, for
> > > example, max_timeout is 0.
> > > 
> > > > +	wdat->stopped_in_sleep = tbl->flags & ACPI_WDAT_STOPPED;
> > > > +	wdat->wdd.info = &wdat_wdt_info;
> > > > +	wdat->wdd.ops = &wdat_wdt_ops;
> > > > +	wdat->pdev = pdev;
> > > > +
> > > > +	/* Request and map all resources */
> > > > +	for (i = 0; i < pdev->num_resources; i++) {
> > > > +		void __iomem *reg;
> > > > +
> > > > +		res = &pdev->resource[i];
> > > > +		if (resource_type(res) == IORESOURCE_MEM) {
> > > > +			reg = devm_ioremap_resource(&pdev->dev, res);
> > > > +		} else if (resource_type(res) == IORESOURCE_IO) {
> > > > +			reg = devm_ioport_map(&pdev->dev, res->start, 1);
> > > > +		} else {
> > > > +			dev_err(&pdev->dev, "Unsupported resource\n");
> > > > +			return -EINVAL;
> > > > +		}
> > > > +
> > > > +		if (!reg)
> > > > +			return -ENOMEM;
> > > > +
> > > > +		regs[i] = reg;
> > > > +	}
> > > > +
> > > > +	entries = (struct acpi_wdat_entry *)(tbl + 1);
> > > > +	for (i = 0; i < tbl->entries; i++) {
> > > > +		const struct acpi_generic_address *gas;
> > > > +		struct wdat_instruction *instr;
> > > > +		struct list_head *instructions;
> > > > +		unsigned int action;
> > > > +		struct resource r;
> > > > +		int j;
> > > > +
> > > > +		action = entries[i].action;
> > > > +		if (action >= MAX_WDAT_ACTIONS) {
> > > > +			dev_dbg(&pdev->dev, "Skipping unknown action: %u\n",
> > > > +				action);
> > > > +			continue;
> > > > +		}
> > > > +
> > > > +		instr = devm_kzalloc(&pdev->dev, sizeof(*instr), GFP_KERNEL);
> > > > +		if (!instr)
> > > > +			return -ENOMEM;
> > > > +
> > > > +		INIT_LIST_HEAD(&instr->node);
> > > > +		instr->entry = entries[i];
> > > > +
> > > > +		gas = &entries[i].register_region;
> > > > +
> > > > +		memset(&r, 0, sizeof(r));
> > > > +		r.start = gas->address;
> > > > +		r.end = r.start + gas->access_width;
> > > > +		if (gas->space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY) {
> > > > +			r.flags = IORESOURCE_MEM;
> > > > +		} else if (gas->space_id == ACPI_ADR_SPACE_SYSTEM_IO) {
> > > > +			r.flags = IORESOURCE_IO;
> > > > +		} else {
> > > > +			dev_dbg(&pdev->dev, "Unsupported address space: %d\n",
> > > > +				gas->space_id);
> > > > +			continue;
> > > > +		}
> > > > +
> > > > +		/* Find the matching resource */
> > > > +		for (j = 0; j < pdev->num_resources; j++) {
> > > > +			res = &pdev->resource[j];
> > > > +			if (resource_contains(res, &r)) {
> > > > +				instr->reg = regs[j] + r.start - res->start;
> > > > +				break;
> > > > +			}
> > > > +		}
> > > > +
> > > > +		if (!instr->reg) {
> > > > +			dev_err(&pdev->dev, "I/O resource not found\n");
> > > > +			return -EINVAL;
> > > > +		}
> > > > +
> > > > +		instructions = wdat->instructions[action];
> > > > +		if (!instructions) {
> > > > +			instructions = devm_kzalloc(&pdev->dev,
> > > > +					sizeof(*instructions), GFP_KERNEL);
> > > > +			if (!instructions)
> > > > +				return -ENOMEM;
> > > > +
> > > > +			INIT_LIST_HEAD(instructions);
> > > > +			wdat->instructions[action] = instructions;
> > > > +		}
> > > > +
> > > > +		list_add_tail(&instr->node, instructions);
> > > > +	}
> > > > +
> > > > +	/* Make sure it is stopped now */
> > > > +	ret = wdat_wdt_stop(&wdat->wdd);
> > > 
> > > Why ? You could set max_hw_heartbeat_ms instead of max_timeout and
> > > inform the watchdog core that the watchdog is running (by setting
> > > the WDOG_HW_RUNNING status flag).
> > 
> > Hmm is the watchdog core then kicking it?
> > 
> > It is stopped here to make sure system does not reboot until userspace
> > explicitly opens the device and starts kicking the watchdog.
> > 
> 
> Yes, that functionality was recently added to the watchdog core.

Cool. So then I'll just set WDOG_HW_RUNNING and drop stopping the
watchdog here.

> > > > +		 */
> > > > +		ret = wdat_wdt_stop(&wdat->wdd);
> > > > +		if (ret)
> > > > +			return ret;
> > > > +
> > > > +		ret = wdat_wdt_set_timeout(&wdat->wdd, wdat->wdd.timeout);
> > > > +		if (ret)
> > > > +			return ret;
> > > > +
> > > > +		ret = wdat_wdt_enable_reboot(wdat);
> > > > +		if (ret)
> > > > +			return ret;
> > > > +
> > > > +		ret = wdat_wdt_ping(&wdat->wdd);
> > > > +		if (ret)
> > > > +			return ret;
> > > 
> > > The watchdog is already running here. Why start it again ?
> > 
> > No it's not. We stopped it few lines above before we reprogram it.
> > 
> But you start it below, don't you ? And it is stopped here, so why ping it ?
> 
> If it is necessary to ping the watchdog before starting it,
> maybe the start code should do it ?

Now that you mentioned, I don't immediately remember why we ping it
here. It should not be necessary at this point. I'll remove that call in
next revision.

  reply	other threads:[~2016-09-14 15:38 UTC|newest]

Thread overview: 12+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-09-13 15:23 [PATCH 0/4] ACPI: Add support for WDAT (Watchdog Action Table) Mika Westerberg
2016-09-13 15:23 ` [PATCH 1/4] ACPI / watchdog: Add support for WDAT hardware watchdog Mika Westerberg
2016-09-13 21:00   ` Guenter Roeck
2016-09-14  8:06     ` Mika Westerberg
2016-09-14 14:54       ` Guenter Roeck
2016-09-14 15:29         ` Mika Westerberg [this message]
2016-09-13 15:23 ` [PATCH 2/4] mfd: lpc_ich: Do not create iTCO watchdog when WDAT table exists Mika Westerberg
2016-09-14 20:03   ` Guenter Roeck
2016-09-13 15:23 ` [PATCH 3/4] i2c: i801: " Mika Westerberg
2016-09-14 20:04   ` Guenter Roeck
2016-09-13 15:23 ` [PATCH 4/4] platform/x86: intel_pmc_ipc: " Mika Westerberg
2016-09-14 20:04   ` Guenter Roeck

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=20160914152917.GA1811@lahna.fi.intel.com \
    --to=mika.westerberg@linux.intel.com \
    --cc=dvhart@infradead.org \
    --cc=jdelvare@suse.com \
    --cc=lee.jones@linaro.org \
    --cc=lenb@kernel.org \
    --cc=linux-acpi@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux@roeck-us.net \
    --cc=ptyser@xes-inc.com \
    --cc=qipeng.zha@intel.com \
    --cc=rjw@rjwysocki.net \
    --cc=wim@iguana.be \
    --cc=wsa@the-dreams.de \
    /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).