]> git.proxmox.com Git - mirror_ubuntu-zesty-kernel.git/blame - drivers/i2c/busses/scx200_acb.c
i2c: i2c_register_driver() cleanup
[mirror_ubuntu-zesty-kernel.git] / drivers / i2c / busses / scx200_acb.c
CommitLineData
99c3adb4 1/*
1da177e4
LT
2 Copyright (c) 2001,2002 Christer Weinigel <wingel@nano-system.com>
3
4 National Semiconductor SCx200 ACCESS.bus support
16ffc5c9 5 Also supports the AMD CS5535 and AMD CS5536
99c3adb4 6
1da177e4
LT
7 Based on i2c-keywest.c which is:
8 Copyright (c) 2001 Benjamin Herrenschmidt <benh@kernel.crashing.org>
9 Copyright (c) 2000 Philip Edelbrock <phil@stimpy.netroedge.com>
99c3adb4 10
1da177e4
LT
11 This program is free software; you can redistribute it and/or
12 modify it under the terms of the GNU General Public License as
13 published by the Free Software Foundation; either version 2 of the
14 License, or (at your option) any later version.
99c3adb4 15
1da177e4
LT
16 This program is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 General Public License for more details.
99c3adb4 20
1da177e4
LT
21 You should have received a copy of the GNU General Public License
22 along with this program; if not, write to the Free Software
23 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
1da177e4
LT
24*/
25
1da177e4
LT
26#include <linux/module.h>
27#include <linux/errno.h>
28#include <linux/kernel.h>
29#include <linux/init.h>
30#include <linux/i2c.h>
31#include <linux/smp_lock.h>
32#include <linux/pci.h>
33#include <linux/delay.h>
3fb9a655 34#include <linux/mutex.h>
1da177e4
LT
35#include <asm/io.h>
36
37#include <linux/scx200.h>
38
39#define NAME "scx200_acb"
40
41MODULE_AUTHOR("Christer Weinigel <wingel@nano-system.com>");
42MODULE_DESCRIPTION("NatSemi SCx200 ACCESS.bus Driver");
43MODULE_LICENSE("GPL");
44
45#define MAX_DEVICES 4
46static int base[MAX_DEVICES] = { 0x820, 0x840 };
47module_param_array(base, int, NULL, 0);
48MODULE_PARM_DESC(base, "Base addresses for the ACCESS.bus controllers");
49
f933ff50 50#define POLL_TIMEOUT (HZ/5)
1da177e4
LT
51
52enum scx200_acb_state {
53 state_idle,
54 state_address,
55 state_command,
56 state_repeat_start,
57 state_quick,
58 state_read,
59 state_write,
60};
61
62static const char *scx200_acb_state_name[] = {
63 "idle",
64 "address",
65 "command",
66 "repeat_start",
67 "quick",
68 "read",
69 "write",
70};
71
72/* Physical interface */
99c3adb4 73struct scx200_acb_iface {
1da177e4
LT
74 struct scx200_acb_iface *next;
75 struct i2c_adapter adapter;
76 unsigned base;
3fb9a655 77 struct mutex mutex;
1da177e4
LT
78
79 /* State machine data */
80 enum scx200_acb_state state;
81 int result;
82 u8 address_byte;
83 u8 command;
84 u8 *ptr;
85 char needs_reset;
86 unsigned len;
80cd3a87
JC
87
88 /* PCI device info */
89 struct pci_dev *pdev;
90 int bar;
1da177e4
LT
91};
92
93/* Register Definitions */
94#define ACBSDA (iface->base + 0)
95#define ACBST (iface->base + 1)
96#define ACBST_SDAST 0x40 /* SDA Status */
99c3adb4 97#define ACBST_BER 0x20
1da177e4
LT
98#define ACBST_NEGACK 0x10 /* Negative Acknowledge */
99#define ACBST_STASTR 0x08 /* Stall After Start */
100#define ACBST_MASTER 0x02
101#define ACBCST (iface->base + 2)
102#define ACBCST_BB 0x02
103#define ACBCTL1 (iface->base + 3)
104#define ACBCTL1_STASTRE 0x80
105#define ACBCTL1_NMINTE 0x40
99c3adb4
BG
106#define ACBCTL1_ACK 0x10
107#define ACBCTL1_STOP 0x02
108#define ACBCTL1_START 0x01
1da177e4
LT
109#define ACBADDR (iface->base + 4)
110#define ACBCTL2 (iface->base + 5)
111#define ACBCTL2_ENABLE 0x01
112
113/************************************************************************/
114
115static void scx200_acb_machine(struct scx200_acb_iface *iface, u8 status)
116{
117 const char *errmsg;
118
ef4d9275
BG
119 dev_dbg(&iface->adapter.dev, "state %s, status = 0x%02x\n",
120 scx200_acb_state_name[iface->state], status);
1da177e4
LT
121
122 if (status & ACBST_BER) {
123 errmsg = "bus error";
124 goto error;
125 }
126 if (!(status & ACBST_MASTER)) {
127 errmsg = "not master";
128 goto error;
129 }
9b7b6d3b
BG
130 if (status & ACBST_NEGACK) {
131 dev_dbg(&iface->adapter.dev, "negative ack in state %s\n",
132 scx200_acb_state_name[iface->state]);
133
134 iface->state = state_idle;
135 iface->result = -ENXIO;
136
137 outb(inb(ACBCTL1) | ACBCTL1_STOP, ACBCTL1);
138 outb(ACBST_STASTR | ACBST_NEGACK, ACBST);
95563d34
JC
139
140 /* Reset the status register */
141 outb(0, ACBST);
9b7b6d3b
BG
142 return;
143 }
1da177e4
LT
144
145 switch (iface->state) {
146 case state_idle:
147 dev_warn(&iface->adapter.dev, "interrupt in idle state\n");
148 break;
149
150 case state_address:
151 /* Do a pointer write first */
152 outb(iface->address_byte & ~1, ACBSDA);
153
154 iface->state = state_command;
155 break;
156
157 case state_command:
158 outb(iface->command, ACBSDA);
159
160 if (iface->address_byte & 1)
161 iface->state = state_repeat_start;
162 else
163 iface->state = state_write;
164 break;
165
166 case state_repeat_start:
167 outb(inb(ACBCTL1) | ACBCTL1_START, ACBCTL1);
168 /* fallthrough */
99c3adb4 169
1da177e4
LT
170 case state_quick:
171 if (iface->address_byte & 1) {
99c3adb4 172 if (iface->len == 1)
1da177e4
LT
173 outb(inb(ACBCTL1) | ACBCTL1_ACK, ACBCTL1);
174 else
175 outb(inb(ACBCTL1) & ~ACBCTL1_ACK, ACBCTL1);
176 outb(iface->address_byte, ACBSDA);
177
178 iface->state = state_read;
179 } else {
180 outb(iface->address_byte, ACBSDA);
181
182 iface->state = state_write;
183 }
184 break;
185
186 case state_read:
fd627a01
TA
187 /* Set ACK if _next_ byte will be the last one */
188 if (iface->len == 2)
1da177e4
LT
189 outb(inb(ACBCTL1) | ACBCTL1_ACK, ACBCTL1);
190 else
191 outb(inb(ACBCTL1) & ~ACBCTL1_ACK, ACBCTL1);
192
fd627a01 193 if (iface->len == 1) {
1da177e4
LT
194 iface->result = 0;
195 iface->state = state_idle;
196 outb(inb(ACBCTL1) | ACBCTL1_STOP, ACBCTL1);
197 }
198
fd627a01
TA
199 *iface->ptr++ = inb(ACBSDA);
200 --iface->len;
201
1da177e4
LT
202 break;
203
204 case state_write:
205 if (iface->len == 0) {
206 iface->result = 0;
207 iface->state = state_idle;
208 outb(inb(ACBCTL1) | ACBCTL1_STOP, ACBCTL1);
209 break;
210 }
99c3adb4 211
1da177e4
LT
212 outb(*iface->ptr++, ACBSDA);
213 --iface->len;
99c3adb4 214
1da177e4
LT
215 break;
216 }
217
218 return;
219
1da177e4
LT
220 error:
221 dev_err(&iface->adapter.dev, "%s in state %s\n", errmsg,
222 scx200_acb_state_name[iface->state]);
223
224 iface->state = state_idle;
225 iface->result = -EIO;
226 iface->needs_reset = 1;
227}
228
1da177e4
LT
229static void scx200_acb_poll(struct scx200_acb_iface *iface)
230{
9b7b6d3b 231 u8 status;
1da177e4
LT
232 unsigned long timeout;
233
234 timeout = jiffies + POLL_TIMEOUT;
3e3183ba 235 while (1) {
1da177e4 236 status = inb(ACBST);
95563d34
JC
237
238 /* Reset the status register to avoid the hang */
239 outb(0, ACBST);
240
1da177e4
LT
241 if ((status & (ACBST_SDAST|ACBST_BER|ACBST_NEGACK)) != 0) {
242 scx200_acb_machine(iface, status);
243 return;
244 }
3e3183ba
DW
245 if (time_after(jiffies, timeout))
246 break;
247 cpu_relax();
248 cond_resched();
1da177e4
LT
249 }
250
9b7b6d3b
BG
251 dev_err(&iface->adapter.dev, "timeout in state %s\n",
252 scx200_acb_state_name[iface->state]);
253
254 iface->state = state_idle;
255 iface->result = -EIO;
256 iface->needs_reset = 1;
1da177e4 257}
1da177e4
LT
258
259static void scx200_acb_reset(struct scx200_acb_iface *iface)
260{
261 /* Disable the ACCESS.bus device and Configure the SCL
99c3adb4 262 frequency: 16 clock cycles */
1da177e4
LT
263 outb(0x70, ACBCTL2);
264 /* Polling mode */
265 outb(0, ACBCTL1);
266 /* Disable slave address */
267 outb(0, ACBADDR);
268 /* Enable the ACCESS.bus device */
269 outb(inb(ACBCTL2) | ACBCTL2_ENABLE, ACBCTL2);
270 /* Free STALL after START */
271 outb(inb(ACBCTL1) & ~(ACBCTL1_STASTRE | ACBCTL1_NMINTE), ACBCTL1);
272 /* Send a STOP */
273 outb(inb(ACBCTL1) | ACBCTL1_STOP, ACBCTL1);
274 /* Clear BER, NEGACK and STASTR bits */
275 outb(ACBST_BER | ACBST_NEGACK | ACBST_STASTR, ACBST);
276 /* Clear BB bit */
277 outb(inb(ACBCST) | ACBCST_BB, ACBCST);
278}
279
280static s32 scx200_acb_smbus_xfer(struct i2c_adapter *adapter,
99c3adb4
BG
281 u16 address, unsigned short flags,
282 char rw, u8 command, int size,
283 union i2c_smbus_data *data)
1da177e4
LT
284{
285 struct scx200_acb_iface *iface = i2c_get_adapdata(adapter);
286 int len;
287 u8 *buffer;
288 u16 cur_word;
289 int rc;
290
291 switch (size) {
292 case I2C_SMBUS_QUICK:
99c3adb4
BG
293 len = 0;
294 buffer = NULL;
295 break;
296
1da177e4 297 case I2C_SMBUS_BYTE:
9b7b6d3b
BG
298 len = 1;
299 buffer = rw ? &data->byte : &command;
99c3adb4
BG
300 break;
301
1da177e4 302 case I2C_SMBUS_BYTE_DATA:
99c3adb4
BG
303 len = 1;
304 buffer = &data->byte;
305 break;
306
1da177e4
LT
307 case I2C_SMBUS_WORD_DATA:
308 len = 2;
99c3adb4
BG
309 cur_word = cpu_to_le16(data->word);
310 buffer = (u8 *)&cur_word;
1da177e4 311 break;
99c3adb4 312
c3efacaa
JD
313 case I2C_SMBUS_I2C_BLOCK_DATA:
314 if (rw == I2C_SMBUS_READ)
315 data->block[0] = I2C_SMBUS_BLOCK_MAX; /* For now */
99c3adb4 316 len = data->block[0];
c3efacaa
JD
317 if (len == 0 || len > I2C_SMBUS_BLOCK_MAX)
318 return -EINVAL;
99c3adb4 319 buffer = &data->block[1];
1da177e4 320 break;
99c3adb4 321
1da177e4 322 default:
99c3adb4 323 return -EINVAL;
1da177e4
LT
324 }
325
ef4d9275
BG
326 dev_dbg(&adapter->dev,
327 "size=%d, address=0x%x, command=0x%x, len=%d, read=%d\n",
328 size, address, command, len, rw);
1da177e4
LT
329
330 if (!len && rw == I2C_SMBUS_READ) {
ef4d9275 331 dev_dbg(&adapter->dev, "zero length read\n");
1da177e4
LT
332 return -EINVAL;
333 }
334
3fb9a655 335 mutex_lock(&iface->mutex);
1da177e4 336
9b7b6d3b 337 iface->address_byte = (address << 1) | rw;
1da177e4
LT
338 iface->command = command;
339 iface->ptr = buffer;
340 iface->len = len;
341 iface->result = -EINVAL;
342 iface->needs_reset = 0;
343
344 outb(inb(ACBCTL1) | ACBCTL1_START, ACBCTL1);
345
346 if (size == I2C_SMBUS_QUICK || size == I2C_SMBUS_BYTE)
347 iface->state = state_quick;
348 else
349 iface->state = state_address;
350
1da177e4
LT
351 while (iface->state != state_idle)
352 scx200_acb_poll(iface);
1da177e4
LT
353
354 if (iface->needs_reset)
355 scx200_acb_reset(iface);
356
357 rc = iface->result;
358
3fb9a655 359 mutex_unlock(&iface->mutex);
1da177e4
LT
360
361 if (rc == 0 && size == I2C_SMBUS_WORD_DATA && rw == I2C_SMBUS_READ)
99c3adb4 362 data->word = le16_to_cpu(cur_word);
1da177e4
LT
363
364#ifdef DEBUG
ef4d9275 365 dev_dbg(&adapter->dev, "transfer done, result: %d", rc);
1da177e4
LT
366 if (buffer) {
367 int i;
368 printk(" data:");
369 for (i = 0; i < len; ++i)
370 printk(" %02x", buffer[i]);
371 }
372 printk("\n");
373#endif
374
375 return rc;
376}
377
378static u32 scx200_acb_func(struct i2c_adapter *adapter)
379{
380 return I2C_FUNC_SMBUS_QUICK | I2C_FUNC_SMBUS_BYTE |
381 I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA |
c3efacaa 382 I2C_FUNC_SMBUS_I2C_BLOCK;
1da177e4
LT
383}
384
385/* For now, we only handle combined mode (smbus) */
8f9082c5 386static const struct i2c_algorithm scx200_acb_algorithm = {
1da177e4
LT
387 .smbus_xfer = scx200_acb_smbus_xfer,
388 .functionality = scx200_acb_func,
389};
390
391static struct scx200_acb_iface *scx200_acb_list;
8a05940d 392static DECLARE_MUTEX(scx200_acb_list_mutex);
1da177e4 393
99173926 394static __init int scx200_acb_probe(struct scx200_acb_iface *iface)
1da177e4
LT
395{
396 u8 val;
397
398 /* Disable the ACCESS.bus device and Configure the SCL
99c3adb4 399 frequency: 16 clock cycles */
1da177e4
LT
400 outb(0x70, ACBCTL2);
401
402 if (inb(ACBCTL2) != 0x70) {
ef4d9275 403 pr_debug(NAME ": ACBCTL2 readback failed\n");
1da177e4
LT
404 return -ENXIO;
405 }
406
407 outb(inb(ACBCTL1) | ACBCTL1_NMINTE, ACBCTL1);
408
409 val = inb(ACBCTL1);
410 if (val) {
ef4d9275
BG
411 pr_debug(NAME ": disabled, but ACBCTL1=0x%02x\n",
412 val);
1da177e4
LT
413 return -ENXIO;
414 }
415
416 outb(inb(ACBCTL2) | ACBCTL2_ENABLE, ACBCTL2);
417
418 outb(inb(ACBCTL1) | ACBCTL1_NMINTE, ACBCTL1);
419
420 val = inb(ACBCTL1);
421 if ((val & ACBCTL1_NMINTE) != ACBCTL1_NMINTE) {
ef4d9275
BG
422 pr_debug(NAME ": enabled, but NMINTE won't be set, "
423 "ACBCTL1=0x%02x\n", val);
1da177e4
LT
424 return -ENXIO;
425 }
426
427 return 0;
428}
429
80cd3a87 430static __init struct scx200_acb_iface *scx200_create_iface(const char *text,
12a917f6 431 struct device *dev, int index)
1da177e4
LT
432{
433 struct scx200_acb_iface *iface;
434 struct i2c_adapter *adapter;
1da177e4 435
5263ebb5 436 iface = kzalloc(sizeof(*iface), GFP_KERNEL);
1da177e4
LT
437 if (!iface) {
438 printk(KERN_ERR NAME ": can't allocate memory\n");
80cd3a87 439 return NULL;
1da177e4
LT
440 }
441
1da177e4
LT
442 adapter = &iface->adapter;
443 i2c_set_adapdata(adapter, iface);
16ffc5c9 444 snprintf(adapter->name, I2C_NAME_SIZE, "%s ACB%d", text, index);
1da177e4 445 adapter->owner = THIS_MODULE;
1684a984 446 adapter->id = I2C_HW_SMBUS_SCX200;
1da177e4
LT
447 adapter->algo = &scx200_acb_algorithm;
448 adapter->class = I2C_CLASS_HWMON;
12a917f6 449 adapter->dev.parent = dev;
1da177e4 450
3fb9a655 451 mutex_init(&iface->mutex);
1da177e4 452
80cd3a87
JC
453 return iface;
454}
455
456static int __init scx200_acb_create(struct scx200_acb_iface *iface)
457{
458 struct i2c_adapter *adapter;
459 int rc;
460
461 adapter = &iface->adapter;
1da177e4
LT
462
463 rc = scx200_acb_probe(iface);
464 if (rc) {
ef4d9275 465 printk(KERN_WARNING NAME ": probe failed\n");
80cd3a87 466 return rc;
1da177e4
LT
467 }
468
469 scx200_acb_reset(iface);
470
471 if (i2c_add_adapter(adapter) < 0) {
ef4d9275 472 printk(KERN_ERR NAME ": failed to register\n");
80cd3a87 473 return -ENODEV;
1da177e4
LT
474 }
475
8a05940d 476 down(&scx200_acb_list_mutex);
1da177e4
LT
477 iface->next = scx200_acb_list;
478 scx200_acb_list = iface;
8a05940d 479 up(&scx200_acb_list_mutex);
1da177e4
LT
480
481 return 0;
80cd3a87 482}
1da177e4 483
80cd3a87
JC
484static __init int scx200_create_pci(const char *text, struct pci_dev *pdev,
485 int bar)
486{
487 struct scx200_acb_iface *iface;
488 int rc;
489
12a917f6 490 iface = scx200_create_iface(text, &pdev->dev, 0);
80cd3a87
JC
491
492 if (iface == NULL)
493 return -ENOMEM;
494
495 iface->pdev = pdev;
496 iface->bar = bar;
497
ffb3d134
JG
498 rc = pci_enable_device_bars(iface->pdev, 1 << iface->bar);
499 if (rc)
500 goto errout_free;
80cd3a87
JC
501
502 rc = pci_request_region(iface->pdev, iface->bar, iface->adapter.name);
ffb3d134 503 if (rc) {
80cd3a87
JC
504 printk(KERN_ERR NAME ": can't allocate PCI BAR %d\n",
505 iface->bar);
506 goto errout_free;
507 }
508
509 iface->base = pci_resource_start(iface->pdev, iface->bar);
510 rc = scx200_acb_create(iface);
511
512 if (rc == 0)
513 return 0;
514
515 pci_release_region(iface->pdev, iface->bar);
516 pci_dev_put(iface->pdev);
9b7b6d3b
BG
517 errout_free:
518 kfree(iface);
1da177e4
LT
519 return rc;
520}
521
80cd3a87
JC
522static int __init scx200_create_isa(const char *text, unsigned long base,
523 int index)
524{
525 struct scx200_acb_iface *iface;
526 int rc;
527
12a917f6 528 iface = scx200_create_iface(text, NULL, index);
80cd3a87
JC
529
530 if (iface == NULL)
531 return -ENOMEM;
532
533 if (request_region(base, 8, iface->adapter.name) == 0) {
534 printk(KERN_ERR NAME ": can't allocate io 0x%lx-0x%lx\n",
535 base, base + 8 - 1);
536 rc = -EBUSY;
537 goto errout_free;
538 }
539
540 iface->base = base;
541 rc = scx200_acb_create(iface);
542
543 if (rc == 0)
544 return 0;
1da177e4 545
80cd3a87
JC
546 release_region(base, 8);
547 errout_free:
548 kfree(iface);
549 return rc;
550}
551
552/* Driver data is an index into the scx200_data array that indicates
553 * the name and the BAR where the I/O address resource is located. ISA
554 * devices are flagged with a bar value of -1 */
555
556static struct pci_device_id scx200_pci[] = {
557 { PCI_DEVICE(PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_SCx200_BRIDGE),
558 .driver_data = 0 },
559 { PCI_DEVICE(PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_SC1100_BRIDGE),
560 .driver_data = 0 },
561 { PCI_DEVICE(PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_CS5535_ISA),
562 .driver_data = 1 },
563 { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_CS5536_ISA),
564 .driver_data = 2 }
16ffc5c9
BG
565};
566
80cd3a87
JC
567static struct {
568 const char *name;
569 int bar;
570} scx200_data[] = {
571 { "SCx200", -1 },
572 { "CS5535", 0 },
573 { "CS5536", 0 }
574};
16ffc5c9 575
80cd3a87 576static __init int scx200_scan_pci(void)
16ffc5c9 577{
80cd3a87
JC
578 int data, dev;
579 int rc = -ENODEV;
580 struct pci_dev *pdev;
581
582 for(dev = 0; dev < ARRAY_SIZE(scx200_pci); dev++) {
583 pdev = pci_get_device(scx200_pci[dev].vendor,
584 scx200_pci[dev].device, NULL);
585
586 if (pdev == NULL)
587 continue;
588
589 data = scx200_pci[dev].driver_data;
590
591 /* if .bar is greater or equal to zero, this is a
592 * PCI device - otherwise, we assume
593 that the ports are ISA based
594 */
595
596 if (scx200_data[data].bar >= 0)
597 rc = scx200_create_pci(scx200_data[data].name, pdev,
598 scx200_data[data].bar);
599 else {
600 int i;
601
602 for (i = 0; i < MAX_DEVICES; ++i) {
603 if (base[i] == 0)
604 continue;
605
606 rc = scx200_create_isa(scx200_data[data].name,
607 base[i],
608 i);
609 }
610 }
16ffc5c9 611
80cd3a87 612 break;
16ffc5c9
BG
613 }
614
80cd3a87 615 return rc;
16ffc5c9
BG
616}
617
1da177e4
LT
618static int __init scx200_acb_init(void)
619{
80cd3a87 620 int rc;
1da177e4
LT
621
622 pr_debug(NAME ": NatSemi SCx200 ACCESS.bus Driver\n");
623
80cd3a87 624 rc = scx200_scan_pci();
1da177e4 625
6f9c2963
JD
626 /* If at least one bus was created, init must succeed */
627 if (scx200_acb_list)
628 return 0;
1da177e4
LT
629 return rc;
630}
631
632static void __exit scx200_acb_cleanup(void)
633{
634 struct scx200_acb_iface *iface;
99c3adb4 635
8a05940d 636 down(&scx200_acb_list_mutex);
1da177e4
LT
637 while ((iface = scx200_acb_list) != NULL) {
638 scx200_acb_list = iface->next;
8a05940d 639 up(&scx200_acb_list_mutex);
1da177e4
LT
640
641 i2c_del_adapter(&iface->adapter);
80cd3a87
JC
642
643 if (iface->pdev) {
644 pci_release_region(iface->pdev, iface->bar);
645 pci_dev_put(iface->pdev);
646 }
647 else
648 release_region(iface->base, 8);
649
1da177e4 650 kfree(iface);
8a05940d 651 down(&scx200_acb_list_mutex);
1da177e4 652 }
8a05940d 653 up(&scx200_acb_list_mutex);
1da177e4
LT
654}
655
656module_init(scx200_acb_init);
657module_exit(scx200_acb_cleanup);