Re: [PATCH/RFC] Add support for PowerQUICC watchdog

2007-12-28 Thread Stephen Rothwell
Hi Jochen,

Just a couple of suggestions.

On Fri, 28 Dec 2007 16:13:11 +0100 Jochen Friedrich <[EMAIL PROTECTED]> wrote:
>
> +int __init pq_wdt_early_init(void)
> +{
>
> + data = of_get_property(soc, "bus-frequency", NULL);
> + if (!data) {
> + of_node_put(soc);
> + printk(KERN_ERR "Could not find bus-frequency in soc node\n");
> + ret = -ENODEV;
> + goto out;
> + }
> + of_node_put(soc);

If you move the "of_node_put(soc)" just above the "if (!data)" then you
won't need to repeat it.

> +static struct of_platform_driver pq_wdt_driver = {
> + .owner  = THIS_MODULE,
> + .name   = "pq-wdt",
> + .match_table= pq_wdt_match,
> + .probe  = pq_wdt_probe,
> + .remove = pq_wdt_remove,
> +};

We are removing the owner and name fields from struct of_platform_driver, so 
the preferred initialization looks like this:

static struct of_platform_driver pq_wdt_driver = {
.match_table= pq_wdt_match,
.probe  = pq_wdt_probe,
.remove = pq_wdt_remove,
.driver = {
.name   = "pq-wdt",
.owner  = THIS_MODULE,
}
};

or similar.

-- 
Cheers,
Stephen Rothwell[EMAIL PROTECTED]
http://www.canb.auug.org.au/~sfr/


pgpdbMrwDEd84.pgp
Description: PGP signature


[PATCH/RFC] Add support for PowerQUICC watchdog

2007-12-28 Thread Jochen Friedrich

The PowerQUICC series has a watchdog which can be activated by the boot
loader and then needs to be reset in regular intervals. Once the
watchdog is enabled, it can't be disabled anymore. This patch adds
support for this kind of watchdog. An early init function is provided to
manually reset the watchdog in early board setup. Later, a kernel timer
is used to reset the watchdog until the watchdog driver is opened from
user space. This replaces mpc8xx_wdt.c (only usable for ARCH=ppc) and
mpc83xx_wdt.c (untested on this platform).

Signed-off-by: Jochen Friedrich <[EMAIL PROTECTED]>
---
arch/powerpc/platforms/8xx/mpc86xads_setup.c |5 +
arch/powerpc/platforms/8xx/mpc885ads_setup.c |5 +
arch/powerpc/sysdev/Makefile |3 +
arch/powerpc/sysdev/pq_wdt.c |  204 +++
arch/powerpc/sysdev/pq_wdt.h |   28 
drivers/watchdog/Kconfig |   13 ++-
drivers/watchdog/Makefile|1 +
drivers/watchdog/pq_wdt.c|  222 ++
8 files changed, 480 insertions(+), 1 deletions(-)
create mode 100644 arch/powerpc/sysdev/pq_wdt.c
create mode 100644 arch/powerpc/sysdev/pq_wdt.h
create mode 100644 drivers/watchdog/pq_wdt.c

diff --git a/arch/powerpc/platforms/8xx/mpc86xads_setup.c 
b/arch/powerpc/platforms/8xx/mpc86xads_setup.c
index 4901283..c468ec2 100644
--- a/arch/powerpc/platforms/8xx/mpc86xads_setup.c
+++ b/arch/powerpc/platforms/8xx/mpc86xads_setup.c
@@ -38,6 +38,7 @@
#include 

#include 
+#include 

static void init_smc1_uart_ioports(struct fs_uart_platform_info* fpi);
static void init_smc2_uart_ioports(struct fs_uart_platform_info* fpi);
@@ -251,6 +252,10 @@ static void __init mpc86xads_setup_arch(void)
mpc86xads_board_setup();

ROOT_DEV = Root_NFS;
+
+#if defined(CONFIG_PQ_WDT) || defined(CONFIG_PQ_WDT_MODULE)
+   pq_wdt_early_init();
+#endif
}

static int __init mpc86xads_probe(void)
diff --git a/arch/powerpc/platforms/8xx/mpc885ads_setup.c 
b/arch/powerpc/platforms/8xx/mpc885ads_setup.c
index 2cf1b6a..f076b67 100644
--- a/arch/powerpc/platforms/8xx/mpc885ads_setup.c
+++ b/arch/powerpc/platforms/8xx/mpc885ads_setup.c
@@ -41,6 +41,7 @@
#include 

#include 
+#include 

static u32 __iomem *bcsr, *bcsr5;

@@ -246,6 +247,10 @@ static void __init mpc885ads_setup_arch(void)
m8xx_pcmcia_ops.hw_ctrl = pcmcia_hw_setup;
m8xx_pcmcia_ops.voltage_set = pcmcia_set_voltage;
#endif
+
+#if defined(CONFIG_PQ_WDT) || defined(CONFIG_PQ_WDT_MODULE)
+   pq_wdt_early_init();
+#endif
}

static int __init mpc885ads_probe(void)
diff --git a/arch/powerpc/sysdev/Makefile b/arch/powerpc/sysdev/Makefile
index 99a77d7..84f190e 100644
--- a/arch/powerpc/sysdev/Makefile
+++ b/arch/powerpc/sysdev/Makefile
@@ -35,5 +35,8 @@ obj-$(CONFIG_CPM) += cpm_common.o
obj-$(CONFIG_CPM2)  += cpm2_common.o cpm2_pic.o
obj-$(CONFIG_PPC_DCR)   += dcr.o
obj-$(CONFIG_8xx)   += mpc8xx_pic.o commproc.o
+ifneq ($(CONFIG_PQ_WDT),)
+obj-y  += pq_wdt.o
+endif
obj-$(CONFIG_UCODE_PATCH)   += micropatch.o
endif
diff --git a/arch/powerpc/sysdev/pq_wdt.c b/arch/powerpc/sysdev/pq_wdt.c
new file mode 100644
index 000..0adbe42
--- /dev/null
+++ b/arch/powerpc/sysdev/pq_wdt.c
@@ -0,0 +1,204 @@
+/*
+ * pq_wdt.c - Freescale PowerQUICC watchdog driver
+ *
+ * Author: Florian Schirmer <[EMAIL PROTECTED]>
+ *
+ * 2002 (c) Florian Schirmer <[EMAIL PROTECTED]> This file is licensed under
+ * the terms of the GNU General Public License version 2. This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
+ *
+ * 2007 (c) Jochen Friedrich <[EMAIL PROTECTED]> ported to ARCH=powerpc and
+ * extended to be useful on any Power QUICC 1/2/2pro which have the same
+ * style of watchdog.
+ */
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "pq_wdt.h"
+
+struct pq_wdt {
+   __be32 res0;
+   __be32 swcrr; /* System watchdog control register */
+   __be32 swcnr; /* System watchdog count register */
+   u8 res1[2];
+   __be16 swsrr; /* System watchdog service register */
+};
+
+static int wdt_timeout;
+static int wdt_freq;
+static struct pq_wdt __iomem *wdt_reg;
+static int wdt_scale;
+
+void pq_wdt_reset(void)
+{
+   if (!wdt_reg)
+   return;
+
+   out_be16(_reg->swsrr, 0x556c);   /* write magic1 */
+   out_be16(_reg->swsrr, 0xaa39);   /* write magic2 */
+}
+EXPORT_SYMBOL(pq_wdt_reset);
+
+static void wdt_timer_func(unsigned long data);
+
+static struct timer_list wdt_timer =
+   TIMER_INITIALIZER(wdt_timer_func, 0, 0);
+
+void pq_wdt_stop_timer(void)
+{
+   del_timer(_timer);
+}
+EXPORT_SYMBOL_GPL(pq_wdt_stop_timer);
+
+void pq_wdt_install_timer(void)
+{
+   pq_wdt_reset();
+   mod_timer(_timer, jiffies + (HZ/2));
+}
+EXPORT_SYMBOL_GPL(pq_wdt_install_timer);
+
+static 

[PATCH/RFC] Add support for PowerQUICC watchdog

2007-12-28 Thread Jochen Friedrich

The PowerQUICC series has a watchdog which can be activated by the boot
loader and then needs to be reset in regular intervals. Once the
watchdog is enabled, it can't be disabled anymore. This patch adds
support for this kind of watchdog. An early init function is provided to
manually reset the watchdog in early board setup. Later, a kernel timer
is used to reset the watchdog until the watchdog driver is opened from
user space. This replaces mpc8xx_wdt.c (only usable for ARCH=ppc) and
mpc83xx_wdt.c (untested on this platform).

Signed-off-by: Jochen Friedrich [EMAIL PROTECTED]
---
arch/powerpc/platforms/8xx/mpc86xads_setup.c |5 +
arch/powerpc/platforms/8xx/mpc885ads_setup.c |5 +
arch/powerpc/sysdev/Makefile |3 +
arch/powerpc/sysdev/pq_wdt.c |  204 +++
arch/powerpc/sysdev/pq_wdt.h |   28 
drivers/watchdog/Kconfig |   13 ++-
drivers/watchdog/Makefile|1 +
drivers/watchdog/pq_wdt.c|  222 ++
8 files changed, 480 insertions(+), 1 deletions(-)
create mode 100644 arch/powerpc/sysdev/pq_wdt.c
create mode 100644 arch/powerpc/sysdev/pq_wdt.h
create mode 100644 drivers/watchdog/pq_wdt.c

diff --git a/arch/powerpc/platforms/8xx/mpc86xads_setup.c 
b/arch/powerpc/platforms/8xx/mpc86xads_setup.c
index 4901283..c468ec2 100644
--- a/arch/powerpc/platforms/8xx/mpc86xads_setup.c
+++ b/arch/powerpc/platforms/8xx/mpc86xads_setup.c
@@ -38,6 +38,7 @@
#include asm/prom.h

#include sysdev/commproc.h
+#include sysdev/pq_wdt.h

static void init_smc1_uart_ioports(struct fs_uart_platform_info* fpi);
static void init_smc2_uart_ioports(struct fs_uart_platform_info* fpi);
@@ -251,6 +252,10 @@ static void __init mpc86xads_setup_arch(void)
mpc86xads_board_setup();

ROOT_DEV = Root_NFS;
+
+#if defined(CONFIG_PQ_WDT) || defined(CONFIG_PQ_WDT_MODULE)
+   pq_wdt_early_init();
+#endif
}

static int __init mpc86xads_probe(void)
diff --git a/arch/powerpc/platforms/8xx/mpc885ads_setup.c 
b/arch/powerpc/platforms/8xx/mpc885ads_setup.c
index 2cf1b6a..f076b67 100644
--- a/arch/powerpc/platforms/8xx/mpc885ads_setup.c
+++ b/arch/powerpc/platforms/8xx/mpc885ads_setup.c
@@ -41,6 +41,7 @@
#include asm/udbg.h

#include sysdev/commproc.h
+#include sysdev/pq_wdt.h

static u32 __iomem *bcsr, *bcsr5;

@@ -246,6 +247,10 @@ static void __init mpc885ads_setup_arch(void)
m8xx_pcmcia_ops.hw_ctrl = pcmcia_hw_setup;
m8xx_pcmcia_ops.voltage_set = pcmcia_set_voltage;
#endif
+
+#if defined(CONFIG_PQ_WDT) || defined(CONFIG_PQ_WDT_MODULE)
+   pq_wdt_early_init();
+#endif
}

static int __init mpc885ads_probe(void)
diff --git a/arch/powerpc/sysdev/Makefile b/arch/powerpc/sysdev/Makefile
index 99a77d7..84f190e 100644
--- a/arch/powerpc/sysdev/Makefile
+++ b/arch/powerpc/sysdev/Makefile
@@ -35,5 +35,8 @@ obj-$(CONFIG_CPM) += cpm_common.o
obj-$(CONFIG_CPM2)  += cpm2_common.o cpm2_pic.o
obj-$(CONFIG_PPC_DCR)   += dcr.o
obj-$(CONFIG_8xx)   += mpc8xx_pic.o commproc.o
+ifneq ($(CONFIG_PQ_WDT),)
+obj-y  += pq_wdt.o
+endif
obj-$(CONFIG_UCODE_PATCH)   += micropatch.o
endif
diff --git a/arch/powerpc/sysdev/pq_wdt.c b/arch/powerpc/sysdev/pq_wdt.c
new file mode 100644
index 000..0adbe42
--- /dev/null
+++ b/arch/powerpc/sysdev/pq_wdt.c
@@ -0,0 +1,204 @@
+/*
+ * pq_wdt.c - Freescale PowerQUICC watchdog driver
+ *
+ * Author: Florian Schirmer [EMAIL PROTECTED]
+ *
+ * 2002 (c) Florian Schirmer [EMAIL PROTECTED] This file is licensed under
+ * the terms of the GNU General Public License version 2. This program
+ * is licensed as is without any warranty of any kind, whether express
+ * or implied.
+ *
+ * 2007 (c) Jochen Friedrich [EMAIL PROTECTED] ported to ARCH=powerpc and
+ * extended to be useful on any Power QUICC 1/2/2pro which have the same
+ * style of watchdog.
+ */
+#include linux/kernel.h
+#include linux/module.h
+#include linux/init.h
+#include linux/sched.h
+#include linux/irq.h
+#include linux/of.h
+#include asm/irq.h
+#include asm/io.h
+#include asm/prom.h
+
+#include pq_wdt.h
+
+struct pq_wdt {
+   __be32 res0;
+   __be32 swcrr; /* System watchdog control register */
+   __be32 swcnr; /* System watchdog count register */
+   u8 res1[2];
+   __be16 swsrr; /* System watchdog service register */
+};
+
+static int wdt_timeout;
+static int wdt_freq;
+static struct pq_wdt __iomem *wdt_reg;
+static int wdt_scale;
+
+void pq_wdt_reset(void)
+{
+   if (!wdt_reg)
+   return;
+
+   out_be16(wdt_reg-swsrr, 0x556c);   /* write magic1 */
+   out_be16(wdt_reg-swsrr, 0xaa39);   /* write magic2 */
+}
+EXPORT_SYMBOL(pq_wdt_reset);
+
+static void wdt_timer_func(unsigned long data);
+
+static struct timer_list wdt_timer =
+   TIMER_INITIALIZER(wdt_timer_func, 0, 0);
+
+void pq_wdt_stop_timer(void)
+{
+   del_timer(wdt_timer);
+}

Re: [PATCH/RFC] Add support for PowerQUICC watchdog

2007-12-28 Thread Stephen Rothwell
Hi Jochen,

Just a couple of suggestions.

On Fri, 28 Dec 2007 16:13:11 +0100 Jochen Friedrich [EMAIL PROTECTED] wrote:

 +int __init pq_wdt_early_init(void)
 +{

 + data = of_get_property(soc, bus-frequency, NULL);
 + if (!data) {
 + of_node_put(soc);
 + printk(KERN_ERR Could not find bus-frequency in soc node\n);
 + ret = -ENODEV;
 + goto out;
 + }
 + of_node_put(soc);

If you move the of_node_put(soc) just above the if (!data) then you
won't need to repeat it.

 +static struct of_platform_driver pq_wdt_driver = {
 + .owner  = THIS_MODULE,
 + .name   = pq-wdt,
 + .match_table= pq_wdt_match,
 + .probe  = pq_wdt_probe,
 + .remove = pq_wdt_remove,
 +};

We are removing the owner and name fields from struct of_platform_driver, so 
the preferred initialization looks like this:

static struct of_platform_driver pq_wdt_driver = {
.match_table= pq_wdt_match,
.probe  = pq_wdt_probe,
.remove = pq_wdt_remove,
.driver = {
.name   = pq-wdt,
.owner  = THIS_MODULE,
}
};

or similar.

-- 
Cheers,
Stephen Rothwell[EMAIL PROTECTED]
http://www.canb.auug.org.au/~sfr/


pgpdbMrwDEd84.pgp
Description: PGP signature