/*--------------------------------------------------------------------------------*\ * * Copyright (C) 2014 AVM GmbH * * 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. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA \*--------------------------------------------------------------------------------*/ #include #include #include #include #include #include #include #include #include #include #include #include #include #include "avm_sammel.h" #include "avm_event.h" /*--- #define AVM_WATCHDOG_DEBUG ---*/ #if defined(AVM_WATCHDOG_DEBUG) #define DBG(...) printk(KERN_INFO __VA_ARGS__) #else /*--- #if defined(AVM_WATCHDOG_DEBUG) ---*/ #define DBG(...) #endif /*--- #else ---*/ /*--- #if defined(AVM_WATCHDOG_DEBUG) ---*/ static unsigned int wdt_running; /*-----------------------------------------------------------------------------------------------*\ \*-----------------------------------------------------------------------------------------------*/ int ar7wdt_hw_is_wdt_running(void) { return wdt_running; } /**--------------------------------------------------------------------------------**\ * dummy \**--------------------------------------------------------------------------------**/ void ar7wdt_hw_secure_wdt_disable(void) { } static void *remote_event_source_handle; #if defined(CONFIG_AVM_EVENTNODE_PUMA6) || defined(CONFIG_AVM_EVENTNODE_PUMA7) /*--------------------------------------------------------------------------------*\ \*--------------------------------------------------------------------------------*/ static void lwdt_remotesend(const struct _avm_event_remotewatchdog *pevent) { struct _avm_event_remotewatchdog *event = (struct _avm_event_remotewatchdog *)kmalloc( sizeof(struct _avm_event_remotewatchdog), GFP_ATOMIC); if(event == NULL) { printk(KERN_WARNING "%s (remote): can't alloc event\n", __func__); return; } memcpy(event, pevent, sizeof(struct _avm_event_remotewatchdog)); avm_event_source_trigger(remote_event_source_handle, avm_event_id_remotewatchdog, sizeof(struct _avm_event_remotewatchdog), event); } /*--------------------------------------------------------------------------------*\ \*--------------------------------------------------------------------------------*/ static void lwdt_register(void) { const struct _avm_event_remotewatchdog event = { event_header: { id: avm_event_id_remotewatchdog }, cmd: wdt_register, name: "ATOM", param: 120 + WDT_DEFAULT_TIME * 4, // 2 * lockup detection time + std. timeout }; lwdt_remotesend(&event); } /*--------------------------------------------------------------------------------*\ \*--------------------------------------------------------------------------------*/ static void lwdt_release(void) { struct _avm_event_remotewatchdog event = { event_header: { id: avm_event_id_remotewatchdog }, cmd: wdt_release, name: "ATOM", param: 0, }; lwdt_remotesend(&event); } /*--------------------------------------------------------------------------------*\ \*--------------------------------------------------------------------------------*/ static void lwdt_trigger(void) { struct _avm_event_remotewatchdog event = { event_header: { id: avm_event_id_remotewatchdog }, cmd: wdt_trigger, name: "ATOM", param: 0, }; lwdt_remotesend(&event); } /*--------------------------------------------------------------------------------*\ \*--------------------------------------------------------------------------------*/ static void avm_event_remote_notify(void *context __attribute__((unused)), enum _avm_event_id id __attribute__((unused))) { } /*--------------------------------------------------------------------------------*\ * erst wenn Remote-Event-Node oben, Event-Schnittstellen anmelden \*--------------------------------------------------------------------------------*/ static void remote_event_node_established(void *private __attribute__((unused)), unsigned int param1 __attribute__((unused)), unsigned int param2 __attribute__((unused))){ struct _avm_event_id_mask id_mask; remote_event_source_handle = avm_event_source_register("avm_event_remotewatchdog", avm_event_build_id_mask(&id_mask, 1, avm_event_id_remotewatchdog), avm_event_remote_notify, NULL); if(remote_event_source_handle == NULL) { printk(KERN_ERR"%s not registered\n", __func__); return; } lwdt_register(); wdt_running = 1; } #endif/*--- #if defined(CONFIG_AVM_EVENTNODE_PUMA6) ---*/ /*-----------------------------------------------------------------------------------------------*\ \*-----------------------------------------------------------------------------------------------*/ void ar7wdt_hw_init(void) { printk(KERN_ERR"%s\n", __func__); #if defined(CONFIG_AVM_EVENTNODE_PUMA6) || defined(CONFIG_AVM_EVENTNODE_PUMA7) avm_event_node_established(remote_event_node_established, NULL, 0, 0); #else/*--- #if defined(CONFIG_AVM_EVENTNODE_PUMA6) ---*/ #error no watchdog implemented #endif/*--- #if defined(CONFIG_AVM_EVENT_20) ---*/ } /*--------------------------------------------------------------------------------*\ \*--------------------------------------------------------------------------------*/ void ar7wdt_hw_deinit(void) { #if defined(CONFIG_AVM_EVENTNODE_PUMA6) || defined(CONFIG_AVM_EVENTNODE_PUMA7) if(wdt_running) { lwdt_release(); wdt_running = 0; } #endif/*--- #if defined(CONFIG_AVM_EVENTNODE_PUMA6) ---*/ } /*------------------------------------------------------------------------------------------*\ \*------------------------------------------------------------------------------------------*/ void ar7wdt_hw_reboot(void) { DBG("ar7wdt_hw_reboot!!\n"); panic("ar7wdt_hw_reboot: watchdog expired\n"); } /*--------------------------------------------------------------------------------*\ \*--------------------------------------------------------------------------------*/ void ar7wdt_hw_trigger(void) { DBG("ar7wdt_hw_trigger !!\n"); #if defined(CONFIG_AVM_EVENTNODE_PUMA6) || defined(CONFIG_AVM_EVENTNODE_PUMA7) if(wdt_running) { lwdt_trigger(); } #endif/*--- #if defined(CONFIG_AVM_EVENTNODE_PUMA6) ---*/ } EXPORT_SYMBOL(ar7wdt_hw_trigger);