i2c: __must_check fixes (core drivers)
[pandora-kernel.git] / drivers / i2c / busses / i2c-isa.c
1 /*
2     i2c-isa.c - an i2c-core-like thing for ISA hardware monitoring chips
3     Copyright (C) 2005  Jean Delvare <khali@linux-fr.org>
4
5     Based on the i2c-isa pseudo-adapter from the lm_sensors project
6     Copyright (c) 1998, 1999  Frodo Looijaard <frodol@dds.nl> 
7
8     This program is free software; you can redistribute it and/or modify
9     it under the terms of the GNU General Public License as published by
10     the Free Software Foundation; either version 2 of the License, or
11     (at your option) any later version.
12
13     This program is distributed in the hope that it will be useful,
14     but WITHOUT ANY WARRANTY; without even the implied warranty of
15     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16     GNU General Public License for more details.
17
18     You should have received a copy of the GNU General Public License
19     along with this program; if not, write to the Free Software
20     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 */
22
23 /* This implements an i2c-core-like thing for ISA hardware monitoring
24    chips. Such chips are linked to the i2c subsystem for historical
25    reasons (because the early ISA hardware monitoring chips such as the
26    LM78 had both an I2C and an ISA interface). They used to be
27    registered with the main i2c-core, but as a first step in the
28    direction of a clean separation between I2C and ISA chip drivers,
29    we now have this separate core for ISA ones. It is significantly
30    more simple than the real one, of course, because we don't have to
31    handle multiple busses: there is only one (fake) ISA adapter.
32    It is worth noting that we still rely on i2c-core for some things
33    at the moment - but hopefully this won't last. */
34
35 #include <linux/init.h>
36 #include <linux/module.h>
37 #include <linux/kernel.h>
38 #include <linux/errno.h>
39 #include <linux/i2c.h>
40 #include <linux/i2c-isa.h>
41 #include <linux/platform_device.h>
42
43 static u32 isa_func(struct i2c_adapter *adapter);
44
45 /* This is the actual algorithm we define */
46 static struct i2c_algorithm isa_algorithm = {
47         .functionality  = isa_func,
48 };
49
50 /* There can only be one... */
51 static struct i2c_adapter isa_adapter = {
52         .owner          = THIS_MODULE,
53         .id             = I2C_HW_ISA,
54         .class          = I2C_CLASS_HWMON,
55         .algo           = &isa_algorithm,
56         .name           = "ISA main adapter",
57 };
58
59 /* We can't do a thing... */
60 static u32 isa_func(struct i2c_adapter *adapter)
61 {
62         return 0;
63 }
64
65
66 /* Copied from i2c-core */
67 static ssize_t show_adapter_name(struct device *dev,
68                 struct device_attribute *attr, char *buf)
69 {
70         struct i2c_adapter *adap = dev_to_i2c_adapter(dev);
71         return sprintf(buf, "%s\n", adap->name);
72 }
73 static DEVICE_ATTR(name, S_IRUGO, show_adapter_name, NULL);
74
75
76 /* We implement an interface which resembles i2c_{add,del}_driver,
77    but for i2c-isa drivers. We don't have to remember and handle lists
78    of drivers and adapters so this is much more simple, of course. */
79
80 int i2c_isa_add_driver(struct i2c_driver *driver)
81 {
82         int res;
83
84         /* Add the driver to the list of i2c drivers in the driver core */
85         driver->driver.bus = &i2c_bus_type;
86         res = driver_register(&driver->driver);
87         if (res)
88                 return res;
89         dev_dbg(&isa_adapter.dev, "Driver %s registered\n", driver->driver.name);
90
91         /* Now look for clients */
92         driver->attach_adapter(&isa_adapter);
93
94         return 0;
95 }
96
97 int i2c_isa_del_driver(struct i2c_driver *driver)
98 {
99         struct list_head *item, *_n;
100         struct i2c_client *client;
101         int res;
102
103         /* Detach all clients belonging to this one driver */
104         list_for_each_safe(item, _n, &isa_adapter.clients) {
105                 client = list_entry(item, struct i2c_client, list);
106                 if (client->driver != driver)
107                         continue;
108                 dev_dbg(&isa_adapter.dev, "Detaching client %s at 0x%x\n",
109                         client->name, client->addr);
110                 if ((res = driver->detach_client(client))) {
111                         dev_err(&isa_adapter.dev, "Failed, driver "
112                                 "%s not unregistered!\n",
113                                 driver->driver.name);
114                         return res;
115                 }
116         }
117
118         /* Get the driver off the core list */
119         driver_unregister(&driver->driver);
120         dev_dbg(&isa_adapter.dev, "Driver %s unregistered\n", driver->driver.name);
121
122         return 0;
123 }
124
125
126 static int __init i2c_isa_init(void)
127 {
128         int err;
129
130         mutex_init(&isa_adapter.clist_lock);
131         INIT_LIST_HEAD(&isa_adapter.clients);
132
133         isa_adapter.nr = ANY_I2C_ISA_BUS;
134         isa_adapter.dev.parent = &platform_bus;
135         sprintf(isa_adapter.dev.bus_id, "i2c-%d", isa_adapter.nr);
136         isa_adapter.dev.driver = &i2c_adapter_driver;
137         isa_adapter.dev.release = &i2c_adapter_dev_release;
138         err = device_register(&isa_adapter.dev);
139         if (err) {
140                 printk(KERN_ERR "i2c-isa: Failed to register device\n");
141                 goto exit;
142         }
143         err = device_create_file(&isa_adapter.dev, &dev_attr_name);
144         if (err) {
145                 printk(KERN_ERR "i2c-isa: Failed to create name file\n");
146                 goto exit_unregister;
147         }
148
149         /* Add this adapter to the i2c_adapter class */
150         memset(&isa_adapter.class_dev, 0x00, sizeof(struct class_device));
151         isa_adapter.class_dev.dev = &isa_adapter.dev;
152         isa_adapter.class_dev.class = &i2c_adapter_class;
153         strlcpy(isa_adapter.class_dev.class_id, isa_adapter.dev.bus_id,
154                 BUS_ID_SIZE);
155         err = class_device_register(&isa_adapter.class_dev);
156         if (err) {
157                 printk(KERN_ERR "i2c-isa: Failed to register class device\n");
158                 goto exit_remove_name;
159         }
160
161         dev_dbg(&isa_adapter.dev, "%s registered\n", isa_adapter.name);
162
163         return 0;
164
165 exit_remove_name:
166         device_remove_file(&isa_adapter.dev, &dev_attr_name);
167 exit_unregister:
168         init_completion(&isa_adapter.dev_released); /* Needed? */
169         device_unregister(&isa_adapter.dev);
170         wait_for_completion(&isa_adapter.dev_released);
171 exit:
172         return err;
173 }
174
175 static void __exit i2c_isa_exit(void)
176 {
177 #ifdef DEBUG
178         struct list_head  *item, *_n;
179         struct i2c_client *client = NULL;
180 #endif
181
182         /* There should be no more active client */
183 #ifdef DEBUG
184         dev_dbg(&isa_adapter.dev, "Looking for clients\n");
185         list_for_each_safe(item, _n, &isa_adapter.clients) {
186                 client = list_entry(item, struct i2c_client, list);
187                 dev_err(&isa_adapter.dev, "Driver %s still has an active "
188                         "ISA client at 0x%x\n", client->driver->driver.name,
189                         client->addr);
190         }
191         if (client != NULL)
192                 return;
193 #endif
194
195         /* Clean up the sysfs representation */
196         dev_dbg(&isa_adapter.dev, "Unregistering from sysfs\n");
197         init_completion(&isa_adapter.dev_released);
198         init_completion(&isa_adapter.class_dev_released);
199         class_device_unregister(&isa_adapter.class_dev);
200         device_remove_file(&isa_adapter.dev, &dev_attr_name);
201         device_unregister(&isa_adapter.dev);
202
203         /* Wait for sysfs to drop all references */
204         dev_dbg(&isa_adapter.dev, "Waiting for sysfs completion\n");
205         wait_for_completion(&isa_adapter.dev_released);
206         wait_for_completion(&isa_adapter.class_dev_released);
207
208         dev_dbg(&isa_adapter.dev, "%s unregistered\n", isa_adapter.name);
209 }
210
211 EXPORT_SYMBOL(i2c_isa_add_driver);
212 EXPORT_SYMBOL(i2c_isa_del_driver);
213
214 MODULE_AUTHOR("Jean Delvare <khali@linux-fr.org>");
215 MODULE_DESCRIPTION("ISA bus access through i2c");
216 MODULE_LICENSE("GPL");
217
218 module_init(i2c_isa_init);
219 module_exit(i2c_isa_exit);