diff options
Diffstat (limited to 'drivers/hwmon')
-rw-r--r-- | drivers/hwmon/Kconfig | 2 | ||||
-rw-r--r-- | drivers/hwmon/coretemp.c | 4 | ||||
-rw-r--r-- | drivers/hwmon/emc1403.c | 10 | ||||
-rw-r--r-- | drivers/hwmon/ltc2945.c | 6 | ||||
-rw-r--r-- | drivers/hwmon/ntc_thermistor.c | 15 | ||||
-rw-r--r-- | drivers/hwmon/vexpress.c | 83 |
6 files changed, 91 insertions, 29 deletions
diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig index bc196f49ec53..4af0da96c2e2 100644 --- a/drivers/hwmon/Kconfig +++ b/drivers/hwmon/Kconfig | |||
@@ -1053,7 +1053,7 @@ config SENSORS_PC87427 | |||
1053 | 1053 | ||
1054 | config SENSORS_NTC_THERMISTOR | 1054 | config SENSORS_NTC_THERMISTOR |
1055 | tristate "NTC thermistor support" | 1055 | tristate "NTC thermistor support" |
1056 | depends on (!OF && !IIO) || (OF && IIO) | 1056 | depends on !OF || IIO=n || IIO |
1057 | help | 1057 | help |
1058 | This driver supports NTC thermistors sensor reading and its | 1058 | This driver supports NTC thermistors sensor reading and its |
1059 | interpretation. The driver can also monitor the temperature and | 1059 | interpretation. The driver can also monitor the temperature and |
diff --git a/drivers/hwmon/coretemp.c b/drivers/hwmon/coretemp.c index 6d02e3b06375..d76f0b70c6e0 100644 --- a/drivers/hwmon/coretemp.c +++ b/drivers/hwmon/coretemp.c | |||
@@ -365,12 +365,12 @@ static int get_tjmax(struct cpuinfo_x86 *c, u32 id, struct device *dev) | |||
365 | if (cpu_has_tjmax(c)) | 365 | if (cpu_has_tjmax(c)) |
366 | dev_warn(dev, "Unable to read TjMax from CPU %u\n", id); | 366 | dev_warn(dev, "Unable to read TjMax from CPU %u\n", id); |
367 | } else { | 367 | } else { |
368 | val = (eax >> 16) & 0x7f; | 368 | val = (eax >> 16) & 0xff; |
369 | /* | 369 | /* |
370 | * If the TjMax is not plausible, an assumption | 370 | * If the TjMax is not plausible, an assumption |
371 | * will be used | 371 | * will be used |
372 | */ | 372 | */ |
373 | if (val >= 85) { | 373 | if (val) { |
374 | dev_dbg(dev, "TjMax is %d degrees C\n", val); | 374 | dev_dbg(dev, "TjMax is %d degrees C\n", val); |
375 | return val * 1000; | 375 | return val * 1000; |
376 | } | 376 | } |
diff --git a/drivers/hwmon/emc1403.c b/drivers/hwmon/emc1403.c index 90ec1173b8a1..01723f04fe45 100644 --- a/drivers/hwmon/emc1403.c +++ b/drivers/hwmon/emc1403.c | |||
@@ -163,7 +163,7 @@ static ssize_t store_hyst(struct device *dev, | |||
163 | if (retval < 0) | 163 | if (retval < 0) |
164 | goto fail; | 164 | goto fail; |
165 | 165 | ||
166 | hyst = val - retval * 1000; | 166 | hyst = retval * 1000 - val; |
167 | hyst = DIV_ROUND_CLOSEST(hyst, 1000); | 167 | hyst = DIV_ROUND_CLOSEST(hyst, 1000); |
168 | if (hyst < 0 || hyst > 255) { | 168 | if (hyst < 0 || hyst > 255) { |
169 | retval = -ERANGE; | 169 | retval = -ERANGE; |
@@ -330,7 +330,7 @@ static int emc1403_detect(struct i2c_client *client, | |||
330 | } | 330 | } |
331 | 331 | ||
332 | id = i2c_smbus_read_byte_data(client, THERMAL_REVISION_REG); | 332 | id = i2c_smbus_read_byte_data(client, THERMAL_REVISION_REG); |
333 | if (id != 0x01) | 333 | if (id < 0x01 || id > 0x04) |
334 | return -ENODEV; | 334 | return -ENODEV; |
335 | 335 | ||
336 | return 0; | 336 | return 0; |
@@ -355,9 +355,9 @@ static int emc1403_probe(struct i2c_client *client, | |||
355 | if (id->driver_data) | 355 | if (id->driver_data) |
356 | data->groups[1] = &emc1404_group; | 356 | data->groups[1] = &emc1404_group; |
357 | 357 | ||
358 | hwmon_dev = hwmon_device_register_with_groups(&client->dev, | 358 | hwmon_dev = devm_hwmon_device_register_with_groups(&client->dev, |
359 | client->name, data, | 359 | client->name, data, |
360 | data->groups); | 360 | data->groups); |
361 | if (IS_ERR(hwmon_dev)) | 361 | if (IS_ERR(hwmon_dev)) |
362 | return PTR_ERR(hwmon_dev); | 362 | return PTR_ERR(hwmon_dev); |
363 | 363 | ||
diff --git a/drivers/hwmon/ltc2945.c b/drivers/hwmon/ltc2945.c index c104cc32989d..c9cddf5f056b 100644 --- a/drivers/hwmon/ltc2945.c +++ b/drivers/hwmon/ltc2945.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* | 1 | /* |
2 | * Driver for Linear Technology LTC2945 I2C Power Monitor | 2 | * Driver for Linear Technology LTC2945 I2C Power Monitor |
3 | * | 3 | * |
4 | * Copyright (c) 2014 Guenter Roeck | 4 | * Copyright (c) 2014 Guenter Roeck |
@@ -314,8 +314,8 @@ static ssize_t ltc2945_reset_history(struct device *dev, | |||
314 | reg = LTC2945_MAX_ADIN_H; | 314 | reg = LTC2945_MAX_ADIN_H; |
315 | break; | 315 | break; |
316 | default: | 316 | default: |
317 | BUG(); | 317 | WARN_ONCE(1, "Bad register: 0x%x\n", reg); |
318 | break; | 318 | return -EINVAL; |
319 | } | 319 | } |
320 | /* Reset maximum */ | 320 | /* Reset maximum */ |
321 | ret = regmap_bulk_write(regmap, reg, buf_max, num_regs); | 321 | ret = regmap_bulk_write(regmap, reg, buf_max, num_regs); |
diff --git a/drivers/hwmon/ntc_thermistor.c b/drivers/hwmon/ntc_thermistor.c index 8a17f01e8672..e76feb86a1d4 100644 --- a/drivers/hwmon/ntc_thermistor.c +++ b/drivers/hwmon/ntc_thermistor.c | |||
@@ -44,6 +44,7 @@ struct ntc_compensation { | |||
44 | unsigned int ohm; | 44 | unsigned int ohm; |
45 | }; | 45 | }; |
46 | 46 | ||
47 | /* Order matters, ntc_match references the entries by index */ | ||
47 | static const struct platform_device_id ntc_thermistor_id[] = { | 48 | static const struct platform_device_id ntc_thermistor_id[] = { |
48 | { "ncp15wb473", TYPE_NCPXXWB473 }, | 49 | { "ncp15wb473", TYPE_NCPXXWB473 }, |
49 | { "ncp18wb473", TYPE_NCPXXWB473 }, | 50 | { "ncp18wb473", TYPE_NCPXXWB473 }, |
@@ -141,7 +142,7 @@ struct ntc_data { | |||
141 | char name[PLATFORM_NAME_SIZE]; | 142 | char name[PLATFORM_NAME_SIZE]; |
142 | }; | 143 | }; |
143 | 144 | ||
144 | #ifdef CONFIG_OF | 145 | #if defined(CONFIG_OF) && IS_ENABLED(CONFIG_IIO) |
145 | static int ntc_adc_iio_read(struct ntc_thermistor_platform_data *pdata) | 146 | static int ntc_adc_iio_read(struct ntc_thermistor_platform_data *pdata) |
146 | { | 147 | { |
147 | struct iio_channel *channel = pdata->chan; | 148 | struct iio_channel *channel = pdata->chan; |
@@ -163,15 +164,15 @@ static int ntc_adc_iio_read(struct ntc_thermistor_platform_data *pdata) | |||
163 | 164 | ||
164 | static const struct of_device_id ntc_match[] = { | 165 | static const struct of_device_id ntc_match[] = { |
165 | { .compatible = "ntc,ncp15wb473", | 166 | { .compatible = "ntc,ncp15wb473", |
166 | .data = &ntc_thermistor_id[TYPE_NCPXXWB473] }, | 167 | .data = &ntc_thermistor_id[0] }, |
167 | { .compatible = "ntc,ncp18wb473", | 168 | { .compatible = "ntc,ncp18wb473", |
168 | .data = &ntc_thermistor_id[TYPE_NCPXXWB473] }, | 169 | .data = &ntc_thermistor_id[1] }, |
169 | { .compatible = "ntc,ncp21wb473", | 170 | { .compatible = "ntc,ncp21wb473", |
170 | .data = &ntc_thermistor_id[TYPE_NCPXXWB473] }, | 171 | .data = &ntc_thermistor_id[2] }, |
171 | { .compatible = "ntc,ncp03wb473", | 172 | { .compatible = "ntc,ncp03wb473", |
172 | .data = &ntc_thermistor_id[TYPE_NCPXXWB473] }, | 173 | .data = &ntc_thermistor_id[3] }, |
173 | { .compatible = "ntc,ncp15wl333", | 174 | { .compatible = "ntc,ncp15wl333", |
174 | .data = &ntc_thermistor_id[TYPE_NCPXXWL333] }, | 175 | .data = &ntc_thermistor_id[4] }, |
175 | { }, | 176 | { }, |
176 | }; | 177 | }; |
177 | MODULE_DEVICE_TABLE(of, ntc_match); | 178 | MODULE_DEVICE_TABLE(of, ntc_match); |
@@ -223,6 +224,8 @@ ntc_thermistor_parse_dt(struct platform_device *pdev) | |||
223 | return NULL; | 224 | return NULL; |
224 | } | 225 | } |
225 | 226 | ||
227 | #define ntc_match NULL | ||
228 | |||
226 | static void ntc_iio_channel_release(struct ntc_thermistor_platform_data *pdata) | 229 | static void ntc_iio_channel_release(struct ntc_thermistor_platform_data *pdata) |
227 | { } | 230 | { } |
228 | #endif | 231 | #endif |
diff --git a/drivers/hwmon/vexpress.c b/drivers/hwmon/vexpress.c index d867e6bb2be1..8242b75d96c8 100644 --- a/drivers/hwmon/vexpress.c +++ b/drivers/hwmon/vexpress.c | |||
@@ -27,15 +27,15 @@ | |||
27 | struct vexpress_hwmon_data { | 27 | struct vexpress_hwmon_data { |
28 | struct device *hwmon_dev; | 28 | struct device *hwmon_dev; |
29 | struct vexpress_config_func *func; | 29 | struct vexpress_config_func *func; |
30 | const char *name; | ||
30 | }; | 31 | }; |
31 | 32 | ||
32 | static ssize_t vexpress_hwmon_name_show(struct device *dev, | 33 | static ssize_t vexpress_hwmon_name_show(struct device *dev, |
33 | struct device_attribute *dev_attr, char *buffer) | 34 | struct device_attribute *dev_attr, char *buffer) |
34 | { | 35 | { |
35 | const char *compatible = of_get_property(dev->of_node, "compatible", | 36 | struct vexpress_hwmon_data *data = dev_get_drvdata(dev); |
36 | NULL); | ||
37 | 37 | ||
38 | return sprintf(buffer, "%s\n", compatible); | 38 | return sprintf(buffer, "%s\n", data->name); |
39 | } | 39 | } |
40 | 40 | ||
41 | static ssize_t vexpress_hwmon_label_show(struct device *dev, | 41 | static ssize_t vexpress_hwmon_label_show(struct device *dev, |
@@ -43,9 +43,6 @@ static ssize_t vexpress_hwmon_label_show(struct device *dev, | |||
43 | { | 43 | { |
44 | const char *label = of_get_property(dev->of_node, "label", NULL); | 44 | const char *label = of_get_property(dev->of_node, "label", NULL); |
45 | 45 | ||
46 | if (!label) | ||
47 | return -ENOENT; | ||
48 | |||
49 | return snprintf(buffer, PAGE_SIZE, "%s\n", label); | 46 | return snprintf(buffer, PAGE_SIZE, "%s\n", label); |
50 | } | 47 | } |
51 | 48 | ||
@@ -84,6 +81,20 @@ static ssize_t vexpress_hwmon_u64_show(struct device *dev, | |||
84 | to_sensor_dev_attr(dev_attr)->index)); | 81 | to_sensor_dev_attr(dev_attr)->index)); |
85 | } | 82 | } |
86 | 83 | ||
84 | static umode_t vexpress_hwmon_attr_is_visible(struct kobject *kobj, | ||
85 | struct attribute *attr, int index) | ||
86 | { | ||
87 | struct device *dev = kobj_to_dev(kobj); | ||
88 | struct device_attribute *dev_attr = container_of(attr, | ||
89 | struct device_attribute, attr); | ||
90 | |||
91 | if (dev_attr->show == vexpress_hwmon_label_show && | ||
92 | !of_get_property(dev->of_node, "label", NULL)) | ||
93 | return 0; | ||
94 | |||
95 | return attr->mode; | ||
96 | } | ||
97 | |||
87 | static DEVICE_ATTR(name, S_IRUGO, vexpress_hwmon_name_show, NULL); | 98 | static DEVICE_ATTR(name, S_IRUGO, vexpress_hwmon_name_show, NULL); |
88 | 99 | ||
89 | #define VEXPRESS_HWMON_ATTRS(_name, _label_attr, _input_attr) \ | 100 | #define VEXPRESS_HWMON_ATTRS(_name, _label_attr, _input_attr) \ |
@@ -94,14 +105,27 @@ struct attribute *vexpress_hwmon_attrs_##_name[] = { \ | |||
94 | NULL \ | 105 | NULL \ |
95 | } | 106 | } |
96 | 107 | ||
108 | struct vexpress_hwmon_type { | ||
109 | const char *name; | ||
110 | const struct attribute_group **attr_groups; | ||
111 | }; | ||
112 | |||
97 | #if !defined(CONFIG_REGULATOR_VEXPRESS) | 113 | #if !defined(CONFIG_REGULATOR_VEXPRESS) |
98 | static DEVICE_ATTR(in1_label, S_IRUGO, vexpress_hwmon_label_show, NULL); | 114 | static DEVICE_ATTR(in1_label, S_IRUGO, vexpress_hwmon_label_show, NULL); |
99 | static SENSOR_DEVICE_ATTR(in1_input, S_IRUGO, vexpress_hwmon_u32_show, | 115 | static SENSOR_DEVICE_ATTR(in1_input, S_IRUGO, vexpress_hwmon_u32_show, |
100 | NULL, 1000); | 116 | NULL, 1000); |
101 | static VEXPRESS_HWMON_ATTRS(volt, in1_label, in1_input); | 117 | static VEXPRESS_HWMON_ATTRS(volt, in1_label, in1_input); |
102 | static struct attribute_group vexpress_hwmon_group_volt = { | 118 | static struct attribute_group vexpress_hwmon_group_volt = { |
119 | .is_visible = vexpress_hwmon_attr_is_visible, | ||
103 | .attrs = vexpress_hwmon_attrs_volt, | 120 | .attrs = vexpress_hwmon_attrs_volt, |
104 | }; | 121 | }; |
122 | static struct vexpress_hwmon_type vexpress_hwmon_volt = { | ||
123 | .name = "vexpress_volt", | ||
124 | .attr_groups = (const struct attribute_group *[]) { | ||
125 | &vexpress_hwmon_group_volt, | ||
126 | NULL, | ||
127 | }, | ||
128 | }; | ||
105 | #endif | 129 | #endif |
106 | 130 | ||
107 | static DEVICE_ATTR(curr1_label, S_IRUGO, vexpress_hwmon_label_show, NULL); | 131 | static DEVICE_ATTR(curr1_label, S_IRUGO, vexpress_hwmon_label_show, NULL); |
@@ -109,52 +133,84 @@ static SENSOR_DEVICE_ATTR(curr1_input, S_IRUGO, vexpress_hwmon_u32_show, | |||
109 | NULL, 1000); | 133 | NULL, 1000); |
110 | static VEXPRESS_HWMON_ATTRS(amp, curr1_label, curr1_input); | 134 | static VEXPRESS_HWMON_ATTRS(amp, curr1_label, curr1_input); |
111 | static struct attribute_group vexpress_hwmon_group_amp = { | 135 | static struct attribute_group vexpress_hwmon_group_amp = { |
136 | .is_visible = vexpress_hwmon_attr_is_visible, | ||
112 | .attrs = vexpress_hwmon_attrs_amp, | 137 | .attrs = vexpress_hwmon_attrs_amp, |
113 | }; | 138 | }; |
139 | static struct vexpress_hwmon_type vexpress_hwmon_amp = { | ||
140 | .name = "vexpress_amp", | ||
141 | .attr_groups = (const struct attribute_group *[]) { | ||
142 | &vexpress_hwmon_group_amp, | ||
143 | NULL | ||
144 | }, | ||
145 | }; | ||
114 | 146 | ||
115 | static DEVICE_ATTR(temp1_label, S_IRUGO, vexpress_hwmon_label_show, NULL); | 147 | static DEVICE_ATTR(temp1_label, S_IRUGO, vexpress_hwmon_label_show, NULL); |
116 | static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, vexpress_hwmon_u32_show, | 148 | static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, vexpress_hwmon_u32_show, |
117 | NULL, 1000); | 149 | NULL, 1000); |
118 | static VEXPRESS_HWMON_ATTRS(temp, temp1_label, temp1_input); | 150 | static VEXPRESS_HWMON_ATTRS(temp, temp1_label, temp1_input); |
119 | static struct attribute_group vexpress_hwmon_group_temp = { | 151 | static struct attribute_group vexpress_hwmon_group_temp = { |
152 | .is_visible = vexpress_hwmon_attr_is_visible, | ||
120 | .attrs = vexpress_hwmon_attrs_temp, | 153 | .attrs = vexpress_hwmon_attrs_temp, |
121 | }; | 154 | }; |
155 | static struct vexpress_hwmon_type vexpress_hwmon_temp = { | ||
156 | .name = "vexpress_temp", | ||
157 | .attr_groups = (const struct attribute_group *[]) { | ||
158 | &vexpress_hwmon_group_temp, | ||
159 | NULL | ||
160 | }, | ||
161 | }; | ||
122 | 162 | ||
123 | static DEVICE_ATTR(power1_label, S_IRUGO, vexpress_hwmon_label_show, NULL); | 163 | static DEVICE_ATTR(power1_label, S_IRUGO, vexpress_hwmon_label_show, NULL); |
124 | static SENSOR_DEVICE_ATTR(power1_input, S_IRUGO, vexpress_hwmon_u32_show, | 164 | static SENSOR_DEVICE_ATTR(power1_input, S_IRUGO, vexpress_hwmon_u32_show, |
125 | NULL, 1); | 165 | NULL, 1); |
126 | static VEXPRESS_HWMON_ATTRS(power, power1_label, power1_input); | 166 | static VEXPRESS_HWMON_ATTRS(power, power1_label, power1_input); |
127 | static struct attribute_group vexpress_hwmon_group_power = { | 167 | static struct attribute_group vexpress_hwmon_group_power = { |
168 | .is_visible = vexpress_hwmon_attr_is_visible, | ||
128 | .attrs = vexpress_hwmon_attrs_power, | 169 | .attrs = vexpress_hwmon_attrs_power, |
129 | }; | 170 | }; |
171 | static struct vexpress_hwmon_type vexpress_hwmon_power = { | ||
172 | .name = "vexpress_power", | ||
173 | .attr_groups = (const struct attribute_group *[]) { | ||
174 | &vexpress_hwmon_group_power, | ||
175 | NULL | ||
176 | }, | ||
177 | }; | ||
130 | 178 | ||
131 | static DEVICE_ATTR(energy1_label, S_IRUGO, vexpress_hwmon_label_show, NULL); | 179 | static DEVICE_ATTR(energy1_label, S_IRUGO, vexpress_hwmon_label_show, NULL); |
132 | static SENSOR_DEVICE_ATTR(energy1_input, S_IRUGO, vexpress_hwmon_u64_show, | 180 | static SENSOR_DEVICE_ATTR(energy1_input, S_IRUGO, vexpress_hwmon_u64_show, |
133 | NULL, 1); | 181 | NULL, 1); |
134 | static VEXPRESS_HWMON_ATTRS(energy, energy1_label, energy1_input); | 182 | static VEXPRESS_HWMON_ATTRS(energy, energy1_label, energy1_input); |
135 | static struct attribute_group vexpress_hwmon_group_energy = { | 183 | static struct attribute_group vexpress_hwmon_group_energy = { |
184 | .is_visible = vexpress_hwmon_attr_is_visible, | ||
136 | .attrs = vexpress_hwmon_attrs_energy, | 185 | .attrs = vexpress_hwmon_attrs_energy, |
137 | }; | 186 | }; |
187 | static struct vexpress_hwmon_type vexpress_hwmon_energy = { | ||
188 | .name = "vexpress_energy", | ||
189 | .attr_groups = (const struct attribute_group *[]) { | ||
190 | &vexpress_hwmon_group_energy, | ||
191 | NULL | ||
192 | }, | ||
193 | }; | ||
138 | 194 | ||
139 | static struct of_device_id vexpress_hwmon_of_match[] = { | 195 | static struct of_device_id vexpress_hwmon_of_match[] = { |
140 | #if !defined(CONFIG_REGULATOR_VEXPRESS) | 196 | #if !defined(CONFIG_REGULATOR_VEXPRESS) |
141 | { | 197 | { |
142 | .compatible = "arm,vexpress-volt", | 198 | .compatible = "arm,vexpress-volt", |
143 | .data = &vexpress_hwmon_group_volt, | 199 | .data = &vexpress_hwmon_volt, |
144 | }, | 200 | }, |
145 | #endif | 201 | #endif |
146 | { | 202 | { |
147 | .compatible = "arm,vexpress-amp", | 203 | .compatible = "arm,vexpress-amp", |
148 | .data = &vexpress_hwmon_group_amp, | 204 | .data = &vexpress_hwmon_amp, |
149 | }, { | 205 | }, { |
150 | .compatible = "arm,vexpress-temp", | 206 | .compatible = "arm,vexpress-temp", |
151 | .data = &vexpress_hwmon_group_temp, | 207 | .data = &vexpress_hwmon_temp, |
152 | }, { | 208 | }, { |
153 | .compatible = "arm,vexpress-power", | 209 | .compatible = "arm,vexpress-power", |
154 | .data = &vexpress_hwmon_group_power, | 210 | .data = &vexpress_hwmon_power, |
155 | }, { | 211 | }, { |
156 | .compatible = "arm,vexpress-energy", | 212 | .compatible = "arm,vexpress-energy", |
157 | .data = &vexpress_hwmon_group_energy, | 213 | .data = &vexpress_hwmon_energy, |
158 | }, | 214 | }, |
159 | {} | 215 | {} |
160 | }; | 216 | }; |
@@ -165,6 +221,7 @@ static int vexpress_hwmon_probe(struct platform_device *pdev) | |||
165 | int err; | 221 | int err; |
166 | const struct of_device_id *match; | 222 | const struct of_device_id *match; |
167 | struct vexpress_hwmon_data *data; | 223 | struct vexpress_hwmon_data *data; |
224 | const struct vexpress_hwmon_type *type; | ||
168 | 225 | ||
169 | data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL); | 226 | data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL); |
170 | if (!data) | 227 | if (!data) |
@@ -174,12 +231,14 @@ static int vexpress_hwmon_probe(struct platform_device *pdev) | |||
174 | match = of_match_device(vexpress_hwmon_of_match, &pdev->dev); | 231 | match = of_match_device(vexpress_hwmon_of_match, &pdev->dev); |
175 | if (!match) | 232 | if (!match) |
176 | return -ENODEV; | 233 | return -ENODEV; |
234 | type = match->data; | ||
235 | data->name = type->name; | ||
177 | 236 | ||
178 | data->func = vexpress_config_func_get_by_dev(&pdev->dev); | 237 | data->func = vexpress_config_func_get_by_dev(&pdev->dev); |
179 | if (!data->func) | 238 | if (!data->func) |
180 | return -ENODEV; | 239 | return -ENODEV; |
181 | 240 | ||
182 | err = sysfs_create_group(&pdev->dev.kobj, match->data); | 241 | err = sysfs_create_groups(&pdev->dev.kobj, type->attr_groups); |
183 | if (err) | 242 | if (err) |
184 | goto error; | 243 | goto error; |
185 | 244 | ||