1 /* 2 * SPDX-License-Identifier: BSD-2-Clause 3 * 4 * Copyright (c) 2025 Poul-Henning Kamp <phk@FreeBSD.org> 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 16 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18 * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, 19 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 20 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 21 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 23 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 24 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 25 * POSSIBILITY OF SUCH DAMAGE. 26 * 27 * QualComm GENI I2C controller 28 * 29 * The GENI is actually a multi-protocol serial controller, so a lot of 30 * this can probably be shared if we ever get to those protocols. 31 * 32 * The best open "documentation" of the hardware is the Linux device driver 33 * from which much was learned, and we tip our hat to the authors of it. 34 */ 35 36 #include <sys/cdefs.h> 37 38 #include "opt_acpi.h" 39 40 #include <sys/param.h> 41 #include <sys/kernel.h> 42 #include <sys/module.h> 43 #include <sys/endian.h> 44 #include <sys/time.h> 45 #include <sys/lock.h> 46 #include <sys/mutex.h> 47 #include <sys/sysctl.h> 48 #include <sys/sx.h> 49 #include <sys/bus.h> 50 51 #include <machine/bus.h> 52 #include <sys/rman.h> 53 54 #include <dev/iicbus/iicbus.h> 55 #include <dev/iicbus/iiconf.h> 56 57 #include <dev/iicbus/controller/qcom/geni_iic_var.h> 58 59 #define GENI_ALL_REGISTERS(THIS_MACRO) \ 60 THIS_MACRO(GENI_FORCE_DEFAULT_REG, 0x020) \ 61 THIS_MACRO(GENI_OUTPUT_CTRL, 0x024) \ 62 THIS_MACRO(GENI_STATUS, 0x040) \ 63 THIS_MACRO(GENI_SER_M_CLK_CFG, 0x048) \ 64 THIS_MACRO(GENI_SER_S_CLK_CFG, 0x04c) \ 65 THIS_MACRO(GENI_IF_DISABLE_RO, 0x064) \ 66 THIS_MACRO(GENI_FW_REVISION_RO, 0x068) \ 67 THIS_MACRO(GENI_CLK_SEL, 0x07c) \ 68 THIS_MACRO(GENI_CFG_SEQ_START, 0x084) \ 69 THIS_MACRO(GENI_BYTE_GRANULARITY, 0x254) \ 70 THIS_MACRO(GENI_DMA_MODE_EN, 0x258) \ 71 THIS_MACRO(GENI_TX_PACKING_CFG0, 0x260) \ 72 THIS_MACRO(GENI_TX_PACKING_CFG1, 0x264) \ 73 THIS_MACRO(GENI_I2C_TX_TRANS_LEN, 0x26c) \ 74 THIS_MACRO(GENI_I2C_RX_TRANS_LEN, 0x270) \ 75 THIS_MACRO(GENI_I2C_SCL_COUNTERS, 0x278) \ 76 THIS_MACRO(GENI_RX_PACKING_CFG0, 0x284) \ 77 THIS_MACRO(GENI_RX_PACKING_CFG1, 0x288) \ 78 THIS_MACRO(GENI_M_CMD0, 0x600) \ 79 THIS_MACRO(GENI_M_CMD_CTRL_REG, 0x604) \ 80 THIS_MACRO(GENI_M_IRQ_STATUS, 0x610) \ 81 THIS_MACRO(GENI_M_IRQ_EN, 0x614) \ 82 THIS_MACRO(GENI_M_IRQ_CLEAR, 0x618) \ 83 THIS_MACRO(GENI_M_IRQ_EN_SET, 0x61c) \ 84 THIS_MACRO(GENI_M_IRQ_EN_CLEAR, 0x620) \ 85 THIS_MACRO(GENI_S_CMD0, 0x630) \ 86 THIS_MACRO(GENI_S_CMD_CTRL_REG, 0x634) \ 87 THIS_MACRO(GENI_S_IRQ_STATUS, 0x640) \ 88 THIS_MACRO(GENI_S_IRQ_EN, 0x644) \ 89 THIS_MACRO(GENI_S_IRQ_CLEAR, 0x648) \ 90 THIS_MACRO(GENI_S_IRQ_EN_SET, 0x64c) \ 91 THIS_MACRO(GENI_S_IRQ_EN_CLEAR, 0x650) \ 92 THIS_MACRO(GENI_TX_FIFOn, 0x700) \ 93 THIS_MACRO(GENI_RX_FIFOn, 0x780) \ 94 THIS_MACRO(GENI_TX_FIFO_STATUS, 0x800) \ 95 THIS_MACRO(GENI_RX_FIFO_STATUS, 0x804) \ 96 THIS_MACRO(GENI_TX_WATERMARK_REG, 0x80c) \ 97 THIS_MACRO(GENI_RX_WATERMARK_REG, 0x810) \ 98 THIS_MACRO(GENI_RX_RFR_WATERMARK_REG, 0x814) \ 99 THIS_MACRO(GENI_IOS, 0x908) \ 100 THIS_MACRO(GENI_M_GP_LENGTH, 0x910) \ 101 THIS_MACRO(GENI_S_GP_LENGTH, 0x914) \ 102 THIS_MACRO(GENI_DMA_TX_IRQ_STAT, 0xc40) \ 103 THIS_MACRO(GENI_DMA_TX_IRQ_CLR, 0xc44) \ 104 THIS_MACRO(GENI_DMA_TX_IRQ_EN, 0xc48) \ 105 THIS_MACRO(GENI_DMA_TX_IRQ_EN_CLR, 0xc4c) \ 106 THIS_MACRO(GENI_DMA_TX_IRQ_EN_SET, 0xc50) \ 107 THIS_MACRO(GENI_DMA_TX_FSM_RST, 0xc58) \ 108 THIS_MACRO(GENI_DMA_RX_IRQ_STAT, 0xd40) \ 109 THIS_MACRO(GENI_DMA_RX_IRQ_CLR, 0xd44) \ 110 THIS_MACRO(GENI_DMA_RX_IRQ_EN, 0xd48) \ 111 THIS_MACRO(GENI_DMA_RX_IRQ_EN_CLR, 0xd4c) \ 112 THIS_MACRO(GENI_DMA_RX_IRQ_EN_SET, 0xd50) \ 113 THIS_MACRO(GENI_DMA_RX_LEN_IN, 0xd54) \ 114 THIS_MACRO(GENI_DMA_RX_FSM_RST, 0xd58) \ 115 THIS_MACRO(GENI_IRQ_EN, 0xe1c) \ 116 THIS_MACRO(GENI_HW_PARAM_0, 0xe24) \ 117 THIS_MACRO(GENI_HW_PARAM_1, 0xe28) 118 119 enum geni_registers { 120 #define ITER_MACRO(name, offset) name = offset, 121 GENI_ALL_REGISTERS(ITER_MACRO) 122 #undef ITER_MACRO 123 }; 124 125 #define RD(sc, reg) bus_read_4((sc)->regs_res, reg) 126 #define WR(sc, reg, val) bus_write_4((sc)->regs_res, reg, val) 127 128 static void 129 geni_dump_regs(geniiic_softc_t *sc) 130 { 131 device_printf(sc->dev, "Register Dump\n"); 132 #define DUMP_MACRO(name, offset) \ 133 device_printf(sc->dev, \ 134 " %08x %04x " #name "\n", \ 135 RD(sc, offset), offset); 136 GENI_ALL_REGISTERS(DUMP_MACRO) 137 #undef DUMP_MACRO 138 } 139 140 static unsigned geniiic_debug_units = 0; 141 142 static SYSCTL_NODE(_hw, OID_AUTO, geniiic, CTLFLAG_RW, 0, "GENI I2C"); 143 SYSCTL_INT(_hw_geniiic, OID_AUTO, debug_units, CTLFLAG_RWTUN, 144 &geniiic_debug_units, 1, "Bitmask of units to debug"); 145 146 147 static driver_filter_t geniiic_intr; 148 149 static int 150 geniiic_intr(void *cookie) 151 { 152 uint32_t m_status, rx_fifo_status; 153 int retval = FILTER_STRAY; 154 geniiic_softc_t *sc = cookie; 155 156 mtx_lock_spin(&sc->intr_lock); 157 m_status = RD(sc, GENI_M_IRQ_STATUS); 158 159 rx_fifo_status = RD(sc, GENI_RX_FIFO_STATUS); 160 if (sc->rx_buf != NULL && rx_fifo_status & 0x3f) { 161 162 // Number of whole FIFO words, each 4 bytes 163 unsigned gotlen = (((rx_fifo_status & 0x3f) << 2)-1) * 4; 164 165 // Valid bytes in the last FIFO word 166 // (Field is 3 bits, we'll only ever see 0…3) 167 gotlen += (rx_fifo_status >> 28) & 0x7; 168 169 unsigned cnt; 170 for (cnt = 0; cnt < (rx_fifo_status & 0x3f); cnt++) { 171 uint32_t data = RD(sc, GENI_RX_FIFOn); 172 unsigned u; 173 for (u = 0; u < 4 && sc->rx_len && gotlen; u++) { 174 *sc->rx_buf++ = data & 0xff; 175 data >>= 8; 176 sc->rx_len--; 177 gotlen--; 178 } 179 } 180 } 181 if (m_status & (1<<26)) { 182 WR(sc, GENI_M_IRQ_CLEAR, (1<<26)); 183 retval = FILTER_HANDLED; 184 } 185 186 if (m_status & (1<<0)) { 187 sc->rx_complete = true; 188 WR(sc, GENI_M_IRQ_EN_CLEAR, (1<<0)); 189 WR(sc, GENI_M_IRQ_EN_CLEAR, (1<<26)); 190 WR(sc, GENI_M_IRQ_CLEAR, (1<<0)); 191 wakeup(sc); 192 retval = FILTER_HANDLED; 193 } 194 sc->cmd_status = m_status; 195 196 if (sc->rx_buf == NULL) { 197 device_printf(sc->dev, 198 "Interrupt m_stat %x rx_fifo_status %x retval %d\n", 199 m_status, rx_fifo_status, retval); 200 WR(sc, GENI_M_IRQ_EN, 0); 201 WR(sc, GENI_M_IRQ_CLEAR, m_status); 202 device_printf(sc->dev, 203 "Interrupt M_IRQ_STATUS 0x%x M_IRQ_EN 0x%x\n", 204 RD(sc, GENI_M_IRQ_STATUS), RD(sc, GENI_M_IRQ_EN)); 205 device_printf(sc->dev, 206 "Interrupt S_IRQ_STATUS 0x%x S_IRQ_EN 0x%x\n", 207 RD(sc, GENI_S_IRQ_STATUS), RD(sc, GENI_S_IRQ_EN)); 208 device_printf(sc->dev, 209 "Interrupt DMA_TX_IRQ_STAT 0x%x DMA_RX_IRQ_STAT 0x%x\n", 210 RD(sc, GENI_DMA_TX_IRQ_STAT), RD(sc, GENI_DMA_RX_IRQ_STAT)); 211 device_printf(sc->dev, 212 "Interrupt DMA_TX_IRQ_EN 0x%x DMA_RX_IRQ_EN 0x%x\n", 213 RD(sc, GENI_DMA_TX_IRQ_EN), RD(sc, GENI_DMA_RX_IRQ_EN)); 214 WR(sc, GENI_DMA_TX_IRQ_EN_CLR, RD(sc, GENI_DMA_TX_IRQ_STAT)); 215 WR(sc, GENI_DMA_TX_IRQ_CLR, RD(sc, GENI_DMA_TX_IRQ_STAT)); 216 WR(sc, GENI_DMA_RX_IRQ_EN_CLR, RD(sc, GENI_DMA_RX_IRQ_STAT)); 217 WR(sc, GENI_DMA_RX_IRQ_CLR, RD(sc, GENI_DMA_RX_IRQ_STAT)); 218 } 219 mtx_unlock_spin(&sc->intr_lock); 220 return(retval); 221 } 222 223 static int 224 geniiic_wait_m_ireq(geniiic_softc_t *sc, uint32_t bits) 225 { 226 uint32_t status; 227 int timeout; 228 229 for (timeout = 0; timeout < 10000; timeout++) { 230 status = RD(sc, GENI_M_IRQ_STATUS); 231 if (status & bits) { 232 return (0); 233 } 234 DELAY(10); 235 } 236 return (IIC_ETIMEOUT); 237 } 238 239 static int 240 geniiic_read(geniiic_softc_t *sc, 241 uint8_t slave, uint8_t *buf, uint16_t len, bool nonfinal) 242 { 243 uint32_t cmd, istatus; 244 245 istatus = RD(sc, GENI_M_IRQ_STATUS); 246 WR(sc, GENI_M_IRQ_CLEAR, istatus); 247 248 sc->rx_complete = false; 249 sc->rx_fifo = false; 250 sc->rx_buf = buf; 251 sc->rx_len = len; 252 WR(sc, GENI_I2C_RX_TRANS_LEN, len); 253 254 // GENI_M_CMD0_OPCODE_I2C_READ << M_OPCODE_SHFT 255 cmd = (0x2 << 27); 256 257 // GENI_M_CMD0_SLV_ADDR_SHIFT 258 cmd |= slave << 9; 259 260 if (nonfinal) { 261 // GENI_M_CMD0_STOP_STRETCH 262 cmd |= (1<<2); 263 } 264 WR(sc, GENI_RX_WATERMARK_REG, sc->rx_fifo_size - 4); 265 266 // CMD_DONE, RX_FIFO_WATERMARK 267 WR(sc, GENI_M_IRQ_EN, (1<<0) | (1<<26)); 268 269 // M_IRQ 270 WR(sc, GENI_IRQ_EN, (1<<2)); 271 272 WR(sc, GENI_M_CMD0, cmd); 273 274 mtx_lock_spin(&sc->intr_lock); 275 sc->rx_fifo = false; 276 unsigned msec; 277 for (msec = 0; msec < 100; msec++) { 278 msleep_spin_sbt(sc, &sc->intr_lock, 279 "geniwait", SBT_1MS, SBT_1MS / 10, 0); 280 if (sc->rx_complete) 281 break; 282 } 283 if (msec > sc->worst) { 284 device_printf(sc->dev, 285 "Tworst from %u to %u\n", sc->worst, msec); 286 if (msec != 100) 287 sc->worst = msec; 288 } 289 290 if (!sc->rx_complete) { 291 // S_GENI_CMD_CANCEL 292 WR(sc, GENI_M_CMD_CTRL_REG, (1<<2)); 293 294 WR(sc, GENI_IRQ_EN, 0); 295 device_printf(sc->dev, 296 "Incomplete read (residual %x)\n", sc->rx_len); 297 } 298 299 sc->rx_buf = NULL; 300 len = sc->rx_len; 301 sc->rx_len = 0; 302 303 mtx_unlock_spin(&sc->intr_lock); 304 305 #define COMPLAIN(about) \ 306 device_printf(sc->dev, \ 307 "read " about " slave=0x%x len=0x%x, cmd=0x%x cmd_status=0x%x\n", \ 308 slave, len, cmd, sc->cmd_status \ 309 ) 310 311 if (geniiic_debug_units) { 312 unsigned unit = device_get_unit(sc->dev); 313 if (unit < 32 && geniiic_debug_units & (1<<unit) && len == 0) { 314 COMPLAIN("OK"); 315 return(IIC_NOERR); 316 } 317 } 318 if (len == 0) 319 return(IIC_NOERR); 320 321 if (sc->cmd_status & (1<<10)) { 322 COMPLAIN("ESTATUS"); 323 return(IIC_ESTATUS); 324 } 325 if (len) { 326 COMPLAIN("EUNDERFLOW"); 327 return(IIC_EUNDERFLOW); 328 } 329 COMPLAIN("EBUSERR"); 330 return (IIC_EBUSERR); 331 #undef COMPLAIN 332 } 333 334 static int 335 geniiic_write(geniiic_softc_t *sc, 336 uint8_t slave, uint8_t *buf, uint16_t len, bool nonfinal) 337 { 338 uint32_t status, data, cmd; 339 int timeout, error; 340 341 status = RD(sc, GENI_M_IRQ_STATUS); 342 WR(sc, GENI_M_IRQ_CLEAR, status); 343 344 WR(sc, GENI_I2C_TX_TRANS_LEN, len); 345 346 // GENI_M_CMD0_OPCODE_I2C_WRITE << M_OPCODE_SHFT 347 cmd = (0x1 << 27); 348 349 // GENI_M_CMD0_SLV_ADDR_SHIFT 350 cmd |= slave << 9; 351 352 if (nonfinal) { 353 // GENI_M_CMD0_STOP_STRETCH 354 cmd |= (1<<2); 355 } 356 WR(sc, GENI_M_CMD0, cmd); 357 for(timeout = 0; len > 0 && timeout < 100; timeout++) { 358 status = RD(sc, GENI_TX_FIFO_STATUS); 359 if (status < 16) { 360 data = 0; 361 if (len) { data |= *buf << 0; buf++; len--; } 362 if (len) { data |= *buf << 8; buf++; len--; } 363 if (len) { data |= *buf << 16; buf++; len--; } 364 if (len) { data |= *buf << 24; buf++; len--; } 365 WR(sc, GENI_TX_FIFOn, data); 366 } else { 367 DELAY(10); 368 } 369 } 370 371 // GENI_M_IRQ_CMD_DONE 372 error = geniiic_wait_m_ireq(sc, 1); 373 374 if (len == 0 && error == 0) 375 return(IIC_NOERR); 376 device_printf(sc->dev, 377 "write ERR len=%d, error=%d cmd=0x%x\n", len, error, cmd); 378 return (IIC_EBUSERR); 379 } 380 381 static void 382 geniiic_dumpmsg(device_t dev, struct iic_msg *msgs, uint32_t nmsgs) 383 { 384 unsigned u; 385 386 device_printf(dev, "transfer:\n"); 387 for (u = 0; u < nmsgs; u++) { 388 device_printf(dev, 389 " [%d] slave=0x%x, flags=0x%x len=0x%x buf=%p\n", 390 u, msgs[u].slave, msgs[u].flags, msgs[u].len, msgs[u].buf 391 ); 392 } 393 } 394 395 int 396 geniiic_transfer(device_t dev, struct iic_msg *msgs, uint32_t nmsgs) 397 { 398 geniiic_softc_t *sc = device_get_softc(dev); 399 unsigned u; 400 int error; 401 402 if (sc->nfail > 4) { 403 pause_sbt("geniic_fail", SBT_1S * 5, SBT_1S, 0); 404 return (IIC_ERESOURCE); 405 } 406 407 sx_xlock(&sc->real_bus_lock); 408 409 if (geniiic_debug_units) { 410 unsigned unit = device_get_unit(dev); 411 if (unit < 32 && geniiic_debug_units & (1<<unit)) { 412 geniiic_dumpmsg(dev, msgs, nmsgs); 413 } 414 } 415 416 error = 0; 417 for (u = 0; u < nmsgs; u++) { 418 bool nonfinal = 419 (u < nmsgs - 1) && (msgs[u].flags & IIC_M_NOSTOP); 420 unsigned slave = msgs[u].slave >> 1; 421 if (msgs[u].flags & IIC_M_RD) { 422 error = geniiic_read(sc, 423 slave, msgs[u].buf, msgs[u].len, nonfinal); 424 } else { 425 error = geniiic_write(sc, 426 slave, msgs[u].buf, msgs[u].len, nonfinal); 427 } 428 } 429 if (error) { 430 device_printf(dev, "transfer error %d\n", error); 431 geniiic_dumpmsg(dev, msgs, nmsgs); 432 } 433 if (error) { 434 geniiic_reset(dev, 0, 0, NULL); 435 } 436 if (error) 437 sc->nfail++; 438 else 439 sc->nfail = 0; 440 sx_xunlock(&sc->real_bus_lock); 441 return (error); 442 } 443 444 int 445 geniiic_reset(device_t dev, u_char speed, u_char addr, u_char *oldaddr) 446 { 447 geniiic_softc_t *sc = device_get_softc(dev); 448 unsigned u; 449 450 device_printf(dev, "reset\n"); 451 WR(sc, GENI_M_IRQ_EN, 0); 452 WR(sc, GENI_M_IRQ_CLEAR, ~0); 453 WR(sc, GENI_DMA_TX_IRQ_EN_CLR, ~0); 454 WR(sc, GENI_DMA_TX_IRQ_CLR, ~0); 455 WR(sc, GENI_DMA_RX_IRQ_EN_CLR, ~0); 456 WR(sc, GENI_DMA_RX_IRQ_CLR, ~0); 457 458 // S_GENI_CMD_ABORT 459 WR(sc, GENI_M_CMD_CTRL_REG, (1<<1)); 460 461 WR(sc, GENI_DMA_RX_FSM_RST, 1); 462 for (u = 0; u < 1000; u++) { 463 if (RD(sc, GENI_DMA_RX_IRQ_STAT) & 0x8) 464 break; 465 DELAY(10); 466 } 467 if (u > 0) 468 device_printf(dev, "RXRESET time %u\n", u); 469 WR(sc, GENI_DMA_TX_FSM_RST, 1); 470 for (u = 0; u < 1000; u++) { 471 if (RD(sc, GENI_DMA_TX_IRQ_STAT) & 0x8) 472 break; 473 DELAY(10); 474 } 475 if (u > 0) 476 device_printf(dev, "TXRESET time %u\n", u); 477 return (0); 478 } 479 480 int 481 geniiic_callback(device_t dev, int index, caddr_t data) 482 { 483 geniiic_softc_t *sc = device_get_softc(dev); 484 int error = 0; 485 486 return(0); 487 switch (index) { 488 case IIC_REQUEST_BUS: 489 if (sx_try_xlock(&sc->bus_lock) == 0) 490 error = IIC_EBUSBSY; 491 else 492 sc->bus_locked = true; 493 break; 494 495 case IIC_RELEASE_BUS: 496 if (!sc->bus_locked) { 497 device_printf(dev, "Unlocking unlocked bus\n"); 498 } 499 sc->bus_locked = false; 500 sx_xunlock(&sc->bus_lock); 501 break; 502 503 default: 504 device_printf(dev, "callback unknown %d\n", index); 505 error = errno2iic(EINVAL); 506 } 507 508 return (error); 509 } 510 511 int 512 geniiic_attach(geniiic_softc_t *sc) 513 { 514 int error = 0; 515 516 if (bootverbose) 517 geni_dump_regs(sc); 518 mtx_init(&sc->intr_lock, "geniiic intr lock", NULL, MTX_SPIN); 519 sx_init(&sc->real_bus_lock, "geniiic real bus lock"); 520 sx_init(&sc->bus_lock, "geniiic bus lock"); 521 522 sc->rx_fifo_size = (RD(sc, GENI_HW_PARAM_1) >> 16) & 0x3f; 523 device_printf(sc->dev, " RX fifo size= 0x%x\n", sc->rx_fifo_size); 524 525 // We might want to set/check the following registers: 526 // GENI_BYTE_GRANULARITY (0x00000000) 527 // GENI_TX_PACKING_CFG0 (0x0007f8fe) 528 // GENI_TX_PACKING_CFG1 (000ffefe) 529 // GENI_RX_PACKING_CFG0 (0x0007f8fe) 530 // GENI_RX_PACKING_CFG1 (000ffefe) 531 532 sc->iicbus = device_add_child(sc->dev, "iicbus", DEVICE_UNIT_ANY); 533 if (sc->iicbus == NULL) { 534 device_printf(sc->dev, "iicbus driver not found\n"); 535 return(ENXIO); 536 } 537 538 error = bus_setup_intr(sc->dev, 539 sc->intr_res, INTR_TYPE_MISC | INTR_MPSAFE, 540 geniiic_intr, NULL, sc, &sc->intr_handle); 541 if (error) { 542 device_printf(sc->dev, 543 "Unable to setup irq: error %d\n", error); 544 } 545 546 bus_attach_children(sc->dev); 547 return (error); 548 } 549 550 int 551 geniiic_detach(geniiic_softc_t *sc) 552 { 553 int error = 0; 554 555 error = bus_generic_detach(sc->dev); 556 if (error) 557 return (error); 558 559 WR(sc, GENI_M_IRQ_EN, 0); 560 561 if (sc->intr_handle) { 562 bus_teardown_intr(sc->dev, sc->intr_res, sc->intr_handle); 563 } 564 565 sx_xlock(&sc->bus_lock); 566 sx_xlock(&sc->real_bus_lock); 567 568 geniiic_reset(sc->dev, 0, 0, NULL); 569 sc->iicbus = NULL; 570 sc->intr_handle = NULL; 571 572 sx_xunlock(&sc->real_bus_lock); 573 sx_xunlock(&sc->bus_lock); 574 575 sx_destroy(&sc->real_bus_lock); 576 sx_destroy(&sc->bus_lock); 577 578 mtx_destroy(&sc->intr_lock); 579 return (error); 580 } 581 582 int 583 geniiic_suspend(geniiic_softc_t *sc) 584 { 585 int error; 586 587 device_printf(sc->dev, "suspend method is NO-OP (good luck!)\n"); 588 589 error = bus_generic_suspend(sc->dev); 590 591 return (error); 592 } 593 594 int geniiic_resume(geniiic_softc_t *sc) 595 { 596 int error; 597 598 device_printf(sc->dev, "resume method is NO-OP (good luck!)\n"); 599 600 error = bus_generic_resume(sc->dev); 601 602 return (error); 603 } 604 605 DRIVER_MODULE(iicbus, geniiic, iicbus_driver, NULL, NULL); 606 DRIVER_MODULE(acpi_iicbus, geniiic, acpi_iicbus_driver, NULL, NULL); 607 MODULE_DEPEND(geniiic, iicbus, IICBUS_MINVER, IICBUS_PREFVER, IICBUS_MAXVER); 608 MODULE_VERSION(geniiic, 1); 609