Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

hwmon: (scpi) skip unsupported sensors properly

Currently it's assumed that firmware exports only the class of sensors
supported by the driver. However with newer firmware or SCPI protocol
revision, support for newer classes of sensors can be present.

The driver fails to probe with the following warning if an unsupported
class of sensor is encountered in the firmware.

sysfs: cannot create duplicate filename
'/devices/platform/scpi/scpi:sensors/hwmon/hwmon0/'
------------[ cut here ]------------
WARNING: at fs/sysfs/dir.c:31
Modules linked in:

CPU: 0 PID: 6 Comm: kworker/u12:0 Not tainted 4.3.0-rc7 #137
Hardware name: ARM Juno development board (r0) (DT)
Workqueue: deferwq deferred_probe_work_func
PC is at sysfs_warn_dup+0x54/0x78
LR is at sysfs_warn_dup+0x54/0x78

This patch fixes the above issue by skipping through the unsupported
class of SCPI sensors.

Fixes: 68acc77a2d51 ("hwmon: Support thermal zones registration for SCP temperature sensors")
Fixes: ea98b29a05e9 ("hwmon: Support sensors exported via ARM SCP interface")
Cc: Guenter Roeck <linux@roeck-us.net>
Reviewed-by: Punit Agrawal <punit.agrawal@arm.com>
Signed-off-by: Sudeep Holla <sudeep.holla@arm.com>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>

authored by

Sudeep Holla and committed by
Guenter Roeck
cef03d7e d42d5b6f

+11 -10
+11 -10
drivers/hwmon/scpi-hwmon.c
··· 117 117 struct scpi_ops *scpi_ops; 118 118 struct device *hwdev, *dev = &pdev->dev; 119 119 struct scpi_sensors *scpi_sensors; 120 - int ret; 120 + int ret, idx; 121 121 122 122 scpi_ops = get_scpi_ops(); 123 123 if (!scpi_ops) ··· 146 146 147 147 scpi_sensors->scpi_ops = scpi_ops; 148 148 149 - for (i = 0; i < nr_sensors; i++) { 150 - struct sensor_data *sensor = &scpi_sensors->data[i]; 149 + for (i = 0, idx = 0; i < nr_sensors; i++) { 150 + struct sensor_data *sensor = &scpi_sensors->data[idx]; 151 151 152 152 ret = scpi_ops->sensor_get_info(i, &sensor->info); 153 153 if (ret) ··· 183 183 num_power++; 184 184 break; 185 185 default: 186 - break; 186 + continue; 187 187 } 188 188 189 189 sensor->dev_attr_input.attr.mode = S_IRUGO; ··· 194 194 sensor->dev_attr_label.show = scpi_show_label; 195 195 sensor->dev_attr_label.attr.name = sensor->label; 196 196 197 - scpi_sensors->attrs[i << 1] = &sensor->dev_attr_input.attr; 198 - scpi_sensors->attrs[(i << 1) + 1] = &sensor->dev_attr_label.attr; 197 + scpi_sensors->attrs[idx << 1] = &sensor->dev_attr_input.attr; 198 + scpi_sensors->attrs[(idx << 1) + 1] = &sensor->dev_attr_label.attr; 199 199 200 - sysfs_attr_init(scpi_sensors->attrs[i << 1]); 201 - sysfs_attr_init(scpi_sensors->attrs[(i << 1) + 1]); 200 + sysfs_attr_init(scpi_sensors->attrs[idx << 1]); 201 + sysfs_attr_init(scpi_sensors->attrs[(idx << 1) + 1]); 202 + idx++; 202 203 } 203 204 204 205 scpi_sensors->group.attrs = scpi_sensors->attrs; ··· 237 236 238 237 zone->sensor_id = i; 239 238 zone->scpi_sensors = scpi_sensors; 240 - zone->tzd = thermal_zone_of_sensor_register(dev, i, zone, 241 - &scpi_sensor_ops); 239 + zone->tzd = thermal_zone_of_sensor_register(dev, 240 + sensor->info.sensor_id, zone, &scpi_sensor_ops); 242 241 /* 243 242 * The call to thermal_zone_of_sensor_register returns 244 243 * an error for sensors that are not associated with