| Start/ | End/ | |||
| True | False | - | Line | Source |
| 1 | /* i2c-core.c - a device driver for the iic-bus interface */ | |||
| 2 | /* ------------------------------------------------------------------------- */ | |||
| 3 | /* Copyright (C) 1995-99 Simon G. Vogl | |||
| 4 | ||||
| 5 | This program is free software; you can redistribute it and/or modify | |||
| 6 | it under the terms of the GNU General Public License as published by | |||
| 7 | the Free Software Foundation; either version 2 of the License, or | |||
| 8 | (at your option) any later version. | |||
| 9 | ||||
| 10 | This program is distributed in the hope that it will be useful, | |||
| 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
| 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
| 13 | GNU General Public License for more details. | |||
| 14 | ||||
| 15 | You should have received a copy of the GNU General Public License | |||
| 16 | along with this program; if not, write to the Free Software | |||
| 17 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ | |||
| 18 | /* ------------------------------------------------------------------------- */ | |||
| 19 | ||||
| 20 | /* With some changes from Kyösti Mälkki <kmalkki@cc.hut.fi>. | |||
| 21 | All SMBus-related things are written by Frodo Looijaard <frodol@dds.nl> | |||
| 22 | SMBus 2.0 support by Mark Studebaker <mdsxyz123@yahoo.com> and | |||
| 23 | Jean Delvare <khali@linux-fr.org> */ | |||
| 24 | ||||
| 25 | #include <linux/module.h> | |||
| 26 | #include <linux/kernel.h> | |||
| 27 | #include <linux/errno.h> | |||
| 28 | #include <linux/slab.h> | |||
| 29 | #include <linux/i2c.h> | |||
| 30 | #include <linux/init.h> | |||
| 31 | #include <linux/idr.h> | |||
| 32 | #include <linux/seq_file.h> | |||
| 33 | #include <linux/platform_device.h> | |||
| 34 | #include <asm/uaccess.h> | |||
| 35 | ||||
| 36 | ||||
| 37 | static LIST_HEAD(adapters); | |||
| 38 | static LIST_HEAD(drivers); | |||
| 39 | static DECLARE_MUTEX(core_lists); | |||
| 40 | static DEFINE_IDR(i2c_adapter_idr); | |||
| 41 | ||||
| 42 | /* match always succeeds, as we want the probe() to tell if we really accept this match */ | |||
| 0 | 0 | - | 43 | static int i2c_device_match(struct device *dev, struct device_driver *drv) |
| 44 | { | |||
| 0 | - | 45 | return 1; | |
| 46 | } | |||
| 47 | ||||
| 0 | 0 | - | 48 | static int i2c_bus_suspend(struct device * dev, pm_message_t state) |
| 49 | { | |||
| 50 | int rc = 0; | |||
| 51 | ||||
| 0 | 0 | - | 52 | if (dev->driver && dev->driver->suspend) |
| 0 | - | 52 | T && T | |
| 0 | - | 52 | T && F | |
| 0 | - | 52 | F && _ | |
| 53 | rc = dev->driver->suspend(dev, state); | |||
| 0 | - | 54 | return rc; | |
| 55 | } | |||
| 56 | ||||
| 0 | 0 | - | 57 | static int i2c_bus_resume(struct device * dev) |
| 58 | { | |||
| 59 | int rc = 0; | |||
| 60 | ||||
| 0 | 0 | - | 61 | if (dev->driver && dev->driver->resume) |
| 0 | - | 61 | T && T | |
| 0 | - | 61 | T && F | |
| 0 | - | 61 | F && _ | |
| 62 | rc = dev->driver->resume(dev); | |||
| 0 | - | 63 | return rc; | |
| 64 | } | |||
| 65 | ||||
| 0 | 0 | - | 66 | static int i2c_device_probe(struct device *dev) |
| 67 | { | |||
| 0 | - | 68 | return -ENODEV; | |
| 69 | } | |||
| 70 | ||||
| 0 | 0 | - | 71 | static int i2c_device_remove(struct device *dev) |
| 72 | { | |||
| 0 | - | 73 | return 0; | |
| 74 | } | |||
| 75 | ||||
| 76 | struct bus_type i2c_bus_type = { | |||
| 77 | .name = "i2c", | |||
| 78 | .match = i2c_device_match, | |||
| 79 | .probe = i2c_device_probe, | |||
| 80 | .remove = i2c_device_remove, | |||
| 81 | .suspend = i2c_bus_suspend, | |||
| 82 | .resume = i2c_bus_resume, | |||
| 83 | }; | |||
| 84 | ||||
| 0 | 0 | - | 85 | void i2c_adapter_dev_release(struct device *dev) |
| 86 | { | |||
| 87 | struct i2c_adapter *adap = dev_to_i2c_adapter(dev); | |||
| 88 | complete(&adap->dev_released); | |||
| 89 | } | |||
| 90 | ||||
| 91 | struct device_driver i2c_adapter_driver = { | |||
| 92 | .owner = THIS_MODULE, | |||
| 93 | .name = "i2c_adapter", | |||
| 94 | .bus = &i2c_bus_type, | |||
| 95 | }; | |||
| 96 | ||||
| 0 | 0 | - | 97 | static void i2c_adapter_class_dev_release(struct class_device *dev) |
| 98 | { | |||
| 99 | struct i2c_adapter *adap = class_dev_to_i2c_adapter(dev); | |||
| 100 | complete(&adap->class_dev_released); | |||
| 101 | } | |||
| 102 | ||||
| 103 | struct class i2c_adapter_class = { | |||
| 104 | .owner = THIS_MODULE, | |||
| 105 | .name = "i2c-adapter", | |||
| 106 | .release = &i2c_adapter_class_dev_release, | |||
| 107 | }; | |||
| 108 | ||||
| 0 | 0 | - | 109 | static ssize_t show_adapter_name(struct device *dev, struct device_attribute *attr, char *buf) |
| 110 | { | |||
| 111 | struct i2c_adapter *adap = dev_to_i2c_adapter(dev); | |||
| 0 | - | 112 | return sprintf(buf, "%s\n", adap->name); | |
| 113 | } | |||
| 114 | static DEVICE_ATTR(name, S_IRUGO, show_adapter_name, NULL); | |||
| 115 | ||||
| 116 | ||||
| 0 | 0 | - | 117 | static void i2c_client_release(struct device *dev) |
| 118 | { | |||
| 119 | struct i2c_client *client = to_i2c_client(dev); | |||
| 120 | complete(&client->released); | |||
| 121 | } | |||
| 122 | ||||
| 0 | 0 | - | 123 | static ssize_t show_client_name(struct device *dev, struct device_attribute *attr, char *buf) |
| 124 | { | |||
| 125 | struct i2c_client *client = to_i2c_client(dev); | |||
| 0 | - | 126 | return sprintf(buf, "%s\n", client->name); | |
| 127 | } | |||
| 128 | ||||
| 129 | /* | |||
| 130 | * We can't use the DEVICE_ATTR() macro here as we want the same filename for a | |||
| 131 | * different type of a device. So beware if the DEVICE_ATTR() macro ever | |||
| 132 | * changes, this definition will also have to change. | |||
| 133 | */ | |||
| 134 | static struct device_attribute dev_attr_client_name = { | |||
| 135 | .attr = {.name = "name", .mode = S_IRUGO, .owner = THIS_MODULE }, | |||
| 136 | .show = &show_client_name, | |||
| 137 | }; | |||
| 138 | ||||
| 139 | ||||
| 140 | /* --------------------------------------------------- | |||
| 141 | * registering functions | |||
| 142 | * --------------------------------------------------- | |||
| 143 | */ | |||
| 144 | ||||
| 145 | /* ----- | |||
| 146 | * i2c_add_adapter is called from within the algorithm layer, | |||
| 147 | * when a new hw adapter registers. A new device is register to be | |||
| 148 | * available for clients. | |||
| 149 | */ | |||
| 30 | 0 | 150 | int i2c_add_adapter(struct i2c_adapter *adap) | |
| 151 | { | |||
| 152 | int id, res = 0; | |||
| 153 | struct list_head *item; | |||
| 154 | struct i2c_driver *driver; | |||
| 155 | ||||
| 156 | down(&core_lists); | |||
| 157 | ||||
| 0 | 30 | - | 158 | if (idr_pre_get(&i2c_adapter_idr, GFP_KERNEL) == 0) { |
| 159 | res = -ENOMEM; | |||
| 0 | - | 160 | goto out_unlock; | |
| 161 | } | |||
| 162 | ||||
| 163 | res = idr_get_new(&i2c_adapter_idr, adap, &id); | |||
| 0 | 30 | - | 164 | if (res < 0) { |
| 0 | 0 | - | 165 | if (res == -EAGAIN) |
| 166 | res = -ENOMEM; | |||
| 0 | - | 167 | goto out_unlock; | |
| 168 | } | |||
| 169 | ||||
| 170 | adap->nr = id & MAX_ID_MASK; | |||
| 171 | init_MUTEX(&adap->bus_lock); | |||
| 172 | init_MUTEX(&adap->clist_lock); | |||
| 173 | list_add_tail(&adap->list,&adapters); | |||
| 174 | INIT_LIST_HEAD(&adap->clients); | |||
| 175 | ||||
| 176 | /* Add the adapter to the driver core. | |||
| 177 | * If the parent pointer is not set up, | |||
| 178 | * we add this adapter to the host bus. | |||
| 179 | */ | |||
| 0 | 30 | - | 180 | if (adap->dev.parent == NULL) |
| 181 | adap->dev.parent = &platform_bus; | |||
| 182 | sprintf(adap->dev.bus_id, "i2c-%d", adap->nr); | |||
| 183 | adap->dev.driver = &i2c_adapter_driver; | |||
| 184 | adap->dev.release = &i2c_adapter_dev_release; | |||
| 185 | device_register(&adap->dev); | |||
| 186 | device_create_file(&adap->dev, &dev_attr_name); | |||
| 187 | ||||
| 188 | /* Add this adapter to the i2c_adapter class */ | |||
| 189 | memset(&adap->class_dev, 0x00, sizeof(struct class_device)); | |||
| 190 | adap->class_dev.dev = &adap->dev; | |||
| 191 | adap->class_dev.class = &i2c_adapter_class; | |||
| 192 | strlcpy(adap->class_dev.class_id, adap->dev.bus_id, BUS_ID_SIZE); | |||
| 193 | class_device_register(&adap->class_dev); | |||
| 194 | ||||
| 195 | dev_dbg(&adap->dev, "adapter [%s] registered\n", adap->name); | |||
| 30 | 0 | - | 195 | ternary-?: ( & adap -> dev ) -> driver |
| 196 | ||||
| 197 | /* inform drivers of new adapters */ | |||
| 54 | 30 | 198 | list_for_each(item,&drivers) { | |
| 199 | driver = list_entry(item, struct i2c_driver, list); | |||
| 54 | 0 | - | 200 | if (driver->attach_adapter) |
| 201 | /* We ignore the return code; if it fails, too bad */ | |||
| 202 | driver->attach_adapter(adap); | |||
| 203 | } | |||
| 204 | ||||
| 205 | out_unlock: | |||
| 206 | up(&core_lists); | |||
| 30 | 207 | return res; | ||
| 208 | } | |||
| 209 | ||||
| 210 | ||||
| 0 | 0 | - | 211 | int i2c_del_adapter(struct i2c_adapter *adap) |
| 212 | { | |||
| 213 | struct list_head *item, *_n; | |||
| 214 | struct i2c_adapter *adap_from_list; | |||
| 215 | struct i2c_driver *driver; | |||
| 216 | struct i2c_client *client; | |||
| 217 | int res = 0; | |||
| 218 | ||||
| 219 | down(&core_lists); | |||
| 220 | ||||
| 221 | /* First make sure that this adapter was ever added */ | |||
| 0 | 0 | - | 222 | list_for_each_entry(adap_from_list, &adapters, list) { |
| 0 | 0 | - | 223 | if (adap_from_list == adap) |
| 0 | - | 224 | break; | |
| 225 | } | |||
| 0 | 0 | - | 226 | if (adap_from_list != adap) { |
| 227 | pr_debug("i2c-core: attempting to delete unregistered " | |||
| 228 | "adapter [%s]\n", adap->name); | |||
| 229 | res = -EINVAL; | |||
| 0 | - | 230 | goto out_unlock; | |
| 231 | } | |||
| 232 | ||||
| 0 | 0 | - | 233 | list_for_each(item,&drivers) { |
| 234 | driver = list_entry(item, struct i2c_driver, list); | |||
| 0 | 0 | - | 235 | if (driver->detach_adapter) |
| 0 | 0 | - | 236 | if ((res = driver->detach_adapter(adap))) { |
| 237 | dev_err(&adap->dev, "detach_adapter failed " | |||
| 0 | 0 | - | 237 | ternary-?: ( & adap -> dev ) -> driver |
| 238 | "for driver [%s]\n", | |||
| 239 | driver->driver.name); | |||
| 0 | - | 240 | goto out_unlock; | |
| 241 | } | |||
| 242 | } | |||
| 243 | ||||
| 244 | /* detach any active clients. This must be done first, because | |||
| 245 | * it can fail; in which case we give up. */ | |||
| 0 | 0 | - | 246 | list_for_each_safe(item, _n, &adap->clients) { |
| 247 | client = list_entry(item, struct i2c_client, list); | |||
| 248 | ||||
| 0 | 0 | - | 249 | if ((res=client->driver->detach_client(client))) { |
| 250 | dev_err(&adap->dev, "detach_client failed for client " | |||
| 0 | 0 | - | 250 | ternary-?: ( & adap -> dev ) -> driver |
| 251 | "[%s] at address 0x%02x\n", client->name, | |||
| 252 | client->addr); | |||
| 0 | - | 253 | goto out_unlock; | |
| 254 | } | |||
| 255 | } | |||
| 256 | ||||
| 257 | /* clean up the sysfs representation */ | |||
| 258 | init_completion(&adap->dev_released); | |||
| 259 | init_completion(&adap->class_dev_released); | |||
| 260 | class_device_unregister(&adap->class_dev); | |||
| 261 | device_remove_file(&adap->dev, &dev_attr_name); | |||
| 262 | device_unregister(&adap->dev); | |||
| 263 | list_del(&adap->list); | |||
| 264 | ||||
| 265 | /* wait for sysfs to drop all references */ | |||
| 266 | wait_for_completion(&adap->dev_released); | |||
| 267 | wait_for_completion(&adap->class_dev_released); | |||
| 268 | ||||
| 269 | /* free dynamically allocated bus id */ | |||
| 270 | idr_remove(&i2c_adapter_idr, adap->nr); | |||
| 271 | ||||
| 272 | dev_dbg(&adap->dev, "adapter [%s] unregistered\n", adap->name); | |||
| 0 | 0 | - | 272 | ternary-?: ( & adap -> dev ) -> driver |
| 273 | ||||
| 274 | out_unlock: | |||
| 275 | up(&core_lists); | |||
| 0 | - | 276 | return res; | |
| 277 | } | |||
| 278 | ||||
| 279 | ||||
| 280 | /* ----- | |||
| 281 | * What follows is the "upwards" interface: commands for talking to clients, | |||
| 282 | * which implement the functions to access the physical information of the | |||
| 283 | * chips. | |||
| 284 | */ | |||
| 285 | ||||
| 54 | 0 | 286 | int i2c_register_driver(struct module *owner, struct i2c_driver *driver) | |
| 287 | { | |||
| 288 | struct list_head *item; | |||
| 289 | struct i2c_adapter *adapter; | |||
| 290 | int res = 0; | |||
| 291 | ||||
| 292 | down(&core_lists); | |||
| 293 | ||||
| 294 | /* add the driver to the list of i2c drivers in the driver core */ | |||
| 295 | driver->driver.owner = owner; | |||
| 296 | driver->driver.bus = &i2c_bus_type; | |||
| 297 | ||||
| 298 | res = driver_register(&driver->driver); | |||
| 0 | 54 | - | 299 | if (res) |
| 0 | - | 300 | goto out_unlock; | |
| 301 | ||||
| 302 | list_add_tail(&driver->list,&drivers); | |||
| 303 | pr_debug("i2c-core: driver [%s] registered\n", driver->driver.name); | |||
| 304 | ||||
| 305 | /* now look for instances of driver on our adapters */ | |||
| 54 | 0 | - | 306 | if (driver->attach_adapter) { |
| 216 | 54 | 307 | list_for_each(item,&adapters) { | |
| 308 | adapter = list_entry(item, struct i2c_adapter, list); | |||
| 309 | driver->attach_adapter(adapter); | |||
| 310 | } | |||
| 311 | } | |||
| 312 | ||||
| 313 | out_unlock: | |||
| 314 | up(&core_lists); | |||
| 54 | 315 | return res; | ||
| 316 | } | |||
| 317 | EXPORT_SYMBOL(i2c_register_driver); | |||
| 318 | ||||
| 0 | 0 | - | 319 | int i2c_del_driver(struct i2c_driver *driver) |
| 320 | { | |||
| 321 | struct list_head *item1, *item2, *_n; | |||
| 322 | struct i2c_client *client; | |||
| 323 | struct i2c_adapter *adap; | |||
| 324 | ||||
| 325 | int res = 0; | |||
| 326 | ||||
| 327 | down(&core_lists); | |||
| 328 | ||||
| 329 | /* Have a look at each adapter, if clients of this driver are still | |||
| 330 | * attached. If so, detach them to be able to kill the driver | |||
| 331 | * afterwards. | |||
| 332 | */ | |||
| 0 | 0 | - | 333 | list_for_each(item1,&adapters) { |
| 334 | adap = list_entry(item1, struct i2c_adapter, list); | |||
| 0 | 0 | - | 335 | if (driver->detach_adapter) { |
| 0 | 0 | - | 336 | if ((res = driver->detach_adapter(adap))) { |
| 337 | dev_err(&adap->dev, "detach_adapter failed " | |||
| 0 | 0 | - | 337 | ternary-?: ( & adap -> dev ) -> driver |
| 338 | "for driver [%s]\n", | |||
| 339 | driver->driver.name); | |||
| 0 | - | 340 | goto out_unlock; | |
| 341 | } | |||
| 342 | } else { | |||
| 0 | 0 | - | 343 | list_for_each_safe(item2, _n, &adap->clients) { |
| 344 | client = list_entry(item2, struct i2c_client, list); | |||
| 0 | 0 | - | 345 | if (client->driver != driver) |
| 0 | - | 346 | continue; | |
| 347 | dev_dbg(&adap->dev, "detaching client [%s] " | |||
| 0 | 0 | - | 347 | ternary-?: ( & adap -> dev ) -> driver |
| 348 | "at 0x%02x\n", client->name, | |||
| 349 | client->addr); | |||
| 0 | 0 | - | 350 | if ((res = driver->detach_client(client))) { |
| 351 | dev_err(&adap->dev, "detach_client " | |||
| 0 | 0 | - | 351 | ternary-?: ( & adap -> dev ) -> driver |
| 352 | "failed for client [%s] at " | |||
| 353 | "0x%02x\n", client->name, | |||
| 354 | client->addr); | |||
| 0 | - | 355 | goto out_unlock; | |
| 356 | } | |||
| 357 | } | |||
| 358 | } | |||
| 359 | } | |||
| 360 | ||||
| 361 | driver_unregister(&driver->driver); | |||
| 362 | list_del(&driver->list); | |||
| 363 | pr_debug("i2c-core: driver [%s] unregistered\n", driver->driver.name); | |||
| 364 | ||||
| 365 | out_unlock: | |||
| 366 | up(&core_lists); | |||
| 0 | - | 367 | return 0; | |
| 368 | } | |||
| 369 | ||||
| 0 | 0 | - | 370 | static int __i2c_check_addr(struct i2c_adapter *adapter, unsigned int addr) |
| 371 | { | |||
| 372 | struct list_head *item; | |||
| 373 | struct i2c_client *client; | |||
| 374 | ||||
| 0 | 0 | - | 375 | list_for_each(item,&adapter->clients) { |
| 376 | client = list_entry(item, struct i2c_client, list); | |||
| 0 | 0 | - | 377 | if (client->addr == addr) |
| 0 | - | 378 | return -EBUSY; | |
| 379 | } | |||
| 0 | - | 380 | return 0; | |
| 381 | } | |||
| 382 | ||||
| 0 | 0 | - | 383 | int i2c_check_addr(struct i2c_adapter *adapter, int addr) |
| 384 | { | |||
| 385 | int rval; | |||
| 386 | ||||
| 387 | down(&adapter->clist_lock); | |||
| 388 | rval = __i2c_check_addr(adapter, addr); | |||
| 389 | up(&adapter->clist_lock); | |||
| 390 | ||||
| 0 | - | 391 | return rval; | |
| 392 | } | |||
| 393 | ||||
| 0 | 0 | - | 394 | int i2c_attach_client(struct i2c_client *client) |
| 395 | { | |||
| 396 | struct i2c_adapter *adapter = client->adapter; | |||
| 397 | ||||
| 398 | down(&adapter->clist_lock); | |||
| 0 | 0 | - | 399 | if (__i2c_check_addr(client->adapter, client->addr)) { |
| 400 | up(&adapter->clist_lock); | |||
| 0 | - | 401 | return -EBUSY; | |
| 402 | } | |||
| 403 | list_add_tail(&client->list,&adapter->clients); | |||
| 404 | up(&adapter->clist_lock); | |||
| 405 | ||||
| 0 | 0 | - | 406 | if (adapter->client_register) { |
| 0 | 0 | - | 407 | if (adapter->client_register(client)) { |
| 408 | dev_dbg(&adapter->dev, "client_register " | |||
| 0 | 0 | - | 408 | ternary-?: ( & adapter -> dev ) -> driver |
| 409 | "failed for client [%s] at 0x%02x\n", | |||
| 410 | client->name, client->addr); | |||
| 411 | } | |||
| 412 | } | |||
| 413 | ||||
| 414 | client->usage_count = 0; | |||
| 415 | ||||
| 416 | client->dev.parent = &client->adapter->dev; | |||
| 417 | client->dev.driver = &client->driver->driver; | |||
| 418 | client->dev.bus = &i2c_bus_type; | |||
| 419 | client->dev.release = &i2c_client_release; | |||
| 420 | ||||
| 421 | snprintf(&client->dev.bus_id[0], sizeof(client->dev.bus_id), | |||
| 422 | "%d-%04x", i2c_adapter_id(adapter), client->addr); | |||
| 423 | dev_dbg(&adapter->dev, "client [%s] registered with bus id %s\n", | |||
| 0 | 0 | - | 423 | ternary-?: ( & adapter -> dev ) -> driver |
| 424 | client->name, client->dev.bus_id); | |||
| 425 | device_register(&client->dev); | |||
| 426 | device_create_file(&client->dev, &dev_attr_client_name); | |||
| 427 | ||||
| 0 | - | 428 | return 0; | |
| 429 | } | |||
| 430 | ||||
| 431 | ||||
| 0 | 0 | - | 432 | int i2c_detach_client(struct i2c_client *client) |
| 433 | { | |||
| 434 | struct i2c_adapter *adapter = client->adapter; | |||
| 435 | int res = 0; | |||
| 436 | ||||
| 0 | 0 | - | 437 | if (client->usage_count > 0) { |
| 438 | dev_warn(&client->dev, "Client [%s] still busy, " | |||
| 0 | 0 | - | 438 | ternary-?: ( & client -> dev ) -> driver |
| 439 | "can't detach\n", client->name); | |||
| 0 | - | 440 | return -EBUSY; | |
| 441 | } | |||
| 442 | ||||
| 0 | 0 | - | 443 | if (adapter->client_unregister) { |
| 444 | res = adapter->client_unregister(client); | |||
| 0 | 0 | - | 445 | if (res) { |
| 446 | dev_err(&client->dev, | |||
| 0 | 0 | - | 446 | ternary-?: ( & client -> dev ) -> driver |
| 447 | "client_unregister [%s] failed, " | |||
| 448 | "client not detached\n", client->name); | |||
| 0 | - | 449 | goto out; | |
| 450 | } | |||
| 451 | } | |||
| 452 | ||||
| 453 | down(&adapter->clist_lock); | |||
| 454 | list_del(&client->list); | |||
| 455 | init_completion(&client->released); | |||
| 456 | device_remove_file(&client->dev, &dev_attr_client_name); | |||
| 457 | device_unregister(&client->dev); | |||
| 458 | up(&adapter->clist_lock); | |||
| 459 | wait_for_completion(&client->released); | |||
| 460 | ||||
| 461 | out: | |||
| 0 | - | 462 | return res; | |
| 463 | } | |||
| 464 | ||||
| 0 | 0 | - | 465 | static int i2c_inc_use_client(struct i2c_client *client) |
| 466 | { | |||
| 467 | ||||
| 0 | 0 | - | 468 | if (!try_module_get(client->driver->driver.owner)) |
| 0 | - | 469 | return -ENODEV; | |
| 0 | 0 | - | 470 | if (!try_module_get(client->adapter->owner)) { |
| 471 | module_put(client->driver->driver.owner); | |||
| 0 | - | 472 | return -ENODEV; | |
| 473 | } | |||
| 474 | ||||
| 0 | - | 475 | return 0; | |
| 476 | } | |||
| 477 | ||||
| 0 | 0 | - | 478 | static void i2c_dec_use_client(struct i2c_client *client) |
| 479 | { | |||
| 480 | module_put(client->driver->driver.owner); | |||
| 481 | module_put(client->adapter->owner); | |||
| 482 | } | |||
| 483 | ||||
| 0 | 0 | - | 484 | int i2c_use_client(struct i2c_client *client) |
| 485 | { | |||
| 486 | int ret; | |||
| 487 | ||||
| 488 | ret = i2c_inc_use_client(client); | |||
| 0 | 0 | - | 489 | if (ret) |
| 0 | - | 490 | return ret; | |
| 491 | ||||
| 492 | client->usage_count++; | |||
| 493 | ||||
| 0 | - | 494 | return 0; | |
| 495 | } | |||
| 496 | ||||
| 0 | 0 | - | 497 | int i2c_release_client(struct i2c_client *client) |
| 498 | { | |||
| 0 | 0 | - | 499 | if (!client->usage_count) { |
| 500 | pr_debug("i2c-core: %s used one too many times\n", | |||
| 501 | __FUNCTION__); | |||
| 0 | - | 502 | return -EPERM; | |
| 503 | } | |||
| 504 | ||||
| 505 | client->usage_count--; | |||
| 506 | i2c_dec_use_client(client); | |||
| 507 | ||||
| 0 | - | 508 | return 0; | |
| 509 | } | |||
| 510 | ||||
| 0 | 0 | - | 511 | void i2c_clients_command(struct i2c_adapter *adap, unsigned int cmd, void *arg) |
| 512 | { | |||
| 513 | struct list_head *item; | |||
| 514 | struct i2c_client *client; | |||
| 515 | ||||
| 516 | down(&adap->clist_lock); | |||
| 0 | 0 | - | 517 | list_for_each(item,&adap->clients) { |
| 518 | client = list_entry(item, struct i2c_client, list); | |||
| 0 | 0 | - | 519 | if (!try_module_get(client->driver->driver.owner)) |
| 0 | - | 520 | continue; | |
| 0 | 0 | - | 521 | if (NULL != client->driver->command) { |
| 522 | up(&adap->clist_lock); | |||
| 523 | client->driver->command(client,cmd,arg); | |||
| 524 | down(&adap->clist_lock); | |||