diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2019-05-19 14:47:03 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2019-05-19 14:47:03 -0400 |
commit | f23d8719e76fd32828ae6f1b55e4659144467742 (patch) | |
tree | 7ddb9a4fbbc029d37f718235a0deb54e78d829e1 | |
parent | c4d36b63b28b76cd584bec48af7b562b4513b87b (diff) | |
parent | b8f5fe3bc5b9318d95770a09a480c31aced20cd2 (diff) |
Merge branch 'i2c/for-next' of git://git.kernel.org/pub/scm/linux/kernel/git/wsa/linux
Pull i2c updates from Wolfram Sang:
"Some I2C core API additions which are kind of simple but enhance error
checking for users a lot, especially by returning errno now.
There are wrappers to still support the old API but it will be removed
once all users are converted"
* 'i2c/for-next' of git://git.kernel.org/pub/scm/linux/kernel/git/wsa/linux:
i2c: core: add device-managed version of i2c_new_dummy
i2c: core: improve return value handling of i2c_new_device and i2c_new_dummy
-rw-r--r-- | Documentation/driver-model/devres.txt | 3 | ||||
-rw-r--r-- | drivers/i2c/i2c-core-base.c | 118 | ||||
-rw-r--r-- | include/linux/i2c.h | 3 |
3 files changed, 111 insertions, 13 deletions
diff --git a/Documentation/driver-model/devres.txt b/Documentation/driver-model/devres.txt index 99994a461359..69c7fa7f616c 100644 --- a/Documentation/driver-model/devres.txt +++ b/Documentation/driver-model/devres.txt | |||
@@ -271,6 +271,9 @@ GPIO | |||
271 | devm_gpio_request_one() | 271 | devm_gpio_request_one() |
272 | devm_gpio_free() | 272 | devm_gpio_free() |
273 | 273 | ||
274 | I2C | ||
275 | devm_i2c_new_dummy_device() | ||
276 | |||
274 | IIO | 277 | IIO |
275 | devm_iio_device_alloc() | 278 | devm_iio_device_alloc() |
276 | devm_iio_device_free() | 279 | devm_iio_device_free() |
diff --git a/drivers/i2c/i2c-core-base.c b/drivers/i2c/i2c-core-base.c index 9732a81bb7dd..d389d4fb0623 100644 --- a/drivers/i2c/i2c-core-base.c +++ b/drivers/i2c/i2c-core-base.c | |||
@@ -714,7 +714,7 @@ static int i2c_dev_irq_from_resources(const struct resource *resources, | |||
714 | } | 714 | } |
715 | 715 | ||
716 | /** | 716 | /** |
717 | * i2c_new_device - instantiate an i2c device | 717 | * i2c_new_client_device - instantiate an i2c device |
718 | * @adap: the adapter managing the device | 718 | * @adap: the adapter managing the device |
719 | * @info: describes one I2C device; bus_num is ignored | 719 | * @info: describes one I2C device; bus_num is ignored |
720 | * Context: can sleep | 720 | * Context: can sleep |
@@ -727,17 +727,17 @@ static int i2c_dev_irq_from_resources(const struct resource *resources, | |||
727 | * before any i2c_adapter could exist. | 727 | * before any i2c_adapter could exist. |
728 | * | 728 | * |
729 | * This returns the new i2c client, which may be saved for later use with | 729 | * This returns the new i2c client, which may be saved for later use with |
730 | * i2c_unregister_device(); or NULL to indicate an error. | 730 | * i2c_unregister_device(); or an ERR_PTR to describe the error. |
731 | */ | 731 | */ |
732 | struct i2c_client * | 732 | static struct i2c_client * |
733 | i2c_new_device(struct i2c_adapter *adap, struct i2c_board_info const *info) | 733 | i2c_new_client_device(struct i2c_adapter *adap, struct i2c_board_info const *info) |
734 | { | 734 | { |
735 | struct i2c_client *client; | 735 | struct i2c_client *client; |
736 | int status; | 736 | int status; |
737 | 737 | ||
738 | client = kzalloc(sizeof *client, GFP_KERNEL); | 738 | client = kzalloc(sizeof *client, GFP_KERNEL); |
739 | if (!client) | 739 | if (!client) |
740 | return NULL; | 740 | return ERR_PTR(-ENOMEM); |
741 | 741 | ||
742 | client->adapter = adap; | 742 | client->adapter = adap; |
743 | 743 | ||
@@ -803,7 +803,31 @@ out_err: | |||
803 | client->name, client->addr, status); | 803 | client->name, client->addr, status); |
804 | out_err_silent: | 804 | out_err_silent: |
805 | kfree(client); | 805 | kfree(client); |
806 | return NULL; | 806 | return ERR_PTR(status); |
807 | } | ||
808 | EXPORT_SYMBOL_GPL(i2c_new_client_device); | ||
809 | |||
810 | /** | ||
811 | * i2c_new_device - instantiate an i2c device | ||
812 | * @adap: the adapter managing the device | ||
813 | * @info: describes one I2C device; bus_num is ignored | ||
814 | * Context: can sleep | ||
815 | * | ||
816 | * This deprecated function has the same functionality as | ||
817 | * @i2c_new_client_device, it just returns NULL instead of an ERR_PTR in case of | ||
818 | * an error for compatibility with current I2C API. It will be removed once all | ||
819 | * users are converted. | ||
820 | * | ||
821 | * This returns the new i2c client, which may be saved for later use with | ||
822 | * i2c_unregister_device(); or NULL to indicate an error. | ||
823 | */ | ||
824 | struct i2c_client * | ||
825 | i2c_new_device(struct i2c_adapter *adap, struct i2c_board_info const *info) | ||
826 | { | ||
827 | struct i2c_client *ret; | ||
828 | |||
829 | ret = i2c_new_client_device(adap, info); | ||
830 | return IS_ERR(ret) ? NULL : ret; | ||
807 | } | 831 | } |
808 | EXPORT_SYMBOL_GPL(i2c_new_device); | 832 | EXPORT_SYMBOL_GPL(i2c_new_device); |
809 | 833 | ||
@@ -854,7 +878,7 @@ static struct i2c_driver dummy_driver = { | |||
854 | }; | 878 | }; |
855 | 879 | ||
856 | /** | 880 | /** |
857 | * i2c_new_dummy - return a new i2c device bound to a dummy driver | 881 | * i2c_new_dummy_device - return a new i2c device bound to a dummy driver |
858 | * @adapter: the adapter managing the device | 882 | * @adapter: the adapter managing the device |
859 | * @address: seven bit address to be used | 883 | * @address: seven bit address to be used |
860 | * Context: can sleep | 884 | * Context: can sleep |
@@ -869,18 +893,86 @@ static struct i2c_driver dummy_driver = { | |||
869 | * different driver. | 893 | * different driver. |
870 | * | 894 | * |
871 | * This returns the new i2c client, which should be saved for later use with | 895 | * This returns the new i2c client, which should be saved for later use with |
872 | * i2c_unregister_device(); or NULL to indicate an error. | 896 | * i2c_unregister_device(); or an ERR_PTR to describe the error. |
873 | */ | 897 | */ |
874 | struct i2c_client *i2c_new_dummy(struct i2c_adapter *adapter, u16 address) | 898 | static struct i2c_client * |
899 | i2c_new_dummy_device(struct i2c_adapter *adapter, u16 address) | ||
875 | { | 900 | { |
876 | struct i2c_board_info info = { | 901 | struct i2c_board_info info = { |
877 | I2C_BOARD_INFO("dummy", address), | 902 | I2C_BOARD_INFO("dummy", address), |
878 | }; | 903 | }; |
879 | 904 | ||
880 | return i2c_new_device(adapter, &info); | 905 | return i2c_new_client_device(adapter, &info); |
906 | } | ||
907 | EXPORT_SYMBOL_GPL(i2c_new_dummy_device); | ||
908 | |||
909 | /** | ||
910 | * i2c_new_dummy - return a new i2c device bound to a dummy driver | ||
911 | * @adapter: the adapter managing the device | ||
912 | * @address: seven bit address to be used | ||
913 | * Context: can sleep | ||
914 | * | ||
915 | * This deprecated function has the same functionality as @i2c_new_dummy_device, | ||
916 | * it just returns NULL instead of an ERR_PTR in case of an error for | ||
917 | * compatibility with current I2C API. It will be removed once all users are | ||
918 | * converted. | ||
919 | * | ||
920 | * This returns the new i2c client, which should be saved for later use with | ||
921 | * i2c_unregister_device(); or NULL to indicate an error. | ||
922 | */ | ||
923 | struct i2c_client *i2c_new_dummy(struct i2c_adapter *adapter, u16 address) | ||
924 | { | ||
925 | struct i2c_client *ret; | ||
926 | |||
927 | ret = i2c_new_dummy_device(adapter, address); | ||
928 | return IS_ERR(ret) ? NULL : ret; | ||
881 | } | 929 | } |
882 | EXPORT_SYMBOL_GPL(i2c_new_dummy); | 930 | EXPORT_SYMBOL_GPL(i2c_new_dummy); |
883 | 931 | ||
932 | struct i2c_dummy_devres { | ||
933 | struct i2c_client *client; | ||
934 | }; | ||
935 | |||
936 | static void devm_i2c_release_dummy(struct device *dev, void *res) | ||
937 | { | ||
938 | struct i2c_dummy_devres *this = res; | ||
939 | |||
940 | i2c_unregister_device(this->client); | ||
941 | } | ||
942 | |||
943 | /** | ||
944 | * devm_i2c_new_dummy_device - return a new i2c device bound to a dummy driver | ||
945 | * @dev: device the managed resource is bound to | ||
946 | * @adapter: the adapter managing the device | ||
947 | * @address: seven bit address to be used | ||
948 | * Context: can sleep | ||
949 | * | ||
950 | * This is the device-managed version of @i2c_new_dummy_device. It returns the | ||
951 | * new i2c client or an ERR_PTR in case of an error. | ||
952 | */ | ||
953 | struct i2c_client *devm_i2c_new_dummy_device(struct device *dev, | ||
954 | struct i2c_adapter *adapter, | ||
955 | u16 address) | ||
956 | { | ||
957 | struct i2c_dummy_devres *dr; | ||
958 | struct i2c_client *client; | ||
959 | |||
960 | dr = devres_alloc(devm_i2c_release_dummy, sizeof(*dr), GFP_KERNEL); | ||
961 | if (!dr) | ||
962 | return ERR_PTR(-ENOMEM); | ||
963 | |||
964 | client = i2c_new_dummy_device(adapter, address); | ||
965 | if (IS_ERR(client)) { | ||
966 | devres_free(dr); | ||
967 | } else { | ||
968 | dr->client = client; | ||
969 | devres_add(dev, dr); | ||
970 | } | ||
971 | |||
972 | return client; | ||
973 | } | ||
974 | EXPORT_SYMBOL_GPL(devm_i2c_new_dummy_device); | ||
975 | |||
884 | /** | 976 | /** |
885 | * i2c_new_secondary_device - Helper to get the instantiated secondary address | 977 | * i2c_new_secondary_device - Helper to get the instantiated secondary address |
886 | * and create the associated device | 978 | * and create the associated device |
@@ -1000,9 +1092,9 @@ i2c_sysfs_new_device(struct device *dev, struct device_attribute *attr, | |||
1000 | info.flags |= I2C_CLIENT_SLAVE; | 1092 | info.flags |= I2C_CLIENT_SLAVE; |
1001 | } | 1093 | } |
1002 | 1094 | ||
1003 | client = i2c_new_device(adap, &info); | 1095 | client = i2c_new_client_device(adap, &info); |
1004 | if (!client) | 1096 | if (IS_ERR(client)) |
1005 | return -EINVAL; | 1097 | return PTR_ERR(client); |
1006 | 1098 | ||
1007 | /* Keep track of the added device */ | 1099 | /* Keep track of the added device */ |
1008 | mutex_lock(&adap->userspace_clients_lock); | 1100 | mutex_lock(&adap->userspace_clients_lock); |
diff --git a/include/linux/i2c.h b/include/linux/i2c.h index be27062f8ed1..6c4db54714f6 100644 --- a/include/linux/i2c.h +++ b/include/linux/i2c.h | |||
@@ -470,6 +470,9 @@ extern struct i2c_client * | |||
470 | i2c_new_dummy(struct i2c_adapter *adap, u16 address); | 470 | i2c_new_dummy(struct i2c_adapter *adap, u16 address); |
471 | 471 | ||
472 | extern struct i2c_client * | 472 | extern struct i2c_client * |
473 | devm_i2c_new_dummy_device(struct device *dev, struct i2c_adapter *adap, u16 address); | ||
474 | |||
475 | extern struct i2c_client * | ||
473 | i2c_new_secondary_device(struct i2c_client *client, | 476 | i2c_new_secondary_device(struct i2c_client *client, |
474 | const char *name, | 477 | const char *name, |
475 | u16 default_addr); | 478 | u16 default_addr); |