From 0340cf3b8b2116c847b4f326ea29ea2eb4050b45 Mon Sep 17 00:00:00 2001 From: Wirut Getbamrung Date: Wed, 24 Jul 2019 00:00:02 +0700 Subject: [PATCH] [device/celestica]: Implement device base APIs for Fan/PSU API based on the new platform API (#3163) * [platform/cel]: add fan present sysfs * [device/celestica]: move component device to chassis * [device/celestica]: add basic device api --- .../sonic_platform/chassis.py | 7 ++- .../sonic_platform/device.py | 47 ---------------- .../x86_64-cel_e1031-r0/sonic_platform/fan.py | 29 +++++++++- .../x86_64-cel_e1031-r0/sonic_platform/psu.py | 44 +++++++++++++++ .../sonic_platform/chassis.py | 5 +- .../sonic_platform/device.py | 47 ---------------- .../sonic_platform/fan.py | 19 +++++++ .../sonic_platform/psu.py | 53 +++++++++++++++++++ .../haliburton/modules/smc.c | 29 ++++++++++ 9 files changed, 177 insertions(+), 103 deletions(-) delete mode 100644 device/celestica/x86_64-cel_e1031-r0/sonic_platform/device.py delete mode 100644 device/celestica/x86_64-cel_seastone-r0/sonic_platform/device.py diff --git a/device/celestica/x86_64-cel_e1031-r0/sonic_platform/chassis.py b/device/celestica/x86_64-cel_e1031-r0/sonic_platform/chassis.py index 28e29e67dc..3703928e9c 100644 --- a/device/celestica/x86_64-cel_e1031-r0/sonic_platform/chassis.py +++ b/device/celestica/x86_64-cel_e1031-r0/sonic_platform/chassis.py @@ -18,17 +18,17 @@ try: from sonic_platform_base.chassis_base import ChassisBase from sonic_platform.fan import Fan from sonic_platform.psu import Psu - from sonic_platform.device import Device from sonic_platform.component import Component from sonic_platform.watchdog import Watchdog except ImportError as e: raise ImportError(str(e) + "- required module not found") -CONFIG_DB_PATH = "/etc/sonic/config_db.json" NUM_FAN = 3 NUM_PSU = 2 +CONFIG_DB_PATH = "/etc/sonic/config_db.json" RESET_REGISTER = "0x112" REBOOT_CAUSE_PATH = "/host/reboot-cause/previous-reboot-cause.txt" +COMPONENT_NAME_LIST = ["SMC_CPLD", "MMC_CPLD", "BIOS"] class Chassis(ChassisBase): @@ -43,8 +43,7 @@ class Chassis(ChassisBase): psu = Psu(index) self._psu_list.append(psu) ChassisBase.__init__(self) - self._component_device = Device("component") - self._component_name_list = self._component_device.get_name_list() + self._component_name_list = COMPONENT_NAME_LIST self._watchdog = Watchdog() def __read_config_db(self): diff --git a/device/celestica/x86_64-cel_e1031-r0/sonic_platform/device.py b/device/celestica/x86_64-cel_e1031-r0/sonic_platform/device.py deleted file mode 100644 index e95d372510..0000000000 --- a/device/celestica/x86_64-cel_e1031-r0/sonic_platform/device.py +++ /dev/null @@ -1,47 +0,0 @@ -#!/usr/bin/env python - -############################################################################# -# Celestica -# -# Device contains an implementation of SONiC Platform Base API and -# provides the device information -# -############################################################################# - -try: - from sonic_platform_base.device_base import DeviceBase -except ImportError as e: - raise ImportError(str(e) + "- required module not found") - - -class Device(DeviceBase): - """Platform-specific Device class""" - - COMPONENTS_NAME = ["SMC_CPLD", "MMC_CPLD", "BIOS"] - - def __init__(self, device_type, index=None): - self.device_type = device_type - self.index = index - DeviceBase.__init__(self) - - def get_name(self): - """ - Retrieves the name of the device - Returns: - string: The name of the device - """ - device_name = { - "component": self.COMPONENTS_NAME[self.index] - }.get(self.device_type, None) - return device_name - - def get_name_list(self): - """ - Retrieves list of the device name that available in this device type - Returns: - string: The list of device name - """ - name_list = { - "component": self.COMPONENTS_NAME - }.get(self.device_type, None) - return name_list diff --git a/device/celestica/x86_64-cel_e1031-r0/sonic_platform/fan.py b/device/celestica/x86_64-cel_e1031-r0/sonic_platform/fan.py index d16290aa45..ad993ce241 100644 --- a/device/celestica/x86_64-cel_e1031-r0/sonic_platform/fan.py +++ b/device/celestica/x86_64-cel_e1031-r0/sonic_platform/fan.py @@ -24,6 +24,7 @@ EMC2305_MAX_PWM = 255 EMC2305_FAN_PWM = "pwm{}" EMC2305_FAN_TARGET = "fan{}_target" EMC2305_FAN_INPUT = "pwm{}" +FAN_NAME_LIST = ["FAN-1", "FAN-2", "FAN-3"] class Fan(FanBase): @@ -43,8 +44,7 @@ class Fan(FanBase): 'index_map': [1, 2, 4] } ] - - # TODO: Add fan presence status in sysfs + self.fan_e1031_presence = "fan{}_prs" self.fan_e1031_direction = "fan{}_dir" self.fan_e1031_led = "fan{}_led" @@ -181,3 +181,28 @@ class Fan(FanBase): return False return True + + def get_name(self): + """ + Retrieves the name of the device + Returns: + string: The name of the device + """ + return FAN_NAME_LIST[self.index] + + def get_presence(self): + """ + Retrieves the presence of the PSU + Returns: + bool: True if PSU is present, False if not + """ + + try: + fan_direction_file = (FAN_PATH + + self.fan_e1031_presence.format(self.index+1)) + with open(fan_direction_file, 'r') as file: + present = int(file.read().strip('\r\n')) + except IOError: + return False + + return present == 0 diff --git a/device/celestica/x86_64-cel_e1031-r0/sonic_platform/psu.py b/device/celestica/x86_64-cel_e1031-r0/sonic_platform/psu.py index 8fd32fd64d..73b890a8b7 100644 --- a/device/celestica/x86_64-cel_e1031-r0/sonic_platform/psu.py +++ b/device/celestica/x86_64-cel_e1031-r0/sonic_platform/psu.py @@ -19,6 +19,7 @@ except ImportError as e: FAN_E1031_SPEED_PATH = "/sys/class/hwmon/hwmon{}/fan1_input" FAN_MAX_RPM = 11000 +PSU_NAME_LIST = ["PSU-R", "PSU-L"] class Psu(PsuBase): @@ -27,6 +28,9 @@ class Psu(PsuBase): def __init__(self, psu_index): PsuBase.__init__(self) self.index = psu_index + self.psu_path = "/sys/devices/platform/e1031.smc/" + self.psu_presence = "psu{}_prs" + self.psu_oper_status = "psu{}_status" def get_fan(self): """ @@ -59,3 +63,43 @@ class Psu(PsuBase): """ # Hardware not supported return False + + def get_name(self): + """ + Retrieves the name of the device + Returns: + string: The name of the device + """ + return PSU_NAME_LIST[self.index] + + def get_presence(self): + """ + Retrieves the presence of the PSU + Returns: + bool: True if PSU is present, False if not + """ + psu_location = ["R", "L"] + status = 0 + try: + with open(self.psu_path + self.psu_presence.format(psu_location[self.index]), 'r') as psu_prs: + status = int(psu_prs.read()) + except IOError: + return False + + return status == 1 + + def get_status(self): + """ + Retrieves the operational status of the device + Returns: + A boolean value, True if device is operating properly, False if not + """ + psu_location = ["R", "L"] + status = 0 + try: + with open(self.psu_path + self.psu_oper_status.format(psu_location[self.index]), 'r') as power_status: + status = int(power_status.read()) + except IOError: + return False + + return status == 1 diff --git a/device/celestica/x86_64-cel_seastone-r0/sonic_platform/chassis.py b/device/celestica/x86_64-cel_seastone-r0/sonic_platform/chassis.py index 8f5926df33..d7ff4adfa3 100644 --- a/device/celestica/x86_64-cel_seastone-r0/sonic_platform/chassis.py +++ b/device/celestica/x86_64-cel_seastone-r0/sonic_platform/chassis.py @@ -18,7 +18,6 @@ try: from sonic_platform_base.chassis_base import ChassisBase from sonic_platform.fan import Fan from sonic_platform.psu import Psu - from sonic_platform.device import Device from sonic_platform.component import Component from sonic_platform.watchdog import Watchdog except ImportError as e: @@ -29,6 +28,7 @@ NUM_FAN = 5 NUM_PSU = 2 RESET_REGISTER = "0x103" REBOOT_CAUSE_PATH = "/host/reboot-cause/previous-reboot-cause.txt" +COMPONENT_NAME_LIST = ["CPLD1", "CPLD2", "CPLD3", "CPLD4", "BIOS"] class Chassis(ChassisBase): @@ -43,8 +43,7 @@ class Chassis(ChassisBase): psu = Psu(index) self._psu_list.append(psu) ChassisBase.__init__(self) - self._component_device = Device("component") - self._component_name_list = self._component_device.get_name_list() + self._component_name_list = COMPONENT_NAME_LIST self._watchdog = Watchdog() def __read_config_db(self): diff --git a/device/celestica/x86_64-cel_seastone-r0/sonic_platform/device.py b/device/celestica/x86_64-cel_seastone-r0/sonic_platform/device.py deleted file mode 100644 index 2d717beed3..0000000000 --- a/device/celestica/x86_64-cel_seastone-r0/sonic_platform/device.py +++ /dev/null @@ -1,47 +0,0 @@ -#!/usr/bin/env python - -############################################################################# -# Celestica -# -# Device contains an implementation of SONiC Platform Base API and -# provides the device information -# -############################################################################# - -try: - from sonic_platform_base.device_base import DeviceBase -except ImportError as e: - raise ImportError(str(e) + "- required module not found") - - -class Device(DeviceBase): - """Platform-specific Device class""" - - COMPONENTS_NAME = ["CPLD1", "CPLD2", "CPLD3", "CPLD4", "BIOS"] - - def __init__(self, device_type, index=None): - self.device_type = device_type - self.index = index - DeviceBase.__init__(self) - - def get_name(self): - """ - Retrieves the name of the device - Returns: - string: The name of the device - """ - device_name = { - "component": self.COMPONENTS_NAME[self.index] - }.get(self.device_type, None) - return device_name - - def get_name_list(self): - """ - Retrieves list of the device name that available in this device type - Returns: - string: The list of device name - """ - name_list = { - "component": self.COMPONENTS_NAME - }.get(self.device_type, None) - return name_list diff --git a/device/celestica/x86_64-cel_seastone-r0/sonic_platform/fan.py b/device/celestica/x86_64-cel_seastone-r0/sonic_platform/fan.py index 227c1d2ade..99e86d0a6c 100644 --- a/device/celestica/x86_64-cel_seastone-r0/sonic_platform/fan.py +++ b/device/celestica/x86_64-cel_seastone-r0/sonic_platform/fan.py @@ -24,6 +24,7 @@ EMC2305_MAX_PWM = 255 EMC2305_FAN_PWM = "pwm{}" EMC2305_FAN_TARGET = "fan{}_target" EMC2305_FAN_INPUT = "pwm{}" +FAN_NAME_LIST = ["FAN-1", "FAN-2", "FAN-3", "FAN-4", "FAN-5"] class Fan(FanBase): @@ -226,3 +227,21 @@ class Fan(FanBase): return False return True + + def get_name(self): + """ + Retrieves the name of the device + Returns: + string: The name of the device + """ + return FAN_NAME_LIST[self.index] + + def get_presence(self): + """ + Retrieves the presence of the PSU + Returns: + bool: True if PSU is present, False if not + """ + raw = self.get_gpio_value(self.dx010_fan_gpio[self.index+1]['prs']) + + return int(raw, 10) == 0 diff --git a/device/celestica/x86_64-cel_seastone-r0/sonic_platform/psu.py b/device/celestica/x86_64-cel_seastone-r0/sonic_platform/psu.py index c70e452144..ab22314495 100644 --- a/device/celestica/x86_64-cel_seastone-r0/sonic_platform/psu.py +++ b/device/celestica/x86_64-cel_seastone-r0/sonic_platform/psu.py @@ -20,6 +20,8 @@ except ImportError as e: FAN_DX010_SPEED_PATH = "/sys/class/hwmon/hwmon{}/fan1_input" GREEN_LED_PATH = "/sys/devices/platform/leds_dx010/leds/dx010:green:p-{}/brightness" FAN_MAX_RPM = 11000 +SYS_GPIO_DIR = "/sys/class/gpio" +PSU_NAME_LIST = ["PSU-1", "PSU-2"] class Psu(PsuBase): @@ -29,6 +31,31 @@ class Psu(PsuBase): PsuBase.__init__(self) self.index = psu_index self.green_led_path = GREEN_LED_PATH.format(self.index+1) + self.dx010_psu_gpio = [ + {'base': self.get_gpio_base()}, + {'prs': 27, 'status': 22}, + {'prs': 28, 'status': 25} + ] + + def get_gpio_base(self): + for r in os.listdir(SYS_GPIO_DIR): + if "gpiochip" in r: + return int(r[8:], 10) + return 216 # Reserve + + def get_gpio_value(self, pinnum): + gpio_base = self.dx010_psu_gpio[0]['base'] + gpio_file = "{}/gpio{}/value".format(SYS_GPIO_DIR, + str(gpio_base+pinnum)) + + try: + with open(gpio_file, 'r') as fd: + retval = fd.read() + except IOError: + raise IOError("Unable to open " + gpio_file + "file !") + + retval = retval.rstrip('\r\n') + return retval def get_fan(self): """ @@ -76,3 +103,29 @@ class Psu(PsuBase): return False return True + + def get_name(self): + """ + Retrieves the name of the device + Returns: + string: The name of the device + """ + return PSU_NAME_LIST[self.index] + + def get_presence(self): + """ + Retrieves the presence of the PSU + Returns: + bool: True if PSU is present, False if not + """ + raw = self.get_gpio_value(self.dx010_psu_gpio[self.index+1]['prs']) + return int(raw, 10) == 0 + + def get_status(self): + """ + Retrieves the operational status of the device + Returns: + A boolean value, True if device is operating properly, False if not + """ + raw = self.get_gpio_value(self.dx010_psu_gpio[self.index+1]['status']) + return int(raw, 10) == 1 diff --git a/platform/broadcom/sonic-platform-modules-cel/haliburton/modules/smc.c b/platform/broadcom/sonic-platform-modules-cel/haliburton/modules/smc.c index 7b8d410cdd..7ec9753066 100644 --- a/platform/broadcom/sonic-platform-modules-cel/haliburton/modules/smc.c +++ b/platform/broadcom/sonic-platform-modules-cel/haliburton/modules/smc.c @@ -116,6 +116,16 @@ enum MASTER_LED { #define FAN_2 1 #define FAN_1 0 +/* FAN STATUS + * [7:5] FAN STATUS + * [4] FAN INTERRUPT + * [3:0] PSU ALERT + */ +#define FAN_STAT 0x0234 +#define FAN3_PRS 7 +#define FAN2_PRS 6 +#define FAN1_PRS 5 + /* SFP PORT INT TRIGGER MODE * [7:6] RESERVED * [5:4] RXLOS @@ -442,6 +452,19 @@ static ssize_t fan_dir_show(struct device *dev, struct device_attribute *devattr return sprintf(buf, "%s\n", data ? "B2F" : "F2B" ); } +static ssize_t fan_prs_show(struct device *dev, struct device_attribute *devattr, + char *buf) +{ + struct sensor_device_attribute *sa = to_sensor_dev_attr(devattr); + int index = sa->index; + unsigned char data = 0; + mutex_lock(&cpld_data->cpld_lock); + data = inb(FAN_STAT); + mutex_unlock(&cpld_data->cpld_lock); + data = ( data >> index ) & 1U; + return sprintf(buf, "%d\n", data); +} + static ssize_t sfp_txfault_show(struct device *dev, struct device_attribute *attr, char *buf) { unsigned char data; @@ -870,6 +893,9 @@ static SENSOR_DEVICE_ATTR(fan3_dir, S_IRUGO, fan_dir_show, NULL, FAN_3); static SENSOR_DEVICE_ATTR(fan1_led, S_IWUSR | S_IRUGO, fan_led_show, fan_led_store, FAN_1); static SENSOR_DEVICE_ATTR(fan2_led, S_IWUSR | S_IRUGO, fan_led_show, fan_led_store, FAN_2); static SENSOR_DEVICE_ATTR(fan3_led, S_IWUSR | S_IRUGO, fan_led_show, fan_led_store, FAN_3); +static SENSOR_DEVICE_ATTR(fan1_prs, S_IRUGO, fan_prs_show, NULL, FAN1_PRS); +static SENSOR_DEVICE_ATTR(fan2_prs, S_IRUGO, fan_prs_show, NULL, FAN2_PRS); +static SENSOR_DEVICE_ATTR(fan3_prs, S_IRUGO, fan_prs_show, NULL, FAN3_PRS); static struct attribute *cpld_attrs[] = { &dev_attr_version.attr, @@ -891,6 +917,9 @@ static struct attribute *cpld_attrs[] = { &sensor_dev_attr_fan1_led.dev_attr.attr, &sensor_dev_attr_fan2_led.dev_attr.attr, &sensor_dev_attr_fan3_led.dev_attr.attr, + &sensor_dev_attr_fan1_prs.dev_attr.attr, + &sensor_dev_attr_fan2_prs.dev_attr.attr, + &sensor_dev_attr_fan3_prs.dev_attr.attr, NULL, };