* [PATCH v2] cs5535-mfgpt: Add another reset method
2013-04-02 6:29 linux-next: build failure after merge of the char-misc tree Stephen Rothwell
@ 2013-04-02 6:46 ` Richard Weinberger
2013-04-02 7:17 ` Stephen Rothwell
2013-04-02 6:49 ` linux-next: build failure after merge of the char-misc tree Richard Weinberger
1 sibling, 1 reply; 5+ messages in thread
From: Richard Weinberger @ 2013-04-02 6:46 UTC (permalink / raw)
To: greg; +Cc: arnd, sfr, linux-next, linux-kernel, Richard Weinberger
The CS5535/CS5536 MFGPT has no support to reset the device.
The current method uses an undocumented bit but does not work on all
devices. At least on my ALIX board it completely freezes the board.
This new method tries to soft reset all timers by unconfiguring them.
But this does not clear the RO setup register and therefore it has to
be ignored while probing.
Resetting the timers is not only needed on broken BIOSes also when
kexec is used. Otherwise the new kernel will find preconfigured timers
and odd things will happen.
Signed-off-by: Richard Weinberger <richard@nod.at>
---
drivers/misc/cs5535-mfgpt.c | 41 +++++++++++++++++++++++++++++++++++++----
1 file changed, 37 insertions(+), 4 deletions(-)
diff --git a/drivers/misc/cs5535-mfgpt.c b/drivers/misc/cs5535-mfgpt.c
index 9858f36..effd8c6 100644
--- a/drivers/misc/cs5535-mfgpt.c
+++ b/drivers/misc/cs5535-mfgpt.c
@@ -24,8 +24,11 @@
static int mfgpt_reset_timers;
module_param_named(mfgptfix, mfgpt_reset_timers, int, 0644);
-MODULE_PARM_DESC(mfgptfix, "Reset the MFGPT timers during init; "
- "required by some broken BIOSes (ie, TinyBIOS < 0.99).");
+MODULE_PARM_DESC(mfgptfix, "Try to reset the MFGPT timers during init; "
+ "required by some broken BIOSes (ie, TinyBIOS < 0.99) or kexec "
+ "(1 = reset the MFGPT using an undocumented bit, "
+ "2 = perform a soft reset by unconfiguring all timers); "
+ "use what works best for you.");
struct cs5535_mfgpt_timer {
struct cs5535_mfgpt_chip *chip;
@@ -256,6 +259,28 @@ static void reset_all_timers(void)
}
/*
+ * This is another sledgehammer to reset all MFGPT timers.
+ * Instead of using the undocumented bit method it clears
+ * IRQ, NMI and RESET settings.
+ */
+static void soft_reset(void)
+{
+ int i;
+ struct cs5535_mfgpt_timer t;
+
+ for (i = 0; i < MFGPT_MAX_TIMERS; i++) {
+ t.nr = i;
+
+ cs5535_mfgpt_toggle_event(&t, MFGPT_CMP1, MFGPT_EVENT_RESET, 0);
+ cs5535_mfgpt_toggle_event(&t, MFGPT_CMP2, MFGPT_EVENT_RESET, 0);
+ cs5535_mfgpt_toggle_event(&t, MFGPT_CMP1, MFGPT_EVENT_NMI, 0);
+ cs5535_mfgpt_toggle_event(&t, MFGPT_CMP2, MFGPT_EVENT_NMI, 0);
+ cs5535_mfgpt_toggle_event(&t, MFGPT_CMP1, MFGPT_EVENT_IRQ, 0);
+ cs5535_mfgpt_toggle_event(&t, MFGPT_CMP2, MFGPT_EVENT_IRQ, 0);
+ }
+}
+
+/*
* Check whether any MFGPTs are available for the kernel to use. In most
* cases, firmware that uses AMD's VSA code will claim all timers during
* bootup; we certainly don't want to take them if they're already in use.
@@ -271,15 +296,17 @@ static int scan_timers(struct cs5535_mfgpt_chip *mfgpt)
int i;
/* bios workaround */
- if (mfgpt_reset_timers)
+ if (mfgpt_reset_timers == 1)
reset_all_timers();
+ else if (mfgpt_reset_timers == 2)
+ soft_reset();
/* just to be safe, protect this section w/ lock */
spin_lock_irqsave(&mfgpt->lock, flags);
for (i = 0; i < MFGPT_MAX_TIMERS; i++) {
timer.nr = i;
val = cs5535_mfgpt_read(&timer, MFGPT_REG_SETUP);
- if (!(val & MFGPT_SETUP_SETUP)) {
+ if (!(val & MFGPT_SETUP_SETUP) || mfgpt_reset_timers == 2) {
__set_bit(i, mfgpt->avail);
timers++;
}
@@ -294,6 +321,12 @@ static int cs5535_mfgpt_probe(struct platform_device *pdev)
struct resource *res;
int err = -EIO, t;
+ if (mfgpt_reset_timers < 0 || mfgpt_reset_timers > 2) {
+ dev_err(&pdev->dev, "Bad mfgpt_reset_timers value: %i\n",
+ mfgpt_reset_timers);
+ goto done;
+ }
+
/* There are two ways to get the MFGPT base address; one is by
* fetching it from MSR_LBAR_MFGPT, the other is by reading the
* PCI BAR info. The latter method is easier (especially across
--
1.8.1.4
^ permalink raw reply related [flat|nested] 5+ messages in thread
* Re: linux-next: build failure after merge of the char-misc tree
2013-04-02 6:29 linux-next: build failure after merge of the char-misc tree Stephen Rothwell
2013-04-02 6:46 ` [PATCH v2] cs5535-mfgpt: Add another reset method Richard Weinberger
@ 2013-04-02 6:49 ` Richard Weinberger
1 sibling, 0 replies; 5+ messages in thread
From: Richard Weinberger @ 2013-04-02 6:49 UTC (permalink / raw)
To: Stephen Rothwell; +Cc: Greg KH, Arnd Bergmann, linux-next, linux-kernel
Am Tue, 2 Apr 2013 17:29:50 +1100
schrieb Stephen Rothwell <sfr@canb.auug.org.au>:
> Hi all,
>
> After merging the char-misc tree, today's linux-next build (x86_64
> allmodconfig) failed like this:
>
> drivers/misc/cs5535-mfgpt.c:30:3: warning: missing terminating "
> character [enabled by default] drivers/misc/cs5535-mfgpt.c:31:31:
> warning: missing terminating " character [enabled by default]
> drivers/misc/cs5535-mfgpt.c:384:0: error: unterminated argument list
> invoking macro "MODULE_PARM_DESC" drivers/misc/cs5535-mfgpt.c:27:1:
> error: expected '=', ',', ';', 'asm' or '__attribute__' at end of
> input
>
> Caused by commit 945480b159aa ("cs5535-mfgpt: Add another reset
> method").
>
> I have used the char-misc tree from next-20130328 for today.
New patch sent.
A terminating quote was missing.
Looks like I fat fingered it while editing the patch file by hand...
Sorry for that,
//richard
^ permalink raw reply [flat|nested] 5+ messages in thread