diff options
Diffstat (limited to 'drivers/input')
| -rw-r--r-- | drivers/input/input.c | 64 |
1 files changed, 63 insertions, 1 deletions
diff --git a/drivers/input/input.c b/drivers/input/input.c index 7c237e6ac711..b8ed4294fccd 100644 --- a/drivers/input/input.c +++ b/drivers/input/input.c | |||
| @@ -11,6 +11,7 @@ | |||
| 11 | */ | 11 | */ |
| 12 | 12 | ||
| 13 | #include <linux/init.h> | 13 | #include <linux/init.h> |
| 14 | #include <linux/types.h> | ||
| 14 | #include <linux/input.h> | 15 | #include <linux/input.h> |
| 15 | #include <linux/module.h> | 16 | #include <linux/module.h> |
| 16 | #include <linux/random.h> | 17 | #include <linux/random.h> |
| @@ -514,7 +515,7 @@ static void input_disconnect_device(struct input_dev *dev) | |||
| 514 | * that there are no threads in the middle of input_open_device() | 515 | * that there are no threads in the middle of input_open_device() |
| 515 | */ | 516 | */ |
| 516 | mutex_lock(&dev->mutex); | 517 | mutex_lock(&dev->mutex); |
| 517 | dev->going_away = 1; | 518 | dev->going_away = true; |
| 518 | mutex_unlock(&dev->mutex); | 519 | mutex_unlock(&dev->mutex); |
| 519 | 520 | ||
| 520 | spin_lock_irq(&dev->event_lock); | 521 | spin_lock_irq(&dev->event_lock); |
| @@ -1259,10 +1260,71 @@ static int input_dev_uevent(struct device *device, struct kobj_uevent_env *env) | |||
| 1259 | return 0; | 1260 | return 0; |
| 1260 | } | 1261 | } |
| 1261 | 1262 | ||
| 1263 | #define INPUT_DO_TOGGLE(dev, type, bits, on) \ | ||
| 1264 | do { \ | ||
| 1265 | int i; \ | ||
| 1266 | if (!test_bit(EV_##type, dev->evbit)) \ | ||
| 1267 | break; \ | ||
| 1268 | for (i = 0; i < type##_MAX; i++) { \ | ||
| 1269 | if (!test_bit(i, dev->bits##bit) || \ | ||
| 1270 | !test_bit(i, dev->bits)) \ | ||
| 1271 | continue; \ | ||
| 1272 | dev->event(dev, EV_##type, i, on); \ | ||
| 1273 | } \ | ||
| 1274 | } while (0) | ||
| 1275 | |||
| 1276 | static void input_dev_reset(struct input_dev *dev, bool activate) | ||
| 1277 | { | ||
| 1278 | if (!dev->event) | ||
| 1279 | return; | ||
| 1280 | |||
| 1281 | INPUT_DO_TOGGLE(dev, LED, led, activate); | ||
| 1282 | INPUT_DO_TOGGLE(dev, SND, snd, activate); | ||
| 1283 | |||
| 1284 | if (activate && test_bit(EV_REP, dev->evbit)) { | ||
| 1285 | dev->event(dev, EV_REP, REP_PERIOD, dev->rep[REP_PERIOD]); | ||
| 1286 | dev->event(dev, EV_REP, REP_DELAY, dev->rep[REP_DELAY]); | ||
| 1287 | } | ||
| 1288 | } | ||
| 1289 | |||
| 1290 | #ifdef CONFIG_PM | ||
| 1291 | static int input_dev_suspend(struct device *dev) | ||
| 1292 | { | ||
| 1293 | struct input_dev *input_dev = to_input_dev(dev); | ||
| 1294 | |||
| 1295 | mutex_lock(&input_dev->mutex); | ||
| 1296 | input_dev_reset(input_dev, false); | ||
| 1297 | mutex_unlock(&input_dev->mutex); | ||
| 1298 | |||
| 1299 | return 0; | ||
| 1300 | } | ||
| 1301 | |||
| 1302 | static int input_dev_resume(struct device *dev) | ||
| 1303 | { | ||
| 1304 | struct input_dev *input_dev = to_input_dev(dev); | ||
| 1305 | |||
| 1306 | mutex_lock(&input_dev->mutex); | ||
| 1307 | input_dev_reset(input_dev, true); | ||
| 1308 | mutex_unlock(&input_dev->mutex); | ||
| 1309 | |||
| 1310 | return 0; | ||
| 1311 | } | ||
| 1312 | |||
| 1313 | static const struct dev_pm_ops input_dev_pm_ops = { | ||
| 1314 | .suspend = input_dev_suspend, | ||
| 1315 | .resume = input_dev_resume, | ||
| 1316 | .poweroff = input_dev_suspend, | ||
| 1317 | .restore = input_dev_resume, | ||
| 1318 | }; | ||
| 1319 | #endif /* CONFIG_PM */ | ||
| 1320 | |||
| 1262 | static struct device_type input_dev_type = { | 1321 | static struct device_type input_dev_type = { |
| 1263 | .groups = input_dev_attr_groups, | 1322 | .groups = input_dev_attr_groups, |
| 1264 | .release = input_dev_release, | 1323 | .release = input_dev_release, |
| 1265 | .uevent = input_dev_uevent, | 1324 | .uevent = input_dev_uevent, |
| 1325 | #ifdef CONFIG_PM | ||
| 1326 | .pm = &input_dev_pm_ops, | ||
| 1327 | #endif | ||
| 1266 | }; | 1328 | }; |
| 1267 | 1329 | ||
| 1268 | static char *input_nodename(struct device *dev) | 1330 | static char *input_nodename(struct device *dev) |
