xref: /openbmc/linux/drivers/i2c/busses/i2c-powermac.c (revision 8f9082c5ce0e2c2f7ad0211b0c089f680d2efc11)
1a28d3af2SBenjamin Herrenschmidt /*
2a28d3af2SBenjamin Herrenschmidt     i2c Support for Apple SMU Controller
3a28d3af2SBenjamin Herrenschmidt 
4a28d3af2SBenjamin Herrenschmidt     Copyright (c) 2005 Benjamin Herrenschmidt, IBM Corp.
5a28d3af2SBenjamin Herrenschmidt                        <benh@kernel.crashing.org>
6a28d3af2SBenjamin Herrenschmidt 
7a28d3af2SBenjamin Herrenschmidt     This program is free software; you can redistribute it and/or modify
8a28d3af2SBenjamin Herrenschmidt     it under the terms of the GNU General Public License as published by
9a28d3af2SBenjamin Herrenschmidt     the Free Software Foundation; either version 2 of the License, or
10a28d3af2SBenjamin Herrenschmidt     (at your option) any later version.
11a28d3af2SBenjamin Herrenschmidt 
12a28d3af2SBenjamin Herrenschmidt     This program is distributed in the hope that it will be useful,
13a28d3af2SBenjamin Herrenschmidt     but WITHOUT ANY WARRANTY; without even the implied warranty of
14a28d3af2SBenjamin Herrenschmidt     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15a28d3af2SBenjamin Herrenschmidt     GNU General Public License for more details.
16a28d3af2SBenjamin Herrenschmidt 
17a28d3af2SBenjamin Herrenschmidt     You should have received a copy of the GNU General Public License
18a28d3af2SBenjamin Herrenschmidt     along with this program; if not, write to the Free Software
19a28d3af2SBenjamin Herrenschmidt     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20a28d3af2SBenjamin Herrenschmidt 
21a28d3af2SBenjamin Herrenschmidt */
22a28d3af2SBenjamin Herrenschmidt 
23a28d3af2SBenjamin Herrenschmidt #include <linux/module.h>
24a28d3af2SBenjamin Herrenschmidt #include <linux/kernel.h>
25a28d3af2SBenjamin Herrenschmidt #include <linux/types.h>
26a28d3af2SBenjamin Herrenschmidt #include <linux/i2c.h>
27a28d3af2SBenjamin Herrenschmidt #include <linux/init.h>
28a28d3af2SBenjamin Herrenschmidt #include <linux/completion.h>
29a28d3af2SBenjamin Herrenschmidt #include <linux/device.h>
30a28d3af2SBenjamin Herrenschmidt #include <linux/platform_device.h>
31a28d3af2SBenjamin Herrenschmidt #include <asm/prom.h>
32a28d3af2SBenjamin Herrenschmidt #include <asm/pmac_low_i2c.h>
33a28d3af2SBenjamin Herrenschmidt 
34a28d3af2SBenjamin Herrenschmidt MODULE_AUTHOR("Benjamin Herrenschmidt <benh@kernel.crashing.org>");
35a28d3af2SBenjamin Herrenschmidt MODULE_DESCRIPTION("I2C driver for Apple PowerMac");
36a28d3af2SBenjamin Herrenschmidt MODULE_LICENSE("GPL");
37a28d3af2SBenjamin Herrenschmidt 
38a28d3af2SBenjamin Herrenschmidt /*
39a28d3af2SBenjamin Herrenschmidt  * SMBUS-type transfer entrypoint
40a28d3af2SBenjamin Herrenschmidt  */
41a28d3af2SBenjamin Herrenschmidt static s32 i2c_powermac_smbus_xfer(	struct i2c_adapter*	adap,
42a28d3af2SBenjamin Herrenschmidt 					u16			addr,
43a28d3af2SBenjamin Herrenschmidt 					unsigned short		flags,
44a28d3af2SBenjamin Herrenschmidt 					char			read_write,
45a28d3af2SBenjamin Herrenschmidt 					u8			command,
46a28d3af2SBenjamin Herrenschmidt 					int			size,
47a28d3af2SBenjamin Herrenschmidt 					union i2c_smbus_data*	data)
48a28d3af2SBenjamin Herrenschmidt {
49a28d3af2SBenjamin Herrenschmidt 	struct pmac_i2c_bus	*bus = i2c_get_adapdata(adap);
50a28d3af2SBenjamin Herrenschmidt 	int			rc = 0;
51a28d3af2SBenjamin Herrenschmidt 	int			read = (read_write == I2C_SMBUS_READ);
52a28d3af2SBenjamin Herrenschmidt 	int			addrdir = (addr << 1) | read;
53a28d3af2SBenjamin Herrenschmidt 	u8			local[2];
54a28d3af2SBenjamin Herrenschmidt 
55a28d3af2SBenjamin Herrenschmidt 	rc = pmac_i2c_open(bus, 0);
56a28d3af2SBenjamin Herrenschmidt 	if (rc)
57a28d3af2SBenjamin Herrenschmidt 		return rc;
58a28d3af2SBenjamin Herrenschmidt 
59a28d3af2SBenjamin Herrenschmidt 	switch (size) {
60a28d3af2SBenjamin Herrenschmidt         case I2C_SMBUS_QUICK:
61a28d3af2SBenjamin Herrenschmidt 		rc = pmac_i2c_setmode(bus, pmac_i2c_mode_std);
62a28d3af2SBenjamin Herrenschmidt 		if (rc)
63a28d3af2SBenjamin Herrenschmidt 			goto bail;
64a28d3af2SBenjamin Herrenschmidt 		rc = pmac_i2c_xfer(bus, addrdir, 0, 0, NULL, 0);
65a28d3af2SBenjamin Herrenschmidt 	    	break;
66a28d3af2SBenjamin Herrenschmidt         case I2C_SMBUS_BYTE:
67a28d3af2SBenjamin Herrenschmidt 		rc = pmac_i2c_setmode(bus, pmac_i2c_mode_std);
68a28d3af2SBenjamin Herrenschmidt 		if (rc)
69a28d3af2SBenjamin Herrenschmidt 			goto bail;
70a28d3af2SBenjamin Herrenschmidt 		rc = pmac_i2c_xfer(bus, addrdir, 0, 0, &data->byte, 1);
71a28d3af2SBenjamin Herrenschmidt 	    	break;
72a28d3af2SBenjamin Herrenschmidt         case I2C_SMBUS_BYTE_DATA:
73a28d3af2SBenjamin Herrenschmidt 		rc = pmac_i2c_setmode(bus, read ?
74a28d3af2SBenjamin Herrenschmidt 				      pmac_i2c_mode_combined :
75a28d3af2SBenjamin Herrenschmidt 				      pmac_i2c_mode_stdsub);
76a28d3af2SBenjamin Herrenschmidt 		if (rc)
77a28d3af2SBenjamin Herrenschmidt 			goto bail;
78a28d3af2SBenjamin Herrenschmidt 		rc = pmac_i2c_xfer(bus, addrdir, 1, command, &data->byte, 1);
79a28d3af2SBenjamin Herrenschmidt 	    	break;
80a28d3af2SBenjamin Herrenschmidt         case I2C_SMBUS_WORD_DATA:
81a28d3af2SBenjamin Herrenschmidt 		rc = pmac_i2c_setmode(bus, read ?
82a28d3af2SBenjamin Herrenschmidt 				      pmac_i2c_mode_combined :
83a28d3af2SBenjamin Herrenschmidt 				      pmac_i2c_mode_stdsub);
84a28d3af2SBenjamin Herrenschmidt 		if (rc)
85a28d3af2SBenjamin Herrenschmidt 			goto bail;
86a28d3af2SBenjamin Herrenschmidt 		if (!read) {
87a28d3af2SBenjamin Herrenschmidt 			local[0] = data->word & 0xff;
88a28d3af2SBenjamin Herrenschmidt 			local[1] = (data->word >> 8) & 0xff;
89a28d3af2SBenjamin Herrenschmidt 		}
90a28d3af2SBenjamin Herrenschmidt 		rc = pmac_i2c_xfer(bus, addrdir, 1, command, local, 2);
91a28d3af2SBenjamin Herrenschmidt 		if (rc == 0 && read) {
92a28d3af2SBenjamin Herrenschmidt 			data->word = ((u16)local[1]) << 8;
93a28d3af2SBenjamin Herrenschmidt 			data->word |= local[0];
94a28d3af2SBenjamin Herrenschmidt 		}
95a28d3af2SBenjamin Herrenschmidt 	    	break;
96a28d3af2SBenjamin Herrenschmidt 
97a28d3af2SBenjamin Herrenschmidt 	/* Note that these are broken vs. the expected smbus API where
98a28d3af2SBenjamin Herrenschmidt 	 * on reads, the lenght is actually returned from the function,
99a28d3af2SBenjamin Herrenschmidt 	 * but I think the current API makes no sense and I don't want
100a28d3af2SBenjamin Herrenschmidt 	 * any driver that I haven't verified for correctness to go
101a28d3af2SBenjamin Herrenschmidt 	 * anywhere near a pmac i2c bus anyway ...
102a28d3af2SBenjamin Herrenschmidt 	 *
103a28d3af2SBenjamin Herrenschmidt 	 * I'm also not completely sure what kind of phases to do between
104a28d3af2SBenjamin Herrenschmidt 	 * the actual command and the data (what I am _supposed_ to do that
105a28d3af2SBenjamin Herrenschmidt 	 * is). For now, I assume writes are a single stream and reads have
106a28d3af2SBenjamin Herrenschmidt 	 * a repeat start/addr phase (but not stop in between)
107a28d3af2SBenjamin Herrenschmidt 	 */
108a28d3af2SBenjamin Herrenschmidt         case I2C_SMBUS_BLOCK_DATA:
109a28d3af2SBenjamin Herrenschmidt 		rc = pmac_i2c_setmode(bus, read ?
110a28d3af2SBenjamin Herrenschmidt 				      pmac_i2c_mode_combined :
111a28d3af2SBenjamin Herrenschmidt 				      pmac_i2c_mode_stdsub);
112a28d3af2SBenjamin Herrenschmidt 		if (rc)
113a28d3af2SBenjamin Herrenschmidt 			goto bail;
114a28d3af2SBenjamin Herrenschmidt 		rc = pmac_i2c_xfer(bus, addrdir, 1, command, data->block,
115a28d3af2SBenjamin Herrenschmidt 				   data->block[0] + 1);
116a28d3af2SBenjamin Herrenschmidt 
117a28d3af2SBenjamin Herrenschmidt 		break;
118a28d3af2SBenjamin Herrenschmidt 	case I2C_SMBUS_I2C_BLOCK_DATA:
119a28d3af2SBenjamin Herrenschmidt 		rc = pmac_i2c_setmode(bus, read ?
120a28d3af2SBenjamin Herrenschmidt 				      pmac_i2c_mode_combined :
121a28d3af2SBenjamin Herrenschmidt 				      pmac_i2c_mode_stdsub);
122a28d3af2SBenjamin Herrenschmidt 		if (rc)
123a28d3af2SBenjamin Herrenschmidt 			goto bail;
124a28d3af2SBenjamin Herrenschmidt 		rc = pmac_i2c_xfer(bus, addrdir, 1, command,
125a28d3af2SBenjamin Herrenschmidt 				   read ? data->block : &data->block[1],
126a28d3af2SBenjamin Herrenschmidt 				   data->block[0]);
127a28d3af2SBenjamin Herrenschmidt 		break;
128a28d3af2SBenjamin Herrenschmidt 
129a28d3af2SBenjamin Herrenschmidt         default:
130a28d3af2SBenjamin Herrenschmidt 	    	rc = -EINVAL;
131a28d3af2SBenjamin Herrenschmidt 	}
132a28d3af2SBenjamin Herrenschmidt  bail:
133a28d3af2SBenjamin Herrenschmidt 	pmac_i2c_close(bus);
134a28d3af2SBenjamin Herrenschmidt 	return rc;
135a28d3af2SBenjamin Herrenschmidt }
136a28d3af2SBenjamin Herrenschmidt 
137a28d3af2SBenjamin Herrenschmidt /*
138a28d3af2SBenjamin Herrenschmidt  * Generic i2c master transfer entrypoint. This driver only support single
139a28d3af2SBenjamin Herrenschmidt  * messages (for "lame i2c" transfers). Anything else should use the smbus
140a28d3af2SBenjamin Herrenschmidt  * entry point
141a28d3af2SBenjamin Herrenschmidt  */
142a28d3af2SBenjamin Herrenschmidt static int i2c_powermac_master_xfer(	struct i2c_adapter *adap,
143a28d3af2SBenjamin Herrenschmidt 					struct i2c_msg *msgs,
144a28d3af2SBenjamin Herrenschmidt 					int num)
145a28d3af2SBenjamin Herrenschmidt {
146a28d3af2SBenjamin Herrenschmidt 	struct pmac_i2c_bus	*bus = i2c_get_adapdata(adap);
147a28d3af2SBenjamin Herrenschmidt 	int			rc = 0;
148a28d3af2SBenjamin Herrenschmidt 	int			read;
149a28d3af2SBenjamin Herrenschmidt 	int			addrdir;
150a28d3af2SBenjamin Herrenschmidt 
151a28d3af2SBenjamin Herrenschmidt 	if (msgs->flags & I2C_M_TEN)
152a28d3af2SBenjamin Herrenschmidt 		return -EINVAL;
153a28d3af2SBenjamin Herrenschmidt 	read = (msgs->flags & I2C_M_RD) != 0;
154a28d3af2SBenjamin Herrenschmidt 	addrdir = (msgs->addr << 1) | read;
155a28d3af2SBenjamin Herrenschmidt 	if (msgs->flags & I2C_M_REV_DIR_ADDR)
156a28d3af2SBenjamin Herrenschmidt 		addrdir ^= 1;
157a28d3af2SBenjamin Herrenschmidt 
158a28d3af2SBenjamin Herrenschmidt 	rc = pmac_i2c_open(bus, 0);
159a28d3af2SBenjamin Herrenschmidt 	if (rc)
160a28d3af2SBenjamin Herrenschmidt 		return rc;
161a28d3af2SBenjamin Herrenschmidt 	rc = pmac_i2c_setmode(bus, pmac_i2c_mode_std);
162a28d3af2SBenjamin Herrenschmidt 	if (rc)
163a28d3af2SBenjamin Herrenschmidt 		goto bail;
164a28d3af2SBenjamin Herrenschmidt 	rc = pmac_i2c_xfer(bus, addrdir, 0, 0, msgs->buf, msgs->len);
165a28d3af2SBenjamin Herrenschmidt  bail:
166a28d3af2SBenjamin Herrenschmidt 	pmac_i2c_close(bus);
1678ced8eeeSJean Delvare 	return rc < 0 ? rc : 1;
168a28d3af2SBenjamin Herrenschmidt }
169a28d3af2SBenjamin Herrenschmidt 
170a28d3af2SBenjamin Herrenschmidt static u32 i2c_powermac_func(struct i2c_adapter * adapter)
171a28d3af2SBenjamin Herrenschmidt {
172a28d3af2SBenjamin Herrenschmidt 	return I2C_FUNC_SMBUS_QUICK | I2C_FUNC_SMBUS_BYTE |
173a28d3af2SBenjamin Herrenschmidt 		I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA |
174a28d3af2SBenjamin Herrenschmidt 		I2C_FUNC_SMBUS_BLOCK_DATA | I2C_FUNC_I2C;
175a28d3af2SBenjamin Herrenschmidt }
176a28d3af2SBenjamin Herrenschmidt 
177a28d3af2SBenjamin Herrenschmidt /* For now, we only handle smbus */
178*8f9082c5SJean Delvare static const struct i2c_algorithm i2c_powermac_algorithm = {
179a28d3af2SBenjamin Herrenschmidt 	.smbus_xfer	= i2c_powermac_smbus_xfer,
180a28d3af2SBenjamin Herrenschmidt 	.master_xfer	= i2c_powermac_master_xfer,
181a28d3af2SBenjamin Herrenschmidt 	.functionality	= i2c_powermac_func,
182a28d3af2SBenjamin Herrenschmidt };
183a28d3af2SBenjamin Herrenschmidt 
184a28d3af2SBenjamin Herrenschmidt 
185a28d3af2SBenjamin Herrenschmidt static int i2c_powermac_remove(struct device *dev)
186a28d3af2SBenjamin Herrenschmidt {
187a28d3af2SBenjamin Herrenschmidt 	struct i2c_adapter	*adapter = dev_get_drvdata(dev);
188a28d3af2SBenjamin Herrenschmidt 	struct pmac_i2c_bus	*bus = i2c_get_adapdata(adapter);
189a28d3af2SBenjamin Herrenschmidt 	int			rc;
190a28d3af2SBenjamin Herrenschmidt 
191a28d3af2SBenjamin Herrenschmidt 	rc = i2c_del_adapter(adapter);
192a28d3af2SBenjamin Herrenschmidt 	pmac_i2c_detach_adapter(bus, adapter);
193a28d3af2SBenjamin Herrenschmidt 	i2c_set_adapdata(adapter, NULL);
194a28d3af2SBenjamin Herrenschmidt 	/* We aren't that prepared to deal with this... */
195a28d3af2SBenjamin Herrenschmidt 	if (rc)
196a28d3af2SBenjamin Herrenschmidt 		printk("i2c-powermac.c: Failed to remove bus %s !\n",
197a28d3af2SBenjamin Herrenschmidt 		       adapter->name);
198a28d3af2SBenjamin Herrenschmidt 	dev_set_drvdata(dev, NULL);
199a28d3af2SBenjamin Herrenschmidt 	kfree(adapter);
200a28d3af2SBenjamin Herrenschmidt 
201a28d3af2SBenjamin Herrenschmidt 	return 0;
202a28d3af2SBenjamin Herrenschmidt }
203a28d3af2SBenjamin Herrenschmidt 
204a28d3af2SBenjamin Herrenschmidt 
205a28d3af2SBenjamin Herrenschmidt static int i2c_powermac_probe(struct device *dev)
206a28d3af2SBenjamin Herrenschmidt {
207a28d3af2SBenjamin Herrenschmidt 	struct pmac_i2c_bus *bus = dev->platform_data;
208a28d3af2SBenjamin Herrenschmidt 	struct device_node *parent = NULL;
209a28d3af2SBenjamin Herrenschmidt 	struct i2c_adapter *adapter;
210018a3d1dSJeremy Kerr 	char name[32];
211018a3d1dSJeremy Kerr 	const char *basename;
212a28d3af2SBenjamin Herrenschmidt 	int rc;
213a28d3af2SBenjamin Herrenschmidt 
214a28d3af2SBenjamin Herrenschmidt 	if (bus == NULL)
215a28d3af2SBenjamin Herrenschmidt 		return -EINVAL;
216a28d3af2SBenjamin Herrenschmidt 
217a28d3af2SBenjamin Herrenschmidt 	/* Ok, now we need to make up a name for the interface that will
218a28d3af2SBenjamin Herrenschmidt 	 * match what we used to do in the past, that is basically the
219a28d3af2SBenjamin Herrenschmidt 	 * controller's parent device node for keywest. PMU didn't have a
220a28d3af2SBenjamin Herrenschmidt 	 * naming convention and SMU has a different one
221a28d3af2SBenjamin Herrenschmidt 	 */
222a28d3af2SBenjamin Herrenschmidt 	switch(pmac_i2c_get_type(bus)) {
223a28d3af2SBenjamin Herrenschmidt 	case pmac_i2c_bus_keywest:
224a28d3af2SBenjamin Herrenschmidt 		parent = of_get_parent(pmac_i2c_get_controller(bus));
225a28d3af2SBenjamin Herrenschmidt 		if (parent == NULL)
226a28d3af2SBenjamin Herrenschmidt 			return -EINVAL;
227a28d3af2SBenjamin Herrenschmidt 		basename = parent->name;
228a28d3af2SBenjamin Herrenschmidt 		break;
229a28d3af2SBenjamin Herrenschmidt 	case pmac_i2c_bus_pmu:
230a28d3af2SBenjamin Herrenschmidt 		basename = "pmu";
231a28d3af2SBenjamin Herrenschmidt 		break;
232a28d3af2SBenjamin Herrenschmidt 	case pmac_i2c_bus_smu:
233a28d3af2SBenjamin Herrenschmidt 		/* This is not what we used to do but I'm fixing drivers at
234a28d3af2SBenjamin Herrenschmidt 		 * the same time as this change
235a28d3af2SBenjamin Herrenschmidt 		 */
236a28d3af2SBenjamin Herrenschmidt 		basename = "smu";
237a28d3af2SBenjamin Herrenschmidt 		break;
238a28d3af2SBenjamin Herrenschmidt 	default:
239a28d3af2SBenjamin Herrenschmidt 		return -EINVAL;
240a28d3af2SBenjamin Herrenschmidt 	}
241a28d3af2SBenjamin Herrenschmidt 	snprintf(name, 32, "%s %d", basename, pmac_i2c_get_channel(bus));
242a28d3af2SBenjamin Herrenschmidt 	of_node_put(parent);
243a28d3af2SBenjamin Herrenschmidt 
244a28d3af2SBenjamin Herrenschmidt 	adapter = kzalloc(sizeof(struct i2c_adapter), GFP_KERNEL);
245a28d3af2SBenjamin Herrenschmidt 	if (adapter == NULL) {
246a28d3af2SBenjamin Herrenschmidt 		printk(KERN_ERR "i2c-powermac: can't allocate inteface !\n");
247a28d3af2SBenjamin Herrenschmidt 		return -ENOMEM;
248a28d3af2SBenjamin Herrenschmidt 	}
249a28d3af2SBenjamin Herrenschmidt 	dev_set_drvdata(dev, adapter);
250a28d3af2SBenjamin Herrenschmidt 	strcpy(adapter->name, name);
251a28d3af2SBenjamin Herrenschmidt 	adapter->algo = &i2c_powermac_algorithm;
252a28d3af2SBenjamin Herrenschmidt 	i2c_set_adapdata(adapter, bus);
253a28d3af2SBenjamin Herrenschmidt 	adapter->dev.parent = dev;
254a28d3af2SBenjamin Herrenschmidt 	pmac_i2c_attach_adapter(bus, adapter);
255a28d3af2SBenjamin Herrenschmidt 	rc = i2c_add_adapter(adapter);
256a28d3af2SBenjamin Herrenschmidt 	if (rc) {
257a28d3af2SBenjamin Herrenschmidt 		printk(KERN_ERR "i2c-powermac: Adapter %s registration "
258a28d3af2SBenjamin Herrenschmidt 		       "failed\n", name);
259a28d3af2SBenjamin Herrenschmidt 		i2c_set_adapdata(adapter, NULL);
260a28d3af2SBenjamin Herrenschmidt 		pmac_i2c_detach_adapter(bus, adapter);
261a28d3af2SBenjamin Herrenschmidt 	}
262a28d3af2SBenjamin Herrenschmidt 
263a28d3af2SBenjamin Herrenschmidt 	printk(KERN_INFO "PowerMac i2c bus %s registered\n", name);
264a28d3af2SBenjamin Herrenschmidt 	return rc;
265a28d3af2SBenjamin Herrenschmidt }
266a28d3af2SBenjamin Herrenschmidt 
267a28d3af2SBenjamin Herrenschmidt 
268a28d3af2SBenjamin Herrenschmidt static struct device_driver i2c_powermac_driver = {
269a28d3af2SBenjamin Herrenschmidt 	.name = "i2c-powermac",
270a28d3af2SBenjamin Herrenschmidt 	.bus = &platform_bus_type,
271a28d3af2SBenjamin Herrenschmidt 	.probe = i2c_powermac_probe,
272a28d3af2SBenjamin Herrenschmidt 	.remove = i2c_powermac_remove,
273a28d3af2SBenjamin Herrenschmidt };
274a28d3af2SBenjamin Herrenschmidt 
275a28d3af2SBenjamin Herrenschmidt static int __init i2c_powermac_init(void)
276a28d3af2SBenjamin Herrenschmidt {
277a28d3af2SBenjamin Herrenschmidt 	driver_register(&i2c_powermac_driver);
278a28d3af2SBenjamin Herrenschmidt 	return 0;
279a28d3af2SBenjamin Herrenschmidt }
280a28d3af2SBenjamin Herrenschmidt 
281a28d3af2SBenjamin Herrenschmidt 
282a28d3af2SBenjamin Herrenschmidt static void __exit i2c_powermac_cleanup(void)
283a28d3af2SBenjamin Herrenschmidt {
284a28d3af2SBenjamin Herrenschmidt 	driver_unregister(&i2c_powermac_driver);
285a28d3af2SBenjamin Herrenschmidt }
286a28d3af2SBenjamin Herrenschmidt 
287a28d3af2SBenjamin Herrenschmidt module_init(i2c_powermac_init);
288a28d3af2SBenjamin Herrenschmidt module_exit(i2c_powermac_cleanup);
289