9
0
Fork 0

Merge branch 'for-next/restart'

This commit is contained in:
Sascha Hauer 2015-09-01 09:43:55 +02:00
commit 67e0a30e77
78 changed files with 1153 additions and 319 deletions

View File

@ -16,6 +16,7 @@
#include <libbb.h>
#include <magicvar.h>
#include <binfmt.h>
#include <restart.h>
#include <asm/byteorder.h>
#include <asm/setup.h>
@ -111,7 +112,7 @@ static int __do_bootm_linux(struct image_data *data, unsigned long free_mem, int
start_linux((void *)kernel, swap, initrd_start, initrd_size, data->oftree);
reset_cpu(0);
restart_machine();
return -ERESTARTSYS;
}
@ -378,7 +379,7 @@ static int do_bootm_barebox(struct image_data *data)
start_linux(barebox, 0, 0, 0, data->oftree);
reset_cpu(0);
restart_machine();
}
static struct image_handler barebox_handler = {
@ -518,7 +519,7 @@ static int do_bootm_aimage(struct image_data *data)
second();
reset_cpu(0);
restart_machine();
}
close(fd);

View File

@ -28,6 +28,7 @@
#include <common.h>
#include <init.h>
#include <clock.h>
#include <restart.h>
#include <mach/hardware.h>
#include <mach/at91_tc.h>
#include <mach/at91_st.h>
@ -77,7 +78,7 @@ core_initcall(clocksource_init);
/*
* Reset the cpu through the reset controller
*/
void __noreturn reset_cpu (unsigned long ignored)
static void __noreturn at91rm9200_restart_soc(struct restart_handler *rst)
{
/*
* Perform a hardware reset with the use of the Watchdog timer.
@ -86,6 +87,13 @@ void __noreturn reset_cpu (unsigned long ignored)
at91_sys_write(AT91_ST_CR, AT91_ST_WDRST);
/* Not reached */
while (1);
hang();
}
EXPORT_SYMBOL(reset_cpu);
static int restart_register_feature(void)
{
restart_handler_register_fn(at91rm9200_restart_soc);
return 0;
}
coredevice_initcall(restart_register_feature);

View File

@ -20,9 +20,9 @@
.arm
.globl reset_cpu
.globl restart_sam9
reset_cpu: ldr r0, .at91_va_base_sdramc @ preload constants
restart_sam9: ldr r0, .at91_va_base_sdramc @ preload constants
ldr r1, .at91_va_base_rstc_cr
mov r2, #1

View File

@ -17,9 +17,9 @@
.arm
.globl reset_cpu
.globl restart_sam9g45
reset_cpu: ldr r0, .at91_va_base_sdramc @ preload constants
restart_sam9g45: ldr r0, .at91_va_base_sdramc @ preload constants
ldr r1, .at91_va_base_rstc_cr
mov r2, #1

View File

@ -9,6 +9,7 @@
#include <mach/bootstrap.h>
#include <linux/sizes.h>
#include <malloc.h>
#include <restart.h>
#include <init.h>
#include <menu.h>
@ -145,7 +146,7 @@ static void boot_mmc_disk_action(struct menu *m, struct menu_entry *me)
static void boot_reset_action(struct menu *m, struct menu_entry *me)
{
reset_cpu(0);
restart_machine();
}
void at91_bootstrap_menu(void)

View File

@ -8,6 +8,7 @@
#include <common.h>
#include <io.h>
#include <init.h>
#include <restart.h>
#include <mach/hardware.h>
#include <mach/cpu.h>
@ -296,6 +297,9 @@ static int at91_detect(void)
}
postcore_initcall(at91_detect);
void restart_sam9(struct restart_handler *rst);
void restart_sam9g45(struct restart_handler *rst);
static int at91_soc_device(void)
{
struct device_d *dev;
@ -304,6 +308,11 @@ static int at91_soc_device(void)
dev_add_param_fixed(dev, "name", (char*)at91_get_soc_type(&at91_soc_initdata));
dev_add_param_fixed(dev, "subname", (char*)at91_get_soc_subtype(&at91_soc_initdata));
if (IS_ENABLED(CONFIG_AT91SAM9_RESET))
restart_handler_register_fn(restart_sam9);
if (IS_ENABLED(CONFIG_AT91SAM9G45_RESET))
restart_handler_register_fn(restart_sam9g45);
return 0;
}
coredevice_initcall(at91_soc_device);

View File

@ -18,6 +18,7 @@
#include <common.h>
#include <init.h>
#include <restart.h>
#include <linux/clk.h>
#include <linux/clkdev.h>
@ -51,13 +52,6 @@ static int bcm2835_clk_init(void)
}
postcore_initcall(bcm2835_clk_init);
static int bcm2835_dev_init(void)
{
add_generic_device("bcm2835-gpio", 0, NULL, BCM2835_GPIO_BASE, 0xB0, IORESOURCE_MEM, NULL);
return 0;
}
coredevice_initcall(bcm2835_dev_init);
void bcm2835_register_uart(void)
{
amba_apb_device_add(NULL, "uart0-pl011", 0, BCM2835_UART0_BASE, 4096, NULL, 0);
@ -72,7 +66,7 @@ void bcm2835_add_device_sdram(u32 size)
}
#define RESET_TIMEOUT 10
void __noreturn reset_cpu(unsigned long addr)
static void __noreturn bcm2835_restart_soc(struct restart_handler *rst)
{
uint32_t rstc;
@ -82,6 +76,13 @@ void __noreturn reset_cpu(unsigned long addr)
writel(PM_PASSWORD | RESET_TIMEOUT, PM_WDOG);
writel(PM_PASSWORD | rstc, PM_RSTC);
while (1);
hang();
}
EXPORT_SYMBOL(reset_cpu);
static int bcm2835_dev_init(void)
{
add_generic_device("bcm2835-gpio", 0, NULL, BCM2835_GPIO_BASE, 0xB0, IORESOURCE_MEM, NULL);
restart_handler_register_fn(bcm2835_restart_soc);
return 0;
}
coredevice_initcall(bcm2835_dev_init);

View File

@ -8,8 +8,10 @@
*/
#include <common.h>
#include <init.h>
#include <restart.h>
void __noreturn reset_cpu(unsigned long addr)
static void __noreturn clps711x_restart_soc(struct restart_handler *rst)
{
shutdown_barebox();
@ -17,3 +19,11 @@ void __noreturn reset_cpu(unsigned long addr)
hang();
}
static int restart_register_feature(void)
{
restart_handler_register_fn(clps711x_restart_soc);
return 0;
}
coredevice_initcall(restart_register_feature);

View File

@ -12,6 +12,7 @@
#include <common.h>
#include <io.h>
#include <init.h>
#include <restart.h>
#include <clock.h>
#include <mach/time.h>
@ -164,7 +165,7 @@ static int clocksource_init(void)
core_initcall(clocksource_init);
/* reset board using watchdog timer */
void __noreturn reset_cpu(ulong addr)
static void __noreturn davinci_restart_soc(struct restart_handler *rst)
{
u32 tgcr, wdtcr;
void __iomem *base;
@ -204,6 +205,13 @@ void __noreturn reset_cpu(ulong addr)
wdtcr = 0x00004000;
__raw_writel(wdtcr, base + WDTCR);
unreachable();
hang();
}
EXPORT_SYMBOL(reset_cpu);
static int restart_register_feature(void)
{
restart_handler_register_fn(davinci_restart_soc);
return 0;
}
coredevice_initcall(restart_register_feature);

View File

@ -1 +1 @@
obj-y += core.o
obj- := __dummy__.o

View File

@ -1,25 +0,0 @@
/*
* Copyright (C) 2013 Antony Pavlov <antonynpavlov@gmail.com>
*
* This file is part of barebox.
* See file CREDITS for list of people who contributed to this project.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation.
*
* 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 <common.h>
void __noreturn reset_cpu(unsigned long ignored)
{
pr_err("%s: unimplemented\n", __func__);
hang();
}
EXPORT_SYMBOL(reset_cpu);

View File

@ -20,6 +20,7 @@
#include <init.h>
#include <clock.h>
#include <io.h>
#include <restart.h>
#include <mach/ep93xx-regs.h>
#define TIMER_CLKSEL (1 << 3)
@ -63,10 +64,8 @@ static int clocksource_init(void)
core_initcall(clocksource_init);
/*
* Reset the cpu
*/
void __noreturn reset_cpu(unsigned long addr)
/* Reset the SoC */
static void __noreturn ep92xx_restart_soc(struct restart_handler *rst)
{
struct syscon_regs *syscon = (struct syscon_regs *)SYSCON_BASE;
uint32_t value;
@ -84,7 +83,13 @@ void __noreturn reset_cpu(unsigned long addr)
writel(value, &syscon->devicecfg);
/* Dying... */
while (1)
; /* noop */
hang();
}
EXPORT_SYMBOL(reset_cpu);
static int restart_register_feature(void)
{
restart_handler_register_fn(ep92xx_restart_soc);
return 0;
}
coredevice_initcall(restart_register_feature);

View File

@ -6,18 +6,28 @@
#include <common.h>
#include <io.h>
#include <restart.h>
#include <init.h>
#include <mach/devices.h>
#include <mach/sysregs.h>
void __noreturn reset_cpu(ulong addr)
static void __noreturn highbank_restart_soc(struct restart_handler *rst)
{
hingbank_set_pwr_hard_reset();
asm(" wfi");
while(1);
hang();
}
static int restart_register_feature(void)
{
restart_handler_register_fn(highbank_restart_soc);
return 0;
}
coredevice_initcall(restart_register_feature);
void __noreturn poweroff()
{
shutdown_barebox();

View File

@ -17,6 +17,7 @@
#include <common.h>
#include <init.h>
#include <io.h>
#include <restart.h>
#include <of.h>
#include <of_address.h>
#include <asm/memory.h>
@ -104,12 +105,12 @@ static int armada_370_xp_soc_id_fixup(void)
return 0;
}
static void __noreturn armada_370_xp_reset_cpu(unsigned long addr)
static void __noreturn armada_370_xp_restart_soc(struct restart_handler *rst)
{
writel(0x1, ARMADA_370_XP_SYSCTL_BASE + 0x60);
writel(0x1, ARMADA_370_XP_SYSCTL_BASE + 0x64);
while (1)
;
hang();
}
static int armada_xp_init_soc(struct device_node *root)
@ -132,7 +133,7 @@ static int armada_370_xp_init_soc(struct device_node *root, void *context)
if (!of_machine_is_compatible("marvell,armada-370-xp"))
return 0;
mvebu_set_reset(armada_370_xp_reset_cpu);
restart_handler_register_fn(armada_370_xp_restart_soc);
barebox_set_model("Marvell Armada 370/XP");
barebox_set_hostname("armada");

View File

@ -123,16 +123,3 @@ int mvebu_set_memory(u64 phys_base, u64 phys_size)
return 0;
}
static __noreturn void (*mvebu_reset_cpu)(unsigned long addr);
void __noreturn reset_cpu(unsigned long addr)
{
mvebu_reset_cpu(addr);
}
EXPORT_SYMBOL(reset_cpu);
void mvebu_set_reset(void __noreturn (*reset)(unsigned long addr))
{
mvebu_reset_cpu = reset;
}

View File

@ -17,6 +17,7 @@
#include <common.h>
#include <init.h>
#include <io.h>
#include <restart.h>
#include <asm/memory.h>
#include <linux/mbus.h>
#include <mach/dove-regs.h>
@ -68,13 +69,13 @@ static inline void dove_memory_find(unsigned long *phys_base,
}
}
static void __noreturn dove_reset_cpu(unsigned long addr)
static void __noreturn dove_restart_soc(struct restart_handler *rst)
{
/* enable and assert RSTOUTn */
writel(SOFT_RESET_OUT_EN, DOVE_BRIDGE_BASE + BRIDGE_RSTOUT_MASK);
writel(SOFT_RESET_EN, DOVE_BRIDGE_BASE + BRIDGE_SYS_SOFT_RESET);
while (1)
;
hang();
}
static int dove_init_soc(struct device_node *root, void *context)
@ -84,7 +85,7 @@ static int dove_init_soc(struct device_node *root, void *context)
if (!of_machine_is_compatible("marvell,dove"))
return 0;
mvebu_set_reset(dove_reset_cpu);
restart_handler_register_fn(dove_restart_soc);
barebox_set_model("Marvell Dove");
barebox_set_hostname("dove");

View File

@ -21,6 +21,5 @@
#define MVEBU_REMAP_INT_REG_BASE 0xf1000000
int mvebu_set_memory(u64 phys_base, u64 phys_size);
void mvebu_set_reset(void __noreturn (*reset)(unsigned long addr));
#endif

View File

@ -16,6 +16,7 @@
#include <common.h>
#include <init.h>
#include <io.h>
#include <restart.h>
#include <asm/memory.h>
#include <linux/mbus.h>
#include <mach/kirkwood-regs.h>
@ -43,12 +44,12 @@ static inline void kirkwood_memory_find(unsigned long *phys_base,
}
}
static void __noreturn kirkwood_reset_cpu(unsigned long addr)
static void __noreturn kirkwood_restart_soc(struct restart_handler *rst)
{
writel(SOFT_RESET_OUT_EN, KIRKWOOD_BRIDGE_BASE + BRIDGE_RSTOUT_MASK);
writel(SOFT_RESET_EN, KIRKWOOD_BRIDGE_BASE + BRIDGE_SYS_SOFT_RESET);
for(;;)
;
hang();
}
static int kirkwood_init_soc(struct device_node *root, void *context)
@ -58,7 +59,7 @@ static int kirkwood_init_soc(struct device_node *root, void *context)
if (!of_machine_is_compatible("marvell,kirkwood"))
return 0;
mvebu_set_reset(kirkwood_reset_cpu);
restart_handler_register_fn(kirkwood_restart_soc);
barebox_set_model("Marvell Kirkwood");
barebox_set_hostname("kirkwood");

View File

@ -16,6 +16,7 @@
#include <common.h>
#include <init.h>
#include <restart.h>
#include <mach/imx23-regs.h>
#include <io.h>
@ -23,18 +24,16 @@
# define HW_CLKCTRL_RESET_CHIP (1 << 1)
/* Reset the full i.MX23 SoC via a chipset feature */
void __noreturn reset_cpu(unsigned long addr)
static void __noreturn imx23_restart_soc(struct restart_handler *rst)
{
u32 reg;
reg = readl(IMX_CCM_BASE + HW_CLKCTRL_RESET);
writel(reg | HW_CLKCTRL_RESET_CHIP, IMX_CCM_BASE + HW_CLKCTRL_RESET);
while (1)
;
hang();
/*NOTREACHED*/
}
EXPORT_SYMBOL(reset_cpu);
static int imx23_devices_init(void)
{
@ -46,6 +45,7 @@ static int imx23_devices_init(void)
add_generic_device("imx23-gpio", 0, NULL, IMX_IOMUXC_BASE, 0x2000, IORESOURCE_MEM, NULL);
add_generic_device("imx23-gpio", 1, NULL, IMX_IOMUXC_BASE, 0x2000, IORESOURCE_MEM, NULL);
add_generic_device("imx23-gpio", 2, NULL, IMX_IOMUXC_BASE, 0x2000, IORESOURCE_MEM, NULL);
restart_handler_register_fn(imx23_restart_soc);
return 0;
}

View File

@ -16,6 +16,7 @@
#include <common.h>
#include <init.h>
#include <restart.h>
#include <mach/imx28-regs.h>
#include <io.h>
@ -24,18 +25,16 @@
#define HW_CLKCTRL_WDOG_POR_DISABLE (1 << 5)
/* Reset the full i.MX28 SoC via a chipset feature */
void __noreturn reset_cpu(unsigned long addr)
static void __noreturn imx28_restart_soc(struct restart_handler *rst)
{
u32 reg;
reg = readl(IMX_CCM_BASE + HW_CLKCTRL_RESET);
writel(reg | HW_CLKCTRL_RESET_CHIP, IMX_CCM_BASE + HW_CLKCTRL_RESET);
while (1)
;
hang();
/*NOTREACHED*/
}
EXPORT_SYMBOL(reset_cpu);
static int imx28_init(void)
{
@ -50,6 +49,8 @@ static int imx28_init(void)
HW_CLKCTRL_WDOG_POR_DISABLE;
writel(reg, IMX_CCM_BASE + HW_CLKCTRL_RESET);
restart_handler_register_fn(imx28_restart_soc);
return 0;
}
postcore_initcall(imx28_init);

View File

@ -15,8 +15,10 @@
*/
#include <common.h>
#include <init.h>
#include <command.h>
#include <io.h>
#include <restart.h>
#include <mach/netx-regs.h>
#include "eth_firmware.h"
@ -134,17 +136,24 @@ failure:
return COMMAND_ERROR_USAGE;
}
void __noreturn reset_cpu(unsigned long addr)
{
SYSTEM_REG(SYSTEM_RES_CR) = 0x01000008;
/* Not reached */
while (1);
}
BAREBOX_CMD_START(loadxc)
.cmd = do_loadxc,
BAREBOX_CMD_DESC("load XMAC/XPEC engine with ethernet firmware")
BAREBOX_CMD_GROUP(CMD_GRP_NET)
BAREBOX_CMD_END
static void __noreturn netx_restart_soc(struct restart_handler *rst)
{
SYSTEM_REG(SYSTEM_RES_CR) = 0x01000008;
/* Not reached */
hang();
}
static int restart_register_feature(void)
{
restart_handler_register_fn(netx_restart_soc);
return 0;
}
coredevice_initcall(restart_register_feature);

View File

@ -15,10 +15,12 @@
*/
#include <common.h>
#include <init.h>
#include <io.h>
#include <restart.h>
#include <mach/hardware.h>
void __noreturn reset_cpu(unsigned long addr)
static void __noreturn nomadik_restart_soc(struct restart_handler *rst)
{
void __iomem *src_rstsr = (void *)(NOMADIK_SRC_BASE + 0x18);
@ -28,6 +30,13 @@ void __noreturn reset_cpu(unsigned long addr)
writel(1, src_rstsr);
/* Not reached */
while (1);
hang();
}
EXPORT_SYMBOL(reset_cpu);
static int restart_register_feature(void)
{
restart_handler_register_fn(nomadik_restart_soc);
return 0;
}
coredevice_initcall(restart_register_feature);

View File

@ -19,6 +19,7 @@
#include <init.h>
#include <io.h>
#include <net.h>
#include <restart.h>
#include <asm/barebox-arm.h>
#include <mach/am33xx-silicon.h>
#include <mach/am33xx-clock.h>
@ -28,11 +29,11 @@
#include <mach/gpmc.h>
#include <reset_source.h>
void __noreturn am33xx_reset_cpu(unsigned long addr)
static void __noreturn am33xx_restart_soc(struct restart_handler *rst)
{
writel(AM33XX_PRM_RSTCTRL_RESET, AM33XX_PRM_RSTCTRL);
while (1);
hang();
}
/**
@ -243,6 +244,8 @@ int am33xx_init(void)
{
omap_gpmc_base = (void *)AM33XX_GPMC_BASE;
restart_handler_register_fn(am33xx_restart_soc);
am33xx_enable_per_clocks();
if (IS_ENABLED(CONFIG_RESET_SOURCE))

View File

@ -28,8 +28,6 @@ u32 am33xx_running_in_flash(void);
u32 am33xx_running_in_sram(void);
u32 am33xx_running_in_sdram(void);
void __noreturn am33xx_reset_cpu(unsigned long addr);
void am33xx_enable_per_clocks(void);
int am33xx_init(void);
int am33xx_devices_init(void);

View File

@ -24,8 +24,6 @@ u32 omap3_running_in_flash(void);
u32 omap3_running_in_sram(void);
u32 omap3_running_in_sdram(void);
void __noreturn omap3_reset_cpu(unsigned long addr);
int omap3_init(void);
int omap3_devices_init(void);

View File

@ -18,8 +18,6 @@ static inline void omap4_save_bootinfo(uint32_t *info)
memcpy((void *)OMAP44XX_SRAM_SCRATCH_SPACE, info, 3 * sizeof(uint32_t));
}
void __noreturn omap4_reset_cpu(unsigned long addr);
int omap4_init(void);
int omap4_devices_init(void);

View File

@ -31,6 +31,7 @@
#include <bootsource.h>
#include <init.h>
#include <io.h>
#include <restart.h>
#include <mach/omap3-silicon.h>
#include <mach/gpmc.h>
#include <mach/generic.h>
@ -52,13 +53,12 @@
*
* @return void
*/
void __noreturn omap3_reset_cpu(unsigned long addr)
static void __noreturn omap3_restart_soc(struct restart_handler *rst)
{
writel(OMAP3_PRM_RSTCTRL_RESET, OMAP3_PRM_REG(RSTCTRL));
while (1);
hang();
}
EXPORT_SYMBOL(reset_cpu);
/**
* @brief Low level CPU type
@ -490,6 +490,8 @@ int omap3_init(void)
{
omap_gpmc_base = (void *)OMAP3_GPMC_BASE;
restart_handler_register_fn(omap3_restart_soc);
return omap3_bootsource();
}

View File

@ -1,6 +1,7 @@
#include <common.h>
#include <bootsource.h>
#include <init.h>
#include <restart.h>
#include <io.h>
#include <mach/omap4-clock.h>
#include <mach/omap4-silicon.h>
@ -34,11 +35,11 @@
#define EMIF_L3_CONFIG_VAL_SYS_10_LL_0 0x0A0000FF
#define EMIF_L3_CONFIG_VAL_SYS_10_MPU_3_LL_0 0x0A300000
void __noreturn omap4_reset_cpu(unsigned long addr)
static void __noreturn omap4_restart_soc(struct restart_handler *rst)
{
writel(OMAP44XX_PRM_RSTCTRL_RESET, OMAP44XX_PRM_RSTCTRL);
while (1);
hang();
}
void omap4_set_warmboot_order(u32 *device_list)
@ -533,6 +534,8 @@ int omap4_init(void)
{
omap_gpmc_base = (void *)OMAP44XX_GPMC_BASE;
restart_handler_register_fn(omap4_restart_soc);
return omap4_bootsource();
}

View File

@ -150,17 +150,6 @@ static int omap_env_init(void)
late_initcall(omap_env_init);
#endif
void __noreturn reset_cpu(unsigned long addr)
{
if (cpu_is_omap3())
omap3_reset_cpu(addr);
if (cpu_is_omap4())
omap4_reset_cpu(addr);
if (cpu_is_am33xx())
am33xx_reset_cpu(addr);
while (1);
}
static int omap_soc_from_dt(void)
{
if (of_machine_is_compatible("ti,am33xx"))

View File

@ -16,6 +16,8 @@
*/
#include <common.h>
#include <init.h>
#include <restart.h>
#include <mach/pxa-regs.h>
#include <asm/io.h>
@ -29,7 +31,7 @@
extern void pxa_clear_reset_source(void);
void reset_cpu(ulong addr)
static void __noreturn pxa_restart_soc(struct restart_handler *rst)
{
/* Clear last reset source */
pxa_clear_reset_source();
@ -39,5 +41,13 @@ void reset_cpu(ulong addr)
writel(OSSR_M3, OSSR);
writel(readl(OSCR) + 368640, OSMR3); /* ... in 100 ms */
while (1);
hang();
}
static int restart_register_feature(void)
{
restart_handler_register_fn(pxa_restart_soc);
return 0;
}
coredevice_initcall(restart_register_feature);

View File

@ -13,16 +13,24 @@
#include <asm/io.h>
#include <common.h>
#include <init.h>
#include <restart.h>
#include <mach/rockchip-regs.h>
void __noreturn reset_cpu(unsigned long addr)
static void __noreturn rockchip_restart_soc(struct restart_handler *rst)
{
/* Map bootrom from address 0 */
writel(RK_SOC_CON0_REMAP << 16, RK_GRF_BASE + RK_GRF_SOC_CON0);
/* Reset */
writel(0xeca8, RK_CRU_BASE + RK_CRU_GLB_SRST_SND);
while (1)
;
hang();
}
EXPORT_SYMBOL(reset_cpu);
static int restart_register_feature(void)
{
restart_handler_register_fn(rockchip_restart_soc);
return 0;
}
coredevice_initcall(restart_register_feature);

View File

@ -21,6 +21,7 @@
#include <config.h>
#include <common.h>
#include <init.h>
#include <restart.h>
#include <io.h>
#include <mach/s3c-iomap.h>
#include <mach/s3c-generic.h>
@ -29,7 +30,7 @@
#define S3C_WTDAT (S3C_WATCHDOG_BASE + 0x04)
#define S3C_WTCNT (S3C_WATCHDOG_BASE + 0x08)
void __noreturn reset_cpu(unsigned long addr)
static void __noreturn samsung_restart_soc(struct restart_handler *rst)
{
/* Disable watchdog */
writew(0x0000, S3C_WTCON);
@ -41,7 +42,13 @@ void __noreturn reset_cpu(unsigned long addr)
writew(0x0021, S3C_WTCON);
/* loop forever and wait for reset to happen */
while(1)
;
hang();
}
EXPORT_SYMBOL(reset_cpu);
static int restart_register_feature(void)
{
restart_handler_register_fn(samsung_restart_soc);
return 0;
}
coredevice_initcall(restart_register_feature);

View File

@ -17,6 +17,8 @@
#include <common.h>
#include <io.h>
#include <init.h>
#include <restart.h>
#include <mach/socfpga-regs.h>
#include <mach/reset-manager.h>
@ -38,7 +40,7 @@ void watchdog_disable(void)
}
/* Write the reset manager register to cause reset */
void reset_cpu(ulong addr)
static void __noreturn socfpga_restart_soc(struct restart_handler *rst)
{
/* request a warm reset */
writel((1 << RSTMGR_CTRL_SWWARMRSTREQ_LSB),
@ -47,5 +49,13 @@ void reset_cpu(ulong addr)
* infinite loop here as watchdog will trigger and reset
* the processor
*/
while (1);
hang();
}
static int restart_register_feature(void)
{
restart_handler_register_fn(socfpga_restart_soc);
return 0;
}
coredevice_initcall(restart_register_feature);

View File

@ -23,6 +23,7 @@
#include <common.h>
#include <init.h>
#include <io.h>
#include <restart.h>
#include <linux/err.h>
#include <linux/clk.h>
#include <linux/reset.h>
@ -36,13 +37,12 @@ static void __iomem *pmc_base;
static int tegra_num_powerdomains;
/* main SoC reset trigger */
void __noreturn reset_cpu(ulong addr)
static void __noreturn tegra20_restart_soc(struct restart_handler *rst)
{
writel(PMC_CNTRL_MAIN_RST, pmc_base + PMC_CNTRL);
unreachable();
hang();
}
EXPORT_SYMBOL(reset_cpu);
static int tegra_powergate_set(int id, bool new_state)
{
@ -219,7 +219,7 @@ static int tegra20_pmc_probe(struct device_d *dev)
static int do_tegrarcm(int argc, char *argv[])
{
writel(2, pmc_base + PMC_SCRATCH(0));
reset_cpu(0);
restart_machine();
return 0;
}
@ -244,6 +244,7 @@ static struct driver_d tegra20_pmc_driver = {
static int tegra20_pmc_init(void)
{
restart_handler_register_fn(tegra20_restart_soc);
return platform_driver_register(&tegra20_pmc_driver);
}
coredevice_initcall(tegra20_pmc_init);

View File

@ -1 +1 @@
obj-y += reset.o
obj- := __dummy__.o

View File

@ -1,24 +0,0 @@
/*
* Copyright (C) 2014 Antony Pavlov <antonynpavlov@gmail.com>
*
* This file is part of barebox.
* See file CREDITS for list of people who contributed to this project.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation.
*
* 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 <common.h>
void __noreturn reset_cpu(ulong addr)
{
hang();
}
EXPORT_SYMBOL(reset_cpu);

View File

@ -26,6 +26,7 @@
#include <init.h>
#include <clock.h>
#include <debug_ll.h>
#include <restart.h>
#include <linux/sizes.h>
#include <linux/clkdev.h>
@ -184,7 +185,7 @@ void versatile_register_uart(unsigned id)
amba_apb_device_add(NULL, "uart-pl011", id, start, 4096, NULL, 0);
}
void __noreturn reset_cpu (unsigned long ignored)
static void versatile_reset_soc(struct restart_handler *rst)
{
u32 val;
@ -195,9 +196,8 @@ void __noreturn reset_cpu (unsigned long ignored)
__raw_writel(val, VERSATILE_SYS_RESETCTL);
__raw_writel(0, VERSATILE_SYS_LOCK);
while(1);
hang();
}
EXPORT_SYMBOL(reset_cpu);
static int versatile_init(void)
{
@ -205,6 +205,7 @@ static int versatile_init(void)
amba_apb_device_add(NULL, "pl061_gpio", 1, 0x101e5000, 4096, NULL, 0);
amba_apb_device_add(NULL, "pl061_gpio", 2, 0x101e6000, 4096, NULL, 0);
amba_apb_device_add(NULL, "pl061_gpio", 3, 0x101e7000, 4096, NULL, 0);
restart_handler_register_fn(versatile_reset_soc);
return 0;
}
coredevice_initcall(versatile_init);

View File

@ -6,17 +6,26 @@
#include <common.h>
#include <io.h>
#include <init.h>
#include <restart.h>
#include <linux/amba/sp805.h>
#include <mach/devices.h>
void __iomem *v2m_wdt_base;
void reset_cpu(ulong addr)
static void vexpress_reset_soc(struct restart_handler *rst)
{
writel(LOAD_MIN, v2m_wdt_base + WDTLOAD);
writeb(RESET_ENABLE, v2m_wdt_base + WDTCONTROL);
while (1)
;
hang();
}
static int restart_register_feature(void)
{
restart_handler_register_fn(vexpress_reset_soc);
return 0;
}
coredevice_initcall(restart_register_feature);

View File

@ -17,8 +17,19 @@
#include <asm-generic/io.h>
#include <common.h>
#include <init.h>
#include <restart.h>
#include <mach/zynq7000-regs.h>
static void __noreturn zynq_restart_soc(struct restart_handler *rst)
{
/* write unlock key to slcr */
writel(0xDF0D, ZYNQ_SLCR_UNLOCK);
/* reset */
writel(0x1, ZYNQ_PSS_RST_CTRL);
hang();
}
static int zynq_init(void)
{
u32 val;
@ -40,17 +51,8 @@ static int zynq_init(void)
add_generic_device("zynq-clock", 0, NULL, ZYNQ_SLCR_BASE, 0x4000, IORESOURCE_MEM, NULL);
add_generic_device("smp_twd", 0, NULL, CORTEXA9_SCU_TIMER_BASE_ADDR,
0x4000, IORESOURCE_MEM, NULL);
restart_handler_register_fn(zynq_restart_soc);
return 0;
}
postcore_initcall(zynq_init);
void __noreturn reset_cpu(unsigned long addr)
{
/* write unlock key to slcr */
writel(0xDF0D, ZYNQ_SLCR_UNLOCK);
/* reset */
writel(0x1, ZYNQ_PSS_RST_CTRL);
while (1)
;
}

View File

@ -27,8 +27,9 @@
#include <asm/entry.h>
#include <asm/cpu.h>
#include <init.h>
#include <restart.h>
void __noreturn reset_cpu(unsigned long addr)
static void __noreturn blackfin_restart_cpu(struct restart_handler *rst)
{
icache_disable();
@ -41,9 +42,17 @@ void __noreturn reset_cpu(unsigned long addr)
);
/* Not reached */
while (1);
hang();
}
static int restart_register_feature(void)
{
restart_handler_register_fn(blackfin_restart_cpu);
return 0;
}
coredevice_initcall(restart_register_feature);
void icache_disable(void)
{
#ifdef __ADSPBF537__

View File

@ -30,6 +30,7 @@
*/
#include <common.h>
#include <restart.h>
#include <linux/types.h>
#include <asm/system.h>
#include <asm/traps.h>
@ -91,7 +92,7 @@ void trap_c (struct pt_regs *regs)
printf("\nPlease reset the board\n");
reset_cpu(0);
restart_machine();
}
void blackfin_irq_panic(int reason, struct pt_regs *regs)
@ -101,6 +102,6 @@ void blackfin_irq_panic(int reason, struct pt_regs *regs)
printf("Unhandled IRQ or exceptions!\n");
printf("Please reset the board \n");
reset_cpu(0);
restart_machine();
}

View File

@ -24,6 +24,7 @@
#include <command.h>
#include <magicvar.h>
#include <init.h>
#include <restart.h>
#include <driver.h>
#include <ns16550.h>
#include <io.h>
@ -273,13 +274,21 @@ static int efi_console_init(void)
}
console_initcall(efi_console_init);
void reset_cpu(unsigned long addr)
static void __noreturn efi_restart_system(struct restart_handler *rst)
{
RT->reset_system(EFI_RESET_WARM, EFI_SUCCESS, 0, NULL);
while(1);
hang();
}
static int restart_register_feature(void)
{
restart_handler_register_fn(efi_restart_system);
return 0;
}
coredevice_initcall(restart_register_feature);
extern char image_base[];
extern initcall_t __barebox_initcalls_start[], __barebox_early_initcalls_end[],
__barebox_initcalls_end[];

View File

@ -5,6 +5,7 @@
#include <fs.h>
#include <errno.h>
#include <binfmt.h>
#include <restart.h>
#include <asm/byteorder.h>
@ -20,7 +21,7 @@ static int do_bootm_barebox(struct image_data *data)
barebox();
reset_cpu(0);
restart_machine();
}
static struct image_handler barebox_handler = {

View File

@ -10,6 +10,7 @@
#include <common.h>
#include <init.h>
#include <io.h>
#include <restart.h>
#include <linux/err.h>
#include <mach/ar2312_regs.h>
@ -17,16 +18,16 @@
static void __iomem *reset_base;
void __noreturn reset_cpu(ulong addr)
static void __noreturn ar2312x_restart_soc(struct restart_handler *rst)
{
printf("reseting cpu\n");
__raw_writel(0x10000,
(char *)KSEG1ADDR(AR2312_WD_TIMER));
__raw_writel(AR2312_WD_CTRL_RESET,
(char *)KSEG1ADDR(AR2312_WD_CTRL));
unreachable();
hang();
}
EXPORT_SYMBOL(reset_cpu);
static u32 ar231x_reset_readl(void)
{
@ -69,6 +70,7 @@ static struct driver_d ar231x_reset_driver = {
static int ar231x_reset_init(void)
{
restart_handler_register_fn(ar2312x_restart_soc);
return platform_driver_register(&ar231x_reset_driver);
}
coredevice_initcall(ar231x_reset_init);

View File

@ -16,9 +16,11 @@
*/
#include <common.h>
#include <init.h>
#include <restart.h>
#include <mach/ath79.h>
void __noreturn reset_cpu(ulong addr)
static void __noreturn ath79_restart_soc(struct restart_handler *rst)
{
ath79_reset_wr(AR933X_RESET_REG_RESET_MODULE, AR71XX_RESET_FULL_CHIP);
/*
@ -26,7 +28,14 @@ void __noreturn reset_cpu(ulong addr)
* pulling the reset pin. The system will reboot with PLL disabled.
* Always zero when read.
*/
unreachable();
hang();
/*NOTREACHED*/
}
EXPORT_SYMBOL(reset_cpu);
static int restart_register_feature(void)
{
restart_handler_register_fn(ath79_restart_soc);
return 0;
}
coredevice_initcall(restart_register_feature);

View File

@ -17,12 +17,22 @@
#include <common.h>
#include <io.h>
#include <init.h>
#include <restart.h>
#include <mach/hardware.h>
void __noreturn reset_cpu(ulong addr)
static void __noreturn bcm47xx_restart_soc(struct restart_handler *rst)
{
__raw_writel(GORESET, (char *)SOFTRES_REG);
while (1);
hang();
/*NOTREACHED*/
}
EXPORT_SYMBOL(reset_cpu);
static int restart_register_feature(void)
{
restart_handler_register_fn(bcm47xx_restart_soc);
return 0;
}
coredevice_initcall(restart_register_feature);

View File

@ -14,14 +14,23 @@
#include <common.h>
#include <io.h>
#include <init.h>
#include <restart.h>
#include <mach/loongson1.h>
void __noreturn reset_cpu(ulong addr)
static void __noreturn longhorn_restart_soc(struct restart_handler *rst)
{
__raw_writel(0x1, LS1X_WDT_EN);
__raw_writel(0x1, LS1X_WDT_SET);
__raw_writel(0x1, LS1X_WDT_TIMER);
unreachable();
hang();
}
EXPORT_SYMBOL(reset_cpu);
static int restart_register_feature(void)
{
restart_handler_register_fn(longhorn_restart_soc);
return 0;
}
coredevice_initcall(restart_register_feature);

View File

@ -22,12 +22,22 @@
#include <common.h>
#include <io.h>
#include <init.h>
#include <restart.h>
#include <mach/hardware.h>
void __noreturn reset_cpu(ulong addr)
static void __noreturn malta_restart_soc(struct restart_handler *rst)
{
__raw_writel(GORESET, (char *)SOFTRES_REG);
while (1);
hang();
/*NOTREACHED*/
}
EXPORT_SYMBOL(reset_cpu);
static int restart_register_feature(void)
{
restart_handler_register_fn(malta_restart_soc);
return 0;
}
coredevice_initcall(restart_register_feature);

View File

@ -18,14 +18,22 @@
*/
#include <common.h>
#include <init.h>
#include <restart.h>
#include <asm/system.h>
void __noreturn reset_cpu(ulong ignored)
static void __noreturn nios2_restart_soc(struct restart_handler *rst)
{
/* indirect call to go beyond 256MB limitation of toolchain */
nios2_callr(RESET_ADDR);
/* Not reached */
while (1);
hang();
}
static int restart_register_feature(void)
{
restart_handler_register_fn(nios2_restart_soc);
}
coredevice_initcall(restart_register_feature);

View File

@ -19,6 +19,7 @@
#include <common.h>
#include <init.h>
#include <restart.h>
#include <asm/system.h>
#include <asm/openrisc_exc.h>
@ -29,11 +30,17 @@ int cleanup_before_linux(void)
extern void __reset(void);
void __noreturn reset_cpu(ulong ignored)
static void __noreturn openrisc_restart_cpu(struct restart_handler *rst)
{
__reset();
/* not reached, __reset does not return */
/* Not reached */
while (1);
hang();
}
static int restart_register_feature(void)
{
restart_handler_register_fn(openrisc_restart_cpu, NULL, RESET_SCOPE_CPU);
}
coredevice_initcall(restart_register_feature);

View File

@ -10,6 +10,7 @@
#include <asm/processor.h>
#include <boot.h>
#include <errno.h>
#include <restart.h>
#include <fs.h>
static int bootm_relocate_fdt(void *addr, struct image_data *data)
@ -87,7 +88,7 @@ static int do_bootm_linux(struct image_data *data)
*/
kernel(data->oftree, kernel, 0, 0, 0);
reset_cpu(0);
restart_machine();
error:
return -1;

View File

@ -31,6 +31,7 @@
#include <types.h>
#include <errno.h>
#include <of.h>
#include <restart.h>
#include <mach/clock.h>
int checkcpu (void)
@ -59,7 +60,7 @@ int checkcpu (void)
/* ------------------------------------------------------------------------- */
void __noreturn reset_cpu (unsigned long addr)
static void __noreturn mpc5xxx_restart_soc(struct restart_handler *rst)
{
ulong msr;
/* Interrupts and MMU off */
@ -71,9 +72,15 @@ void __noreturn reset_cpu (unsigned long addr)
/* Charge the watchdog timer */
*(vu_long *)(MPC5XXX_GPT0_COUNTER) = 0x0001000f;
*(vu_long *)(MPC5XXX_GPT0_ENABLE) = 0x9004; /* wden|ce|timer_ms */
while(1);
hang();
}
static int restart_register_feature(void)
{
restart_handler_register_fn(mpc5xxx_restart_soc);
}
coredevice_initcall(restart_register_feature);
/* ------------------------------------------------------------------------- */
#ifdef CONFIG_OFTREE

View File

@ -26,12 +26,13 @@
#include <common.h>
#include <memory.h>
#include <init.h>
#include <restart.h>
#include <asm/fsl_ddr_sdram.h>
#include <asm-generic/memory_layout.h>
#include <mach/mmu.h>
#include <mach/immap_85xx.h>
void __noreturn reset_cpu(unsigned long addr)
static void __noreturn mpc85xx_restart_soc(struct restart_handler *rst)
{
void __iomem *regs = (void __iomem *)MPC85xx_GUTS_ADDR;
@ -39,10 +40,17 @@ void __noreturn reset_cpu(unsigned long addr)
out_be32(regs + MPC85xx_GUTS_RSTCR_OFFSET, 0x2); /* HRESET_REQ */
udelay(100);
while (1)
;
hang();
}
static int restart_register_feature(void)
{
restart_handler_register_fn(mpc85xx_restart_soc);
return 0;
}
coredevice_initcall(restart_register_feature);
long int initdram(int board_type)
{
phys_size_t dram_size = 0;

View File

@ -4,5 +4,6 @@ obj-y += hostfile.o
obj-y += console.o
obj-y += devices.o
obj-y += dtb.o
obj-y += restart.o
extra-y += barebox.lds

View File

@ -0,0 +1,17 @@
#include <common.h>
#include <init.h>
#include <restart.h>
#include <mach/linux.h>
static void sandbox_restart_cpu(struct restart_handler *restart)
{
linux_exit();
}
static int restart_register_feature(void)
{
restart_handler_register_fn(sandbox_restart_cpu);
return 0;
}
coredevice_initcall(restart_register_feature);

View File

@ -15,6 +15,7 @@ int linux_read_nonblock(int fd, void *buf, size_t count);
ssize_t linux_write(int fd, const void *buf, size_t count);
off_t linux_lseek(int fildes, off_t offset);
int linux_tstc(int fd);
void __attribute__((noreturn)) linux_exit(void);
int linux_execve(const char * filename, char *const argv[], char *const envp[]);

View File

@ -115,7 +115,7 @@ uint64_t linux_get_time(void)
return now;
}
void __attribute__((noreturn)) reset_cpu(unsigned long addr)
void __attribute__((noreturn)) linux_exit(void)
{
cookmode();
exit(0);
@ -133,7 +133,7 @@ int linux_read(int fd, void *buf, size_t count)
if (ret == 0) {
printf("read on fd %d returned 0, device gone? - exiting\n", fd);
reset_cpu(0);
linux_exit();
} else if (ret == -1) {
if (errno == EAGAIN)
return -errno;
@ -141,7 +141,7 @@ int linux_read(int fd, void *buf, size_t count)
continue;
else {
printf("read on fd %d returned -1, errno %d - exiting\n", fd, errno);
reset_cpu(0);
linux_exit();
}
}
} while (ret <= 0);

View File

@ -1,4 +1,2 @@
obj-y += reset.o
# reference clocksource
obj-y += pit_timer.o

View File

@ -1,30 +0,0 @@
/*
* Copyright (C) 2009 Juergen Beisert, Pengutronix
*
* 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.
*
*
*/
/**
* @file
* @brief Resetting an x86 CPU
*/
#include <common.h>
void __noreturn reset_cpu(unsigned long addr)
{
/** How to reset the machine? */
while(1)
;
}
EXPORT_SYMBOL(reset_cpu);

View File

@ -21,6 +21,7 @@
#include <command.h>
#include <complete.h>
#include <getopt.h>
#include <restart.h>
static int cmd_reset(int argc, char *argv[])
{
@ -39,7 +40,7 @@ static int cmd_reset(int argc, char *argv[])
if (shutdown_flag)
shutdown_barebox();
reset_cpu(0);
restart_machine();
/* Not reached */
return 1;

View File

@ -8,6 +8,7 @@ obj-y += misc.o
obj-pbl-y += memsize.o
obj-y += resource.o
obj-y += bootsource.o
obj-y += restart.o
obj-$(CONFIG_AUTO_COMPLETE) += complete.o
obj-$(CONFIG_BANNER) += version.o
obj-$(CONFIG_BAREBOX_UPDATE) += bbu.o

View File

@ -24,6 +24,7 @@
#include <environment.h>
#include <led.h>
#include <of.h>
#include <restart.h>
int errno;
EXPORT_SYMBOL(errno);
@ -206,7 +207,7 @@ void __noreturn panic(const char *fmt, ...)
hang();
} else {
udelay(100000); /* allow messages to go out */
reset_cpu(0);
restart_machine();
}
}
EXPORT_SYMBOL(panic);

View File

@ -11,6 +11,7 @@
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#define pr_fmt(fmt) "reset-source: " fmt
#include <common.h>
#include <init.h>
@ -30,6 +31,7 @@ static const char * const reset_src_names[] = {
};
static enum reset_src_type reset_source;
static unsigned int reset_source_priority;
enum reset_src_type reset_source_get(void)
{
@ -37,20 +39,41 @@ enum reset_src_type reset_source_get(void)
}
EXPORT_SYMBOL(reset_source_get);
void reset_source_set(enum reset_src_type st)
void reset_source_set_priority(enum reset_src_type st, unsigned int priority)
{
reset_source = st;
if (priority <= reset_source_priority)
return;
globalvar_add_simple("system.reset", reset_src_names[reset_source]);
reset_source = st;
reset_source_priority = priority;
pr_debug("Setting reset source to %s with priority %d\n",
reset_src_names[reset_source], priority);
}
EXPORT_SYMBOL(reset_source_set);
/* ensure this runs after the 'global' device is already registerd */
static int reset_source_init(void)
{
reset_source_set(reset_source);
globalvar_add_simple_enum("system.reset", (unsigned int *)&reset_source,
reset_src_names, ARRAY_SIZE(reset_src_names));
return 0;
}
coredevice_initcall(reset_source_init);
/**
* of_get_reset_source_priority() - get the desired reset source priority from
* device tree
* @node: The device_node to read the property from
*
* return: The priority
*/
unsigned int of_get_reset_source_priority(struct device_node *node)
{
unsigned int priority = RESET_SOURCE_DEFAULT_PRIORITY;
of_property_read_u32(node, "reset-source-priority", &priority);
return priority;
}

112
common/restart.c Normal file
View File

@ -0,0 +1,112 @@
/*
* Copyright (c) 2015 Sascha Hauer <s.hauer@pengutronix.de>, Pengutronix
*
* See file CREDITS for list of people who contributed to this
* project.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation.
*
* 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.
*
*/
#define pr_fmt(fmt) "restart: " fmt
#include <common.h>
#include <restart.h>
#include <malloc.h>
#include <of.h>
static LIST_HEAD(restart_handler_list);
/**
* restart_handler_register() - register a handler for restarting the system
* @rst: The handler struct
*
* This adds @rst to the list of registered restart handlers.
*
* return: 0 for success or negative error code
*/
int restart_handler_register(struct restart_handler *rst)
{
if (!rst->name)
rst->name = RESTART_DEFAULT_NAME;
if (!rst->priority)
rst->priority = RESTART_DEFAULT_PRIORITY;
list_add_tail(&rst->list, &restart_handler_list);
pr_debug("registering restart handler \"%s\" with priority %d\n",
rst->name, rst->priority);
return 0;
}
/**
* restart_handler_register_fn() - register a handler function
* @restart_fn: The restart function
*
* convenience wrapper for restart_handler_register() to register a handler
* with given function and default values otherwise.
*
* return: 0 for success or negative error code
*/
int restart_handler_register_fn(void (*restart_fn)(struct restart_handler *))
{
struct restart_handler *rst;
int ret;
rst = xzalloc(sizeof(*rst));
rst->restart = restart_fn;
ret = restart_handler_register(rst);
if (ret)
free(rst);
return ret;
}
/**
* restart_machine() - reset the whole system
*/
void __noreturn restart_machine(void)
{
struct restart_handler *rst = NULL, *tmp;
unsigned int priority = 0;
list_for_each_entry(tmp, &restart_handler_list, list) {
if (tmp->priority > priority) {
priority = tmp->priority;
rst = tmp;
}
}
if (rst) {
pr_debug("%s: using restart handler %s\n", __func__, rst->name);
console_flush();
rst->restart(rst);
}
hang();
}
/**
* of_get_restart_priority() - get the desired restart priority from device tree
* @node: The device_node to read the property from
*
* return: The priority
*/
unsigned int of_get_restart_priority(struct device_node *node)
{
unsigned int priority = RESTART_DEFAULT_PRIORITY;
of_property_read_u32(node, "restart-priority", &priority);
return priority;
}

View File

@ -4,6 +4,17 @@ config MFD_ACT8846
depends on I2C
bool "ACT8846 driver"
config MFD_DA9053
depends on I2C
bool "DA9053 PMIC driver"
help
This power management controller provides configurable power supplies,
a machine restart feature and a watchdog.
config MFD_DA9063
depends on I2C
bool "DA9063 PMIC driver"
config MFD_LP3972
depends on I2C
bool "LP3972 driver"

View File

@ -1,4 +1,6 @@
obj-$(CONFIG_MFD_ACT8846) += act8846.o
obj-$(CONFIG_MFD_DA9053) += da9053.o
obj-$(CONFIG_MFD_DA9063) += da9063.o
obj-$(CONFIG_MFD_LP3972) += lp3972.o
obj-$(CONFIG_MFD_MC13XXX) += mc13xxx.o
obj-$(CONFIG_MFD_MC34704) += mc34704.o

308
drivers/mfd/da9053.c Normal file
View File

@ -0,0 +1,308 @@
/*
* Copyright (C) 2013 Jan Luebbe <jlu@pengutronix.de>
*
* 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 <common.h>
#include <init.h>
#include <driver.h>
#include <xfuncs.h>
#include <errno.h>
#include <watchdog.h>
#include <reset_source.h>
#include <i2c/i2c.h>
#include <restart.h>
#define DRIVERNAME "da9053"
/* STATUS REGISTERS */
#define DA9053_STATUS_A_REG 1
#define DA9053_STATUS_B_REG 2
#define DA9053_STATUS_C_REG 3
#define DA9053_STATUS_D_REG 4
/* PARK REGISTER */
#define DA9053_PARK_REGISTER DA9053_STATUS_D_REG
/* EVENT REGISTERS */
#define DA9053_EVENT_A_REG 5
#define DA9053_EVENT_B_REG 6
#define DA9053_EVENT_C_REG 7
#define DA9053_EVENT_D_REG 8
#define DA9053_FAULTLOG_REG 9
/* IRQ REGISTERS */
#define DA9053_IRQ_MASK_A_REG 10
#define DA9053_IRQ_MASK_B_REG 11
#define DA9053_IRQ_MASK_C_REG 12
#define DA9053_IRQ_MASK_D_REG 13
/* CONTROL REGISTERS */
#define DA9053_CONTROL_A_REG 14
#define DA9053_CONTROL_B_REG 15
#define DA9053_CONTROL_C_REG 16
#define DA9053_CONTROL_D_REG 17
#define DA9053_PDDIS_REG 18
#define DA9053_INTERFACE_REG 19
#define DA9053_RESET_REG 20
/* FAULT LOG REGISTER BITS */
#define DA9053_FAULTLOG_WAITSET 0X80
#define DA9053_FAULTLOG_NSDSET 0X40
#define DA9053_FAULTLOG_KEYSHUT 0X20
#define DA9053_FAULTLOG_TEMPOVER 0X08
#define DA9053_FAULTLOG_VDDSTART 0X04
#define DA9053_FAULTLOG_VDDFAULT 0X02
#define DA9053_FAULTLOG_TWDERROR 0X01
/* CONTROL REGISTER B BITS */
#define DA9053_CONTROLB_SHUTDOWN 0X80
#define DA9053_CONTROLB_DEEPSLEEP 0X40
#define DA9053_CONTROLB_WRITEMODE 0X20
#define DA9053_CONTROLB_BBATEN 0X10
#define DA9053_CONTROLB_OTPREADEN 0X08
#define DA9053_CONTROLB_AUTOBOOT 0X04
#define DA9053_CONTROLB_ACTDIODE 0X02
#define DA9053_CONTROLB_BUCKMERGE 0X01
/* CONTROL REGISTER D BITS */
#define DA9053_CONTROLD_WATCHDOG 0X80
#define DA9053_CONTROLD_ACCDETEN 0X40
#define DA9053_CONTROLD_GPI1415SD 0X20
#define DA9053_CONTROLD_NONKEYSD 0X10
#define DA9053_CONTROLD_KEEPACTEN 0X08
#define DA9053_CONTROLD_TWDSCALE 0X07
struct da9053_priv {
struct watchdog wd;
struct i2c_client *client;
struct device_d *dev;
struct restart_handler restart;
};
#define wd_to_da9053_priv(x) container_of(x, struct da9053_priv, wd)
static int da9053_reg_read(struct da9053_priv *da9053, u32 reg, u8 *val)
{
int ret;
ret = i2c_read_reg(da9053->client, reg, val, 1);
return ret == 1 ? 0 : ret;
}
static int da9053_reg_write(struct da9053_priv *da9053, u32 reg, u8 val)
{
int ret;
ret = i2c_write_reg(da9053->client, reg, &val, 1);
return ret == 1 ? 0 : ret;
}
static int da9053_park(struct da9053_priv *da9053)
{
int ret;
u8 val;
ret = i2c_read_reg(da9053->client, DA9053_PARK_REGISTER, &val, 1);
return ret == 1 ? 0 : ret;
}
static int da9053_enable_multiwrite(struct da9053_priv *da9053)
{
int ret;
u8 val;
ret = da9053_reg_read(da9053, DA9053_CONTROL_B_REG, &val);
if (ret < 0)
return ret;
if (val & DA9053_CONTROLB_WRITEMODE) {
val &= ~DA9053_CONTROLB_WRITEMODE;
ret = da9053_reg_write(da9053, DA9053_CONTROL_B_REG, val);
if (ret < 0)
return ret;
}
ret = da9053_park(da9053);
if (ret < 0)
return ret;
return 0;
}
static int da9053_set_timeout(struct watchdog *wd, unsigned timeout)
{
struct da9053_priv *da9053 = wd_to_da9053_priv(wd);
struct device_d *dev = da9053->cdev.dev;
unsigned scale = 0;
int ret;
u8 val;
if (timeout > 131)
return -EINVAL;
if (timeout) {
timeout *= 1000; /* convert to ms */
scale = 0;
while (timeout > (2048 << scale) && scale <= 6)
scale++;
dev_dbg(dev, "calculated TWDSCALE=%u (req=%ims calc=%ims)\n",
scale, timeout, 2048 << scale);
scale++; /* scale 0 disables the WD */
}
ret = da9053_reg_read(da9053, DA9053_CONTROL_D_REG, &val);
if (ret < 0)
return ret;
dev_dbg(dev, "read watchdog (val=0x%02x)\n", val);
if (scale && scale == (val & DA9053_CONTROLD_TWDSCALE)) {
/* trigger WD */
val |= DA9053_CONTROLD_WATCHDOG;
ret = da9053_reg_write(da9053, DA9053_CONTROL_D_REG, val);
if (ret < 0)
return ret;
dev_dbg(dev, "triggered watchdog (val=0x%02x)\n", val);
} else {
/* disable WD first */
val &= ~DA9053_CONTROLD_TWDSCALE;
ret = da9053_reg_write(da9053, DA9053_CONTROL_D_REG, val);
if (ret < 0)
return ret;
dev_dbg(dev, "disabled watchdog (val=0x%02x)\n", val);
if (scale) {
/* park before waiting */
ret = da9053_park(da9053);
if (ret < 0)
return ret;
/* wait required time */
udelay(150);
/* enable WD with new timeout */
val |= scale;
ret = da9053_reg_write(da9053, DA9053_CONTROL_D_REG, val);
if (ret < 0)
return ret;
dev_dbg(dev, "enabled watchdog (val=0x%02x)\n", val);
}
}
ret = da9053_park(da9053);
if (ret < 0)
return ret;
return 0;
}
static void da9053_detect_reset_source(struct da9053_priv *da9053)
{
unsigned int priority;
enum reset_src_type type;
int ret;
u8 val;
ret = da9053_reg_read(da9053, DA9053_FAULTLOG_REG, &val);
if (ret < 0)
return;
ret = da9053_park(da9053);
if (ret < 0)
return;
if (val & DA9053_FAULTLOG_TWDERROR)
type = RESET_WDG;
else if (val & DA9053_FAULTLOG_VDDFAULT)
type = RESET_POR;
else if (val & DA9053_FAULTLOG_NSDSET)
type = RESET_RST;
else
return;
priority = of_get_reset_source_priority(da9053->dev->device_node);
reset_source_set_priority(type, priority);
}
static void __noreturn da9053_force_system_reset(struct restart_handler *rst)
{
struct da9053_priv *da9053 = container_of(rst, struct da9053_priv, restart);
u8 val;
int ret;
ret = da9053_reg_read(da9053, DA9053_CONTROL_B_REG, &val);
if (ret < 0)
hang();
val |= DA9053_CONTROLB_SHUTDOWN;
ret = da9053_reg_write(da9053, DA9053_CONTROL_B_REG, val);
if (ret < 0)
hang();
da9053_park(da9053);
hang();
}
static int da9053_probe(struct device_d *dev)
{
struct da9053_priv *da9053;
int ret;
da9053 = xzalloc(sizeof(*da9053));
da9053->dev = dev;
da9053->cdev.name = DRIVERNAME;
da9053->client = to_i2c_client(dev);
da9053->wd.set_timeout = da9053_set_timeout;
da9053->wd.priority = of_get_watchdog_priority(dev->device_node);
da9053->wd.dev = dev;
ret = da9053_enable_multiwrite(da9053);
if (ret < 0)
return ret;
ret = watchdog_register(&da9053->wd);
if (ret)
return ret;
da9053_detect_reset_source(da9053);
da9053->restart.priority = of_get_restart_priority(dev->device_node);
da9053->restart.name = "da9063";
da9053->restart.restart = &da9053_force_system_reset;
restart_handler_register(&da9053->restart);
return 0;
}
static struct driver_d da9053_driver = {
.name = DRIVERNAME,
.probe = da9053_probe,
};
static int da9053_init(void)
{
i2c_driver_register(&da9053_driver);
return 0;
}
device_initcall(da9053_init);

169
drivers/mfd/da9063.c Normal file
View File

@ -0,0 +1,169 @@
/*
* Copyright (C) 2015 Pengutronix, Philipp Zabel <p.zabel@pengutronix.de>
*
* 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 <common.h>
#include <driver.h>
#include <restart.h>
#include <init.h>
#include <i2c/i2c.h>
#include <malloc.h>
#include <notifier.h>
#include <reset_source.h>
#include <watchdog.h>
struct da9063 {
struct restart_handler restart;
struct watchdog wd;
struct i2c_client *client;
struct device_d *dev;
};
/* System Control and Event Registers */
#define DA9063_REG_FAULT_LOG 0x05
#define DA9063_REG_CONTROL_D 0x11
#define DA9063_REG_CONTROL_F 0x13
/* DA9063_REG_FAULT_LOG (addr=0x05) */
#define DA9063_TWD_ERROR 0x01
#define DA9063_POR 0x02
#define DA9063_NSHUTDOWN 0x40
/* DA9063_REG_CONTROL_D (addr=0x11) */
#define DA9063_TWDSCALE_MASK 0x07
/* DA9063_REG_CONTROL_F (addr=0x13) */
#define DA9063_SHUTDOWN 0x02
static int da9063_watchdog_set_timeout(struct watchdog *wd, unsigned timeout)
{
struct da9063 *priv = container_of(wd, struct da9063, wd);
struct device_d *dev = priv->dev;
unsigned int scale = 0;
int ret;
u8 val;
if (timeout > 131)
return -EINVAL;
if (timeout) {
timeout *= 1000; /* convert to ms */
scale = 0;
while (timeout > (2048 << scale) && scale <= 6)
scale++;
dev_dbg(dev, "calculated TWDSCALE=%u (req=%ims calc=%ims)\n",
scale, timeout, 2048 << scale);
scale++; /* scale 0 disables the WD */
}
ret = i2c_read_reg(priv->client, DA9063_REG_CONTROL_D, &val, 1);
if (ret < 0)
return ret;
val &= ~DA9063_TWDSCALE_MASK;
val |= scale;
ret = i2c_write_reg(priv->client, DA9063_REG_CONTROL_D, &val, 1);
if (ret < 0)
return ret;
return 0;
}
static void da9063_detect_reset_source(struct da9063 *priv)
{
int ret;
u8 val;
unsigned int priority;
enum reset_src_type type;
ret = i2c_read_reg(priv->client, DA9063_REG_FAULT_LOG, &val, 1);
if (ret < 0)
return;
/* Write one to clear */
i2c_write_reg(priv->client, DA9063_REG_FAULT_LOG, &val, 1);
if (val & DA9063_TWD_ERROR)
type = RESET_WDG;
else if (val & DA9063_POR)
type = RESET_POR;
else if (val & DA9063_NSHUTDOWN)
type = RESET_RST;
else
return;
priority = of_get_reset_source_priority(priv->dev->device_node);
reset_source_set_priority(type, priority);
}
static void da9063_restart(struct restart_handler *rst)
{
struct da9063 *priv = container_of(rst, struct da9063, restart);
u8 val = DA9063_SHUTDOWN;
i2c_write_reg(priv->client, DA9063_REG_CONTROL_F, &val, 1);
}
static int da9063_probe(struct device_d *dev)
{
struct da9063 *priv = NULL;
int ret;
priv = xzalloc(sizeof(struct da9063));
priv->wd.priority = of_get_watchdog_priority(dev->device_node);
priv->wd.set_timeout = da9063_watchdog_set_timeout;
priv->wd.dev = dev;
priv->client = to_i2c_client(dev);
priv->dev = dev;
ret = watchdog_register(&priv->wd);
if (ret)
goto on_error;
da9063_detect_reset_source(priv);
priv->restart.priority = of_get_restart_priority(dev->device_node);
priv->restart.name = "da9063";
priv->restart.restart = &da9063_restart;
restart_handler_register(&priv->restart);
return 0;
on_error:
if (priv)
free(priv);
return ret;
}
static struct platform_device_id da9063_id[] = {
{ "da9063", },
{ }
};
static struct driver_d da9063_driver = {
.name = "da9063",
.probe = da9063_probe,
.id_table = da9063_id,
};
static int da9063_init(void)
{
return i2c_driver_register(&da9063_driver);
}
device_initcall(da9063_init);

View File

@ -31,6 +31,7 @@
#include <progress.h>
#include <environment.h>
#include <globalvar.h>
#include <restart.h>
#include <usb/ch9.h>
#include <usb/gadget.h>
#include <usb/fastboot.h>
@ -520,7 +521,7 @@ static int fastboot_tx_print(struct f_fastboot *f_fb, const char *fmt, ...)
static void compl_do_reset(struct usb_ep *ep, struct usb_request *req)
{
reset_cpu(0);
restart_machine();
}
static void cb_reboot(struct usb_ep *ep, struct usb_request *req, const char *cmd)

View File

@ -147,6 +147,7 @@ static int davinci_wdt_probe(struct device_d *dev)
clk_enable(davinci_wdt->clk);
davinci_wdt->wd.set_timeout = davinci_wdt_set_timeout;
davinci_wdt->wd.dev = dev;
ret = watchdog_register(&davinci_wdt->wd);
if (ret < 0)

View File

@ -197,6 +197,7 @@ static int imx28_wd_probe(struct device_d *dev)
if (IS_ERR(priv->regs))
return PTR_ERR(priv->regs);
priv->wd.set_timeout = imx28_watchdog_set_timeout;
priv->wd.dev = dev;
if (!(readl(priv->regs + MXS_RTC_STAT) & MXS_RTC_STAT_WD_PRESENT)) {
rc = -ENODEV;

View File

@ -18,6 +18,7 @@
#include <of.h>
#include <errno.h>
#include <malloc.h>
#include <restart.h>
#include <watchdog.h>
#include <reset_source.h>
@ -33,6 +34,7 @@ struct imx_wd {
void __iomem *base;
struct device_d *dev;
const struct imx_wd_ops *ops;
struct restart_handler restart;
};
#define to_imx_wd(h) container_of(h, struct imx_wd, wd)
@ -121,12 +123,11 @@ static int imx_watchdog_set_timeout(struct watchdog *wd, unsigned timeout)
return priv->ops->set_timeout(priv, timeout);
}
static struct imx_wd *reset_wd;
void __noreturn reset_cpu(unsigned long addr)
static void __noreturn imxwd_force_soc_reset(struct restart_handler *rst)
{
if (reset_wd)
reset_wd->ops->set_timeout(reset_wd, -1);
struct imx_wd *priv = container_of(rst, struct imx_wd, restart);
priv->ops->set_timeout(priv, -1);
mdelay(1000);
@ -185,11 +186,9 @@ static int imx_wd_probe(struct device_d *dev)
}
priv->ops = ops;
priv->wd.set_timeout = imx_watchdog_set_timeout;
priv->wd.dev = dev;
priv->dev = dev;
if (!reset_wd)
reset_wd = priv;
if (IS_ENABLED(CONFIG_WATCHDOG_IMX)) {
ret = watchdog_register(&priv->wd);
if (ret)
@ -206,28 +205,21 @@ static int imx_wd_probe(struct device_d *dev)
dev->priv = priv;
priv->restart.name = "imxwd";
priv->restart.restart = imxwd_force_soc_reset;
restart_handler_register(&priv->restart);
return 0;
error_unregister:
if (IS_ENABLED(CONFIG_WATCHDOG_IMX))
watchdog_deregister(&priv->wd);
on_error:
if (reset_wd && reset_wd != priv)
free(priv);
free(priv);
return ret;
}
static void imx_wd_remove(struct device_d *dev)
{
struct imx_wd *priv = dev->priv;
if (IS_ENABLED(CONFIG_WATCHDOG_IMX))
watchdog_deregister(&priv->wd);
if (reset_wd && reset_wd != priv)
free(priv);
}
static const struct imx_wd_ops imx21_wd_ops = {
.set_timeout = imx21_watchdog_set_timeout,
.init = imx21_wd_init,
@ -264,7 +256,6 @@ static struct platform_device_id imx_wdt_ids[] = {
static struct driver_d imx_wd_driver = {
.name = "imx-watchdog",
.probe = imx_wd_probe,
.remove = imx_wd_remove,
.of_compatible = DRV_OF_COMPAT(imx_wdt_dt_ids),
.id_table = imx_wdt_ids,
};

View File

@ -16,6 +16,7 @@
#include <common.h>
#include <init.h>
#include <restart.h>
#include <io.h>
#define JZ_REG_WDT_TIMER_DATA 0x0
@ -39,33 +40,30 @@
#define JZ_EXTAL 24000000
struct jz4740_wdt_drvdata {
struct restart_handler restart;
void __iomem *base;
};
static struct jz4740_wdt_drvdata *reset_wd;
void __noreturn reset_cpu(unsigned long addr)
static void __noreturn jz4740_reset_soc(struct restart_handler *rst)
{
if (reset_wd) {
void __iomem *base = reset_wd->base;
struct jz4740_wdt_drvdata *priv =
container_of(rst, struct jz4740_wdt_drvdata, restart);
void __iomem *base = priv->base;
writew(JZ_WDT_CLOCK_DIV_4 | JZ_WDT_CLOCK_EXT,
base + JZ_REG_WDT_TIMER_CONTROL);
writew(0, base + JZ_REG_WDT_TIMER_COUNTER);
writew(JZ_WDT_CLOCK_DIV_4 | JZ_WDT_CLOCK_EXT,
base + JZ_REG_WDT_TIMER_CONTROL);
writew(0, base + JZ_REG_WDT_TIMER_COUNTER);
/* reset after 4ms */
writew(JZ_EXTAL / 1000, base + JZ_REG_WDT_TIMER_DATA);
/* reset after 4ms */
writew(JZ_EXTAL / 1000, base + JZ_REG_WDT_TIMER_DATA);
/* start wdt */
writeb(0x1, base + JZ_REG_WDT_COUNTER_ENABLE);
/* start wdt */
writeb(0x1, base + JZ_REG_WDT_COUNTER_ENABLE);
mdelay(1000);
} else
pr_err("%s: can't reset cpu\n", __func__);
mdelay(1000);
hang();
}
EXPORT_SYMBOL(reset_cpu);
static int jz4740_wdt_probe(struct device_d *dev)
{
@ -78,11 +76,12 @@ static int jz4740_wdt_probe(struct device_d *dev)
return -ENODEV;
}
if (!reset_wd)
reset_wd = priv;
dev->priv = priv;
priv->restart.name = "jz4740-wdt";
priv->restart.restart = jz4740_reset_soc;
restart_handler_register(&priv->restart);
return 0;
}

View File

@ -11,6 +11,7 @@
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#define pr_fmt(fmt) "watchdog: " fmt
#include <common.h>
#include <command.h>
@ -18,40 +19,85 @@
#include <linux/ctype.h>
#include <watchdog.h>
/*
* Note: this simple framework supports one watchdog only.
*/
static struct watchdog *watchdog;
static LIST_HEAD(watchdog_list);
static const char *watchdog_name(struct watchdog *wd)
{
if (wd->dev)
return dev_name(wd->dev);
if (wd->name)
return wd->name;
return "unknown";
}
int watchdog_register(struct watchdog *wd)
{
if (watchdog != NULL)
return -EBUSY;
if (!wd->priority)
wd->priority = WATCHDOG_DEFAULT_PRIORITY;
list_add_tail(&wd->list, &watchdog_list);
pr_debug("registering watchdog %s with priority %d\n", watchdog_name(wd),
wd->priority);
watchdog = wd;
return 0;
}
EXPORT_SYMBOL(watchdog_register);
int watchdog_deregister(struct watchdog *wd)
{
if (watchdog == NULL || wd != watchdog)
return -ENODEV;
list_del(&wd->list);
watchdog = NULL;
return 0;
}
EXPORT_SYMBOL(watchdog_deregister);
static struct watchdog *watchdog_get_default(void)
{
struct watchdog *tmp, *wd = NULL;
int priority = 0;
list_for_each_entry(tmp, &watchdog_list, list) {
if (tmp->priority > priority) {
priority = tmp->priority;
wd = tmp;
}
}
return wd;
}
/*
* start, stop or retrigger the watchdog
* timeout in [seconds]. timeout of '0' will disable the watchdog (if possible)
*/
int watchdog_set_timeout(unsigned timeout)
{
if (watchdog == NULL)
struct watchdog *wd;
wd = watchdog_get_default();
if (!wd)
return -ENODEV;
return watchdog->set_timeout(watchdog, timeout);
pr_debug("setting timeout on %s to %ds\n", watchdog_name(wd), timeout);
return wd->set_timeout(wd, timeout);
}
EXPORT_SYMBOL(watchdog_set_timeout);
/**
* of_get_watchdog_priority() - get the desired watchdog priority from device tree
* @node: The device_node to read the property from
*
* return: The priority
*/
unsigned int of_get_watchdog_priority(struct device_node *node)
{
unsigned int priority = WATCHDOG_DEFAULT_PRIORITY;
of_property_read_u32(node, "watchdog-priority", &priority);
return priority;
}

View File

@ -67,7 +67,6 @@ int readline (const char *prompt, char *buf, int len);
long get_ram_size (volatile long *, long);
/* $(CPU)/cpu.c */
void __noreturn reset_cpu(unsigned long addr);
void __noreturn poweroff(void);
/* lib_$(ARCH)/time.c */

View File

@ -25,10 +25,11 @@ enum reset_src_type {
};
#ifdef CONFIG_RESET_SOURCE
void reset_source_set(enum reset_src_type);
void reset_source_set_priority(enum reset_src_type, unsigned int priority);
enum reset_src_type reset_source_get(void);
#else
static inline void reset_source_set(enum reset_src_type unused)
static inline void reset_source_set_priority(enum reset_src_type type,
unsigned int priority)
{
}
@ -38,4 +39,13 @@ static inline enum reset_src_type reset_source_get(void)
}
#endif
#define RESET_SOURCE_DEFAULT_PRIORITY 100
static inline void reset_source_set(enum reset_src_type type)
{
reset_source_set_priority(type, RESET_SOURCE_DEFAULT_PRIORITY);
}
unsigned int of_get_reset_source_priority(struct device_node *node);
#endif /* __INCLUDE_RESET_SOURCE_H */

21
include/restart.h Normal file
View File

@ -0,0 +1,21 @@
#ifndef __INCLUDE_RESTART_H
#define __INCLUDE_RESTART_H
void __noreturn restart_machine(void);
struct restart_handler {
void (*restart)(struct restart_handler *);
int priority;
const char *name;
struct list_head list;
};
int restart_handler_register(struct restart_handler *);
int restart_handler_register_fn(void (*restart_fn)(struct restart_handler *));
#define RESTART_DEFAULT_PRIORITY 100
#define RESTART_DEFAULT_NAME "default"
unsigned int of_get_restart_priority(struct device_node *node);
#endif /* __INCLUDE_RESTART_H */

View File

@ -15,6 +15,10 @@
struct watchdog {
int (*set_timeout)(struct watchdog *, unsigned);
const char *name;
struct device_d *dev;
unsigned int priority;
struct list_head list;
};
#ifdef CONFIG_WATCHDOG
@ -38,4 +42,8 @@ static inline int watchdog_set_timeout(unsigned t)
}
#endif
#define WATCHDOG_DEFAULT_PRIORITY 100
unsigned int of_get_watchdog_priority(struct device_node *node);
#endif /* INCLUDE_WATCHDOG_H */