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); }
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; }
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; }
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; }
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; }