From 8f569c0b4e6b6bd5db1d09551b2df87d912f124e Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 2 Mar 2018 10:21:16 -0500 Subject: media: dvb-core: add helper functions for I2C binding The dvb_attach()/dvb_detach() methods are ugly hacks designed to keep using the I2C low-level API. The proper way is to do I2C bus bindings instead. Several modules were already converted to use it. Yet, it is painful to use it, as lots of code need to be duplicated. Make it easier by providing two new helper functions: - dvb_module_probe() - dvb_module_release() Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-core/dvbdev.c | 48 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) (limited to 'drivers/media/dvb-core/dvbdev.c') diff --git a/drivers/media/dvb-core/dvbdev.c b/drivers/media/dvb-core/dvbdev.c index 60e9c2ba26be..a840133feacb 100644 --- a/drivers/media/dvb-core/dvbdev.c +++ b/drivers/media/dvb-core/dvbdev.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #include #include @@ -941,6 +942,53 @@ out: return err; } +#ifdef CONFIG_I2C +struct i2c_client *dvb_module_probe(const char *module_name, + const char *name, + struct i2c_adapter *adap, + unsigned char addr, + void *platform_data) +{ + struct i2c_client *client; + struct i2c_board_info *board_info; + + board_info = kzalloc(sizeof(*board_info), GFP_KERNEL); + + if (name) + strlcpy(board_info->type, name, I2C_NAME_SIZE); + else + strlcpy(board_info->type, module_name, I2C_NAME_SIZE); + + board_info->addr = addr; + board_info->platform_data = platform_data; + request_module(module_name); + client = i2c_new_device(adap, board_info); + if (client == NULL || client->dev.driver == NULL) { + kfree(board_info); + return NULL; + } + + if (!try_module_get(client->dev.driver->owner)) { + i2c_unregister_device(client); + client = NULL; + } + + kfree(board_info); + return client; +} +EXPORT_SYMBOL_GPL(dvb_module_probe); + +void dvb_module_release(struct i2c_client *client) +{ + if (!client) + return; + + module_put(client->dev.driver->owner); + i2c_unregister_device(client); +} +EXPORT_SYMBOL_GPL(dvb_module_release); +#endif + static int dvb_uevent(struct device *dev, struct kobj_uevent_env *env) { struct dvb_device *dvbdev = dev_get_drvdata(dev); -- cgit v1.2.2 From 1980bfa67f19d628df30b9b5b76bca37c2a76dde Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Wed, 7 Mar 2018 04:11:50 -0500 Subject: media: dvbdev: fix building on ia64 Not sure why, but, on ia64, with Linaro's gcc 7.3 compiler, using #ifdef (CONFIG_I2C) is not OK. So, replace it by IS_ENABLED(CONFIG_I2C), in order to fix the builds there. Reported-by: kbuild test robot Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-core/dvbdev.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/media/dvb-core/dvbdev.c') diff --git a/drivers/media/dvb-core/dvbdev.c b/drivers/media/dvb-core/dvbdev.c index a840133feacb..cf747d753a79 100644 --- a/drivers/media/dvb-core/dvbdev.c +++ b/drivers/media/dvb-core/dvbdev.c @@ -942,7 +942,7 @@ out: return err; } -#ifdef CONFIG_I2C +#if IS_ENABLED(CONFIG_I2C) struct i2c_client *dvb_module_probe(const char *module_name, const char *name, struct i2c_adapter *adap, -- cgit v1.2.2 From 39adb4e739050dcdb74c3465d261de8de5f224b7 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Thu, 22 Mar 2018 09:01:11 -0400 Subject: media: dvbdev: handle ENOMEM error at dvb_module_probe() If allocation of struct board_info fails, return NULL from dvb_module_probe(). Fix this warning: drivers/media/dvb-core/dvbdev.c:958 dvb_module_probe() error: potential null dereference 'board_info'. (kzalloc returns null) Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-core/dvbdev.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers/media/dvb-core/dvbdev.c') diff --git a/drivers/media/dvb-core/dvbdev.c b/drivers/media/dvb-core/dvbdev.c index cf747d753a79..787fe06df217 100644 --- a/drivers/media/dvb-core/dvbdev.c +++ b/drivers/media/dvb-core/dvbdev.c @@ -953,6 +953,8 @@ struct i2c_client *dvb_module_probe(const char *module_name, struct i2c_board_info *board_info; board_info = kzalloc(sizeof(*board_info), GFP_KERNEL); + if (!board_info) + return NULL; if (name) strlcpy(board_info->type, name, I2C_NAME_SIZE); -- cgit v1.2.2