Create platform_device.h to contain all the platform device details.
[deliverable/linux.git] / drivers / i2c / busses / i2c-isa.c
CommitLineData
1da177e4 1/*
400c455e
JD
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
1da177e4
LT
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
400c455e
JD
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. */
1da177e4 34
1da177e4
LT
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>
400c455e 40#include <linux/i2c-isa.h>
d052d1be 41#include <linux/platform_device.h>
1da177e4
LT
42
43static u32 isa_func(struct i2c_adapter *adapter);
44
45/* This is the actual algorithm we define */
46static struct i2c_algorithm isa_algorithm = {
1da177e4
LT
47 .functionality = isa_func,
48};
49
50/* There can only be one... */
51static struct i2c_adapter isa_adapter = {
52 .owner = THIS_MODULE,
c7a46533 53 .id = I2C_HW_ISA,
1da177e4
LT
54 .class = I2C_CLASS_HWMON,
55 .algo = &isa_algorithm,
56 .name = "ISA main adapter",
57};
58
59/* We can't do a thing... */
60static u32 isa_func(struct i2c_adapter *adapter)
61{
62 return 0;
63}
64
400c455e
JD
65
66/* Copied from i2c-core */
67static 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}
73static DEVICE_ATTR(name, S_IRUGO, show_adapter_name, NULL);
74
75static int i2c_isa_device_probe(struct device *dev)
76{
77 return -ENODEV;
78}
79
80static int i2c_isa_device_remove(struct device *dev)
81{
82 return 0;
83}
84
85
86/* We implement an interface which resembles i2c_{add,del}_driver,
87 but for i2c-isa drivers. We don't have to remember and handle lists
88 of drivers and adapters so this is much more simple, of course. */
89
90int i2c_isa_add_driver(struct i2c_driver *driver)
91{
92 int res;
93
94 /* Add the driver to the list of i2c drivers in the driver core */
95 driver->driver.name = driver->name;
1747ef1b 96 driver->driver.owner = driver->owner;
400c455e
JD
97 driver->driver.bus = &i2c_bus_type;
98 driver->driver.probe = i2c_isa_device_probe;
99 driver->driver.remove = i2c_isa_device_remove;
100 res = driver_register(&driver->driver);
101 if (res)
102 return res;
103 dev_dbg(&isa_adapter.dev, "Driver %s registered\n", driver->name);
104
105 /* Now look for clients */
106 driver->attach_adapter(&isa_adapter);
107
108 return 0;
109}
110
111int i2c_isa_del_driver(struct i2c_driver *driver)
112{
113 struct list_head *item, *_n;
114 struct i2c_client *client;
115 int res;
116
117 /* Detach all clients belonging to this one driver */
118 list_for_each_safe(item, _n, &isa_adapter.clients) {
119 client = list_entry(item, struct i2c_client, list);
120 if (client->driver != driver)
121 continue;
122 dev_dbg(&isa_adapter.dev, "Detaching client %s at 0x%x\n",
123 client->name, client->addr);
124 if ((res = driver->detach_client(client))) {
125 dev_err(&isa_adapter.dev, "Failed, driver "
126 "%s not unregistered!\n",
127 driver->name);
128 return res;
129 }
130 }
131
132 /* Get the driver off the core list */
133 driver_unregister(&driver->driver);
134 dev_dbg(&isa_adapter.dev, "Driver %s unregistered\n", driver->name);
135
136 return 0;
137}
138
139
1da177e4
LT
140static int __init i2c_isa_init(void)
141{
400c455e
JD
142 init_MUTEX(&isa_adapter.clist_lock);
143 INIT_LIST_HEAD(&isa_adapter.clients);
144
145 isa_adapter.nr = ANY_I2C_ISA_BUS;
146 isa_adapter.dev.parent = &platform_bus;
147 sprintf(isa_adapter.dev.bus_id, "i2c-%d", isa_adapter.nr);
148 isa_adapter.dev.driver = &i2c_adapter_driver;
149 isa_adapter.dev.release = &i2c_adapter_dev_release;
150 device_register(&isa_adapter.dev);
151 device_create_file(&isa_adapter.dev, &dev_attr_name);
152
153 /* Add this adapter to the i2c_adapter class */
154 memset(&isa_adapter.class_dev, 0x00, sizeof(struct class_device));
155 isa_adapter.class_dev.dev = &isa_adapter.dev;
156 isa_adapter.class_dev.class = &i2c_adapter_class;
157 strlcpy(isa_adapter.class_dev.class_id, isa_adapter.dev.bus_id,
158 BUS_ID_SIZE);
159 class_device_register(&isa_adapter.class_dev);
160
161 dev_dbg(&isa_adapter.dev, "%s registered\n", isa_adapter.name);
162
163 return 0;
1da177e4
LT
164}
165
166static void __exit i2c_isa_exit(void)
167{
400c455e
JD
168#ifdef DEBUG
169 struct list_head *item, *_n;
170 struct i2c_client *client = NULL;
171#endif
172
173 /* There should be no more active client */
174#ifdef DEBUG
175 dev_dbg(&isa_adapter.dev, "Looking for clients\n");
176 list_for_each_safe(item, _n, &isa_adapter.clients) {
177 client = list_entry(item, struct i2c_client, list);
178 dev_err(&isa_adapter.dev, "Driver %s still has an active "
179 "ISA client at 0x%x\n", client->driver->name,
180 client->addr);
181 }
182 if (client != NULL)
183 return;
184#endif
185
186 /* Clean up the sysfs representation */
187 dev_dbg(&isa_adapter.dev, "Unregistering from sysfs\n");
188 init_completion(&isa_adapter.dev_released);
189 init_completion(&isa_adapter.class_dev_released);
190 class_device_unregister(&isa_adapter.class_dev);
191 device_remove_file(&isa_adapter.dev, &dev_attr_name);
192 device_unregister(&isa_adapter.dev);
193
194 /* Wait for sysfs to drop all references */
195 dev_dbg(&isa_adapter.dev, "Waiting for sysfs completion\n");
196 wait_for_completion(&isa_adapter.dev_released);
197 wait_for_completion(&isa_adapter.class_dev_released);
198
199 dev_dbg(&isa_adapter.dev, "%s unregistered\n", isa_adapter.name);
1da177e4
LT
200}
201
400c455e
JD
202EXPORT_SYMBOL(i2c_isa_add_driver);
203EXPORT_SYMBOL(i2c_isa_del_driver);
204
205MODULE_AUTHOR("Jean Delvare <khali@linux-fr.org>");
1da177e4
LT
206MODULE_DESCRIPTION("ISA bus access through i2c");
207MODULE_LICENSE("GPL");
208
209module_init(i2c_isa_init);
210module_exit(i2c_isa_exit);
This page took 0.089341 seconds and 5 git commands to generate.