From 691b5c72075a97c089b70d39da23e234bda212fd Mon Sep 17 00:00:00 2001 From: wirut Date: Thu, 16 Aug 2018 14:24:29 +0700 Subject: [PATCH 01/18] Merge haliburton with dx010 and fixed issue --- .../debian/changelog | 11 +- .../debian/platform-modules-dx010.init | 53 +- .../debian/platform-modules-haliburton.init | 16 +- .../platform-modules-haliburton.install | 1 + .../dx010/modules/Makefile | 2 +- .../dx010/modules/dx010-fan-led.c | 209 +++++++ .../dx010/modules/lm75.c | 553 ++++++++++++++++++ .../dx010/modules/lm75.h | 49 ++ .../haliburton/tools/lpc_cpld_x64_64 | Bin 0 -> 13465 bytes 9 files changed, 836 insertions(+), 58 deletions(-) create mode 100644 platform/broadcom/sonic-platform-modules-cel/dx010/modules/dx010-fan-led.c create mode 100644 platform/broadcom/sonic-platform-modules-cel/dx010/modules/lm75.c create mode 100644 platform/broadcom/sonic-platform-modules-cel/dx010/modules/lm75.h create mode 100755 platform/broadcom/sonic-platform-modules-cel/haliburton/tools/lpc_cpld_x64_64 diff --git a/platform/broadcom/sonic-platform-modules-cel/debian/changelog b/platform/broadcom/sonic-platform-modules-cel/debian/changelog index 64f2decf2677..35029630491f 100644 --- a/platform/broadcom/sonic-platform-modules-cel/debian/changelog +++ b/platform/broadcom/sonic-platform-modules-cel/debian/changelog @@ -1,8 +1,15 @@ +sonic-cel-platform-modules (0.9) unstable; urgency=low + + * Add haliburton platform module. + + -- Wirut Getbamrung Fri, 21 Aug 2018 10:10:10 +0700 + sonic-cel-platform-modules (0.8) unstable; urgency=low - * Add haliburton platform + * Add dx010 platform fan led control. + * The platform gpio init moved to kernel space. - -- Supakit Fuangkaew Thu, 5 Apr 2018 09:09:09 +0700 + -- Pradchaya Phucharoen Mon, 1 Jul 2018 11:09:13 +0700 sonic-cel-platform-modules (0.7) unstable; urgency=low diff --git a/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-dx010.init b/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-dx010.init index f32785a798ca..0cef69ef5b78 100644 --- a/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-dx010.init +++ b/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-dx010.init @@ -11,24 +11,6 @@ # Short-Description: Setup DX010 board. ### END INIT INFO -function export_gpio { -label=$2 -gpio_num=$1 -gpio_base=`( cat /sys/class/gpio/gpiochip*/base | head -1 ) 2>/dev/null` -gpio_label=`( cat /sys/class/gpio/gpiochip*/label | head -1 ) 2>/dev/null` -if [[ "X$gpio_base" == "X" ]] || -( [[ "X$label" != "X" ]] && [[ "$label" != "$gpio_label" ]] ); then - echo "Platform driver error: No gpiochip found!" - exit 1; -fi -ionum=$((gpio_base+gpio_num)) -echo $ionum > /sys/class/gpio/export -if [ $? -ne 0 ]; then - echo "Platform driver error: Cannot export gpio$ionum!" - exit 1; -fi -} - case "$1" in start) echo -n "Setting up board... " @@ -38,7 +20,6 @@ start) modprobe i2c-mux-pca954x modprobe dx010_wdt modprobe leds-dx010 - modprobe lm75 found=0 for devnum in 0 1; do @@ -75,11 +56,11 @@ start) echo 24lc64t 0x50 > /sys/bus/i2c/devices/i2c-12/new_device # Attach temperature sensors - echo lm75b 0x48 > /sys/bus/i2c/devices/i2c-5/new_device - echo lm75b 0x49 > /sys/bus/i2c/devices/i2c-6/new_device - echo lm75b 0x4a > /sys/bus/i2c/devices/i2c-7/new_device - echo lm75b 0x48 > /sys/bus/i2c/devices/i2c-14/new_device - echo lm75b 0x4e > /sys/bus/i2c/devices/i2c-15/new_device + echo dx010_lm75b 0x48 > /sys/bus/i2c/devices/i2c-5/new_device + echo dx010_lm75b 0x49 > /sys/bus/i2c/devices/i2c-6/new_device + echo dx010_lm75b 0x4a > /sys/bus/i2c/devices/i2c-7/new_device + echo dx010_lm75b 0x48 > /sys/bus/i2c/devices/i2c-14/new_device + echo dx010_lm75b 0x4e > /sys/bus/i2c/devices/i2c-15/new_device # Attach fans echo emc2305 0x2e > /sys/bus/i2c/devices/i2c-13/new_device @@ -95,28 +76,8 @@ start) modprobe dx010_cpld sleep 2 - # Export platform gpio sysfs - export_gpio 10 # Fan 1 present - export_gpio 11 # Fan 2 present - export_gpio 12 # Fan 3 present - export_gpio 13 # Fan 4 present - export_gpio 14 # Fan 5 present - - export_gpio 22 # PSU L PWOK - export_gpio 25 # PSU R PWOK - export_gpio 27 # PSU L ABS - export_gpio 28 # PSU R ABS - - export_gpio 29 # Fan 1 LED: Red - export_gpio 30 # Fan 1 LED: Yellow - export_gpio 31 # Fan 2 LED: Red - export_gpio 32 # Fan 2 LED: Yellow - export_gpio 33 # Fan 3 LED: Red - export_gpio 34 # Fan 3 LED: Yellow - export_gpio 35 # Fan 4 LED: Red - export_gpio 36 # Fan 4 LED: Yellow - export_gpio 37 # Fan 5 LED: Red - export_gpio 38 # Fan 5 LED: Yellow + # Init platform gpios + modprobe dx010-fan-led # Turn off/down lpmod by defult (0 - Normal, 1 - Low Pow) echo 0x00000000 > /sys/devices/platform/dx010_cpld/qsfp_lpmode diff --git a/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-haliburton.init b/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-haliburton.init index 08770d1d64f6..722d788e531d 100644 --- a/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-haliburton.init +++ b/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-haliburton.init @@ -19,6 +19,8 @@ start) modprobe i2c-dev modprobe i2c-mux-pca954x + (cd /usr/local/etc && ./lpc_cpld_x64_64 blu w 0x222 0x1f) + found=0 for devnum in 0 1; do devname=`cat /sys/bus/i2c/devices/i2c-${devnum}/name` @@ -56,15 +58,11 @@ start) # Attach fans echo emc2305 0x4d > /sys/bus/i2c/devices/i2c-23/new_device - # Attach PSUs - echo dps200 0x5a > /sys/bus/i2c/devices/i2c-12/new_device - echo dps200 0x5b > /sys/bus/i2c/devices/i2c-13/new_device - - # Attach 4 SFP+ Uplink - echo optoe1 0x50 > /sys/bus/i2c/devices/i2c-14/new_device - echo optoe1 0x50 > /sys/bus/i2c/devices/i2c-15/new_device - echo optoe1 0x50 > /sys/bus/i2c/devices/i2c-16/new_device - echo optoe1 0x50 > /sys/bus/i2c/devices/i2c-17/new_device + # Attach 4 SFP+ Uplink + echo optoe2 0x50 > /sys/bus/i2c/devices/i2c-14/new_device + echo optoe2 0x50 > /sys/bus/i2c/devices/i2c-15/new_devic + echo optoe2 0x50 > /sys/bus/i2c/devices/i2c-16/new_device + echo optoe2 0x50 > /sys/bus/i2c/devices/i2c-17/new_device echo "done." ;; diff --git a/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-haliburton.install b/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-haliburton.install index 464b77855f95..667300ac037b 100644 --- a/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-haliburton.install +++ b/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-haliburton.install @@ -1 +1,2 @@ haliburton/cfg/haliburton-modules.conf etc/modules-load.d +haliburton/tools/lpc_cpld_x64_64 usr/local/etc diff --git a/platform/broadcom/sonic-platform-modules-cel/dx010/modules/Makefile b/platform/broadcom/sonic-platform-modules-cel/dx010/modules/Makefile index 9b0f10604811..b6cd0f60bb6e 100644 --- a/platform/broadcom/sonic-platform-modules-cel/dx010/modules/Makefile +++ b/platform/broadcom/sonic-platform-modules-cel/dx010/modules/Makefile @@ -1 +1 @@ -obj-m := dx010_cpld.o mc24lc64t.o emc2305.o dx010_wdt.o leds-dx010.o \ No newline at end of file +obj-m := dx010_cpld.o mc24lc64t.o emc2305.o dx010_wdt.o leds-dx010.o lm75.o dx010-fan-led.o \ No newline at end of file diff --git a/platform/broadcom/sonic-platform-modules-cel/dx010/modules/dx010-fan-led.c b/platform/broadcom/sonic-platform-modules-cel/dx010/modules/dx010-fan-led.c new file mode 100644 index 000000000000..c02bc37aedd7 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-cel/dx010/modules/dx010-fan-led.c @@ -0,0 +1,209 @@ +/* + * dx010-fan-led.c - Kernel module for Seastone DX010 fan LEDs + * + * Copyright (C) 2018 Celestica Corp. + * + * 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 + +#define MODULE_NAME "dx010-fan-led" + +#define NUM_FAN 5 +#define NUM_PSU 2 +#define UPDATE_MS 100 +#define CHECK_MS 1000 +#define CHECK_COUNTER CHECK_MS/UPDATE_MS + + +struct fan_gpio { + unsigned char presence_pin; + unsigned char red_led_pin; + unsigned char yel_led_pin; + int prs; +}; + +struct psu_gpio { + unsigned char absence_pin; + unsigned char powerok_pin; +}; + +static int count; +static struct workqueue_struct *dx010_fan_led_workqueue; +static struct delayed_work fan_update; +static struct gpio_chip *gc; +static struct fan_gpio fan_gpios[NUM_FAN] = { + {.presence_pin = 10, + .red_led_pin = 29, + .yel_led_pin = 30, + .prs = 1 + }, + {.presence_pin = 11, + .red_led_pin = 31, + .yel_led_pin = 32, + .prs = 1 + }, + {.presence_pin = 12, + .red_led_pin = 33, + .yel_led_pin = 34, + .prs = 1 + }, + {.presence_pin = 13, + .red_led_pin = 35, + .yel_led_pin = 36, + .prs = 1 + }, + {.presence_pin = 14, + .red_led_pin = 37, + .yel_led_pin = 38, + .prs = 1 + } +}; + +static struct psu_gpio psu_gpios[NUM_PSU] = { + {.absence_pin = 27, + .powerok_pin = 22 + }, + {.absence_pin = 28, + .powerok_pin = 25, + } +}; + +static int chip_match_name(struct gpio_chip *chip, void *data){ + return !strcmp(chip->label, data); +} + +static void init_fan_gpio(void){ + int index; + for( index=0; index < NUM_FAN; index++){ + gpio_request(gc->base+fan_gpios[index].presence_pin, NULL); + gpio_request(gc->base+fan_gpios[index].red_led_pin, NULL); + gpio_request(gc->base+fan_gpios[index].yel_led_pin, NULL); + gpio_direction_input(gc->base+fan_gpios[index].presence_pin); + gpio_direction_output(gc->base+fan_gpios[index].red_led_pin, 1); + gpio_direction_output(gc->base+fan_gpios[index].yel_led_pin, 0); + } +} + +static void init_psu_gpio(void){ + int index; + for( index=0; index < NUM_PSU; index++){ + gpio_request(gc->base+psu_gpios[index].absence_pin, NULL); + gpio_request(gc->base+psu_gpios[index].powerok_pin, NULL); + gpio_direction_input(gc->base+psu_gpios[index].absence_pin); + gpio_direction_input(gc->base+psu_gpios[index].powerok_pin); + gpio_export(gc->base+psu_gpios[index].absence_pin,0); + gpio_export(gc->base+psu_gpios[index].powerok_pin,0); + } +} + +static void update_led(void){ + int index; + int presence; + int delay_ms; + struct gpio_chip *find; + + /* Check for gpio chip exist every CHECK_MS */ + if(count <= 0){ + find = gpiochip_find("pca9505", chip_match_name); + if(find){ + /* Skip check routine, Update the leds */ + if(gc != find){ + gc = find; + init_fan_gpio(); + init_psu_gpio(); + } + count = CHECK_COUNTER; + delay_ms = UPDATE_MS; + }else{ + /* Put the check routine to the queue */ + delay_ms = CHECK_MS; + } + }else{ + for (index=0; index < NUM_FAN; index++){ + presence = !gpio_get_value_cansleep(gc->base+fan_gpios[index].presence_pin); + if( presence != fan_gpios[index].prs ){ + if( presence ){ + gpio_set_value_cansleep(gc->base+fan_gpios[index].red_led_pin, 1); + gpio_set_value_cansleep(gc->base+fan_gpios[index].yel_led_pin, 0); + }else{ + gpio_set_value_cansleep(gc->base+fan_gpios[index].red_led_pin, 0); + gpio_set_value_cansleep(gc->base+fan_gpios[index].yel_led_pin, 1); + } + } + fan_gpios[index].prs = presence; + } + count--; + } + queue_delayed_work(dx010_fan_led_workqueue, &fan_update, + msecs_to_jiffies(delay_ms)); +} + +static void deinit_fan_gpio(void){ + int index; + for( index=0; index < NUM_PSU; index++){ + gpio_free(gc->base+fan_gpios[index].presence_pin); + gpio_free(gc->base+fan_gpios[index].red_led_pin); + gpio_free(gc->base+fan_gpios[index].yel_led_pin); + } +} + +static void deinit_psu_gpio(void){ + int index; + for( index=0; index < NUM_PSU; index++){ + gpio_unexport(gc->base+psu_gpios[index].absence_pin); + gpio_unexport(gc->base+psu_gpios[index].powerok_pin); + gpio_free(gc->base+psu_gpios[index].absence_pin); + gpio_free(gc->base+psu_gpios[index].powerok_pin); + } +} + +static int __init dx010_fan_led_init(void){ + count = 0; + gc = NULL; + dx010_fan_led_workqueue = create_singlethread_workqueue(MODULE_NAME); + if (IS_ERR(dx010_fan_led_workqueue)) { + printk(KERN_INFO "failed to inittialize workqueue\n"); + return PTR_ERR(dx010_fan_led_workqueue); + } + + INIT_DELAYED_WORK(&fan_update, update_led); + queue_delayed_work(dx010_fan_led_workqueue, &fan_update, + msecs_to_jiffies(UPDATE_MS)); + return 0; +} + +static void __exit dx010_fan_led_exit(void){ + cancel_delayed_work_sync(&fan_update); + destroy_workqueue(dx010_fan_led_workqueue); + deinit_fan_gpio(); + deinit_psu_gpio(); + dx010_fan_led_workqueue = NULL; + gc = NULL; +} + +module_init(dx010_fan_led_init); +module_exit(dx010_fan_led_exit); + + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Celestica Inc."); +MODULE_DESCRIPTION("DX010 fan led control"); \ No newline at end of file diff --git a/platform/broadcom/sonic-platform-modules-cel/dx010/modules/lm75.c b/platform/broadcom/sonic-platform-modules-cel/dx010/modules/lm75.c new file mode 100644 index 000000000000..a83745212bbf --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-cel/dx010/modules/lm75.c @@ -0,0 +1,553 @@ +/* + * lm75.c - Part of lm_sensors, Linux kernel modules for hardware + * monitoring + * Copyright (c) 1998, 1999 Frodo Looijaard + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "lm75.h" + + +/* + * This driver handles the LM75 and compatible digital temperature sensors. + */ + +enum lm75_type { /* keep sorted in alphabetical order */ + adt75, + ds1775, + ds75, + ds7505, + g751, + lm75, + lm75a, + lm75b, + max6625, + max6626, + mcp980x, + stds75, + tcn75, + tmp100, + tmp101, + tmp105, + tmp112, + tmp175, + tmp275, + tmp75, +}; + +/* Addresses scanned */ +static const unsigned short normal_i2c[] = { 0x48, 0x49, 0x4a, 0x4b, 0x4c, + 0x4d, 0x4e, 0x4f, I2C_CLIENT_END }; + + +/* The LM75 registers */ +#define LM75_REG_CONF 0x01 +static const u8 LM75_REG_TEMP[3] = { + 0x00, /* input */ + 0x03, /* max */ + 0x02, /* hyst */ +}; + +/* Each client has this additional data */ +struct lm75_data { + struct i2c_client *client; + struct device *hwmon_dev; + struct thermal_zone_device *tz; + struct mutex update_lock; + u8 orig_conf; + u8 resolution; /* In bits, between 9 and 12 */ + u8 resolution_limits; + char valid; /* !=0 if registers are valid */ + unsigned long last_updated; /* In jiffies */ + unsigned long sample_time; /* In jiffies */ + s16 temp[3]; /* Register values, + 0 = input + 1 = max + 2 = hyst */ +}; + +static int lm75_read_value(struct i2c_client *client, u8 reg); +static int lm75_write_value(struct i2c_client *client, u8 reg, u16 value); +static struct lm75_data *lm75_update_device(struct device *dev); + + +/*-----------------------------------------------------------------------*/ + +static inline long lm75_reg_to_mc(s16 temp, u8 resolution) +{ + return ((temp >> (16 - resolution)) * 1000) >> (resolution - 8); +} + +/* sysfs attributes for hwmon */ + +static int lm75_read_temp(void *dev, long *temp) +{ + struct lm75_data *data = lm75_update_device(dev); + + if (IS_ERR(data)) + return PTR_ERR(data); + + *temp = lm75_reg_to_mc(data->temp[0], data->resolution); + + return 0; +} + +static ssize_t show_temp(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct lm75_data *data = lm75_update_device(dev); + + if (IS_ERR(data)) + return PTR_ERR(data); + + return sprintf(buf, "%ld\n", lm75_reg_to_mc(data->temp[attr->index], + data->resolution)); +} + +static ssize_t set_temp(struct device *dev, struct device_attribute *da, + const char *buf, size_t count) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct lm75_data *data = dev_get_drvdata(dev); + struct i2c_client *client = data->client; + int nr = attr->index; + long temp; + int error; + u8 resolution; + + error = kstrtol(buf, 10, &temp); + if (error) + return error; + + /* + * Resolution of limit registers is assumed to be the same as the + * temperature input register resolution unless given explicitly. + */ + if (attr->index && data->resolution_limits) + resolution = data->resolution_limits; + else + resolution = data->resolution; + + mutex_lock(&data->update_lock); + temp = clamp_val(temp, LM75_TEMP_MIN, LM75_TEMP_MAX); + data->temp[nr] = DIV_ROUND_CLOSEST(temp << (resolution - 8), + 1000) << (16 - resolution); + lm75_write_value(client, LM75_REG_TEMP[nr], data->temp[nr]); + mutex_unlock(&data->update_lock); + return count; +} + +static SENSOR_DEVICE_ATTR(temp1_max, S_IWUSR | S_IRUGO, + show_temp, set_temp, 1); +static SENSOR_DEVICE_ATTR(temp1_max_hyst, S_IWUSR | S_IRUGO, + show_temp, set_temp, 2); +static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, show_temp, NULL, 0); + +static struct attribute *lm75_attrs[] = { + &sensor_dev_attr_temp1_input.dev_attr.attr, + &sensor_dev_attr_temp1_max.dev_attr.attr, + &sensor_dev_attr_temp1_max_hyst.dev_attr.attr, + + NULL +}; +ATTRIBUTE_GROUPS(lm75); + +/*-----------------------------------------------------------------------*/ + +/* device probe and removal */ + +static int +lm75_probe(struct i2c_client *client, const struct i2c_device_id *id) +{ + struct device *dev = &client->dev; + struct lm75_data *data; + int status; + u8 set_mask, clr_mask; + int new; + enum lm75_type kind = id->driver_data; + + if (!i2c_check_functionality(client->adapter, + I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA)) + return -EIO; + + data = devm_kzalloc(dev, sizeof(struct lm75_data), GFP_KERNEL); + if (!data) + return -ENOMEM; + + data->client = client; + i2c_set_clientdata(client, data); + mutex_init(&data->update_lock); + + /* Set to LM75 resolution (9 bits, 1/2 degree C) and range. + * Then tweak to be more precise when appropriate. + */ + set_mask = 0; + clr_mask = LM75_SHUTDOWN; /* continuous conversions */ + + switch (kind) { + case adt75: + clr_mask |= 1 << 5; /* not one-shot mode */ + data->resolution = 12; + data->sample_time = HZ / 8; + break; + case ds1775: + case ds75: + case stds75: + clr_mask |= 3 << 5; + set_mask |= 2 << 5; /* 11-bit mode */ + data->resolution = 11; + data->sample_time = HZ; + break; + case ds7505: + set_mask |= 3 << 5; /* 12-bit mode */ + data->resolution = 12; + data->sample_time = HZ / 4; + break; + case g751: + case lm75: + case lm75a: + data->resolution = 9; + data->sample_time = HZ / 2; + break; + case lm75b: + data->resolution = 11; + data->sample_time = HZ / 4; + break; + case max6625: + data->resolution = 9; + data->sample_time = HZ / 4; + break; + case max6626: + data->resolution = 12; + data->resolution_limits = 9; + data->sample_time = HZ / 4; + break; + case tcn75: + data->resolution = 9; + data->sample_time = HZ / 8; + break; + case mcp980x: + data->resolution_limits = 9; + /* fall through */ + case tmp100: + case tmp101: + set_mask |= 3 << 5; /* 12-bit mode */ + data->resolution = 12; + data->sample_time = HZ; + clr_mask |= 1 << 7; /* not one-shot mode */ + break; + case tmp112: + set_mask |= 3 << 5; /* 12-bit mode */ + clr_mask |= 1 << 7; /* not one-shot mode */ + data->resolution = 12; + data->sample_time = HZ / 4; + break; + case tmp105: + case tmp175: + case tmp275: + case tmp75: + set_mask |= 3 << 5; /* 12-bit mode */ + clr_mask |= 1 << 7; /* not one-shot mode */ + data->resolution = 12; + data->sample_time = HZ / 2; + break; + } + + /* configure as specified */ + status = lm75_read_value(client, LM75_REG_CONF); + if (status < 0) { + dev_dbg(dev, "Can't read config? %d\n", status); + return status; + } + data->orig_conf = status; + new = status & ~clr_mask; + new |= set_mask; + if (status != new) + lm75_write_value(client, LM75_REG_CONF, new); + dev_dbg(dev, "Config %02x\n", new); + + data->hwmon_dev = hwmon_device_register_with_groups(dev, client->name, + data, lm75_groups); + if (IS_ERR(data->hwmon_dev)) + return PTR_ERR(data->hwmon_dev); + + data->tz = thermal_zone_of_sensor_register(data->hwmon_dev, + 0, + data->hwmon_dev, + lm75_read_temp, NULL); + if (IS_ERR(data->tz)) + data->tz = NULL; + + dev_info(dev, "%s: sensor '%s'\n", + dev_name(data->hwmon_dev), client->name); + + return 0; +} + +static int lm75_remove(struct i2c_client *client) +{ + struct lm75_data *data = i2c_get_clientdata(client); + + thermal_zone_of_sensor_unregister(data->hwmon_dev, data->tz); + hwmon_device_unregister(data->hwmon_dev); + lm75_write_value(client, LM75_REG_CONF, data->orig_conf); + return 0; +} + +static const struct i2c_device_id lm75_ids[] = { + { "adt75", adt75, }, + { "ds1775", ds1775, }, + { "ds75", ds75, }, + { "ds7505", ds7505, }, + { "g751", g751, }, + { "lm75", lm75, }, + { "lm75a", lm75a, }, + { "dx010_lm75b", lm75b, }, + { "max6625", max6625, }, + { "max6626", max6626, }, + { "mcp980x", mcp980x, }, + { "stds75", stds75, }, + { "tcn75", tcn75, }, + { "tmp100", tmp100, }, + { "tmp101", tmp101, }, + { "tmp105", tmp105, }, + { "tmp112", tmp112, }, + { "tmp175", tmp175, }, + { "tmp275", tmp275, }, + { "tmp75", tmp75, }, + { /* LIST END */ } +}; +MODULE_DEVICE_TABLE(i2c, lm75_ids); + +#define LM75A_ID 0xA1 + +/* Return 0 if detection is successful, -ENODEV otherwise */ +static int lm75_detect(struct i2c_client *new_client, + struct i2c_board_info *info) +{ + struct i2c_adapter *adapter = new_client->adapter; + int i; + int conf, hyst, os; + bool is_lm75a = 0; + + if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA | + I2C_FUNC_SMBUS_WORD_DATA)) + return -ENODEV; + + /* + * Now, we do the remaining detection. There is no identification- + * dedicated register so we have to rely on several tricks: + * unused bits, registers cycling over 8-address boundaries, + * addresses 0x04-0x07 returning the last read value. + * The cycling+unused addresses combination is not tested, + * since it would significantly slow the detection down and would + * hardly add any value. + * + * The National Semiconductor LM75A is different than earlier + * LM75s. It has an ID byte of 0xaX (where X is the chip + * revision, with 1 being the only revision in existence) in + * register 7, and unused registers return 0xff rather than the + * last read value. + * + * Note that this function only detects the original National + * Semiconductor LM75 and the LM75A. Clones from other vendors + * aren't detected, on purpose, because they are typically never + * found on PC hardware. They are found on embedded designs where + * they can be instantiated explicitly so detection is not needed. + * The absence of identification registers on all these clones + * would make their exhaustive detection very difficult and weak, + * and odds are that the driver would bind to unsupported devices. + */ + + /* Unused bits */ + conf = i2c_smbus_read_byte_data(new_client, 1); + if (conf & 0xe0) + return -ENODEV; + + /* First check for LM75A */ + if (i2c_smbus_read_byte_data(new_client, 7) == LM75A_ID) { + /* LM75A returns 0xff on unused registers so + just to be sure we check for that too. */ + if (i2c_smbus_read_byte_data(new_client, 4) != 0xff + || i2c_smbus_read_byte_data(new_client, 5) != 0xff + || i2c_smbus_read_byte_data(new_client, 6) != 0xff) + return -ENODEV; + is_lm75a = 1; + hyst = i2c_smbus_read_byte_data(new_client, 2); + os = i2c_smbus_read_byte_data(new_client, 3); + } else { /* Traditional style LM75 detection */ + /* Unused addresses */ + hyst = i2c_smbus_read_byte_data(new_client, 2); + if (i2c_smbus_read_byte_data(new_client, 4) != hyst + || i2c_smbus_read_byte_data(new_client, 5) != hyst + || i2c_smbus_read_byte_data(new_client, 6) != hyst + || i2c_smbus_read_byte_data(new_client, 7) != hyst) + return -ENODEV; + os = i2c_smbus_read_byte_data(new_client, 3); + if (i2c_smbus_read_byte_data(new_client, 4) != os + || i2c_smbus_read_byte_data(new_client, 5) != os + || i2c_smbus_read_byte_data(new_client, 6) != os + || i2c_smbus_read_byte_data(new_client, 7) != os) + return -ENODEV; + } + + /* Addresses cycling */ + for (i = 8; i <= 248; i += 40) { + if (i2c_smbus_read_byte_data(new_client, i + 1) != conf + || i2c_smbus_read_byte_data(new_client, i + 2) != hyst + || i2c_smbus_read_byte_data(new_client, i + 3) != os) + return -ENODEV; + if (is_lm75a && i2c_smbus_read_byte_data(new_client, i + 7) + != LM75A_ID) + return -ENODEV; + } + + strlcpy(info->type, is_lm75a ? "lm75a" : "lm75", I2C_NAME_SIZE); + + return 0; +} + +#ifdef CONFIG_PM +static int lm75_suspend(struct device *dev) +{ + int status; + struct i2c_client *client = to_i2c_client(dev); + status = lm75_read_value(client, LM75_REG_CONF); + if (status < 0) { + dev_dbg(&client->dev, "Can't read config? %d\n", status); + return status; + } + status = status | LM75_SHUTDOWN; + lm75_write_value(client, LM75_REG_CONF, status); + return 0; +} + +static int lm75_resume(struct device *dev) +{ + int status; + struct i2c_client *client = to_i2c_client(dev); + status = lm75_read_value(client, LM75_REG_CONF); + if (status < 0) { + dev_dbg(&client->dev, "Can't read config? %d\n", status); + return status; + } + status = status & ~LM75_SHUTDOWN; + lm75_write_value(client, LM75_REG_CONF, status); + return 0; +} + +static const struct dev_pm_ops lm75_dev_pm_ops = { + .suspend = lm75_suspend, + .resume = lm75_resume, +}; +#define LM75_DEV_PM_OPS (&lm75_dev_pm_ops) +#else +#define LM75_DEV_PM_OPS NULL +#endif /* CONFIG_PM */ + +static struct i2c_driver lm75_driver = { + .class = I2C_CLASS_HWMON, + .driver = { + .name = "dx010_lm75", + .pm = LM75_DEV_PM_OPS, + }, + .probe = lm75_probe, + .remove = lm75_remove, + .id_table = lm75_ids, +/* + .detect = lm75_detect, + .address_list = normal_i2c, +*/ +}; + +/*-----------------------------------------------------------------------*/ + +/* register access */ + +/* + * All registers are word-sized, except for the configuration register. + * LM75 uses a high-byte first convention, which is exactly opposite to + * the SMBus standard. + */ +static int lm75_read_value(struct i2c_client *client, u8 reg) +{ + if (reg == LM75_REG_CONF) + return i2c_smbus_read_byte_data(client, reg); + else + return i2c_smbus_read_word_swapped(client, reg); +} + +static int lm75_write_value(struct i2c_client *client, u8 reg, u16 value) +{ + if (reg == LM75_REG_CONF) + return i2c_smbus_write_byte_data(client, reg, value); + else + return i2c_smbus_write_word_swapped(client, reg, value); +} + +static struct lm75_data *lm75_update_device(struct device *dev) +{ + struct lm75_data *data = dev_get_drvdata(dev); + struct i2c_client *client = data->client; + struct lm75_data *ret = data; + + mutex_lock(&data->update_lock); + + if (time_after(jiffies, data->last_updated + data->sample_time) + || !data->valid) { + int i; + dev_dbg(&client->dev, "Starting lm75 update\n"); + + for (i = 0; i < ARRAY_SIZE(data->temp); i++) { + int status; + + status = lm75_read_value(client, LM75_REG_TEMP[i]); + if (unlikely(status < 0)) { + dev_dbg(dev, + "LM75: Failed to read value: reg %d, error %d\n", + LM75_REG_TEMP[i], status); + ret = ERR_PTR(status); + data->valid = 0; + goto abort; + } + data->temp[i] = status; + } + data->last_updated = jiffies; + data->valid = 1; + } + +abort: + mutex_unlock(&data->update_lock); + return ret; +} + +module_i2c_driver(lm75_driver); + +MODULE_AUTHOR("Frodo Looijaard "); +MODULE_DESCRIPTION("LM75 driver"); +MODULE_LICENSE("GPL"); diff --git a/platform/broadcom/sonic-platform-modules-cel/dx010/modules/lm75.h b/platform/broadcom/sonic-platform-modules-cel/dx010/modules/lm75.h new file mode 100644 index 000000000000..5cde94e56f17 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-cel/dx010/modules/lm75.h @@ -0,0 +1,49 @@ +/* + lm75.h - Part of lm_sensors, Linux kernel modules for hardware + monitoring + Copyright (c) 2003 Mark M. Hoffman + + 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., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +/* + This file contains common code for encoding/decoding LM75 type + temperature readings, which are emulated by many of the chips + we support. As the user is unlikely to load more than one driver + which contains this code, we don't worry about the wasted space. +*/ + +#include + +/* straight from the datasheet */ +#define LM75_TEMP_MIN (-55000) +#define LM75_TEMP_MAX 125000 +#define LM75_SHUTDOWN 0x01 + +/* TEMP: 0.001C/bit (-55C to +125C) + REG: (0.5C/bit, two's complement) << 7 */ +static inline u16 LM75_TEMP_TO_REG(long temp) +{ + int ntemp = clamp_val(temp, LM75_TEMP_MIN, LM75_TEMP_MAX); + ntemp += (ntemp < 0 ? -250 : 250); + return (u16)((ntemp / 500) << 7); +} + +static inline int LM75_TEMP_FROM_REG(u16 reg) +{ + /* use integer division instead of equivalent right shift to + guarantee arithmetic shift and preserve the sign */ + return ((s16)reg / 128) * 500; +} diff --git a/platform/broadcom/sonic-platform-modules-cel/haliburton/tools/lpc_cpld_x64_64 b/platform/broadcom/sonic-platform-modules-cel/haliburton/tools/lpc_cpld_x64_64 new file mode 100755 index 0000000000000000000000000000000000000000..6d356039be9c4dc9cf2e7d27f3431f286db1995b GIT binary patch literal 13465 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 Tv9{$Hlzztv+xQy Date: Thu, 16 Aug 2018 14:28:35 +0700 Subject: [PATCH 02/18] Fixed fancontrol issue --- .../celestica/x86_64-cel_e1031-r0/fancontrol | 10 +++--- .../x86_64-cel_e1031-r0/sensors.conf | 36 ++++++++++++++----- 2 files changed, 32 insertions(+), 14 deletions(-) diff --git a/device/celestica/x86_64-cel_e1031-r0/fancontrol b/device/celestica/x86_64-cel_e1031-r0/fancontrol index a94c63055fd7..e7e71257a4d2 100644 --- a/device/celestica/x86_64-cel_e1031-r0/fancontrol +++ b/device/celestica/x86_64-cel_e1031-r0/fancontrol @@ -1,12 +1,12 @@ # Configuration file generated by pwmconfig, changes will be lost INTERVAL=2 -DEVPATH=hwmon3=devices/pci0000:00/0000:00:13.0/i2c-0/i2c-8/i2c-23/23-004d/ hwmon2=devices/pci0000:00/0000:00:13.0/i2c-0/i2c-8/i2c-11/11-001a/hwmon/hwmon2 +DEVPATH=hwmon3=devices/pci0000:00/0000:00:13.0/i2c-1/i2c-8/i2c-23/23-004d hwmon2=devices/pci0000:00/0000:00:13.0/i2c-1/i2c-8/i2c-11/11-001a DEVNAME=hwmon3=emc2305 hwmon2=max6697 -FCTEMPS=hwmon3/pwm1=hwmon2/temp2_input hwmon3/pwm2=hwmon2/temp2_input hwmon3/pwm4=hwmon2/temp2_input +FCTEMPS=hwmon3/device/pwm1=hwmon2/temp2_input hwmon3/device/pwm2=hwmon2/temp2_input hwmon3/device/pwm4=hwmon2/temp2_input FCFANS=hwmon3/device/pwm1=hwmon3/device/fan1_input hwmon3/device/pwm2=hwmon3/device/fan2_input hwmon3/device/pwm4=hwmon3/device/fan4_input MINTEMP=hwmon3/device/pwm1=29 hwmon3/device/pwm2=29 hwmon3/device/pwm4=29 MAXTEMP=hwmon3/device/pwm1=44 hwmon3/device/pwm2=44 hwmon3/device/pwm4=44 -MINSTART=hwmon3/device/pwm1=102 hwmon3/device/pwm2=102 hwmon3/device/pwm4=102 -MINSTOP=hwmon3/device/pwm1=102 hwmon3/device/pwm2=102 hwmon3/device/pwm4=102 -MINPWM=hwmon3/device/pwm1=102 hwmon3/device/pwm2=102 hwmon3/device/pwm4=102 +MINSTART=hwmon3/device/pwm1=102 hwmon3/device/pwm2=102 hwmon3/device/pwm4=102 +MINSTOP=hwmon3/device/pwm1=102 hwmon3/device/pwm2=102 hwmon3/device/pwm4=102 +MINPWM=hwmon3/device/pwm1=102 hwmon3/device/pwm2=102 hwmon3/device/pwm4=102 MAXPWM=hwmon3/device/pwm1=255 hwmon3/device/pwm2=255 hwmon3/device/pwm4=255 diff --git a/device/celestica/x86_64-cel_e1031-r0/sensors.conf b/device/celestica/x86_64-cel_e1031-r0/sensors.conf index 1874548cff64..4f7553e96b73 100644 --- a/device/celestica/x86_64-cel_e1031-r0/sensors.conf +++ b/device/celestica/x86_64-cel_e1031-r0/sensors.conf @@ -1,12 +1,30 @@ -# libsensors configuration file for Celestica DX010. +# libsensors configuration file for Celestica E1031. # The i2c bus portion is omit because adapter name # changes every time when system boot up. -chip "max6697-i2c-*-1a" - label temp1 "temp sensor 1" - label temp2 "temp sensor 2" - label temp3 "temp sensor 3" - label temp4 "temp sensor 4" - label temp5 "temp sensor 5" - ignore temp6 - ignore temp7 +bus "i2c-3" "i2c-1-mux (chan_id 1)" +bus "i2c-11" "i2c-8-mux (chan_id 1)" + +chip "max6697-i2c-3-1a" + label temp1 "temp sensor 1" + label temp2 "temp sensor 2" + label temp3 "temp sensor 3" + ignore temp4 + ignore temp5 + ignore temp6 + ignore temp7 + +chip "max6697-i2c-11-1a" + label temp1 "temp sensor 1" + label temp2 "temp sensor 2" + label temp3 "temp sensor 3" + label temp4 "temp sensor 4" + label temp5 "temp sensor 5" + ignore temp6 + ignore temp7 + + +chip "emc2305-i2c-*-4d" + ignore fan3 + ignore fan5 + From 7b8689a866a99151c602dfac2197dd9082ed7e73 Mon Sep 17 00:00:00 2001 From: wirut Date: Thu, 16 Aug 2018 16:19:40 +0700 Subject: [PATCH 03/18] Add sensor's label --- .../x86_64-cel_e1031-r0/sensors.conf | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/device/celestica/x86_64-cel_e1031-r0/sensors.conf b/device/celestica/x86_64-cel_e1031-r0/sensors.conf index 4f7553e96b73..5f65764e4986 100644 --- a/device/celestica/x86_64-cel_e1031-r0/sensors.conf +++ b/device/celestica/x86_64-cel_e1031-r0/sensors.conf @@ -6,20 +6,20 @@ bus "i2c-3" "i2c-1-mux (chan_id 1)" bus "i2c-11" "i2c-8-mux (chan_id 1)" chip "max6697-i2c-3-1a" - label temp1 "temp sensor 1" - label temp2 "temp sensor 2" - label temp3 "temp sensor 3" + label temp1 "CPU board temperature sensor : 1" + label temp2 "CPU board temperature sensor : 2" + label temp3 "CPU board temperature sensor : 3" ignore temp4 ignore temp5 ignore temp6 ignore temp7 chip "max6697-i2c-11-1a" - label temp1 "temp sensor 1" - label temp2 "temp sensor 2" - label temp3 "temp sensor 3" - label temp4 "temp sensor 4" - label temp5 "temp sensor 5" + label temp1 "Main board temperature sensor : 1" + label temp2 "Main board temperature sensor : 2" + label temp3 "Main board temperature sensor : 3" + label temp4 "Main board temperature sensor : 4" + label temp5 "Main board temperature sensor : 5" ignore temp6 ignore temp7 @@ -27,4 +27,7 @@ chip "max6697-i2c-11-1a" chip "emc2305-i2c-*-4d" ignore fan3 ignore fan5 + label fan4 "Fan 1 :" + label fan2 "Fan 2 :" + label fan1 "Fan 3 :" From 0d92e698897f00392a2e037fd8bd11148af2b1eb Mon Sep 17 00:00:00 2001 From: wirut Date: Thu, 16 Aug 2018 16:32:06 +0700 Subject: [PATCH 04/18] Add new submodule version --- platform/broadcom/platform-modules-cel.mk | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/platform/broadcom/platform-modules-cel.mk b/platform/broadcom/platform-modules-cel.mk index 9226d9246308..1224faaa6750 100644 --- a/platform/broadcom/platform-modules-cel.mk +++ b/platform/broadcom/platform-modules-cel.mk @@ -1,7 +1,7 @@ # Celestica DX010 and Haliburton Platform modules -CEL_DX010_PLATFORM_MODULE_VERSION = 0.8 -CEL_HALIBURTON_PLATFORM_MODULE_VERSION = 0.8 +CEL_DX010_PLATFORM_MODULE_VERSION = 0.9 +CEL_HALIBURTON_PLATFORM_MODULE_VERSION = 0.9 export CEL_DX010_PLATFORM_MODULE_VERSION export CEL_HALIBURTON_PLATFORM_MODULE_VERSION From d9d480cc0ac5d9e4c6ae3ee2b95f6b04f6a5c571 Mon Sep 17 00:00:00 2001 From: wirut Date: Thu, 16 Aug 2018 16:34:29 +0700 Subject: [PATCH 05/18] Update changelog version --- platform/broadcom/sonic-platform-modules-cel/debian/changelog | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/broadcom/sonic-platform-modules-cel/debian/changelog b/platform/broadcom/sonic-platform-modules-cel/debian/changelog index 35029630491f..843b028e4301 100644 --- a/platform/broadcom/sonic-platform-modules-cel/debian/changelog +++ b/platform/broadcom/sonic-platform-modules-cel/debian/changelog @@ -2,7 +2,7 @@ sonic-cel-platform-modules (0.9) unstable; urgency=low * Add haliburton platform module. - -- Wirut Getbamrung Fri, 21 Aug 2018 10:10:10 +0700 + -- Wirut Getbamrung Fri, 17 Aug 2018 10:10:10 +0700 sonic-cel-platform-modules (0.8) unstable; urgency=low From c665b8e61b4b7d86633bdf0788c9b355f67a267a Mon Sep 17 00:00:00 2001 From: wirut Date: Thu, 16 Aug 2018 16:37:20 +0700 Subject: [PATCH 06/18] Add command to set permission for lpc tool --- .../debian/platform-modules-haliburton.postinst | 1 + 1 file changed, 1 insertion(+) create mode 100644 platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-haliburton.postinst diff --git a/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-haliburton.postinst b/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-haliburton.postinst new file mode 100644 index 000000000000..288810ce0a85 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-haliburton.postinst @@ -0,0 +1 @@ +chmod +x /usr/local/etc/lpc_cpld_x64_64 From 1d9825e3e3a82a4d9d47f441b28d81ce390d2084 Mon Sep 17 00:00:00 2001 From: wirut Date: Fri, 17 Aug 2018 17:11:45 +0700 Subject: [PATCH 07/18] Add sonic plugin and CPLD driver --- .../x86_64-cel_e1031-r0/plugins/psuutil.py | 62 ++ .../x86_64-cel_e1031-r0/plugins/sfputil.py | 123 +++ .../debian/platform-modules-haliburton.init | 1 + .../haliburton/modules/Makefile | 2 +- .../haliburton/modules/smc.c | 707 ++++++++++++++++++ 5 files changed, 894 insertions(+), 1 deletion(-) create mode 100644 device/celestica/x86_64-cel_e1031-r0/plugins/psuutil.py create mode 100644 device/celestica/x86_64-cel_e1031-r0/plugins/sfputil.py create mode 100644 platform/broadcom/sonic-platform-modules-cel/haliburton/modules/smc.c diff --git a/device/celestica/x86_64-cel_e1031-r0/plugins/psuutil.py b/device/celestica/x86_64-cel_e1031-r0/plugins/psuutil.py new file mode 100644 index 000000000000..f72d05a7027d --- /dev/null +++ b/device/celestica/x86_64-cel_e1031-r0/plugins/psuutil.py @@ -0,0 +1,62 @@ +#!/usr/bin/env python + +import os.path + +try: + from sonic_psu.psu_base import PsuBase +except ImportError as e: + raise ImportError (str(e) + "- required module not found") + +class PsuUtil(PsuBase): + """Platform-specific PSUutil class""" + + def __init__(self): + PsuBase.__init__(self) + + self.psu_path = "/sys/devices/platform/e1031.smc/" + self.psu_presence = "psu{}_prs" + self.psu_oper_status = "psu{}_status" + + def get_num_psus(self): + """ + Retrieves the number of PSUs available on the device + + :return: An integer, the number of PSUs available on the device + """ + return 2 + + def get_psu_status(self, index): + """ + Retrieves the oprational status of power supply unit (PSU) defined + by 1-based index + + :param index: An integer, 1-based index of the PSU of which to query status + :return: Boolean, True if PSU is operating properly, False if PSU is faulty + """ + psu_location = ["R", "L"] + status = 0 + try: + with open(self.psu_path + self.psu_oper_status.format(psu_location[index-1]), 'r') as power_status: + status = int(power_status.read()) + except IOError: + return False + + return status == 1 + + def get_psu_presence(self, index): + """ + Retrieves the presence status of power supply unit (PSU) defined + by 1-based index + + :param index: An integer, 1-based index of the PSU of which to query status + :return: Boolean, True if PSU is plugged, False if not + """ + psu_location = ["R", "L"] + status = 0 + try: + with open(self.psu_path + self.psu_presence.format(psu_location[index-1]), 'r') as psu_prs: + status = int(psu_prs.read()) + except IOError: + return False + + return status == 1 diff --git a/device/celestica/x86_64-cel_e1031-r0/plugins/sfputil.py b/device/celestica/x86_64-cel_e1031-r0/plugins/sfputil.py new file mode 100644 index 000000000000..4e1d4e72254c --- /dev/null +++ b/device/celestica/x86_64-cel_e1031-r0/plugins/sfputil.py @@ -0,0 +1,123 @@ +#!/usr/bin/env python + +try: + import time + import os + from sonic_sfp.sfputilbase import SfpUtilBase +except ImportError as e: + raise ImportError("%s - required module not found" % str(e)) + + +class SfpUtil(SfpUtilBase): + """Platform-specific SfpUtil class""" + + PORT_START = 1 + PORT_END = 52 + port_to_i2c_mapping = { + 1 : None, + 2 : None, + 3 : None, + 4 : None, + 5 : None, + 6 : None, + 7 : None, + 8 : None, + 9 : None, + 10 : None, + 11 : None, + 12 : None, + 13 : None, + 14 : None, + 15 : None, + 16 : None, + 17 : None, + 18 : None, + 19 : None, + 20 : None, + 21 : None, + 22 : None, + 23 : None, + 24 : None, + 25 : None, + 26 : None, + 27 : None, + 28 : None, + 29 : None, + 30 : None, + 31 : None, + 32 : None, + 33 : None, + 34 : None, + 35 : None, + 36 : None, + 37 : None, + 38 : None, + 39 : None, + 40 : None, + 41 : None, + 42 : None, + 43 : None, + 44 : None, + 45 : None, + 46 : None, + 47 : None, + 48 : None, + 49 : 15, + 50 : 14, + 51 : 17, + 52 : 16 + } + _port_to_eeprom_mapping = {} + _sfp_port = range(49, PORT_END + 1) + + @property + def port_start(self): + return self.PORT_START + + @property + def port_end(self): + return self.PORT_END + + @property + def qsfp_ports(self): + return [] + + @property + def port_to_eeprom_mapping(self): + return self._port_to_eeprom_mapping + + def __init__(self): + # Override port_to_eeprom_mapping for class initialization + eeprom_path = '/sys/bus/i2c/devices/i2c-{0}/{0}-0050/eeprom' + for x in range(self.PORT_START, self.PORT_END + 1): + port_eeprom_path = eeprom_path.format(self.port_to_i2c_mapping[x]) + self.port_to_eeprom_mapping[x] = port_eeprom_path + SfpUtilBase.__init__(self) + + def get_presence(self, port_num): + sfp_modabs_path = '/sys/devices/platform/e1031.smc/SFP/SFP{0}/sfp_modabs' + + if port_num not in self._sfp_port: + return False + + status = 1 + try: + with open(sfp_modabs_path.format(port_num - 48), 'r') as port_status: + status = int(port_status.read()) + except IOError: + return False + + return status == 0 + + + def get_low_power_mode(self, port_num): + raise NotImplementedError + + def set_low_power_mode(self, port_num, lpmode): + raise NotImplementedError + + def reset(self, port_num): + raise NotImplementedError + + def get_transceiver_change_event(self): + raise NotImplementedError diff --git a/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-haliburton.init b/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-haliburton.init index 722d788e531d..f47eac37fe5c 100644 --- a/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-haliburton.init +++ b/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-haliburton.init @@ -18,6 +18,7 @@ start) depmod -a modprobe i2c-dev modprobe i2c-mux-pca954x + modprobe smc (cd /usr/local/etc && ./lpc_cpld_x64_64 blu w 0x222 0x1f) diff --git a/platform/broadcom/sonic-platform-modules-cel/haliburton/modules/Makefile b/platform/broadcom/sonic-platform-modules-cel/haliburton/modules/Makefile index 6d0c489154c2..58e2b0bf2d7a 100644 --- a/platform/broadcom/sonic-platform-modules-cel/haliburton/modules/Makefile +++ b/platform/broadcom/sonic-platform-modules-cel/haliburton/modules/Makefile @@ -1 +1 @@ -obj-m := mc24lc64t.o emc2305.o +obj-m := mc24lc64t.o emc2305.o smc.o diff --git a/platform/broadcom/sonic-platform-modules-cel/haliburton/modules/smc.c b/platform/broadcom/sonic-platform-modules-cel/haliburton/modules/smc.c new file mode 100644 index 000000000000..fb1c4e4747bd --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-cel/haliburton/modules/smc.c @@ -0,0 +1,707 @@ +/* + * smc.c - The CPLD driver for E1031 System Management. + * The driver implement sysfs to access CPLD register on the E1031 via LPC bus. + * Copyright (C) 2018 Celestica Corp. + * + * 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. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// Changed: (opt) Add LED control sysfs +// Changed: Add PSU status sysfs* +// Changed: Add SFP mod ctrl sysfs* +// TODO: (opt) Add fan LED sysfs +// TODO: (opt) Add fan direction sysfs + +#define DRIVER_NAME "e1031.smc" + +/** + * CPLD register address for read and write. + */ +#define VERSION 0x0200 +#define SCRATCH 0x0201 +#define BROAD_ID 0x0202 + +/* PSU STATUS + * [7] PSUR_ACOK + * [6] PSUR_PWOK + * [5] PSUR_ALRT + * [4] PSUR_PRS + * [3] PSUL_ACOK + * [2] PSUL_PWOK + * [1] PSUL_ALRT + * [0] PSUL_PRS + */ +#define PSU_STAT 0x0204 +#define PSUR_ACOK 7 +#define PSUR_PWOK 6 +#define PSUR_ALRT 5 +#define PSUR_PRS 4 +#define PSUL_ACOK 3 +#define PSUL_PWOK 2 +#define PSUL_ALRT 1 +#define PSUL_PRS 0 + +/* FAN LED CTRL + * [7:3] RESERVED + * [2:0] LED CTRL + */ +#define FAN_LED_1 0x0205 +#define FAN_LED_2 0x0206 +#define FAN_LED_3 0x0207 + +enum FAN_LED { + fan_led_grn = 0, + fan_led_grn_bnk, + fan_led_amb, + fan_led_amb_bnk, + fan_led_off +} fan_led; + +#define LED_OPMOD 0x0208 +#define LED_TEST 0x0209 + +/* SYSTEM LED + * [7:4] RESERVED + * [3:2] STATUS LED + * [1:0] MASTER LED + */ +#define LED_FPS 0x020a + +enum STAT_LED { + stat_led_off = 0, + stat_led_grn, + stat_led_grn_bnk +} stat_led; + +enum MASTER_LED { + master_led_off = 0, + master_led_grn, + master_led_amb +} master_led; + +/* FAN DIRECTION STAT + * [7:4] RESERVED + * [3] USB HUB STAT + * [2:0] FAN_DIR + */ +#define DEV_STAT 0x020c +#define FAN_3 2 +#define FAN_2 1 +#define FAN_1 0 + +/* SFP PORT STATUS + * [7:4] RESERVED + * [3:0] TX_FAULT / MODABS / RXLOS + */ +#define SFP_TXFAULT 0x0242 +#define SFP_MODABS 0x0243 +#define SFP_RXLOS 0x0244 + +/* SFP PORT CTRL + * [7:4] RATE SEL (RS0/RS1) + * [3:0] TX_DIS + */ +#define SFP_TXCTRL 0x0255 + +/* SFP PORT BIT OFFSET */ +#define SFP4 3 +#define SFP3 2 +#define SFP2 1 +#define SFP1 0 + +struct cpld_data { + struct mutex cpld_lock; + uint16_t read_addr; + struct device *fpp_node; + struct device *sfp_devices[4]; +}; + +struct sfp_device_data { + int portid; +}; + +struct class *celplatform; +struct cpld_data *cpld_data; + +static ssize_t scratch_show(struct device *dev, struct device_attribute *devattr, + char *buf) +{ + unsigned char data = 0; + mutex_lock(&cpld_data->cpld_lock); + data = inb(SCRATCH); + mutex_unlock(&cpld_data->cpld_lock); + return sprintf(buf, "0x%2.2x\n", data); +} + +static ssize_t scratch_store(struct device *dev, struct device_attribute *devattr, + const char *buf, size_t count) +{ + unsigned long data; + char *last; + + mutex_lock(&cpld_data->cpld_lock); + data = (uint16_t)strtoul(buf, &last, 16); + if (data == 0 && buf == last) { + mutex_unlock(&cpld_data->cpld_lock); + return -EINVAL; + } + outb(data, SCRATCH); + mutex_unlock(&cpld_data->cpld_lock); + return count; +} +static DEVICE_ATTR_RW(scratch); + + +static ssize_t version_show(struct device *dev, struct device_attribute *attr, char *buf) +{ + int len = 0; + mutex_lock(&cpld_data->cpld_lock); + len = sprintf(buf, "0x%2.2x\n", inb(VERSION)); + mutex_unlock(&cpld_data->cpld_lock); + return len; +} +static DEVICE_ATTR_RO(version); + +static ssize_t getreg_store(struct device *dev, struct device_attribute *devattr, + const char *buf, size_t count) +{ + uint16_t addr; + char *last; + + addr = (uint16_t)strtoul(buf, &last, 16); + if (addr == 0 && buf == last) { + return -EINVAL; + } + cpld_data->read_addr = addr; + return count; +} + +static ssize_t getreg_show(struct device *dev, struct device_attribute *attr, char *buf) +{ + int len = 0; + mutex_lock(&cpld_data->cpld_lock); + len = sprintf(buf, "0x%2.2x\n", inb(cpld_data->read_addr)); + mutex_unlock(&cpld_data->cpld_lock); + return len; +} +static DEVICE_ATTR_RW(getreg); + +static ssize_t setreg_store(struct device *dev, struct device_attribute *devattr, + const char *buf, size_t count) +{ + uint16_t addr; + uint8_t value; + char *tok; + char clone[count]; + char *pclone = clone; + char *last; + + strcpy(clone, buf); + + mutex_lock(&cpld_data->cpld_lock); + tok = strsep((char**)&pclone, " "); + if (tok == NULL) { + mutex_unlock(&cpld_data->cpld_lock); + return -EINVAL; + } + addr = (uint16_t)strtoul(tok, &last, 16); + if (addr == 0 && tok == last) { + mutex_unlock(&cpld_data->cpld_lock); + return -EINVAL; + } + + tok = strsep((char**)&pclone, " "); + if (tok == NULL) { + mutex_unlock(&cpld_data->cpld_lock); + return -EINVAL; + } + value = (uint8_t)strtoul(tok, &last, 16); + if (value == 0 && tok == last) { + mutex_unlock(&cpld_data->cpld_lock); + return -EINVAL; + } + + outb(value, addr); + mutex_unlock(&cpld_data->cpld_lock); + return count; +} +static DEVICE_ATTR_WO(setreg); + +/** + * Show status led + * @param dev kernel device + * @param devattr kernel device attribute + * @param buf buffer for get value + * @return led state - off/on/blink + */ +static ssize_t status_led_show(struct device *dev, struct device_attribute *devattr, + char *buf) +{ + unsigned char data = 0; + mutex_lock(&cpld_data->cpld_lock); + data = inb(LED_FPS); + mutex_unlock(&cpld_data->cpld_lock); + data = data & 0xc; + return sprintf(buf, "%s\n", + data == stat_led_grn ? "on" : data == stat_led_grn_bnk ? "blink" : "off"); +} + +/** + * Set the status led + * @param dev kernel device + * @param devattr kernel device attribute + * @param buf buffer of set value - off/on/blink + * @param count number of bytes in buffer + * @return number of bytes written, or error code < 0. + */ +static ssize_t status_led_store(struct device *dev, struct device_attribute *devattr, + const char *buf, size_t count) +{ + unsigned char led_status, data; + + if (sysfs_streq(buf, "off")) { + led_status = stat_led_off; + } else if (sysfs_streq(buf, "on")) { + led_status = stat_led_grn; + } else if (sysfs_streq(buf, "blink")) { + led_status = stat_led_grn_bnk; + } else { + count = -EINVAL; + return count; + } + mutex_lock(&cpld_data->cpld_lock); + data = inb(LED_FPS); + data = data & ~(0xc); + data = data | ( led_status << 2 ); + outb(data, LED_FPS); + mutex_unlock(&cpld_data->cpld_lock); + return count; +} +static DEVICE_ATTR_RW(status_led); + + +/** + * Show master led + * @param dev kernel device + * @param devattr kernel device attribute + * @param buf buffer for get value + * @return led state - off/green/amber + */ +static ssize_t master_led_show(struct device *dev, struct device_attribute *devattr, + char *buf) +{ + unsigned char data = 0; + mutex_lock(&cpld_data->cpld_lock); + data = inb(LED_FPS); + mutex_unlock(&cpld_data->cpld_lock); + data = data & 0x3; + return sprintf(buf, "%s\n", + data == master_led_grn ? "on" : data == master_led_amb ? "amber" : "off"); +} + +/** + * Set the master led + * @param dev kernel device + * @param devattr kernel device attribute + * @param buf buffer of set value - off/green/amber + * @param count number of bytes in buffer + * @return number of bytes written, or error code < 0. + */ +static ssize_t master_led_store(struct device *dev, struct device_attribute *devattr, + const char *buf, size_t count) +{ + unsigned char led_status, data; + + if (sysfs_streq(buf, "off")) { + led_status = master_led_off; + } else if (sysfs_streq(buf, "green")) { + led_status = master_led_grn; + } else if (sysfs_streq(buf, "amber")) { + led_status = master_led_amb; + } else { + count = -EINVAL; + return count; + } + mutex_lock(&cpld_data->cpld_lock); + data = inb(LED_FPS); + data = data & ~(0x3); + data = data | led_status; + outb(data, LED_FPS); + mutex_unlock(&cpld_data->cpld_lock); + return count; +} +static DEVICE_ATTR_RW(master_led); + +static ssize_t psuL_prs_show(struct device *dev, struct device_attribute *devattr, + char *buf) +{ + unsigned char data = 0; + mutex_lock(&cpld_data->cpld_lock); + data = inb(PSU_STAT); + mutex_unlock(&cpld_data->cpld_lock); + return sprintf(buf, "%d\n", ~(data >> PSUL_PRS) & 1U); +} +static DEVICE_ATTR_RO(psuL_prs); + +static ssize_t psuR_prs_show(struct device *dev, struct device_attribute *devattr, + char *buf) +{ + unsigned char data = 0; + mutex_lock(&cpld_data->cpld_lock); + data = inb(PSU_STAT); + mutex_unlock(&cpld_data->cpld_lock); + return sprintf(buf, "%d\n", ~(data >> PSUR_PRS) & 1U); +} +static DEVICE_ATTR_RO(psuR_prs); + +static ssize_t psuL_status_show(struct device *dev, struct device_attribute *devattr, + char *buf) +{ + unsigned char data = 0; + mutex_lock(&cpld_data->cpld_lock); + data = inb(PSU_STAT); + mutex_unlock(&cpld_data->cpld_lock); + data = ( data >> PSUL_PWOK ) & 0x3; + return sprintf(buf, "%d\n", data == 0x3 ); +} +static DEVICE_ATTR_RO(psuL_status); + +static ssize_t psuR_status_show(struct device *dev, struct device_attribute *devattr, + char *buf) +{ + unsigned char data = 0; + mutex_lock(&cpld_data->cpld_lock); + data = inb(PSU_STAT); + mutex_unlock(&cpld_data->cpld_lock); + data = ( data >> PSUR_PWOK ) & 0x3; + return sprintf(buf, "%d\n", data == 0x3 ); +} +static DEVICE_ATTR_RO(psuR_status); + + +static struct attribute *cpld_attrs[] = { + &dev_attr_version.attr, + &dev_attr_scratch.attr, + &dev_attr_getreg.attr, + &dev_attr_setreg.attr, + // LEDS + &dev_attr_status_led.attr, + &dev_attr_master_led.attr, + // PSUs + &dev_attr_psuL_prs.attr, + &dev_attr_psuR_prs.attr, + &dev_attr_psuL_status.attr, + &dev_attr_psuR_status.attr, + NULL, +}; + +static struct attribute_group cpld_attrs_grp = { + .attrs = cpld_attrs, +}; + +static ssize_t sfp_txfault_show(struct device *dev, struct device_attribute *attr, char *buf) +{ + unsigned char data; + struct sfp_device_data *dev_data = dev_get_drvdata(dev); + unsigned int port_bit = dev_data->portid - 1; + + mutex_lock(&cpld_data->cpld_lock); + data = inb(SFP_TXFAULT); + mutex_unlock(&cpld_data->cpld_lock); + return sprintf(buf, "%d\n", (data >> port_bit ) & 1U); +} +static DEVICE_ATTR_RO(sfp_txfault); + +static ssize_t sfp_modabs_show(struct device *dev, struct device_attribute *attr, char *buf) +{ + unsigned char data; + struct sfp_device_data *dev_data = dev_get_drvdata(dev); + unsigned int port_bit = dev_data->portid - 1; + + mutex_lock(&cpld_data->cpld_lock); + data = inb(SFP_MODABS); + mutex_unlock(&cpld_data->cpld_lock); + return sprintf(buf, "%d\n", (data >> port_bit ) & 1U); +} +static DEVICE_ATTR_RO(sfp_modabs); + +static ssize_t sfp_rxlos_show(struct device *dev, struct device_attribute *attr, char *buf) +{ + unsigned char data; + struct sfp_device_data *dev_data = dev_get_drvdata(dev); + unsigned int port_bit = dev_data->portid - 1; + + mutex_lock(&cpld_data->cpld_lock); + data = inb(SFP_RXLOS); + mutex_unlock(&cpld_data->cpld_lock); + return sprintf(buf, "%d\n", (data >> port_bit ) & 1U); +} +static DEVICE_ATTR_RO(sfp_rxlos); + +static ssize_t sfp_txdis_show(struct device *dev, struct device_attribute *attr, char *buf) +{ + unsigned char data; + struct sfp_device_data *dev_data = dev_get_drvdata(dev); + unsigned int port_bit = dev_data->portid - 1; + mutex_lock(&cpld_data->cpld_lock); + data = inb(SFP_TXCTRL); + mutex_unlock(&cpld_data->cpld_lock); + return sprintf(buf, "%d\n", (data >> port_bit ) & 1U); +} + +static ssize_t sfp_txdis_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t size) +{ + long value; + ssize_t status; + unsigned char data; + struct sfp_device_data *dev_data = dev_get_drvdata(dev); + unsigned int port_bit = dev_data->portid - 1; + + mutex_lock(&cpld_data->cpld_lock); + status = kstrtol(buf, 0, &value); + if (status == 0) { + // check if value is 0, clear + data = inb(SFP_TXCTRL); + if (!value) + data = data & ~( 1U << port_bit); + else + data = data | ( 1U << port_bit); + outb(data, SFP_TXCTRL); + status = size; + } + mutex_unlock(&cpld_data->cpld_lock); + return status; +} +static DEVICE_ATTR_RW(sfp_txdis); + +static ssize_t sfp_rs_show(struct device *dev, struct device_attribute *attr, char *buf) +{ + unsigned char data; + struct sfp_device_data *dev_data = dev_get_drvdata(dev); + unsigned int port_bit = dev_data->portid - 1; + + // High nibble + port_bit = port_bit + 4; + mutex_lock(&cpld_data->cpld_lock); + data = inb(SFP_TXCTRL); + mutex_unlock(&cpld_data->cpld_lock); + return sprintf(buf, "%d\n", (data >> port_bit ) & 1U); +} + +static ssize_t sfp_rs_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t size) +{ + long value; + ssize_t status; + unsigned char data; + struct sfp_device_data *dev_data = dev_get_drvdata(dev); + unsigned int port_bit = dev_data->portid - 1; + + // High nibble + port_bit = port_bit + 4; + mutex_lock(&cpld_data->cpld_lock); + status = kstrtol(buf, 0, &value); + if (status == 0) { + // check if value is 0, clear + data = inb(SFP_TXCTRL); + if (!value) + data = data & ~( 1U << port_bit); + else + data = data | ( 1U << port_bit); + outb(data, SFP_TXCTRL); + status = size; + } + mutex_unlock(&cpld_data->cpld_lock); + return status; +} +static DEVICE_ATTR_RW(sfp_rs); + +static struct attribute *sfp_attrs[] = { + // SFP + &dev_attr_sfp_txfault.attr, + &dev_attr_sfp_modabs.attr, + &dev_attr_sfp_rxlos.attr, + &dev_attr_sfp_txdis.attr, + &dev_attr_sfp_rs.attr, + NULL, +}; + +static struct attribute_group sfp_attr_grp = { + .attrs = sfp_attrs, +}; + +static const struct attribute_group *sfp_attr_grps[] = { + &sfp_attr_grp, + NULL +}; + +static struct resource cpld_resources[] = { + { + .start = 0x0200, + .end = 0x0255, + .flags = IORESOURCE_IO, + }, +}; + +static struct device * sfp_init(int portid) { + struct sfp_device_data *new_data; + struct device *new_device; + + new_data = kzalloc(sizeof(*new_data), GFP_KERNEL); + if (!new_data) { + printk(KERN_ALERT "Cannot alloc sff device data @port%d", portid); + return NULL; + } + /* Front panel port ID start from 1 */ + new_data->portid = portid + 1; + new_device = device_create_with_groups(celplatform, cpld_data->fpp_node, MKDEV(0, 0), new_data, sfp_attr_grps, "SFP%d", new_data->portid); + if (IS_ERR(new_device)) { + printk(KERN_ALERT "Cannot create sff device @port%d", portid); + kfree(new_data); + return NULL; + } + return new_device; +} + +static void cpld_dev_release( struct device * dev) +{ + return; +} + +static struct platform_device cpld_dev = { + .name = DRIVER_NAME, + .id = -1, + .num_resources = ARRAY_SIZE(cpld_resources), + .resource = cpld_resources, + .dev = { + .release = cpld_dev_release, + } +}; + +static int cpld_drv_probe(struct platform_device *pdev) +{ + struct resource *res; + int err, i = 0; + + cpld_data = devm_kzalloc(&pdev->dev, sizeof(struct cpld_data), + GFP_KERNEL); + if (!cpld_data) + return -ENOMEM; + + mutex_init(&cpld_data->cpld_lock); + + cpld_data->read_addr = VERSION; + + res = platform_get_resource(pdev, IORESOURCE_IO, 0); + if (unlikely(!res)) { + printk(KERN_ERR "Specified Resource Not Available...\n"); + return -ENODEV; + } + + err = sysfs_create_group(&pdev->dev.kobj, &cpld_attrs_grp); + if (err) { + printk(KERN_ERR "Cannot create sysfs for SMC.\n"); + return err; + } + + celplatform = class_create(THIS_MODULE, "celplatform"); + if (IS_ERR(celplatform)) { + printk(KERN_ERR "Failed to register device class\n"); + sysfs_remove_group(&pdev->dev.kobj, &cpld_attrs_grp); + return PTR_ERR(celplatform); + } + + cpld_data->fpp_node = device_create(celplatform, NULL, MKDEV(0, 0), NULL, "optical_ports"); + if (IS_ERR(cpld_data->fpp_node)) { + class_destroy(celplatform); + sysfs_remove_group(&pdev->dev.kobj, &cpld_attrs_grp); + return PTR_ERR(cpld_data->fpp_node); + } + + err = sysfs_create_link(&pdev->dev.kobj, &cpld_data->fpp_node->kobj, "SFP"); + if (err != 0) { + put_device(cpld_data->fpp_node); + device_unregister(cpld_data->fpp_node); + class_destroy(celplatform); + sysfs_remove_group(&pdev->dev.kobj, &cpld_attrs_grp); + return err; + } + + // Creae SFP devices + for ( i = 0; i < 4; i++) { + cpld_data->sfp_devices[i] = sfp_init(i); + } + return 0; +} + +static int cpld_drv_remove(struct platform_device *pdev) +{ + struct sfp_device_data *rem_data; + int i; + + for ( i = 0; i < 4; i++) { + rem_data = dev_get_drvdata(cpld_data->sfp_devices[i]); + put_device(cpld_data->sfp_devices[i]); + device_unregister(cpld_data->sfp_devices[i]); + kzfree(rem_data); + } + put_device(cpld_data->fpp_node); + device_unregister(cpld_data->fpp_node); + sysfs_remove_group(&pdev->dev.kobj, &cpld_attrs_grp); + class_destroy(celplatform); + return 0; +} + +static struct platform_driver cpld_drv = { + .probe = cpld_drv_probe, + .remove = __exit_p(cpld_drv_remove), + .driver = { + .name = DRIVER_NAME, + }, +}; + +int cpld_init(void) +{ + // Register platform device and platform driver + platform_device_register(&cpld_dev); + platform_driver_register(&cpld_drv); + return 0; +} + +void cpld_exit(void) +{ + // Unregister platform device and platform driver + platform_driver_unregister(&cpld_drv); + platform_device_unregister(&cpld_dev); +} + +module_init(cpld_init); +module_exit(cpld_exit); + + +MODULE_AUTHOR("Celestica Inc."); +MODULE_DESCRIPTION("Celestica E1031 SMC driver"); +MODULE_VERSION("0.0.1"); +MODULE_LICENSE("GPL"); From f8c6d95a692d54f375c65fe2104b0a9cd906b89d Mon Sep 17 00:00:00 2001 From: Wirut Getbamrung Date: Tue, 21 Aug 2018 17:58:21 +0700 Subject: [PATCH 08/18] Update platform configuration and fixed issues --- .../Celestica-E1031-T48S4/port_config.ini | 106 +++++----- .../celestica/x86_64-cel_e1031-r0/fancontrol | 2 +- .../x86_64-cel_e1031-r0/plugins/psuutil.py | 17 +- .../x86_64-cel_e1031-r0/sensors.conf | 2 +- .../debian/platform-modules-haliburton.init | 4 +- .../platform-modules-haliburton.install | 1 + .../platform-modules-haliburton.postinst | 2 + .../haliburton/modules/smc.c | 200 +++++++++++------- .../platform-modules-haliburton.service | 14 ++ 9 files changed, 209 insertions(+), 139 deletions(-) create mode 100644 platform/broadcom/sonic-platform-modules-cel/haliburton/systemd/platform-modules-haliburton.service diff --git a/device/celestica/x86_64-cel_e1031-r0/Celestica-E1031-T48S4/port_config.ini b/device/celestica/x86_64-cel_e1031-r0/Celestica-E1031-T48S4/port_config.ini index 6a7debfa45f6..a2b64ea155df 100644 --- a/device/celestica/x86_64-cel_e1031-r0/Celestica-E1031-T48S4/port_config.ini +++ b/device/celestica/x86_64-cel_e1031-r0/Celestica-E1031-T48S4/port_config.ini @@ -1,53 +1,53 @@ -# name lanes speed alias autoneg -Ethernet0 2 1000 etp1 1 -Ethernet1 1 1000 etp2 1 -Ethernet2 4 1000 etp3 1 -Ethernet3 3 1000 etp4 1 -Ethernet4 6 1000 etp5 1 -Ethernet5 5 1000 etp6 1 -Ethernet6 8 1000 etp7 1 -Ethernet7 7 1000 etp8 1 -Ethernet8 10 1000 etp9 1 -Ethernet9 9 1000 etp10 1 -Ethernet10 12 1000 etp11 1 -Ethernet11 11 1000 etp12 1 -Ethernet12 14 1000 etp13 1 -Ethernet13 13 1000 etp14 1 -Ethernet14 16 1000 etp15 1 -Ethernet15 15 1000 etp16 1 -Ethernet16 18 1000 etp17 1 -Ethernet17 17 1000 etp18 1 -Ethernet18 20 1000 etp19 1 -Ethernet19 19 1000 etp20 1 -Ethernet20 22 1000 etp21 1 -Ethernet21 21 1000 etp22 1 -Ethernet22 24 1000 etp23 1 -Ethernet23 23 1000 etp24 1 -Ethernet24 26 1000 etp25 1 -Ethernet25 25 1000 etp26 1 -Ethernet26 28 1000 etp27 1 -Ethernet27 27 1000 etp28 1 -Ethernet28 30 1000 etp29 1 -Ethernet29 29 1000 etp30 1 -Ethernet30 32 1000 etp31 1 -Ethernet31 31 1000 etp32 1 -Ethernet32 34 1000 etp33 1 -Ethernet33 33 1000 etp34 1 -Ethernet34 36 1000 etp35 1 -Ethernet35 35 1000 etp36 1 -Ethernet36 38 1000 etp37 1 -Ethernet37 37 1000 etp38 1 -Ethernet38 40 1000 etp39 1 -Ethernet39 39 1000 etp40 1 -Ethernet40 42 1000 etp41 1 -Ethernet41 41 1000 etp42 1 -Ethernet42 44 1000 etp43 1 -Ethernet43 43 1000 etp44 1 -Ethernet44 46 1000 etp45 1 -Ethernet45 45 1000 etp46 1 -Ethernet46 48 1000 etp47 1 -Ethernet47 47 1000 etp48 1 -Ethernet48 54 10000 etp49 0 -Ethernet49 53 10000 etp50 0 -Ethernet50 56 10000 etp51 0 -Ethernet51 55 10000 etp52 0 +# name lanes index speed alias autoneg +Ethernet0 2 1 1000 etp1 1 +Ethernet1 1 2 1000 etp2 1 +Ethernet2 4 3 1000 etp3 1 +Ethernet3 3 4 1000 etp4 1 +Ethernet4 6 5 1000 etp5 1 +Ethernet5 5 6 1000 etp6 1 +Ethernet6 8 7 1000 etp7 1 +Ethernet7 7 8 1000 etp8 1 +Ethernet8 10 9 1000 etp9 1 +Ethernet9 9 10 1000 etp10 1 +Ethernet10 12 11 1000 etp11 1 +Ethernet11 11 12 1000 etp12 1 +Ethernet12 14 13 1000 etp13 1 +Ethernet13 13 14 1000 etp14 1 +Ethernet14 16 15 1000 etp15 1 +Ethernet15 15 16 1000 etp16 1 +Ethernet16 18 17 1000 etp17 1 +Ethernet17 17 18 1000 etp18 1 +Ethernet18 20 19 1000 etp19 1 +Ethernet19 19 20 1000 etp20 1 +Ethernet20 22 21 1000 etp21 1 +Ethernet21 21 22 1000 etp22 1 +Ethernet22 24 23 1000 etp23 1 +Ethernet23 23 24 1000 etp24 1 +Ethernet24 26 25 1000 etp25 1 +Ethernet25 25 26 1000 etp26 1 +Ethernet26 28 27 1000 etp27 1 +Ethernet27 27 28 1000 etp28 1 +Ethernet28 30 29 1000 etp29 1 +Ethernet29 29 30 1000 etp30 1 +Ethernet30 32 31 1000 etp31 1 +Ethernet31 31 32 1000 etp32 1 +Ethernet32 34 33 1000 etp33 1 +Ethernet33 33 34 1000 etp34 1 +Ethernet34 36 35 1000 etp35 1 +Ethernet35 35 36 1000 etp36 1 +Ethernet36 38 37 1000 etp37 1 +Ethernet37 37 38 1000 etp38 1 +Ethernet38 40 39 1000 etp39 1 +Ethernet39 39 40 1000 etp40 1 +Ethernet40 42 41 1000 etp41 1 +Ethernet41 41 42 1000 etp42 1 +Ethernet42 44 43 1000 etp43 1 +Ethernet43 43 44 1000 etp44 1 +Ethernet44 46 45 1000 etp45 1 +Ethernet45 45 46 1000 etp46 1 +Ethernet46 48 47 1000 etp47 1 +Ethernet47 47 48 1000 etp48 1 +Ethernet48 54 49 10000 etp49 0 +Ethernet49 53 50 10000 etp50 0 +Ethernet50 56 51 10000 etp51 0 +Ethernet51 55 52 10000 etp52 0 diff --git a/device/celestica/x86_64-cel_e1031-r0/fancontrol b/device/celestica/x86_64-cel_e1031-r0/fancontrol index e7e71257a4d2..27c6dcb78e2c 100644 --- a/device/celestica/x86_64-cel_e1031-r0/fancontrol +++ b/device/celestica/x86_64-cel_e1031-r0/fancontrol @@ -1,6 +1,6 @@ # Configuration file generated by pwmconfig, changes will be lost INTERVAL=2 -DEVPATH=hwmon3=devices/pci0000:00/0000:00:13.0/i2c-1/i2c-8/i2c-23/23-004d hwmon2=devices/pci0000:00/0000:00:13.0/i2c-1/i2c-8/i2c-11/11-001a +DEVPATH=hwmon3=devices/pci0000:00/0000:00:13.0/i2c-0/i2c-8/i2c-23/23-004d hwmon2=devices/pci0000:00/0000:00:13.0/i2c-0/i2c-8/i2c-11/11-001a DEVNAME=hwmon3=emc2305 hwmon2=max6697 FCTEMPS=hwmon3/device/pwm1=hwmon2/temp2_input hwmon3/device/pwm2=hwmon2/temp2_input hwmon3/device/pwm4=hwmon2/temp2_input FCFANS=hwmon3/device/pwm1=hwmon3/device/fan1_input hwmon3/device/pwm2=hwmon3/device/fan2_input hwmon3/device/pwm4=hwmon3/device/fan4_input diff --git a/device/celestica/x86_64-cel_e1031-r0/plugins/psuutil.py b/device/celestica/x86_64-cel_e1031-r0/plugins/psuutil.py index f72d05a7027d..71b8d4ad3c59 100644 --- a/device/celestica/x86_64-cel_e1031-r0/plugins/psuutil.py +++ b/device/celestica/x86_64-cel_e1031-r0/plugins/psuutil.py @@ -5,7 +5,8 @@ try: from sonic_psu.psu_base import PsuBase except ImportError as e: - raise ImportError (str(e) + "- required module not found") + raise ImportError(str(e) + "- required module not found") + class PsuUtil(PsuBase): """Platform-specific PSUutil class""" @@ -27,16 +28,15 @@ def get_num_psus(self): def get_psu_status(self, index): """ - Retrieves the oprational status of power supply unit (PSU) defined - by 1-based index + Retrieves the oprational status of power supply unit (PSU) defined by 1-based index :param index: An integer, 1-based index of the PSU of which to query status :return: Boolean, True if PSU is operating properly, False if PSU is faulty """ - psu_location = ["R", "L"] + psu_location = ["R", "L"] status = 0 try: - with open(self.psu_path + self.psu_oper_status.format(psu_location[index-1]), 'r') as power_status: + with open(self.psu_path + self.psu_oper_status.format(psu_location[index - 1]), 'r') as power_status: status = int(power_status.read()) except IOError: return False @@ -45,16 +45,15 @@ def get_psu_status(self, index): def get_psu_presence(self, index): """ - Retrieves the presence status of power supply unit (PSU) defined - by 1-based index + Retrieves the presence status of power supply unit (PSU) defined by 1-based index :param index: An integer, 1-based index of the PSU of which to query status :return: Boolean, True if PSU is plugged, False if not """ - psu_location = ["R", "L"] + psu_location = ["R", "L"] status = 0 try: - with open(self.psu_path + self.psu_presence.format(psu_location[index-1]), 'r') as psu_prs: + with open(self.psu_path + self.psu_presence.format(psu_location[index - 1]), 'r') as psu_prs: status = int(psu_prs.read()) except IOError: return False diff --git a/device/celestica/x86_64-cel_e1031-r0/sensors.conf b/device/celestica/x86_64-cel_e1031-r0/sensors.conf index 5f65764e4986..25c6047137b6 100644 --- a/device/celestica/x86_64-cel_e1031-r0/sensors.conf +++ b/device/celestica/x86_64-cel_e1031-r0/sensors.conf @@ -2,7 +2,7 @@ # The i2c bus portion is omit because adapter name # changes every time when system boot up. -bus "i2c-3" "i2c-1-mux (chan_id 1)" +bus "i2c-3" "i2c-0-mux (chan_id 1)" bus "i2c-11" "i2c-8-mux (chan_id 1)" chip "max6697-i2c-3-1a" diff --git a/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-haliburton.init b/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-haliburton.init index f47eac37fe5c..d68d227ec708 100644 --- a/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-haliburton.init +++ b/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-haliburton.init @@ -16,8 +16,6 @@ start) echo -n "Setting up board... " depmod -a - modprobe i2c-dev - modprobe i2c-mux-pca954x modprobe smc (cd /usr/local/etc && ./lpc_cpld_x64_64 blu w 0x222 0x1f) @@ -61,7 +59,7 @@ start) # Attach 4 SFP+ Uplink echo optoe2 0x50 > /sys/bus/i2c/devices/i2c-14/new_device - echo optoe2 0x50 > /sys/bus/i2c/devices/i2c-15/new_devic + echo optoe2 0x50 > /sys/bus/i2c/devices/i2c-15/new_device echo optoe2 0x50 > /sys/bus/i2c/devices/i2c-16/new_device echo optoe2 0x50 > /sys/bus/i2c/devices/i2c-17/new_device diff --git a/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-haliburton.install b/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-haliburton.install index 667300ac037b..1a30b1eb554a 100644 --- a/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-haliburton.install +++ b/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-haliburton.install @@ -1,2 +1,3 @@ haliburton/cfg/haliburton-modules.conf etc/modules-load.d haliburton/tools/lpc_cpld_x64_64 usr/local/etc +haliburton/systemd/platform-modules-haliburton.service lib/systemd/system diff --git a/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-haliburton.postinst b/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-haliburton.postinst index 288810ce0a85..0692a0c12752 100644 --- a/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-haliburton.postinst +++ b/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-haliburton.postinst @@ -1 +1,3 @@ chmod +x /usr/local/etc/lpc_cpld_x64_64 +systemctl enable platform-modules-haliburton.service +systemctl start platform-modules-haliburton.service 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 fb1c4e4747bd..5df4c698b8b6 100644 --- a/platform/broadcom/sonic-platform-modules-cel/haliburton/modules/smc.c +++ b/platform/broadcom/sonic-platform-modules-cel/haliburton/modules/smc.c @@ -9,31 +9,24 @@ * (at your option) any later version. */ -#include -#include -#include -#include -#include -#include -#include -#include -#include #include -#include #include -#include -#include #include +#include +#include +#include +#include +#include +#include +#include +#include #include +#include +#include +#include #include #include -#include -// Changed: (opt) Add LED control sysfs -// Changed: Add PSU status sysfs* -// Changed: Add SFP mod ctrl sysfs* -// TODO: (opt) Add fan LED sysfs -// TODO: (opt) Add fan direction sysfs #define DRIVER_NAME "e1031.smc" @@ -126,12 +119,6 @@ enum MASTER_LED { */ #define SFP_TXCTRL 0x0255 -/* SFP PORT BIT OFFSET */ -#define SFP4 3 -#define SFP3 2 -#define SFP2 1 -#define SFP1 0 - struct cpld_data { struct mutex cpld_lock; uint16_t read_addr; @@ -146,6 +133,11 @@ struct sfp_device_data { struct class *celplatform; struct cpld_data *cpld_data; +struct index_device_attribute { + struct device_attribute dev_attr; + int index; +}; + static ssize_t scratch_show(struct device *dev, struct device_attribute *devattr, char *buf) { @@ -172,7 +164,6 @@ static ssize_t scratch_store(struct device *dev, struct device_attribute *devatt mutex_unlock(&cpld_data->cpld_lock); return count; } -static DEVICE_ATTR_RW(scratch); static ssize_t version_show(struct device *dev, struct device_attribute *attr, char *buf) @@ -183,7 +174,6 @@ static ssize_t version_show(struct device *dev, struct device_attribute *attr, c mutex_unlock(&cpld_data->cpld_lock); return len; } -static DEVICE_ATTR_RO(version); static ssize_t getreg_store(struct device *dev, struct device_attribute *devattr, const char *buf, size_t count) @@ -207,7 +197,6 @@ static ssize_t getreg_show(struct device *dev, struct device_attribute *attr, ch mutex_unlock(&cpld_data->cpld_lock); return len; } -static DEVICE_ATTR_RW(getreg); static ssize_t setreg_store(struct device *dev, struct device_attribute *devattr, const char *buf, size_t count) @@ -248,7 +237,6 @@ static ssize_t setreg_store(struct device *dev, struct device_attribute *devattr mutex_unlock(&cpld_data->cpld_lock); return count; } -static DEVICE_ATTR_WO(setreg); /** * Show status led @@ -300,8 +288,6 @@ static ssize_t status_led_store(struct device *dev, struct device_attribute *dev mutex_unlock(&cpld_data->cpld_lock); return count; } -static DEVICE_ATTR_RW(status_led); - /** * Show master led @@ -353,7 +339,6 @@ static ssize_t master_led_store(struct device *dev, struct device_attribute *dev mutex_unlock(&cpld_data->cpld_lock); return count; } -static DEVICE_ATTR_RW(master_led); static ssize_t psuL_prs_show(struct device *dev, struct device_attribute *devattr, char *buf) @@ -364,7 +349,6 @@ static ssize_t psuL_prs_show(struct device *dev, struct device_attribute *devatt mutex_unlock(&cpld_data->cpld_lock); return sprintf(buf, "%d\n", ~(data >> PSUL_PRS) & 1U); } -static DEVICE_ATTR_RO(psuL_prs); static ssize_t psuR_prs_show(struct device *dev, struct device_attribute *devattr, char *buf) @@ -387,7 +371,6 @@ static ssize_t psuL_status_show(struct device *dev, struct device_attribute *dev data = ( data >> PSUL_PWOK ) & 0x3; return sprintf(buf, "%d\n", data == 0x3 ); } -static DEVICE_ATTR_RO(psuL_status); static ssize_t psuR_status_show(struct device *dev, struct device_attribute *devattr, char *buf) @@ -399,28 +382,22 @@ static ssize_t psuR_status_show(struct device *dev, struct device_attribute *dev data = ( data >> PSUR_PWOK ) & 0x3; return sprintf(buf, "%d\n", data == 0x3 ); } -static DEVICE_ATTR_RO(psuR_status); -static struct attribute *cpld_attrs[] = { - &dev_attr_version.attr, - &dev_attr_scratch.attr, - &dev_attr_getreg.attr, - &dev_attr_setreg.attr, - // LEDS - &dev_attr_status_led.attr, - &dev_attr_master_led.attr, - // PSUs - &dev_attr_psuL_prs.attr, - &dev_attr_psuR_prs.attr, - &dev_attr_psuL_status.attr, - &dev_attr_psuR_status.attr, - NULL, -}; +static ssize_t fan_dir_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; -static struct attribute_group cpld_attrs_grp = { - .attrs = cpld_attrs, -}; + // Use index to determind the status bit + mutex_lock(&cpld_data->cpld_lock); + data = inb(DEV_STAT); + mutex_unlock(&cpld_data->cpld_lock); + data = ( data >> index ) & 1U; + return sprintf(buf, "%s\n", data ? "B2F" : "F2B" ); +} static ssize_t sfp_txfault_show(struct device *dev, struct device_attribute *attr, char *buf) { @@ -433,7 +410,6 @@ static ssize_t sfp_txfault_show(struct device *dev, struct device_attribute *att mutex_unlock(&cpld_data->cpld_lock); return sprintf(buf, "%d\n", (data >> port_bit ) & 1U); } -static DEVICE_ATTR_RO(sfp_txfault); static ssize_t sfp_modabs_show(struct device *dev, struct device_attribute *attr, char *buf) { @@ -446,7 +422,6 @@ static ssize_t sfp_modabs_show(struct device *dev, struct device_attribute *attr mutex_unlock(&cpld_data->cpld_lock); return sprintf(buf, "%d\n", (data >> port_bit ) & 1U); } -static DEVICE_ATTR_RO(sfp_modabs); static ssize_t sfp_rxlos_show(struct device *dev, struct device_attribute *attr, char *buf) { @@ -459,7 +434,6 @@ static ssize_t sfp_rxlos_show(struct device *dev, struct device_attribute *attr, mutex_unlock(&cpld_data->cpld_lock); return sprintf(buf, "%d\n", (data >> port_bit ) & 1U); } -static DEVICE_ATTR_RO(sfp_rxlos); static ssize_t sfp_txdis_show(struct device *dev, struct device_attribute *attr, char *buf) { @@ -495,7 +469,6 @@ static ssize_t sfp_txdis_store(struct device *dev, struct device_attribute *attr mutex_unlock(&cpld_data->cpld_lock); return status; } -static DEVICE_ATTR_RW(sfp_txdis); static ssize_t sfp_rs_show(struct device *dev, struct device_attribute *attr, char *buf) { @@ -536,7 +509,97 @@ static ssize_t sfp_rs_store(struct device *dev, struct device_attribute *attr, c mutex_unlock(&cpld_data->cpld_lock); return status; } + +static ssize_t fan_led_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; + char *led_str[5] = {"green", "green-blink", "amber", "amber-blink", "off"}; + + // Use index to determind the status bit + mutex_lock(&cpld_data->cpld_lock); + data = inb(FAN_LED_1 + index); + data = data & 0x7; + mutex_unlock(&cpld_data->cpld_lock); + return sprintf(buf, "%s\n", led_str[data]); +} + +static ssize_t fan_led_store(struct device *dev, struct device_attribute *devattr, + const char *buf, size_t count) +{ + struct sensor_device_attribute *sa = to_sensor_dev_attr(devattr); + int index = sa->index; + unsigned char led_status = 0; + + if (sysfs_streq(buf, "off")) { + led_status = fan_led_off; + } else if (sysfs_streq(buf, "green")) { + led_status = fan_led_grn; + } else if (sysfs_streq(buf, "amber")) { + led_status = fan_led_amb; + } else if (sysfs_streq(buf, "green-blink")) { + led_status = fan_led_grn_bnk; + } else if (sysfs_streq(buf, "amber-blink")) { + led_status = fan_led_amb_bnk; + } else { + count = -EINVAL; + return count; + } + mutex_lock(&cpld_data->cpld_lock); + outb(led_status, FAN_LED_1 + index); + mutex_unlock(&cpld_data->cpld_lock); + return count; +} + +static DEVICE_ATTR_RO(version); +static DEVICE_ATTR_RW(scratch); +static DEVICE_ATTR_RW(getreg); +static DEVICE_ATTR_WO(setreg); +static DEVICE_ATTR_RW(status_led); +static DEVICE_ATTR_RW(master_led); +static DEVICE_ATTR_RO(psuL_prs); +static DEVICE_ATTR_RO(psuL_status); +static DEVICE_ATTR_RO(psuR_status); +static DEVICE_ATTR_RO(sfp_txfault); +static DEVICE_ATTR_RO(sfp_modabs); +static DEVICE_ATTR_RO(sfp_rxlos); +static DEVICE_ATTR_RW(sfp_txdis); static DEVICE_ATTR_RW(sfp_rs); +static SENSOR_DEVICE_ATTR(fan1_dir, S_IRUGO, fan_dir_show, NULL, FAN_1); +static SENSOR_DEVICE_ATTR(fan2_dir, S_IRUGO, fan_dir_show, NULL, FAN_2); +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 struct attribute *cpld_attrs[] = { + &dev_attr_version.attr, + &dev_attr_scratch.attr, + &dev_attr_getreg.attr, + &dev_attr_setreg.attr, + // LEDs + &dev_attr_status_led.attr, + &dev_attr_master_led.attr, + // PSUs + &dev_attr_psuL_prs.attr, + &dev_attr_psuR_prs.attr, + &dev_attr_psuL_status.attr, + &dev_attr_psuR_status.attr, + // FANs + &sensor_dev_attr_fan1_dir.dev_attr.attr, + &sensor_dev_attr_fan2_dir.dev_attr.attr, + &sensor_dev_attr_fan3_dir.dev_attr.attr, + &sensor_dev_attr_fan1_led.dev_attr.attr, + &sensor_dev_attr_fan2_led.dev_attr.attr, + &sensor_dev_attr_fan3_led.dev_attr.attr, + NULL, +}; + +static struct attribute_group cpld_group = { + .attrs = cpld_attrs, +}; static struct attribute *sfp_attrs[] = { // SFP @@ -548,14 +611,7 @@ static struct attribute *sfp_attrs[] = { NULL, }; -static struct attribute_group sfp_attr_grp = { - .attrs = sfp_attrs, -}; - -static const struct attribute_group *sfp_attr_grps[] = { - &sfp_attr_grp, - NULL -}; +ATTRIBUTE_GROUPS(sfp); static struct resource cpld_resources[] = { { @@ -576,7 +632,7 @@ static struct device * sfp_init(int portid) { } /* Front panel port ID start from 1 */ new_data->portid = portid + 1; - new_device = device_create_with_groups(celplatform, cpld_data->fpp_node, MKDEV(0, 0), new_data, sfp_attr_grps, "SFP%d", new_data->portid); + new_device = device_create_with_groups(celplatform, cpld_data->fpp_node, MKDEV(0, 0), new_data, sfp_groups, "SFP%d", new_data->portid); if (IS_ERR(new_device)) { printk(KERN_ALERT "Cannot create sff device @port%d", portid); kfree(new_data); @@ -620,7 +676,7 @@ static int cpld_drv_probe(struct platform_device *pdev) return -ENODEV; } - err = sysfs_create_group(&pdev->dev.kobj, &cpld_attrs_grp); + err = sysfs_create_group(&pdev->dev.kobj, &cpld_group); if (err) { printk(KERN_ERR "Cannot create sysfs for SMC.\n"); return err; @@ -629,14 +685,14 @@ static int cpld_drv_probe(struct platform_device *pdev) celplatform = class_create(THIS_MODULE, "celplatform"); if (IS_ERR(celplatform)) { printk(KERN_ERR "Failed to register device class\n"); - sysfs_remove_group(&pdev->dev.kobj, &cpld_attrs_grp); + sysfs_remove_group(&pdev->dev.kobj, &cpld_group); return PTR_ERR(celplatform); } cpld_data->fpp_node = device_create(celplatform, NULL, MKDEV(0, 0), NULL, "optical_ports"); if (IS_ERR(cpld_data->fpp_node)) { class_destroy(celplatform); - sysfs_remove_group(&pdev->dev.kobj, &cpld_attrs_grp); + sysfs_remove_group(&pdev->dev.kobj, &cpld_group); return PTR_ERR(cpld_data->fpp_node); } @@ -645,7 +701,7 @@ static int cpld_drv_probe(struct platform_device *pdev) put_device(cpld_data->fpp_node); device_unregister(cpld_data->fpp_node); class_destroy(celplatform); - sysfs_remove_group(&pdev->dev.kobj, &cpld_attrs_grp); + sysfs_remove_group(&pdev->dev.kobj, &cpld_group); return err; } @@ -661,7 +717,7 @@ static int cpld_drv_remove(struct platform_device *pdev) struct sfp_device_data *rem_data; int i; - for ( i = 0; i < 4; i++) { + for ( i = 0; i < 4; i++ ) { rem_data = dev_get_drvdata(cpld_data->sfp_devices[i]); put_device(cpld_data->sfp_devices[i]); device_unregister(cpld_data->sfp_devices[i]); @@ -669,7 +725,7 @@ static int cpld_drv_remove(struct platform_device *pdev) } put_device(cpld_data->fpp_node); device_unregister(cpld_data->fpp_node); - sysfs_remove_group(&pdev->dev.kobj, &cpld_attrs_grp); + sysfs_remove_group(&pdev->dev.kobj, &cpld_group); class_destroy(celplatform); return 0; } @@ -703,5 +759,5 @@ module_exit(cpld_exit); MODULE_AUTHOR("Celestica Inc."); MODULE_DESCRIPTION("Celestica E1031 SMC driver"); -MODULE_VERSION("0.0.1"); +MODULE_VERSION("0.0.3"); MODULE_LICENSE("GPL"); diff --git a/platform/broadcom/sonic-platform-modules-cel/haliburton/systemd/platform-modules-haliburton.service b/platform/broadcom/sonic-platform-modules-cel/haliburton/systemd/platform-modules-haliburton.service new file mode 100644 index 000000000000..bf1295038856 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-cel/haliburton/systemd/platform-modules-haliburton.service @@ -0,0 +1,14 @@ + +[Unit] +Description=Celestica haliburton platform modules +After=local-fs.target +Before=pmon.service + +[Service] +Type=oneshot +ExecStart=-/etc/init.d/platform-modules-haliburton start +ExecStop=-/etc/init.d/platform-modules-haliburton stop +RemainAfterExit=yes + +[Install] +WantedBy=multi-user.target \ No newline at end of file From cf18fdda6bc92364c7e06630990a3a998973da93 Mon Sep 17 00:00:00 2001 From: Wirut Getbamrung Date: Wed, 22 Aug 2018 15:06:28 +0700 Subject: [PATCH 09/18] Fix-PR-1960 --- .../x86_64-cel_e1031-r0/plugins/sfputil.py | 6 +- .../debian/platform-modules-dx010.init | 10 +- .../dx010/modules/lm75.c | 553 ------------------ .../dx010/modules/lm75.h | 49 -- .../haliburton/tools/lpc_cpld_x64_64 | Bin 13465 -> 0 bytes 5 files changed, 8 insertions(+), 610 deletions(-) delete mode 100644 platform/broadcom/sonic-platform-modules-cel/dx010/modules/lm75.c delete mode 100644 platform/broadcom/sonic-platform-modules-cel/dx010/modules/lm75.h delete mode 100755 platform/broadcom/sonic-platform-modules-cel/haliburton/tools/lpc_cpld_x64_64 diff --git a/device/celestica/x86_64-cel_e1031-r0/plugins/sfputil.py b/device/celestica/x86_64-cel_e1031-r0/plugins/sfputil.py index 4e1d4e72254c..851fb9ccc071 100644 --- a/device/celestica/x86_64-cel_e1031-r0/plugins/sfputil.py +++ b/device/celestica/x86_64-cel_e1031-r0/plugins/sfputil.py @@ -111,13 +111,13 @@ def get_presence(self, port_num): def get_low_power_mode(self, port_num): - raise NotImplementedError + raise NotImplementedError def set_low_power_mode(self, port_num, lpmode): - raise NotImplementedError + raise NotImplementedError def reset(self, port_num): - raise NotImplementedError + raise NotImplementedError def get_transceiver_change_event(self): raise NotImplementedError diff --git a/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-dx010.init b/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-dx010.init index 0cef69ef5b78..9ea023128423 100644 --- a/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-dx010.init +++ b/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-dx010.init @@ -56,11 +56,11 @@ start) echo 24lc64t 0x50 > /sys/bus/i2c/devices/i2c-12/new_device # Attach temperature sensors - echo dx010_lm75b 0x48 > /sys/bus/i2c/devices/i2c-5/new_device - echo dx010_lm75b 0x49 > /sys/bus/i2c/devices/i2c-6/new_device - echo dx010_lm75b 0x4a > /sys/bus/i2c/devices/i2c-7/new_device - echo dx010_lm75b 0x48 > /sys/bus/i2c/devices/i2c-14/new_device - echo dx010_lm75b 0x4e > /sys/bus/i2c/devices/i2c-15/new_device + echo lm75b 0x48 > /sys/bus/i2c/devices/i2c-5/new_device + echo lm75b 0x49 > /sys/bus/i2c/devices/i2c-6/new_device + echo lm75b 0x4a > /sys/bus/i2c/devices/i2c-7/new_device + echo lm75b 0x48 > /sys/bus/i2c/devices/i2c-14/new_device + echo lm75b 0x4e > /sys/bus/i2c/devices/i2c-15/new_device # Attach fans echo emc2305 0x2e > /sys/bus/i2c/devices/i2c-13/new_device diff --git a/platform/broadcom/sonic-platform-modules-cel/dx010/modules/lm75.c b/platform/broadcom/sonic-platform-modules-cel/dx010/modules/lm75.c deleted file mode 100644 index a83745212bbf..000000000000 --- a/platform/broadcom/sonic-platform-modules-cel/dx010/modules/lm75.c +++ /dev/null @@ -1,553 +0,0 @@ -/* - * lm75.c - Part of lm_sensors, Linux kernel modules for hardware - * monitoring - * Copyright (c) 1998, 1999 Frodo Looijaard - * - * 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., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "lm75.h" - - -/* - * This driver handles the LM75 and compatible digital temperature sensors. - */ - -enum lm75_type { /* keep sorted in alphabetical order */ - adt75, - ds1775, - ds75, - ds7505, - g751, - lm75, - lm75a, - lm75b, - max6625, - max6626, - mcp980x, - stds75, - tcn75, - tmp100, - tmp101, - tmp105, - tmp112, - tmp175, - tmp275, - tmp75, -}; - -/* Addresses scanned */ -static const unsigned short normal_i2c[] = { 0x48, 0x49, 0x4a, 0x4b, 0x4c, - 0x4d, 0x4e, 0x4f, I2C_CLIENT_END }; - - -/* The LM75 registers */ -#define LM75_REG_CONF 0x01 -static const u8 LM75_REG_TEMP[3] = { - 0x00, /* input */ - 0x03, /* max */ - 0x02, /* hyst */ -}; - -/* Each client has this additional data */ -struct lm75_data { - struct i2c_client *client; - struct device *hwmon_dev; - struct thermal_zone_device *tz; - struct mutex update_lock; - u8 orig_conf; - u8 resolution; /* In bits, between 9 and 12 */ - u8 resolution_limits; - char valid; /* !=0 if registers are valid */ - unsigned long last_updated; /* In jiffies */ - unsigned long sample_time; /* In jiffies */ - s16 temp[3]; /* Register values, - 0 = input - 1 = max - 2 = hyst */ -}; - -static int lm75_read_value(struct i2c_client *client, u8 reg); -static int lm75_write_value(struct i2c_client *client, u8 reg, u16 value); -static struct lm75_data *lm75_update_device(struct device *dev); - - -/*-----------------------------------------------------------------------*/ - -static inline long lm75_reg_to_mc(s16 temp, u8 resolution) -{ - return ((temp >> (16 - resolution)) * 1000) >> (resolution - 8); -} - -/* sysfs attributes for hwmon */ - -static int lm75_read_temp(void *dev, long *temp) -{ - struct lm75_data *data = lm75_update_device(dev); - - if (IS_ERR(data)) - return PTR_ERR(data); - - *temp = lm75_reg_to_mc(data->temp[0], data->resolution); - - return 0; -} - -static ssize_t show_temp(struct device *dev, struct device_attribute *da, - char *buf) -{ - struct sensor_device_attribute *attr = to_sensor_dev_attr(da); - struct lm75_data *data = lm75_update_device(dev); - - if (IS_ERR(data)) - return PTR_ERR(data); - - return sprintf(buf, "%ld\n", lm75_reg_to_mc(data->temp[attr->index], - data->resolution)); -} - -static ssize_t set_temp(struct device *dev, struct device_attribute *da, - const char *buf, size_t count) -{ - struct sensor_device_attribute *attr = to_sensor_dev_attr(da); - struct lm75_data *data = dev_get_drvdata(dev); - struct i2c_client *client = data->client; - int nr = attr->index; - long temp; - int error; - u8 resolution; - - error = kstrtol(buf, 10, &temp); - if (error) - return error; - - /* - * Resolution of limit registers is assumed to be the same as the - * temperature input register resolution unless given explicitly. - */ - if (attr->index && data->resolution_limits) - resolution = data->resolution_limits; - else - resolution = data->resolution; - - mutex_lock(&data->update_lock); - temp = clamp_val(temp, LM75_TEMP_MIN, LM75_TEMP_MAX); - data->temp[nr] = DIV_ROUND_CLOSEST(temp << (resolution - 8), - 1000) << (16 - resolution); - lm75_write_value(client, LM75_REG_TEMP[nr], data->temp[nr]); - mutex_unlock(&data->update_lock); - return count; -} - -static SENSOR_DEVICE_ATTR(temp1_max, S_IWUSR | S_IRUGO, - show_temp, set_temp, 1); -static SENSOR_DEVICE_ATTR(temp1_max_hyst, S_IWUSR | S_IRUGO, - show_temp, set_temp, 2); -static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, show_temp, NULL, 0); - -static struct attribute *lm75_attrs[] = { - &sensor_dev_attr_temp1_input.dev_attr.attr, - &sensor_dev_attr_temp1_max.dev_attr.attr, - &sensor_dev_attr_temp1_max_hyst.dev_attr.attr, - - NULL -}; -ATTRIBUTE_GROUPS(lm75); - -/*-----------------------------------------------------------------------*/ - -/* device probe and removal */ - -static int -lm75_probe(struct i2c_client *client, const struct i2c_device_id *id) -{ - struct device *dev = &client->dev; - struct lm75_data *data; - int status; - u8 set_mask, clr_mask; - int new; - enum lm75_type kind = id->driver_data; - - if (!i2c_check_functionality(client->adapter, - I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA)) - return -EIO; - - data = devm_kzalloc(dev, sizeof(struct lm75_data), GFP_KERNEL); - if (!data) - return -ENOMEM; - - data->client = client; - i2c_set_clientdata(client, data); - mutex_init(&data->update_lock); - - /* Set to LM75 resolution (9 bits, 1/2 degree C) and range. - * Then tweak to be more precise when appropriate. - */ - set_mask = 0; - clr_mask = LM75_SHUTDOWN; /* continuous conversions */ - - switch (kind) { - case adt75: - clr_mask |= 1 << 5; /* not one-shot mode */ - data->resolution = 12; - data->sample_time = HZ / 8; - break; - case ds1775: - case ds75: - case stds75: - clr_mask |= 3 << 5; - set_mask |= 2 << 5; /* 11-bit mode */ - data->resolution = 11; - data->sample_time = HZ; - break; - case ds7505: - set_mask |= 3 << 5; /* 12-bit mode */ - data->resolution = 12; - data->sample_time = HZ / 4; - break; - case g751: - case lm75: - case lm75a: - data->resolution = 9; - data->sample_time = HZ / 2; - break; - case lm75b: - data->resolution = 11; - data->sample_time = HZ / 4; - break; - case max6625: - data->resolution = 9; - data->sample_time = HZ / 4; - break; - case max6626: - data->resolution = 12; - data->resolution_limits = 9; - data->sample_time = HZ / 4; - break; - case tcn75: - data->resolution = 9; - data->sample_time = HZ / 8; - break; - case mcp980x: - data->resolution_limits = 9; - /* fall through */ - case tmp100: - case tmp101: - set_mask |= 3 << 5; /* 12-bit mode */ - data->resolution = 12; - data->sample_time = HZ; - clr_mask |= 1 << 7; /* not one-shot mode */ - break; - case tmp112: - set_mask |= 3 << 5; /* 12-bit mode */ - clr_mask |= 1 << 7; /* not one-shot mode */ - data->resolution = 12; - data->sample_time = HZ / 4; - break; - case tmp105: - case tmp175: - case tmp275: - case tmp75: - set_mask |= 3 << 5; /* 12-bit mode */ - clr_mask |= 1 << 7; /* not one-shot mode */ - data->resolution = 12; - data->sample_time = HZ / 2; - break; - } - - /* configure as specified */ - status = lm75_read_value(client, LM75_REG_CONF); - if (status < 0) { - dev_dbg(dev, "Can't read config? %d\n", status); - return status; - } - data->orig_conf = status; - new = status & ~clr_mask; - new |= set_mask; - if (status != new) - lm75_write_value(client, LM75_REG_CONF, new); - dev_dbg(dev, "Config %02x\n", new); - - data->hwmon_dev = hwmon_device_register_with_groups(dev, client->name, - data, lm75_groups); - if (IS_ERR(data->hwmon_dev)) - return PTR_ERR(data->hwmon_dev); - - data->tz = thermal_zone_of_sensor_register(data->hwmon_dev, - 0, - data->hwmon_dev, - lm75_read_temp, NULL); - if (IS_ERR(data->tz)) - data->tz = NULL; - - dev_info(dev, "%s: sensor '%s'\n", - dev_name(data->hwmon_dev), client->name); - - return 0; -} - -static int lm75_remove(struct i2c_client *client) -{ - struct lm75_data *data = i2c_get_clientdata(client); - - thermal_zone_of_sensor_unregister(data->hwmon_dev, data->tz); - hwmon_device_unregister(data->hwmon_dev); - lm75_write_value(client, LM75_REG_CONF, data->orig_conf); - return 0; -} - -static const struct i2c_device_id lm75_ids[] = { - { "adt75", adt75, }, - { "ds1775", ds1775, }, - { "ds75", ds75, }, - { "ds7505", ds7505, }, - { "g751", g751, }, - { "lm75", lm75, }, - { "lm75a", lm75a, }, - { "dx010_lm75b", lm75b, }, - { "max6625", max6625, }, - { "max6626", max6626, }, - { "mcp980x", mcp980x, }, - { "stds75", stds75, }, - { "tcn75", tcn75, }, - { "tmp100", tmp100, }, - { "tmp101", tmp101, }, - { "tmp105", tmp105, }, - { "tmp112", tmp112, }, - { "tmp175", tmp175, }, - { "tmp275", tmp275, }, - { "tmp75", tmp75, }, - { /* LIST END */ } -}; -MODULE_DEVICE_TABLE(i2c, lm75_ids); - -#define LM75A_ID 0xA1 - -/* Return 0 if detection is successful, -ENODEV otherwise */ -static int lm75_detect(struct i2c_client *new_client, - struct i2c_board_info *info) -{ - struct i2c_adapter *adapter = new_client->adapter; - int i; - int conf, hyst, os; - bool is_lm75a = 0; - - if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA | - I2C_FUNC_SMBUS_WORD_DATA)) - return -ENODEV; - - /* - * Now, we do the remaining detection. There is no identification- - * dedicated register so we have to rely on several tricks: - * unused bits, registers cycling over 8-address boundaries, - * addresses 0x04-0x07 returning the last read value. - * The cycling+unused addresses combination is not tested, - * since it would significantly slow the detection down and would - * hardly add any value. - * - * The National Semiconductor LM75A is different than earlier - * LM75s. It has an ID byte of 0xaX (where X is the chip - * revision, with 1 being the only revision in existence) in - * register 7, and unused registers return 0xff rather than the - * last read value. - * - * Note that this function only detects the original National - * Semiconductor LM75 and the LM75A. Clones from other vendors - * aren't detected, on purpose, because they are typically never - * found on PC hardware. They are found on embedded designs where - * they can be instantiated explicitly so detection is not needed. - * The absence of identification registers on all these clones - * would make their exhaustive detection very difficult and weak, - * and odds are that the driver would bind to unsupported devices. - */ - - /* Unused bits */ - conf = i2c_smbus_read_byte_data(new_client, 1); - if (conf & 0xe0) - return -ENODEV; - - /* First check for LM75A */ - if (i2c_smbus_read_byte_data(new_client, 7) == LM75A_ID) { - /* LM75A returns 0xff on unused registers so - just to be sure we check for that too. */ - if (i2c_smbus_read_byte_data(new_client, 4) != 0xff - || i2c_smbus_read_byte_data(new_client, 5) != 0xff - || i2c_smbus_read_byte_data(new_client, 6) != 0xff) - return -ENODEV; - is_lm75a = 1; - hyst = i2c_smbus_read_byte_data(new_client, 2); - os = i2c_smbus_read_byte_data(new_client, 3); - } else { /* Traditional style LM75 detection */ - /* Unused addresses */ - hyst = i2c_smbus_read_byte_data(new_client, 2); - if (i2c_smbus_read_byte_data(new_client, 4) != hyst - || i2c_smbus_read_byte_data(new_client, 5) != hyst - || i2c_smbus_read_byte_data(new_client, 6) != hyst - || i2c_smbus_read_byte_data(new_client, 7) != hyst) - return -ENODEV; - os = i2c_smbus_read_byte_data(new_client, 3); - if (i2c_smbus_read_byte_data(new_client, 4) != os - || i2c_smbus_read_byte_data(new_client, 5) != os - || i2c_smbus_read_byte_data(new_client, 6) != os - || i2c_smbus_read_byte_data(new_client, 7) != os) - return -ENODEV; - } - - /* Addresses cycling */ - for (i = 8; i <= 248; i += 40) { - if (i2c_smbus_read_byte_data(new_client, i + 1) != conf - || i2c_smbus_read_byte_data(new_client, i + 2) != hyst - || i2c_smbus_read_byte_data(new_client, i + 3) != os) - return -ENODEV; - if (is_lm75a && i2c_smbus_read_byte_data(new_client, i + 7) - != LM75A_ID) - return -ENODEV; - } - - strlcpy(info->type, is_lm75a ? "lm75a" : "lm75", I2C_NAME_SIZE); - - return 0; -} - -#ifdef CONFIG_PM -static int lm75_suspend(struct device *dev) -{ - int status; - struct i2c_client *client = to_i2c_client(dev); - status = lm75_read_value(client, LM75_REG_CONF); - if (status < 0) { - dev_dbg(&client->dev, "Can't read config? %d\n", status); - return status; - } - status = status | LM75_SHUTDOWN; - lm75_write_value(client, LM75_REG_CONF, status); - return 0; -} - -static int lm75_resume(struct device *dev) -{ - int status; - struct i2c_client *client = to_i2c_client(dev); - status = lm75_read_value(client, LM75_REG_CONF); - if (status < 0) { - dev_dbg(&client->dev, "Can't read config? %d\n", status); - return status; - } - status = status & ~LM75_SHUTDOWN; - lm75_write_value(client, LM75_REG_CONF, status); - return 0; -} - -static const struct dev_pm_ops lm75_dev_pm_ops = { - .suspend = lm75_suspend, - .resume = lm75_resume, -}; -#define LM75_DEV_PM_OPS (&lm75_dev_pm_ops) -#else -#define LM75_DEV_PM_OPS NULL -#endif /* CONFIG_PM */ - -static struct i2c_driver lm75_driver = { - .class = I2C_CLASS_HWMON, - .driver = { - .name = "dx010_lm75", - .pm = LM75_DEV_PM_OPS, - }, - .probe = lm75_probe, - .remove = lm75_remove, - .id_table = lm75_ids, -/* - .detect = lm75_detect, - .address_list = normal_i2c, -*/ -}; - -/*-----------------------------------------------------------------------*/ - -/* register access */ - -/* - * All registers are word-sized, except for the configuration register. - * LM75 uses a high-byte first convention, which is exactly opposite to - * the SMBus standard. - */ -static int lm75_read_value(struct i2c_client *client, u8 reg) -{ - if (reg == LM75_REG_CONF) - return i2c_smbus_read_byte_data(client, reg); - else - return i2c_smbus_read_word_swapped(client, reg); -} - -static int lm75_write_value(struct i2c_client *client, u8 reg, u16 value) -{ - if (reg == LM75_REG_CONF) - return i2c_smbus_write_byte_data(client, reg, value); - else - return i2c_smbus_write_word_swapped(client, reg, value); -} - -static struct lm75_data *lm75_update_device(struct device *dev) -{ - struct lm75_data *data = dev_get_drvdata(dev); - struct i2c_client *client = data->client; - struct lm75_data *ret = data; - - mutex_lock(&data->update_lock); - - if (time_after(jiffies, data->last_updated + data->sample_time) - || !data->valid) { - int i; - dev_dbg(&client->dev, "Starting lm75 update\n"); - - for (i = 0; i < ARRAY_SIZE(data->temp); i++) { - int status; - - status = lm75_read_value(client, LM75_REG_TEMP[i]); - if (unlikely(status < 0)) { - dev_dbg(dev, - "LM75: Failed to read value: reg %d, error %d\n", - LM75_REG_TEMP[i], status); - ret = ERR_PTR(status); - data->valid = 0; - goto abort; - } - data->temp[i] = status; - } - data->last_updated = jiffies; - data->valid = 1; - } - -abort: - mutex_unlock(&data->update_lock); - return ret; -} - -module_i2c_driver(lm75_driver); - -MODULE_AUTHOR("Frodo Looijaard "); -MODULE_DESCRIPTION("LM75 driver"); -MODULE_LICENSE("GPL"); diff --git a/platform/broadcom/sonic-platform-modules-cel/dx010/modules/lm75.h b/platform/broadcom/sonic-platform-modules-cel/dx010/modules/lm75.h deleted file mode 100644 index 5cde94e56f17..000000000000 --- a/platform/broadcom/sonic-platform-modules-cel/dx010/modules/lm75.h +++ /dev/null @@ -1,49 +0,0 @@ -/* - lm75.h - Part of lm_sensors, Linux kernel modules for hardware - monitoring - Copyright (c) 2003 Mark M. Hoffman - - 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., 675 Mass Ave, Cambridge, MA 02139, USA. -*/ - -/* - This file contains common code for encoding/decoding LM75 type - temperature readings, which are emulated by many of the chips - we support. As the user is unlikely to load more than one driver - which contains this code, we don't worry about the wasted space. -*/ - -#include - -/* straight from the datasheet */ -#define LM75_TEMP_MIN (-55000) -#define LM75_TEMP_MAX 125000 -#define LM75_SHUTDOWN 0x01 - -/* TEMP: 0.001C/bit (-55C to +125C) - REG: (0.5C/bit, two's complement) << 7 */ -static inline u16 LM75_TEMP_TO_REG(long temp) -{ - int ntemp = clamp_val(temp, LM75_TEMP_MIN, LM75_TEMP_MAX); - ntemp += (ntemp < 0 ? -250 : 250); - return (u16)((ntemp / 500) << 7); -} - -static inline int LM75_TEMP_FROM_REG(u16 reg) -{ - /* use integer division instead of equivalent right shift to - guarantee arithmetic shift and preserve the sign */ - return ((s16)reg / 128) * 500; -} diff --git a/platform/broadcom/sonic-platform-modules-cel/haliburton/tools/lpc_cpld_x64_64 b/platform/broadcom/sonic-platform-modules-cel/haliburton/tools/lpc_cpld_x64_64 deleted file mode 100755 index 6d356039be9c4dc9cf2e7d27f3431f286db1995b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 13465 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 Tv9{$Hlzztv+xQy Date: Wed, 22 Aug 2018 15:13:36 +0700 Subject: [PATCH 10/18] Fixed Makefile --- .../broadcom/sonic-platform-modules-cel/dx010/modules/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/broadcom/sonic-platform-modules-cel/dx010/modules/Makefile b/platform/broadcom/sonic-platform-modules-cel/dx010/modules/Makefile index b6cd0f60bb6e..8bddf38789a5 100644 --- a/platform/broadcom/sonic-platform-modules-cel/dx010/modules/Makefile +++ b/platform/broadcom/sonic-platform-modules-cel/dx010/modules/Makefile @@ -1 +1 @@ -obj-m := dx010_cpld.o mc24lc64t.o emc2305.o dx010_wdt.o leds-dx010.o lm75.o dx010-fan-led.o \ No newline at end of file +obj-m := dx010_cpld.o mc24lc64t.o emc2305.o dx010_wdt.o leds-dx010.o dx010-fan-led.o \ No newline at end of file From 280e1a09c699d0c6513cd19153cd1e5a59b5bfd2 Mon Sep 17 00:00:00 2001 From: Pradchaya P Date: Wed, 22 Aug 2018 15:23:41 +0700 Subject: [PATCH 11/18] export fan-leds gpio to sysfs. --- .../dx010/modules/Makefile | 2 +- .../modules/{dx010-fan-led.c => dx010-gpio.c} | 90 +++++-------------- 2 files changed, 25 insertions(+), 67 deletions(-) rename platform/broadcom/sonic-platform-modules-cel/dx010/modules/{dx010-fan-led.c => dx010-gpio.c} (62%) diff --git a/platform/broadcom/sonic-platform-modules-cel/dx010/modules/Makefile b/platform/broadcom/sonic-platform-modules-cel/dx010/modules/Makefile index b6cd0f60bb6e..ae427f2879c4 100644 --- a/platform/broadcom/sonic-platform-modules-cel/dx010/modules/Makefile +++ b/platform/broadcom/sonic-platform-modules-cel/dx010/modules/Makefile @@ -1 +1 @@ -obj-m := dx010_cpld.o mc24lc64t.o emc2305.o dx010_wdt.o leds-dx010.o lm75.o dx010-fan-led.o \ No newline at end of file +obj-m := dx010_cpld.o mc24lc64t.o emc2305.o dx010_wdt.o leds-dx010.o lm75.o dx010-gpio.o \ No newline at end of file diff --git a/platform/broadcom/sonic-platform-modules-cel/dx010/modules/dx010-fan-led.c b/platform/broadcom/sonic-platform-modules-cel/dx010/modules/dx010-gpio.c similarity index 62% rename from platform/broadcom/sonic-platform-modules-cel/dx010/modules/dx010-fan-led.c rename to platform/broadcom/sonic-platform-modules-cel/dx010/modules/dx010-gpio.c index c02bc37aedd7..9a2f2adc350f 100644 --- a/platform/broadcom/sonic-platform-modules-cel/dx010/modules/dx010-fan-led.c +++ b/platform/broadcom/sonic-platform-modules-cel/dx010/modules/dx010-gpio.c @@ -1,5 +1,5 @@ /* - * dx010-fan-led.c - Kernel module for Seastone DX010 fan LEDs + * dx010-gpio.c - Kernel module for Seastone DX010 gpios. * * Copyright (C) 2018 Celestica Corp. * @@ -19,13 +19,12 @@ */ #include -#include #include #include #include #include -#define MODULE_NAME "dx010-fan-led" +#define MODULE_NAME "dx010-gpio" #define NUM_FAN 5 #define NUM_PSU 2 @@ -46,9 +45,6 @@ struct psu_gpio { unsigned char powerok_pin; }; -static int count; -static struct workqueue_struct *dx010_fan_led_workqueue; -static struct delayed_work fan_update; static struct gpio_chip *gc; static struct fan_gpio fan_gpios[NUM_FAN] = { {.presence_pin = 10, @@ -100,6 +96,9 @@ static void init_fan_gpio(void){ gpio_direction_input(gc->base+fan_gpios[index].presence_pin); gpio_direction_output(gc->base+fan_gpios[index].red_led_pin, 1); gpio_direction_output(gc->base+fan_gpios[index].yel_led_pin, 0); + gpio_export(gc->base+fan_gpios[index].presence_pin,0); + gpio_export(gc->base+fan_gpios[index].red_led_pin,0); + gpio_export(gc->base+fan_gpios[index].yel_led_pin,0); } } @@ -115,51 +114,12 @@ static void init_psu_gpio(void){ } } -static void update_led(void){ - int index; - int presence; - int delay_ms; - struct gpio_chip *find; - - /* Check for gpio chip exist every CHECK_MS */ - if(count <= 0){ - find = gpiochip_find("pca9505", chip_match_name); - if(find){ - /* Skip check routine, Update the leds */ - if(gc != find){ - gc = find; - init_fan_gpio(); - init_psu_gpio(); - } - count = CHECK_COUNTER; - delay_ms = UPDATE_MS; - }else{ - /* Put the check routine to the queue */ - delay_ms = CHECK_MS; - } - }else{ - for (index=0; index < NUM_FAN; index++){ - presence = !gpio_get_value_cansleep(gc->base+fan_gpios[index].presence_pin); - if( presence != fan_gpios[index].prs ){ - if( presence ){ - gpio_set_value_cansleep(gc->base+fan_gpios[index].red_led_pin, 1); - gpio_set_value_cansleep(gc->base+fan_gpios[index].yel_led_pin, 0); - }else{ - gpio_set_value_cansleep(gc->base+fan_gpios[index].red_led_pin, 0); - gpio_set_value_cansleep(gc->base+fan_gpios[index].yel_led_pin, 1); - } - } - fan_gpios[index].prs = presence; - } - count--; - } - queue_delayed_work(dx010_fan_led_workqueue, &fan_update, - msecs_to_jiffies(delay_ms)); -} - static void deinit_fan_gpio(void){ int index; for( index=0; index < NUM_PSU; index++){ + gpio_unexport(gc->base+fan_gpios[index].presence_pin); + gpio_unexport(gc->base+fan_gpios[index].red_led_pin); + gpio_unexport(gc->base+fan_gpios[index].yel_led_pin); gpio_free(gc->base+fan_gpios[index].presence_pin); gpio_free(gc->base+fan_gpios[index].red_led_pin); gpio_free(gc->base+fan_gpios[index].yel_led_pin); @@ -176,34 +136,32 @@ static void deinit_psu_gpio(void){ } } -static int __init dx010_fan_led_init(void){ - count = 0; - gc = NULL; - dx010_fan_led_workqueue = create_singlethread_workqueue(MODULE_NAME); - if (IS_ERR(dx010_fan_led_workqueue)) { - printk(KERN_INFO "failed to inittialize workqueue\n"); - return PTR_ERR(dx010_fan_led_workqueue); - } +static int __init dx010_gpio_init(void){ + - INIT_DELAYED_WORK(&fan_update, update_led); - queue_delayed_work(dx010_fan_led_workqueue, &fan_update, - msecs_to_jiffies(UPDATE_MS)); + struct gpio_chip *find; + gc = NULL; + find = gpiochip_find("pca9505", chip_match_name); + if(!find){ + printk(KERN_ERR "DX010 GPIO Chip not found!"); + return -ENODEV; + } + gc = find; + init_fan_gpio(); + init_psu_gpio(); return 0; } -static void __exit dx010_fan_led_exit(void){ - cancel_delayed_work_sync(&fan_update); - destroy_workqueue(dx010_fan_led_workqueue); +static void __exit dx010_gpio_exit(void){ deinit_fan_gpio(); deinit_psu_gpio(); - dx010_fan_led_workqueue = NULL; gc = NULL; } -module_init(dx010_fan_led_init); -module_exit(dx010_fan_led_exit); +module_init(dx010_gpio_init); +module_exit(dx010_gpio_exit); MODULE_LICENSE("GPL"); MODULE_AUTHOR("Celestica Inc."); -MODULE_DESCRIPTION("DX010 fan led control"); \ No newline at end of file +MODULE_DESCRIPTION("DX010 gpio driver"); \ No newline at end of file From 6d9a4709433d6477eeb06634d96850028e901b3f Mon Sep 17 00:00:00 2001 From: Wirut Getbamrung Date: Wed, 22 Aug 2018 15:46:45 +0700 Subject: [PATCH 12/18] Fix install file --- .../debian/platform-modules-haliburton.install | 1 - 1 file changed, 1 deletion(-) diff --git a/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-haliburton.install b/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-haliburton.install index 1a30b1eb554a..93b2eed633d1 100644 --- a/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-haliburton.install +++ b/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-haliburton.install @@ -1,3 +1,2 @@ haliburton/cfg/haliburton-modules.conf etc/modules-load.d -haliburton/tools/lpc_cpld_x64_64 usr/local/etc haliburton/systemd/platform-modules-haliburton.service lib/systemd/system From 5bc787805ab85a7816868988dcf8c5d0be2826c8 Mon Sep 17 00:00:00 2001 From: Wirut Getbamrung Date: Wed, 22 Aug 2018 17:52:48 +0700 Subject: [PATCH 13/18] Add dx010 service --- .../debian/platform-modules-dx010.install | 1 + .../debian/platform-modules-haliburton.init | 2 -- .../systemd/platform-modules-dx010.service | 14 ++++++++++++++ 3 files changed, 15 insertions(+), 2 deletions(-) create mode 100644 platform/broadcom/sonic-platform-modules-cel/haliburton/systemd/platform-modules-dx010.service diff --git a/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-dx010.install b/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-dx010.install index 329b584dc427..65f1b493202d 100644 --- a/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-dx010.install +++ b/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-dx010.install @@ -1,2 +1,3 @@ dx010/scripts/dx010_check_qsfp.sh usr/local/bin dx010/cfg/dx010-modules.conf etc/modules-load.d +dx010/systemd/platform-modules-dx010.service lib/systemd/system \ No newline at end of file diff --git a/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-haliburton.init b/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-haliburton.init index d68d227ec708..0e0e94d680c5 100644 --- a/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-haliburton.init +++ b/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-haliburton.init @@ -17,8 +17,6 @@ start) depmod -a modprobe smc - - (cd /usr/local/etc && ./lpc_cpld_x64_64 blu w 0x222 0x1f) found=0 for devnum in 0 1; do diff --git a/platform/broadcom/sonic-platform-modules-cel/haliburton/systemd/platform-modules-dx010.service b/platform/broadcom/sonic-platform-modules-cel/haliburton/systemd/platform-modules-dx010.service new file mode 100644 index 000000000000..0e04aca3d8d5 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-cel/haliburton/systemd/platform-modules-dx010.service @@ -0,0 +1,14 @@ + +[Unit] +Description=Celestica dx010 platform modules +After=local-fs.target +Before=pmon.service + +[Service] +Type=oneshot +ExecStart=-/etc/init.d/platform-modules-dx010 start +ExecStop=-/etc/init.d/platform-modules-dx010 stop +RemainAfterExit=yes + +[Install] +WantedBy=multi-user.target \ No newline at end of file From fb5c248d9a792ae692382adb8db0be66b8bd5164 Mon Sep 17 00:00:00 2001 From: Wirut Getbamrung Date: Wed, 22 Aug 2018 17:58:42 +0700 Subject: [PATCH 14/18] Add dx010 service --- .../{haliburton => dx010}/systemd/platform-modules-dx010.service | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename platform/broadcom/sonic-platform-modules-cel/{haliburton => dx010}/systemd/platform-modules-dx010.service (100%) diff --git a/platform/broadcom/sonic-platform-modules-cel/haliburton/systemd/platform-modules-dx010.service b/platform/broadcom/sonic-platform-modules-cel/dx010/systemd/platform-modules-dx010.service similarity index 100% rename from platform/broadcom/sonic-platform-modules-cel/haliburton/systemd/platform-modules-dx010.service rename to platform/broadcom/sonic-platform-modules-cel/dx010/systemd/platform-modules-dx010.service From 8bd9645ffddfa221023d0e7a7f845ead657535b2 Mon Sep 17 00:00:00 2001 From: Wirut Getbamrung Date: Thu, 23 Aug 2018 11:23:10 +0700 Subject: [PATCH 15/18] Add port reset in driver --- .../haliburton/modules/smc.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) 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 5df4c698b8b6..82abc9e8ea1f 100644 --- a/platform/broadcom/sonic-platform-modules-cel/haliburton/modules/smc.c +++ b/platform/broadcom/sonic-platform-modules-cel/haliburton/modules/smc.c @@ -37,6 +37,17 @@ #define SCRATCH 0x0201 #define BROAD_ID 0x0202 +/* SEPERATE RESET + * [7:5] RESERVED + * [4] RESET PCIE + * [3] RESET USBHUB + * [2] RESET B50282 + * [1] RESET PCA9548 + * [0] RESET BCM54616 + * 1: not reset, 0: reset + */ +#define SPR_RESET 0x0222 + /* PSU STATUS * [7] PSUR_ACOK * [6] PSUR_PWOK @@ -709,6 +720,9 @@ static int cpld_drv_probe(struct platform_device *pdev) for ( i = 0; i < 4; i++) { cpld_data->sfp_devices[i] = sfp_init(i); } + + // Clear all reset signals + outb(0xFF, SPR_RESET); return 0; } From 9515bb6f7bbc7479523d4b5e9231149dfa862196 Mon Sep 17 00:00:00 2001 From: Wirut Getbamrung Date: Thu, 23 Aug 2018 14:17:58 +0700 Subject: [PATCH 16/18] Fixed invalid path --- .../debian/platform-modules-dx010.postinst | 2 ++ .../debian/platform-modules-haliburton.postinst | 1 - 2 files changed, 2 insertions(+), 1 deletion(-) create mode 100644 platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-dx010.postinst diff --git a/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-dx010.postinst b/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-dx010.postinst new file mode 100644 index 000000000000..6a81bb432462 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-dx010.postinst @@ -0,0 +1,2 @@ +systemctl enable platform-modules-dx010.service +systemctl start platform-modules-dx010.service diff --git a/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-haliburton.postinst b/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-haliburton.postinst index 0692a0c12752..0713a7a09312 100644 --- a/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-haliburton.postinst +++ b/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-haliburton.postinst @@ -1,3 +1,2 @@ -chmod +x /usr/local/etc/lpc_cpld_x64_64 systemctl enable platform-modules-haliburton.service systemctl start platform-modules-haliburton.service From f84b14c30d6b186bac096808a13808727af8354f Mon Sep 17 00:00:00 2001 From: Wirut Getbamrung Date: Thu, 23 Aug 2018 15:23:13 +0700 Subject: [PATCH 17/18] Revert dx010 gpio --- .../dx010/modules/Makefile | 2 +- .../dx010/modules/dx010-gpio.c | 167 ------------------ 2 files changed, 1 insertion(+), 168 deletions(-) delete mode 100644 platform/broadcom/sonic-platform-modules-cel/dx010/modules/dx010-gpio.c diff --git a/platform/broadcom/sonic-platform-modules-cel/dx010/modules/Makefile b/platform/broadcom/sonic-platform-modules-cel/dx010/modules/Makefile index 7f3be9654ae4..5c2cf0bf2d48 100644 --- a/platform/broadcom/sonic-platform-modules-cel/dx010/modules/Makefile +++ b/platform/broadcom/sonic-platform-modules-cel/dx010/modules/Makefile @@ -1 +1 @@ -obj-m := dx010_cpld.o mc24lc64t.o emc2305.o dx010_wdt.o leds-dx010.o dx010-gpio.o \ No newline at end of file +obj-m := dx010_cpld.o mc24lc64t.o emc2305.o dx010_wdt.o leds-dx010.o diff --git a/platform/broadcom/sonic-platform-modules-cel/dx010/modules/dx010-gpio.c b/platform/broadcom/sonic-platform-modules-cel/dx010/modules/dx010-gpio.c deleted file mode 100644 index 9a2f2adc350f..000000000000 --- a/platform/broadcom/sonic-platform-modules-cel/dx010/modules/dx010-gpio.c +++ /dev/null @@ -1,167 +0,0 @@ -/* - * dx010-gpio.c - Kernel module for Seastone DX010 gpios. - * - * Copyright (C) 2018 Celestica Corp. - * - * 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 - -#define MODULE_NAME "dx010-gpio" - -#define NUM_FAN 5 -#define NUM_PSU 2 -#define UPDATE_MS 100 -#define CHECK_MS 1000 -#define CHECK_COUNTER CHECK_MS/UPDATE_MS - - -struct fan_gpio { - unsigned char presence_pin; - unsigned char red_led_pin; - unsigned char yel_led_pin; - int prs; -}; - -struct psu_gpio { - unsigned char absence_pin; - unsigned char powerok_pin; -}; - -static struct gpio_chip *gc; -static struct fan_gpio fan_gpios[NUM_FAN] = { - {.presence_pin = 10, - .red_led_pin = 29, - .yel_led_pin = 30, - .prs = 1 - }, - {.presence_pin = 11, - .red_led_pin = 31, - .yel_led_pin = 32, - .prs = 1 - }, - {.presence_pin = 12, - .red_led_pin = 33, - .yel_led_pin = 34, - .prs = 1 - }, - {.presence_pin = 13, - .red_led_pin = 35, - .yel_led_pin = 36, - .prs = 1 - }, - {.presence_pin = 14, - .red_led_pin = 37, - .yel_led_pin = 38, - .prs = 1 - } -}; - -static struct psu_gpio psu_gpios[NUM_PSU] = { - {.absence_pin = 27, - .powerok_pin = 22 - }, - {.absence_pin = 28, - .powerok_pin = 25, - } -}; - -static int chip_match_name(struct gpio_chip *chip, void *data){ - return !strcmp(chip->label, data); -} - -static void init_fan_gpio(void){ - int index; - for( index=0; index < NUM_FAN; index++){ - gpio_request(gc->base+fan_gpios[index].presence_pin, NULL); - gpio_request(gc->base+fan_gpios[index].red_led_pin, NULL); - gpio_request(gc->base+fan_gpios[index].yel_led_pin, NULL); - gpio_direction_input(gc->base+fan_gpios[index].presence_pin); - gpio_direction_output(gc->base+fan_gpios[index].red_led_pin, 1); - gpio_direction_output(gc->base+fan_gpios[index].yel_led_pin, 0); - gpio_export(gc->base+fan_gpios[index].presence_pin,0); - gpio_export(gc->base+fan_gpios[index].red_led_pin,0); - gpio_export(gc->base+fan_gpios[index].yel_led_pin,0); - } -} - -static void init_psu_gpio(void){ - int index; - for( index=0; index < NUM_PSU; index++){ - gpio_request(gc->base+psu_gpios[index].absence_pin, NULL); - gpio_request(gc->base+psu_gpios[index].powerok_pin, NULL); - gpio_direction_input(gc->base+psu_gpios[index].absence_pin); - gpio_direction_input(gc->base+psu_gpios[index].powerok_pin); - gpio_export(gc->base+psu_gpios[index].absence_pin,0); - gpio_export(gc->base+psu_gpios[index].powerok_pin,0); - } -} - -static void deinit_fan_gpio(void){ - int index; - for( index=0; index < NUM_PSU; index++){ - gpio_unexport(gc->base+fan_gpios[index].presence_pin); - gpio_unexport(gc->base+fan_gpios[index].red_led_pin); - gpio_unexport(gc->base+fan_gpios[index].yel_led_pin); - gpio_free(gc->base+fan_gpios[index].presence_pin); - gpio_free(gc->base+fan_gpios[index].red_led_pin); - gpio_free(gc->base+fan_gpios[index].yel_led_pin); - } -} - -static void deinit_psu_gpio(void){ - int index; - for( index=0; index < NUM_PSU; index++){ - gpio_unexport(gc->base+psu_gpios[index].absence_pin); - gpio_unexport(gc->base+psu_gpios[index].powerok_pin); - gpio_free(gc->base+psu_gpios[index].absence_pin); - gpio_free(gc->base+psu_gpios[index].powerok_pin); - } -} - -static int __init dx010_gpio_init(void){ - - - struct gpio_chip *find; - gc = NULL; - find = gpiochip_find("pca9505", chip_match_name); - if(!find){ - printk(KERN_ERR "DX010 GPIO Chip not found!"); - return -ENODEV; - } - gc = find; - init_fan_gpio(); - init_psu_gpio(); - return 0; -} - -static void __exit dx010_gpio_exit(void){ - deinit_fan_gpio(); - deinit_psu_gpio(); - gc = NULL; -} - -module_init(dx010_gpio_init); -module_exit(dx010_gpio_exit); - - -MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Celestica Inc."); -MODULE_DESCRIPTION("DX010 gpio driver"); \ No newline at end of file From 9d259ef35a684a82dff372f52d1ac09cf5e3455c Mon Sep 17 00:00:00 2001 From: Wirut Getbamrung Date: Thu, 23 Aug 2018 15:26:26 +0700 Subject: [PATCH 18/18] Move depmod from init to postinst --- .../debian/platform-modules-dx010.init | 3 +-- .../debian/platform-modules-dx010.postinst | 1 + .../debian/platform-modules-haliburton.init | 1 - .../debian/platform-modules-haliburton.postinst | 1 + 4 files changed, 3 insertions(+), 3 deletions(-) diff --git a/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-dx010.init b/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-dx010.init index 9ea023128423..a07e474e3457 100644 --- a/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-dx010.init +++ b/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-dx010.init @@ -14,8 +14,7 @@ case "$1" in start) echo -n "Setting up board... " - - depmod -a + modprobe i2c-dev modprobe i2c-mux-pca954x modprobe dx010_wdt diff --git a/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-dx010.postinst b/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-dx010.postinst index 6a81bb432462..baff704171c7 100644 --- a/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-dx010.postinst +++ b/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-dx010.postinst @@ -1,2 +1,3 @@ +depmod -a systemctl enable platform-modules-dx010.service systemctl start platform-modules-dx010.service diff --git a/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-haliburton.init b/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-haliburton.init index 0e0e94d680c5..66f1ee5529c2 100644 --- a/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-haliburton.init +++ b/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-haliburton.init @@ -15,7 +15,6 @@ case "$1" in start) echo -n "Setting up board... " - depmod -a modprobe smc found=0 diff --git a/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-haliburton.postinst b/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-haliburton.postinst index 0713a7a09312..bdc23c66d5a4 100644 --- a/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-haliburton.postinst +++ b/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-haliburton.postinst @@ -1,2 +1,3 @@ +depmod -a systemctl enable platform-modules-haliburton.service systemctl start platform-modules-haliburton.service