[devices]:Add attributes for cpupld and swpld. (#1516)
Signed-off-by: Stanley Chi <stanley.chi@deltaww.com>
This commit is contained in:
parent
94c90cd5e5
commit
baa9d45343
@ -1,4 +1,6 @@
|
||||
obj-m += delta_ag9064_platform.o
|
||||
obj-m += delta_ag9064_cpld.o
|
||||
obj-m += delta_ag9064_swpld.o
|
||||
obj-m += i2c-mei.o
|
||||
i2c-mei-objs := i2c-mei_io.o i2c-mei_main.o i2c-mei_rw.o
|
||||
|
||||
|
@ -0,0 +1,567 @@
|
||||
#include <linux/device.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/sysfs.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/mutex.h>
|
||||
#include <linux/completion.h>
|
||||
#include <linux/ipmi.h>
|
||||
#include <linux/ipmi_smi.h>
|
||||
#include <linux/hwmon-sysfs.h>
|
||||
#include <linux/hwmon.h>
|
||||
|
||||
#define IPMI_MAX_INTF (4)
|
||||
#define DELTA_NETFN 0x38
|
||||
#define BMC_BUS_5 0x04
|
||||
#define CMD_SETDATA 0x03
|
||||
#define CMD_GETDATA 0x02
|
||||
|
||||
#define CPUPLD_ADDR 0x31
|
||||
#define SWPLD1_ADDR 0x35
|
||||
#define SWPLD2_ADDR 0x34
|
||||
#define SWPLD3_ADDR 0x33
|
||||
#define SWPLD4_ADDR 0x32
|
||||
#define QSFP_PORT_MUX_REG 0x13
|
||||
|
||||
#define DEFAULT_NUM 1
|
||||
#define BUS9_DEV_NUM 64
|
||||
#define BUS9_BASE_NUM 20
|
||||
|
||||
extern int dni_bmc_cmd(char set_cmd, char *cmd_data, int cmd_data_len);
|
||||
extern int dni_create_user(void);
|
||||
extern unsigned char dni_log2 (unsigned char num);
|
||||
|
||||
extern void device_release(struct device *dev);
|
||||
extern void msg_handler(struct ipmi_recv_msg *recv_msg,void* handler_data);
|
||||
extern void dummy_smi_free(struct ipmi_smi_msg *msg);
|
||||
extern void dummy_recv_free(struct ipmi_recv_msg *msg);
|
||||
|
||||
static ipmi_user_t ipmi_mh_user = NULL;
|
||||
static struct ipmi_user_hndl ipmi_hndlrs = { .ipmi_recv_hndl = msg_handler,};
|
||||
static atomic_t dummy_count = ATOMIC_INIT(0);
|
||||
|
||||
static struct ipmi_smi_msg halt_smi_msg = {
|
||||
.done = dummy_smi_free
|
||||
};
|
||||
static struct ipmi_recv_msg halt_recv_msg = {
|
||||
.done = dummy_recv_free
|
||||
};
|
||||
|
||||
enum{
|
||||
BUS0 = 0,
|
||||
BUS1,
|
||||
BUS2,
|
||||
BUS3,
|
||||
BUS4,
|
||||
BUS5,
|
||||
BUS6,
|
||||
BUS7,
|
||||
BUS8,
|
||||
BUS9,
|
||||
BUS10,
|
||||
BUS11,
|
||||
BUS12,
|
||||
BUS13,
|
||||
BUS14,
|
||||
};
|
||||
|
||||
static struct cpld_attribute_data {
|
||||
uint8_t bus;
|
||||
uint8_t addr;
|
||||
uint8_t reg;
|
||||
uint8_t mask;
|
||||
char note[200];
|
||||
};
|
||||
|
||||
|
||||
enum cpld_type {
|
||||
system_cpld,
|
||||
swpld1,
|
||||
swpld2,
|
||||
swpld3,
|
||||
swpld4,
|
||||
};
|
||||
|
||||
struct cpld_platform_data {
|
||||
int reg_addr;
|
||||
struct i2c_client *client;
|
||||
};
|
||||
|
||||
static struct cpld_platform_data ag9064_cpld_platform_data[] = {
|
||||
[system_cpld] = {
|
||||
.reg_addr = CPUPLD_ADDR,
|
||||
},
|
||||
};
|
||||
|
||||
static struct cpld_platform_data ag9064_swpld1_platform_data[] = {
|
||||
[swpld1] = {
|
||||
.reg_addr = SWPLD1_ADDR,
|
||||
},
|
||||
};
|
||||
|
||||
static struct cpld_platform_data ag9064_swpld2_platform_data[] = {
|
||||
[swpld2] = {
|
||||
.reg_addr = SWPLD2_ADDR,
|
||||
},
|
||||
};
|
||||
|
||||
static struct cpld_platform_data ag9064_swpld3_platform_data[] = {
|
||||
[swpld3] = {
|
||||
.reg_addr = SWPLD3_ADDR,
|
||||
},
|
||||
};
|
||||
|
||||
static struct cpld_platform_data ag9064_swpld4_platform_data[] = {
|
||||
[swpld4] = {
|
||||
.reg_addr = SWPLD4_ADDR,
|
||||
},
|
||||
};
|
||||
|
||||
enum cpld_attributes {
|
||||
CPLD_REG_ADDR,
|
||||
CPLD_REG_VALUE,
|
||||
SWPLD1_REG_ADDR,
|
||||
SWPLD1_REG_VALUE,
|
||||
SWPLD2_REG_ADDR,
|
||||
SWPLD2_REG_VALUE,
|
||||
SWPLD3_REG_ADDR,
|
||||
SWPLD3_REG_VALUE,
|
||||
SWPLD4_REG_ADDR,
|
||||
SWPLD4_REG_VALUE,
|
||||
//CPLD
|
||||
CPLD_VER,
|
||||
CPU_BOARD_VER,
|
||||
CPU_ID,
|
||||
MB_ID,
|
||||
MB_VER,
|
||||
CPU0_PWR_OK,
|
||||
PSU_OVER_TEMP,
|
||||
PWR_RAIL_OVER_TEMP,
|
||||
CPU_DISOMIC_OVER_TEMP,
|
||||
DDR_OVER_TEMP,
|
||||
CPLD_PWR_ON_RST,
|
||||
CPLD_HARD_RST,
|
||||
CPLD_RST,
|
||||
MB_PWR,
|
||||
MB_RST,
|
||||
PSU_FAN_INT,
|
||||
OP_MODULE_INT,
|
||||
//SWPLD1
|
||||
SWPLD1_MAJOR_VER,
|
||||
SWPLD1_MINOR_VER,
|
||||
SWPLD1_SCRTCH_REG,
|
||||
PSU1_PWR_OK,
|
||||
PSU1_INT,
|
||||
PSU2_PWR_OK,
|
||||
PSU2_INT,
|
||||
SYNCE_INT,
|
||||
SYNCE_RST,
|
||||
SYNCE_EEPROM_WP,
|
||||
PSU1_GREEN_LED,
|
||||
PSU1_RED_LED,
|
||||
PSU2_GREEN_LED,
|
||||
PSU2_RED_LED,
|
||||
PSU_LED_MODE,
|
||||
//SWPLD2
|
||||
SWPLD2_MAJOR_VER,
|
||||
SWPLD2_MINOR_VER,
|
||||
SWPLD2_SCRTCH_REG,
|
||||
FAN_LED,
|
||||
SYS_LED,
|
||||
FAN_MOD1_LED,
|
||||
FAN_MOD2_LED,
|
||||
FAN_MOD3_LED,
|
||||
FAN_MOD4_LED,
|
||||
//SWPLD3
|
||||
SWPLD3_MAJOR_VER,
|
||||
SWPLD3_MINOR_VER,
|
||||
SWPLD3_SCRTCH_REG,
|
||||
SB_VER,
|
||||
PLATFORM_TYPE,
|
||||
//SWPLD4
|
||||
SWPLD4_MAJOR_VER,
|
||||
SWPLD4_MINOR_VER,
|
||||
SWPLD4_SCRTCH_REG,
|
||||
BMC_RST,
|
||||
CPLD_LPC_RST,
|
||||
CPLD_SW_RST,
|
||||
MB_CPLD_RST,
|
||||
BCM56970_RST,
|
||||
CPLD_UPGRADE_RST,
|
||||
MB_RST_CPLD,
|
||||
CPU_RST_MB_OOB,
|
||||
GPIO_PHY_RST,
|
||||
PSU_FAN_EVENT,
|
||||
CPU_THERMAL_INT,
|
||||
FAN_INT,
|
||||
CPLD_SPI_WP,
|
||||
RJ45_CONSOLE_SEL,
|
||||
SYSTEM_INT,
|
||||
CPLD_MB_RST_DONE,
|
||||
MB_PWR_OK,
|
||||
FAN_EEPROM_WP,
|
||||
};
|
||||
|
||||
static struct cpld_attribute_data attribute_data[] = {
|
||||
[CPLD_REG_ADDR] = {
|
||||
},
|
||||
[CPLD_REG_VALUE] = {
|
||||
},
|
||||
[SWPLD1_REG_ADDR] = {
|
||||
},
|
||||
[SWPLD1_REG_VALUE] = {
|
||||
},
|
||||
[SWPLD2_REG_ADDR] = {
|
||||
},
|
||||
[SWPLD2_REG_VALUE] = {
|
||||
},
|
||||
[SWPLD3_REG_ADDR] = {
|
||||
},
|
||||
[SWPLD3_REG_VALUE] = {
|
||||
},
|
||||
[SWPLD4_REG_ADDR] = {
|
||||
},
|
||||
[SWPLD4_REG_VALUE] = {
|
||||
},
|
||||
//CPLD
|
||||
[CPLD_VER] = {
|
||||
.bus = BUS0, .addr = CPUPLD_ADDR,
|
||||
.reg = 0x01, .mask = 0xFF,
|
||||
.note = "CPLD Version, controlled by CPLD editor"
|
||||
},
|
||||
[CPU_BOARD_VER] = {
|
||||
.bus = BUS0, .addr = CPUPLD_ADDR,
|
||||
.reg = 0x02, .mask = 0xF0,
|
||||
.note = "“0x0”: proto A1\n“0x1”: proto A2\n“0x2”: PR (Production)"
|
||||
},
|
||||
[CPU_ID] = {
|
||||
.bus = BUS0, .addr = CPUPLD_ADDR,
|
||||
.reg = 0x02, .mask = 0x0F,
|
||||
.note = "“0x0”: C2558 ECC\n“0x1”: Rangeley ECC\n“0x2”: BROADWELL-DE ECC"
|
||||
},
|
||||
[MB_ID] = {
|
||||
.bus = BUS0, .addr = CPUPLD_ADDR,
|
||||
.reg = 0x03, .mask = 0xFF,
|
||||
.note = "“0x00”: proto A1\n“0x01”: proto A2\n“0x02”: PR (Production)"
|
||||
},
|
||||
[MB_VER] = {
|
||||
.bus = BUS0, .addr = CPUPLD_ADDR,
|
||||
.reg = 0x04, .mask = 0x0F,
|
||||
.note = "“0x0”: proto-A\n“0x1”: proto-B"
|
||||
},
|
||||
[CPU0_PWR_OK] = {
|
||||
.bus = BUS0, .addr = CPUPLD_ADDR,
|
||||
.reg = 0x08, .mask = 1 << 3,
|
||||
.note = "“1” =Power rail is good\n“0” = Power rail is failed"
|
||||
},
|
||||
[PSU_OVER_TEMP] = {
|
||||
.bus = BUS0, .addr = CPUPLD_ADDR,
|
||||
.reg = 0x0b, .mask = 1 << 4,
|
||||
.note = "“1” = Not over temperature\n“0” = Over temperature"
|
||||
},
|
||||
[PWR_RAIL_OVER_TEMP] = {
|
||||
.bus = BUS0, .addr = CPUPLD_ADDR,
|
||||
.reg = 0x0b, .mask = 1 << 3,
|
||||
.note = "“1” = Not over temperature\n“0” = Over temperature"
|
||||
},
|
||||
[CPU_DISOMIC_OVER_TEMP] = {
|
||||
.bus = BUS0, .addr = CPUPLD_ADDR,
|
||||
.reg = 0x0b, .mask = 1 << 1,
|
||||
.note = "“1” = Not over temperature\n“0” = Over temperature"
|
||||
},
|
||||
[DDR_OVER_TEMP] = {
|
||||
.bus = BUS0, .addr = CPUPLD_ADDR,
|
||||
.reg = 0x0b, .mask = 1 << 0,
|
||||
.note = "“1” = Not over temperature\n“0” = Over temperature"
|
||||
},
|
||||
[CPLD_PWR_ON_RST] = {
|
||||
.bus = BUS0, .addr = CPUPLD_ADDR,
|
||||
.reg = 0x11, .mask = 1 << 4,
|
||||
.note = "“0” = Reset\n“1” = Normal operation"
|
||||
},
|
||||
[CPLD_HARD_RST] = {
|
||||
.bus = BUS0, .addr = CPUPLD_ADDR,
|
||||
.reg = 0x11, .mask = 1 << 2,
|
||||
.note = "“0” = Reset\n“1” = Normal operation"
|
||||
},
|
||||
[CPLD_RST] = {
|
||||
.bus = BUS0, .addr = CPUPLD_ADDR,
|
||||
.reg = 0x11, .mask = 1 << 0,
|
||||
.note = "“0” = Reset\n“1” = Normal operation"
|
||||
},
|
||||
[MB_PWR] = {
|
||||
.bus = BUS0, .addr = CPUPLD_ADDR,
|
||||
.reg = 0x12, .mask = 1 << 2,
|
||||
.note = "“0” = Power rail is failed\n“1” =Power rail is good"
|
||||
},
|
||||
[MB_RST] = {
|
||||
.bus = BUS0, .addr = CPUPLD_ADDR,
|
||||
.reg = 0x12, .mask = 1 << 0,
|
||||
.note = "“0” = Reset\n“1” = Normal operation"
|
||||
},
|
||||
[PSU_FAN_INT] = {
|
||||
.bus = BUS0, .addr = CPUPLD_ADDR,
|
||||
.reg = 0x15, .mask = 1 << 1,
|
||||
.note = "“0” = Interrupt occurs\n“1” = Interrupt doesn't occur"
|
||||
},
|
||||
[OP_MODULE_INT] = {
|
||||
.bus = BUS0, .addr = CPUPLD_ADDR,
|
||||
.reg = 0x15, .mask = 1 << 0,
|
||||
.note = "“0” = Interrupt occurs\n“1” = Interrupt doesn't occur"
|
||||
},
|
||||
//SWPLD1
|
||||
[SWPLD1_MAJOR_VER] = {
|
||||
.bus = BUS0, .addr = SWPLD1_ADDR,
|
||||
.reg = 0x00, .mask = 0xF0,
|
||||
.note = "CPLD Major Version, controlled by CPLD editor."
|
||||
},
|
||||
[SWPLD1_MINOR_VER] = {
|
||||
.bus = BUS0, .addr = SWPLD1_ADDR,
|
||||
.reg = 0x00, .mask = 0x0F,
|
||||
.note = "CPLD Minor Version, controlled by CPLD editor."
|
||||
},
|
||||
[SWPLD1_SCRTCH_REG] = {
|
||||
.bus = BUS0, .addr = SWPLD1_ADDR,
|
||||
.reg = 0x01, .mask = 0xFF,
|
||||
.note = "CPLD read/write test register, to provide a way to test CPLD access."
|
||||
},
|
||||
[PSU1_PWR_OK] = {
|
||||
.bus = BUS0, .addr = SWPLD1_ADDR,
|
||||
.reg = 0x02, .mask = 1 << 6,
|
||||
.note = "‘0’ = Power rail is good\n‘1’ = Power rail is failed"
|
||||
},
|
||||
[PSU1_INT] = {
|
||||
.bus = BUS0, .addr = SWPLD1_ADDR,
|
||||
.reg = 0x02, .mask = 1 << 5,
|
||||
.note = "‘0’ = Interrupt doesn’t occur\n‘1’ = Interrupt occurs"
|
||||
},
|
||||
[PSU2_PWR_OK] = {
|
||||
.bus = BUS0, .addr = SWPLD1_ADDR,
|
||||
.reg = 0x02, .mask = 1 << 2,
|
||||
.note = "‘0’ = Power rail is good\n‘1’ = Power rail is failed"
|
||||
},
|
||||
[PSU2_INT] = {
|
||||
.bus = BUS0, .addr = SWPLD1_ADDR,
|
||||
.reg = 0x02, .mask = 1 << 1,
|
||||
.note = "‘0’ = Interrupt doesn’t occur\n‘1’ = Interrupt occurs"
|
||||
},
|
||||
[SYNCE_INT] = {
|
||||
.bus = BUS0, .addr = SWPLD1_ADDR,
|
||||
.reg = 0x12, .mask = 1 << 7,
|
||||
.note = "‘0’ = Interrupt occurs\n‘1’ = Interrupt doesn’t occur"
|
||||
},
|
||||
[SYNCE_RST] = {
|
||||
.bus = BUS0, .addr = SWPLD1_ADDR,
|
||||
.reg = 0x12, .mask = 1 << 6,
|
||||
.note = "“0” = Reset\n“1” = Normal operation"
|
||||
},
|
||||
[SYNCE_EEPROM_WP] = {
|
||||
.bus = BUS0, .addr = SWPLD1_ADDR,
|
||||
.reg = 0x12, .mask = 1 << 5,
|
||||
.note = "“1” = enables the lock-down mechanism.\n“0” = overrides the lock-down function enabling blocks to be erased or programmed using software commands."
|
||||
},
|
||||
[PSU1_GREEN_LED] = {
|
||||
.bus = BUS0, .addr = SWPLD1_ADDR,
|
||||
.reg = 0x13, .mask = 1 << 7,
|
||||
.note = "“0”: Solid Green – Power Supply 1 is supplied to the switch & operating normally\n“1”: OFF"
|
||||
},
|
||||
[PSU1_RED_LED] = {
|
||||
.bus = BUS0, .addr = SWPLD1_ADDR,
|
||||
.reg = 0x13, .mask = 1 << 6,
|
||||
.note = "“0”: Solid Red – Power Supply 1 is supplied to the switch & operating normally\n“1”: OFF"
|
||||
},
|
||||
[PSU2_GREEN_LED] = {
|
||||
.bus = BUS0, .addr = SWPLD1_ADDR,
|
||||
.reg = 0x13, .mask = 1 << 5,
|
||||
.note = "“0”: Solid Green – Power Supply 2 is supplied to the switch & operating normally\n“1”: OFF"
|
||||
},
|
||||
[PSU2_RED_LED] = {
|
||||
.bus = BUS0, .addr = SWPLD1_ADDR,
|
||||
.reg = 0x13, .mask = 1 << 4,
|
||||
.note = "“0”: Solid Red – Power Supply 1=2 is supplied to the switch & operating normally\n“1”: OFF"
|
||||
},
|
||||
[PSU_LED_MODE] = {
|
||||
.bus = BUS0, .addr = SWPLD1_ADDR,
|
||||
.reg = 0x13, .mask = 1 << 0,
|
||||
.note = "“0”: PSU LED can be changed manually\n“1”: PSU LED can’t be changed manually"
|
||||
},
|
||||
//SWPLD2
|
||||
[SWPLD2_MAJOR_VER] = {
|
||||
.bus = BUS0, .addr = SWPLD2_ADDR,
|
||||
.reg = 0x00, .mask =0xF0 ,
|
||||
.note = "CPLD Major Version, controlled by CPLD editor."
|
||||
},
|
||||
[SWPLD2_MINOR_VER] = {
|
||||
.bus = BUS0, .addr = SWPLD2_ADDR,
|
||||
.reg = 0x00, .mask = 0x0F,
|
||||
.note = "CPLD Minor Version, controlled by CPLD editor."
|
||||
},
|
||||
[SWPLD2_SCRTCH_REG] = {
|
||||
.bus = BUS0, .addr = SWPLD2_ADDR,
|
||||
.reg = 0x01, .mask = 0xFF,
|
||||
.note = "CPLD read/write test register, to provide a way to test CPLD access."
|
||||
},
|
||||
[FAN_LED] = {
|
||||
.bus = BUS0, .addr = SWPLD2_ADDR,
|
||||
.reg = 0x02, .mask = 0xC0,
|
||||
.note = "“00’/”11”: OFF\n“01”: Solid Green – FANs are operating normally\n“10”: Solid Amber – FANs are Error"
|
||||
},
|
||||
[SYS_LED] = {
|
||||
.bus = BUS0, .addr = SWPLD2_ADDR,
|
||||
.reg = 0x02, .mask = 0x30,
|
||||
.note = "‘00’: Off\n‘01’: Solid Green – Normal operation\n‘10’: Blinking Green – Booting Progress\n‘11’: Solid Red – System Fail"
|
||||
},
|
||||
[FAN_MOD1_LED] = {
|
||||
.bus = BUS0, .addr = SWPLD2_ADDR,
|
||||
.reg = 0x1b, .mask = 1 << 7,
|
||||
.note = "‘0’ = Amber\n‘1’ = Green"
|
||||
},
|
||||
[FAN_MOD2_LED] = {
|
||||
.bus = BUS0, .addr = SWPLD2_ADDR,
|
||||
.reg = 0x1b, .mask = 1 << 6,
|
||||
.note = "‘0’ = Amber\n‘1’ = Green"
|
||||
},
|
||||
[FAN_MOD3_LED] = {
|
||||
.bus = BUS0, .addr = SWPLD2_ADDR,
|
||||
.reg = 0x1b, .mask = 1 << 5,
|
||||
.note = "‘0’ = Amber\n‘1’ = Green"
|
||||
},
|
||||
[FAN_MOD4_LED] = {
|
||||
.bus = BUS0, .addr = SWPLD2_ADDR,
|
||||
.reg = 0x1b, .mask = 1 << 4,
|
||||
.note = "‘0’ = Amber\n‘1’ = Green"
|
||||
},
|
||||
//SWPLD3
|
||||
[SWPLD3_MAJOR_VER] = {
|
||||
.bus = BUS0, .addr = SWPLD3_ADDR,
|
||||
.reg = 0x00, .mask = 0xF0,
|
||||
.note = "CPLD Major Version, controlled by CPLD editor."
|
||||
},
|
||||
[SWPLD3_MINOR_VER] = {
|
||||
.bus = BUS0, .addr = SWPLD3_ADDR,
|
||||
.reg = 0x00, .mask = 0x0F,
|
||||
.note = "CPLD Minor Version, controlled by CPLD editor."
|
||||
},
|
||||
[SWPLD3_SCRTCH_REG] = {
|
||||
.bus = BUS0, .addr = SWPLD3_ADDR,
|
||||
.reg = 0x01, .mask = 0xFF,
|
||||
.note = "CPLD read/write test register, to provide a way to test CPLD access."
|
||||
},
|
||||
[SB_VER] = {
|
||||
.bus = BUS0, .addr = SWPLD3_ADDR,
|
||||
.reg = 0x02, .mask = 0xF0,
|
||||
.note = "“0x0”: proto-A\n“0x1”: proto-B"
|
||||
},
|
||||
[PLATFORM_TYPE] = {
|
||||
.bus = BUS0, .addr = SWPLD3_ADDR,
|
||||
.reg = 0x02, .mask = 0x0F,
|
||||
.note = "“0x0”: 64X100G_2U\n“0x1”~”0xF” Reserved"
|
||||
},
|
||||
//SWPLD4
|
||||
[SWPLD4_MAJOR_VER] = {
|
||||
.bus = BUS0, .addr = SWPLD4_ADDR,
|
||||
.reg = 0x00, .mask = 0xF0,
|
||||
.note = "CPLD Major Version, controlled by CPLD editor."
|
||||
},
|
||||
[SWPLD4_MINOR_VER] = {
|
||||
.bus = BUS0, .addr = SWPLD4_ADDR,
|
||||
.reg = 0x00, .mask = 0x0F,
|
||||
.note = "CPLD Minor Version, controlled by CPLD editor."
|
||||
},
|
||||
[SWPLD4_SCRTCH_REG] = {
|
||||
.bus = BUS0, .addr = SWPLD4_ADDR,
|
||||
.reg = 0x01, .mask = 0xFF,
|
||||
.note = "CPLD read/write test register, to provide a way to test CPLD access."
|
||||
},
|
||||
[BMC_RST] = {
|
||||
.bus = BUS0, .addr = SWPLD4_ADDR,
|
||||
.reg = 0x02, .mask = 1 << 6,
|
||||
.note = "“0” = Reset\n“1” = Normal operation"
|
||||
},
|
||||
[CPLD_LPC_RST] = {
|
||||
.bus = BUS0, .addr = SWPLD4_ADDR,
|
||||
.reg = 0x02, .mask = 1 << 5,
|
||||
.note = "“0” = Reset\n“1” = Normal operation"
|
||||
},
|
||||
[CPLD_SW_RST] = {
|
||||
.bus = BUS0, .addr = SWPLD4_ADDR,
|
||||
.reg = 0x02, .mask = 1 << 3,
|
||||
.note = "“0” = Reset\n“1” = Normal operation"
|
||||
},
|
||||
[MB_CPLD_RST] = {
|
||||
.bus = BUS0, .addr = SWPLD4_ADDR,
|
||||
.reg = 0x02, .mask = 1 << 2,
|
||||
.note = "“0” = Reset\n“1” = Normal operation"
|
||||
},
|
||||
[BCM56970_RST] = {
|
||||
.bus = BUS0, .addr = SWPLD4_ADDR,
|
||||
.reg = 0x02, .mask = 1 << 1,
|
||||
.note = "“0” = Reset\n“1” = Normal operation"
|
||||
},
|
||||
[CPLD_UPGRADE_RST] = {
|
||||
.bus = BUS0, .addr = SWPLD4_ADDR,
|
||||
.reg = 0x03, .mask = 1 << 7,
|
||||
.note = "“0” = Reset\n“1” = Normal operation"
|
||||
},
|
||||
[MB_RST_CPLD] = {
|
||||
.bus = BUS0, .addr = SWPLD4_ADDR,
|
||||
.reg = 0x03, .mask = 1 << 6,
|
||||
.note = "“0” = Reset\n“1” = Normal operation"
|
||||
},
|
||||
[CPU_RST_MB_OOB] = {
|
||||
.bus = BUS0, .addr = SWPLD4_ADDR,
|
||||
.reg = 0x03, .mask = 1 << 5,
|
||||
.note = "“0” = Reset\n“1” = Normal operation"
|
||||
},
|
||||
[GPIO_PHY_RST] = {
|
||||
.bus = BUS0, .addr = SWPLD4_ADDR,
|
||||
.reg = 0x03, .mask = 1 << 4,
|
||||
.note = "“0” = Reset\n“1” = Normal operation"
|
||||
},
|
||||
[PSU_FAN_EVENT] = {
|
||||
.bus = BUS0, .addr = SWPLD4_ADDR,
|
||||
.reg = 0x04, .mask = 1 << 4,
|
||||
.note = "‘0’ = Interrupt occurs\n‘1’ = Interrupt doesn’t occur"
|
||||
},
|
||||
[CPU_THERMAL_INT] = {
|
||||
.bus = BUS0, .addr = SWPLD4_ADDR,
|
||||
.reg = 0x04, .mask = 1 << 1,
|
||||
.note = "‘0’ = Interrupt occurs\n‘1’ = Interrupt doesn’t occur"
|
||||
},
|
||||
[FAN_INT] = {
|
||||
.bus = BUS0, .addr = SWPLD4_ADDR,
|
||||
.reg = 0x04, .mask = 1 << 0,
|
||||
.note = "‘0’ = Interrupt occurs\n‘1’ = Interrupt doesn’t occur"
|
||||
},
|
||||
[CPLD_SPI_WP] = {
|
||||
.bus = BUS0, .addr = SWPLD4_ADDR,
|
||||
.reg = 0x06, .mask = 1 << 3,
|
||||
.note = "“0” = SPI write operation is disabled\n“1” = SPI write operation is enabled"
|
||||
},
|
||||
[RJ45_CONSOLE_SEL] = {
|
||||
.bus = BUS0, .addr = SWPLD4_ADDR,
|
||||
.reg = 0x06, .mask = 1 << 2,
|
||||
.note = "“0” = Use BCM UART\n“1” = Use CPU UART"
|
||||
},
|
||||
[SYSTEM_INT] = {
|
||||
.bus = BUS0, .addr = SWPLD4_ADDR,
|
||||
.reg = 0x07, .mask = 1 << 2,
|
||||
.note = "“0” = Interrupt is asserted\n“1” = Interrupt is deasserted"
|
||||
},
|
||||
[CPLD_MB_RST_DONE] = {
|
||||
.bus = BUS0, .addr = SWPLD4_ADDR,
|
||||
.reg = 0x07, .mask = 1 << 1,
|
||||
.note = "“0” = Is done\n“1” = Is not done"
|
||||
},
|
||||
[MB_PWR_OK] = {
|
||||
.bus = BUS0, .addr = SWPLD4_ADDR,
|
||||
.reg = 0x07, .mask = 1 << 0,
|
||||
.note = "‘0’ = Power is failed\n‘1’ = Power is good"
|
||||
},
|
||||
[FAN_EEPROM_WP] = {
|
||||
.bus = BUS0, .addr = SWPLD4_ADDR,
|
||||
.reg = 0x15, .mask = 1 << 2,
|
||||
.note = "“1” = enables the lock-down mechanism.\n“0” = overrides the lock-down function enabling blocks to be erased or programmed using software commands."
|
||||
},
|
||||
};
|
@ -0,0 +1,860 @@
|
||||
#include "delta_ag9064_common.h"
|
||||
|
||||
#define QSFP_PRESENCE_1 0x03
|
||||
#define QSFP_PRESENCE_2 0x03
|
||||
#define QSFP_PRESENCE_3 0x24
|
||||
#define QSFP_PRESENCE_4 0x24
|
||||
#define QSFP_PRESENCE_5 0x04
|
||||
#define QSFP_PRESENCE_6 0x04
|
||||
#define QSFP_PRESENCE_7 0x25
|
||||
#define QSFP_PRESENCE_8 0x25
|
||||
|
||||
#define QSFP_LP_MODE_1 0x0c
|
||||
#define QSFP_LP_MODE_2 0x0c
|
||||
#define QSFP_LP_MODE_3 0x2a
|
||||
#define QSFP_LP_MODE_4 0x2a
|
||||
#define QSFP_LP_MODE_5 0x0d
|
||||
#define QSFP_LP_MODE_6 0x0d
|
||||
#define QSFP_LP_MODE_7 0x2b
|
||||
#define QSFP_LP_MODE_8 0x2b
|
||||
|
||||
#define QSFP_RESET_1 0x06
|
||||
#define QSFP_RESET_2 0x06
|
||||
#define QSFP_RESET_3 0x26
|
||||
#define QSFP_RESET_4 0x26
|
||||
#define QSFP_RESET_5 0x07
|
||||
#define QSFP_RESET_6 0x07
|
||||
#define QSFP_RESET_7 0x27
|
||||
#define QSFP_RESET_8 0x27
|
||||
|
||||
#define QSFP_RESPONSE_1 0x09
|
||||
#define QSFP_RESPONSE_2 0x09
|
||||
#define QSFP_RESPONSE_3 0x28
|
||||
#define QSFP_RESPONSE_4 0x28
|
||||
#define QSFP_RESPONSE_5 0x0a
|
||||
#define QSFP_RESPONSE_6 0x0a
|
||||
#define QSFP_RESPONSE_7 0x29
|
||||
#define QSFP_RESPONSE_8 0x29
|
||||
|
||||
#define QSFP_INTERRUPT_1 0x0f
|
||||
#define QSFP_INTERRUPT_2 0x0f
|
||||
#define QSFP_INTERRUPT_3 0x2c
|
||||
#define QSFP_INTERRUPT_4 0x2c
|
||||
#define QSFP_INTERRUPT_5 0x10
|
||||
#define QSFP_INTERRUPT_6 0x10
|
||||
#define QSFP_INTERRUPT_7 0x2d
|
||||
#define QSFP_INTERRUPT_8 0x2d
|
||||
|
||||
unsigned char cpupld_reg_addr;
|
||||
/*---------------- CPLD - start ------------- */
|
||||
/* CPLD -- device */
|
||||
static struct platform_device ag9064_cpld = {
|
||||
.name = "delta-ag9064-cpld",
|
||||
.id = 0,
|
||||
.dev = {
|
||||
.platform_data = ag9064_cpld_platform_data,
|
||||
.release = device_release
|
||||
},
|
||||
};
|
||||
|
||||
static ssize_t get_present(struct device *dev, struct device_attribute \
|
||||
*dev_attr, char *buf)
|
||||
{
|
||||
int ret;
|
||||
u64 data = 0;
|
||||
uint8_t cmd_data[4]={0};
|
||||
uint8_t set_cmd;
|
||||
int cmd_data_len;
|
||||
|
||||
set_cmd = CMD_GETDATA;
|
||||
|
||||
/*QSFP1~8*/
|
||||
cmd_data[0] = BMC_BUS_5;
|
||||
cmd_data[1] = SWPLD1_ADDR;
|
||||
cmd_data[2] = QSFP_PRESENCE_1;
|
||||
cmd_data[3] = 1;
|
||||
cmd_data_len = sizeof(cmd_data);
|
||||
ret = dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len);
|
||||
data = (u64)(ret & 0xff);
|
||||
|
||||
/*QSFP9~16*/
|
||||
cmd_data[1] = SWPLD2_ADDR;
|
||||
cmd_data[2] = QSFP_PRESENCE_2;
|
||||
ret = dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len);
|
||||
data |= (u64)(ret & 0xff) << 8;
|
||||
|
||||
/*QSFP17~24*/
|
||||
cmd_data[1] = SWPLD4_ADDR;
|
||||
cmd_data[2] = QSFP_PRESENCE_3;
|
||||
ret = dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len);
|
||||
data |= (u64)(ret & 0xff) << 16;
|
||||
|
||||
/*QSFP25~32*/
|
||||
cmd_data[1] = SWPLD3_ADDR;
|
||||
cmd_data[2] = QSFP_PRESENCE_4;
|
||||
ret = dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len);
|
||||
data |= (u64)(ret & 0xff) << 24;
|
||||
|
||||
/*QSFP33~40*/
|
||||
cmd_data[1] = SWPLD1_ADDR;
|
||||
cmd_data[2] = QSFP_PRESENCE_5;
|
||||
ret = dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len);
|
||||
data |= (u64)(ret & 0xff) << 32;
|
||||
|
||||
/*QSFP41~48*/
|
||||
cmd_data[1] = SWPLD2_ADDR;
|
||||
cmd_data[2] = QSFP_PRESENCE_6;
|
||||
ret = dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len);
|
||||
data |= (u64)(ret & 0xff) << 40;
|
||||
|
||||
/*QSFP49~56*/
|
||||
cmd_data[1] = SWPLD4_ADDR;
|
||||
cmd_data[2] = QSFP_PRESENCE_7;
|
||||
ret = dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len);
|
||||
data |= (u64)(ret & 0xff) << 48;
|
||||
|
||||
/*QSFP57~64*/
|
||||
cmd_data[1] = SWPLD3_ADDR;
|
||||
cmd_data[2] = QSFP_PRESENCE_8;
|
||||
ret = dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len);
|
||||
data |= (u64)(ret & 0xff) << 56;
|
||||
|
||||
return sprintf(buf, "0x%016llx\n", data);
|
||||
}
|
||||
|
||||
static ssize_t get_lpmode(struct device *dev, struct device_attribute \
|
||||
*dev_attr, char *buf)
|
||||
{
|
||||
int ret;
|
||||
u64 data = 0;
|
||||
uint8_t cmd_data[4]={0};
|
||||
uint8_t set_cmd;
|
||||
int cmd_data_len;
|
||||
|
||||
set_cmd = CMD_GETDATA;
|
||||
|
||||
/*QSFP1~8*/
|
||||
cmd_data[0] = BMC_BUS_5;
|
||||
cmd_data[1] = SWPLD1_ADDR;
|
||||
cmd_data[2] = QSFP_LP_MODE_1;
|
||||
cmd_data[3] = 1;
|
||||
cmd_data_len = sizeof(cmd_data);
|
||||
ret = dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len);
|
||||
data = (u64)(ret & 0xff);
|
||||
|
||||
/*QSFP9~16*/
|
||||
cmd_data[1] = SWPLD2_ADDR;
|
||||
cmd_data[2] = QSFP_LP_MODE_2;
|
||||
ret = dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len);
|
||||
data |= (u64)(ret & 0xff) << 8;
|
||||
|
||||
/*QSFP17~24*/
|
||||
cmd_data[1] = SWPLD4_ADDR;
|
||||
cmd_data[2] = QSFP_LP_MODE_3;
|
||||
ret = dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len);
|
||||
data |= (u64)(ret & 0xff) << 16;
|
||||
|
||||
/*QSFP25~32*/
|
||||
cmd_data[1] = SWPLD3_ADDR;
|
||||
cmd_data[2] = QSFP_LP_MODE_4;
|
||||
ret = dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len);
|
||||
data |= (u64)(ret & 0xff) << 24;
|
||||
|
||||
/*QSFP33~40*/
|
||||
cmd_data[1] = SWPLD1_ADDR;
|
||||
cmd_data[2] = QSFP_LP_MODE_5;
|
||||
ret = dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len);
|
||||
data |= (u64)(ret & 0xff) << 32;
|
||||
|
||||
/*QSFP41~48*/
|
||||
cmd_data[1] = SWPLD2_ADDR;
|
||||
cmd_data[2] = QSFP_LP_MODE_6;
|
||||
ret = dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len);
|
||||
data |= (u64)(ret & 0xff) << 40;
|
||||
|
||||
/*QSFP49~56*/
|
||||
cmd_data[1] = SWPLD4_ADDR;
|
||||
cmd_data[2] = QSFP_LP_MODE_7;
|
||||
ret = dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len);
|
||||
data |= (u64)(ret & 0xff) << 48;
|
||||
|
||||
/*QSFP57~64*/
|
||||
cmd_data[1] = SWPLD3_ADDR;
|
||||
cmd_data[2] = QSFP_LP_MODE_8;
|
||||
ret = dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len);
|
||||
data |= (u64)(ret & 0xff) << 56;
|
||||
|
||||
return sprintf(buf, "0x%016llx\n", data);
|
||||
}
|
||||
|
||||
static ssize_t get_reset(struct device *dev, struct device_attribute \
|
||||
*dev_attr, char *buf)
|
||||
{
|
||||
int ret;
|
||||
u64 data = 0;
|
||||
uint8_t cmd_data[4]={0};
|
||||
uint8_t set_cmd;
|
||||
int cmd_data_len;
|
||||
|
||||
set_cmd = CMD_GETDATA;
|
||||
|
||||
/*QSFP1~8*/
|
||||
cmd_data[0] = BMC_BUS_5;
|
||||
cmd_data[1] = SWPLD1_ADDR;
|
||||
cmd_data[2] = QSFP_RESET_1;
|
||||
cmd_data[3] = 1;
|
||||
cmd_data_len = sizeof(cmd_data);
|
||||
ret = dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len);
|
||||
data = (u64)(ret & 0xff);
|
||||
|
||||
/*QSFP9~16*/
|
||||
cmd_data[1] = SWPLD2_ADDR;
|
||||
cmd_data[2] = QSFP_RESET_2;
|
||||
ret = dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len);
|
||||
data |= (u64)(ret & 0xff) << 8;
|
||||
|
||||
/*QSFP17~24*/
|
||||
cmd_data[1] = SWPLD4_ADDR;
|
||||
cmd_data[2] = QSFP_RESET_3;
|
||||
ret = dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len);
|
||||
data |= (u64)(ret & 0xff) << 16;
|
||||
|
||||
/*QSFP25~32*/
|
||||
cmd_data[1] = SWPLD3_ADDR;
|
||||
cmd_data[2] = QSFP_RESET_4;
|
||||
ret = dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len);
|
||||
data |= (u64)(ret & 0xff) << 24;
|
||||
|
||||
/*QSFP33~40*/
|
||||
cmd_data[1] = SWPLD1_ADDR;
|
||||
cmd_data[2] = QSFP_RESET_5;
|
||||
ret = dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len);
|
||||
data |= (u64)(ret & 0xff) << 32;
|
||||
|
||||
/*QSFP41~48*/
|
||||
cmd_data[1] = SWPLD2_ADDR;
|
||||
cmd_data[2] = QSFP_RESET_6;
|
||||
ret = dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len);
|
||||
data |= (u64)(ret & 0xff) << 40;
|
||||
|
||||
/*QSFP49~56*/
|
||||
cmd_data[1] = SWPLD4_ADDR;
|
||||
cmd_data[2] = QSFP_RESET_7;
|
||||
ret = dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len);
|
||||
data |= (u64)(ret & 0xff) << 48;
|
||||
|
||||
/*QSFP57~64*/
|
||||
cmd_data[1] = SWPLD3_ADDR;
|
||||
cmd_data[2] = QSFP_RESET_8;
|
||||
ret = dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len);
|
||||
data |= (u64)(ret & 0xff) << 56;
|
||||
|
||||
return sprintf(buf, "0x%016llx\n", data);
|
||||
}
|
||||
|
||||
static ssize_t get_response(struct device *dev, struct device_attribute \
|
||||
*dev_attr, char *buf)
|
||||
{
|
||||
int ret;
|
||||
u64 data = 0;
|
||||
uint8_t cmd_data[4]={0};
|
||||
uint8_t set_cmd;
|
||||
int cmd_data_len;
|
||||
|
||||
set_cmd = CMD_GETDATA;
|
||||
|
||||
/*QSFP1~8*/
|
||||
cmd_data[0] = BMC_BUS_5;
|
||||
cmd_data[1] = SWPLD1_ADDR;
|
||||
cmd_data[2] = QSFP_RESPONSE_1;
|
||||
cmd_data[3] = 1;
|
||||
cmd_data_len = sizeof(cmd_data);
|
||||
ret = dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len);
|
||||
data = (u64)(ret & 0xff);
|
||||
|
||||
/*QSFP9~16*/
|
||||
cmd_data[1] = SWPLD2_ADDR;
|
||||
cmd_data[2] = QSFP_RESPONSE_2;
|
||||
ret = dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len);
|
||||
data |= (u64)(ret & 0xff) << 8;
|
||||
|
||||
/*QSFP17~24*/
|
||||
cmd_data[1] = SWPLD4_ADDR;
|
||||
cmd_data[2] = QSFP_RESPONSE_3;
|
||||
ret = dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len);
|
||||
data |= (u64)(ret & 0xff) << 16;
|
||||
|
||||
/*QSFP25~32*/
|
||||
cmd_data[1] = SWPLD3_ADDR;
|
||||
cmd_data[2] = QSFP_RESPONSE_4;
|
||||
ret = dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len);
|
||||
data |= (u64)(ret & 0xff) << 24;
|
||||
|
||||
/*QSFP33~40*/
|
||||
cmd_data[1] = SWPLD1_ADDR;
|
||||
cmd_data[2] = QSFP_RESPONSE_5;
|
||||
ret = dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len);
|
||||
data |= (u64)(ret & 0xff) << 32;
|
||||
|
||||
/*QSFP41~48*/
|
||||
cmd_data[1] = SWPLD2_ADDR;
|
||||
cmd_data[2] = QSFP_RESPONSE_6;
|
||||
ret = dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len);
|
||||
data |= (u64)(ret & 0xff) << 40;
|
||||
|
||||
/*QSFP49~56*/
|
||||
cmd_data[1] = SWPLD4_ADDR;
|
||||
cmd_data[2] = QSFP_RESPONSE_7;
|
||||
ret = dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len);
|
||||
data |= (u64)(ret & 0xff) << 48;
|
||||
|
||||
/*QSFP57~64*/
|
||||
cmd_data[1] = SWPLD3_ADDR;
|
||||
cmd_data[2] = QSFP_RESPONSE_8;
|
||||
ret = dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len);
|
||||
data |= (u64)(ret & 0xff) << 56;
|
||||
|
||||
return sprintf(buf, "0x%016llx\n", data);
|
||||
}
|
||||
|
||||
static ssize_t get_interrupt(struct device *dev, struct device_attribute \
|
||||
*dev_attr, char *buf)
|
||||
{
|
||||
int ret;
|
||||
u64 data = 0;
|
||||
uint8_t cmd_data[4]={0};
|
||||
uint8_t set_cmd;
|
||||
int cmd_data_len;
|
||||
|
||||
set_cmd = CMD_GETDATA;
|
||||
|
||||
/*QSFP1~8*/
|
||||
cmd_data[0] = BMC_BUS_5;
|
||||
cmd_data[1] = SWPLD1_ADDR;
|
||||
cmd_data[2] = QSFP_INTERRUPT_1;
|
||||
cmd_data[3] = 1;
|
||||
cmd_data_len = sizeof(cmd_data);
|
||||
ret = dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len);
|
||||
data = (u64)(ret & 0xff);
|
||||
|
||||
/*QSFP9~16*/
|
||||
cmd_data[1] = SWPLD2_ADDR;
|
||||
cmd_data[2] = QSFP_INTERRUPT_2;
|
||||
ret = dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len);
|
||||
data |= (u64)(ret & 0xff) << 8;
|
||||
|
||||
/*QSFP17~24*/
|
||||
cmd_data[1] = SWPLD4_ADDR;
|
||||
cmd_data[2] = QSFP_INTERRUPT_3;
|
||||
ret = dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len);
|
||||
data |= (u64)(ret & 0xff) << 16;
|
||||
|
||||
/*QSFP25~32*/
|
||||
cmd_data[1] = SWPLD3_ADDR;
|
||||
cmd_data[2] = QSFP_INTERRUPT_4;
|
||||
ret = dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len);
|
||||
data |= (u64)(ret & 0xff) << 24;
|
||||
|
||||
/*QSFP33~40*/
|
||||
cmd_data[1] = SWPLD1_ADDR;
|
||||
cmd_data[2] = QSFP_INTERRUPT_5;
|
||||
ret = dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len);
|
||||
data |= (u64)(ret & 0xff) << 32;
|
||||
|
||||
/*QSFP41~48*/
|
||||
cmd_data[1] = SWPLD2_ADDR;
|
||||
cmd_data[2] = QSFP_INTERRUPT_6;
|
||||
ret = dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len);
|
||||
data |= (u64)(ret & 0xff) << 40;
|
||||
|
||||
/*QSFP49~56*/
|
||||
cmd_data[1] = SWPLD4_ADDR;
|
||||
cmd_data[2] = QSFP_INTERRUPT_7;
|
||||
ret = dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len);
|
||||
data |= (u64)(ret & 0xff) << 48;
|
||||
|
||||
/*QSFP57~64*/
|
||||
cmd_data[1] = SWPLD3_ADDR;
|
||||
cmd_data[2] = QSFP_INTERRUPT_8;
|
||||
ret = dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len);
|
||||
data |= (u64)(ret & 0xff) << 56;
|
||||
|
||||
return sprintf(buf, "0x%016llx\n", data);
|
||||
}
|
||||
|
||||
static ssize_t set_lpmode(struct device *dev, struct device_attribute *devattr, const char *buf, size_t count)
|
||||
{
|
||||
unsigned long long set_data;
|
||||
int err;
|
||||
|
||||
err = kstrtoull(buf, 16, &set_data);
|
||||
if (err){
|
||||
return err;
|
||||
}
|
||||
uint8_t cmd_data[4]={0};
|
||||
uint8_t set_cmd;
|
||||
int cmd_data_len;
|
||||
|
||||
set_cmd = CMD_SETDATA;
|
||||
/*QSFP1~8*/
|
||||
cmd_data[0] = BMC_BUS_5;
|
||||
cmd_data[1] = SWPLD1_ADDR;
|
||||
cmd_data[2] = QSFP_LP_MODE_1;
|
||||
cmd_data[3] = (set_data & 0xff);
|
||||
cmd_data_len = sizeof(cmd_data);
|
||||
dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len);
|
||||
|
||||
/*QSFP9~16*/
|
||||
cmd_data[1] = SWPLD2_ADDR;
|
||||
cmd_data[2] = QSFP_LP_MODE_2;
|
||||
cmd_data[3] = ((set_data >> 8 ) & 0xff);
|
||||
dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len);
|
||||
|
||||
/*QSFP17~24*/
|
||||
cmd_data[1] = SWPLD4_ADDR;
|
||||
cmd_data[2] = QSFP_LP_MODE_3;
|
||||
cmd_data[3] = ((set_data >> 16 ) & 0xff);
|
||||
dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len);
|
||||
|
||||
/*QSFP25~32*/
|
||||
cmd_data[1] = SWPLD3_ADDR;
|
||||
cmd_data[2] = QSFP_LP_MODE_4;
|
||||
cmd_data[3] = ((set_data >> 24 ) & 0xff);
|
||||
dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len);
|
||||
|
||||
/*QSFP33~40*/
|
||||
cmd_data[1] = SWPLD1_ADDR;
|
||||
cmd_data[2] = QSFP_LP_MODE_5;
|
||||
cmd_data[3] = ((set_data >> 32 ) & 0xff);
|
||||
dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len);
|
||||
|
||||
/*QSFP41~48*/
|
||||
cmd_data[1] = SWPLD2_ADDR;
|
||||
cmd_data[2] = QSFP_LP_MODE_6;
|
||||
cmd_data[3] = ((set_data >> 40 ) & 0xff);
|
||||
dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len);
|
||||
|
||||
/*QSFP49~56*/
|
||||
cmd_data[1] = SWPLD4_ADDR;
|
||||
cmd_data[2] = QSFP_LP_MODE_7;
|
||||
cmd_data[3] = ((set_data >> 48 ) & 0xff);
|
||||
dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len);
|
||||
|
||||
/*QSFP57~64*/
|
||||
cmd_data[1] = SWPLD3_ADDR;
|
||||
cmd_data[2] = QSFP_LP_MODE_8;
|
||||
cmd_data[3] = ((set_data >> 56 ) & 0xff);
|
||||
dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len);
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
static ssize_t set_reset(struct device *dev, struct device_attribute *devattr, const char *buf, size_t count)
|
||||
{
|
||||
unsigned long long set_data;
|
||||
int err;
|
||||
|
||||
err = kstrtoull(buf, 16, &set_data);
|
||||
if (err){
|
||||
return err;
|
||||
}
|
||||
uint8_t cmd_data[4]={0};
|
||||
uint8_t set_cmd;
|
||||
int cmd_data_len;
|
||||
|
||||
set_cmd = CMD_SETDATA;
|
||||
|
||||
/*QSFP1~8*/
|
||||
cmd_data[0] = BMC_BUS_5;
|
||||
cmd_data[1] = SWPLD1_ADDR;
|
||||
cmd_data[2] = QSFP_RESET_1;
|
||||
cmd_data[3] = (set_data & 0xff);
|
||||
cmd_data_len = sizeof(cmd_data);
|
||||
dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len);
|
||||
|
||||
/*QSFP9~16*/
|
||||
cmd_data[1] = SWPLD2_ADDR;
|
||||
cmd_data[2] = QSFP_RESET_2;
|
||||
cmd_data[3] = ((set_data >> 8 ) & 0xff);
|
||||
dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len);
|
||||
|
||||
/*QSFP17~24*/
|
||||
cmd_data[1] = SWPLD4_ADDR;
|
||||
cmd_data[2] = QSFP_RESET_3;
|
||||
cmd_data[3] = ((set_data >> 16 ) & 0xff);
|
||||
dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len);
|
||||
|
||||
/*QSFP25~32*/
|
||||
cmd_data[1] = SWPLD3_ADDR;
|
||||
cmd_data[2] = QSFP_RESET_4;
|
||||
cmd_data[3] = ((set_data >> 24 ) & 0xff);
|
||||
dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len);
|
||||
|
||||
/*QSFP33~40*/
|
||||
cmd_data[1] = SWPLD1_ADDR;
|
||||
cmd_data[2] = QSFP_RESET_5;
|
||||
cmd_data[3] = ((set_data >> 32 ) & 0xff);
|
||||
dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len);
|
||||
|
||||
/*QSFP41~48*/
|
||||
cmd_data[1] = SWPLD2_ADDR;
|
||||
cmd_data[2] = QSFP_RESET_6;
|
||||
cmd_data[3] = ((set_data >> 40 ) & 0xff);
|
||||
dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len);
|
||||
|
||||
/*QSFP49~56*/
|
||||
cmd_data[1] = SWPLD4_ADDR;
|
||||
cmd_data[2] = QSFP_RESET_7;
|
||||
cmd_data[3] = ((set_data >> 48 ) & 0xff);
|
||||
dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len);
|
||||
|
||||
/*QSFP57~64*/
|
||||
cmd_data[1] = SWPLD3_ADDR;
|
||||
cmd_data[2] = QSFP_RESET_8;
|
||||
cmd_data[3] = ((set_data >> 56 ) & 0xff);
|
||||
dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len);
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
static ssize_t set_response(struct device *dev, struct device_attribute *devattr, const char *buf, size_t count)
|
||||
{
|
||||
unsigned long long set_data;
|
||||
int err;
|
||||
|
||||
err = kstrtoull(buf, 16, &set_data);
|
||||
if (err){
|
||||
return err;
|
||||
}
|
||||
uint8_t cmd_data[4]={0};
|
||||
uint8_t set_cmd;
|
||||
int cmd_data_len;
|
||||
|
||||
set_cmd = CMD_SETDATA;
|
||||
|
||||
/*QSFP1~8*/
|
||||
cmd_data[0] = BMC_BUS_5;
|
||||
cmd_data[1] = SWPLD1_ADDR;
|
||||
cmd_data[2] = QSFP_RESPONSE_1;
|
||||
cmd_data[3] = (set_data & 0xff);
|
||||
cmd_data_len = sizeof(cmd_data);
|
||||
dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len);
|
||||
|
||||
/*QSFP9~16*/
|
||||
cmd_data[1] = SWPLD2_ADDR;
|
||||
cmd_data[2] = QSFP_RESPONSE_2;
|
||||
cmd_data[3] = ((set_data >> 8 ) & 0xff);
|
||||
dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len);
|
||||
|
||||
/*QSFP17~24*/
|
||||
cmd_data[1] = SWPLD4_ADDR;
|
||||
cmd_data[2] = QSFP_RESPONSE_3;
|
||||
cmd_data[3] = ((set_data >> 16 ) & 0xff);
|
||||
dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len);
|
||||
|
||||
/*QSFP25~32*/
|
||||
cmd_data[1] = SWPLD3_ADDR;
|
||||
cmd_data[2] = QSFP_RESPONSE_4;
|
||||
cmd_data[3] = ((set_data >> 24 ) & 0xff);
|
||||
dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len);
|
||||
|
||||
/*QSFP33~40*/
|
||||
cmd_data[1] = SWPLD1_ADDR;
|
||||
cmd_data[2] = QSFP_RESPONSE_5;
|
||||
cmd_data[3] = ((set_data >> 32 ) & 0xff);
|
||||
dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len);
|
||||
|
||||
/*QSFP41~48*/
|
||||
cmd_data[1] = SWPLD2_ADDR;
|
||||
cmd_data[2] = QSFP_RESPONSE_6;
|
||||
cmd_data[3] = ((set_data >> 40 ) & 0xff);
|
||||
dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len);
|
||||
|
||||
/*QSFP49~56*/
|
||||
cmd_data[1] = SWPLD4_ADDR;
|
||||
cmd_data[2] = QSFP_RESPONSE_7;
|
||||
cmd_data[3] = ((set_data >> 48 ) & 0xff);
|
||||
dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len);
|
||||
|
||||
/*QSFP57~64*/
|
||||
cmd_data[1] = SWPLD3_ADDR;
|
||||
cmd_data[2] = QSFP_RESPONSE_8;
|
||||
cmd_data[3] = ((set_data >> 56 ) & 0xff);
|
||||
dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len);
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
static ssize_t get_cpld_reg(struct device *dev, struct device_attribute *dev_attr, char *buf)
|
||||
{
|
||||
int ret;
|
||||
int mask;
|
||||
int value;
|
||||
char note[200];
|
||||
unsigned char reg;
|
||||
struct sensor_device_attribute *attr = to_sensor_dev_attr(dev_attr);
|
||||
struct cpld_platform_data *pdata = dev->platform_data;
|
||||
|
||||
switch (attr->index) {
|
||||
case CPLD_REG_ADDR:
|
||||
return sprintf(buf, "0x%02x\n", cpupld_reg_addr);
|
||||
case CPLD_REG_VALUE:
|
||||
ret = i2c_smbus_read_byte_data(pdata[system_cpld].client, cpupld_reg_addr);
|
||||
return sprintf(buf, "0x%02x\n", ret);
|
||||
case CPLD_VER ... OP_MODULE_INT:
|
||||
reg = attribute_data[attr->index].reg;
|
||||
mask = attribute_data[attr->index].mask;
|
||||
value = i2c_smbus_read_byte_data(pdata[system_cpld].client, reg);
|
||||
sprintf(note, "\n%s\n",attribute_data[attr->index].note);
|
||||
value = (value & mask);
|
||||
break;
|
||||
default:
|
||||
return sprintf(buf, "%d not found", attr->index);
|
||||
}
|
||||
|
||||
switch (mask) {
|
||||
case 0xFF:
|
||||
return sprintf(buf, "0x%02x%s", value, note);
|
||||
case 0x0F:
|
||||
return sprintf(buf, "0x%01x%s", value, note);
|
||||
case 0xF0:
|
||||
value = value >> 4;
|
||||
return sprintf(buf, "0x%01x%s", value, note);
|
||||
default :
|
||||
value = value >> dni_log2(mask);
|
||||
return sprintf(buf, "%d%s", value, note);
|
||||
}
|
||||
}
|
||||
|
||||
static ssize_t set_cpld_reg(struct device *dev, struct device_attribute *dev_attr,
|
||||
const char *buf, size_t count)
|
||||
{
|
||||
int err;
|
||||
int value;
|
||||
int set_data;
|
||||
unsigned char reg;
|
||||
unsigned char mask;
|
||||
unsigned char mask_out;
|
||||
|
||||
struct sensor_device_attribute *attr = to_sensor_dev_attr(dev_attr);
|
||||
struct cpld_platform_data *pdata = dev->platform_data;
|
||||
|
||||
err = kstrtoul(buf, 0, &set_data);
|
||||
if (err){
|
||||
return err;
|
||||
}
|
||||
|
||||
if (set_data > 0xff){
|
||||
printk(KERN_ALERT "address out of range (0x00-0xFF)\n");
|
||||
return count;
|
||||
}
|
||||
|
||||
switch (attr->index) {
|
||||
case CPLD_REG_ADDR:
|
||||
cpupld_reg_addr = set_data;
|
||||
return count;
|
||||
case CPLD_REG_VALUE:
|
||||
i2c_smbus_write_byte_data(pdata[system_cpld].client, cpupld_reg_addr, set_data);
|
||||
return count;
|
||||
case CPLD_VER ... OP_MODULE_INT:
|
||||
reg = attribute_data[attr->index].reg;
|
||||
mask = attribute_data[attr->index].mask;
|
||||
value = i2c_smbus_read_byte_data(pdata[system_cpld].client, reg);
|
||||
mask_out = value & ~(mask);
|
||||
break;
|
||||
default:
|
||||
return sprintf(buf, "%d not found", attr->index);
|
||||
}
|
||||
|
||||
switch (mask) {
|
||||
case 0xFF:
|
||||
set_data = mask_out | (set_data & mask);
|
||||
break;
|
||||
case 0x0F:
|
||||
set_data = mask_out | (set_data & mask);
|
||||
break;
|
||||
case 0xF0:
|
||||
set_data = set_data << 4;
|
||||
set_data = mask_out | (set_data & mask);
|
||||
break;
|
||||
default :
|
||||
set_data = mask_out | (set_data << dni_log2(mask) );
|
||||
}
|
||||
|
||||
i2c_smbus_write_byte_data(pdata[system_cpld].client, reg, set_data);
|
||||
return count;
|
||||
}
|
||||
|
||||
static DEVICE_ATTR(qsfp_present, S_IRUGO, get_present, NULL);
|
||||
static DEVICE_ATTR(qsfp_lpmode, S_IWUSR | S_IRUGO, get_lpmode, set_lpmode);
|
||||
static DEVICE_ATTR(qsfp_reset, S_IWUSR | S_IRUGO, get_reset, set_reset);
|
||||
static DEVICE_ATTR(qsfp_modsel, S_IWUSR | S_IRUGO, get_response, set_response);
|
||||
static DEVICE_ATTR(qsfp_interrupt, S_IRUGO, get_interrupt, NULL);
|
||||
|
||||
static SENSOR_DEVICE_ATTR(cpld_reg_addr, S_IRUGO | S_IWUSR, get_cpld_reg, set_cpld_reg, CPLD_REG_ADDR);
|
||||
static SENSOR_DEVICE_ATTR(cpld_reg_value, S_IRUGO | S_IWUSR, get_cpld_reg, set_cpld_reg, CPLD_REG_VALUE);
|
||||
static SENSOR_DEVICE_ATTR(cpld_ver, S_IRUGO, get_cpld_reg, NULL, CPLD_VER);
|
||||
static SENSOR_DEVICE_ATTR(cpu_board_ver, S_IRUGO, get_cpld_reg, NULL, CPU_BOARD_VER);
|
||||
static SENSOR_DEVICE_ATTR(cpu_id, S_IRUGO, get_cpld_reg, NULL, CPU_ID);
|
||||
static SENSOR_DEVICE_ATTR(mb_id, S_IRUGO, get_cpld_reg, NULL, MB_ID);
|
||||
static SENSOR_DEVICE_ATTR(mb_ver, S_IRUGO, get_cpld_reg, NULL, MB_VER);
|
||||
static SENSOR_DEVICE_ATTR(cpu0_pwr_ok, S_IRUGO, get_cpld_reg, NULL, CPU0_PWR_OK);
|
||||
static SENSOR_DEVICE_ATTR(psu_over_temp, S_IRUGO, get_cpld_reg, NULL, PSU_OVER_TEMP);
|
||||
static SENSOR_DEVICE_ATTR(pwr_rail_over_temp, S_IRUGO, get_cpld_reg, NULL, PWR_RAIL_OVER_TEMP);
|
||||
static SENSOR_DEVICE_ATTR(cpu_disomic_over_temp, S_IRUGO, get_cpld_reg, NULL, CPU_DISOMIC_OVER_TEMP);
|
||||
static SENSOR_DEVICE_ATTR(ddr_over_temp, S_IRUGO, get_cpld_reg, NULL, DDR_OVER_TEMP);
|
||||
static SENSOR_DEVICE_ATTR(cpld_pwr_on_rst, S_IRUGO, get_cpld_reg, NULL, CPLD_PWR_ON_RST);
|
||||
static SENSOR_DEVICE_ATTR(cpld_hard_rst, S_IRUGO, get_cpld_reg, NULL, CPLD_HARD_RST);
|
||||
static SENSOR_DEVICE_ATTR(cpld_rst, S_IRUGO | S_IWUSR, get_cpld_reg, set_cpld_reg, CPLD_RST);
|
||||
static SENSOR_DEVICE_ATTR(mb_pwr, S_IRUGO, get_cpld_reg, NULL, MB_PWR);
|
||||
static SENSOR_DEVICE_ATTR(mb_rst, S_IRUGO | S_IWUSR, get_cpld_reg, set_cpld_reg, MB_RST);
|
||||
static SENSOR_DEVICE_ATTR(psu_fan_int, S_IRUGO, get_cpld_reg, NULL, PSU_FAN_INT);
|
||||
static SENSOR_DEVICE_ATTR(op_module_int, S_IRUGO, get_cpld_reg, NULL, OP_MODULE_INT);
|
||||
|
||||
static struct attribute *ag9064_cpld_attrs[] = {
|
||||
&dev_attr_qsfp_present.attr,
|
||||
&dev_attr_qsfp_lpmode.attr,
|
||||
&dev_attr_qsfp_reset.attr,
|
||||
&dev_attr_qsfp_modsel.attr,
|
||||
&dev_attr_qsfp_interrupt.attr,
|
||||
&sensor_dev_attr_cpld_reg_value.dev_attr.attr,
|
||||
&sensor_dev_attr_cpld_reg_addr.dev_attr.attr,
|
||||
&sensor_dev_attr_cpld_ver.dev_attr.attr,
|
||||
&sensor_dev_attr_cpu_board_ver.dev_attr.attr,
|
||||
&sensor_dev_attr_cpu_id.dev_attr.attr,
|
||||
&sensor_dev_attr_mb_id.dev_attr.attr,
|
||||
&sensor_dev_attr_mb_ver.dev_attr.attr,
|
||||
&sensor_dev_attr_cpu0_pwr_ok.dev_attr.attr,
|
||||
&sensor_dev_attr_psu_over_temp.dev_attr.attr,
|
||||
&sensor_dev_attr_pwr_rail_over_temp.dev_attr.attr,
|
||||
&sensor_dev_attr_cpu_disomic_over_temp.dev_attr.attr,
|
||||
&sensor_dev_attr_ddr_over_temp.dev_attr.attr,
|
||||
&sensor_dev_attr_cpld_pwr_on_rst.dev_attr.attr,
|
||||
&sensor_dev_attr_cpld_hard_rst.dev_attr.attr,
|
||||
&sensor_dev_attr_cpld_rst.dev_attr.attr,
|
||||
&sensor_dev_attr_mb_pwr.dev_attr.attr,
|
||||
&sensor_dev_attr_mb_rst.dev_attr.attr,
|
||||
&sensor_dev_attr_psu_fan_int.dev_attr.attr,
|
||||
&sensor_dev_attr_op_module_int.dev_attr.attr,
|
||||
NULL,
|
||||
};
|
||||
|
||||
static struct attribute_group ag9064_cpld_attr_grp = {
|
||||
.attrs = ag9064_cpld_attrs,
|
||||
};
|
||||
|
||||
static int __init cpld_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct cpld_platform_data *pdata;
|
||||
struct i2c_adapter *parent;
|
||||
int ret;
|
||||
|
||||
pdata = pdev->dev.platform_data;
|
||||
if (!pdata) {
|
||||
dev_err(&pdev->dev, "CPLD platform data not found\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
parent = i2c_get_adapter(BUS7);
|
||||
if (!parent) {
|
||||
printk(KERN_WARNING "Parent adapter (%d) not found\n",BUS7);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
pdata[system_cpld].client = i2c_new_dummy(parent, pdata[system_cpld].reg_addr);
|
||||
if (!pdata[system_cpld].client) {
|
||||
printk(KERN_WARNING "Fail to create dummy i2c client for addr %d\n", pdata[system_cpld].reg_addr);
|
||||
goto error;
|
||||
}
|
||||
|
||||
ret = sysfs_create_group(&pdev->dev.kobj, &ag9064_cpld_attr_grp);
|
||||
if (ret) {
|
||||
printk(KERN_WARNING "Fail to create cpld attribute group");
|
||||
goto error;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
error:
|
||||
i2c_unregister_device(pdata[system_cpld].client);
|
||||
i2c_put_adapter(parent);
|
||||
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
static int __exit cpld_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct i2c_adapter *parent = NULL;
|
||||
struct cpld_platform_data *pdata = pdev->dev.platform_data;
|
||||
sysfs_remove_group(&pdev->dev.kobj, &ag9064_cpld_attr_grp);
|
||||
|
||||
if (!pdata) {
|
||||
dev_err(&pdev->dev, "Missing platform data\n");
|
||||
}
|
||||
else {
|
||||
if (pdata[system_cpld].client) {
|
||||
if (!parent) {
|
||||
parent = (pdata[system_cpld].client)->adapter;
|
||||
}
|
||||
i2c_unregister_device(pdata[system_cpld].client);
|
||||
}
|
||||
}
|
||||
i2c_put_adapter(parent);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct platform_driver cpld_driver = {
|
||||
.probe = cpld_probe,
|
||||
.remove = __exit_p(cpld_remove),
|
||||
.driver = {
|
||||
.owner = THIS_MODULE,
|
||||
.name = "delta-ag9064-cpld",
|
||||
},
|
||||
};
|
||||
|
||||
/*---------------- CPLD - end ------------- */
|
||||
|
||||
/*---------------- module initialization ------------- */
|
||||
static void __init delta_ag9064_cpupld_init(void)
|
||||
{
|
||||
int ret;
|
||||
printk(KERN_WARNING "ag9064_platform_cpupld module initialization\n");
|
||||
|
||||
ret = dni_create_user();
|
||||
if (ret != 0){
|
||||
printk(KERN_WARNING "Fail to create IPMI user\n");
|
||||
}
|
||||
|
||||
// set the CPUPLD prob and remove
|
||||
ret = platform_driver_register(&cpld_driver);
|
||||
if (ret) {
|
||||
printk(KERN_WARNING "Fail to register cpupld driver\n");
|
||||
goto error_cpupld_driver;
|
||||
}
|
||||
|
||||
// register the CPUPLD
|
||||
ret = platform_device_register(&ag9064_cpld);
|
||||
if (ret) {
|
||||
printk(KERN_WARNING "Fail to create cpupld device\n");
|
||||
goto error_ag9064_cpupld;
|
||||
}
|
||||
return 0;
|
||||
|
||||
error_ag9064_cpupld:
|
||||
platform_driver_unregister(&cpld_driver);
|
||||
error_cpupld_driver:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void __exit delta_ag9064_cpupld_exit(void)
|
||||
{
|
||||
platform_device_unregister(&ag9064_cpld);
|
||||
platform_driver_unregister(&cpld_driver);
|
||||
}
|
||||
module_init(delta_ag9064_cpupld_init);
|
||||
module_exit(delta_ag9064_cpupld_exit);
|
||||
|
||||
MODULE_DESCRIPTION("DNI ag9064 CPLD Platform Support");
|
||||
MODULE_AUTHOR("Stanley Chi <stanley.chi@deltaww.com>");
|
||||
MODULE_LICENSE("GPL");
|
@ -1,86 +1,14 @@
|
||||
#include <linux/device.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/sysfs.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/dmi.h>
|
||||
#include <linux/version.h>
|
||||
#include <linux/ctype.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/i2c/pca954x.h>
|
||||
#include <linux/i2c-mux.h>
|
||||
#include <linux/i2c-mux-gpio.h>
|
||||
#include <linux/i2c/sff-8436.h>
|
||||
#include <linux/hwmon.h>
|
||||
|
||||
#include <linux/mutex.h>
|
||||
#include <linux/completion.h>
|
||||
#include <linux/ipmi.h>
|
||||
#include <linux/ipmi_smi.h>
|
||||
|
||||
#define DEFAULT_NUM 1
|
||||
#define BUS9_DEV_NUM 64
|
||||
#define BUS9_BASE_NUM 20
|
||||
|
||||
#define IPMI_MAX_INTF (4)
|
||||
#define DELTA_NETFN 0x38
|
||||
#define BMC_BUS_5 0x04
|
||||
#define CMD_SETDATA 0x3
|
||||
#define CMD_GETDATA 0x2
|
||||
|
||||
#define CPLD_REG 0x31
|
||||
#define SWPLD1_ADDR 0x35
|
||||
#define SWPLD2_ADDR 0x34
|
||||
#define SWPLD3_ADDR 0x33
|
||||
#define SWPLD4_ADDR 0x32
|
||||
#define QSFP_PORT_MUX_REG 0x13
|
||||
|
||||
#define QSFP_PRESENCE_1 0x3
|
||||
#define QSFP_PRESENCE_2 0x3
|
||||
#define QSFP_PRESENCE_3 0x24
|
||||
#define QSFP_PRESENCE_4 0x24
|
||||
#define QSFP_PRESENCE_5 0x4
|
||||
#define QSFP_PRESENCE_6 0x4
|
||||
#define QSFP_PRESENCE_7 0x25
|
||||
#define QSFP_PRESENCE_8 0x25
|
||||
|
||||
#define QSFP_LP_MODE_1 0x0c
|
||||
#define QSFP_LP_MODE_2 0x0c
|
||||
#define QSFP_LP_MODE_3 0x2a
|
||||
#define QSFP_LP_MODE_4 0x2a
|
||||
#define QSFP_LP_MODE_5 0x0d
|
||||
#define QSFP_LP_MODE_6 0x0d
|
||||
#define QSFP_LP_MODE_7 0x2b
|
||||
#define QSFP_LP_MODE_8 0x2b
|
||||
|
||||
#define QSFP_RESET_1 0x06
|
||||
#define QSFP_RESET_2 0x06
|
||||
#define QSFP_RESET_3 0x26
|
||||
#define QSFP_RESET_4 0x26
|
||||
#define QSFP_RESET_5 0x07
|
||||
#define QSFP_RESET_6 0x07
|
||||
#define QSFP_RESET_7 0x27
|
||||
#define QSFP_RESET_8 0x27
|
||||
|
||||
#define QSFP_RESPONSE_1 0x09
|
||||
#define QSFP_RESPONSE_2 0x09
|
||||
#define QSFP_RESPONSE_3 0x28
|
||||
#define QSFP_RESPONSE_4 0x28
|
||||
#define QSFP_RESPONSE_5 0x0a
|
||||
#define QSFP_RESPONSE_6 0x0a
|
||||
#define QSFP_RESPONSE_7 0x29
|
||||
#define QSFP_RESPONSE_8 0x29
|
||||
|
||||
#define QSFP_INTERRUPT_1 0x0f
|
||||
#define QSFP_INTERRUPT_2 0x0f
|
||||
#define QSFP_INTERRUPT_3 0x2c
|
||||
#define QSFP_INTERRUPT_4 0x2c
|
||||
#define QSFP_INTERRUPT_5 0x10
|
||||
#define QSFP_INTERRUPT_6 0x10
|
||||
#define QSFP_INTERRUPT_7 0x2d
|
||||
#define QSFP_INTERRUPT_8 0x2d
|
||||
#include "delta_ag9064_common.h"
|
||||
|
||||
#define SFF8436_INFO(data) \
|
||||
.type = "sff8436", .addr = 0x50, .platform_data = (data)
|
||||
@ -97,56 +25,8 @@
|
||||
}, \
|
||||
}
|
||||
|
||||
|
||||
static void msg_handler(struct ipmi_recv_msg *recv_msg,void* handler_data)
|
||||
{
|
||||
struct completion *comp = recv_msg->user_msg_data;
|
||||
if (comp)
|
||||
complete(comp);
|
||||
else
|
||||
ipmi_free_recv_msg(recv_msg);
|
||||
return;
|
||||
}
|
||||
|
||||
static ipmi_user_t ipmi_mh_user = NULL;
|
||||
static struct ipmi_user_hndl ipmi_hndlrs = { .ipmi_recv_hndl = msg_handler,};
|
||||
|
||||
static atomic_t dummy_count = ATOMIC_INIT(0);
|
||||
static void dummy_smi_free(struct ipmi_smi_msg *msg)
|
||||
{
|
||||
atomic_dec(&dummy_count);
|
||||
}
|
||||
static void dummy_recv_free(struct ipmi_recv_msg *msg)
|
||||
{
|
||||
atomic_dec(&dummy_count);
|
||||
}
|
||||
static struct ipmi_smi_msg halt_smi_msg = {
|
||||
.done = dummy_smi_free
|
||||
};
|
||||
static struct ipmi_recv_msg halt_recv_msg = {
|
||||
.done = dummy_recv_free
|
||||
};
|
||||
|
||||
struct i2c_client * i2c_client_9548;
|
||||
|
||||
enum{
|
||||
BUS0 = 0,
|
||||
BUS1,
|
||||
BUS2,
|
||||
BUS3,
|
||||
BUS4,
|
||||
BUS5,
|
||||
BUS6,
|
||||
BUS7,
|
||||
BUS8,
|
||||
BUS9,
|
||||
BUS10,
|
||||
BUS11,
|
||||
BUS12,
|
||||
BUS13,
|
||||
BUS14,
|
||||
};
|
||||
|
||||
/* pca9548 - add 8 bus */
|
||||
static struct pca954x_platform_mode pca954x_mode[] =
|
||||
{
|
||||
@ -265,8 +145,45 @@ static struct sff_8436_platform_data sff_8436_port[] = {
|
||||
{ SFF_8346_PORT() },
|
||||
};
|
||||
|
||||
/*---------------- IPMI - start ------------- */
|
||||
void device_release(struct device *dev)
|
||||
{
|
||||
return;
|
||||
}
|
||||
EXPORT_SYMBOL(device_release);
|
||||
|
||||
void msg_handler(struct ipmi_recv_msg *recv_msg, void* handler_data)
|
||||
{
|
||||
struct completion *comp = recv_msg->user_msg_data;
|
||||
if (comp)
|
||||
complete(comp);
|
||||
else
|
||||
ipmi_free_recv_msg(recv_msg);
|
||||
return;
|
||||
}
|
||||
EXPORT_SYMBOL(msg_handler);
|
||||
|
||||
void dummy_smi_free(struct ipmi_smi_msg *msg)
|
||||
{
|
||||
atomic_dec(&dummy_count);
|
||||
}
|
||||
EXPORT_SYMBOL(dummy_smi_free);
|
||||
|
||||
void dummy_recv_free(struct ipmi_recv_msg *msg)
|
||||
{
|
||||
atomic_dec(&dummy_count);
|
||||
}
|
||||
EXPORT_SYMBOL(dummy_recv_free);
|
||||
|
||||
unsigned char dni_log2 (unsigned char num){
|
||||
unsigned char num_log2 = 0;
|
||||
while(num > 0){
|
||||
num = num >> 1;
|
||||
num_log2 += 1;
|
||||
}
|
||||
return num_log2 -1;
|
||||
}
|
||||
EXPORT_SYMBOL(dni_log2);
|
||||
/*---------------- IPMI - start ------------- */
|
||||
int dni_create_user(void)
|
||||
{
|
||||
int rv, i;
|
||||
@ -281,6 +198,7 @@ int dni_create_user(void)
|
||||
return rv;
|
||||
}
|
||||
}
|
||||
EXPORT_SYMBOL(dni_create_user);
|
||||
|
||||
int dni_bmc_cmd(char set_cmd, char *cmd_data, int cmd_data_len)
|
||||
{
|
||||
@ -299,7 +217,7 @@ int dni_bmc_cmd(char set_cmd, char *cmd_data, int cmd_data_len)
|
||||
msg.data = cmd_data;
|
||||
|
||||
init_completion(&comp);
|
||||
rv = ipmi_request_supply_msgs(ipmi_mh_user, (struct ipmi_addr*)&addr, 0,&msg, &comp, &halt_smi_msg, &halt_recv_msg, 0);
|
||||
rv = ipmi_request_supply_msgs(ipmi_mh_user, (struct ipmi_addr*)&addr, 0, &msg, &comp, &halt_smi_msg, &halt_recv_msg, 0);
|
||||
if (rv) {
|
||||
return -6;
|
||||
}
|
||||
@ -334,16 +252,11 @@ int dni_bmc_cmd(char set_cmd, char *cmd_data, int cmd_data_len)
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL(dni_bmc_cmd);
|
||||
/*---------------- IPMI - stop ------------- */
|
||||
|
||||
/*---------------- I2C device - start ------------- */
|
||||
|
||||
static void device_release(struct device *dev)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
struct i2c_device_platform_data {
|
||||
int parent;
|
||||
struct i2c_board_info info;
|
||||
@ -1014,7 +927,6 @@ alloc_failed:
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static int __exit swpld_mux_remove(struct platform_device *pdev)
|
||||
{
|
||||
int i;
|
||||
@ -1063,657 +975,8 @@ static struct platform_driver swpld_mux_driver = {
|
||||
.name = "delta-ag9064-swpld-mux",
|
||||
},
|
||||
};
|
||||
|
||||
/*---------------- MUX - end ------------- */
|
||||
|
||||
/*---------------- CPLD - start ------------- */
|
||||
|
||||
/* CPLD -- device */
|
||||
|
||||
static ssize_t get_present(struct device *dev, struct device_attribute \
|
||||
*dev_attr, char *buf)
|
||||
{
|
||||
int ret;
|
||||
u64 data = 0;
|
||||
uint8_t cmd_data[4]={0};
|
||||
uint8_t set_cmd;
|
||||
int cmd_data_len;
|
||||
|
||||
set_cmd = CMD_GETDATA;
|
||||
|
||||
/*QSFP1~8*/
|
||||
cmd_data[0] = BMC_BUS_5;
|
||||
cmd_data[1] = SWPLD1_ADDR;
|
||||
cmd_data[2] = QSFP_PRESENCE_1;
|
||||
cmd_data[3] = 1;
|
||||
cmd_data_len = sizeof(cmd_data);
|
||||
ret = dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len);
|
||||
data = (u64)(ret & 0xff);
|
||||
|
||||
/*QSFP9~16*/
|
||||
cmd_data[1] = SWPLD2_ADDR;
|
||||
cmd_data[2] = QSFP_PRESENCE_2;
|
||||
ret = dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len);
|
||||
data |= (u64)(ret & 0xff) << 8;
|
||||
|
||||
/*QSFP17~24*/
|
||||
cmd_data[1] = SWPLD4_ADDR;
|
||||
cmd_data[2] = QSFP_PRESENCE_3;
|
||||
ret = dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len);
|
||||
data |= (u64)(ret & 0xff) << 16;
|
||||
|
||||
/*QSFP25~32*/
|
||||
cmd_data[1] = SWPLD3_ADDR;
|
||||
cmd_data[2] = QSFP_PRESENCE_4;
|
||||
ret = dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len);
|
||||
data |= (u64)(ret & 0xff) << 24;
|
||||
|
||||
/*QSFP33~40*/
|
||||
cmd_data[1] = SWPLD1_ADDR;
|
||||
cmd_data[2] = QSFP_PRESENCE_5;
|
||||
ret = dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len);
|
||||
data |= (u64)(ret & 0xff) << 32;
|
||||
|
||||
/*QSFP41~48*/
|
||||
cmd_data[1] = SWPLD2_ADDR;
|
||||
cmd_data[2] = QSFP_PRESENCE_6;
|
||||
ret = dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len);
|
||||
data |= (u64)(ret & 0xff) << 40;
|
||||
|
||||
/*QSFP49~56*/
|
||||
cmd_data[1] = SWPLD4_ADDR;
|
||||
cmd_data[2] = QSFP_PRESENCE_7;
|
||||
ret = dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len);
|
||||
data |= (u64)(ret & 0xff) << 48;
|
||||
|
||||
/*QSFP57~64*/
|
||||
cmd_data[1] = SWPLD3_ADDR;
|
||||
cmd_data[2] = QSFP_PRESENCE_8;
|
||||
ret = dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len);
|
||||
data |= (u64)(ret & 0xff) << 56;
|
||||
|
||||
return sprintf(buf, "0x%016llx\n", data);
|
||||
}
|
||||
|
||||
static ssize_t get_lpmode(struct device *dev, struct device_attribute \
|
||||
*dev_attr, char *buf)
|
||||
{
|
||||
int ret;
|
||||
u64 data = 0;
|
||||
uint8_t cmd_data[4]={0};
|
||||
uint8_t set_cmd;
|
||||
int cmd_data_len;
|
||||
|
||||
set_cmd = CMD_GETDATA;
|
||||
|
||||
/*QSFP1~8*/
|
||||
cmd_data[0] = BMC_BUS_5;
|
||||
cmd_data[1] = SWPLD1_ADDR;
|
||||
cmd_data[2] = QSFP_LP_MODE_1;
|
||||
cmd_data[3] = 1;
|
||||
cmd_data_len = sizeof(cmd_data);
|
||||
ret = dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len);
|
||||
data = (u64)(ret & 0xff);
|
||||
|
||||
/*QSFP9~16*/
|
||||
cmd_data[1] = SWPLD2_ADDR;
|
||||
cmd_data[2] = QSFP_LP_MODE_2;
|
||||
ret = dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len);
|
||||
data |= (u64)(ret & 0xff) << 8;
|
||||
|
||||
/*QSFP17~24*/
|
||||
cmd_data[1] = SWPLD4_ADDR;
|
||||
cmd_data[2] = QSFP_LP_MODE_3;
|
||||
ret = dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len);
|
||||
data |= (u64)(ret & 0xff) << 16;
|
||||
|
||||
/*QSFP25~32*/
|
||||
cmd_data[1] = SWPLD3_ADDR;
|
||||
cmd_data[2] = QSFP_LP_MODE_4;
|
||||
ret = dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len);
|
||||
data |= (u64)(ret & 0xff) << 24;
|
||||
|
||||
/*QSFP33~40*/
|
||||
cmd_data[1] = SWPLD1_ADDR;
|
||||
cmd_data[2] = QSFP_LP_MODE_5;
|
||||
ret = dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len);
|
||||
data |= (u64)(ret & 0xff) << 32;
|
||||
|
||||
/*QSFP41~48*/
|
||||
cmd_data[1] = SWPLD2_ADDR;
|
||||
cmd_data[2] = QSFP_LP_MODE_6;
|
||||
ret = dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len);
|
||||
data |= (u64)(ret & 0xff) << 40;
|
||||
|
||||
/*QSFP49~56*/
|
||||
cmd_data[1] = SWPLD4_ADDR;
|
||||
cmd_data[2] = QSFP_LP_MODE_7;
|
||||
ret = dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len);
|
||||
data |= (u64)(ret & 0xff) << 48;
|
||||
|
||||
/*QSFP57~64*/
|
||||
cmd_data[1] = SWPLD3_ADDR;
|
||||
cmd_data[2] = QSFP_LP_MODE_8;
|
||||
ret = dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len);
|
||||
data |= (u64)(ret & 0xff) << 56;
|
||||
|
||||
return sprintf(buf, "0x%016llx\n", data);
|
||||
}
|
||||
|
||||
static ssize_t get_reset(struct device *dev, struct device_attribute \
|
||||
*dev_attr, char *buf)
|
||||
{
|
||||
int ret;
|
||||
u64 data = 0;
|
||||
uint8_t cmd_data[4]={0};
|
||||
uint8_t set_cmd;
|
||||
int cmd_data_len;
|
||||
|
||||
set_cmd = CMD_GETDATA;
|
||||
|
||||
/*QSFP1~8*/
|
||||
cmd_data[0] = BMC_BUS_5;
|
||||
cmd_data[1] = SWPLD1_ADDR;
|
||||
cmd_data[2] = QSFP_RESET_1;
|
||||
cmd_data[3] = 1;
|
||||
cmd_data_len = sizeof(cmd_data);
|
||||
ret = dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len);
|
||||
data = (u64)(ret & 0xff);
|
||||
|
||||
/*QSFP9~16*/
|
||||
cmd_data[1] = SWPLD2_ADDR;
|
||||
cmd_data[2] = QSFP_RESET_2;
|
||||
ret = dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len);
|
||||
data |= (u64)(ret & 0xff) << 8;
|
||||
|
||||
/*QSFP17~24*/
|
||||
cmd_data[1] = SWPLD4_ADDR;
|
||||
cmd_data[2] = QSFP_RESET_3;
|
||||
ret = dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len);
|
||||
data |= (u64)(ret & 0xff) << 16;
|
||||
|
||||
/*QSFP25~32*/
|
||||
cmd_data[1] = SWPLD3_ADDR;
|
||||
cmd_data[2] = QSFP_RESET_4;
|
||||
ret = dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len);
|
||||
data |= (u64)(ret & 0xff) << 24;
|
||||
|
||||
/*QSFP33~40*/
|
||||
cmd_data[1] = SWPLD1_ADDR;
|
||||
cmd_data[2] = QSFP_RESET_5;
|
||||
ret = dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len);
|
||||
data |= (u64)(ret & 0xff) << 32;
|
||||
|
||||
/*QSFP41~48*/
|
||||
cmd_data[1] = SWPLD2_ADDR;
|
||||
cmd_data[2] = QSFP_RESET_6;
|
||||
ret = dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len);
|
||||
data |= (u64)(ret & 0xff) << 40;
|
||||
|
||||
/*QSFP49~56*/
|
||||
cmd_data[1] = SWPLD4_ADDR;
|
||||
cmd_data[2] = QSFP_RESET_7;
|
||||
ret = dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len);
|
||||
data |= (u64)(ret & 0xff) << 48;
|
||||
|
||||
/*QSFP57~64*/
|
||||
cmd_data[1] = SWPLD3_ADDR;
|
||||
cmd_data[2] = QSFP_RESET_8;
|
||||
ret = dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len);
|
||||
data |= (u64)(ret & 0xff) << 56;
|
||||
|
||||
return sprintf(buf, "0x%016llx\n", data);
|
||||
}
|
||||
|
||||
static ssize_t get_response(struct device *dev, struct device_attribute \
|
||||
*dev_attr, char *buf)
|
||||
{
|
||||
int ret;
|
||||
u64 data = 0;
|
||||
uint8_t cmd_data[4]={0};
|
||||
uint8_t set_cmd;
|
||||
int cmd_data_len;
|
||||
|
||||
set_cmd = CMD_GETDATA;
|
||||
|
||||
/*QSFP1~8*/
|
||||
cmd_data[0] = BMC_BUS_5;
|
||||
cmd_data[1] = SWPLD1_ADDR;
|
||||
cmd_data[2] = QSFP_RESPONSE_1;
|
||||
cmd_data[3] = 1;
|
||||
cmd_data_len = sizeof(cmd_data);
|
||||
ret = dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len);
|
||||
data = (u64)(ret & 0xff);
|
||||
|
||||
/*QSFP9~16*/
|
||||
cmd_data[1] = SWPLD2_ADDR;
|
||||
cmd_data[2] = QSFP_RESPONSE_2;
|
||||
ret = dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len);
|
||||
data |= (u64)(ret & 0xff) << 8;
|
||||
|
||||
/*QSFP17~24*/
|
||||
cmd_data[1] = SWPLD4_ADDR;
|
||||
cmd_data[2] = QSFP_RESPONSE_3;
|
||||
ret = dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len);
|
||||
data |= (u64)(ret & 0xff) << 16;
|
||||
|
||||
/*QSFP25~32*/
|
||||
cmd_data[1] = SWPLD3_ADDR;
|
||||
cmd_data[2] = QSFP_RESPONSE_4;
|
||||
ret = dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len);
|
||||
data |= (u64)(ret & 0xff) << 24;
|
||||
|
||||
/*QSFP33~40*/
|
||||
cmd_data[1] = SWPLD1_ADDR;
|
||||
cmd_data[2] = QSFP_RESPONSE_5;
|
||||
ret = dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len);
|
||||
data |= (u64)(ret & 0xff) << 32;
|
||||
|
||||
/*QSFP41~48*/
|
||||
cmd_data[1] = SWPLD2_ADDR;
|
||||
cmd_data[2] = QSFP_RESPONSE_6;
|
||||
ret = dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len);
|
||||
data |= (u64)(ret & 0xff) << 40;
|
||||
|
||||
/*QSFP49~56*/
|
||||
cmd_data[1] = SWPLD4_ADDR;
|
||||
cmd_data[2] = QSFP_RESPONSE_7;
|
||||
ret = dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len);
|
||||
data |= (u64)(ret & 0xff) << 48;
|
||||
|
||||
/*QSFP57~64*/
|
||||
cmd_data[1] = SWPLD3_ADDR;
|
||||
cmd_data[2] = QSFP_RESPONSE_8;
|
||||
ret = dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len);
|
||||
data |= (u64)(ret & 0xff) << 56;
|
||||
|
||||
return sprintf(buf, "0x%016llx\n", data);
|
||||
}
|
||||
|
||||
static ssize_t get_interrupt(struct device *dev, struct device_attribute \
|
||||
*dev_attr, char *buf)
|
||||
{
|
||||
int ret;
|
||||
u64 data = 0;
|
||||
uint8_t cmd_data[4]={0};
|
||||
uint8_t set_cmd;
|
||||
int cmd_data_len;
|
||||
|
||||
set_cmd = CMD_GETDATA;
|
||||
|
||||
/*QSFP1~8*/
|
||||
cmd_data[0] = BMC_BUS_5;
|
||||
cmd_data[1] = SWPLD1_ADDR;
|
||||
cmd_data[2] = QSFP_INTERRUPT_1;
|
||||
cmd_data[3] = 1;
|
||||
cmd_data_len = sizeof(cmd_data);
|
||||
ret = dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len);
|
||||
data = (u64)(ret & 0xff);
|
||||
|
||||
/*QSFP9~16*/
|
||||
cmd_data[1] = SWPLD2_ADDR;
|
||||
cmd_data[2] = QSFP_INTERRUPT_2;
|
||||
ret = dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len);
|
||||
data |= (u64)(ret & 0xff) << 8;
|
||||
|
||||
/*QSFP17~24*/
|
||||
cmd_data[1] = SWPLD4_ADDR;
|
||||
cmd_data[2] = QSFP_INTERRUPT_3;
|
||||
ret = dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len);
|
||||
data |= (u64)(ret & 0xff) << 16;
|
||||
|
||||
/*QSFP25~32*/
|
||||
cmd_data[1] = SWPLD3_ADDR;
|
||||
cmd_data[2] = QSFP_INTERRUPT_4;
|
||||
ret = dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len);
|
||||
data |= (u64)(ret & 0xff) << 24;
|
||||
|
||||
/*QSFP33~40*/
|
||||
cmd_data[1] = SWPLD1_ADDR;
|
||||
cmd_data[2] = QSFP_INTERRUPT_5;
|
||||
ret = dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len);
|
||||
data |= (u64)(ret & 0xff) << 32;
|
||||
|
||||
/*QSFP41~48*/
|
||||
cmd_data[1] = SWPLD2_ADDR;
|
||||
cmd_data[2] = QSFP_INTERRUPT_6;
|
||||
ret = dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len);
|
||||
data |= (u64)(ret & 0xff) << 40;
|
||||
|
||||
/*QSFP49~56*/
|
||||
cmd_data[1] = SWPLD4_ADDR;
|
||||
cmd_data[2] = QSFP_INTERRUPT_7;
|
||||
ret = dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len);
|
||||
data |= (u64)(ret & 0xff) << 48;
|
||||
|
||||
/*QSFP57~64*/
|
||||
cmd_data[1] = SWPLD3_ADDR;
|
||||
cmd_data[2] = QSFP_INTERRUPT_8;
|
||||
ret = dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len);
|
||||
data |= (u64)(ret & 0xff) << 56;
|
||||
|
||||
return sprintf(buf, "0x%016llx\n", data);
|
||||
}
|
||||
|
||||
|
||||
static ssize_t set_lpmode(struct device *dev, struct device_attribute *devattr, const char *buf, size_t count)
|
||||
{
|
||||
unsigned long long set_data;
|
||||
int err;
|
||||
|
||||
err = kstrtoull(buf, 16, &set_data);
|
||||
if (err){
|
||||
return err;
|
||||
}
|
||||
uint8_t cmd_data[4]={0};
|
||||
uint8_t set_cmd;
|
||||
int cmd_data_len;
|
||||
|
||||
set_cmd = CMD_SETDATA;
|
||||
/*QSFP1~8*/
|
||||
cmd_data[0] = BMC_BUS_5;
|
||||
cmd_data[1] = SWPLD1_ADDR;
|
||||
cmd_data[2] = QSFP_LP_MODE_1;
|
||||
cmd_data[3] = (set_data & 0xff);
|
||||
cmd_data_len = sizeof(cmd_data);
|
||||
dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len);
|
||||
|
||||
/*QSFP9~16*/
|
||||
cmd_data[1] = SWPLD2_ADDR;
|
||||
cmd_data[2] = QSFP_LP_MODE_2;
|
||||
cmd_data[3] = ((set_data >> 8 ) & 0xff);
|
||||
dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len);
|
||||
|
||||
/*QSFP17~24*/
|
||||
cmd_data[1] = SWPLD4_ADDR;
|
||||
cmd_data[2] = QSFP_LP_MODE_3;
|
||||
cmd_data[3] = ((set_data >> 16 ) & 0xff);
|
||||
dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len);
|
||||
|
||||
/*QSFP25~32*/
|
||||
cmd_data[1] = SWPLD3_ADDR;
|
||||
cmd_data[2] = QSFP_LP_MODE_4;
|
||||
cmd_data[3] = ((set_data >> 24 ) & 0xff);
|
||||
dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len);
|
||||
|
||||
/*QSFP33~40*/
|
||||
cmd_data[1] = SWPLD1_ADDR;
|
||||
cmd_data[2] = QSFP_LP_MODE_5;
|
||||
cmd_data[3] = ((set_data >> 32 ) & 0xff);
|
||||
dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len);
|
||||
|
||||
/*QSFP41~48*/
|
||||
cmd_data[1] = SWPLD2_ADDR;
|
||||
cmd_data[2] = QSFP_LP_MODE_6;
|
||||
cmd_data[3] = ((set_data >> 40 ) & 0xff);
|
||||
dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len);
|
||||
|
||||
/*QSFP49~56*/
|
||||
cmd_data[1] = SWPLD4_ADDR;
|
||||
cmd_data[2] = QSFP_LP_MODE_7;
|
||||
cmd_data[3] = ((set_data >> 48 ) & 0xff);
|
||||
dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len);
|
||||
|
||||
/*QSFP57~64*/
|
||||
cmd_data[1] = SWPLD3_ADDR;
|
||||
cmd_data[2] = QSFP_LP_MODE_8;
|
||||
cmd_data[3] = ((set_data >> 56 ) & 0xff);
|
||||
dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len);
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
static ssize_t set_reset(struct device *dev, struct device_attribute *devattr, const char *buf, size_t count)
|
||||
{
|
||||
unsigned long long set_data;
|
||||
int err;
|
||||
|
||||
err = kstrtoull(buf, 16, &set_data);
|
||||
if (err){
|
||||
return err;
|
||||
}
|
||||
uint8_t cmd_data[4]={0};
|
||||
uint8_t set_cmd;
|
||||
int cmd_data_len;
|
||||
|
||||
set_cmd = CMD_SETDATA;
|
||||
|
||||
/*QSFP1~8*/
|
||||
cmd_data[0] = BMC_BUS_5;
|
||||
cmd_data[1] = SWPLD1_ADDR;
|
||||
cmd_data[2] = QSFP_RESET_1;
|
||||
cmd_data[3] = (set_data & 0xff);
|
||||
cmd_data_len = sizeof(cmd_data);
|
||||
dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len);
|
||||
|
||||
/*QSFP9~16*/
|
||||
cmd_data[1] = SWPLD2_ADDR;
|
||||
cmd_data[2] = QSFP_RESET_2;
|
||||
cmd_data[3] = ((set_data >> 8 ) & 0xff);
|
||||
dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len);
|
||||
|
||||
/*QSFP17~24*/
|
||||
cmd_data[1] = SWPLD4_ADDR;
|
||||
cmd_data[2] = QSFP_RESET_3;
|
||||
cmd_data[3] = ((set_data >> 16 ) & 0xff);
|
||||
dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len);
|
||||
|
||||
/*QSFP25~32*/
|
||||
cmd_data[1] = SWPLD3_ADDR;
|
||||
cmd_data[2] = QSFP_RESET_4;
|
||||
cmd_data[3] = ((set_data >> 24 ) & 0xff);
|
||||
dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len);
|
||||
|
||||
/*QSFP33~40*/
|
||||
cmd_data[1] = SWPLD1_ADDR;
|
||||
cmd_data[2] = QSFP_RESET_5;
|
||||
cmd_data[3] = ((set_data >> 32 ) & 0xff);
|
||||
dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len);
|
||||
|
||||
/*QSFP41~48*/
|
||||
cmd_data[1] = SWPLD2_ADDR;
|
||||
cmd_data[2] = QSFP_RESET_6;
|
||||
cmd_data[3] = ((set_data >> 40 ) & 0xff);
|
||||
dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len);
|
||||
|
||||
/*QSFP49~56*/
|
||||
cmd_data[1] = SWPLD4_ADDR;
|
||||
cmd_data[2] = QSFP_RESET_7;
|
||||
cmd_data[3] = ((set_data >> 48 ) & 0xff);
|
||||
dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len);
|
||||
|
||||
/*QSFP57~64*/
|
||||
cmd_data[1] = SWPLD3_ADDR;
|
||||
cmd_data[2] = QSFP_RESET_8;
|
||||
cmd_data[3] = ((set_data >> 56 ) & 0xff);
|
||||
dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len);
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
static ssize_t set_response(struct device *dev, struct device_attribute *devattr, const char *buf, size_t count)
|
||||
{
|
||||
unsigned long long set_data;
|
||||
int err;
|
||||
|
||||
err = kstrtoull(buf, 16, &set_data);
|
||||
if (err){
|
||||
return err;
|
||||
}
|
||||
uint8_t cmd_data[4]={0};
|
||||
uint8_t set_cmd;
|
||||
int cmd_data_len;
|
||||
|
||||
set_cmd = CMD_SETDATA;
|
||||
|
||||
/*QSFP1~8*/
|
||||
cmd_data[0] = BMC_BUS_5;
|
||||
cmd_data[1] = SWPLD1_ADDR;
|
||||
cmd_data[2] = QSFP_RESPONSE_1;
|
||||
cmd_data[3] = (set_data & 0xff);
|
||||
cmd_data_len = sizeof(cmd_data);
|
||||
dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len);
|
||||
|
||||
/*QSFP9~16*/
|
||||
cmd_data[1] = SWPLD2_ADDR;
|
||||
cmd_data[2] = QSFP_RESPONSE_2;
|
||||
cmd_data[3] = ((set_data >> 8 ) & 0xff);
|
||||
dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len);
|
||||
|
||||
/*QSFP17~24*/
|
||||
cmd_data[1] = SWPLD4_ADDR;
|
||||
cmd_data[2] = QSFP_RESPONSE_3;
|
||||
cmd_data[3] = ((set_data >> 16 ) & 0xff);
|
||||
dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len);
|
||||
|
||||
/*QSFP25~32*/
|
||||
cmd_data[1] = SWPLD3_ADDR;
|
||||
cmd_data[2] = QSFP_RESPONSE_4;
|
||||
cmd_data[3] = ((set_data >> 24 ) & 0xff);
|
||||
dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len);
|
||||
|
||||
/*QSFP33~40*/
|
||||
cmd_data[1] = SWPLD1_ADDR;
|
||||
cmd_data[2] = QSFP_RESPONSE_5;
|
||||
cmd_data[3] = ((set_data >> 32 ) & 0xff);
|
||||
dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len);
|
||||
|
||||
/*QSFP41~48*/
|
||||
cmd_data[1] = SWPLD2_ADDR;
|
||||
cmd_data[2] = QSFP_RESPONSE_6;
|
||||
cmd_data[3] = ((set_data >> 40 ) & 0xff);
|
||||
dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len);
|
||||
|
||||
/*QSFP49~56*/
|
||||
cmd_data[1] = SWPLD4_ADDR;
|
||||
cmd_data[2] = QSFP_RESPONSE_7;
|
||||
cmd_data[3] = ((set_data >> 48 ) & 0xff);
|
||||
dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len);
|
||||
|
||||
/*QSFP57~64*/
|
||||
cmd_data[1] = SWPLD3_ADDR;
|
||||
cmd_data[2] = QSFP_RESPONSE_8;
|
||||
cmd_data[3] = ((set_data >> 56 ) & 0xff);
|
||||
dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len);
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
static DEVICE_ATTR(qsfp_present, S_IRUGO, get_present, NULL);
|
||||
static DEVICE_ATTR(qsfp_lpmode, S_IWUSR | S_IRUGO, get_lpmode, set_lpmode);
|
||||
static DEVICE_ATTR(qsfp_reset, S_IWUSR | S_IRUGO, get_reset, set_reset);
|
||||
static DEVICE_ATTR(qsfp_modsel, S_IWUSR | S_IRUGO, get_response, set_response);
|
||||
static DEVICE_ATTR(qsfp_interrupt, S_IRUGO, get_interrupt, NULL);
|
||||
|
||||
static struct attribute *ag9064_cpld_attrs[] = {
|
||||
&dev_attr_qsfp_present.attr,
|
||||
&dev_attr_qsfp_lpmode.attr,
|
||||
&dev_attr_qsfp_reset.attr,
|
||||
&dev_attr_qsfp_modsel.attr,
|
||||
&dev_attr_qsfp_interrupt.attr,
|
||||
NULL,
|
||||
};
|
||||
|
||||
static struct attribute_group ag9064_cpld_attr_grp = {
|
||||
.attrs = ag9064_cpld_attrs,
|
||||
};
|
||||
|
||||
enum cpld_type {
|
||||
system_cpld,
|
||||
};
|
||||
|
||||
struct cpld_platform_data {
|
||||
int reg_addr;
|
||||
struct i2c_client *client;
|
||||
};
|
||||
|
||||
static struct cpld_platform_data ag9064_cpld_platform_data[] = {
|
||||
[system_cpld] = {
|
||||
.reg_addr = CPLD_REG,
|
||||
},
|
||||
};
|
||||
|
||||
static struct platform_device ag9064_cpld = {
|
||||
.name = "delta-ag9064-cpld",
|
||||
.id = 0,
|
||||
.dev = {
|
||||
.platform_data = ag9064_cpld_platform_data,
|
||||
.release = device_release
|
||||
},
|
||||
};
|
||||
|
||||
static int __init cpld_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct cpld_platform_data *pdata;
|
||||
struct i2c_adapter *parent;
|
||||
int ret;
|
||||
|
||||
pdata = pdev->dev.platform_data;
|
||||
if (!pdata) {
|
||||
dev_err(&pdev->dev, "CPLD platform data not found\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
parent = i2c_get_adapter(BUS7);
|
||||
if (!parent) {
|
||||
printk(KERN_WARNING "Parent adapter (%d) not found\n",BUS7);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
pdata[system_cpld].client = i2c_new_dummy(parent, pdata[system_cpld].reg_addr);
|
||||
if (!pdata[system_cpld].client) {
|
||||
printk(KERN_WARNING "Fail to create dummy i2c client for addr %d\n", pdata[system_cpld].reg_addr);
|
||||
goto error;
|
||||
}
|
||||
|
||||
ret = sysfs_create_group(&pdev->dev.kobj, &ag9064_cpld_attr_grp);
|
||||
if (ret) {
|
||||
printk(KERN_WARNING "Fail to create cpld attribute group");
|
||||
goto error;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
error:
|
||||
i2c_unregister_device(pdata[system_cpld].client);
|
||||
i2c_put_adapter(parent);
|
||||
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
static int __exit cpld_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct i2c_adapter *parent = NULL;
|
||||
struct cpld_platform_data *pdata = pdev->dev.platform_data;
|
||||
sysfs_remove_group(&pdev->dev.kobj, &ag9064_cpld_attr_grp);
|
||||
|
||||
if (!pdata) {
|
||||
dev_err(&pdev->dev, "Missing platform data\n");
|
||||
}
|
||||
else {
|
||||
if (pdata[system_cpld].client) {
|
||||
if (!parent) {
|
||||
parent = (pdata[system_cpld].client)->adapter;
|
||||
}
|
||||
i2c_unregister_device(pdata[system_cpld].client);
|
||||
}
|
||||
}
|
||||
i2c_put_adapter(parent);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct platform_driver cpld_driver = {
|
||||
.probe = cpld_probe,
|
||||
.remove = __exit_p(cpld_remove),
|
||||
.driver = {
|
||||
.owner = THIS_MODULE,
|
||||
.name = "delta-ag9064-cpld",
|
||||
},
|
||||
};
|
||||
|
||||
/*---------------- CPLD - end ------------- */
|
||||
|
||||
/*---------------- module initialization ------------- */
|
||||
|
||||
static void __init delta_ag9064_platform_init(void)
|
||||
@ -1734,12 +997,6 @@ static void __init delta_ag9064_platform_init(void)
|
||||
printk(KERN_WARNING "Fail to create IPMI user\n");
|
||||
}
|
||||
|
||||
ret = platform_driver_register(&cpld_driver);
|
||||
if (ret) {
|
||||
printk(KERN_WARNING "Fail to register cpld driver\n");
|
||||
goto error_cpld_driver;
|
||||
}
|
||||
|
||||
// register the mux prob which call the SWPLD
|
||||
ret = platform_driver_register(&swpld_mux_driver);
|
||||
if (ret) {
|
||||
@ -1754,13 +1011,6 @@ static void __init delta_ag9064_platform_init(void)
|
||||
goto error_i2c_device_driver;
|
||||
}
|
||||
|
||||
// register the CPLD
|
||||
ret = platform_device_register(&ag9064_cpld);
|
||||
if (ret) {
|
||||
printk(KERN_WARNING "Fail to create cpld device\n");
|
||||
goto error_ag9064_cpld;
|
||||
}
|
||||
|
||||
swpld_pdata = ag9064_swpld_mux[0].dev.platform_data;
|
||||
//swpld_pdata->cpld = cpld_pdata[system_cpld].client;
|
||||
ret = platform_device_register(&ag9064_swpld_mux);
|
||||
@ -1794,14 +1044,10 @@ error_ag9064_swpld_mux:
|
||||
for (; i >= 0; i--) {
|
||||
platform_device_unregister(&ag9064_swpld_mux);
|
||||
}
|
||||
platform_driver_unregister(&ag9064_cpld);
|
||||
error_ag9064_cpld:
|
||||
platform_driver_unregister(&i2c_device_driver);
|
||||
error_i2c_device_driver:
|
||||
platform_driver_unregister(&swpld_mux_driver);
|
||||
error_swpld_mux_driver:
|
||||
platform_driver_unregister(&cpld_driver);
|
||||
error_cpld_driver:
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -1814,10 +1060,8 @@ static void __exit delta_ag9064_platform_exit(void)
|
||||
}
|
||||
|
||||
platform_device_unregister(&ag9064_swpld_mux);
|
||||
platform_device_unregister(&ag9064_cpld);
|
||||
platform_driver_unregister(&i2c_device_driver);
|
||||
platform_driver_unregister(&swpld_mux_driver);
|
||||
platform_driver_unregister(&cpld_driver);
|
||||
i2c_unregister_device(i2c_client_9548);
|
||||
}
|
||||
|
||||
@ -1826,4 +1070,4 @@ module_exit(delta_ag9064_platform_exit);
|
||||
|
||||
MODULE_DESCRIPTION("DELTA ag9064 Platform Support");
|
||||
MODULE_AUTHOR("Johnson Lu <johnson.lu@deltaww.com>");
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_LICENSE("GPL");
|
@ -0,0 +1,620 @@
|
||||
#include "delta_ag9064_common.h"
|
||||
|
||||
unsigned char swpld1_reg_addr;
|
||||
unsigned char swpld2_reg_addr;
|
||||
unsigned char swpld3_reg_addr;
|
||||
unsigned char swpld4_reg_addr;
|
||||
|
||||
/*---------------- CPLD - start ------------- */
|
||||
/* SWPLD1 -- device */
|
||||
static struct platform_device swpld1_device = {
|
||||
.name = "delta-ag9064-swpld1",
|
||||
.id = 0,
|
||||
.dev = {
|
||||
.platform_data = ag9064_swpld1_platform_data,
|
||||
.release = device_release
|
||||
},
|
||||
};
|
||||
|
||||
static struct platform_device swpld2_device = {
|
||||
.name = "delta-ag9064-swpld2",
|
||||
.id = 0,
|
||||
.dev = {
|
||||
.platform_data = ag9064_swpld2_platform_data,
|
||||
.release = device_release
|
||||
},
|
||||
};
|
||||
static struct platform_device swpld3_device = {
|
||||
.name = "delta-ag9064-swpld3",
|
||||
.id = 0,
|
||||
.dev = {
|
||||
.platform_data = ag9064_swpld3_platform_data,
|
||||
.release = device_release
|
||||
},
|
||||
};
|
||||
static struct platform_device swpld4_device = {
|
||||
.name = "delta-ag9064-swpld4",
|
||||
.id = 0,
|
||||
.dev = {
|
||||
.platform_data = ag9064_swpld4_platform_data,
|
||||
.release = device_release
|
||||
},
|
||||
};
|
||||
|
||||
static ssize_t get_swpld_reg(struct device *dev, struct device_attribute *dev_attr, char *buf)
|
||||
{
|
||||
int ret;
|
||||
int mask;
|
||||
int value;
|
||||
int cmd_data_len;
|
||||
char note[200];
|
||||
uint8_t cmd_data[4]={0};
|
||||
uint8_t get_cmd;
|
||||
struct sensor_device_attribute *attr = to_sensor_dev_attr(dev_attr);
|
||||
|
||||
cmd_data_len = sizeof(cmd_data);
|
||||
get_cmd = CMD_GETDATA;
|
||||
cmd_data[0] = BMC_BUS_5;
|
||||
cmd_data[3] = 1;
|
||||
mask = attribute_data[attr->index].mask;
|
||||
sprintf(note, "\n%s\n",attribute_data[attr->index].note);
|
||||
|
||||
if (attr->index <= SWPLD4_REG_VALUE){
|
||||
switch (attr->index) {
|
||||
case SWPLD1_REG_ADDR:
|
||||
return sprintf(buf, "0x%02x\n", swpld1_reg_addr);
|
||||
case SWPLD2_REG_ADDR:
|
||||
return sprintf(buf, "0x%02x\n", swpld2_reg_addr);
|
||||
case SWPLD3_REG_ADDR:
|
||||
return sprintf(buf, "0x%02x\n", swpld3_reg_addr);
|
||||
case SWPLD4_REG_ADDR:
|
||||
return sprintf(buf, "0x%02x\n", swpld4_reg_addr);
|
||||
case SWPLD1_REG_VALUE:
|
||||
cmd_data[1] = SWPLD1_ADDR;
|
||||
cmd_data[2] = swpld1_reg_addr;
|
||||
break;
|
||||
case SWPLD2_REG_VALUE:
|
||||
cmd_data[1] = SWPLD2_ADDR;
|
||||
cmd_data[2] = swpld2_reg_addr;
|
||||
break;
|
||||
case SWPLD3_REG_VALUE:
|
||||
cmd_data[1] = SWPLD3_ADDR;
|
||||
cmd_data[2] = swpld3_reg_addr;
|
||||
break;
|
||||
case SWPLD4_REG_VALUE:
|
||||
cmd_data[1] = SWPLD4_ADDR;
|
||||
cmd_data[2] = swpld4_reg_addr;
|
||||
break;
|
||||
default:
|
||||
return sprintf(buf, "%d not found", attr->index);
|
||||
}
|
||||
ret = dni_bmc_cmd(get_cmd, cmd_data, cmd_data_len);
|
||||
ret = ret & 0xff;
|
||||
return sprintf(buf, "0x%02x\n", ret);
|
||||
}else{
|
||||
|
||||
switch (attr->index) {
|
||||
case SWPLD1_MAJOR_VER ... PSU_LED_MODE :
|
||||
cmd_data[1] = SWPLD1_ADDR;
|
||||
break;
|
||||
case SWPLD2_MAJOR_VER ... FAN_MOD4_LED :
|
||||
cmd_data[1] = SWPLD2_ADDR;
|
||||
break;
|
||||
case SWPLD3_MAJOR_VER ... PLATFORM_TYPE :
|
||||
cmd_data[1] = SWPLD3_ADDR;
|
||||
break;
|
||||
case SWPLD4_MAJOR_VER ... FAN_EEPROM_WP :
|
||||
cmd_data[1] = SWPLD4_ADDR;
|
||||
break;
|
||||
default:
|
||||
return sprintf(buf, "%d not found", attr->index);
|
||||
}
|
||||
cmd_data[2] = attribute_data[attr->index].reg;
|
||||
value = dni_bmc_cmd(get_cmd, cmd_data, cmd_data_len);
|
||||
value = value & mask;
|
||||
switch (mask) {
|
||||
case 0xFF:
|
||||
return sprintf(buf, "0x%02x%s", value, note);
|
||||
case 0x0F:
|
||||
return sprintf(buf, "0x%01x%s", value, note);
|
||||
case 0xF0:
|
||||
value = value >> 4;
|
||||
return sprintf(buf, "0x%01x%s", value, note);
|
||||
case 0xC0:
|
||||
value = value >> 6;
|
||||
return sprintf(buf, "0x%01x%s", value, note);
|
||||
case 0x30:
|
||||
value = value >> 4;
|
||||
return sprintf(buf, "0x%01x%s", value, note);
|
||||
default :
|
||||
value = value >> dni_log2(mask);
|
||||
return sprintf(buf, "%d%s", value, note);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static ssize_t set_swpld_reg(struct device *dev, struct device_attribute *dev_attr,
|
||||
const char *buf, size_t count)
|
||||
{
|
||||
int err;
|
||||
int value;
|
||||
int set_data;
|
||||
int cmd_data_len;
|
||||
uint8_t cmd_data[4]={0};
|
||||
uint8_t set_cmd;
|
||||
uint8_t get_cmd;
|
||||
unsigned char mask;
|
||||
unsigned char mask_out;
|
||||
struct sensor_device_attribute *attr = to_sensor_dev_attr(dev_attr);
|
||||
|
||||
cmd_data_len = sizeof(cmd_data);
|
||||
set_cmd = CMD_SETDATA;
|
||||
get_cmd = CMD_GETDATA;
|
||||
|
||||
err = kstrtoul(buf, 0, &set_data);
|
||||
if (err){
|
||||
return err;
|
||||
}
|
||||
|
||||
if (set_data > 0xff){
|
||||
printk(KERN_ALERT "address out of range (0x00-0xFF)\n");
|
||||
return count;
|
||||
}
|
||||
if (attr->index <= SWPLD4_REG_VALUE){
|
||||
cmd_data[0] = BMC_BUS_5;
|
||||
cmd_data[3] = set_data;
|
||||
switch (attr->index) {
|
||||
//reg_addr
|
||||
case SWPLD1_REG_ADDR:
|
||||
swpld1_reg_addr = set_data;
|
||||
return count;
|
||||
case SWPLD2_REG_ADDR:
|
||||
swpld2_reg_addr = set_data;
|
||||
return count;
|
||||
case SWPLD3_REG_ADDR:
|
||||
swpld3_reg_addr = set_data;
|
||||
return count;
|
||||
case SWPLD4_REG_ADDR:
|
||||
swpld4_reg_addr = set_data;
|
||||
return count;
|
||||
//reg_value
|
||||
case SWPLD1_REG_VALUE:
|
||||
cmd_data[1] = SWPLD1_ADDR;
|
||||
cmd_data[2] = swpld1_reg_addr;
|
||||
break;
|
||||
case SWPLD2_REG_VALUE:
|
||||
cmd_data[1] = SWPLD2_ADDR;
|
||||
cmd_data[2] = swpld2_reg_addr;
|
||||
break;
|
||||
case SWPLD3_REG_VALUE:
|
||||
cmd_data[1] = SWPLD3_ADDR;
|
||||
cmd_data[2] = swpld3_reg_addr;
|
||||
break;
|
||||
case SWPLD4_REG_VALUE:
|
||||
cmd_data[1] = SWPLD4_ADDR;
|
||||
cmd_data[2] = swpld4_reg_addr;
|
||||
break;
|
||||
default :
|
||||
return sprintf(buf, "%d not found", attr->index);
|
||||
}
|
||||
dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len);
|
||||
return count;
|
||||
}
|
||||
else{
|
||||
cmd_data[0] = BMC_BUS_5;
|
||||
cmd_data[2] = attribute_data[attr->index].reg;
|
||||
cmd_data[3] = 1;
|
||||
switch (attr->index) {
|
||||
//attributes
|
||||
case SWPLD1_MAJOR_VER ... PSU_LED_MODE://SWPLD1
|
||||
cmd_data[1] = SWPLD1_ADDR;
|
||||
break;
|
||||
case SWPLD2_MAJOR_VER ... FAN_MOD4_LED://SWPLD2
|
||||
cmd_data[1] = SWPLD2_ADDR;
|
||||
break;
|
||||
case SWPLD3_MAJOR_VER ... PLATFORM_TYPE://SWPLD3
|
||||
cmd_data[1] = SWPLD3_ADDR;
|
||||
break;
|
||||
case SWPLD4_MAJOR_VER ... FAN_EEPROM_WP://SWPLD4
|
||||
cmd_data[1] = SWPLD4_ADDR;
|
||||
break;
|
||||
default:
|
||||
return sprintf(buf, "%d not found", attr->index);
|
||||
}
|
||||
|
||||
value = dni_bmc_cmd(get_cmd, cmd_data, cmd_data_len);
|
||||
mask = attribute_data[attr->index].mask;
|
||||
mask_out = value & ~(mask);
|
||||
cmd_data[3] = set_data;
|
||||
switch (mask) {
|
||||
case 0xFF:
|
||||
set_data = mask_out | (set_data & mask);
|
||||
break;
|
||||
case 0x0F:
|
||||
set_data = mask_out | (set_data & mask);
|
||||
break;
|
||||
case 0xF0:
|
||||
set_data = set_data << 4;
|
||||
set_data = mask_out | (set_data & mask);
|
||||
break;
|
||||
case 0xC0:
|
||||
set_data = set_data << 6;
|
||||
set_data = mask_out | (set_data & mask);
|
||||
break;
|
||||
case 0x30:
|
||||
set_data = set_data << 4;
|
||||
set_data = mask_out | (set_data & mask);
|
||||
break;
|
||||
default :
|
||||
set_data = mask_out | (set_data << dni_log2(mask) );
|
||||
}
|
||||
dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len);
|
||||
return count;
|
||||
}
|
||||
}
|
||||
|
||||
//SWPLD
|
||||
static SENSOR_DEVICE_ATTR(swpld1_reg_addr, S_IRUGO | S_IWUSR, get_swpld_reg, set_swpld_reg, SWPLD1_REG_ADDR);
|
||||
static SENSOR_DEVICE_ATTR(swpld1_reg_value, S_IRUGO | S_IWUSR, get_swpld_reg, set_swpld_reg, SWPLD1_REG_VALUE);
|
||||
static SENSOR_DEVICE_ATTR(swpld2_reg_addr, S_IRUGO | S_IWUSR, get_swpld_reg, set_swpld_reg, SWPLD2_REG_ADDR);
|
||||
static SENSOR_DEVICE_ATTR(swpld2_reg_value, S_IRUGO | S_IWUSR, get_swpld_reg, set_swpld_reg, SWPLD2_REG_VALUE);
|
||||
static SENSOR_DEVICE_ATTR(swpld3_reg_addr, S_IRUGO | S_IWUSR, get_swpld_reg, set_swpld_reg, SWPLD3_REG_ADDR);
|
||||
static SENSOR_DEVICE_ATTR(swpld3_reg_value, S_IRUGO | S_IWUSR, get_swpld_reg, set_swpld_reg, SWPLD3_REG_VALUE);
|
||||
static SENSOR_DEVICE_ATTR(swpld4_reg_addr, S_IRUGO | S_IWUSR, get_swpld_reg, set_swpld_reg, SWPLD4_REG_ADDR);
|
||||
static SENSOR_DEVICE_ATTR(swpld4_reg_value, S_IRUGO | S_IWUSR, get_swpld_reg, set_swpld_reg, SWPLD4_REG_VALUE);
|
||||
//SWPLD1
|
||||
static SENSOR_DEVICE_ATTR(swpld1_major_ver, S_IRUGO, get_swpld_reg, NULL, SWPLD1_MAJOR_VER);
|
||||
static SENSOR_DEVICE_ATTR(swpld1_minor_ver, S_IRUGO, get_swpld_reg, NULL, SWPLD1_MINOR_VER);
|
||||
static SENSOR_DEVICE_ATTR(swpld1_scrtch_reg, S_IRUGO | S_IWUSR, get_swpld_reg, set_swpld_reg, SWPLD1_SCRTCH_REG);
|
||||
static SENSOR_DEVICE_ATTR(psu1_pwr_ok, S_IRUGO, get_swpld_reg, NULL, PSU1_PWR_OK);
|
||||
static SENSOR_DEVICE_ATTR(psu1_int, S_IRUGO, get_swpld_reg, NULL, PSU1_INT);
|
||||
static SENSOR_DEVICE_ATTR(psu2_pwr_ok, S_IRUGO, get_swpld_reg, NULL, PSU2_PWR_OK);
|
||||
static SENSOR_DEVICE_ATTR(psu2_int, S_IRUGO, get_swpld_reg, NULL, PSU2_INT);
|
||||
static SENSOR_DEVICE_ATTR(synce_int, S_IRUGO, get_swpld_reg, NULL, SYNCE_INT);
|
||||
static SENSOR_DEVICE_ATTR(synce_rst, S_IRUGO | S_IWUSR, get_swpld_reg, set_swpld_reg, SYNCE_RST);
|
||||
static SENSOR_DEVICE_ATTR(synce_eeprom_wp, S_IRUGO | S_IWUSR, get_swpld_reg, set_swpld_reg, SYNCE_EEPROM_WP);
|
||||
static SENSOR_DEVICE_ATTR(psu1_green_led, S_IRUGO | S_IWUSR, get_swpld_reg, set_swpld_reg, PSU1_GREEN_LED);
|
||||
static SENSOR_DEVICE_ATTR(psu1_red_led, S_IRUGO | S_IWUSR, get_swpld_reg, set_swpld_reg, PSU1_RED_LED);
|
||||
static SENSOR_DEVICE_ATTR(psu2_green_led, S_IRUGO | S_IWUSR, get_swpld_reg, set_swpld_reg, PSU2_GREEN_LED);
|
||||
static SENSOR_DEVICE_ATTR(psu2_red_led, S_IRUGO | S_IWUSR, get_swpld_reg, set_swpld_reg, PSU2_RED_LED);
|
||||
static SENSOR_DEVICE_ATTR(psu_led_mode, S_IRUGO, get_swpld_reg, NULL, PSU_LED_MODE);
|
||||
//SWPLD2
|
||||
static SENSOR_DEVICE_ATTR(swpld2_major_ver, S_IRUGO, get_swpld_reg, NULL, SWPLD2_MAJOR_VER);
|
||||
static SENSOR_DEVICE_ATTR(swpld2_minor_ver, S_IRUGO, get_swpld_reg, NULL, SWPLD2_MINOR_VER);
|
||||
static SENSOR_DEVICE_ATTR(swpld2_scrtch_reg, S_IRUGO | S_IWUSR, get_swpld_reg, set_swpld_reg, SWPLD2_SCRTCH_REG);
|
||||
static SENSOR_DEVICE_ATTR(fan_led, S_IRUGO | S_IWUSR, get_swpld_reg, set_swpld_reg, FAN_LED);
|
||||
static SENSOR_DEVICE_ATTR(sys_led, S_IRUGO | S_IWUSR, get_swpld_reg, set_swpld_reg, SYS_LED);
|
||||
static SENSOR_DEVICE_ATTR(fan_mod1_led, S_IRUGO | S_IWUSR, get_swpld_reg, set_swpld_reg, FAN_MOD1_LED);
|
||||
static SENSOR_DEVICE_ATTR(fan_mod2_led, S_IRUGO | S_IWUSR, get_swpld_reg, set_swpld_reg, FAN_MOD2_LED);
|
||||
static SENSOR_DEVICE_ATTR(fan_mod3_led, S_IRUGO | S_IWUSR, get_swpld_reg, set_swpld_reg, FAN_MOD3_LED);
|
||||
static SENSOR_DEVICE_ATTR(fan_mod4_led, S_IRUGO | S_IWUSR, get_swpld_reg, set_swpld_reg, FAN_MOD4_LED);
|
||||
//SWPLD3
|
||||
static SENSOR_DEVICE_ATTR(swpld3_major_ver, S_IRUGO, get_swpld_reg, NULL, SWPLD3_MAJOR_VER);
|
||||
static SENSOR_DEVICE_ATTR(swpld3_minor_ver, S_IRUGO, get_swpld_reg, NULL, SWPLD3_MINOR_VER);
|
||||
static SENSOR_DEVICE_ATTR(swpld3_scrtch_reg, S_IRUGO | S_IWUSR, get_swpld_reg, set_swpld_reg, SWPLD3_SCRTCH_REG);
|
||||
static SENSOR_DEVICE_ATTR(sb_ver, S_IRUGO, get_swpld_reg, NULL, SB_VER);
|
||||
static SENSOR_DEVICE_ATTR(platform_type, S_IRUGO, get_swpld_reg, NULL, PLATFORM_TYPE);
|
||||
|
||||
//SWPLD4
|
||||
static SENSOR_DEVICE_ATTR(swpld4_major_ver, S_IRUGO, get_swpld_reg, NULL, SWPLD4_MAJOR_VER);
|
||||
static SENSOR_DEVICE_ATTR(swpld4_minor_ver, S_IRUGO, get_swpld_reg, NULL, SWPLD4_MINOR_VER);
|
||||
static SENSOR_DEVICE_ATTR(swpld4_scrtch_reg, S_IRUGO | S_IWUSR, get_swpld_reg, set_swpld_reg, SWPLD4_SCRTCH_REG);
|
||||
static SENSOR_DEVICE_ATTR(bmc_rst, S_IRUGO | S_IWUSR, get_swpld_reg, set_swpld_reg, BMC_RST);
|
||||
static SENSOR_DEVICE_ATTR(cpld_lpc_rst, S_IRUGO | S_IWUSR, get_swpld_reg, set_swpld_reg, CPLD_LPC_RST);
|
||||
static SENSOR_DEVICE_ATTR(cpld_sw_rst, S_IRUGO | S_IWUSR, get_swpld_reg, set_swpld_reg, CPLD_SW_RST);
|
||||
static SENSOR_DEVICE_ATTR(mb_cpld_rst, S_IRUGO | S_IWUSR, get_swpld_reg, set_swpld_reg, MB_CPLD_RST);
|
||||
static SENSOR_DEVICE_ATTR(bcm56970_rst, S_IRUGO | S_IWUSR, get_swpld_reg, set_swpld_reg, BCM56970_RST);
|
||||
|
||||
static SENSOR_DEVICE_ATTR(cpld_upgrade_rst, S_IRUGO, get_swpld_reg, NULL, CPLD_UPGRADE_RST);
|
||||
static SENSOR_DEVICE_ATTR(mb_rst_cpld, S_IRUGO, get_swpld_reg, NULL, MB_RST_CPLD);
|
||||
static SENSOR_DEVICE_ATTR(cpu_rst_mb_oob, S_IRUGO, get_swpld_reg, NULL, CPU_RST_MB_OOB);
|
||||
static SENSOR_DEVICE_ATTR(gpio_phy_rst, S_IRUGO, get_swpld_reg, NULL, GPIO_PHY_RST);
|
||||
static SENSOR_DEVICE_ATTR(psu_fan_event, S_IRUGO, get_swpld_reg, NULL, PSU_FAN_EVENT);
|
||||
static SENSOR_DEVICE_ATTR(cpu_thermal_int, S_IRUGO, get_swpld_reg, NULL, CPU_THERMAL_INT);
|
||||
static SENSOR_DEVICE_ATTR(fan_int, S_IRUGO, get_swpld_reg, NULL, FAN_INT);
|
||||
|
||||
static SENSOR_DEVICE_ATTR(cpld_spi_wp, S_IRUGO | S_IWUSR, get_swpld_reg, set_swpld_reg, CPLD_SPI_WP);
|
||||
static SENSOR_DEVICE_ATTR(rj45_console_sel, S_IRUGO | S_IWUSR, get_swpld_reg, set_swpld_reg, RJ45_CONSOLE_SEL);
|
||||
static SENSOR_DEVICE_ATTR(system_int, S_IRUGO | S_IWUSR, get_swpld_reg, set_swpld_reg, SYSTEM_INT);
|
||||
static SENSOR_DEVICE_ATTR(cpld_mb_rst_done, S_IRUGO | S_IWUSR, get_swpld_reg, set_swpld_reg, CPLD_MB_RST_DONE);
|
||||
static SENSOR_DEVICE_ATTR(mb_pwr_ok, S_IRUGO | S_IWUSR, get_swpld_reg, set_swpld_reg, MB_PWR_OK);
|
||||
static SENSOR_DEVICE_ATTR(fan_eeprom_wp, S_IRUGO | S_IWUSR, get_swpld_reg, set_swpld_reg, FAN_EEPROM_WP);
|
||||
|
||||
static struct attribute *swpld1_device_attrs[] = {
|
||||
&sensor_dev_attr_swpld1_reg_value.dev_attr.attr,
|
||||
&sensor_dev_attr_swpld1_reg_addr.dev_attr.attr,
|
||||
&sensor_dev_attr_swpld1_major_ver.dev_attr.attr,
|
||||
&sensor_dev_attr_swpld1_minor_ver.dev_attr.attr,
|
||||
&sensor_dev_attr_swpld1_scrtch_reg.dev_attr.attr,
|
||||
&sensor_dev_attr_psu1_pwr_ok.dev_attr.attr,
|
||||
&sensor_dev_attr_psu1_int.dev_attr.attr,
|
||||
&sensor_dev_attr_psu2_pwr_ok.dev_attr.attr,
|
||||
&sensor_dev_attr_psu2_int.dev_attr.attr,
|
||||
&sensor_dev_attr_synce_int.dev_attr.attr,
|
||||
&sensor_dev_attr_synce_rst.dev_attr.attr,
|
||||
&sensor_dev_attr_synce_eeprom_wp.dev_attr.attr,
|
||||
&sensor_dev_attr_psu1_green_led.dev_attr.attr,
|
||||
&sensor_dev_attr_psu1_red_led.dev_attr.attr,
|
||||
&sensor_dev_attr_psu2_green_led.dev_attr.attr,
|
||||
&sensor_dev_attr_psu2_red_led.dev_attr.attr,
|
||||
&sensor_dev_attr_psu_led_mode.dev_attr.attr,
|
||||
NULL,
|
||||
};
|
||||
|
||||
static struct attribute *swpld2_device_attrs[] = {
|
||||
&sensor_dev_attr_swpld2_reg_value.dev_attr.attr,
|
||||
&sensor_dev_attr_swpld2_reg_addr.dev_attr.attr,
|
||||
&sensor_dev_attr_swpld2_major_ver.dev_attr.attr,
|
||||
&sensor_dev_attr_swpld2_minor_ver.dev_attr.attr,
|
||||
&sensor_dev_attr_swpld2_scrtch_reg.dev_attr.attr,
|
||||
&sensor_dev_attr_fan_led.dev_attr.attr,
|
||||
&sensor_dev_attr_sys_led.dev_attr.attr,
|
||||
&sensor_dev_attr_fan_mod1_led.dev_attr.attr,
|
||||
&sensor_dev_attr_fan_mod2_led.dev_attr.attr,
|
||||
&sensor_dev_attr_fan_mod3_led.dev_attr.attr,
|
||||
&sensor_dev_attr_fan_mod4_led.dev_attr.attr,
|
||||
NULL,
|
||||
};
|
||||
|
||||
static struct attribute *swpld3_device_attrs[] = {
|
||||
&sensor_dev_attr_swpld3_reg_value.dev_attr.attr,
|
||||
&sensor_dev_attr_swpld3_reg_addr.dev_attr.attr,
|
||||
&sensor_dev_attr_swpld3_major_ver.dev_attr.attr,
|
||||
&sensor_dev_attr_swpld3_minor_ver.dev_attr.attr,
|
||||
&sensor_dev_attr_swpld3_scrtch_reg.dev_attr.attr,
|
||||
&sensor_dev_attr_sb_ver.dev_attr.attr,
|
||||
&sensor_dev_attr_platform_type.dev_attr.attr,
|
||||
NULL,
|
||||
};
|
||||
|
||||
static struct attribute *swpld4_device_attrs[] = {
|
||||
&sensor_dev_attr_swpld4_reg_value.dev_attr.attr,
|
||||
&sensor_dev_attr_swpld4_reg_addr.dev_attr.attr,
|
||||
&sensor_dev_attr_swpld4_major_ver.dev_attr.attr,
|
||||
&sensor_dev_attr_swpld4_minor_ver.dev_attr.attr,
|
||||
&sensor_dev_attr_swpld4_scrtch_reg.dev_attr.attr,
|
||||
&sensor_dev_attr_bmc_rst.dev_attr.attr,
|
||||
&sensor_dev_attr_cpld_lpc_rst.dev_attr.attr,
|
||||
&sensor_dev_attr_cpld_sw_rst.dev_attr.attr,
|
||||
&sensor_dev_attr_mb_cpld_rst.dev_attr.attr,
|
||||
&sensor_dev_attr_bcm56970_rst.dev_attr.attr,
|
||||
&sensor_dev_attr_cpld_upgrade_rst.dev_attr.attr,
|
||||
&sensor_dev_attr_mb_rst_cpld.dev_attr.attr,
|
||||
&sensor_dev_attr_cpu_rst_mb_oob.dev_attr.attr,
|
||||
&sensor_dev_attr_gpio_phy_rst.dev_attr.attr,
|
||||
&sensor_dev_attr_psu_fan_event.dev_attr.attr,
|
||||
&sensor_dev_attr_cpu_thermal_int.dev_attr.attr,
|
||||
&sensor_dev_attr_fan_int.dev_attr.attr,
|
||||
&sensor_dev_attr_cpld_spi_wp.dev_attr.attr,
|
||||
&sensor_dev_attr_rj45_console_sel.dev_attr.attr,
|
||||
&sensor_dev_attr_system_int.dev_attr.attr,
|
||||
&sensor_dev_attr_cpld_mb_rst_done.dev_attr.attr,
|
||||
&sensor_dev_attr_mb_pwr_ok.dev_attr.attr,
|
||||
&sensor_dev_attr_fan_eeprom_wp.dev_attr.attr,
|
||||
NULL,
|
||||
};
|
||||
|
||||
static struct attribute_group swpld1_device_attr_grp = {
|
||||
.attrs = swpld1_device_attrs,
|
||||
};
|
||||
|
||||
static struct attribute_group swpld2_device_attr_grp = {
|
||||
.attrs = swpld2_device_attrs,
|
||||
};
|
||||
|
||||
static struct attribute_group swpld3_device_attr_grp = {
|
||||
.attrs = swpld3_device_attrs,
|
||||
};
|
||||
|
||||
static struct attribute_group swpld4_device_attr_grp = {
|
||||
.attrs = swpld4_device_attrs,
|
||||
};
|
||||
|
||||
static int __init swpld1_probe(struct platform_device *pdev)
|
||||
{
|
||||
int ret;
|
||||
ret = sysfs_create_group(&pdev->dev.kobj, &swpld1_device_attr_grp);
|
||||
if (ret) {
|
||||
printk(KERN_WARNING "Fail to create cpld attribute group");
|
||||
return -ENODEV;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int __init swpld2_probe(struct platform_device *pdev)
|
||||
{
|
||||
int ret;
|
||||
ret = sysfs_create_group(&pdev->dev.kobj, &swpld2_device_attr_grp);
|
||||
if (ret) {
|
||||
printk(KERN_WARNING "Fail to create cpld attribute group");
|
||||
return -ENODEV;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int __init swpld3_probe(struct platform_device *pdev)
|
||||
{
|
||||
int ret;
|
||||
ret = sysfs_create_group(&pdev->dev.kobj, &swpld3_device_attr_grp);
|
||||
if (ret) {
|
||||
printk(KERN_WARNING "Fail to create cpld attribute group");
|
||||
return -ENODEV;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int __init swpld4_probe(struct platform_device *pdev)
|
||||
{
|
||||
int ret;
|
||||
ret = sysfs_create_group(&pdev->dev.kobj, &swpld4_device_attr_grp);
|
||||
if (ret) {
|
||||
printk(KERN_WARNING "Fail to create cpld attribute group");
|
||||
return -ENODEV;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int __exit swpld1_remove(struct platform_device *pdev)
|
||||
{
|
||||
sysfs_remove_group(&pdev->dev.kobj, &swpld1_device_attr_grp);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int __exit swpld2_remove(struct platform_device *pdev)
|
||||
{
|
||||
sysfs_remove_group(&pdev->dev.kobj, &swpld2_device_attr_grp);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int __exit swpld3_remove(struct platform_device *pdev)
|
||||
{
|
||||
sysfs_remove_group(&pdev->dev.kobj, &swpld3_device_attr_grp);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int __exit swpld4_remove(struct platform_device *pdev)
|
||||
{
|
||||
sysfs_remove_group(&pdev->dev.kobj, &swpld4_device_attr_grp);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct platform_driver swpld1_driver = {
|
||||
.probe = swpld1_probe,
|
||||
.remove = __exit_p(swpld1_remove),
|
||||
.driver = {
|
||||
.owner = THIS_MODULE,
|
||||
.name = "delta-ag9064-swpld1",
|
||||
},
|
||||
};
|
||||
|
||||
static struct platform_driver swpld2_driver = {
|
||||
.probe = swpld2_probe,
|
||||
.remove = __exit_p(swpld2_remove),
|
||||
.driver = {
|
||||
.owner = THIS_MODULE,
|
||||
.name = "delta-ag9064-swpld2",
|
||||
},
|
||||
};
|
||||
|
||||
static struct platform_driver swpld3_driver = {
|
||||
.probe = swpld3_probe,
|
||||
.remove = __exit_p(swpld3_remove),
|
||||
.driver = {
|
||||
.owner = THIS_MODULE,
|
||||
.name = "delta-ag9064-swpld3",
|
||||
},
|
||||
};
|
||||
|
||||
static struct platform_driver swpld4_driver = {
|
||||
.probe = swpld4_probe,
|
||||
.remove = __exit_p(swpld4_remove),
|
||||
.driver = {
|
||||
.owner = THIS_MODULE,
|
||||
.name = "delta-ag9064-swpld4",
|
||||
},
|
||||
};
|
||||
/*---------------- CPLD - end ------------- */
|
||||
|
||||
/*---------------- module initialization ------------- */
|
||||
static void __init delta_ag9064_swpld_init(void)
|
||||
{
|
||||
int ret;
|
||||
printk(KERN_WARNING "ag9064_platform_swpld module initialization\n");
|
||||
|
||||
ret = dni_create_user();
|
||||
if (ret != 0){
|
||||
printk(KERN_WARNING "Fail to create IPMI user\n");
|
||||
}
|
||||
|
||||
// set the SWPLD prob and remove
|
||||
ret = platform_driver_register(&swpld1_driver);
|
||||
if (ret) {
|
||||
printk(KERN_WARNING "Fail to register swpld driver\n");
|
||||
goto error_swpld1_driver;
|
||||
}
|
||||
|
||||
// register the SWPLD
|
||||
ret = platform_device_register(&swpld1_device);
|
||||
if (ret) {
|
||||
printk(KERN_WARNING "Fail to create swpld device\n");
|
||||
goto error_swpld1_device;
|
||||
}
|
||||
|
||||
// set the SWPLD prob and remove
|
||||
ret = platform_driver_register(&swpld2_driver);
|
||||
if (ret) {
|
||||
printk(KERN_WARNING "Fail to register swpld driver\n");
|
||||
goto error_swpld2_driver;
|
||||
}
|
||||
|
||||
// register the SWPLD
|
||||
ret = platform_device_register(&swpld2_device);
|
||||
if (ret) {
|
||||
printk(KERN_WARNING "Fail to create swpld device\n");
|
||||
goto error_swpld2_device;
|
||||
}
|
||||
|
||||
// set the SWPLD prob and remove
|
||||
ret = platform_driver_register(&swpld3_driver);
|
||||
if (ret) {
|
||||
printk(KERN_WARNING "Fail to register swpld driver\n");
|
||||
goto error_swpld3_driver;
|
||||
}
|
||||
|
||||
// register the SWPLD
|
||||
ret = platform_device_register(&swpld3_device);
|
||||
if (ret) {
|
||||
printk(KERN_WARNING "Fail to create swpld device\n");
|
||||
goto error_swpld3_device;
|
||||
}
|
||||
|
||||
// set the SWPLD prob and remove
|
||||
ret = platform_driver_register(&swpld4_driver);
|
||||
if (ret) {
|
||||
printk(KERN_WARNING "Fail to register swpld driver\n");
|
||||
goto error_swpld4_driver;
|
||||
}
|
||||
|
||||
// register the SWPLD
|
||||
ret = platform_device_register(&swpld4_device);
|
||||
if (ret) {
|
||||
printk(KERN_WARNING "Fail to create swpld device\n");
|
||||
goto error_swpld4_device;
|
||||
}
|
||||
return 0;
|
||||
|
||||
error_swpld4_device:
|
||||
platform_driver_unregister(&swpld4_driver);
|
||||
error_swpld4_driver:
|
||||
platform_driver_unregister(&swpld3_device);
|
||||
error_swpld3_device:
|
||||
platform_driver_unregister(&swpld3_driver);
|
||||
error_swpld3_driver:
|
||||
platform_driver_unregister(&swpld2_device);
|
||||
error_swpld2_device:
|
||||
platform_driver_unregister(&swpld2_driver);
|
||||
error_swpld2_driver:
|
||||
platform_driver_unregister(&swpld1_device);
|
||||
error_swpld1_device:
|
||||
platform_driver_unregister(&swpld1_driver);
|
||||
error_swpld1_driver:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void __exit delta_ag9064_swpld_exit(void)
|
||||
{
|
||||
platform_device_unregister(&swpld1_device);
|
||||
platform_driver_unregister(&swpld1_driver);
|
||||
platform_device_unregister(&swpld2_device);
|
||||
platform_driver_unregister(&swpld2_driver);
|
||||
platform_device_unregister(&swpld3_device);
|
||||
platform_driver_unregister(&swpld3_driver);
|
||||
platform_device_unregister(&swpld4_device);
|
||||
platform_driver_unregister(&swpld4_driver);
|
||||
}
|
||||
module_init(delta_ag9064_swpld_init);
|
||||
module_exit(delta_ag9064_swpld_exit);
|
||||
|
||||
MODULE_DESCRIPTION("DNI ag9064 CPLD Platform Support");
|
||||
MODULE_AUTHOR("Stanley Chi <stanley.chi@deltaww.com>");
|
||||
MODULE_LICENSE("GPL");
|
@ -26,6 +26,8 @@ start)
|
||||
modprobe ipmi_devintf
|
||||
modprobe ipmi_si trydefaults=1
|
||||
modprobe delta_ag9064_platform
|
||||
modprobe delta_ag9064_cpld
|
||||
modprobe delta_ag9064_swpld
|
||||
|
||||
/usr/local/bin/ag9064_platform_init.sh
|
||||
|
||||
|
Reference in New Issue
Block a user