Skip to content

Commit 8614819

Browse files
mellanoxbmcandy-shev
authored andcommitted
platform/mellanox: mlxreg-io: Add support for complex attributes
Add support for attributes composed from few registers. Such attributes could occupy from 2 to 4 sequential registers. For word size register space complex attributes can occupy up to two registers, for byte size - up to four. These attributes can carry, for example, CPLD or FPGA versioning, power consuming info, etcetera. Such registers contain read-only data. Signed-off-by: Vadim Pasternak <[email protected]> Signed-off-by: Andy Shevchenko <[email protected]>
1 parent ae1aabf commit 8614819

File tree

1 file changed

+33
-12
lines changed

1 file changed

+33
-12
lines changed

drivers/platform/mellanox/mlxreg-io.c

Lines changed: 33 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
* @mlxreg_io_dev_attr: sysfs sensor device attribute array;
3131
* @group: sysfs attribute group;
3232
* @groups: list of sysfs attribute group for hwmon registration;
33+
* @regsize: size of a register value;
3334
*/
3435
struct mlxreg_io_priv_data {
3536
struct platform_device *pdev;
@@ -39,27 +40,30 @@ struct mlxreg_io_priv_data {
3940
struct sensor_device_attribute mlxreg_io_dev_attr[MLXREG_IO_ATT_NUM];
4041
struct attribute_group group;
4142
const struct attribute_group *groups[2];
43+
int regsize;
4244
};
4345

4446
static int
4547
mlxreg_io_get_reg(void *regmap, struct mlxreg_core_data *data, u32 in_val,
46-
bool rw_flag, u32 *regval)
48+
bool rw_flag, int regsize, u32 *regval)
4749
{
48-
int ret;
50+
int i, val, ret;
4951

5052
ret = regmap_read(regmap, data->reg, regval);
5153
if (ret)
5254
goto access_error;
5355

5456
/*
55-
* There are three kinds of attributes: single bit, full register's
56-
* bits and bit sequence. For the first kind field mask indicates which
57-
* bits are not related and field bit is set zero. For the second kind
58-
* field mask is set to zero and field bit is set with all bits one.
59-
* No special handling for such kind of attributes - pass value as is.
60-
* For the third kind, field mask indicates which bits are related and
61-
* field bit is set to the first bit number (from 1 to 32) is the bit
62-
* sequence.
57+
* There are four kinds of attributes: single bit, full register's
58+
* bits, bit sequence, bits in few registers For the first kind field
59+
* mask indicates which bits are not related and field bit is set zero.
60+
* For the second kind field mask is set to zero and field bit is set
61+
* with all bits one. No special handling for such kind of attributes -
62+
* pass value as is. For the third kind, the field mask indicates which
63+
* bits are related and the field bit is set to the first bit number
64+
* (from 1 to 32) is the bit sequence. For the fourth kind - the number
65+
* of registers which should be read for getting an attribute are
66+
* specified through 'data->regnum' field.
6367
*/
6468
if (!data->bit) {
6569
/* Single bit. */
@@ -83,6 +87,19 @@ mlxreg_io_get_reg(void *regmap, struct mlxreg_core_data *data, u32 in_val,
8387
/* Clear relevant bits and set them to new value. */
8488
*regval = (*regval & ~data->mask) | in_val;
8589
}
90+
} else {
91+
/*
92+
* Some attributes could occupied few registers in case regmap
93+
* bit size is 8 or 16. Compose such attributes from 'regnum'
94+
* registers. Such attributes contain read-only data.
95+
*/
96+
for (i = 1; i < data->regnum; i++) {
97+
ret = regmap_read(regmap, data->reg + i, &val);
98+
if (ret)
99+
goto access_error;
100+
101+
*regval |= rol32(val, regsize * i);
102+
}
86103
}
87104

88105
access_error:
@@ -99,7 +116,8 @@ mlxreg_io_attr_show(struct device *dev, struct device_attribute *attr,
99116
u32 regval = 0;
100117
int ret;
101118

102-
ret = mlxreg_io_get_reg(priv->pdata->regmap, data, 0, true, &regval);
119+
ret = mlxreg_io_get_reg(priv->pdata->regmap, data, 0, true,
120+
priv->regsize, &regval);
103121
if (ret)
104122
goto access_error;
105123

@@ -128,7 +146,7 @@ mlxreg_io_attr_store(struct device *dev, struct device_attribute *attr,
128146
return ret;
129147

130148
ret = mlxreg_io_get_reg(priv->pdata->regmap, data, input_val, false,
131-
&regval);
149+
priv->regsize, &regval);
132150
if (ret)
133151
goto access_error;
134152

@@ -207,6 +225,9 @@ static int mlxreg_io_probe(struct platform_device *pdev)
207225
}
208226

209227
priv->pdev = pdev;
228+
priv->regsize = regmap_get_val_bytes(priv->pdata->regmap);
229+
if (priv->regsize < 0)
230+
return priv->regsize;
210231

211232
err = mlxreg_io_attr_init(priv);
212233
if (err) {

0 commit comments

Comments
 (0)