Skip to content

Commit 26e118e

Browse files
vadimp-nvidiajwrdegoede
authored andcommitted
platform/mellanox: mlxreg-hotplug: Allow more flexible hotplug events configuration
Currently hotplug configuration in logic device assumes that all items are provided with no holes. Thus, any group of hotplug events, associated with the specific status/event/mask registers is configured in those registers successively from bit zero to bit #n (#n < 8). This logic is changed int order to allow non-successive definition to support configuration with the skipped bits – for example bits 3, 5, 7 in status/event/mask registers can be associated with hotplug events, while others can be skipped. Signed-off-by: Vadim Pasternak <[email protected]> Reviewed-by: Michael Shych <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Hans de Goede <[email protected]>
1 parent 233fd7e commit 26e118e

File tree

1 file changed

+23
-5
lines changed

1 file changed

+23
-5
lines changed

drivers/platform/mellanox/mlxreg-hotplug.c

Lines changed: 23 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -239,14 +239,25 @@ static ssize_t mlxreg_hotplug_attr_show(struct device *dev,
239239
#define PRIV_ATTR(i) priv->mlxreg_hotplug_attr[i]
240240
#define PRIV_DEV_ATTR(i) priv->mlxreg_hotplug_dev_attr[i]
241241

242+
static int mlxreg_hotplug_item_label_index_get(u32 mask, u32 bit)
243+
{
244+
int i, j;
245+
246+
for (i = 0, j = -1; i <= bit; i++) {
247+
if (mask & BIT(i))
248+
j++;
249+
}
250+
return j;
251+
}
252+
242253
static int mlxreg_hotplug_attr_init(struct mlxreg_hotplug_priv_data *priv)
243254
{
244255
struct mlxreg_core_hotplug_platform_data *pdata;
245256
struct mlxreg_core_item *item;
246257
struct mlxreg_core_data *data;
247258
unsigned long mask;
248259
u32 regval;
249-
int num_attrs = 0, id = 0, i, j, k, ret;
260+
int num_attrs = 0, id = 0, i, j, k, count, ret;
250261

251262
pdata = dev_get_platdata(&priv->pdev->dev);
252263
item = pdata->items;
@@ -272,7 +283,8 @@ static int mlxreg_hotplug_attr_init(struct mlxreg_hotplug_priv_data *priv)
272283
/* Go over all unmasked units within item. */
273284
mask = item->mask;
274285
k = 0;
275-
for_each_set_bit(j, &mask, item->count) {
286+
count = item->ind ? item->ind : item->count;
287+
for_each_set_bit(j, &mask, count) {
276288
if (data->capability) {
277289
/*
278290
* Read capability register and skip non
@@ -282,16 +294,17 @@ static int mlxreg_hotplug_attr_init(struct mlxreg_hotplug_priv_data *priv)
282294
data->capability, &regval);
283295
if (ret)
284296
return ret;
297+
285298
if (!(regval & data->bit)) {
286299
data++;
287300
continue;
288301
}
289302
}
303+
290304
PRIV_ATTR(id) = &PRIV_DEV_ATTR(id).dev_attr.attr;
291305
PRIV_ATTR(id)->name = devm_kasprintf(&priv->pdev->dev,
292306
GFP_KERNEL,
293307
data->label);
294-
295308
if (!PRIV_ATTR(id)->name) {
296309
dev_err(priv->dev, "Memory allocation failed for attr %d.\n",
297310
id);
@@ -365,9 +378,14 @@ mlxreg_hotplug_work_helper(struct mlxreg_hotplug_priv_data *priv,
365378
regval &= item->mask;
366379
asserted = item->cache ^ regval;
367380
item->cache = regval;
368-
369381
for_each_set_bit(bit, &asserted, 8) {
370-
data = item->data + bit;
382+
int pos;
383+
384+
pos = mlxreg_hotplug_item_label_index_get(item->mask, bit);
385+
if (pos < 0)
386+
goto out;
387+
388+
data = item->data + pos;
371389
if (regval & BIT(bit)) {
372390
if (item->inversed)
373391
mlxreg_hotplug_device_destroy(priv, data, item->kind);

0 commit comments

Comments
 (0)