]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/dev/ichiic/ig4_iic.c
MFV r329502: 7614 zfs device evacuation/removal
[FreeBSD/FreeBSD.git] / sys / dev / ichiic / ig4_iic.c
1 /*
2  * Copyright (c) 2014 The DragonFly Project.  All rights reserved.
3  *
4  * This code is derived from software contributed to The DragonFly Project
5  * by Matthew Dillon <dillon@backplane.com> and was subsequently ported
6  * to FreeBSD by Michael Gmelin <freebsd@grem.de>
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  *
12  * 1. Redistributions of source code must retain the above copyright
13  *    notice, this list of conditions and the following disclaimer.
14  * 2. Redistributions in binary form must reproduce the above copyright
15  *    notice, this list of conditions and the following disclaimer in
16  *    the documentation and/or other materials provided with the
17  *    distribution.
18  * 3. Neither the name of The DragonFly Project nor the names of its
19  *    contributors may be used to endorse or promote products derived
20  *    from this software without specific, prior written permission.
21  *
22  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
23  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
24  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
25  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
26  * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
27  * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING,
28  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
29  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
30  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
31  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
32  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33  * SUCH DAMAGE.
34  */
35
36 #include <sys/cdefs.h>
37 __FBSDID("$FreeBSD$");
38
39 /*
40  * Intel fourth generation mobile cpus integrated I2C device.
41  *
42  * See ig4_reg.h for datasheet reference and notes.
43  * See ig4_var.h for locking semantics.
44  */
45
46 #include <sys/param.h>
47 #include <sys/systm.h>
48 #include <sys/kernel.h>
49 #include <sys/module.h>
50 #include <sys/errno.h>
51 #include <sys/lock.h>
52 #include <sys/mutex.h>
53 #include <sys/sx.h>
54 #include <sys/syslog.h>
55 #include <sys/bus.h>
56 #include <sys/sysctl.h>
57
58 #include <machine/bus.h>
59 #include <sys/rman.h>
60
61 #include <dev/pci/pcivar.h>
62 #include <dev/pci/pcireg.h>
63 #include <dev/iicbus/iicbus.h>
64 #include <dev/iicbus/iiconf.h>
65
66 #include <dev/ichiic/ig4_reg.h>
67 #include <dev/ichiic/ig4_var.h>
68
69 #define TRANS_NORMAL    1
70 #define TRANS_PCALL     2
71 #define TRANS_BLOCK     3
72
73 static void ig4iic_start(void *xdev);
74 static void ig4iic_intr(void *cookie);
75 static void ig4iic_dump(ig4iic_softc_t *sc);
76
77 static int ig4_dump;
78 SYSCTL_INT(_debug, OID_AUTO, ig4_dump, CTLFLAG_RW,
79            &ig4_dump, 0, "Dump controller registers");
80
81 /*
82  * Low-level inline support functions
83  */
84 static __inline void
85 reg_write(ig4iic_softc_t *sc, uint32_t reg, uint32_t value)
86 {
87         bus_write_4(sc->regs_res, reg, value);
88         bus_barrier(sc->regs_res, reg, 4, BUS_SPACE_BARRIER_WRITE);
89 }
90
91 static __inline uint32_t
92 reg_read(ig4iic_softc_t *sc, uint32_t reg)
93 {
94         uint32_t value;
95
96         bus_barrier(sc->regs_res, reg, 4, BUS_SPACE_BARRIER_READ);
97         value = bus_read_4(sc->regs_res, reg);
98         return (value);
99 }
100
101 /*
102  * Enable or disable the controller and wait for the controller to acknowledge
103  * the state change.
104  */
105 static int
106 set_controller(ig4iic_softc_t *sc, uint32_t ctl)
107 {
108         int retry;
109         int error;
110         uint32_t v;
111
112         /*
113          * When the controller is enabled, interrupt on STOP detect
114          * or receive character ready and clear pending interrupts.
115          */
116         if (ctl & IG4_I2C_ENABLE) {
117                 reg_write(sc, IG4_REG_INTR_MASK, IG4_INTR_STOP_DET |
118                                                  IG4_INTR_RX_FULL);
119                 reg_read(sc, IG4_REG_CLR_INTR);
120         } else
121                 reg_write(sc, IG4_REG_INTR_MASK, 0);
122
123         reg_write(sc, IG4_REG_I2C_EN, ctl);
124         error = IIC_ETIMEOUT;
125
126         for (retry = 100; retry > 0; --retry) {
127                 v = reg_read(sc, IG4_REG_ENABLE_STATUS);
128                 if (((v ^ ctl) & IG4_I2C_ENABLE) == 0) {
129                         error = 0;
130                         break;
131                 }
132                 if (cold)
133                         DELAY(1000);
134                 else
135                         mtx_sleep(sc, &sc->io_lock, 0, "i2cslv", 1);
136         }
137         return (error);
138 }
139
140 /*
141  * Wait up to 25ms for the requested status using a 25uS polling loop.
142  */
143 static int
144 wait_status(ig4iic_softc_t *sc, uint32_t status)
145 {
146         uint32_t v;
147         int error;
148         int txlvl = -1;
149         u_int count_us = 0;
150         u_int limit_us = 25000; /* 25ms */
151
152         error = IIC_ETIMEOUT;
153
154         for (;;) {
155                 /*
156                  * Check requested status
157                  */
158                 v = reg_read(sc, IG4_REG_I2C_STA);
159                 if (v & status) {
160                         error = 0;
161                         break;
162                 }
163
164                 /*
165                  * When waiting for receive data break-out if the interrupt
166                  * loaded data into the FIFO.
167                  */
168                 if (status & IG4_STATUS_RX_NOTEMPTY) {
169                         if (sc->rpos != sc->rnext) {
170                                 error = 0;
171                                 break;
172                         }
173                 }
174
175                 /*
176                  * When waiting for the transmit FIFO to become empty,
177                  * reset the timeout if we see a change in the transmit
178                  * FIFO level as progress is being made.
179                  */
180                 if (status & IG4_STATUS_TX_EMPTY) {
181                         v = reg_read(sc, IG4_REG_TXFLR) & IG4_FIFOLVL_MASK;
182                         if (txlvl != v) {
183                                 txlvl = v;
184                                 count_us = 0;
185                         }
186                 }
187
188                 /*
189                  * Stop if we've run out of time.
190                  */
191                 if (count_us >= limit_us)
192                         break;
193
194                 /*
195                  * When waiting for receive data let the interrupt do its
196                  * work, otherwise poll with the lock held.
197                  */
198                 if (status & IG4_STATUS_RX_NOTEMPTY) {
199                         mtx_sleep(sc, &sc->io_lock, 0, "i2cwait",
200                                   (hz + 99) / 100); /* sleep up to 10ms */
201                         count_us += 10000;
202                 } else {
203                         DELAY(25);
204                         count_us += 25;
205                 }
206         }
207
208         return (error);
209 }
210
211 /*
212  * Read I2C data.  The data might have already been read by
213  * the interrupt code, otherwise it is sitting in the data
214  * register.
215  */
216 static uint8_t
217 data_read(ig4iic_softc_t *sc)
218 {
219         uint8_t c;
220
221         if (sc->rpos == sc->rnext) {
222                 c = (uint8_t)reg_read(sc, IG4_REG_DATA_CMD);
223         } else {
224                 c = sc->rbuf[sc->rpos & IG4_RBUFMASK];
225                 ++sc->rpos;
226         }
227         return (c);
228 }
229
230 /*
231  * Set the slave address.  The controller must be disabled when
232  * changing the address.
233  *
234  * This operation does not issue anything to the I2C bus but sets
235  * the target address for when the controller later issues a START.
236  */
237 static void
238 set_slave_addr(ig4iic_softc_t *sc, uint8_t slave)
239 {
240         uint32_t tar;
241         uint32_t ctl;
242         int use_10bit;
243
244         use_10bit = 0;
245         if (sc->slave_valid && sc->last_slave == slave &&
246             sc->use_10bit == use_10bit) {
247                 return;
248         }
249         sc->use_10bit = use_10bit;
250
251         /*
252          * Wait for TXFIFO to drain before disabling the controller.
253          *
254          * If a write message has not been completed it's really a
255          * programming error, but for now in that case issue an extra
256          * byte + STOP.
257          *
258          * If a read message has not been completed it's also a programming
259          * error, for now just ignore it.
260          */
261         wait_status(sc, IG4_STATUS_TX_NOTFULL);
262         if (sc->write_started) {
263                 reg_write(sc, IG4_REG_DATA_CMD, IG4_DATA_STOP);
264                 sc->write_started = 0;
265         }
266         if (sc->read_started)
267                 sc->read_started = 0;
268         wait_status(sc, IG4_STATUS_TX_EMPTY);
269
270         set_controller(sc, 0);
271         ctl = reg_read(sc, IG4_REG_CTL);
272         ctl &= ~IG4_CTL_10BIT;
273         ctl |= IG4_CTL_RESTARTEN;
274
275         tar = slave;
276         if (sc->use_10bit) {
277                 tar |= IG4_TAR_10BIT;
278                 ctl |= IG4_CTL_10BIT;
279         }
280         reg_write(sc, IG4_REG_CTL, ctl);
281         reg_write(sc, IG4_REG_TAR_ADD, tar);
282         set_controller(sc, IG4_I2C_ENABLE);
283         sc->slave_valid = 1;
284         sc->last_slave = slave;
285 }
286
287 /*
288  *                              IICBUS API FUNCTIONS
289  */
290 static int
291 ig4iic_xfer_start(ig4iic_softc_t *sc, uint16_t slave)
292 {
293         set_slave_addr(sc, slave >> 1);
294         return (0);
295 }
296
297 static int
298 ig4iic_read(ig4iic_softc_t *sc, uint8_t *buf, uint16_t len,
299     bool repeated_start, bool stop)
300 {
301         uint32_t cmd;
302         uint16_t i;
303         int error;
304
305         if (len == 0)
306                 return (0);
307
308         cmd = IG4_DATA_COMMAND_RD;
309         cmd |= repeated_start ? IG4_DATA_RESTART : 0;
310         cmd |= stop && len == 1 ? IG4_DATA_STOP : 0;
311
312         /* Issue request for the first byte (could be last as well). */
313         reg_write(sc, IG4_REG_DATA_CMD, cmd);
314
315         for (i = 0; i < len; i++) {
316                 /*
317                  * Maintain a pipeline by queueing the allowance for the next
318                  * read before waiting for the current read.
319                  */
320                 cmd = IG4_DATA_COMMAND_RD;
321                 if (i < len - 1) {
322                         cmd = IG4_DATA_COMMAND_RD;
323                         cmd |= stop && i == len - 2 ? IG4_DATA_STOP : 0;
324                         reg_write(sc, IG4_REG_DATA_CMD, cmd);
325                 }
326                 error = wait_status(sc, IG4_STATUS_RX_NOTEMPTY);
327                 if (error)
328                         break;
329                 buf[i] = data_read(sc);
330         }
331
332         (void)reg_read(sc, IG4_REG_TX_ABRT_SOURCE);
333         return (error);
334 }
335
336 static int
337 ig4iic_write(ig4iic_softc_t *sc, uint8_t *buf, uint16_t len,
338     bool repeated_start, bool stop)
339 {
340         uint32_t cmd;
341         uint16_t i;
342         int error;
343
344         if (len == 0)
345                 return (0);
346
347         cmd = repeated_start ? IG4_DATA_RESTART : 0;
348         for (i = 0; i < len; i++) {
349                 error = wait_status(sc, IG4_STATUS_TX_NOTFULL);
350                 if (error)
351                         break;
352                 cmd |= buf[i];
353                 cmd |= stop && i == len - 1 ? IG4_DATA_STOP : 0;
354                 reg_write(sc, IG4_REG_DATA_CMD, cmd);
355                 cmd = 0;
356         }
357
358         (void)reg_read(sc, IG4_REG_TX_ABRT_SOURCE);
359         return (error);
360 }
361
362 int
363 ig4iic_transfer(device_t dev, struct iic_msg *msgs, uint32_t nmsgs)
364 {
365         ig4iic_softc_t *sc = device_get_softc(dev);
366         const char *reason = NULL;
367         uint32_t i;
368         int error;
369         int unit;
370         bool rpstart;
371         bool stop;
372
373         /*
374          * The hardware interface imposes limits on allowed I2C messages.
375          * It is not possible to explicitly send a start or stop.
376          * They are automatically sent (or not sent, depending on the
377          * configuration) when a data byte is transferred.
378          * For this reason it's impossible to send a message with no data
379          * at all (like an SMBus quick message).
380          * The start condition is automatically generated after the stop
381          * condition, so it's impossible to not have a start after a stop.
382          * The repeated start condition is automatically sent if a change
383          * of the transfer direction happens, so it's impossible to have
384          * a change of direction without a (repeated) start.
385          * The repeated start can be forced even without the change of
386          * direction.
387          * Changing the target slave address requires resetting the hardware
388          * state, so it's impossible to do that without the stop followed
389          * by the start.
390          */
391         for (i = 0; i < nmsgs; i++) {
392 #if 0
393                 if (i == 0 && (msgs[i].flags & IIC_M_NOSTART) != 0) {
394                         reason = "first message without start";
395                         break;
396                 }
397                 if (i == nmsgs - 1 && (msgs[i].flags & IIC_M_NOSTOP) != 0) {
398                         reason = "last message without stop";
399                         break;
400                 }
401 #endif
402                 if (msgs[i].len == 0) {
403                         reason = "message with no data";
404                         break;
405                 }
406                 if (i > 0) {
407                         if ((msgs[i].flags & IIC_M_NOSTART) != 0 &&
408                             (msgs[i - 1].flags & IIC_M_NOSTOP) == 0) {
409                                 reason = "stop not followed by start";
410                                 break;
411                         }
412                         if ((msgs[i - 1].flags & IIC_M_NOSTOP) != 0 &&
413                             msgs[i].slave != msgs[i - 1].slave) {
414                                 reason = "change of slave without stop";
415                                 break;
416                         }
417                         if ((msgs[i].flags & IIC_M_NOSTART) != 0 &&
418                             (msgs[i].flags & IIC_M_RD) !=
419                             (msgs[i - 1].flags & IIC_M_RD)) {
420                                 reason = "change of direction without repeated"
421                                     " start";
422                                 break;
423                         }
424                 }
425         }
426         if (reason != NULL) {
427                 if (bootverbose)
428                         device_printf(dev, "%s\n", reason);
429                 return (IIC_ENOTSUPP);
430         }
431
432         sx_xlock(&sc->call_lock);
433         mtx_lock(&sc->io_lock);
434
435         /* Debugging - dump registers. */
436         if (ig4_dump) {
437                 unit = device_get_unit(dev);
438                 if (ig4_dump & (1 << unit)) {
439                         ig4_dump &= ~(1 << unit);
440                         ig4iic_dump(sc);
441                 }
442         }
443
444         /*
445          * Clear any previous abort condition that may have been holding
446          * the txfifo in reset.
447          */
448         reg_read(sc, IG4_REG_CLR_TX_ABORT);
449
450         /*
451          * Clean out any previously received data.
452          */
453         if (sc->rpos != sc->rnext && bootverbose) {
454                 device_printf(sc->dev, "discarding %d bytes of spurious data\n",
455                     sc->rnext - sc->rpos);
456         }
457         sc->rpos = 0;
458         sc->rnext = 0;
459
460         rpstart = false;
461         error = 0;
462         for (i = 0; i < nmsgs; i++) {
463                 if ((msgs[i].flags & IIC_M_NOSTART) == 0) {
464                         error = ig4iic_xfer_start(sc, msgs[i].slave);
465                 } else {
466                         if (!sc->slave_valid ||
467                             (msgs[i].slave >> 1) != sc->last_slave) {
468                                 device_printf(dev, "start condition suppressed"
469                                     "but slave address is not set up");
470                                 error = EINVAL;
471                                 break;
472                         }
473                         rpstart = false;
474                 }
475                 if (error != 0)
476                         break;
477
478                 stop = (msgs[i].flags & IIC_M_NOSTOP) == 0;
479                 if (msgs[i].flags & IIC_M_RD)
480                         error = ig4iic_read(sc, msgs[i].buf, msgs[i].len,
481                             rpstart, stop);
482                 else
483                         error = ig4iic_write(sc, msgs[i].buf, msgs[i].len,
484                             rpstart, stop);
485                 if (error != 0)
486                         break;
487
488                 rpstart = !stop;
489         }
490
491         mtx_unlock(&sc->io_lock);
492         sx_unlock(&sc->call_lock);
493         return (error);
494 }
495
496 int
497 ig4iic_reset(device_t dev, u_char speed, u_char addr, u_char *oldaddr)
498 {
499         ig4iic_softc_t *sc = device_get_softc(dev);
500
501         sx_xlock(&sc->call_lock);
502         mtx_lock(&sc->io_lock);
503
504         /* TODO handle speed configuration? */
505         if (oldaddr != NULL)
506                 *oldaddr = sc->last_slave << 1;
507         set_slave_addr(sc, addr >> 1);
508         if (addr == IIC_UNKNOWN)
509                 sc->slave_valid = false;
510
511         mtx_unlock(&sc->io_lock);
512         sx_unlock(&sc->call_lock);
513         return (0);
514 }
515
516 /*
517  * Called from ig4iic_pci_attach/detach()
518  */
519 int
520 ig4iic_attach(ig4iic_softc_t *sc)
521 {
522         int error;
523         uint32_t v;
524
525         mtx_init(&sc->io_lock, "IG4 I/O lock", NULL, MTX_DEF);
526         sx_init(&sc->call_lock, "IG4 call lock");
527
528         v = reg_read(sc, IG4_REG_COMP_TYPE);
529         v = reg_read(sc, IG4_REG_COMP_PARAM1);
530         v = reg_read(sc, IG4_REG_GENERAL);
531         if ((v & IG4_GENERAL_SWMODE) == 0) {
532                 v |= IG4_GENERAL_SWMODE;
533                 reg_write(sc, IG4_REG_GENERAL, v);
534                 v = reg_read(sc, IG4_REG_GENERAL);
535         }
536
537         v = reg_read(sc, IG4_REG_SW_LTR_VALUE);
538         v = reg_read(sc, IG4_REG_AUTO_LTR_VALUE);
539
540         v = reg_read(sc, IG4_REG_COMP_VER);
541         if (v != IG4_COMP_VER) {
542                 error = ENXIO;
543                 goto done;
544         }
545         v = reg_read(sc, IG4_REG_SS_SCL_HCNT);
546         v = reg_read(sc, IG4_REG_SS_SCL_LCNT);
547         v = reg_read(sc, IG4_REG_FS_SCL_HCNT);
548         v = reg_read(sc, IG4_REG_FS_SCL_LCNT);
549         v = reg_read(sc, IG4_REG_SDA_HOLD);
550
551         v = reg_read(sc, IG4_REG_SS_SCL_HCNT);
552         reg_write(sc, IG4_REG_FS_SCL_HCNT, v);
553         v = reg_read(sc, IG4_REG_SS_SCL_LCNT);
554         reg_write(sc, IG4_REG_FS_SCL_LCNT, v);
555
556         /*
557          * Program based on a 25000 Hz clock.  This is a bit of a
558          * hack (obviously).  The defaults are 400 and 470 for standard
559          * and 60 and 130 for fast.  The defaults for standard fail
560          * utterly (presumably cause an abort) because the clock time
561          * is ~18.8ms by default.  This brings it down to ~4ms (for now).
562          */
563         reg_write(sc, IG4_REG_SS_SCL_HCNT, 100);
564         reg_write(sc, IG4_REG_SS_SCL_LCNT, 125);
565         reg_write(sc, IG4_REG_FS_SCL_HCNT, 100);
566         reg_write(sc, IG4_REG_FS_SCL_LCNT, 125);
567
568         /*
569          * Use a threshold of 1 so we get interrupted on each character,
570          * allowing us to use mtx_sleep() in our poll code.  Not perfect
571          * but this is better than using DELAY() for receiving data.
572          *
573          * See ig4_var.h for details on interrupt handler synchronization.
574          */
575         reg_write(sc, IG4_REG_RX_TL, 1);
576
577         reg_write(sc, IG4_REG_CTL,
578                   IG4_CTL_MASTER |
579                   IG4_CTL_SLAVE_DISABLE |
580                   IG4_CTL_RESTARTEN |
581                   IG4_CTL_SPEED_STD);
582
583         sc->iicbus = device_add_child(sc->dev, "iicbus", -1);
584         if (sc->iicbus == NULL) {
585                 device_printf(sc->dev, "iicbus driver not found\n");
586                 error = ENXIO;
587                 goto done;
588         }
589
590 #if 0
591         /*
592          * Don't do this, it blows up the PCI config
593          */
594         reg_write(sc, IG4_REG_RESETS, IG4_RESETS_ASSERT);
595         reg_write(sc, IG4_REG_RESETS, IG4_RESETS_DEASSERT);
596 #endif
597
598         mtx_lock(&sc->io_lock);
599         if (set_controller(sc, 0))
600                 device_printf(sc->dev, "controller error during attach-1\n");
601         if (set_controller(sc, IG4_I2C_ENABLE))
602                 device_printf(sc->dev, "controller error during attach-2\n");
603         mtx_unlock(&sc->io_lock);
604         error = bus_setup_intr(sc->dev, sc->intr_res, INTR_TYPE_MISC | INTR_MPSAFE,
605                                NULL, ig4iic_intr, sc, &sc->intr_handle);
606         if (error) {
607                 device_printf(sc->dev,
608                               "Unable to setup irq: error %d\n", error);
609         }
610
611         sc->enum_hook.ich_func = ig4iic_start;
612         sc->enum_hook.ich_arg = sc->dev;
613
614         /*
615          * We have to wait until interrupts are enabled. I2C read and write
616          * only works if the interrupts are available.
617          */
618         if (config_intrhook_establish(&sc->enum_hook) != 0)
619                 error = ENOMEM;
620         else
621                 error = 0;
622
623 done:
624         return (error);
625 }
626
627 void
628 ig4iic_start(void *xdev)
629 {
630         int error;
631         ig4iic_softc_t *sc;
632         device_t dev = (device_t)xdev;
633
634         sc = device_get_softc(dev);
635
636         config_intrhook_disestablish(&sc->enum_hook);
637
638         error = bus_generic_attach(sc->dev);
639         if (error) {
640                 device_printf(sc->dev,
641                               "failed to attach child: error %d\n", error);
642         }
643 }
644
645 int
646 ig4iic_detach(ig4iic_softc_t *sc)
647 {
648         int error;
649
650         if (device_is_attached(sc->dev)) {
651                 error = bus_generic_detach(sc->dev);
652                 if (error)
653                         return (error);
654         }
655         if (sc->iicbus)
656                 device_delete_child(sc->dev, sc->iicbus);
657         if (sc->intr_handle)
658                 bus_teardown_intr(sc->dev, sc->intr_res, sc->intr_handle);
659
660         sx_xlock(&sc->call_lock);
661         mtx_lock(&sc->io_lock);
662
663         sc->iicbus = NULL;
664         sc->intr_handle = NULL;
665         reg_write(sc, IG4_REG_INTR_MASK, 0);
666         set_controller(sc, 0);
667
668         mtx_unlock(&sc->io_lock);
669         sx_xunlock(&sc->call_lock);
670
671         mtx_destroy(&sc->io_lock);
672         sx_destroy(&sc->call_lock);
673
674         return (0);
675 }
676
677 /*
678  * Interrupt Operation, see ig4_var.h for locking semantics.
679  */
680 static void
681 ig4iic_intr(void *cookie)
682 {
683         ig4iic_softc_t *sc = cookie;
684         uint32_t status;
685
686         mtx_lock(&sc->io_lock);
687 /*      reg_write(sc, IG4_REG_INTR_MASK, IG4_INTR_STOP_DET);*/
688         reg_read(sc, IG4_REG_CLR_INTR);
689         status = reg_read(sc, IG4_REG_I2C_STA);
690         while (status & IG4_STATUS_RX_NOTEMPTY) {
691                 sc->rbuf[sc->rnext & IG4_RBUFMASK] =
692                     (uint8_t)reg_read(sc, IG4_REG_DATA_CMD);
693                 ++sc->rnext;
694                 status = reg_read(sc, IG4_REG_I2C_STA);
695         }
696         wakeup(sc);
697         mtx_unlock(&sc->io_lock);
698 }
699
700 #define REGDUMP(sc, reg)        \
701         device_printf(sc->dev, "  %-23s %08x\n", #reg, reg_read(sc, reg))
702
703 static void
704 ig4iic_dump(ig4iic_softc_t *sc)
705 {
706         device_printf(sc->dev, "ig4iic register dump:\n");
707         REGDUMP(sc, IG4_REG_CTL);
708         REGDUMP(sc, IG4_REG_TAR_ADD);
709         REGDUMP(sc, IG4_REG_SS_SCL_HCNT);
710         REGDUMP(sc, IG4_REG_SS_SCL_LCNT);
711         REGDUMP(sc, IG4_REG_FS_SCL_HCNT);
712         REGDUMP(sc, IG4_REG_FS_SCL_LCNT);
713         REGDUMP(sc, IG4_REG_INTR_STAT);
714         REGDUMP(sc, IG4_REG_INTR_MASK);
715         REGDUMP(sc, IG4_REG_RAW_INTR_STAT);
716         REGDUMP(sc, IG4_REG_RX_TL);
717         REGDUMP(sc, IG4_REG_TX_TL);
718         REGDUMP(sc, IG4_REG_I2C_EN);
719         REGDUMP(sc, IG4_REG_I2C_STA);
720         REGDUMP(sc, IG4_REG_TXFLR);
721         REGDUMP(sc, IG4_REG_RXFLR);
722         REGDUMP(sc, IG4_REG_SDA_HOLD);
723         REGDUMP(sc, IG4_REG_TX_ABRT_SOURCE);
724         REGDUMP(sc, IG4_REG_SLV_DATA_NACK);
725         REGDUMP(sc, IG4_REG_DMA_CTRL);
726         REGDUMP(sc, IG4_REG_DMA_TDLR);
727         REGDUMP(sc, IG4_REG_DMA_RDLR);
728         REGDUMP(sc, IG4_REG_SDA_SETUP);
729         REGDUMP(sc, IG4_REG_ENABLE_STATUS);
730         REGDUMP(sc, IG4_REG_COMP_PARAM1);
731         REGDUMP(sc, IG4_REG_COMP_VER);
732         REGDUMP(sc, IG4_REG_COMP_TYPE);
733         REGDUMP(sc, IG4_REG_CLK_PARMS);
734         REGDUMP(sc, IG4_REG_RESETS);
735         REGDUMP(sc, IG4_REG_GENERAL);
736         REGDUMP(sc, IG4_REG_SW_LTR_VALUE);
737         REGDUMP(sc, IG4_REG_AUTO_LTR_VALUE);
738 }
739 #undef REGDUMP
740
741 DRIVER_MODULE(iicbus, ig4iic_acpi, iicbus_driver, iicbus_devclass, NULL, NULL);
742 DRIVER_MODULE(iicbus, ig4iic_pci, iicbus_driver, iicbus_devclass, NULL, NULL);