Merge tag 'hwmon-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/groeck/linux-staging

Pull hwmon fixes from Guenter Roeck:
- ltc2945: Don't unecessarily crash kernel on implementation error
- vexpress: Fix 'name' and 'label' attributes

* tag 'hwmon-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/groeck/linux-staging:
hwmon: (ltc2945) Don't crash the kernel unnecessarily
hwmon: (vexpress) Avoid creating non-existing attributes
hwmon: (vexpress) Use legal hwmon device names

Changed files
+74 -15
drivers
+3 -3
drivers/hwmon/ltc2945.c
··· 1 - /* 1 + /* 2 2 * Driver for Linear Technology LTC2945 I2C Power Monitor 3 3 * 4 4 * Copyright (c) 2014 Guenter Roeck ··· 314 314 reg = LTC2945_MAX_ADIN_H; 315 315 break; 316 316 default: 317 - BUG(); 318 - break; 317 + WARN_ONCE(1, "Bad register: 0x%x\n", reg); 318 + return -EINVAL; 319 319 } 320 320 /* Reset maximum */ 321 321 ret = regmap_bulk_write(regmap, reg, buf_max, num_regs);
+71 -12
drivers/hwmon/vexpress.c
··· 27 27 struct vexpress_hwmon_data { 28 28 struct device *hwmon_dev; 29 29 struct vexpress_config_func *func; 30 + const char *name; 30 31 }; 31 32 32 33 static ssize_t vexpress_hwmon_name_show(struct device *dev, 33 34 struct device_attribute *dev_attr, char *buffer) 34 35 { 35 - const char *compatible = of_get_property(dev->of_node, "compatible", 36 - NULL); 36 + struct vexpress_hwmon_data *data = dev_get_drvdata(dev); 37 37 38 - return sprintf(buffer, "%s\n", compatible); 38 + return sprintf(buffer, "%s\n", data->name); 39 39 } 40 40 41 41 static ssize_t vexpress_hwmon_label_show(struct device *dev, 42 42 struct device_attribute *dev_attr, char *buffer) 43 43 { 44 44 const char *label = of_get_property(dev->of_node, "label", NULL); 45 - 46 - if (!label) 47 - return -ENOENT; 48 45 49 46 return snprintf(buffer, PAGE_SIZE, "%s\n", label); 50 47 } ··· 81 84 to_sensor_dev_attr(dev_attr)->index)); 82 85 } 83 86 87 + static umode_t vexpress_hwmon_attr_is_visible(struct kobject *kobj, 88 + struct attribute *attr, int index) 89 + { 90 + struct device *dev = kobj_to_dev(kobj); 91 + struct device_attribute *dev_attr = container_of(attr, 92 + struct device_attribute, attr); 93 + 94 + if (dev_attr->show == vexpress_hwmon_label_show && 95 + !of_get_property(dev->of_node, "label", NULL)) 96 + return 0; 97 + 98 + return attr->mode; 99 + } 100 + 84 101 static DEVICE_ATTR(name, S_IRUGO, vexpress_hwmon_name_show, NULL); 85 102 86 103 #define VEXPRESS_HWMON_ATTRS(_name, _label_attr, _input_attr) \ ··· 105 94 NULL \ 106 95 } 107 96 97 + struct vexpress_hwmon_type { 98 + const char *name; 99 + const struct attribute_group **attr_groups; 100 + }; 101 + 108 102 #if !defined(CONFIG_REGULATOR_VEXPRESS) 109 103 static DEVICE_ATTR(in1_label, S_IRUGO, vexpress_hwmon_label_show, NULL); 110 104 static SENSOR_DEVICE_ATTR(in1_input, S_IRUGO, vexpress_hwmon_u32_show, 111 105 NULL, 1000); 112 106 static VEXPRESS_HWMON_ATTRS(volt, in1_label, in1_input); 113 107 static struct attribute_group vexpress_hwmon_group_volt = { 108 + .is_visible = vexpress_hwmon_attr_is_visible, 114 109 .attrs = vexpress_hwmon_attrs_volt, 110 + }; 111 + static struct vexpress_hwmon_type vexpress_hwmon_volt = { 112 + .name = "vexpress_volt", 113 + .attr_groups = (const struct attribute_group *[]) { 114 + &vexpress_hwmon_group_volt, 115 + NULL, 116 + }, 115 117 }; 116 118 #endif 117 119 ··· 133 109 NULL, 1000); 134 110 static VEXPRESS_HWMON_ATTRS(amp, curr1_label, curr1_input); 135 111 static struct attribute_group vexpress_hwmon_group_amp = { 112 + .is_visible = vexpress_hwmon_attr_is_visible, 136 113 .attrs = vexpress_hwmon_attrs_amp, 114 + }; 115 + static struct vexpress_hwmon_type vexpress_hwmon_amp = { 116 + .name = "vexpress_amp", 117 + .attr_groups = (const struct attribute_group *[]) { 118 + &vexpress_hwmon_group_amp, 119 + NULL 120 + }, 137 121 }; 138 122 139 123 static DEVICE_ATTR(temp1_label, S_IRUGO, vexpress_hwmon_label_show, NULL); ··· 149 117 NULL, 1000); 150 118 static VEXPRESS_HWMON_ATTRS(temp, temp1_label, temp1_input); 151 119 static struct attribute_group vexpress_hwmon_group_temp = { 120 + .is_visible = vexpress_hwmon_attr_is_visible, 152 121 .attrs = vexpress_hwmon_attrs_temp, 122 + }; 123 + static struct vexpress_hwmon_type vexpress_hwmon_temp = { 124 + .name = "vexpress_temp", 125 + .attr_groups = (const struct attribute_group *[]) { 126 + &vexpress_hwmon_group_temp, 127 + NULL 128 + }, 153 129 }; 154 130 155 131 static DEVICE_ATTR(power1_label, S_IRUGO, vexpress_hwmon_label_show, NULL); ··· 165 125 NULL, 1); 166 126 static VEXPRESS_HWMON_ATTRS(power, power1_label, power1_input); 167 127 static struct attribute_group vexpress_hwmon_group_power = { 128 + .is_visible = vexpress_hwmon_attr_is_visible, 168 129 .attrs = vexpress_hwmon_attrs_power, 130 + }; 131 + static struct vexpress_hwmon_type vexpress_hwmon_power = { 132 + .name = "vexpress_power", 133 + .attr_groups = (const struct attribute_group *[]) { 134 + &vexpress_hwmon_group_power, 135 + NULL 136 + }, 169 137 }; 170 138 171 139 static DEVICE_ATTR(energy1_label, S_IRUGO, vexpress_hwmon_label_show, NULL); ··· 181 133 NULL, 1); 182 134 static VEXPRESS_HWMON_ATTRS(energy, energy1_label, energy1_input); 183 135 static struct attribute_group vexpress_hwmon_group_energy = { 136 + .is_visible = vexpress_hwmon_attr_is_visible, 184 137 .attrs = vexpress_hwmon_attrs_energy, 138 + }; 139 + static struct vexpress_hwmon_type vexpress_hwmon_energy = { 140 + .name = "vexpress_energy", 141 + .attr_groups = (const struct attribute_group *[]) { 142 + &vexpress_hwmon_group_energy, 143 + NULL 144 + }, 185 145 }; 186 146 187 147 static struct of_device_id vexpress_hwmon_of_match[] = { 188 148 #if !defined(CONFIG_REGULATOR_VEXPRESS) 189 149 { 190 150 .compatible = "arm,vexpress-volt", 191 - .data = &vexpress_hwmon_group_volt, 151 + .data = &vexpress_hwmon_volt, 192 152 }, 193 153 #endif 194 154 { 195 155 .compatible = "arm,vexpress-amp", 196 - .data = &vexpress_hwmon_group_amp, 156 + .data = &vexpress_hwmon_amp, 197 157 }, { 198 158 .compatible = "arm,vexpress-temp", 199 - .data = &vexpress_hwmon_group_temp, 159 + .data = &vexpress_hwmon_temp, 200 160 }, { 201 161 .compatible = "arm,vexpress-power", 202 - .data = &vexpress_hwmon_group_power, 162 + .data = &vexpress_hwmon_power, 203 163 }, { 204 164 .compatible = "arm,vexpress-energy", 205 - .data = &vexpress_hwmon_group_energy, 165 + .data = &vexpress_hwmon_energy, 206 166 }, 207 167 {} 208 168 }; ··· 221 165 int err; 222 166 const struct of_device_id *match; 223 167 struct vexpress_hwmon_data *data; 168 + const struct vexpress_hwmon_type *type; 224 169 225 170 data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL); 226 171 if (!data) ··· 231 174 match = of_match_device(vexpress_hwmon_of_match, &pdev->dev); 232 175 if (!match) 233 176 return -ENODEV; 177 + type = match->data; 178 + data->name = type->name; 234 179 235 180 data->func = vexpress_config_func_get_by_dev(&pdev->dev); 236 181 if (!data->func) 237 182 return -ENODEV; 238 183 239 - err = sysfs_create_group(&pdev->dev.kobj, match->data); 184 + err = sysfs_create_groups(&pdev->dev.kobj, type->attr_groups); 240 185 if (err) 241 186 goto error; 242 187