From: "Émeric Vigier" <emeric.vigier-4ysUXcep3aM1wj+D4I0NRVaTQe2KTcn/@public.gmane.org>
To: linux-i2c-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
Subject: how to gracefully unload an i2c driver if chip not detected?
Date: Mon, 18 Mar 2013 10:47:26 -0400 (EDT) [thread overview]
Message-ID: <35709576.270615.1363618046395.JavaMail.root@mail> (raw)
In-Reply-To: <931575758.126890.1363615027376.JavaMail.root@mail>
Hi,
I work on an omap platform running linux 3.0.21. The kernel image embeds two built-in i2c drivers for two different proximity sensors.
The hardware platform embeds only one sensor, so there is a detection mechanism of which chip is present in each driver (code below).
I recently changed the sensor on my board. Leading to kernel crash when entering suspend.
Thanks to "no_console_suspend" cmdline argument, I found out that the suspend function of the "absent" chip gets called. It tries to take a mutex which has been freed in probe's "device not found" fallback code. Leading to kernel panic.
I naively tried to add "i2c_del_driver(&vcnl4010_driver);" in the driver's probe function.
But it triggers a null ptr deref in i2c_do_del_adapter().
How can I gracefully unload this i2c driver if chip is not detected, while keeping this driver built-in in the kernel?
What is the recommended method to do just that?
Thanks,
Emeric
---------
static struct i2c_driver vcnl4010_driver;
static int __devinit vcnl4010_driver_probe(struct i2c_client *client, const struct i2c_device_id *id)
{
[...]
if(vcnl4010_read_transfer(data, VCNL4010_PROD_ID_VER, ®_val, 1) !=0 )
{
pr_err("vcnl4010: Device not found!");
goto nochip;
}
if(reg_val != 0x21)
{
pr_err("vcnl4010: Found device isn't a vcnl4010, is a vcnl4000 installed?");
goto badchip;
}
[...]
badchip:
nochip:
input_unregister_device(data->input_dev);
dev_register_error:
input_free_device(data->input_dev);
dev_allocate_error:
mutex_destroy(&data->lock);
kfree(data);
error:
/* i2c_del_driver(&vcnl4010_driver); triggers NULL ptr deref in i2c_do_del_adapter() */
return ret;
}
static int vcnl4010_driver_suspend(struct device *dev)
{
struct platform_device *pdev = to_platform_device(dev);
struct vcnl4010_data *data = platform_get_drvdata(pdev);
mutex_lock(&data->lock); /* panic kernel if chip is not present */
vcnl4010_write(data, VCNL4010_CMD_REG, 0x00);
vcnl4010_write(data, VCNL4010_IR_LED_CURR, 0);
mutex_unlock(&data->lock);
return 0;
}
static struct i2c_driver vcnl4010_driver = {
.probe = vcnl4010_driver_probe,
.remove = vcnl4010_driver_remove,
.id_table = vcnl4010_idtable,
.driver = {
.name = DRIVER_NAME,
#ifdef CONFIG_PM
.pm = &vcnl4010_pm_ops,
#endif
},
};
next parent reply other threads:[~2013-03-18 14:47 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
[not found] <931575758.126890.1363615027376.JavaMail.root@mail>
2013-03-18 14:47 ` Émeric Vigier [this message]
2013-04-09 9:26 ` how to gracefully unload an i2c driver if chip not detected? Wolfram Sang
[not found] ` <20130409092625.GD3624-z923LK4zBo2bacvFa/9K2g@public.gmane.org>
2013-04-21 3:38 ` Émeric Vigier
2013-04-21 15:48 ` Wolfram Sang
[not found] ` <20130421154832.GA9593-z923LK4zBo2bacvFa/9K2g@public.gmane.org>
2013-04-22 11:18 ` Émeric Vigier
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=35709576.270615.1363618046395.JavaMail.root@mail \
--to=emeric.vigier-4ysuxcep3am1wj+d4i0nrvatqe2ktcn/@public.gmane.org \
--cc=linux-i2c-u79uwXL29TY76Z2rM5mHXA@public.gmane.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.