diff options
| author | Dmitry Torokhov <dmitry.torokhov@gmail.com> | 2014-12-29 18:13:06 -0500 |
|---|---|---|
| committer | Dmitry Torokhov <dmitry.torokhov@gmail.com> | 2015-01-08 16:55:30 -0500 |
| commit | b388de88308fde104fb6520dbf9e7b342fd5761a (patch) | |
| tree | 584789383e65149142704cc46e372311a3f33bc4 /drivers/input/misc | |
| parent | 5b6c26a9f6437c4467f5d7cbf0313a7ae2be86b1 (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.c | 64 |
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 | ||
| 144 | static struct dev_ext_attribute axp20x_dev_attr_startup = { | 145 | static 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 | ||
| 149 | static struct dev_ext_attribute axp20x_dev_attr_shutdown = { | 150 | static 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 | |||
| 155 | static struct attribute *axp20x_attributes[] = { | ||
| 156 | &axp20x_dev_attr_startup.attr.attr, | ||
| 157 | &axp20x_dev_attr_shutdown.attr.attr, | ||
| 158 | NULL, | ||
| 159 | }; | ||
| 160 | |||
| 161 | static const struct attribute_group axp20x_attribute_group = { | ||
| 162 | .attrs = axp20x_attributes, | ||
| 152 | }; | 163 | }; |
| 153 | 164 | ||
| 154 | static irqreturn_t axp20x_pek_irq(int irq, void *pwr) | 165 | static 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 | ||
| 180 | static 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 | |||
| 169 | static int axp20x_pek_probe(struct platform_device *pdev) | 187 | static 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 | |||
| 254 | clear_attr: | ||
| 255 | device_remove_file(&pdev->dev, &axp20x_dev_attr_shutdown.attr); | ||
| 256 | |||
| 257 | clear_startup_attr: | ||
| 258 | device_remove_file(&pdev->dev, &axp20x_dev_attr_startup.attr); | ||
| 259 | |||
| 260 | return error; | ||
| 261 | } | ||
| 262 | |||
| 263 | static 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 | ||
| 271 | static struct platform_driver axp20x_pek_driver = { | 280 | static 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 | }, |
