Commit bd4217d8c6ef48425c8d6b28d2e089a83e01af04
Committed by
Jean Delvare
1 parent
907135aaa0
Exists in
master
and in
7 other branches
i2c-dev: Unbound new-style i2c clients aren't busy
Let i2c-dev deal properly with new-style i2c clients. Instead of considering them always busy, it needs to check wether a driver is bound to them or not. This is still not completely correct, as the client could become busy later, but the same problem already existed before new-style clients were introduced. We'll want to fix it someday. Signed-off-by: Jean Delvare <khali@linux-fr.org> Acked-by: David Brownell <dbrownell@users.sourceforge.net>
Showing 1 changed file with 25 additions and 1 deletions Side-by-side Diff
drivers/i2c/i2c-dev.c
... | ... | @@ -182,6 +182,29 @@ |
182 | 182 | return ret; |
183 | 183 | } |
184 | 184 | |
185 | +/* This address checking function differs from the one in i2c-core | |
186 | + in that it considers an address with a registered device, but no | |
187 | + bounded driver, as NOT busy. */ | |
188 | +static int i2cdev_check_addr(struct i2c_adapter *adapter, unsigned int addr) | |
189 | +{ | |
190 | + struct list_head *item; | |
191 | + struct i2c_client *client; | |
192 | + int res = 0; | |
193 | + | |
194 | + mutex_lock(&adapter->clist_lock); | |
195 | + list_for_each(item, &adapter->clients) { | |
196 | + client = list_entry(item, struct i2c_client, list); | |
197 | + if (client->addr == addr) { | |
198 | + if (client->driver) | |
199 | + res = -EBUSY; | |
200 | + break; | |
201 | + } | |
202 | + } | |
203 | + mutex_unlock(&adapter->clist_lock); | |
204 | + | |
205 | + return res; | |
206 | +} | |
207 | + | |
185 | 208 | static int i2cdev_ioctl(struct inode *inode, struct file *file, |
186 | 209 | unsigned int cmd, unsigned long arg) |
187 | 210 | { |
188 | 211 | |
... | ... | @@ -213,8 +236,9 @@ |
213 | 236 | if ((arg > 0x3ff) || |
214 | 237 | (((client->flags & I2C_M_TEN) == 0) && arg > 0x7f)) |
215 | 238 | return -EINVAL; |
216 | - if ((cmd == I2C_SLAVE) && i2c_check_addr(client->adapter,arg)) | |
239 | + if (cmd == I2C_SLAVE && i2cdev_check_addr(client->adapter, arg)) | |
217 | 240 | return -EBUSY; |
241 | + /* REVISIT: address could become busy later */ | |
218 | 242 | client->addr = arg; |
219 | 243 | return 0; |
220 | 244 | case I2C_TENBIT: |