diff options
author | Sudeep Holla <sudeep.holla@arm.com> | 2016-01-29 12:35:52 -0500 |
---|---|---|
committer | Guenter Roeck <linux@roeck-us.net> | 2016-03-05 09:25:33 -0500 |
commit | c32f5eff2db51f0126b0a4e42bdefea2d9d2872e (patch) | |
tree | 661fb32258a1372fb34bc4f8b5483d2e9f100e22 /drivers/hwmon/vexpress-hwmon.c | |
parent | fc77dbd34c5c99bce46d40a2491937c3bcbd10af (diff) |
hwmon: (vexpress) rename vexpress hwmon implementation
The vexpress hwmon implementation is currently just called vexpress.
This is a problem because it clashes with another module with the same
name in regulators.
This patch renames the vexpress hwmon implementation to vexpress-hwmon
so that there will be no clash in the module namespace.
Cc: Liviu Dudau <liviu.dudau@arm.com>
Cc: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
Cc: Jean Delvare <jdelvare@suse.com>
Cc: Guenter Roeck <linux@roeck-us.net>
Cc: lm-sensors@lm-sensors.org
Reported-by: Rusty Russell <rusty@rustcorp.com.au>
Signed-off-by: Sudeep Holla <sudeep.holla@arm.com>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
Diffstat (limited to 'drivers/hwmon/vexpress-hwmon.c')
-rw-r--r-- | drivers/hwmon/vexpress-hwmon.c | 259 |
1 files changed, 259 insertions, 0 deletions
diff --git a/drivers/hwmon/vexpress-hwmon.c b/drivers/hwmon/vexpress-hwmon.c new file mode 100644 index 000000000000..8ba419d343f8 --- /dev/null +++ b/drivers/hwmon/vexpress-hwmon.c | |||
@@ -0,0 +1,259 @@ | |||
1 | /* | ||
2 | * This program is free software; you can redistribute it and/or modify | ||
3 | * it under the terms of the GNU General Public License version 2 as | ||
4 | * published by the Free Software Foundation. | ||
5 | * | ||
6 | * This program is distributed in the hope that it will be useful, | ||
7 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
8 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
9 | * GNU General Public License for more details. | ||
10 | * | ||
11 | * Copyright (C) 2012 ARM Limited | ||
12 | */ | ||
13 | |||
14 | #define DRVNAME "vexpress-hwmon" | ||
15 | #define pr_fmt(fmt) DRVNAME ": " fmt | ||
16 | |||
17 | #include <linux/device.h> | ||
18 | #include <linux/err.h> | ||
19 | #include <linux/hwmon.h> | ||
20 | #include <linux/hwmon-sysfs.h> | ||
21 | #include <linux/module.h> | ||
22 | #include <linux/of.h> | ||
23 | #include <linux/of_device.h> | ||
24 | #include <linux/platform_device.h> | ||
25 | #include <linux/vexpress.h> | ||
26 | |||
27 | struct vexpress_hwmon_data { | ||
28 | struct device *hwmon_dev; | ||
29 | struct regmap *reg; | ||
30 | }; | ||
31 | |||
32 | static ssize_t vexpress_hwmon_label_show(struct device *dev, | ||
33 | struct device_attribute *dev_attr, char *buffer) | ||
34 | { | ||
35 | const char *label = of_get_property(dev->of_node, "label", NULL); | ||
36 | |||
37 | return snprintf(buffer, PAGE_SIZE, "%s\n", label); | ||
38 | } | ||
39 | |||
40 | static ssize_t vexpress_hwmon_u32_show(struct device *dev, | ||
41 | struct device_attribute *dev_attr, char *buffer) | ||
42 | { | ||
43 | struct vexpress_hwmon_data *data = dev_get_drvdata(dev); | ||
44 | int err; | ||
45 | u32 value; | ||
46 | |||
47 | err = regmap_read(data->reg, 0, &value); | ||
48 | if (err) | ||
49 | return err; | ||
50 | |||
51 | return snprintf(buffer, PAGE_SIZE, "%u\n", value / | ||
52 | to_sensor_dev_attr(dev_attr)->index); | ||
53 | } | ||
54 | |||
55 | static ssize_t vexpress_hwmon_u64_show(struct device *dev, | ||
56 | struct device_attribute *dev_attr, char *buffer) | ||
57 | { | ||
58 | struct vexpress_hwmon_data *data = dev_get_drvdata(dev); | ||
59 | int err; | ||
60 | u32 value_hi, value_lo; | ||
61 | |||
62 | err = regmap_read(data->reg, 0, &value_lo); | ||
63 | if (err) | ||
64 | return err; | ||
65 | |||
66 | err = regmap_read(data->reg, 1, &value_hi); | ||
67 | if (err) | ||
68 | return err; | ||
69 | |||
70 | return snprintf(buffer, PAGE_SIZE, "%llu\n", | ||
71 | div_u64(((u64)value_hi << 32) | value_lo, | ||
72 | to_sensor_dev_attr(dev_attr)->index)); | ||
73 | } | ||
74 | |||
75 | static umode_t vexpress_hwmon_attr_is_visible(struct kobject *kobj, | ||
76 | struct attribute *attr, int index) | ||
77 | { | ||
78 | struct device *dev = kobj_to_dev(kobj); | ||
79 | struct device_attribute *dev_attr = container_of(attr, | ||
80 | struct device_attribute, attr); | ||
81 | |||
82 | if (dev_attr->show == vexpress_hwmon_label_show && | ||
83 | !of_get_property(dev->of_node, "label", NULL)) | ||
84 | return 0; | ||
85 | |||
86 | return attr->mode; | ||
87 | } | ||
88 | |||
89 | struct vexpress_hwmon_type { | ||
90 | const char *name; | ||
91 | const struct attribute_group **attr_groups; | ||
92 | }; | ||
93 | |||
94 | #if !defined(CONFIG_REGULATOR_VEXPRESS) | ||
95 | static DEVICE_ATTR(in1_label, S_IRUGO, vexpress_hwmon_label_show, NULL); | ||
96 | static SENSOR_DEVICE_ATTR(in1_input, S_IRUGO, vexpress_hwmon_u32_show, | ||
97 | NULL, 1000); | ||
98 | static struct attribute *vexpress_hwmon_attrs_volt[] = { | ||
99 | &dev_attr_in1_label.attr, | ||
100 | &sensor_dev_attr_in1_input.dev_attr.attr, | ||
101 | NULL | ||
102 | }; | ||
103 | static struct attribute_group vexpress_hwmon_group_volt = { | ||
104 | .is_visible = vexpress_hwmon_attr_is_visible, | ||
105 | .attrs = vexpress_hwmon_attrs_volt, | ||
106 | }; | ||
107 | static struct vexpress_hwmon_type vexpress_hwmon_volt = { | ||
108 | .name = "vexpress_volt", | ||
109 | .attr_groups = (const struct attribute_group *[]) { | ||
110 | &vexpress_hwmon_group_volt, | ||
111 | NULL, | ||
112 | }, | ||
113 | }; | ||
114 | #endif | ||
115 | |||
116 | static DEVICE_ATTR(curr1_label, S_IRUGO, vexpress_hwmon_label_show, NULL); | ||
117 | static SENSOR_DEVICE_ATTR(curr1_input, S_IRUGO, vexpress_hwmon_u32_show, | ||
118 | NULL, 1000); | ||
119 | static struct attribute *vexpress_hwmon_attrs_amp[] = { | ||
120 | &dev_attr_curr1_label.attr, | ||
121 | &sensor_dev_attr_curr1_input.dev_attr.attr, | ||
122 | NULL | ||
123 | }; | ||
124 | static struct attribute_group vexpress_hwmon_group_amp = { | ||
125 | .is_visible = vexpress_hwmon_attr_is_visible, | ||
126 | .attrs = vexpress_hwmon_attrs_amp, | ||
127 | }; | ||
128 | static struct vexpress_hwmon_type vexpress_hwmon_amp = { | ||
129 | .name = "vexpress_amp", | ||
130 | .attr_groups = (const struct attribute_group *[]) { | ||
131 | &vexpress_hwmon_group_amp, | ||
132 | NULL | ||
133 | }, | ||
134 | }; | ||
135 | |||
136 | static DEVICE_ATTR(temp1_label, S_IRUGO, vexpress_hwmon_label_show, NULL); | ||
137 | static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, vexpress_hwmon_u32_show, | ||
138 | NULL, 1000); | ||
139 | static struct attribute *vexpress_hwmon_attrs_temp[] = { | ||
140 | &dev_attr_temp1_label.attr, | ||
141 | &sensor_dev_attr_temp1_input.dev_attr.attr, | ||
142 | NULL | ||
143 | }; | ||
144 | static struct attribute_group vexpress_hwmon_group_temp = { | ||
145 | .is_visible = vexpress_hwmon_attr_is_visible, | ||
146 | .attrs = vexpress_hwmon_attrs_temp, | ||
147 | }; | ||
148 | static struct vexpress_hwmon_type vexpress_hwmon_temp = { | ||
149 | .name = "vexpress_temp", | ||
150 | .attr_groups = (const struct attribute_group *[]) { | ||
151 | &vexpress_hwmon_group_temp, | ||
152 | NULL | ||
153 | }, | ||
154 | }; | ||
155 | |||
156 | static DEVICE_ATTR(power1_label, S_IRUGO, vexpress_hwmon_label_show, NULL); | ||
157 | static SENSOR_DEVICE_ATTR(power1_input, S_IRUGO, vexpress_hwmon_u32_show, | ||
158 | NULL, 1); | ||
159 | static struct attribute *vexpress_hwmon_attrs_power[] = { | ||
160 | &dev_attr_power1_label.attr, | ||
161 | &sensor_dev_attr_power1_input.dev_attr.attr, | ||
162 | NULL | ||
163 | }; | ||
164 | static struct attribute_group vexpress_hwmon_group_power = { | ||
165 | .is_visible = vexpress_hwmon_attr_is_visible, | ||
166 | .attrs = vexpress_hwmon_attrs_power, | ||
167 | }; | ||
168 | static struct vexpress_hwmon_type vexpress_hwmon_power = { | ||
169 | .name = "vexpress_power", | ||
170 | .attr_groups = (const struct attribute_group *[]) { | ||
171 | &vexpress_hwmon_group_power, | ||
172 | NULL | ||
173 | }, | ||
174 | }; | ||
175 | |||
176 | static DEVICE_ATTR(energy1_label, S_IRUGO, vexpress_hwmon_label_show, NULL); | ||
177 | static SENSOR_DEVICE_ATTR(energy1_input, S_IRUGO, vexpress_hwmon_u64_show, | ||
178 | NULL, 1); | ||
179 | static struct attribute *vexpress_hwmon_attrs_energy[] = { | ||
180 | &dev_attr_energy1_label.attr, | ||
181 | &sensor_dev_attr_energy1_input.dev_attr.attr, | ||
182 | NULL | ||
183 | }; | ||
184 | static struct attribute_group vexpress_hwmon_group_energy = { | ||
185 | .is_visible = vexpress_hwmon_attr_is_visible, | ||
186 | .attrs = vexpress_hwmon_attrs_energy, | ||
187 | }; | ||
188 | static struct vexpress_hwmon_type vexpress_hwmon_energy = { | ||
189 | .name = "vexpress_energy", | ||
190 | .attr_groups = (const struct attribute_group *[]) { | ||
191 | &vexpress_hwmon_group_energy, | ||
192 | NULL | ||
193 | }, | ||
194 | }; | ||
195 | |||
196 | static const struct of_device_id vexpress_hwmon_of_match[] = { | ||
197 | #if !defined(CONFIG_REGULATOR_VEXPRESS) | ||
198 | { | ||
199 | .compatible = "arm,vexpress-volt", | ||
200 | .data = &vexpress_hwmon_volt, | ||
201 | }, | ||
202 | #endif | ||
203 | { | ||
204 | .compatible = "arm,vexpress-amp", | ||
205 | .data = &vexpress_hwmon_amp, | ||
206 | }, { | ||
207 | .compatible = "arm,vexpress-temp", | ||
208 | .data = &vexpress_hwmon_temp, | ||
209 | }, { | ||
210 | .compatible = "arm,vexpress-power", | ||
211 | .data = &vexpress_hwmon_power, | ||
212 | }, { | ||
213 | .compatible = "arm,vexpress-energy", | ||
214 | .data = &vexpress_hwmon_energy, | ||
215 | }, | ||
216 | {} | ||
217 | }; | ||
218 | MODULE_DEVICE_TABLE(of, vexpress_hwmon_of_match); | ||
219 | |||
220 | static int vexpress_hwmon_probe(struct platform_device *pdev) | ||
221 | { | ||
222 | const struct of_device_id *match; | ||
223 | struct vexpress_hwmon_data *data; | ||
224 | const struct vexpress_hwmon_type *type; | ||
225 | |||
226 | data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL); | ||
227 | if (!data) | ||
228 | return -ENOMEM; | ||
229 | platform_set_drvdata(pdev, data); | ||
230 | |||
231 | match = of_match_device(vexpress_hwmon_of_match, &pdev->dev); | ||
232 | if (!match) | ||
233 | return -ENODEV; | ||
234 | type = match->data; | ||
235 | |||
236 | data->reg = devm_regmap_init_vexpress_config(&pdev->dev); | ||
237 | if (IS_ERR(data->reg)) | ||
238 | return PTR_ERR(data->reg); | ||
239 | |||
240 | data->hwmon_dev = devm_hwmon_device_register_with_groups(&pdev->dev, | ||
241 | type->name, data, type->attr_groups); | ||
242 | |||
243 | return PTR_ERR_OR_ZERO(data->hwmon_dev); | ||
244 | } | ||
245 | |||
246 | static struct platform_driver vexpress_hwmon_driver = { | ||
247 | .probe = vexpress_hwmon_probe, | ||
248 | .driver = { | ||
249 | .name = DRVNAME, | ||
250 | .of_match_table = vexpress_hwmon_of_match, | ||
251 | }, | ||
252 | }; | ||
253 | |||
254 | module_platform_driver(vexpress_hwmon_driver); | ||
255 | |||
256 | MODULE_AUTHOR("Pawel Moll <pawel.moll@arm.com>"); | ||
257 | MODULE_DESCRIPTION("Versatile Express hwmon sensors driver"); | ||
258 | MODULE_LICENSE("GPL"); | ||
259 | MODULE_ALIAS("platform:vexpress-hwmon"); | ||