as6712-32x to support kernel 4.14 (from Brandon)

This commit is contained in:
Lewis Kang
2018-05-18 15:35:35 +08:00
parent 0c313b1c9f
commit ab5f904a3f
3 changed files with 68 additions and 73 deletions

View File

@@ -1 +1 @@
!include $ONL_TEMPLATES/platform-modules.yml VENDOR=accton BASENAME=x86-64-accton-as6712-32x ARCH=amd64 KERNELS="onl-kernel-3.16-lts-x86-64-all:amd64"
!include $ONL_TEMPLATES/platform-modules.yml VENDOR=accton BASENAME=x86-64-accton-as6712-32x ARCH=amd64 KERNELS="onl-kernel-4.14-lts-x86-64-all:amd64"

View File

@@ -1,4 +1,4 @@
KERNELS := onl-kernel-3.16-lts-x86-64-all:amd64
KERNELS := onl-kernel-4.14-lts-x86-64-all:amd64
KMODULES := $(wildcard *.c)
VENDOR := accton
BASENAME := x86-64-accton-as6712-32x

View File

@@ -44,9 +44,6 @@
#define NUM_OF_CPLD2_CHANS 0x10
#define NUM_OF_CPLD3_CHANS 0x10
#define CPLD_CHANNEL_SELECT_REG 0x2
#define CPLD_DESELECT_CHANNEL 0xFF
#define ACCTON_I2C_CPLD_MUX_MAX_NCHANS NUM_OF_CPLD3_CHANS
static LIST_HEAD(cpld_client_list);
static struct mutex list_lock;
@@ -64,7 +61,7 @@ enum cpld_mux_type {
struct as6712_32x_cpld_data {
enum cpld_mux_type type;
struct i2c_adapter *virt_adaps[ACCTON_I2C_CPLD_MUX_MAX_NCHANS];
struct i2c_client *client;
u8 last_chan; /* last register value */
struct device *hwmon_dev;
@@ -273,8 +270,9 @@ static ssize_t show_present_all(struct device *dev, struct device_attribute *da,
int i, status;
u8 values[2] = {0};
u8 regs[] = {0xA, 0xB};
struct i2c_client *client = to_i2c_client(dev);
struct as6712_32x_cpld_data *data = i2c_get_clientdata(client);
struct i2c_client *client = to_i2c_client(dev);
struct i2c_mux_core *muxc = i2c_get_clientdata(client);
struct as6712_32x_cpld_data *data = i2c_mux_priv(muxc);
mutex_lock(&data->update_lock);
@@ -303,7 +301,8 @@ static ssize_t show_status(struct device *dev, struct device_attribute *da,
{
struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
struct i2c_client *client = to_i2c_client(dev);
struct as6712_32x_cpld_data *data = i2c_get_clientdata(client);
struct i2c_mux_core *muxc = i2c_get_clientdata(client);
struct as6712_32x_cpld_data *data = i2c_mux_priv(muxc);
int status = 0;
u8 reg = 0, mask = 0;
@@ -345,10 +344,11 @@ exit:
static ssize_t access(struct device *dev, struct device_attribute *da,
const char *buf, size_t count)
{
struct i2c_client *client = to_i2c_client(dev);
struct i2c_mux_core *muxc = i2c_get_clientdata(client);
struct as6712_32x_cpld_data *data = i2c_mux_priv(muxc);
int status;
u32 addr, val;
struct i2c_client *client = to_i2c_client(dev);
struct as6712_32x_cpld_data *data = i2c_get_clientdata(client);
if (sscanf(buf, "0x%x 0x%x", &addr, &val) != 2) {
return -EINVAL;
@@ -404,32 +404,34 @@ static int as6712_32x_cpld_mux_reg_write(struct i2c_adapter *adap,
return res;
}
static int as6712_32x_cpld_mux_select_chan(struct i2c_adapter *adap,
void *client, u32 chan)
static int as6712_32x_cpld_mux_select_chan(struct i2c_mux_core *muxc,
u32 chan)
{
struct as6712_32x_cpld_data *data = i2c_get_clientdata(client);
struct as6712_32x_cpld_data *data = i2c_mux_priv(muxc);
struct i2c_client *client = data->client;
u8 regval;
int ret = 0;
regval = chan;
/* Only select the channel if its different from the last channel */
if (data->last_chan != regval) {
ret = as6712_32x_cpld_mux_reg_write(adap, client, regval);
ret = as6712_32x_cpld_mux_reg_write(muxc->parent, client, regval);
data->last_chan = regval;
}
return ret;
}
static int as6712_32x_cpld_mux_deselect_mux(struct i2c_adapter *adap,
void *client, u32 chan)
static int as6712_32x_cpld_mux_deselect_mux(struct i2c_mux_core *muxc,
u32 chan)
{
struct as6712_32x_cpld_data *data = i2c_get_clientdata(client);
struct as6712_32x_cpld_data *data = i2c_mux_priv(muxc);
struct i2c_client *client = data->client;
/* Deselect active channel */
data->last_chan = chips[data->type].deselectChan;
return as6712_32x_cpld_mux_reg_write(adap, client, data->last_chan);
return as6712_32x_cpld_mux_reg_write(muxc->parent, client, data->last_chan);
}
static void as6712_32x_cpld_add_client(struct i2c_client *client)
@@ -456,8 +458,7 @@ static void as6712_32x_cpld_remove_client(struct i2c_client *client)
mutex_lock(&list_lock);
list_for_each(list_node, &cpld_client_list)
{
list_for_each(list_node, &cpld_client_list) {
cpld_node = list_entry(list_node, struct cpld_client_node, list);
if (cpld_node->client == client) {
@@ -494,44 +495,43 @@ static ssize_t show_version(struct device *dev, struct device_attribute *attr, c
static int as6712_32x_cpld_mux_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
struct i2c_adapter *adap = to_i2c_adapter(client->dev.parent);
int chan=0;
struct i2c_adapter *adap = to_i2c_adapter(client->dev.parent);
int num, force, class;
struct i2c_mux_core *muxc;
struct as6712_32x_cpld_data *data;
int ret = -ENODEV;
const struct attribute_group *group = NULL;
int ret = 0;
const struct attribute_group *group = NULL;
if (!i2c_check_functionality(adap, I2C_FUNC_SMBUS_BYTE))
goto exit;
return -ENODEV;
data = kzalloc(sizeof(struct as6712_32x_cpld_data), GFP_KERNEL);
if (!data) {
ret = -ENOMEM;
goto exit;
}
muxc = i2c_mux_alloc(adap, &client->dev,
chips[id->driver_data].nchans, sizeof(*data), 0,
as6712_32x_cpld_mux_select_chan, as6712_32x_cpld_mux_deselect_mux);
if (!muxc)
return -ENOMEM;
i2c_set_clientdata(client, data);
i2c_set_clientdata(client, muxc);
data = i2c_mux_priv(muxc);
data->client = client;
data->type = id->driver_data;
data->last_chan = chips[data->type].deselectChan; /* force the first selection */
mutex_init(&data->update_lock);
data->type = id->driver_data;
if (data->type == as6712_32x_cpld2 || data->type == as6712_32x_cpld3) {
data->last_chan = chips[data->type].deselectChan; /* force the first selection */
/* Now create an adapter for each channel */
for (num = 0; num < chips[data->type].nchans; num++) {
force = 0; /* dynamic adap number */
class = 0; /* no class by default */
/* Now create an adapter for each channel */
for (chan = 0; chan < chips[data->type].nchans; chan++) {
data->virt_adaps[chan] = i2c_add_mux_adapter(adap, &client->dev, client, 0, chan, 0,
as6712_32x_cpld_mux_select_chan,
as6712_32x_cpld_mux_deselect_mux);
ret = i2c_mux_add_adapter(muxc, force, num, class);
if (data->virt_adaps[chan] == NULL) {
ret = -ENODEV;
dev_err(&client->dev, "failed to register multiplexed adapter %d\n", chan);
goto exit_mux_register;
}
}
dev_info(&client->dev, "registered %d multiplexed busses for I2C mux %s\n",
chan, client->name);
}
if (ret) {
dev_err(&client->dev,
"failed to register multiplexed adapter"
" %d as bus %d\n", num, force);
goto add_mux_failed;
}
}
/* Register sysfs hooks */
switch (data->type) {
@@ -547,33 +547,37 @@ static int as6712_32x_cpld_mux_probe(struct i2c_client *client,
default:
break;
}
if (group) {
ret = sysfs_create_group(&client->dev.kobj, group);
if (ret) {
goto exit_mux_register;
goto add_mux_failed;
}
}
if (chips[data->type].nchans) {
dev_info(&client->dev,
"registered %d multiplexed busses for I2C %s\n",
num, client->name);
}
else {
dev_info(&client->dev,
"device %s registered\n", client->name);
}
as6712_32x_cpld_add_client(client);
return 0;
exit_mux_register:
for (chan--; chan >= 0; chan--) {
i2c_del_mux_adapter(data->virt_adaps[chan]);
}
kfree(data);
exit:
add_mux_failed:
i2c_mux_del_adapters(muxc);
return ret;
}
static int as6712_32x_cpld_mux_remove(struct i2c_client *client)
{
struct as6712_32x_cpld_data *data = i2c_get_clientdata(client);
const struct chip_desc *chip = &chips[data->type];
int chan;
struct i2c_mux_core *muxc = i2c_get_clientdata(client);
struct as6712_32x_cpld_data *data = i2c_mux_priv(muxc);
const struct attribute_group *group = NULL;
as6712_32x_cpld_remove_client(client);
@@ -597,14 +601,7 @@ static int as6712_32x_cpld_mux_remove(struct i2c_client *client)
sysfs_remove_group(&client->dev.kobj, group);
}
for (chan = 0; chan < chip->nchans; ++chan) {
if (data->virt_adaps[chan]) {
i2c_del_mux_adapter(data->virt_adaps[chan]);
data->virt_adaps[chan] = NULL;
}
}
kfree(data);
i2c_mux_del_adapters(muxc);
return 0;
}
@@ -653,8 +650,7 @@ int as6712_32x_cpld_read(unsigned short cpld_addr, u8 reg)
mutex_lock(&list_lock);
list_for_each(list_node, &cpld_client_list)
{
list_for_each(list_node, &cpld_client_list) {
cpld_node = list_entry(list_node, struct cpld_client_node, list);
if (cpld_node->client->addr == cpld_addr) {
@@ -677,8 +673,7 @@ int as6712_32x_cpld_write(unsigned short cpld_addr, u8 reg, u8 value)
mutex_lock(&list_lock);
list_for_each(list_node, &cpld_client_list)
{
list_for_each(list_node, &cpld_client_list) {
cpld_node = list_entry(list_node, struct cpld_client_node, list);
if (cpld_node->client->addr == cpld_addr) {