aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDudley Du <dudley.dulixin@gmail.com>2014-11-09 15:36:34 -0500
committerDmitry Torokhov <dmitry.torokhov@gmail.com>2014-11-10 01:59:48 -0500
commitb1cfa7b4388285c0f0b486f152ab0cb18612c779 (patch)
tree6ad423475d8f90c72633865e21957017398ea895
parentbd447b61c49fc26f0299587db3e6d66da49dc529 (diff)
Input: cyapa - switch to using managed resources
Use of managed resources simplifies error handling and device removal code. Signed-off-by: Dudley Du <dudl@cypress.com> [Dmitry: added open/close methods so cyapa_remove is no longer needed.] Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
-rw-r--r--drivers/input/mouse/cyapa.c184
1 files changed, 105 insertions, 79 deletions
diff --git a/drivers/input/mouse/cyapa.c b/drivers/input/mouse/cyapa.c
index 1d978c7289b4..c84a9ebeb2ff 100644
--- a/drivers/input/mouse/cyapa.c
+++ b/drivers/input/mouse/cyapa.c
@@ -577,10 +577,13 @@ static int cyapa_set_power_mode(struct cyapa *cyapa, u8 power_mode)
577 power = ret & ~PWR_MODE_MASK; 577 power = ret & ~PWR_MODE_MASK;
578 power |= power_mode & PWR_MODE_MASK; 578 power |= power_mode & PWR_MODE_MASK;
579 ret = cyapa_write_byte(cyapa, CYAPA_CMD_POWER_MODE, power); 579 ret = cyapa_write_byte(cyapa, CYAPA_CMD_POWER_MODE, power);
580 if (ret < 0) 580 if (ret < 0) {
581 dev_err(dev, "failed to set power_mode 0x%02x err = %d\n", 581 dev_err(dev, "failed to set power_mode 0x%02x err = %d\n",
582 power_mode, ret); 582 power_mode, ret);
583 return ret; 583 return ret;
584 }
585
586 return 0;
584} 587}
585 588
586static int cyapa_get_query_data(struct cyapa *cyapa) 589static int cyapa_get_query_data(struct cyapa *cyapa)
@@ -753,16 +756,40 @@ static u8 cyapa_check_adapter_functionality(struct i2c_client *client)
753 return ret; 756 return ret;
754} 757}
755 758
759static int cyapa_open(struct input_dev *input)
760{
761 struct cyapa *cyapa = input_get_drvdata(input);
762 struct i2c_client *client = cyapa->client;
763 int error;
764
765 error = cyapa_set_power_mode(cyapa, PWR_MODE_FULL_ACTIVE);
766 if (error) {
767 dev_err(&client->dev, "set active power failed: %d\n", error);
768 return error;
769 }
770
771 enable_irq(client->irq);
772 return 0;
773}
774
775static void cyapa_close(struct input_dev *input)
776{
777 struct cyapa *cyapa = input_get_drvdata(input);
778
779 disable_irq(cyapa->client->irq);
780 cyapa_set_power_mode(cyapa, PWR_MODE_OFF);
781}
782
756static int cyapa_create_input_dev(struct cyapa *cyapa) 783static int cyapa_create_input_dev(struct cyapa *cyapa)
757{ 784{
758 struct device *dev = &cyapa->client->dev; 785 struct device *dev = &cyapa->client->dev;
759 int ret;
760 struct input_dev *input; 786 struct input_dev *input;
787 int error;
761 788
762 if (!cyapa->physical_size_x || !cyapa->physical_size_y) 789 if (!cyapa->physical_size_x || !cyapa->physical_size_y)
763 return -EINVAL; 790 return -EINVAL;
764 791
765 input = cyapa->input = input_allocate_device(); 792 input = devm_input_allocate_device(dev);
766 if (!input) { 793 if (!input) {
767 dev_err(dev, "allocate memory for input device failed\n"); 794 dev_err(dev, "allocate memory for input device failed\n");
768 return -ENOMEM; 795 return -ENOMEM;
@@ -775,6 +802,9 @@ static int cyapa_create_input_dev(struct cyapa *cyapa)
775 input->id.product = 0; /* means any product in eventcomm. */ 802 input->id.product = 0; /* means any product in eventcomm. */
776 input->dev.parent = &cyapa->client->dev; 803 input->dev.parent = &cyapa->client->dev;
777 804
805 input->open = cyapa_open;
806 input->close = cyapa_close;
807
778 input_set_drvdata(input, cyapa); 808 input_set_drvdata(input, cyapa);
779 809
780 __set_bit(EV_ABS, input->evbit); 810 __set_bit(EV_ABS, input->evbit);
@@ -802,34 +832,24 @@ static int cyapa_create_input_dev(struct cyapa *cyapa)
802 __set_bit(INPUT_PROP_BUTTONPAD, input->propbit); 832 __set_bit(INPUT_PROP_BUTTONPAD, input->propbit);
803 833
804 /* handle pointer emulation and unused slots in core */ 834 /* handle pointer emulation and unused slots in core */
805 ret = input_mt_init_slots(input, CYAPA_MAX_MT_SLOTS, 835 error = input_mt_init_slots(input, CYAPA_MAX_MT_SLOTS,
806 INPUT_MT_POINTER | INPUT_MT_DROP_UNUSED); 836 INPUT_MT_POINTER | INPUT_MT_DROP_UNUSED);
807 if (ret) { 837 if (error) {
808 dev_err(dev, "allocate memory for MT slots failed, %d\n", ret); 838 dev_err(dev, "failed to initialize MT slots: %d\n", error);
809 goto err_free_device; 839 return error;
810 } 840 }
811 841
812 /* Register the device in input subsystem */ 842 cyapa->input = input;
813 ret = input_register_device(input);
814 if (ret) {
815 dev_err(dev, "input device register failed, %d\n", ret);
816 goto err_free_device;
817 }
818 return 0; 843 return 0;
819
820err_free_device:
821 input_free_device(input);
822 cyapa->input = NULL;
823 return ret;
824} 844}
825 845
826static int cyapa_probe(struct i2c_client *client, 846static int cyapa_probe(struct i2c_client *client,
827 const struct i2c_device_id *dev_id) 847 const struct i2c_device_id *dev_id)
828{ 848{
829 int ret;
830 u8 adapter_func;
831 struct cyapa *cyapa;
832 struct device *dev = &client->dev; 849 struct device *dev = &client->dev;
850 struct cyapa *cyapa;
851 u8 adapter_func;
852 int error;
833 853
834 adapter_func = cyapa_check_adapter_functionality(client); 854 adapter_func = cyapa_check_adapter_functionality(client);
835 if (adapter_func == CYAPA_ADAPTER_FUNC_NONE) { 855 if (adapter_func == CYAPA_ADAPTER_FUNC_NONE) {
@@ -837,11 +857,9 @@ static int cyapa_probe(struct i2c_client *client,
837 return -EIO; 857 return -EIO;
838 } 858 }
839 859
840 cyapa = kzalloc(sizeof(struct cyapa), GFP_KERNEL); 860 cyapa = devm_kzalloc(dev, sizeof(struct cyapa), GFP_KERNEL);
841 if (!cyapa) { 861 if (!cyapa)
842 dev_err(dev, "allocate memory for cyapa failed\n");
843 return -ENOMEM; 862 return -ENOMEM;
844 }
845 863
846 cyapa->gen = CYAPA_GEN3; 864 cyapa->gen = CYAPA_GEN3;
847 cyapa->client = client; 865 cyapa->client = client;
@@ -852,66 +870,61 @@ static int cyapa_probe(struct i2c_client *client,
852 /* i2c isn't supported, use smbus */ 870 /* i2c isn't supported, use smbus */
853 if (adapter_func == CYAPA_ADAPTER_FUNC_SMBUS) 871 if (adapter_func == CYAPA_ADAPTER_FUNC_SMBUS)
854 cyapa->smbus = true; 872 cyapa->smbus = true;
873
855 cyapa->state = CYAPA_STATE_NO_DEVICE; 874 cyapa->state = CYAPA_STATE_NO_DEVICE;
856 ret = cyapa_check_is_operational(cyapa);
857 if (ret) {
858 dev_err(dev, "device not operational, %d\n", ret);
859 goto err_mem_free;
860 }
861 875
862 ret = cyapa_create_input_dev(cyapa); 876 error = cyapa_check_is_operational(cyapa);
863 if (ret) { 877 if (error) {
864 dev_err(dev, "create input_dev instance failed, %d\n", ret); 878 dev_err(dev, "device not operational, %d\n", error);
865 goto err_mem_free; 879 return error;
866 } 880 }
867 881
868 ret = cyapa_set_power_mode(cyapa, PWR_MODE_FULL_ACTIVE); 882 /* Power down the device until we need it */
869 if (ret) { 883 error = cyapa_set_power_mode(cyapa, PWR_MODE_OFF);
870 dev_err(dev, "set active power failed, %d\n", ret); 884 if (error) {
871 goto err_unregister_device; 885 dev_err(dev, "failed to quiesce the device: %d\n", error);
886 return error;
872 } 887 }
873 888
874 cyapa->irq = client->irq; 889 error = cyapa_create_input_dev(cyapa);
875 ret = request_threaded_irq(cyapa->irq, 890 if (error)
876 NULL, 891 return error;
877 cyapa_irq, 892
878 IRQF_TRIGGER_FALLING | IRQF_ONESHOT, 893 error = devm_request_threaded_irq(dev, client->irq,
879 "cyapa", 894 NULL, cyapa_irq,
880 cyapa); 895 IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
881 if (ret) { 896 "cyapa", cyapa);
882 dev_err(dev, "IRQ request failed: %d\n, ", ret); 897 if (error) {
883 goto err_unregister_device; 898 dev_err(dev, "IRQ request failed: %d\n, ", error);
899 return error;
884 } 900 }
885 901
886 return 0; 902 /* Disable IRQ until the device is opened */
887 903 disable_irq(client->irq);
888err_unregister_device:
889 input_unregister_device(cyapa->input);
890err_mem_free:
891 kfree(cyapa);
892 904
893 return ret; 905 /* Register the device in input subsystem */
894} 906 error = input_register_device(cyapa->input);
895 907 if (error) {
896static int cyapa_remove(struct i2c_client *client) 908 dev_err(dev, "failed to register input device: %d\n", error);
897{ 909 return error;
898 struct cyapa *cyapa = i2c_get_clientdata(client); 910 }
899
900 free_irq(cyapa->irq, cyapa);
901 input_unregister_device(cyapa->input);
902 cyapa_set_power_mode(cyapa, PWR_MODE_OFF);
903 kfree(cyapa);
904 911
905 return 0; 912 return 0;
906} 913}
907 914
908static int __maybe_unused cyapa_suspend(struct device *dev) 915static int __maybe_unused cyapa_suspend(struct device *dev)
909{ 916{
910 int ret; 917 struct i2c_client *client = to_i2c_client(dev);
918 struct cyapa *cyapa = i2c_get_clientdata(client);
919 struct input_dev *input = cyapa->input;
911 u8 power_mode; 920 u8 power_mode;
912 struct cyapa *cyapa = dev_get_drvdata(dev); 921 int error;
922
923 error = mutex_lock_interruptible(&input->mutex);
924 if (error)
925 return error;
913 926
914 disable_irq(cyapa->irq); 927 disable_irq(client->irq);
915 928
916 /* 929 /*
917 * Set trackpad device to idle mode if wakeup is allowed, 930 * Set trackpad device to idle mode if wakeup is allowed,
@@ -919,28 +932,42 @@ static int __maybe_unused cyapa_suspend(struct device *dev)
919 */ 932 */
920 power_mode = device_may_wakeup(dev) ? PWR_MODE_IDLE 933 power_mode = device_may_wakeup(dev) ? PWR_MODE_IDLE
921 : PWR_MODE_OFF; 934 : PWR_MODE_OFF;
922 ret = cyapa_set_power_mode(cyapa, power_mode); 935 error = cyapa_set_power_mode(cyapa, power_mode);
923 if (ret < 0) 936 if (error)
924 dev_err(dev, "set power mode failed, %d\n", ret); 937 dev_err(dev, "resume: set power mode to %d failed: %d\n",
938 power_mode, error);
925 939
926 if (device_may_wakeup(dev)) 940 if (device_may_wakeup(dev))
927 cyapa->irq_wake = (enable_irq_wake(cyapa->irq) == 0); 941 cyapa->irq_wake = (enable_irq_wake(cyapa->irq) == 0);
942
943 mutex_unlock(&input->mutex);
944
928 return 0; 945 return 0;
929} 946}
930 947
931static int __maybe_unused cyapa_resume(struct device *dev) 948static int __maybe_unused cyapa_resume(struct device *dev)
932{ 949{
933 int ret; 950 struct i2c_client *client = to_i2c_client(dev);
934 struct cyapa *cyapa = dev_get_drvdata(dev); 951 struct cyapa *cyapa = i2c_get_clientdata(client);
952 struct input_dev *input = cyapa->input;
953 u8 power_mode;
954 int error;
955
956 mutex_lock(&input->mutex);
935 957
936 if (device_may_wakeup(dev) && cyapa->irq_wake) 958 if (device_may_wakeup(dev) && cyapa->irq_wake)
937 disable_irq_wake(cyapa->irq); 959 disable_irq_wake(cyapa->irq);
938 960
939 ret = cyapa_set_power_mode(cyapa, PWR_MODE_FULL_ACTIVE); 961 power_mode = input->users ? PWR_MODE_FULL_ACTIVE : PWR_MODE_OFF;
940 if (ret) 962 error = cyapa_set_power_mode(cyapa, PWR_MODE_FULL_ACTIVE);
941 dev_warn(dev, "resume active power failed, %d\n", ret); 963 if (error)
964 dev_warn(dev, "resume: set power mode to %d failed: %d\n",
965 power_mode, error);
942 966
943 enable_irq(cyapa->irq); 967 enable_irq(cyapa->irq);
968
969 mutex_unlock(&input->mutex);
970
944 return 0; 971 return 0;
945} 972}
946 973
@@ -960,7 +987,6 @@ static struct i2c_driver cyapa_driver = {
960 }, 987 },
961 988
962 .probe = cyapa_probe, 989 .probe = cyapa_probe,
963 .remove = cyapa_remove,
964 .id_table = cyapa_id_table, 990 .id_table = cyapa_id_table,
965}; 991};
966 992