diff options
Diffstat (limited to 'drivers/hwmon/vexpress.c')
-rw-r--r-- | drivers/hwmon/vexpress.c | 83 |
1 files changed, 71 insertions, 12 deletions
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 | ||