Skip to content

Commit f23d871

Browse files
committed
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
2 parents c4d36b6 + b8f5fe3 commit f23d871

File tree

3 files changed

+111
-13
lines changed

3 files changed

+111
-13
lines changed

Documentation/driver-model/devres.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -271,6 +271,9 @@ GPIO
271271
devm_gpio_request_one()
272272
devm_gpio_free()
273273

274+
I2C
275+
devm_i2c_new_dummy_device()
276+
274277
IIO
275278
devm_iio_device_alloc()
276279
devm_iio_device_free()

drivers/i2c/i2c-core-base.c

Lines changed: 105 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -714,7 +714,7 @@ static int i2c_dev_irq_from_resources(const struct resource *resources,
714714
}
715715

716716
/**
717-
* i2c_new_device - instantiate an i2c device
717+
* i2c_new_client_device - instantiate an i2c device
718718
* @adap: the adapter managing the device
719719
* @info: describes one I2C device; bus_num is ignored
720720
* Context: can sleep
@@ -727,17 +727,17 @@ static int i2c_dev_irq_from_resources(const struct resource *resources,
727727
* before any i2c_adapter could exist.
728728
*
729729
* 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.
731731
*/
732-
struct i2c_client *
733-
i2c_new_device(struct i2c_adapter *adap, struct i2c_board_info const *info)
732+
static struct i2c_client *
733+
i2c_new_client_device(struct i2c_adapter *adap, struct i2c_board_info const *info)
734734
{
735735
struct i2c_client *client;
736736
int status;
737737

738738
client = kzalloc(sizeof *client, GFP_KERNEL);
739739
if (!client)
740-
return NULL;
740+
return ERR_PTR(-ENOMEM);
741741

742742
client->adapter = adap;
743743

@@ -803,7 +803,31 @@ i2c_new_device(struct i2c_adapter *adap, struct i2c_board_info const *info)
803803
client->name, client->addr, status);
804804
out_err_silent:
805805
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;
807831
}
808832
EXPORT_SYMBOL_GPL(i2c_new_device);
809833

@@ -854,7 +878,7 @@ static struct i2c_driver dummy_driver = {
854878
};
855879

856880
/**
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
858882
* @adapter: the adapter managing the device
859883
* @address: seven bit address to be used
860884
* Context: can sleep
@@ -869,18 +893,86 @@ static struct i2c_driver dummy_driver = {
869893
* different driver.
870894
*
871895
* 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.
873897
*/
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)
875900
{
876901
struct i2c_board_info info = {
877902
I2C_BOARD_INFO("dummy", address),
878903
};
879904

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;
881929
}
882930
EXPORT_SYMBOL_GPL(i2c_new_dummy);
883931

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+
884976
/**
885977
* i2c_new_secondary_device - Helper to get the instantiated secondary address
886978
* and create the associated device
@@ -1000,9 +1092,9 @@ i2c_sysfs_new_device(struct device *dev, struct device_attribute *attr,
10001092
info.flags |= I2C_CLIENT_SLAVE;
10011093
}
10021094

1003-
client = i2c_new_device(adap, &info);
1004-
if (!client)
1005-
return -EINVAL;
1095+
client = i2c_new_client_device(adap, &info);
1096+
if (IS_ERR(client))
1097+
return PTR_ERR(client);
10061098

10071099
/* Keep track of the added device */
10081100
mutex_lock(&adap->userspace_clients_lock);

include/linux/i2c.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -469,6 +469,9 @@ extern int i2c_probe_func_quick_read(struct i2c_adapter *, unsigned short addr);
469469
extern struct i2c_client *
470470
i2c_new_dummy(struct i2c_adapter *adap, u16 address);
471471

472+
extern struct i2c_client *
473+
devm_i2c_new_dummy_device(struct device *dev, struct i2c_adapter *adap, u16 address);
474+
472475
extern struct i2c_client *
473476
i2c_new_secondary_device(struct i2c_client *client,
474477
const char *name,

0 commit comments

Comments
 (0)