aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/input/misc
diff options
context:
space:
mode:
authorDmitry Torokhov <dmitry.torokhov@gmail.com>2014-12-29 18:13:06 -0500
committerDmitry Torokhov <dmitry.torokhov@gmail.com>2015-01-08 16:55:30 -0500
commitb388de88308fde104fb6520dbf9e7b342fd5761a (patch)
tree584789383e65149142704cc46e372311a3f33bc4 /drivers/input/misc
parent5b6c26a9f6437c4467f5d7cbf0313a7ae2be86b1 (diff)
Input: axp20x-pek - switch over to using attribute group
Instead of registering device attributes individually let's use attribute groups and also devm_* infrastructure to ease cleanup. Tested-by: Chen-Yu Tsai <wens@csie.org> Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
Diffstat (limited to 'drivers/input/misc')
-rw-r--r--drivers/input/misc/axp20x-pek.c64
1 files changed, 36 insertions, 28 deletions
diff --git a/drivers/input/misc/axp20x-pek.c b/drivers/input/misc/axp20x-pek.c
index 8dbd097ac939..f1c844739cd7 100644
--- a/drivers/input/misc/axp20x-pek.c
+++ b/drivers/input/misc/axp20x-pek.c
@@ -138,17 +138,28 @@ static ssize_t axp20x_store_ext_attr(struct device *dev,
138 axp20x_ea->mask, idx); 138 axp20x_ea->mask, idx);
139 if (ret != 0) 139 if (ret != 0)
140 return -EINVAL; 140 return -EINVAL;
141
141 return count; 142 return count;
142} 143}
143 144
144static struct dev_ext_attribute axp20x_dev_attr_startup = { 145static struct dev_ext_attribute axp20x_dev_attr_startup = {
145 .attr = __ATTR(startup, 0644, axp20x_show_ext_attr, axp20x_store_ext_attr), 146 .attr = __ATTR(startup, 0644, axp20x_show_ext_attr, axp20x_store_ext_attr),
146 .var = &axp20x_pek_startup_ext_attr 147 .var = &axp20x_pek_startup_ext_attr,
147}; 148};
148 149
149static struct dev_ext_attribute axp20x_dev_attr_shutdown = { 150static struct dev_ext_attribute axp20x_dev_attr_shutdown = {
150 .attr = __ATTR(shutdown, 0644, axp20x_show_ext_attr, axp20x_store_ext_attr), 151 .attr = __ATTR(shutdown, 0644, axp20x_show_ext_attr, axp20x_store_ext_attr),
151 .var = &axp20x_pek_shutdown_ext_attr 152 .var = &axp20x_pek_shutdown_ext_attr,
153};
154
155static struct attribute *axp20x_attributes[] = {
156 &axp20x_dev_attr_startup.attr.attr,
157 &axp20x_dev_attr_shutdown.attr.attr,
158 NULL,
159};
160
161static const struct attribute_group axp20x_attribute_group = {
162 .attrs = axp20x_attributes,
152}; 163};
153 164
154static irqreturn_t axp20x_pek_irq(int irq, void *pwr) 165static irqreturn_t axp20x_pek_irq(int irq, void *pwr)
@@ -166,6 +177,13 @@ static irqreturn_t axp20x_pek_irq(int irq, void *pwr)
166 return IRQ_HANDLED; 177 return IRQ_HANDLED;
167} 178}
168 179
180static void axp20x_remove_sysfs_group(void *_data)
181{
182 struct device *dev = _data;
183
184 sysfs_remove_group(&dev->kobj, &axp20x_attribute_group);
185}
186
169static int axp20x_pek_probe(struct platform_device *pdev) 187static int axp20x_pek_probe(struct platform_device *pdev)
170{ 188{
171 struct axp20x_pek *axp20x_pek; 189 struct axp20x_pek *axp20x_pek;
@@ -214,12 +232,11 @@ static int axp20x_pek_probe(struct platform_device *pdev)
214 input_set_drvdata(idev, axp20x_pek); 232 input_set_drvdata(idev, axp20x_pek);
215 233
216 error = devm_request_any_context_irq(&pdev->dev, axp20x_pek->irq_dbr, 234 error = devm_request_any_context_irq(&pdev->dev, axp20x_pek->irq_dbr,
217 axp20x_pek_irq, 0, 235 axp20x_pek_irq, 0,
218 "axp20x-pek-dbr", idev); 236 "axp20x-pek-dbr", idev);
219 if (error < 0) { 237 if (error < 0) {
220 dev_err(axp20x->dev, "Failed to request dbr IRQ#%d: %d\n", 238 dev_err(axp20x->dev, "Failed to request dbr IRQ#%d: %d\n",
221 axp20x_pek->irq_dbr, error); 239 axp20x_pek->irq_dbr, error);
222
223 return error; 240 return error;
224 } 241 }
225 242
@@ -232,45 +249,36 @@ static int axp20x_pek_probe(struct platform_device *pdev)
232 return error; 249 return error;
233 } 250 }
234 251
235 error = device_create_file(&pdev->dev, &axp20x_dev_attr_startup.attr); 252 error = sysfs_create_group(&pdev->dev.kobj, &axp20x_attribute_group);
236 if (error) 253 if (error) {
254 dev_err(axp20x->dev, "Failed to create sysfs attributes: %d\n",
255 error);
237 return error; 256 return error;
257 }
238 258
239 error = device_create_file(&pdev->dev, &axp20x_dev_attr_shutdown.attr); 259 error = devm_add_action(&pdev->dev,
240 if (error) 260 axp20x_remove_sysfs_group, &pdev->dev);
241 goto clear_startup_attr; 261 if (error) {
262 axp20x_remove_sysfs_group(&pdev->dev);
263 dev_err(&pdev->dev, "Failed to add sysfs cleanup action: %d\n",
264 error);
265 return error;
266 }
242 267
243 error = input_register_device(idev); 268 error = input_register_device(idev);
244 if (error) { 269 if (error) {
245 dev_err(axp20x->dev, "Can't register input device: %d\n", 270 dev_err(axp20x->dev, "Can't register input device: %d\n",
246 error); 271 error);
247 goto clear_attr; 272 return error;
248 } 273 }
249 274
250 platform_set_drvdata(pdev, axp20x_pek); 275 platform_set_drvdata(pdev, axp20x_pek);
251 276
252 return 0; 277 return 0;
253
254clear_attr:
255 device_remove_file(&pdev->dev, &axp20x_dev_attr_shutdown.attr);
256
257clear_startup_attr:
258 device_remove_file(&pdev->dev, &axp20x_dev_attr_startup.attr);
259
260 return error;
261}
262
263static int axp20x_pek_remove(struct platform_device *pdev)
264{
265 device_remove_file(&pdev->dev, &axp20x_dev_attr_shutdown.attr);
266 device_remove_file(&pdev->dev, &axp20x_dev_attr_startup.attr);
267
268 return 0;
269} 278}
270 279
271static struct platform_driver axp20x_pek_driver = { 280static struct platform_driver axp20x_pek_driver = {
272 .probe = axp20x_pek_probe, 281 .probe = axp20x_pek_probe,
273 .remove = axp20x_pek_remove,
274 .driver = { 282 .driver = {
275 .name = "axp20x-pek", 283 .name = "axp20x-pek",
276 }, 284 },