Notify user when hotplug device signal is received in order to allow user to handle such case, if it wishes to take some action on this matter. Signed-off-by: Vadim Pasternak <vadimp@xxxxxxxxxxxx> --- drivers/platform/mellanox/mlxreg-hotplug.c | 29 ++++++++++++++++++++--------- 1 file changed, 20 insertions(+), 9 deletions(-) diff --git a/drivers/platform/mellanox/mlxreg-hotplug.c b/drivers/platform/mellanox/mlxreg-hotplug.c index f32637e..4761211 100644 --- a/drivers/platform/mellanox/mlxreg-hotplug.c +++ b/drivers/platform/mellanox/mlxreg-hotplug.c @@ -68,6 +68,7 @@ * @dwork_irq: delayed work template; * @lock: spin lock; * @hwmon: hwmon device; + * @kobj: hwmon kobject for notification; * @mlxreg_hotplug_attr: sysfs attributes array; * @mlxreg_hotplug_dev_attr: sysfs sensor device attribute array; * @group: sysfs attribute group; @@ -87,6 +88,7 @@ struct mlxreg_hotplug_priv_data { struct delayed_work dwork_irq; spinlock_t lock; /* sync with interrupt */ struct device *hwmon; + struct kobject *kobj; struct attribute *mlxreg_hotplug_attr[MLXREG_HOTPLUG_ATTRS_MAX + 1]; struct sensor_device_attribute_2 mlxreg_hotplug_dev_attr[MLXREG_HOTPLUG_ATTRS_MAX]; @@ -104,6 +106,9 @@ static int mlxreg_hotplug_device_create(struct mlxreg_hotplug_priv_data *priv, { struct mlxreg_core_hotplug_platform_data *pdata; + /* Notify user by sending hwmon uevent. */ + kobject_uevent(priv->kobj, KOBJ_CHANGE); + /* * Return if adapter number is negative. It could be in case hotplug * event is not associated with hotplug device. @@ -135,8 +140,13 @@ static int mlxreg_hotplug_device_create(struct mlxreg_hotplug_priv_data *priv, return 0; } -static void mlxreg_hotplug_device_destroy(struct mlxreg_core_data *data) +static void +mlxreg_hotplug_device_destroy(struct mlxreg_hotplug_priv_data *priv, + struct mlxreg_core_data *data) { + /* Notify user by sending hwmon uevent. */ + kobject_uevent(priv->kobj, KOBJ_CHANGE); + if (data->hpdev.client) { i2c_unregister_device(data->hpdev.client); data->hpdev.client = NULL; @@ -279,14 +289,14 @@ mlxreg_hotplug_work_helper(struct mlxreg_hotplug_priv_data *priv, data = item->data + bit; if (regval & BIT(bit)) { if (item->inversed) - mlxreg_hotplug_device_destroy(data); + mlxreg_hotplug_device_destroy(priv, data); else mlxreg_hotplug_device_create(priv, data); } else { if (item->inversed) mlxreg_hotplug_device_create(priv, data); else - mlxreg_hotplug_device_destroy(data); + mlxreg_hotplug_device_destroy(priv, data); } } @@ -357,7 +367,7 @@ mlxreg_hotplug_health_work_helper(struct mlxreg_hotplug_priv_data *priv, * in steady state. Disconnect associated * device, if it has been connected. */ - mlxreg_hotplug_device_destroy(data); + mlxreg_hotplug_device_destroy(priv, data); data->attached = false; data->health_cntr = 0; } else if (regval == MLXREG_HOTPLUG_DOWN_MASK && @@ -583,7 +593,7 @@ static void mlxreg_hotplug_unset_irq(struct mlxreg_hotplug_priv_data *priv) /* Remove all the attached devices in group. */ count = item->count; for (j = 0; j < count; j++, data++) - mlxreg_hotplug_device_destroy(data); + mlxreg_hotplug_device_destroy(priv, data); } } @@ -648,10 +658,6 @@ static int mlxreg_hotplug_probe(struct platform_device *pdev) disable_irq(priv->irq); spin_lock_init(&priv->lock); INIT_DELAYED_WORK(&priv->dwork_irq, mlxreg_hotplug_work_handler); - /* Perform initial interrupts setup. */ - mlxreg_hotplug_set_irq(priv); - - priv->after_probe = true; dev_set_drvdata(&pdev->dev, priv); err = mlxreg_hotplug_attr_init(priv); @@ -668,6 +674,11 @@ static int mlxreg_hotplug_probe(struct platform_device *pdev) PTR_ERR(priv->hwmon)); return PTR_ERR(priv->hwmon); } + priv->kobj = &priv->hwmon->kobj; + + /* Perform initial interrupts setup. */ + mlxreg_hotplug_set_irq(priv); + priv->after_probe = true; return 0; } -- 2.1.4