summaryrefslogtreecommitdiffstats
path: root/drivers/platform/mellanox/mlxreg-hotplug.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/platform/mellanox/mlxreg-hotplug.c')
-rw-r--r--drivers/platform/mellanox/mlxreg-hotplug.c31
1 files changed, 21 insertions, 10 deletions
diff --git a/drivers/platform/mellanox/mlxreg-hotplug.c b/drivers/platform/mellanox/mlxreg-hotplug.c
index 313cf8ad77bf..ea9e7f4479ca 100644
--- a/drivers/platform/mellanox/mlxreg-hotplug.c
+++ b/drivers/platform/mellanox/mlxreg-hotplug.c
@@ -93,9 +93,11 @@ struct mlxreg_hotplug_priv_data {
bool after_probe;
};
-static int mlxreg_hotplug_device_create(struct device *dev,
+static int mlxreg_hotplug_device_create(struct mlxreg_hotplug_priv_data *priv,
struct mlxreg_core_data *data)
{
+ struct mlxreg_core_hotplug_platform_data *pdata;
+
/*
* Return if adapter number is negative. It could be in case hotplug
* event is not associated with hotplug device.
@@ -103,19 +105,21 @@ static int mlxreg_hotplug_device_create(struct device *dev,
if (data->hpdev.nr < 0)
return 0;
- data->hpdev.adapter = i2c_get_adapter(data->hpdev.nr);
+ pdata = dev_get_platdata(&priv->pdev->dev);
+ data->hpdev.adapter = i2c_get_adapter(data->hpdev.nr +
+ pdata->shift_nr);
if (!data->hpdev.adapter) {
- dev_err(dev, "Failed to get adapter for bus %d\n",
- data->hpdev.nr);
+ dev_err(priv->dev, "Failed to get adapter for bus %d\n",
+ data->hpdev.nr + pdata->shift_nr);
return -EFAULT;
}
data->hpdev.client = i2c_new_device(data->hpdev.adapter,
data->hpdev.brdinfo);
if (!data->hpdev.client) {
- dev_err(dev, "Failed to create client %s at bus %d at addr 0x%02x\n",
- data->hpdev.brdinfo->type, data->hpdev.nr,
- data->hpdev.brdinfo->addr);
+ dev_err(priv->dev, "Failed to create client %s at bus %d at addr 0x%02x\n",
+ data->hpdev.brdinfo->type, data->hpdev.nr +
+ pdata->shift_nr, data->hpdev.brdinfo->addr);
i2c_put_adapter(data->hpdev.adapter);
data->hpdev.adapter = NULL;
@@ -270,10 +274,10 @@ mlxreg_hotplug_work_helper(struct mlxreg_hotplug_priv_data *priv,
if (item->inversed)
mlxreg_hotplug_device_destroy(data);
else
- mlxreg_hotplug_device_create(priv->dev, data);
+ mlxreg_hotplug_device_create(priv, data);
} else {
if (item->inversed)
- mlxreg_hotplug_device_create(priv->dev, data);
+ mlxreg_hotplug_device_create(priv, data);
else
mlxreg_hotplug_device_destroy(data);
}
@@ -319,7 +323,7 @@ mlxreg_hotplug_health_work_helper(struct mlxreg_hotplug_priv_data *priv,
if (regval == MLXREG_HOTPLUG_HEALTH_MASK) {
if ((data->health_cntr++ == MLXREG_HOTPLUG_RST_CNTR) ||
!priv->after_probe) {
- mlxreg_hotplug_device_create(priv->dev, data);
+ mlxreg_hotplug_device_create(priv, data);
data->attached = true;
}
} else {
@@ -550,6 +554,7 @@ static int mlxreg_hotplug_probe(struct platform_device *pdev)
{
struct mlxreg_core_hotplug_platform_data *pdata;
struct mlxreg_hotplug_priv_data *priv;
+ struct i2c_adapter *deferred_adap;
int err;
pdata = dev_get_platdata(&pdev->dev);
@@ -558,6 +563,12 @@ static int mlxreg_hotplug_probe(struct platform_device *pdev)
return -EINVAL;
}
+ /* Defer probing if the necessary adapter is not configured yet. */
+ deferred_adap = i2c_get_adapter(pdata->deferred_nr);
+ if (!deferred_adap)
+ return -EPROBE_DEFER;
+ i2c_put_adapter(deferred_adap);
+
priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
if (!priv)
return -ENOMEM;