Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Input: adxl34 - make enable/disable separate from suspend/resume

Suspending and resuming the device should be separate from enabling
and disabling it through sysfs attribute and thus should not alter
ac->disabled flag.

[michael.hennerich@analog.com: various fixups]
Tested-by: Michael Hennerich <michael.hennerich@analog.com>
Signed-off-by: Dmitry Torokhov <dtor@mail.ru>

+70 -48
+11 -11
drivers/input/misc/adxl34x-i2c.c
··· 58 58 return 0; 59 59 } 60 60 61 - static const struct adxl34x_bus_ops adx134x_smbus_bops = { 61 + static const struct adxl34x_bus_ops adxl34x_smbus_bops = { 62 62 .bustype = BUS_I2C, 63 63 .write = adxl34x_smbus_write, 64 64 .read = adxl34x_smbus_read, 65 65 .read_block = adxl34x_smbus_read_block, 66 66 }; 67 67 68 - static const struct adxl34x_bus_ops adx134x_i2c_bops = { 68 + static const struct adxl34x_bus_ops adxl34x_i2c_bops = { 69 69 .bustype = BUS_I2C, 70 70 .write = adxl34x_smbus_write, 71 71 .read = adxl34x_smbus_read, ··· 88 88 ac = adxl34x_probe(&client->dev, client->irq, false, 89 89 i2c_check_functionality(client->adapter, 90 90 I2C_FUNC_SMBUS_READ_I2C_BLOCK) ? 91 - &adx134x_smbus_bops : &adx134x_i2c_bops); 91 + &adxl34x_smbus_bops : &adxl34x_i2c_bops); 92 92 if (IS_ERR(ac)) 93 93 return PTR_ERR(ac); 94 94 ··· 105 105 } 106 106 107 107 #ifdef CONFIG_PM 108 - static int adxl34x_suspend(struct i2c_client *client, pm_message_t message) 108 + static int adxl34x_i2c_suspend(struct i2c_client *client, pm_message_t message) 109 109 { 110 110 struct adxl34x *ac = i2c_get_clientdata(client); 111 111 112 - adxl34x_disable(ac); 112 + adxl34x_suspend(ac); 113 113 114 114 return 0; 115 115 } 116 116 117 - static int adxl34x_resume(struct i2c_client *client) 117 + static int adxl34x_i2c_resume(struct i2c_client *client) 118 118 { 119 119 struct adxl34x *ac = i2c_get_clientdata(client); 120 120 121 - adxl34x_enable(ac); 121 + adxl34x_resume(ac); 122 122 123 123 return 0; 124 124 } 125 125 #else 126 - # define adxl34x_suspend NULL 127 - # define adxl34x_resume NULL 126 + # define adxl34x_i2c_suspend NULL 127 + # define adxl34x_i2c_resume NULL 128 128 #endif 129 129 130 130 static const struct i2c_device_id adxl34x_id[] = { ··· 141 141 }, 142 142 .probe = adxl34x_i2c_probe, 143 143 .remove = __devexit_p(adxl34x_i2c_remove), 144 - .suspend = adxl34x_suspend, 145 - .resume = adxl34x_resume, 144 + .suspend = adxl34x_i2c_suspend, 145 + .resume = adxl34x_i2c_resume, 146 146 .id_table = adxl34x_id, 147 147 }; 148 148
+8 -8
drivers/input/misc/adxl34x-spi.c
··· 94 94 } 95 95 96 96 #ifdef CONFIG_PM 97 - static int adxl34x_suspend(struct spi_device *spi, pm_message_t message) 97 + static int adxl34x_spi_suspend(struct spi_device *spi, pm_message_t message) 98 98 { 99 99 struct adxl34x *ac = dev_get_drvdata(&spi->dev); 100 100 101 - adxl34x_disable(ac); 101 + adxl34x_suspend(ac); 102 102 103 103 return 0; 104 104 } 105 105 106 - static int adxl34x_resume(struct spi_device *spi) 106 + static int adxl34x_spi_resume(struct spi_device *spi) 107 107 { 108 108 struct adxl34x *ac = dev_get_drvdata(&spi->dev); 109 109 110 - adxl34x_enable(ac); 110 + adxl34x_resume(ac); 111 111 112 112 return 0; 113 113 } 114 114 #else 115 - # define adxl34x_suspend NULL 116 - # define adxl34x_resume NULL 115 + # define adxl34x_spi_suspend NULL 116 + # define adxl34x_spi_resume NULL 117 117 #endif 118 118 119 119 static struct spi_driver adxl34x_driver = { ··· 124 124 }, 125 125 .probe = adxl34x_spi_probe, 126 126 .remove = __devexit_p(adxl34x_spi_remove), 127 - .suspend = adxl34x_suspend, 128 - .resume = adxl34x_resume, 127 + .suspend = adxl34x_spi_suspend, 128 + .resume = adxl34x_spi_resume, 129 129 }; 130 130 131 131 static int __init adxl34x_spi_init(void)
+49 -27
drivers/input/misc/adxl34x.c
··· 200 200 unsigned orient3d_saved; 201 201 bool disabled; /* P: mutex */ 202 202 bool opened; /* P: mutex */ 203 + bool suspended; /* P: mutex */ 203 204 bool fifo_delay; 204 205 int irq; 205 206 unsigned model; ··· 400 399 401 400 static void __adxl34x_disable(struct adxl34x *ac) 402 401 { 403 - if (!ac->disabled && ac->opened) { 404 - /* 405 - * A '0' places the ADXL34x into standby mode 406 - * with minimum power consumption. 407 - */ 408 - AC_WRITE(ac, POWER_CTL, 0); 409 - 410 - ac->disabled = true; 411 - } 402 + /* 403 + * A '0' places the ADXL34x into standby mode 404 + * with minimum power consumption. 405 + */ 406 + AC_WRITE(ac, POWER_CTL, 0); 412 407 } 413 408 414 409 static void __adxl34x_enable(struct adxl34x *ac) 415 410 { 416 - if (ac->disabled && ac->opened) { 417 - AC_WRITE(ac, POWER_CTL, ac->pdata.power_mode | PCTL_MEASURE); 418 - ac->disabled = false; 419 - } 411 + AC_WRITE(ac, POWER_CTL, ac->pdata.power_mode | PCTL_MEASURE); 420 412 } 421 413 422 - void adxl34x_disable(struct adxl34x *ac) 414 + void adxl34x_suspend(struct adxl34x *ac) 423 415 { 424 416 mutex_lock(&ac->mutex); 425 - __adxl34x_disable(ac); 417 + 418 + if (!ac->suspended && !ac->disabled && ac->opened) 419 + __adxl34x_disable(ac); 420 + 421 + ac->suspended = true; 422 + 426 423 mutex_unlock(&ac->mutex); 427 424 } 428 - EXPORT_SYMBOL_GPL(adxl34x_disable); 425 + EXPORT_SYMBOL_GPL(adxl34x_suspend); 429 426 430 - void adxl34x_enable(struct adxl34x *ac) 427 + void adxl34x_resume(struct adxl34x *ac) 431 428 { 432 429 mutex_lock(&ac->mutex); 433 - __adxl34x_enable(ac); 430 + 431 + if (ac->suspended && !ac->disabled && ac->opened) 432 + __adxl34x_enable(ac); 433 + 434 + ac->suspended= false; 435 + 434 436 mutex_unlock(&ac->mutex); 435 437 } 436 438 437 - EXPORT_SYMBOL_GPL(adxl34x_enable); 439 + EXPORT_SYMBOL_GPL(adxl34x_resume); 438 440 439 441 static ssize_t adxl34x_disable_show(struct device *dev, 440 442 struct device_attribute *attr, char *buf) ··· 459 455 if (error) 460 456 return error; 461 457 462 - if (val) 463 - adxl34x_disable(ac); 464 - else 465 - adxl34x_enable(ac); 458 + mutex_lock(&ac->mutex); 459 + 460 + if (!ac->suspended && ac->opened) { 461 + if (val) { 462 + if (!ac->disabled) 463 + __adxl34x_disable(ac); 464 + } else { 465 + if (ac->disabled) 466 + __adxl34x_enable(ac); 467 + } 468 + } 469 + 470 + ac->disabled = !!val; 471 + 472 + mutex_unlock(&ac->mutex); 466 473 467 474 return count; 468 475 } ··· 590 575 else 591 576 ac->pdata.power_mode &= ~(PCTL_AUTO_SLEEP | PCTL_LINK); 592 577 593 - if (!ac->disabled && ac->opened) 578 + if (!ac->disabled && !ac->suspended && ac->opened) 594 579 AC_WRITE(ac, POWER_CTL, ac->pdata.power_mode | PCTL_MEASURE); 595 580 596 581 mutex_unlock(&ac->mutex); ··· 664 649 struct adxl34x *ac = input_get_drvdata(input); 665 650 666 651 mutex_lock(&ac->mutex); 652 + 653 + if (!ac->suspended && !ac->disabled) 654 + __adxl34x_enable(ac); 655 + 667 656 ac->opened = true; 668 - __adxl34x_enable(ac); 657 + 669 658 mutex_unlock(&ac->mutex); 670 659 671 660 return 0; ··· 680 661 struct adxl34x *ac = input_get_drvdata(input); 681 662 682 663 mutex_lock(&ac->mutex); 683 - __adxl34x_disable(ac); 664 + 665 + if (!ac->suspended && !ac->disabled) 666 + __adxl34x_disable(ac); 667 + 684 668 ac->opened = false; 669 + 685 670 mutex_unlock(&ac->mutex); 686 671 } 687 672 ··· 901 878 902 879 int adxl34x_remove(struct adxl34x *ac) 903 880 { 904 - adxl34x_disable(ac); 905 881 sysfs_remove_group(&ac->dev->kobj, &adxl34x_attr_group); 906 882 free_irq(ac->irq, ac); 907 883 input_unregister_device(ac->input);
+2 -2
drivers/input/misc/adxl34x.h
··· 20 20 int (*write)(struct device *, unsigned char, unsigned char); 21 21 }; 22 22 23 - void adxl34x_disable(struct adxl34x *ac); 24 - void adxl34x_enable(struct adxl34x *ac); 23 + void adxl34x_suspend(struct adxl34x *ac); 24 + void adxl34x_resume(struct adxl34x *ac); 25 25 struct adxl34x *adxl34x_probe(struct device *dev, int irq, 26 26 bool fifo_delay_default, 27 27 const struct adxl34x_bus_ops *bops);