Home | History | Annotate | Line # | Download | only in ic
      1 /*	$NetBSD: sc16is7xx.c,v 1.6 2026/08/27 01:01:24 brad Exp $	*/
      2 
      3 /*
      4  * Copyright (c) 2025 Brad Spencer <brad (at) anduin.eldar.org>
      5  *
      6  * Permission to use, copy, modify, and distribute this software for any
      7  * purpose with or without fee is hereby granted, provided that the above
      8  * copyright notice and this permission notice appear in all copies.
      9  *
     10  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
     11  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
     12  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
     13  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
     14  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
     15  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
     16  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
     17  */
     18 
     19 #include "opt_fdt.h"
     20 
     21 #include <sys/cdefs.h>
     22 __KERNEL_RCSID(0, "$NetBSD: sc16is7xx.c,v 1.6 2026/08/27 01:01:24 brad Exp $");
     23 
     24 /* Common driver for the frontend to the NXP SC16IS7xx UART bridge */
     25 
     26 #include <sys/param.h>
     27 #include <sys/systm.h>
     28 #include <sys/kernel.h>
     29 #include <sys/kthread.h>
     30 #include <sys/device.h>
     31 #include <sys/module.h>
     32 #include <sys/sysctl.h>
     33 #include <sys/mutex.h>
     34 #include <sys/proc.h>
     35 #include <sys/workqueue.h>
     36 
     37 #ifdef FDT
     38 #include <dev/fdt/fdtvar.h>
     39 #endif
     40 
     41 #include <dev/ic/sc16is7xxreg.h>
     42 #include <dev/ic/sc16is7xxvar.h>
     43 #include <dev/ic/sc16is7xx_ttyvar.h>
     44 
     45 const struct device_compatible_entry sc16is7xx_compat_data[] = {
     46 	{.compat = "nxp,sc16is740"},
     47 	{.compat = "nxp,sc16is741"},
     48 	{.compat = "nxp,sc16is750"},
     49 	{.compat = "nxp,sc16is752"},
     50 	{.compat = "nxp,sc16is760"},
     51 	{.compat = "nxp,sc16is762"},
     52 
     53 	DEVICE_COMPAT_EOL
     54 };
     55 
     56 void sc16is7xx_attach(struct sc16is7xx_sc *);
     57 static int sc16is7xx_verify_poll(SYSCTLFN_ARGS);
     58 static int sc16is7xx_verify_freq_sysctl(SYSCTLFN_ARGS);
     59 void sc16is7xx_thread(void *);
     60 
     61 /* Artificial interrupts and the like */
     62 
     63 static void
     64 sc16is7xx_comintr(struct sc16is7xx_sc *sc)
     65 {
     66 	struct sc16is7xx_tty_softc *csc;
     67 
     68 	for (int i = 0; i <= 1; i++){
     69 		if (sc->sc_ttydevchannel[i] != NULL) {
     70 			csc = device_private(sc->sc_ttydevchannel[i]);
     71 			if (csc != NULL)
     72 				comintr(&csc->sc_com);
     73 		}
     74 	}
     75 }
     76 
     77 void
     78 sc16is7xx_thread(void *arg)
     79 {
     80 	struct sc16is7xx_sc *sc = arg;
     81 
     82 	while (sc->sc_thread_state != SC16IS7XX_THREAD_EXIT) {
     83 		mutex_enter(&sc->sc_thread_mutex);
     84 		if (sc->sc_thread_state == SC16IS7XX_THREAD_PAUSED ||
     85 		    sc->sc_thread_state == SC16IS7XX_THREAD_STALLED ||
     86 		    sc->sc_thread_state == SC16IS7XX_THREAD_STOPPED)
     87 			cv_wait(&sc->sc_threadvar, &sc->sc_thread_mutex);
     88 		mutex_exit(&sc->sc_thread_mutex);
     89 
     90 		mutex_enter(&sc->sc_thread_mutex);
     91 		if (sc->sc_thread_state == SC16IS7XX_THREAD_RUNNING) {
     92 			mutex_exit(&sc->sc_thread_mutex);
     93 			sc16is7xx_comintr(sc);
     94 		} else {
     95 			mutex_exit(&sc->sc_thread_mutex);
     96 		}
     97 
     98 		mutex_enter(&sc->sc_thread_mutex);
     99 		if (sc->sc_thread_state == SC16IS7XX_THREAD_RUNNING)
    100 			cv_timedwait(&sc->sc_threadvar, &sc->sc_thread_mutex,
    101 			    mstohz(sc->sc_poll));
    102 		mutex_exit(&sc->sc_thread_mutex);
    103 
    104 	}
    105 	kthread_exit(0);
    106 }
    107 
    108 #ifdef FDT
    109 /* This song and dance is needed because:
    110 
    111    sc16is7xx_intr is entered in a hard interrupt context.  It is not
    112    allowed to call workqueue_enqueue() and can't call comintr()
    113    because that might need to talk to the I2C or SPI bus, allocate
    114    memory, or otherwise wait.
    115 
    116    sc16is7xx_softintr wasn't able to call comintr() directly as that
    117    resulted in a panic.
    118 
    119    Hence..  sc16is7xx_comintr() and then comintr() needed to be
    120    entered from a thread or a workqueue worker.
    121 */
    122 
    123 static void
    124 sc16is7xx_wq(struct work *wk, void *arg)
    125 {
    126 	struct sc16is7xx_sc *sc = arg;
    127 
    128 	sc16is7xx_comintr(sc);
    129 }
    130 
    131 static void
    132 sc16is7xx_softintr(void *arg)
    133 {
    134 	struct sc16is7xx_sc *sc = arg;
    135 
    136 	/* This is a little strange,  See workqueue(9) about "A work must
    137 	 * not be enqueued again until the callback is called by the
    138 	 * workqueue framework."
    139 	 *
    140 	 * If one tries to use a variable from the stack here you will panic if
    141 	 * there are a number of interrupts coming in quickly.  kmem_alloc()
    142 	 * also panic'ed.  This is running in a interrupt context, although it
    143 	 * is soft and kmem(9) didn't like that.
    144 	 *
    145 	 * There could be a lot of interrupts going on if the there is a lot to
    146 	 * receive or transmit.
    147 	 *
    148 	 * It may be possible to get clever and send a couple of work items, one
    149 	 * for each possible channel. */
    150 
    151 	workqueue_enqueue(sc->sc_wq, (struct work *)&sc->sc_wqkk, NULL);
    152 }
    153 
    154 static int
    155 sc16is7xx_intr(void *arg)
    156 {
    157 	struct sc16is7xx_sc *sc = arg;
    158 
    159 	softint_schedule(sc->sc_sih);
    160 
    161 	return 1;
    162 }
    163 #endif
    164 
    165 /* GPIO */
    166 
    167 static uint32_t
    168 sc16is7xx_to_gpio_flags(struct sc16is7xx_sc *sc, int pin, int nc,
    169     uint8_t iocontrol, uint8_t iodir)
    170 {
    171 	int f = 0;
    172 
    173 	if (pin <= 3) {
    174 		if (nc == 2) {
    175 			if (iocontrol & SC16IS7XX_IOCONTROL_3_0)
    176 				f = GPIO_PIN_ALT0;
    177 		}
    178 		if (f == 0) {
    179 			if (iodir & (1 << pin))
    180 				f = GPIO_PIN_OUTPUT;
    181 			else
    182 				f = GPIO_PIN_INPUT;
    183 		}
    184 	} else {
    185 		if (iocontrol & SC16IS7XX_IOCONTROL_7_4)
    186 			f = GPIO_PIN_ALT0;
    187 		else if (iodir & (1 << pin))
    188 			f = GPIO_PIN_OUTPUT;
    189 		else
    190 			f = GPIO_PIN_INPUT;
    191 	}
    192 
    193 	return f;
    194 }
    195 
    196 static int
    197 sc16is7xx_gpio_pin_read(void *arg, int pin)
    198 {
    199 	struct sc16is7xx_sc *sc = arg;
    200 	uint8_t r;
    201 	int rr = GPIO_PIN_LOW, error;
    202 
    203 	error = sc->sc_funcs->read_reg(sc, SC16IS7XX_REGISTER_IOSTATE, 1, &r, 1);
    204 	if (!error && (r & (1 << pin)))
    205 		rr = GPIO_PIN_HIGH;
    206 
    207 	return rr;
    208 }
    209 
    210 static void
    211 sc16is7xx_gpio_pin_write(void *arg, int pin, int value)
    212 {
    213 	struct sc16is7xx_sc *sc = arg;
    214 	uint8_t r;
    215 	int error;
    216 
    217 	error = sc->sc_funcs->read_reg(sc, SC16IS7XX_REGISTER_IOSTATE, 1, &r, 1);
    218 	if (!error) {
    219 		if (value)
    220 			r |= (1 << pin);
    221 		else
    222 			r &= ~(1 << pin);
    223 		error = sc->sc_funcs->write_reg(sc, SC16IS7XX_REGISTER_IOSTATE, 1, &r, 1);
    224 	}
    225 }
    226 
    227 static void
    228 sc16is7xx_gpio_ctl_alt0(struct sc16is7xx_sc *sc, uint8_t bank_mask,
    229     int low_pin, int high_pin, uint32_t flags)
    230 {
    231 	int error;
    232 	uint8_t iocontrol;
    233 
    234 	error = sc->sc_funcs->read_reg(sc, SC16IS7XX_REGISTER_IOCONTROL, 1, &iocontrol, 1);
    235 	if (!error) {
    236 		iocontrol |= bank_mask;
    237 		error = sc->sc_funcs->write_reg(sc, SC16IS7XX_REGISTER_IOCONTROL, 1, &iocontrol, 1);
    238 		if (!error) {
    239 			for (int i = low_pin; i <= high_pin; i++)
    240 				sc->sc_gpio_pins[i].pin_flags = flags;
    241 		}
    242 	}
    243 }
    244 
    245 static void
    246 sc16is7xx_gpio_ctl_inout(struct sc16is7xx_sc *sc, uint8_t bank_mask,
    247     int low_pin, int high_pin, int a_pin, uint32_t flags)
    248 {
    249 	int error;
    250 	uint8_t iocontrol, iodir;
    251 
    252 	error = sc->sc_funcs->read_reg(sc, SC16IS7XX_REGISTER_IOCONTROL, 1, &iocontrol, 1);
    253 	if (!error) {
    254 		iocontrol &= ~bank_mask;
    255 		error = sc->sc_funcs->write_reg(sc, SC16IS7XX_REGISTER_IOCONTROL, 1, &iocontrol, 1);
    256 		if (!error) {
    257 			error = sc->sc_funcs->read_reg(sc, SC16IS7XX_REGISTER_IODIR, 1, &iodir, 1);
    258 			if (flags & GPIO_PIN_OUTPUT)
    259 				iodir |= (1 << a_pin);
    260 			if (flags & GPIO_PIN_INPUT)
    261 				iodir &= ~(1 << a_pin);
    262 			error = sc->sc_funcs->write_reg(sc, SC16IS7XX_REGISTER_IODIR, 1, &iodir, 1);
    263 			if (!error) {
    264 				for (int i = low_pin; i <= high_pin; i++)
    265 					sc->sc_gpio_pins[i].pin_flags = sc16is7xx_to_gpio_flags(sc, i, sc->sc_num_channels, iocontrol, iodir);
    266 			}
    267 		}
    268 	}
    269 }
    270 
    271 static void
    272 sc16is7xx_gpio_pin_ctl(void *arg, int pin, int flags)
    273 {
    274 	struct sc16is7xx_sc *sc = arg;
    275 	uint8_t bank_mask;
    276 	int low_pin, high_pin;
    277 
    278 	if (pin <= 3) {
    279 		bank_mask = SC16IS7XX_IOCONTROL_3_0;
    280 		low_pin = 0;
    281 		high_pin = 3;
    282 	} else {
    283 		bank_mask = SC16IS7XX_IOCONTROL_7_4;
    284 		low_pin = 4;
    285 		high_pin = SC16IS7XX_NPINS - 1;
    286 	}
    287 
    288 	if (flags & GPIO_PIN_ALT0) {
    289 		sc16is7xx_gpio_ctl_alt0(sc, bank_mask, low_pin, high_pin, flags);
    290 	} else {
    291 		sc16is7xx_gpio_ctl_inout(sc, bank_mask, low_pin, high_pin, pin, flags);
    292 	}
    293 }
    294 /* sysctl */
    295 
    296 int
    297 sc16is7xx_verify_poll(SYSCTLFN_ARGS)
    298 {
    299 	int error, t;
    300 	struct sysctlnode node;
    301 
    302 	node = *rnode;
    303 	t = *(int *)rnode->sysctl_data;
    304 	node.sysctl_data = &t;
    305 	error = sysctl_lookup(SYSCTLFN_CALL(&node));
    306 	if (error || newp == NULL)
    307 		return error;
    308 
    309 	if (t < 1)
    310 		return EINVAL;
    311 
    312 	*(int *)rnode->sysctl_data = t;
    313 
    314 	return 0;
    315 }
    316 
    317 int
    318 sc16is7xx_verify_freq_sysctl(SYSCTLFN_ARGS)
    319 {
    320 	struct sc16is7xx_sc *sc;
    321 	struct sc16is7xx_tty_softc *csc;
    322 	int error, t;
    323 	struct sysctlnode node;
    324 
    325 	node = *rnode;
    326 	sc = node.sysctl_data;
    327 	t = sc->sc_frequency;
    328 	node.sysctl_data = &t;
    329 	error = sysctl_lookup(SYSCTLFN_CALL(&node));
    330 	if (error || newp == NULL)
    331 		return error;
    332 
    333 	if (t < 1)
    334 		return EINVAL;
    335 
    336 	sc->sc_frequency = t;
    337 
    338 	for (int i = 0; i <= 1; i++){
    339 		if (sc->sc_ttydevchannel[i] != NULL) {
    340 			csc = device_private(sc->sc_ttydevchannel[i]);
    341 			if (csc != NULL)
    342 				csc->sc_com.sc_frequency = sc->sc_frequency;
    343 		}
    344 	}
    345 
    346 	return 0;
    347 }
    348 
    349 static int
    350 sc16is7xx_sysctl_init(struct sc16is7xx_sc *sc)
    351 {
    352 	int error;
    353 	const struct sysctlnode *cnode;
    354 	int sysctlroot_num;
    355 
    356 	if ((error = sysctl_createv(&sc->sc_sc16is7xx_log, 0, NULL, &cnode,
    357 		    0, CTLTYPE_NODE, device_xname(sc->sc_dev),
    358 		    SYSCTL_DESCR("sc16ix7xx controls"), NULL, 0, NULL, 0, CTL_HW,
    359 		    CTL_CREATE, CTL_EOL)) != 0)
    360 		return error;
    361 
    362 	sysctlroot_num = cnode->sysctl_num;
    363 
    364 	if ((error = sysctl_createv(&sc->sc_sc16is7xx_log, 0, NULL, &cnode,
    365 		    CTLFLAG_READWRITE, CTLTYPE_INT, "frequency",
    366 		    SYSCTL_DESCR("Frequency of the oscillator in Hz"), sc16is7xx_verify_freq_sysctl, 0,
    367 		    (void *)sc, 0, CTL_HW, sysctlroot_num, CTL_CREATE,
    368 		    CTL_EOL)) != 0)
    369 		return error;
    370 
    371 	if ((error = sysctl_createv(&sc->sc_sc16is7xx_log, 0, NULL, &cnode,
    372 		    CTLFLAG_READWRITE, CTLTYPE_INT, "poll",
    373 		    SYSCTL_DESCR("In polling mode, how often to check the status register in ms"), sc16is7xx_verify_poll, 0,
    374 		    &sc->sc_poll, 0, CTL_HW, sysctlroot_num, CTL_CREATE,
    375 		    CTL_EOL)) != 0)
    376 		return error;
    377 
    378 #define __DEBUGGING_THE_KTHREAD 1
    379 #ifdef __DEBUGGING_THE_KTHREAD
    380 	if ((error = sysctl_createv(&sc->sc_sc16is7xx_log, 0, NULL, &cnode,
    381 		    CTLFLAG_READONLY, CTLTYPE_INT, "thread_state",
    382 		    SYSCTL_DESCR("Kernel thread state"), NULL, 0,
    383 		    (int *)&sc->sc_thread_state, 0, CTL_HW, sysctlroot_num, CTL_CREATE,
    384 		    CTL_EOL)) != 0)
    385 		return error;
    386 
    387 	if ((error = sysctl_createv(&sc->sc_sc16is7xx_log, 0, NULL, &cnode,
    388 		    CTLFLAG_READONLY, CTLTYPE_INT, "de_count",
    389 		    SYSCTL_DESCR("Disable / Enable count"), NULL, 0,
    390 		    &sc->sc_de_count, 0, CTL_HW, sysctlroot_num, CTL_CREATE,
    391 		    CTL_EOL)) != 0)
    392 		return error;
    393 #endif
    394 
    395 	return 0;
    396 }
    397 /* attach, detach and such */
    398 
    399 static int
    400 sc16is7xx_print(void *aux, const char *pnp)
    401 {
    402 	struct sc16is7xx_tty_attach_args *aa = aux;
    403 
    404 	if (pnp)
    405 		aprint_normal("%s", pnp);
    406 	aprint_normal(" channel %d", aa->aa_channel);
    407 	return (UNCONF);
    408 }
    409 
    410 void
    411 sc16is7xx_attach(struct sc16is7xx_sc *sc)
    412 {
    413 	int error;
    414 	char chip_type[SC16IS7XX_TYPE_STRINGLEN];
    415 	int num_channels;
    416 	int num_gpio;
    417 	uint8_t buf[1];
    418 	uint8_t iocontrol_reg;
    419 	struct sc16is7xx_tty_attach_args aa;
    420 	int reset_count = 0;
    421 
    422 	aprint_normal("\n");
    423 
    424 	sc->sc_frequency = SC16IS7XX_DEFAULT_FREQUENCY;
    425 	sc->sc_poll = SC16IS7XX_DEFAULT_POLL;
    426 	sc->sc_thread_state = SC16IS7XX_THREAD_GPIO;
    427 	sc->sc_thread = NULL;
    428 	sc->sc_wq = NULL;
    429 	sc->sc_ih = NULL;
    430 	sc->sc_sih = NULL;
    431 	sc->sc_de_count = 0;
    432 	sc->sc_wqkk = 0xdeadbeefdeadbeef;
    433 
    434 	mutex_init(&sc->sc_thread_mutex, MUTEX_DEFAULT, IPL_SOFTSERIAL);
    435 	cv_init(&sc->sc_threadvar, "sc16is_cv");
    436 
    437 	if ((error = sc16is7xx_sysctl_init(sc)) != 0) {
    438 		aprint_error_dev(sc->sc_dev, "Can't setup sysctl tree (%d)\n", error);
    439 		goto out;
    440 	}
    441 
    442 	/* Reset of the chip is a little odd.  Setting the SRESET bit is the
    443 	 * only write that will NACK.  So, an expected error will result in
    444 	 * that case.  Just ignore the error and read a few times to make sure
    445 	 * that the reset is done.  After the reset, one must delay at least
    446 	 * 3us before trying to talk to the chip again. */
    447 	error = sc->sc_funcs->read_reg(sc, SC16IS7XX_REGISTER_IOCONTROL, 0, &iocontrol_reg, 1);
    448 	if (!error) {
    449 		iocontrol_reg |= SC16IS7XX_IOCONTROL_SRESET;
    450 		sc->sc_funcs->write_reg(sc, SC16IS7XX_REGISTER_IOCONTROL, 0, &iocontrol_reg, 1);
    451 		delay(5);
    452 		do {
    453 			error = sc->sc_funcs->read_reg(sc, SC16IS7XX_REGISTER_IOCONTROL, 0, &iocontrol_reg, 1);
    454 			if (!error) {
    455 				if (iocontrol_reg & SC16IS7XX_IOCONTROL_SRESET) {
    456 					delay(2);
    457 				}
    458 				reset_count++;
    459 			}
    460 		} while ((iocontrol_reg & SC16IS7XX_IOCONTROL_SRESET) &&
    461 		    (reset_count < 100) &&
    462 		    (!error));
    463 	}
    464 	if (!error) {
    465 		if (iocontrol_reg & SC16IS7XX_IOCONTROL_SRESET) {
    466 			aprint_error_dev(sc->sc_dev,
    467 			    "Chip did not reset in time.  reset_count=%d\n", reset_count);
    468 		}
    469 	} else {
    470 		aprint_error_dev(sc->sc_dev,
    471 		    "Error resetting chip: error=%d, reset_count=%d\n",
    472 		    error, reset_count);
    473 	}
    474 
    475 	/* After a reset, the LCR register will be 0x1d.  If this isn't the
    476 	 * case with channel 1, then channel 1 does not exist and this is a
    477 	 * single UART chip, that is a SC16IS740, SC16IS750 or SC16IS760 and
    478 	 * not a SC16IS752 or SC16IS762.
    479 	 *
    480 	 * There does not appear to be a way to distinguish a SC16IS740 /
    481 	 * SC16IS741 from a SC16IS750 / SC16IS760.  The GPIO registers exist in
    482 	 * both variants and appear to behave the same.  Obviously the physical
    483 	 * pins are missing from the SC16IS74x branch of the family.  A bit
    484 	 * more detail is available if you have a system with FDT.
    485 	 *
    486 	 * */
    487 
    488 	num_channels = 1;
    489 	num_gpio = SC16IS7XX_NPINS;
    490 	strncpy(chip_type, "UNKNOWN", SC16IS7XX_TYPE_STRINGLEN);
    491 
    492 	error = sc->sc_funcs->read_reg(sc, SC16IS7XX_REGISTER_LCR, 1, buf, 1);
    493 	if (!error) {
    494 		if (buf[0] == 0x1d) {
    495 			strncpy(chip_type, "SC16IS752/SC16IS762", SC16IS7XX_TYPE_STRINGLEN);
    496 			num_channels = 2;
    497 		} else {
    498 			strncpy(chip_type, "SC16IS740/SC16IS741/SC16IS750/SC16IS760", SC16IS7XX_TYPE_STRINGLEN);
    499 		}
    500 	}
    501 	sc->sc_num_channels = num_channels;
    502 
    503 	aprint_normal_dev(sc->sc_dev, "NXP %s\n", chip_type);
    504 
    505 	sc->sc_ttydevchannel[0] = sc->sc_ttydevchannel[1] = NULL;
    506 
    507 	bool use_polling = true;
    508 
    509 #ifdef FDT
    510 
    511 	error = workqueue_create(&sc->sc_wq, device_xname(sc->sc_dev),
    512 	    sc16is7xx_wq, sc, PRI_SOFTSERIAL, IPL_SOFTSERIAL, WQ_MPSAFE);
    513 	if (error) {
    514 		aprint_error_dev(sc->sc_dev,
    515 		    "Could not create workqueue: %d\n",
    516 		    error);
    517 	}
    518 	if (!error &&
    519 	    devhandle_type(device_handle(sc->sc_dev)) == DEVHANDLE_TYPE_OF) {
    520 		char intrstr[128];
    521 
    522 		sc->sc_phandle = devhandle_to_of(device_handle(sc->sc_dev));
    523 
    524 		if (!of_hasprop(sc->sc_phandle, "gpio-controller")) {
    525 			num_gpio = 0;
    526 
    527 			/* If there is an indication that the GPIO is not
    528 			 * desired, turn the pins into modem control pins. */
    529 			error = sc->sc_funcs->read_reg(sc, SC16IS7XX_REGISTER_IOCONTROL, 1, &iocontrol_reg, 1);
    530 			if (error)
    531 				goto out;
    532 			if (num_channels == 2)
    533 				iocontrol_reg |= SC16IS7XX_IOCONTROL_7_4 | SC16IS7XX_IOCONTROL_3_0;
    534 			else
    535 				iocontrol_reg |= SC16IS7XX_IOCONTROL_7_4;	/* No strictly correct
    536 										 * for the SC16IS74x */
    537 			error = sc->sc_funcs->write_reg(sc, SC16IS7XX_REGISTER_IOCONTROL, 1, &iocontrol_reg, 1);
    538 			if (error)
    539 				goto out;
    540 		}
    541 		if (fdtbus_intr_str(sc->sc_phandle, 0,
    542 		    intrstr, sizeof(intrstr))) {
    543 
    544 			aprint_normal_dev(sc->sc_dev, "interrupting on %s\n", intrstr);
    545 
    546 			sc->sc_ih = fdtbus_intr_establish(sc->sc_phandle, 0, IPL_VM, 0,
    547 			    sc16is7xx_intr, sc);
    548 
    549 			if (sc->sc_ih == NULL) {
    550 				aprint_error_dev(sc->sc_dev,
    551 				    "unable to establish interrupt\n");
    552 			} else {
    553 				sc->sc_sih =
    554 				    softint_establish(SOFTINT_SERIAL, sc16is7xx_softintr, sc);
    555 				if (sc->sc_sih == NULL) {
    556 					aprint_error_dev(sc->sc_dev,
    557 					    "unable to establish soft interrupt\n");
    558 					fdtbus_intr_disestablish(sc->sc_phandle, sc->sc_ih);
    559 					sc->sc_ih = NULL;
    560 				} else {
    561 					use_polling = false;
    562 				}
    563 			}
    564 		}
    565 		const u_int * cf;
    566 		int len;
    567 		cf = fdtbus_get_prop(sc->sc_phandle, "clock-frequency", &len);
    568 		if (cf != NULL && len > 0) {
    569 			sc->sc_frequency = be32toh(cf[0]);
    570 		}
    571 	}
    572 
    573 #endif
    574 
    575 	if (use_polling) {
    576 		aprint_normal_dev(sc->sc_dev, "polling for interrupts\n");
    577 		sc->sc_thread_state = SC16IS7XX_THREAD_STOPPED;
    578 	}
    579 
    580 	for (int i = 0; i < num_channels; i++){
    581 		aa.aa_channel = i;
    582 
    583 		sc->sc_ttydevchannel[i] = config_found(sc->sc_dev, &aa, sc16is7xx_print,
    584 		    CFARGS(.submatch = config_stdsubmatch,
    585 		    .iattr = "sc16is7xxbus"));
    586 
    587 	}
    588 
    589 	if (num_gpio > 0) {
    590 		struct gpiobus_attach_args gba;
    591 		uint8_t iodir_reg;
    592 		int c = 3;
    593 
    594 		if (num_channels == 2)
    595 			c = -1;
    596 
    597 		error = sc->sc_funcs->read_reg(sc, SC16IS7XX_REGISTER_IOCONTROL, 1, &iocontrol_reg, 1);
    598 		if (error)
    599 			goto out;
    600 		error = sc->sc_funcs->read_reg(sc, SC16IS7XX_REGISTER_IODIR, 1, &iodir_reg, 1);
    601 		if (error)
    602 			goto out;
    603 
    604 		for (int i = 0; i < num_gpio; i++){
    605 			sc->sc_gpio_pins[i].pin_num = i;
    606 			sc->sc_gpio_pins[i].pin_caps = GPIO_PIN_INPUT;
    607 			sc->sc_gpio_pins[i].pin_caps |= GPIO_PIN_OUTPUT;
    608 			if (i > c)
    609 				sc->sc_gpio_pins[i].pin_caps |= GPIO_PIN_ALT0;
    610 			sc->sc_gpio_pins[i].pin_flags =
    611 			    sc16is7xx_to_gpio_flags(sc, i, num_channels, iocontrol_reg, iodir_reg);
    612 			sc->sc_gpio_pins[i].pin_intrcaps = 0;
    613 			snprintf(sc->sc_gpio_pins[i].pin_defname, 4, "GP%d", i);
    614 		}
    615 
    616 		sc->sc_gpio_gc.gp_cookie = sc;
    617 		sc->sc_gpio_gc.gp_pin_read = sc16is7xx_gpio_pin_read;
    618 		sc->sc_gpio_gc.gp_pin_write = sc16is7xx_gpio_pin_write;
    619 		sc->sc_gpio_gc.gp_pin_ctl = sc16is7xx_gpio_pin_ctl;
    620 
    621 		gba.gba_gc = &sc->sc_gpio_gc;
    622 		gba.gba_pins = sc->sc_gpio_pins;
    623 		gba.gba_npins = SC16IS7XX_NPINS;
    624 
    625 		sc->sc_gpio_dev = config_found(sc->sc_dev, &gba, gpiobus_print,
    626 		    CFARGS(.iattr = "gpiobus"));
    627 	}
    628 
    629 out:
    630 
    631 	return;
    632 }
    633 
    634 int
    635 sc16is7xx_detach(struct sc16is7xx_sc *sc, int flags)
    636 {
    637 	int err = 0;
    638 
    639 	err = config_detach_children(sc->sc_dev, flags);
    640 
    641 	mutex_enter(&sc->sc_thread_mutex);
    642 	if (sc->sc_thread &&
    643 	    sc->sc_thread_state != SC16IS7XX_THREAD_GPIO &&
    644 	    sc->sc_thread_state != SC16IS7XX_THREAD_STOPPED &&
    645 	    sc->sc_thread_state != SC16IS7XX_THREAD_EXIT) {
    646 		sc->sc_thread_state = SC16IS7XX_THREAD_EXIT;
    647 		cv_signal(&sc->sc_threadvar);
    648 		mutex_exit(&sc->sc_thread_mutex);
    649 		kthread_join(sc->sc_thread);
    650 	} else {
    651 		mutex_exit(&sc->sc_thread_mutex);
    652 	}
    653 #ifdef FDT
    654 	if (sc->sc_ih != NULL)
    655 		fdtbus_intr_disestablish(sc->sc_phandle, sc->sc_ih);
    656 
    657 	if (sc->sc_sih != NULL)
    658 		softint_disestablish(sc->sc_sih);
    659 #endif
    660 
    661 	sysctl_teardown(&sc->sc_sc16is7xx_log);
    662 
    663 	cv_destroy(&sc->sc_threadvar);
    664 	mutex_destroy(&sc->sc_thread_mutex);
    665 
    666 	return err;
    667 }
    668