]> git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/blame - drivers/i2c/busses/i2c-isa.c
i2c: Class attribute cleanup
[mirror_ubuntu-bionic-kernel.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>
b8d6f45b 42#include <linux/completion.h>
1da177e4
LT
43
44static u32 isa_func(struct i2c_adapter *adapter);
45
46/* This is the actual algorithm we define */
8f9082c5 47static const struct i2c_algorithm isa_algorithm = {
1da177e4
LT
48 .functionality = isa_func,
49};
50
51/* There can only be one... */
52static struct i2c_adapter isa_adapter = {
53 .owner = THIS_MODULE,
c7a46533 54 .id = I2C_HW_ISA,
1da177e4
LT
55 .class = I2C_CLASS_HWMON,
56 .algo = &isa_algorithm,
57 .name = "ISA main adapter",
58};
59
60/* We can't do a thing... */
61static u32 isa_func(struct i2c_adapter *adapter)
62{
63 return 0;
64}
65
400c455e 66
400c455e
JD
67/* We implement an interface which resembles i2c_{add,del}_driver,
68 but for i2c-isa drivers. We don't have to remember and handle lists
69 of drivers and adapters so this is much more simple, of course. */
70
71int i2c_isa_add_driver(struct i2c_driver *driver)
72{
73 int res;
74
75 /* Add the driver to the list of i2c drivers in the driver core */
400c455e 76 driver->driver.bus = &i2c_bus_type;
400c455e
JD
77 res = driver_register(&driver->driver);
78 if (res)
79 return res;
e1c489b0 80 dev_dbg(&isa_adapter.dev, "Driver %s registered\n", driver->driver.name);
400c455e
JD
81
82 /* Now look for clients */
82026326
DH
83 res = driver->attach_adapter(&isa_adapter);
84 if (res) {
e693810c 85 dev_dbg(&isa_adapter.dev,
82026326
DH
86 "Driver %s failed to attach adapter, unregistering\n",
87 driver->driver.name);
88 driver_unregister(&driver->driver);
89 }
90 return res;
400c455e
JD
91}
92
93int i2c_isa_del_driver(struct i2c_driver *driver)
94{
95 struct list_head *item, *_n;
96 struct i2c_client *client;
97 int res;
98
99 /* Detach all clients belonging to this one driver */
100 list_for_each_safe(item, _n, &isa_adapter.clients) {
101 client = list_entry(item, struct i2c_client, list);
102 if (client->driver != driver)
103 continue;
104 dev_dbg(&isa_adapter.dev, "Detaching client %s at 0x%x\n",
105 client->name, client->addr);
106 if ((res = driver->detach_client(client))) {
107 dev_err(&isa_adapter.dev, "Failed, driver "
108 "%s not unregistered!\n",
35d8b2e6 109 driver->driver.name);
400c455e
JD
110 return res;
111 }
112 }
113
114 /* Get the driver off the core list */
115 driver_unregister(&driver->driver);
e1c489b0 116 dev_dbg(&isa_adapter.dev, "Driver %s unregistered\n", driver->driver.name);
400c455e
JD
117
118 return 0;
119}
120
121
1da177e4
LT
122static int __init i2c_isa_init(void)
123{
b119c6c9
JD
124 int err;
125
5c085d36 126 mutex_init(&isa_adapter.clist_lock);
400c455e
JD
127 INIT_LIST_HEAD(&isa_adapter.clients);
128
129 isa_adapter.nr = ANY_I2C_ISA_BUS;
130 isa_adapter.dev.parent = &platform_bus;
131 sprintf(isa_adapter.dev.bus_id, "i2c-%d", isa_adapter.nr);
400c455e 132 isa_adapter.dev.release = &i2c_adapter_dev_release;
fccb56e4 133 isa_adapter.dev.class = &i2c_adapter_class;
b119c6c9
JD
134 err = device_register(&isa_adapter.dev);
135 if (err) {
136 printk(KERN_ERR "i2c-isa: Failed to register device\n");
137 goto exit;
138 }
400c455e 139
400c455e
JD
140 dev_dbg(&isa_adapter.dev, "%s registered\n", isa_adapter.name);
141
142 return 0;
b119c6c9 143
b119c6c9
JD
144exit:
145 return err;
1da177e4
LT
146}
147
148static void __exit i2c_isa_exit(void)
149{
400c455e
JD
150#ifdef DEBUG
151 struct list_head *item, *_n;
152 struct i2c_client *client = NULL;
153#endif
154
155 /* There should be no more active client */
156#ifdef DEBUG
157 dev_dbg(&isa_adapter.dev, "Looking for clients\n");
158 list_for_each_safe(item, _n, &isa_adapter.clients) {
159 client = list_entry(item, struct i2c_client, list);
160 dev_err(&isa_adapter.dev, "Driver %s still has an active "
e1c489b0 161 "ISA client at 0x%x\n", client->driver->driver.name,
400c455e
JD
162 client->addr);
163 }
164 if (client != NULL)
165 return;
166#endif
167
168 /* Clean up the sysfs representation */
169 dev_dbg(&isa_adapter.dev, "Unregistering from sysfs\n");
170 init_completion(&isa_adapter.dev_released);
400c455e
JD
171 device_unregister(&isa_adapter.dev);
172
173 /* Wait for sysfs to drop all references */
174 dev_dbg(&isa_adapter.dev, "Waiting for sysfs completion\n");
175 wait_for_completion(&isa_adapter.dev_released);
400c455e
JD
176
177 dev_dbg(&isa_adapter.dev, "%s unregistered\n", isa_adapter.name);
1da177e4
LT
178}
179
400c455e
JD
180EXPORT_SYMBOL(i2c_isa_add_driver);
181EXPORT_SYMBOL(i2c_isa_del_driver);
182
183MODULE_AUTHOR("Jean Delvare <khali@linux-fr.org>");
1da177e4
LT
184MODULE_DESCRIPTION("ISA bus access through i2c");
185MODULE_LICENSE("GPL");
186
187module_init(i2c_isa_init);
188module_exit(i2c_isa_exit);