Re: [PATCH v5 3/5] hwmon: (pmbus/core): Notify hwmon events

From: Naresh Solanki
Date: Mon Dec 05 2022 - 02:08:09 EST


Hi Guenter

On 02-12-2022 01:45 am, Guenter Roeck wrote:
On Thu, Dec 01, 2022 at 08:30:22PM +0100, Naresh Solanki wrote:
Notify hwmon events using the pmbus irq handler.


Unfortunately, as implemented, this only works if regulator support
is enabled, which is unacceptable.
Will work on this to check all pages instead of regulators. I hope that is ok.

Regards,
Naresh

Guenter

Signed-off-by: Naresh Solanki <Naresh.Solanki@xxxxxxxxxxxxx>
---
drivers/hwmon/pmbus/pmbus_core.c | 46 +++++++++++++++++++++++++++++---
1 file changed, 43 insertions(+), 3 deletions(-)

diff --git a/drivers/hwmon/pmbus/pmbus_core.c b/drivers/hwmon/pmbus/pmbus_core.c
index 6a3a3fd59b8e..ad3c0cc884a4 100644
--- a/drivers/hwmon/pmbus/pmbus_core.c
+++ b/drivers/hwmon/pmbus/pmbus_core.c
@@ -2782,7 +2782,35 @@ static const struct pmbus_regulator_status_category pmbus_regulator_flag_map[] =
},
};
-static int pmbus_regulator_get_error_flags(struct regulator_dev *rdev, unsigned int *flags)
+#define to_dev_attr(_dev_attr) \
+ container_of(_dev_attr, struct device_attribute, attr)
+
+static void pmbus_notify(struct pmbus_data *data, int page, int reg, int flags)
+{
+ int i;
+
+ for (i = 0; i < data->num_attributes; i++) {
+ struct device_attribute *da = to_dev_attr(data->group.attrs[i]);
+ struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
+ int index = attr->index;
+ u16 smask = pb_index_to_mask(index);
+ u8 spage = pb_index_to_page(index);
+ u16 sreg = pb_index_to_reg(index);
+
+ if (reg == sreg && page == spage && (smask & flags)) {
+ dev_dbg(data->dev, "sysfs notify: %s", da->attr.name);
+ sysfs_notify(&data->dev->kobj, NULL, da->attr.name);
+ kobject_uevent(&data->dev->kobj, KOBJ_CHANGE);
+ flags &= ~smask;
+ }
+
+ if (!flags)
+ break;
+ }
+}
+
+static int pmbus_regulator_get_flags(struct regulator_dev *rdev, unsigned int *error,
+ bool notify)
{
int i, status;
const struct pmbus_regulator_status_category *cat;
@@ -2812,6 +2840,9 @@ static int pmbus_regulator_get_error_flags(struct regulator_dev *rdev, unsigned
if (status & bit->pflag)
*flags |= bit->rflag;
}
+
+ if (notify && status)
+ pmbus_notify(data, page, cat->reg, status);
}
/*
@@ -2856,6 +2887,11 @@ static int pmbus_regulator_get_error_flags(struct regulator_dev *rdev, unsigned
return 0;
}
+static int pmbus_regulator_get_error_flags(struct regulator_dev *rdev, unsigned int *flags)
+{
+ return pmbus_regulator_get_flags(rdev, flags, false);
+}
+
static int pmbus_regulator_get_status(struct regulator_dev *rdev)
{
struct device *dev = rdev_get_dev(rdev);
@@ -3087,7 +3123,7 @@ static irqreturn_t pmbus_fault_handler(int irq, void *pdata)
{
struct pmbus_data *data = pdata;
struct i2c_client *client = to_i2c_client(data->dev);
- int i, status;
+ int i, ret = IRQ_NONE, status;
u8 page;
for (i = 0; i < data->info->num_regulators; i++) {
@@ -3095,6 +3131,10 @@ static irqreturn_t pmbus_fault_handler(int irq, void *pdata)
if (!data->rdevs[i])
continue;
+ ret = pmbus_regulator_get_flags(data->rdevs[i], &status, true);
+ if (ret)
+ return ret;
+
page = rdev_get_id(data->rdevs[i]);
mutex_lock(&data->update_lock);
status = pmbus_read_status_word(client, page);
@@ -3109,7 +3149,7 @@ static irqreturn_t pmbus_fault_handler(int irq, void *pdata)
mutex_unlock(&data->update_lock);
}
- return IRQ_HANDLED;
+ return ret;
}
static int pmbus_irq_setup(struct i2c_client *client, struct pmbus_data *data)
--
2.37.3