[devices]: DELL S6000 CPLD driver update to recover if mux is hung during i2c operation (#2858)

This commit is contained in:
Sudharsan D.G 2019-05-09 00:12:26 -07:00 committed by lguohan
parent e7485fdcef
commit 25f285d2ed

View File

@ -9,6 +9,7 @@
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <linux/i2c/sff-8436.h> #include <linux/i2c/sff-8436.h>
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/gpio.h>
#define S6000_MUX_BASE_NR 10 #define S6000_MUX_BASE_NR 10
#define QSFP_MODULE_BASE_NR 20 #define QSFP_MODULE_BASE_NR 20
@ -20,6 +21,7 @@
#define QSFP_MODULE_NUM 16 #define QSFP_MODULE_NUM 16
#define QSFP_DEVICE_NUM 2 #define QSFP_DEVICE_NUM 2
#define GPIO_I2C_MUX_PIN 10
static void device_release(struct device *dev) static void device_release(struct device *dev)
{ {
@ -247,28 +249,59 @@ static struct platform_driver qsfp_mux_driver = {
/* TODO */ /* TODO */
/* module_platform_driver */ /* module_platform_driver */
static int dell_i2c_smbus_read_byte_data(const struct i2c_client *client,
u8 command)
{
int ret = 0;
ret = i2c_smbus_read_byte_data(client, command);
if(ret < 0) {
printk(KERN_WARNING "I2C smbus read failed. Resetting mux with gpio10");
gpio_set_value(GPIO_I2C_MUX_PIN, 1);
gpio_set_value(GPIO_I2C_MUX_PIN, 0);
ret = i2c_smbus_read_byte_data(client, command);
}
return ret;
}
static int dell_i2c_smbus_write_byte_data(const struct i2c_client *client,
u8 command, u8 value)
{
int ret = 0;
ret = i2c_smbus_write_byte_data(client, command, value);
if(ret < 0)
{
printk(KERN_WARNING "I2C smbus write failed. Resetting mux with gpio10");
gpio_set_value(GPIO_I2C_MUX_PIN, 1);
gpio_set_value(GPIO_I2C_MUX_PIN, 0);
ret = i2c_smbus_write_byte_data(client, command, value);
}
return ret;
}
static ssize_t get_modsel(struct device *dev, struct device_attribute *devattr, char *buf) static ssize_t get_modsel(struct device *dev, struct device_attribute *devattr, char *buf)
{ {
int ret; int ret;
u32 data = 0; u32 data = 0;
struct cpld_platform_data *pdata = dev->platform_data; struct cpld_platform_data *pdata = dev->platform_data;
ret = i2c_smbus_read_byte_data(pdata[slave_cpld].client, 0x0); ret = dell_i2c_smbus_read_byte_data(pdata[slave_cpld].client, 0x0);
if (ret < 0) if (ret < 0)
return sprintf(buf, "na"); return sprintf(buf, "na");
data = (u32)ret & 0xff; data = (u32)ret & 0xff;
ret = i2c_smbus_read_byte_data(pdata[slave_cpld].client, 0x1); ret = dell_i2c_smbus_read_byte_data(pdata[slave_cpld].client, 0x1);
if (ret < 0) if (ret < 0)
return sprintf(buf, "na"); return sprintf(buf, "na");
data |= (u32)(ret & 0xff) << 8; data |= (u32)(ret & 0xff) << 8;
ret = i2c_smbus_read_byte_data(pdata[master_cpld].client, 0xa); ret = dell_i2c_smbus_read_byte_data(pdata[master_cpld].client, 0xa);
if (ret < 0) if (ret < 0)
return sprintf(buf, "na"); return sprintf(buf, "na");
data |= (u32)(ret & 0xff) << 16; data |= (u32)(ret & 0xff) << 16;
ret = i2c_smbus_read_byte_data(pdata[master_cpld].client, 0xb); ret = dell_i2c_smbus_read_byte_data(pdata[master_cpld].client, 0xb);
if (ret < 0) if (ret < 0)
return sprintf(buf, "na"); return sprintf(buf, "na");
data |= (u32)(ret & 0xff) << 24; data |= (u32)(ret & 0xff) << 24;
@ -282,22 +315,22 @@ static ssize_t get_lpmode(struct device *dev, struct device_attribute *devattr,
u32 data = 0; u32 data = 0;
struct cpld_platform_data *pdata = dev->platform_data; struct cpld_platform_data *pdata = dev->platform_data;
ret = i2c_smbus_read_byte_data(pdata[slave_cpld].client, 0x2); ret = dell_i2c_smbus_read_byte_data(pdata[slave_cpld].client, 0x2);
if (ret < 0) if (ret < 0)
return sprintf(buf, "na"); return sprintf(buf, "na");
data = (u32)ret & 0xff; data = (u32)ret & 0xff;
ret = i2c_smbus_read_byte_data(pdata[slave_cpld].client, 0x3); ret = dell_i2c_smbus_read_byte_data(pdata[slave_cpld].client, 0x3);
if (ret < 0) if (ret < 0)
return sprintf(buf, "na"); return sprintf(buf, "na");
data |= (u32)(ret & 0xff) << 8; data |= (u32)(ret & 0xff) << 8;
ret = i2c_smbus_read_byte_data(pdata[master_cpld].client, 0xc); ret = dell_i2c_smbus_read_byte_data(pdata[master_cpld].client, 0xc);
if (ret < 0) if (ret < 0)
return sprintf(buf, "na"); return sprintf(buf, "na");
data |= (u32)(ret & 0xff) << 16; data |= (u32)(ret & 0xff) << 16;
ret = i2c_smbus_read_byte_data(pdata[master_cpld].client, 0xd); ret = dell_i2c_smbus_read_byte_data(pdata[master_cpld].client, 0xd);
if (ret < 0) if (ret < 0)
return sprintf(buf, "na"); return sprintf(buf, "na");
data |= (u32)(ret & 0xff) << 24; data |= (u32)(ret & 0xff) << 24;
@ -315,10 +348,10 @@ static ssize_t set_lpmode(struct device *dev, struct device_attribute *devattr,
if (err) if (err)
return err; return err;
i2c_smbus_write_byte_data(pdata[slave_cpld].client, 0x2, (u8)(data & 0xff)); dell_i2c_smbus_write_byte_data(pdata[slave_cpld].client, 0x2, (u8)(data & 0xff));
i2c_smbus_write_byte_data(pdata[slave_cpld].client, 0x3, (u8)((data >> 8) & 0xff)); dell_i2c_smbus_write_byte_data(pdata[slave_cpld].client, 0x3, (u8)((data >> 8) & 0xff));
i2c_smbus_write_byte_data(pdata[master_cpld].client, 0xc, (u8)((data >> 16) & 0xff)); dell_i2c_smbus_write_byte_data(pdata[master_cpld].client, 0xc, (u8)((data >> 16) & 0xff));
i2c_smbus_write_byte_data(pdata[master_cpld].client, 0xd, (u8)((data >> 24) & 0xff)); dell_i2c_smbus_write_byte_data(pdata[master_cpld].client, 0xd, (u8)((data >> 24) & 0xff));
return count; return count;
} }
@ -329,22 +362,22 @@ static ssize_t get_reset(struct device *dev, struct device_attribute *devattr, c
u32 data = 0; u32 data = 0;
struct cpld_platform_data *pdata = dev->platform_data; struct cpld_platform_data *pdata = dev->platform_data;
ret = i2c_smbus_read_byte_data(pdata[slave_cpld].client, 0x6); ret = dell_i2c_smbus_read_byte_data(pdata[slave_cpld].client, 0x6);
if (ret < 0) if (ret < 0)
return sprintf(buf, "na"); return sprintf(buf, "na");
data = (u32)ret & 0xff; data = (u32)ret & 0xff;
ret = i2c_smbus_read_byte_data(pdata[slave_cpld].client, 0x7); ret = dell_i2c_smbus_read_byte_data(pdata[slave_cpld].client, 0x7);
if (ret < 0) if (ret < 0)
return sprintf(buf, "na"); return sprintf(buf, "na");
data |= (u32)(ret & 0xff) << 8; data |= (u32)(ret & 0xff) << 8;
ret = i2c_smbus_read_byte_data(pdata[master_cpld].client, 0x10); ret = dell_i2c_smbus_read_byte_data(pdata[master_cpld].client, 0x10);
if (ret < 0) if (ret < 0)
return sprintf(buf, "na"); return sprintf(buf, "na");
data |= (u32)(ret & 0xff) << 16; data |= (u32)(ret & 0xff) << 16;
ret = i2c_smbus_read_byte_data(pdata[master_cpld].client, 0x11); ret = dell_i2c_smbus_read_byte_data(pdata[master_cpld].client, 0x11);
if (ret < 0) if (ret < 0)
return sprintf(buf, "na"); return sprintf(buf, "na");
data |= (u32)(ret & 0xff) << 24; data |= (u32)(ret & 0xff) << 24;
@ -362,10 +395,10 @@ static ssize_t set_reset(struct device *dev, struct device_attribute *devattr, c
if (err) if (err)
return err; return err;
i2c_smbus_write_byte_data(pdata[slave_cpld].client, 0x6, (u8)(data & 0xff)); dell_i2c_smbus_write_byte_data(pdata[slave_cpld].client, 0x6, (u8)(data & 0xff));
i2c_smbus_write_byte_data(pdata[slave_cpld].client, 0x7, (u8)((data >> 8)& 0xff)); dell_i2c_smbus_write_byte_data(pdata[slave_cpld].client, 0x7, (u8)((data >> 8)& 0xff));
i2c_smbus_write_byte_data(pdata[master_cpld].client, 0x10, (u8)((data >> 16) & 0xff)); dell_i2c_smbus_write_byte_data(pdata[master_cpld].client, 0x10, (u8)((data >> 16) & 0xff));
i2c_smbus_write_byte_data(pdata[master_cpld].client, 0x11, (u8)((data >> 24) & 0xff)); dell_i2c_smbus_write_byte_data(pdata[master_cpld].client, 0x11, (u8)((data >> 24) & 0xff));
return count; return count;
} }
@ -376,22 +409,22 @@ static ssize_t get_modprs(struct device *dev, struct device_attribute *devattr,
u32 data = 0; u32 data = 0;
struct cpld_platform_data *pdata = dev->platform_data; struct cpld_platform_data *pdata = dev->platform_data;
ret = i2c_smbus_read_byte_data(pdata[slave_cpld].client, 0x4); ret = dell_i2c_smbus_read_byte_data(pdata[slave_cpld].client, 0x4);
if (ret < 0) if (ret < 0)
return sprintf(buf, "read error"); return sprintf(buf, "read error");
data = (u32)ret & 0xff; data = (u32)ret & 0xff;
ret = i2c_smbus_read_byte_data(pdata[slave_cpld].client, 0x5); ret = dell_i2c_smbus_read_byte_data(pdata[slave_cpld].client, 0x5);
if (ret < 0) if (ret < 0)
return sprintf(buf, "read error"); return sprintf(buf, "read error");
data |= (u32)(ret & 0xff) << 8; data |= (u32)(ret & 0xff) << 8;
ret = i2c_smbus_read_byte_data(pdata[master_cpld].client, 0xe); ret = dell_i2c_smbus_read_byte_data(pdata[master_cpld].client, 0xe);
if (ret < 0) if (ret < 0)
return sprintf(buf, "na"); return sprintf(buf, "na");
data |= (u32)(ret & 0xff) << 16; data |= (u32)(ret & 0xff) << 16;
ret = i2c_smbus_read_byte_data(pdata[master_cpld].client, 0xf); ret = dell_i2c_smbus_read_byte_data(pdata[master_cpld].client, 0xf);
if (ret < 0) if (ret < 0)
return sprintf(buf, "na"); return sprintf(buf, "na");
data |= (u32)(ret & 0xff) << 24; data |= (u32)(ret & 0xff) << 24;
@ -411,7 +444,7 @@ static ssize_t set_power_reset(struct device *dev, struct device_attribute *deva
if (data) if (data)
{ {
i2c_smbus_write_byte_data(pdata[system_cpld].client, 0x1, (u8)(0xfd)); dell_i2c_smbus_write_byte_data(pdata[system_cpld].client, 0x1, (u8)(0xfd));
} }
return count; return count;
@ -422,7 +455,7 @@ static ssize_t get_power_reset(struct device *dev, struct device_attribute *deva
uint8_t ret = 0; uint8_t ret = 0;
struct cpld_platform_data *pdata = dev->platform_data; struct cpld_platform_data *pdata = dev->platform_data;
ret = i2c_smbus_read_byte_data(pdata[system_cpld].client, 0x1); ret = dell_i2c_smbus_read_byte_data(pdata[system_cpld].client, 0x1);
if (ret < 0) if (ret < 0)
return sprintf(buf, "read error"); return sprintf(buf, "read error");
@ -435,12 +468,12 @@ static ssize_t get_fan_prs(struct device *dev, struct device_attribute *devattr,
u32 data = 0; u32 data = 0;
struct cpld_platform_data *pdata = dev->platform_data; struct cpld_platform_data *pdata = dev->platform_data;
ret = i2c_smbus_read_byte_data(pdata[master_cpld].client, 0x8); ret = dell_i2c_smbus_read_byte_data(pdata[master_cpld].client, 0x8);
if (ret < 0) if (ret < 0)
return sprintf(buf, "read error"); return sprintf(buf, "read error");
data = (u32)((ret & 0xc0) >> 6); data = (u32)((ret & 0xc0) >> 6);
ret = i2c_smbus_read_byte_data(pdata[master_cpld].client, 0x9); ret = dell_i2c_smbus_read_byte_data(pdata[master_cpld].client, 0x9);
if (ret < 0) if (ret < 0)
return sprintf(buf, "read error"); return sprintf(buf, "read error");
data |= (u32)((ret & 0x01) << 2); data |= (u32)((ret & 0x01) << 2);
@ -455,7 +488,7 @@ static ssize_t get_psu0_prs(struct device *dev, struct device_attribute *devattr
u32 data = 0; u32 data = 0;
struct cpld_platform_data *pdata = dev->platform_data; struct cpld_platform_data *pdata = dev->platform_data;
ret = i2c_smbus_read_byte_data(pdata[master_cpld].client, 0x3); ret = dell_i2c_smbus_read_byte_data(pdata[master_cpld].client, 0x3);
if (ret < 0) if (ret < 0)
return sprintf(buf, "read error"); return sprintf(buf, "read error");
@ -471,7 +504,7 @@ static ssize_t get_psu1_prs(struct device *dev, struct device_attribute *devattr
u32 data = 0; u32 data = 0;
struct cpld_platform_data *pdata = dev->platform_data; struct cpld_platform_data *pdata = dev->platform_data;
ret = i2c_smbus_read_byte_data(pdata[master_cpld].client, 0x3); ret = dell_i2c_smbus_read_byte_data(pdata[master_cpld].client, 0x3);
if (ret < 0) if (ret < 0)
return sprintf(buf, "read error"); return sprintf(buf, "read error");
@ -487,7 +520,7 @@ static ssize_t get_psu0_status(struct device *dev, struct device_attribute *deva
u32 data = 0; u32 data = 0;
struct cpld_platform_data *pdata = dev->platform_data; struct cpld_platform_data *pdata = dev->platform_data;
ret = i2c_smbus_read_byte_data(pdata[master_cpld].client, 0x3); ret = dell_i2c_smbus_read_byte_data(pdata[master_cpld].client, 0x3);
if (ret < 0) if (ret < 0)
return sprintf(buf, "read error"); return sprintf(buf, "read error");
@ -503,7 +536,7 @@ static ssize_t get_psu1_status(struct device *dev, struct device_attribute *deva
u32 data = 0; u32 data = 0;
struct cpld_platform_data *pdata = dev->platform_data; struct cpld_platform_data *pdata = dev->platform_data;
ret = i2c_smbus_read_byte_data(pdata[master_cpld].client, 0x3); ret = dell_i2c_smbus_read_byte_data(pdata[master_cpld].client, 0x3);
if (ret < 0) if (ret < 0)
return sprintf(buf, "read error"); return sprintf(buf, "read error");
@ -519,7 +552,7 @@ static ssize_t get_system_led(struct device *dev, struct device_attribute *devat
u32 data = 0; u32 data = 0;
struct cpld_platform_data *pdata = dev->platform_data; struct cpld_platform_data *pdata = dev->platform_data;
ret = i2c_smbus_read_byte_data(pdata[master_cpld].client, 0x7); ret = dell_i2c_smbus_read_byte_data(pdata[master_cpld].client, 0x7);
if (ret < 0) if (ret < 0)
return sprintf(buf, "read error"); return sprintf(buf, "read error");
@ -570,11 +603,11 @@ static ssize_t set_system_led(struct device *dev, struct device_attribute *devat
return -1; return -1;
} }
ret = i2c_smbus_read_byte_data(pdata[master_cpld].client, 0x7); ret = dell_i2c_smbus_read_byte_data(pdata[master_cpld].client, 0x7);
if (ret < 0) if (ret < 0)
return ret; return ret;
i2c_smbus_write_byte_data(pdata[master_cpld].client, 0x7, (u8)((ret & 0x9F) | (data << 5))); dell_i2c_smbus_write_byte_data(pdata[master_cpld].client, 0x7, (u8)((ret & 0x9F) | (data << 5)));
return count; return count;
} }
@ -585,7 +618,7 @@ static ssize_t get_locator_led(struct device *dev, struct device_attribute *deva
u32 data = 0; u32 data = 0;
struct cpld_platform_data *pdata = dev->platform_data; struct cpld_platform_data *pdata = dev->platform_data;
ret = i2c_smbus_read_byte_data(pdata[master_cpld].client, 0x7); ret = dell_i2c_smbus_read_byte_data(pdata[master_cpld].client, 0x7);
if (ret < 0) if (ret < 0)
return sprintf(buf, "read error"); return sprintf(buf, "read error");
@ -632,11 +665,11 @@ static ssize_t set_locator_led(struct device *dev, struct device_attribute *deva
return -1; return -1;
} }
ret = i2c_smbus_read_byte_data(pdata[master_cpld].client, 0x7); ret = dell_i2c_smbus_read_byte_data(pdata[master_cpld].client, 0x7);
if (ret < 0) if (ret < 0)
return ret; return ret;
i2c_smbus_write_byte_data(pdata[master_cpld].client, 0x7, (u8)((ret & 0xE7) | (data << 3))); dell_i2c_smbus_write_byte_data(pdata[master_cpld].client, 0x7, (u8)((ret & 0xE7) | (data << 3)));
return count; return count;
} }
@ -647,7 +680,7 @@ static ssize_t get_power_led(struct device *dev, struct device_attribute *devatt
u32 data = 0; u32 data = 0;
struct cpld_platform_data *pdata = dev->platform_data; struct cpld_platform_data *pdata = dev->platform_data;
ret = i2c_smbus_read_byte_data(pdata[master_cpld].client, 0x7); ret = dell_i2c_smbus_read_byte_data(pdata[master_cpld].client, 0x7);
if (ret < 0) if (ret < 0)
return sprintf(buf, "read error"); return sprintf(buf, "read error");
@ -698,11 +731,11 @@ static ssize_t set_power_led(struct device *dev, struct device_attribute *devatt
return -1; return -1;
} }
ret = i2c_smbus_read_byte_data(pdata[master_cpld].client, 0x7); ret = dell_i2c_smbus_read_byte_data(pdata[master_cpld].client, 0x7);
if (ret < 0) if (ret < 0)
return ret; return ret;
i2c_smbus_write_byte_data(pdata[master_cpld].client, 0x7, (u8)((ret & 0xF9) | (data << 1))); dell_i2c_smbus_write_byte_data(pdata[master_cpld].client, 0x7, (u8)((ret & 0xF9) | (data << 1)));
return count; return count;
} }
@ -713,7 +746,7 @@ static ssize_t get_master_led(struct device *dev, struct device_attribute *devat
u32 data = 0; u32 data = 0;
struct cpld_platform_data *pdata = dev->platform_data; struct cpld_platform_data *pdata = dev->platform_data;
ret = i2c_smbus_read_byte_data(pdata[master_cpld].client, 0x7); ret = dell_i2c_smbus_read_byte_data(pdata[master_cpld].client, 0x7);
if (ret < 0) if (ret < 0)
return sprintf(buf, "read error"); return sprintf(buf, "read error");
@ -751,11 +784,11 @@ static ssize_t set_master_led(struct device *dev, struct device_attribute *devat
return -1; return -1;
} }
ret = i2c_smbus_read_byte_data(pdata[master_cpld].client, 0x7); ret = dell_i2c_smbus_read_byte_data(pdata[master_cpld].client, 0x7);
if (ret < 0) if (ret < 0)
return ret; return ret;
i2c_smbus_write_byte_data(pdata[master_cpld].client, 0x7, (u8)((ret & 0xFE) | data)); dell_i2c_smbus_write_byte_data(pdata[master_cpld].client, 0x7, (u8)((ret & 0xFE) | data));
return count; return count;
} }
@ -766,7 +799,7 @@ static ssize_t get_fan_led(struct device *dev, struct device_attribute *devattr,
u32 data = 0; u32 data = 0;
struct cpld_platform_data *pdata = dev->platform_data; struct cpld_platform_data *pdata = dev->platform_data;
ret = i2c_smbus_read_byte_data(pdata[master_cpld].client, 0x9); ret = dell_i2c_smbus_read_byte_data(pdata[master_cpld].client, 0x9);
if (ret < 0) if (ret < 0)
return sprintf(buf, "read error"); return sprintf(buf, "read error");
@ -817,11 +850,11 @@ static ssize_t set_fan_led(struct device *dev, struct device_attribute *devattr,
return -1; return -1;
} }
ret = i2c_smbus_read_byte_data(pdata[master_cpld].client, 0x9); ret = dell_i2c_smbus_read_byte_data(pdata[master_cpld].client, 0x9);
if (ret < 0) if (ret < 0)
return ret; return ret;
i2c_smbus_write_byte_data(pdata[master_cpld].client, 0x9, (u8)((ret & 0xE7) | (data << 3))); dell_i2c_smbus_write_byte_data(pdata[master_cpld].client, 0x9, (u8)((ret & 0xE7) | (data << 3)));
return count; return count;
} }
@ -832,7 +865,7 @@ static ssize_t get_fan0_led(struct device *dev, struct device_attribute *devattr
u32 data = 0; u32 data = 0;
struct cpld_platform_data *pdata = dev->platform_data; struct cpld_platform_data *pdata = dev->platform_data;
ret = i2c_smbus_read_byte_data(pdata[master_cpld].client, 0x8); ret = dell_i2c_smbus_read_byte_data(pdata[master_cpld].client, 0x8);
if (ret < 0) if (ret < 0)
return sprintf(buf, "read error"); return sprintf(buf, "read error");
@ -879,11 +912,11 @@ static ssize_t set_fan0_led(struct device *dev, struct device_attribute *devattr
return -1; return -1;
} }
ret = i2c_smbus_read_byte_data(pdata[master_cpld].client, 0x8); ret = dell_i2c_smbus_read_byte_data(pdata[master_cpld].client, 0x8);
if (ret < 0) if (ret < 0)
return ret; return ret;
i2c_smbus_write_byte_data(pdata[master_cpld].client, 0x8, (u8)((ret & 0xFC) | data)); dell_i2c_smbus_write_byte_data(pdata[master_cpld].client, 0x8, (u8)((ret & 0xFC) | data));
return count; return count;
} }
@ -895,7 +928,7 @@ static ssize_t get_fan1_led(struct device *dev, struct device_attribute *devattr
u32 data = 0; u32 data = 0;
struct cpld_platform_data *pdata = dev->platform_data; struct cpld_platform_data *pdata = dev->platform_data;
ret = i2c_smbus_read_byte_data(pdata[master_cpld].client, 0x8); ret = dell_i2c_smbus_read_byte_data(pdata[master_cpld].client, 0x8);
if (ret < 0) if (ret < 0)
return sprintf(buf, "read error"); return sprintf(buf, "read error");
@ -942,11 +975,11 @@ static ssize_t set_fan1_led(struct device *dev, struct device_attribute *devattr
return -1; return -1;
} }
ret = i2c_smbus_read_byte_data(pdata[master_cpld].client, 0x8); ret = dell_i2c_smbus_read_byte_data(pdata[master_cpld].client, 0x8);
if (ret < 0) if (ret < 0)
return ret; return ret;
i2c_smbus_write_byte_data(pdata[master_cpld].client, 0x8, (u8)((ret & 0xF3) | (data << 2))); dell_i2c_smbus_write_byte_data(pdata[master_cpld].client, 0x8, (u8)((ret & 0xF3) | (data << 2)));
return count; return count;
} }
@ -957,7 +990,7 @@ static ssize_t get_fan2_led(struct device *dev, struct device_attribute *devattr
u32 data = 0; u32 data = 0;
struct cpld_platform_data *pdata = dev->platform_data; struct cpld_platform_data *pdata = dev->platform_data;
ret = i2c_smbus_read_byte_data(pdata[master_cpld].client, 0x8); ret = dell_i2c_smbus_read_byte_data(pdata[master_cpld].client, 0x8);
if (ret < 0) if (ret < 0)
return sprintf(buf, "read error"); return sprintf(buf, "read error");
@ -1004,11 +1037,11 @@ static ssize_t set_fan2_led(struct device *dev, struct device_attribute *devattr
return -1; return -1;
} }
ret = i2c_smbus_read_byte_data(pdata[master_cpld].client, 0x8); ret = dell_i2c_smbus_read_byte_data(pdata[master_cpld].client, 0x8);
if (ret < 0) if (ret < 0)
return ret; return ret;
i2c_smbus_write_byte_data(pdata[master_cpld].client, 0x8, (u8)((ret & 0xCF) | (data << 4))); dell_i2c_smbus_write_byte_data(pdata[master_cpld].client, 0x8, (u8)((ret & 0xCF) | (data << 4)));
return count; return count;
} }
@ -1020,7 +1053,7 @@ static ssize_t get_system_cpld_ver(struct device *dev,
u32 data = 0; u32 data = 0;
struct cpld_platform_data *pdata = dev->platform_data; struct cpld_platform_data *pdata = dev->platform_data;
ret = i2c_smbus_read_byte_data(pdata[system_cpld].client, 0x0); ret = dell_i2c_smbus_read_byte_data(pdata[system_cpld].client, 0x0);
if (ret < 0) if (ret < 0)
return sprintf(buf, "read error"); return sprintf(buf, "read error");
@ -1036,7 +1069,7 @@ static ssize_t get_master_cpld_ver(struct device *dev,
u32 data = 0; u32 data = 0;
struct cpld_platform_data *pdata = dev->platform_data; struct cpld_platform_data *pdata = dev->platform_data;
ret = i2c_smbus_read_byte_data(pdata[master_cpld].client, 0x1); ret = dell_i2c_smbus_read_byte_data(pdata[master_cpld].client, 0x1);
if (ret < 0) if (ret < 0)
return sprintf(buf, "read error"); return sprintf(buf, "read error");
@ -1052,7 +1085,7 @@ static ssize_t get_slave_cpld_ver(struct device *dev,
u32 data = 0; u32 data = 0;
struct cpld_platform_data *pdata = dev->platform_data; struct cpld_platform_data *pdata = dev->platform_data;
ret = i2c_smbus_read_byte_data(pdata[slave_cpld].client, 0xa); ret = dell_i2c_smbus_read_byte_data(pdata[slave_cpld].client, 0xa);
if (ret < 0) if (ret < 0)
return sprintf(buf, "read error"); return sprintf(buf, "read error");
@ -1201,8 +1234,28 @@ static int __init dell_s6000_platform_init(void)
struct cpld_platform_data *cpld_pdata; struct cpld_platform_data *cpld_pdata;
struct qsfp_mux_platform_data *qsfp_pdata; struct qsfp_mux_platform_data *qsfp_pdata;
int i; int i;
bool gpio_allocated = false;
printk("delll_s6000_platform module initialization\n"); printk("dell_s6000_platform module initialization\n");
ret = gpio_request(GPIO_I2C_MUX_PIN, "gpio10");
if(ret < 0) {
printk(KERN_WARNING "Failed to request gpio 10");
goto error_gpio_init;
}
gpio_allocated = true;
ret = gpio_export(GPIO_I2C_MUX_PIN, false);
if(ret < 0) {
printk(KERN_WARNING "Failed to export gpio 10");
goto error_gpio_init;
}
ret = gpio_direction_output(GPIO_I2C_MUX_PIN, 0);
if(ret < 0) {
printk(KERN_WARNING "Failed to set direction out on gpio 10");
goto error_gpio_init;
}
ret = platform_driver_register(&cpld_driver); ret = platform_driver_register(&cpld_driver);
if (ret) { if (ret) {
@ -1261,6 +1314,11 @@ error_qsfp_mux_driver:
platform_driver_unregister(&cpld_driver); platform_driver_unregister(&cpld_driver);
error_cpld_driver: error_cpld_driver:
return ret; return ret;
error_gpio_init:
if(gpio_allocated) {
gpio_free(GPIO_I2C_MUX_PIN);
}
return ret;
} }
static void __exit dell_s6000_platform_exit(void) static void __exit dell_s6000_platform_exit(void)
@ -1274,6 +1332,7 @@ static void __exit dell_s6000_platform_exit(void)
platform_driver_unregister(&cpld_driver); platform_driver_unregister(&cpld_driver);
platform_driver_unregister(&qsfp_mux_driver); platform_driver_unregister(&qsfp_mux_driver);
gpio_free(GPIO_I2C_MUX_PIN);
} }
module_init(dell_s6000_platform_init); module_init(dell_s6000_platform_init);