Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -853,6 +853,41 @@ static ssize_t fan_led_store(struct device *dev, struct device_attribute *devatt
return count;
}

static ssize_t watchdog_show(struct device *dev,
struct device_attribute *devattr, char *buf)
{
s32 ret;
u8 data = 0;
struct cpld_platform_data *pdata = dev->platform_data;

ret = i2c_smbus_read_byte_data(pdata[cpu_cpld].client, 0x7);
if (ret < 0)
return sprintf(buf, "read error");
data = ret;

return sprintf(buf, "%x\n", data);
}

static ssize_t watchdog_store(struct device *dev, struct device_attribute *devattr, const char *buf, size_t count)
{
s32 ret, err;
unsigned long val;
u8 data = 0;
struct cpld_platform_data *pdata = dev->platform_data;

err = kstrtoul(buf, 10, &val);
if (err)
return err;

if (data)
{
ret = i2c_smbus_write_byte_data(pdata[cpu_cpld].client, 0x7, data);
if (ret < 0)
return ret;
}

return count;
}

static ssize_t power_good_show(struct device *dev,
struct device_attribute *devattr, char *buf)
Expand Down Expand Up @@ -947,6 +982,7 @@ static DEVICE_ATTR_RO(psu1_prs);
static DEVICE_ATTR_RO(psu0_status);
static DEVICE_ATTR_RO(psu1_status);
static DEVICE_ATTR_RW(system_led);
static DEVICE_ATTR_RW(watchdog);
static DEVICE_ATTR_RW(locator_led);
static DEVICE_ATTR_RW(power_led);
static DEVICE_ATTR_RW(master_led);
Expand Down Expand Up @@ -988,6 +1024,7 @@ static struct attribute *n3248pxe_cpld_attrs[] = {
&dev_attr_psu0_status.attr,
&dev_attr_psu1_status.attr,
&dev_attr_system_led.attr,
&dev_attr_watchdog.attr,
&dev_attr_locator_led.attr,
&dev_attr_power_led.attr,
&dev_attr_master_led.attr,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@

try:
import ctypes
import subprocess
from sonic_platform_base.watchdog_base import WatchdogBase
except ImportError as e:
raise ImportError(str(e) + "- required module not found")
Expand All @@ -29,43 +28,53 @@ class Watchdog(WatchdogBase):
Abstract base class for interfacing with a hardware watchdog module
"""

TIMERS = [15,20,30,40,50,60,65,70]
TIMERS = [15,20,30,40,50,60,65,70,80,100,120,140,160,180,210,240]

armed_time = 0
timeout = 0
CLOCK_MONOTONIC = 1

def __init__(self):
WatchdogBase.__init__(self)
self._librt = ctypes.CDLL('librt.so.1', use_errno=True)
self._clock_gettime = self._librt.clock_gettime
self._clock_gettime.argtypes=[ctypes.c_int, ctypes.POINTER(_timespec)]
self.watchdog_reg = "watchdog"

def _get_command_result(self, cmdline):
def _get_cpld_register(self, reg_name):
# On successful read, returns the value read from given
# reg name and on failure rethrns 'ERR'
cpld_dir = "/sys/devices/platform/dell-n3248pxe-cpld.0/"
cpld_reg_file = cpld_dir + '/' + reg_name
try:
proc = subprocess.Popen(cmdline.split(), stdout=subprocess.PIPE,
stderr=subprocess.STDOUT)
stdout = proc.communicate()[0]
proc.wait()
result = stdout.rstrip('\n')
except OSError:
result = None
with open(cpld_reg_file, 'r') as fd:
rv = fd.read()
except IOError : return 'ERR'
return rv.strip('\r\n').lstrip(' ')

return result
def _set_cpld_register(self, reg_name, value):
# On successful write, returns the value will be written on
# reg_name and on failure returns 'ERR'

cpld_dir = "/sys/devices/platform/dell-n3248pxe-cpld.0/"
cpld_reg_file = cpld_dir + '/' + reg_name

try:
with open(cpld_reg_file, 'w') as fd:
rv = fd.write(str(value))
except Exception:
rv = 'ERR'

return rv

def _get_reg_val(self):
# 0x31 = CPLD I2C Base Address
# 0x07 = Watchdog Function Register
value = self._get_command_result("/usr/sbin/i2cget -y 601 0x31 0x07")
if not value:
return None
else:
return int(value, 16)
value = self._get_cpld_register(self.watchdog_reg).strip()
if value == 'ERR': return False

return int(value,16)

def _set_reg_val(self,val):
# 0x31 = CPLD I2C Base Address
# 0x07 = Watchdog Function Register
value = self._get_command_result("/usr/sbin/i2cset -y 601 0x31 0x07 %s"
% (val))
value = self._set_cpld_register(self.watchdog_reg, val)
return value

def _get_time(self):
Expand Down Expand Up @@ -93,48 +102,37 @@ def arm(self, seconds):
"""
timer_offset = -1
for key,timer_seconds in enumerate(self.TIMERS):
if seconds <= timer_seconds:
if seconds > 0 and seconds <= timer_seconds:
timer_offset = key
seconds = timer_seconds
break

if timer_offset == -1:
return -1

# Extracting 5th to 7th bits for WD timer values
# 000 - 15 sec
# 001 - 20 sec
# 010 - 30 sec
# 011 - 40 sec
# 100 - 50 sec
# 101 - 60 sec
# 110 - 65 sec
# 111 - 70 sec
# Extracting 5th to 8th bits for WD timer values
reg_val = self._get_reg_val()
wd_timer_offset = (reg_val >> 4) & 0x7
wd_timer_offset = (reg_val >> 4) & 0xF

if wd_timer_offset != timer_offset:
# Setting 5th to 7th bits
# Setting 5th to 8th bits
# value from timer_offset
self.disarm()
self._set_reg_val(reg_val | (timer_offset << 4))
self._set_reg_val((reg_val & 0x0F) | (timer_offset << 4))

if self.is_armed():
# Setting last bit to WD Timer punch
# Last bit = WD Timer punch
self._set_reg_val(reg_val & 0xFE)

self.armed_time = self._get_time()
self.timeout = seconds
else:
# Setting 4th bit to enable WD
# 4th bit = Enable WD
reg_val = self._get_reg_val()
self._set_reg_val(reg_val | 0x8)

self.armed_time = self._get_time()
self.timeout = seconds

self.armed_time = self._get_time()
self.timeout = seconds
return seconds

def disarm(self):
Expand Down Expand Up @@ -207,4 +205,3 @@ def get_remaining_time(self):
return self.timeout - diff_time

return 0

Original file line number Diff line number Diff line change
Expand Up @@ -572,7 +572,7 @@ static ssize_t system_led_show(struct device *dev, struct device_attribute *deva
if (ret < 0)
return sprintf(buf, "read error");

data = (u8)(ret & 0x30) >> 5;
data = (u8)(ret & 0x30) >> 4;

switch (data)
{
Expand Down Expand Up @@ -878,6 +878,42 @@ static ssize_t fan_led_store(struct device *dev, struct device_attribute *devatt
return count;
}

static ssize_t watchdog_show(struct device *dev,
struct device_attribute *devattr, char *buf)
{
s32 ret;
u8 data = 0;
struct cpld_platform_data *pdata = dev->platform_data;

ret = i2c_smbus_read_byte_data(pdata[cpu_cpld].client, 0x7);
if (ret < 0)
return sprintf(buf, "read error");
data = ret;

return sprintf(buf, "%x\n", data);
}

static ssize_t watchdog_store(struct device *dev, struct device_attribute *devattr, const char *buf, size_t count)
{
s32 ret, err;
unsigned long val;
u8 data = 0;
struct cpld_platform_data *pdata = dev->platform_data;

err = kstrtoul(buf, 10, &val);
if (err)
return err;

data = (u8) val;
if (data)
{
ret = i2c_smbus_write_byte_data(pdata[cpu_cpld].client, 0x7, data);
if (ret < 0)
return ret;
}

return count;
}

static ssize_t power_good_show(struct device *dev,
struct device_attribute *devattr, char *buf)
Expand Down Expand Up @@ -974,6 +1010,7 @@ static DEVICE_ATTR_RO(psu1_prs);
static DEVICE_ATTR_RO(psu0_status);
static DEVICE_ATTR_RO(psu1_status);
static DEVICE_ATTR_RW(system_led);
static DEVICE_ATTR_RW(watchdog);
static DEVICE_ATTR_RW(locator_led);
static DEVICE_ATTR_RW(power_led);
static DEVICE_ATTR_RW(master_led);
Expand Down Expand Up @@ -1017,6 +1054,7 @@ static struct attribute *n3248te_cpld_attrs[] = {
&dev_attr_psu0_status.attr,
&dev_attr_psu1_status.attr,
&dev_attr_system_led.attr,
&dev_attr_watchdog.attr,
&dev_attr_locator_led.attr,
&dev_attr_power_led.attr,
&dev_attr_master_led.attr,
Expand Down
Loading