Module Name: src Committed By: jmcneill Date: Tue Mar 31 12:23:17 UTC 2020
Modified Files: src/sys/arch/arm/broadcom: bcm2835_bsc.c files.bcm2835 src/sys/arch/evbarm/conf: GENERIC64 Added Files: src/sys/arch/arm/broadcom: bcm2835_bsc_acpi.c bcm2835_bsc_fdt.c Log Message: Add ACPI support. To generate a diff of this commit: cvs rdiff -u -r1.14 -r1.15 src/sys/arch/arm/broadcom/bcm2835_bsc.c cvs rdiff -u -r0 -r1.1 src/sys/arch/arm/broadcom/bcm2835_bsc_acpi.c \ src/sys/arch/arm/broadcom/bcm2835_bsc_fdt.c cvs rdiff -u -r1.38 -r1.39 src/sys/arch/arm/broadcom/files.bcm2835 cvs rdiff -u -r1.148 -r1.149 src/sys/arch/evbarm/conf/GENERIC64 Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/arch/arm/broadcom/bcm2835_bsc.c diff -u src/sys/arch/arm/broadcom/bcm2835_bsc.c:1.14 src/sys/arch/arm/broadcom/bcm2835_bsc.c:1.15 --- src/sys/arch/arm/broadcom/bcm2835_bsc.c:1.14 Sun Dec 22 23:24:56 2019 +++ src/sys/arch/arm/broadcom/bcm2835_bsc.c Tue Mar 31 12:23:17 2020 @@ -1,4 +1,4 @@ -/* $NetBSD: bcm2835_bsc.c,v 1.14 2019/12/22 23:24:56 thorpej Exp $ */ +/* $NetBSD: bcm2835_bsc.c,v 1.15 2020/03/31 12:23:17 jmcneill Exp $ */ /* * Copyright (c) 2019 Jason R. Thorpe @@ -28,7 +28,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: bcm2835_bsc.c,v 1.14 2019/12/22 23:24:56 thorpej Exp $"); +__KERNEL_RCSID(0, "$NetBSD: bcm2835_bsc.c,v 1.15 2020/03/31 12:23:17 jmcneill Exp $"); #include <sys/param.h> #include <sys/bus.h> @@ -42,64 +42,7 @@ __KERNEL_RCSID(0, "$NetBSD: bcm2835_bsc. #include <arm/broadcom/bcm2835reg.h> #include <arm/broadcom/bcm2835_bscreg.h> - -#include <dev/fdt/fdtvar.h> - -typedef enum { - BSC_EXEC_STATE_IDLE = 0, - BSC_EXEC_STATE_SEND_ADDR = 1, - BSC_EXEC_STATE_SEND_CMD = 2, - BSC_EXEC_STATE_SEND_DATA = 3, - BSC_EXEC_STATE_RECV_DATA = 4, - BSC_EXEC_STATE_DONE = 5, - BSC_EXEC_STATE_ERROR = 6, -} bsc_exec_state_t; - -#define BSC_EXEC_STATE_SENDING(sc) \ - ((sc)->sc_exec_state >= BSC_EXEC_STATE_SEND_ADDR && \ - (sc)->sc_exec_state <= BSC_EXEC_STATE_SEND_DATA) - -#define BSC_EXEC_STATE_RECEIVING(sc) \ - ((sc)->sc_exec_state == BSC_EXEC_STATE_RECV_DATA) - -struct bsciic_softc { - device_t sc_dev; - bus_space_tag_t sc_iot; - bus_space_handle_t sc_ioh; - struct i2c_controller sc_i2c; - void *sc_inth; - - struct clk *sc_clk; - u_int sc_frequency; - u_int sc_clkrate; - - kmutex_t sc_intr_lock; - kcondvar_t sc_intr_wait; - - struct { - i2c_op_t op; - i2c_addr_t addr; - const void *cmdbuf; - size_t cmdlen; - void *databuf; - size_t datalen; - int flags; - } sc_exec; - - /* - * Everything below here protected by the i2c controller lock - * /and/ sc_intr_lock (if we're using interrupts). - */ - - bsc_exec_state_t sc_exec_state; - - uint8_t *sc_buf; - size_t sc_bufpos; - size_t sc_buflen; - - uint32_t sc_c_bits; - bool sc_expecting_interrupt; -}; +#include <arm/broadcom/bcm2835_bscvar.h> static void bsciic_exec_func_idle(struct bsciic_softc * const); static void bsciic_exec_func_send_addr(struct bsciic_softc * const); @@ -143,84 +86,13 @@ const struct { }, }; -static int bsciic_match(device_t, cfdata_t, void *); -static void bsciic_attach(device_t, device_t, void *); - -static int bsciic_acquire_bus(void *, int); -static void bsciic_release_bus(void *, int); -static int bsciic_exec(void *, i2c_op_t, i2c_addr_t, const void *, size_t, - void *, size_t, int); - -static int bsciic_intr(void *); - int bsciic_debug = 0; -CFATTACH_DECL_NEW(bsciic, sizeof(struct bsciic_softc), - bsciic_match, bsciic_attach, NULL, NULL); - -static int -bsciic_match(device_t parent, cfdata_t match, void *aux) +void +bsciic_attach(struct bsciic_softc *sc) { - const char * const compatible[] = { "brcm,bcm2835-i2c", NULL }; - struct fdt_attach_args * const faa = aux; - - return of_match_compatible(faa->faa_phandle, compatible); -} - -static void -bsciic_attach(device_t parent, device_t self, void *aux) -{ - struct bsciic_softc * const sc = device_private(self); - struct fdt_attach_args * const faa = aux; - const int phandle = faa->faa_phandle; - prop_dictionary_t prop = device_properties(self); - bool disable = false; - - bus_addr_t addr; - bus_size_t size; - - sc->sc_dev = self; - sc->sc_iot = faa->faa_bst; - - int error = fdtbus_get_reg(phandle, 0, &addr, &size); - if (error) { - aprint_error(": unable to get device registers\n"); - return; - } - - prop_dictionary_get_bool(prop, "disable", &disable); - if (disable) { - aprint_naive(": disabled\n"); - aprint_normal(": disabled\n"); - return; - } - - /* Enable clock */ - sc->sc_clk = fdtbus_clock_get_index(phandle, 0); - if (sc->sc_clk == NULL) { - aprint_error(": couldn't acquire clock\n"); - return; - } - - if (clk_enable(sc->sc_clk) != 0) { - aprint_error(": failed to enable clock\n"); - return; - } - - sc->sc_frequency = clk_get_rate(sc->sc_clk); - - if (of_getprop_uint32(phandle, "clock-frequency", - &sc->sc_clkrate) != 0) { - sc->sc_clkrate = 100000; - } - - if (bus_space_map(sc->sc_iot, addr, size, 0, &sc->sc_ioh)) { - aprint_error(": unable to map device\n"); - return; - } - - aprint_naive("\n"); - aprint_normal(": Broadcom Serial Controller\n"); + mutex_init(&sc->sc_intr_lock, MUTEX_DEFAULT, IPL_VM); + cv_init(&sc->sc_intr_wait, device_xname(sc->sc_dev)); /* clear FIFO, disable controller */ bus_space_write_4(sc->sc_iot, sc->sc_ioh, BSC_C, BSC_C_CLEAR_CLEAR); @@ -231,34 +103,9 @@ bsciic_attach(device_t parent, device_t u_int divider = howmany(sc->sc_frequency, sc->sc_clkrate); bus_space_write_4(sc->sc_iot, sc->sc_ioh, BSC_DIV, __SHIFTIN(divider, BSC_DIV_CDIV)); - - mutex_init(&sc->sc_intr_lock, MUTEX_DEFAULT, IPL_VM); - cv_init(&sc->sc_intr_wait, device_xname(self)); - - char intrstr[128]; - if (!fdtbus_intr_str(phandle, 0, intrstr, sizeof(intrstr))) { - aprint_error_dev(sc->sc_dev, "failed to decode interrupt\n"); - return; - } - sc->sc_inth = fdtbus_intr_establish(phandle, 0, IPL_VM, - FDT_INTR_MPSAFE, bsciic_intr, sc); - if (sc->sc_inth == NULL) { - aprint_error_dev(sc->sc_dev, - "failed to establish interrupt %s\n", intrstr); - return; - } - aprint_normal_dev(sc->sc_dev, "interrupting on %s\n", intrstr); - - iic_tag_init(&sc->sc_i2c); - sc->sc_i2c.ic_cookie = sc; - sc->sc_i2c.ic_acquire_bus = bsciic_acquire_bus; - sc->sc_i2c.ic_release_bus = bsciic_release_bus; - sc->sc_i2c.ic_exec = bsciic_exec; - - fdtbus_attach_i2cbus(self, phandle, &sc->sc_i2c, iicbus_print); } -static int +int bsciic_acquire_bus(void *v, int flags) { struct bsciic_softc * const sc = v; @@ -274,7 +121,7 @@ bsciic_acquire_bus(void *v, int flags) return 0; } -static void +void bsciic_release_bus(void *v, int flags) { struct bsciic_softc * const sc = v; @@ -391,7 +238,7 @@ bsciic_abort(struct bsciic_softc * const bsciic_phase_done(sc); } -static int +int bsciic_intr(void *v) { struct bsciic_softc * const sc = v; @@ -590,7 +437,7 @@ bsciic_exec_func_error(struct bsciic_sof bsciic_signal(sc); } -static int +int bsciic_exec(void *v, i2c_op_t op, i2c_addr_t addr, const void *cmdbuf, size_t cmdlen, void *databuf, size_t datalen, int flags) { Index: src/sys/arch/arm/broadcom/files.bcm2835 diff -u src/sys/arch/arm/broadcom/files.bcm2835:1.38 src/sys/arch/arm/broadcom/files.bcm2835:1.39 --- src/sys/arch/arm/broadcom/files.bcm2835:1.38 Tue Dec 31 00:59:26 2019 +++ src/sys/arch/arm/broadcom/files.bcm2835 Tue Mar 31 12:23:17 2020 @@ -1,4 +1,4 @@ -# $NetBSD: files.bcm2835,v 1.38 2019/12/31 00:59:26 jmcneill Exp $ +# $NetBSD: files.bcm2835,v 1.39 2020/03/31 12:23:17 jmcneill Exp $ # # Configuration info for Broadcom BCM2835 ARM Peripherals # @@ -85,8 +85,13 @@ file arch/arm/broadcom/bcm2835_spi.c bc # BSC (I2C) controller (BCM2835_BSC[01]_BASE) device bsciic: i2cbus, bcm2835_gpio_subr -attach bsciic at fdt file arch/arm/broadcom/bcm2835_bsc.c bsciic needs-flag +attach bsciic at fdt with bsciic_fdt +file arch/arm/broadcom/bcm2835_bsc_fdt.c bsciic_fdt +ifdef acpinodebus +attach bsciic at acpinodebus with bsciic_acpi +file arch/arm/broadcom/bcm2835_bsc_acpi.c bsciic_acpi +endif # Generic framebuffer console driver attach genfb at fdt with bcmgenfb: edid Index: src/sys/arch/evbarm/conf/GENERIC64 diff -u src/sys/arch/evbarm/conf/GENERIC64:1.148 src/sys/arch/evbarm/conf/GENERIC64:1.149 --- src/sys/arch/evbarm/conf/GENERIC64:1.148 Sat Mar 28 08:35:36 2020 +++ src/sys/arch/evbarm/conf/GENERIC64 Tue Mar 31 12:23:17 2020 @@ -1,5 +1,5 @@ # -# $NetBSD: GENERIC64,v 1.148 2020/03/28 08:35:36 isaki Exp $ +# $NetBSD: GENERIC64,v 1.149 2020/03/31 12:23:17 jmcneill Exp $ # # GENERIC ARM (aarch64) kernel # @@ -384,6 +384,7 @@ com* at puc? port ? # I2C controllers options I2C_MAX_ADDR=0xfff bsciic* at fdt? # Broadcom BCM283x Serial Control +bsciic* at acpi? dwiic* at fdt? # Designware I2C dwiic* at acpi? imxi2c* at fdt? pass 4 # IMX I2C Added files: Index: src/sys/arch/arm/broadcom/bcm2835_bsc_acpi.c diff -u /dev/null src/sys/arch/arm/broadcom/bcm2835_bsc_acpi.c:1.1 --- /dev/null Tue Mar 31 12:23:18 2020 +++ src/sys/arch/arm/broadcom/bcm2835_bsc_acpi.c Tue Mar 31 12:23:17 2020 @@ -0,0 +1,189 @@ +/* $NetBSD: bcm2835_bsc_acpi.c,v 1.1 2020/03/31 12:23:17 jmcneill Exp $ */ + +/*- + * Copyright (c) 2020 Jared McNeill <jmcne...@invisible.ca> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__KERNEL_RCSID(0, "$NetBSD: bcm2835_bsc_acpi.c,v 1.1 2020/03/31 12:23:17 jmcneill Exp $"); + +#include <sys/param.h> +#include <sys/bus.h> +#include <sys/cpu.h> +#include <sys/device.h> + +#include <dev/acpi/acpireg.h> +#include <dev/acpi/acpivar.h> +#include <dev/acpi/acpi_intr.h> +#include <dev/acpi/acpi_i2c.h> + +#include <arm/broadcom/bcm2835var.h> +#include <arm/broadcom/bcm2835_mbox.h> +#include <arm/broadcom/bcm2835_bscvar.h> + +#include <evbarm/rpi/vcio.h> +#include <evbarm/rpi/vcpm.h> +#include <evbarm/rpi/vcprop.h> + +static int bsciic_acpi_match(device_t, cfdata_t, void *); +static void bsciic_acpi_attach(device_t, device_t, void *); + +static u_int bsciic_acpi_vpu_clock_rate(void); + +CFATTACH_DECL_NEW(bsciic_acpi, sizeof(struct bsciic_softc), bsciic_acpi_match, bsciic_acpi_attach, NULL, NULL); + +static const char * const compatible[] = { + "BCM2841", + NULL +}; + +static struct { + struct vcprop_buffer_hdr vb_hdr; + struct vcprop_tag_clockrate vbt_vpuclockrate; + struct vcprop_tag end; +} vb_vpu __cacheline_aligned = { + .vb_hdr = { + .vpb_len = sizeof(vb_vpu), + .vpb_rcode = VCPROP_PROCESS_REQUEST + }, + .vbt_vpuclockrate = { + .tag = { + .vpt_tag = VCPROPTAG_GET_CLOCKRATE, + .vpt_len = VCPROPTAG_LEN(vb_vpu.vbt_vpuclockrate), + .vpt_rcode = VCPROPTAG_REQUEST + }, + .id = VCPROP_CLK_CORE + }, + .end = { + .vpt_tag = VCPROPTAG_NULL + } +}; + +static int +bsciic_acpi_match(device_t parent, cfdata_t cf, void *aux) +{ + struct acpi_attach_args *aa = aux; + + if (aa->aa_node->ad_type != ACPI_TYPE_DEVICE) + return 0; + + return acpi_match_hid(aa->aa_node->ad_devinfo, compatible); +} + +static void +bsciic_acpi_attach(device_t parent, device_t self, void *aux) +{ + struct bsciic_softc * const sc = device_private(self); + struct acpi_attach_args *aa = aux; + struct i2cbus_attach_args iba; + struct acpi_resources res; + struct acpi_mem *mem; + struct acpi_irq *irq; + ACPI_STATUS rv; + ACPI_INTEGER clock_freq; + void *ih; + + sc->sc_dev = self; + + rv = acpi_resource_parse(sc->sc_dev, aa->aa_node->ad_handle, "_CRS", + &res, &acpi_resource_parse_ops_default); + if (ACPI_FAILURE(rv)) + return; + + mem = acpi_res_mem(&res, 0); + if (mem == NULL) { + aprint_error_dev(self, "couldn't find mem resource\n"); + goto done; + } + + irq = acpi_res_irq(&res, 0); + if (irq == NULL) { + aprint_error_dev(self, "couldn't find irq resource\n"); + goto done; + } + + sc->sc_dev = self; + sc->sc_iot = aa->aa_memt; + if (bus_space_map(aa->aa_memt, mem->ar_base, mem->ar_length, 0, &sc->sc_ioh) != 0) { + aprint_error_dev(self, "couldn't map registers\n"); + goto done; + } + + sc->sc_frequency = bsciic_acpi_vpu_clock_rate(); + if (sc->sc_frequency == 0) { + aprint_error_dev(self, "couldn't determine parent clock rate\n"); + goto done; + } + + rv = acpi_dsd_integer(aa->aa_node->ad_handle, "clock-frequency", &clock_freq); + if (ACPI_SUCCESS(rv)) + sc->sc_clkrate = clock_freq; + else + sc->sc_clkrate = 100000; + + bsciic_attach(sc); + + ih = acpi_intr_establish(self, (uint64_t)aa->aa_node->ad_handle, + IPL_VM, true, bsciic_intr, sc, device_xname(self)); + if (ih == NULL) { + aprint_error_dev(self, "couldn't install interrupt handler\n"); + goto done; + } + + iic_tag_init(&sc->sc_i2c); + sc->sc_i2c.ic_cookie = sc; + sc->sc_i2c.ic_acquire_bus = bsciic_acquire_bus; + sc->sc_i2c.ic_release_bus = bsciic_release_bus; + sc->sc_i2c.ic_exec = bsciic_exec; + + memset(&iba, 0, sizeof(iba)); + iba.iba_tag = &sc->sc_i2c; + iba.iba_child_devices = acpi_enter_i2c_devs(aa->aa_node); + config_found_ia(self, "i2cbus", &iba, iicbus_print); + +done: + acpi_resource_cleanup(&res); +} + +static u_int +bsciic_acpi_vpu_clock_rate(void) +{ + uint32_t res; + int error; + + error = bcmmbox_request(BCMMBOX_CHANARM2VC, &vb_vpu, + sizeof(vb_vpu), &res); + if (error != 0) { + printf("%s: mbox request failed (%d)\n", __func__, error); + return 0; + } + + if (!vcprop_buffer_success_p(&vb_vpu.vb_hdr) || + !vcprop_tag_success_p(&vb_vpu.vbt_vpuclockrate.tag) || + vb_vpu.vbt_vpuclockrate.rate < 0) + return 0; + + return vb_vpu.vbt_vpuclockrate.rate; +} Index: src/sys/arch/arm/broadcom/bcm2835_bsc_fdt.c diff -u /dev/null src/sys/arch/arm/broadcom/bcm2835_bsc_fdt.c:1.1 --- /dev/null Tue Mar 31 12:23:18 2020 +++ src/sys/arch/arm/broadcom/bcm2835_bsc_fdt.c Tue Mar 31 12:23:17 2020 @@ -0,0 +1,142 @@ +/* $NetBSD: bcm2835_bsc_fdt.c,v 1.1 2020/03/31 12:23:17 jmcneill Exp $ */ + +/* + * Copyright (c) 2019 Jason R. Thorpe + * Copyright (c) 2012 Jonathan A. Kollasch + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__KERNEL_RCSID(0, "$NetBSD: bcm2835_bsc_fdt.c,v 1.1 2020/03/31 12:23:17 jmcneill Exp $"); + +#include <sys/param.h> +#include <sys/bus.h> +#include <sys/device.h> +#include <sys/kernhist.h> +#include <sys/intr.h> +#include <sys/mutex.h> +#include <sys/systm.h> + +#include <dev/i2c/i2cvar.h> + +#include <arm/broadcom/bcm2835reg.h> +#include <arm/broadcom/bcm2835_bscreg.h> +#include <arm/broadcom/bcm2835_bscvar.h> + +#include <dev/fdt/fdtvar.h> + +static int bsciic_fdt_match(device_t, cfdata_t, void *); +static void bsciic_fdt_attach(device_t, device_t, void *); + +CFATTACH_DECL_NEW(bsciic_fdt, sizeof(struct bsciic_softc), + bsciic_fdt_match, bsciic_fdt_attach, NULL, NULL); + +static int +bsciic_fdt_match(device_t parent, cfdata_t match, void *aux) +{ + const char * const compatible[] = { "brcm,bcm2835-i2c", NULL }; + struct fdt_attach_args * const faa = aux; + + return of_match_compatible(faa->faa_phandle, compatible); +} + +static void +bsciic_fdt_attach(device_t parent, device_t self, void *aux) +{ + struct bsciic_softc * const sc = device_private(self); + struct fdt_attach_args * const faa = aux; + const int phandle = faa->faa_phandle; + prop_dictionary_t prop = device_properties(self); + bool disable = false; + + bus_addr_t addr; + bus_size_t size; + + sc->sc_dev = self; + sc->sc_iot = faa->faa_bst; + + int error = fdtbus_get_reg(phandle, 0, &addr, &size); + if (error) { + aprint_error(": unable to get device registers\n"); + return; + } + + prop_dictionary_get_bool(prop, "disable", &disable); + if (disable) { + aprint_naive(": disabled\n"); + aprint_normal(": disabled\n"); + return; + } + + /* Enable clock */ + sc->sc_clk = fdtbus_clock_get_index(phandle, 0); + if (sc->sc_clk == NULL) { + aprint_error(": couldn't acquire clock\n"); + return; + } + + if (clk_enable(sc->sc_clk) != 0) { + aprint_error(": failed to enable clock\n"); + return; + } + + sc->sc_frequency = clk_get_rate(sc->sc_clk); + + if (of_getprop_uint32(phandle, "clock-frequency", + &sc->sc_clkrate) != 0) { + sc->sc_clkrate = 100000; + } + + if (bus_space_map(sc->sc_iot, addr, size, 0, &sc->sc_ioh)) { + aprint_error(": unable to map device\n"); + return; + } + + aprint_naive("\n"); + aprint_normal(": Broadcom Serial Controller\n"); + + bsciic_attach(sc); + + char intrstr[128]; + if (!fdtbus_intr_str(phandle, 0, intrstr, sizeof(intrstr))) { + aprint_error_dev(sc->sc_dev, "failed to decode interrupt\n"); + return; + } + sc->sc_inth = fdtbus_intr_establish(phandle, 0, IPL_VM, + FDT_INTR_MPSAFE, bsciic_intr, sc); + if (sc->sc_inth == NULL) { + aprint_error_dev(sc->sc_dev, + "failed to establish interrupt %s\n", intrstr); + return; + } + aprint_normal_dev(sc->sc_dev, "interrupting on %s\n", intrstr); + + iic_tag_init(&sc->sc_i2c); + sc->sc_i2c.ic_cookie = sc; + sc->sc_i2c.ic_acquire_bus = bsciic_acquire_bus; + sc->sc_i2c.ic_release_bus = bsciic_release_bus; + sc->sc_i2c.ic_exec = bsciic_exec; + + fdtbus_attach_i2cbus(self, phandle, &sc->sc_i2c, iicbus_print); +}