[PATCH v3 03/15] ARM: mxs: Add reset routines

Uwe Kleine-König u.kleine-koenig at pengutronix.de
Tue Dec 7 15:27:50 EST 2010


Hello Shawn,

On Wed, Dec 08, 2010 at 12:31:53AM +0800, Shawn Guo wrote:
>  - The mxs wdog is implemented in RTC block.
>  - There is a generic software reset routine for most modules on mxs.
> 
> Signed-off-by: Shawn Guo <shawn.guo at freescale.com>
> ---
> Changes for v3:
>  - Change wdog timeout to 10ms for safety
>  - Simplify function mxs_reset_block() to get it look better
> 
> Changes for v2:
>  - Move rtc clock enabling from arch_reset() into mxs_arch_reset_init()
> 
>  arch/arm/mach-mxs/include/mach/system.h |   27 ++++++
>  arch/arm/mach-mxs/system.c              |  134 +++++++++++++++++++++++++++++++
>  2 files changed, 161 insertions(+), 0 deletions(-)
>  create mode 100644 arch/arm/mach-mxs/include/mach/system.h
>  create mode 100644 arch/arm/mach-mxs/system.c
> 
> diff --git a/arch/arm/mach-mxs/include/mach/system.h b/arch/arm/mach-mxs/include/mach/system.h
> new file mode 100644
> index 0000000..0e42823
> --- /dev/null
> +++ b/arch/arm/mach-mxs/include/mach/system.h
> @@ -0,0 +1,27 @@
> +/*
> + *  Copyright (C) 1999 ARM Limited
> + *  Copyright (C) 2000 Deep Blue Solutions Ltd
> + *  Copyright 2004-2008 Freescale Semiconductor, Inc. All Rights Reserved.
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License as published by
> + * the Free Software Foundation; either version 2 of the License, or
> + * (at your option) any later version.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + * GNU General Public License for more details.
> + */
> +
> +#ifndef __MACH_MXS_SYSTEM_H__
> +#define __MACH_MXS_SYSTEM_H__
> +
> +static inline void arch_idle(void)
> +{
> +	cpu_do_idle();
> +}
> +
> +void arch_reset(char mode, const char *cmd);
> +
> +#endif /* __MACH_MXS_SYSTEM_H__ */
> diff --git a/arch/arm/mach-mxs/system.c b/arch/arm/mach-mxs/system.c
> new file mode 100644
> index 0000000..58cb044
> --- /dev/null
> +++ b/arch/arm/mach-mxs/system.c
> @@ -0,0 +1,134 @@
> +/*
> + * Copyright (C) 1999 ARM Limited
> + * Copyright (C) 2000 Deep Blue Solutions Ltd
> + * Copyright 2006-2007,2010 Freescale Semiconductor, Inc. All Rights Reserved.
> + * Copyright 2008 Juergen Beisert, kernel at pengutronix.de
> + * Copyright 2009 Ilya Yanok, Emcraft Systems Ltd, yanok at emcraft.com
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License as published by
> + * the Free Software Foundation; either version 2 of the License, or
> + * (at your option) any later version.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + * GNU General Public License for more details.
> + */
> +
> +#include <linux/kernel.h>
> +#include <linux/clk.h>
> +#include <linux/io.h>
> +#include <linux/err.h>
> +#include <linux/delay.h>
> +
> +#include <asm/proc-fns.h>
> +#include <asm/system.h>
> +
> +#include <mach/hardware.h>
> +#include <mach/common.h>
> +
> +#define MXS_RTC_WATCHDOG	0x50
> +#define MXS_WATCHDOG_EN		(1 << 4)
> +
> +#define MXS_MODULE_CLKGATE	(1 << 30)
> +#define MXS_MODULE_SFTRST	(1 << 31)
> +
> +static void __iomem *wdog_base;
> +
> +/*
> + * Reset the system. It is called by machine_restart().
> + */
> +void arch_reset(char mode, const char *cmd)
> +{
> +	/* Set wdog timer 10 ms */
> +	__raw_writel(10, wdog_base + MXS_RTC_WATCHDOG);
> +
> +	/* Enable wdog reset */
> +	__raw_writel(MXS_WATCHDOG_EN, wdog_base + MXS_SET_ADDR);
> +
> +	/* Wait for reset to assert... */
> +	mdelay(10);
> +
> +	pr_err("Watchdog reset failed to assert reset\n");
> +
> +	/* Delay to allow the serial port to show the message */
> +	mdelay(50);
> +
> +	/* We'll take a jump through zero as a poor second */
> +	cpu_reset(0);
> +}
> +
> +void mxs_arch_reset_init(void __iomem *base)
> +{
> +	struct clk *clk;
> +
> +	wdog_base = base;
> +
> +	clk = clk_get_sys("rtc", NULL);
> +	if (!IS_ERR(clk))
> +		clk_enable(clk);
> +}
> +
> +/*
> + * Clear the bit and poll it cleared.  This is usually called with
> + * a reset address and mask being either SFTRST(bit 31) or CLKGATE
> + * (bit 30).
> + */
> +static int clear_poll_bit(void __iomem *addr, u32 mask)
> +{
> +	int timeout = 0x400;
> +
> +	/* clear the bit */
> +	__raw_writel(mask, addr + MXS_CLR_ADDR);
> +
> +	/*
> +	 * SFTRST needs 3 GPMI clocks to settle, the reference manual
> +	 * recommends to wait 1us.
> +	 */
> +	udelay(1);
> +
> +	/* poll the bit becoming clear */
> +	while ((__raw_readl(addr) & mask) && --timeout)
> +		/* nothing */;
> +
> +	return !timeout;
> +}
> +
> +int mxs_reset_block(void __iomem *reset_addr)
> +{
> +	int ret;
> +	int timeout = 0x400;
> +
> +	/* clear and poll SFTRST */
> +	ret = clear_poll_bit(reset_addr, MXS_MODULE_SFTRST);
> +	if (ret)
unlikely(ret)?

> +		goto error;
> +
> +	/* clear CLKGATE */
> +	__raw_writel(MXS_MODULE_CLKGATE, reset_addr + MXS_CLR_ADDR);

> +	/* set SFTRST to reset the block */
> +	__raw_writel(MXS_MODULE_SFTRST, reset_addr + MXS_SET_ADDR);
> +	udelay(1);

> +	/* poll CLKGATE becoming set */
Can you add empty lines above the comments, please.  This makes it much
easier to read.

> +	while ((!(__raw_readl(reset_addr) & MXS_MODULE_CLKGATE)) && --timeout)
> +		/* nothing */;
> +	if (unlikely(!timeout))
> +		goto error;
> +
> +	/* clear and poll SFTRST */
> +	ret = clear_poll_bit(reset_addr, MXS_MODULE_SFTRST);
> +	if (ret)
> +		goto error;
> +
> +	/* clear and poll CLKGATE */
> +	ret = clear_poll_bit(reset_addr, MXS_MODULE_CLKGATE);
> +	if (ret)
> +		goto error;
> +
> +	return 0;
> +
> +error:
> +	pr_err("%s(%p): module reset timeout\n", __func__, reset_addr);
> +	return -ETIMEDOUT;
> +}
> -- 
> 1.7.1

Best regards
Uwe

-- 
Pengutronix e.K.                           | Uwe Kleine-König            |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |



More information about the linux-arm-kernel mailing list