Beispiel #1
0
int __cpuinit arch_host_irq_init(void)
{
	int rc;
	physical_addr_t intc_pa;
	struct vmm_devtree_node *node;

	node = vmm_devtree_find_compatible(NULL, NULL, "ti,omap2-intc");
	if (!node) {
		return VMM_ENODEV;
	}

	rc = vmm_devtree_regaddr(node, &intc_pa, 0);
	if (rc) {
		return rc;
	}

	return intc_init(intc_pa, OMAP3_MPU_INTC_NRIRQ);
}
Beispiel #2
0
static int rbd_driver_probe(struct vmm_device *dev,
			    const struct vmm_devtree_nodeid *devid)
{
	int rc;
	physical_addr_t pa;
	physical_size_t sz;

	rc = vmm_devtree_regaddr(dev->node, &pa, 0);
	if (rc) {
		return rc;
	}

	rc = vmm_devtree_regsize(dev->node, &sz, 0);
	if (rc) {
		return rc;
	}

	dev->priv = __rbd_create(dev, dev->node->name, pa, sz);
	if (!dev->priv) {
		return VMM_EFAIL;
	}

	return VMM_OK;
}
Beispiel #3
0
static int sram_probe(struct vmm_device *dev,
		      const struct vmm_devtree_nodeid *nodeid)
{
	void *virt_base = NULL;
	struct sram_dev *sram = NULL;
	physical_addr_t start = 0;
	virtual_size_t size = 0;
	int ret = VMM_OK;

	ret = vmm_devtree_regaddr(dev->of_node, &start, 0);
	if (VMM_OK != ret) {
		vmm_printf("%s: Failed to get device base\n", dev->name);
		return ret;
	}

	ret = vmm_devtree_regsize(dev->of_node, &size, 0);
	if (VMM_OK != ret) {
		vmm_printf("%s: Failed to get device size\n", dev->name);
		goto err_out;
	}

	virt_base = (void *)vmm_host_iomap(start, size);
	if (NULL == virt_base) {
		vmm_printf("%s: Failed to get remap memory\n", dev->name);
		ret = VMM_ENOMEM;
		goto err_out;
	}

	sram = vmm_devm_zalloc(dev, sizeof(*sram));
	if (!sram) {
		vmm_printf("%s: Failed to allocate structure\n", dev->name);
		ret = VMM_ENOMEM;
		goto err_out;
	}

	sram->clk = devm_clk_get(dev, NULL);
	if (VMM_IS_ERR(sram->clk))
		sram->clk = NULL;
	else
		clk_prepare_enable(sram->clk);

	sram->pool = devm_gen_pool_create(dev, SRAM_GRANULARITY_LOG);
	if (!sram->pool) {
		vmm_printf("%s: Failed to create memory pool\n", dev->name);
		ret = VMM_ENOMEM;
	}

	ret = gen_pool_add_virt(sram->pool, (unsigned long)virt_base,
				start, size);
	if (ret < 0) {
		vmm_printf("%s: Failed to add memory chunk\n", dev->name);
		goto err_out;
	}

	vmm_devdrv_set_data(dev, sram);

	vmm_printf("%s: SRAM pool: %ld KiB @ 0x%p\n", dev->name, size / 1024,
		   virt_base);

	return 0;

err_out:
	if (sram->pool)
		gen_pool_destroy(sram->pool);

#if 0
	if (sram->clk)
		clk_disable_unprepare(sram->clk);
#endif /* 0 */

	if (sram)
		vmm_free(sram);
	sram = NULL;

	if (virt_base)
		vmm_host_iounmap((virtual_addr_t)virt_base);
	virt_base = NULL;

	return ret;
}
Beispiel #4
0
static int mmci_driver_probe(struct vmm_device *dev,
				   const struct vmm_devtree_nodeid *devid)
{
	int rc;
	u32 sdi;
	virtual_addr_t base;
	physical_addr_t basepa;
	struct mmc_host *mmc;
	struct mmci_host *host;

	mmc = mmc_alloc_host(sizeof(struct mmci_host), dev);
	if (!mmc) {
		rc = VMM_ENOMEM;
		goto free_nothing;
	}
	host = mmc_priv(mmc);

	rc = vmm_devtree_regmap(dev->node, &base, 0);
	if (rc) {
		goto free_host;
	}
	host->base = (struct sdi_registers *)base;

	rc = vmm_devtree_irq_get(dev->node, &host->irq0, 0);
	if (rc) {
		goto free_reg;
	}
	if ((rc = vmm_host_irq_register(host->irq0, dev->name, 
					mmci_cmd_irq_handler, mmc))) {
		goto free_reg;
	}

	rc = vmm_devtree_irq_get(dev->node, &host->irq1, 1);
	if (!rc) {
		if ((rc = vmm_host_irq_register(host->irq1, dev->name, 
						mmci_pio_irq_handler, mmc))) {
			goto free_irq0;
		}
		host->singleirq = 0;
	} else {
		host->singleirq = 1;
	}

	/* Retrive matching data */
	host->pwr_init = ((const u32 *)devid->data)[0];
	host->clkdiv_init = ((const u32 *)devid->data)[1];
	host->voltages = ((const u32 *)devid->data)[2];
	host->caps = ((const u32 *)devid->data)[3];
	host->clock_in = ((const u32 *)devid->data)[4];
	host->clock_min = ((const u32 *)devid->data)[5];
	host->clock_max = ((const u32 *)devid->data)[6];
	host->b_max = ((const u32 *)devid->data)[7];
	host->version2 = ((const u32 *)devid->data)[8];

	/* Initialize power and clock divider */
	vmm_writel(host->pwr_init, &host->base->power);
	vmm_writel(host->clkdiv_init, &host->base->clock);
	vmm_udelay(CLK_CHANGE_DELAY);

	/* Disable interrupts */
	sdi = vmm_readl(&host->base->mask0) & ~SDI_MASK0_MASK;
	vmm_writel(sdi, &host->base->mask0);

	/* Setup mmc host configuration */
	mmc->caps = host->caps;
	mmc->voltages = host->voltages;
	mmc->f_min = host->clock_min;
	mmc->f_max = host->clock_max;
	mmc->b_max = host->b_max;

	/* Setup mmc host operations */
	mmc->ops.send_cmd = mmci_request;
	mmc->ops.set_ios = mmci_set_ios;
	mmc->ops.init_card = mmci_init_card;
	mmc->ops.get_cd = NULL;
	mmc->ops.get_wp = NULL;

	rc = mmc_add_host(mmc);
	if (rc) {
		goto free_irq1;
	}

	dev->priv = mmc;

	vmm_devtree_regaddr(dev->node, &basepa, 0);
	vmm_printf("%s: PL%03x manf %x rev%u at 0x%08llx irq %d,%d (pio)\n",
		   dev->name, amba_part(dev), amba_manf(dev),
		   amba_rev(dev), (unsigned long long)basepa,
		   host->irq0, host->irq1);

	return VMM_OK;

free_irq1:
	if (!host->singleirq) {
		vmm_host_irq_unregister(host->irq1, mmc);
	}
free_irq0:
	vmm_host_irq_unregister(host->irq0, mmc);
free_reg:
	vmm_devtree_regunmap(dev->node, (virtual_addr_t)host->base, 0);
free_host:
	mmc_free_host(mmc);
free_nothing:
	return rc;
}
Beispiel #5
0
static int uart_8250_driver_probe(struct vmm_device *dev,
				  const struct vmm_devtree_nodeid *devid)
{
	int rc;
	struct uart_8250_port *port;
	physical_addr_t ioport;
	const char *aval;

	port = vmm_zalloc(sizeof(struct uart_8250_port));
	if(!port) {
		rc = VMM_ENOMEM;
		goto free_nothing;
	}

	if (vmm_devtree_read_string(dev->node,
				    VMM_DEVTREE_ADDRESS_TYPE_ATTR_NAME,
				    &aval)) {
		aval = NULL;
	}
	if (aval && !strcmp(aval, VMM_DEVTREE_ADDRESS_TYPE_VAL_IO)) {
		port->use_ioport = TRUE;
	} else {
		port->use_ioport = FALSE;
	}

	if (port->use_ioport) {
		rc = vmm_devtree_regaddr(dev->node, &ioport, 0);
		if (rc) {
			goto free_port;
		}
		port->base = ioport;
	} else {
		rc = vmm_devtree_request_regmap(dev->node, &port->base, 0,
						"UART 8250");
		if (rc) {
			goto free_port;
		}
	}

	if (vmm_devtree_read_u32(dev->node, "reg-shift",
				 &port->reg_shift)) {
		port->reg_shift = 0;
	}

	if (vmm_devtree_read_u32(dev->node, "reg-io-width",
				 &port->reg_width)) {
		port->reg_width = 1;
	}

	if (vmm_devtree_read_u32(dev->node, "baudrate",
				 &port->baudrate)) {
		port->baudrate = 115200;
	}

	rc = vmm_devtree_clock_frequency(dev->node, &port->input_clock);
	if (rc) {
		goto free_reg;
	}

	/* Call low-level init function
	 * Note: low-level init will make sure that
	 * interrupts are disabled in IER register.
	 */
	uart_8250_lowlevel_init(port);

	/* Setup interrupt handler */
	port->irq = vmm_devtree_irq_parse_map(dev->node, 0);
	if (!port->irq) {
		rc = VMM_ENODEV;
		goto free_reg;
	}
	if ((rc = vmm_host_irq_register(port->irq, dev->name,
					uart_8250_irq_handler, port))) {
		goto free_reg;
	}

	/* Create Serial Port */
	port->p = serial_create(dev, 256, uart_8250_tx, port);
	if (VMM_IS_ERR_OR_NULL(port->p)) {
		rc = VMM_PTR_ERR(port->p);
		goto free_irq;
	}

	/* Save port pointer */
	dev->priv = port;

	/* Unmask Rx interrupt */
	port->ier |= (UART_IER_RLSI | UART_IER_RDI);
	uart_8250_out(port, UART_IER_OFFSET, port->ier);

	return VMM_OK;

free_irq:
	vmm_host_irq_unregister(port->irq, port);
free_reg:
	if (!port->use_ioport) {
		vmm_devtree_regunmap_release(dev->node, port->base, 0);
	}
free_port:
	vmm_free(port);
free_nothing:
	return rc;
}