Update Inventec d7032q28b.

This commit is contained in:
Joe Chan
2017-10-10 15:21:47 -07:00
parent 874273c434
commit 54197c317c
11 changed files with 213 additions and 837 deletions

View File

@@ -2004,7 +2004,7 @@ CONFIG_GPIO_GENERIC_PLATFORM=y
# CONFIG_GPIO_F7188X is not set
# CONFIG_GPIO_SCH311X is not set
CONFIG_GPIO_SCH=y
# CONFIG_GPIO_ICH is not set
CONFIG_GPIO_ICH=m
# CONFIG_GPIO_VX855 is not set
# CONFIG_GPIO_LYNXPOINT is not set

View File

@@ -1,548 +0,0 @@
/*
* Intel ICH6-10, Series 5 and 6, Atom C2000 (Avoton/Rangeley) GPIO driver
*
* Copyright (C) 2010 Extreme Engineering Solutions.
*
* 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.
*/
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
#include <linux/module.h>
#include <linux/pci.h>
#include <linux/gpio.h>
#include <linux/platform_device.h>
#include <linux/mfd/lpc_ich.h>
#define DRV_NAME "gpio_ich"
/*
* GPIO register offsets in GPIO I/O space.
* Each chunk of 32 GPIOs is manipulated via its own USE_SELx, IO_SELx, and
* LVLx registers. Logic in the read/write functions takes a register and
* an absolute bit number and determines the proper register offset and bit
* number in that register. For example, to read the value of GPIO bit 50
* the code would access offset ichx_regs[2(=GPIO_LVL)][1(=50/32)],
* bit 18 (50%32).
*/
enum GPIO_REG {
GPIO_USE_SEL = 0,
GPIO_IO_SEL,
GPIO_LVL,
GPO_BLINK
};
static const u8 ichx_regs[4][3] = {
{0x00, 0x30, 0x40}, /* USE_SEL[1-3] offsets */
{0x04, 0x34, 0x44}, /* IO_SEL[1-3] offsets */
{0x0c, 0x38, 0x48}, /* LVL[1-3] offsets */
{0x18, 0x18, 0x18}, /* BLINK offset */
};
static const u8 ichx_reglen[3] = {
0x30, 0x10, 0x10,
};
static const u8 avoton_regs[4][3] = {
{0x00, 0x80, 0x00},
{0x04, 0x84, 0x00},
{0x08, 0x88, 0x00},
};
static const u8 avoton_reglen[3] = {
0x10, 0x10, 0x00,
};
#define ICHX_WRITE(val, reg, base_res) outl(val, (reg) + (base_res)->start)
#define ICHX_READ(reg, base_res) inl((reg) + (base_res)->start)
struct ichx_desc {
/* Max GPIO pins the chipset can have */
uint ngpio;
/* chipset registers */
const u8 (*regs)[3];
const u8 *reglen;
/* GPO_BLINK is available on this chipset */
bool have_blink;
/* Whether the chipset has GPIO in GPE0_STS in the PM IO region */
bool uses_gpe0;
/* USE_SEL is bogus on some chipsets, eg 3100 */
u32 use_sel_ignore[3];
/* Some chipsets have quirks, let these use their own request/get */
int (*request)(struct gpio_chip *chip, unsigned offset);
int (*get)(struct gpio_chip *chip, unsigned offset);
/*
* Some chipsets don't let reading output values on GPIO_LVL register
* this option allows driver caching written output values
*/
bool use_outlvl_cache;
};
static struct {
spinlock_t lock;
struct platform_device *dev;
struct gpio_chip chip;
struct resource *gpio_base; /* GPIO IO base */
struct resource *pm_base; /* Power Mangagment IO base */
struct ichx_desc *desc; /* Pointer to chipset-specific description */
u32 orig_gpio_ctrl; /* Orig CTRL value, used to restore on exit */
u8 use_gpio; /* Which GPIO groups are usable */
int outlvl_cache[3]; /* cached output values */
} ichx_priv;
static int modparam_gpiobase = -1; /* dynamic */
module_param_named(gpiobase, modparam_gpiobase, int, 0444);
MODULE_PARM_DESC(gpiobase, "The GPIO number base. -1 means dynamic, "
"which is the default.");
static int ichx_write_bit(int reg, unsigned nr, int val, int verify)
{
unsigned long flags;
u32 data, tmp;
int reg_nr = nr / 32;
int bit = nr & 0x1f;
int ret = 0;
spin_lock_irqsave(&ichx_priv.lock, flags);
if (reg == GPIO_LVL && ichx_priv.desc->use_outlvl_cache)
data = ichx_priv.outlvl_cache[reg_nr];
else
data = ICHX_READ(ichx_priv.desc->regs[reg][reg_nr],
ichx_priv.gpio_base);
if (val)
data |= 1 << bit;
else
data &= ~(1 << bit);
ICHX_WRITE(data, ichx_priv.desc->regs[reg][reg_nr],
ichx_priv.gpio_base);
if (reg == GPIO_LVL && ichx_priv.desc->use_outlvl_cache)
ichx_priv.outlvl_cache[reg_nr] = data;
tmp = ICHX_READ(ichx_priv.desc->regs[reg][reg_nr],
ichx_priv.gpio_base);
if (verify && data != tmp)
ret = -EPERM;
spin_unlock_irqrestore(&ichx_priv.lock, flags);
return ret;
}
static int ichx_read_bit(int reg, unsigned nr)
{
unsigned long flags;
u32 data;
int reg_nr = nr / 32;
int bit = nr & 0x1f;
spin_lock_irqsave(&ichx_priv.lock, flags);
data = ICHX_READ(ichx_priv.desc->regs[reg][reg_nr],
ichx_priv.gpio_base);
if (reg == GPIO_LVL && ichx_priv.desc->use_outlvl_cache)
data = ichx_priv.outlvl_cache[reg_nr] | data;
spin_unlock_irqrestore(&ichx_priv.lock, flags);
return data & (1 << bit) ? 1 : 0;
}
static bool ichx_gpio_check_available(struct gpio_chip *gpio, unsigned nr)
{
return !!(ichx_priv.use_gpio & (1 << (nr / 32)));
}
static int ichx_gpio_direction_input(struct gpio_chip *gpio, unsigned nr)
{
/*
* Try setting pin as an input and verify it worked since many pins
* are output-only.
*/
if (ichx_write_bit(GPIO_IO_SEL, nr, 1, 1))
return -EINVAL;
return 0;
}
static int ichx_gpio_direction_output(struct gpio_chip *gpio, unsigned nr,
int val)
{
/* Disable blink hardware which is available for GPIOs from 0 to 31. */
if (nr < 32 && ichx_priv.desc->have_blink)
ichx_write_bit(GPO_BLINK, nr, 0, 0);
/* Set GPIO output value. */
ichx_write_bit(GPIO_LVL, nr, val, 0);
/*
* Try setting pin as an output and verify it worked since many pins
* are input-only.
*/
if (ichx_write_bit(GPIO_IO_SEL, nr, 0, 1))
return -EINVAL;
return 0;
}
static int ichx_gpio_get(struct gpio_chip *chip, unsigned nr)
{
return ichx_read_bit(GPIO_LVL, nr);
}
static int ich6_gpio_get(struct gpio_chip *chip, unsigned nr)
{
unsigned long flags;
u32 data;
/*
* GPI 0 - 15 need to be read from the power management registers on
* a ICH6/3100 bridge.
*/
if (nr < 16) {
if (!ichx_priv.pm_base)
return -ENXIO;
spin_lock_irqsave(&ichx_priv.lock, flags);
/* GPI 0 - 15 are latched, write 1 to clear*/
ICHX_WRITE(1 << (16 + nr), 0, ichx_priv.pm_base);
data = ICHX_READ(0, ichx_priv.pm_base);
spin_unlock_irqrestore(&ichx_priv.lock, flags);
return (data >> 16) & (1 << nr) ? 1 : 0;
} else {
return ichx_gpio_get(chip, nr);
}
}
static int ichx_gpio_request(struct gpio_chip *chip, unsigned nr)
{
if (!ichx_gpio_check_available(chip, nr))
return -ENXIO;
/*
* Note we assume the BIOS properly set a bridge's USE value. Some
* chips (eg Intel 3100) have bogus USE values though, so first see if
* the chipset's USE value can be trusted for this specific bit.
* If it can't be trusted, assume that the pin can be used as a GPIO.
*/
if (ichx_priv.desc->use_sel_ignore[nr / 32] & (1 << (nr & 0x1f)))
return 0;
return ichx_read_bit(GPIO_USE_SEL, nr) ? 0 : -ENODEV;
}
static int ich6_gpio_request(struct gpio_chip *chip, unsigned nr)
{
/*
* Fixups for bits 16 and 17 are necessary on the Intel ICH6/3100
* bridge as they are controlled by USE register bits 0 and 1. See
* "Table 704 GPIO_USE_SEL1 register" in the i3100 datasheet for
* additional info.
*/
if (nr == 16 || nr == 17)
nr -= 16;
return ichx_gpio_request(chip, nr);
}
static void ichx_gpio_set(struct gpio_chip *chip, unsigned nr, int val)
{
ichx_write_bit(GPIO_LVL, nr, val, 0);
}
static void ichx_gpiolib_setup(struct gpio_chip *chip)
{
chip->owner = THIS_MODULE;
chip->label = DRV_NAME;
chip->dev = &ichx_priv.dev->dev;
/* Allow chip-specific overrides of request()/get() */
chip->request = ichx_priv.desc->request ?
ichx_priv.desc->request : ichx_gpio_request;
chip->get = ichx_priv.desc->get ?
ichx_priv.desc->get : ichx_gpio_get;
chip->set = ichx_gpio_set;
chip->direction_input = ichx_gpio_direction_input;
chip->direction_output = ichx_gpio_direction_output;
chip->base = modparam_gpiobase;
chip->ngpio = ichx_priv.desc->ngpio;
chip->can_sleep = false;
chip->dbg_show = NULL;
}
/* ICH6-based, 631xesb-based */
static struct ichx_desc ich6_desc = {
/* Bridges using the ICH6 controller need fixups for GPIO 0 - 17 */
.request = ich6_gpio_request,
.get = ich6_gpio_get,
/* GPIO 0-15 are read in the GPE0_STS PM register */
.uses_gpe0 = true,
.ngpio = 50,
.have_blink = true,
.regs = ichx_regs,
.reglen = ichx_reglen,
};
/* Intel 3100 */
static struct ichx_desc i3100_desc = {
/*
* Bits 16,17, 20 of USE_SEL and bit 16 of USE_SEL2 always read 0 on
* the Intel 3100. See "Table 712. GPIO Summary Table" of 3100
* Datasheet for more info.
*/
.use_sel_ignore = {0x00130000, 0x00010000, 0x0},
/* The 3100 needs fixups for GPIO 0 - 17 */
.request = ich6_gpio_request,
.get = ich6_gpio_get,
/* GPIO 0-15 are read in the GPE0_STS PM register */
.uses_gpe0 = true,
.ngpio = 50,
.regs = ichx_regs,
.reglen = ichx_reglen,
};
/* ICH7 and ICH8-based */
static struct ichx_desc ich7_desc = {
.ngpio = 50,
.have_blink = true,
.regs = ichx_regs,
.reglen = ichx_reglen,
};
/* ICH9-based */
static struct ichx_desc ich9_desc = {
.ngpio = 61,
.have_blink = true,
.regs = ichx_regs,
.reglen = ichx_reglen,
};
/* ICH10-based - Consumer/corporate versions have different amount of GPIO */
static struct ichx_desc ich10_cons_desc = {
.ngpio = 61,
.have_blink = true,
.regs = ichx_regs,
.reglen = ichx_reglen,
};
static struct ichx_desc ich10_corp_desc = {
.ngpio = 72,
.have_blink = true,
.regs = ichx_regs,
.reglen = ichx_reglen,
};
/* Intel 5 series, 6 series, 3400 series, and C200 series */
static struct ichx_desc intel5_desc = {
.ngpio = 76,
.regs = ichx_regs,
.reglen = ichx_reglen,
};
/* Avoton */
static struct ichx_desc avoton_desc = {
/* Avoton has only 59 GPIOs, but we assume the first set of register
* (Core) has 32 instead of 31 to keep gpio-ich compliance
*/
.ngpio = 60,
.regs = avoton_regs,
.reglen = avoton_reglen,
.use_outlvl_cache = true,
};
static int ichx_gpio_request_regions(struct resource *res_base,
const char *name, u8 use_gpio)
{
int i;
if (!res_base || !res_base->start || !res_base->end)
return -ENODEV;
for (i = 0; i < ARRAY_SIZE(ichx_priv.desc->regs[0]); i++) {
if (!(use_gpio & (1 << i)))
continue;
if (!request_region(
res_base->start + ichx_priv.desc->regs[0][i],
ichx_priv.desc->reglen[i], name))
goto request_err;
}
return 0;
request_err:
/* Clean up: release already requested regions, if any */
for (i--; i >= 0; i--) {
if (!(use_gpio & (1 << i)))
continue;
release_region(res_base->start + ichx_priv.desc->regs[0][i],
ichx_priv.desc->reglen[i]);
}
return -EBUSY;
}
static void ichx_gpio_release_regions(struct resource *res_base, u8 use_gpio)
{
int i;
for (i = 0; i < ARRAY_SIZE(ichx_priv.desc->regs[0]); i++) {
if (!(use_gpio & (1 << i)))
continue;
release_region(res_base->start + ichx_priv.desc->regs[0][i],
ichx_priv.desc->reglen[i]);
}
}
static int ichx_gpio_probe(struct platform_device *pdev)
{
struct resource *res_base, *res_pm;
int err;
struct lpc_ich_info *ich_info = dev_get_platdata(&pdev->dev);
if (!ich_info)
return -ENODEV;
ichx_priv.dev = pdev;
switch (ich_info->gpio_version) {
case ICH_I3100_GPIO:
ichx_priv.desc = &i3100_desc;
break;
case ICH_V5_GPIO:
ichx_priv.desc = &intel5_desc;
break;
case ICH_V6_GPIO:
ichx_priv.desc = &ich6_desc;
break;
case ICH_V7_GPIO:
ichx_priv.desc = &ich7_desc;
break;
case ICH_V9_GPIO:
ichx_priv.desc = &ich9_desc;
break;
case ICH_V10CORP_GPIO:
ichx_priv.desc = &ich10_corp_desc;
break;
case ICH_V10CONS_GPIO:
ichx_priv.desc = &ich10_cons_desc;
break;
case AVOTON_GPIO:
ichx_priv.desc = &avoton_desc;
break;
default:
return -ENODEV;
}
spin_lock_init(&ichx_priv.lock);
res_base = platform_get_resource(pdev, IORESOURCE_IO, ICH_RES_GPIO);
ichx_priv.use_gpio = ich_info->use_gpio;
err = ichx_gpio_request_regions(res_base, pdev->name,
ichx_priv.use_gpio);
if (err)
return err;
ichx_priv.gpio_base = res_base;
/*
* If necessary, determine the I/O address of ACPI/power management
* registers which are needed to read the the GPE0 register for GPI pins
* 0 - 15 on some chipsets.
*/
if (!ichx_priv.desc->uses_gpe0)
goto init;
res_pm = platform_get_resource(pdev, IORESOURCE_IO, ICH_RES_GPE0);
if (!res_pm) {
pr_warn("ACPI BAR is unavailable, GPI 0 - 15 unavailable\n");
goto init;
}
if (!request_region(res_pm->start, resource_size(res_pm),
pdev->name)) {
pr_warn("ACPI BAR is busy, GPI 0 - 15 unavailable\n");
goto init;
}
ichx_priv.pm_base = res_pm;
init:
ichx_gpiolib_setup(&ichx_priv.chip);
err = gpiochip_add(&ichx_priv.chip);
if (err) {
pr_err("Failed to register GPIOs\n");
goto add_err;
}
pr_info("GPIO from %d to %d on %s\n", ichx_priv.chip.base,
ichx_priv.chip.base + ichx_priv.chip.ngpio - 1, DRV_NAME);
return 0;
add_err:
ichx_gpio_release_regions(ichx_priv.gpio_base, ichx_priv.use_gpio);
if (ichx_priv.pm_base)
release_region(ichx_priv.pm_base->start,
resource_size(ichx_priv.pm_base));
return err;
}
static int ichx_gpio_remove(struct platform_device *pdev)
{
int err;
err = gpiochip_remove(&ichx_priv.chip);
if (err) {
dev_err(&pdev->dev, "%s failed, %d\n",
"gpiochip_remove()", err);
return err;
}
ichx_gpio_release_regions(ichx_priv.gpio_base, ichx_priv.use_gpio);
if (ichx_priv.pm_base)
release_region(ichx_priv.pm_base->start,
resource_size(ichx_priv.pm_base));
return 0;
}
static struct platform_driver ichx_gpio_driver = {
.driver = {
.owner = THIS_MODULE,
.name = DRV_NAME,
},
.probe = ichx_gpio_probe,
.remove = ichx_gpio_remove,
};
module_platform_driver(ichx_gpio_driver);
MODULE_AUTHOR("Peter Tyser <ptyser@xes-inc.com>");
MODULE_DESCRIPTION("GPIO interface for Intel ICH series");
MODULE_LICENSE("GPL");
MODULE_ALIAS("platform:"DRV_NAME);

View File

@@ -5,40 +5,40 @@
###############################################################################
cdefs: &cdefs
- x86_64_inventec_d7032q28b_CONFIG_INCLUDE_LOGGING:
- X86_64_INVENTEC_D7032Q28B_CONFIG_INCLUDE_LOGGING:
doc: "Include or exclude logging."
default: 1
- x86_64_inventec_d7032q28b_CONFIG_LOG_OPTIONS_DEFAULT:
- X86_64_INVENTEC_D7032Q28B_CONFIG_LOG_OPTIONS_DEFAULT:
doc: "Default enabled log options."
default: AIM_LOG_OPTIONS_DEFAULT
- x86_64_inventec_d7032q28b_CONFIG_LOG_BITS_DEFAULT:
- X86_64_INVENTEC_D7032Q28B_CONFIG_LOG_BITS_DEFAULT:
doc: "Default enabled log bits."
default: AIM_LOG_BITS_DEFAULT
- x86_64_inventec_d7032q28b_CONFIG_LOG_CUSTOM_BITS_DEFAULT:
- X86_64_INVENTEC_D7032Q28B_CONFIG_LOG_CUSTOM_BITS_DEFAULT:
doc: "Default enabled custom log bits."
default: 0
- x86_64_inventec_d7032q28b_CONFIG_PORTING_STDLIB:
- X86_64_INVENTEC_D7032Q28B_CONFIG_PORTING_STDLIB:
doc: "Default all porting macros to use the C standard libraries."
default: 1
- x86_64_inventec_d7032q28b_CONFIG_PORTING_INCLUDE_STDLIB_HEADERS:
- X86_64_INVENTEC_D7032Q28B_CONFIG_PORTING_INCLUDE_STDLIB_HEADERS:
doc: "Include standard library headers for stdlib porting macros."
default: x86_64_inventec_d7032q28b_CONFIG_PORTING_STDLIB
- x86_64_inventec_d7032q28b_CONFIG_INCLUDE_UCLI:
default: X86_64_INVENTEC_D7032Q28B_CONFIG_PORTING_STDLIB
- X86_64_INVENTEC_D7032Q28B_CONFIG_INCLUDE_UCLI:
doc: "Include generic uCli support."
default: 0
- x86_64_inventec_d7032q28b_CONFIG_INCLUDE_DEFAULT_FAN_DIRECTION:
- X86_64_INVENTEC_D7032Q28B_CONFIG_INCLUDE_DEFAULT_FAN_DIRECTION:
doc: "Assume chassis fan direction is the same as the PSU fan direction."
default: 0
definitions:
cdefs:
x86_64_inventec_d7032q28b_CONFIG_HEADER:
X86_64_INVENTEC_D7032Q28B_CONFIG_HEADER:
defs: *cdefs
basename: x86_64_inventec_d7032q28b_config
portingmacro:
x86_64_inventec_d7032q28b:
X86_64_INVENTEC_D7032Q28B:
macros:
- malloc
- free

View File

@@ -1,45 +0,0 @@
#include "x86_64_inventec_d7032q28b_int.h"
#if x86_64_inventec_d7032q28b_CONFIG_INCLUDE_DEBUG == 1
#include <unistd.h>
static char help__[] =
"Usage: debug [options]\n"
" -c CPLD Versions\n"
" -h Help\n"
;
int
x86_64_inventec_d7032q28b_debug_main(int argc, char* argv[])
{
int c = 0;
int help = 0;
int rv = 0;
while( (c = getopt(argc, argv, "ch")) != -1) {
switch(c)
{
case 'c': c = 1; break;
case 'h': help = 1; rv = 0; break;
default: help = 1; rv = 1; break;
}
}
if(help || argc == 1) {
printf("%s", help__);
return rv;
}
if(c) {
printf("Not implemented.\n");
}
return 0;
}
#endif

View File

@@ -23,6 +23,7 @@
* Fan Platform Implementation Defaults.
*
***********************************************************/
#include <onlplib/file.h>
#include <onlp/platformi/fani.h>
#include <onlplib/mmap.h>
#include <fcntl.h>
@@ -47,15 +48,15 @@
#define FAN_1_ON_PSU1 7
#define FAN_1_ON_PSU2 8
typedef struct fan_path_S
{
char present[LEN_FILE_NAME];
char status[LEN_FILE_NAME];
char speed[LEN_FILE_NAME];
char direction[LEN_FILE_NAME];
char ctrl_speed[LEN_FILE_NAME];
char r_speed[LEN_FILE_NAME];
}fan_path_T;
enum fan_id {
FAN_1_ON_FAN_BOARD = 1,
FAN_2_ON_FAN_BOARD,
FAN_3_ON_FAN_BOARD,
FAN_4_ON_FAN_BOARD,
FAN_5_ON_FAN_BOARD,
FAN_1_ON_PSU_1,
FAN_1_ON_PSU_2,
};
#define _MAKE_FAN_PATH_ON_MAIN_BOARD(prj,id) \
{ #prj"fan"#id"_present", #prj"fan"#id"_fault", #prj"fan"#id"_front_speed_rpm", \
@@ -67,19 +68,6 @@ typedef struct fan_path_S
{"", #folder"/psu_fan1_fault", #folder"/psu_fan1_speed_rpm", \
"", #folder"/psu_fan1_duty_cycle_percentage", "" }
static fan_path_T fan_path[] = /* must map with onlp_fan_id */
{
MAKE_FAN_PATH_ON_MAIN_BOARD(PROJECT_NAME, FAN_RESERVED),
MAKE_FAN_PATH_ON_MAIN_BOARD(PROJECT_NAME, FAN_1_ON_MAIN_BOARD),
MAKE_FAN_PATH_ON_MAIN_BOARD(PROJECT_NAME, FAN_2_ON_MAIN_BOARD),
MAKE_FAN_PATH_ON_MAIN_BOARD(PROJECT_NAME, FAN_3_ON_MAIN_BOARD),
MAKE_FAN_PATH_ON_MAIN_BOARD(PROJECT_NAME, FAN_4_ON_MAIN_BOARD),
MAKE_FAN_PATH_ON_MAIN_BOARD(PROJECT_NAME, FAN_5_ON_MAIN_BOARD),
MAKE_FAN_PATH_ON_MAIN_BOARD(PROJECT_NAME, FAN_6_ON_MAIN_BOARD),
MAKE_FAN_PATH_ON_PSU(11-005b),
MAKE_FAN_PATH_ON_PSU(10-0058)
};
#define MAKE_FAN_INFO_NODE_ON_MAIN_BOARD(id) \
{ \
{ ONLP_FAN_ID_CREATE(FAN_##id##_ON_MAIN_BOARD), "Chassis Fan "#id, 0 }, \
@@ -120,19 +108,83 @@ onlp_fan_info_t linfo[] = {
} \
} while(0)
#define OPEN_READ_FILE(fd,fullpath,data,nbytes,len) \
DEBUG_PRINT("[Debug][%s][%d][openfile: %s]\n", __FUNCTION__, __LINE__, fullpath); \
if ((fd = open(fullpath, O_RDONLY)) == -1) \
return ONLP_STATUS_E_INTERNAL; \
if ((len = read(fd, r_data, nbytes)) <= 0){ \
close(fd); \
return ONLP_STATUS_E_INTERNAL;} \
DEBUG_PRINT("[Debug][%s][%d][read data: %s]\n", __FUNCTION__, __LINE__, r_data); \
if (close(fd) == -1) \
return ONLP_STATUS_E_INTERNAL
static int
_onlp_fani_info_get_fan(int fid, onlp_fan_info_t* info)
{
int value, ret;
/* get fan present status
*/
ret = onlp_file_read_int(&value, "%s""fan%d_present", FAN_BOARD_PATH, fid);
if (ret < 0) {
return ONLP_STATUS_E_INTERNAL;
}
if (value == 0) {
return ONLP_STATUS_OK;
}
info->status |= ONLP_FAN_STATUS_PRESENT;
/* get fan fault status (turn on when any one fails)
*/
ret = onlp_file_read_int(&value, "%s""fan%d_fault", FAN_BOARD_PATH, fid);
if (ret < 0) {
return ONLP_STATUS_E_INTERNAL;
}
if (value > 0) {
info->status |= ONLP_FAN_STATUS_FAILED;
}
/* get fan direction (both : the same)
*/
ret = onlp_file_read_int(&value, "%s""fan%d_direction", FAN_BOARD_PATH, fid);
if (ret < 0) {
return ONLP_STATUS_E_INTERNAL;
}
info->status |= value ? ONLP_FAN_STATUS_B2F : ONLP_FAN_STATUS_F2B;
/* get front fan speed
*/
ret = onlp_file_read_int(&value, "%s""fan%d_front_speed_rpm", FAN_BOARD_PATH, fid);
if (ret < 0) {
return ONLP_STATUS_E_INTERNAL;
}
info->rpm = value;
/* get rear fan speed
*/
ret = onlp_file_read_int(&value, "%s""fan%d_rear_speed_rpm", FAN_BOARD_PATH, fid);
if (ret < 0) {
return ONLP_STATUS_E_INTERNAL;
}
/* take the min value from front/rear fan speed
*/
if (info->rpm > value) {
info->rpm = value;
}
/* get speed percentage from rpm
*/
ret = onlp_file_read_int(&value, "%s""fan_max_speed_rpm", FAN_BOARD_PATH);
if (ret < 0) {
return ONLP_STATUS_E_INTERNAL;
}
info->percentage = (info->rpm * 100)/value;
return ONLP_STATUS_OK;
}
static uint32_t
_onlp_fani_info_get_psu_fan_direction(void)
_onlp_get_fan_direction_on_psu(void)
{
/* Try to read direction from PSU1.
* If PSU1 is not valid, read from PSU2
@@ -147,106 +199,46 @@ _onlp_fani_info_get_psu_fan_direction(void)
continue;
}
switch (psu_type) {
case PSU_TYPE_AC_F2B:
case PSU_TYPE_DC_48V_F2B:
case PSU_TYPE_DC_12V_F2B:
return ONLP_FAN_STATUS_F2B;
case PSU_TYPE_AC_B2F:
case PSU_TYPE_DC_48V_B2F:
case PSU_TYPE_DC_12V_B2F:
return ONLP_FAN_STATUS_B2F;
default:
return 0;
};
if (PSU_TYPE_AC_F2B == psu_type) {
return ONLP_FAN_STATUS_F2B;
}
else {
return ONLP_FAN_STATUS_B2F;
}
}
return 0;
}
static int
_onlp_fani_info_get_fan(int local_id, onlp_fan_info_t* info)
{
int fd, len, nbytes = 10;
char r_data[10] = {0};
char fullpath[65] = {0};
/* check if fan is present
*/
sprintf(fullpath, "%s%s", PREFIX_PATH_ON_MAIN_BOARD, fan_path[local_id].present);
OPEN_READ_FILE(fd,fullpath,r_data,nbytes,len);
if (atoi(r_data) == 0) {
return ONLP_STATUS_OK;
}
info->status |= ONLP_FAN_STATUS_PRESENT;
/* get fan fault status (turn on when any one fails)
*/
sprintf(fullpath, "%s%s", PREFIX_PATH_ON_MAIN_BOARD, fan_path[local_id].status);
OPEN_READ_FILE(fd,fullpath,r_data,nbytes,len);
if (atoi(r_data) > 0) {
info->status |= ONLP_FAN_STATUS_FAILED;
return ONLP_STATUS_OK;
}
/* get fan/fanr direction (both : the same)
*/
sprintf(fullpath, "%s%s", PREFIX_PATH_ON_MAIN_BOARD, fan_path[local_id].direction);
OPEN_READ_FILE(fd,fullpath,r_data,nbytes,len);
if (atoi(r_data) == 0) /*B2F*/
info->status |= ONLP_FAN_STATUS_B2F;
else
info->status |= ONLP_FAN_STATUS_F2B;
/* get fan speed (take the min from two speeds)
*/
sprintf(fullpath, "%s%s", PREFIX_PATH_ON_MAIN_BOARD, fan_path[local_id].speed);
OPEN_READ_FILE(fd,fullpath,r_data,nbytes,len);
info->rpm = atoi(r_data);
sprintf(fullpath, "%s%s", PREFIX_PATH_ON_MAIN_BOARD, fan_path[local_id].r_speed);
OPEN_READ_FILE(fd,fullpath,r_data,nbytes,len);
if (info->rpm > atoi(r_data)) {
info->rpm = atoi(r_data);
}
/* get speed percentage from rpm */
info->percentage = (info->rpm * 100)/MAX_FAN_SPEED;
return ONLP_STATUS_OK;
}
static int
_onlp_fani_info_get_fan_on_psu(int local_id, onlp_fan_info_t* info)
_onlp_fani_info_get_fan_on_psu(int pid, onlp_fan_info_t* info)
{
int fd, len, nbytes = 10;
char r_data[10] = {0};
char fullpath[80] = {0};
int val = 0;
info->status |= ONLP_FAN_STATUS_PRESENT;
/* get fan direction
*/
info->status |= _onlp_fani_info_get_psu_fan_direction();
info->status |= _onlp_get_fan_direction_on_psu();
/* get fan fault status
*/
sprintf(fullpath, "%s%s", PREFIX_PATH_ON_PSU, fan_path[local_id].status);
OPEN_READ_FILE(fd,fullpath,r_data,nbytes,len);
info->status |= (atoi(r_data) > 0) ? ONLP_FAN_STATUS_FAILED : 0;
if (psu_pmbus_info_get(pid, "psu_fan1_fault", &val) == ONLP_STATUS_OK) {
info->status |= (val > 0) ? ONLP_FAN_STATUS_FAILED : 0;
}
/* get fan speed
*/
sprintf(fullpath, "%s%s", PREFIX_PATH_ON_PSU, fan_path[local_id].speed);
OPEN_READ_FILE(fd,fullpath,r_data,nbytes,len);
info->rpm = atoi(r_data);
/* get speed percentage from rpm */
info->percentage = (info->rpm * 100) / MAX_PSU_FAN_SPEED;
info->status |= ONLP_FAN_STATUS_PRESENT;
if (psu_pmbus_info_get(pid, "psu_fan1_speed_rpm", &val) == ONLP_STATUS_OK) {
info->rpm = val;
info->percentage = (info->rpm * 100) / MAX_PSU_FAN_SPEED;
}
return ONLP_STATUS_OK;
}
/*
* This function will be called prior to all of onlp_fani_* functions.
*/
@@ -288,20 +280,6 @@ onlp_fani_info_get(onlp_oid_t id, onlp_fan_info_t* info)
return rc;
}
/*
* This function sets the speed of the given fan in RPM.
*
* This function will only be called if the fan supprots the RPM_SET
* capability.
*
* It is optional if you have no fans at all with this feature.
*/
int
onlp_fani_rpm_set(onlp_oid_t id, int rpm)
{
return ONLP_STATUS_E_UNSUPPORTED;
}
/*
* This function sets the fan speed of the given OID as a percentage.
*
@@ -313,90 +291,39 @@ onlp_fani_rpm_set(onlp_oid_t id, int rpm)
int
onlp_fani_percentage_set(onlp_oid_t id, int p)
{
int fd, len, nbytes=10, local_id;
char data[10] = {0};
char fullpath[70] = {0};
int fid;
char *path = NULL;
VALIDATE(id);
local_id = ONLP_OID_ID_GET(id);
fid = ONLP_OID_ID_GET(id);
/* reject p=0 (p=0, stop fan) */
if (p == 0){
return ONLP_STATUS_E_INVALID;
}
/* get fullpath */
switch (local_id)
{
case FAN_1_ON_PSU1:
case FAN_1_ON_PSU2:
sprintf(fullpath, "%s%s", PREFIX_PATH_ON_PSU, fan_path[local_id].ctrl_speed);
break;
case FAN_1_ON_MAIN_BOARD:
case FAN_2_ON_MAIN_BOARD:
case FAN_3_ON_MAIN_BOARD:
case FAN_4_ON_MAIN_BOARD:
case FAN_5_ON_MAIN_BOARD:
case FAN_6_ON_MAIN_BOARD:
sprintf(fullpath, "%s%s", PREFIX_PATH_ON_MAIN_BOARD, fan_path[local_id].ctrl_speed);
break;
switch (fid)
{
case FAN_1_ON_PSU_1:
return psu_pmbus_info_set(PSU1_ID, "psu_fan1_duty_cycle_percentage", p);
case FAN_1_ON_PSU_2:
return psu_pmbus_info_set(PSU2_ID, "psu_fan1_duty_cycle_percentage", p);
case FAN_1_ON_FAN_BOARD:
case FAN_2_ON_FAN_BOARD:
case FAN_3_ON_FAN_BOARD:
case FAN_4_ON_FAN_BOARD:
case FAN_5_ON_FAN_BOARD:
path = FAN_NODE(fan_duty_cycle_percentage);
break;
default:
return ONLP_STATUS_E_INVALID;
}
sprintf(data, "%d", p);
DEBUG_PRINT("[Debug][%s][%d][openfile: %s][data=%s]\n", __FUNCTION__, __LINE__, fullpath, data);
/* Create output file descriptor */
fd = open(fullpath, O_WRONLY, 0644);
if (fd == -1){
if (onlp_file_write_integer(path, p) < 0) {
AIM_LOG_ERROR("Unable to write data to file (%s)\r\n", path);
return ONLP_STATUS_E_INTERNAL;
}
len = write (fd, data, (ssize_t) nbytes);
if (len != nbytes) {
close(fd);
return ONLP_STATUS_E_INTERNAL;
}
close(fd);
return ONLP_STATUS_OK;
return ONLP_STATUS_OK;
}
/*
* This function sets the fan speed of the given OID as per
* the predefined ONLP fan speed modes: off, slow, normal, fast, max.
*
* Interpretation of these modes is up to the platform.
*
*/
int
onlp_fani_mode_set(onlp_oid_t id, onlp_fan_mode_t mode)
{
return ONLP_STATUS_E_UNSUPPORTED;
}
/*
* This function sets the fan direction of the given OID.
*
* This function is only relevant if the fan OID supports both direction
* capabilities.
*
* This function is optional unless the functionality is available.
*/
int
onlp_fani_dir_set(onlp_oid_t id, onlp_fan_dir_t dir)
{
return ONLP_STATUS_E_UNSUPPORTED;
}
/*
* Generic fan ioctl. Optional.
*/
int
onlp_fani_ioctl(onlp_oid_t id, va_list vargs)
{
return ONLP_STATUS_E_UNSUPPORTED;
}

View File

@@ -191,7 +191,7 @@ onlp_ledi_info_get(onlp_oid_t id, onlp_led_info_t* info)
*info = linfo[ONLP_OID_ID_GET(id)];
/* Set LED mode */
if (deviceNodeReadString(fullpath, data, sizeof(data), 0) != 0) {
if (onlp_file_read_string(fullpath, data, sizeof(data), 0) != 0) {
DEBUG_PRINT("%s(%d)\r\n", __FUNCTION__, __LINE__);
return ONLP_STATUS_E_INTERNAL;
}
@@ -244,20 +244,10 @@ onlp_ledi_mode_set(onlp_oid_t id, onlp_led_mode_t mode)
local_id = ONLP_OID_ID_GET(id);
sprintf(fullpath, "%s%s/%s", prefix_path, last_path[local_id], filename);
if (deviceNodeWriteInt(fullpath, onlp_to_driver_led_mode(local_id, mode), 0) != 0)
if (onlp_file_write_integer(fullpath, onlp_to_driver_led_mode(local_id, mode)) != 0)
{
return ONLP_STATUS_E_INTERNAL;
}
return ONLP_STATUS_OK;
}
/*
* Generic LED ioctl interface.
*/
int
onlp_ledi_ioctl(onlp_oid_t id, va_list vargs)
{
return ONLP_STATUS_E_UNSUPPORTED;
}

View File

@@ -30,9 +30,13 @@
#include <unistd.h>
#include <fcntl.h>
#include <AIM/aim.h>
#include <onlplib/file.h>
#include <onlp/onlp.h>
#include "platform_lib.h"
int deviceNodeWrite(char *filename, char *buffer, int buf_size, int data_len)
#define PSU_NODE_MAX_PATH_LEN 64
int _onlp_file_write(char *filename, char *buffer, int buf_size, int data_len)
{
int fd;
int len;
@@ -61,15 +65,15 @@ int deviceNodeWrite(char *filename, char *buffer, int buf_size, int data_len)
return 0;
}
int deviceNodeWriteInt(char *filename, int value, int data_len)
int onlp_file_write_integer(char *filename, int value)
{
char buf[8] = {0};
sprintf(buf, "%d", value);
return deviceNodeWrite(filename, buf, (int)strlen(buf), data_len);
return _onlp_file_write(filename, buf, (int)strlen(buf), 0);
}
int deviceNodeReadBinary(char *filename, char *buffer, int buf_size, int data_len)
int onlp_file_read_binary(char *filename, char *buffer, int buf_size, int data_len)
{
int fd;
int len;
@@ -98,7 +102,7 @@ int deviceNodeReadBinary(char *filename, char *buffer, int buf_size, int data_le
return 0;
}
int deviceNodeReadString(char *filename, char *buffer, int buf_size, int data_len)
int onlp_file_read_string(char *filename, char *buffer, int buf_size, int data_len)
{
int ret;
@@ -106,7 +110,7 @@ int deviceNodeReadString(char *filename, char *buffer, int buf_size, int data_le
return -1;
}
ret = deviceNodeReadBinary(filename, buffer, buf_size-1, data_len);
ret = onlp_file_read_binary(filename, buffer, buf_size-1, data_len);
if (ret == 0) {
buffer[buf_size-1] = '\0';
@@ -127,7 +131,7 @@ psu_type_t get_psu_type(int id, char* modelname, int modelname_len)
/* Check AC model name */
node = (id == PSU1_ID) ? PSU1_AC_HWMON_NODE(psu_model_name) : PSU2_AC_HWMON_NODE(psu_model_name);
if (deviceNodeReadString(node, model_name, sizeof(model_name), 0) != 0) {
if (onlp_file_read_string(node, model_name, sizeof(model_name), 0) != 0) {
return PSU_TYPE_UNKNOWN;
}
@@ -141,7 +145,7 @@ psu_type_t get_psu_type(int id, char* modelname, int modelname_len)
}
node = (id == PSU1_ID) ? PSU1_AC_PMBUS_NODE(psu_fan_dir) : PSU2_AC_PMBUS_NODE(psu_fan_dir);
if (deviceNodeReadString(node, fan_dir, sizeof(fan_dir), 0) != 0) {
if (onlp_file_read_string(node, fan_dir, sizeof(fan_dir), 0) != 0) {
return PSU_TYPE_UNKNOWN;
}
@@ -160,7 +164,7 @@ psu_type_t get_psu_type(int id, char* modelname, int modelname_len)
}
node = (id == PSU1_ID) ? PSU1_AC_PMBUS_NODE(psu_fan_dir) : PSU2_AC_PMBUS_NODE(psu_fan_dir);
if (deviceNodeReadString(node, fan_dir, sizeof(fan_dir), 0) != 0) {
if (onlp_file_read_string(node, fan_dir, sizeof(fan_dir), 0) != 0) {
return PSU_TYPE_UNKNOWN;
}
@@ -179,7 +183,7 @@ psu_type_t get_psu_type(int id, char* modelname, int modelname_len)
}
node = (id == PSU1_ID) ? PSU1_AC_HWMON_NODE(psu_fan_dir) : PSU2_AC_HWMON_NODE(psu_fan_dir);
if (deviceNodeReadString(node, fan_dir, sizeof(fan_dir), 0) != 0) {
if (onlp_file_read_string(node, fan_dir, sizeof(fan_dir), 0) != 0) {
return PSU_TYPE_UNKNOWN;
}
@@ -198,3 +202,45 @@ psu_type_t get_psu_type(int id, char* modelname, int modelname_len)
return PSU_TYPE_UNKNOWN;
}
int psu_pmbus_info_get(int id, char *node, int *value)
{
int ret = 0;
*value = 0;
if (PSU1_ID == id) {
ret = onlp_file_read_int(value, "%s%s", PSU1_AC_PMBUS_PREFIX, node);
}
else {
ret = onlp_file_read_int(value, "%s%s", PSU2_AC_PMBUS_PREFIX, node);
}
if (ret < 0) {
return ONLP_STATUS_E_INTERNAL;
}
return ret;
}
int psu_pmbus_info_set(int id, char *node, int value)
{
char path[PSU_NODE_MAX_PATH_LEN] = {0};
switch (id) {
case PSU1_ID:
sprintf(path, "%s%s", PSU1_AC_PMBUS_PREFIX, node);
break;
case PSU2_ID:
sprintf(path, "%s%s", PSU2_AC_PMBUS_PREFIX, node);
break;
default:
return ONLP_STATUS_E_UNSUPPORTED;
};
if (onlp_file_write_integer(path, value) < 0) {
AIM_LOG_ERROR("Unable to write data to file (%s)\r\n", path);
return ONLP_STATUS_E_INTERNAL;
}
return ONLP_STATUS_OK;
}

View File

@@ -46,11 +46,17 @@
#define PSU1_AC_HWMON_NODE(node) PSU1_AC_HWMON_PREFIX#node
#define PSU2_AC_HWMON_NODE(node) PSU2_AC_HWMON_PREFIX#node
#define FAN_BOARD_PATH "/sys/devices/platform/fan/"
#define FAN_NODE(node) FAN_BOARD_PATH#node
#define IDPROM_PATH "/sys/class/i2c-adapter/i2c-1/1-0057/eeprom"
int deviceNodeWriteInt(char *filename, int value, int data_len);
int deviceNodeReadBinary(char *filename, char *buffer, int buf_size, int data_len);
int deviceNodeReadString(char *filename, char *buffer, int buf_size, int data_len);
int onlp_file_write_integer(char *filename, int value);
int onlp_file_read_binary(char *filename, char *buffer, int buf_size, int data_len);
int onlp_file_read_string(char *filename, char *buffer, int buf_size, int data_len);
int psu_pmbus_info_get(int id, char *node, int *value);
int psu_pmbus_info_set(int id, char *node, int value);
typedef enum psu_type {
PSU_TYPE_UNKNOWN,

View File

@@ -58,7 +58,7 @@ psu_status_info_get(int id, char *node, int *value)
sprintf(node_path, "%s%s", PSU2_AC_HWMON_PREFIX, node);
}
ret = deviceNodeReadString(node_path, buf, sizeof(buf), 0);
ret = onlp_file_read_string(node_path, buf, sizeof(buf), 0);
if (ret == 0) {
*value = atoi(buf);
@@ -83,7 +83,7 @@ psu_ym2651_pmbus_info_get(int id, char *node, int *value)
sprintf(node_path, "%s%s", PSU2_AC_PMBUS_PREFIX, node);
}
ret = deviceNodeReadString(node_path, buf, sizeof(buf), 0);
ret = onlp_file_read_string(node_path, buf, sizeof(buf), 0);
if (ret == 0) {
*value = atoi(buf);

View File

@@ -48,13 +48,13 @@ static const int sfp_mux_index[NUM_OF_SFP_PORT] = {
#define FRONT_PORT_TO_MUX_INDEX(port) (sfp_mux_index[port]+MUX_START_INDEX)
static int
as7512_32x_sfp_node_read_int(char *node_path, int *value, int data_len)
sfp_node_read_int(char *node_path, int *value, int data_len)
{
int ret = 0;
char buf[8];
*value = 0;
ret = deviceNodeReadString(node_path, buf, sizeof(buf), data_len);
ret = onlp_file_read_string(node_path, buf, sizeof(buf), data_len);
if (ret == 0) {
*value = atoi(buf);
@@ -64,7 +64,7 @@ as7512_32x_sfp_node_read_int(char *node_path, int *value, int data_len)
}
static char*
as7512_32x_sfp_get_port_path(int port, char *node_name)
sfp_get_port_path(int port, char *node_name)
{
sprintf(sfp_node_path, "/sys/bus/i2c/devices/%d-0050/%s",
FRONT_PORT_TO_MUX_INDEX(port),
@@ -110,9 +110,9 @@ onlp_sfpi_is_present(int port)
* Return < 0 if error.
*/
int present;
char* path = as7512_32x_sfp_get_port_path(port, "sfp_is_present");
char* path = sfp_get_port_path(port, "sfp_is_present");
if (as7512_32x_sfp_node_read_int(path, &present, 0) != 0) {
if (sfp_node_read_int(path, &present, 0) != 0) {
AIM_LOG_ERROR("Unable to read present status from port(%d)\r\n", port);
return ONLP_STATUS_E_INTERNAL;
}
@@ -127,7 +127,7 @@ onlp_sfpi_presence_bitmap_get(onlp_sfp_bitmap_t* dst)
char* path;
FILE* fp;
path = as7512_32x_sfp_get_port_path(0, "sfp_is_present_all");
path = sfp_get_port_path(0, "sfp_is_present_all");
fp = fopen(path, "r");
if(fp == NULL) {
@@ -167,7 +167,7 @@ onlp_sfpi_presence_bitmap_get(onlp_sfp_bitmap_t* dst)
int
onlp_sfpi_eeprom_read(int port, uint8_t data[256])
{
char* path = as7512_32x_sfp_get_port_path(port, "sfp_eeprom");
char* path = sfp_get_port_path(port, "sfp_eeprom");
/*
* Read the SFP eeprom into data[]
@@ -177,7 +177,7 @@ onlp_sfpi_eeprom_read(int port, uint8_t data[256])
*/
memset(data, 0, 256);
if (deviceNodeReadBinary(path, (char*)data, 256, 256) != 0) {
if (onlp_file_read_binary(path, (char*)data, 256, 256) != 0) {
AIM_LOG_ERROR("Unable to read eeprom from port(%d)\r\n", port);
return ONLP_STATUS_E_INTERNAL;
}

View File

@@ -8,7 +8,7 @@ class OnlPlatform_x86_64_inventec_d7032q28b_r0(OnlPlatformInventec,
SYS_OBJECT_ID=".1.32"
def baseconfig(self):
os.system("insmod /lib/modules/`uname -r`/onl/inventec/x86-64-inventec-d7032q28b/gpio-ich.ko gpiobase=0")
os.system("insmod /lib/modules/`uname -r`/kernel/drivers/gpio/gpio-ich.ko gpiobase=0")
self.insmod('inv_platform')
self.insmod('inv_psoc')
self.insmod('inv_cpld')