Esempio n. 1
0
/*
 * Setup interrupt handling.  This is done only if the cache controller is
 * disabled, for debugging.  We set counters so when a cache event happens we'll
 * get interrupted and be warned that something is wrong, because no cache
 * events should happen if we're disabled.
 */
static void
pl310_config_intr(void *arg)
{
	struct pl310_softc * sc;

	sc = arg;

	/* activate the interrupt */
	bus_setup_intr(sc->sc_dev, sc->sc_irq_res, INTR_TYPE_MISC | INTR_MPSAFE,
	    pl310_filter, NULL, sc, &sc->sc_irq_h);

	/* Cache Line Eviction for Counter 0 */
	pl310_write4(sc, PL310_EVENT_COUNTER0_CONF,
	    EVENT_COUNTER_CONF_INCR | EVENT_COUNTER_CONF_CO);
	/* Data Read Request for Counter 1 */
	pl310_write4(sc, PL310_EVENT_COUNTER1_CONF,
	    EVENT_COUNTER_CONF_INCR | EVENT_COUNTER_CONF_DRREQ);

	/* Enable and clear pending interrupts */
	pl310_write4(sc, PL310_INTR_CLEAR, INTR_MASK_ECNTR);
	pl310_write4(sc, PL310_INTR_MASK, INTR_MASK_ALL);

	/* Enable counters and reset C0 and C1 */
	pl310_write4(sc, PL310_EVENT_COUNTER_CTRL,
	    EVENT_COUNTER_CTRL_ENABLED |
	    EVENT_COUNTER_CTRL_C0_RESET |
	    EVENT_COUNTER_CTRL_C1_RESET);

	config_intrhook_disestablish(sc->sc_ich);
	free(sc->sc_ich, M_DEVBUF);
	sc->sc_ich = NULL;
}
Esempio n. 2
0
static void
pcf8563_start(void *xdev)
{
	device_t dev;
	uint8_t reg = PCF8563_R_SECOND, val;
	struct iic_msg msgs[] = {
		{ 0, IIC_M_WR, sizeof(reg), &reg },
		{ 0, IIC_M_RD, sizeof(val), &val }
	};
	struct pcf8563_softc *sc;

	dev = (device_t)xdev;
	sc = device_get_softc(dev);
	config_intrhook_disestablish(&sc->enum_hook);

	/*
	 * NB: PCF8563_R_SECOND_VL doesn't automatically clear when VDD
	 * rises above Vlow again and needs to be cleared manually.
	 * However, apparently this needs all of the time registers to be
	 * set, i.e. pcf8563_settime(), and not just PCF8563_R_SECOND in
	 * order for PCF8563_R_SECOND_VL to stick.  Thus, we just issue a
	 * warning here rather than failing with ENXIO in case it is set.
	 * Note that pcf8563_settime() will also clear PCF8563_R_SECOND_VL
	 * as a side-effect.
	 */
	msgs[0].slave = msgs[1].slave = sc->sc_addr;
	if (iicbus_transfer(dev, msgs, nitems(msgs)) != 0) {
		device_printf(dev, "%s: cannot read RTC\n", __func__);
		return;
	}
	if ((val & PCF8563_R_SECOND_VL) != 0)
		device_printf(dev, "%s: battery low\n", __func__);

	clock_register(dev, 1000000);   /* 1 second resolution */
}
Esempio n. 3
0
/**
 *	twl_scan - scans the i2c bus for sub modules
 *	@dev: the twl device
 *
 *	TWL devices don't just have one i2c slave address, rather they have up to
 *	5 other addresses, each is for separate modules within the device. This
 *	function scans the bus for 4 possible sub-devices and stores the info
 *	internally.
 *
 */
static void
twl_scan(void *dev)
{
	struct twl_softc *sc;
	unsigned i;
	uint8_t devs[TWL_MAX_SUBADDRS];
	uint8_t base = TWL_CHIP_ID0;

	sc = device_get_softc((device_t)dev);

	memset(devs, TWL_INVALID_CHIP_ID, TWL_MAX_SUBADDRS);

	/* Try each of the addresses (0x48, 0x49, 0x4a & 0x4b) to determine which
	 * sub modules we have.
	 */
	for (i = 0; i < TWL_MAX_SUBADDRS; i++) {
		if (twl_test_present(sc, (base + i)) == 0) {
			devs[i] = (base + i);
			device_printf(sc->sc_dev, "Found (sub)device at 0x%02x\n", (base + i));
		}
	}

	TWL_LOCK(sc);
	memcpy(sc->sc_subaddr_map, devs, TWL_MAX_SUBADDRS);
	TWL_UNLOCK(sc);

	/* Finished with the interrupt hook */
	config_intrhook_disestablish(&sc->sc_scan_hook);
}
static void
am335x_pmic_start(void *xdev)
{
	struct am335x_pmic_softc *sc;
	device_t dev = (device_t)xdev;
	uint8_t reg;
	char name[20];
	char pwr[4][11] = {"Unknown", "USB", "AC", "USB and AC"};

	sc = device_get_softc(dev);

	am335x_pmic_read(dev, TPS65217_CHIPID_REG, &reg, 1);
	switch (reg>>4) {
		case TPS65217A:
			sprintf(name, "TPS65217A ver 1.%u", reg & 0xF);
			break;
		case TPS65217B:
			sprintf(name, "TPS65217B ver 1.%u", reg & 0xF);
			break;
		default:
			sprintf(name, "Unknown PMIC");
	}

	am335x_pmic_read(dev, TPS65217_STATUS_REG, &reg, 1);
	device_printf(dev, "%s powered by %s\n", name, pwr[(reg>>2)&0x03]);

	config_intrhook_disestablish(&sc->enum_hook);
}
Esempio n. 5
0
static void
i2s_postattach(void *xsc)
{
	struct i2s_softc 	*sc = xsc;
	device_t 		 self;
	int 			 i;

	self = sc->aoa.sc_dev;

	/* Reset the codec. */
	i2s_audio_hw_reset(sc);

	/* If we have a codec, initialize it. */
	if (i2s_mixer)
		mixer_init(self, i2s_mixer_class, i2s_mixer);

	/* Read initial port status. */
	i2s_cint(sc);

	/* Enable GPIO interrupt callback. */	
	for (i = 0; i < GPIO_CTRL_NUM; i++)
		if (gpio_ctrls[i])
			gpio_ctrls[i]->i2s = sc;

	config_intrhook_disestablish(i2s_delayed_attach);
	free(i2s_delayed_attach, M_TEMP);
}
Esempio n. 6
0
/**
 * \brief Attach the XenBus back bus.
 *
 * \param dev  NewBus device_t for this XenBus back bus instance.
 *
 * \return  On success, 0. Otherwise an errno value indicating the
 *          type of failure.
 */
static int
xenbusb_back_attach(device_t dev)
{
	struct xenbusb_softc *xbs;
	int error;

	xbs = device_get_softc(dev);
	error = xenbusb_attach(dev, "backend", /*id_components*/2);

	/*
	 * Backend devices operate to serve other domains,
	 * so there is no need to hold up boot processing
	 * while connections to foreign domains are made.
	 */
	mtx_lock(&xbs->xbs_lock);
	if ((xbs->xbs_flags & XBS_ATTACH_CH_ACTIVE) != 0) {
		xbs->xbs_flags &= ~XBS_ATTACH_CH_ACTIVE;
		mtx_unlock(&xbs->xbs_lock);
		config_intrhook_disestablish(&xbs->xbs_attach_ch);
	} else {
		mtx_unlock(&xbs->xbs_lock);
	}

	return (error);
}
void isci_controller_domain_discovery_complete(
    struct ISCI_CONTROLLER *isci_controller, struct ISCI_DOMAIN *isci_domain)
{
	if (!isci_controller->has_been_scanned)
	{
		/* Controller has not been scanned yet.  We'll clear
		 *  the discovery bit for this domain, then check if all bits
		 *  are now clear.  That would indicate that all domains are
		 *  done with discovery and we can then proceed with initial
		 *  scan.
		 */

		isci_controller->initial_discovery_mask &=
		    ~(1 << isci_domain->index);

		if (isci_controller->initial_discovery_mask == 0) {
			struct isci_softc *driver = isci_controller->isci;
			uint8_t next_index = isci_controller->index + 1;

			isci_controller->has_been_scanned = TRUE;

			/* Unfreeze simq to allow initial scan to proceed. */
			xpt_release_simq(isci_controller->sim, TRUE);

#if __FreeBSD_version < 800000
			/* When driver is loaded after boot, we need to
			 *  explicitly rescan here for versions <8.0, because
			 *  CAM only automatically scans new buses at boot
			 *  time.
			 */
			union ccb *ccb = xpt_alloc_ccb_nowait();

			xpt_create_path(&ccb->ccb_h.path, xpt_periph,
			    cam_sim_path(isci_controller->sim),
			    CAM_TARGET_WILDCARD, CAM_LUN_WILDCARD);

			xpt_rescan(ccb);
#endif

			if (next_index < driver->controller_count) {
				/*  There are more controllers that need to
				 *   start.  So start the next one.
				 */
				isci_controller_start(
				    &driver->controllers[next_index]);
			}
			else
			{
				/* All controllers have been started and completed discovery.
				 *  Disestablish the config hook while will signal to the
				 *  kernel during boot that it is safe to try to find and
				 *  mount the root partition.
				 */
				config_intrhook_disestablish(
				    &driver->config_hook);
			}
		}
	}
}
Esempio n. 8
0
static void
intr_setup(void *arg)
{
	struct imx6_anatop_softc *sc;

	sc = arg;
	bus_setup_intr(sc->dev, sc->res[IRQRES], INTR_TYPE_MISC | INTR_MPSAFE,
	    tempmon_intr, NULL, sc, &sc->temp_intrhand);
	config_intrhook_disestablish(&sc->intr_setup_hook);
}
Esempio n. 9
0
/********************************************************************************
 * Delayed-startup hook
 */
static void
twe_intrhook(void *arg)
{
    struct twe_softc		*sc = (struct twe_softc *)arg;

    /* pull ourselves off the intrhook chain */
    config_intrhook_disestablish(&sc->twe_ich);

    /* call core startup routine */
    twe_init(sc);
}
Esempio n. 10
0
static void
ida_startup(void *arg)
{
	struct ida_softc *ida;

	ida = arg;

	config_intrhook_disestablish(&ida->ich);

	mtx_lock(&Giant);
	bus_generic_attach(ida->dev);
	mtx_unlock(&Giant);
}
Esempio n. 11
0
/*
 * Function name:	twa_intrhook
 * Description:		Callback for us to enable interrupts.
 *
 * Input:		arg	-- ptr to per ctlr structure
 * Output:		None
 * Return value:	None
 */
static void
twa_intrhook(void *arg)
{
	struct twa_softc	*sc = (struct twa_softc *)arg;

	twa_dbg_dprint(4, sc, "twa_intrhook Entered");

	/* Pull ourselves off the intrhook chain. */
	config_intrhook_disestablish(&sc->twa_ich);

	/* Enable interrupts. */
	twa_enable_interrupts(sc);
}
Esempio n. 12
0
static void
bcm_fb_init(void *arg)
{
	struct bcmsc_softc *sc = arg;
	struct video_adapter_softc *va_sc = &va_softc;
	int err;
	volatile struct bcm_fb_config*	fb_config = sc->fb_config;

	/* TODO: replace it with FDT stuff */
	fb_config->xres = FB_WIDTH;
	fb_config->yres = FB_HEIGHT;
	fb_config->vxres = 0;
	fb_config->vyres = 0;
	fb_config->xoffset = 0;
	fb_config->yoffset = 0;
	fb_config->bpp = 24;
	fb_config->base = 0;
	fb_config->pitch = 0;
	fb_config->screen_size = 0;

	bus_dmamap_sync(sc->dma_tag, sc->dma_map,
		BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
	bcm_mbox_write(BCM2835_MBOX_CHAN_FB, sc->fb_config_phys);
	bcm_mbox_read(BCM2835_MBOX_CHAN_FB, &err);
	bus_dmamap_sync(sc->dma_tag, sc->dma_map,
		BUS_DMASYNC_POSTREAD);

	if (err == 0) {
		device_printf(sc->dev, "%dx%d(%dx%d@%d,%d) %dbpp\n", 
			fb_config->xres, fb_config->yres,
			fb_config->vxres, fb_config->vyres,
			fb_config->xoffset, fb_config->yoffset,
			fb_config->bpp);


		device_printf(sc->dev, "pitch %d, base 0x%08x, screen_size %d\n", 
			fb_config->pitch, fb_config->base,
			fb_config->screen_size);

		if (fb_config->base) {
			va_sc->fb_addr = (intptr_t)pmap_mapdev(fb_config->base, fb_config->screen_size);
			va_sc->fb_size = fb_config->screen_size;
			va_sc->stride = fb_config->pitch;
		}
	}
	else
		device_printf(sc->dev, "Failed to set framebuffer info\n");

	config_intrhook_disestablish(&sc->init_hook);
}
Esempio n. 13
0
/**
 * \brief Decrement the number of XenBus child devices in the
 *        connecting state by one and release the xbs_attch_ch
 *        interrupt configuration hook if the connecting count
 *        drops to zero.
 *
 * \param xbs  XenBus Bus device softc of the owner of the bus to enumerate.
 */
static void
xenbusb_release_confighook(struct xenbusb_softc *xbs)
{
	mtx_lock(&xbs->xbs_lock);
	KASSERT(xbs->xbs_connecting_children > 0,
		("Connecting device count error\n"));
	xbs->xbs_connecting_children--;
	if (xbs->xbs_connecting_children == 0
	 && (xbs->xbs_flags & XBS_ATTACH_CH_ACTIVE) != 0) {
		xbs->xbs_flags &= ~XBS_ATTACH_CH_ACTIVE;
		mtx_unlock(&xbs->xbs_lock);
		config_intrhook_disestablish(&xbs->xbs_attach_ch);
	} else {
		mtx_unlock(&xbs->xbs_lock);
	}
}
Esempio n. 14
0
void
ig4iic_start(void *xdev)
{
	int error;
	ig4iic_softc_t *sc;
	device_t dev = (device_t)xdev;

	sc = device_get_softc(dev);

	config_intrhook_disestablish(&sc->enum_hook);

	/* Attach us to the smbus */
	error = bus_generic_attach(sc->dev);
	if (error) {
		device_printf(sc->dev,
			      "failed to attach child: error %d\n", error);
	}
}
Esempio n. 15
0
static void
athp_attach_preinit(void *arg)
{
	struct ath10k *ar = arg;
	struct ath10k_pci *ar_pci = ar->sc_psc;
	int ret;

	config_intrhook_disestablish(&ar->sc_preinit_hook);

	/* Setup ioctl handler */
	athp_ioctl_setup(ar);

	ret = ath10k_core_register(ar);
	if (ret == 0)
		return;

	/* Shutdown ioctl handler */
	athp_ioctl_teardown(ar);

	/* XXX TODO: refactor this stuff out */
	athp_pci_free_bufs(ar_pci);

	/* Ensure we disable interrupts from the device */
	ath10k_pci_deinit_irq(ar_pci);

	ath10k_pci_free_irq(ar_pci);

	bus_release_resource(ar->sc_dev, SYS_RES_MEMORY, BS_BAR, ar_pci->sc_sr);

	/* XXX disable busmaster? */
	mtx_destroy(&ar_pci->ps_mtx);
	mtx_destroy(&ar_pci->ce_mtx);
	mtx_destroy(&ar->sc_conf_mtx);
	mtx_destroy(&ar->sc_data_mtx);
	mtx_destroy(&ar->sc_buf_mtx);
	mtx_destroy(&ar->sc_dma_mtx);
	mtx_destroy(&ar->sc_mtx);
	if (ar_pci->pipe_taskq) {
		taskqueue_drain_all(ar_pci->pipe_taskq);
		taskqueue_free(ar_pci->pipe_taskq);
	}
	ath10k_core_destroy(ar);
}
Esempio n. 16
0
void isci_controller_domain_discovery_complete(
    struct ISCI_CONTROLLER *isci_controller, struct ISCI_DOMAIN *isci_domain)
{
	if (isci_controller->sim == NULL)
	{
		/* Controller has not been attached to CAM yet.  We'll clear
		 *  the discovery bit for this domain, then check if all bits
		 *  are now clear.  That would indicate that all domains are
		 *  done with discovery and we can then attach the controller
		 *  to CAM.
		 */

		isci_controller->initial_discovery_mask &=
		    ~(1 << isci_domain->index);

		if (isci_controller->initial_discovery_mask == 0) {
			struct isci_softc *driver = isci_controller->isci;
			uint8_t next_index = isci_controller->index + 1;

			isci_controller_attach_to_cam(isci_controller);

			if (next_index < driver->controller_count) {
				/*  There are more controllers that need to
				 *   start.  So start the next one.
				 */
				isci_controller_start(
				    &driver->controllers[next_index]);
			}
			else
			{
				/* All controllers have been started and completed discovery.
				 *  Disestablish the config hook while will signal to the
				 *  kernel during boot that it is safe to try to find and
				 *  mount the root partition.
				 */
				config_intrhook_disestablish(
				    &driver->config_hook);
			}
		}
	}
}
static void
xenbus_attach_deferred(void *arg)
{
	device_t dev = (device_t) arg;
	struct xenbus_softc *sc = device_get_softc(dev);
	int error;
	
	error = xenbus_enumerate_bus(dev, "device");
	if (error)
		return;
	xenbus_probe_children(dev);

	sc->xs_dev = dev;
	sc->xs_devicewatch.node = "device";
	sc->xs_devicewatch.callback = xenbus_devices_changed;

	TASK_INIT(&sc->xs_probechildren, 0, xenbus_probe_children_cb, dev);

	register_xenbus_watch(&sc->xs_devicewatch);

	config_intrhook_disestablish(&sc->xs_attachcb);
}
Esempio n. 18
0
static void
ds1307_start(void *xdev)
{
	device_t dev;
	struct ds1307_softc *sc;
	struct sysctl_ctx_list *ctx;
	struct sysctl_oid *tree_node;
	struct sysctl_oid_list *tree;

	dev = (device_t)xdev;
	sc = device_get_softc(dev);
	ctx = device_get_sysctl_ctx(dev);
	tree_node = device_get_sysctl_tree(dev);
	tree = SYSCTL_CHILDREN(tree_node);

	config_intrhook_disestablish(&sc->enum_hook);
	/* Set the 24 hours mode. */
	if (ds1307_set_24hrs_mode(sc) != 0)
		return;
	/* Enable the oscillator if halted. */
	if (ds1307_osc_enable(sc) != 0)
		return;

	/* Configuration parameters. */
	SYSCTL_ADD_PROC(ctx, tree, OID_AUTO, "sqwe",
	    CTLFLAG_RW | CTLTYPE_UINT | CTLFLAG_MPSAFE, sc, 0,
	    ds1307_sqwe_sysctl, "IU", "DS1307 square-wave enable");
	SYSCTL_ADD_PROC(ctx, tree, OID_AUTO, "sqw_freq",
	    CTLFLAG_RW | CTLTYPE_UINT | CTLFLAG_MPSAFE, sc, 0,
	    ds1307_sqw_freq_sysctl, "IU",
	    "DS1307 square-wave output frequency");
	SYSCTL_ADD_PROC(ctx, tree, OID_AUTO, "sqw_out",
	    CTLFLAG_RW | CTLTYPE_UINT | CTLFLAG_MPSAFE, sc, 0,
	    ds1307_sqw_out_sysctl, "IU", "DS1307 square-wave output state");

	/* 1 second resolution. */
	clock_register(dev, 1000000);
}
Esempio n. 19
0
static void
bcm2835_audio_delayed_init(void *xsc)
{
    	struct bcm2835_audio_info *sc;
    	char status[SND_STATUSLEN];

	sc = xsc;

	config_intrhook_disestablish(&sc->intr_hook);

	bcm2835_audio_init(sc);
	bcm2835_audio_open(sc);
	sc->volume = 75;
	sc->dest = DEST_AUTO;

    	if (mixer_init(sc->dev, &bcmmixer_class, sc)) {
		device_printf(sc->dev, "mixer_init failed\n");
		goto no;
	}

    	if (pcm_register(sc->dev, sc, 1, 1)) {
		device_printf(sc->dev, "pcm_register failed\n");
		goto no;
	}

	pcm_addchan(sc->dev, PCMDIR_PLAY, &bcmchan_class, sc);
    	snprintf(status, SND_STATUSLEN, "at VCHIQ");
	pcm_setstatus(sc->dev, status);

	bcm2835_audio_reset_channel(&sc->pch);
	bcm2835_audio_create_worker(sc);

	vchi_audio_sysctl_init(sc);

no:
	;
}
static void
ata_boot_attach(void)
{
    struct ata_channel *ch;
    int ctlr;

    mtx_lock(&Giant);       /* newbus suckage it needs Giant */

    /* kick of probe and attach on all channels */
    for (ctlr = 0; ctlr < devclass_get_maxunit(ata_devclass); ctlr++) {
	if ((ch = devclass_get_softc(ata_devclass, ctlr))) {
	    ata_identify(ch->dev);
	}
    }

    /* release the hook that got us here, we are only needed once during boot */
    if (ata_delayed_attach) {
	config_intrhook_disestablish(ata_delayed_attach);
	free(ata_delayed_attach, M_TEMP);
	ata_delayed_attach = NULL;
    }

    mtx_unlock(&Giant);     /* newbus suckage dealt with, release Giant */
}
Esempio n. 21
0
static void
bcm2835_cpufreq_init(void *arg)
{
	struct bcm2835_cpufreq_softc *sc = arg;
	struct sysctl_ctx_list *ctx;
	device_t cpu;
	int arm_freq, core_freq, sdram_freq;
	int arm_max_freq, arm_min_freq, core_max_freq, core_min_freq;
	int sdram_max_freq, sdram_min_freq;
	int voltage_core, voltage_sdram_c, voltage_sdram_i, voltage_sdram_p;
	int max_voltage_core, min_voltage_core;
	int max_voltage_sdram_c, min_voltage_sdram_c;
	int max_voltage_sdram_i, min_voltage_sdram_i;
	int max_voltage_sdram_p, min_voltage_sdram_p;
	int turbo, temperature;

	VC_LOCK(sc);

	/* current clock */
	arm_freq = bcm2835_cpufreq_get_clock_rate(sc,
	    BCM2835_MBOX_CLOCK_ID_ARM);
	core_freq = bcm2835_cpufreq_get_clock_rate(sc,
	    BCM2835_MBOX_CLOCK_ID_CORE);
	sdram_freq = bcm2835_cpufreq_get_clock_rate(sc,
	    BCM2835_MBOX_CLOCK_ID_SDRAM);

	/* max/min clock */
	arm_max_freq = bcm2835_cpufreq_get_max_clock_rate(sc,
	    BCM2835_MBOX_CLOCK_ID_ARM);
	arm_min_freq = bcm2835_cpufreq_get_min_clock_rate(sc,
	    BCM2835_MBOX_CLOCK_ID_ARM);
	core_max_freq = bcm2835_cpufreq_get_max_clock_rate(sc,
	    BCM2835_MBOX_CLOCK_ID_CORE);
	core_min_freq = bcm2835_cpufreq_get_min_clock_rate(sc,
	    BCM2835_MBOX_CLOCK_ID_CORE);
	sdram_max_freq = bcm2835_cpufreq_get_max_clock_rate(sc,
	    BCM2835_MBOX_CLOCK_ID_SDRAM);
	sdram_min_freq = bcm2835_cpufreq_get_min_clock_rate(sc,
	    BCM2835_MBOX_CLOCK_ID_SDRAM);

	/* turbo mode */
	turbo = bcm2835_cpufreq_get_turbo(sc);
	if (turbo > 0)
		sc->turbo_mode = BCM2835_MBOX_TURBO_ON;
	else
		sc->turbo_mode = BCM2835_MBOX_TURBO_OFF;

	/* voltage */
	voltage_core = bcm2835_cpufreq_get_voltage(sc,
	    BCM2835_MBOX_VOLTAGE_ID_CORE);
	voltage_sdram_c = bcm2835_cpufreq_get_voltage(sc,
	    BCM2835_MBOX_VOLTAGE_ID_SDRAM_C);
	voltage_sdram_i = bcm2835_cpufreq_get_voltage(sc,
	    BCM2835_MBOX_VOLTAGE_ID_SDRAM_I);
	voltage_sdram_p = bcm2835_cpufreq_get_voltage(sc,
	    BCM2835_MBOX_VOLTAGE_ID_SDRAM_P);

	/* current values (offset from 1.2V) */
	sc->voltage_core = voltage_core;
	sc->voltage_sdram = voltage_sdram_c;
	sc->voltage_sdram_c = voltage_sdram_c;
	sc->voltage_sdram_i = voltage_sdram_i;
	sc->voltage_sdram_p = voltage_sdram_p;

	/* max/min voltage */
	max_voltage_core = bcm2835_cpufreq_get_max_voltage(sc,
	    BCM2835_MBOX_VOLTAGE_ID_CORE);
	min_voltage_core = bcm2835_cpufreq_get_min_voltage(sc,
	    BCM2835_MBOX_VOLTAGE_ID_CORE);
	max_voltage_sdram_c = bcm2835_cpufreq_get_max_voltage(sc,
	    BCM2835_MBOX_VOLTAGE_ID_SDRAM_C);
	max_voltage_sdram_i = bcm2835_cpufreq_get_max_voltage(sc,
	    BCM2835_MBOX_VOLTAGE_ID_SDRAM_I);
	max_voltage_sdram_p = bcm2835_cpufreq_get_max_voltage(sc,
	    BCM2835_MBOX_VOLTAGE_ID_SDRAM_P);
	min_voltage_sdram_c = bcm2835_cpufreq_get_min_voltage(sc,
	    BCM2835_MBOX_VOLTAGE_ID_SDRAM_C);
	min_voltage_sdram_i = bcm2835_cpufreq_get_min_voltage(sc,
	    BCM2835_MBOX_VOLTAGE_ID_SDRAM_I);
	min_voltage_sdram_p = bcm2835_cpufreq_get_min_voltage(sc,
	    BCM2835_MBOX_VOLTAGE_ID_SDRAM_P);

	/* temperature */
	temperature = bcm2835_cpufreq_get_temperature(sc);

	/* show result */
	if (cpufreq_verbose || bootverbose) {
		device_printf(sc->dev, "Boot settings:\n");
		device_printf(sc->dev,
		    "current ARM %dMHz, Core %dMHz, SDRAM %dMHz, Turbo %s\n",
		    HZ2MHZ(arm_freq), HZ2MHZ(core_freq), HZ2MHZ(sdram_freq),
		    (sc->turbo_mode == BCM2835_MBOX_TURBO_ON) ? "ON" : "OFF");

		device_printf(sc->dev,
		    "max/min ARM %d/%dMHz, Core %d/%dMHz, SDRAM %d/%dMHz\n",
		    HZ2MHZ(arm_max_freq), HZ2MHZ(arm_min_freq),
		    HZ2MHZ(core_max_freq), HZ2MHZ(core_min_freq),
		    HZ2MHZ(sdram_max_freq), HZ2MHZ(sdram_min_freq));

		device_printf(sc->dev,
		    "current Core %dmV, SDRAM_C %dmV, SDRAM_I %dmV, "
		    "SDRAM_P %dmV\n",
		    OFFSET2MVOLT(voltage_core), OFFSET2MVOLT(voltage_sdram_c),
		    OFFSET2MVOLT(voltage_sdram_i), 
		    OFFSET2MVOLT(voltage_sdram_p));

		device_printf(sc->dev,
		    "max/min Core %d/%dmV, SDRAM_C %d/%dmV, SDRAM_I %d/%dmV, "
		    "SDRAM_P %d/%dmV\n",
		    OFFSET2MVOLT(max_voltage_core),
		    OFFSET2MVOLT(min_voltage_core),
		    OFFSET2MVOLT(max_voltage_sdram_c),
		    OFFSET2MVOLT(min_voltage_sdram_c),
		    OFFSET2MVOLT(max_voltage_sdram_i),
		    OFFSET2MVOLT(min_voltage_sdram_i),
		    OFFSET2MVOLT(max_voltage_sdram_p),
		    OFFSET2MVOLT(min_voltage_sdram_p));

		device_printf(sc->dev,
		    "Temperature %d.%dC\n", (temperature / 1000),
		    (temperature % 1000) / 100);
	} else { /* !cpufreq_verbose && !bootverbose */
		device_printf(sc->dev,
		    "ARM %dMHz, Core %dMHz, SDRAM %dMHz, Turbo %s\n",
		    HZ2MHZ(arm_freq), HZ2MHZ(core_freq), HZ2MHZ(sdram_freq),
		    (sc->turbo_mode == BCM2835_MBOX_TURBO_ON) ? "ON" : "OFF");
	}

	/* keep in softc (MHz/mV) */
	sc->arm_max_freq = HZ2MHZ(arm_max_freq);
	sc->arm_min_freq = HZ2MHZ(arm_min_freq);
	sc->core_max_freq = HZ2MHZ(core_max_freq);
	sc->core_min_freq = HZ2MHZ(core_min_freq);
	sc->sdram_max_freq = HZ2MHZ(sdram_max_freq);
	sc->sdram_min_freq = HZ2MHZ(sdram_min_freq);
	sc->max_voltage_core = OFFSET2MVOLT(max_voltage_core);
	sc->min_voltage_core = OFFSET2MVOLT(min_voltage_core);

	/* if turbo is on, set to max values */
	if (sc->turbo_mode == BCM2835_MBOX_TURBO_ON) {
		bcm2835_cpufreq_set_clock_rate(sc, BCM2835_MBOX_CLOCK_ID_ARM,
		    arm_max_freq);
		DELAY(TRANSITION_LATENCY);
		bcm2835_cpufreq_set_clock_rate(sc, BCM2835_MBOX_CLOCK_ID_CORE,
		    core_max_freq);
		DELAY(TRANSITION_LATENCY);
		bcm2835_cpufreq_set_clock_rate(sc,
		    BCM2835_MBOX_CLOCK_ID_SDRAM, sdram_max_freq);
		DELAY(TRANSITION_LATENCY);
	} else {
		bcm2835_cpufreq_set_clock_rate(sc, BCM2835_MBOX_CLOCK_ID_ARM,
		    arm_min_freq);
		DELAY(TRANSITION_LATENCY);
		bcm2835_cpufreq_set_clock_rate(sc, BCM2835_MBOX_CLOCK_ID_CORE,
		    core_min_freq);
		DELAY(TRANSITION_LATENCY);
		bcm2835_cpufreq_set_clock_rate(sc,
		    BCM2835_MBOX_CLOCK_ID_SDRAM, sdram_min_freq);
		DELAY(TRANSITION_LATENCY);
	}

	VC_UNLOCK(sc);

	/* add human readable temperature to dev.cpu node */
	cpu = device_get_parent(sc->dev);
	if (cpu != NULL) {
		ctx = device_get_sysctl_ctx(cpu);
		SYSCTL_ADD_PROC(ctx,
		    SYSCTL_CHILDREN(device_get_sysctl_tree(cpu)), OID_AUTO,
		    "temperature", CTLTYPE_INT | CTLFLAG_RD, sc, 0,
		    sysctl_bcm2835_devcpu_temperature, "IK",
		    "Current SoC temperature");
	}

	/* release this hook (continue boot) */
	config_intrhook_disestablish(&sc->init_hook);
}
Esempio n. 22
0
static void 
ata_boot_attach(void)
{
    struct ata_channel *ch;
    int ctlr, s;

    if (ata_delayed_attach) {
	config_intrhook_disestablish(ata_delayed_attach);
	free(ata_delayed_attach, M_TEMP);
	ata_delayed_attach = NULL;
    }
    s = splbio();

    /*
     * run through all ata devices and look for real ATA & ATAPI devices
     * using the hints we found in the early probe, this avoids some of
     * the delays probing of non-exsistent devices can cause.
     */
    for (ctlr=0; ctlr<devclass_get_maxunit(ata_devclass); ctlr++) {
	if (!(ch = devclass_get_softc(ata_devclass, ctlr)))
	    continue;
	if (ch->devices & ATA_ATA_SLAVE)
	    if (ata_getparam(&ch->device[SLAVE], ATA_C_ATA_IDENTIFY))
		ch->devices &= ~ATA_ATA_SLAVE;
	if (ch->devices & ATA_ATAPI_SLAVE)
	    if (ata_getparam(&ch->device[SLAVE], ATA_C_ATAPI_IDENTIFY))
		ch->devices &= ~ATA_ATAPI_SLAVE;
	if (ch->devices & ATA_ATA_MASTER)
	    if (ata_getparam(&ch->device[MASTER], ATA_C_ATA_IDENTIFY))
		ch->devices &= ~ATA_ATA_MASTER;
	if (ch->devices & ATA_ATAPI_MASTER)
	    if (ata_getparam(&ch->device[MASTER], ATA_C_ATAPI_IDENTIFY))
		ch->devices &= ~ATA_ATAPI_MASTER;
    }

#if NATADISK > 0
    /* now we know whats there, do the real attach, first the ATA disks */
    for (ctlr=0; ctlr<devclass_get_maxunit(ata_devclass); ctlr++) {
	if (!(ch = devclass_get_softc(ata_devclass, ctlr)))
	    continue;
	if (ch->devices & ATA_ATA_MASTER)
	    ad_attach(&ch->device[MASTER], 0);
	if (ch->devices & ATA_ATA_SLAVE)
	    ad_attach(&ch->device[SLAVE], 0);
    }
    ata_raid_attach();
#endif
#if DEV_ATAPIALL
    /* then the atapi devices */
    for (ctlr=0; ctlr<devclass_get_maxunit(ata_devclass); ctlr++) {
	if (!(ch = devclass_get_softc(ata_devclass, ctlr)))
	    continue;
	if (ch->devices & ATA_ATAPI_MASTER)
	    atapi_attach(&ch->device[MASTER], 0);
	if (ch->devices & ATA_ATAPI_SLAVE)
	    atapi_attach(&ch->device[SLAVE], 0);
#if NATAPICAM > 0
	atapi_cam_attach_bus(ch);
#endif
    }
#endif
    splx(s);
}
Esempio n. 23
0
static void
am335x_pmic_start(void *xdev)
{
	struct am335x_pmic_softc *sc;
	device_t dev = (device_t)xdev;
	struct tps65217_status_reg status_reg;
	struct tps65217_chipid_reg chipid_reg;
	uint8_t reg, vo;
	char name[20];
	char pwr[4][11] = {"Battery", "USB", "AC", "USB and AC"};
	int rv;

	sc = device_get_softc(dev);

	am335x_pmic_read(dev, TPS65217_CHIPID_REG, (uint8_t *)&chipid_reg, 1);
	switch (chipid_reg.chip) {
		case TPS65217A:
			sprintf(name, "TPS65217A ver 1.%u", chipid_reg.rev);
			break;
		case TPS65217B:
			sprintf(name, "TPS65217B ver 1.%u", chipid_reg.rev);
			break;
		case TPS65217C:
			sprintf(name, "TPS65217C ver 1.%u", chipid_reg.rev);
			break;
		case TPS65217D:
			sprintf(name, "TPS65217D ver 1.%u", chipid_reg.rev);
			break;
		default:
			sprintf(name, "Unknown PMIC");
	}

	am335x_pmic_read(dev, TPS65217_STATUS_REG, (uint8_t *)&status_reg, 1);
	device_printf(dev, "%s powered by %s\n", name,
	    pwr[status_reg.usbpwr | (status_reg.acpwr << 1)]);

	if (am335x_pmic_vo[0] != '\0') {
		for (vo = 0; vo < 4; vo++) {
			if (strcmp(tps65217_voreg_c[vo], am335x_pmic_vo) == 0)
				break;
		}
		if (vo == 4) {
			device_printf(dev, "WARNING: hw.am335x_pmic.vo=\"%s\""
			    ": unsupported value\n", am335x_pmic_vo);
		} else {
			am335x_pmic_setvo(dev, vo);
		}
	}

	if (bootverbose || am335x_pmic_bootverbose) {
		am335x_pmic_dump_chgconfig(dev);
	}

	EVENTHANDLER_REGISTER(shutdown_final, am335x_pmic_shutdown, dev,
	    SHUTDOWN_PRI_LAST);

	config_intrhook_disestablish(&sc->enum_hook);

	/* Unmask all interrupts and clear pending status */
	reg = 0;
	am335x_pmic_write(dev, TPS65217_INT_REG, &reg, 1);
	am335x_pmic_read(dev, TPS65217_INT_REG, &reg, 1);

	if (sc->sc_irq_res != NULL) {
		rv = bus_setup_intr(dev, sc->sc_irq_res,
		    INTR_TYPE_MISC | INTR_MPSAFE, NULL, am335x_pmic_intr,
		    sc, &sc->sc_intrhand);
		if (rv != 0)
			device_printf(dev,
			    "Unable to setup the irq handler.\n");
	}
}
Esempio n. 24
0
static void
adb_bus_enumerate(void *xdev)
{
	device_t dev = (device_t)xdev;

	struct adb_softc *sc = device_get_softc(dev);
	uint8_t i, next_free;
	uint16_t r3;

	sc->sc_dev = dev;
	sc->parent = device_get_parent(dev);

	sc->packet_reply = 0;
	sc->autopoll_mask = 0;
	sc->sync_packet = 0xffff;

	/* Initialize devinfo */
	for (i = 0; i < 16; i++) {
		sc->devinfo[i].address = i;
		sc->devinfo[i].default_address = 0;
	}
	
	/* Reset ADB bus */
	adb_send_raw_packet_sync(dev,0,ADB_COMMAND_BUS_RESET,0,0,NULL,NULL);
	DELAY(1500);

	/* Enumerate bus */
	next_free = 8;

	for (i = 1; i <= 7; i++) {
	    int8_t first_relocated = -1;
	    int reply = 0;

	    do {
		reply = adb_send_raw_packet_sync(dev,i,
			    ADB_COMMAND_TALK,3,0,NULL,NULL);
	
		if (reply) {
			/* If we got a response, relocate to next_free */
			r3 = sc->devinfo[i].register3;
			r3 &= 0xf000;
			r3 |= ((uint16_t)(next_free) & 0x000f) << 8;
			r3 |= 0x00fe;

			adb_send_raw_packet_sync(dev,i, ADB_COMMAND_LISTEN,3,
			    sizeof(uint16_t),(u_char *)(&r3),NULL);

			adb_send_raw_packet_sync(dev,next_free,
			    ADB_COMMAND_TALK,3,0,NULL,NULL);

			sc->devinfo[next_free].default_address = i;
			if (first_relocated < 0)
				first_relocated = next_free;

			next_free++;
		} else if (first_relocated > 0) {
			/* Collisions removed, relocate first device back */

			r3 = sc->devinfo[i].register3;
			r3 &= 0xf000;
			r3 |= ((uint16_t)(i) & 0x000f) << 8;
			
			adb_send_raw_packet_sync(dev,first_relocated,
			    ADB_COMMAND_LISTEN,3,
			    sizeof(uint16_t),(u_char *)(&r3),NULL);
			adb_send_raw_packet_sync(dev,i,
			    ADB_COMMAND_TALK,3,0,NULL,NULL);

			sc->devinfo[i].default_address = i;
			sc->devinfo[(int)(first_relocated)].default_address = 0;
			break;
		}
	    } while (reply);
	}

	for (i = 0; i < 16; i++) {
		if (sc->devinfo[i].default_address) {
			sc->children[i] = device_add_child(dev, NULL, -1);
			device_set_ivars(sc->children[i], &sc->devinfo[i]);
		}
	}

	bus_generic_attach(dev);

	config_intrhook_disestablish(&sc->enum_hook);
}
Esempio n. 25
0
static void
atiixp_chip_post_init(void *arg)
{
	struct atiixp_info *sc = (struct atiixp_info *)arg;
	uint32_t subdev;
	int i, timeout, found;
	char status[SND_STATUSLEN];

	atiixp_lock(sc);

	if (sc->delayed_attach.ich_func) {
		config_intrhook_disestablish(&sc->delayed_attach);
		sc->delayed_attach.ich_func = NULL;
	}

	/* wait for the interrupts to happen */
	timeout = 100;
	while (--timeout) {
		snd_mtxsleep(sc, sc->lock, 0, "ixpslp", 1);
		if (sc->codec_not_ready_bits)
			break;
	}

	atiixp_disable_interrupts(sc);

	if (timeout == 0) {
		device_printf(sc->dev,
			"WARNING: timeout during codec detection; "
			"codecs might be present but haven't interrupted\n");
		atiixp_unlock(sc);
		goto postinitbad;
	}

	found = 0;

	/*
	 * ATI IXP can have upto 3 codecs, but single codec should be
	 * suffice for now.
	 */
	if (!(sc->codec_not_ready_bits &
				ATI_REG_ISR_CODEC0_NOT_READY)) {
		/* codec 0 present */
		sc->codec_found++;
		sc->codec_idx = 0;
		found++;
	}

	if (!(sc->codec_not_ready_bits &
				ATI_REG_ISR_CODEC1_NOT_READY)) {
		/* codec 1 present */
		sc->codec_found++;
	}

	if (!(sc->codec_not_ready_bits &
				ATI_REG_ISR_CODEC2_NOT_READY)) {
		/* codec 2 present */
		sc->codec_found++;
	}

	atiixp_unlock(sc);

	if (found == 0)
		goto postinitbad;

	/* create/init mixer */
	sc->codec = AC97_CREATE(sc->dev, sc, atiixp_ac97);
	if (sc->codec == NULL)
		goto postinitbad;

	subdev = (pci_get_subdevice(sc->dev) << 16) | pci_get_subvendor(sc->dev);
	switch (subdev) {
	case 0x11831043:	/* ASUS A6R */
	case 0x2043161f:	/* Maxselect x710s - http://maxselect.ru/ */
		ac97_setflags(sc->codec, ac97_getflags(sc->codec) | AC97_F_EAPD_INV);
		break;
	default:
		break;
	}

	mixer_init(sc->dev, ac97_getmixerclass(), sc->codec);

	if (pcm_register(sc->dev, sc, ATI_IXP_NPCHAN, ATI_IXP_NRCHAN))
		goto postinitbad;

	for (i = 0; i < ATI_IXP_NPCHAN; i++)
		pcm_addchan(sc->dev, PCMDIR_PLAY, &atiixp_chan_class, sc);
	for (i = 0; i < ATI_IXP_NRCHAN; i++)
		pcm_addchan(sc->dev, PCMDIR_REC, &atiixp_chan_class, sc);

	ksnprintf(status, SND_STATUSLEN, "at memory 0x%lx irq %ld %s", 
			rman_get_start(sc->reg), rman_get_start(sc->irq),
			PCM_KLDSTRING(snd_atiixp));

	pcm_setstatus(sc->dev, status);

	atiixp_lock(sc);
	atiixp_enable_interrupts(sc);
	atiixp_unlock(sc);

	return;

postinitbad:
	atiixp_release_resource(sc);
}
Esempio n. 26
0
static void
bcm_fb_init(void *arg)
{
	volatile struct bcm_fb_config *fb_config;
	struct bcmsc_softc *sc;
	struct fb_info *info;
	phandle_t node;
	pcell_t cell;
	device_t mbox;
	device_t fbd;
	int err = 0;

	sc = arg;
	fb_config = sc->fb_config;
	node = ofw_bus_get_node(sc->dev);

	fb_config->xres = 0;
	fb_config->yres = 0;
	fb_config->bpp = 0;
	fb_config->vxres = 0;
	fb_config->vyres = 0;
	fb_config->xoffset = 0;
	fb_config->yoffset = 0;
	fb_config->base = 0;
	fb_config->pitch = 0;
	fb_config->screen_size = 0;

	if ((OF_getprop(node, "broadcom,width", &cell, sizeof(cell))) > 0)
		fb_config->xres = (int)fdt32_to_cpu(cell);
	if (fb_config->xres == 0)
		fb_config->xres = FB_WIDTH;

	if ((OF_getprop(node, "broadcom,height", &cell, sizeof(cell))) > 0)
		fb_config->yres = (uint32_t)fdt32_to_cpu(cell);
	if (fb_config->yres == 0)
		fb_config->yres = FB_HEIGHT;

	if ((OF_getprop(node, "broadcom,depth", &cell, sizeof(cell))) > 0)
		fb_config->bpp = (uint32_t)fdt32_to_cpu(cell);
	if (fb_config->bpp == 0)
		fb_config->bpp = FB_DEPTH;

	bus_dmamap_sync(sc->dma_tag, sc->dma_map,
		BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);

	mbox = devclass_get_device(devclass_find("mbox"), 0);
	if (mbox) {
		MBOX_WRITE(mbox, BCM2835_MBOX_CHAN_FB, sc->fb_config_phys);
		MBOX_READ(mbox, BCM2835_MBOX_CHAN_FB, &err);
	}
	bus_dmamap_sync(sc->dma_tag, sc->dma_map,
		BUS_DMASYNC_POSTREAD);

	if (fb_config->base != 0) {
		device_printf(sc->dev, "%dx%d(%dx%d@%d,%d) %dbpp\n",
			fb_config->xres, fb_config->yres,
			fb_config->vxres, fb_config->vyres,
			fb_config->xoffset, fb_config->yoffset,
			fb_config->bpp);

		device_printf(sc->dev, "pitch %d, base 0x%08x, screen_size %d\n",
			fb_config->pitch, fb_config->base,
			fb_config->screen_size);

		info = malloc(sizeof(struct fb_info), M_DEVBUF,
		    M_WAITOK | M_ZERO);
		info->fb_name = device_get_nameunit(sc->dev);
		info->fb_vbase = (intptr_t)pmap_mapdev(fb_config->base,
		    fb_config->screen_size);
		info->fb_pbase = fb_config->base;
		info->fb_size = fb_config->screen_size;
		info->fb_bpp = info->fb_depth = fb_config->bpp;
		info->fb_stride = fb_config->pitch;
		info->fb_width = fb_config->xres;
		info->fb_height = fb_config->yres;

		sc->info = info;

		fbd = device_add_child(sc->dev, "fbd",
		    device_get_unit(sc->dev));
		if (fbd == NULL) {
			device_printf(sc->dev, "Failed to add fbd child\n");
			return;
		}
		if (device_probe_and_attach(fbd) != 0) {
			device_printf(sc->dev, "Failed to attach fbd device\n");
			return;
		}
	} else {
		device_printf(sc->dev, "Failed to set framebuffer info\n");
		return;
	}

	config_intrhook_disestablish(&sc->init_hook);
}