sonic-buildimage/platform/broadcom/sonic-platform-modules-dell/common/dell_pmc.c

2310 lines
80 KiB
C
Raw Normal View History

/* Copyright (c) 2017 Dell Inc.*
* dell_s6100_smf.c - driver for Dell SMF
*
* Author: Per Fremrot <per_fremrot@dell.com>
* Author: Paavaanan <paavaanan_t_n@dell.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#include <linux/module.h>
#include <linux/device.h>
#include <linux/init.h>
#include <linux/platform_device.h>
#include <linux/mutex.h>
#include <linux/hwmon.h>
#include <linux/hwmon-sysfs.h>
#include <linux/acpi.h>
#include <linux/bitops.h>
#define SIO_DRVNAME "SMF"
#define DEBUG 1
#define LABELS 1
#define SMF_VERSION_ADDR 0x0000
#define FANIN_MAX 12 /* Counted from 1 */
#define VSEN_MAX 48 /* VSEN1.. */
#define CURR_MAX 6
#define TCPU_MAX 15
#define PSU_MAX 4 /* TODO change to actual sensors */
/* Where are the sensors address/data
registers relative to the region offset */
#define IOREGION_OFFSET 0x10
#define IOREGION_LENGTH 0x4
#define SMF_ADDR_REG_OFFSET 0
#define SMF_READ_DATA_REG_OFFSET 2
#define SMF_WRITE_DATA_REG_OFFSET 3
#define SMF_REG_ADDR 0x200
#define SMF_POR_SRC_REG 0x209
#define SMF_RST_SRC_REG 0x20A
#define SMF_PROBE_ADDR 0x210
#define SIO_REG_DEVID 0x1
#define SIO_Z9100_ID 0x1
#define SIO_S6100_ID 0x2
#define SIO_S4200_ID 0x3
#define SIO_S5148_ID 0x4
/* IOM presence */
#define IO_MODULE_STATUS 0x0310
#define IO_MODULE_PRESENCE 0x0311
/* FAN Tray */
#define S6100_MAX_NUM_FAN_TRAYS 4
#define Z9100_MAX_NUM_FAN_TRAYS 5
#define MAX_NUM_FAN_TRAYS 0x00F0
#define MAX_NUM_FANS_PER_TRAY 0x00F1
#define FAN_TRAY_PRESENCE 0x0113
#define FAN_STATUS_GROUP_A 0x0114
#define FAN_STATUS_GROUP_B 0x0115
#define FAN_TRAY_AIRFLOW 0x0116
/* FAN */
#define SMF_FAN_SPEED_ADDR 0x00F3
#define FAN_TRAY_1_SPEED 0x00F3
#define FAN_TRAY_1_FAN_2_SPEED 0x00F5
#define FAN_TRAY_2_SPEED 0x00F7
#define FAN_TRAY_2_FAN_2_SPEED 0x00F9
#define FAN_TRAY_3_SPEED 0x00FB
#define FAN_TRAY_3_FAN_2_SPEED 0x00FD
#define FAN_TRAY_4_SPEED 0x00FF
#define FAN_TRAY_4_FAN_2_SPEED 0x0101
#define FAN_TRAY_5_FAN_1_SPEED 0x0103
#define FAN_TRAY_5_FAN_2_SPEED 0x0105
#define FAN_TRAY_5 4
#define FAN_1_SERIAL_CODE 0x0117
#define FAN_2_SERIAL_CODE 0x013A
#define FAN_3_SERIAL_CODE 0x015D
#define FAN_4_SERIAL_CODE 0x0180
#define FAN_5_SERIAL_CODE 0x01A3
#define FAN_601_FAULT (2 + 1)
#define IN28_INPUT (27 + 1)
#define IN404_INPUT (43 + 1)
#define IOM_PRESENCE (44 + 1)
#define IOM_PRESENCE_MAX (45 + 1)
#define IN602_INPUT (1 + 1)
#define CURR22_INPUT (1 + 1)
#define CURR602_INPUT (3 + 1)
#define TEMP13_INPUT (12 + 1)
#define TEMP601_INPUT (13 + 1)
/* PSUs */
#define S6100_MAX_NUM_PSUS 2
#define MAX_NUM_PSUS 0x0231
#define CURRENT_TOTAL_POWER 0x0232
/* PSU1 */
#define PSU_1_MAX_POWER 0x0234
#define PSU_1_FUNCTION_SUPPORT 0x0236
#define PSU_1_STATUS 0x0237
#define PSU_1_TEMPERATURE 0x0239
#define PSU_1_FAN_SPEED 0x023B
#define PSU_1_FAN_STATUS 0x023D
#define PSU_1_INPUT_VOLTAGE 0x023E
#define PSU_1_OUTPUT_VOLTAGE 0x0240
#define PSU_1_INPUT_CURRENT 0x0242
#define PSU_1_OUTPUT_CURRENT 0x0244
#define PSU_1_INPUT_POWER 0x0246
#define PSU_1_OUTPUT_POWER 0x0248
#define PSU_1_COUNTRY_CODE 0x024A
/* PSU2 */
#define PSU_2_MAX_POWER 0x026D
#define PSU_2_FUNCTION_SUPPORT 0x026F
#define PSU_2_STATUS 0x0270
#define PSU_2_TEMPERATURE 0x0272
#define PSU_2_FAN_SPEED 0x0274
#define PSU_2_FAN_STATUS 0x0276
#define PSU_2_INPUT_VOLTAGE 0x0277
#define PSU_2_OUTPUT_VOLTAGE 0x0279
#define PSU_2_INPUT_CURRENT 0x027B
#define PSU_2_OUTPUT_CURRENT 0x027D
#define PSU_2_INPUT_POWER 0x027F
#define PSU_2_OUTPUT_POWER 0x0281
#define PSU_2_COUNTRY_CODE 0x0283
/* TEMP */
#define TEMP_SENSOR_1 0x0014
#define TEMP_SENSOR_1_STATUS 0x00DC
#define TEMP_SENSOR_1_HW_LIMIT 0x003E
/* VOLTAGE */
#define CPU_1_VOLTAGE 0x02A8
#define IO_MODULE_1_VOLTAGE 0x02E8
#define SWITCH_CURRENT_S6100 0x02E4
#define SWITCH_CURRENT_Z9100 0x02E2
/* VOLTAGE S6100 */
#define CPU_1_MONITOR_STATUS 0x0308
#define CPU_2_MONITOR_STATUS 0x0309
#define CPU_3_MONITOR_STATUS 0x030A
#define CPU_4_MONITOR_STATUS 0x030B
/* VOLTAGE Z9100 */
#define CPU_5_MONITOR_STATUS 0x02E6
#define CPU_6_MONITOR_STATUS 0x02E7
#define CPU_7_MONITOR_STATUS 0x02E8
#define CPU_8_MONITOR_STATUS 0x02E9
/* EEPROM PPID */
/* FAN and PSU EEPROM PPID format is:
COUNTRY_CODE-PART_NO-MFG_ID-MFG_DATE_CODE-SERIAL_NO-LABEL_REV */
#define EEPROM_COUNTRY_CODE_SIZE 2
#define EEPROM_PART_NO_SIZE 6
#define EEPROM_MFG_ID_SIZE 5
#define EEPROM_MFG_DATE_SIZE 8
#define EEPROM_DATE_CODE_SIZE 3
#define EEPROM_SERIAL_NO_SIZE 4
#define EEPROM_SERVICE_TAG_SIZE 7
#define EEPROM_LABEL_REV_SIZE 3
#define EEPROM_PPID_SIZE 28
/* Mailbox PowerOn Reason */
#define TRACK_POWERON_REASON 0x05FF
unsigned long *mmio;
static struct kobject *dell_kobj;
static unsigned short force_id;
module_param(force_id, ushort, 0);
int smf_ver;
enum kinds {
z9100smf, s6100smf
};
struct smf_devices {
const char *name;
u64 tcpu_mask;
u64 vsen_mask;
u32 curr_mask;
u64 fanin_mask;
u64 psu_mask;
const char *const *temp_label;
const char *const *vsen_label;
const char *const *curr_label;
const char *const *fan_label;
const char *const *psu_label;
};
static const char *const z9100_temp_label[] = {
"CPU On-board (U2900)",
"BCM Switch On-Board #1 (U44)",
"Front BCM On-Board (U4)",
"Front BCM On-Board (U2)",
"Unused",
"BCM Switch On-Board #1 (U38)",
"Unused",
"Unused",
"Rear (U2900)",
"",
"",
"",
"",
"",
"PSU 1",
"PSU 2"
};
static const char *const s6100_temp_label[] = {
"CPU On-board (U2900)",
"BCM On-Board #1 (U44)",
"Front BCM On-board (U4)",
"Front BCM On-board (U2)",
"IOM #1",
"IOM #2",
"IOM #3",
"IOM #4",
"U2 Switch board?",
"Front GE",
"Front SFP+",
"BCM Internal",
"CPU Internal",
"",
"PSU 1",
"PSU 2"
};
static const char *const z9100_vsen_label[] = {
/* CPU Board */
"CPU XP3R3V_EARLY",
"CPU XP5R0V_CP",
"CPU XP3R3V_STD",
"CPU XP3R3V_CP ",
"CPU XP0R75V_VTT_A",
"CPU XP0R75V_VTT_B",
"CPU XP1R07V_CPU",
"CPU XP1R0V_CPU",
"CPU XP12R0V",
"CPU VDDR_CPU_2",
"CPU VDDR_CPU_1",
"CPU XP1R5V_CLK",
"CPU XP1R35V_CPU",
"CPU XP1R8V_CPU",
"CPU XP1R0V_CPU_VNN",
"CPU XP1R0V_CPU_VCC",
"CPU XP1R5V_EARLY",
/* Switch Board */
"SW XP12R0V_MON",
"SW XP3R3V_MON",
"SW XP1R8V_MON",
"SW XP1R25V_MON",
"SW XP1R2V_MON",
"SW XP1R0V_SW_MON",
"SW XP1R0V_ROV_SW_MON",
"SW XP5V_MB_MON",
"SW XP1R8V_FPGA_MON",
"SW XP3R3V_FPGA_MON",
"SW XP3R3V_EARLY_MON",
/* PSU */
"PSU1 VIN",
"PSU1 VOUT",
"PSU2 VIN",
"PSU2 VOUT",
/* IOM 1 */
"",
"",
"",
"",
/* IOM 2 */
"",
"",
"",
"",
/* IOM 3 */
"",
"",
"",
"",
/* IOM 4 */
"",
"",
"",
""
};
static const char *const s6100_vsen_label[] = {
/* CPU Board */
"CPU XP3R3V_EARLY",
"CPU XP5R0V_CP",
"CPU XP3R3V_STD",
"CPU XP3R3V_CP ",
"CPU XP0R75V_VTT_A",
"CPU XP0R75V_VTT_B",
"CPU XP1R07V_CPU",
"CPU XP1R0V_CPU",
"CPU XP12R0V",
"CPU VDDR_CPU_2",
"CPU VDDR_CPU_1",
"CPU XP1R5V_CLK",
"CPU XP1R35V_CPU",
"CPU XP1R8V_CPU",
"CPU XP1R0V_CPU_VNN",
"CPU XP1R0V_CPU_VCC",
"CPU XP1R5V_EARLY",
/* Switch Board */
"SW XP12R0V_MON",
"SW XP3R3V_MON",
"SW XP1R8V_MON",
"SW XP1R25V_MON",
"SW XP1R2V_MON",
"SW XP1R0V_SW_MON",
"SW XP1R0V_ROV_SW_MON",
"XR1R0V_BCM84752_MON",
"SW XP5V_MB_MON",
"SW XP1R8V_FPGA_MON",
"SW XP3R3V_FPGA_MON",
/* PSU */
"PSU1 VIN",
"PSU1 VOUT",
"PSU2 VIN",
"PSU2 VOUT",
/* IOM 1 */
"IOM 1 #1",
"IOM 1 #2",
"IOM 1 #3",
"IOM 1 #4",
/* IOM 2 */
"IOM 2 #1",
"IOM 2 #2",
"IOM 2 #3",
"IOM 2 #4",
/* IOM 1 */
"IOM 3 #1",
"IOM 3 #2",
"IOM 3 #3",
"IOM 3 #4",
/* IOM 1 */
"IOM 4 #1",
"IOM 4 #2",
"IOM 4 #3",
"IOM 4 #4"
};
static const char *const z9100_curr_label[] = {
"XP1R0V",
"XP1R0V_ROV"
};
static const char *const s6100_fan_label[] = {
"Tray1 Fan1",
"",
"Tray2 Fan1",
"",
"Tray3 Fan1",
"",
"Tray4 Fan1",
"",
"",
"",
"Psu1 Fan",
"Psu2 Fan"
};
static const char *const z9100_fan_label[] = {
"Tray1 Fan1",
"Tray1 Fan2",
"Tray2 Fan1",
"Tray2 Fan2",
"Tray3 Fan1",
"Tray3 Fan2",
"Tray4 Fan1",
"Tray4 Fan2",
"Tray5 Fan1",
"Tray5 Fan2",
"Psu1 Fan",
"Psu2 Fan"
};
static const char *const s6100_psu_label[] = {
"Psu1 Input",
"Psu1 Output",
"Psu2 Input",
"Psu2 Output",
};
static const struct smf_devices smf_devices[] = {
[z9100smf] = {
.name = "SMF_Z9100_ON",
.tcpu_mask=0xe1ff,
.vsen_mask=0xfffdffff,
.curr_mask=0x3f,
.fanin_mask=0xfff,
.psu_mask=0xf,
.temp_label = z9100_temp_label,
.vsen_label = z9100_vsen_label,
.curr_label = z9100_curr_label,
.fan_label = z9100_fan_label,
.psu_label = s6100_psu_label
},
[s6100smf] = {
.name = "SMF_S6100_ON",
.tcpu_mask=0x7fff,
.vsen_mask=0xfffffefdffff,
.curr_mask=0x3f,
.fanin_mask=0xc55,
.psu_mask=0xf,
.temp_label = s6100_temp_label,
.vsen_label = s6100_vsen_label,
.curr_label = z9100_curr_label,
.fan_label = s6100_fan_label,
.psu_label = s6100_psu_label
}
};
/*
* For each registered chip, we need to keep some data in memory.
* The structure is dynamically allocated.
*/
struct smf_data {
enum kinds kind; /* Inherited from SuperIO kind */
unsigned short addr;
struct device *hwmon_dev;
struct mutex lock;
u64 tcpu_mask;
u64 vsen_mask;
u32 curr_mask;
u64 fanin_mask;
u64 psu_mask;
const char * const *temp_label;
const char * const *vsen_label;
const char * const *curr_label;
const char * const *fan_label;
const char * const *psu_label;
};
struct smf_sio_data {
int sioreg;
enum kinds kind;
};
static int smf_write_reg(struct smf_data *data, u16 reg, u16 dev_data)
{
int res = 0;
mutex_lock(&data->lock);
outb_p(reg>> 8, data->addr + SMF_ADDR_REG_OFFSET);
outb_p(reg & 0xff, data->addr + SMF_ADDR_REG_OFFSET + 1);
outb_p(dev_data & 0xff, data->addr + SMF_WRITE_DATA_REG_OFFSET);
mutex_unlock(&data->lock);
return res;
}
static int smf_read_reg(struct smf_data *data, u16 reg)
{
int res;
mutex_lock(&data->lock);
outb_p(reg>> 8, data->addr + SMF_ADDR_REG_OFFSET);
outb_p(reg & 0xff, data->addr + SMF_ADDR_REG_OFFSET + 1);
res = inb_p(data->addr + SMF_READ_DATA_REG_OFFSET);
mutex_unlock(&data->lock);
return res;
}
static int smf_read_reg16(struct smf_data *data, u16 reg)
{
int res;
mutex_lock(&data->lock);
outb_p(reg>> 8, data->addr + SMF_ADDR_REG_OFFSET);
outb_p(reg & 0xff, data->addr + SMF_ADDR_REG_OFFSET + 1);
res = inb_p(data->addr + SMF_READ_DATA_REG_OFFSET);
outb_p((reg + 1)>> 8, data->addr + SMF_ADDR_REG_OFFSET);
outb_p((reg + 1) & 0xff, data->addr + SMF_ADDR_REG_OFFSET + 1);
res = (res << 8) + inb_p(data->addr + SMF_READ_DATA_REG_OFFSET);
mutex_unlock(&data->lock);
return res;
}
/* SMF Version */
static ssize_t show_smf_version(struct device *dev,
struct device_attribute *devattr, char *buf)
{
int index = to_sensor_dev_attr(devattr)->index;
unsigned int ret = 0;
unsigned int smf_version = 0;
unsigned int smf_firmware_major_ver = 0;
unsigned int smf_firmware_minor_ver = 0;
struct smf_data *data = dev_get_drvdata(dev);
ret = smf_read_reg(data, (SMF_VERSION_ADDR + index*2));
printk("smf_firmware_details-->0x%x index[%d]", ret, index);
if (index > 0) {
smf_firmware_major_ver = ((ret & (0xC0)) >> 6);
smf_firmware_minor_ver = (ret & (0x3F));
ret = sprintf(buf, "%u.%u\n", smf_firmware_major_ver,
smf_firmware_minor_ver);
} else {
smf_version = ret;
ret = sprintf(buf, "%u\n", smf_version);
}
return ret;
}
/* SMF Reset Reason */
static ssize_t show_reset_reason(struct device *dev,
struct device_attribute *devattr, char *buf)
{
unsigned int ret = 0;
ret = inb(SMF_RST_SRC_REG);
if(ret < 0)
return ret;
return sprintf(buf, "%x\n", ret);
}
/* SMF Power ON Reason */
static ssize_t show_power_on_reason(struct device *dev,
struct device_attribute *devattr, char *buf)
{
unsigned int ret = 0;
ret = inb(SMF_POR_SRC_REG);
if(ret < 0)
return ret;
return sprintf(buf, "%x\n", ret);
}
/* SMF Mailbox Power ON Reason */
static ssize_t set_mb_poweron_reason(struct device *dev,
struct device_attribute *devattr, const char *buf, size_t count)
{
int err = 0;
unsigned int dev_data = 0;
struct smf_data *data = dev_get_drvdata(dev);
err = kstrtouint(buf, 16, &dev_data);
if (err)
return err;
err = smf_write_reg(data, TRACK_POWERON_REASON, dev_data);
if(err < 0)
return err;
return count;
}
static ssize_t show_mb_poweron_reason(struct device *dev,
struct device_attribute *devattr, char *buf)
{
unsigned int ret = 0;
struct smf_data *data = dev_get_drvdata(dev);
ret = smf_read_reg(data, TRACK_POWERON_REASON);
if(ret < 0)
return ret;
return sprintf(buf, "0x%x\n", ret);
}
/* FANIN ATTR */
static ssize_t
show_fan_label(struct device *dev, struct device_attribute *attr, char *buf)
{
struct smf_data *data = dev_get_drvdata(dev);
int nr = to_sensor_dev_attr(attr)->index;
return sprintf(buf, "%s\n", data->fan_label[nr]);
}
static ssize_t show_fan(struct device *dev,
struct device_attribute *devattr, char *buf)
{
int index = to_sensor_dev_attr(devattr)->index;
struct smf_data *data = dev_get_drvdata(dev);
int export_hex=0;
unsigned int ret = -1;
unsigned rpm;
if (index <10)
ret = smf_read_reg16(data, SMF_FAN_SPEED_ADDR + index * 2);
else switch (index) {
case 10:
ret = smf_read_reg16(data, PSU_1_FAN_SPEED);
break;
case 11:
ret = smf_read_reg16(data, PSU_2_FAN_SPEED);
break;
case 12:
ret = (~smf_read_reg(data, FAN_TRAY_PRESENCE) & 0xff);
export_hex = 1;
break;
default:
return ret;
}
if (ret < 0)
return ret;
if (ret & 0x8000)
ret = - (ret & 0x7fff);
rpm = ret;
if(export_hex)
return sprintf(buf, "%x\n", rpm);
else
return sprintf(buf, "%u\n", rpm);
}
static ssize_t show_fan_fault(struct device *dev,
struct device_attribute *devattr, char *buf)
{
int index = to_sensor_dev_attr(devattr)->index;
struct smf_data *data = dev_get_drvdata(dev);
int ret=1, fan_status;
index = index / 2;
fan_status = ~smf_read_reg(data, FAN_TRAY_PRESENCE);
if (fan_status & (1 << (index)))
ret=0;
if (ret < 0)
return ret;
return sprintf(buf, "%d\n", ret);
}
static ssize_t show_fan_alarm(struct device *dev,
struct device_attribute *devattr, char *buf)
{
int index = to_sensor_dev_attr(devattr)->index;
struct smf_data *data = dev_get_drvdata(dev);
int ret, psu_fan_status=0;
if (data->kind == z9100smf) {
if ((index % 2) == 0)
index = index / 2;
else
index = (index / 2) + 5;
}
if (data->kind == s6100smf)
index = index / 2;
if (index > 7) {
psu_fan_status = ~smf_read_reg(data, FAN_STATUS_GROUP_A);
index = index % 8;
} else
psu_fan_status = ~smf_read_reg(data, FAN_STATUS_GROUP_B);
if (psu_fan_status & (1 << (index)))
ret=0;
else
ret=1;
return sprintf(buf, "%d\n", ret);
}
static ssize_t show_fan_airflow(struct device *dev,
struct device_attribute *devattr, char *buf)
{
int index = to_sensor_dev_attr(devattr)->index;
struct smf_data *data = dev_get_drvdata(dev);
int ret=1, fan_airflow;
if (data->kind == s6100smf && index == FAN_TRAY_5)
return 0;
fan_airflow = smf_read_reg(data, FAN_TRAY_AIRFLOW);
if (fan_airflow & (1 << (index)))
ret=1;
if (ret < 0)
return ret;
return sprintf(buf, "%d\n", ret);
}
static ssize_t show_psu_fan(struct device *dev,
struct device_attribute *devattr, char *buf)
{
int index = to_sensor_dev_attr(devattr)->index;
struct smf_data *data = dev_get_drvdata(dev);
int ret=0, fan_status;
if (index < FAN_601_FAULT){
fan_status = smf_read_reg(data, PSU_1_FAN_STATUS);
ret = (fan_status >> index) & 1;
}
else{
fan_status = smf_read_reg(data, PSU_2_FAN_STATUS);
ret = (fan_status >> (index - 3)) & 1;
}
if (ret < 0)
return ret;
return sprintf(buf, "%d\n", ret);
}
static umode_t smf_fanin_is_visible(struct kobject *kobj,
struct attribute *a, int n)
{
struct device *dev = container_of(kobj, struct device, kobj);
struct smf_data *data = dev_get_drvdata(dev);
if (data->fanin_mask & (1 << (n % FANIN_MAX)))
return a->mode;
return 0;
}
static umode_t smf_dell_is_visible(struct kobject *kobj,
struct attribute *a, int n)
{
return a->mode;
}
static SENSOR_DEVICE_ATTR(fan1_input, S_IRUGO, show_fan, NULL, 0);
static SENSOR_DEVICE_ATTR(fan2_input, S_IRUGO, show_fan, NULL, 1);
static SENSOR_DEVICE_ATTR(fan3_input, S_IRUGO, show_fan, NULL, 2);
static SENSOR_DEVICE_ATTR(fan4_input, S_IRUGO, show_fan, NULL, 3);
static SENSOR_DEVICE_ATTR(fan5_input, S_IRUGO, show_fan, NULL, 4);
static SENSOR_DEVICE_ATTR(fan6_input, S_IRUGO, show_fan, NULL, 5);
static SENSOR_DEVICE_ATTR(fan7_input, S_IRUGO, show_fan, NULL, 6);
static SENSOR_DEVICE_ATTR(fan8_input, S_IRUGO, show_fan, NULL, 7);
static SENSOR_DEVICE_ATTR(fan9_input, S_IRUGO, show_fan, NULL, 8);
static SENSOR_DEVICE_ATTR(fan10_input, S_IRUGO, show_fan, NULL,9);
/* PSU1 FAN */
static SENSOR_DEVICE_ATTR(fan11_input, S_IRUGO, show_fan, NULL, 10);
/* PSU2 FAN */
static SENSOR_DEVICE_ATTR(fan12_input, S_IRUGO, show_fan, NULL, 11);
static SENSOR_DEVICE_ATTR(fan1_alarm, S_IRUGO, show_fan_alarm, NULL, 0);
static SENSOR_DEVICE_ATTR(fan2_alarm, S_IRUGO, show_fan_alarm, NULL, 1);
static SENSOR_DEVICE_ATTR(fan3_alarm, S_IRUGO, show_fan_alarm, NULL, 2);
static SENSOR_DEVICE_ATTR(fan4_alarm, S_IRUGO, show_fan_alarm, NULL, 3);
static SENSOR_DEVICE_ATTR(fan5_alarm, S_IRUGO, show_fan_alarm, NULL, 4);
static SENSOR_DEVICE_ATTR(fan6_alarm, S_IRUGO, show_fan_alarm, NULL, 5);
static SENSOR_DEVICE_ATTR(fan7_alarm, S_IRUGO, show_fan_alarm, NULL, 6);
static SENSOR_DEVICE_ATTR(fan8_alarm, S_IRUGO, show_fan_alarm, NULL, 7);
static SENSOR_DEVICE_ATTR(fan9_alarm, S_IRUGO, show_fan_alarm, NULL, 8);
static SENSOR_DEVICE_ATTR(fan10_alarm, S_IRUGO, show_fan_alarm, NULL, 9);
static SENSOR_DEVICE_ATTR(fan11_alarm, S_IRUGO, show_psu_fan, NULL, 1);
static SENSOR_DEVICE_ATTR(fan12_alarm, S_IRUGO, show_psu_fan, NULL, 4);
static SENSOR_DEVICE_ATTR(fan1_fault, S_IRUGO, show_fan_fault, NULL, 0);
static SENSOR_DEVICE_ATTR(fan2_fault, S_IRUGO, show_fan_fault, NULL, 1);
static SENSOR_DEVICE_ATTR(fan3_fault, S_IRUGO, show_fan_fault, NULL, 2);
static SENSOR_DEVICE_ATTR(fan4_fault, S_IRUGO, show_fan_fault, NULL, 3);
static SENSOR_DEVICE_ATTR(fan5_fault, S_IRUGO, show_fan_fault, NULL, 4);
static SENSOR_DEVICE_ATTR(fan6_fault, S_IRUGO, show_fan_fault, NULL, 5);
static SENSOR_DEVICE_ATTR(fan7_fault, S_IRUGO, show_fan_fault, NULL, 6);
static SENSOR_DEVICE_ATTR(fan8_fault, S_IRUGO, show_fan_fault, NULL, 7);
static SENSOR_DEVICE_ATTR(fan9_fault, S_IRUGO, show_fan_fault, NULL, 8);
static SENSOR_DEVICE_ATTR(fan10_fault, S_IRUGO, show_fan_fault, NULL, 9);
static SENSOR_DEVICE_ATTR(fan11_fault, S_IRUGO, show_psu_fan, NULL, 2);
static SENSOR_DEVICE_ATTR(fan12_fault, S_IRUGO, show_psu_fan, NULL, 5);
static SENSOR_DEVICE_ATTR(fan1_label, S_IRUGO, show_fan_label, NULL, 0);
static SENSOR_DEVICE_ATTR(fan2_label, S_IRUGO, show_fan_label, NULL, 1);
static SENSOR_DEVICE_ATTR(fan3_label, S_IRUGO, show_fan_label, NULL, 2);
static SENSOR_DEVICE_ATTR(fan4_label, S_IRUGO, show_fan_label, NULL, 3);
static SENSOR_DEVICE_ATTR(fan5_label, S_IRUGO, show_fan_label, NULL, 4);
static SENSOR_DEVICE_ATTR(fan6_label, S_IRUGO, show_fan_label, NULL, 5);
static SENSOR_DEVICE_ATTR(fan7_label, S_IRUGO, show_fan_label, NULL, 6);
static SENSOR_DEVICE_ATTR(fan8_label, S_IRUGO, show_fan_label, NULL, 7);
static SENSOR_DEVICE_ATTR(fan9_label, S_IRUGO, show_fan_label, NULL, 8);
static SENSOR_DEVICE_ATTR(fan10_label, S_IRUGO, show_fan_label, NULL, 9);
static SENSOR_DEVICE_ATTR(fan11_label, S_IRUGO, show_fan_label, NULL, 10);
static SENSOR_DEVICE_ATTR(fan12_label, S_IRUGO, show_fan_label, NULL, 11);
static struct attribute *smf_fanin_attrs[] = {
&sensor_dev_attr_fan1_input.dev_attr.attr,
&sensor_dev_attr_fan2_input.dev_attr.attr,
&sensor_dev_attr_fan3_input.dev_attr.attr,
&sensor_dev_attr_fan4_input.dev_attr.attr,
&sensor_dev_attr_fan5_input.dev_attr.attr,
&sensor_dev_attr_fan6_input.dev_attr.attr,
&sensor_dev_attr_fan7_input.dev_attr.attr,
&sensor_dev_attr_fan8_input.dev_attr.attr,
&sensor_dev_attr_fan9_input.dev_attr.attr,
&sensor_dev_attr_fan10_input.dev_attr.attr,
&sensor_dev_attr_fan11_input.dev_attr.attr,
&sensor_dev_attr_fan12_input.dev_attr.attr,
&sensor_dev_attr_fan1_label.dev_attr.attr,
&sensor_dev_attr_fan2_label.dev_attr.attr,
&sensor_dev_attr_fan3_label.dev_attr.attr,
&sensor_dev_attr_fan4_label.dev_attr.attr,
&sensor_dev_attr_fan5_label.dev_attr.attr,
&sensor_dev_attr_fan6_label.dev_attr.attr,
&sensor_dev_attr_fan7_label.dev_attr.attr,
&sensor_dev_attr_fan8_label.dev_attr.attr,
&sensor_dev_attr_fan9_label.dev_attr.attr,
&sensor_dev_attr_fan10_label.dev_attr.attr,
&sensor_dev_attr_fan11_label.dev_attr.attr,
&sensor_dev_attr_fan12_label.dev_attr.attr,
&sensor_dev_attr_fan1_alarm.dev_attr.attr,
&sensor_dev_attr_fan2_alarm.dev_attr.attr,
&sensor_dev_attr_fan3_alarm.dev_attr.attr,
&sensor_dev_attr_fan4_alarm.dev_attr.attr,
&sensor_dev_attr_fan5_alarm.dev_attr.attr,
&sensor_dev_attr_fan6_alarm.dev_attr.attr,
&sensor_dev_attr_fan7_alarm.dev_attr.attr,
&sensor_dev_attr_fan8_alarm.dev_attr.attr,
&sensor_dev_attr_fan9_alarm.dev_attr.attr,
&sensor_dev_attr_fan10_alarm.dev_attr.attr,
&sensor_dev_attr_fan11_alarm.dev_attr.attr,
&sensor_dev_attr_fan12_alarm.dev_attr.attr,
&sensor_dev_attr_fan1_fault.dev_attr.attr,
&sensor_dev_attr_fan2_fault.dev_attr.attr,
&sensor_dev_attr_fan3_fault.dev_attr.attr,
&sensor_dev_attr_fan4_fault.dev_attr.attr,
&sensor_dev_attr_fan5_fault.dev_attr.attr,
&sensor_dev_attr_fan6_fault.dev_attr.attr,
&sensor_dev_attr_fan7_fault.dev_attr.attr,
&sensor_dev_attr_fan8_fault.dev_attr.attr,
&sensor_dev_attr_fan9_fault.dev_attr.attr,
&sensor_dev_attr_fan10_fault.dev_attr.attr,
&sensor_dev_attr_fan11_fault.dev_attr.attr,
&sensor_dev_attr_fan12_fault.dev_attr.attr,
NULL
};
/* VSEN ATTR */
static ssize_t
show_voltage_label(struct device *dev,
struct device_attribute *attr, char *buf)
{
struct smf_data *data = dev_get_drvdata(dev);
int nr = to_sensor_dev_attr(attr)->index;
return sprintf(buf, "%s\n", data->vsen_label[nr]);
}
static ssize_t show_voltage(struct device *dev,
struct device_attribute *devattr, char *buf)
{
int index = to_sensor_dev_attr(devattr)->index;
struct smf_data *data = dev_get_drvdata(dev);
int volt, ret=0;
int export_hex=0;
/*0 to 27 */
if (index < IN28_INPUT) /* Voltage sensors */
ret = smf_read_reg16(data, CPU_1_VOLTAGE + index * 2);
else if ((data->kind == s6100smf) && (index < IN404_INPUT))
ret = smf_read_reg16(data, IO_MODULE_1_VOLTAGE + index * 2);
else if ((data->kind == s6100smf) && (index < IOM_PRESENCE))
ret = smf_read_reg(data, IO_MODULE_STATUS);
else if ((data->kind == s6100smf) && (index < IOM_PRESENCE_MAX))
ret = smf_read_reg(data, IO_MODULE_PRESENCE);
if (ret < 0)
return ret;
if(index < 44)
volt = ret*10;
else
export_hex=1;
if(export_hex)
return sprintf(buf, "%x\n", ret);
else
return sprintf(buf, "%d\n", volt);
}
static ssize_t show_psu_voltage(struct device *dev,
struct device_attribute *devattr, char *buf)
{
int index = to_sensor_dev_attr(devattr)->index;
struct smf_data *data = dev_get_drvdata(dev);
int ret;
if (index < 2) /* PSU1 */
ret = smf_read_reg16(data, PSU_1_INPUT_VOLTAGE + index * 2);
else /* PSU2 */
ret = smf_read_reg16(data, PSU_2_INPUT_VOLTAGE + ((index - 2) * 2));
if (ret < 0)
return ret;
return sprintf(buf, "%d\n", ret*10);
}
static ssize_t show_voltage_alarm(struct device *dev,
struct device_attribute *devattr, char *buf)
{
int index = to_sensor_dev_attr(devattr)->index;
struct smf_data *data = dev_get_drvdata(dev);
unsigned status=0;
int ret;
if (index < 8) {
if (data->kind == s6100smf)
status = smf_read_reg16(data, CPU_1_MONITOR_STATUS);
else
status = smf_read_reg16(data, CPU_5_MONITOR_STATUS);
ret = status & (1 << index);
}
else if (index < 15) {
if (data->kind == s6100smf)
ret = smf_read_reg16(data, CPU_2_MONITOR_STATUS);
else
ret = smf_read_reg16(data, CPU_6_MONITOR_STATUS);
ret = status & (1 << index);
}
else if (index < 23) {
if (data->kind == s6100smf)
ret = smf_read_reg16(data, CPU_3_MONITOR_STATUS);
else
ret = smf_read_reg16(data, CPU_7_MONITOR_STATUS);
ret = status & (1 << index);
}
else {
if (data->kind == s6100smf)
ret = smf_read_reg16(data, CPU_4_MONITOR_STATUS);
else
ret = smf_read_reg16(data, CPU_8_MONITOR_STATUS);
ret = status & (1 << index);
}
if (ret < 0)
return ret;
return sprintf(buf, "%d\n", ret);
}
static umode_t smf_vsen_is_visible(struct kobject *kobj,
struct attribute *a, int n)
{
struct device *dev = container_of(kobj, struct device, kobj);
struct smf_data *data = dev_get_drvdata(dev);
if (data->vsen_mask & (1 << (n % VSEN_MAX)))
return a->mode;
return 0;
}
static SENSOR_DEVICE_ATTR(in1_input, S_IRUGO, show_voltage, NULL, 0);
static SENSOR_DEVICE_ATTR(in2_input, S_IRUGO, show_voltage, NULL, 1);
static SENSOR_DEVICE_ATTR(in3_input, S_IRUGO, show_voltage, NULL, 2);
static SENSOR_DEVICE_ATTR(in4_input, S_IRUGO, show_voltage, NULL, 3);
static SENSOR_DEVICE_ATTR(in5_input, S_IRUGO, show_voltage, NULL, 4);
static SENSOR_DEVICE_ATTR(in6_input, S_IRUGO, show_voltage, NULL, 5);
static SENSOR_DEVICE_ATTR(in7_input, S_IRUGO, show_voltage, NULL, 6);
static SENSOR_DEVICE_ATTR(in8_input, S_IRUGO, show_voltage, NULL, 7);
static SENSOR_DEVICE_ATTR(in9_input, S_IRUGO, show_voltage, NULL, 8);
static SENSOR_DEVICE_ATTR(in10_input, S_IRUGO, show_voltage, NULL, 9);
static SENSOR_DEVICE_ATTR(in11_input, S_IRUGO, show_voltage, NULL, 10);
static SENSOR_DEVICE_ATTR(in12_input, S_IRUGO, show_voltage, NULL, 11);
static SENSOR_DEVICE_ATTR(in13_input, S_IRUGO, show_voltage, NULL, 12);
static SENSOR_DEVICE_ATTR(in14_input, S_IRUGO, show_voltage, NULL, 13);
static SENSOR_DEVICE_ATTR(in15_input, S_IRUGO, show_voltage, NULL, 14);
static SENSOR_DEVICE_ATTR(in16_input, S_IRUGO, show_voltage, NULL, 15);
static SENSOR_DEVICE_ATTR(in17_input, S_IRUGO, show_voltage, NULL, 16);
static SENSOR_DEVICE_ATTR(in18_input, S_IRUGO, show_voltage, NULL, 17);
static SENSOR_DEVICE_ATTR(in19_input, S_IRUGO, show_voltage, NULL, 18);
static SENSOR_DEVICE_ATTR(in20_input, S_IRUGO, show_voltage, NULL, 19);
static SENSOR_DEVICE_ATTR(in21_input, S_IRUGO, show_voltage, NULL, 20);
static SENSOR_DEVICE_ATTR(in22_input, S_IRUGO, show_voltage, NULL, 21);
static SENSOR_DEVICE_ATTR(in23_input, S_IRUGO, show_voltage, NULL, 22);
static SENSOR_DEVICE_ATTR(in24_input, S_IRUGO, show_voltage, NULL, 23);
static SENSOR_DEVICE_ATTR(in25_input, S_IRUGO, show_voltage, NULL, 24);
static SENSOR_DEVICE_ATTR(in26_input, S_IRUGO, show_voltage, NULL, 25);
static SENSOR_DEVICE_ATTR(in27_input, S_IRUGO, show_voltage, NULL, 26);
static SENSOR_DEVICE_ATTR(in28_input, S_IRUGO, show_voltage, NULL, 27);
/* PSU1 Voltage*/
static SENSOR_DEVICE_ATTR(in29_input, S_IRUGO, show_psu_voltage, NULL, 0);
static SENSOR_DEVICE_ATTR(in30_input, S_IRUGO, show_psu_voltage, NULL, 1);
/* PSU2 Voltage*/
static SENSOR_DEVICE_ATTR(in31_input, S_IRUGO, show_psu_voltage, NULL, 2);
static SENSOR_DEVICE_ATTR(in32_input, S_IRUGO, show_psu_voltage, NULL, 3);
/*IO Modules Voltage*/
static SENSOR_DEVICE_ATTR(in101_input, S_IRUGO, show_voltage, NULL, 28);
static SENSOR_DEVICE_ATTR(in102_input, S_IRUGO, show_voltage, NULL, 29);
static SENSOR_DEVICE_ATTR(in103_input, S_IRUGO, show_voltage, NULL, 30);
static SENSOR_DEVICE_ATTR(in104_input, S_IRUGO, show_voltage, NULL, 31);
static SENSOR_DEVICE_ATTR(in201_input, S_IRUGO, show_voltage, NULL, 32);
static SENSOR_DEVICE_ATTR(in202_input, S_IRUGO, show_voltage, NULL, 33);
static SENSOR_DEVICE_ATTR(in203_input, S_IRUGO, show_voltage, NULL, 34);
static SENSOR_DEVICE_ATTR(in204_input, S_IRUGO, show_voltage, NULL, 35);
static SENSOR_DEVICE_ATTR(in301_input, S_IRUGO, show_voltage, NULL, 36);
static SENSOR_DEVICE_ATTR(in302_input, S_IRUGO, show_voltage, NULL, 37);
static SENSOR_DEVICE_ATTR(in303_input, S_IRUGO, show_voltage, NULL, 38);
static SENSOR_DEVICE_ATTR(in304_input, S_IRUGO, show_voltage, NULL, 39);
static SENSOR_DEVICE_ATTR(in401_input, S_IRUGO, show_voltage, NULL, 40);
static SENSOR_DEVICE_ATTR(in402_input, S_IRUGO, show_voltage, NULL, 41);
static SENSOR_DEVICE_ATTR(in403_input, S_IRUGO, show_voltage, NULL, 42);
static SENSOR_DEVICE_ATTR(in404_input, S_IRUGO, show_voltage, NULL, 43);
static SENSOR_DEVICE_ATTR(in1_label, S_IRUGO, show_voltage_label, NULL, 0);
static SENSOR_DEVICE_ATTR(in2_label, S_IRUGO, show_voltage_label, NULL, 1);
static SENSOR_DEVICE_ATTR(in3_label, S_IRUGO, show_voltage_label, NULL, 2);
static SENSOR_DEVICE_ATTR(in4_label, S_IRUGO, show_voltage_label, NULL, 3);
static SENSOR_DEVICE_ATTR(in5_label, S_IRUGO, show_voltage_label, NULL, 4);
static SENSOR_DEVICE_ATTR(in6_label, S_IRUGO, show_voltage_label, NULL, 5);
static SENSOR_DEVICE_ATTR(in7_label, S_IRUGO, show_voltage_label, NULL, 6);
static SENSOR_DEVICE_ATTR(in8_label, S_IRUGO, show_voltage_label, NULL, 7);
static SENSOR_DEVICE_ATTR(in9_label, S_IRUGO, show_voltage_label, NULL, 8);
static SENSOR_DEVICE_ATTR(in10_label, S_IRUGO, show_voltage_label, NULL, 9);
static SENSOR_DEVICE_ATTR(in11_label, S_IRUGO, show_voltage_label, NULL, 10);
static SENSOR_DEVICE_ATTR(in12_label, S_IRUGO, show_voltage_label, NULL, 11);
static SENSOR_DEVICE_ATTR(in13_label, S_IRUGO, show_voltage_label, NULL, 12);
static SENSOR_DEVICE_ATTR(in14_label, S_IRUGO, show_voltage_label, NULL, 13);
static SENSOR_DEVICE_ATTR(in15_label, S_IRUGO, show_voltage_label, NULL, 14);
static SENSOR_DEVICE_ATTR(in16_label, S_IRUGO, show_voltage_label, NULL, 15);
static SENSOR_DEVICE_ATTR(in17_label, S_IRUGO, show_voltage_label, NULL, 16);
static SENSOR_DEVICE_ATTR(in18_label, S_IRUGO, show_voltage_label, NULL, 17);
static SENSOR_DEVICE_ATTR(in19_label, S_IRUGO, show_voltage_label, NULL, 18);
static SENSOR_DEVICE_ATTR(in20_label, S_IRUGO, show_voltage_label, NULL, 19);
static SENSOR_DEVICE_ATTR(in21_label, S_IRUGO, show_voltage_label, NULL, 20);
static SENSOR_DEVICE_ATTR(in22_label, S_IRUGO, show_voltage_label, NULL, 21);
static SENSOR_DEVICE_ATTR(in23_label, S_IRUGO, show_voltage_label, NULL, 22);
static SENSOR_DEVICE_ATTR(in24_label, S_IRUGO, show_voltage_label, NULL, 23);
static SENSOR_DEVICE_ATTR(in25_label, S_IRUGO, show_voltage_label, NULL, 24);
static SENSOR_DEVICE_ATTR(in26_label, S_IRUGO, show_voltage_label, NULL, 25);
static SENSOR_DEVICE_ATTR(in27_label, S_IRUGO, show_voltage_label, NULL, 26);
static SENSOR_DEVICE_ATTR(in28_label, S_IRUGO, show_voltage_label, NULL, 27);
/* PSU1 Voltage Label*/
static SENSOR_DEVICE_ATTR(in29_label, S_IRUGO, show_voltage_label, NULL, 28);
static SENSOR_DEVICE_ATTR(in30_label, S_IRUGO, show_voltage_label, NULL, 29);
/* PSU2 Voltage Label*/
static SENSOR_DEVICE_ATTR(in31_label, S_IRUGO, show_voltage_label, NULL, 30);
static SENSOR_DEVICE_ATTR(in32_label, S_IRUGO, show_voltage_label, NULL, 31);
/*IO Modules Labels*/
static SENSOR_DEVICE_ATTR(in101_label, S_IRUGO, show_voltage_label, NULL, 32);
static SENSOR_DEVICE_ATTR(in102_label, S_IRUGO, show_voltage_label, NULL, 33);
static SENSOR_DEVICE_ATTR(in103_label, S_IRUGO, show_voltage_label, NULL, 34);
static SENSOR_DEVICE_ATTR(in104_label, S_IRUGO, show_voltage_label, NULL, 35);
static SENSOR_DEVICE_ATTR(in201_label, S_IRUGO, show_voltage_label, NULL, 36);
static SENSOR_DEVICE_ATTR(in202_label, S_IRUGO, show_voltage_label, NULL, 37);
static SENSOR_DEVICE_ATTR(in203_label, S_IRUGO, show_voltage_label, NULL, 38);
static SENSOR_DEVICE_ATTR(in204_label, S_IRUGO, show_voltage_label, NULL, 39);
static SENSOR_DEVICE_ATTR(in301_label, S_IRUGO, show_voltage_label, NULL, 40);
static SENSOR_DEVICE_ATTR(in302_label, S_IRUGO, show_voltage_label, NULL, 41);
static SENSOR_DEVICE_ATTR(in303_label, S_IRUGO, show_voltage_label, NULL, 42);
static SENSOR_DEVICE_ATTR(in304_label, S_IRUGO, show_voltage_label, NULL, 43);
static SENSOR_DEVICE_ATTR(in401_label, S_IRUGO, show_voltage_label, NULL, 44);
static SENSOR_DEVICE_ATTR(in402_label, S_IRUGO, show_voltage_label, NULL, 45);
static SENSOR_DEVICE_ATTR(in403_label, S_IRUGO, show_voltage_label, NULL, 46);
static SENSOR_DEVICE_ATTR(in404_label, S_IRUGO, show_voltage_label, NULL, 47);
/* CPU Voltage Alarm */
static SENSOR_DEVICE_ATTR(in1_alarm, S_IRUGO, show_voltage_alarm, NULL, 0);
static SENSOR_DEVICE_ATTR(in2_alarm, S_IRUGO, show_voltage_alarm, NULL, 1);
static SENSOR_DEVICE_ATTR(in3_alarm, S_IRUGO, show_voltage_alarm, NULL, 2);
static SENSOR_DEVICE_ATTR(in4_alarm, S_IRUGO, show_voltage_alarm, NULL, 3);
static SENSOR_DEVICE_ATTR(in5_alarm, S_IRUGO, show_voltage_alarm, NULL, 4);
static SENSOR_DEVICE_ATTR(in6_alarm, S_IRUGO, show_voltage_alarm, NULL, 5);
static SENSOR_DEVICE_ATTR(in7_alarm, S_IRUGO, show_voltage_alarm, NULL, 6);
static SENSOR_DEVICE_ATTR(in8_alarm, S_IRUGO, show_voltage_alarm, NULL, 7);
static SENSOR_DEVICE_ATTR(in9_alarm, S_IRUGO, show_voltage_alarm, NULL, 8);
static SENSOR_DEVICE_ATTR(in10_alarm, S_IRUGO, show_voltage_alarm, NULL, 9);
static SENSOR_DEVICE_ATTR(in11_alarm, S_IRUGO, show_voltage_alarm, NULL, 10);
static SENSOR_DEVICE_ATTR(in12_alarm, S_IRUGO, show_voltage_alarm, NULL, 11);
static SENSOR_DEVICE_ATTR(in13_alarm, S_IRUGO, show_voltage_alarm, NULL, 12);
static SENSOR_DEVICE_ATTR(in14_alarm, S_IRUGO, show_voltage_alarm, NULL, 13);
static SENSOR_DEVICE_ATTR(in15_alarm, S_IRUGO, show_voltage_alarm, NULL, 14);
static SENSOR_DEVICE_ATTR(in16_alarm, S_IRUGO, show_voltage_alarm, NULL, 15);
static SENSOR_DEVICE_ATTR(in17_alarm, S_IRUGO, show_voltage_alarm, NULL, 16);
static SENSOR_DEVICE_ATTR(in18_alarm, S_IRUGO, show_voltage_alarm, NULL, 17);
static SENSOR_DEVICE_ATTR(in19_alarm, S_IRUGO, show_voltage_alarm, NULL, 18);
static SENSOR_DEVICE_ATTR(in20_alarm, S_IRUGO, show_voltage_alarm, NULL, 19);
static SENSOR_DEVICE_ATTR(in21_alarm, S_IRUGO, show_voltage_alarm, NULL, 20);
static SENSOR_DEVICE_ATTR(in22_alarm, S_IRUGO, show_voltage_alarm, NULL, 21);
static SENSOR_DEVICE_ATTR(in23_alarm, S_IRUGO, show_voltage_alarm, NULL, 22);
static SENSOR_DEVICE_ATTR(in24_alarm, S_IRUGO, show_voltage_alarm, NULL, 23);
static SENSOR_DEVICE_ATTR(in25_alarm, S_IRUGO, show_voltage_alarm, NULL, 24);
static SENSOR_DEVICE_ATTR(in26_alarm, S_IRUGO, show_voltage_alarm, NULL, 25);
static SENSOR_DEVICE_ATTR(in27_alarm, S_IRUGO, show_voltage_alarm, NULL, 26);
static SENSOR_DEVICE_ATTR(in28_alarm, S_IRUGO, show_voltage_alarm, NULL, 27);
static struct attribute *smf_vsen_attrs[] = {
&sensor_dev_attr_in1_input.dev_attr.attr,
&sensor_dev_attr_in2_input.dev_attr.attr,
&sensor_dev_attr_in3_input.dev_attr.attr,
&sensor_dev_attr_in4_input.dev_attr.attr,
&sensor_dev_attr_in5_input.dev_attr.attr,
&sensor_dev_attr_in6_input.dev_attr.attr,
&sensor_dev_attr_in7_input.dev_attr.attr,
&sensor_dev_attr_in8_input.dev_attr.attr,
&sensor_dev_attr_in9_input.dev_attr.attr,
&sensor_dev_attr_in10_input.dev_attr.attr,
&sensor_dev_attr_in11_input.dev_attr.attr,
&sensor_dev_attr_in12_input.dev_attr.attr,
&sensor_dev_attr_in13_input.dev_attr.attr,
&sensor_dev_attr_in14_input.dev_attr.attr,
&sensor_dev_attr_in15_input.dev_attr.attr,
&sensor_dev_attr_in16_input.dev_attr.attr,
&sensor_dev_attr_in17_input.dev_attr.attr,
&sensor_dev_attr_in18_input.dev_attr.attr,
&sensor_dev_attr_in19_input.dev_attr.attr,
&sensor_dev_attr_in20_input.dev_attr.attr,
&sensor_dev_attr_in21_input.dev_attr.attr,
&sensor_dev_attr_in22_input.dev_attr.attr,
&sensor_dev_attr_in23_input.dev_attr.attr,
&sensor_dev_attr_in24_input.dev_attr.attr,
&sensor_dev_attr_in25_input.dev_attr.attr,
&sensor_dev_attr_in26_input.dev_attr.attr,
&sensor_dev_attr_in27_input.dev_attr.attr,
&sensor_dev_attr_in28_input.dev_attr.attr,
&sensor_dev_attr_in29_input.dev_attr.attr,
&sensor_dev_attr_in30_input.dev_attr.attr,
&sensor_dev_attr_in31_input.dev_attr.attr,
&sensor_dev_attr_in32_input.dev_attr.attr,
&sensor_dev_attr_in101_input.dev_attr.attr,
&sensor_dev_attr_in102_input.dev_attr.attr,
&sensor_dev_attr_in103_input.dev_attr.attr,
&sensor_dev_attr_in104_input.dev_attr.attr,
&sensor_dev_attr_in201_input.dev_attr.attr,
&sensor_dev_attr_in202_input.dev_attr.attr,
&sensor_dev_attr_in203_input.dev_attr.attr,
&sensor_dev_attr_in204_input.dev_attr.attr,
&sensor_dev_attr_in301_input.dev_attr.attr,
&sensor_dev_attr_in302_input.dev_attr.attr,
&sensor_dev_attr_in303_input.dev_attr.attr,
&sensor_dev_attr_in304_input.dev_attr.attr,
&sensor_dev_attr_in401_input.dev_attr.attr,
&sensor_dev_attr_in402_input.dev_attr.attr,
&sensor_dev_attr_in403_input.dev_attr.attr,
&sensor_dev_attr_in404_input.dev_attr.attr,
&sensor_dev_attr_in1_label.dev_attr.attr,
&sensor_dev_attr_in2_label.dev_attr.attr,
&sensor_dev_attr_in3_label.dev_attr.attr,
&sensor_dev_attr_in4_label.dev_attr.attr,
&sensor_dev_attr_in5_label.dev_attr.attr,
&sensor_dev_attr_in6_label.dev_attr.attr,
&sensor_dev_attr_in7_label.dev_attr.attr,
&sensor_dev_attr_in8_label.dev_attr.attr,
&sensor_dev_attr_in9_label.dev_attr.attr,
&sensor_dev_attr_in10_label.dev_attr.attr,
&sensor_dev_attr_in11_label.dev_attr.attr,
&sensor_dev_attr_in12_label.dev_attr.attr,
&sensor_dev_attr_in13_label.dev_attr.attr,
&sensor_dev_attr_in14_label.dev_attr.attr,
&sensor_dev_attr_in15_label.dev_attr.attr,
&sensor_dev_attr_in16_label.dev_attr.attr,
&sensor_dev_attr_in17_label.dev_attr.attr,
&sensor_dev_attr_in18_label.dev_attr.attr,
&sensor_dev_attr_in19_label.dev_attr.attr,
&sensor_dev_attr_in20_label.dev_attr.attr,
&sensor_dev_attr_in21_label.dev_attr.attr,
&sensor_dev_attr_in22_label.dev_attr.attr,
&sensor_dev_attr_in23_label.dev_attr.attr,
&sensor_dev_attr_in24_label.dev_attr.attr,
&sensor_dev_attr_in25_label.dev_attr.attr,
&sensor_dev_attr_in26_label.dev_attr.attr,
&sensor_dev_attr_in27_label.dev_attr.attr,
&sensor_dev_attr_in28_label.dev_attr.attr,
&sensor_dev_attr_in29_label.dev_attr.attr,
&sensor_dev_attr_in30_label.dev_attr.attr,
&sensor_dev_attr_in31_label.dev_attr.attr,
&sensor_dev_attr_in32_label.dev_attr.attr,
&sensor_dev_attr_in101_label.dev_attr.attr,
&sensor_dev_attr_in102_label.dev_attr.attr,
&sensor_dev_attr_in103_label.dev_attr.attr,
&sensor_dev_attr_in104_label.dev_attr.attr,
&sensor_dev_attr_in201_label.dev_attr.attr,
&sensor_dev_attr_in202_label.dev_attr.attr,
&sensor_dev_attr_in203_label.dev_attr.attr,
&sensor_dev_attr_in204_label.dev_attr.attr,
&sensor_dev_attr_in301_label.dev_attr.attr,
&sensor_dev_attr_in302_label.dev_attr.attr,
&sensor_dev_attr_in303_label.dev_attr.attr,
&sensor_dev_attr_in304_label.dev_attr.attr,
&sensor_dev_attr_in401_label.dev_attr.attr,
&sensor_dev_attr_in402_label.dev_attr.attr,
&sensor_dev_attr_in403_label.dev_attr.attr,
&sensor_dev_attr_in404_label.dev_attr.attr,
&sensor_dev_attr_in1_alarm.dev_attr.attr,
&sensor_dev_attr_in2_alarm.dev_attr.attr,
&sensor_dev_attr_in3_alarm.dev_attr.attr,
&sensor_dev_attr_in4_alarm.dev_attr.attr,
&sensor_dev_attr_in5_alarm.dev_attr.attr,
&sensor_dev_attr_in6_alarm.dev_attr.attr,
&sensor_dev_attr_in7_alarm.dev_attr.attr,
&sensor_dev_attr_in8_alarm.dev_attr.attr,
&sensor_dev_attr_in9_alarm.dev_attr.attr,
&sensor_dev_attr_in10_alarm.dev_attr.attr,
&sensor_dev_attr_in11_alarm.dev_attr.attr,
&sensor_dev_attr_in12_alarm.dev_attr.attr,
&sensor_dev_attr_in13_alarm.dev_attr.attr,
&sensor_dev_attr_in14_alarm.dev_attr.attr,
&sensor_dev_attr_in15_alarm.dev_attr.attr,
&sensor_dev_attr_in16_alarm.dev_attr.attr,
&sensor_dev_attr_in17_alarm.dev_attr.attr,
&sensor_dev_attr_in18_alarm.dev_attr.attr,
&sensor_dev_attr_in19_alarm.dev_attr.attr,
&sensor_dev_attr_in20_alarm.dev_attr.attr,
&sensor_dev_attr_in21_alarm.dev_attr.attr,
&sensor_dev_attr_in22_alarm.dev_attr.attr,
&sensor_dev_attr_in23_alarm.dev_attr.attr,
&sensor_dev_attr_in24_alarm.dev_attr.attr,
&sensor_dev_attr_in25_alarm.dev_attr.attr,
&sensor_dev_attr_in26_alarm.dev_attr.attr,
&sensor_dev_attr_in27_alarm.dev_attr.attr,
&sensor_dev_attr_in28_alarm.dev_attr.attr,
NULL
};
static const struct attribute_group smf_vsen_group = {
.attrs = smf_vsen_attrs,
.is_visible = smf_vsen_is_visible,
};
/* CURRENT ATTR */
static ssize_t
show_current_label(struct device *dev, struct device_attribute *attr,
char *buf)
{
struct smf_data *data = dev_get_drvdata(dev);
int nr = to_sensor_dev_attr(attr)->index;
return sprintf(buf, "%s\n", data->curr_label[nr]);
}
static ssize_t show_current(struct device *dev,
struct device_attribute *devattr, char *buf)
{
int index = to_sensor_dev_attr(devattr)->index;
struct smf_data *data = dev_get_drvdata(dev);
int ret=0;
int curr;
if (index < CURR22_INPUT)
if (data->kind == s6100smf)
ret = smf_read_reg16(data, SWITCH_CURRENT_S6100 + index * 2);
else
ret = smf_read_reg16(data, SWITCH_CURRENT_Z9100 + index * 2);
else if (index < CURR602_INPUT)
ret = smf_read_reg16(data, PSU_1_INPUT_CURRENT + (index % 2) * 2);
else
ret = smf_read_reg16(data, PSU_2_INPUT_CURRENT + (index % 4) * 2);
if (ret < 0)
return ret;
curr = ret*10;
return sprintf(buf, "%d\n", curr);
}
static umode_t smf_curr_is_visible(struct kobject *kobj,
struct attribute *a, int n)
{
struct device *dev = container_of(kobj, struct device, kobj);
struct smf_data *data = dev_get_drvdata(dev);
if (data->curr_mask & (1 << (n % CURR_MAX)))
return a->mode;
return 0;
}
static SENSOR_DEVICE_ATTR(curr21_input, S_IRUGO, show_current, NULL, 0);
static SENSOR_DEVICE_ATTR(curr22_input, S_IRUGO, show_current, NULL, 1);
static SENSOR_DEVICE_ATTR(curr601_input, S_IRUGO, show_current, NULL, 2);
static SENSOR_DEVICE_ATTR(curr602_input, S_IRUGO, show_current, NULL, 3);
static SENSOR_DEVICE_ATTR(curr701_input, S_IRUGO, show_current, NULL, 4);
static SENSOR_DEVICE_ATTR(curr702_input, S_IRUGO, show_current, NULL, 5);
static SENSOR_DEVICE_ATTR(curr21_label, S_IRUGO, show_current_label, NULL, 0);
static SENSOR_DEVICE_ATTR(curr22_label, S_IRUGO, show_current_label, NULL, 1);
static SENSOR_DEVICE_ATTR(curr601_label, S_IRUGO, show_current_label, NULL, 2);
static SENSOR_DEVICE_ATTR(curr602_label, S_IRUGO, show_current_label, NULL, 3);
static SENSOR_DEVICE_ATTR(curr701_label, S_IRUGO, show_current_label, NULL, 4);
static SENSOR_DEVICE_ATTR(curr702_label, S_IRUGO, show_current_label, NULL, 5);
static struct attribute *smf_curr_attrs[] = {
&sensor_dev_attr_curr21_input.dev_attr.attr,
&sensor_dev_attr_curr22_input.dev_attr.attr,
&sensor_dev_attr_curr601_input.dev_attr.attr,
&sensor_dev_attr_curr602_input.dev_attr.attr,
&sensor_dev_attr_curr701_input.dev_attr.attr,
&sensor_dev_attr_curr702_input.dev_attr.attr,
&sensor_dev_attr_curr21_label.dev_attr.attr,
&sensor_dev_attr_curr22_label.dev_attr.attr,
&sensor_dev_attr_curr601_label.dev_attr.attr,
&sensor_dev_attr_curr602_label.dev_attr.attr,
&sensor_dev_attr_curr701_label.dev_attr.attr,
&sensor_dev_attr_curr702_label.dev_attr.attr,
NULL
};
static const struct attribute_group smf_curr_group = {
.attrs = smf_curr_attrs,
.is_visible = smf_curr_is_visible,
};
/* CPU_TEMP ATTR */
static ssize_t
show_temp_label(struct device *dev, struct device_attribute *attr, char *buf)
{
struct smf_data *data = dev_get_drvdata(dev);
int nr = to_sensor_dev_attr(attr)->index;
return sprintf(buf, "%s\n", data->temp_label[nr]);
}
static ssize_t show_tcpu(struct device *dev,
struct device_attribute *devattr, char *buf)
{
int index = to_sensor_dev_attr(devattr)->index;
struct smf_data *data = dev_get_drvdata(dev);
int ret;
int temp;
if (index < TEMP13_INPUT) /* Temp sensors */
ret = smf_read_reg16(data, TEMP_SENSOR_1 + index * 2);
else if(index < TEMP601_INPUT)
ret = smf_read_reg16(data, PSU_1_TEMPERATURE);
else
ret = smf_read_reg16(data, PSU_2_TEMPERATURE);
if (ret < 0)
return ret;
if (ret > 65500)
ret = 0;
if (ret & 0x8000)
ret = - (ret & 0x7fff);
temp = ret*100;
return sprintf(buf, "%d\n", temp);
}
static ssize_t show_temp_crit(struct device *dev,
struct device_attribute *devattr, char *buf)
{
int index = to_sensor_dev_attr(devattr)->index;
struct smf_data *data = dev_get_drvdata(dev);
int ret;
int temp;
ret = smf_read_reg16(data, TEMP_SENSOR_1_HW_LIMIT + index * 2);
if (ret < 0)
return ret;
if (ret == 65535)
ret = 0;
if (ret & 0x8000)
ret = - (ret & 0x7fff);
temp = ret*100;
return sprintf(buf, "%d\n", temp);
}
static ssize_t show_temp_alarm(struct device *dev,
struct device_attribute *devattr, char *buf)
{
int index = to_sensor_dev_attr(devattr)->index;
struct smf_data *data = dev_get_drvdata(dev);
int ret = 0;
int temp = 0;
ret = smf_read_reg(data, TEMP_SENSOR_1_STATUS + index);
if (ret < 0) {
return ret;
}
if (ret == 0xff) {
ret = 0;
}
temp = ret;
return sprintf(buf, "%d\n", temp);
}
static umode_t smf_tcpu_is_visible(struct kobject *kobj,
struct attribute *a, int n)
{
struct device *dev = container_of(kobj, struct device, kobj);
struct smf_data *data = dev_get_drvdata(dev);
if (data->tcpu_mask & (1 << (n % TCPU_MAX)))
return a->mode;
return 0;
}
static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, show_tcpu, NULL, 0);
static SENSOR_DEVICE_ATTR(temp2_input, S_IRUGO, show_tcpu, NULL, 1);
static SENSOR_DEVICE_ATTR(temp3_input, S_IRUGO, show_tcpu, NULL, 2);
static SENSOR_DEVICE_ATTR(temp4_input, S_IRUGO, show_tcpu, NULL, 3);
static SENSOR_DEVICE_ATTR(temp5_input, S_IRUGO, show_tcpu, NULL, 4);
static SENSOR_DEVICE_ATTR(temp6_input, S_IRUGO, show_tcpu, NULL, 5);
static SENSOR_DEVICE_ATTR(temp7_input, S_IRUGO, show_tcpu, NULL, 6);
static SENSOR_DEVICE_ATTR(temp8_input, S_IRUGO, show_tcpu, NULL, 7);
static SENSOR_DEVICE_ATTR(temp9_input, S_IRUGO, show_tcpu, NULL, 8);
static SENSOR_DEVICE_ATTR(temp10_input, S_IRUGO, show_tcpu, NULL, 9);
static SENSOR_DEVICE_ATTR(temp11_input, S_IRUGO, show_tcpu, NULL, 10);
static SENSOR_DEVICE_ATTR(temp12_input, S_IRUGO, show_tcpu, NULL, 11);
static SENSOR_DEVICE_ATTR(temp13_input, S_IRUGO, show_tcpu, NULL, 12);
/* PSU1 Fan Temp */
static SENSOR_DEVICE_ATTR(temp14_input, S_IRUGO, show_tcpu, NULL, 13);
/* PSU2 Fan Temp */
static SENSOR_DEVICE_ATTR(temp15_input, S_IRUGO, show_tcpu, NULL, 14);
static SENSOR_DEVICE_ATTR(temp1_label, S_IRUGO, show_temp_label, NULL, 0);
static SENSOR_DEVICE_ATTR(temp2_label, S_IRUGO, show_temp_label, NULL, 1);
static SENSOR_DEVICE_ATTR(temp3_label, S_IRUGO, show_temp_label, NULL, 2);
static SENSOR_DEVICE_ATTR(temp4_label, S_IRUGO, show_temp_label, NULL, 3);
static SENSOR_DEVICE_ATTR(temp5_label, S_IRUGO, show_temp_label, NULL, 4);
static SENSOR_DEVICE_ATTR(temp6_label, S_IRUGO, show_temp_label, NULL, 5);
static SENSOR_DEVICE_ATTR(temp7_label, S_IRUGO, show_temp_label, NULL, 6);
static SENSOR_DEVICE_ATTR(temp8_label, S_IRUGO, show_temp_label, NULL, 7);
static SENSOR_DEVICE_ATTR(temp9_label, S_IRUGO, show_temp_label, NULL, 8);
static SENSOR_DEVICE_ATTR(temp10_label, S_IRUGO, show_temp_label, NULL, 9);
static SENSOR_DEVICE_ATTR(temp11_label, S_IRUGO, show_temp_label, NULL, 10);
static SENSOR_DEVICE_ATTR(temp12_label, S_IRUGO, show_temp_label, NULL, 11);
static SENSOR_DEVICE_ATTR(temp13_label, S_IRUGO, show_temp_label, NULL, 12);
static SENSOR_DEVICE_ATTR(temp14_label, S_IRUGO, show_temp_label, NULL, 14);
static SENSOR_DEVICE_ATTR(temp15_label, S_IRUGO, show_temp_label, NULL, 15);
static SENSOR_DEVICE_ATTR(temp1_crit, S_IRUGO, show_temp_crit, NULL, 1);
static SENSOR_DEVICE_ATTR(temp2_crit, S_IRUGO, show_temp_crit, NULL, 5);
static SENSOR_DEVICE_ATTR(temp3_crit, S_IRUGO, show_temp_crit, NULL, 9);
static SENSOR_DEVICE_ATTR(temp4_crit, S_IRUGO, show_temp_crit, NULL, 13);
static SENSOR_DEVICE_ATTR(temp5_crit, S_IRUGO, show_temp_crit, NULL, 17);
static SENSOR_DEVICE_ATTR(temp6_crit, S_IRUGO, show_temp_crit, NULL, 21);
static SENSOR_DEVICE_ATTR(temp7_crit, S_IRUGO, show_temp_crit, NULL, 25);
static SENSOR_DEVICE_ATTR(temp8_crit, S_IRUGO, show_temp_crit, NULL, 29);
static SENSOR_DEVICE_ATTR(temp9_crit, S_IRUGO, show_temp_crit, NULL, 33);
static SENSOR_DEVICE_ATTR(temp10_crit, S_IRUGO, show_temp_crit, NULL, 37);
static SENSOR_DEVICE_ATTR(temp11_crit, S_IRUGO, show_temp_crit, NULL, 41);
static SENSOR_DEVICE_ATTR(temp12_crit, S_IRUGO, show_temp_crit, NULL, 45);
static SENSOR_DEVICE_ATTR(temp13_crit, S_IRUGO, show_temp_crit, NULL, 49);
static SENSOR_DEVICE_ATTR(temp14_crit, S_IRUGO, show_temp_crit, NULL, 11);
static SENSOR_DEVICE_ATTR(temp15_crit, S_IRUGO, show_temp_crit, NULL, 11);
static SENSOR_DEVICE_ATTR(temp1_max, S_IRUGO, show_temp_crit, NULL, 2);
static SENSOR_DEVICE_ATTR(temp2_max, S_IRUGO, show_temp_crit, NULL, 6);
static SENSOR_DEVICE_ATTR(temp3_max, S_IRUGO, show_temp_crit, NULL, 10);
static SENSOR_DEVICE_ATTR(temp4_max, S_IRUGO, show_temp_crit, NULL, 14);
static SENSOR_DEVICE_ATTR(temp5_max, S_IRUGO, show_temp_crit, NULL, 18);
static SENSOR_DEVICE_ATTR(temp6_max, S_IRUGO, show_temp_crit, NULL, 22);
static SENSOR_DEVICE_ATTR(temp7_max, S_IRUGO, show_temp_crit, NULL, 26);
static SENSOR_DEVICE_ATTR(temp8_max, S_IRUGO, show_temp_crit, NULL, 30);
static SENSOR_DEVICE_ATTR(temp9_max, S_IRUGO, show_temp_crit, NULL, 34);
static SENSOR_DEVICE_ATTR(temp10_max, S_IRUGO, show_temp_crit, NULL, 38);
static SENSOR_DEVICE_ATTR(temp11_max, S_IRUGO, show_temp_crit, NULL, 42);
static SENSOR_DEVICE_ATTR(temp12_max, S_IRUGO, show_temp_crit, NULL, 46);
static SENSOR_DEVICE_ATTR(temp13_max, S_IRUGO, show_temp_crit, NULL, 50);
static SENSOR_DEVICE_ATTR(temp14_max, S_IRUGO, show_temp_crit, NULL, 46);
static SENSOR_DEVICE_ATTR(temp15_max, S_IRUGO, show_temp_crit, NULL, 50);
static SENSOR_DEVICE_ATTR(temp1_alarm, S_IRUGO, show_temp_alarm, NULL, 0);
static SENSOR_DEVICE_ATTR(temp2_alarm, S_IRUGO, show_temp_alarm, NULL, 1);
static SENSOR_DEVICE_ATTR(temp3_alarm, S_IRUGO, show_temp_alarm, NULL, 2);
static SENSOR_DEVICE_ATTR(temp4_alarm, S_IRUGO, show_temp_alarm, NULL, 3);
static SENSOR_DEVICE_ATTR(temp5_alarm, S_IRUGO, show_temp_alarm, NULL, 4);
static SENSOR_DEVICE_ATTR(temp6_alarm, S_IRUGO, show_temp_alarm, NULL, 5);
static SENSOR_DEVICE_ATTR(temp7_alarm, S_IRUGO, show_temp_alarm, NULL, 6);
static SENSOR_DEVICE_ATTR(temp8_alarm, S_IRUGO, show_temp_alarm, NULL, 7);
static SENSOR_DEVICE_ATTR(temp9_alarm, S_IRUGO, show_temp_alarm, NULL, 8);
static SENSOR_DEVICE_ATTR(temp10_alarm, S_IRUGO, show_temp_alarm, NULL, 9);
static SENSOR_DEVICE_ATTR(temp11_alarm, S_IRUGO, show_temp_alarm, NULL, 10);
static SENSOR_DEVICE_ATTR(temp12_alarm, S_IRUGO, show_temp_alarm, NULL, 11);
static SENSOR_DEVICE_ATTR(temp13_alarm, S_IRUGO, show_temp_alarm, NULL, 12);
static SENSOR_DEVICE_ATTR(temp14_alarm, S_IRUGO, show_temp_alarm, NULL, 13);
static SENSOR_DEVICE_ATTR(temp15_alarm, S_IRUGO, show_temp_alarm, NULL, 14);
static struct attribute *smf_tcpu_attrs[] = {
&sensor_dev_attr_temp1_input.dev_attr.attr,
&sensor_dev_attr_temp2_input.dev_attr.attr,
&sensor_dev_attr_temp3_input.dev_attr.attr,
&sensor_dev_attr_temp4_input.dev_attr.attr,
&sensor_dev_attr_temp5_input.dev_attr.attr,
&sensor_dev_attr_temp6_input.dev_attr.attr,
&sensor_dev_attr_temp7_input.dev_attr.attr,
&sensor_dev_attr_temp8_input.dev_attr.attr,
&sensor_dev_attr_temp9_input.dev_attr.attr,
&sensor_dev_attr_temp10_input.dev_attr.attr,
&sensor_dev_attr_temp11_input.dev_attr.attr,
&sensor_dev_attr_temp12_input.dev_attr.attr,
&sensor_dev_attr_temp13_input.dev_attr.attr,
&sensor_dev_attr_temp14_input.dev_attr.attr,
&sensor_dev_attr_temp15_input.dev_attr.attr,
&sensor_dev_attr_temp1_label.dev_attr.attr,
&sensor_dev_attr_temp2_label.dev_attr.attr,
&sensor_dev_attr_temp3_label.dev_attr.attr,
&sensor_dev_attr_temp4_label.dev_attr.attr,
&sensor_dev_attr_temp5_label.dev_attr.attr,
&sensor_dev_attr_temp6_label.dev_attr.attr,
&sensor_dev_attr_temp7_label.dev_attr.attr,
&sensor_dev_attr_temp8_label.dev_attr.attr,
&sensor_dev_attr_temp9_label.dev_attr.attr,
&sensor_dev_attr_temp10_label.dev_attr.attr,
&sensor_dev_attr_temp11_label.dev_attr.attr,
&sensor_dev_attr_temp12_label.dev_attr.attr,
&sensor_dev_attr_temp13_label.dev_attr.attr,
&sensor_dev_attr_temp14_label.dev_attr.attr,
&sensor_dev_attr_temp15_label.dev_attr.attr,
&sensor_dev_attr_temp1_crit.dev_attr.attr,
&sensor_dev_attr_temp2_crit.dev_attr.attr,
&sensor_dev_attr_temp3_crit.dev_attr.attr,
&sensor_dev_attr_temp4_crit.dev_attr.attr,
&sensor_dev_attr_temp5_crit.dev_attr.attr,
&sensor_dev_attr_temp6_crit.dev_attr.attr,
&sensor_dev_attr_temp7_crit.dev_attr.attr,
&sensor_dev_attr_temp8_crit.dev_attr.attr,
&sensor_dev_attr_temp9_crit.dev_attr.attr,
&sensor_dev_attr_temp10_crit.dev_attr.attr,
&sensor_dev_attr_temp11_crit.dev_attr.attr,
&sensor_dev_attr_temp12_crit.dev_attr.attr,
&sensor_dev_attr_temp13_crit.dev_attr.attr,
&sensor_dev_attr_temp14_crit.dev_attr.attr,
&sensor_dev_attr_temp15_crit.dev_attr.attr,
&sensor_dev_attr_temp1_max.dev_attr.attr,
&sensor_dev_attr_temp2_max.dev_attr.attr,
&sensor_dev_attr_temp3_max.dev_attr.attr,
&sensor_dev_attr_temp4_max.dev_attr.attr,
&sensor_dev_attr_temp5_max.dev_attr.attr,
&sensor_dev_attr_temp6_max.dev_attr.attr,
&sensor_dev_attr_temp7_max.dev_attr.attr,
&sensor_dev_attr_temp8_max.dev_attr.attr,
&sensor_dev_attr_temp9_max.dev_attr.attr,
&sensor_dev_attr_temp10_max.dev_attr.attr,
&sensor_dev_attr_temp11_max.dev_attr.attr,
&sensor_dev_attr_temp12_max.dev_attr.attr,
&sensor_dev_attr_temp13_max.dev_attr.attr,
&sensor_dev_attr_temp14_max.dev_attr.attr,
&sensor_dev_attr_temp15_max.dev_attr.attr,
&sensor_dev_attr_temp1_alarm.dev_attr.attr,
&sensor_dev_attr_temp2_alarm.dev_attr.attr,
&sensor_dev_attr_temp3_alarm.dev_attr.attr,
&sensor_dev_attr_temp4_alarm.dev_attr.attr,
&sensor_dev_attr_temp5_alarm.dev_attr.attr,
&sensor_dev_attr_temp6_alarm.dev_attr.attr,
&sensor_dev_attr_temp7_alarm.dev_attr.attr,
&sensor_dev_attr_temp8_alarm.dev_attr.attr,
&sensor_dev_attr_temp9_alarm.dev_attr.attr,
&sensor_dev_attr_temp10_alarm.dev_attr.attr,
&sensor_dev_attr_temp11_alarm.dev_attr.attr,
&sensor_dev_attr_temp12_alarm.dev_attr.attr,
&sensor_dev_attr_temp13_alarm.dev_attr.attr,
&sensor_dev_attr_temp14_alarm.dev_attr.attr,
&sensor_dev_attr_temp15_alarm.dev_attr.attr,
NULL
};
static const struct attribute_group smf_tcpu_group = {
.attrs = smf_tcpu_attrs,
.is_visible = smf_tcpu_is_visible,
};
/* PSU ATTR */
static ssize_t
show_psu_label(struct device *dev, struct device_attribute *attr, char *buf)
{
struct smf_data *data = dev_get_drvdata(dev);
int nr = to_sensor_dev_attr(attr)->index;
return sprintf(buf, "%s\n", data->psu_label[nr]);
}
static ssize_t show_psu(struct device *dev,
struct device_attribute *devattr, char *buf)
{
int index = to_sensor_dev_attr(devattr)->index;
struct smf_data *data = dev_get_drvdata(dev);
int ret=0, export_hex=0;
int psu_status=0, pow;
int pow_val = 0;
switch (index) {
case 0:
pow = smf_read_reg16(data, PSU_1_MAX_POWER);
if (data->kind == s6100smf)
ret = 1000000 * 1100;
else
ret = 1000000 * 750;
break;
case 1:
ret = smf_read_reg(data, PSU_1_STATUS);
export_hex=1;
break;
case 2:
pow_val = smf_read_reg16(data, PSU_1_INPUT_POWER);
/* In case of absent psu, pow_val will be 0xffff */
if (pow_val == 0xffff) {
pow_val = 0;
}
ret = 100000 * pow_val;
break;
case 3:
pow_val = smf_read_reg16(data, PSU_1_OUTPUT_POWER);
/* In case of absent psu, pow_val will be 0xffff */
if (pow_val == 0xffff) {
pow_val = 0;
}
ret = 100000 * pow_val;
break;
case 4:
psu_status = smf_read_reg(data, PSU_1_STATUS);
if (psu_status &(1))
ret=1;
break;
case 5:
pow = smf_read_reg16(data, PSU_2_MAX_POWER);
ret = 1000000 * pow;
if (data->kind == s6100smf)
ret = 1000000 * 1100;
else
ret = 1000000 * 750;
break;
case 6:
ret = smf_read_reg(data, PSU_2_STATUS);
export_hex=1;
break;
case 7:
pow_val = smf_read_reg16(data, PSU_2_INPUT_POWER);
/* In case of absent psu, pow_val will be 0xffff */
if (pow_val == 0xffff) {
pow_val = 0;
}
ret = 100000 * pow_val;
break;
case 8:
pow_val = smf_read_reg16(data, PSU_2_OUTPUT_POWER);
/* In case of absent psu, pow_val will be 0xffff */
if (pow_val == 0xffff) {
pow_val = 0;
}
ret = 100000 * pow_val;
break;
case 9:
psu_status = smf_read_reg(data, PSU_2_STATUS);
if (psu_status &(1))
ret=1;
break;
case 10:
pow = smf_read_reg16(data, CURRENT_TOTAL_POWER);
/* In case of both psu absent, pow will be 0xffff */
if (pow == 0xffff) {
pow = 0;
}
ret = pow/10;
break;
case 11:
psu_status = smf_read_reg(data, PSU_1_STATUS);
if (psu_status &(2))
ret=1;
break;
case 12:
psu_status = smf_read_reg(data, PSU_2_STATUS);
if (psu_status &(2))
ret=1;
break;
default:
return ret;
}
if (ret < 0)
return ret;
pow = ret;
if(export_hex)
return sprintf(buf, "%x\n", pow);
else
return sprintf(buf, "%u\n", pow);
}
/* FAN and PSU EEPROM PPID format is:
COUNTRY_CODE-PART_NO-MFG_ID-MFG_DATE_CODE-SERIAL_NO-LABEL_REV */
static ssize_t show_ppid(struct device *dev,
struct device_attribute *devattr, char *buf)
{
int index = to_sensor_dev_attr(devattr)->index;
struct smf_data *data = dev_get_drvdata(dev);
char ppid[EEPROM_PPID_SIZE + 1] = {0};
char psu_mfg_date[EEPROM_MFG_DATE_SIZE + 1] = {0};
char psu_mfg_date_code[EEPROM_DATE_CODE_SIZE + 1] = {0};
char temp;
int i, reg, ret = 0, ppid_pos = 0;
switch(index) {
/* PPID starts from Country Code*/
case 0:
reg = FAN_1_SERIAL_CODE;
break;
case 1:
reg = FAN_2_SERIAL_CODE;
break;
case 2:
reg = FAN_3_SERIAL_CODE;
break;
case 3:
reg = FAN_4_SERIAL_CODE;
break;
case 4:
reg = FAN_5_SERIAL_CODE;
break;
case 10:
reg = PSU_1_COUNTRY_CODE;
break;
case 11:
reg = PSU_2_COUNTRY_CODE;
break;
default:
return ret;
}
// Get Country Code
for( i = 0; i < EEPROM_COUNTRY_CODE_SIZE; i++) {
ppid[ppid_pos++] = (char)smf_read_reg(data,reg++);
}
ppid[ppid_pos++] = '-';
// Get Part Number
for( i = 0; i < EEPROM_PART_NO_SIZE; i++) {
ppid[ppid_pos++] = (char)smf_read_reg(data,reg++);
}
ppid[ppid_pos++] = '-';
// Get Manufacture ID
for( i = 0; i < EEPROM_MFG_ID_SIZE; i++) {
ppid[ppid_pos++] = (char)smf_read_reg(data,reg++);
}
ppid[ppid_pos++] = '-';
if(index > 9){ //Applicable only for PSU
// Get Manufacture date
for( i = 0; i < EEPROM_MFG_DATE_SIZE; i++) {
psu_mfg_date[i] = (char)smf_read_reg(data,reg++);
}
/* Converting 6 digit date code [yymmdd] to 3 digit[ymd]
Year Starting from 2010 [0-9] , Day : 1-9 and A-V , Month : 1-9 and A-C */
// Year Validation and Conversion
if( ( psu_mfg_date[0] == '1' ) && ( psu_mfg_date[1] >= '0' ) && ( psu_mfg_date[1] <= '9') )
{
psu_mfg_date_code[0] = psu_mfg_date[1];
}
else
{
psu_mfg_date_code[0] = ' ';
}
// Month Validation and Conversion
temp = ( ( psu_mfg_date[2] - 0x30 ) * 10 ) + ( psu_mfg_date[3] - 0x30 );
if( ( temp >= 1) && ( temp < 10) )
{
psu_mfg_date_code[1] = temp + 0x30; // 0- 9
}
else if ( ( temp >= 10) && ( temp <= 12) )
{
psu_mfg_date_code[1] = temp + 0x37; // A-C
}
else
{
psu_mfg_date_code[1]= ' ';
}
// Date Validation and Conversion
temp = ( ( psu_mfg_date[4] - 0x30 ) * 10 ) + ( psu_mfg_date[5] - 0x30 );
if( ( temp >= 1) && ( temp < 10) )
{
psu_mfg_date_code[2] = temp + 0x30; // 0- 9
}
else if( ( temp >= 10) && ( temp <= 31) )
{
psu_mfg_date_code[2] = temp + 0x37; // A-V
}
else
{
psu_mfg_date_code[2] = ' ';
}
for( i = 0; i < EEPROM_DATE_CODE_SIZE; i++) {
ppid[ppid_pos++] = psu_mfg_date_code[i];
}
}else{
for( i = 0; i < EEPROM_DATE_CODE_SIZE; i++) {
ppid[ppid_pos++] = (char)smf_read_reg(data,reg++);
}
}
ppid[ppid_pos++] = '-';
// Get Serial Number
for( i = 0; i < EEPROM_SERIAL_NO_SIZE; i++) {
ppid[ppid_pos++] = (char)smf_read_reg(data,reg++);
}
ppid[ppid_pos++] = '-';
if(index > 9){
// Skipping PSU service tag in PPID
reg += EEPROM_SERVICE_TAG_SIZE;
}
else{
// Skipping FAN partno tag in PPID
reg += EEPROM_PART_NO_SIZE;
}
// Get Label Revision
for( i = 0; i < EEPROM_LABEL_REV_SIZE; i++) {
ppid[ppid_pos++] = (char)smf_read_reg(data,reg++);
}
return sprintf(buf, "%s\n",ppid);
}
static umode_t smf_psu_is_visible(struct kobject *kobj,
struct attribute *a, int n)
{
struct device *dev = container_of(kobj, struct device, kobj);
struct smf_data *data = dev_get_drvdata(dev);
if (data->psu_mask & (1 << (n % PSU_MAX)))
return a->mode;
return 0;
}
/* PSU */
static SENSOR_DEVICE_ATTR(power1_input, S_IRUGO, show_psu, NULL, 2);
static SENSOR_DEVICE_ATTR(power2_input, S_IRUGO, show_psu, NULL, 3);
static SENSOR_DEVICE_ATTR(power3_input, S_IRUGO, show_psu, NULL, 7);
static SENSOR_DEVICE_ATTR(power4_input, S_IRUGO, show_psu, NULL, 8);
static SENSOR_DEVICE_ATTR(power1_label, S_IRUGO, show_psu_label, NULL, 0);
static SENSOR_DEVICE_ATTR(power2_label, S_IRUGO, show_psu_label, NULL, 1);
static SENSOR_DEVICE_ATTR(power3_label, S_IRUGO, show_psu_label, NULL, 2);
static SENSOR_DEVICE_ATTR(power4_label, S_IRUGO, show_psu_label, NULL, 3);
static SENSOR_DEVICE_ATTR(power1_max, S_IRUGO, show_psu, NULL, 0);
static SENSOR_DEVICE_ATTR(power2_max, S_IRUGO, show_psu, NULL, 0);
static SENSOR_DEVICE_ATTR(power3_max, S_IRUGO, show_psu, NULL, 5);
static SENSOR_DEVICE_ATTR(power4_max, S_IRUGO, show_psu, NULL, 5);
/* PSU2 */
//static SENSOR_DEVICE_ATTR(power602_alarm, S_IRUGO, show_psu, NULL, 4);
//static SENSOR_DEVICE_ATTR(power702_alarm, S_IRUGO, show_psu, NULL, 9);
static struct attribute *smf_psu_attrs[] = {
&sensor_dev_attr_power1_input.dev_attr.attr,
&sensor_dev_attr_power2_input.dev_attr.attr,
&sensor_dev_attr_power3_input.dev_attr.attr,
&sensor_dev_attr_power4_input.dev_attr.attr,
&sensor_dev_attr_power1_label.dev_attr.attr,
&sensor_dev_attr_power2_label.dev_attr.attr,
&sensor_dev_attr_power3_label.dev_attr.attr,
&sensor_dev_attr_power4_label.dev_attr.attr,
&sensor_dev_attr_power1_max.dev_attr.attr,
&sensor_dev_attr_power2_max.dev_attr.attr,
&sensor_dev_attr_power3_max.dev_attr.attr,
&sensor_dev_attr_power4_max.dev_attr.attr,
NULL
};
static const struct attribute_group smf_psu_group = {
.attrs = smf_psu_attrs,
.is_visible = smf_psu_is_visible,
};
static const struct attribute_group smf_fanin_group = {
.attrs = smf_fanin_attrs,
.is_visible = smf_fanin_is_visible,
};
static SENSOR_DEVICE_ATTR(fan_tray_presence, S_IRUGO, show_fan, NULL, 12);
static SENSOR_DEVICE_ATTR(fan1_airflow, S_IRUGO, show_fan_airflow, NULL, 0);
static SENSOR_DEVICE_ATTR(fan3_airflow, S_IRUGO, show_fan_airflow, NULL, 1);
static SENSOR_DEVICE_ATTR(fan5_airflow, S_IRUGO, show_fan_airflow, NULL, 2);
static SENSOR_DEVICE_ATTR(fan7_airflow, S_IRUGO, show_fan_airflow, NULL, 3);
static SENSOR_DEVICE_ATTR(fan9_airflow, S_IRUGO, show_fan_airflow, NULL, 4);
static SENSOR_DEVICE_ATTR(fan11_airflow, S_IRUGO, show_psu_fan, NULL, 0);
static SENSOR_DEVICE_ATTR(fan12_airflow, S_IRUGO, show_psu_fan, NULL, 3);
static SENSOR_DEVICE_ATTR(fan1_serialno, S_IRUGO, show_ppid, NULL, 0);
static SENSOR_DEVICE_ATTR(fan3_serialno, S_IRUGO, show_ppid, NULL, 1);
static SENSOR_DEVICE_ATTR(fan5_serialno, S_IRUGO, show_ppid, NULL, 2);
static SENSOR_DEVICE_ATTR(fan7_serialno, S_IRUGO, show_ppid, NULL, 3);
static SENSOR_DEVICE_ATTR(fan9_serialno, S_IRUGO, show_ppid, NULL, 4);
/* IOM status */
static SENSOR_DEVICE_ATTR(iom_status, S_IRUGO, show_voltage, NULL, 44);
static SENSOR_DEVICE_ATTR(iom_presence, S_IRUGO, show_voltage, NULL, 45);
static SENSOR_DEVICE_ATTR(psu1_presence, S_IRUGO, show_psu, NULL, 1);
static SENSOR_DEVICE_ATTR(psu2_presence, S_IRUGO, show_psu, NULL, 6);
static SENSOR_DEVICE_ATTR(psu1_serialno, S_IRUGO, show_ppid, NULL, 10);
static SENSOR_DEVICE_ATTR(psu2_serialno, S_IRUGO, show_ppid, NULL, 11);
static SENSOR_DEVICE_ATTR(psu1_type, S_IRUGO, show_psu, NULL, 11);
static SENSOR_DEVICE_ATTR(psu2_type, S_IRUGO, show_psu, NULL, 12);
static SENSOR_DEVICE_ATTR(current_total_power, S_IRUGO, show_psu, NULL, 10);
/* SMF Version */
static SENSOR_DEVICE_ATTR(smf_version, S_IRUGO, show_smf_version, NULL, 0);
static SENSOR_DEVICE_ATTR(smf_firmware_ver, S_IRUGO, show_smf_version, NULL, 1);
/* SMF Reset Reason */
static SENSOR_DEVICE_ATTR(smf_reset_reason, S_IRUGO, show_reset_reason, NULL, 1);
/* SMF PowerOn Reason */
static SENSOR_DEVICE_ATTR(smf_poweron_reason, S_IRUGO,
show_power_on_reason, NULL, 1);
/* Mailbox Power tracking Reason */
static SENSOR_DEVICE_ATTR(mb_poweron_reason, S_IRUGO|S_IWUSR,
show_mb_poweron_reason, set_mb_poweron_reason, 0);
static struct attribute *smf_dell_attrs[] = {
&sensor_dev_attr_smf_version.dev_attr.attr,
&sensor_dev_attr_smf_firmware_ver.dev_attr.attr,
&sensor_dev_attr_smf_reset_reason.dev_attr.attr,
&sensor_dev_attr_smf_poweron_reason.dev_attr.attr,
&sensor_dev_attr_mb_poweron_reason.dev_attr.attr,
&sensor_dev_attr_fan_tray_presence.dev_attr.attr,
&sensor_dev_attr_fan1_airflow.dev_attr.attr,
&sensor_dev_attr_fan3_airflow.dev_attr.attr,
&sensor_dev_attr_fan5_airflow.dev_attr.attr,
&sensor_dev_attr_fan7_airflow.dev_attr.attr,
&sensor_dev_attr_fan9_airflow.dev_attr.attr,
&sensor_dev_attr_fan11_airflow.dev_attr.attr,
&sensor_dev_attr_fan12_airflow.dev_attr.attr,
&sensor_dev_attr_iom_status.dev_attr.attr,
&sensor_dev_attr_iom_presence.dev_attr.attr,
&sensor_dev_attr_psu1_presence.dev_attr.attr,
&sensor_dev_attr_psu2_presence.dev_attr.attr,
&sensor_dev_attr_psu1_serialno.dev_attr.attr,
&sensor_dev_attr_psu2_serialno.dev_attr.attr,
&sensor_dev_attr_fan1_serialno.dev_attr.attr,
&sensor_dev_attr_fan3_serialno.dev_attr.attr,
&sensor_dev_attr_fan5_serialno.dev_attr.attr,
&sensor_dev_attr_fan7_serialno.dev_attr.attr,
&sensor_dev_attr_fan9_serialno.dev_attr.attr,
&sensor_dev_attr_current_total_power.dev_attr.attr,
NULL
};
static const struct attribute_group smf_dell_group = {
.attrs = smf_dell_attrs,
.is_visible = smf_dell_is_visible,
};
static const struct attribute_group *smf_groups[] = {
&smf_psu_group,
&smf_fanin_group,
&smf_vsen_group,
&smf_curr_group,
&smf_tcpu_group,
&smf_dell_group,
NULL
};
static int smf_probe(struct platform_device *pdev)
{
struct smf_data *data;
struct device *dev = &pdev->dev;
struct smf_sio_data *sio_data = dev_get_platdata(dev);
struct resource *res;
int err = 0;
res = platform_get_resource(pdev, IORESOURCE_IO, 0);
if (!request_region(res->start, IOREGION_LENGTH,
smf_devices[sio_data->kind].name)) {
err = -EBUSY;
dev_err(dev, "Failed to request region 0x%lx-0x%lx\n",
(unsigned long)res->start,
(unsigned long)res->start + IOREGION_LENGTH - 1);
return err;
}
data = devm_kzalloc(dev, sizeof(struct smf_data), GFP_KERNEL);
/* TODO Use probe address value */
data->addr = SMF_PROBE_ADDR;
data->kind = sio_data->kind;
if (!data)
return -ENOMEM;
mutex_init(&data->lock);
/* PSU attributes */
data->psu_mask = smf_devices[data->kind].psu_mask;
data->psu_label = smf_devices[data->kind].psu_label;
/* FANIN attributes */
data->fanin_mask = smf_devices[data->kind].fanin_mask;
data->fan_label = smf_devices[data->kind].fan_label;
/* VSEN attributes */
data->vsen_mask = smf_devices[data->kind].vsen_mask;
data->vsen_label = smf_devices[data->kind].vsen_label;
/* CURR attributes */
data->curr_mask = smf_devices[data->kind].curr_mask;
data->curr_label = smf_devices[data->kind].curr_label;
/* CPU_TEMP attributes */
data->tcpu_mask = smf_devices[data->kind].tcpu_mask;
data->temp_label = smf_devices[data->kind].temp_label;
data->hwmon_dev = devm_hwmon_device_register_with_groups(dev,
smf_devices[data->kind].name,
data, smf_groups);
return PTR_ERR_OR_ZERO(data->hwmon_dev);
}
static int smf_remove(struct platform_device *pdev)
{
struct resource *res;
res = platform_get_resource(pdev, IORESOURCE_IO, 0);
release_region(res->start, IOREGION_LENGTH);
return 0;
}
static struct platform_driver smf_driver = {
.driver = {
.name = "SMF",
},
.probe = smf_probe,
.remove = smf_remove
};
int __init
smf_find(int sioaddr, unsigned short *addr, struct smf_sio_data *sio_data)
{
int val;
if (force_id)
val = force_id;
else
val = inb(sioaddr + SIO_REG_DEVID);
switch (val) {
case SIO_Z9100_ID:
sio_data->kind = z9100smf;
break;
case SIO_S6100_ID:
sio_data->kind = s6100smf;
break;
default:
if (val != 0xffff)
pr_debug("unsupported chip ID: 0x%04x\n", val);
return -ENODEV;
}
/* TODO Use define, should this be 0x200 or 0x210??? */
*addr = sioaddr;
pr_info("Found %s chip at %#x\n", smf_devices[sio_data->kind].name, *addr);
sio_data->sioreg = sioaddr;
return (0);
}
/*
* when Super-I/O functions move to a separate file, the Super-I/O
* bus will manage the lifetime of the device and this module will only keep
* track of the smf driver. But since we platform_device_alloc(), we
* must keep track of the device
*/
static struct platform_device *pdev;
static int __init sensors_smf_init(void)
{
int err;
unsigned short address;
struct resource res;
struct smf_sio_data sio_data;
/*
* initialize sio_data->kind and sio_data->sioreg.
* when Super-I/O functions move to a separate file, the Super-I/O
* driver will probe and auto-detect the presence of a
* smf hardware monitor, and call probe()
*/
if (smf_find(SMF_REG_ADDR, &address, &sio_data))
return -ENODEV;
err = platform_driver_register(&smf_driver);
if (err)
goto exit;
pdev = platform_device_alloc(SIO_DRVNAME, address);
if (!pdev) {
err = -ENOMEM;
pr_err("Device allocation failed\n");
goto exit_unregister;
}
err = platform_device_add_data(pdev, &sio_data,
sizeof(struct smf_sio_data));
if (err) {
pr_err("Platform data allocation failed\n");
goto exit_device_put;
}
memset(&res, 0, sizeof(res));
res.name = SIO_DRVNAME;
res.start = address + IOREGION_OFFSET;
res.end = address + IOREGION_OFFSET + IOREGION_LENGTH - 1;
res.flags = IORESOURCE_IO;
err = acpi_check_resource_conflict(&res);
if (err)
goto exit_device_put;
err = platform_device_add_resources(pdev, &res, 1);
if (err) {
pr_err("Device resource addition failed (%d)\n", err);
goto exit_device_put;
}
/* platform_device_add calls probe() */
err = platform_device_add(pdev);
if (err) {
pr_err("Device addition failed (%d)\n", err);
goto exit_device_put;
}
return 0;
exit_device_put:
platform_device_put(pdev);
exit_unregister:
platform_driver_unregister(&smf_driver);
exit:
return err;
}
static void __exit sensors_smf_exit(void)
{
platform_device_unregister(pdev);
platform_driver_unregister(&smf_driver);
/*Remove sysfs dell_kobj*/
kobject_put(dell_kobj);
}
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("SMF driver");
MODULE_PARM_DESC(force_id, "Override the detected device ID");
MODULE_AUTHOR("Per Fremrot <per_fremrot@dell.com>");
MODULE_AUTHOR("Paavaanan <paavaanan_t_n@dell.com>");
module_init(sensors_smf_init);
module_exit(sensors_smf_exit);